Pollinations.ai Enhancer

Enhanced markdown formatting for pollinations.ai with better readability, and smoother viewing

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Pollinations.ai Enhancer
// @namespace    https://greasyfork.org/en/users/1462897-fisventurous
// @version      1.9.4
// @description  Enhanced markdown formatting for pollinations.ai with better readability, and smoother viewing
// @author       fisventurous
// @match        *://*.pollinations.ai/*
// @connect      *
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_xmlhttpRequest
// @grant        unsafeWindow
// @run-at       document-start
// @license MIT
// ==/UserScript==

(function () {
    "use strict";

    const THEME_KEY = "pollinations_enhancer_theme";
    const FONT_SIZE_KEY = "pollinations_enhancer_fontsize";

    let observer = null;

    if (document.readyState === "loading") {
        document.addEventListener("DOMContentLoaded", init);
    } else {
        init();
    }

    function init() {
        const hostname = window.location.hostname;
    
        if (!hostname.startsWith('text.pollinations.ai') && !hostname.startsWith('image.pollinations.ai')) {
            console.log("Pollinations Enhancer: Skipping execution on unsupported domain:", hostname);
            if (document.readyState === "loading") {
                document.removeEventListener("DOMContentLoaded", init);
            }
            return;
        }
    
        addStyles();
        applyTheme();
        applyFontSize();
    
        const pageType = detectPageType();
        setupLinkPreviews();
    
        if (pageType.isText) enhanceTextPage();
        else if (pageType.isImage) enhanceImagePage();
        else if (pageType.isAudio) enhanceAudioPage();
        else createCommonButtons(extractUrlParameters(), "unknown");
    
        if (pageType.isText)
            updateThemeToggleButton(
                document.body.classList.contains("theme-dark"),
            );
    
        startObserver(pageType);
    }

    function detectPageType() {
        const url = window.location.href.toLowerCase();
        const urlParams = new URLSearchParams(window.location.search);

        let isImage = false;
        let isAudio = false;
        let isText = false;

        if (
            url.includes("image.pollinations.ai") ||
            url.includes("/image/")
        ) {
            isImage = true;
        } else if (
            url.includes("audio") ||
            url.match(/\.(mp3|wav|ogg|m4a)(\?|$)/i)
        ) {
            isAudio = true;
        } else if (url.includes("text.pollinations.ai")) {
            isText = true;
        }

        if (!isImage && !isAudio && !isText) {
            const model = urlParams.get("model") || "";
            const hasVoice = urlParams.has("voice");

            if (model.includes("audio") || hasVoice) {
                isAudio = true;
            } else if (model.includes("image")) {
                isImage = true;
            }
        }

        if (!isImage && !isAudio && !isText) {
            if (document.querySelector('img:not([width="16"][height="16"])')) {
                isImage = true;
            } else if (
                document.querySelector('audio, video, [type*="audio"]')
            ) {
                isAudio = true;
            } else {
                isText = true;
            }
        }

        return { isText, isImage, isAudio };
    }

    function startObserver(pageType) {
        if (observer) observer.disconnect();

        observer = new MutationObserver((mutations) => {
            for (const mutation of mutations) {
                if (
                    mutation.type === "childList" &&
                    mutation.addedNodes.length
                ) {
                    if (
                        pageType.isImage &&
                        !document.getElementById("save-image-btn")
                    ) {
                        const newImages = Array.from(mutation.addedNodes).filter(
                            (node) =>
                                node.tagName === "IMG" ||
                                (node.querySelectorAll &&
                                    node.querySelectorAll("img").length),
                        );

                        if (newImages.length) {
                            setTimeout(enhanceImagePage, 100);
                        }
                    }

                    if (
                        pageType.isAudio &&
                        !document.getElementById("save-audio-btn")
                    ) {
                        const newAudio = Array.from(mutation.addedNodes).filter(
                            (node) =>
                                node.tagName === "AUDIO" ||
                                node.tagName === "VIDEO" ||
                                (node.querySelectorAll &&
                                    (node.querySelectorAll("audio").length ||
                                        node.querySelectorAll("video")
                                            .length ||
                                        node.querySelectorAll(
                                            'source[type*="audio"]',
                                        ).length)),
                        );

                        if (newAudio.length) {
                            setTimeout(enhanceAudioPage, 100);
                        }
                    }
                }
            }
        });

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

    function applyTheme() {
        const savedTheme = GM_getValue(THEME_KEY, "theme-dark");
        document.body.classList.remove("theme-dark", "theme-light");
        document.body.classList.add(savedTheme);
    }

    function toggleTheme() {
        const isDark = document.body.classList.contains("theme-dark");
        const newTheme = isDark ? "theme-light" : "theme-dark";
        document.body.classList.remove("theme-dark", "theme-light");
        document.body.classList.add(newTheme);
        GM_setValue(THEME_KEY, newTheme);
        updateThemeToggleButton(newTheme === "theme-dark");
    }

    function updateThemeToggleButton(isDark) {
        const btn = document.getElementById("theme-toggle-btn");
        if (btn) {
            btn.innerHTML = isDark
                ? '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"></circle><path d="M12 1v2M12 21v2M4.2 4.2l1.4 1.4M18.4 18.4l1.4 1.4M1 12h2M21 12h2M4.2 19.8l1.4-1.4M18.4 5.6l1.4-1.4"></path></svg>'
                : '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>';
        }
    }

    function setupLinkPreviews() {
        const preview = document.createElement("div");
        preview.className = "preview";
        document.body.appendChild(preview);
        let showTimeout = null,
            hideTimeout = null,
            currentLink = null;

        document.body.addEventListener("mouseover", (e) => {
            const link = e.target.closest("a");
            if (link && link.href) {
                clearTimeout(hideTimeout);
                if (currentLink !== link) {
                    currentLink = link;
                    clearTimeout(showTimeout);
                    showTimeout = setTimeout(
                        () => showPreview(link, preview),
                        200,
                    );
                }
            }
        });

        document.body.addEventListener("mouseout", (e) => {
            if (e.target.closest("a")) {
                clearTimeout(showTimeout);
                hideTimeout = setTimeout(() => {
                    preview.style.opacity = "0";
                    setTimeout(() => {
                        preview.style.display = "none";
                        currentLink = null;
                    }, 150);
                }, 200);
            }
        });

        preview.addEventListener("mouseenter", () => clearTimeout(hideTimeout));
        preview.addEventListener("mouseleave", () => {
            hideTimeout = setTimeout(() => {
                preview.style.opacity = "0";
                setTimeout(() => {
                    preview.style.display = "none";
                    currentLink = null;
                }, 150);
            }, 200);
        });
    }

    function showPreview(link, preview) {
        try {
            const url = link.href;
            const rect = link.getBoundingClientRect();
            let sourceName = "Source",
                faviconUrl = "";
            try {
                const urlObj = new URL(url);
                sourceName = urlObj.hostname.replace(/^www\./, "");
                faviconUrl = `https://www.google.com/s2/favicons?domain=${urlObj.hostname}&sz=64`;
            } catch (err) {}
            let contentHTML = link.textContent?.trim() || url;
            if (link.closest("pre, code"))
                contentHTML = `<code class="inline-code">${contentHTML}</code>`;
            preview.innerHTML = `<div class="preview-header"><div class="preview-icon">${faviconUrl ? `<img src="${faviconUrl}" alt="" onerror="this.style.display='none'; this.parentElement.textContent='${sourceName.charAt(0).toUpperCase()}';" />` : sourceName.charAt(0).toUpperCase()}</div><div>${sourceName}</div></div><div class="preview-content">${contentHTML}</div><div class="preview-url">${url}</div>`;
            preview.style.opacity = 0;
            preview.style.display = "block";
            requestAnimationFrame(() => {
                const previewRect = preview.getBoundingClientRect();
                const winWidth = window.innerWidth,
                    winHeight = window.innerHeight;
                let top = rect.bottom + window.scrollY + 5,
                    left = rect.left + window.scrollX;
                if (left + previewRect.width > winWidth - 10)
                    left = winWidth - previewRect.width - 10;
                if (left < 10) left = 10;
                if (top + previewRect.height > winHeight + window.scrollY - 10)
                    top = rect.top + window.scrollY - previewRect.height - 5;
                if (top < window.scrollY + 10) top = window.scrollY + 10;
                preview.style.top = `${top}px`;
                preview.style.left = `${left}px`;
                preview.classList.add("active");
                preview.style.opacity = 1;
            });
        } catch (e) {
            console.error("Pollinations Enhancer: Error showing preview", e);
            preview.classList.remove("active");
        }
    }

    function enhanceTextPage() {
        document.body.classList.add("text-enhanced");
        const params = extractUrlParameters();
        let contentContainer = null;
        let originalContent = "";

        try {
            contentContainer = document.querySelector(
                "main:not(:empty), article:not(:empty), .content:not(:empty), #content:not(:empty), .main-content:not(:empty), .post-content:not(:empty)",
            );

            if (
                !contentContainer &&
                document.body.children.length === 1 &&
                document.body.firstElementChild?.tagName === "PRE"
            ) {
                contentContainer = document.body.firstElementChild;
            }

            if (
                !contentContainer &&
                (document.body.innerText || document.body.textContent || "")
                    .trim().length > 50
            ) {
                contentContainer = document.createElement("div");
                contentContainer.className = "content-container-generated";
                while (
                    document.body.firstChild &&
                    (!document.body.firstChild.matches ||
                        !document.body.firstChild.matches(
                            "#pollinations-enhancer-buttons, .preview, script, style, #metadata-box",
                        ))
                ) {
                    contentContainer.appendChild(document.body.firstChild);
                }
                document.body.appendChild(contentContainer);
            }

            if (contentContainer) {
                contentContainer.classList.add("content-container");
                originalContent =
                    contentContainer.innerText ||
                    contentContainer.textContent ||
                    "";

                if (params.json === "true") {
                    const jsonText = originalContent;
                    contentContainer.innerHTML = "";

                    const pre = document.createElement("pre");
                    pre.className = "code-block-container";

                    const header = document.createElement("div");
                    header.className = "code-header";

                    const langSpan = document.createElement("span");
                    langSpan.className = "code-language";
                    langSpan.textContent = "json";

                    const copyBtn = document.createElement("button");
                    copyBtn.className = "code-copy-btn";
                    copyBtn.title = "Copy code";
                    copyBtn.textContent = "Copy";
                    copyBtn.addEventListener("click", () => {
                        navigator.clipboard
                            .writeText(jsonText)
                            .then(() => {
                                const originalText = copyBtn.textContent;
                                copyBtn.textContent = "Copied!";
                                setTimeout(() => {
                                    copyBtn.textContent = originalText;
                                }, 1500);
                            })
                            .catch((err) => {
                                console.error("Failed to copy JSON:", err);
                            });
                    });

                    header.appendChild(langSpan);
                    header.appendChild(copyBtn);

                    const code = document.createElement("code");
                    code.className = "language-json";
                    code.textContent = jsonText;

                    pre.appendChild(header);
                    pre.appendChild(code);
                    contentContainer.appendChild(pre);
                } else {
                    if (contentContainer.tagName !== "PRE") {
                        processMarkdown(contentContainer);
                    } else {
                        const preContent = contentContainer.textContent || "";
                        contentContainer.innerHTML = "";

                        const preWrapper = document.createElement("pre");
                        preWrapper.className = "code-block-container";

                        const header = document.createElement("div");
                        header.className = "code-header";
                        const langSpan = document.createElement("span");
                        langSpan.className = "code-language";
                        langSpan.textContent = "text";
                        const copyBtn = document.createElement("button");
                        copyBtn.className = "code-copy-btn";
                        copyBtn.title = "Copy code";
                        copyBtn.textContent = "Copy";
                        copyBtn.addEventListener("click", () => {
                            navigator.clipboard
                                .writeText(preContent)
                                .then(() => {
                                    const originalText = copyBtn.textContent;
                                    copyBtn.textContent = "Copied!";
                                    setTimeout(() => {
                                        copyBtn.textContent = originalText;
                                    }, 1500);
                                })
                                .catch((err) => {
                                    console.error(
                                        "Failed to copy preformatted text:",
                                        err,
                                    );
                                });
                        });

                        header.appendChild(langSpan);
                        header.appendChild(copyBtn);

                        const code = document.createElement("code");
                        code.className = "language-text";
                        code.textContent = preContent;

                        preWrapper.appendChild(header);
                        preWrapper.appendChild(code);
                        contentContainer.appendChild(preWrapper);
                    }
                }
            } else {
                console.warn(
                    "Pollinations Enhancer: Could not find suitable content container.",
                );
            }
        } catch (error) {
            console.error(
                "Pollinations Enhancer: Error enhancing text page:",
                error,
            );
        }

        createCommonButtons(params, "text", contentContainer, originalContent);
    }

    function processMarkdown(container) {
        if (!container) return;

        container.innerHTML = container.innerHTML
            .replace(/<span class="[^"]*">/g, "")
            .replace(/<\/span>/g, "");

        const codeBlocks = [];
        let codeBlockCount = 0;

        container.innerHTML = container.innerHTML.replace(
            /```(\w*)\n([\s\S]*?)```/g,
            (match, lang, code) => {
                const placeholder = `<!--CODEBLOCK_${codeBlockCount}-->`;
                codeBlocks.push({
                    placeholder,
                    language: lang || "text",
                    code: code.replace(/`/g, "`"),
                });
                codeBlockCount++;
                return placeholder;
            },
        );

        const originalHtml = container.innerHTML;

        const content = container.textContent;

        const blockquoteHtml = processBlockquotes(content);

        if (blockquoteHtml !== content) {
            const processedWithCodeBlocksPreserved = restoreCodeBlocks(
                blockquoteHtml,
                originalHtml,
            );
            container.innerHTML = processedWithCodeBlocksPreserved;
        }

        container.innerHTML = container.innerHTML.replace(
            /^(#{1,6})\s+(.+)$/gm,
            function (match, hashes, content) {
                const level = hashes.length;
                return `<h${level}>${content}</h${level}>`;
            },
        );

        container.innerHTML = container.innerHTML.replace(
            /^---+$/gm,
            '<hr class="markdown-hr">',
        );

        container.innerHTML = processLists(container.innerHTML);

        container.innerHTML = container.innerHTML
            .replace(/\*\*(.*?)\*\*|__(.*?)__/g, "<strong>$1$2</strong>")
            .replace(/\*(.*?)\*|_(.*?)_/g, "<em>$1$2</em>")
            .replace(/~~(.*?)~~/g, "<del>$1</del>")
            .replace(
                /\[([^\]]+?)\]\((https?:\/\/[^)]+)\)/g,
                '<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>',
            )
            .replace(/`([^`]+?)`/g, '<code class="inline-code">$1</code>');

        for (let i = 0; i < codeBlocks.length; i++) {
            const block = codeBlocks[i];
            const html = `<pre class="code-block-container"><div class="code-header"><span class="code-language">${block.language}</span><button class="code-copy-btn" title="Copy code">Copy</button></div><code class="language-${block.language}">${block.code}</code></pre>`;
            container.innerHTML = container.innerHTML.replace(
                block.placeholder,
                html,
            );
        }

        const copyButtons = container.querySelectorAll(".code-copy-btn");
        copyButtons.forEach((btn) => {
            btn.addEventListener("click", () => {
                const codeBlock = btn.parentElement.nextElementSibling;
                const textToCopy = codeBlock.textContent;
                navigator.clipboard
                    .writeText(textToCopy)
                    .then(() => {
                        const originalText = btn.textContent;
                        btn.textContent = "Copied!";
                        setTimeout(() => {
                            btn.textContent = originalText;
                        }, 1500);
                    })
                    .catch((err) => {
                        console.error("Failed to copy code:", err);
                    });
            });
        });
    }

    function processBlockquotes(text) {
        const lines = text.split("\n");
        let result = [];
        let inMultiBlockquote = false;
        let blockquoteContent = [];

        for (let i = 0; i < lines.length; i++) {
            const line = lines[i];
            const trimmedLine = line.trim();

            if (trimmedLine.startsWith(">>>")) {
                if (inMultiBlockquote) {
                    result.push(
                        `<blockquote class="blockquote-multi">${blockquoteContent.join(" ")}</blockquote>`,
                    );
                }
                inMultiBlockquote = true;
                const initial = trimmedLine.substring(3).trim();
                blockquoteContent = initial ? [initial] : [];
                continue;
            }

            if (inMultiBlockquote) {
                if (trimmedLine === "" || trimmedLine.startsWith(">")) {
                    result.push(
                        `<blockquote class="blockquote-multi">${blockquoteContent.join(" ")}</blockquote>`,
                    );
                    inMultiBlockquote = false;
                    blockquoteContent = [];
                    if (trimmedLine === "") {
                        result.push("");
                        continue;
                    }
                } else {
                    blockquoteContent.push(trimmedLine);
                    continue;
                }
            }

            if (trimmedLine === ">") {
                result.push("");
                continue;
            }

            if (trimmedLine.startsWith("> ")) {
                const content = trimmedLine.substring(2);
                if (content) {
                    result.push(
                        `<blockquote class="blockquote-single">${content}</blockquote>`,
                    );
                } else {
                    result.push("");
                }
                continue;
            }

            result.push(line);
        }

        if (inMultiBlockquote) {
            result.push(
                `<blockquote class="blockquote-multi">${blockquoteContent.join(" ")}</blockquote>`,
            );
        }

        return result.join("\n");
    }

    function restoreCodeBlocks(blockquoteHtml, originalHtml) {
        const placeholders = [];
        const regex = /<!--CODEBLOCK_\d+-->/g;
        let match;
        while ((match = regex.exec(originalHtml)) !== null) {
            placeholders.push(match[0]);
        }

        if (placeholders.length === 0) {
            return blockquoteHtml;
        }

        const blockquoteLines = blockquoteHtml.split("\n");
        const originalLines = originalHtml.split("\n");

        let placeholderIndex = 0;
        for (let i = 0; i < originalLines.length; i++) {
            if (
                originalLines[i].includes("<!--CODEBLOCK_") &&
                placeholderIndex < placeholders.length
            ) {
                const placeholder = placeholders[placeholderIndex];

                const insertPosition = Math.min(i, blockquoteLines.length);
                blockquoteLines.splice(insertPosition, 0, placeholder);

                placeholderIndex++;
            }
        }

        return blockquoteLines.join("\n");
    }

    function processLists(text) {
        const lines = text.split("\n");
        let result = [];
        let lastWasNumbered = false;

        for (let i = 0; i < lines.length; i++) {
            const line = lines[i];

            const numberedMatch = line.match(/^(\d+)\.\s+(.*)/);

            const dashMatch = line.match(/^[-*]\s+(.*)/);

            if (numberedMatch) {
                const num = numberedMatch[1];
                const content = numberedMatch[2];
                result.push(
                    `<div class="numbered-item">${num}. ${content}</div>`,
                );
                lastWasNumbered = true;
            } else if (dashMatch && lastWasNumbered) {
                const content = dashMatch[1];
                result.push(
                    `<div class="nested-bullet-item">${content}</div>`,
                );
            } else if (dashMatch) {
                const content = dashMatch[1];
                result.push(`<div class="bullet-item">${content}</div>`);
            } else if (line.trim() === "") {
                result.push(line);
                lastWasNumbered = false;
            } else {
                result.push(line);
                lastWasNumbered = false;
            }
        }

        return result.join("\n");
    }

    function enhanceImagePage() {
        let mainImage = null;
        removeExistingButtons();

        try {
            const directImages = document.querySelectorAll("body > img");
            if (directImages.length > 0) {
                let largestArea = 0;
                directImages.forEach((img) => {
                    if (img.complete) {
                        const area = img.naturalWidth * img.naturalHeight;
                        if (area > largestArea) {
                            largestArea = area;
                            mainImage = img;
                        }
                    } else {
                        img.addEventListener("load", () => {
                            setTimeout(enhanceImagePage, 100);
                        });
                    }
                });
            }

            if (!mainImage) {
                const allImages = document.querySelectorAll("img");
                let largestArea = 0;

                allImages.forEach((img) => {
                    if (img.width < 30 || img.height < 30) return;

                    const area =
                        img.naturalWidth * img.naturalHeight ||
                        img.width * img.height;
                    if (area > largestArea) {
                        largestArea = area;
                        mainImage = img;
                    }
                });
            }
        } catch (error) {
            console.error(
                "Pollinations Enhancer: Error finding image element:",
                error,
            );
        }

        const params = extractUrlParameters();
        if (mainImage) {
            params.width = mainImage.naturalWidth || mainImage.width || 0;
            params.height = mainImage.naturalHeight || mainImage.height || 0;
            createCommonButtons(params, "image", mainImage);
        } else {
            setTimeout(enhanceImagePage, 500);
        }
    }

    function enhanceAudioPage() {
        removeExistingButtons();
        const params = extractUrlParameters();
        let audioSrc = findAudioSource();

        if (!audioSrc) {
            audioSrc = window.location.href;
        }

        createCommonButtons(params, "audio", null, "", audioSrc);
    }

    function removeExistingButtons() {
        const existingContainer = document.getElementById(
            "pollinations-enhancer-buttons",
        );
        if (existingContainer) existingContainer.remove();

        const existingMetadata = document.getElementById("metadata-box");
        if (existingMetadata) existingMetadata.remove();
    }

    function findAudioSource() {
        const audioExtRegex = /\.(mp3|wav|ogg|m4a|flac|aac)(\?|$)/i;

        const audioElements = document.querySelectorAll("audio, video");
        for (const el of audioElements) {
            if (el.src && el.src.length > 10) {
                return el.src;
            }

            for (const source of el.querySelectorAll("source")) {
                if (source.src && source.src.length > 10) {
                    return source.src;
                }
            }
        }

        for (const link of document.querySelectorAll("a[href]")) {
            try {
                const url = new URL(
                    link.getAttribute("href"),
                    window.location.href,
                );
                if (
                    audioExtRegex.test(url.pathname) ||
                    url.pathname.includes("/audio/")
                ) {
                    return url.href;
                }
            } catch (e) {}
        }

        for (const el of document.querySelectorAll(
            '[type*="audio"], [src*=".mp3"], [src*="/audio/"]',
        )) {
            const src = el.getAttribute("src") || el.getAttribute("data-src");
            if (src && src.length > 10) {
                return new URL(src, window.location.href).href;
            }
        }

        const metaOgAudio = document.querySelector(
            'meta[property="og:audio"], meta[property="og:audio:url"]',
        );
        if (metaOgAudio && metaOgAudio.content) {
            return metaOgAudio.content;
        }

        const htmlContent = document.documentElement.outerHTML;
        const audioUrlMatches = htmlContent.match(
            /https?:\/\/[^"'\s]+\.(mp3|wav|ogg|m4a)(\?[^"'\s]*)?/gi,
        );
        if (audioUrlMatches && audioUrlMatches.length) {
            return audioUrlMatches[0];
        }

        return null;
    }

    function createCommonButtons(
        params,
        type,
        targetElement = null,
        originalContent = "",
        resourceUrl = "",
    ) {
        try {
            removeExistingButtons();

            const buttonContainer = document.createElement("div");
            buttonContainer.id = "pollinations-enhancer-buttons";
            buttonContainer.style.cssText =
                "position: fixed; top: 10px; right: 20px; z-index: 9999; display: flex; flex-direction: column; gap: 8px;";

            if (type === "text") {
                const themeToggleBtn = createButton(
                    "theme-toggle-btn",
                    "Toggle theme (Light/Dark)",
                    "",
                    toggleTheme,
                );
                buttonContainer.appendChild(themeToggleBtn);
            }
            if (type === "text" && targetElement) {
                const copyContentBtn = createButton(
                    "copy-content-btn",
                    "Copy text content",
                    '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>',
                    () => {
                        navigator.clipboard
                            .writeText(
                                originalContent ||
                                    (targetElement.innerText ||
                                        targetElement.textContent ||
                                        ""),
                            )
                            .then(
                                () => flashButton(copyContentBtn, true),
                                () => flashButton(copyContentBtn, false),
                            );
                    },
                );
                buttonContainer.appendChild(copyContentBtn);

                const fontSizeContainer = document.createElement("div");
                fontSizeContainer.className = "font-size-controls";
                fontSizeContainer.style.cssText =
                    "position: relative; right: 41px; display: flex; gap: 5px;";

                const increaseFontBtn = createButton(
                    "increase-font-btn",
                    "Increase text size",
                    '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="16"></line><line x1="8" y1="12" x2="16" y2="12"></line></svg>',
                    increaseFontSize,
                );
                const decreaseFontBtn = createButton(
                    "decrease-font-btn",
                    "Decrease text size",
                    '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="8" y1="12" x2="16" y2="12"></line></svg>',
                    decreaseFontSize,
                );

                fontSizeContainer.appendChild(increaseFontBtn);
                fontSizeContainer.appendChild(decreaseFontBtn);
                buttonContainer.appendChild(fontSizeContainer);
            }
            if (type === "image" && targetElement?.src) {
                const saveImageBtn = createButton(
                    "save-image-btn",
                    "Save image (Stripped EXIF)",
                    '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>',
                    () =>
                        downloadResource(
                            targetElement.src,
                            `pollinations-image-${Date.now()}.jpg`,
                            saveImageBtn,
                            "image",
                        ),
                );
                buttonContainer.appendChild(saveImageBtn);
            }
            if (type === "audio" && resourceUrl) {
                const saveAudioBtn = createButton(
                    "save-audio-btn",
                    "Save audio",
                    '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"></path><polyline points="17 21 17 13 7 13 7 21"></polyline><polyline points="7 3 7 8 15 8"></polyline></svg>',
                    () =>
                        downloadResource(
                            resourceUrl,
                            `pollinations-audio-${Date.now()}.mp3`,
                            saveAudioBtn,
                            "audio",
                        ),
                );
                buttonContainer.appendChild(saveAudioBtn);
            }
            const hasMetadata =
                params.model ||
                params.prompt ||
                params.seed ||
                params.voice ||
                params.width ||
                params.system ||
                params.private ||
                params.nologo;
            if (hasMetadata) {
                const metadataBtn = createButton(
                    "metadata-btn",
                    "View metadata",
                    '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>',
                    () => {
                        const box = document.getElementById("metadata-box");
                        if (box) {
                            box.classList.toggle("visible");
                            if (box.classList.contains("visible"))
                                box.classList.remove("collapsed");
                            updateMetadataToggleIcon(box);
                        }
                    },
                );
                buttonContainer.appendChild(metadataBtn);
                createMetadataBox(params, type);
            }
            if (buttonContainer.hasChildNodes())
                document.body.appendChild(buttonContainer);
        } catch (error) {
            console.error(
                "Pollinations Enhancer: Error creating common buttons:",
                error,
            );
        }
    }

    function increaseFontSize() {
        const currentScale = parseFloat(GM_getValue(FONT_SIZE_KEY, "1")) || 1;
        const newScale = Math.min(currentScale + 0.1, 2.0).toFixed(1);
        GM_setValue(FONT_SIZE_KEY, newScale);
        applyFontSize();
    }

    function decreaseFontSize() {
        const currentScale = parseFloat(GM_getValue(FONT_SIZE_KEY, "1")) || 1;
        const newScale = Math.max(currentScale - 0.1, 0.7).toFixed(1);
        GM_setValue(FONT_SIZE_KEY, newScale);
        applyFontSize();
    }

    function applyFontSize() {
        const scale = GM_getValue(FONT_SIZE_KEY, "1") || "1";
        const existingStyle = document.getElementById("font-size-style");
        if (existingStyle) existingStyle.remove();

        const styleEl = document.createElement("style");
        styleEl.id = "font-size-style";
        styleEl.textContent = `
            .content-container {
                font-size: calc(17px * ${scale}) !important;
                line-height: 1.5 !important;
                transform: scale(1) !important;
            }
        `;
        document.head.appendChild(styleEl);
    }

    function createButton(id, title, innerHTML, onClick) {
        const btn = document.createElement("div");
        btn.id = id;
        btn.className = "p-btn";
        btn.title = title;
        btn.innerHTML = innerHTML;
        btn.addEventListener("click", onClick);
        btn.style.position = "relative";
        btn.style.margin = "0";
        return btn;
    }

    function flashButton(button, success) {
        if (!button) return;
        const originalColor = button.style.backgroundColor;
        button.style.backgroundColor = success
            ? "var(--success-color)"
            : "var(--error-color)";
        button.style.transform = "scale(1.1)";
        setTimeout(() => {
            if (button) {
                button.style.backgroundColor = originalColor;
                button.style.transform = "scale(1)";
            }
        }, 1000);
    }

    function downloadResource(
        url,
        filename,
        buttonToFlash,
        resourceType = "unknown",
    ) {
        GM_xmlhttpRequest({
            method: "GET",
            url: url,
            responseType: "blob",
            onload: function (response) {
                if (response.status === 200 && response.response) {
                    const originalBlob = response.response;

                    if (
                        resourceType === "image" &&
                        originalBlob.type.startsWith("image/")
                    ) {
                        const img = document.createElement("img");
                        const canvas = document.createElement("canvas");
                        const ctx = canvas.getContext("2d");
                        const objectURL = URL.createObjectURL(originalBlob);

                        img.onload = () => {
                            try {
                                canvas.width = img.naturalWidth;
                                canvas.height = img.naturalHeight;
                                ctx.drawImage(img, 0, 0);

                                let mimeType = originalBlob.type;
                                if (
                                    ![
                                        "image/jpeg",
                                        "image/png",
                                        "image/webp",
                                    ].includes(mimeType)
                                ) {
                                    mimeType = "image/jpeg";
                                    filename = filename.replace(
                                        /\.[^.]+$/,
                                        ".jpg",
                                    );
                                }

                                canvas.toBlob(
                                    (processedBlob) => {
                                        if (processedBlob) {
                                            triggerDownload(
                                                processedBlob,
                                                filename,
                                                buttonToFlash,
                                                true,
                                            );
                                        } else {
                                            triggerDownload(
                                                originalBlob,
                                                filename,
                                                buttonToFlash,
                                                false,
                                            );
                                        }
                                        URL.revokeObjectURL(objectURL);
                                    },
                                    mimeType,
                                    0.92,
                                );
                            } catch (e) {
                                URL.revokeObjectURL(objectURL);
                                triggerDownload(
                                    originalBlob,
                                    filename,
                                    buttonToFlash,
                                    false,
                                );
                            }
                        };

                        img.onerror = () => {
                            URL.revokeObjectURL(objectURL);
                            triggerDownload(
                                originalBlob,
                                filename,
                                buttonToFlash,
                                false,
                            );
                        };

                        img.src = objectURL;
                    } else {
                        triggerDownload(
                            originalBlob,
                            filename,
                            buttonToFlash,
                            true,
                        );
                    }
                } else {
                    if (buttonToFlash) flashButton(buttonToFlash, false);
                    tryDirectDownload(url, filename, buttonToFlash);
                }
            },
            onerror: function (response) {
                if (buttonToFlash) flashButton(buttonToFlash, false);
                tryDirectDownload(url, filename, buttonToFlash);
            },
        });
    }

    function triggerDownload(blob, filename, buttonToFlash, successStatus) {
        try {
            const link = document.createElement("a");
            link.href = URL.createObjectURL(blob);
            link.download = filename;
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            URL.revokeObjectURL(link.href);
            if (buttonToFlash) flashButton(buttonToFlash, successStatus);
        } catch (e) {
            if (buttonToFlash) flashButton(buttonToFlash, false);
        }
    }

    function tryDirectDownload(url, filename, buttonToFlash) {
        try {
            const link = document.createElement("a");
            link.href = url;
            link.download = filename;
            link.target = "_blank";
            link.rel = "noopener noreferrer";
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        } catch (err) {
            if (buttonToFlash) flashButton(buttonToFlash, false);
        }
    }

    function createMetadataBox(params, type) {
        const existingBox = document.getElementById("metadata-box");
        if (existingBox) existingBox.remove();

        const metadataBox = document.createElement("div");
        metadataBox.id = "metadata-box";
        metadataBox.className = "meta-box";

        let contentHTML = "";

        if (params.model) contentHTML += createMetaRow("Model", params.model);
        if (params.prompt)
            contentHTML += createMetaRow("Prompt", params.prompt, true);
        if (params.seed) contentHTML += createMetaRow("Seed", params.seed);
        if (params.private)
            contentHTML += createMetaRow("Private", params.private);
        if (params.json) contentHTML += createMetaRow("JSON Mode", params.json);

        if (type === "image") {
            if (params.width && params.height)
                contentHTML += createMetaRow(
                    "Size",
                    `${params.width} × ${params.height}`,
                );
            if (params.guidance_scale)
                contentHTML += createMetaRow(
                    "Guidance Scale",
                    params.guidance_scale,
                );
            if (params.negative_prompt)
                contentHTML += createMetaRow(
                    "Negative Prompt",
                    params.negative_prompt,
                    true,
                );
            if (params.strength)
                contentHTML += createMetaRow("Strength", params.strength);
            if (params.steps)
                contentHTML += createMetaRow("Steps", params.steps);
            if (params.nologo)
                contentHTML += createMetaRow("No Logo", params.nologo);
        }

        if (type === "audio") {
            if (params.voice)
                contentHTML += createMetaRow("Voice", params.voice);
            if (params.format)
                contentHTML += createMetaRow("Format", params.format);
        }

        if (type === "text") {
            if (params.system)
                contentHTML += createMetaRow("System", params.system, true);
            if (params.language)
                contentHTML += createMetaRow("Language", params.language);
            if (params.modalities)
                contentHTML += createMetaRow("Modalities", params.modalities);
        }

        if (!contentHTML.trim()) return;

        metadataBox.innerHTML = `
            <div class="meta-header" title="Click to toggle details">
                <span>${type.charAt(0).toUpperCase() + type.slice(1)} Parameters</span>
                <span class="toggle-icon">▼</span>
            </div>
            <div class="meta-content">${contentHTML}</div>
        `;

        document.body.appendChild(metadataBox);

        metadataBox.querySelector(".meta-header").addEventListener("click", () => {
            if (metadataBox.classList.contains("visible")) {
                metadataBox.classList.toggle("collapsed");
            } else {
                metadataBox.classList.add("visible");
                metadataBox.classList.remove("collapsed");
            }
            updateMetadataToggleIcon(metadataBox);
        });

        metadataBox
            .querySelectorAll(".copy-btn[data-copy-target]")
            .forEach((copyBtn) => {
                const targetLabel = copyBtn.getAttribute("data-copy-target");
                const paramKey = targetLabel.toLowerCase().replace(" ", "_");
                const textToCopy = params[paramKey];
                if (textToCopy) {
                    copyBtn.addEventListener("click", (e) => {
                        e.stopPropagation();
                        navigator.clipboard
                            .writeText(textToCopy)
                            .then(() => {
                                copyBtn.textContent = "✓";
                                setTimeout(() => {
                                    copyBtn.textContent = "📋";
                                }, 1200);
                            })
                            .catch((err) =>
                                console.error(
                                    `Failed to copy ${targetLabel}:`,
                                    err,
                                ),
                            );
                    });
                } else {
                    copyBtn.style.display = "none";
                }
            });

        updateMetadataToggleIcon(metadataBox);
    }

    function updateMetadataToggleIcon(box) {
        const icon = box?.querySelector(".toggle-icon");
        if (icon)
            icon.textContent = box.classList.contains("collapsed") ? "▼" : "▲";
    }

    function createMetaRow(label, value, addCopyButton = false) {
        if (!value) return "";
        const cleanValue = String(value)
            .replace(/</g, "<")
            .replace(/>/g, ">");
        const copyBtnHTML = addCopyButton
            ? `<span class="copy-btn" title="Copy ${label}" data-copy-target="${label}">📋</span>`
            : "";
        return `<div class="meta-row"><div class="meta-label">${label}:</div><div class="meta-value">${cleanValue}${copyBtnHTML}</div></div>`;
    }

    function sanitizePrompt(text) {
        if (!text) return "";
        try {
            let decoded = text;
            for (let i = 0; i < 3; i++) {
                if (decoded.includes("%")) decoded = decodeURIComponent(decoded);
                else break;
            }
            return decoded.replace(/\+/g, " ").replace(/\uFFFD/gu, "").trim();
        } catch (e) {
            return text.replace(/\+/g, " ").replace(/%20/g, " ").trim();
        }
    }

    function extractUrlParameters() {
        const urlParams = new URLSearchParams(window.location.search);
        const path = window.location.pathname;
        let rawPrompt = "";
        if (urlParams.has("prompt")) {
            rawPrompt = urlParams.get("prompt");
        } else {
            const promptFromPath = decodeURIComponent(path)
                .split("/")
                .filter(Boolean)
                .pop();
            if (promptFromPath) rawPrompt = promptFromPath;
        }

        return {
            prompt: sanitizePrompt(rawPrompt),
            model: urlParams.get("model") || "",
            seed: urlParams.get("seed") || "",
            voice: urlParams.get("voice") || "",
            width: urlParams.get("width") || "",
            height: urlParams.get("height") || "",
            system: sanitizePrompt(urlParams.get("system") || ""),
            private: urlParams.get("private") || "",
            format: urlParams.get("format") || "",
            modalities: urlParams.get("modalities") || "",
            guidance_scale: urlParams.get("guidance_scale") || "",
            negative_prompt: sanitizePrompt(
                urlParams.get("negative_prompt") || "",
            ),
            strength: urlParams.get("strength") || "",
            steps: urlParams.get("steps") || "",
            language: urlParams.get("language") || "",
            json: urlParams.get("json") || "",
            nologo: urlParams.get("nologo") || "",
        };
    }

    function addStyles() {
        GM_addStyle(`
            :root { --text-color: #f0f0f0; --bg-color: #1a1a1a; --accent: #3498db; --accent-hover: #2980b9; --light-bg: #f2f2f2; --light-text: #333333; --light-content-bg: #ffffff; --dark-content-bg: #2d2d2d; --border-color-dark: #444; --border-color-light: #ddd; --button-bg: #333; --button-hover-bg: #444; --success-color: #27ae60; --error-color: #e74c3c; }
            body.theme-light { background-color: var(--light-bg) !important; color: var(--light-text) !important; }
            body.theme-dark { background-color: var(--bg-color) !important; color: var(--text-color) !important; }
            body { transition: background-color 0.3s, color 0.3s; }
            .p-btn { background-color: var(--accent); color: white; border: none; border-radius: 50%; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; cursor: pointer; margin: 5px; transition: all 0.2s; box-shadow: 0 2px 5px rgba(0,0,0,0.2); flex-shrink: 0; }
            .p-btn:hover { background-color: var(--accent-hover); transform: scale(1.05); }
            .p-btn svg { pointer-events: none; }
            .font-size-controls { display: flex; gap: 5px; justify-content: center; }
            .meta-box { position: fixed; bottom: 20px; right: 20px; background-color: rgba(45, 45, 45, 0.9); color: var(--text-color); border-radius: 8px; padding: 12px; max-width: 320px; width: auto; font-size: 13px; line-height: 1.5; z-index: 9998; transition: opacity 0.3s, transform 0.3s, height 0.3s ease-out; box-shadow: 0 4px 15px rgba(0,0,0,0.3); opacity: 0; transform: translateY(10px); pointer-events: none; overflow: hidden; backdrop-filter: blur(3px); }
            body.theme-light .meta-box { background-color: rgba(255, 255, 255, 0.9); color: var(--light-text); }
            .meta-box.visible { opacity: 1; transform: translateY(0); pointer-events: auto; }
            .meta-box.collapsed { height: 24px; padding-top: 5px; padding-bottom: 5px; min-height: 24px; }
            .meta-box.collapsed .meta-content { display: none; }
            .meta-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; cursor: pointer; user-select: none; font-weight: bold; }
            .meta-box.collapsed .meta-header { margin-bottom: 0; }
            .meta-header .toggle-icon { font-size: 16px; padding: 0 5px; }
            .meta-content { margin-top: 5px; }
            .meta-row { display: flex; margin-bottom: 5px; }
            .meta-label { font-weight: 600; width: 70px; color: #aaa; flex-shrink: 0; }
            body.theme-light .meta-label { color: #555; }
            .meta-value { flex: 1; word-break: break-word; }
            .copy-btn { display: inline-block; cursor: pointer; margin-left: 8px; font-size: 14px; opacity: 0.7; transition: opacity 0.2s; }
            .copy-btn:hover { opacity: 1; }
            .preview { position: absolute; display: none; max-width: 350px; background-color: #383838; color: #eee; border-radius: 6px; box-shadow: 0 5px 20px rgba(0, 0, 0, 0.4); padding: 10px 12px; font-size: 13px; z-index: 10001; pointer-events: none; transition: opacity 0.15s ease-in-out; opacity: 0; border: 1px solid rgba(255, 255, 255, 0.1); }
            body.theme-light .preview { background-color: white; color: #333; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15); border: 1px solid #eee; }
            .preview.active { opacity: 1; pointer-events: auto; display: block; }
            .preview-header { display: flex; align-items: center; margin-bottom: 6px; font-weight: 600; color: #f5f5f5; }
            body.theme-light .preview-header { color: #444; }
            .preview-icon { width: 16px; height: 16px; margin-right: 7px; border-radius: 3px; background-color: var(--accent); display: flex; align-items: center; justify-content: center; font-size: 10px; color: white; overflow: hidden; flex-shrink: 0; }
            .preview-icon img { width: 100%; height: 100%; object-fit: cover; }
            .preview-content { line-height: 1.4; max-height: 100px; overflow: hidden; text-overflow: ellipsis; }
            .preview-url { font-size: 11px; color: #aaa; margin-top: 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
            body.theme-light .preview-url { color: #777; }
            body.text-enhanced { font-family: Arial, sans-serif !important; font-size: 17px !important; line-height: 1.5 !important; }
            .content-container { max-width: 850px !important; margin: 20px auto !important; padding: 20px 30px !important; border-radius: 8px !important; }
            body.theme-dark .content-container { background-color: var(--dark-content-bg) !important; box-shadow: 0 3px 10px rgba(0,0,0,0.2); }
            body.theme-light .content-container { background-color: var(--light-content-bg) !important; box-shadow: 0 2px 10px rgba(0,0,0,0.08) !important; }
            .content-container h1, .content-container h2, .content-container h3, .content-container h4, .content-container h5, .content-container h6 { margin-top: 0.8em !important; margin-bottom: 0.3em !important; font-weight: 600; line-height: 1.1; }
            body.theme-dark .content-container h1, body.theme-dark .content-container h2, body.theme-dark .content-container h3 { color: #eee !important; }
            body.theme-light .content-container h1, body.theme-light .content-container h2, body.theme-light .content-container h3 { color: #222 !important; }
            .content-container h3 + .code-block-container { margin-top: 0.25em !important; }
            .content-container h3:has(+ .code-block-container) { margin-bottom: 0.25em !important; }
            .content-container h1 { font-size: 2.0em !important; border-bottom: 1px solid var(--border-color-dark); padding-bottom: 0.2em; }
            .content-container h2 { font-size: 1.6em !important; border-bottom: 1px solid var(--border-color-dark); padding-bottom: 0.2em;}
            .content-container h3 { font-size: 1.3em !important; }
            body.theme-light .content-container h1, body.theme-light .content-container h2 { border-bottom-color: var(--border-color-light); }
            .content-container a { color: var(--accent) !important; text-decoration: none !important; transition: color 0.2s; }
            .content-container a:hover { color: var(--accent-hover) !important; text-decoration: underline !important; }
            .content-container blockquote,
            .content-container .blockquote-single,
            .content-container .blockquote-multi {
                border-left: 4px solid var(--accent) !important;
                padding: 8px 15px !important;
                margin: 0.8em 0 !important;
                background-color: rgba(128,128,128,0.08);
                border-radius: 0 4px 4px 0;
            }
            body.theme-dark .content-container blockquote,
            body.theme-dark .content-container .blockquote-single,
            body.theme-dark .content-container .blockquote-multi {
                color: #ccc !important;
                background-color: rgba(255,255,255,0.05);
            }
            body.theme-light .content-container blockquote,
            body.theme-light .content-container .blockquote-single,
            body.theme-light .content-container .blockquote-multi {
                color: #555 !important;
                background-color: rgba(0,0,0,0.03);
            }
            .content-container ul, .content-container ol { list-style: disc; margin: 0; padding-left: 20px; }
            .content-container ul li, .content-container ol li { margin: 0; padding: 0; line-height: 0.05; }
            .content-container ul ul, .content-container ol ol, .content-container ul ol, .content-container ol ul { margin: 0.1em 0; }
            .code-block-container ul { list-style: none; margin: 0; padding: 0; }
            .code-block-container ul li { margin: 0; }
            .content-container code:not(pre code) { font-family: 'Consolas', 'Monaco', monospace !important; background-color: rgba(128, 128, 128, 0.15) !important; padding: 2px 5px !important; border-radius: 4px !important; font-size: 0.9em; }
            .content-container pre { background-color: #262626 !important; border: 1px solid var(--border-color-dark); border-radius: 6px !important; padding: 15px !important; overflow-x: auto !important; margin: 1em 0 !important; font-family: 'Consolas', 'Monaco', monospace !important; font-size: 0.9em; line-height: 1.45; color: #eee; }
            body.theme-light .content-container pre { background-color: #f8f8f8 !important; border-color: var(--border-color-light); color: #333 !important; }
            .content-container pre code { background-color: transparent !important; padding: 0 !important; border-radius: 0 !important; font-size: inherit; }
            .content-container strong, .content-container b { font-weight: 600 !important; }
            .content-container em, .content-container i { font-style: italic !important; }
            .code-block-container {
                position: relative;
                background-color: #1e1e1e !important;
                border: 1px solid var(--border-color-dark);
                border-radius: 6px !important;
                margin: 0.50em 0 !important;
                padding: 0 !important;
                overflow: hidden !important;
            }
            body.theme-light .code-block-container {
                background-color: #ffffff !important;
                border-color: var(--border-color-light);
            }
            .code-header {
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 8px 12px;
                background: linear-gradient(90deg, rgba(30,30,30,1) 0%, rgba(45,45,45,1) 100%);
                border-bottom: 1px solid #444;
                font-family: 'Consolas', 'Monaco', monospace !important;
                font-size: 12px;
            }
            body.theme-light .code-header {
                background: linear-gradient(90deg, rgba(245,245,245,1) 0%, rgba(235,235,235,1) 100%);
                border-bottom: 1px solid #ddd;
            }
            .code-language {
                color: #aaa;
                text-transform: lowercase;
                font-weight: bold;
            }
            body.theme-light .code-language {
                color: #666;
            }
            .code-copy-btn {
                background: rgba(255,255,255,0.1);
                border: 1px solid rgba(255,255,255,0.3);
                color: #fff;
                font-size: 11px;
                padding: 4px 10px;
                border-radius: 4px;
                cursor: pointer;
                transition: all 0.2s;
                font-weight: bold;
                text-transform: uppercase;
                letter-spacing: 0.5px;
            }
            body.theme-light .code-copy-btn {
                background: rgba(0,0,0,0.05);
                border: 1px solid rgba(0,0,0,0.2);
                color: #333;
            }
            .code-copy-btn:hover {
                background-color: rgba(255,255,255,0.2);
                transform: translateY(-1px);
                box-shadow: 0 2px 5px rgba(0,0,0,0.2);
            }
            body.theme-light .code-copy-btn:hover {
                background-color: rgba(0,0,0,0.1);
                color: black;
            }
            .code-block-container code {
                display: block;
                padding: 15px !important;
                overflow-x: auto !important;
                font-family: 'Consolas', 'Monaco', monospace !important;
                font-size: 0.9em;
                line-height: 1.45;
                color: #e9e9e9;
            }
            body.theme-light .code-block-container code {
                color: #2d2d2d !important;
            }
            .inline-code {
                font-family: 'Consolas', 'Monaco', monospace !important;
                background-color: rgba(128, 128, 128, 0.15) !important;
                padding: 2px 5px !important;
                border-radius: 4px !important;
                font-size: 0.9em;
            }
            .content-container .numbered-item {
                font-weight: bold;
                margin: 0 0 0.1em 0;
                line-height: 1.1;
            }
            .content-container .nested-bullet-item {
                margin: 0 0 0.1em 0;
                line-height: 1.1;
                padding-left: 2em;
            }
            .content-container .nested-bullet-item:before {
                content: "◦ ";
                margin-right: 3px;
            }
            .content-container .bullet-item {
                margin: 0 0 0.1em 0;
                line-height: 1.1;
                padding-left: 1em;
            }
            .content-container .bullet-item:before {
                content: "• ";
                margin-right: 3px;
            }
            .content-container hr.markdown-hr {
                border: 0;
                height: 1px;
                background: var(--border-color-dark);
                margin: 0.6em 0;
            }
            body.theme-light .content-container hr.markdown-hr {
                background: var(--border-color-light);
            }
        `);
    }
})();