AI Conversation Navigator

Floating navigator for your prompts in conversations with bookmark feature. Applied for ChatGPT, Gemini, Aistudio, NotebookLM, Google search, Grok, Claude, Mistral, Meta, Deepseek, Kimi, Z.ai (GLM), Chatglm, Ernie, Xiaomimimo, Perplexity, Poe, Deepai, Huggingface, Manus, Longcat, Chatboxai, Lmarena, Quillbot, Canva, Genspark, Character, Spacefrontiers, Scienceos, Evidencehunt, Playground (allen), Paperfigureqa (allen), Liner, Scira, Scispace, Exa.ai, Consensus, Openevidence, Math-gpt.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey, Greasemonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

You will need to install an extension such as Tampermonkey to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey किंवा Violentmonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला Tampermonkey यासारखे एक्स्टेंशन इंस्टॉल करावे लागेल..

ही स्क्रिप्ट इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्क्रिप्ट व्यवस्थापक एक्स्टेंशन इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्क्रिप्ट व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला Stylus सारखे एक्स्टेंशन इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

ही स्टाईल इंस्टॉल करण्यासाठी तुम्हाला एक युझर स्टाईल व्यवस्थापक इंस्टॉल करावे लागेल.

(माझ्याकडे आधीच युझर स्टाईल व्यवस्थापक आहे, मला इंस्टॉल करू द्या!)

