KeepChatGPT--平台修改版

支持上传文件对话;这是一个ChatGPT的畅聊与增强插件。开源免费。不仅能解决所有报错不再刷新,还有保持活跃、取消审计、克隆对话、净化首页、展示大屏、展示全屏、言无不尽、拦截跟踪、日新月异等多个高级功能。

  1. // ==UserScript==
  2. // @name KeepChatGPT--平台修改版
  3. // @description 支持上传文件对话;这是一个ChatGPT的畅聊与增强插件。开源免费。不仅能解决所有报错不再刷新,还有保持活跃、取消审计、克隆对话、净化首页、展示大屏、展示全屏、言无不尽、拦截跟踪、日新月异等多个高级功能。
  4. // @version 14.94
  5. // @author akmibo
  6. // @namespace https://github.com/xcanwin/KeepChatGPT/
  7. // @supportURL https://github.com/xcanwin/KeepChatGPT/
  8. // @description:zh-CN 这是一个ChatGPT的畅聊与增强插件。开源免费。不仅能解决所有报错不再刷新,还有保持活跃、取消审计、克隆对话、净化首页、展示大屏、展示全屏、言无不尽等多个高级功能。让我们的AI体验无比顺畅、丝滑、高效、简洁。
  9. // @license GPL-2.0-only
  10. // @match https://chat.openai.com/*
  11. // @grant GM_addStyle
  12. // @grant GM_addElement
  13. // @grant GM_setValue
  14. // @grant GM_getValue
  15. // @grant unsafeWindow
  16. // @run-at document-idle
  17. // @noframes
  18. // ==/UserScript==
  19.  
  20.  
  21. (function() {
  22. 'use strict';
  23.  
  24. var global = {};
  25.  
  26. const $ = (Selector, el) => (el || document).querySelector(Selector);
  27. const $$ = (Selector, el) => (el || document).querySelectorAll(Selector);
  28.  
  29. const u = `/api/${GM_info.script.namespace.slice(33, 34)}uth/s${GM_info.script.namespace.slice(28, 29)}ssion`;
  30. const symbol1_selector = 'nav.flex .transition-colors';
  31. const symbol2_selector = 'button.justify-center .sr-only';
  32.  
  33. const getLang = function() {
  34. let lang = `
  35. {
  36. "index": {"暗色主题": "dm", "显示调试": "sd", "取消审计": "cm", "取消动画": "ca", "关于": "ab", "建议间隔30秒": "si", "调整间隔": "mi", "检查更新": "cu", "当前版本": "cv", "发现最新版": "dl", "已是最新版": "lv", "克隆对话": "cc", "净化页面": "pp", "展示大屏": "ls", "展示全屏": "fs", "言无不尽": "sc", "拦截跟踪": "it", "日新月异": "ec", "赞赏鼓励": "ap"},
  37. "local": {
  38. "ar": {"dm": "الوضع الداكن", "sd": "إظهار التصحيح", "cm": "إلغاء التدقيق", "ca": "إلغاء الرسوم المتحركة", "ab": "حول", "si": "اقتراح فاصل زمني 30 ثانية", "mi": "تعديل الفاصل", "cu": "التحقق من التحديثات", "cv": "الإصدار الحالي", "dl": "اكتشف أحدث إصدار", "lv": "أحدث إصدار", "cc": "استنساخ المحادثة", "pp": "تنقية الصفحة", "ls": "عرض الشاشة الكبيرة", "fs": "عرض بملء الشاشة", "sc": "تحدث بشكل كامل", "it": "اعتراض التتبع", "ec": "التغير المستمر", "ap": "تقدير"},
  39. "bg": {"dm": "Тъмна тема", "sd": "Показване на отстраняване на грешки", "cm": "Отказ от одит", "ca": "Отмяна на анимацията", "ab": "За", "si": "Предложете интервал от 30 секунди", "mi": "Промяна на интервала", "cu": "Проверка на актуализации", "cc": "Клониране на разговора", "pp": "Почистване на страницата", "ls": "Показване на голям екран", "fs": "Показване на цял екран", "sc": "Говорете пълно", "it": "Прихващане на проследяването", "ec": "Непрекъснато променящ се", "ap": "Оценка"},
  40. "cs": {"dm": "Tmavý režim", "sd": "Zobrazit ladění", "cm": "Zrušení auditu", "ca": "Zrušit animaci", "ab": "O", "si": "Navrhnout interval 30 sekund", "mi": "Upravit interval", "cu": "Kontrola aktualizací", "cc": "Klonovat konverzaci", "pp": "Očistit stránku", "ls": "Zobrazení velkého displeje", "fs": "Zobrazit na celou obrazovku", "sc": "Mluvte úplně", "it": "Zachytávání sledování", "ec": "Neustále se měnící", "ap": "Ocenění"},
  41. "da": {"dm": "Mørk tilstand", "sd": "Vis fejlfinding", "cm": "Annuller revision", "ca": "Annuller animation", "ab": "Om", "si": "Forslag interval på 30 sekunder", "mi": "Ændre interval", "cu": "Tjek for opdateringer", "cc": "Klon samtalen", "pp": "Rensning af siden", "ls": "Vis stor skærm", "fs": "Vis i fuld skærm", "sc": "Fuldfør udtalelsen", "it": "Interceptor sporing", "ec": "Konstant forandring", "ap": "Værdssættelse"},
  42. "de": {"dm": "Dunkler Modus", "sd": "Fehlerbehebung anzeigen", "cm": "Prüfung abbrechen", "ca": "Animation abbrechen", "ab": "Über", "si": "Vorschlag für Intervall von 30 Sekunden", "mi": "Intervall bearbeiten", "cu": "Überprüfung auf Updates", "cv": "Aktuelle Version", "dl": "Entdecken Sie die neueste Version", "lv": "ist die neueste Version", "cc": "Konversation klonen", "pp": "Seite bereinigen", "ls": "Großen Bildschirm anzeigen", "fs": "Vollbild anzeigen", "sc": "Sprich vollständig", "it": "Tracking abfangen", "ec": "Ständiger Wandel", "ap": "Wertschätzung"},
  43. "el": {"dm": "Σκοτεινή θεματολογία", "sd": "Εμφάνιση αποσφαλμάτωσης", "cm": "Ακύρωση ελέγχου", "ca": "Ακύρωση κινούμενων σχεδίων", "ab": "Σχετικά με", "si": "Προτείνετε διάστημα 30 δευτερολέπτων", "mi": "Τροποποίηση διαστήματος", "cu": "Έλεγχος ενημερώσεων", "cc": "Κλωνοποίηση συνομιλίας", "pp": "Καθαρισμός σελίδας", "ls": "Εμφάνιση μεγάλης οθόνης", "fs": "Εμφάνιση πλήρους οθόνης", "sc": "Ολοκλήρωσε την ομιλία", "it": "Ανίχνευση παρακολούθησης", "ec": "Αδιάκοπη αλλαγή", "ap": "Εκτίμηση"},
  44. "en": {"dm": "Dark mode", "sd": "Show debugging", "cm": "Cancel audit", "ca": "Cancel animation", "ab": "About", "si": "Suggest interval of 30 seconds; The author usually sets 150", "mi": "Modify interval", "cu": "Check for updates", "cv": "Current version", "dl": "Discover the latest version", "lv": "is the latest version", "cc": "Conversation cloning", "pp": "Purified page", "ls": "Wide display mode", "fs": "Fullscreen mode", "sc": "Complete response", "it": "Intercept tracking", "ec": "More chat info", "ap": "Sponsor"},
  45. "eo": {"dm": "Malhela moduso", "sd": "Montri depuradon", "cm": "Nuligi kontroli", "ca": "Nuligi animacion", "ab": "Pri", "si": "Sugesti intervalon de 30 sekundoj", "mi": "Modifi intervalon", "cu": "Kontroli ĝisdatigojn", "cc": "Kloni konversacion", "pp": "Pura paĝo", "ls": "Montri grandan ekrane", "fs": "Montri plenekranon", "sc": "Parolu plene", "it": "Intercepti Trakadon", "ec": "Ĉiam ŝanĝiĝanta", "ap": "Aprobo"},
  46. "es": {"dm": "Modo oscuro", "sd": "Mostrar depuración", "cm": "Cancelar auditoría", "ca": "Cancelar animación", "ab": "Acerca de", "si": "Sugerir un intervalo de 30 segundos", "mi": "Modificar intervalo", "cu": "Comprobar actualizaciones", "cv": "Versión actual", "dl": "Descubre la última versión", "lv": "es la última versión", "cc": "Clonar conversación", "pp": "Purificar página", "ls": "Mostrar pantalla grande", "fs": "Mostrar pantalla completa", "sc": "Termina tu discurso", "it": "Interceptar Rastreo", "ec": "Cambio constante", "ap": "Apreciación"},
  47. "fi": {"dm": "Tumma tila", "sd": "Näytä virheenkorjaus", "cm": "Peruuta tarkistus", "ca": "Peruuta animaatio", "ab": "Tietoa", "si": "Ehdota 30 sekunnin väliaikaa", "mi": "Muokkaa väliä", "cu": "Tarkista päivitykset", "cc": "Kloonaa keskustelu", "pp": "Puhdista sivu", "ls": "Näytä suuri näyttö", "fs": "Näytä koko näyttö", "sc": "Puhu loppuun asti", "it": "Sieppaa seuranta", "ec": "Jatkuvasti muuttuva", "ap": "Arvostus"},
  48. "fr": {"dm": "Mode sombre", "sd": "Afficher le débogage", "cm": "Annuler l'audit", "ca": "Annuler l'animation", "ab": "À propos de", "si": "Suggérer un intervalle de 30 secondes", "mi": "Modifier l'intervalle", "cu": "Vérifier les mises à jour", "cv": "Version actuelle", "dl": "Découvrir la dernière version", "lv": "est la dernière version", "cc": "Cloner la conversation", "pp": "Purifier la page", "ls": "Afficher grand écran", "fs": "Afficher en plein écran", "sc": "Parlez complètement", "it": "Interception de suivi", "ec": "En perpétuelle évolution", "ap": "Appréciation"},
  49. "fr-CA": {"dm": "Mode nuit", "sd": "Afficher le débogage", "cm": "Annuler la vérification", "ca": "Annuler l'animation", "ab": "À propos de", "si": "Suggérer un intervalle de 30 secondes", "mi": "Modifier l'intervalle", "cu": "Vérifier les mises à jour", "cv": "Version actuelle", "dl": "Découvrir la dernière version", "lv": "est la dernière version", "cc": "Cloner la conversation", "pp": "Purifier la page", "ls": "Afficher grand écran", "fs": "Afficher en plein écran", "sc": "Parlez complètement", "it": "Intercepter le suivi", "ec": "Évolution constante", "ap": "Appréciation"},
  50. "he": {"dm": "מצב כהה", "sd": "הצגת התיקון", "cm": "ביטול ביקורת", "ca": "בטל אנימציה", "ab": "אודות", "si": "הצע מרווח של 30 שניות", "mi": "שינוי מרווח", "cu": "בדיקת עדכונים", "cc": "שכפול שיחה", "pp": "טיהור הדף", "ls": "תצוגת מסך גדול", "fs": "הצג מסך מלא", "sc": "דבר במלואו", "it": "התערבות במעקב", "ec": "שינוי מתמיד", "ap": "הערכה"},
  51. "hu": {"dm": "Sötét mód", "sd": "Hibakeresés mutatása", "cm": "Ellenőrzés megszüntetése", "ca": "Animáció törlése", "ab": "Rólunk", "si": "Javaslat 30 másodperces időközre", "mi": "Időköz módosítása", "cu": "Frissítések keresése", "cc": "Beszélgetés klónozása", "pp": "Oldal tisztítása", "ls": "Nagy képernyő megjelenítése", "fs": "Teljes képernyő megjelenítése", "sc": "Beszélj teljesen", "it": "Követés elfogása", "ec": "Folyamatos változás", "ap": "Elismerés"},
  52. "id": {"dm": "Mode gelap", "sd": "Tampilkan debugging", "cm": "Batalkan audit", "ca": "Batalkan animasi", "ab": "Tentang", "si": "Sarankan interval 30 detik", "mi": "Modifikasi interval", "cu": "Periksa Pembaruan", "cc": "Klon percakapan", "pp": "Membersihkan halaman", "ls": "Tampilkan layar besar", "fs": "Tampilkan layar penuh", "sc": "Berbicara secara lengkap", "it": "Intersepsi Pelacakan", "ec": "Perubahan terus-menerus", "ap": "Penghargaan"},
  53. "it": {"dm": "Modalità scura", "sd": "Mostra debug", "cm": "Annulla verifica", "ca": "Annulla animazione", "ab": "Riguardo a", "si": "Suggerisci un intervallo di 30 secondi", "mi": "Modifica intervallo", "cu": "Verifica aggiornamenti", "cv": "Versione attuale", "dl": "Scopri l'ultima versione", "lv": "è l'ultima versione", "cc": "Clona conversazione", "pp": "Purifica pagina", "ls": "Mostra grande schermo", "fs": "Mostra a schermo intero", "sc": "Parla completamente", "it": "Intercettare il tracciamento", "ec": "Cambiamento costante", "ap": "Apprezzamento"},
  54. "ja": {"dm": "ダークモード", "sd": "デバッグを表示", "cm": "監査をキャンセル", "ca": "アニメーションのキャンセル", "ab": "について", "si": "30秒間隔を提案する", "mi": "間隔を変更する", "cu": "更新をチェックする", "cv": "現在のバージョン", "dl": "最新バージョンを発見する", "lv": "最新バージョンです", "cc": "会話をクローンする", "pp": "ページを浄化する", "ls": "ビッグスクリーンを表示する", "fs": "フルスクリーン表示", "sc": "完全に話してください", "it": "トラッキングの傍受", "ec": "絶え間ない変化", "ap": "評価"},
  55. "ka": {"dm": "ბნელი რეჟიმი", "sd": "გამოჩენა დებაგი", "cm": "ანულირება აუდიტი", "ca": "ანიმაციის გაუქმება", "ab": "შესახებ", "si": "30 წამის ინტერვალის შეტანა", "mi": "ინტერვალის შეცვლა", "cu": "განახლებების შემოწმება", "cc": "კონვერსაციის კლონირება", "pp": "გვერდის გაწმენდა", "ls": "დიდი ეკრანის გამოსახულება", "fs": "მთელი ეკრანის ჩვენება", "sc": "სრულად ილაპარაკეთ", "it": "თვალყური მისმართავა", "ec": "მუდმივი ცვლილება", "ap": "შეფასება"},
  56. "ko": {"dm": "다크 모드", "sd": "디버깅 표시", "cm": "감사 취소", "ca": "애니메이션 취소", "ab": "관하여", "si": "30초 간격 건의", "mi": "간격 수정", "cu": "업데이트 확인", "cv": "현재 버전", "dl": "최신 버전 찾기", "lv": "최신 버전입니다.", "cc": "대화 복제", "pp": "페이지 정화", "ls": "큰 화면 표시", "fs": "전체 화면 표시", "sc": "완전히 말하세요", "it": "추적 가로채기", "ec": "끊임없는 변화", "ap": "감사"},
  57. "nb": {"dm": "Mørk modus", "sd": "Vis feilsøking", "cm": "Avbryt revisjonen", "ca": "Avbryt animasjon", "ab": "Om", "si": "Forslag om et intervall på 30 sekunder", "mi": "Endre intervall", "cu": "Sjekk etter oppdateringer", "cc": "Klon samtalen", "pp": "Rens side", "ls": "Vis stor skjerm", "fs": "Vis i fullskjerm", "sc": "Snakk fullstendig", "it": "Intercept sporing", "ec": "Kontinuerlig endring", "ap": "Verdsatt"},
  58. "nl": {"dm": "Donkere modus", "sd": "Foutopsporing weergeven", "cm": "Controle annuleren", "ca": "Animatie annuleren", "ab": "Over", "si": "Stel een interval van 30 seconden voor", "mi": "Interval wijzigen", "cu": "Controleren op updates", "cc": "Gesprek klonen", "pp": "Pagina zuiveren", "ls": "Groot scherm weergeven", "fs": "Volledig scherm weergeven", "sc": "Spreek volledig uit", "it": "Onderscheppen van tracking", "ec": "Voortdurende verandering", "ap": "Waardering"},
  59. "pl": {"dm": "Tryb ciemny", "sd": "Pokaż debugowanie", "cm": "Anuluj audyt", "ca": "Anuluj animację", "ab": "O", "si": "Zasugeruj interwał 30 sekund", "mi": "Zmień interwał", "cu": "Sprawdź aktualizacje", "cc": "Klonuj rozmowę", "pp": "Oczyść stronę", "ls": "Wyświetl duży ekran", "fs": "Wyświetl pełny ekran", "sc": "Mów całkowicie", "it": "Przechwytywanie śledzenia", "ec": "Ciągłe zmiany", "ap": "Docenienie"},
  60. "pt-BR": {"dm": "Modo escuro", "sd": "Mostrar depuração", "cm": "Cancelar auditoria", "ca": "Cancelar animação", "ab": "Sobre", "si": "Sugira um intervalo de 30 segundos", "mi": "Modificar intervalo", "cu": "Verificar atualizações", "cc": "Clonar conversa", "pp": "Purificar página", "ls": "Exibir tela grande", "fs": "Exibir em tela cheia", "sc": "Fale completamente", "it": "Interceptar Rastreamento", "ec": "Mudança constante", "ap": "Apreciação"},
  61. "ro": {"dm": "Mod întunecat", "sd": "Afișare depanare", "cm": "Anulare audit", "ca": "Anulare animație", "ab": "Despre", "si": "Sugerați un interval de 30 secunde", "mi": "Modificați intervalul", "cu": "Verifică actualizări", "cc": "Clonează conversația", "pp": "Purificare pagină", "ls": "Afișare ecran mare", "fs": "Afișare pe tot ecranul", "sc": "Vorbiți complet", "it": "Interceptarea urmăririi", "ec": "Schimbare continuă", "ap": "Apreciere"},
  62. "ru": {"dm": "Темный режим", "sd": "Показать отладку", "cm": "Отменить аудит", "ca": "Отменить анимацию", "ab": "О", "si": "Предложить интервал в 30 секунд", "mi": "Изменить интервал", "cu": "Проверить обновления", "cc": "Клонировать диалог", "pp": "Очистить страницу", "ls": "Показать большой экран", "fs": "Показать на полный экран", "sc": "Говорите полностью", "it": "Перехват отслеживания", "ec": "Постоянное изменение", "ap": "Признательность"},
  63. "sk": {"dm": "Tmavý režim", "sd": "Zobraziť ladenie", "cm": "Zrušiť audit", "ca": "Zrušiť animáciu", "ab": "O", "si": "Navrhnúť interval 30 sekúnd", "mi": "Zmena intervalu", "cu": "Kontrola aktualizácií", "cc": "Klonovať konverzáciu", "pp": "Očistiť stránku", "ls": "Zobraziť veľkú obrazovku", "fs": "Zobraziť na celú obrazovku", "sc": "Hovorte úplne", "it": "Zachytenie sledovania", "ec": "Neustále sa meniace", "ap": "Ocenenie"},
  64. "sr": {"dm": "Тамни режим", "sd": "Прикажи отклањање грешака", "cm": "Откажи ревизију", "ca": "Откажи анимацију", "ab": "О", "si": "Predložiti interval od 30 sekundi", "mi": "Измена интервала", "cu": "Provera ažuriranja", "cc": "Клонирај разговор", "pp": "Прочисти страницу", "ls": "Прикажи велики екран", "fs": "Прикажи на целом екрану", "sc": "Говорите у потпуности", "it": "Пресретање праћења", "ec": "Непрестана промена", "ap": "Поштовање"},
  65. "sv": {"dm": "Mörkt läge", "sd": "Visa felsökning", "cm": "Avbryt revision", "ca": "Avbryt animation", "ab": "Om", "si": "Föreslå intervall på 30 sekunder", "mi": "Ändra intervall", "cu": "Kontrollera uppdateringar", "cc": "Klonar samtal", "pp": "Rensa sidan", "ls": "Visa stor skärm", "fs": "Visa i helskärm", "sc": "Tala helt klart", "it": "Interceptera spårning", "ec": "Ständig förändring", "ap": "Uppskattning"},
  66. "th": {"dm": "โหมดมืด", "sd": "แสดงการแก้ไขข้อผิดพลาด", "cm": "ยกเลิกการตรวจสอบ", "ca": "ยกเลิกการเคลื่อนไหว", "ab": "เกี่ยวกับ", "si": "เสนอช่วงเวลา 30 วินาที", "mi": "แก้ไขระยะห่าง", "cu": "ตรวจสอบการอัปเดต", "cc": "โคลนสนทนา", "pp": "ทำความสะอาดหน้า", "ls": "แสดงหน้าจอใหญ่", "fs": "แสดงแบบเต็มหน้าจอ", "sc": "พูดคุยให้เสร็จสิ้น", "it": "การดักจับการติดตาม", "ec": "การเปลี่ยนแปลงตลอดเวลา", "ap": "การประเมินค่า"},
  67. "tr": {"dm": "Karanlık mod", "sd": "Hata ayıklama göster", "cm": "Denetimi İptal Et", "ca": "Animasyonu iptal et", "ab": "Hakkında", "si": "30 saniyelik aralık önerin", "mi": "Aralığı değiştir", "cu": "Güncelleştirmeleri kontrol et", "cc": "Sohbeti kopyala", "pp": "Sayfayı temizle", "ls": "Büyük ekranı görüntüle", "fs": "Tam ekran görüntüle", "sc": "Tamamlayın konuşmayı", "it": "İzlemeyi Engellemek", "ec": "Sürekli değişim", "ap": "Takdir"},
  68. "uk": {"dm": "Темний режим", "sd": "Показати налагодження", "cm": "Скасувати аудит", "ca": "Скасувати анімацію", "ab": "Про", "si": "Запропонуйте інтервал у 30 секунд", "mi": "Змінити інтервал", "cu": "Перевірити оновлення", "cc": "Клонувати діалог", "pp": "Очистити сторінку", "ls": "Відобразити великий екран", "fs": "Показати на повний екран", "sc": "Говоріть повністю", "it": "Перехоплення відстеження", "ec": "Постійна зміна", "ap": "Вдячність"},
  69. "ug": {"dm": "تېما كۆرسىتىش", "sd": "كۆرسەتكەن يۇقىرىلاش", "cm": "ئەمەلدىن قالدۇرۇش", "ca": "ئېنىماتىكىنى بىكار قىلىش", "ab": "ئۇچۇرلىق", "si": "30 سىكونتلىك ئارىلىقنى سۇنۇشتۇرۇش", "mi": "ئارىلىق ئۆزگەرتىش", "cu": "يېڭىلانما كۆزەت", "cc": "كۆپچەي ئىككىلىش", "pp": "چۈشۈرۈش بەت", "ls": "كۆرسىتىش چوڭ ئېكران", "fs": "تولانما پۈتۈن ئېكران", "sc": "تاماملا سۆزلىشىڭىز", "it": "قولايلىنىش تىزىتكۈن", "ec": "تەڭشەك ئىستىقامەت", "ap": "قىلىش"},
  70. "vi": {"dm": "Chế độ tối", "sd": "Hiển thị gỡ lỗi", "cm": "Hủy đánh giá", "ca": "Hủy hoạt hình", "ab": "Về", "si": "Đề xuất khoảng thời gian 30 giây", "mi": "Sửa khoảng cách", "cu": "Kiểm tra cập nhật", "cc": "Sao chép cuộc trò chuyện", "pp": "Làm sạch trang", "ls": "Hiển thị màn hình lớn", "fs": "Hiển thị toàn màn hình", "sc": "Nói đầy đủ", "it": "Chặn Theo Dõi", "ec": "Luôn thay đổi", "ap": "Đánh giá"},
  71. "zh-CN": {"dm": "暗色主题", "sd": "显示调试", "cm": "取消审计", "ca": "取消动画", "ab": "关于", "si": "建议间隔30秒以上,作者平时设置的是150", "mi": "调整间隔", "cu": "检查更新", "cc": "克隆对话", "pp": "净化页面", "ls": "展示大屏", "fs": "展示全屏", "sc": "言无不尽", "it": "拦截跟踪", "ec": "日新月异", "ap": "赞赏鼓励"},
  72. "zh-TW": {"dm": "暗黑模式", "sd": "顯示調試", "cm": "取消稽核", "ca": "取消動畫", "ab": "關於", "si": "建議間隔30秒", "mi": "調整間隔", "cu": "檢查更新", "cc": "複製對話", "pp": "淨化頁面", "ls": "顯示大螢幕", "fs": "顯示全螢幕", "sc": "言無不盡", "it": "拦截追踪", "ec": "日新月異", "ap": "讚賞鼓勵"}
  73. }
  74. }
  75. `;
  76. lang = JSON.parse(lang);
  77. for(let k in lang.local){
  78. if (k.length > 2 && !(k.slice(0, 2) in lang.local)) {
  79. lang.local[k.slice(0, 2)] = lang.local[k];
  80. }
  81. }
  82. const nls = navigator.languages;
  83. let language = "zh-CN";
  84. for (let j = 0; j < nls.length; j++) {
  85. let nl = nls[j];
  86. if (nl in lang.local) {
  87. language = nl;
  88. break;
  89. } else if (nl.length > 2 && nl.slice(0, 2) in lang.local) {
  90. language = nl.slice(0, 2);
  91. break;
  92. }
  93. }
  94. //language = "en"; //Debug English
  95. return [lang.index, lang.local[language], language];
  96. };
  97.  
  98. const [langIndex, langLocal, language] = getLang();
  99.  
  100. const tl = function(s) {
  101. let r;
  102. try {
  103. const i = langIndex[s];
  104. r = langLocal[i];
  105. } catch (e) {
  106. r = s;
  107. }
  108. if (r === undefined) {r = s;}
  109. return r;
  110. };
  111.  
  112. const sv = function(key, value = "") {
  113. GM_setValue(key, value);
  114. };
  115.  
  116. const gv = function(key, value = "") {
  117. return GM_getValue(key, value);
  118. };
  119.  
  120. const formatDate = function(d) {
  121. return (new Date(d)).toLocaleString();
  122. };
  123.  
  124. const formatDate2 = function(datetime) {
  125. const Y = datetime.getFullYear();
  126. const M = (datetime.getMonth() + 1).toString().padStart(2, '0');
  127. const D = datetime.getDate().toString().padStart(2, '0');
  128. const h = datetime.getHours().toString().padStart(2, '0');
  129. const m = datetime.getMinutes().toString().padStart(2, '0');
  130. const currentDate = new Date();
  131. let formatted_date;
  132. if (currentDate.toISOString().split('T')[0] === (datetime).toISOString().split('T')[0]) {
  133. formatted_date = `${h}:${m}`;
  134. } else if (Math.floor(Math.abs(datetime - currentDate) / (24 * 60 * 60 * 1000)) < 6) {
  135. const weekday = language.slice(0, 2) === "zh" ? ['周日', '周一', '周二', '周三', '周四', '周五', '周六'] : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
  136. formatted_date = weekday[datetime.getDay()];
  137. } else {
  138. formatted_date = `${M}-${D}`;
  139. }
  140. return formatted_date;
  141. }
  142.  
  143. const formatJson = function(d) {
  144. try {
  145. const j = JSON.parse(d);
  146. return `<pre>${JSON.stringify(j, null, 2)}</pre>`;
  147. } catch (e) {
  148. return d;
  149. }
  150. };
  151.  
  152. const setIfr = function(u = "") {
  153. if ($("#xcanwin") === null) {
  154. const nIfr = document.createElement('iframe');
  155. nIfr.id = "xcanwin";
  156. nIfr.style = `height: 80px; width: 100%; display: none;`;
  157. if (gv("k_showDebug", false) === true) {
  158. nIfr.style.display = '';
  159. } else {
  160. nIfr.style.display = 'none';
  161. }
  162. if (u) {
  163. nIfr.src = u;
  164. }
  165. nIfr.onload = function() {
  166. const nIfrText = $("#xcanwin").contentWindow.document.documentElement.innerText;
  167. try {
  168. $("#xcanwin").contentWindow.document.documentElement.style = `background: #FCF3CF; height: 360px; width: 1080px; overflow; auto;`;
  169. if (nIfrText.indexOf(`"expires":"`) > -1) {
  170. console.log(`KeepChatGPT: IFRAME: Expire date: ${formatDate(JSON.parse(nIfrText).expires)}`);
  171. $("#xcanwin").contentWindow.document.documentElement.innerHTML = formatJson(nIfrText);
  172. } else if (nIfrText.match(/Please stand by|while we are checking your browser|Please turn JavaScript on|Please enable Cookies|reload the page/)) {
  173. console.log(`KeepChatGPT: IFRAME: BypassCF`);
  174. }
  175. } catch (e) {
  176. console.log(`KeepChatGPT: IFRAME: ERROR: ${e},\nERROR RESPONSE:\n${nIfrText}`);
  177. }
  178. };
  179. $("main").lastElementChild.appendChild(nIfr);
  180. } else{
  181. if (u) {
  182. $("#xcanwin").src = u;
  183. }
  184. }
  185. };
  186.  
  187. const keepChat = function() {
  188. fetch(u).then((response) => {
  189. response.text().then((data) => {
  190. try {
  191. const contentType = response.headers.get('Content-Type');
  192. if (contentType.indexOf("application/json") > -1 && response.status !== 403 && data.indexOf(`"expires":"`) > -1) {
  193. console.log(`KeepChatGPT: FETCH: Expire date: ${formatDate(JSON.parse(data).expires)}`);
  194. $("#xcanwin").contentWindow.document.documentElement.innerHTML = formatJson(data);
  195. } else {
  196. setIfr(u);
  197. }
  198. } catch (e) {
  199. console.log(`KeepChatGPT: FETCH: ERROR: ${e},\nERROR RESPONSE:\n${data}`);
  200. setIfr(u);
  201. }
  202. })
  203. });
  204. }
  205.  
  206. const ncheckbox = function() {
  207. const nsvg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
  208. nsvg.setAttribute("viewBox", "0 0 100 30");
  209. nsvg.classList.add("checkbutton");
  210. nsvg.innerHTML = `<g fill="none" fill-rule="evenodd"><path fill="#E3E3E3" d="M0 15C0 6.716 6.716 0 15 0h14c8.284 0 15 6.716 15 15s-6.716 15-15 15H15C6.716 30 0 23.284 0 15z"/><circle fill="#FFF" cx="15" cy="15" r="13"/></g>`;
  211. return nsvg.cloneNode(true);
  212. };
  213.  
  214. const ndialog = function(title = 'KeepChatGPT', content = '', buttonvalue = 'OK', buttonfun = function(t) {return t;}, inputtype = 'br', inputvalue = '') {
  215. const ndivalert = document.createElement('div');
  216. ndivalert.setAttribute("class", "kdialog relative z-50");
  217. ndivalert.innerHTML = `
  218. <div class="fixed inset-0 bg-gray-500/90"></div>
  219. <div class="fixed inset-0 overflow-y-auto z-50" style="display: flex; justify-content: center; align-items: center;">
  220. <div class="flex items-end justify-center min-h-full p-4 sm:items-center sm:p-0 text-center">
  221. <div class="kdialogwin bg-white dark:bg-gray-900 rounded-lg sm:max-w-lg sm:p-6 text-left">
  222. <div class="flex items-center justify-between">
  223. <div style="min-width: 15rem">
  224. <div class="flex items-center justify-between">
  225. <h3 class="dark:text-gray-200 text-gray-900 text-lg">${title}</h3>
  226. <p class="kdialogclose" style="cursor: pointer; font-weight: bold; color: #aaa;">X</p>
  227. </div>
  228. <p class="dark:text-gray-100 mt-2 text-gray-500 text-sm" style="margin-bottom: 0.6rem;">${content}</p>
  229. <div class="md:py-3 md:pl-4 border border-black/10 bg-white dark:border-gray-900/50 dark:text-white dark:bg-gray-700 rounded-md shadow-[0_0_10px_rgba(0,0,0,0.10)] dark:shadow-[0_0_15px_rgba(0,0,0,0.10)]">
  230. <${inputtype} class="kdialoginput resize-none border-0 bg-transparent p-0 pr-7 focus:ring-0 focus-visible:ring-0 dark:bg-transparent" style="max-height: 12.5rem; height: 1.5rem; outline: none;" placeholder=""></${inputtype}>
  231. </div>
  232. </div>
  233. </div>
  234. <div class="flex sm:flex-row-reverse sm:mt-4"><button class="btn btn-neutral kdialogbtn">${buttonvalue}</button>
  235. </div>
  236. </div>
  237. </div>
  238. </div>
  239. `;
  240. if (inputtype === 'br') {
  241. $(".kdialoginput", ndivalert).parentElement.style.display = 'none';
  242. } else if (inputtype === 'img') {
  243. $(".kdialoginput", ndivalert).src = inputvalue;
  244. $(".kdialoginput", ndivalert).style = `max-height: 19rem; height: unset; display: block; margin: 0 auto;`;
  245. $(".kdialogwin", ndivalert).style = `max-width: 37.5rem;`;
  246. }else {
  247. $(".kdialoginput", ndivalert).value = inputvalue;
  248. }
  249. $(".kdialogclose", ndivalert).onclick = function() {
  250. ndivalert.remove();
  251. };
  252. $(".kdialogbtn", ndivalert).onclick = function() {
  253. buttonfun(ndivalert);
  254. $(".kdialogclose", ndivalert).onclick();
  255. };
  256. document.body.appendChild(ndivalert);
  257. };
  258.  
  259. const loadMenu = function() {
  260. if ($(".kmenu") !== null) {
  261. return;
  262. }
  263. const ndivmenu = document.createElement('div');
  264. ndivmenu.setAttribute("class", "kmenu");
  265. ndivmenu.innerHTML = `
  266. <ul>
  267. <li id=nmenuid_af>${tl("调整间隔")}</li>
  268. <li id=nmenuid_cm>${tl("取消审计")}</li>
  269. <li id=nmenuid_cc>${tl("重新编辑对话-点击对话头像体验")}</li>
  270. <li id=nmenuid_sc>${tl("保存对话不间断")}</li>
  271. <li id=nmenuid_pp>${tl("净化页面")}</li>
  272. <li id=nmenuid_ls>${tl("展示大屏")}</li>
  273. <li id=nmenuid_fs>${tl("展示全屏")}</li>
  274. <li id=nmenuid_it>${tl("拦截跟踪")}</li>
  275. <li id=nmenuid_ec>${tl("展示对话时间")}</li>
  276. <li id=nmenuid_dm>${tl("暗色主题")}</li>
  277. <li id=nmenuid_ca>${tl("取消动画")}</li>
  278. <li id=nmenuid_sd>${tl("显示调试")}</li>
  279.  
  280. </ul>
  281. `;
  282. document.body.appendChild(ndivmenu);
  283.  
  284. $('#nmenuid_sd').appendChild(ncheckbox());
  285. $('#nmenuid_dm').appendChild(ncheckbox());
  286. $('#nmenuid_ca').appendChild(ncheckbox());
  287. $('#nmenuid_cm').appendChild(ncheckbox());
  288. $('#nmenuid_cc').appendChild(ncheckbox());
  289. $('#nmenuid_pp').appendChild(ncheckbox());
  290. $('#nmenuid_ls').appendChild(ncheckbox());
  291. $('#nmenuid_fs').appendChild(ncheckbox());
  292. $('#nmenuid_sc').appendChild(ncheckbox());
  293. $('#nmenuid_it').appendChild(ncheckbox());
  294. $('#nmenuid_ec').appendChild(ncheckbox());
  295.  
  296. $('#nmenuid_sd').onclick = function() {
  297. if ($('.checkbutton', this).classList.contains('checked')) {
  298. $('#xcanwin').style.display = 'none';
  299. sv("k_showDebug", false);
  300. } else {
  301. $('#xcanwin').style.display = '';
  302. sv("k_showDebug", true);
  303. }
  304. $('.checkbutton', this).classList.toggle('checked');
  305. };
  306.  
  307. $('#nmenuid_dm').onclick = function() {
  308. if ($('.checkbutton', this).classList.contains('checked')) {
  309. $('#kcg').style = $('#kcg').styleOrigin;
  310. sv("k_theme", "light");
  311. } else {
  312. $('#kcg').styleOrigin = $('#kcg').style;
  313. $('#kcg').style.background = "#2C3E50";
  314. $('#kcg').style.animation = "none";
  315. $('#kcg').style.color = "#ffffff";
  316. $('#kcg').style.marginRight = "inherit";
  317. sv("k_theme", "dark");
  318. }
  319. $('.checkbutton', this).classList.toggle('checked');
  320. };
  321.  
  322. $('#nmenuid_ca').onclick = function() {
  323. sv("k_cancelAnimation", !$('.checkbutton', this).classList.contains('checked'));
  324. $('#kcg').classList.toggle('shine');
  325. $('.checkbutton', this).classList.toggle('checked');
  326. };
  327.  
  328. $('#nmenuid_cm').onclick = function() {
  329. if ($('.checkbutton', this).classList.contains('checked')) {
  330. sv("k_closeModer", false);
  331. } else {
  332. sv("k_closeModer", true);
  333. }
  334. $('.checkbutton', this).classList.toggle('checked');
  335. };
  336.  
  337. $('#nmenuid_af').onclick = function() {
  338. toggleMenu('hide');
  339. ndialog(`${tl("调整间隔")}`, `${tl("建议间隔30秒")}`, `Go`, function(t) {
  340. try {
  341. interval2Time = parseInt($(".kdialoginput", t).value);
  342. } catch (e) {
  343. interval2Time = parseInt(gv("k_interval", 30));
  344. }
  345. if (interval2Time < 10) {
  346. return;
  347. }
  348. clearInterval(nInterval2);
  349. nInterval2 = setInterval(nInterval2Fun, 1000 * interval2Time);
  350. sv("k_interval", interval2Time);
  351. }, `input`, parseInt(gv("k_interval", 30)));
  352. };
  353.  
  354. $('#nmenuid_cc').onclick = function() {
  355. if ($('.checkbutton', this).classList.contains('checked')) {
  356. sv("k_clonechat", false);
  357. cloneChat(false);
  358. } else {
  359. sv("k_clonechat", true);
  360. cloneChat(true);
  361. }
  362. $('.checkbutton', this).classList.toggle('checked');
  363. };
  364.  
  365. $('#nmenuid_pp').onclick = function() {
  366. if ($('.checkbutton', this).classList.contains('checked')) {
  367. sv("k_cleanlyhome", false);
  368. } else {
  369. sv("k_cleanlyhome", true);
  370. }
  371. $('.checkbutton', this).classList.toggle('checked');
  372. };
  373.  
  374. $('#nmenuid_ls').onclick = function() {
  375. if ($('.checkbutton', this).classList.contains('checked')) {
  376. sv("k_largescreen", false);
  377. } else {
  378. sv("k_largescreen", true);
  379. }
  380. $("#__next>.overflow-hidden.w-full>div.overflow-hidden").classList.toggle('largescreen');
  381. $('.checkbutton', this).classList.toggle('checked');
  382. };
  383.  
  384. $('#nmenuid_fs').onclick = function() {
  385. if ($('.checkbutton', this).classList.contains('checked')) {
  386. sv("k_fullscreen", false);
  387. fullScreen(false);
  388. } else {
  389. sv("k_fullscreen", true);
  390. fullScreen(true);
  391. }
  392. $('.checkbutton', this).classList.toggle('checked');
  393. };
  394.  
  395. $('#nmenuid_sc').onclick = function() {
  396. if ($('.checkbutton', this).classList.contains('checked')) {
  397. sv("k_speakcompletely", false);
  398. } else {
  399. sv("k_speakcompletely", true);
  400. }
  401. $('.checkbutton', this).classList.toggle('checked');
  402. };
  403.  
  404. $('#nmenuid_it').onclick = function() {
  405. if ($('.checkbutton', this).classList.contains('checked')) {
  406. sv("k_intercepttracking", false);
  407. interceptTracking(false);
  408. } else {
  409. sv("k_intercepttracking", true);
  410. interceptTracking(true);
  411. }
  412. $('.checkbutton', this).classList.toggle('checked');
  413. };
  414.  
  415. $('#nmenuid_ec').onclick = function() {
  416. if ($('.checkbutton', this).classList.contains('checked')) {
  417. sv("k_everchanging", false);
  418. } else {
  419. sv("k_everchanging", true);
  420. }
  421. $('.checkbutton', this).classList.toggle('checked');
  422. location.reload();
  423. };
  424.  
  425. $('#nmenuid_cu').onclick = function() {
  426. toggleMenu('hide');
  427. checkForUpdates();
  428. };
  429.  
  430. $('#nmenuid_ap').onclick = function() {
  431. ndialog(`${tl("赞赏鼓励")}`, 本项目没有研发经费,但是功能研发、升级、BUG修复都会消耗很多个人时间、精力,并且有不少技术研究成本。<br>
  432. <br 如果你体验完本项目以后眉开眼笑,觉得好用!NB!神器!好顺畅!感觉很棒!NICE
  433. <br 如果你觉得本项目打开了你进入AI世界的高速通道
  434. <br 如果你希望作者的小猫吃到更好的猫粮、猫罐头
  435. <br 如果本项目对你有帮助
  436. <br 如果本项目提高了你工作效率
  437. <br 如果你希望本项目持续维护、升级更多的功能
  438. <br 如果你希望鼓励、激励作者投入更多的时间精力提升项目,欢迎各位支持和鼓励本项目`, `更多鼓励方式`, function(t) {
  439. window.open(`${GM_info.script.namespace}#赞赏`, '_blank');
  440. }, `img`, `https://github.com/xcanwin/KeepChatGPT/raw/main/assets/appreciate_wechat.png`);
  441. };
  442.  
  443. $('#nmenuid_ab').onclick = function() {
  444. window.open(GM_info.script.namespace, '_blank');
  445. };
  446. };
  447.  
  448. const setUserOptions = function() {
  449. if (gv("k_showDebug", false) === true) {
  450. $('#nmenuid_sd .checkbutton').classList.add('checked');
  451. $('#xcanwin').style.display = '';
  452. } else {
  453. $('#xcanwin').style.display = 'none';
  454. }
  455.  
  456. if (gv("k_theme", "light") === "light") {
  457. $('#kcg').styleOrigin = $('#kcg').style;
  458. } else {
  459. $('#nmenuid_dm .checkbutton').classList.add('checked');
  460. $('#kcg').style.background = "#2C3E50";
  461. $('#kcg').style.animation = "none";
  462. $('#kcg').style.color = "#ffffff";
  463. $('#kcg').style.marginRight = "inherit";
  464. }
  465.  
  466. if (gv("k_cancelAnimation", false) === true) {
  467. $('#nmenuid_ca .checkbutton').classList.add('checked');
  468. $('#kcg').classList.remove('shine');
  469. } else {
  470. $('#kcg').classList.add('shine');
  471. }
  472.  
  473. if (gv("k_closeModer", false) === true) {
  474. $('#nmenuid_cm .checkbutton').classList.add('checked');
  475. }
  476.  
  477. if (gv("k_clonechat", false) === true) {
  478. $('#nmenuid_cc .checkbutton').classList.add('checked');
  479. cloneChat(true);
  480. }
  481.  
  482. if (gv("k_cleanlyhome", false) === true) {
  483. $('#nmenuid_pp .checkbutton').classList.add('checked');
  484. }
  485.  
  486. if (gv("k_largescreen", false) === true) {
  487. $('#nmenuid_ls .checkbutton').classList.add('checked');
  488. $("#__next>.overflow-hidden.w-full>div.overflow-hidden").classList.toggle('largescreen');
  489. }
  490.  
  491. if (gv("k_fullscreen", false) === true) {
  492. $('#nmenuid_fs .checkbutton').classList.add('checked');
  493. fullScreen(true);
  494. }
  495.  
  496. if (gv("k_speakcompletely", false) === true) {
  497. $('#nmenuid_sc .checkbutton').classList.add('checked');
  498. }
  499.  
  500. if (gv("k_intercepttracking", false) === true) {
  501. $('#nmenuid_it .checkbutton').classList.add('checked');
  502. interceptTracking(true);
  503. }
  504.  
  505. if (gv("k_everchanging", false) === true) {
  506. $('#nmenuid_ec .checkbutton').classList.add('checked');
  507. }
  508. };
  509.  
  510. const toggleMenu = function(action) {
  511. const ndivmenu = $(".kmenu");
  512. if (action === "show") {
  513. ndivmenu.style.display = 'block';
  514. if ($("#kcg")) {
  515. ndivmenu.style.left = `${$("#kcg").getBoundingClientRect().right + 20}px`;
  516. ndivmenu.style.top = `${$("#kcg").getBoundingClientRect().top}px`;
  517. }
  518. } else {
  519. ndivmenu.style.display = 'none';
  520. }
  521. };
  522.  
  523. const loadKCG = function() {
  524. let symbol_prt;
  525. if ($("#kcg") !== null) {
  526. return;
  527. }
  528. var kcg_html;
  529. if (kcg_html !== undefined) {
  530. if ($(symbol1_selector)) {
  531. kcg_html.innerHTML = kcg_html._symbol1_innerHTML;
  532. symbol_prt = findParent($(symbol1_selector), "nav.flex", 3);
  533. } else if ($(symbol2_selector)) {
  534. kcg_html.innerHTML = kcg_html._symbol2_innerHTML;
  535. symbol_prt = findParent($(symbol2_selector), ".sticky", 2);
  536. }
  537. symbol_prt.insertBefore(kcg_html, symbol_prt.childNodes[0]);
  538. return;
  539. }
  540.  
  541. loadMenu();
  542. setIfr(u);
  543.  
  544. const ndivkcg = document.createElement("div");
  545. ndivkcg.id = "kcg";
  546. ndivkcg.setAttribute("class", "kgold shine flex py-3 px-3 items-center gap-3 rounded-md text-sm mb-1 flex-shrink-0 border border-white/20");
  547.  
  548. const ndivmenu = $(".kmenu");
  549. ndivkcg.onmouseover = ndivmenu.onmouseover = function() {
  550. toggleMenu('show');
  551. };
  552. ndivkcg.onmouseleave = ndivmenu.onmouseleave = function() {
  553. toggleMenu('hide');
  554. };
  555. ndivkcg.onclick = function() {
  556. if (ndivmenu.style.display === 'none') {
  557. toggleMenu('show');
  558. } else {
  559. toggleMenu('hide');
  560. }
  561. };
  562. const icon = GM_info.script.icon ? GM_info.script.icon : `${GM_info.script.namespace}raw/main/assets/logo.svg`;
  563. ndivkcg._symbol1_innerHTML = `<img src='${icon}' />Keep${ndivkcg.id.slice(1,2).toUpperCase()}hatGPT by 平台修改版;点我设置`;
  564. ndivkcg._symbol2_innerHTML = `Keep${ndivkcg.id.slice(1,2).toUpperCase()}hatGPT`;
  565.  
  566. if ($(symbol1_selector)) {
  567. ndivkcg.innerHTML = ndivkcg._symbol1_innerHTML;
  568. symbol_prt = findParent($(symbol1_selector), "nav.flex", 3);
  569. } else if ($(symbol2_selector)) {
  570. ndivkcg.innerHTML = ndivkcg._symbol2_innerHTML;
  571. symbol_prt = findParent($(symbol2_selector), ".sticky", 2);
  572. }
  573. kcg_html = ndivkcg;
  574. symbol_prt.insertBefore(kcg_html, symbol_prt.childNodes[0]);
  575.  
  576. addStyle();
  577. setUserOptions();
  578. };
  579.  
  580. const addStyle = function() {
  581. GM_addStyle(`
  582. .kgold {
  583. color: #555;
  584. background: linear-gradient(to top right, #F0B27A, #FDE184, #F0B27A);
  585. animation: gradient 6s ease-in-out infinite;
  586. position: relative;
  587. overflow: hidden;
  588. font-weight: bold;
  589. user-select: none;
  590. }
  591. @keyframes gradient {
  592. 0%{background-color:#F0B27A;}
  593. 50%{background-color:#FDE184;}
  594. 100%{background-color:#F0B27A;}
  595. }
  596.  
  597. .shine::before {
  598. content: '';
  599. position: absolute;
  600. top: -50%;
  601. left: -50%;
  602. width: 200%;
  603. height: 200%;
  604. background: linear-gradient(
  605. to bottom right,
  606. rgba(255, 255, 255, 0.3),
  607. rgba(255, 255, 255, 0.15),
  608. rgba(255, 255, 255, 0)
  609. );
  610. transform: rotate(-45deg);
  611. animation: shine 2.8s linear infinite;
  612. }
  613. @keyframes shine {
  614. from {
  615. transform: translateX(-50%) translateY(-50%) rotate(-45deg);
  616. }
  617. to {
  618. transform: translateX(150%) translateY(150%) rotate(-45deg);
  619. }
  620. }
  621.  
  622. .kmenu {
  623. background-color: #202123;
  624. color: #FFFFFF;
  625. border: 0.06rem solid #4D4D4F;
  626. border-radius: 0.625rem;
  627. box-shadow: 0 0.125rem 0.375rem rgba(0, 0, 0, 0.15);
  628. display: none;
  629. min-width: 12.5rem;
  630. padding: 0.75rem 0;
  631. position: absolute;
  632. z-index: 1000;
  633. }
  634. .kmenu::before {
  635. content: "";
  636. position: absolute;
  637. top: 0rem;
  638. bottom: 0rem;
  639. left: -6rem;
  640. right: 0rem;
  641. pointer-events: auto;
  642. z-index: -1;
  643. }
  644. .kmenu::after {
  645. content: "";
  646. position: absolute;
  647. top: 1rem;
  648. left: -1.25rem;
  649. border-style: solid;
  650. border-width: 0.625rem 0.625rem 0.625rem 0.625rem;
  651. border-color: transparent #202123 transparent transparent;
  652. }
  653. .kmenu li {
  654. display: block;
  655. padding: 0.5rem 1.5rem;
  656. text-align: left;
  657. user-select: none;
  658. display: flex;
  659. align-items: center;
  660. }
  661. .kmenu li:hover {
  662. background-color: #273746;
  663. cursor: pointer;
  664. }
  665.  
  666. main div.items-end>div:first-child {
  667. user-select: none;
  668. max-width: 30px;
  669. cursor: pointer;
  670. }
  671.  
  672. nav {
  673. position: relative;
  674. }
  675.  
  676. .checkbutton {
  677. height: 20px;
  678. margin-left: auto;
  679. margin-right: -35px;
  680. padding-left: 10px;
  681. }
  682. .checkbutton:hover {
  683. cursor: pointer;
  684. }
  685. .checked path {
  686. fill: #30D158;
  687. }
  688. .checked circle {
  689. transform: translateX(14px);
  690. transition: transform 0.2s ease-in-out;
  691. }
  692.  
  693. .largescreen .md\\:max-w-2xl, .largescreen .lg\\:max-w-xl, .largescreen .xl\\:max-w-3xl {
  694. max-width: unset;
  695. }
  696. .largescreen .lg\\:px-0 {
  697. padding-left: 25px;
  698. padding-right: 50px;
  699. }
  700. @media (min-width:1024px) {
  701. .largescreen form.stretch {
  702. max-width: 85%;
  703. }
  704. }
  705. .largescreen div.items-end>div.text-xs {
  706. top: -20px;
  707. left: -5px;
  708. margin-left: unset;
  709. -webkit-transform: unset;
  710. transform: unset;
  711. position: absolute;
  712. }
  713.  
  714. .fullscreen {
  715. max-width: 0px;
  716. }
  717. .btn-neutral {
  718. cursor: pointer;
  719. }
  720.  
  721. #new-chat-button + div, #expand-sidebar-bottom-button, #nav-toggle-button, #user-menu ~ div {
  722. display: none !important;
  723. max-height: 0 !important;
  724. }
  725.  
  726. .navdate {
  727. font-size: 0.75rem;
  728. padding-right: 0.5rem;
  729. }
  730. nav.flex div.overflow-y-auto a.hover\\:pr-4 {
  731. padding-right: unset;
  732. }
  733. nav.flex div.overflow-y-auto{
  734. scrollbar-width: thin;
  735. }
  736.  
  737. #nmenuid_ap {
  738. color: #00bf78;
  739. }
  740. `);
  741. };
  742.  
  743. const hookFetch = function() {
  744. unsafeWindow.fetch = new Proxy(fetch, {
  745. apply: function (target, thisArg, argumentsList) {
  746. const fetchReqUrl = argumentsList[0];
  747. let fetchRsp;
  748. try {
  749. if (gv("k_closeModer", false) && fetchReqUrl.match('/backend-api/moderations(\\?|$)')) {
  750. fetchRsp = Promise.resolve({
  751. json: () => {return {}}
  752. });
  753. return fetchRsp;
  754. } else if (gv("k_closeModer", false) && fetchReqUrl.match('/backend-api/conversation(\\?|$)')) {
  755. const post_body = JSON.parse(argumentsList[1].body);
  756. post_body.supports_modapi = false;
  757. argumentsList[1].body = JSON.stringify(post_body);
  758. } else if (gv("k_intercepttracking", false) && fetchReqUrl.match('sentry\.io|sentry_key=|widget\.intercom\.io|featuregates\.org|/v1/initialize|api-iam\.intercom\.io|/messenger/|nexus-websocket-a\.intercom\.io|statsigapi\.net|/rgstr|/v1/sdk_exception')) {
  759. fetchRsp = Promise.resolve({
  760. });
  761. return fetchRsp;
  762. }
  763. } catch (e) {}
  764. fetchRsp = target.apply(thisArg, argumentsList);
  765. fetchRsp.then(response => {
  766. let clonedResponse = response.clone();
  767. clonedResponse.text().then(fetchRspBody => {
  768. const fetchRspHeaders = clonedResponse.headers;
  769. if (gv("k_everchanging", false) && fetchReqUrl.match('/backend-api/conversations\\?.*offset=')) {
  770. const b = JSON.parse(fetchRspBody).items;
  771. if (!global.kec_object) global.kec_object = {};
  772. b.forEach(el => {
  773. const update_time = new Date(el.update_time);
  774. if (global.kec_object[el.id] && global.kec_object[el.id].date && global.kec_object[el.id].update_time >= update_time) return;
  775. global.kec_object[el.id] = {};
  776. global.kec_object[el.id].title = el.title;
  777. global.kec_object[el.id].update_time = update_time;
  778. });
  779. setTimeout(function() {
  780. attachDate();
  781. }, 300);
  782. }
  783. });
  784. return clonedResponse;
  785. }).catch(error => {});
  786. return fetchRsp;
  787. }
  788. });
  789. navigator.sendBeacon = function(url, data) {};
  790. };
  791.  
  792. const everChanging = function() {
  793. if (!$('.navdate')) {
  794. attachDate();
  795. }
  796. };
  797.  
  798. const attachDate = function() {
  799. if (!global.kec_object) return;
  800. $$('nav.flex li a.group').forEach(el => {
  801. const keyrf = Object.keys(el).find(key => key.startsWith("__reactFiber"));
  802. const a_id = el[keyrf].return.return.memoizedProps.id;
  803. const title = global.kec_object[a_id].title || "";
  804. const update_time = global.kec_object[a_id].update_time || "";
  805. if (!title || !update_time) return;
  806. if ($('.navtitle', el) && $('.navdate', el)) {
  807. $('.navtitle', el).innerHTML = title;
  808. $('.navdate', el).innerHTML = formatDate2(update_time);
  809. } else {
  810. const cdiv_old = $(`.overflow-hidden`, el);
  811. cdiv_old.style.display = "none";
  812. const cdiv_new = document.createElement("div");
  813. cdiv_new.className = `flex-1 text-ellipsis overflow-hidden break-all relative`;
  814. cdiv_new.innerHTML = `
  815. <div style="max-height: unset; max-width: 70%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; position: absolute;" class="navtitle">
  816. ${title}
  817. </div>
  818. <div style="right: 0;position: absolute;color: grey;font-size: 0.75rem;" class="navdate">
  819. ${formatDate2(update_time)}
  820. </div>
  821. <br>
  822. <div style="max-height: unset; max-width: 70%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: gray; font-size: 0.75rem;">
  823. </div>
  824. `;
  825. el.insertBefore(cdiv_new, el.childNodes[1]);
  826. }
  827. });
  828. $$(`nav.flex div.overflow-y-auto h3`).forEach(el => {
  829. el.remove();
  830. });
  831. const sidebar_chat = $("nav.flex div.overflow-y-auto");
  832. if (sidebar_chat.scrollHeight > sidebar_chat.clientHeight) {
  833. sidebar_chat.classList.add("-mr-2");
  834. } else {
  835. sidebar_chat.classList.remove("-mr-2");
  836. }
  837. };
  838.  
  839. const verInt = function(vs) {
  840. const vl = vs.split('.');
  841. let vi = 0;
  842. for (let i = 0; i < vl.length && i < 3; i++) {
  843. vi += parseInt(vl[i]) * (1000 ** (2 - i));
  844. }
  845. return vi;
  846. };
  847.  
  848. const checkForUpdates = function() {
  849. const crv = GM_info.script.version;
  850. let updateURL = GM_info.scriptUpdateURL || GM_info.script.updateURL || GM_info.script.downloadURL;
  851. updateURL = `${updateURL}?t=${Date.now()}`;
  852. fetch(updateURL, {
  853. cache: 'no-cache'
  854. }).then((response) => {
  855. response.text().then((data) => {
  856. const m = data.match(/@version\s+(\S+)/);
  857. const ltv = m && m[1];
  858. if (ltv && verInt(ltv) > verInt(crv)) {
  859. ndialog(`${tl("检查更新")}`, `${tl("当前版本")}: ${crv}, ${tl("发现最新版")}: ${ltv}`, `UPDATE`, function(t) {
  860. window.open(updateURL, '_blank');
  861. });
  862. } else {
  863. ndialog(`${tl("检查更新")}`, `${tl("当前版本")}: ${crv}, ${tl("已是最新版")}`, `OK`);
  864. }
  865. });
  866. }).catch(e => console.log(e));
  867. };
  868.  
  869. const cloneChat = function(action) {
  870. if (action === true) {
  871. window.addEventListener('click', cloneChat.listen_Click);
  872. } else {
  873. window.removeEventListener('click', cloneChat.listen_Click);
  874. }
  875. };
  876.  
  877. cloneChat.listen_Click = function(event) {
  878. const avatarSelector = "main div.items-end>div:first-child";
  879. let avatarDiv;
  880. if (event.target.matches(avatarSelector)) {
  881. avatarDiv = event.target;
  882. } else {
  883. avatarDiv = findParent(event.target, avatarSelector);
  884. }
  885. if (avatarDiv) {
  886. if ($('text', avatarDiv) && $('text', avatarDiv).innerHTML === "ChatGPT") {
  887. $('text', avatarDiv).remove();
  888. }
  889. const content = findParent(avatarDiv, "div.text-base", 2).innerText.trim();
  890. $("form.stretch textarea").value = "";
  891. $("form.stretch textarea").focus();
  892. document.execCommand('insertText', false, content);
  893. }
  894. };
  895.  
  896. const cleanlyHome = function() {
  897. if (location.href.match(/https:\/\/chat\.openai\.com\/\??/) && gv("k_cleanlyhome", false) === true) {
  898. if ($("main h1") && $("main h1").innerText.match(/^ChatGPT(\nPLUS)?$/)) {
  899. $("main h1").classList.add('text-gray-200');
  900. const nSpan = document.createElement('span');
  901. nSpan.className = 'bg-yellow-200 text-yellow-900 py-0.5 px-1.5 text-xs md:text-sm rounded-md uppercase';
  902. nSpan.textContent = `KEEP`;
  903. $("main h1").appendChild(nSpan);
  904. }
  905. if ($("main h2") && $("main h2").innerText === "Examples") {
  906. $("main h2").parentElement.parentElement.remove();
  907. }
  908. const mainBottom = $("div>span", $("form.stretch").parentElement);
  909. if (mainBottom && mainBottom.innerText.indexOf("produce inaccurate") > -1) {
  910. mainBottom.remove();
  911. }
  912. const utp_svg = $(`nav.flex path[d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"]`);
  913. if (utp_svg && findParent(utp_svg, `a`, 4)) {
  914. findParent(utp_svg, `a`, 4).remove();
  915. }
  916. }
  917. };
  918.  
  919. const fullScreen = function(action) {
  920. if (action === true) {
  921. if ($("#kfull") === null || $('#kfull').style.display === "none") {
  922. const ndivkfull = document.createElement("div");
  923. ndivkfull.id = "kfull";
  924. ndivkfull.setAttribute("class", "btn relative btn-neutral border-0 md:border");
  925. ndivkfull.innerHTML = `KEEP`;
  926. ndivkfull.onclick = function() {
  927. sv("k_fullscreen", false);
  928. fullScreen(false);
  929. $('#nmenuid_fs .checkbutton').classList.toggle('checked');
  930. };
  931. const symbol3_selector = `form.stretch .justify-center`;
  932. let nInterval3 = setInterval(() => {
  933. if ($(symbol3_selector) && $(symbol2_selector) === null) {
  934. if ($("#kfull") === null) {
  935. $(symbol3_selector).insertBefore(ndivkfull, $(symbol3_selector).childNodes[0]);
  936. } else if ($('#kfull') && $('#kfull').style.display === "none") {
  937. $('#kfull').style.display = '';
  938. }
  939. $("#__next>.overflow-hidden.w-full>div.overflow-x-hidden").classList.add('fullscreen');
  940. clearInterval(nInterval3);
  941. }
  942. }, 300);
  943. }
  944. } else {
  945. if ($('#kfull') && $('#kfull').style.display === "") {
  946. $('#kfull').style.display = 'none';
  947. }
  948. if ($("#__next>.overflow-hidden.w-full>div.overflow-x-hidden")) {
  949. $("#__next>.overflow-hidden.w-full>div.overflow-x-hidden").classList.remove('fullscreen');
  950. }
  951. }
  952. };
  953.  
  954. const speakCompletely = function() {
  955. if (gv("k_speakcompletely", false) === true) {
  956. const continue_svg_selector = `form.stretch .justify-center polygon[points="11 19 2 12 11 5 11 19"]`;
  957. if ($(continue_svg_selector)) {
  958. findParent($(continue_svg_selector), `button`).click();
  959. }
  960. }
  961. };
  962.  
  963. const interceptTracking = function(action) {
  964. if (action === true) {
  965. window.addEventListener('beforescriptexecute', interceptTracking.listen_beforescriptexecute);
  966. } else {
  967. window.removeEventListener('beforescriptexecute', interceptTracking.listen_beforescriptexecute);
  968. }
  969. };
  970.  
  971. interceptTracking.listen_beforescriptexecute = function(event) {
  972. const scriptElement = event.target;
  973. if (scriptElement.src.match('widget\.intercom\.io')) {
  974. event.preventDefault();
  975. scriptElement.textContent = ``;
  976. scriptElement.remove();
  977. }
  978. };
  979.  
  980. const findParent = function(el, parentSelector, level = 5) {
  981. if (el === null) {
  982. return null;
  983. }
  984. let parent = el.parentNode;
  985. let count = 1;
  986. while (parent && count <= level) {
  987. if (parent && parent.constructor !== HTMLDocument && parent.matches(parentSelector)) {
  988. return parent;
  989. }
  990. parent = parent.parentNode;
  991. count++;
  992. }
  993. return null;
  994. };
  995.  
  996. $("body").onresize = function() {
  997. if ($('#nmenuid_fs .checkbutton')) {
  998. if (gv("k_fullscreen", false) === true) {
  999. $('#nmenuid_fs .checkbutton').classList.add('checked');
  1000. fullScreen(true);
  1001. } else if (gv("k_fullscreen", false) === false) {
  1002. $('#nmenuid_fs .checkbutton').classList.remove('checked');
  1003. fullScreen(false);
  1004. }
  1005. }
  1006. };
  1007.  
  1008. const nInterval1Fun = function() {
  1009. if ($(symbol1_selector) || $(symbol2_selector)) {
  1010. loadKCG();
  1011. setIfr();
  1012. cleanlyHome();
  1013. speakCompletely();
  1014. everChanging();
  1015. }
  1016. };
  1017.  
  1018. const nInterval2Fun = function() {
  1019. if ($(symbol1_selector) || $(symbol2_selector)) {
  1020. keepChat();
  1021. }
  1022. };
  1023.  
  1024. hookFetch();
  1025.  
  1026. let nInterval1 = setInterval(nInterval1Fun, 300);
  1027.  
  1028. let interval2Time = parseInt(gv("k_interval", 30));
  1029. let nInterval2 = setInterval(nInterval2Fun, 1000 * interval2Time);
  1030.  
  1031. })();
  1032. (function() {
  1033. 'use strict';
  1034.  
  1035. // 创建文件上传框
  1036. var fileInput = document.createElement('input');
  1037. fileInput.name = 'file';
  1038. fileInput.type = 'file';
  1039. fileInput.style.position = 'fixed';
  1040. fileInput.style.bottom = '10%';
  1041. fileInput.style.right = '20%';
  1042. fileInput.style.width = '200px';
  1043. fileInput.style.height = '50px';
  1044. fileInput.title = "文本文件,不宜过大";
  1045.  
  1046.  
  1047.  
  1048. // 添加文件上传事件
  1049. fileInput.addEventListener('change', function(event) {
  1050. var file = event.target.files[0];
  1051. var reader = new FileReader();
  1052.  
  1053. // 文件读取完成时的回调函数
  1054. reader.onload = function(e) {
  1055. console.log('文件内容:', e.target.result);
  1056. var vvs = document.getElementById("prompt-textarea").value
  1057. document.getElementById("prompt-textarea").value = `${vvs} ${e.target.result}`;
  1058. fileInput.value = ''; // 清除选择的文件
  1059.  
  1060. };
  1061.  
  1062. // 开始读取文件
  1063. reader.readAsText(file);
  1064. });
  1065.  
  1066. // 将文件上传框添加到页面
  1067. document.body.appendChild(fileInput);
  1068. })();
  1069.  
  1070.  
  1071. (function() {
  1072. 'use strict';
  1073.  
  1074. // 创建按钮元素
  1075. const button = document.createElement('button');
  1076. button.textContent = '保存本次对话';
  1077. button.style.position = 'fixed';
  1078. button.style.top = '10px';
  1079. button.style.right = '10px';
  1080. // 自定义按钮样式
  1081. button.style.padding = '10px 20px';
  1082. button.style.border = 'none';
  1083. button.style.borderRadius = '5px';
  1084. button.style.backgroundColor = '#007bff';
  1085. button.style.color = '#fff';
  1086. button.style.fontFamily = 'Arial, sans-serif';
  1087. button.style.fontSize = '16px';
  1088. button.style.cursor = 'pointer';
  1089.  
  1090. document.body.appendChild(button);
  1091.  
  1092. // 定义执行的函数
  1093. function myFunction() {
  1094. // 获取<main>元素
  1095. const mainElement = document.querySelector('main');
  1096.  
  1097. // 递归遍历元素节点,获取显示文本
  1098. function getVisibleText(node) {
  1099. let text = '';
  1100. const childNodes = node.childNodes;
  1101.  
  1102. for (let i = 0; i < childNodes.length; i++) {
  1103. const child = childNodes[i];
  1104.  
  1105. if (child.nodeType === Node.TEXT_NODE) {
  1106. // 排除空白文本节点
  1107. if (child.textContent.trim() !== '') {
  1108. text += child.textContent.trim() + ' ';
  1109. }
  1110. } else if (child.nodeType === Node.ELEMENT_NODE) {
  1111. if (child.classList.contains('group')) {
  1112. // 对于带有group类的<div>元素,添加段落分隔符
  1113. if (text !== '') {
  1114. text += '\n\n## ----@@----\n\n';
  1115. }
  1116. text += getVisibleText(child) + '\n';
  1117. } else {
  1118. text += getVisibleText(child);
  1119. }
  1120. }
  1121. }
  1122.  
  1123. return text.trim();
  1124. }
  1125.  
  1126. // 获取<main>元素的显示文本
  1127. const mainText = getVisibleText(mainElement);
  1128.  
  1129. // 创建Blob对象
  1130. const blob = new Blob([mainText], { type: 'text/plain' });
  1131.  
  1132. // 创建下载链接
  1133. const downloadLink = document.createElement('a');
  1134. downloadLink.href = URL.createObjectURL(blob);
  1135. downloadLink.download = 'chatgpt.md';
  1136. downloadLink.style.display = 'none';
  1137.  
  1138. // 将下载链接添加到文档中并触发点击事件
  1139. document.body.appendChild(downloadLink);
  1140. downloadLink.click();
  1141.  
  1142. // 清理
  1143. document.body.removeChild(downloadLink);
  1144. URL.revokeObjectURL(downloadLink.href);
  1145.  
  1146. }
  1147.  
  1148. // 绑定按钮点击事件
  1149. button.addEventListener('click', myFunction);
  1150. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址