私のプロンプト

ワンクリックで簡単かつスピーディーにプロンプトを保存・使用!ChatGPT、DeepSeek、Gemini、Claude、Kimi、Qwen、LMArena、Z.ai、Google AI Studio に対応しています。

スクリプトをインストール?
作者が勧める他のスクリプト

CodeDownも気に入るかもしれません

スクリプトをインストール
このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name                My Prompt
// @name:pt-BR          Meu Prompt
// @name:zh-CN          我的提示
// @name:zh-TW          我的提示詞
// @name:en             My Prompt
// @name:es             Mi Prompt
// @name:ja             私のプロンプト
// @name:ko             나의 프롬프트
// @name:de             Mein Prompt
// @name:fr             Mon Prompt
// @namespace           https://github.com/0H4S
// @version             1.8
// @description         Save and use your prompts quickly and easily with just one click! Compatible with ChatGPT, DeepSeek, Gemini, Claude, Kimi, Qwen, LMArena, Z.ai, and Google AI Studio.
// @description:pt-BR   Salve e use seus prompts de forma rápida e fácil com apenas um clique! Compatível com ChatGPT, DeepSeek, Gemini, Claude, Kimi, Qwen, LMArena, Z.ai e Google AI Studio.
// @description:zh-CN   只需一键即可快速轻松地保存和使用您的提示!兼容 ChatGPT、DeepSeek、Gemini、Claude、Kimi、Qwen、LMArena、Z.ai 和 Google AI Studio。
// @description:zh-TW   只需一鍵即可快速輕鬆地儲存並使用您的提示!相容於 ChatGPT、DeepSeek、Gemini、Claude、Kimi、Qwen、LMArena、Z.ai 和 Google AI Studio。
// @description:en      Save and use your prompts quickly and easily with just one click! Compatible with ChatGPT, DeepSeek, Gemini, Claude, Kimi, Qwen, LMArena, Z.ai, and Google AI Studio.
// @description:es      ¡Guarda y usa tus prompts de forma rápida y sencilla con un solo clic! Compatible con ChatGPT, DeepSeek, Gemini, Claude, Kimi, Qwen, LMArena, Z.ai y Google AI Studio.
// @description:ja      ワンクリックで簡単かつスピーディーにプロンプトを保存・使用!ChatGPT、DeepSeek、Gemini、Claude、Kimi、Qwen、LMArena、Z.ai、Google AI Studio に対応しています。
// @description:ko      클릭 한 번으로 프롬프트를 빠르고 쉽게 저장하고 사용할 수 있습니다! ChatGPT, DeepSeek, Gemini, Claude, Kimi, Qwen, LMArena, Z.ai 및 Google AI Studio와 호환됩니다.
// @description:de      Speichern und verwenden Sie Ihre Prompts schnell und einfach mit nur einem Klick! Kompatibel mit ChatGPT, DeepSeek, Gemini, Claude, Kimi, Qwen, LMArena, Z.ai und Google AI Studio.
// @description:fr      Enregistrez et utilisez vos prompts rapidement et facilement en un seul clic ! Compatible avec ChatGPT, DeepSeek, Gemini, Claude, Kimi, Qwen, LMArena, Z.ai et Google AI Studio.
// @author              OHAS
// @homepage            https://github.com/0H4S
// @icon                https://cdn-icons-png.flaticon.com/512/4997/4997543.png
// @license             CC-BY-NC-ND-4.0
// @copyright           2025 OHAS. All Rights Reserved.
// @match               https://aistudio.google.com/*
// @match               https://gemini.google.com/*
// @match               https://chat.deepseek.com/*
// @match               https://www.kimi.com/*
// @match               https://chat.qwen.ai/*
// @match               https://chatgpt.com/*
// @match               https://lmarena.ai/*
// @match               https://chat.z.ai/*
// @match               https://claude.ai/*
// @require             https://update.greasyfork.org/scripts/549920.js
// @connect             gist.github.com
// @grant               GM_getValue
// @grant               GM_setValue
// @grant               GM_xmlhttpRequest
// @grant               GM_registerMenuCommand
// @run-at              document-end
// @noframes
// @compatible          chrome
// @compatible          firefox
// @compatible          edge
// @compatible          opera
// @bgf-colorLT         #847dfd
// @bgf-colorDT         #6963ca
// @bgf-compatible      brave
// @bgf-copyright       [2025 OHAS. All Rights Reserved.](https://gist.github.com/0H4S/ae2fa82957a089576367e364cbf02438)
// @bgf-social          https://github.com/0H4S
// @contributionURL     https://linktr.ee/0H4S
// ==/UserScript==

