Greasy Fork is available in English.

Greasyfork Utility Toolkit

Providing various features for Greasyfork, including absolute time, widescreen web pages, script page enhancements, download extensions, panel fixes, and more.

// ==UserScript==
// @name        Greasyfork Utility Toolkit
// @name:en     Greasyfork Utility Toolkit
// @name:zh-CN  Greasyfork 糊裱匠
// @name:zh-TW  Greasyfork 糊裱匠
// @name:ja     Greasyfork ツールキット
// @name:ko     Greasyfork 유틸리티 툴킷
// @name:ru     Набор инструментов для Greasyfork
// @name:de     Greasyfork Dienstprogramm-Toolkit
// @name:fr     Toolkit utilitaire Greasyfork
// @name:it     Kit di strumenti utilitari Greasyfork
// @name:ar     مجموعة أدوات Greasyfork
// @name:he     ערכת כלים Greasyfork
// @name:vi     Bộ công cụ tiện ích Greasyfork

// @namespace    https://greasyfork.org/zh-CN/users/1169082-%E4%BA%BA%E6%B0%91%E7%9A%84%E5%8B%A4%E5%8A%A1%E5%91%98
// @description Providing various features for Greasyfork, including absolute time, widescreen web pages, script page enhancements, download extensions, panel fixes, and more.
// @description:en Providing various features for Greasyfork, including absolute time, widescreen web pages, script page enhancements, download extensions, panel fixes, and more.
// @description:zh-CN 为 Greasyfork 提供各种使用功能,绝对时间,网页宽屏,脚本页增强,下载拓展,面板修复等一系列操作
// @description:zh-TW 為 Greasyfork 提供各種使用功能,絕對時間,網頁寬屏,腳本頁增強,下載擴展,面板修復等一系列操作
// @description:ja Greasyfork に絶対時間、ワイドスクリーンウェブページ、スクリプトページの強化、ダウンロード拡張、パネル修正など、さまざまな機能を提供します。
// @description:ko Greasyfork에 절대 시간, 와이드스크린 웹 페이지, 스크립트 페이지 강화, 다운로드 확장, 패널 수정 등을 포함한 다양한 기능을 제공합니다.
// @description:ru Предоставление различных функций для Greasyfork, включая абсолютное время, широкоформатные веб-страницы, улучшения страниц скриптов, расширения для загрузки, исправления панелей и многое другое.
// @description:de Bereitstellung verschiedener Funktionen für Greasyfork, einschließlich absoluter Zeit, Breitbild-Webseiten, Skriptseitenerweiterungen, Download-Erweiterungen, Panelkorrekturen und mehr.
// @description:fr Fournir diverses fonctionnalités pour Greasyfork, y compris le temps absolu, les pages Web en écran large, les améliorations de pages de scripts, les extensions de téléchargement, les correctifs de panneau, et plus encore.
// @description:it Fornire varie funzionalità per Greasyfork, inclusi il tempo assoluto, le pagine Web widescreen, i miglioramenti delle pagine degli script, le estensioni di download, le correzioni dei pannelli e altro ancora.
// @description:ar توفير وظائف متنوعة لـ Greasyfork، بما في ذلك الوقت المطلق، وصفحات الويب ذات الشاشة العريضة، وتعزيز صفحات النصوص البرمجية، وتوسعات التنزيل، وإصلاحات اللوحة، والمزيد.
// @description:he מתן מגוון פונקציות עבור Greasyfork, כולל זמן מוחלט, דפי אינטרנט ברוחב מסך רחב, שיפורי דפי סקריפטים, הרחבות להורדה, תיקוני לוח ועוד.
// @description:vi Cung cấp các tính năng khác nhau cho Greasyfork, bao gồm thời gian tuyệt đối, trang web màn hình rộng, nâng cao trang kịch bản, tiện ích mở rộng tải xuống, sửa lỗi bảng điều khiển và nhiều hơn nữa.
// @author       人民的勤务员 <toniaiwanowskiskr47@gmail.com>
// @match        https://greasyfork.org/*
// @match        https://sleazyfork.org/*
// @license      MIT
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @grant        GM_setClipboard
// @grant      GM_xmlhttpRequest
// @require https://update.greasyfork.org/scripts/498897/1400461/Toastnew.js
// @require      https://cdn.jsdelivr.net/gh/fuzetsu/userscripts@ec863aa92cea78a20431f92e80ac0e93262136df/wait-for-elements/wait-for-elements.js

// @require      https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js
// @require      https://cdn.jsdelivr.net/npm/bootstrap@4.5.2/dist/js/bootstrap.bundle.min.js
// @grant        GM_registerMenuCommand
// @icon          https://www.google.com/s2/favicons?domain=https://greasyfork.org
// @compatible     chrome
// @compatible     firefox
// @compatible     edge
// @compatible     opera
// @compatible     safari
// @version      2.1.1


// ==/UserScript==
           