// ==UserScript==
// @name         AI Conversation Navigator
// @namespace    https://greasyfork.org
// @version      13.14
// @description  Floating navigator for your prompts in conversations with bookmark feature. Applied for ChatGPT, Gemini, Aistudio, NotebookLM, Google search, Grok, Claude, Mistral, Meta, Deepseek, Kimi, Z.ai (GLM), Chatglm, Ernie, Xiaomimimo, Perplexity, Poe, Deepai, Huggingface, Manus, Longcat, Chatboxai, Lmarena, Quillbot, Canva, Genspark, Character, Spacefrontiers, Scienceos, Evidencehunt, Playground (allen), Paperfigureqa (allen), Liner, Scira, Scispace, Exa.ai, Consensus, Openevidence, Math-gpt.
// @author       Bui Quoc Dung
// @match        https://chatgpt.com/*
// @match        https://gemini.google.com/*
// @match        https://aistudio.google.com/*
// @match        https://notebooklm.google.com/*
// @match        https://www.google.com/*
// @match        https://grok.com/*
// @match        https://claude.ai/*
// @match        https://www.kimi.com/*
// @match        https://chat.mistral.ai/*
// @match        https://www.perplexity.ai/*
// @match        https://www.meta.ai/*
// @match        https://poe.com/*
// @match        https://deepai.org/*
// @match        https://huggingface.co/chat/*
// @match        https://chat.deepseek.com/*
// @match        https://chat.qwen.ai/*
// @match        https://manus.im/*
// @match        https://chat.z.ai/*
// @match        https://longcat.chat/*
// @match        https://chatglm.cn/*
// @match        https://ernie.baidu.com/*
// @match        https://aistudio.xiaomimimo.com/*
// @match        https://web.chatboxai.app/*
// @match        https://lmarena.ai/*
// @match        https://quillbot.com/*
// @match        https://www.canva.com/*
// @match        https://www.genspark.ai/*
// @match        https://character.ai/*
// @match        https://spacefrontiers.org/*
// @match        https://app.scienceos.ai/*
// @match        https://evidencehunt.com/*
// @match        https://playground.allenai.org/*
// @match        https://paperfigureqa.allen.ai/*
// @match        https://app.liner.com/*
// @match        https://scira.ai/*
// @match        https://exa.ai/*
// @match        https://consensus.app/*
// @match        https://www.openevidence.com/*
// @match        https://math-gpt.org/*
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant        GM_listValues
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    const NAV_WIDTH = 250;
    const NAV_MINI_WIDTH = 35;
    const DEBOUNCE_TIME = 500;
    const AISTUDIO_DEBOUNCE_TIME = 200;
    const BOOKMARK_TTL_MS = 5 * 24 * 60 * 60 * 1000;
    const BOOKMARK_PREFIX = 'acn_';
    const MINI_BAR_STORAGE_KEY = 'acn_mini_bar_' + window.location.hostname;

    let activeMessageIndex = -1;
    let lastUrl = window.location.href;
    let lastPromptsContent = "";
    let cachedPrompts = [];
    let urlCheckInterval = null;
    let injectedStyleId = 'nav-shift-styles';
    let bookmarkedMessages = new Set();
    let conversationObserver = null;
    let isClosedByUser = false;
    let tooltipTimeout = null;

    let isMiniBar = GM_getValue(MINI_BAR_STORAGE_KEY, false);
    window.navigatorUpdateTimeout = null;

    // --- UTILS: Bypassing CSP (Trusted Types & Blocked APIs) ---
    function safeSetTimeout(callback, delay) {
        let start = null;
        let frameId;
        function step(timestamp) {
            if (!start) start = timestamp;
            if (timestamp - start >= delay) {
                callback();
            } else {
                frameId = window.requestAnimationFrame(step);
            }
        }
        frameId = window.requestAnimationFrame(step);
        return { clear: () => window.cancelAnimationFrame(frameId) };
    }

    function safeSetInterval(callback, delay) {
        let start = null;
        let frameId;
        function step(timestamp) {
            if (!start) start = timestamp;
            if (timestamp - start >= delay) {
                callback();
                start = timestamp;
            }
            frameId = window.requestAnimationFrame(step);
        }
        frameId = window.requestAnimationFrame(step);
        return { clear: () => window.cancelAnimationFrame(frameId) };
    }
    // -------------------------------------------------------------

    function injectStyles() {
        GM_addStyle(`
            #message-nav { position: fixed; top: 0; right: 0; bottom: 0; z-index: 9999;
                font-family: Calibri, sans-serif; font-size: 17px; color: CanvasText; text-align: left;
                transition: width 0.25s ease, opacity 0.25s ease;  }

            /* 1. SHARED STYLES  */
            #nav-header { display: flex; position: sticky; top: 0; z-index: 10; background-color: Canvas; border-bottom: 1px solid color-mix(in srgb, CanvasText 15%, transparent); }
            #nav-buttons-group { display: flex; }
            .nav-control-btn { background: none; border: none; cursor: pointer; color: inherit; }
            #nav-btn-close, #nav-btn-mini { background: none; border: none; cursor: pointer; color: inherit;
            display: flex; align-items: center; justify-content: center; }
            #nav-message-counter { user-select: none;
            color: color-mix(in srgb, CanvasText 80%, transparent);
            font-weight: normal; display: flex; align-items: center; justify-content: center;}
            @keyframes nav-blink-animation { 0% { opacity: 1;
            } 50% { opacity: 0.1; } 100% { opacity: 1;
            } }
            .nav-blink-active { animation: nav-blink-animation 0.5s ease-in-out 3;
            }

            /* 2. MINI-BAR STYLES */
            #message-nav.mini-bar { width: ${NAV_MINI_WIDTH}px;
            overflow: hidden; opacity: 1; background-color: Canvas; border-left: 1px solid color-mix(in srgb, CanvasText 20%, transparent);
            }
            #message-nav.mini-bar #message-nav-content,
            #message-nav.mini-bar #nav-bookmarks-header { display: none !important;
            }
            #message-nav.mini-bar #nav-header { flex-direction: column; height: 100%;
            padding: 8px 0; gap: 6px; border-bottom: none; overflow: hidden; align-items: center; justify-content: flex-start;
            }
            #message-nav.mini-bar #nav-buttons-group { flex-direction: column; gap: 5px;
            align-items: center; }
            #message-nav.mini-bar .nav-control-btn { font-size: 13px;
            padding: 4px 2px; transform: rotate(90deg); }
            #message-nav.mini-bar #nav-btn-close { position: static;
            width: ${NAV_MINI_WIDTH}px; height: 28px; border-radius: 0; font-size: 15px; }
            #message-nav.mini-bar #nav-btn-mini { position: static;
            background: none !important; opacity: 1 !important; width: ${NAV_MINI_WIDTH}px; height: 32px; font-size: 15px;
            }
            #message-nav.mini-bar #nav-message-counter { flex-direction: column; font-size: 14px;
            padding: 4px 0; text-align: center; gap: 2px; }
            #message-nav.mini-bar .counter-divider { font-size: 0; width: 16px; height: 1px; background-color: color-mix(in srgb, CanvasText 15%, transparent); margin: 1px 0; }

            #nav-mini-msg-wrapper { display: none;
            flex-direction: column; align-items: center; width: 100%; flex: 1; overflow: hidden; margin-top: 2px;
            }
            #message-nav.mini-bar #nav-mini-msg-wrapper { display: flex;
            }
            #nav-mini-msg-numbers { display: flex; flex-direction: column; align-items: center;
            gap: 6px; width: 100%; overflow-y: hidden; scroll-behavior: smooth; flex: 1;
            padding: 4px 0;}
            .nav-mini-scroll-btn { display: none; background: none;
            border: none; cursor: pointer; color: inherit; font-size: 10px; width: 100%; padding: 5px 0; opacity: 0.8; flex-shrink: 0; transition: opacity 0.2s;
            }
            .nav-mini-scroll-btn:hover { opacity: 1;
            background-color: color-mix(in srgb, CanvasText 12%, transparent); }
            .nav-mini-num { font-size: 17px;
            line-height: 1; cursor: pointer; user-select: none; padding: 4px; border-radius: 3px; color: color-mix(in srgb, CanvasText 75%, transparent); width: 100%; text-align: center;
            box-sizing: border-box; transition: font-size 0.2s ease, background-color 0.2s ease; }
            .nav-mini-num:hover { background-color: color-mix(in srgb, CanvasText 12%, transparent);
            color: CanvasText; }
            .nav-mini-num.active { font-size: 22px; font-weight: bold;
            color: CanvasText; background-color: color-mix(in srgb, CanvasText 10%, transparent); }
            .nav-mini-num.bookmarked { background-color: #fff59d;
            color: black; }
            #acn-mini-tooltip {
                position: fixed; z-index: 10000; background: Canvas; color: CanvasText;
                border: 1px solid color-mix(in srgb, CanvasText 20%, transparent);
                border-radius: 6px; padding: 8px 12px; max-width: 300px;
                box-shadow: 0 4px 12px rgba(0,0,0,0.15); pointer-events: auto;
                font-family: Calibri, sans-serif; font-size: 15px; line-height: 1.4;
                word-break: break-word; display: none;
            }
            #acn-mini-tooltip .nav-item-number { cursor: pointer; font-weight: normal; transition: font-weight 0.1s ease; }
            #acn-mini-tooltip .nav-item-number.bookmarked { background-color: #fff59d !important; color: black !important; padding: 2px 4px; border-radius: 3px; }
            #acn-mini-tooltip .nav-file-tag { display: inline-block; font-size: 12px; font-weight: 700; padding: 1px 4px; border-radius: 6px; margin: 0 3px 0 2px; vertical-align: middle; letter-spacing: 0.04em; opacity: 0.9; background-color: color-mix(in srgb, CanvasText 12%, transparent); color: CanvasText; border: 1px solid color-mix(in srgb, CanvasText 20%, transparent); line-height: 1.4; }
            #acn-mini-tooltip .nav-version-controls { display: inline-flex; align-items: center; margin-left: 5px; gap: 2px; border-radius: 10px; padding: 2px; border: 1px solid color-mix(in srgb, CanvasText 20%, transparent); }
            #acn-mini-tooltip .nav-version-btn { background: none; border: none; cursor: pointer; font-size: 12px; padding: 1px 4px; border-radius: 3px; color: inherit; line-height: 1; }
            #acn-mini-tooltip .nav-version-btn:hover { background-color: color-mix(in srgb, CanvasText 10%, transparent); }
            #acn-mini-tooltip .nav-version-btn:disabled { opacity: 0.3; cursor: not-allowed; }
            #acn-mini-tooltip .nav-version-text { font-size: 12px; color: color-mix(in srgb, CanvasText 70%, transparent); margin: 0 2px; }


            /* 3. MAX-BAR STYLES (Header & Content) */
            #message-nav.max-bar { width: ${NAV_WIDTH}px;
            overflow-y: auto; border-left: 1px solid color-mix(in srgb, CanvasText 15%, transparent);
            }
            #message-nav.max-bar #nav-header { align-items: center; justify-content: center;
            padding: 12px 10px 12px 10px; }
            #message-nav.max-bar #nav-buttons-group { gap: 0;
            align-items: center; }
            #message-nav.max-bar .nav-control-btn { font-size: 16px;
            padding: 2px 5px; }
            #message-nav.max-bar #nav-btn-close { position: absolute;
            top: 0; right: 0; font-size: 15px; width: 24px; height: 24px;
            }
            #message-nav.max-bar #nav-btn-mini { position: absolute; top: 0;
            right: 22px; font-size: 15px; width: 24px; height: 24px; }
            #message-nav.max-bar #nav-message-counter { padding: 0;
            min-width: 40px; text-align: center; font-size: 15px; flex-direction: row; gap: 2px; }

            #message-nav.max-bar #message-nav-content { padding: 5px;
            }
            #message-nav.max-bar #nav-list { padding: 0; margin: 0;
            list-style: none; }
            #message-nav.max-bar .nav-list-item { cursor: pointer;
            padding: 5px 0 5px 5px; font-weight: normal; transition: font-weight 0.1s ease;
            }
            #message-nav.max-bar .nav-list-item.active { font-weight: bold !important;
            background-color: color-mix(in srgb, CanvasText 10%, transparent); }
            #message-nav.max-bar .nav-item-number.bookmarked { background-color: #fff59d !important;
            color: black !important; padding: 2px 4px; border-radius: 3px; }
            #message-nav.max-bar .nav-file-tag { display: inline-block;
            font-size: 12px; font-weight: 700; padding: 1px 4px; border-radius: 6px; margin: 0 3px 0 2px; vertical-align: middle; letter-spacing: 0.04em; opacity: 0.9;
            background-color: color-mix(in srgb, CanvasText 12%, transparent); color: CanvasText; border: 1px solid color-mix(in srgb, CanvasText 20%, transparent); line-height: 1.4;
            }
            #message-nav.max-bar .nav-version-controls { display: inline-flex; align-items: center;
            margin-left: 5px; gap: 2px; border-radius: 10px; padding: 2px; border: 1px solid color-mix(in srgb, CanvasText 20%, transparent);
            }
            #message-nav.max-bar .nav-version-btn { background: none; border: none;
            cursor: pointer; font-size: 12px; padding: 1px 4px; border-radius: 3px; color: inherit; line-height: 1;
            }
            #message-nav.max-bar .nav-version-btn:hover { background-color: color-mix(in srgb, CanvasText 10%, transparent);
            }
            #message-nav.max-bar .nav-version-btn:disabled { opacity: 0.3; cursor: not-allowed;
            }
            #message-nav.max-bar .nav-version-text { font-size: 12px;
            color: color-mix(in srgb, CanvasText 70%, transparent); margin: 0 2px; }
            #message-nav.max-bar .nav-bookmarks-container { display: flex;
            align-items: center; gap: 5px; flex-wrap: wrap; padding: 4px 10px; background-color: Canvas; border-bottom: 1px solid color-mix(in srgb, CanvasText 10%, transparent);
            min-height: 34px; box-sizing: border-box; width: 100%; flex-shrink: 0; position: sticky; z-index: 9;
            }
            #message-nav.max-bar .nav-bookmark-item { background-color: #fff59d; color: black;
            padding: 3px 6px; border-radius: 3px; cursor: pointer; font-size: 15px; user-select: none; transition: background-color 0.2s;
            }
            #message-nav.max-bar .nav-bookmark-item:hover { background-color: #fff176;
            }
            #message-nav.max-bar .nav-bookmark-item.active { font-weight: bold; background-color: #ffeb3b;
            }


            /* --- INLINE BADGE STYLES --- */
            .acn-message-inline-badge {  display: inline-block;
            font-size: 12px; font-weight: 700; padding: 1px 4px; border-radius: 6px;
                margin: 0 6px 0 0; vertical-align: middle; letter-spacing: 0.04em;opacity: 0.9;
            user-select: none; transition: background-color 0.2s, color  0.2s;
                background-color: color-mix(in srgb, CanvasText 12%, transparent);color: CanvasText;
                border: 1px solid color-mix(in srgb, CanvasText 20%, transparent); line-height: 1.4;
            }
            .acn-message-inline-badge.bookmarked {
                background-color: #fff59d !important;
                color: black !important;
                border-color: #fbc02d !important;
            }
        `);

        const allUserSelectors = Object.values(SITE_CONFIGS)
            .map(config => config.userMessage?.container)
            .filter(selector => typeof selector === 'string' && selector.length > 0)
            .join(', ');
        if (allUserSelectors) {
            GM_addStyle(`${allUserSelectors} { scroll-margin-top: 10px !important; }`);
        }
    }

    function getAIStudioData() {
        const prompts = [];
        const scrollButtons = document.querySelectorAll('ms-prompt-scrollbar button[id^="scrollbar-item-"]');
        scrollButtons.forEach(btn => {
            const isUser = btn.querySelector('.prompt-scrollbar-dot');
            if (isUser) {
                const text = btn.getAttribute('aria-label');
                if (text) prompts.push({ element: btn, textElement: btn, text: text.trim() });
            }
        });
        return prompts;
    }

    const SITE_CONFIGS = {
        chatgpt: {
            domain: 'chatgpt.com',
            userMessage: {
                container: 'div[data-message-author-role="user"]',
                file: '.p-2 .truncate.font-semibold',
                text: '.user-message-bubble-color',
                image: 'img'
            },
            shiftTarget: '.flex.h-svh.w-screen.flex-col',
            versionControl: {
                container: '.z-0.flex.justify-end',
                versionText: '.tabular-nums',
                prevButton: 'button[aria-label*="Previous response"]',
                nextButton: 'button[aria-label*="Next response"]'
            }
        },
        gemini: {
            domain: 'gemini.google.com',
            userMessage: {
                container: '.user-query-container .user-query-container .user-query-container',
                file: '.new-file-preview-container button[aria-label]',
                text: '.query-text p',
                image: '.preview-image'
            },
            shiftTarget: 'chat-app, .boqOnegoogleliteOgbOneGoogleBar, top-bar-actions',
        },
        aistudio: {
            domain: 'aistudio.google.com',
            customFinder: getAIStudioData,
            useClick: true,
            shiftTarget: '.layout-wrapper',
            fastUpdate: true,
            debounceTime: AISTUDIO_DEBOUNCE_TIME,
        },
        notebooklm: {
            domain: 'notebooklm.google.com',
            userMessage: { container: 'chat-message .from-user-container p' },
            shiftTarget: 'notebook, .boqOnegoogleliteOgbOneGoogleBar',
        },
        googleSearch: {
            domain: 'www.google.com',
            userMessage: { container: '[aria-hidden="false"] [role="heading"][aria-level="2"][jsuid]' },
            shiftTarget: '[jsname="oEQ3x"], header[jsname="kNXmHc"], .eT9Cje',
        },
        grok: {
            domain: 'grok.com',
            userMessage: {
                container: '.relative.group.flex.flex-col.justify-center.items-end',
                file: '.flex.flex-row.flex-wrap.justify-end.gap-2.mt-2',
                text: '.message-bubble',
                image: 'img'
            },
            shiftTarget: 'main',
            versionControl: {
                container: '.relative.group.flex.flex-col.justify-center.items-end .action-buttons',
                versionText: '[class="px-0.5"]',
                prevButton: 'button[aria-label="Previous message"]',
                nextButton: 'button[aria-label="Next message"]'
            }
        },
        claude: {
            domain: 'claude.ai',
            userMessage: {
                container: '.mb-1.mt-6.group',
                file: '[data-testid="file-thumbnail"]',
                fileType: '.uppercase.truncate',
                fileName: 'p',
                image: '[data-testid*="."]',
                text: '[data-testid="user-message"]'
            },
            shiftTarget: '#main-content',
            versionControl: {
                container: '.mb-1.mt-6.group',
                versionText: '.self-center.select-none',
                prevButton: 'button[aria-label="Previous"]',
                nextButton: 'button[aria-label="Next"]'
            }
        },
        mistral: {
            domain: 'chat.mistral.ai',
            userMessage: {
                container: 'div[data-message-author-role="user"] div[dir="auto"]',
                file: '.max-w-2xs',
                image: 'img',
                text: '.select-none'
            },
            shiftTarget: 'main.bg-sidebar-subtle',
            versionControl: {
                container: 'div[data-message-author-role="user"]',
                versionText: '[class*="text-muted"][class*="dark:text-muted"]',
                prevButton: 'button[aria-label*="Previous version"]',
                nextButton: 'button[aria-label*="Next version"]'
            }
        },
        meta: {
            domain: 'meta.ai',
            userMessage: {
                container: '[data-message-type="user"]',
                file: '.mb-1.self-end',
                fileName: '.mb-1.self-end .text-footnote',
                fileType: '.mb-1.self-end .text-text-secondary',
                text: '.relative .text-response',
                image: 'button [alt="Image attachment"]'
            },
            shiftTarget: '[data-slot="sidebar-wrapper"]',
            versionControl: {
                container: '[data-message-type="user"] .min-h-0.min-w-0.items-center',
                versionText: '.tabular-nums',
                prevButton: 'button[aria-label="Previous revision"]',
                nextButton: 'button[aria-label="Next revision"]'
            }
        },
        deepseek: {
            domain: 'chat.deepseek.com',
            userMessage: {
                container: '.d29f3d7d',
                file: '.f3a54b52',
                image: 'img',
                text: '._9663006 .fbb737a4'
            },
            shiftTarget: ' ._2be88ba, ._2bd7b35',
            versionControl: {
                container: '._9663006',
                versionText: '.dd7e4fda',
                prevButton: '.e7367035:first-of-type',
                nextButton: '.e7367035:last-of-type'
            }
        },
        kimi: {
            domain: 'www.kimi.com',
            userMessage: {
                container: '.segment.segment-user',
                file: '.attachment-list .file-card-info-name',
                image: '.image-wrapper.image-detail img',
                text: '.user-content'
            },
            shiftTarget: '.has-sidebar',
            versionControl: {
                container: '.segment-user-actions',
                versionText: '.assistant-page-info',
                prevButton: '.icon-button.assistant-page-item:first-of-type',
                nextButton: '.icon-button.assistant-page-item:last-of-type'
            }
        },
        glm: {
            domain: 'chat.z.ai',
            userMessage: {
                container: '.chat-user',
                file: '.mb-1.truncate',
                image: 'img.object-cover',
                text: '.flex.justify-end.pb-1'
            },
            shiftTarget: '#chat-container',
            versionControl: {
                container: '.chat-user .flex.justify-end.text-gray-600',
                versionText: '.self-center.text-sm.font-semibold.tracking-widest',
                prevButton: '.self-center.p-1.rounded-md.transition:first-of-type',
                nextButton: '.self-center.p-1.rounded-md.transition:last-of-type'
            }
        },
        qwen: {
            domain: 'chat.qwen.ai',
            userMessage: {
                container: '.chat-user-message-container',
                file: '.index-module__file-message___SeOoR',
                fileType: '.fileitem-file-name-ext',
                fileName: '.fileitem-file-name-text',
                image: 'img',
                text: '.chat-user-message'
            },
            shiftTarget: '.desktop-layout-content',
            versionControl: {
                container: '.user-message-footer.ant-flex',
                versionText: '.qwen-chat-ui-packages-siblings-text',
                prevButton: '.anticon.qwen-chat-ui-packages-siblings-active-icon:first-of-type',
                nextButton: '.anticon.qwen-chat-ui-packages-siblings-active-icon:last-of-type'
            }
        },
        chatglm: {
            domain: 'chatglm.cn',
            userMessage: { container: '.question-txt.dots' },
            shiftTarget: '.detail-container',
        },
        ernie: {
            domain: 'ernie.baidu.com',
            userMessage: {
                container: '.roleUser__TCPTqNDW',
                file: '.chat-file-item-card',
                fileType: '.metaDesc__zRkzT0lZ span:first-of-type',
                fileName: '.title__gkcd9NRs',
                image: '.singleImage__BG1t1bGa img',
                text: '#question_text_id'
            },
            shiftTarget: '#root',
            versionControl: {
                container: '.editControls__OdmgmAiJ',
                versionText: '.pageCount__SvI_mTsu',
                prevButton: '.turnIcon__oN1i9Cks:first-of-type',
                nextButton: '.turnIcon__oN1i9Cks:last-of-type'
            },
            reverse: true,
        },
        xiaomimimo: {
            domain: 'aistudio.xiaomimimo.com',
            userMessage: { container: '.relative.inline-block.whitespace-pre-wrap' },
            shiftTarget: '.overflow-hidden.bg-gray-50',
        },
        perplexity: {
            domain: 'perplexity.ai',
            userMessage: { container: 'div.group\\/title' },
            shiftTarget: '#root',
        },
        poe: {
            domain: 'poe.com',
            userMessage: { container: '[class*="ChatMessagesView_tupleGroupContainer"] > div > div:first-child' },
            shiftTarget: '[class*="CanvasSidebarLayout_chat-column"]'
        },
        deepai: {
            domain: 'deepai.org',
            userMessage: { container: '.chatbox' },
            shiftTarget: '.chat-layout-container, .new-chat-button-container, .persistent-compose-area, .nav-items'
        },
        huggingface: {
            domain: 'huggingface.co',
            userMessage: { container: '.disabled.w-full.appearance-none' },
            shiftTarget: '.relative.min-h-0.min-w-0'
        },
        manus: {
            domain: 'manus.im',
            userMessage: { container: '.flex.relative.flex-col.gap-2.items-end' },
            shiftTarget: '.simplebar-content'
        },
        longcat: {
            domain: 'longcat.chat',
            userMessage: { container: '.user-message' },
            shiftTarget: '.content',
        },
        chatboxai: {
            domain: 'web.chatboxai.app',
            userMessage: { container: '.user-msg' },
            shiftTarget: '.h-full.w-full.MuiBox-root'
        },
        lmarena: {
            domain: 'lmarena.ai',
            userMessage: { container: '.justify-end.gap-2' },
            shiftTarget: '#chat-area',
            reverse: true
        },
        quillbot: {
            domain: 'quillbot.com',
            userMessage: { container: 'div.MuiGrid-root.MuiGrid-container > div.MuiGrid-root > p.MuiTypography-root.MuiTypography-bodyMedium.MuiTypography-paragraph' },
            shiftTarget: '#root-client'
        },
        canva: {
            domain: 'www.canva.com',
            userMessage: { container: '#_r_1_ .uV9Uzw .Ka9auQ p' },
            shiftTarget: '#root'
        },
        genspark: {
            domain: 'www.genspark.ai',
            userMessage: { container: '.conversation-item-desc.user' },
            shiftTarget: '.n-config-provider'
        },
        character: {
            domain: 'character.ai',
            userMessage: { container: '.w-full .bg-surface-elevation-3.opacity-90' },
            shiftTarget: '#__next, #chat-header-background',
            reverse: true
        },
        spacefrontiers: {
            domain: 'spacefrontiers.org',
            userMessage: { container: '.inline.whitespace-pre-line' },
            shiftTarget: '#app'
        },
        scienceos: {
            domain: 'app.scienceos.ai',
            userMessage: { container: 'div[data-prompt]' },
            shiftTarget: 'div[data-strategy]',
            versionControl: {
                container: 'div:has(> button[aria-label*="thread"])',
                versionText: 'div[style*="tabular-nums"]',
                prevButton: 'button[aria-label="Previous thread"]',
                nextButton: 'button[aria-label="Next thread"]'
            },
        },
        evidencehunt: {
            domain: 'evidencehunt.com',
            userMessage: { container: '.chat__message:has(.message__user-image) .message__content p' },
            shiftTarget: '.v-main, .v-app-bar, .chat-tab-bar'
        },
        playground: {
            domain: 'playground.allenai.org',
            userMessage: { container: 'div[class*="chat-message"]:nth-of-type(even)' },
            shiftTarget: '.MuiPaper-outlined'
        },
        paperfigure: {
            domain: 'paperfigureqa.allen.ai',
            userMessage: { container: '#chat-scroll-container > div > div:nth-of-type(odd) .MuiPaper-root' },
            shiftTarget: '#root'
        },
        liner: {
            domain: 'app.liner.com',
            userMessage: { container: 'div.gap-positive-300.flex.flex-col p' },
            shiftTarget: '.flex.min-h-0.w-full.flex-1,.flex.relative.w-full.gap-1'
        },
        scira: {
            domain: 'scira.ai',
            userMessage: { container: '.max-w-full .relative' },
            shiftTarget: '.sm\\:max-w-2xl'
        },
        exa: {
            domain: 'exa.ai',
            userMessage: { container: 'div[data-test-id="UserMessage"]' },
            shiftTarget: 'div[data-test-id="ChatPresentation"]'
        },
        consensus: {
            domain: 'consensus.app',
            userMessage: { container: '.flex.flex-col.pt-6.w-full.max-w-page h2' },
            shiftTarget: '#__next'
        },
        openevidence: {
            domain: 'openevidence.com',
            userMessage: { container: '.brandable--query-bar--container form' },
            shiftTarget: '#__next, .brandable--query-bar--container.hide-on-print.follow-up'
        },
        mathgpt: {
            domain: 'math-gpt.org',
            userMessage: { container: '.w-full.flex.items-end.flex-col.pb-8.relative' },
            shiftTarget: '.overflow-x-hidden, .px-2.flex.flex-col.gap-1'
        },
    };
    function getCurrentConfig() {
        const hostname = window.location.hostname;
        for (const key in SITE_CONFIGS) {
            if (hostname.includes(SITE_CONFIGS[key].domain)) return SITE_CONFIGS[key];
        }
        return null;
    }

    const CURRENT_SITE = getCurrentConfig();
    if (!CURRENT_SITE) return;

    function hasUserMessages() {
        if (CURRENT_SITE.customFinder) {
            const prompts = CURRENT_SITE.customFinder();
            return prompts && prompts.length > 0;
        }
        if (!CURRENT_SITE.userMessage || !CURRENT_SITE.userMessage.container) return false;
        return document.querySelectorAll(CURRENT_SITE.userMessage.container).length > 0;
    }

    function getEffectiveNavWidth() {
        return isMiniBar ? NAV_MINI_WIDTH : (CURRENT_SITE.width || NAV_WIDTH);
    }

    const getShiftStyle = (width, selector = '') => {
        if (!selector) return '';
        const selectors = selector.split(',');
        const prefixedSelector = selectors.map(s => `body.navigator-expanded ${s.trim()}`).join(', ');
        return `
            ${selector} { transition: margin-right 0.3s ease, max-width 0.3s ease, margin-left 0.3s ease;
            }
            ${prefixedSelector} { margin-left: 0 !important; margin-right: ${width}px !important;
            max-width: calc(100% - ${width}px) !important; }
        `;
    };
    function updateShiftStyles(shouldInject) {
        let existingStyle = document.getElementById(injectedStyleId);
        if (shouldInject) {
            const currentWidth = getEffectiveNavWidth();
            const cssContent = CURRENT_SITE.shiftTarget ? getShiftStyle(currentWidth, CURRENT_SITE.shiftTarget) : '';
            if (cssContent) {
                if (!existingStyle) {
                    existingStyle = document.createElement('style');
                    existingStyle.id = injectedStyleId;
                    document.head.appendChild(existingStyle);
                }
                existingStyle.textContent = cssContent;
            } else if (existingStyle) {
                existingStyle.remove();
            }
        } else if (!shouldInject && existingStyle) {
            existingStyle.remove();
        }
    }

    function updateBodyClassForLayout() {
        const container = document.getElementById('message-nav');
        if (!container || container.style.display === 'none') {
            document.body.classList.remove('navigator-expanded');
            return;
        }
        document.body.classList.add('navigator-expanded');
    }

    function checkMiniScrollVisibility() {
        safeSetTimeout(() => {
            const numContainer = document.getElementById('nav-mini-msg-numbers');
            const scrollUpBtn = document.getElementById('nav-mini-scroll-up');
            const scrollDownBtn = document.getElementById('nav-mini-scroll-down');
            const nav = document.getElementById('message-nav');

            if (!numContainer || !scrollUpBtn || !scrollDownBtn || !nav) return;

            if (nav.classList.contains('mini-bar') && nav.style.display !== 'none') {
                const hasOverflow = numContainer.scrollHeight > numContainer.clientHeight;
                scrollUpBtn.style.display = hasOverflow ? 'block' : 'none';
                scrollDownBtn.style.display = hasOverflow ? 'block' : 'none';
            }
        }, 250);
    }

    function applyMiniBar(isMini) {
        isMiniBar = isMini;
        if (isMini) {
            GM_setValue(MINI_BAR_STORAGE_KEY, true);
        } else {
            GM_deleteValue(MINI_BAR_STORAGE_KEY);
        }

        const container = document.getElementById('message-nav');
        if (!container) return;
        if (isMini) {
            container.classList.add('mini-bar');
            container.classList.remove('max-bar');
        } else {
            container.classList.remove('mini-bar');
            container.classList.add('max-bar');
            const tooltipEl = document.getElementById('acn-mini-tooltip');
            if(tooltipEl) tooltipEl.style.display = 'none';
        }
        updateShiftStyles(true);
        checkMiniScrollVisibility();
    }

    // --- BOOKMARKS & NAVIGATION LOGIC ---

    function getStorageKey() {
        return BOOKMARK_PREFIX + window.location.hostname + window.location.pathname;
    }

    function saveBookmarks() {
        const key = getStorageKey();
        const data = Array.from(bookmarkedMessages);
        if (data.length === 0) {
            GM_deleteValue(key);
            return;
        }
        const value = Date.now() + '|' + data.sort((a, b) => a - b).join(',');
        GM_setValue(key, value);
    }

    function loadBookmarks() {
        const key = getStorageKey();
        const raw = GM_getValue(key, '');
        if (!raw) {
            bookmarkedMessages = new Set();
            return;
        }
        const sep = raw.indexOf('|');
        if (sep === -1) {
            GM_deleteValue(key);
            bookmarkedMessages = new Set();
            return;
        }
        const savedAt = parseInt(raw.slice(0, sep));
        const age = Date.now() - savedAt;
        if (age > BOOKMARK_TTL_MS) {
            GM_deleteValue(key);
            bookmarkedMessages = new Set();
            return;
        }
        const indices = raw.slice(sep + 1);
        bookmarkedMessages = new Set(indices.split(',').map(Number).filter(n => !isNaN(n) && n > 0));
    }

    function cleanupExpiredBookmarks() {
        try {
            GM_listValues().forEach(key => {
                if (!key.startsWith(BOOKMARK_PREFIX)) return;
                const raw = GM_getValue(key, '');
                if (!raw) {
                    GM_deleteValue(key);
                    return;
                }
                const sep = raw.indexOf('|');
                if (sep === -1) {
                    GM_deleteValue(key);
                    return;
                }
                const age = Date.now() - parseInt(raw.slice(0, sep));
                if (age > BOOKMARK_TTL_MS) GM_deleteValue(key);
            });
        } catch (e) {}
    }

    function toggleBookmark(index) {
        if (bookmarkedMessages.has(index)) {
            bookmarkedMessages.delete(index);
        } else {
            bookmarkedMessages.add(index);
        }
        saveBookmarks();
        updateBookmarkVisuals();
        updateBookmarksHeader();
    }

    function updateBookmarkVisuals() {
        const content = document.getElementById('message-nav-content');
        if (content) {
            const list = content.querySelector('#nav-list');
            if (list) {
                list.querySelectorAll('.nav-list-item').forEach((item, idx) => {
                    const numberContainer = item.querySelector('.nav-item-number');
                    if (numberContainer) {
                        const index = idx + 1;
                        if (bookmarkedMessages.has(index)) {
                            numberContainer.textContent = `${index}`;
                            numberContainer.classList.add('bookmarked');
                        } else {
                            numberContainer.textContent = `${index}.`;
                            numberContainer.classList.remove('bookmarked');
                        }
                    }
                });
            }
        }

        const miniNums = document.getElementById('nav-mini-msg-numbers');
        if (miniNums) {
            miniNums.querySelectorAll('.nav-mini-num').forEach((numEl, idx) => {
                const index = idx + 1;
                if (bookmarkedMessages.has(index)) {
                    numEl.classList.add('bookmarked');
                } else {
                    numEl.classList.remove('bookmarked');
                }
            });
        }

        document.querySelectorAll('.acn-message-inline-badge').forEach(badge => {
            const index = parseInt(badge.textContent);
            if (!isNaN(index)) {
                if (bookmarkedMessages.has(index)) {
                    badge.classList.add('bookmarked');
                } else {
                    badge.classList.remove('bookmarked');
                }
            }
        });
    }

    function updateBookmarksHeader() {
        let bookmarksContainer = document.getElementById('nav-bookmarks-header');
        const header = document.getElementById('nav-header');
        if (!header) return;
        if (bookmarkedMessages.size === 0 || cachedPrompts.length < 6 || isMiniBar) {
            if (bookmarksContainer) bookmarksContainer.remove();
            return;
        }
        if (!bookmarksContainer) {
            bookmarksContainer = document.createElement('div');
            bookmarksContainer.id = 'nav-bookmarks-header';
            bookmarksContainer.className = 'nav-bookmarks-container';
            bookmarksContainer.style.top = header.offsetHeight + 'px';
            header.parentNode.insertBefore(bookmarksContainer, header.nextSibling);
        }
        while (bookmarksContainer.firstChild) bookmarksContainer.removeChild(bookmarksContainer.firstChild);
        Array.from(bookmarkedMessages).sort((a, b) => a - b).forEach(index => {
            const bookmarkItem = document.createElement('span');
            bookmarkItem.className = 'nav-bookmark-item';
            bookmarkItem.textContent = index;
            if (index === activeMessageIndex) bookmarkItem.classList.add('active');
            bookmarkItem.addEventListener('click', () => navigateToMessage(index));
            bookmarksContainer.appendChild(bookmarkItem);
        });
    }

    function updateMessageCounter() {
        const tooltipEl = document.getElementById('acn-mini-tooltip');
        if(tooltipEl) tooltipEl.style.display = 'none';

        const counterSpan = document.getElementById('nav-message-counter');
        if (counterSpan) {
            const current = activeMessageIndex > 0 ? activeMessageIndex : (cachedPrompts.length > 0 ? 1 : 0);
            counterSpan.textContent = '';

            const numSpan = document.createElement('span');
            numSpan.className = 'counter-num';
            numSpan.textContent = current;

            const divSpan = document.createElement('span');
            divSpan.className = 'counter-divider';
            divSpan.textContent = '/';

            const totalSpan = document.createElement('span');
            totalSpan.className = 'counter-total';
            totalSpan.textContent = cachedPrompts.length;

            counterSpan.appendChild(numSpan);
            counterSpan.appendChild(divSpan);
            counterSpan.appendChild(totalSpan);
        }

        const miniNums = document.getElementById('nav-mini-msg-numbers');
        if (miniNums) {
            while (miniNums.firstChild) miniNums.removeChild(miniNums.firstChild);
            for (let i = 1; i <= cachedPrompts.length; i++) {
                const numEl = document.createElement('span');
                numEl.className = 'nav-mini-num';
                numEl.textContent = i;

                if (i === activeMessageIndex) {
                    numEl.classList.add('active');
                    if (isMiniBar) {
                        safeSetTimeout(() => {
                            const parent = numEl.parentNode;
                            if (parent) {
                               parent.scrollTo({ top: numEl.offsetTop - parent.offsetTop - (parent.clientHeight / 2) + (numEl.clientHeight / 2), behavior: 'smooth' });
                            }
                        }, 50);
                    }
                }

                if (bookmarkedMessages.has(i)) numEl.classList.add('bookmarked');

                numEl.addEventListener('click', (e) => {
                    e.stopPropagation();
                    navigateToMessage(i);
                });

                numEl.addEventListener('dblclick', (e) => {
                    e.stopPropagation();
                    toggleBookmark(i);
                    window.getSelection().removeAllRanges();
                });

                numEl.addEventListener('mouseenter', (e) => showMiniTooltip(e, i));
                numEl.addEventListener('mouseleave', (e) => scheduleHideMiniTooltip());

                miniNums.appendChild(numEl);
            }
        }
        checkMiniScrollVisibility();
    }


    function scheduleHideMiniTooltip() {
        tooltipTimeout = setTimeout(() => {
            const tooltipEl = document.getElementById('acn-mini-tooltip');
            if (tooltipEl) tooltipEl.style.display = 'none';
        }, 200);
    }

    function showMiniTooltip(event, index) {
        clearTimeout(tooltipTimeout);
        const tooltipEl = document.getElementById('acn-mini-tooltip');
        if (!tooltipEl || !cachedPrompts[index - 1]) return;

        tooltipEl.textContent = '';

        const prompt = cachedPrompts[index - 1];
        const preview = prompt.text.length > 80 ? prompt.text.slice(0, 80) + '...' : prompt.text;

        const numberContainer = document.createElement('span');
        numberContainer.className = 'nav-item-number';
        if (bookmarkedMessages.has(index)) {
            numberContainer.textContent = `${index}`;
            numberContainer.classList.add('bookmarked');
        } else {
            numberContainer.textContent = `${index}.`;
        }
        numberContainer.addEventListener('click', (e) => {
            e.stopPropagation();
            toggleBookmark(index);
            if (bookmarkedMessages.has(index)) {
                numberContainer.textContent = `${index}`;
                numberContainer.classList.add('bookmarked');
            } else {
                numberContainer.textContent = `${index}.`;
                numberContainer.classList.remove('bookmarked');
            }
        });
        tooltipEl.appendChild(numberContainer);

        const { tag, text: displayText } = parseFileTag(preview);
        if (tag) {
            const tagEl = document.createElement('span');
            tagEl.className = 'nav-file-tag';
            tagEl.textContent = tag;
            tooltipEl.appendChild(tagEl);
        }

        const textSpan = document.createElement('span');
        textSpan.textContent = tag ? displayText : ` ${displayText}`;
        tooltipEl.appendChild(textSpan);

        if (prompt.versionInfo && prompt.versionInfo.hasMultipleVersions) {
            const versionControls = document.createElement('span');
            versionControls.className = 'nav-version-controls';

            const prevVersionBtn = document.createElement('button');
            prevVersionBtn.className = 'nav-version-btn';
            prevVersionBtn.textContent = '◀';
            prevVersionBtn.disabled = !prompt.versionInfo.prevButton || prompt.versionInfo.prevButton.disabled;
            prevVersionBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                if (prompt.versionInfo.prevButton && !prompt.versionInfo.prevButton.disabled) {
                    prompt.versionInfo.prevButton.click();
                    safeSetTimeout(() => updateMessageList(true), 300);
                }
            });

            const versionText = document.createElement('span');
            versionText.className = 'nav-version-text';
            versionText.textContent = `${prompt.versionInfo.currentVersion}/${prompt.versionInfo.totalVersions}`;

            const nextVersionBtn = document.createElement('button');
            nextVersionBtn.className = 'nav-version-btn';
            nextVersionBtn.textContent = '▶';
            nextVersionBtn.disabled = !prompt.versionInfo.nextButton || prompt.versionInfo.nextButton.disabled;
            nextVersionBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                if (prompt.versionInfo.nextButton && !prompt.versionInfo.nextButton.disabled) {
                    prompt.versionInfo.nextButton.click();
                    safeSetTimeout(() => updateMessageList(true), 300);
                }
            });

            versionControls.appendChild(prevVersionBtn);
            versionControls.appendChild(versionText);
            versionControls.appendChild(nextVersionBtn);
            tooltipEl.appendChild(versionControls);
        }

        tooltipEl.addEventListener('mouseenter', () => clearTimeout(tooltipTimeout));
        tooltipEl.addEventListener('mouseleave', () => scheduleHideMiniTooltip());

        tooltipEl.style.visibility = 'hidden';
        tooltipEl.style.display = 'block';
        tooltipEl.style.left = '0px';
        tooltipEl.style.top = '0px';

        const tWidth = tooltipEl.offsetWidth;
        const tHeight = tooltipEl.offsetHeight;

        const viewportWidth = document.documentElement.clientWidth;
        const viewportHeight = document.documentElement.clientHeight;

        const gap = 12;
        let left = event.clientX - tWidth - gap;
        const maxLeft = viewportWidth - NAV_MINI_WIDTH - tWidth - gap;

        if (left > maxLeft) {
            left = maxLeft;
        }

        if (left < 5) left = 5;
        let top = event.clientY - (tHeight / 2);
        if (top + tHeight > viewportHeight) {
            top = viewportHeight - tHeight - 5;
        }
        if (top < 5) top = 5;
        tooltipEl.style.left = `${left}px`;
        tooltipEl.style.top = `${top}px`;
        tooltipEl.style.visibility = 'visible';
    }

    function navigateToMessage(messageIndex) {
        const targetElement = findPromptElementByIndex(messageIndex - 1);
        if (!targetElement) return;
        const list = document.getElementById('nav-list');
        if (list) {
            list.querySelectorAll('.nav-list-item').forEach(li => li.classList.remove('active'));
            const targetItem = list.children[messageIndex - 1];
            if (targetItem) {
                targetItem.classList.add('active');
                targetItem.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
            }
        }
        activeMessageIndex = messageIndex;
        updateMessageCounter();
        updateBookmarksHeader();
        if (CURRENT_SITE.useClick) {
            targetElement.click();
        } else {
            targetElement.scrollIntoView({ behavior: 'instant', block: 'start' });
        }
        const observer = new IntersectionObserver((entries) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    targetElement.classList.add('nav-blink-active');
                    safeSetTimeout(() => targetElement.classList.remove('nav-blink-active'), 2000);
                    observer.unobserve(targetElement);
                }
            });
        }, { threshold: 0.5 });
        observer.observe(targetElement);
    }

    function createContainer() {
        let container = document.getElementById('message-nav');
        if (!container) {
            container = document.createElement('div');
            container.id = 'message-nav';
            if (isMiniBar) {
                container.classList.add('mini-bar');
            } else {
                container.classList.add('max-bar');
            }

            const header = document.createElement('div');
            header.id = 'nav-header';
            const navButtonsContainer = document.createElement('div');
            navButtonsContainer.id = 'nav-buttons-group';
            const firstBtn = document.createElement('button');
            firstBtn.id = 'nav-btn-first';
            firstBtn.className = 'nav-control-btn';
            firstBtn.textContent = '|◀';
            firstBtn.title = "Go to first message";
            firstBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                if (cachedPrompts.length > 0) navigateToMessage(1);
            });
            const prevBtn = document.createElement('button');
            prevBtn.id = 'nav-btn-prev';
            prevBtn.className = 'nav-control-btn';
            prevBtn.textContent = '◀';
            prevBtn.title = "Previous message";
            prevBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                if (cachedPrompts.length > 0 && activeMessageIndex > 1) navigateToMessage(activeMessageIndex - 1);
            });
            const messageCounter = document.createElement('span');
            messageCounter.id = 'nav-message-counter';

            const nextBtn = document.createElement('button');
            nextBtn.id = 'nav-btn-next';
            nextBtn.className = 'nav-control-btn';
            nextBtn.textContent = '▶';
            nextBtn.title = "Next message";
            nextBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                if (cachedPrompts.length > 0 && activeMessageIndex < cachedPrompts.length) navigateToMessage(activeMessageIndex + 1);
            });
            const lastBtn = document.createElement('button');
            lastBtn.id = 'nav-btn-last';
            lastBtn.className = 'nav-control-btn';
            lastBtn.textContent = '▶|';
            lastBtn.title = "Go to last message";
            lastBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                if (cachedPrompts.length > 0) navigateToMessage(cachedPrompts.length);
            });
            navButtonsContainer.appendChild(firstBtn);
            navButtonsContainer.appendChild(prevBtn);
            navButtonsContainer.appendChild(messageCounter);
            navButtonsContainer.appendChild(nextBtn);
            navButtonsContainer.appendChild(lastBtn);

            const miniBtn = document.createElement('button');
            miniBtn.id = 'nav-btn-mini';
            miniBtn.textContent = '▢';
            miniBtn.title = "Toggle mini-bar / max-bar";
            miniBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                applyMiniBar(!isMiniBar);
            });
            const closeBtn = document.createElement('button');
            closeBtn.id = 'nav-btn-close';
            closeBtn.textContent = '✕';
            closeBtn.title = "Close Navigator";

            header.appendChild(closeBtn);
            header.appendChild(miniBtn);
            header.appendChild(navButtonsContainer);
            const miniMsgWrapper = document.createElement('div');
            miniMsgWrapper.id = 'nav-mini-msg-wrapper';

            const miniScrollUp = document.createElement('button');
            miniScrollUp.id = 'nav-mini-scroll-up';
            miniScrollUp.className = 'nav-mini-scroll-btn';
            miniScrollUp.textContent = '△';
            miniScrollUp.title = "Scroll Up";
            miniScrollUp.addEventListener('click', (e) => {
                e.stopPropagation();
                const cont = document.getElementById('nav-mini-msg-numbers');
                if (cont) cont.scrollBy({ top: -60, behavior: 'smooth' });
            });
            const miniMsgNumbers = document.createElement('div');
            miniMsgNumbers.id = 'nav-mini-msg-numbers';

            const miniScrollDown = document.createElement('button');
            miniScrollDown.id = 'nav-mini-scroll-down';
            miniScrollDown.className = 'nav-mini-scroll-btn';
            miniScrollDown.textContent = '▽';
            miniScrollDown.title = "Scroll Down";
            miniScrollDown.addEventListener('click', (e) => {
                e.stopPropagation();
                const cont = document.getElementById('nav-mini-msg-numbers');
                if (cont) cont.scrollBy({ top: 60, behavior: 'smooth' });
            });
            miniMsgWrapper.appendChild(miniScrollUp);
            miniMsgWrapper.appendChild(miniMsgNumbers);
            miniMsgWrapper.appendChild(miniScrollDown);
            header.appendChild(miniMsgWrapper);

            const content = document.createElement('div');
            content.id = 'message-nav-content';

            container.appendChild(header);
            container.appendChild(content);
            document.body.appendChild(container);

            let tooltipEl = document.getElementById('acn-mini-tooltip');
            if (!tooltipEl) {
                tooltipEl = document.createElement('div');
                tooltipEl.id = 'acn-mini-tooltip';
                document.body.appendChild(tooltipEl);
            }

            closeBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                container.style.display = 'none';
                isClosedByUser = true;
                updateBodyClassForLayout();
            });
            updateBodyClassForLayout();
        }
        return container;
    }

    // --- PROMPT DATA & LIST LOGIC ---

    function updateMessageBadges(prompts) {
        prompts.forEach((prompt, index) => {
            const targetEl = prompt.textElement || prompt.element;
            if (!targetEl) return;

            let badge = targetEl.querySelector('.acn-message-inline-badge');
            if (!badge) {
                badge = document.createElement('span');
                badge.className = 'acn-message-inline-badge';
                badge.contentEditable = "false";

                let insertTarget = targetEl;
                while (true) {
                    let firstMeaningful = null;
                    for (let i = 0; i < insertTarget.childNodes.length; i++) {
                        let node = insertTarget.childNodes[i];
                        if (node.nodeType === 3 && node.textContent.trim() === '') continue;
                        firstMeaningful = node;
                        break;
                    }

                    if (firstMeaningful && firstMeaningful.nodeType === 1 && ['P', 'DIV', 'SPAN', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(firstMeaningful.tagName)) {
                        insertTarget = firstMeaningful;
                    } else {
                        break;
                    }
                }

                insertTarget.insertBefore(badge, insertTarget.firstChild);
            }

            badge.textContent = index + 1;

            if (bookmarkedMessages.has(index + 1)) {
                badge.classList.add('bookmarked');
            } else {
                badge.classList.remove('bookmarked');
            }
        });
    }

    function extractCleanText(element) {
        if (!element) return "";
        const clone = element.cloneNode(true);
        const badges = clone.querySelectorAll('.acn-message-inline-badge');
        badges.forEach(b => b.remove());
        return clone.textContent.trim();
    }

    function getVersionInfo(container, vc) {
        if (!container || !vc) return null;
        const versionText = container.querySelector(vc.versionText);
        if (!versionText) return null;
        const text = versionText.textContent.trim();
        let match = text.match(/(\d+)\D+(\d+)/);
        let currentVersion, totalVersions;
        if (match) {
            currentVersion = parseInt(match[1]);
            totalVersions = parseInt(match[2]);
        } else if (text.length >= 2 && /^\d+$/.test(text)) {
            currentVersion = parseInt(text[0]);
            totalVersions = parseInt(text.slice(1));
        } else {
            return null;
        }
        const prevButton = container.querySelector(vc.prevButton);
        const nextButton = container.querySelector(vc.nextButton);
        return {
            currentVersion,
            totalVersions,
            prevButton,
            nextButton,
            hasMultipleVersions: totalVersions > 1
        };
    }

    function findUserPrompts() {
        if (CURRENT_SITE.customFinder) return CURRENT_SITE.customFinder();
        let prompts = [];
        if (!CURRENT_SITE.userMessage || !CURRENT_SITE.userMessage.container) return prompts;
        const userElements = Array.from(document.querySelectorAll(CURRENT_SITE.userMessage.container));
        let containerElements = [];
        if (CURRENT_SITE.versionControl && CURRENT_SITE.versionControl.container) {
            containerElements = Array.from(document.querySelectorAll(CURRENT_SITE.versionControl.container));
        }
        if (CURRENT_SITE.reverse) {
            userElements.reverse();
            containerElements.reverse();
        }
        userElements.forEach((container, index) => {
            let text = "";
            const msgConfig = CURRENT_SITE.userMessage;
            const hasChildSelectors = msgConfig.file || msgConfig.text || msgConfig.image;
            let msgEl = null;

            if (hasChildSelectors) {
                const fileEl = msgConfig.file ? container.querySelector(msgConfig.file) : null;
                msgEl = msgConfig.text ? container.querySelector(msgConfig.text) : null;
                const imageEl = msgConfig.image ? container.querySelector(msgConfig.image) : null;
                let fileTypeEl = null, fileNameEl = null, fileText = "";
                if (fileEl) {
                     const ariaLabel = fileEl.getAttribute('aria-label');
                    if (ariaLabel) {
                        fileText = ariaLabel.trim();
                    } else {
                        if (msgConfig.fileType) fileTypeEl = fileEl.querySelector(msgConfig.fileType);
                        if (msgConfig.fileName) fileNameEl = fileEl.querySelector(msgConfig.fileName);
                        fileText = fileNameEl ? extractCleanText(fileNameEl) : extractCleanText(fileEl);
                    }
                }
                const msgText = msgEl ? extractCleanText(msgEl) : "";
                let fileExt = "";
                if (fileTypeEl) {
                    fileExt = fileTypeEl.textContent.trim().toLowerCase();
                } else if (fileText) {
                    const m = fileText.match(/\.([a-z0-9]+)[^a-z0-9]*$/i);
                    fileExt = m ? m[1].toLowerCase() : "";
                }
                const imageExtensions = ['.png', '.jpg', '.jpeg', '.webp', '.gif', '.bmp'];
                const isImageFile = imageExtensions.some(ext => fileText.toLowerCase().endsWith(ext)) || imageExtensions.some(ext => ext.slice(1) === fileExt);
                const hasRealImage = !!imageEl || isImageFile;
                const hasDocument = (fileText && !isImageFile) || (fileExt && !isImageFile);
                const fileTag = fileExt ? `[${fileExt}]` : "[file]";
                const combinedTag = fileExt ? `[${fileExt}+img]` : "[file+img]";
                if (msgText) {
                    if (hasRealImage && !hasDocument) text = `[img] ${msgText}`;
                    else if (hasDocument && !hasRealImage) text = `${fileTag} ${msgText}`;
                    else if (hasRealImage && hasDocument) text = `${combinedTag} ${msgText}`;
                    else text = msgText;
                } else {
                    if (hasRealImage && !hasDocument) text = `[img] ${fileText || ""}`.trim() || "[img]";
                    else if (hasDocument && !hasRealImage) text = `${fileTag} ${fileText}`;
                    else if (hasRealImage && hasDocument) text = `${combinedTag} ${fileText}`;
                    else text = "[file]";
                }
            } else {
                text = extractCleanText(container);
                if (!text && (container.querySelector('img') || container.querySelector('canvas') || container.querySelector('svg'))) {
                    text = "[img]";
                }
            }
            if (text) {
                const promptData = { element: container, textElement: msgEl || container, text };
                if (CURRENT_SITE.versionControl && containerElements[index]) {
                    const versionInfo = getVersionInfo(containerElements[index], CURRENT_SITE.versionControl);
                    if (versionInfo) promptData.versionInfo = versionInfo;
                }
                prompts.push(promptData);
            }
        });
        return prompts;
    }

    function findPromptElementByIndex(targetIndex) {
        if (CURRENT_SITE.customFinder) {
            const prompts = CURRENT_SITE.customFinder();
            return prompts[targetIndex] ? prompts[targetIndex].element : null;
        }
        if (!CURRENT_SITE.userMessage || !CURRENT_SITE.userMessage.container) return null;
        const elements = Array.from(document.querySelectorAll(CURRENT_SITE.userMessage.container));
        if (CURRENT_SITE.reverse) elements.reverse();
        return elements[targetIndex] || null;
    }

    function parseFileTag(rawText) {
        const match = rawText.match(/^\[([^\]]+)\]\s*/);
        if (!match) return { tag: null, text: rawText };
        return { tag: match[1], text: rawText.slice(match[0].length) };
    }

    function createListItem(prompt, index) {
        const listItem = document.createElement('li');
        listItem.className = 'nav-list-item';
        if (index === activeMessageIndex) listItem.classList.add('active');
        const preview = prompt.text.length > 80 ? prompt.text.slice(0, 80) + '...' : prompt.text;
        const numberContainer = document.createElement('span');
        numberContainer.className = 'nav-item-number';
        if (bookmarkedMessages.has(index)) {
            numberContainer.textContent = `${index}`;
            numberContainer.classList.add('bookmarked');
        } else {
            numberContainer.textContent = `${index}.`;
        }
        numberContainer.addEventListener('click', (e) => {
            e.stopPropagation();
            toggleBookmark(index);
        });
        listItem.appendChild(numberContainer);
        const { tag, text: displayText } = parseFileTag(preview);
        if (tag) {
            const tagEl = document.createElement('span');
            tagEl.className = 'nav-file-tag';
            tagEl.textContent = tag;
            listItem.appendChild(tagEl);
        }
        const textSpan = document.createElement('span');
        textSpan.textContent = tag ? displayText : ` ${displayText}`;
        listItem.appendChild(textSpan);
        if (prompt.versionInfo && prompt.versionInfo.hasMultipleVersions) {
            const versionControls = document.createElement('span');
            versionControls.className = 'nav-version-controls';
            const prevVersionBtn = document.createElement('button');
            prevVersionBtn.className = 'nav-version-btn';
            prevVersionBtn.textContent = '◀';
            prevVersionBtn.disabled = !prompt.versionInfo.prevButton || prompt.versionInfo.prevButton.disabled;
            prevVersionBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                if (prompt.versionInfo.prevButton && !prompt.versionInfo.prevButton.disabled) {
                    prompt.versionInfo.prevButton.click();
                    safeSetTimeout(() => updateMessageList(true), 300);
                }
            });
            const versionText = document.createElement('span');
            versionText.className = 'nav-version-text';
            versionText.textContent = `${prompt.versionInfo.currentVersion}/${prompt.versionInfo.totalVersions}`;
            const nextVersionBtn = document.createElement('button');
            nextVersionBtn.className = 'nav-version-btn';
            nextVersionBtn.textContent = '▶';
            nextVersionBtn.disabled = !prompt.versionInfo.nextButton || prompt.versionInfo.nextButton.disabled;
            nextVersionBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                if (prompt.versionInfo.nextButton && !prompt.versionInfo.nextButton.disabled) {
                    prompt.versionInfo.nextButton.click();
                    safeSetTimeout(() => updateMessageList(true), 300);
                }
            });
            versionControls.appendChild(prevVersionBtn);
            versionControls.appendChild(versionText);
            versionControls.appendChild(nextVersionBtn);
            listItem.appendChild(versionControls);
        }
        textSpan.addEventListener('click', () => navigateToMessage(index));
        return listItem;
    }

    function updateMessageList(forceUpdate = false) {
        const currentUrl = window.location.href;
        let container = document.getElementById('message-nav');
        if (currentUrl !== lastUrl) {
            lastUrl = currentUrl;
            lastPromptsContent = "";
            activeMessageIndex = -1;
            cachedPrompts = [];
            bookmarkedMessages.clear();
            loadBookmarks();
            isClosedByUser = false;
            forceUpdate = true;
        }
        const shouldShow = hasUserMessages();
        updateShiftStyles(shouldShow);
        if (!shouldShow || isClosedByUser) {
            if (container) container.style.display = 'none';
            document.body.classList.remove('navigator-expanded');
            updateBodyClassForLayout();
            return;
        }
        const activeContainer = createContainer();
        activeContainer.style.display = 'block';
        updateBodyClassForLayout();
        const content = document.getElementById('message-nav-content');
        if (!content) return;
        let list = document.getElementById('nav-list');
        if (!list) {
            list = document.createElement('ul');
            list.id = 'nav-list';
            content.appendChild(list);
        }
        const prompts = findUserPrompts();

        updateMessageBadges(prompts);

        const currentPromptsContent = prompts.map(p => p.text).join('|');
        if (!forceUpdate && currentPromptsContent === lastPromptsContent) return;
        lastPromptsContent = currentPromptsContent;
        cachedPrompts = prompts;
        while (list.firstChild) list.removeChild(list.firstChild);
        prompts.forEach((prompt, index) => list.appendChild(createListItem(prompt, index + 1)));
        updateMessageCounter();
        updateBookmarksHeader();
    }

    function startUrlWatcher() {
        if (!CURRENT_SITE.fastUpdate) return;
        if (urlCheckInterval) urlCheckInterval.clear();
        urlCheckInterval = safeSetInterval(() => {
            if (window.location.href !== lastUrl) updateMessageList(true);
        }, 300);
    }

    function observeConversation() {
        if (conversationObserver) conversationObserver.disconnect();
        const debounceTime = CURRENT_SITE.debounceTime || DEBOUNCE_TIME;
        conversationObserver = new MutationObserver(() => {
            if (window.navigatorUpdateTimeout) window.navigatorUpdateTimeout.clear();
            window.navigatorUpdateTimeout = safeSetTimeout(() => updateMessageList(), debounceTime);
        });
        conversationObserver.observe(document.body, { childList: true, subtree: true });
        window.addEventListener('popstate', () => {
            lastPromptsContent = "";
            cachedPrompts = [];
            updateMessageList(true);
        });
        const originalPushState = history.pushState;
        history.pushState = function () {
            originalPushState.apply(this, arguments);
            lastPromptsContent = "";
            cachedPrompts = [];
            safeSetTimeout(() => updateMessageList(true), 100);
        };
    }

    window.addEventListener('resize', () => {
        if (isMiniBar) checkMiniScrollVisibility();
    });
    injectStyles();
    safeSetTimeout(() => {
        cleanupExpiredBookmarks();
        loadBookmarks();
        updateMessageList(true);
        applyMiniBar(isMiniBar);
        startUrlWatcher();
    }, 1000);
    observeConversation();
})();