(function() {
    'use strict';
    // #region GLOBAL
    const translations = {
        'en': {
            langName:           'English',
            prompt:             'Prompt',
            prompts:            'Prompts',
            newPrompt:          'New Prompt',
            editPrompt:         'Edit Prompt',
            title:              'Title',
            text:               'Prompt',
            save:               'Save',
            close:              'Close',
            edit:               'Edit',
            delete:             'Delete',
            noSavedPrompts:     'No saved prompts.',
            addPrompt:          'Add prompt',
            import:             'Import',
            export:             'Export',
            confirmDelete:      'Delete prompt "{title}"?',
            noPromptsToExport:  'No prompts to export.',
            promptsImported:    '{count} prompts imported successfully!',
            errorImporting:     'Error importing file: {error}',
            requiredFields:     'Title and prompt are required.',
            editorNotFound:     'Could not find the text area for {platform}.',
            languageSettings:   '🌐 Language',
            fillPlaceholders:   'Fill in the Information',
            insert:             'Insert',
            enablePlaceholders: 'Enable interactive information: [...]',
            fileName:           'My_Prompts.json'
        },
        'pt-BR': {
            langName:           'Português (BR)',
            prompt:             'Prompt',
            prompts:            'Prompts',
            newPrompt:          'Novo Prompt',
            editPrompt:         'Editar Prompt',
            title:              'Título',
            text:               'Prompt',
            save:               'Salvar',
            close:              'Fechar',
            edit:               'Editar',
            delete:             'Excluir',
            noSavedPrompts:     'Nenhum prompt salvo.',
            addPrompt:          'Adicionar prompt',
            import:             'Importar',
            export:             'Exportar',
            confirmDelete:      'Excluir prompt "{title}"?',
            noPromptsToExport:  'Não há prompts para exportar.',
            promptsImported:    '{count} prompts importados com sucesso!',
            errorImporting:     'Erro ao importar o arquivo: {error}',
            requiredFields:     'Título e prompt são obrigatórios.',
            editorNotFound:     'Não foi possível encontrar a área de texto para {platform}.',
            languageSettings:   '🌐 Idioma',
            fillPlaceholders:   'Preencha as Informações',
            insert:             'Inserir',
            enablePlaceholders: 'Ativar informações interativas: [...]',
            fileName:           'Meus_Prompts.json'
        },
        'es': {
            langName:           'Español',
            prompt:             'Prompt',
            prompts:            'Prompts',
            newPrompt:          'Nuevo Prompt',
            editPrompt:         'Editar Prompt',
            title:              'Título',
            text:               'Prompt',
            save:               'Guardar',
            close:              'Cerrar',
            edit:               'Editar',
            delete:             'Eliminar',
            noSavedPrompts:     'No hay prompts guardados.',
            addPrompt:          'Añadir prompt',
            import:             'Importar',
            export:             'Exportar',
            confirmDelete:      '¿Eliminar prompt "{title}"?',
            noPromptsToExport:  'No hay prompts para exportar.',
            promptsImported:    '¡{count} prompts importados con éxito!',
            errorImporting:     'Error al importar el archivo: {error}',
            requiredFields:     'El título y el prompt son obligatorios.',
            editorNotFound:     'No se pudo encontrar el área de texto para {platform}.',
            languageSettings:   '🌐 Idioma',
            fillPlaceholders:   'Rellene la Información',
            insert:             'Insertar',
            enablePlaceholders: 'Activar información interactiva: [...]',
            fileName:           'Mis_Prompts.json'
        },
        'zh-CN': {
            langName:           '简体中文',
            prompt:             '提示',
            prompts:            '提示',
            newPrompt:          '新建提示',
            editPrompt:         '编辑提示',
            title:              '标题',
            text:               '提示内容',
            save:               '保存',
            close:              '关闭',
            edit:               '编辑',
            delete:             '删除',
            noSavedPrompts:     '没有已保存的提示。',
            addPrompt:          '添加提示',
            import:             '导入',
            export:             '导出',
            confirmDelete:      '确定要删除提示 "{title}" 吗?',
            noPromptsToExport:  '沒有可導出的提示。',
            promptsImported:    '成功导入 {count} 个提示!',
            errorImporting:     '导入文件时出错: {error}',
            requiredFields:     '标题和提示内容为必填项。',
            editorNotFound:     '未能找到 {platform} 的文本输入区域。',
            languageSettings:   '🌐 语言',
            fillPlaceholders:   '填写信息',
            insert:             '插入',
            enablePlaceholders: '启用交互式信息: [...]',
            fileName:           '我的提示.json'
        },
        'ja': {
            langName:           '日本語',
            prompt:             'プロンプト',
            prompts:            'プロンプト',
            newPrompt:          '新規プロンプト',
            editPrompt:         'プロンプト編集',
            title:              'タイトル',
            text:               'プロンプト',
            save:               '保存',
            close:              '閉じる',
            edit:               '編集',
            delete:             '削除',
            noSavedPrompts:     '保存されたプロンプトはありません',
            addPrompt:          'プロンプトを追加',
            import:             'インポート',
            export:             'エクスポート',
            confirmDelete:      'プロンプト「{title}」を削除しますか?',
            noPromptsToExport:  'エクスポートするプロンプトがありません',
            promptsImported:    '{count}件のプロンプトをインポートしました',
            errorImporting:     'ファイルのインポート中にエラーが発生しました: {error}',
            requiredFields:     'タイトルとプロンプトは必須です',
            editorNotFound:     '{platform}のテキストエリアが見つかりません',
            languageSettings:   '🌐 言語設定',
            fillPlaceholders:   '情報を入力',
            insert:             '挿入',
            enablePlaceholders: 'インタラクティブな情報を有効にする: [...]',
            fileName:           'マイプロンプト.json'
        },
        'ko': {
            langName:           '한국어',
            prompt:             '프롬프트',
            prompts:            '프롬프트',
            newPrompt:          '새 프롬프트',
            editPrompt:         '프롬프트 편집',
            title:              '제목',
            text:               '프롬프트',
            save:               '저장',
            close:              '닫기',
            edit:               '편집',
            delete:             '삭제',
            noSavedPrompts:     '저장된 프롬프트가 없습니다',
            addPrompt:          '프롬프트 추가',
            import:             '가져오기',
            export:             '내보내기',
            confirmDelete:      '프롬프트 "{title}"을(를) 삭제하시겠습니까?',
            noPromptsToExport:  '내보낼 프롬프트가 없습니다',
            promptsImported:    '프롬프트 {count}개를 성공적으로 가져왔습니다',
            errorImporting:     '파일 가져오기 오류: {error}',
            requiredFields:     '제목과 프롬프트는 필수 항목입니다',
            editorNotFound:     '{platform}의 텍스트 영역을 찾을 수 없습니다',
            languageSettings:   '🌐 언어 설정',
            fillPlaceholders:   '정보 채우기',
            insert:             '삽입',
            enablePlaceholders: '대화형 정보 활성화: [...]',
            fileName:           '내_프롬프트.json'
        }
    };
    const LANG_STORAGE_KEY = 'UserScriptLang';
    let currentLang = 'en';

    const SCRIPT_CONFIG = {
        notificationsUrl:   'https://gist.github.com/0H4S/b2f9a9f92259deadc35bdccb11cd9a75',
        scriptVersion:      '1.8',
    };
    const notifier = new ScriptNotifier(SCRIPT_CONFIG);
    notifier.run();

    const PROMPT_STORAGE_KEY = 'Prompts';
    let isInitialized   = false;
    let isInitializing  = false;
    let currentButton   = null;
    let currentPlatform = null;
    let pageObserver    = null;
    let currentMenu     = null;
    let currentModal    = null;
    let languageModal   = null;
    let currentPlaceholderModal = null;

    const scriptPolicy = window.trustedTypes
        ? window.trustedTypes.createPolicy('MyPromptPolicy', { createHTML: (input) => input })
        : null;

    function setSafeInnerHTML(element, html) {
        if (!element) return;
        if (scriptPolicy) {
            element.innerHTML = scriptPolicy.createHTML(html);
        } else {
            element.innerHTML = html;
        }
    }

    function getTranslation(key, replacements = {}) {
        let text = translations[currentLang]?.[key] || translations.en[key];
        Object.entries(replacements).forEach(([p, v]) => text = text.replace(`{${p}}`, v));
        return text;
    }

    async function determineLanguage() {
        const savedLang = await GM_getValue(LANG_STORAGE_KEY);
        if (savedLang && translations[savedLang]) {
            currentLang = savedLang;
            return;
        }
        const browserLang = (navigator.language || navigator.userLanguage).toLowerCase();
        if      (browserLang.startsWith('pt')) currentLang = 'pt-BR';
        else if (browserLang.startsWith('zh')) currentLang = 'zh-CN';
        else if (browserLang.startsWith('en')) currentLang = 'en';
        else if (browserLang.startsWith('es')) currentLang = 'es';
        else if (browserLang.startsWith('ja')) currentLang = 'ja';
        else if (browserLang.startsWith('ko')) currentLang = 'ko';
        else currentLang = 'en';
    }

    function waitFor(selector, timeout = 8000) {
        return new Promise((resolve, reject) => {
            const el = document.querySelector(selector);
            if (el) { resolve(el); return; }
            const timer = setTimeout(() => { obs.disconnect(); reject(`Timeout esperando por ${selector}`); }, timeout);
            const obs = new MutationObserver(() => {
                const target = document.querySelector(selector);
                if (target) { clearTimeout(timer); obs.disconnect(); resolve(target); }
            });
            if (document.body) obs.observe(document.body, { childList: true, subtree: true });
            else document.addEventListener('DOMContentLoaded', () => obs.observe(document.body, { childList: true, subtree: true }));
        });
    }

    const debounce = (func, wait) => {
        let timeout;
        return (...args) => {
            clearTimeout(timeout);
            timeout = setTimeout(() => func.apply(this, args), wait);
        };
    };

    async function getAll() { return await GM_getValue(PROMPT_STORAGE_KEY, []); }

    async function addItem(item) {
        const prompts = await getAll();
        prompts.unshift(item);
        await GM_setValue(PROMPT_STORAGE_KEY, prompts);
    }

    async function update(index, item) {
        let prompts = await getAll();
        if (prompts[index]) {
            prompts[index] = item;
            await GM_setValue(PROMPT_STORAGE_KEY, prompts);
        }
    }

    async function remove(index) {
        let prompts = await getAll();
        prompts.splice(index, 1);
        await GM_setValue(PROMPT_STORAGE_KEY, prompts);
    }

    function createCustomTooltip(button, text, position = 'top') {
        let tooltipElement = null;
		const showTooltip = () => {
		  if (tooltipElement) return;
		  tooltipElement = document.createElement('div');
          tooltipElement.className = 'mp-tooltip';
		  tooltipElement.textContent = text;
		  document.body.appendChild(tooltipElement);
		  const btnRect = button.getBoundingClientRect();
		  const tooltipRect = tooltipElement.getBoundingClientRect();
		  let top;
		  const margin = 8;
		  if (position === 'bottom') {
			top = btnRect.bottom + margin;
			if (top + tooltipRect.height > window.innerHeight) {
			  top = btnRect.top - tooltipRect.height - margin;
			}
		  } else {
			top = btnRect.top - tooltipRect.height - margin;
			if (top < 0) {
			  top = btnRect.bottom + margin;
			}
		  }
		  let left = btnRect.left + (btnRect.width / 2) - (tooltipRect.width / 2);
		  if (left < 0) { left = margin; }
		  if (left + tooltipRect.width > window.innerWidth) { left = window.innerWidth - tooltipRect.width - margin; }
		  tooltipElement.style.left = `${left}px`;
		  tooltipElement.style.top = `${top}px`;
          requestAnimationFrame(() => {
			tooltipElement.classList.add('visible');
		  });
		};
		const hideTooltip = () => {
		  if (!tooltipElement) return;
		  const el = tooltipElement;
		  tooltipElement = null;
		  el.classList.remove('visible');
		  setTimeout(() => {
			if (document.body.contains(el)) {
			  document.body.removeChild(el);
			}
		  }, 150);
		};
		button.addEventListener('mouseenter',   showTooltip);
		button.addEventListener('mouseleave',   hideTooltip);
		button.addEventListener('mousedown',    hideTooltip);
    }

    function injectGlobalStyles() {
        const styleId='my-prompt-styles';
        if (document.getElementById(styleId)) return;
        const styleElement=document.createElement('style');
        styleElement.id=styleId;
        setSafeInnerHTML(styleElement, ` @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
            :root {
                --mp-font-family-base: 'Inter', sans-serif;
                --mp-bg-primary: #fff;
                --mp-bg-secondary: #f8f9fa;
                --mp-bg-tertiary: #f1f3f5;
                --mp-bg-overlay: rgba(10, 10, 10, .5);
                --mp-text-primary: #212529;
                --mp-text-secondary: #495057;
                --mp-text-tertiary: #868e96;
                --mp-border-primary: #dee2e6;
                --mp-border-secondary: #ced4da;
                --mp-accent-primary: #7071fc;
                --mp-accent-primary-hover: #595ac9;
                --mp-accent-yellow: #fab005;
                --mp-accent-yellow-hover: #f08c00;
                --mp-accent-red: #f03e3e;
                --mp-accent-red-hover: #c92a2a;
                --mp-shadow-sm: 0 1px 2px rgba(0, 0, 0, .04);
                --mp-shadow-md: 0 4px 12px rgba(0, 0, 0, .1);
                --mp-shadow-lg: 0 10px 30px rgba(0, 0, 0, .1);
                --mp-border-radius-sm: 4px;
                --mp-border-radius-md: 8px;
                --mp-border-radius-lg: 16px;
                --mp-transition-fast: .2s cubic-bezier(.25, 1, .5, 1)
            }

            @media (prefers-color-scheme:dark) {
                :root {
                    --mp-bg-primary: #212529;
                    --mp-bg-secondary: #2c2c30;
                    --mp-bg-tertiary: #343a40;
                    --mp-bg-overlay: rgba(0, 0, 0, .6);
                    --mp-text-primary: #f8f9fa;
                    --mp-text-secondary: #e9ecef;
                    --mp-text-tertiary: #adb5bd;
                    --mp-border-primary: #495057;
                    --mp-border-secondary: #868e96;
                    --mp-shadow-sm: 0 1px 2px rgba(0, 0, 0, .15);
                    --mp-shadow-md: 0 4px 12px rgba(0, 0, 0, .25);
                    --mp-shadow-lg: 0 10px 30px rgba(0, 0, 0, .3)
                }
            }

            .mp-hidden {
                display: none !important;
            }

            .mp-overlay {
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background-color: var(--mp-bg-overlay);
                z-index: 2147483647;
                display: flex;
                justify-content: center;
                align-items: center;
                backdrop-filter: blur(4px);
                opacity: 0;
                visibility: hidden;
                transition: opacity var(--mp-transition-fast), visibility var(--mp-transition-fast);
            }

            .mp-overlay.visible {
                opacity: 1;
                visibility: visible;
            }

            .mp-modal-box {
                font-family: var(--mp-font-family-base);
                background-color: var(--mp-bg-primary);
                color: var(--mp-text-primary);
                border-radius: var(--mp-border-radius-lg);
                padding: 24px;
                box-shadow: var(--mp-shadow-lg);
                width: min(90vw, 520px);
                border: 1px solid var(--mp-border-primary);
                transform: scale(.95) translateY(10px);
                opacity: 0;
                transition: transform var(--mp-transition-fast), opacity var(--mp-transition-fast);
                position: relative;
            }

            .mp-overlay.visible .mp-modal-box {
                transform: scale(1) translateY(0);
                opacity: 1;
            }

            .mp-modal-close-btn {
                position: absolute;
                top: 12px;
                right: 12px;
                background: none;
                border: none;
                color: var(--mp-text-tertiary);
                font-size: 22px;
                cursor: pointer;
                width: 32px;
                height: 32px;
                border-radius: 50%;
                transition: transform .3s ease, color .3s ease, background-color .3s ease;
                display: flex;
                justify-content: center;
                align-items: center;
                line-height: 1;
            }

            .mp-modal-close-btn:hover {
                transform: rotate(90deg);
                color: var(--mp-accent-red);
                background-color: color-mix(in srgb, var(--mp-accent-red) 15%, transparent);
            }

            .prompt-menu {
                position: fixed;
                min-width: 320px;
                max-width: 420px;
                background-color: var(--mp-bg-primary);
                border: 1px solid var(--mp-border-primary);
                border-radius: var(--mp-border-radius-lg);
                box-shadow: var(--mp-shadow-lg);
                z-index: 2147483647;
                display: flex;
                flex-direction: column;
                user-select: none;
                color: var(--mp-text-primary);
                font-family: var(--mp-font-family-base);
                overflow: hidden;
                opacity: 0;
                visibility: hidden;
                transform: scale(.95);
                transform-origin: top left;
                transition: opacity .2s ease, transform .2s ease, visibility 0s linear .2s;
            }

            .prompt-menu.visible {
                opacity: 1;
                visibility: visible;
                transform: scale(1);
                transition-delay: 0s;
            }

            .prompt-menu-list {
                max-height: 220px;
                overflow-y: auto;
                padding: 4px;
            }

            .prompt-item-row {
                display: flex;
                align-items: center;
                justify-content: space-between;
                padding: 8px 12px;
                border-radius: var(--mp-border-radius-md);
                cursor: pointer;
                transition: background-color .15s ease-in-out;
            }

            .prompt-item-row:hover {
                background-color: var(--mp-bg-tertiary);
            }

            .prompt-title {
                font-size: 14px;
                font-weight: 500;
                flex: 1;
                padding-right: 12px;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
                color: var(--mp-text-secondary);
            }

            .prompt-item-row:hover .prompt-title {
                color: var(--mp-text-primary);
            }

            .prompt-actions {
                display: flex;
                align-items: center;
                gap: 4px;
            }

            .action-btn {
                background: 0 0;
                border: none;
                cursor: pointer;
                font-size: 13px;
                font-weight: 500;
                padding: 4px 8px;
                border-radius: var(--mp-border-radius-sm);
                transition: background-color .15s ease-in-out, color .15s ease-in-out;
                font-family: var(--mp-font-family-base);
            }

            .action-btn.edit {
                color: var(--mp-accent-yellow);
            }

            .action-btn.edit:hover {
                background-color: var(--mp-accent-yellow);
                color: var(--mp-bg-primary);
            }

            .action-btn.delete {
                color: var(--mp-accent-red);
            }

            .action-btn.delete:hover {
                background-color: var(--mp-accent-red);
                color: var(--mp-bg-primary);
            }

            .menu-footer,
            .menu-section {
                border-top: 1px solid var(--mp-border-primary);
                padding: 4px;
            }

            .menu-button {
                display: flex;
                align-items: center;
                justify-content: center;
                padding: 8px 12px;
                cursor: pointer;
                transition: background-color .15s ease-in-out;
                color: var(--mp-text-secondary);
                border-radius: var(--mp-border-radius-md);
                font-size: 14px;
                font-weight: 500;
            }

            .menu-button:hover {
                background-color: var(--mp-bg-tertiary);
                color: var(--mp-text-primary);
            }

            .menu-button svg {
                margin-right: 8px;
            }

            .import-export-container {
                display: flex;
            }

            .import-export-container .menu-button {
                flex: 1;
            }

            .divider {
                border-left: 1px solid var(--mp-border-primary);
                height: 24px;
                align-self: center;
            }

            .empty-state {
                padding: 24px 16px;
                text-align: center;
                color: var(--mp-text-tertiary);
                font-size: 14px;
            }

            .form-group {
                display: flex;
                flex-direction: column;
                margin-bottom: 16px;
            }

            .form-label {
                margin-bottom: 6px;
                font-size: 13px;
                font-weight: 500;
                color: var(--mp-text-secondary);
            }

            .form-input {
                background-color: var(--mp-bg-secondary);
                color: var(--mp-text-primary);
                border: 1px solid var(--mp-border-primary) !important;
                border-radius: var(--mp-border-radius-md);
                padding: 10px;
                width: 100%;
                box-sizing: border-box;
                transition: border-color .2s, box-shadow .2s;
                outline: 0 !important;
                font-family: var(--mp-font-family-base);
                font-size: 14px
            }

            .form-textarea {
                background-color: var(--mp-bg-secondary);
                color: var(--mp-text-primary);
                border: 1px solid var(--mp-border-primary) !important;
                border-radius: var(--mp-border-radius-md);
                padding: 10px;
                width: 100%;
                box-sizing: border-box;
                outline: 0 !important;
                font-family: var(--mp-font-family-base);
                font-size: 14px;
                height: 140px;
                resize: vertical;
                transition: border-color .2s, box-shadow .2s;
            }

            .form-input:focus,
            .form-textarea:focus {
                border-color: var(--mp-accent-primary) !important;
                box-shadow: 0 0 0 3px color-mix(in srgb, var(--mp-accent-primary) 25%, transparent) !important;
            }

            .modal-title {
                font-size: 18px;
                font-weight: 600;
                margin: 0 0 24px;
                text-align: center;
                color: var(--mp-text-primary);
            }

            .modal-footer {
                display: flex;
                justify-content: flex-end;
            }

            .save-button {
                padding: 10px 28px;
                border-radius: var(--mp-border-radius-md);
                background-color: var(--mp-accent-primary);
                color: #fff;
                border: none;
                font-weight: 600;
                cursor: pointer;
                transition: all .2s ease-in-out;
                font-family: var(--mp-font-family-base);
            }

            .save-button:hover {
                background-color: var(--mp-accent-primary-hover);
                transform: translateY(-1px);
            }

            .lang-box {
                width: min(90vw, 320px);
            }

            .lang-buttons-container {
                display: flex;
                flex-direction: column;
                gap: 12px;
            }

            #__ap_placeholders_container {
                max-height: 350px;
                overflow-y: auto;
                padding-right: 12px;
                margin-right: -12px;
                scrollbar-width: thin;
                scrollbar-color: var(--mp-border-secondary) var(--mp-bg-tertiary);
            }

            #__ap_placeholders_container::-webkit-scrollbar {
                width: 10px !important;
                height: 10px !important;
            }

            #__ap_placeholders_container::-webkit-scrollbar-track {
                background-color: var(--mp-bg-tertiary) !important;
                border-radius: 10px !important;
                border: none !important;
            }

            #__ap_placeholders_container::-webkit-scrollbar-thumb {
                background-color: var(--mp-border-secondary) !important;
                border-radius: 10px !important;
                border: 2px solid var(--mp-bg-primary) !important;
            }

            #__ap_placeholders_container::-webkit-scrollbar-thumb:hover {
                background-color: var(--mp-text-tertiary) !important;
            }

            .form-checkbox-group {
                display: flex;
                align-items: center;
                gap: 10px;
                margin-top: -8px;
                margin-bottom: 20px;
            }

            .form-checkbox-group label {
                font-size: 13px;
                font-weight: 500;
                color: var(--mp-text-secondary);
                cursor: pointer;
                margin-bottom: 0;
            }

            .form-checkbox-group input[type="checkbox"] {
                cursor: pointer;
                width: 16px;
                height: 16px;
                accent-color: var(--mp-accent-primary);
            }

            @keyframes mp-fade-in-up {
                from {
                    opacity: 0;
                    transform: translateY(10px);
                }

                to {
                    opacity: 1;
                    transform: translateY(0);
                }
            }

            .lang-button {
                all: unset;
                box-sizing: border-box;
                display: block;
                width: 100%;
                padding: 12px 20px;
                border-radius: var(--mp-border-radius-md);
                background-color: var(--mp-bg-secondary);
                color: var(--mp-text-primary);
                border: 1px solid var(--mp-border-primary);
                font-weight: 500;
                cursor: pointer;
                text-align: center;
                opacity: 0;
                animation: mp-fade-in-up .4s ease forwards;
                transition: transform .2s ease, box-shadow .2s ease, background-color .2s ease;
                font-family: var(--mp-font-family-base);
            }

            .lang-button:hover {
                transform: translateY(-3px);
                box-shadow: var(--mp-shadow-md);
                background-color: var(--mp-bg-tertiary);
            }

            .lang-button:active {
                transform: translateY(0);
                transition-duration: .1s;
            }

            .prompt-menu-list {
                scrollbar-width: thin;
                scrollbar-color: var(--mp-border-secondary) var(--mp-bg-tertiary);
            }

            .prompt-menu-list::-webkit-scrollbar {
                width: 10px !important;
                height: 10px !important;
            }

            .prompt-menu-list::-webkit-scrollbar-track {
                background-color: var(--mp-bg-tertiary) !important;
                border-radius: 10px !important;
                border: none !important;
            }

            .prompt-menu-list::-webkit-scrollbar-thumb {
                background-color: var(--mp-border-secondary) !important;
                border-radius: 10px !important;
                border: 2px solid var(--mp-bg-primary) !important;
            }

            .prompt-menu-list::-webkit-scrollbar-thumb:hover {
                background-color: var(--mp-text-tertiary) !important;
            }

            .mp-tooltip {
                position: fixed;
                z-index: 2147483647;
                border-radius: var(--mp-border-radius-sm);
                padding: 6px 12px;
                pointer-events: none;
                white-space: nowrap;
                font-family: var(--mp-font-family-base);
                font-size: 14px;
                font-weight: 500;
                background-color: var(--mp-text-primary);
                color: var(--mp-bg-primary);
                box-shadow: var(--mp-shadow-md);
                border: 1px solid var(--mp-bg-tertiary);
                opacity: 0;
                transform: scale(0.95);
                transition: opacity 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1);
            }

            .mp-tooltip.visible {
                opacity: 1;
                transform: scale(1);
            }

        `);
        document.head.appendChild(styleElement);
    }
    // #endregion
    // #region CRIAR BOTÕES

    // CHATGPT
    function createChatGPTButton() {
        const btn = document.createElement('button');
        btn.type = 'button';
        btn.setAttribute('data-testid', 'composer-button-prompts');
        btn.className = 'composer-btn';
        setSafeInnerHTML(btn, `<svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path d="M4 5h12M4 10h12M4 15h12" stroke="currentColor" stroke-width="2"/></svg>`);
        createCustomTooltip(btn, getTranslation('prompts'));
        return btn;
    }

    // DEEPSEEK
    function createDeepSeekButton() {
        const btn = document.createElement('button');
        btn.setAttribute('data-testid', 'composer-button-prompts');
        setSafeInnerHTML(btn, `<div class="ds-icon" style="font-size: 17px; width: 17px; height: 17px; color: currentColor; margin-right: 6px;"><svg width="20" height="20" fill="currentColor" viewBox="0 0 20 20"><path d="M4 5h12M4 10h12M4 15h12" stroke="currentColor" stroke-width="2"/></svg></div><span><span class="_6dbc175">${getTranslation('prompt')}</span></span>`);
        return btn;
    }

    // GOOGLE AI STUDIO
    function createGoogleStudioButton() {
        const styleId = 'my-prompt-gstudio-hover-fix';
        if (!document.getElementById(styleId)) {
            const styleElement = document.createElement('style');
            styleElement.id = styleId;
            setSafeInnerHTML(styleElement, `
                button[data-testid="composer-button-prompts"]:hover {
                background-color: rgba(60, 64, 67, 0.08) !important;
                }
                @media (prefers-color-scheme: dark) {
                    button[data-testid="composer-button-prompts"]:hover {
                        background-color: rgba(232, 234, 237, 0.08) !important;
                    }
                }
            `);
            document.head.appendChild(styleElement);
        }
        const btn = document.createElement('button');
        btn.setAttribute('data-testid', 'composer-button-prompts');
        btn.type = 'button';
        btn.style.backgroundColor = 'transparent';
        btn.style.border = 'none';
        btn.style.boxShadow = 'none';
        btn.style.borderRadius = '50%';
        btn.style.width = '48px';
        btn.style.height = '48px';
        btn.style.padding = '0';
        btn.style.margin = '0';
        btn.style.cursor = 'pointer';
        btn.style.display = 'inline-flex';
        btn.style.alignItems = 'center';
        btn.style.justifyContent = 'center';
        btn.style.transition = 'background-color 150ms ease-in-out';
        setSafeInnerHTML(btn, `<svg fill="currentColor" style="width: 24px; height: 24px;" viewBox="0 0 100 100"><g><path d="M17.563,30.277h0.012c0,1.245,1.004,2.254,2.246,2.267v0.002h60.359v-0.001c1.248-0.006,2.259-1.018,2.259-2.268h0.01 l0-10.459h0c-0.002-1.251-1.017-2.265-2.269-2.265l0,0H19.821v0c0,0,0,0,0,0c-1.253,0-2.269,1.017-2.269,2.269 c0,0.039,0.01,0.076,0.012,0.115L17.563,30.277z"/><path d="M80.179,42.504L80.179,42.504H19.821v0c0,0,0,0,0,0c-1.253,0-2.269,1.017-2.269,2.269c0,0.039,0.01,0.076,0.012,0.115 l0,10.34h0.012c0,1.245,1.004,2.254,2.246,2.267v0.002h60.359v-0.001c1.248-0.006,2.259-1.018,2.259-2.268h0.01l0-10.459h0 C82.446,43.518,81.431,42.504,80.179,42.504z"/><path d="M80.179,67.454L80.179,67.454H19.821l0,0c0,0,0,0,0,0c-1.253,0-2.269,1.017-2.269,2.269c0,0.039,0.01,0.076,0.012,0.115 l0,10.34h0.012c0,1.245,1.004,2.254,2.246,2.267v0.002h60.359v-0.001c1.248-0.006,2.259-1.019,2.259-2.269h0.01l0-10.459h0 C82.446,68.468,81.431,67.454,80.179,67.454z"/></g></svg>`);
        createCustomTooltip(btn, getTranslation('prompts'));
        return btn;
    }

    // QWEN
    function createQwenButton() {
        const btn = document.createElement('button');
        btn.className = 'chat-input-feature-btn';
        btn.setAttribute('data-testid', 'composer-button-prompts');
        setSafeInnerHTML(btn, `<svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor" xmlns="http://www.w3.org/2000/svg" class="chat-input-feature-btn-icon" style="font-size: 16px;"><path d="M4 5h12M4 10h12M4 15h12" stroke="currentColor" stroke-width="2"/></svg><span class="chat-input-feature-btn-text">${getTranslation('prompt')}</span>`);
        return btn;
    }

    // Z.AI
    function createZaiButton() {
        const btnWrapper = document.createElement('div');
        setSafeInnerHTML(btnWrapper, `<button type="button" class="px-2 @xl:px-3 py-1.5 flex gap-1.5 items-center text-sm rounded-lg border transition-colors duration-300 focus:outline-hidden max-w-full overflow-hidden bg-transparent dark:text-gray-300 border-[#E5E5E5] dark:border-[#3C3E3F] hover:bg-black/5 dark:hover:bg-white/5"><svg class=" size-4" stroke-width="2" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9 17L3 12L9 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><path d="M15 17L21 12L15 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="hidden @sm:block whitespace-nowrap overflow-hidden text-ellipsis translate-y-[0.5px] mr-0.5">${getTranslation('prompt')}</span></button>`);
        const btn = btnWrapper.firstElementChild;
        btn.setAttribute('data-testid', 'composer-button-prompts');
        return btn;
    }

    // GEMINI
    function createGeminiButton() {
        const btn = document.createElement('button');
        btn.setAttribute('data-testid', 'composer-button-prompts');
        btn.className = 'mdc-icon-button mat-mdc-icon-button mat-mdc-button-base mat-primary mat-mdc-tooltip-trigger';
        const svgHTML = `<span class="mat-mdc-button-persistent-ripple mdc-icon-button__ripple"></span><span class="mat-icon notranslate" style="display: inline-flex; align-items: center; justify-content: center;"><svg style="width: 24px; height: 24px;" viewBox="0 0 20 20" fill="currentColor"><path d="M4 5h12M4 10h12M4 15h12" stroke="currentColor" stroke-width="2"></path></svg></span><span class="mat-focus-indicator"></span><span class="mat-mdc-button-touch-target"></span><span class="mat-ripple mat-mdc-button-ripple"></span>`;
        setSafeInnerHTML(btn, svgHTML);
        createCustomTooltip(btn, getTranslation('prompt'), 'bottom');
        return btn;
    }

    // LMARENA
    function createLmarenaButton() {
        const btn = document.createElement('button');
        btn.setAttribute('data-testid', 'composer-button-prompts');
        btn.className = 'inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ring-offset-2 focus-visible:ring-offset-surface-primary disabled:pointer-events-none disabled:opacity-50 text-interactive-active border border-border-faint bg-transparent hover:text-interactive-normal active:text-text-tertiary h-8 w-8 p-2 rounded-md active:scale-[0.96] active:transition-transform active:duration-75 transition-colors duration-150 ease-out hover:shadow-sm hover:bg-interactive-normal/10 hover:border-interactive-normal/10';
        btn.type = 'button';
        setSafeInnerHTML(btn, `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 20 20" fill="currentColor" class="w-4 h-4"><path d="M4 5h12M4 10h12M4 15h12" stroke="currentColor" stroke-width="2"/></svg>`);
        createCustomTooltip(btn, getTranslation('prompt'));
        return btn;
    }

    // KIMI
    function createKimiButton() {
        const referenceButton = document.querySelector('.deep-research-switch.normal');
        if (!referenceButton) {
            return null;
        }
        const btn = referenceButton.cloneNode(true);
        btn.setAttribute('data-testid', 'composer-button-prompts');
        const oldSvg = btn.querySelector('svg');
        const textSpan = btn.querySelector('span');
        const newSvgElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
        if (oldSvg) newSvgElement.setAttribute('class', oldSvg.getAttribute('class'));
        newSvgElement.setAttribute('width', '1em');
        newSvgElement.setAttribute('height', '1em');
        newSvgElement.setAttribute('viewBox', '0 0 20 20');
        newSvgElement.setAttribute('fill', 'currentColor');
        setSafeInnerHTML(newSvgElement, `<path d="M4 5h12M4 10h12M4 15h12" stroke="currentColor" stroke-width="2"/>`);
        if (oldSvg) {
            oldSvg.replaceWith(newSvgElement);
        }
        if (textSpan) {
            textSpan.textContent = getTranslation('prompt');
        }
        return btn;
    }

    // CLAUDE
    function createClaudeButton() {
        const wrapper = document.createElement('div');
        wrapper.className = 'relative shrink-0';
        const btnHTML = `<button class="border-0.5 transition-all h-8 min-w-8 rounded-lg flex items-center px-[7.5px] group !pointer-events-auto !outline-offset-1 text-text-300 border-border-300 hover:text-text-200/90 hover:bg-bg-100 active:scale-[0.98]" data-testid="composer-button-prompts" type="button"><div class="flex flex-row items-center justify-center gap-1"><div style="transform: none;"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 20 20"><path d="M4 5h12M4 10h12M4 15h12" stroke="currentColor" stroke-width="2"></path></svg></div></div></button>`;
        setSafeInnerHTML(wrapper, btnHTML);
        const btn = wrapper.querySelector('button');
        createCustomTooltip(btn, getTranslation('prompts'));
        return wrapper;
    }
    // #endregion
    // #region CRIAR MENU E MODAIS
    function createPromptMenu() {
        const menu = document.createElement('div');
        menu.className = 'prompt-menu';
        menu.id = 'prompt-menu-container';
        return menu;
    }

    function createPromptModal() {
        const overlay = document.createElement('div');
        overlay.className = 'mp-overlay mp-hidden';
        overlay.id = '__ap_modal_overlay';
        const box = document.createElement('div');
        box.className = 'mp-modal-box';
        box.onclick = e => e.stopPropagation();
        const modalContentHTML = `
            <button id="__ap_close_prompt" class="mp-modal-close-btn" aria-label="${getTranslation('close')}">✕</button>
            <h2 class="modal-title">${getTranslation('newPrompt')}</h2>
            <div class="form-group">
                <label for="__ap_title" class="form-label">${getTranslation('title')}</label>
                <input id="__ap_title" class="form-input" />
            </div>
            <div class="form-group">
                <label for="__ap_text" class="form-label">${getTranslation('text')}</label>
                <textarea id="__ap_text" class="form-textarea"></textarea>
            </div>
            <div class="form-checkbox-group">
                <input type="checkbox" id="__ap_use_placeholders" />
                <label for="__ap_use_placeholders">${getTranslation('enablePlaceholders')}</label>
            </div>
            <div class="modal-footer">
                <button id="__ap_save" class="save-button">${getTranslation('save')}</button>
            </div>
        `;
        setSafeInnerHTML(box, modalContentHTML);
        overlay.appendChild(box);
        return overlay;
    }

    function createLanguageModal() {
        const overlay = document.createElement('div');
        overlay.className = 'mp-overlay mp-hidden lang-overlay';
        overlay.id = '__ap_lang_modal_overlay';
        overlay.onclick = () => hideModal(overlay);
        const box = document.createElement('div');
        box.className = 'mp-modal-box lang-box';
        box.onclick = (e) => e.stopPropagation();
        const buttonsContainer = document.createElement('div');
        buttonsContainer.className = 'lang-buttons-container';
        Object.keys(translations).forEach((langKey, index) => {
            const btn = document.createElement('button');
            btn.className = 'lang-button';
            btn.textContent = translations[langKey].langName;
            btn.style.animationDelay = `${index * 60}ms`;
            btn.onclick = async () => {
                await GM_setValue(LANG_STORAGE_KEY, langKey);
                window.location.reload();
            };
            buttonsContainer.appendChild(btn);
        });
        box.appendChild(buttonsContainer);
        overlay.appendChild(box);
        return overlay;
    }

    function showModal(modal) {
        if (!modal) return;
        modal.classList.remove('mp-hidden');
        setTimeout(() => modal.classList.add('visible'), 10);
    }

    function hideModal(modal) {
        if (!modal) return;
        modal.classList.remove('visible');
        setTimeout(() => modal.classList.add('mp-hidden'), 200);
    }

    function openPromptModal(item = null, index = -1) {
        if (!currentModal) return;
        const isEditing = !!item;
        currentModal.dataset.index = index;
        currentModal.querySelector('.modal-title').textContent = isEditing ? getTranslation('editPrompt') : getTranslation('newPrompt');
        document.getElementById('__ap_title').value = item?.title || '';
        document.getElementById('__ap_text').value = item?.text || '';
        document.getElementById('__ap_use_placeholders').checked = item?.usePlaceholders || false;
        showModal(currentModal);
        setTimeout(() => document.getElementById('__ap_title').focus(), 100);
    }

    function createPlaceholderModal() {
        const overlay = document.createElement('div');
        overlay.className = 'mp-overlay mp-hidden';
        overlay.id = '__ap_placeholder_modal_overlay';
        const box = document.createElement('div');
        box.className = 'mp-modal-box';
        box.onclick = e => e.stopPropagation();
        const modalContentHTML = `
            <button id="__ap_close_placeholder" class="mp-modal-close-btn" aria-label="${getTranslation('close')}">✕</button>
            <h2 class="modal-title">${getTranslation('fillPlaceholders')}</h2>
            <div id="__ap_placeholders_container">
                <!-- Os campos de input serão inseridos aqui dinamicamente -->
            </div>
            <div class="modal-footer">
                <button id="__ap_insert_prompt" class="save-button">${getTranslation('insert')}</button>
            </div>
        `;
        setSafeInnerHTML(box, modalContentHTML);
        overlay.appendChild(box);
        return overlay;
    }
    // #endregion
    // #region FUNÇÕES AUXILIARES
    function moveCursorToEnd(editor) {
        setTimeout(() => {
            try {
                editor.focus();
                if (currentPlatform === 'gemini') {
                    const selection = window.getSelection();
                    const range = document.createRange();
                    range.selectNodeContents(editor);
                    range.collapse(false);
                    selection.removeAllRanges();
                    selection.addRange(range);
                    editor.scrollTop = editor.scrollHeight;
                } else if (currentPlatform === 'chatgpt') {
                    const selection = window.getSelection();
                    const range = document.createRange();
                    range.selectNodeContents(editor);
                    range.collapse(false);
                    selection.removeAllRanges();
                    selection.addRange(range);
                    const scrollContainer = editor.parentElement;
                    if (scrollContainer) {
                        scrollContainer.scrollTop = scrollContainer.scrollHeight;
                    }
                } else if (currentPlatform === 'googlestudio') {
                    const textLength = editor.value.length;
                    editor.selectionStart = editor.selectionEnd = textLength;
                    let scrollContainer = editor.parentElement;
                    let i = 0;
                    while (scrollContainer && i < 10) {
                        const style = window.getComputedStyle(scrollContainer);
                        if (style.overflowY === 'auto' || style.overflowY === 'scroll') {
                            break;
                        }
                        scrollContainer = scrollContainer.parentElement;
                        i++;
                    }
                    if (scrollContainer) {
                        scrollContainer.scrollTop = scrollContainer.scrollHeight;
                    }
                } else {
                    const textLength = editor.value.length;
                    editor.selectionStart = editor.selectionEnd = textLength;
                    editor.scrollTop = editor.scrollHeight;
                }
            } catch (e) {
            }
        }, 10);
    }

    function closeMenu() {
        if (currentMenu && currentMenu.classList.contains('visible')) {
            currentMenu.classList.remove('visible');
        }
    }

    function positionMenu(menu, button) {
        const btnRect = button.getBoundingClientRect();
        const menuHeight = menu.offsetHeight;
        const menuWidth = menu.offsetWidth;
        const viewportHeight = window.innerHeight;
        const viewportWidth = window.innerWidth;
        const margin = 8;
        let top, left;
        const spaceBelow = viewportHeight - btnRect.bottom - margin;
        const spaceAbove = btnRect.top - margin;
        if (spaceBelow >= menuHeight) {
            top = btnRect.bottom + margin;
        } else if (spaceAbove >= menuHeight) {
            top = btnRect.top - menuHeight - margin;
        } else {
            top = Math.max(margin, viewportHeight - menuHeight - margin);
        }
        const spaceRight = viewportWidth - btnRect.left - margin;
        const spaceLeft = btnRect.right - margin;
        if (spaceRight >= menuWidth) {
            left = btnRect.left;
        } else if (spaceLeft >= menuWidth) {
            left = btnRect.right - menuWidth;
        } else {
            left = (viewportWidth - menuWidth) / 2;
        }
        menu.style.top = `${Math.max(margin, Math.min(top, viewportHeight - menuHeight - margin))}px`;
        menu.style.left = `${Math.max(margin, Math.min(left, viewportWidth - menuWidth - margin))}px`;
    }

    async function refreshMenu() {
        if (!currentMenu) return;
        const listContainer = document.createElement('div');
        listContainer.className = 'prompt-menu-list';
        const items = await getAll();
        if (!items.length) {
            setSafeInnerHTML(listContainer, `<div class="empty-state">${getTranslation('noSavedPrompts')}</div>`);
        } else {
            items.forEach((p, index) => {
                const row = document.createElement('div');
                row.className = 'prompt-item-row';
                const titleDiv = document.createElement('div');
                titleDiv.className = 'prompt-title';
                titleDiv.textContent = p.title;
                titleDiv.onclick = (e) => {
                    e.stopPropagation();
                    if (p.usePlaceholders) {
                        const placeholderRegex = /\[([^\]]+)\]/g;
                        const placeholders = [...p.text.matchAll(placeholderRegex)];
                        if (placeholders.length > 0) {
                            openPlaceholderModal(p, index, placeholders);
                        } else {
                            insertPrompt(p, index);
                        }
                    } else {
                        insertPrompt(p, index);
                    }
                    closeMenu();
                };
                const actionsDiv = document.createElement('div');
                actionsDiv.className = 'prompt-actions';
                const btnE = document.createElement('button');
                btnE.textContent = getTranslation('edit');
                btnE.className = 'action-btn edit';
                btnE.onclick = (e) => { e.stopPropagation(); openPromptModal(p, index); };
                const btnD = document.createElement('button');
                btnD.textContent = getTranslation('delete');
                btnD.className = 'action-btn delete';
                btnD.onclick = (e) => { e.stopPropagation(); if (confirm(getTranslation('confirmDelete', { title: p.title }))) remove(index).then(refreshMenu); };
                actionsDiv.appendChild(btnE);
                actionsDiv.appendChild(btnD);
                row.appendChild(titleDiv);
                row.appendChild(actionsDiv);
                listContainer.appendChild(row);
            });
        }
        const addSection = document.createElement('div');
        addSection.className = 'menu-section';
        const addBtn = document.createElement('div');
        addBtn.className = 'menu-button';
        setSafeInnerHTML(addBtn, `<svg width="16" height="16" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" /></svg>${getTranslation('addPrompt')}`);
        addBtn.onclick = (e) => { e.stopPropagation(); openPromptModal(); };
        addSection.appendChild(addBtn);
        const footer = document.createElement('div');
        footer.className = 'menu-footer';
        const importExportContainer = document.createElement('div');
        importExportContainer.className = 'import-export-container';
        const exportBtn = document.createElement('div');
        exportBtn.className = 'menu-button';
        exportBtn.textContent = getTranslation('export');
        exportBtn.onclick = (e) => { e.stopPropagation(); exportPrompts(); };
        const importBtn = document.createElement('div');
        importBtn.className = 'menu-button';
        importBtn.textContent = getTranslation('import');
        importBtn.onclick = (e) => { e.stopPropagation(); importPrompts(); };
        const divider = document.createElement('div');
        divider.className = 'divider';
        importExportContainer.appendChild(exportBtn);
        importExportContainer.appendChild(divider);
        importExportContainer.appendChild(importBtn);
        footer.appendChild(importExportContainer);
        setSafeInnerHTML(currentMenu, '');
        currentMenu.appendChild(listContainer);
        currentMenu.appendChild(addSection);
        currentMenu.appendChild(footer);
    }

    function openPlaceholderModal(item, index, placeholders) {
        if (!currentPlaceholderModal) return;
        const container = document.getElementById('__ap_placeholders_container');
        setSafeInnerHTML(container, '');
        currentPlaceholderModal.dataset.prompt = JSON.stringify(item);
        currentPlaceholderModal.dataset.index = index;
        const uniquePlaceholders = [...new Map(placeholders.map(p => [p[1], p])).values()];
        uniquePlaceholders.forEach((match, i) => {
            const placeholderText = match[1];
            const formGroup = document.createElement('div');
            formGroup.className = 'form-group';
            const label = document.createElement('label');
            label.className = 'form-label';
            label.textContent = placeholderText;
            const textarea = document.createElement('textarea');
            textarea.className = 'form-input';
            textarea.dataset.placeholder = placeholderText;
            textarea.rows = 1;
            textarea.style.resize = 'vertical';
            textarea.style.height = 'auto';
            textarea.addEventListener('keydown', (event) => {
                if (event.key === 'Enter' && !event.shiftKey) {
                    event.preventDefault();
                    document.getElementById('__ap_insert_prompt').click();
                }
            });
            formGroup.appendChild(label);
            formGroup.appendChild(textarea);
            container.appendChild(formGroup);
        });
        showModal(currentPlaceholderModal);
        setTimeout(() => container.querySelector('input')?.focus(), 100);
    }
    // #endregion
    // #region DETECTAR E INTERAGIR
    function detectPlatform() {
        const hostname = window.location.hostname;
        if (hostname.includes('chatgpt.com'))           return 'chatgpt';
        if (hostname.includes('deepseek.com'))          return 'deepseek';
        if (hostname.includes('aistudio.google.com'))   return 'googlestudio';
        if (hostname.includes('chat.qwen.ai'))          return 'qwen';
        if (hostname.includes('chat.z.ai'))             return 'zai';
        if (hostname.includes('gemini.google.com'))     return 'gemini';
        if (hostname.includes('lmarena.ai'))            return 'lmarena';
        if (hostname.includes('kimi.com'))              return 'kimi';
        if (hostname.includes('claude.ai'))             return 'claude';
        return null;
    }

    async function insertPrompt(promptItem, index) {
        const platformSelectors = {
            chatgpt:        '#prompt-textarea',
            deepseek:       'textarea[placeholder="Message DeepSeek"]',
            googlestudio:   'ms-autosize-textarea textarea',
            qwen:           'textarea#chat-input',
            zai:            'textarea#chat-input',
            gemini:         'div.ql-editor[contenteditable="true"]',
            lmarena:        'textarea[name="message"]',
            kimi:           'div.chat-input-editor[contenteditable="true"]',
            claude:         'div.ProseMirror[contenteditable="true"]'
        };
        const editor = document.querySelector(platformSelectors[currentPlatform]);
        if (!editor) { alert(getTranslation('editorNotFound', { platform: currentPlatform })); return; }
        editor.focus();
        setTimeout(() => {
            const isFirefox = navigator.userAgent.toLowerCase().includes('firefox');
            if (isFirefox && currentPlatform === 'kimi') {
                document.execCommand('selectAll', false, null);
                document.execCommand('insertText', false, promptItem.text);
            }
            else if (isFirefox && (currentPlatform === 'chatgpt' || currentPlatform === 'claude')) {
                setSafeInnerHTML(editor, '');
                const lines = promptItem.text.split('\n');
                lines.forEach(line => {
                    const p = document.createElement('p');
                    if (line.trim() === '') {
                        p.appendChild(document.createElement('br'));
                    } else {
                        p.textContent = line;
                    }
                    editor.appendChild(p);
                });
                editor.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
            }
            else if (currentPlatform === 'gemini') {
                let p = editor.querySelector('p') || document.createElement('p');
                setSafeInnerHTML(editor, '');
                p.textContent = promptItem.text;
                editor.appendChild(p);
                editor.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
            }
            else {
                const dt = new DataTransfer();
                dt.setData('text/plain', promptItem.text);
                editor.dispatchEvent(new ClipboardEvent('paste', { clipboardData: dt, bubbles: true, cancelable: true }));
                if (editor.value !== undefined && editor.value !== promptItem.text) {
                    const setter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value').set;
                    setter.call(editor, promptItem.text);
                    editor.dispatchEvent(new Event('input', { bubbles: true }));
                }
            }
            moveCursorToEnd(editor);
        }, 100);
        let prompts = await getAll();
        if (index > 0) {
            const item = prompts.splice(index, 1)[0];
            prompts.unshift(item);
            await GM_setValue(PROMPT_STORAGE_KEY, prompts);
        }
    }

    async function exportPrompts() {
        const prompts = await getAll();
        if(prompts.length===0){alert(getTranslation('noPromptsToExport'));return}
        const a=document.createElement('a');
        a.href=URL.createObjectURL(new Blob([JSON.stringify(prompts,null,2)],{type:'application/json'}));
        a.download=getTranslation('fileName');
        a.click();
        URL.revokeObjectURL(a.href);
        closeMenu();
    }

    function importPrompts() {
        const input=document.createElement('input');
        input.type='file';
        input.accept='.json';
        input.onchange=e=>{
            const file=e.target.files[0];
            if(!file)return;
            const reader=new FileReader();
            reader.onload=async event=>{
                try{
                    const imported=JSON.parse(event.target.result);
                    if(!Array.isArray(imported))throw new Error("Not an array.");
                    const current=await getAll();
                    const newPrompts = imported.map(p => ({
                        title: p.title || 'No Title',
                        text: p.text || '',
                        usePlaceholders: p.usePlaceholders || false
                    }));
                    await GM_setValue(PROMPT_STORAGE_KEY,[...current,...newPrompts]);
                    await refreshMenu();
                    alert(getTranslation('promptsImported',{count:newPrompts.length}));
                }catch(err){alert(getTranslation('errorImporting',{error:err.message}))}
            };
            reader.readAsText(file);
        };
        input.click();
        closeMenu();
    }

    function cleanup() {
        if (currentButton)  { currentButton.remove  (); currentButton   = null; }
        if (currentMenu)    { currentMenu.remove    (); currentMenu     = null; }
        if (currentModal)   { currentModal.remove   (); currentModal    = null; }
        if (languageModal)  { languageModal.remove  (); languageModal   = null; }
        if (currentPlaceholderModal) { currentPlaceholderModal.remove(); currentPlaceholderModal = null; }
        isInitialized = false;
    }
    // #endregion
    // #region INICIALIZAÇÃO E OBSERVAÇÃO
    async function initUI() {
        if (pageObserver) pageObserver.disconnect();
        cleanup();
        currentPlatform = detectPlatform();
        if (!currentPlatform) return;
        try {
            let btn, elementToInsert, insertionPoint, insertionMethod = 'before';
            // CHATGPT
            if (currentPlatform === 'chatgpt') {
                insertionPoint = await waitFor('div[class*="[grid-area:leading]"]');
                insertionPoint.style.display = 'flex';
                insertionPoint.style.alignItems = 'center';
                btn = createChatGPTButton();
                elementToInsert = btn;
                insertionMethod = 'append';
            // DEEPSEEK
            } else if (currentPlatform === 'deepseek') {
                const container = await waitFor('.ec4f5d61');
                insertionPoint = container.querySelector('.bf38813a');
                const allButtons = Array.from(container.querySelectorAll('button'));
                const refBtn = allButtons.find(b => b.textContent.trim() === 'Search');
                if (!refBtn || !insertionPoint) throw new Error('DeepSeek UI reference button "Search" not found.');
                btn = createDeepSeekButton();
                btn.className = refBtn.className;
                elementToInsert = btn;
            // GOOGLE STUDIO
            } else if (currentPlatform === 'googlestudio') {
                insertionPoint = await waitFor('ms-add-chunk-menu', 5000).then(el => el.closest('.button-wrapper'));
                const wrapper = document.createElement('div');
                wrapper.className = 'button-wrapper';
                btn = createGoogleStudioButton();
                wrapper.appendChild(btn);
                elementToInsert = wrapper;
                const parent = insertionPoint.closest('.prompt-input-wrapper-container');
                if (parent) parent.style.alignItems = 'center';
            // QWEN
            } else if (currentPlatform === 'qwen') {
                const referenceButton = await waitFor('button.websearch_button', 5000);
                const buttonContainer = referenceButton.parentElement;
                if (!buttonContainer) throw new Error('Qwen button container not found.');
                insertionPoint = buttonContainer.firstChild;
                insertionMethod = 'before';
                btn = createQwenButton();
                elementToInsert = btn;
                const qwenPositionObserver = new MutationObserver(() => {
                    const myButton = buttonContainer.querySelector('button[data-testid="composer-button-prompts"]');
                    if (myButton && buttonContainer.firstElementChild !== myButton) {
                        buttonContainer.prepend(myButton);
                    }
                });
                qwenPositionObserver.observe(buttonContainer, { childList: true });
            // Z.AI
            } else if (currentPlatform === 'zai') {
                const referenceElement = await waitFor('button[data-autothink="true"]', 8000);
                insertionPoint = referenceElement.closest('.flex.gap-\\[8px\\].items-center');
                if (!insertionPoint) throw new Error('Z.ai button container not found.');
                btn = createZaiButton();
                elementToInsert = btn;
                insertionMethod = 'append';
            // GEMENI
            } else if (currentPlatform === 'gemini') {
                insertionPoint = await waitFor('uploader', 8000);
                btn = createGeminiButton();
                elementToInsert = btn;
                insertionMethod = 'after';
                const wrapper = insertionPoint.parentElement;
                if (wrapper) {
                    wrapper.style.display = 'flex';
                    wrapper.style.alignItems = 'center';
                    wrapper.style.gap = '3px';
                }
            // LM ARENA
            } else if (currentPlatform === 'lmarena') {
                insertionPoint = await waitFor('div[data-sentry-component="SelectChatModality"]', 8000);
                btn = createLmarenaButton();
                elementToInsert = btn;
                insertionMethod = 'append';
            // KIMI
            } else if (currentPlatform === 'kimi') {
                insertionPoint = await waitFor('div.left-area', 8000);
                btn = createKimiButton();
                if (!btn) return;
                elementToInsert = btn;
                const ensureButtonIsPresent = () => {
                    if (!insertionPoint.contains(elementToInsert)) {
                        insertionPoint.appendChild(elementToInsert);
                    }
                };
                ensureButtonIsPresent();
                const guardianObserver = new MutationObserver(ensureButtonIsPresent);
                guardianObserver.observe(insertionPoint, { childList: true });
                insertionMethod = 'handled_by_kimi_guardian';
            // CLAUDE
            } else if (currentPlatform === 'claude') {
                insertionPoint = await waitFor('button[data-testid="input-menu-plus"]', 8000).then(el => el.closest('div.relative.shrink-0'));
                btn = createClaudeButton();
                elementToInsert = btn;
                insertionMethod = 'after';
            }
            if (!btn || !insertionPoint) return;
            currentButton = elementToInsert;
            const clickable = btn;
            if (insertionMethod === 'append') {
                insertionPoint.appendChild(elementToInsert);
            } else if (insertionMethod === 'before') {
                insertionPoint.parentNode.insertBefore(elementToInsert, insertionPoint);
            } else if (insertionMethod === 'after') {
                insertionPoint.parentNode.insertBefore(elementToInsert, insertionPoint.nextSibling);
            }
            currentMenu = createPromptMenu();
            currentModal = createPromptModal();
            languageModal = createLanguageModal();
            currentPlaceholderModal = createPlaceholderModal();
            document.body.appendChild(currentMenu);
            document.body.appendChild(currentModal);
            document.body.appendChild(languageModal);
            document.body.appendChild(currentPlaceholderModal);
            clickable.addEventListener('click', e => {
                e.stopPropagation();
                e.preventDefault();
                const menu = currentMenu;
                if (menu.classList.contains('visible')) {
                    closeMenu();
                    return;
                }
                refreshMenu().then(() => {
                    positionMenu(menu, clickable);
                    menu.classList.add('visible');
                });
            });
            currentModal.querySelector('#__ap_save').onclick = async (e) => {
                e.stopPropagation();
                const index = parseInt(currentModal.dataset.index, 10);
                const title = document.getElementById('__ap_title').value.trim();
                const text = document.getElementById('__ap_text').value.trim();
                const usePlaceholders = document.getElementById('__ap_use_placeholders').checked;
                if (!title || !text) { alert(getTranslation('requiredFields')); return; }
                const op = index > -1 ? update(index, { title, text, usePlaceholders }) : addItem({ title, text, usePlaceholders });
                op.then(() => { hideModal(currentModal); refreshMenu(); });
            };
            currentModal.querySelector('#__ap_close_prompt').onclick = (e) => {
                e.stopPropagation();
                hideModal(currentModal);
            };
            currentPlaceholderModal.querySelector('#__ap_insert_prompt').onclick = async (e) => {
                e.stopPropagation();
                const item = JSON.parse(currentPlaceholderModal.dataset.prompt);
                const index = parseInt(currentPlaceholderModal.dataset.index, 10);
                let completedText = item.text;
                const textareas = currentPlaceholderModal.querySelectorAll('#__ap_placeholders_container textarea');
                textareas.forEach(textarea => {
                    const placeholder = textarea.dataset.placeholder;
                    const userValue = textarea.value;
                    const regex = new RegExp(`\\[${placeholder.replace(/[\.\+\*?\[\^\]\$\(\)\{\}\=\!<>\|\:\-]/g, '\\$&')}\\]`, 'g');
                    completedText = completedText.replace(regex, userValue);
                });
                const finalPrompt = { ...item, text: completedText };
                await insertPrompt(finalPrompt, index);
                hideModal(currentPlaceholderModal);
            };
            currentPlaceholderModal.querySelector('#__ap_close_placeholder').onclick = (e) => {
                e.stopPropagation();
                hideModal(currentPlaceholderModal);
            };
            isInitialized = true;
        } catch (error) {
            cleanup();
        } finally {
            setupPageObserver();
        }
    }

    const debouncedTryInit = debounce(tryInit, 500);

    function setupPageObserver() {
        if (pageObserver) pageObserver.disconnect();
        pageObserver = new MutationObserver(() => {
            if (!document.body.contains(currentButton)) {
                debouncedTryInit();
            }
        });
        pageObserver.observe(document.body, { childList: true, subtree: true });
    }

    function setupGlobalEventListeners() {
        document.addEventListener('click', ev => {
            if (!currentMenu || !currentButton) return;
            if (ev.target.closest('#prompt-menu-container, [data-testid="composer-button-prompts"]')) return;
            closeMenu();
        });
        document.addEventListener('keydown', ev => {
            if (ev.key === 'Escape') {
                closeMenu();
                if (currentModal && currentModal.classList.contains('visible')) hideModal(currentModal);
                if (languageModal && languageModal.classList.contains('visible')) hideModal(languageModal);
                if (currentPlaceholderModal && currentPlaceholderModal.classList.contains('visible')) hideModal(currentPlaceholderModal);
            }
        });
        window.addEventListener('resize', debounce(() => {
            if (currentMenu && currentMenu.classList.contains('visible')) {
                positionMenu(currentMenu, currentButton);
            }
        }, 100));
    }

    function tryInit() {
        if (isInitializing) return;
        if (isInitialized && currentButton && document.body.contains(currentButton) && currentPlatform === detectPlatform()) {
            return;
        }
        isInitializing = true;
        initUI().finally(() => { isInitializing = false; });
    }
    // #endregion
    // #region INICIAR SCRIPT
    async function start() {
        await determineLanguage();
        injectGlobalStyles();
        setupGlobalEventListeners();
        GM_registerMenuCommand(getTranslation('languageSettings'), () => {
            if (!languageModal) {
                languageModal = createLanguageModal();
                document.body.appendChild(languageModal);
            }
            showModal(languageModal);
        });
        tryInit();
    }
    start();
    // #endregion
})();