const translate = (function () {
  const userLang = location.pathname.split('/')[1];
  const strings = {
    'en': {
      'newScript': 'Post a new Script',
      'linesOfCode': 'Lines of code',
      'wordCount': 'Word count',
      'setDisplay': 'Set display options',
      'showJump': 'Show jump to code',
      'beautifyDis': 'Beautify discussion page options',
      'AutoEnableCodeEditor': 'Auto enable code editor beautification',
      'showRating': 'Show rating',
      'scriptLinNumb': 'Script code line number display',
      'ScriptListByCreat': 'Sort script list by creation date',
      'moveSidebar': 'Move sidebar favorites up',
      'fixNavbar': 'Fix navbar',
      'addNewScript': 'Add new script option to navbar',
      'exactDate': 'Exact date',
      'addDownButton': 'Add download button to scripts & libraries',
      'jumpTo18': '🔞Jump to adult scripts',
      'maxView': 'Maximize website view',
      'cleanUpOld': 'Clean up comments older than days',
      'openTab': 'Open links in new Greasemonkey tab',
      'showIcon': 'Show script icon',
      'scriptHisAddInstall': 'Add install to script history',
      'Settings': 'Settings',
      'Close': 'Close',
      'inputDaysToCleanUp': 'Please enter days to clean up:',
      'download': 'Download ⇩',
      'downloading': 'Downloading...',
      'errorCode': 'Error: Download failed, server returned status code:',
      'errorNetwork': 'Download failed, network error or cross-domain issue',
      'install': 'Install',
      'downloadFailed': 'Download failed',
      'dallScripts': 'All Released Scripts',
      'JSScripts': "Number of JS Scripts:",
      'CSSScripts': "Number of CSS Scripts:",
      'DailyTotal': "Daily Installs:",
      'TotalInstalls': "Total Installs:",
      'ok': "All Scripts:",
      'bad': "Total Bad Reviews:",
      'good': "Total Good Reviews:",
      'ok': "Average:",
      'loading': "Fetching, please wait.",
      'viewauthor': 'Author',
      'viewdaily_installs': 'Daily installs',
      'tviewotal_installs': 'Total installs',
      'viewfan_score': 'Fan score',
      'viewversion': 'Version',
      'viewcreated_at': 'Created at',
      'viewcode_updated_at': 'Updated at',
      'viewlicense': 'License',
      'viewlocale': 'Locale',
      'copyto': 'Copy code to clipboard.',
      'htmlViewtotext': ' Toggle the TEXT view',
      'texttohtmlView': ' Toggle the HTML view',
      'Rememberme': 'Auto check Remember Me on the login page.',
      'locklang': 'Switching the website language to:',
      'locklangset': 'Lock Language after you click the language switcher',
      'openindoc': 'Add to the navigation bar to open this page',
      'thisname': ' Greasyfork Utility Toolkit',
      '脚本详情': ' Details Page',
      '导航栏': 'Navigation Bar',
      'website': 'Site Settings',
      '复制短链接': 'Copy short link',
      '主页脚本添加操作': 'Adding Operations to Homepage Script',
    },
    'zh-CN': {
      'newScript': '发布新脚本',
      'linesOfCode': '行数',
      'wordCount': '字数',
      'setDisplay': '设置显示选项',
      'showJump': '显示跳转代码',
      'beautifyDis': '讨论页面美化选项',
      'AutoEnableCodeEditor': '自动启用代码编辑框美化',
      'showRating': '显示评分',
      'scriptLinNumb': '脚本代码显示行数字数',
      'ScriptListByCreat': '脚本列表按创建日期排序',
      'moveSidebar': '侧边栏收藏上移',
      'fixNavbar': '导航栏修复',
      'addNewScript': '导航栏增加发布新脚本选项',
      'exactDate': '精确日期',
      'addDownButton': '脚本&库增加下载按钮',
      'jumpTo18': '🔞跳转成人脚本',
      'maxView': '网站最大化浏览',
      'cleanUpOld': '清理超过天数的脚本评论',
      'openTab': '油猴新窗口打开链接',
      'showIcon': '显示脚本图标',
      'scriptHisAddInstall': '脚本历史增加安装',
      'Settings': '设置',
      'Close': '关闭',
      'inputDaysToCleanUp': '请输入清理超过天数:',
      'download': '下载 ⇩',
      'downloading': '下载中...',
      'errorCode': '错误: 下载失败,服务器返回状态码:',
      'errorNetwork': '下载失败,网络错误或跨域问题',
      'install': '安装',
      'downloadFailed': '下载失败',
      'dallScripts': '所有发布脚本',
      'JSScripts': 'JS脚本数量:',
      'CSSScripts': 'CSS脚本数量:',
      'DailyTotal': '每日安装:',
      'TotalInstalls': '总安装:',
      'ok': '所有脚本:',
      'bad': '总差评:',
      'good': '总好评:',
      'ok': '一般:',
      'loading': '正在获取中,请耐心等待。',
      'viewauthor': '作者',
      'viewdaily_installs': '日安装量',
      'tviewotal_installs': '总安装量',
      'viewfan_score': '评分',
      'viewversion': '版本',
      'viewcreated_at': '创建于',
      'viewcode_updated_at': '更新于',
      'viewlicense': '许可证',
      'viewlocale': '适用于',
      'copyto': '复制代码',
      'htmlViewtotext': '切换文档视图',
      'texttohtmlView': '切换网页视图',
      'Rememberme': '在登录页面勾选记住我',
      'locklang': '即将切换网站语言到:',
      'locklangset': '选择语言后设置锁定',
      'openindoc': '在导航栏添加打开本界面',
      'thisname': 'Greasyfork 糊裱匠',
      '脚本详情': '脚本详情',
      '导航栏': '导航栏',
      'website': '网站',
      '复制短链接': '复制短链接',
      '主页脚本添加操作': '主页脚本添加操作',
    },
    'zh-TW': {
      'newScript': '發布新腳本',
      'linesOfCode': '行數',
      'wordCount': '字數',
      'setDisplay': '設置顯示選項',
      'showJump': '顯示跳轉程式碼',
      'beautifyDis': '討論頁面美化選項',
      'AutoEnableCodeEditor': '自動啟用程式碼編輯框美化',
      'showRating': '顯示評分',
      'scriptLinNumb': '腳本程式碼顯示行數字數',
      'ScriptListByCreat': '腳本列表按創建日期排序',
      'moveSidebar': '側邊欄收藏上移',
      'fixNavbar': '導航欄修復',
      'addNewScript': '導航欄增加發布新腳本選項',
      'exactDate': '精確日期',
      'addDownButton': '腳本&庫增加下載按鈕',
      'jumpTo18': '跳轉成人腳本',
      'maxView': '網站最大化瀏覽',
      'cleanUpOld': '清理超過天數的腳步評論',
      'openTab': '油猴新視窗打開連結',
      'showIcon': '顯示腳本圖標',
      'scriptHisAddInstall': '腳本歷史增加安裝',
      'Settings': '設置',
      'Close': '關閉',
      'inputDaysToCleanUp': '請輸入清理超過天數:',
      'download': '下載 ⇩',
      'downloading': '下載中...',
      'errorCode': '錯誤: 下載失敗,伺服器返回狀態碼:',
      'errorNetwork': '下載失敗,網路錯誤或跨域問題',
      'install': '安裝',
      'downloadFailed': '下載失敗',
      'dallScripts': "所有發布腳本",
      'JSScripts': "JS腳本數量:",
      'CSSScripts': "CSS腳本數量:",
      'DailyTotal': "每日安裝:",
      'TotalInstalls': "總安裝:",
      'ok': "所有腳本:",
      'bad': "總差評:",
      'good': "總好評:",
      'ok': "一般:",
      'loading': "正在獲取中,請耐心等待。"
    },
    'ja': {
      'newScript': '新しいスクリプトを公開する',
      'linesOfCode': 'コード行数',
      'wordCount': '単語数',
      'setDisplay': '表示オプションを設定する',
      'showJump': 'ジャンプコードを表示する',
      'beautifyDis': 'ディスカッションページの美化オプション',
      'AutoEnableCodeEditor': '自動でコードエディタを有効にする',
      'showRating': '評価を表示する',
      'scriptLinNumb': 'スクリプトコードの行番号を表示する',
      'ScriptListByCreat': '作成日でスクリプトリストをソートする',
      'moveSidebar': 'サイドバーのお気に入りを移動する',
      'fixNavbar': 'ナビゲーションバーを修正する',
      'addNewScript': 'ナビゲーションバーに新しいスクリプトの投稿オプションを追加する',
      'exactDate': '正確な日付',
      'addDownButton': 'スクリプトとライブラリにダウンロードボタンを追加する',
      'jumpTo18': '成人向けスクリプトにジャンプする',
      'maxView': 'ウェブサイトの最大化表示',
      'cleanUpOld': '指定日数を超える古いスクリプトコメントをクリアする',
      'openTab': '新しいタブでリンクを開く',
      'showIcon': 'スクリプトアイコンを表示する',
      'scriptHisAddInstall': 'スクリプト履歴にインストールを追加する',
      'Settings': '設定',
      'Close': '閉じる',
      'inputDaysToCleanUp': 'クリーンアップする日数を入力してください:',
      'download': 'ダウンロード ⇩',
      'downloading': 'ダウンロード中...',
      'errorCode': 'エラー:ダウンロードに失敗しました、サーバーからのステータスコード:',
      'errorNetwork': 'ダウンロードに失敗しました、ネットワークエラーまたはクロスドメインの問題が発生しました',
      'install': 'インストール',
      'downloadFailed': 'ダウンロードに失敗しました',
      'dallScripts': "すべてのリリースされたスクリプト",
      'JSScripts': "JSスクリプトの数:",
      'CSSScripts': "CSSスクリプトの数:",
      'DailyTotal': "毎日のインストール:",
      'TotalInstalls': "総インストール数:",
      'ok': "すべてのスクリプト:",
      'bad': "総悪いレビュー:",
      'good': "総良いレビュー:",
      'ok': "平均:",
      'loading': "取得中、お待ちください。"
    },
    'ko': {
      'newScript': '새 스크립트 게시',
      'linesOfCode': '코드 라인 수',
      'wordCount': '단어 수',
      'setDisplay': '표시 옵션 설정',
      'showJump': '점프 코드 표시',
      'beautifyDis': '토론 페이지 미화 옵션',
      'AutoEnableCodeEditor': '자동 코드 편집기 활성화',
      'showRating': '평점 표시',
      'scriptLinNumb': '스크립트 코드 줄 번호 표시',
      'ScriptListByCreat': '작성 날짜로 스크립트 목록 정렬',
      'moveSidebar': '사이드바 즐겨찾기 이동',
      'fixNavbar': '네비게이션 바 수정',
      'addNewScript': '네비게이션 바에 새 스크립트 게시 옵션 추가',
      'exactDate': '정확한 날짜',
      'addDownButton': '스크립트 및 라이브러리에 다운로드 버튼 추가',
      'jumpTo18': '성인 스크립트로 이동',
      'maxView': '웹사이트 최대화 보기',
      'cleanUpOld': '지정한 일 수 이상으로 오래된 스크립트 댓글 정리',
      'openTab': '새 탭에서 링크 열기',
      'showIcon': '스크립트 아이콘 표시',
      'scriptHisAddInstall': '스크립트 이력에 설치 추가',
      'Settings': '설정',
      'Close': '닫기',
      'inputDaysToCleanUp': '삭제할 일 수를 입력하십시오:',
      'download': '다운로드 ⇩',
      'downloading': '다운로드 중...',
      'errorCode': '오류: 다운로드 실패, 서버가 반환한 상태 코드:',
      'errorNetwork': '다운로드 실패, 네트워크 오류 또는 크로스도메인 문제',
      'install': '설치',
      'downloadFailed': '다운로드 실패',
      'dallScripts': "모든 릴리스된 스크립트",
      'JSScripts': "JS 스크립트 수:",
      'CSSScripts': "CSS 스크립트 수:",
      'DailyTotal': "일일 설치:",
      'TotalInstalls': "총 설치:",
      'ok': "모든 스크립트:",
      'bad': "총 나쁜 리뷰:",
      'good': "총 좋은 리뷰:",
      'ok': "보통:",
      'loading': "가져오는 중, 잠시 기다려 주세요."
    },
    'ru': {
      'newScript': 'Опубликовать новый скрипт',
      'linesOfCode': 'Количество строк кода',
      'wordCount': 'Количество слов',
      'setDisplay': 'Настройка параметров отображения',
      'showJump': 'Показать переход к коду',
      'beautifyDis': 'Опции улучшения страницы обсуждения',
      'AutoEnableCodeEditor': 'Автоматически включать редактор кода',
      'showRating': 'Показать рейтинг',
      'scriptLinNumb': 'Отображать номера строк кода скрипта',
      'ScriptListByCreat': 'Сортировать список скриптов по дате создания',
      'moveSidebar': 'Переместить боковую панель вверх',
      'fixNavbar': 'Исправить навигационную панель',
      'addNewScript': 'Добавить опцию размещения нового скрипта в навигационную панель',
      'exactDate': 'Точная дата',
      'addDownButton': 'Добавить кнопку загрузки к скриптам и библиотекам',
      'jumpTo18': 'Перейти к взрослым скриптам',
      'maxView': 'Максимизировать просмотр веб-сайта',
      'cleanUpOld': 'Очистить комментарии к скриптам старше указанного количества дней',
      'openTab': 'Открыть ссылку в новой вкладке',
      'showIcon': 'Показать иконку скрипта',
      'scriptHisAddInstall': 'Добавить установку в историю скриптов',
      'Settings': 'Настройки',
      'Close': 'Закрыть',
      'inputDaysToCleanUp': 'Введите количество дней для очистки:',
      'download': 'Скачать ⇩',
      'downloading': 'Загрузка...',
      'errorCode': 'Ошибка: сбой загрузки, сервер вернул код состояния:',
      'errorNetwork': 'Сбой загрузки, сетевая ошибка или проблема с кросс-доменом',
      'install': 'Установить',
      'downloadFailed': 'Сбой загрузки',
      'dallScripts': "Все выпущенные скрипты",
      'JSScripts': "Количество JS скриптов:",
      'CSSScripts': "Количество CSS скриптов:",
      'DailyTotal': "Ежедневные установки:",
      'TotalInstalls': "Всего установок:",
      'ok': "Все скрипты:",
      'bad': "Всего плохих отзывов:",
      'good': "Всего хороших отзывов:",
      'ok': "Средний:",
      'loading': "Получение данных, пожалуйста, подождите."
    },
    'de': {
      'newScript': 'Neues Skript veröffentlichen',
      'linesOfCode': 'Zeilenanzahl',
      'wordCount': 'Wortanzahl',
      'setDisplay': 'Anzeigeoptionen einstellen',
      'showJump': 'Sprung zum Code anzeigen',
      'beautifyDis': 'Optionen zur Verschönerung der Diskussionsseite',
      'AutoEnableCodeEditor': 'Automatische Aktivierung des Code-Editors',
      'showRating': 'Bewertung anzeigen',
      'scriptLinNumb': 'Anzeige der Zeilennummer im Skriptcode',
      'ScriptListByCreat': 'Skriptliste nach Erstellungsdatum sortieren',
      'moveSidebar': 'Favoriten in der Seitenleiste nach oben verschieben',
      'fixNavbar': 'Navigationsleiste reparieren',
      'addNewScript': 'Option zum Veröffentlichen neuer Skripte zur Navigationsleiste hinzufügen',
      'exactDate': 'Exaktes Datum',
      'addDownButton': 'Download-Schaltfläche zu Skripten und Bibliotheken hinzufügen',
      'jumpTo18': 'Zu Erwachsenenskripten springen',
      'maxView': 'Website maximieren',
      'cleanUpOld': 'Kommentare zu Skripten, die älter als eine bestimmte Anzahl von Tagen sind, aufräumen',
      'openTab': 'Links in neuem Tab öffnen',
      'showIcon': 'Skriptsymbol anzeigen',
      'scriptHisAddInstall': 'Installation zur Skript-Historie hinzufügen',
      'Settings': 'Einstellungen',
      'Close': 'Schließen',
      'inputDaysToCleanUp': 'Bitte geben Sie die Anzahl der Tage zum Aufräumen ein:',
      'download': 'Herunterladen ⇩',
      'downloading': 'Herunterladen...',
      'errorCode': 'Fehler: Download fehlgeschlagen, Server hat Statuscode zurückgegeben:',
      'errorNetwork': 'Download fehlgeschlagen, Netzwerkfehler oder Cross-Domain-Probleme',
      'install': 'Installieren',
      'downloadFailed': 'Download fehlgeschlagen',
      'dallScripts': "Alle veröffentlichten Skripte",
      'JSScripts': "Anzahl der JS-Skripte:",
      'CSSScripts': "Anzahl der CSS-Skripte:",
      'DailyTotal': "Tägliche Installationen:",
      'TotalInstalls': "Gesamtinstallationen:",
      'ok': "Alle Skripte:",
      'bad': "Gesamtschlechte Bewertungen:",
      'good': "Gesamtgute Bewertungen:",
      'ok': "Durchschnitt:",
      'loading': "Abrufen, bitte warten."
    },
    'fr': {
      'newScript': 'Publier un nouveau script',
      'linesOfCode': 'Nombre de lignes de code',
      'wordCount': 'Nombre de mots',
      'setDisplay': 'Configurer les options d\'affichage',
      'showJump': 'Afficher le saut de code',
      'beautifyDis': 'Options d\'embellissement de la page de discussion',
      'AutoEnableCodeEditor': 'Activer automatiquement l\'éditeur de code',
      'showRating': 'Afficher la note',
      'scriptLinNumb': 'Afficher le numéro de ligne du code du script',
      'ScriptListByCreat': 'Trier la liste des scripts par date de création',
      'moveSidebar': 'Déplacer les favoris de la barre latérale vers le haut',
      'fixNavbar': 'Réparer la barre de navigation',
      'addNewScript': 'Ajouter une option de publication de nouveau script dans la barre de navigation',
      'exactDate': 'Date exacte',
      'addDownButton': 'Ajouter un bouton de téléchargement aux scripts et aux bibliothèques',
      'jumpTo18': 'Aller aux scripts pour adultes',
      'maxView': 'Maximiser la vue du site Web',
      'cleanUpOld': 'Nettoyer les commentaires de scripts plus anciens que le nombre de jours spécifié',
      'openTab': 'Ouvrir le lien dans un nouvel onglet',
      'showIcon': 'Afficher l\'icône du script',
      'scriptHisAddInstall': 'Ajouter une installation à l\'historique des scripts',
      'Settings': 'Paramètres',
      'Close': 'Fermer',
      'inputDaysToCleanUp': 'Veuillez entrer le nombre de jours pour nettoyer :',
      'download': 'Télécharger ⇩',
      'downloading': 'Téléchargement en cours...',
      'errorCode': 'Erreur : échec du téléchargement, le serveur a renvoyé le code d\'état :',
      'errorNetwork': 'Échec du téléchargement, erreur réseau ou problème de domaine croisé',
      'install': 'Installer',
      'downloadFailed': 'Échec du téléchargement',
      'dallScripts': "Tous les scripts publiés",
      'JSScripts': "Nombre de scripts JS:",
      'CSSScripts': "Nombre de scripts CSS:",
      'DailyTotal': "Installations quotidiennes:",
      'TotalInstalls': "Total des installations:",
      'ok': "Tous les scripts:",
      'bad': "Total des mauvais avis:",
      'good': "Total des bons avis:",
      'ok': "Moyenne:",
      'loading': "Récupération en cours, veuillez patienter."
    },
    'it': {
      'newScript': 'Pubblica nuovo script',
      'linesOfCode': 'Numero di righe di codice',
      'wordCount': 'Numero di parole',
      'setDisplay': 'Imposta opzioni di visualizzazione',
      'showJump': 'Mostra salto al codice',
      'beautifyDis': 'Opzioni di abbellimento della pagina di discussione',
      'AutoEnableCodeEditor': 'Abilita automaticamente l\'editor di codice',
      'showRating': 'Mostra valutazione',
      'scriptLinNumb': 'Mostra numero di righe nel codice dello script',
      'ScriptListByCreat': 'Ordina lista script per data di creazione',
      'moveSidebar': 'Sposta preferiti nella barra laterale in alto',
      'fixNavbar': 'Ripara la barra di navigazione',
      'addNewScript': 'Aggiungi opzione per pubblicare nuovo script nella barra di navigazione',
      'exactDate': 'Data esatta',
      'addDownButton': 'Aggiungi pulsante download a script e librerie',
      'jumpTo18': 'Vai a script per adulti',
      'maxView': 'Massimizza visualizzazione del sito web',
      'cleanUpOld': 'Pulisci commenti script più vecchi di un certo numero di giorni',
      'openTab': 'Apri link in una nuova scheda',
      'showIcon': 'Mostra icona dello script',
      'scriptHisAddInstall': 'Aggiungi installazione alla cronologia degli script',
      'Settings': 'Impostazioni',
      'Close': 'Chiudi',
      'inputDaysToCleanUp': 'Inserisci i giorni per la pulizia:',
      'download': 'Scarica ⇩',
      'downloading': 'Scaricamento...',
      'errorCode': 'Errore: download fallito, il server ha restituito il codice di stato:',
      'errorNetwork': 'Download fallito, errore di rete o problema di dominio incrociato',
      'install': 'Installa',
      'downloadFailed': 'Download fallito',
      'dallScripts': "Tutti gli script rilasciati",
      'JSScripts': "Numero di script JS:",
      'CSSScripts': "Numero di script CSS:",
      'DailyTotal': "Installazioni giornaliere:",
      'TotalInstalls': "Installazioni totali:",
      'ok': "Tutti gli script:",
      'bad': "Totale recensioni negative:",
      'good': "Totale recensioni positive:",
      'ok': "Media:",
      'loading': "Recupero in corso, attendere prego."
    },
    'ar': {
      'newScript': 'نشر سكريبت جديد',
      'linesOfCode': 'عدد الأسطر في الكود',
      'wordCount': 'عدد الكلمات',
      'setDisplay': 'تعيين خيارات العرض',
      'showJump': 'إظهار الانتقال إلى الكود',
      'beautifyDis': 'خيارات تجميل صفحة المناقشة',
      'AutoEnableCodeEditor': 'تمكين محرر الكود تلقائيًا',
      'showRating': 'إظهار التقييم',
      'scriptLinNumb': 'عرض أرقام الأسطر في كود السكريبت',
      'ScriptListByCreat': 'فرز قائمة السكريبتات حسب تاريخ الإنشاء',
      'moveSidebar': 'نقل الاختيارات في الشريط الجانبي لأعلى',
      'fixNavbar': 'إصلاح شريط التنقل',
      'addNewScript': 'إضافة خيار نشر سكريبت جديد إلى شريط التنقل',
      'exactDate': 'تاريخ دقيق',
      'addDownButton': 'إضافة زر التنزيل للسكريبتات والمكتبات',
      'jumpTo18': 'الانتقال إلى السكريبتات الخاصة بالبالغين',
      'maxView': 'تكبير عرض الموقع الإلكتروني',
      'cleanUpOld': 'تنظيف تعليقات السكريبتات القديمة بعد عدد معين من الأيام',
      'openTab': 'فتح الروابط في علامة تبويب جديدة',
      'showIcon': 'إظهار رمز السكريبت',
      'scriptHisAddInstall': 'إضافة التثبيت إلى سجل السكريبتات',
      'Settings': 'الإعدادات',
      'Close': 'إغلاق',
      'inputDaysToCleanUp': 'يرجى إدخال عدد الأيام لتنظيفها:',
      'download': 'تحميل ⇩',
      'downloading': 'جار التحميل...',
      'errorCode': 'خطأ: فشل التحميل، استجابة خادم برمز الحالة:',
      'errorNetwork': 'فشل التحميل، خطأ في الشبكة أو مشكلة في النطاق العابر',
      'install': 'تثبيت',
      'downloadFailed': 'فشل التحميل',
      'dallScripts': "جميع البرامج النصية المنشورة",
      'JSScripts': "عدد برامج JS النصية:",
      'CSSScripts': "عدد برامج CSS النصية:",
      'DailyTotal': "التثبيتات اليومية:",
      'TotalInstalls': "إجمالي التثبيتات:",
      'ok': "جميع البرامج النصية:",
      'bad': "إجمالي التقييمات السلبية:",
      'good': "إجمالي التقييمات الإيجابية:",
      'ok': "متوسط:",
      'loading': "جارٍ التحميل، يرجى الانتظار."
    },
    'he': {
      'newScript': 'פרסם סקריפט חדש',
      'linesOfCode': 'מספר שורות בקוד',
      'wordCount': 'מספר מילים',
      'setDisplay': 'הגדר אפשרויות תצוגה',
      'showJump': 'הצג קפיצה לקוד',
      'beautifyDis': 'אפשרויות ייפוי דף הדיון',
      'AutoEnableCodeEditor': 'הפעל עורך קוד באופן אוטומטי',
      'showRating': 'הצג דירוג',
      'scriptLinNumb': 'הצג מספרי שורות בקוד הסקריפט',
      'ScriptListByCreat': 'מיין רשימת סקריפטים לפי תאריך יצירה',
      'moveSidebar': 'הזז את המועדפים בסרגל הצד',
      'fixNavbar': 'תקן את תפריט הניווט',
      'addNewScript': 'הוסף אפשרות לפרסום סקריפט חדש לתפריט הניווט',
      'exactDate': 'תאריך מדויק',
      'addDownButton': 'הוסף כפתור הורדה לסקריפטים וספריות',
      'jumpTo18': 'קפיצה לסקריפטים למבוגרים',
      'maxView': 'הצגה מקסימלית של האתר',
      'cleanUpOld': 'ניקוי תגובות סקריפטים ישנות מעל מספר ימים מסוים',
      'openTab': 'פתח קישור בכרטיסייה חדשה',
      'showIcon': 'הצג סמל סקריפט',
      'scriptHisAddInstall': 'הוסף התקנה להיסטוריית הסקריפטים',
      'Settings': 'הגדרות',
      'Close': 'סגור',
      'inputDaysToCleanUp': 'אנא הזן את מספר הימים לניקוי:',
      'download': 'הורדה ⇩',
      'downloading': 'מוריד...',
      'errorCode': 'שגיאה: הורדה נכשלה, השרת החזיר קוד מצב:',
      'errorNetwork': 'הורדה נכשלה, בעיה ברשת או בקריאה חוצה דומיין',
      'install': 'התקן',
      'downloadFailed': 'הורדה נכשלה',
      'dallScripts': "כל הסקריפטים שפורסמו",
      'JSScripts': "מספר סקריפטים JS:",
      'CSSScripts': "מספר סקריפטים CSS:",
      'DailyTotal': "התקנות יומיות:",
      'TotalInstalls': "סך ההתקנות:",
      'ok': "כל הסקריפטים:",
      'bad': "סה\"כ ביקורות רעות:",
      'good': "סה\"כ ביקורות טובות:",
      'ok': "ממוצע:",
      'loading': "טוען, נא להמתין."
    },
    'vi': {
      'newScript': 'Đăng bài kịch mới',
      'linesOfCode': 'Số dòng mã',
      'wordCount': 'Số từ',
      'setDisplay': 'Thiết lập tùy chọn hiển thị',
      'showJump': 'Hiển thị chuyển đến mã',
      'beautifyDis': 'Tùy chọn làm đẹp trang thảo luận',
      'AutoEnableCodeEditor': 'Tự động bật trình soạn thảo mã',
      'showRating': 'Hiển thị xếp hạng',
      'scriptLinNumb': 'Hiển thị số dòng mã script',
      'ScriptListByCreat': 'Sắp xếp danh sách script theo ngày tạo',
      'moveSidebar': 'Di chuyển ưa thích trong thanh bên',
      'fixNavbar': 'Sửa chữa thanh điều hướng',
      'addNewScript': 'Thêm tùy chọn đăng bài kịch mới vào thanh điều hướng',
      'exactDate': 'Ngày chính xác',
      'addDownButton': 'Thêm nút tải về cho script và thư viện',
      'jumpTo18': 'Chuyển đến script người lớn',
      'maxView': 'Tối đa hóa xem trang web',
      'cleanUpOld': 'Dọn dẹp bình luận script cũ hơn một số ngày nhất định',
      'openTab': 'Mở liên kết trong tab mới',
      'showIcon': 'Hiển thị biểu tượng script',
      'scriptHisAddInstall': 'Thêm cài đặt vào lịch sử script',
      'Settings': 'Cài đặt',
      'Close': 'Đóng',
      'inputDaysToCleanUp': 'Vui lòng nhập số ngày để dọn dẹp:',
      'download': 'Tải xuống ⇩',
      'downloading': 'Đang tải xuống...',
      'errorCode': 'Lỗi: Tải xuống thất bại, máy chủ đã trả về mã trạng thái:',
      'errorNetwork': 'Tải xuống thất bại, lỗi mạng hoặc vấn đề vượt miền',
      'install': 'Cài đặt',
      'downloadFailed': 'Tải xuống thất bại',
      'dallScripts': "Tất cả các tập lệnh đã phát hành",
      'JSScripts': "Số lượng tập lệnh JS:",
      'CSSScripts': "Số lượng tập lệnh CSS:",
      'DailyTotal': "Lượt cài đặt hàng ngày:",
      'TotalInstalls': "Tổng lượt cài đặt:",
      'ok': "Tất cả tập lệnh:",
      'bad': "Tổng số đánh giá xấu:",
      'good': "Tổng số đánh giá tốt:",
      'ok': "Trung bình:",
      'loading': "Đang tải, vui lòng đợi."
    }

  };

  return (id, lang = '') => {
    const selectedLang = lang || userLang;
    return (strings[selectedLang] || strings.en)[id] || strings.en[id];
  };
  //  return id => (strings[userLang] || strings.en)[id] || strings.en[id];
}());

(function () {

  'use strict';

  var showRating = GM_getValue('showRating', false); // 默认展示评分
  var showSourceCode = GM_getValue('showSourceCode', false); // 默认展示源码按钮
  var modifyRadioLabels = GM_getValue('modifyRadioLabels', false);//评论区梅花
  var autocheck = GM_getValue('autocheck', false);//自动点击美化编辑器
  var showtotal = GM_getValue('showtotal', false);//显示代码字数
  var scriptwithdata = GM_getValue('scriptwithdata', true);//导航栏点击跳转时间创建
  var scriptset = GM_getValue('scriptset', true);//侧边栏脚本上移动
  var HeaderStyleFix = GM_getValue('HeaderStyleFix', true);//修复导航栏
  var AbsoluteTime = GM_getValue('AbsoluteTime', false);//精确时间
  var addbutton = GM_getValue('addbutton', true);//添加下载按钮
  var jumpto = GM_getValue('jumpto', false);//跳转18
  var greasymaxWidth = GM_getValue('greasymaxWidth', false);//最大窗口
  var clearhomepage = GM_getValue('clearhomepage', true);//清理主页过期评论
  var clearhomepagedays = GM_getValue('clearhomepagedays', false);//清理主页过期评论的天数
  var newtabtoinstall = GM_getValue('newtabtoinstall', false);  //油猴新窗口打开
  var viewicon = GM_getValue('viewicon', true);//查看脚本的图标
  var installforversions = GM_getValue('installforversions', true);//下载历史版本
  var setcopylink = GM_getValue('setcopylink', true);//复制代码
  var sethtmlview = GM_getValue('sethtmlview', false);//脚本简介转文档查看
  var Postlink = GM_getValue('Postlink', true);//发布新脚本
  var remme = GM_getValue('remme', true);//在登录页自动点击记住我
  var setlocklang = GM_getValue('setlocklang', false);// 锁点语言
  var setopenindoc = GM_getValue('setopenindoc', true); //在导航栏添加打开设置界面
  var buttonopen = true;
  var copyshortlink = GM_getValue('copyshortlink', true); //复制短链接
  var cleanscriptname = GM_getValue('cleanscriptname', true); //清理脚本名称
  var addedittohomepage = GM_getValue('addedittohomepage', true); //在主页脚本增加编辑删除安装
  //功能-发布新脚本链接放在导航栏 

  if (Postlink) {
    const country_code = getCountryCode();
    setTimeout(function () {
      addNavLink(translate('newScript'), "/" + country_code + '/script_versions/new', false);
    }, 100);
  }
  if (remme) {
    //功能-登录页面自动点击记住我
    function clickLabelsDirectly() {
      // 直接选中并点击第一个元素
      document.querySelector("#new_user > div:nth-child(4) > label").click();

      // 直接选中并点击第二个元素
      document.querySelector("body > div.width-constraint > section > div > div > form > div.remember-me > label").click();

    }
    if (window.location.href.includes("users/sign_in")) {
      clickLabelsDirectly();


    }

  }

  // 调用函数


  //功能-增加图标  
  if (viewicon) {
    if (/^https:\/\/(greasy|sleazy)fork\.org\/([^/]+\/)?scripts\/([^/]+|$)/.test(window.location.href)) {

      const installArea = document.querySelector('div#install-area');
      if (installArea) {
        addIcon(installArea);
      }

    }

  }
  //功能-油猴新窗口打开
  if (newtabtoinstall) {
    //      installBtn.target = '_blank';
    document.querySelectorAll('a').forEach(item => {
      //不给空href和greasyfork的page页加_blank
      if (!/javascript/.test(item.href) && !/page/.test(item.href)) {
        item.setAttribute('target', '_blank');
      }
    });
  }
  //功能-作者界面清理超过30天的评论 
  if (clearhomepage) {
    if (window.location.href.includes("users")) {
      let items = document.querySelectorAll("#user-discussions-on-scripts-written > section > div")
      let now = new Date()
      let num = 0
      for (let item of items) {
        let item_time = item.querySelector('relative-time').date
        if (now - new Date(item_time) > 24 * 3600 * 1000 * clearhomepagedays) {
          item.style.display = "none"
          num += 1
        }
      }
    }
  }
  //功能-最大化使用  
  if (greasymaxWidth) {
    try {
      var e = document.getElementsByClassName("width-constraint");
      e[0].style.maxWidth = "95%"; //header
      e[1].style.maxWidth = "95%"; //content
    } catch (exp) { }
    try {
      document.getElementById("browse-script-list").style.width = "100%";
    } catch (exp) { } //suchergebnisse;
    try {
      document.getElementById("user-script-list").style.width = "100%";
    } catch (exp) { } //suchergebnisse;
    try {
      document.getElementById("script-list-option-groups").style.width = "100%";
    } catch (exp) { } //sidebar;
    try {
      document.getElementById("carbonads").style.height = "0px";
    } catch (exp) { } //carbon werbung
    //try{document.getElementsByClassName("adsbygoogle")[0].style.height = "0px";}catch(exp){} //google werbung
  }
  //功能-点击导航栏默认跳转创建日期
  if (scriptwithdata) {
    var scriptslinks = document.getElementsByClassName("scripts-index-link");
    scriptslinks[0].firstChild.href = scriptslinks[0].firstChild.href.replace("/scripts", "/scripts?sort=created");
  }

  // 功能-跳转大人

  if (jumpto) {
    var currentUrl = window.location.href;
    const country_code = getCountryCode();
    if (currentUrl.includes("greasyfork.org")) {
      addNavLink("🔞", "https://sleazyfork.org/" + country_code + '/scripts');
    } else if (currentUrl.includes("sleazyfork.org")) {

      addNavLink("🍴", "https://greasyfork.org/" + country_code + '/scripts', false, false);
    }



  }

  // 功能-脚本名称清理 https://greasyfork.org/zh-CN/scripts/431940
  const m = /(\/[^/]+\/scripts\/\d+)-[^/]+(\/.*)?/.exec(location.pathname)
  if (m && cleanscriptname) {
    history.replaceState({}, null, `${location.origin}${m[1]}${m[2] ?? ''}${location.search}${location.hash}`)
  }
  // 功能-主页增加编辑  // Adds a new link plus a separator
  //https://update.greasyfork.org/scripts/15201/Greasy%20Fork%20Links.user.js
  if (addedittohomepage) {
    function insertElement(link, text, href) {
      var el = document.createElement(href ? 'a' : 'span');
      if (href) {
        el.href = href;
      }
      el.innerText = text;
      link.parentNode.insertBefore(el, link.nextElementSibling);
    }
    function addLink(link, text, href, separator) {
      insertElement(link, text, href);
      insertElement(link, separator, null);
    }

    if (document.querySelector('#user-script-list')) {
      var loggedIn = document.querySelector('#nav-user-info > .user-profile-link');
      var items = document.querySelectorAll('#user-script-list > li');
      for (var i = 0; i < items.length; i++) {
        var link = items[i].querySelector('a');
        if (loggedIn) {
          addLink(link, 'Edit', '/en/scripts/' + items[i].getAttribute('data-script-id') + '/versions/new', ' - ');
          addLink(link, 'Delete', link.href + '/delete', '/');
        }
        addLink(link, 'Install', link.href + '/code/' + encodeURIComponent(link.innerText) + '.user.js', ' - ');
      }

      // Display number of userscripts
      var scripts = document.querySelector('body > .width-constraint > section:nth-child(3) > header > h3');
      if (scripts) {
        scripts.innerText = 'Scripts (' + items.length + ')';
      }
    }
  }
  // 功能-短链接复制
  const idPrefix = ""; // 根据需要设置前缀
  if (copyshortlink) {
    shortLink();
  }

  function shortLink() {


    const description = document.querySelector("div#script-content");
    const url = window.location.href;
    const scriptId = url.match(/\/scripts\/(\d+)/)?.[1];
    if (!scriptId || !description) return;

    const id = idPrefix + "short-link";
    const current = document.getElementById(id);
    const short = `https://greasyfork.org/scripts/${scriptId}`;

    if (current) {
      console.log("Removing existing short link element");
      // Remove the existing short link element
      current.remove();
    } else {
      console.log("Adding new short link element");
      // Add the short link element
      const p = description.insertAdjacentElement("beforebegin", document.createElement("p"));
      p.id = id;
      p.textContent = "Short link";
      const link = p.appendChild(document.createElement("a"));
      link.href = short;
      //link.textContent = short;
      const copy = p.appendChild(document.createElement("a"));
      copy.textContent = "Copy";
      copy.style.marginLeft = "1em";
      copy.style.cursor = "pointer";
      copy.title = "Copy short link to clipboard";
      copy.addEventListener("click", () => {
        if (copy.textContent === "Copied!") return;
        navigator.clipboard.writeText(short).then(() => {
          copy.textContent = "Copied!";
          window.setTimeout(() => {
            copy.textContent = "Copy";
          }, 1000);
        });
      });
    }
  }
  //webhoot


  // 功能-导航栏增加打开设置
  if (setopenindoc) {
    addNavLink(translate('thisname'), '#', false, false, "renminde");
    var customClassName = 'renminde'; // 自定义类名
    var link = document.querySelector(`.${customClassName} > a`);
    if (link) {
      link.addEventListener('click', event => {
        event.preventDefault();
        showSettingsModal();
      });
    }
  }



  function getCountryCode() {
    return window.location.pathname.split('/')[1];
  }

  function addNavLink(link_text, linkurl, newtab, lastone, lclassname) {

    var li = document.createElement('li');
    if (lclassname) {
      li.className = lclassname;
    } else {
      li.className = 'scripts-index-link';
    }

    // 创建新的 <a> 元素
    var a = document.createElement('a');
    a.href = linkurl;
    a.innerText = link_text;
    if (newtab) {
      a.target = "_blank"; // 设置为新窗口打开

    }

    // 将 <a> 元素添加到 <li> 中
    li.appendChild(a);

    // 将 <li> 元素添加到导航栏中
    var nav = document.querySelector('div#site-nav > nav');
    if (nav) {
      if (lastone) {
        nav.append(li);
      } else {
        nav.prepend(li);
      }

    } else {
      console.error('Navigation element not found');
    }
  }
  // 功能-评论区美化选项
  if (modifyRadioLabels) {
    if (document.location.pathname.endsWith('/feedback')) {
      var ratings = {
        'discussion_rating_0': {
          separator: ' - ',
          originalText: ''
        },
        'discussion_rating_2': {
          separator: ' - ',
          originalText: ''
        },
        'discussion_rating_3': {
          separator: ' - ',
          originalText: ''
        },
        'discussion_rating_4': {
          separator: ' - ',
          originalText: ''
        }
      };

      // 遍历评分信息对象,获取并处理每个评分选项的原始文本
      Object.keys(ratings).forEach(function (key) {
        ratings[key].originalText = $('.radio-label[for="' + key + '"]').text();
        ratings[key].parts = ratings[key].originalText.split(ratings[key].separator);
      });

      // 更新页面上的评分选项内容
      $('.radio-label[for="discussion_rating_0"]').html('<span class="rating-icon rating-icon-none">' + ratings['discussion_rating_0'].parts[0] + '</span> - ' + ratings['discussion_rating_0'].parts[1]);
      $('.radio-label[for="discussion_rating_2"]').html('<span class="rating-icon rating-icon-bad">' + ratings['discussion_rating_2'].parts[0] + '</span> - ' + ratings['discussion_rating_2'].parts[1]);
      $('.radio-label[for="discussion_rating_3"]').html('<span class="rating-icon rating-icon-ok">' + ratings['discussion_rating_3'].parts[0] + '</span> - ' + ratings['discussion_rating_3'].parts[1]);
      $('.radio-label[for="discussion_rating_4"]').html('<span class="rating-icon rating-icon-good">' + ratings['discussion_rating_4'].parts[0] + '</span> - ' + ratings['discussion_rating_4'].parts[1]);

    }

    //
  }
  // 功能-代码字数
  function get_size_from_doc(doc) {
    let t = doc.querySelector('#script-content .code-container pre').innerText;
    return {
      lines: t.split('\n').length,
      chars: t.length,
    };
  }

  function handle_code_page() {
    let s = get_size_from_doc(document);
    let e = document.createElement('span');
    e.innerText = `Lines: ${s.lines}, Characters: ${s.chars}`;
    e.innerHTML = `<span style="font-size: 15px; border-radius: 3px; background: rgb(45, 45, 45); color: rgb(255, 255, 255); margin: 0px 4px; padding: 0 4px; outline: 2px solid red;">
                    <span style="width: 8px; height: 8px; display: inline-flex; margin-bottom: 1px; margin-left: 4px; border-radius: 50%; background: yellow;"></span>
                    ${translate('linesOfCode')} ${s.lines}, ${translate('wordCount')} ${s.chars}
                  </span>`;

    if (isMobile()) {
      var parentElement = document.querySelector('#script-feedback-suggestion');
      var referenceElement = parentElement.nextElementSibling;

      parentElement.insertAdjacentElement('afterend', e);
    } else {
      document.querySelector('#script-feedback-suggestion').appendChild(e);
    }
  }

  if (document.location.pathname.endsWith('/code')) {
    if (showtotal) {
      handle_code_page();
    }

  }

  function isMobile() {
    let flag = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
    return flag;
  }

  if (setcopylink) {
    if (window.location.href.substring(window.location.href.lastIndexOf('/') + 1).includes('code')) {
      copycodelink();
    } else {
      //可以去访问JS文件去复制。
    }
  }


  // 功能-代码复制按钮
  function copycodelink() {

    let b = document.createElement('a');

    b.href = '#';
    b.draggable = false;
    b.innerText = translate('copyto');
    b.className = 'copycode';
    b.onclick = async event => {
      event.preventDefault();
      await execCopy();
      Toast('Copy successful', 3000, '#0000ff', '#ffffff', 'top');

    };


    if (isMobile()) {
      var parentElement = document.querySelector("#script-content > div.code-container")
      var referenceElement = parentElement.nextElementSibling;

      parentElement.insertAdjacentElement('beforebegin', b);
    } else {
      document.querySelector('#script-feedback-suggestion').appendChild(b);
    }
  }
  function execCopy() {

    var code = '';
    if ($(".prettyprint li").length > 0) {
      $(".prettyprint li").each(function () {
        code += $(this).text() + '\n';
      });
    }
    else {
      code = $(".prettyprint").text();
    }

    //&nbsp;转正常空格
    code = encodeURI(code)
    code = code.replace(/%C2%A0/g, '%20');
    code = decodeURI(code);

    /*
    const input = document.createElement('textarea');
    input.style.opacity  = 0;
    input.style.position = 'absolute';
    input.style.left = '-100000px';
    document.body.appendChild(input);

    input.value = code;
    input.select();
    input.setSelectionRange(0, code.length);
    document.execCommand('copy');
    document.body.removeChild(input);
    */

    GM_setClipboard(code, 'text');

    return true;
  }

  // 功能-切换脚本简介greasyfork.org/scripts/471149



  let additionalInfoDiv = document.querySelector('#additional-info.user-content');
  if (sethtmlview) {
    const htmlViewb = document.createElement("a");
    htmlViewb.href = "#";
    htmlViewb.className = "install-link htmlViewb";
    htmlViewb.style.marginLeft = "0.5rem";
    htmlViewb.textContent = translate('htmlViewtotext');


    htmlViewb.addEventListener('click', () => {
      event.preventDefault();
      // Toggle the HTML view
      if (additionalInfoDiv.dataset.htmlView === 'true') {
        // Revert to the original content
        additionalInfoDiv.dataset.htmlView = 'false';
        additionalInfoDiv.innerHTML = additionalInfoDiv.dataset.originalContent;
        htmlViewb.textContent = translate('htmlViewtotext');
      } else {
        // Save the original content and replace with the HTML view
        additionalInfoDiv.dataset.htmlView = 'true';
        additionalInfoDiv.dataset.originalContent = additionalInfoDiv.innerHTML;
        additionalInfoDiv.textContent = additionalInfoDiv.innerHTML;
        htmlViewb.textContent = translate('texttohtmlView');
      }
    });


    if (additionalInfoDiv) {
      additionalInfoDiv.parentNode.insertBefore(htmlViewb, additionalInfoDiv);
    }
  }

  // 功能-侧边栏脚本上移动
  if (scriptset) {
    var observer = new MutationObserver(function (mutationsList) {
      for (var mutation of mutationsList) {
        if (mutation.type === 'childList') {
          // 检查是否出现了 Script set 元素
          var setDiv = document.getElementById("script-list-set");
          if (setDiv) {
            // 找到 script-list-sort 元素
            var sortDiv = document.getElementById("script-list-sort");

            // 将 setDiv 插入到 sortDiv 下面
            sortDiv.parentNode.insertBefore(setDiv, sortDiv.nextSibling);

            // 弹出提示

            // 停止监听DOM的变化
            observer.disconnect();
            break;
          }
        }
      }
    });

    //  功能-配置 MutationObserver 监听DOM的变化 设置评分与代码跳转
    observer.observe(document.body, {
      childList: true,
      subtree: true
    });
  }



  // 功能-编辑器自动美化

  if (/\/(versions|script_versions)\/new/.test(window.location.href)) {
    if (autocheck) {
      var textarea = document.getElementById('script_version_code');
      waitForElems({
        sel: '#enable-source-editor-code',
        stop: true,
        onmatch(checkbox) {
          // 检查当前页面的 URL 是否包含 "scripts" 和 "versions"
          // https://update.greasyfork.org/scripts/22223/
          checkbox.click();
          textarea.style.height = '800px';
          console.log("Clicked checkbox based on URL conditions.");
          // @match               *://greasyfork.org/*/*versions/new

        }

      }

      );
    }
  }
  // 注册油猴菜单命令
  GM_registerMenuCommand(translate('setDisplay'), () => {
    // 创建一个设置窗口
    // createsetui();
    showSettingsModal();
  });

  function createsetui() {
    const controls = [{
      type: 'checkbox',
      id: 'showRating',
      label: translate('showRating'),
      checked: GM_getValue('showRating', false),
      onchange: function () {
        GM_setValue('showRating', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'showSourceCode',
      label: translate('showJump'),
      checked: GM_getValue('showSourceCode', false),
      onchange: function () {
        GM_setValue('showSourceCode', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'modifyRadioLabels',
      label: translate('beautifyDis'),
      checked: GM_getValue('modifyRadioLabels', false),
      onchange: function () {
        GM_setValue('modifyRadioLabels', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'autocheck',
      label: translate('AutoEnableCodeEditor'),
      checked: GM_getValue('autocheck', false),
      onchange: function () {
        GM_setValue('autocheck', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'showtotal',
      label: translate('scriptLinNumb'),
      checked: GM_getValue('showtotal', false),
      onchange: function () {
        GM_setValue('showtotal', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'scriptwithdata',
      label: translate('ScriptListByCreat'),
      checked: GM_getValue('scriptwithdata', true),
      onchange: function () {
        GM_setValue('scriptwithdata', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'scriptset',
      label: translate('moveSidebar'),
      checked: GM_getValue('scriptset', true),
      onchange: function () {
        GM_setValue('scriptset', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'HeaderStyleFix',
      label: translate('fixNavbar'),
      checked: GM_getValue('HeaderStyleFix', true),
      onchange: function () {
        GM_setValue('HeaderStyleFix', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'Postlink',
      label: translate('addNewScript'),
      checked: GM_getValue('Postlink', true),
      onchange: function () {
        GM_setValue('Postlink', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'AbsoluteTime',
      label: translate('exactDate'),
      checked: GM_getValue('AbsoluteTime', false),
      onchange: function () {
        GM_setValue('AbsoluteTime', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'addbutton',
      label: translate('addDownButton'),
      checked: GM_getValue('addbutton', true),
      onchange: function () {
        GM_setValue('addbutton', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'jumpto',
      label: translate('jumpTo18'),
      checked: GM_getValue('jumpto', false),
      onchange: function () {
        GM_setValue('jumpto', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'greasymaxWidth',
      label: translate('maxView'),
      checked: GM_getValue('greasymaxWidth', false),
      onchange: function () {
        GM_setValue('greasymaxWidth', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'clearhomepage',
      label: translate('cleanUpOld'),
      checked: GM_getValue('clearhomepage', false),
      onchange: handleCheckboxChange
    }, {
      type: 'checkbox',
      id: 'newtabtoinstall',
      label: translate('openTab'),
      checked: GM_getValue('newtabtoinstall', false),
      onchange: function () {
        GM_setValue('newtabtoinstall', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'viewicon',
      label: translate('showIcon'),
      checked: GM_getValue('viewicon', true),
      onchange: function () {
        GM_setValue('viewicon', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'installforversions',
      label: translate('scriptHisAddInstall'),
      checked: GM_getValue('installforversions', true),
      onchange: function () {
        GM_setValue('installforversions', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'setcopylink',
      label: translate('copyto'),
      checked: GM_getValue('setcopylink', true),
      onchange: function () {
        GM_setValue('setcopylink', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'sethtmlview',
      label: translate('htmlViewtotext'),
      checked: GM_getValue('sethtmlview', false),
      onchange: function () {
        GM_setValue('sethtmlview', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'remme',
      label: translate('Rememberme'),
      checked: GM_getValue('remme', true),
      onchange: function () {
        GM_setValue('remme', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'setlocklang',
      label: translate('locklangset'),
      checked: GM_getValue('setlocklang', false),
      onchange: function () {
        GM_setValue('setlocklang', this.checked);
      }
    }, {
      type: 'checkbox',
      id: 'setopenindoc',
      label: translate('openindoc'),
      checked: GM_getValue('setopenindoc', false),
      onchange: function () {
        GM_setValue('setopenindoc', this.checked);
      }
    }];


    const modalContainer = createControl('div', {
      className: 'settings-modal'
    }, {
      position: 'fixed',
      top: '50%',
      left: '50%',
      transform: 'translate(-50%, -50%)',
      backgroundColor: 'rgba(255, 255, 255, 1)',
      borderRadius: '8px',
      boxShadow: '0 4px 8px rgba(0, 0, 0, 0.2)',
      zIndex: '9999',
      padding: '20px',
      width: '400px',
      maxWidth: '80%'
    });

    const title = createControl('h2', {
      textContent: translate('Settings')
    }, {
      textAlign: 'center'
    });
    const closeButton = createControl('button', {
      textContent: translate('Close'),
      onclick: () => {

        document.body.removeChild(modalContainer);
      }
    }, {
      marginTop: '10px',
      padding: '10px 20px',
      fontSize: '16px',
      backgroundColor: '#007bff',
      color: '#fff',
      border: 'none',
      borderRadius: '5px',
      cursor: 'pointer',
      float: 'right'
    });

    modalContainer.appendChild(closeButton);

    modalContainer.appendChild(title);
    controls.forEach(control => {
      const input = createControl('input', {
        type: control.type,
        id: control.id,
        checked: control.checked,
        value: control.value,
        placeholder: control.placeholder,
        onchange: control.onchange
      }, {
        marginRight: '10px'
      });

      const label = createControl('label', {
        textContent: control.label,
        htmlFor: control.id
      }, {
        fontSize: '14px',
        marginLeft: '5px'
      });

      modalContainer.appendChild(input);
      modalContainer.appendChild(label);
      modalContainer.appendChild(createControl('br'));
    });
  }

  function handleCheckboxChange() {
    if (this.checked) {
      let input = prompt(translate('inputDaysToCleanUp'), "30");
      let number = parseInt(input);
      if (isNaN(number)) {
        number = 30;
      }
      GM_setValue('clearhomepage', true);
      GM_setValue('clearhomepagedays', number);
    } else {
      GM_setValue('clearhomepage', false);
    }
  }
  // 检测脚本列表的出现,并自动插入评分
  function createControl(tagName, attributes = {}, styles = {}, parent = document.body) {
    const element = document.createElement(tagName);

    // 设置属性
    for (const key in attributes) {
      element[key] = attributes[key];
    }

    // 设置样式
    Object.assign(element.style, styles);

    // 添加到父元素
    if (parent) {
      parent.appendChild(element);
    }

    return element;
  }

  function observeScriptList() {

    const scriptList = document.querySelector('.script-list');

    if (scriptList) {

      // 插入评分

      insertRatings(scriptList);



      // 配置观察器

      const observer = new MutationObserver(function (mutationsList, observer) {

        for (let mutation of mutationsList) {

          if (mutation.type === 'childList') {

            for (let node of mutation.addedNodes) {

              // 检查是否为脚本列表项

              if (node.nodeType === Node.ELEMENT_NODE && node.matches('li[data-script-id]')) {

                insertRating(node);

              }

            }

          }

        }

      });

      // 开始观察脚本列表的变化

      observer.observe(scriptList, {
        childList: true,
        subtree: true
      });

    }

  }

  // 插入评分

  function insertRating(scriptBlock) {
    const ratingElement = scriptBlock.querySelector('dd.script-list-ratings');

    if (ratingElement) {
      const rating = ratingElement.getAttribute('data-rating-score');
      const ratingDisplay = document.createElement('span');


      if (showRating) {
        ratingDisplay.textContent = rating.replace(/[^\d.]/g, '');
        ratingDisplay.style.marginLeft = '30px';
        ratingDisplay.style.fontSize = '1em';
        ratingDisplay.style.color = '#ff8c00';
        ratingDisplay.style.fontWeight = 'bold';

      }
      const titleElement = scriptBlock.querySelector('.script-link');

      if (titleElement) {

        titleElement.insertAdjacentElement('afterend', ratingDisplay);


        if (showSourceCode) {
          // 创建链接元素
          const link = document.createElement('a');
          link.textContent = 'code'; // 链接文本为 "code"
          link.href = titleElement.href + '/code'; // 设置跳转链接

          // 样式
          link.style.marginLeft = '10px'; // 为链接增加一些左侧间距
          link.style.color = '#007bff'; // 设置链接颜色为蓝色
          link.style.marginLeft = '10px';
          link.style.paddingLeft = '2px';
          link.style.paddingRight = '2px';
          link.style.fontSize = '12px';
          link.style.background = '#0084ff';
          link.style.color = 'white';
          link.style.textDecoration = 'none';
          link.style.textDecoration = 'none'; // 去除链接的下划线

          // 插入链接
          ratingDisplay.insertAdjacentElement('afterend', link);
        }

      }
    }


    /*  document.querySelectorAll('relative-time').forEach(relativeTime => {
        let datetime = new Date(relativeTime.getAttribute('datetime'));
        let year = datetime.getFullYear();
        let month = (datetime.getMonth() + 1).toString().padStart(2, '0');
        let date = datetime.getDate().toString().padStart(2, '0');
        let hours = datetime.getHours().toString().padStart(2, '0');
        let minutes = datetime.getMinutes().toString().padStart(2, '0');
        let seconds = datetime.getSeconds().toString().padStart(2, '0');
        let formattedDatetime = `${year}-${month}-${date}\xa0\xa0${hours}:${minutes}:${seconds}`;

         relativeTime.textContent  = formattedDatetime;
        console.log(relativeTime.outerHTML);
    });*/
  }



  // 插入评分到当前页面的脚本列表中

  function insertRatings(scriptList) {

    const scriptBlocks = scriptList.querySelectorAll('li[data-script-id]');

    scriptBlocks.forEach(insertRating);

  }

  // 开始观察当前页面脚本列表的出现

  observeScriptList();

  // 观察 body 元素以检测页面加载了下一页

  const bodyObserver = new MutationObserver(function (mutationsList, observer) {

    mutationsList.forEach(mutation => {

      mutation.addedNodes.forEach(node => {

        if (node.nodeType === Node.ELEMENT_NODE && node.matches('.script-list')) {

          // 页面加载了下一页,自动插入评分

          insertRatings(node);

        }

      });

    });

  });

  // 开始观察 body 元素的子节点变化

  bodyObserver.observe(document.body, {
    childList: true,
    subtree: true
  });

  //  功能- 修复导航栏https://update.greasyfork.org/scripts/473269/GreasyFork%20Header%20Style%20Fix.user.js
  if (HeaderStyleFix) {
    let css = `
    /* Insert code here... */
    html {
        --main-header-scale: 1.0;
    }

    #site-nav {
        font-size: min(16px, calc(20px * var(--main-header-scale)));
    }

    #site-name {
        display: flex;
        flex-direction: row;
        flex-wrap: nowrap;
        margin: 0;
    }
    #site-name-text h1 {

        font-size: calc(38pt * var(--main-header-scale));
        white-space: nowrap;
        margin: 0;
    }

    #site-name-text {
        margin: 0;
    }

    #main-header > .width-constraint:only-child {
        display: flex;
        place-items: center;
        padding-top: calc(8px * var(--main-header-scale));
        padding-bottom: calc(8px * var(--main-header-scale));
        padding-right: calc(24px * var(--main-header-scale));
        padding-left: calc(24px * var(--main-header-scale));
        flex-direction: row;
        margin: 0;
    }
    #site-nav > nav,
    #nav-user-info {
        position: static;
        margin: 0;
    }

    #site-nav {

        display: flex;
        row-gap: 4px;
        flex-direction: column;
        margin: 0;
    }
    #main-header > .width-constraint:only-child > #site-nav:last-child {
        flex-grow: 1;
        margin: 0;
    }

    html #site-name img {
        width: calc(58px * var(--main-header-scale));
        height: calc(58px * var(--main-header-scale));
        margin: 0;
    }


    @media screen and (max-width: 768px) {

        html {
            --main-header-scale: 0.74;
        }
    }



    @media screen and (max-width: 672px) {

        html {
            --main-header-scale: 0.62;
        }
    }
`;
    if (typeof GM_addStyle !== "undefined") {
      GM_addStyle(css);
    } else {
      let styleNode = document.createElement("style");
      styleNode.appendChild(document.createTextNode(css));
      (document.querySelector("head") || document.documentElement).appendChild(styleNode);
    }
  }
  //功能- 显示绝对时间 https://update.greasyfork.org/scripts/470348/Absolute%20Time%20on%20GreasyFork.user.js
  if (AbsoluteTime) {
    let langUsed = null;

    const Promise = (async () => { })().constructor;

    const PromiseExternal = ((resolve_, reject_) => {
      const h = (resolve, reject) => {
        resolve_ = resolve;
        reject_ = reject
      };
      return class PromiseExternal extends Promise {
        constructor(cb = h) {
          super(cb);
          if (cb === h) {
            /** @type {(value: any) => void} */
            this.resolve = resolve_;
            /** @type {(reason?: any) => void} */
            this.reject = reject_;
          }
        }
      };
    })();

    function pad(s, d) {
      s = `000000${s}`
      return s.substring(s.length - d)
    }

    /**
     * @callback formatDateTimeFn
     * @param {DateTime} dt
     * @returns {string} formated text for date & time
     */

    /** @type {formatDateTimeFn} */
    const formatUFn = (dt) => {
      return `${dt.getFullYear()}.${pad(dt.getMonth() + 1, 2)}.${pad(dt.getDate(), 2)} ${pad(dt.getHours(), 2)}:${pad(dt.getMinutes(), 2)}:${pad(dt.getSeconds(), 2)}`;


    }

    /** @type {formatDateTimeFn} */
    const formatFrFn = (dt) => {
      return `${pad(dt.getDate(), 2)}.${pad(dt.getMonth() + 1, 2)}.${dt.getFullYear()} ${pad(dt.getHours(), 2)}:${pad(dt.getMinutes(), 2)}:${pad(dt.getSeconds(), 2)}`;
    }

    let formatFn = formatUFn;

    let rafPromise = null;

    const getRafPromise = () => rafPromise || (rafPromise = new Promise(resolve => {
      requestAnimationFrame(hRes => {
        rafPromise = null;
        resolve(hRes);
      });
    }));

    let delay100 = null;

    delay100 = new PromiseExternal();
    setInterval(() => {
      delay100.resolve();
      delay100 = new PromiseExternal();
    }, 100);

    let psk = 0;

    const cssText = `

    @keyframes relativeTimeNotAbsoluteAppended {
        from{
            background-position-x: 1px;
        }
        to{
            background-position-x: 2px;
        }
    }
    relative-time[datetime]:not(.absolute) {
        animation: relativeTimeNotAbsoluteAppended 1ms linear 0s 1 normal forwards;
    }

  `;

    async function fixRelativeTime(s) {

      psk = Date.now();

      s.classList.add("absolute")
      s.format = 'datetime';
      await Promise.resolve().then();
      await getRafPromise().then();

      if (langUsed === null) {
        langUsed = document.documentElement.lang;
        if (typeof langUsed === 'string' && (langUsed === 'fr' || langUsed.startsWith('fr-'))) {
          formatFn = formatFrFn;
        }
      }

      let d = s.getAttribute('datetime');
      let dt = d ? new Date(d) : null;
      if (dt && s.shadowRoot && s.shadowRoot.firstChild) {

        psk = Date.now();
        while (Date.now() - psk < 800) {
          s.shadowRoot.firstChild.textContent = formatFn(dt);
          await delay100.then();
        }

      }

    }

    document.addEventListener('animationstart', (evt) => {
      const animationName = evt.animationName;
      if (!animationName) return;
      if (animationName === 'relativeTimeNotAbsoluteAppended') {
        fixRelativeTime(evt.target);
      }
    }, {
      capture: true,
      passive: true
    });

    document.head.appendChild(document.createElement('style')).textContent = cssText;

  }

  //功能- 给库和脚本详情页增加下载按钮  https://greasyfork.org/users/980489
  if (addbutton) {



    const installArea = document.querySelector('div#install-area');
    const installBtns = installArea?.querySelectorAll(':scope > a.install-link');
    const installHelpLinks = document.querySelectorAll('a.install-help-link');
    const suggestion = document.querySelector('div#script-feedback-suggestion');
    const libraryRequire = document.querySelector('div#script-content > p > code');
    const libraryVersion = document.querySelector(
      '#script-stats > dd.script-show-version > span'
    );

    if (
      installArea &&
      (installBtns.length > 0) &&
      (installBtns.length === installHelpLinks.length)
    ) {
      for (let i = 0; i < installBtns.length; i++) {
        mountScriptDownloadButton(installBtns[i], installArea, installHelpLinks[i]);
      }
    }
    // or maybe a library
    else if (suggestion && libraryRequire) {
      mountLibraryDownloadButton(suggestion, libraryRequire, libraryVersion);
    }

    function mountLibraryDownloadButton(suggestion, libraryRequire, libraryVersion) {
      let [
        libraryHref,
        libraryName,
      ] = libraryRequire.innerText.match(
        /\/\/ @require (https:\/\/.+\/scripts\/\d+\/\d+\/(.*)\.js)/
      ).slice(1);

      // this probably is completely useless but whatever
      if (!libraryHref) throw new Error('library href is not found');

      libraryName = decodeURIComponent(libraryName);

      if (libraryVersion?.innerText) libraryName += ` ${libraryVersion.innerText}`;



      const b = document.createElement('a');

      b.href = '#';
      b.draggable = false;
      b.innerText = translate('download');
      b.className = 'GF-DSB__library-download-button';

      suggestion.appendChild(b);
      b.addEventListener('click', function () {
        event.preventDefault();


        const filename = getFilenameFromUrl(libraryHref);

        b.textContent = translate('downloading'); // 修改链接文本为 "下载中..."
        b.style.pointerEvents = 'none'; // 禁用点击事件,防止重复点击
        b.blur(); // 让链接失去焦点


        downloadFile(libraryHref, filename, function (error) {
          // 下载完成后执行的操作
          if (error) {
            b.textContent = translate('download'); // 恢复链接文本为 "下载"
            b.style.pointerEvents = 'auto'; // 恢复点击事件
            // 如果下载失败,处理错误情况
            Toast(error.message, 3000, '#ff6347', '#ffffff', 'top');
            // 可以进行其他错误处理,例如显示错误消息给用户
          } else {
            // 下载成功后执行的操作
            b.textContent = translate('download'); // 恢复链接文本为 "下载"
            b.style.pointerEvents = 'auto'; // 恢复点击事件
            b.focus(); // 让链接重新获取焦点,给用户一种下载完成的感觉
          }
        });



      });

    }

    function mountScriptDownloadButton(
      installBtn,
      installArea,
      installHelpLink,
    ) {
      if (!installBtn.href) throw new Error('script href is not found');
      const linkText = installBtn.textContent.trim();
      installBtn.innerHTML = `
         <svg aria-hidden="true" height="16" viewBox="0 0 24 24" width="16">
            <path fill="currentColor" d="M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10 10-4.486 10-10S17.514 2 12 2zm4 11h-3v3a1 1 0 0 1-2 0v-3H8a1 1 0 0 1 0-2h3V8a1 1 0 0 1 2 0v3h3a1 1 0 0 1 0 2z"/>
        </svg>
         ${linkText}`;

      const downloadButton = document.createElement('a');
      downloadButton.href = "#";
      downloadButton.className = "install-link down-code-link";
      downloadButton.innerHTML = `
    <svg aria-hidden="true" height="16" viewBox="0 0 24 24" width="16">
            <path fill="currentColor" d="M12 2a1 1 0 0 1 1 1v8h3.586a1 1 0 0 1 .707 1.707l-5 5a1 1 0 0 1-1.414 0l-5-5A1 1 0 0 1 7.414 11H11V3a1 1 0 0 1 1-1zm8 14a1 1 0 0 1 1 1v2a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3v-2a1 1 0 0 1 2 0v2a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2a1 1 0 0 1 1-1z"/>
        </svg>
    `;
      downloadButton.style.marginLeft = '"0.5rem';
      // suggestion.appendChild(downloadButton);
      installArea.insertBefore(downloadButton, installHelpLink);

      installHelpLink.remove();
      downloadButton.addEventListener('click', function () {
        event.preventDefault();
        const filename = getFilenameFromUrl(installBtn.href);


        downloadFile(installBtn.href, filename, function (error) {
          // 下载完成后执行的操作
          if (error) {


            Toast(error.message, 3000, '#ff6347', '#ffffff', 'top');
          } else {

          }
        });


      });
    }


  }
  //功能- 插入图标选项


  function addIcon(h2Element) {
    var scriptID = location.href.match(/scripts\/(\d+)/)[1];
    var iconsrc = GM_getValue(scriptID);

    if (iconsrc && iconsrc.match(/^data:image|https:/)) {
      __addIcon(iconsrc, h2Element);

    } else {
      GM_xmlhttpRequest({
        method: 'GET',
        url: location.pathname.replace(/(scripts\/\d+[^/]+)(\/.*)?$/, '$1/code/1.user.js'),
        timeout: 10000,
        onload: function (r) {
          var url = (r.responseText.match(/\n\s*\/\/\s+@icon(?:url)?\s+((?:https?:\/\/|data:image\/).+)|$/i)[1] || '').trim();
          if (!url)
            return;
          if (!/^http:/.test(url))
            return __addIcon(url, h2Element);
          // download http icon and store it in script db if it's small
          GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            timeout: 10000,
            headers: {
              'Accept': 'image/png,image/*;q=0.8,*/*;q=0.5'
            },
            responseType: 'arraybuffer',
            onload: function (ri) {
              var /**@type ArrayBuffer*/ rb = ri.response,
                rbl = rb.byteLength;
              if (rbl > 100000) {
                console.log('Script icon exceeds 100k, ignoring');
                return;
              }
              var mime = ri.responseHeaders.match(/(^|\n\s*)Content-Type:\s*(image\/[^;,\s]+)|$/i)[2];
              var rb8 = new Uint8Array(rb);
              var rbs = Array(rbl);
              for (var i = 0; i < rbl; i++)
                rbs[i] = String.fromCharCode(rb8[i]);
              var dataUrl = 'data:image/' + (mime || 'png') + ';base64,' + btoa(rbs.join(''));
              __addIcon(dataUrl, h2Element);
            }
          });
        }
      });
    }

    function __addIcon(url, h2Element) {
      if (!h2Element) {
        console.error('Missing h2 element to append icon.');
        return;
      }

      h2Element.insertAdjacentHTML('afterbegin', '<div style="\
        position: absolute;\
        width: 80px;\
        margin-left: calc(-80px - 1ex);\
        display: inline-block;\
        text-align: right"></div>');
      var img = h2Element.appendChild(document.createElement('img'));
      img.style.maxWidth = img.style.maxHeight = '64px';
      img.style.width = img.style.height = 'auto';
      img.src = url;

      GM_setValue(scriptID, url);
    }
  }
  //下载函数
  function downloadFile(url, filename, callback) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = 'blob';

    xhr.onload = function () {
      if (xhr.status === 200) {
        var blob = xhr.response;
        var url = window.URL.createObjectURL(blob);

        var a = document.createElement('a');
        a.href = url;
        a.download = filename; // 设置下载文件名
        document.body.appendChild(a);
        a.click();

        window.URL.revokeObjectURL(url);
        document.body.removeChild(a); // 清理 DOM

        if (callback && typeof callback === 'function') {
          callback(null); // 执行回调,传递 null 表示没有错误
        }
      } else {
        // 请求失败的处理
        if (callback && typeof callback === 'function') {
          callback(new Error(translate('errorCode') + xhr.status));
        }
      }
    };

    xhr.onerror = function () {
      // 网络错误等导致请求无法完成时的处理
      if (callback && typeof callback === 'function') {
        callback(new Error(translate('errorNetwork')));
      }
    };

    xhr.send();
  }



  function getFilenameFromUrl(url) {
    if (typeof url !== 'string' || url.trim() === '') {
      console.error('Invalid URL provided');
      return 'download'; // 返回一个默认的文件名
    }

    var lastSlashIndex = url.lastIndexOf('/');
    if (lastSlashIndex === -1 || lastSlashIndex === url.length - 1) {
      console.error('Invalid URL format: missing filename');
      return 'download'; // 返回一个默认的文件名
    }

    var filenameWithExtension = url.substring(lastSlashIndex + 1);
    var decodedFilename = decodeURIComponent(filenameWithExtension);
    decodedFilename = decodedFilename.replace(/%20/g, '_'); // 替换所有的 %20 为下划线

    return decodedFilename;
  }
  //功能- 下载历史版本
  if (window.location.href.includes('versions') && installforversions) {
    window.addEventListener('load', function () {
      fetchAndProcessJSON();
    }, false);
  }

  function fetchAndProcessJSON() {
    var jsonLink = document.querySelector('link[href$=".json"]');
    var currentUrl = window.location.href;
    // 在 `versions` 后面添加 `.json`
    var jsonUrl = currentUrl.replace(/(\/versions)([^\/]*)$/, '$1.json$2');
    if (jsonUrl) {
      fetch(jsonUrl)
        .then(response => response.json())
        .then(data => {
          console.log("JSON data:", data);
          createLinks(data);
        })
        .catch(error => {
          console.error("Error fetching JSON:", error);
        });
    } else {
      console.log("JSON link element not found");
    }
  }

  function createLinks(jsonData) {
    var ulElement = document.querySelector("#script-content > form > ul");
    if (ulElement) {
      console.log("Parent element found:", ulElement);

      // Iterate over each version in JSON data
      jsonData.forEach(function (versionInfo, index) {
        console.log("Version info " + (index + 1) + ":", versionInfo);

        // Create link element
        var link = document.createElement('a');
        link.href = versionInfo.code_url; // 设置链接地址为当前版本的 url
        link.textContent = translate('install'); // 设置链接文本为 "安装"
        var link2 = document.createElement('a');
        link2.href = '#'; // 设置链接地址为 "#",这里假设点击后执行下载操作
        link2.textContent = translate('download'); // 设置链接文本为 "下载"
        link2.style.color = 'bule'; // 请根据需要设置具体的颜色值b
        link2.setAttribute('download', ''); // 设置下载属性,空字符串表示使用默认文件名
        // 创建一个容器元素
        var container = document.createElement('div');

        // 设置容器样式,这里通过CSS来控制间距
        container.style.display = 'flex'; // 使用flex布局
        container.style.gap = '10px'; // 设置链接元素之间的间距为20px

        // 将链接元素添加到容器中
        container.appendChild(link);
        container.appendChild(link2);



        // Find corresponding .diff-controls element (assuming index corresponds to the order)
        var diffControls = ulElement.querySelectorAll(".diff-controls");
        if (index < diffControls.length) {
          var diffControl = diffControls[index];
          diffControl.insertAdjacentElement('beforebegin', container);
          link2.addEventListener('click', function (event) {
            event.preventDefault(); // 阻止默认的链接跳转行为
            var name = getFilenameFromUrl(versionInfo.code_url);
            name = name.replace(/\?version=\d+/g, '');
            link2.textContent = translate('downloading'); // 修改链接文本为 "下载中..."
            link2.style.pointerEvents = 'none'; // 禁用点击事件,防止重复点击
            link2.blur(); // 让链接失去焦点
            downloadFile(versionInfo.code_url, name, function (error) {
              // 下载完成后执行的操作
              if (error) {
                link2.textContent = translate('download'); // 恢复链接文本为 "下载"
                link2.style.pointerEvents = 'auto'; // 恢复点击事件
                // 如果下载失败,处理错误情况

                Toast(error.message, 3000, '#ff6347', '#ffffff', 'top');
                // 可以进行其他错误处理,例如显示错误消息给用户
              } else {
                // 下载成功后执行的操作
                link2.textContent = translate('download'); // 恢复链接文本为 "下载"
                link2.style.pointerEvents = 'auto'; // 恢复点击事件
                link2.focus(); // 让链接重新获取焦点,给用户一种下载完成的感觉
              }
            });
          });
        } else {
          console.warn("No corresponding .diff-controls element found for version info", versionInfo);
        }
      });
    } else {
      console.log("Parent element not found");
    }
  }

  //功能- 脚本详情页增加作者所有脚本
  function createAuthorScriptsLink() {
    // 检查是否已经存在作者其他脚本链接
    if (document.querySelector('[data-author-scripts-link]')) {
      // 如果已经存在,则添加点击事件监听器
      document.querySelector('[data-author-scripts-link]').addEventListener('click', function (event) {
        event.preventDefault();
        gotopage(); // 调用 gotopage 函数
      });
      return; // 结束函数,不再继续执行
    }

    // 创建新的链接元素
    var newLink = document.createElement('a');
    newLink.textContent = translate('dallScripts');
    newLink.setAttribute('href', '#');
    newLink.setAttribute('data-author-scripts-link', ''); // 添加标记

    // 获取或创建用于显示新链接的容器 li 元素
    var targetLi = document.querySelector('#script-links > li:first-child');

    // 检查目标 li 元素是否存在,如果存在则添加新的 li 元素和链接
    if (targetLi) {
      var newLi = document.createElement('li');
      newLi.appendChild(newLink);
      targetLi.insertAdjacentElement('afterend', newLi);

    } else {
      console.error('找不到目标 li 元素。');
    }

    // 添加点击事件监听器
    newLink.addEventListener('click', function (event) {
      event.preventDefault();
      gotopage(); // 调用 gotopage 函数
    });
  }
  createAuthorScriptsLink();
  let backup;
  var LatestCreated, LatestUpdated, ok, bad, good, DailyTotal, TotalInstalls = ''; // 创建新变量

  async function fetchAndMergeJSON(urls) {
    try {
      // 使用Promise.all并行获取多个JSON数据
      urls.forEach(url => console.log('Fetching:', url));
      const responses = await Promise.all(urls.map(url => fetch(url)));
      const jsonResults = await Promise.all(responses.map(response => response.json()));

      // 将所有数据合并到一个数组中
      const allScripts = jsonResults.reduce((acc, curr) => {
        return acc.concat(curr.all_listable_scripts);
      }, []);

      // 返回合并后的JSON数组
      return allScripts;
    } catch (error) {
      console.error('Error fetching or merging JSON data:', error);
      throw error; // 抛出错误以便上层处理
    }
  }

  function fetchJSON(jsonlink) {
    return fetch(jsonlink)
      .then(response => response.json())
      .catch(error => {
        console.error('Error fetching or parsing JSON:', error);
        throw error;
      });
  }

  function gotopage() {


    let scriptData = [];
    let scr = [];
    const currentUrl = window.location.href; // 获取当前页面的 URL
    const match2 = currentUrl.match(/\/scripts\/(\d+)/);
    const jsonlink = 'https://greasyfork.org/zh-CN/scripts/' + match2[1] + '.json';
    const textContents = getDtContents("#script-stats");

    fetchJSON(jsonlink)
      .then(data => {
        // 在这里可以访问并使用获取到的数据
        scr = data.users[0];

        const ds = ['https://greasyfork.org/zh-CN/users/' + scr.id + '.json'];
        console.log("fafaf", ds);
        fetchAndMergeJSON(ds)
          .then(mergedData => {
            scriptData = mergedData;

            const sc = scriptData.map(scriptDetails => createScriptInfoHtml(scriptDetails, scr.name, scr.url, textContents));
            //计算各项统计
            const color = '#ffcc00';

            let cssCount = 0;
            let jsCount = 0;

            // 使用 map 和 reduce 统计 CSS 脚本数量
            cssCount = scriptData
              .map(obj => obj.code_url.endsWith('.css') ? 1 : 0) // 判断 code_url 是否以 .css 结尾
              .reduce((acc, curr) => acc + curr, 0); // 累加符合条件的数量
            jsCount = scriptData
              .map(obj => obj.code_url.endsWith('.js') ? 1 : 0) // 判断 code_url 是否以 .js 结尾
              .reduce((acc, curr) => acc + curr, 0); // 累加符合条件的数量
            LatestCreated = new Date(Math.max(...scriptData.map(obj => new Date(obj.created_at))));
            LatestUpdated = new Date(Math.max(...scriptData.map(obj => new Date(obj.code_updated_at))));
            ok = scriptData.map(obj => parseInt(obj.ok_ratings, 10)).reduce((acc, curr) => acc + curr, 0);
            bad = scriptData.map(obj => parseInt(obj.bad_ratings, 10)).reduce((acc, curr) => acc + curr, 0);
            good = scriptData.map(obj => parseInt(obj.good_ratings, 10)).reduce((acc, curr) => acc + curr, 0);
            DailyTotal = scriptData.map(obj => parseInt(obj.daily_installs, 10)).reduce((acc, curr) => acc + curr, 0);
            TotalInstalls = scriptData.map(obj => parseInt(obj.total_installs, 10)).reduce((acc, curr) => acc + curr, 0);
            backup = document.querySelector('#script-info').innerHTML;
            addCustomStyle();
            //const  tab=document.querySelector("#script-links").innerHTML;
            document.querySelector('#script-info').innerHTML = `
     <section>
    <header>
      <h3>${scr.name}:${translate('dallScripts')} <button id="close-button" style="margin-left: 10px;" onclick="document.querySelector('#script-info').innerHTML = backup;">${translate('Close')}</button></h3>

    </header>
    <section class="text-content">
            <ul>
            <span style="font-size: 15px;border-radius: 3px;background: rgb(45, 45, 45);color: rgb(255, 255, 255);margin: 0px 4px;padding: 0 4px;outline: 2px solid ${color};"><span style="width: 8px;height: 8px;display: inline-flex;margin-bottom: 1px;margin-left: 4px;border-radius: 50%;background: ${color};"></span> ${translate('JSScripts')} ${jsCount.toLocaleString()}</span><br>
            <span style="font-size: 15px;border-radius: 3px;background: rgb(45, 45, 45);color: rgb(255, 255, 255);margin: 0px 4px;padding: 0 4px;outline: 2px solid ${color};"><span style="width: 8px;height: 8px;display: inline-flex;margin-bottom: 1px;margin-left: 4px;border-radius: 50%;background: ${color};"></span> ${translate('CSSScripts')} ${cssCount.toLocaleString()}</span><br>
               <span style="font-size: 15px;border-radius: 3px;background: rgb(45, 45, 45);color: rgb(255, 255, 255);margin: 0px 4px;padding: 0 4px;outline: 2px solid ${color};"><span style="width: 8px;height: 8px;display: inline-flex;margin-bottom: 1px;margin-left: 4px;border-radius: 50%;background: ${color};"></span> ${translate('dallScripts')}  ${scriptData.length}</span><br>

               <span style="font-size: 15px;border-radius: 3px;background: rgb(45, 45, 45);color: rgb(255, 255, 255);margin: 0px 4px;padding: 0 4px;outline: 2px solid ${color};"><span style="width: 8px;height: 8px;display: inline-flex;margin-bottom: 1px;margin-left: 4px;border-radius: 50%;background: ${color};"></span>${translate('DailyTotal')} ${DailyTotal.toLocaleString()}</span><br>
               <span style="font-size: 15px;border-radius: 3px;background: rgb(45, 45, 45);color: rgb(255, 255, 255);margin: 0px 4px;padding: 0 4px;outline: 2px solid ${color};"><span style="width: 8px;height: 8px;display: inline-flex;margin-bottom: 1px;margin-left: 4px;border-radius: 50%;background: ${color};"></span> ${translate('TotalInstalls')} ${TotalInstalls.toLocaleString()}</span><br>
                <span style="font-size: 15px;border-radius: 3px;background: rgb(45, 45, 45);color: rgb(255, 255, 255);margin: 0px 4px;padding: 0 4px;outline: 2px solid ${color};"><span style="width: 8px;height: 8px;display: inline-flex;margin-bottom: 1px;margin-left: 4px;border-radius: 50%;background: ${color};"></span>${translate('ok')} ${ok.toLocaleString()}</span><br>
                <span style="font-size: 15px;border-radius: 3px;background: rgb(45, 45, 45);color: rgb(255, 255, 255);margin: 0px 4px;padding: 0 4px;outline: 2px solid ${color};"><span style="width: 8px;height: 8px;display: inline-flex;margin-bottom: 1px;margin-left: 4px;border-radius: 50%;background: ${color};"></span> ${translate('bad')}${bad.toLocaleString()}</span><br>
                <span style="font-size: 15px;border-radius: 3px;background: rgb(45, 45, 45);color: rgb(255, 255, 255);margin: 0px 4px;padding: 0 4px;outline: 2px solid ${color};"><span style="width: 8px;height: 8px;display: inline-flex;margin-bottom: 1px;margin-left: 4px;border-radius: 50%;background: ${color};"></span>${translate('good')}${good.toLocaleString()}</span><br>

            </ul>
  </section>
   <ol id="browse-script-list" class="script-list ">
       ${sc.join('')}
 </ol>
    `;


            document.getElementById('close-button').addEventListener('click', restoreBackup);

            function restoreBackup() {
              document.querySelector('#script-info').innerHTML = backup;
              createAuthorScriptsLink();
            }
            // 在这里处理合并后的JSON数组
          })
          .catch(error => {
            console.error('Error fetching or merging JSON data:', error);
          });



      })
      .catch(error => {
        // 处理错误情况
        console.error('Error fetching or parsing JSON:', error);
      });


  }

  //给增加下CSS美化下
  function addCustomStyle() {
    GM_addStyle(`
            [style-54998] {
                float: right;
                font-size: 70%;
                text-decoration: none;
            }
         input[type="submit"],
button {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    line-height: 1;
    height: 32px;
    white-space: nowrap;
    cursor: pointer;
    text-align: center;
    box-sizing: border-box;
    outline: none;
    transition: 0.1s;
    font-weight: 500;
    user-select: none;
    vertical-align: middle;
    -webkit-appearance: none;
    background-color: #ff6666; /* 红色背景 */
    border: 1px solid #ff6666; /* 红色边框 */
    padding: 8px 15px;
    font-size: 14px;
    color: #ffffff; /* 白色文字 */
    border-radius: 4px;
}

button:hover,
button:focus {
    color: #ffffff; /* 白色文字 */
    border-color: #ff0000; /* 淡红色边框 */
    background-color: #ff0000; /* 淡红色背景 */
    outline: none;
}
.badge {
    /* 通用的徽章样式 */
    display: inline-block;
    padding: 0.25em 0.4em;
    font-size: 75%;
    font-weight: 700;
    line-height: 1;
    text-align: center;
    white-space: nowrap;
    vertical-align: baseline;
    border-radius: 0.25rem;
}
.badge-css {
    background-color: #254bdd;
    color: #fff
}

.badge-js {
    /* JavaScript 相关的徽章样式 */
    background-color: #efd81d; /* 蓝色背景 */
    color: #fff; /* 白色文字 */
    padding: 0.2em 0.4em; /* 调整内边距 */
    margin-left: 5px; /* 可选:左侧间距 */
}

        `);
  }
  //免于翻译
  function getDtContents(selector) {
    const elements = document.querySelectorAll(`${selector} > dt`);
    const dtContents = Array.from(elements)
      .map(element => element.textContent.trim());
    return dtContents;
  }


  //构建HTML内容
  function createScriptInfoHtml(scriptDetails, fname, fuRl, tran) {
    // 解构传入的脚本详情对象
    const {
      url,
      name,
      description,
      created_at,
      code_updated_at,
      daily_installs,
      total_installs,
      good_ratings,
      ok_ratings,
      bad_ratings,
      code_url,
      version,
      license
    } = scriptDetails;
    const extension = code_url.substring(code_url.lastIndexOf('.') + 1);
    console.log(tran);
    let badgeContent = '';
    let badgeClass = '';
    if (extension === 'js') {
      badgeContent = 'JS';
      badgeClass = 'badge-js'; // 根据实际需求添加对应的 CSS 类名
    } else if (extension === 'css') {
      badgeContent = 'CSS';
      badgeClass = 'badge-css'; // 根据实际需求添加对应的 CSS 类名
    }
    // 构建 HTML 结构
    const scriptInfoHtml = `
      <li  >
                <h2>
                  <a class="script-link" href="${url}">${name}</a>
                  <span class="badge ${badgeClass}" title="用户脚本">${badgeContent}</span><a class="install-link" href="${code_url}" style-54998="" style="text-decoration: none;">${translate('install')} ${version}</a></span>
                  <span class="name-description-separator">

                  </span>
                  <br>
                  <span class="script-description description">
                   ${description}
                  </span>
                </h2>
                <div class="script-meta-block">
                  <dl class="inline-script-stats">
                    <dt class="script-list-author"><span>${translate('viewauthor')}</span></dt>
                    <dd class="script-list-author"><span><a href="${fuRl}">${fname}</a></span></dd>
                      <dt class="script-list-daily-installs"><span>${translate('viewdaily_installs')}</span></dt>
                      <dd class="script-list-daily-installs"><span> ${daily_installs}</span></dd>
                      <dt class="script-list-total-installs"><span>${translate('tviewotal_installs')}</span></dt>
                      <dd class="script-list-total-installs"><span>${total_installs}</span></dd>
                      <dt class="script-list-ratings"><span>${translate('viewfan_score')}</span></dt>
                      <dd class="script-list-ratings" data-rating-score="0.0"><span><span class="good-rating-count" title="好评或收藏的人数。">${good_ratings}</span>
        <span class="ok-rating-count" title="评级为一般的人数。">${ok_ratings}</span>
        <span class="bad-rating-count" title="评级为差评的人数。">${bad_ratings}</span>

        </span></dd>
                   <dt class="script-show-version"><span>${translate('viewversion')}</span></dt>
    <dd class="script-show-version"><span>${version}</span></dd>
                    <dt class="script-list-created-date"><span>${translate('viewcreated_at')}</span></dt>
                    <dd class="script-list-created-date"><span><relative-time datetime="${created_at}" prefix="" title="2024年6月26日 GMT+8 08:04">2024-06-26</relative-time></span></dd>
                    <dt class="script-list-updated-date"><span>${translate('viewcode_updated_at')}</span></dt>
                    <dd class="script-list-updated-date"><span><relative-time datetime="${code_updated_at}" prefix="" title="2024年6月26日 GMT+8 08:04">2024-06-26</relative-time></span></dd>
                            <dt class="script-show-license"><span>${translate('viewlicense')}</span></dt>
    <dd class="script-show-license"><span><i>${license}</i></span></dd>
                  </dl>
                </div>

            </li>



    `;

    return scriptInfoHtml;
  }
  //功能- 锁定语言  greasyfork.org/scripts/6245/
  if (setlocklang) {
    let valuehe = '';
    if (window.location.origin == 'https://greasyfork.org') {
      valuehe = 'language';
    } else if (window.location.origin == 'https://sleazyfork.org') {

      valuehe = 'language_sleasy';
    } else {
      // 如果没有匹配的情况,可以设置一个默认值
      valuehe = 'language';
    }

    var language = GM_getValue(valuehe, 'en');
    maybeRedirect(location);

    window.addEventListener('load', function _() {
      window.removeEventListener('load', _);
      var _timer, _title;

      document.getElementById('language-selector-locale').addEventListener('change', function () {

        GM_setValue(valuehe, this.value);
        _title = _title || this.title;
        this.title = this.value + ' saved in ' + GM_info.script.name;
        clearTimeout(_timer);
        _timer = setTimeout(function () {
          this.title = _title;
          _title = null;
        }, 5000);
      });
    });

    window.addEventListener('mousedown', function (e) {
      var a = e.target.closest('a');
      if (a &&
        (a.origin === 'https://greasyfork.org' || a.origin === 'https://sleazyfork.org') &&

        a.pathname.lastIndexOf('/system/', 0) < 0 &&
        !a.pathname.match(/\/code\/.*?\.user\.(js|css)/))
        maybeRedirect(a);
    }, true);

    function makeRedirectedUrl(url) {
      var m = url.href.split('/');
      if (!/^\w\w(?:-\w\w)?$/.test(m[3]))
        m.splice(3, 0, '');
      if (m[3] === language)
        return url.href;
      m[3] = language;
      var newUrl = m.join('/').replace(/&?locale_override[^&]*/, '').replace(/\?$/, '');
      var noOvr = m[4] === 'forum' || m[4] === 'scripts' && /^\D|^$/.test(m[5]);
      return noOvr ? newUrl : newUrl + (newUrl.indexOf('?') > 0 ? '&' : '?') + 'locale_override=1';
    }

    function maybeRedirect(url) {
      var newUrl = makeRedirectedUrl(url);
      if (newUrl === url.href ||
        document.referrer && makeRedirectedUrl({
          href: document.referrer
        }) === newUrl)
        return;
      Toast(translate('locklang', language) + language, 1000, '#0000ff', '#ffffff', 'top')
      url.href = newUrl;

    }
  }
  // 添加Bootstrap CSS
  function addScopedStyles() {
    const styleElement = document.createElement('style');
    styleElement.id = 'scoped-bootstrap-styles';
    styleElement.innerHTML = `
    @import url('https://cdn.jsdelivr.net/npm/bootstrap@4.5.2/dist/css/bootstrap.min.css');
    .nav-link {
        white-space: nowrap;
    }
    .modal-content {
        background-color: #fff; /* 修改背景色 */
        border: 1px solid #ccc; /* 修改边框样式 */
        border-radius: 5px; /* 添加圆角 */
    }
    .close:focus {
    background-color: red;
}
.close:hover {
    background-color: red;
}


@media (max-width: 767px) {
  .nav-pills .nav-link {
    background-color: transparent !important; /* 取消背景色 */
     color: #000 !important; /* 设置文字颜色为黑色 */
  }
  .nav-pills .nav-link.active {
    color: #007BFF !important; /* 设置选中时文字颜色为蓝色 */
  }

}

    `;

    document.head.appendChild(styleElement);
  }

  function removeScopedStyles() {
    const styleElement = document.getElementById('scoped-bootstrap-styles');
    if (styleElement) {
      document.head.removeChild(styleElement);
    }
  }

  // 控件数据示例


  // 初始化分类数据
  const categories = [];

  // 创建模态框的HTML结构
  const modalHTML = `
<div class="modal fade" id="settingsModal" tabindex="-1" role="dialog" aria-labelledby="settingsModalLabel" aria-hidden="true" style="display: none;">
  <div class="modal-dialog  modal-dialog-centered modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="settingsModalLabel">Settings</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <div class="row">
          <div class="col-3">
            <ul class="nav flex-column nav-pills" id="settingsTabs" role="tablist">
            </ul>
          </div>
          <div class="col-9">
            <div class="tab-content" id="settingsTabsContent">
            </div>
          </div>
        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary" id="saveSettings">Save Settings</button>
      </div>
    </div>
  </div>
</div>
`;



  // 将模态框HTML添加到页面
 $('body').prepend(modalHTML);
  // 封装函数:创建分类
function createCategory(id, name, controls, controlsPerRow = 1) {
  const tabId = `${id}-tab`;
  const tabPaneId = id;

  // 计算每列的宽度
  const colWidth = Math.floor(12 / controlsPerRow);

  // 添加Tab项
  $('#settingsTabs').append(`
    <li class="nav-item">
      <a class="nav-link" id="${tabId}" data-toggle="pill" href="#${tabPaneId}" role="tab" aria-controls="${tabPaneId}" aria-selected="false">${name}</a>
    </li>
  `);

  // 添加Tab内容
  $('#settingsTabsContent').append(`
    <div class="tab-pane fade" id="${tabPaneId}" role="tabpanel" aria-labelledby="${tabId}">
      <form id="${tabPaneId}Form">
        <div class="container-fluid">
          <div class="row">
            ${controls.map(control => generateControlHTML(control, colWidth)).join('')}
          </div>
        </div>
      </form>
    </div>
  `);

  // 绑定事件
  controls.forEach(control => {
    if (control.onclick) {
      $(`#${control.id}`).click(control.onclick);
    }
    if (control.onchange) {
      $(`#${control.id}`).change(control.onchange);
    }
  });

  // 初始化第一个分类为激活状态
  if ($('#settingsTabs .nav-link.active').length === 0) {
    $(`#${tabId}`).addClass('active');
    $(`#${tabPaneId}`).addClass('show active');
  }
}

  // 生成控件HTML,并指定每列的宽度
function generateControlHTML(control, colWidth) {
  switch (control.type) {
    case 'link':
      return `
        <div class="col-md-${colWidth}">
          <div class="form-group">
            <a href="${control.href}" target="${control.target}" class="btn btn-link custom-link">${control.text}</a>
          </div>
        </div>
      `;
    case 'label':
      return `
        <div class="col-md-${colWidth}">
          <div class="form-group">
           <label class="${control.class || ''}">
              ${control.label}
              ${control.link ? `<a href="${control.link.href}" target="${control.link.target}" class="${control.link.class}">${control.link.text}</a>` : ''}
            </label>
          </div>
        </div>
      `;
    case 'checkbox':
      return `
        <div class="col-md-${colWidth}">
          <div class="form-check">
            <input type="checkbox" class="form-check-input" id="${control.id}" ${control.checked ? 'checked' : ''} onchange="${control.onchange ? control.onchange.toString() : ''}">
            <label class="form-check-label" for="${control.id}">${control.label}</label>
          </div>
        </div>
      `;
    case 'text':
      return `
        <div class="col-md-${colWidth}">
          <div class="form-group">
            <label for="${control.id}">${control.label}</label>
            <input type="text" class="form-control" id="${control.id}" value="${control.value}" placeholder="${control.placeholder}" onchange="${control.onchange ? control.onchange.toString() : ''}">
          </div>
        </div>
      `;
    case 'button':
      return `
        <div class="col-md-${colWidth}">
          <button type="button" id="${control.id}" class="btn btn-primary" onclick="${control.onclick ? control.onclick.toString() : ''}">${control.text}</button>
        </div>
      `;
    case 'textarea':
      return `
        <div class="col-md-${colWidth}">
          <div class="form-group">
            <label for="${control.id}">${control.label}</label>
            <textarea id="${control.id}" class="form-control" placeholder="${control.placeholder}" onchange="${control.onchange ? control.onchange.toString() : ''}">${control.value}</textarea>
          </div>
        </div>
      `;
    case 'select':
      return `
        <div class="col-md-${colWidth}">
          <div class="form-group">
            <label for="${control.id}">${control.label}</label>
            <select id="${control.id}" class="form-control" onchange="${control.onchange ? control.onchange.toString() : ''}">
              ${control.options.map(option => `<option value="${option.value}" ${option.selected ? 'selected' : ''}>${option.text}</option>`).join('')}
            </select>
          </div>
        </div>
      `;
    // 其他控件类型的处理
    default:
      return '';
  }
}



  // 初始化模态框
  $(document).ready(function() {
    $('#settingsModal').on('shown.bs.modal', function() {
      addScopedStyles();
    });

    $('#settingsModal').on('hidden.bs.modal', function() {
      saveSettings();
      removeScopedStyles();
    });

          // 示例按钮来打开设置模态框
    const settingsButton = $('<button>')
      .text('打开设置')
      .addClass('btn btn-primary')
      .css({
        position: 'fixed',
        bottom: '10px',
        right: '10px',
        'z-index': 1000
      })
      .on('click', function() {
        $('#settingsModal').modal('show');
      });
 //   $('body').append(settingsButton);
  });





  // 保存设置
  function saveSettings() {
    // 遍历每个控件
    $('#settingsTabsContent').find('input, select').each(function() {
      const element = this;
      const controlId = element.id;
      const controlType = element.type;

      // 根据控件类型保存值
      if (controlType === 'checkbox') {
        GM_setValue(controlId, element.checked);
      } else if (controlType === 'text' || controlType === 'number' || controlType === 'select-one') {
        GM_setValue(controlId, element.value);
      }
    });

    // 弹出提示或执行其他操作
    // alert('设置已保存');
  }

  // 显示模态框
  function showSettingsModal() {
     // $('body').addClass('modal-open'); 
    $('#settingsModal').modal('show');
  }

  // 添加按钮来打开设置模态框
  /*   const settingsButton = $('<button>')
      .text('打开设置')
      .addClass('btn btn-primary')
      .css({
        position: 'fixed',
        bottom: '10px',
        right: '10px',
        'z-index': 1000
      })
      .on('click', showSettingsModal);
    $('body').append(settingsButton); */

  // 保存设置按钮事件
  $('#saveSettings').on('click', function() {
    saveSettings();
    $('#settingsModal').modal('hide');
  });

  // 使用封装函数创建分类
 createCategory('category1', translate('脚本详情'), [
  { type: 'checkbox', id: 'sethtmlview', label: translate('htmlViewtotext'), checked: GM_getValue('sethtmlview', false), onchange: function() { GM_setValue('sethtmlview', this.checked); } },
  { type: 'checkbox', id: 'setcopylink', label: translate('copyto'), checked: GM_getValue('setcopylink', true), onchange: function() { GM_setValue('setcopylink', this.checked); } },
  { type: 'checkbox', id: 'viewicon', label: translate('showIcon'), checked: GM_getValue('viewicon', true), onchange: function() { GM_setValue('viewicon', this.checked); } },
  { type: 'checkbox', id: 'installforversions', label: translate('scriptHisAddInstall'), checked: GM_getValue('installforversions', true), onchange: function() { GM_setValue('installforversions', this.checked); } },
  { type: 'checkbox', id: 'addbutton', label: translate('addDownButton'), checked: GM_getValue('addbutton', true), onchange: function() { GM_setValue('addbutton', this.checked); } },
  { type: 'checkbox', id: 'showtotal', label: translate('scriptLinNumb'), checked: GM_getValue('showtotal', false), onchange: function() { GM_setValue('showtotal', this.checked); } },
  { type: 'checkbox', id: 'addbutton', label: translate('addDownButton'), checked: GM_getValue('addbutton', true), onchange: function() { GM_setValue('addbutton', this.checked); } },
  { type: 'checkbox', id: 'copyshortlink', label:translate('复制短链接'), checked: GM_getValue('copyshortlink', true), onchange: function() { GM_setValue('copyshortlink', this.checked); } }
], 2);

createCategory('category2', translate('导航栏'), [
  { type: 'checkbox', id: 'Postlink', label: translate('addNewScript'), checked: GM_getValue('Postlink', true), onchange: function() { GM_setValue('Postlink', this.checked); } },
  { type: 'checkbox', id: 'jumpto', label: translate('jumpTo18'), checked: GM_getValue('jumpto', false), onchange: function() { GM_setValue('jumpto', this.checked); } },
  { type: 'checkbox', id: 'HeaderStyleFix', label: translate('fixNavbar'), checked: GM_getValue('HeaderStyleFix', true), onchange: function() { GM_setValue('HeaderStyleFix', this.checked); } },
  { type: 'checkbox', id: 'setopenindoc', label: translate('openindoc'), checked: GM_getValue('setopenindoc', true), onchange: function() { GM_setValue('setopenindoc', this.checked); } }
]);

createCategory('category3', translate('website'), [
  { type: 'checkbox', id: 'setlocklang', label: translate('locklangset'), checked: GM_getValue('setlocklang', false), onchange: function() { GM_setValue('setlocklang', this.checked); } },
  { type: 'checkbox', id: 'showRating', label: translate('showRating'), checked: GM_getValue('showRating', false), onchange: function() { GM_setValue('showRating', this.checked); } },
  { type: 'checkbox', id: 'autocheck', label: translate('AutoEnableCodeEditor'), checked: GM_getValue('autocheck', false), onchange: function() { GM_setValue('autocheck', this.checked); } },
  { type: 'checkbox', id: 'newtabtoinstall', label: translate('openTab'), checked: GM_getValue('newtabtoinstall', false), onchange: function() { GM_setValue('newtabtoinstall', this.checked); } },
  { type: 'checkbox', id: 'AbsoluteTime', label: translate('exactDate'), checked: GM_getValue('AbsoluteTime', false), onchange: function() { GM_setValue('AbsoluteTime', this.checked); } },
  { type: 'checkbox', id: 'greasymaxWidth', label: translate('maxView'), checked: GM_getValue('greasymaxWidth', false), onchange: function() { GM_setValue('greasymaxWidth', this.checked); } },
  { type: 'checkbox', id: 'scriptset', label: translate('moveSidebar'), checked: GM_getValue('scriptset', true), onchange: function() { GM_setValue('scriptset', this.checked); } },
  { type: 'checkbox', id: 'modifyRadioLabels', label: translate('beautifyDis'), checked: GM_getValue('modifyRadioLabels', false), onchange: function() { GM_setValue('modifyRadioLabels', this.checked); } },
  { type: 'checkbox', id: 'scriptwithdata', label: translate('ScriptListByCreat'), checked: GM_getValue('scriptwithdata', true), onchange: function() { GM_setValue('scriptwithdata', this.checked); } },
  { type: 'checkbox', id: 'remme', label: translate('Rememberme'), checked: GM_getValue('remme', true), onchange: function() { GM_setValue('remme', this.checked); } },
  { type: 'checkbox', id: 'clearhomepage', label: translate('cleanUpOld'), checked: GM_getValue('clearhomepage', false)},
  { type: 'text', id: 'clearhomepagedays', label: translate('cleanUpOld'), value: GM_getValue('clearhomepagedays', 30) },
  { type: 'checkbox', id: 'showSourceCode', label: translate('showJump'), checked: GM_getValue('showSourceCode', false), onchange: function() { GM_setValue('showSourceCode', this.checked); } },
  { type: 'checkbox', id: 'addedittohomepage', label:translate('主页脚本添加操作'), checked: GM_getValue('addedittohomepage', true), onchange: function() { GM_setValue('addedittohomepage', this.checked); } }
], 2);


const controls2 = [
{ type: 'label', label: 'Thank You', class: 'text-center', link: { href: '', target: '_blank', class: 'ml-2', text: '' } },
  { type: 'link', id: 'greasyforkInYourLanguage', text: 'Greasyfork in your language', href: 'https://greasyfork.org/zh-CN/scripts/6245', target: '_blank' },
  { type: 'link', id: 'greasyforkOptimization', text: 'Greasyfork 优化', href: 'https://greasyfork.org/zh-CN/scripts/411837', target: '_blank' },
  { type: 'link', id: 'greasyforkCopyCodeSnippet', text: 'GreasyFork Copy Code Snippet', href: 'https://greasyfork.org/zh-CN/scripts/423726', target: '_blank' },
  { type: 'link', id: 'downloadScriptButton', text: 'download script button', href: 'https://greasyfork.org/zh-CN/scripts/420872', target: '_blank' },
  { type: 'link', id: 'greasyforkScriptIcon', text: 'GreasyFork script icon', href: 'https://greasyfork.org/zh-CN/scripts/6861', target: '_blank' },
  { type: 'link', id: 'postANewScript', text: 'Add "Post a new script" link', href: 'https://greasyfork.org/zh-CN/scripts/450357', target: '_blank' },
  { type: 'link', id: 'openScriptsListSorting', text: 'Open scripts list sorting for creation date by default', href: 'https://greasyfork.org/zh-CN/scripts/495477', target: '_blank' },
  { type: 'link', id: 'absoluteTimeOnGreasyFork', text: 'Absolute Time on GreasyFork', href: 'https://greasyfork.org/zh-CN/scripts/470348', target: '_blank' },
  { type: 'link', id: 'collapseGreasyforkExpiredDiscussion', text: '折叠 greasyfork 过期讨论', href: 'https://greasyfork.org/scripts/426549/', target: '_blank' },
  { type: 'link', id: 'maximaleFensterbreite', text: 'maximale Fensterbreite auf nutzen', href: 'https://greasyfork.org/de/scripts/36037', target: '_blank' },
  { type: 'link', id: 'toggleHTMLView', text: 'Toggle HTML View', href: 'https://greasyfork.org/de/scripts/471149', target: '_blank' },
  { type: 'link', id: 'greasyforkHeaderStyleFix', text: 'GreasyFork Header Style Fix', href: 'https://greasyfork.org/zh-CN/scripts/473269', target: '_blank' },
  { type: 'link', id: 'autoEnableSyntaxHighlightingSourceEditor', text: 'Auto Enable Syntax-Highlighting Source Editor', href: 'https://greasyfork.org/zh-CN/scripts/22223', target: '_blank' },
  { type: 'link', id: 'showScriptSizeOnGreasyFork', text: 'Show script size on Greasy Fork', href: 'https://greasyfork.org/zh-CN/scripts/478498', target: '_blank' }
];

createCategory('category52', 'Thank You', controls2, 1);

})();