Rapidbooru

이미지/태그 우클릭 프리뷰 기능, 편리한 태그 복사

// ==UserScript==
// @name         Rapidbooru
// @name:ko      Rapidbooru
// @namespace    Violentmonkey Scripts
// @match        *://danbooru.donmai.us/*
// @grant        none
// @version      250710.2
// @author       -
// @license      MIT
// @description  이미지/태그 우클릭 프리뷰 기능, 편리한 태그 복사
// @icon         https://i.imgur.com/FxoAjfI.png
// ==/UserScript==

(function() {
    'use strict';

    // 프리뷰 및 관련 태그 페이지에서 사용할 태그 리스트
    let selectedTags = [];
    let relatedPageSelectedTags = [];
    // [추가] 사이드바 태그 선택 임시 리스트
    let sidebarSelectedTags = [];

    // 태그 카테고리별 색상 매핑 (사이드바 태그 컨테이너용)
    const tagColors = {
        artist: '#e67e22',
        copyright: '#2980b9',
        character: '#8e44ad',
        general: '#2ecc71',
        meta: '#95a5a6'
    };

    // CSS 스타일 추가
    function addStyles() {
        const style = document.createElement('style');
        style.textContent = `
            #rapidbooru-settings-btn {
                position: fixed;
                bottom: 20px;
                right: 20px;
                width: 50px;
                height: 50px;
                background: var(--rapidbooru-accent-color);
                border: none;
                border-radius: 50%;
                color: var(--rapidbooru-text-color);
                display: flex;
                align-items: center;
                justify-content: center;
                cursor: pointer;
                z-index: 10002;
                box-shadow: 0 4px 8px rgba(0,0,0,0.2);
                transition: all 0.3s ease;
            }
            #rapidbooru-settings-btn:hover {
                background: var(--rapidbooru-accent-hover-color);
                transform: translateY(-2px);
            }

            /* Consolas 폰트 적용 */
            * {
                font-family: 'Consolas', 'Monaco', 'Lucida Console', monospace !important;
            }

            /* 버튼 스타일 개선 */
            .ui-button, button, input[type="submit"], input[type="button"], .button {
                background: linear-gradient(135deg, var(--rapidbooru-accent-color) 0%, var(--rapidbooru-accent-hover-color) 100%) !important;
                border: none !important;
                border-radius: 6px !important;
                color: var(--rapidbooru-text-color) !important;
                padding: 8px 16px !important;
                margin: 4px !important;
                cursor: pointer !important;
                transition: all 0.3s ease !important;
                font-weight: 500 !important;
                box-shadow: 0 2px 4px rgba(0,0,0,0.1) !important;
            }

            .ui-button:hover, button:hover, input[type="submit"]:hover, input[type="button"]:hover, .button:hover {
                transform: translateY(-2px) !important;
                box-shadow: 0 4px 8px rgba(0,0,0,0.2) !important;
                background: linear-gradient(135deg, var(--rapidbooru-accent-hover-color) 0%, var(--rapidbooru-accent-color) 100%) !important;
            }

            /* 네비게이션 버튼 정렬 */
            .navbar, .nav, .navigation {
                display: flex !important;
                align-items: center !important;
                gap: 8px !important;
                flex-wrap: wrap !important;
            }

            /* 검색 폼 정렬 */
            .search-form, #search-form {
                display: flex !important;
                align-items: center !important;
                gap: 8px !important;
                margin: 10px 0 !important;
            }

            /* 페이지네이션 정렬 */
            .paginator, .pagination {
                display: flex !important;
                justify-content: center !important;
                align-items: center !important;
                gap: 4px !important;
                margin: 20px 0 !important;
            }

            /* 프리뷰 오버레이 스타일 */
            .rapidbooru-overlay {
                position: fixed;
                top: 0;
                left: 0;
                width: 100vw;
                height: 100vh;
                background: rgba(0, 0, 0, 0.8);
                backdrop-filter: blur(10px);
                z-index: 10000;
                display: flex;
                justify-content: center;
                align-items: center;
                opacity: 0;
                transition: opacity 0.3s ease;
            }

            .rapidbooru-overlay.show {
                opacity: 1;
            }

            .rapidbooru-preview {
                width: 75vw;
                height: 75vh;
                background: var(--rapidbooru-bg-color);
                border-radius: 12px;
                box-shadow: 0 20px 40px rgba(0,0,0,0.5);
                display: flex;
                overflow: hidden;
                position: relative;
            }

            .rapidbooru-close,
            .rapidbooru-newtab {
                position: absolute;
                top: 15px;
                width: 40px;
                height: 40px;
                border-radius: 50%;
                background: rgba(255,255,255,0.2);
                border: none;
                color: var(--rapidbooru-text-color);
                font-size: 24px;
                display: flex;
                align-items: center;
                justify-content: center;
                cursor: pointer;
                z-index: 10001;
                transition: background 0.3s ease;
            }
            .rapidbooru-close:hover,
            .rapidbooru-newtab:hover {
                background: rgba(255,255,255,0.3);
            }
            .rapidbooru-close {
                right: 15px;
            }
            .rapidbooru-newtab {
                right: 61px;
            }
            .rapidbooru-newtab svg {
                display: block;
            }

            .rapidbooru-tags {
                width: 40%;
                padding: 20px;
                background: var(--rapidbooru-secondary-bg-color);
                overflow-y: auto;
                border-right: 1px solid var(--rapidbooru-border-color);
            }

            .rapidbooru-content {
                width: 60%;
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                padding: 20px;
                position: relative;
            }

            .rapidbooru-image {
                max-width: 100%;
                max-height: 100%;
                object-fit: contain;
                border-radius: 8px;
            }

            .rapidbooru-wiki {
                width: 100%;
                height: 80%;
                border: none;
                border-radius: 8px;
                background: white;
            }

            .rapidbooru-buttons {
                position: absolute;
                bottom: 20px;
                right: 20px;
                display: flex;
                gap: 10px;
            }

            .rapidbooru-btn {
                background: linear-gradient(135deg, var(--rapidbooru-accent-color) 0%, var(--rapidbooru-accent-hover-color) 100%);
                border: none;
                border-radius: 6px;
                color: var(--rapidbooru-text-color);
                padding: 10px 20px;
                cursor: pointer;
                font-weight: 500;
                transition: all 0.3s ease;
                text-decoration: none;
                display: inline-block;
            }

            .rapidbooru-btn:hover {
                transform: translateY(-2px);
                box-shadow: 0 4px 8px rgba(0,0,0,0.2);
                background: linear-gradient(135deg, var(--rapidbooru-accent-hover-color) 0%, var(--rapidbooru-accent-color) 100%);
            }

            /* 태그 카테고리 박스 스타일 */
            .rapidbooru-category-box {
                margin-bottom: 10px;
                padding: 8px 12px;
                background: var(--rapidbooru-secondary-bg-color);
                border-radius: 4px;
                border-left: 4px solid var(--rapidbooru-accent-color);
                font-size: 12px;
                color: var(--rapidbooru-text-color);
                font-family: 'Consolas', monospace;
                min-height: 20px;
                display: flex;
                align-items: center;
                gap: 8px;
            }

            .rapidbooru-category-tags-wrapper {
                flex-grow: 1;
                word-break: break-word;
            }

            .rapidbooru-category-copy-btn {
                flex-shrink: 0;
                width: 28px;
                height: 28px;
                background: #555 !important;
                padding: 0 !important;
                margin: 0 !important;
                display: flex;
                align-items: center;
                justify-content: center;
                box-shadow: none !important;
            }

            .rapidbooru-category-copy-btn:hover {
                background: #666 !important;
                transform: translateY(-1px) !important;
                box-shadow: 0 2px 4px rgba(0,0,0,0.2) !important;
            }

            .rapidbooru-category-copy-btn.copied,
            .rapidbooru-category-copy-btn.copied:hover {
                background: #28a745 !important;
                transform: translateY(0) !important;
            }

            .rapidbooru-category-copy-btn svg {
                width: 16px;
                height: 16px;
                fill: var(--rapidbooru-text-color);
            }

            .rapidbooru-category-label {
                color: var(--rapidbooru-accent-color);
                font-weight: bold;
                margin-right: 5px;
            }

            /* 태그 버튼 스타일 */
            .rapidbooru-tag-button {
                display: inline-block;
                background: var(--rapidbooru-border-color);
                color: var(--rapidbooru-text-color);
                padding: 6px 10px;
                margin: 3px;
                border-radius: 4px;
                font-size: 12px;
                cursor: pointer;
                transition: all 0.3s ease;
                border: 2px solid transparent;
                font-family: 'Consolas', monospace;
                user-select: none;
                text-decoration: none;
            }

            .rapidbooru-tag-button:hover {
                background: #555;
                transform: translateY(-1px);
            }

            .rapidbooru-tag-button.selected {
                background: var(--rapidbooru-accent-color);
                border-color: var(--rapidbooru-accent-hover-color);
                box-shadow: 0 2px 4px rgba(102, 126, 234, 0.3);
            }

            .rapidbooru-tag-button.selected:hover {
                background: var(--rapidbooru-accent-hover-color);
            }

            /* 카테고리 태그(artist/style/character) 링크는 선택 효과 없음 */
            .rapidbooru-category-tags-wrapper a.rapidbooru-tag-button.selected {
                background: var(--rapidbooru-border-color) !important;
                border-color: transparent !important;
                box-shadow: none !important;
            }
            .rapidbooru-category-tags-wrapper a.rapidbooru-tag-button:hover {
                background: #555 !important;
            }

            /* 메인 태그 컨테이너 */
            .rapidbooru-main-tags {
                background: var(--rapidbooru-bg-color);
                padding: 15px;
                border-radius: 6px;
                margin-top: 10px;
                max-height: 200px;
                overflow-y: auto;
            }

            /* 복사 버튼 개선 */
            .rapidbooru-copy-btn {
                margin-top: 15px;
                background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
                border: none;
                color: var(--rapidbooru-text-color);
                padding: 10px 20px;
                border-radius: 6px;
                cursor: pointer;
                font-family: 'Consolas', monospace;
                font-weight: 500;
                transition: all 0.3s ease;
                width: 100%;
            }

            .rapidbooru-copy-btn:hover {
                transform: translateY(-2px);
                box-shadow: 0 4px 8px rgba(40, 167, 69, 0.3);
                background: linear-gradient(135deg, #218838 0%, #1e7e34 100%);
            }

            .rapidbooru-copy-btn.copied {
                background: linear-gradient(135deg, #ffc107 0%, #e0a800 100%);
            }

            /* 액션 버튼 컨테이너 */
            .rapidbooru-action-buttons {
                display: flex;
                gap: 10px;
                margin-top: 15px;
            }
            .rapidbooru-action-buttons .rapidbooru-copy-btn {
                width: auto; /* Override width */
                flex-grow: 1; /* Allow buttons to grow */
            }

            /* Related Tags 페이지용 태그 버튼 스타일 */
            #rapidbooru-related-tags-buttons .rapidbooru-tag-button {
                background: #fbeded;
                color: #495057;
                border: 1px solid #f5b8b8;
                padding: 4px 8px;
                margin: 2px;
            }

            #rapidbooru-related-tags-buttons .rapidbooru-tag-button.selected {
                background: #f5b8b8;
                color: #212529;
                border-color: #e5a7a7;
            }

            /* I'm Feeling Lucky! 버튼 스타일 */
            #rapidbooru-lucky-btn {
                position: fixed;
                top: 20px;
                right: 20px;
                z-index: 10003;
                width: 180px;
                height: 50px;
                background: var(--rapidbooru-accent-color, #8454cc);
                color: var(--rapidbooru-text-color, #fff);
                border: none;
                border-radius: 25px;
                box-shadow: 0 4px 8px rgba(0,0,0,0.2);
                font-weight: bold;
                font-size: 16px;
                cursor: pointer;
                display: flex;
                align-items: center;
                justify-content: center;
                transition: all 0.3s;
                gap: 8px;
            }

            #rapidbooru-lucky-btn:hover {
                background: var(--rapidbooru-accent-hover-color, #56687a);
            }

            #rapidbooru-lucky-btn:disabled {
                background: #aaa;
                cursor: not-allowed;
            }
        `;
        document.head.appendChild(style);
    }

    // 태그를 카테고리별로 분류하는 함수
    function categorizeTags(tags, postData) {
        const categories = {
            artist: [],
            copyright: [],
            character: [],
            general: [],
            meta: []
        };

        if (postData) {
            // API 데이터에서 카테고리 정보 사용
            const tagString = postData.tag_string || '';
            const artistTags = postData.tag_string_artist ? postData.tag_string_artist.split(' ') : [];
            const copyrightTags = postData.tag_string_copyright ? postData.tag_string_copyright.split(' ') : [];
            const characterTags = postData.tag_string_character ? postData.tag_string_character.split(' ') : [];
            const generalTags = postData.tag_string_general ? postData.tag_string_general.split(' ') : [];
            const metaTags = postData.tag_string_meta ? postData.tag_string_meta.split(' ') : [];

            categories.artist = artistTags.filter(tag => tag.length > 0);
            categories.copyright = copyrightTags.filter(tag => tag.length > 0);
            categories.character = characterTags.filter(tag => tag.length > 0);
            categories.general = generalTags.filter(tag => tag.length > 0);
            categories.meta = metaTags.filter(tag => tag.length > 0);
        } else {
            // 기본적으로 모든 태그를 general로 분류
            categories.general = tags.filter(tag => tag.length > 0);
        }

        return categories;
    }

    // 태그 버튼들을 생성하는 함수
    function createTagButtons(tags) {
        const container = document.createElement('div');
        container.className = 'rapidbooru-main-tags';

        tags.forEach((tag, index) => {
            const button = document.createElement('span');
            button.className = 'rapidbooru-tag-button';
            button.textContent = tag.replace(/_/g, ' ') + (index < tags.length - 1 ? ', ' : '');
            button.dataset.tag = tag.replace(/_/g, ' ') + (index < tags.length - 1 ? ', ' : '');

            button.addEventListener('click', function() {
                const tagText = this.dataset.tag;

                if (this.classList.contains('selected')) {
                    // 선택 해제
                    this.classList.remove('selected');
                    const index = selectedTags.indexOf(tagText);
                    if (index > -1) {
                        selectedTags.splice(index, 1);
                    }
                } else {
                    // 선택
                    this.classList.add('selected');
                    selectedTags.push(tagText);
                }
            });

            container.appendChild(button);
        });

        return container;
    }

    // 카테고리 태그 링크들을 생성하는 함수
    function createCategoryTagLinks(categoryName, tags) {
        const box = document.createElement('div');
        box.className = 'rapidbooru-category-box';

        const tagsWrapper = document.createElement('div');
        tagsWrapper.className = 'rapidbooru-category-tags-wrapper';

        const label = document.createElement('span');
        label.className = 'rapidbooru-category-label';
        label.textContent = `${categoryName}:`;
        // [추가] 카테고리별 색상 적용
        if (categoryName === 'artist') label.style.color = '#dd5555';
        else if (categoryName === 'copyright') label.style.color = '#8454cc';
        else if (categoryName === 'character') label.style.color = '#2ab367';

        tagsWrapper.appendChild(label);

        if (tags.length === 0) {
            const noneText = document.createTextNode(' None');
            tagsWrapper.appendChild(noneText);
        } else {
            tags.forEach((tag, index) => {
                const link = document.createElement('a');
                link.className = 'rapidbooru-tag-button';

                const displayTag = tag.replace(/_/g, ' ');
                const urlTag = tag;

                link.textContent = displayTag + (index < tags.length - 1 ? ', ' : '');
                link.href = `https://danbooru.donmai.us/posts?tags=${encodeURIComponent(urlTag)}`;
                link.target = '_blank';
                link.onclick = (e) => e.stopPropagation();

                tagsWrapper.appendChild(link);
            });
        }

        box.appendChild(tagsWrapper);

        if (tags.length > 0) {
            const copyBtn = document.createElement('button');
            copyBtn.className = 'rapidbooru-category-copy-btn';
            copyBtn.title = `Copy "${categoryName}" tags`;
            copyBtn.innerHTML = `
                <svg viewBox="0 0 24 24">
                    <path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/>
                </svg>
            `;

            copyBtn.onclick = (e) => {
                e.stopPropagation();
                const tagsText = tags.map(t => t.replace(/_/g, ' ')).join(', ');
                const textToCopy = `${categoryName}:${tagsText}`;

                navigator.clipboard.writeText(textToCopy).then(() => {
                    copyBtn.classList.add('copied');
                    copyBtn.innerHTML = `
                        <svg viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z"/></svg>
                    `;
                    setTimeout(() => {
                        copyBtn.classList.remove('copied');
                        copyBtn.innerHTML = `
                            <svg viewBox="0 0 24 24"><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></svg>
                        `;
                    }, 1500);
                });
            };
            box.appendChild(copyBtn);
        }

        return box;
    }

    // 이미지 프리뷰 기능
    function createImagePreview(imageUrl, tags, postId, postData = null) {
        // 기존 프리뷰 오버레이 제거 (설정 패널은 제외)
        document.querySelectorAll('.rapidbooru-overlay').forEach(overlay => {
            if (overlay.id !== 'rapidbooru-settings-panel') {
                overlay.remove();
            }
        });

        // 선택된 태그 리스트 초기화
        selectedTags = [];

        // 오버레이 생성
        const overlay = document.createElement('div');
        overlay.className = 'rapidbooru-overlay';

        // 프리뷰 컨테이너 생성
        const preview = document.createElement('div');
        preview.className = 'rapidbooru-preview';

        // [추가] 새 탭 버튼 생성 (이미지 프리뷰용)
        const newTabBtn = document.createElement('button');
        newTabBtn.className = 'rapidbooru-newtab';
        newTabBtn.title = 'Open post in new tab';
        newTabBtn.innerHTML = `
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none">
                <rect x="3" y="3" width="18" height="18" rx="6" fill="none" stroke="white" stroke-width="2"/>
                <path d="M9 15L15 9M15 9H10M15 9V14" stroke="white" stroke-width="2" stroke-linecap="round"/>
            </svg>
        `;
        newTabBtn.onclick = (e) => {
            e.stopPropagation();
            if (postId) {
                window.open(`https://danbooru.donmai.us/posts/${postId}`, '_blank');
            }
        };

        // 닫기 버튼
        const closeBtn = document.createElement('button');
        closeBtn.className = 'rapidbooru-close';
        closeBtn.innerHTML = '×';
        closeBtn.onclick = () => {
            selectedTags = [];
            overlay.remove();
        };

        // 태그 섹션
        const tagsSection = document.createElement('div');
        tagsSection.className = 'rapidbooru-tags';
        tagsSection.innerHTML = `<h3 style="color: var(--rapidbooru-text-color); margin-bottom: 15px;">Tags</h3>`;

        if (tags && tags.length > 0) {
            // 태그 분류
            const categorizedTags = categorizeTags(tags, postData);

            // Artist, Copyright, Character 태그들을 버튼으로 생성
            tagsSection.appendChild(createCategoryTagLinks('artist', categorizedTags.artist));
            tagsSection.appendChild(createCategoryTagLinks('copyright', categorizedTags.copyright));
            tagsSection.appendChild(createCategoryTagLinks('character', categorizedTags.character));

            // General 태그 버튼들
            if (categorizedTags.general.length > 0) {
                const generalLabel = document.createElement('h4');
                generalLabel.style.cssText = `color: var(--rapidbooru-text-color); margin: 15px 0 10px 0; font-size: 14px;`;
                generalLabel.textContent = 'General Tags (Click to select):';
                tagsSection.appendChild(generalLabel);

                const tagButtons = createTagButtons(categorizedTags.general);
                tagsSection.appendChild(tagButtons);
            }

            // 버튼 컨테이너
            const buttonContainer = document.createElement('div');
            buttonContainer.className = 'rapidbooru-action-buttons';

            // Select All 버튼 추가 (General 태그가 있을 경우)
            if (categorizedTags.general.length > 0) {
                const selectAllBtn = document.createElement('button');
                selectAllBtn.textContent = 'Select All';
                selectAllBtn.className = 'rapidbooru-copy-btn';
                selectAllBtn.style.background = 'linear-gradient(135deg, #56687a 0%, #3c4a58 100%)';
                selectAllBtn.style.flexGrow = '0';
                selectAllBtn.onclick = () => {
                    // General 태그(span)만 선택/해제
                    const allTagButtons = tagsSection.querySelectorAll('.rapidbooru-main-tags .rapidbooru-tag-button');
                    const shouldSelectAll = Array.from(allTagButtons).some(btn => !btn.classList.contains('selected'));

                    allTagButtons.forEach(button => {
                        const tagText = button.dataset.tag;
                        const isSelected = button.classList.contains('selected');
                        if (shouldSelectAll) {
                            if (!isSelected) {
                                button.classList.add('selected');
                                selectedTags.push(tagText);
                            }
                        } else {
                            if (isSelected) {
                                button.classList.remove('selected');
                                const index = selectedTags.indexOf(tagText);
                                if (index > -1) {
                                    selectedTags.splice(index, 1);
                                }
                            }
                        }
                    });
                    selectedTags = [...new Set(selectedTags)];
                    selectAllBtn.textContent = shouldSelectAll ? 'Deselect All' : 'Select All';
                };
                buttonContainer.appendChild(selectAllBtn);
            }

            // 복사 버튼
            const copyBtn = document.createElement('button');
            copyBtn.textContent = 'Copy Selected Tags';
            copyBtn.className = 'rapidbooru-copy-btn';
            copyBtn.onclick = () => {
                const selectedText = selectedTags.join('');
                if (selectedText) {
                    navigator.clipboard.writeText(selectedText.trim().replace(/,$/, ''));
                    copyBtn.textContent = 'Copied!';
                    copyBtn.classList.add('copied');
                    setTimeout(() => { copyBtn.textContent = 'Copy Selected Tags'; copyBtn.classList.remove('copied'); }, 2000);
                }
            };
            buttonContainer.appendChild(copyBtn);
            tagsSection.appendChild(buttonContainer);
        } else {
            tagsSection.innerHTML += '<p style="color: #ccc;">태그 정보를 불러올 수 없습니다.</p>';
        }

        // 이미지 섹션
        const contentSection = document.createElement('div');
        contentSection.className = 'rapidbooru-content';

        // 미디어 요소 생성 (이미지, 비디오, GIF 지원)
        let mediaElement;
        const fileExtension = imageUrl.split('.').pop().toLowerCase();

        if (fileExtension === 'mp4' || fileExtension === 'webm') {
            // 비디오 파일
            mediaElement = document.createElement('video');
            mediaElement.controls = true;
            mediaElement.autoplay = true;
            mediaElement.loop = true;
            mediaElement.muted = true;
        } else {
            // 이미지 파일 (png, jpg, webp, gif 포함)
            mediaElement = document.createElement('img');
            mediaElement.alt = 'Preview Image';
        }

        mediaElement.className = 'rapidbooru-image';
        mediaElement.src = imageUrl;

        contentSection.appendChild(mediaElement);

        // 조립
        preview.appendChild(newTabBtn); // [추가] 새 탭 버튼을 닫기 버튼 왼쪽에 추가
        preview.appendChild(closeBtn);
        preview.appendChild(tagsSection);
        preview.appendChild(contentSection);
        overlay.appendChild(preview);

        // 이벤트 리스너
        overlay.onclick = (e) => {
            if (e.target === overlay) {
                selectedTags = [];
                overlay.remove();
            }
        };

        document.addEventListener('keydown', function escHandler(e) {
            if (e.key === 'Escape') {
                selectedTags = [];
                overlay.remove();
                document.removeEventListener('keydown', escHandler);
            }
        });

        // DOM에 추가
        document.body.appendChild(overlay);

        // 애니메이션
        setTimeout(() => overlay.classList.add('show'), 10);
    }

    // 썸네일에서 이미지 정보 추출 (원본 URL 가져오기 개선)
    function extractImageInfo(thumbnail) {
        let imageUrl = '';
        let tags = [];
        let postId = '';

        // 포스트 ID 추출
        const link = thumbnail.closest('a') || thumbnail.querySelector('a');
        if (link && link.href) {
            const match = link.href.match(/\/posts\/(\d+)/);
            if (match) {
                postId = match[1];
            }
        }

        // 링크에서 ID를 찾지 못한 경우, data-id 속성에서 가져오기 시도
        // 포스트 페이지의 원본 이미지를 처리하는 데 핵심적인 부분
        if (!postId && thumbnail.dataset.id) {
            postId = thumbnail.dataset.id;
        }

        // 이미지 URL 찾기 - 원본 이미지 URL 추출
        const img = thumbnail.querySelector('img');
        if (img && postId) {
            // Danbooru API를 통해 원본 이미지 URL 가져오기
            fetch(`https://danbooru.donmai.us/posts/${postId}.json`)
                .then(response => response.json())
                .then(data => {
                    if (data.file_url) {
                        // 원본 파일 URL 사용
                        imageUrl = data.file_url;
                        if (data.tag_string) {
                            tags = data.tag_string.split(' ');
                        }
                        createImagePreview(imageUrl, tags, postId, data);
                    }
                })
                .catch(error => {
                    console.error('Failed to fetch post data:', error);
                    // 실패 시 썸네일 URL 사용
                    const src = img.src;
                    if (src.includes('preview')) {
                        imageUrl = src.replace('/preview/', '/original/').replace('preview_', '');
                    } else {
                        imageUrl = src;
                    }
                    createImagePreview(imageUrl, tags, postId);
                });
            return null; // API 호출로 처리하므로 null 반환
        }

        // API 호출 실패 시 기존 방식 사용
        if (img) {
            const src = img.src;
            if (src.includes('preview')) {
                imageUrl = src.replace('/preview/', '/original/').replace('preview_', '');
            } else {
                imageUrl = src;
            }
        }

        // 태그 정보 추출 (data 속성이나 클래스에서)
        const tagElements = thumbnail.querySelectorAll('[data-tags]');
        if (tagElements.length > 0) {
            tagElements.forEach(el => {
                const tagData = el.getAttribute('data-tags');
                if (tagData) {
                    tags = tags.concat(tagData.split(' '));
                }
            });
        }

        // 부모 요소에서 태그 정보 찾기
        let parent = thumbnail.closest('[data-tags]');
        if (parent) {
            const tagData = parent.getAttribute('data-tags');
            if (tagData) {
                tags = tagData.split(' ');
            }
        }

        return { imageUrl, tags, postId };
    }

    // 썸네일 우클릭 이벤트 설정
    function setupImagePreview() {
        document.addEventListener('contextmenu', function(e) {
            // 이미지 썸네일인지 확인
            const thumbnail = e.target.closest('.post-preview') ||
                            e.target.closest('.post-thumbnail') ||
                            e.target.closest('[data-id]') ||
                            (e.target.tagName === 'IMG' && e.target.closest('a[href*="/posts/"]'));

            if (thumbnail) {
                e.preventDefault();

                const result = extractImageInfo(thumbnail);

                // API 호출이 아닌 경우에만 직접 프리뷰 생성
                if (result && result.imageUrl) {
                    createImagePreview(result.imageUrl, result.tags, result.postId);
                }
            }
        });
    }

    // 태그 프리뷰 기능
    function createTagPreview(tagName) {
        // 기존 프리뷰 오버레이 제거 (설정 패널은 제외)
        document.querySelectorAll('.rapidbooru-overlay').forEach(overlay => {
            if (overlay.id !== 'rapidbooru-settings-panel') {
                overlay.remove();
            }
        });

        // 태그명에서 공백을 언더스코어로 변환
        const formattedTag = tagName.replace(/\s+/g, '_');
        const searchOrder = rapidbooruSettings.searchOrder || 'Jaccard';
        const wikiUrl = `https://danbooru.donmai.us/wiki_pages/${encodeURIComponent(formattedTag)}`;
        const charUrl = `https://danbooru.donmai.us/related_tag?commit=Search&search%5Bcategory%5D=Character&search%5Border%5D=${searchOrder}&search%5Bquery%5D=${encodeURIComponent(formattedTag)}`;
        const genUrl = `https://danbooru.donmai.us/related_tag?commit=Search&search%5Bcategory%5D=General&search%5Border%5D=${searchOrder}&search%5Bquery%5D=${encodeURIComponent(formattedTag)}`;

        // 오버레이 생성
        const overlay = document.createElement('div');
        overlay.className = 'rapidbooru-overlay';

        // 프리뷰 컨테이너 생성
        const preview = document.createElement('div');
        preview.className = 'rapidbooru-preview';

        // [추가] 새 탭 버튼 생성 (태그 프리뷰용)
        const newTabBtn = document.createElement('button');
        newTabBtn.className = 'rapidbooru-newtab';
        newTabBtn.title = 'Open wiki page in new tab';
        newTabBtn.innerHTML = `
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none">
                <rect x="3" y="3" width="18" height="18" rx="6" fill="none" stroke="white" stroke-width="2"/>
                <path d="M9 15L15 9M15 9H10M15 9V14" stroke="white" stroke-width="2" stroke-linecap="round"/>
            </svg>
        `;
        newTabBtn.onclick = (e) => {
            e.stopPropagation();
            window.open(`https://danbooru.donmai.us/wiki_pages/${encodeURIComponent(formattedTag)}`, '_blank');
        };

        // 닫기 버튼
        const closeBtn = document.createElement('button');
        closeBtn.className = 'rapidbooru-close';
        closeBtn.innerHTML = '×';
        closeBtn.onclick = () => overlay.remove();

        // 컨텐츠 섹션 (위키 iframe)
        const contentSection = document.createElement('div');
        contentSection.className = 'rapidbooru-content';
        contentSection.style.width = '100%';
        contentSection.style.position = 'relative';

        // 위키 제목
        const title = document.createElement('h2');
        title.style.color = 'white';
        title.style.marginBottom = '15px';
        title.style.textAlign = 'center';
        title.textContent = `Tag: ${tagName}`;

        // 위키 iframe
        const iframe = document.createElement('iframe');
        iframe.className = 'rapidbooru-wiki';
        iframe.src = wikiUrl;
        iframe.style.width = '100%';
        iframe.style.height = 'calc(100% - 100px)';
        iframe.style.border = 'none';
        iframe.style.borderRadius = '8px';
        iframe.style.background = 'white';

        // 버튼 컨테이너
        const buttonsContainer = document.createElement('div');
        buttonsContainer.className = 'rapidbooru-buttons';

        // Char 버튼
        const charBtn = document.createElement('a');
        charBtn.className = 'rapidbooru-btn';
        charBtn.textContent = 'Char';
        charBtn.href = charUrl;
        charBtn.target = '_blank';
        charBtn.onclick = (e) => {
            e.stopPropagation();
        };

        // Gen 버튼
        const genBtn = document.createElement('a');
        genBtn.className = 'rapidbooru-btn';
        genBtn.textContent = 'Gen';
        genBtn.href = genUrl;
        genBtn.target = '_blank';
        genBtn.onclick = (e) => {
            e.stopPropagation();
        };

        buttonsContainer.appendChild(charBtn);
        buttonsContainer.appendChild(genBtn);

        // 조립
        contentSection.appendChild(title);
        contentSection.appendChild(iframe);
        contentSection.appendChild(buttonsContainer);

        preview.appendChild(newTabBtn); // [추가] 새 탭 버튼을 닫기 버튼 왼쪽에 추가
        preview.appendChild(closeBtn);
        preview.appendChild(contentSection);
        overlay.appendChild(preview);

        // 이벤트 리스너
        overlay.onclick = (e) => {
            if (e.target === overlay) {
                overlay.remove();
            }
        };

        document.addEventListener('keydown', function escHandler(e) {
            if (e.key === 'Escape') {
                overlay.remove();
                document.removeEventListener('keydown', escHandler);
            }
        });

        // DOM에 추가
        document.body.appendChild(overlay);

        // 애니메이션
        setTimeout(() => overlay.classList.add('show'), 10);
    }

    // 태그 요소 감지 및 우클릭 이벤트 설정
    function setupTagPreview() {
        document.addEventListener('contextmenu', function(e) {
            // 태그 요소인지 확인
            const tagElement = e.target.closest('.tag') ||
                             e.target.closest('.tag-type-0') ||
                             e.target.closest('.tag-type-1') ||
                             e.target.closest('.tag-type-3') ||
                             e.target.closest('.tag-type-4') ||
                             e.target.closest('.tag-type-5') ||
                             e.target.closest('[data-tag-name]') ||
                             (e.target.classList && (
                                 e.target.classList.contains('tag') ||
                                 e.target.classList.contains('tag-link') ||
                                 e.target.classList.contains('search-tag')
                             ));

            if (tagElement) {
                // 이미지 썸네일이 아닌 경우에만 태그 프리뷰 실행
                const isImageThumbnail = e.target.closest('.post-preview') ||
                                       e.target.closest('.post-thumbnail') ||
                                       e.target.closest('[data-id]') ||
                                       (e.target.tagName === 'IMG' && e.target.closest('a[href*="/posts/"]'));

                if (!isImageThumbnail) {
                    e.preventDefault();

                    // 태그명 추출
                    let tagName = '';

                    // data-tag-name 속성에서 추출
                    if (tagElement.hasAttribute('data-tag-name')) {
                        tagName = tagElement.getAttribute('data-tag-name');
                    }
                    // href에서 추출
                    else if (tagElement.href && tagElement.href.includes('tags=')) {
                        const match = tagElement.href.match(/tags=([^&]+)/);
                        if (match) {
                            tagName = decodeURIComponent(match[1]);
                        }
                    }
                    // 텍스트 내용에서 추출
                    else {
                        tagName = tagElement.textContent.trim();
                        // 태그 앞의 숫자나 기호 제거
                        tagName = tagName.replace(/^\d+\s*/, '').replace(/^[?!+-]\s*/, '');
                    }

                    if (tagName) {
                        createTagPreview(tagName);
                    }
                }
            }
        });
    }

    // Debounce function to limit the rate at which a function gets called.
    function debounce(func, wait) {
        let timeout;
        return function executedFunction(...args) {
            const later = () => {
                clearTimeout(timeout);
                func.apply(this, args);
            };
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    }

    // Related tags 화면 기능
    function setupRelatedTagsFeature() {
        // Related tags 페이지인지 확인
        if (!window.location.pathname.includes('/related_tag')) {
            return;
        }

        // 삽입 위치 결정: 검색 결과 테이블 위
        const resultsTable = document.querySelector('table.striped');
        if (resultsTable) {
            insertRelatedTagsUI(resultsTable, 'before');
        } else {
            // 테이블이 없으면 기존 방식대로 검색 폼 뒤에 삽입 (폴백)
            const searchForm = document.querySelector('form') || document.querySelector('.search-form');
            if (searchForm) {
                insertRelatedTagsUI(searchForm, 'after');
            } else {
                const searchButton = document.querySelector('input[type="submit"]') ||
                                   Array.from(document.querySelectorAll('input')).find(input =>
                                       input.type === 'submit' || input.value === 'Search'
                                   );
                if (searchButton && searchButton.parentElement) {
                    insertRelatedTagsUI(searchButton.parentElement, 'after');
                }
            }
        }

        // Debounce the update function to prevent performance issues
        const debouncedUpdate = debounce(updateRelatedTagsList, 300);

        // 페이지 변화 감지하여 태그 목록 업데이트
        const observer = new MutationObserver(function(mutations) {
            // Call the debounced function once per batch of mutations.
            debouncedUpdate();
        });

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

        // 초기 태그 목록 업데이트
        setTimeout(updateRelatedTagsList, 500);
    }

    function insertRelatedTagsUI(targetElement, position = 'after') {
        // 이미 추가된 컨테이너가 있는지 확인
        if (document.getElementById('rapidbooru-related-tags-container')) {
            return;
        }

        // 컨테이너 생성
        const container = document.createElement('div');
        container.id = 'rapidbooru-related-tags-container';
        container.style.cssText = `
            margin: 20px 0;
            padding: 15px;
            background: #f5b8b8;
            border: 1px solid #e5a7a7;
            color: #212529;
        `;

        // 제목 추가
        const title = document.createElement('h4');
        title.textContent = 'Top 20 Related Tags (Click to select)';
        title.style.cssText = `
            margin: 0 0 10px 0;
            color: #212529;
            font-family: 'Consolas', monospace;
            font-size: 16px;
        `;

        // 태그 버튼들이 들어갈 컨테이너
        const tagsContainer = document.createElement('div');
        tagsContainer.id = 'rapidbooru-related-tags-buttons';
        tagsContainer.className = 'rapidbooru-main-tags';
        tagsContainer.style.cssText = `
            background: #ffdddd;
            max-height: none;
            padding: 10px;
            border: 1px solid #f5b8b8;
            min-height: 60px;
            border-radius: 4px;
            margin-bottom: 10px;
        `;

        // 버튼 컨테이너
        const buttonContainer = document.createElement('div');
        buttonContainer.className = 'rapidbooru-action-buttons';
        buttonContainer.style.marginTop = '0';

        // Select All 버튼 생성
        const selectAllButton = document.createElement('button');
        selectAllButton.textContent = 'Select All';
        selectAllButton.type = 'button';
        selectAllButton.className = 'rapidbooru-copy-btn';
        selectAllButton.style.background = 'linear-gradient(135deg, #56687a 0%, #3c4a58 100%)';
        selectAllButton.style.flexGrow = '0';
        selectAllButton.onclick = function() {
            const allTagButtons = tagsContainer.querySelectorAll('.rapidbooru-tag-button');
            if (allTagButtons.length === 0) return;

            const shouldSelectAll = Array.from(allTagButtons).some(btn => !btn.classList.contains('selected'));

            allTagButtons.forEach(button => {
                const tagText = button.dataset.tag;
                const isSelected = button.classList.contains('selected');

                if (shouldSelectAll) {
                    if (!isSelected) {
                        button.classList.add('selected');
                        relatedPageSelectedTags.push(tagText);
                    }
                } else {
                    if (isSelected) {
                        button.classList.remove('selected');
                        const index = relatedPageSelectedTags.indexOf(tagText);
                        if (index > -1) {
                            relatedPageSelectedTags.splice(index, 1);
                        }
                    }
                }
            });
            relatedPageSelectedTags = [...new Set(relatedPageSelectedTags)];
            this.textContent = shouldSelectAll ? 'Deselect All' : 'Select All';
        };

        // 복사 버튼
        const copyButton = document.createElement('button');
        copyButton.textContent = 'Copy Selected';
        copyButton.type = 'button';
        copyButton.className = 'rapidbooru-copy-btn';
        copyButton.style.flexGrow = '0';
        copyButton.onclick = function() {
            if (relatedPageSelectedTags.length > 0) {
                navigator.clipboard.writeText(relatedPageSelectedTags.join(', ')).then(() => {
                    const originalText = copyButton.textContent;
                    copyButton.textContent = 'Copied!';
                    copyButton.classList.add('copied');
                    setTimeout(() => { copyButton.textContent = originalText; copyButton.classList.remove('copied'); }, 2000);
                });
            }
        };

        // 조립
        container.appendChild(title);
        container.appendChild(tagsContainer);
        buttonContainer.appendChild(selectAllButton);
        buttonContainer.appendChild(copyButton);
        container.appendChild(buttonContainer);

        // 위치에 따라 삽입
        if (position === 'before') {
            targetElement.parentNode.insertBefore(container, targetElement);
        } else { // 'after'
            if (targetElement.nextSibling) {
                targetElement.parentNode.insertBefore(container, targetElement.nextSibling);
            } else {
                targetElement.parentNode.appendChild(container);
            }
        }
    }

    function updateRelatedTagsList() {
        const tagsContainer = document.getElementById('rapidbooru-related-tags-buttons');
        if (!tagsContainer) {
            return;
        }

        // 검색 결과 영역에서 태그 링크들 찾기 (더 정확한 선택자 사용)
        const tagLinks = [];

        // 방법 1: 자동완성 드롭다운에서 태그 추출
        const autocompleteItems = document.querySelectorAll('.ui-menu-item a, .autocomplete-item a');
        if (autocompleteItems.length > 0) {
            autocompleteItems.forEach(item => {
                if (item.textContent.trim()) {
                    tagLinks.push(item);
                }
            });
        }

        // 방법 2: 검색 결과 테이블이나 리스트에서 태그 추출
        if (tagLinks.length === 0) {
            const resultLinks = document.querySelectorAll('table a, .search-results a, .tag-list a');
            resultLinks.forEach(link => {
                const text = link.textContent.trim();
                const href = link.href;

                // 태그 링크인지 확인 (숫자로 시작하지 않고, 특정 패턴 제외)
                if (text &&
                    !href.includes('/wiki') &&
                    !href.includes('/artists') &&
                    !href.includes('/pools') &&
                    !href.includes('/forum') &&
                    !href.includes('/users') &&
                    !text.match(/^(Terms|Privacy|Contact|Help|More|Login|Posts|Comments)$/i) &&
                    (href.includes('tags=') || href.includes('/posts?') || text.includes('_') || text.includes(' '))) {
                    tagLinks.push(link);
                }
            });
        }

        // 방법 3: 현재 페이지의 모든 링크에서 태그 패턴 찾기
        if (tagLinks.length === 0) {
            const allLinks = document.querySelectorAll('a');
            allLinks.forEach(link => {
                const text = link.textContent.trim();
                const href = link.href;

                // 태그 패턴 매칭 (언더스코어 포함, 괄호 포함 등)
                if (text &&
                    (text.includes('_') || text.match(/\([^)]+\)/)) &&
                    !href.includes('/wiki') &&
                    !href.includes('/artists') &&
                    !href.includes('/pools') &&
                    !href.includes('/forum') &&
                    !href.includes('/users') &&
                    !text.match(/^(Terms|Privacy|Contact|Help|More|Login|Posts|Comments|Danbooru)$/i)) {
                    tagLinks.push(link);
                }
            });
        }

        // 상위 20개 태그 추출 및 포맷팅
        const topTags = tagLinks.slice(0, 20).map(link => {
            let tagName = link.textContent.trim();

            // 숫자나 기타 정보 제거 (태그명만 추출)
            tagName = tagName.replace(/^\d+\s*/, '').replace(/\s*\d+$/, '').replace(/\s*\(\d+\)$/, '');

            // '_'를 띄어쓰기로 변환
            return tagName.replace(/_/g, ' ');
        }).filter(tag => tag.length > 0 && tag.length < 100); // 너무 긴 텍스트 제외

        const uniqueTags = [...new Set(topTags)].slice(0, 20);

        // 이미 렌더링된 태그와 새로 가져온 태그를 비교합니다.
        const currentTagButtons = tagsContainer.querySelectorAll('.rapidbooru-tag-button');
        const currentTags = Array.from(currentTagButtons).map(btn => btn.dataset.tag);

        // 태그 목록에 변화가 없으면 함수를 종료하여, 사용자의 태그 선택 상태가
        // 계속 초기화되는 현상이 방지합니다.
        if (uniqueTags.length === currentTags.length && uniqueTags.every((tag, i) => tag === currentTags[i])) {
            return;
        }

        // 이전 상태 초기화
        tagsContainer.innerHTML = '';
        relatedPageSelectedTags = [];
        const selectAllBtn = document.querySelector('#rapidbooru-related-tags-container button');
        if (selectAllBtn && selectAllBtn.textContent.includes('Deselect')) {
            selectAllBtn.textContent = 'Select All';
        }

        if (uniqueTags.length > 0) {
            uniqueTags.forEach((tag, index) => {
                const button = document.createElement('span');
                button.className = 'rapidbooru-tag-button';
                button.textContent = tag + (index < uniqueTags.length - 1 ? ', ' : '');
                button.dataset.tag = tag;

                button.addEventListener('click', function() {
                    this.classList.toggle('selected');
                    if (this.classList.contains('selected')) {
                        relatedPageSelectedTags.push(this.dataset.tag);
                    } else {
                        const tagIndex = relatedPageSelectedTags.indexOf(this.dataset.tag);
                        if (tagIndex > -1) relatedPageSelectedTags.splice(tagIndex, 1);
                    }
                });
                tagsContainer.appendChild(button);
            });
        } else {
            tagsContainer.textContent = 'No related tags found. Please perform a search first.';
        }
    }

    // [추가] 사이드바 태그 버튼형 리스트 기능
    function setupSidebarTagButtonList() {
        const path = window.location.pathname;
        if (
            path === '/' ||
            path.startsWith('/posts') ||
            path.startsWith('/wiki_pages')
        ) {
            // 사이드바 컨테이너(태그 리스트의 부모)를 강제로 찾음
            let sidebar = document.querySelector('.sidebar') || document.querySelector('.aside') || document.querySelector('#sidebar') || document.querySelector('.side-menu') || document.body;
            // 기존 태그 리스트(ul, .tag-list 등) 완전히 숨기기
            const tagListCandidates = sidebar.querySelectorAll('.tag-list, .sidebar-section .tag-list, #tag-list, ul[data-category], .sidebar-section, .sidebar');
            tagListCandidates.forEach(el => {
                el.style.display = 'none';
                el.style.visibility = 'hidden';
                el.style.height = '0';
                el.style.margin = '0';
                el.style.padding = '0';
            });
            // 실제 태그 리스트 컨테이너를 찾음 (최초로 발견되는 것)
            let tagListContainer = null;
            for (const el of tagListCandidates) {
                if (el.matches('.tag-list, .sidebar-section .tag-list, #tag-list, ul[data-category]')) {
                    tagListContainer = el;
                    break;
                }
            }
            // 이미 생성된 경우 중복 생성 방지
            if (document.getElementById('rapidbooru-sidebar-taglist')) return;
            // 태그 정보 추출 함수 (카테고리별)
            function extractSidebarTags() {
                const categories = { artist: [], copyright: [], character: [], general: [], meta: [] };
                // ul[data-category] 우선
                const uls = sidebar.querySelectorAll('ul[data-category]');
                if (uls.length > 0) {
                    uls.forEach(ul => {
                        const cat = ul.getAttribute('data-category');
                        let key = '';
                        if (cat === '0') key = 'general';
                        else if (cat === '1') key = 'artist';
                        else if (cat === '3') key = 'copyright';
                        else if (cat === '4') key = 'character';
                        else if (cat === '5') key = 'meta';
                        else return;
                        ul.querySelectorAll('li').forEach(li => {
                            // 실제 태그명과 카운트 파싱 (danbooru 구조에 맞춤)
                            const tagA = li.querySelector('a.search-tag');
                            const countSpan = li.querySelector('span.post-count');
                            if (!tagA) return;
                            const tag = tagA.textContent.trim();
                            const count = countSpan ? countSpan.textContent.trim() : '';
                            if (tag) categories[key].push({ tag, count });
                        });
                    });
                } else {
                    // li.tag-type-x
                    sidebar.querySelectorAll('li, .tag-type-0, .tag-type-1, .tag-type-3, .tag-type-4, .tag-type-5').forEach(li => {
                        let key = '';
                        if (li.classList.contains('tag-type-0')) key = 'general';
                        else if (li.classList.contains('tag-type-1')) key = 'artist';
                        else if (li.classList.contains('tag-type-3')) key = 'copyright';
                        else if (li.classList.contains('tag-type-4')) key = 'character';
                        else if (li.classList.contains('tag-type-5')) key = 'meta';
                        else return;
                        const tagA = li.querySelector('a.search-tag');
                        const countSpan = li.querySelector('span.post-count');
                        if (!tagA) return;
                        const tag = tagA.textContent.trim();
                        const count = countSpan ? countSpan.textContent.trim() : '';
                        if (tag) categories[key].push({ tag, count });
                    });
                }
                return categories;
            }
            // 태그 버튼 생성 함수
            function createSidebarTagButtons(categories) {
                const wrapper = document.createElement('div');
                wrapper.style.display = 'flex';
                wrapper.style.flexDirection = 'column';
                wrapper.style.gap = '0px';
                ['artist', 'copyright', 'character', 'general', 'meta'].forEach(cat => {
                    categories[cat].forEach(({ tag, count }) => {
                        const btn = document.createElement('button');
                        btn.type = 'button';
                        btn.className = 'rapidbooru-sidebar-tag-btn';
                        btn.textContent = tag;
                        btn.dataset.tag = tag;
                        btn.dataset.category = cat;
                        btn.style.background = tagColors[cat].normal;
                        btn.style.color = '#ffffff';
                        btn.style.border = 'none';
                        btn.style.borderRadius = '4px';
                        btn.style.margin = '0 0 4px 0';
                        btn.style.padding = '6px 10px';
                        btn.style.fontSize = '13px';
                        btn.style.textAlign = 'left';
                        btn.style.cursor = 'pointer';
                        btn.style.transition = 'background 0.2s';
                        btn.style.userSelect = 'none';
                        btn.style.width = '100%';
                        btn.style.boxShadow = 'none';
                        btn.style.position = 'relative';
                        // 태그 오른쪽 끝에 count 표시
                        if (count) {
                            const countSpan = document.createElement('span');
                            countSpan.textContent = count;
                            countSpan.style.position = 'absolute';
                            countSpan.style.right = '12px';
                            countSpan.style.top = '50%';
                            countSpan.style.transform = 'translateY(-50%)';
                            countSpan.style.color = '#ffffff';
                            countSpan.style.fontSize = '12px';
                            countSpan.style.pointerEvents = 'none';
                            btn.appendChild(countSpan);
                        }
                        // 좌클릭: 선택/해제
                        btn.addEventListener('click', function(e) {
                            if (e.button !== 0) return;
                            e.preventDefault();
                            if (btn.classList.contains('selected')) {
                                btn.classList.remove('selected');
                                btn.style.background = tagColors[cat].normal;
                                const idx = sidebarSelectedTags.indexOf(tag);
                                if (idx > -1) sidebarSelectedTags.splice(idx, 1);
                            } else {
                                btn.classList.add('selected');
                                btn.style.background = tagColors[cat].selected;
                                sidebarSelectedTags.push(tag);
                            }
                            sidebarSelectedTags = [...new Set(sidebarSelectedTags)];
                        });
                        // 가운데 클릭: 새 탭으로 검색
                        btn.addEventListener('mousedown', function(e) {
                            if (e.button === 1) {
                                e.preventDefault();
                                const url = `https://danbooru.donmai.us/posts?tags=${encodeURIComponent(tag.replace(/\s/g, '_'))}`;
                                window.open(url, '_blank');
                            }
                        });
                        // 우클릭: 태그 프리뷰
                        btn.addEventListener('contextmenu', function(e) {
                            e.preventDefault();
                            createTagPreview(tag);
                        });
                        // 드래그 다중 선택 지원
                        btn.addEventListener('mouseenter', function(e) {
                            if (window.__rapidbooru_sidebar_dragging) {
                                if (!btn.classList.contains('selected')) {
                                    btn.classList.add('selected');
                                    btn.style.background = tagColors[cat].selected;
                                    sidebarSelectedTags.push(tag);
                                    sidebarSelectedTags = [...new Set(sidebarSelectedTags)];
                                } else {
                                    btn.classList.remove('selected');
                                    btn.style.background = tagColors[cat].normal;
                                    const idx = sidebarSelectedTags.indexOf(tag);
                                    if (idx > -1) sidebarSelectedTags.splice(idx, 1);
                                }
                            }
                        });
                        wrapper.appendChild(btn);
                    });
                });
                return wrapper;
            }

            // 사이드바에 삽입할 컨테이너 생성
            const sidebarBox = document.createElement('div');
            sidebarBox.id = 'rapidbooru-sidebar-taglist';
            sidebarBox.style.margin = '24px 0 0 0';
            sidebarBox.style.padding = '12px 8px 12px 8px';
            sidebarBox.style.background = '#474756'; // 배경색 지정
            sidebarBox.style.borderRadius = '8px';
            sidebarBox.style.boxShadow = '0 2px 8px rgba(0,0,0,0.04)';
            sidebarBox.style.display = 'flex';
            sidebarBox.style.flexDirection = 'column';
            sidebarBox.style.alignItems = 'stretch';
            sidebarBox.style.maxHeight = '70vh';
            sidebarBox.style.overflowY = 'auto';
            sidebarBox.style.minWidth = '120px';

            // 버튼 컨테이너(Select All, Copy)
            const topBtnBox = document.createElement('div');
            topBtnBox.style.display = 'flex';
            topBtnBox.style.gap = '8px';
            topBtnBox.style.marginBottom = '12px';

            // Select All 버튼
            const selectAllBtn = document.createElement('button');
            selectAllBtn.type = 'button';
            selectAllBtn.textContent = 'Select All';
            selectAllBtn.className = 'rapidbooru-copy-btn';
            selectAllBtn.style.background = 'linear-gradient(135deg, #56687a 0%, #3c4a58 100%)';
            selectAllBtn.style.flexGrow = '1';
            selectAllBtn.style.fontSize = '13px';
            selectAllBtn.style.padding = '6px 0';
            selectAllBtn.addEventListener('click', function() {
                const btns = sidebarBox.querySelectorAll('.rapidbooru-sidebar-tag-btn');
                const shouldSelectAll = Array.from(btns).some(btn => !btn.classList.contains('selected'));
                btns.forEach(btn => {
                    const tag = btn.dataset.tag;
                    const cat = btn.dataset.category;
                    if (shouldSelectAll) {
                        if (!btn.classList.contains('selected')) {
                            btn.classList.add('selected');
                            btn.style.background = tagColors[cat].selected;
                            sidebarSelectedTags.push(tag);
                        }
                    } else {
                        if (btn.classList.contains('selected')) {
                            btn.classList.remove('selected');
                            btn.style.background = tagColors[cat].normal;
                            const idx = sidebarSelectedTags.indexOf(tag);
                            if (idx > -1) sidebarSelectedTags.splice(idx, 1);
                        }
                    }
                });
                sidebarSelectedTags = [...new Set(sidebarSelectedTags)];
                selectAllBtn.textContent = shouldSelectAll ? 'Deselect All' : 'Select All';
            });

            // Copy Selected Tags 버튼
            const copyBtn = document.createElement('button');
            copyBtn.type = 'button';
            copyBtn.textContent = 'Copy Selected Tags';
            copyBtn.className = 'rapidbooru-copy-btn';
            copyBtn.style.flexGrow = '1';
            copyBtn.style.fontSize = '13px';
            copyBtn.style.padding = '6px 0';
            copyBtn.addEventListener('click', function() {
                if (sidebarSelectedTags.length > 0) {
                    const str = sidebarSelectedTags.join(', ');
                    navigator.clipboard.writeText(str).then(() => {
                        copyBtn.textContent = 'Copied!';
                        copyBtn.classList.add('copied');
                        setTimeout(() => {
                            copyBtn.textContent = 'Copy Selected Tags';
                            copyBtn.classList.remove('copied');
                        }, 1500);
                    });
                }
            });

            topBtnBox.appendChild(selectAllBtn);
            topBtnBox.appendChild(copyBtn);

            // 태그 버튼 리스트 생성
            const categories = extractSidebarTags();
            const tagBtnList = createSidebarTagButtons(categories);

            // 드래그 다중 선택 지원
            sidebarBox.addEventListener('mousedown', function(e) {
                if (e.target.classList.contains('rapidbooru-sidebar-tag-btn') && e.button === 0) {
                    window.__rapidbooru_sidebar_dragging = true;
                }
            });
            sidebarBox.addEventListener('mouseup', function() {
                window.__rapidbooru_sidebar_dragging = false;
            });
            sidebarBox.addEventListener('mouseleave', function() {
                window.__rapidbooru_sidebar_dragging = false;
            });

            // 조립
            sidebarBox.appendChild(topBtnBox);
            sidebarBox.appendChild(tagBtnList);

            // 사이드바에 삽입 (기존 태그 리스트 바로 위에)
            if (tagListContainer && tagListContainer.parentNode) {
                tagListContainer.parentNode.insertBefore(sidebarBox, tagListContainer);
            } else {
                // 태그 리스트가 없으면 sidebar 맨 앞에 삽입
                sidebar.insertBefore(sidebarBox, sidebar.firstChild);
            }

            // 스타일 추가 (카테고리별 버튼 색상)
            const style = document.createElement('style');
            style.textContent = `
                .rapidbooru-sidebar-tag-btn.selected[data-category="artist"] { background: #7a0a2c !important; }
                .rapidbooru-sidebar-tag-btn[data-category="artist"] { background: #dd5555 !important; }
                .rapidbooru-sidebar-tag-btn.selected[data-category="copyright"] { background: #2d0766 !important; }
                .rapidbooru-sidebar-tag-btn[data-category="copyright"] { background: #8454cc !important; }
                .rapidbooru-sidebar-tag-btn.selected[data-category="character"] { background: #04472d !important; }
                .rapidbooru-sidebar-tag-btn[data-category="character"] { background: #2ab367 !important; }
                .rapidbooru-sidebar-tag-btn.selected[data-category="general"] { background: #10164d !important; }
                .rapidbooru-sidebar-tag-btn[data-category="general"] { background: #47799c !important; }
                .rapidbooru-sidebar-tag-btn.selected[data-category="meta"] { background: #1f1c03 !important; }
                .rapidbooru-sidebar-tag-btn[data-category="meta"] { background: #79722a !important; }
                .rapidbooru-sidebar-tag-btn { outline: none; }
                .rapidbooru-sidebar-tag-btn:active { filter: brightness(0.95); }
            `;
            document.head.appendChild(style);
        }
    }

    // [수정] 태그 그룹 페이지용 태그 버튼 컨테이너 기능 (본문만 변환, Copy 버튼 위치 개선)
    function setupTagGroupPageTagButtons() {
        // 태그 그룹 페이지인지 확인
        if (!/^\/wiki_pages\/tag_group%3A/i.test(window.location.pathname)) return;
        // 본문 컨테이너(id/class 모두 대응)
        const mainContent = document.querySelector('#wiki-page-body.prose') || document.querySelector('.wiki-page-body') || document.querySelector('.content') || document.body;
        if (!mainContent) return;
        // 본문 내 <ul>만 수집 (직계/하위 모두)
        const ulList = Array.from(mainContent.querySelectorAll('ul'));
        if (ulList.length === 0) return;
        // 선택된 태그 임시 리스트
        let tagGroupSelectedTags = [];
        // 스타일 재사용
        const tagColors = {
            artist: { normal: '#dd5555', selected: '#7a0a2c' },
            copyright: { normal: '#8454cc', selected: '#2d0766' },
            character: { normal: '#2ab367', selected: '#04472d' },
            general: { normal: '#47799c', selected: '#10164d' },
            meta: { normal: '#79722a', selected: '#1f1c03' }
        };
        // 태그 타입 추출 함수
        function getTagType(a) {
            if (a.classList.contains('tag-type-1')) return 'artist';
            if (a.classList.contains('tag-type-3')) return 'copyright';
            if (a.classList.contains('tag-type-4')) return 'character';
            if (a.classList.contains('tag-type-5')) return 'meta';
            return 'general';
        }
        // 태그 버튼 컨테이너 생성 함수
        function createTagGroupButtonContainer(tagObjs) {
            const wrapper = document.createElement('div');
            wrapper.style.display = 'flex';
            wrapper.style.flexWrap = 'wrap';
            wrapper.style.gap = '6px';
            wrapper.style.background = '#474756';
            wrapper.style.borderRadius = '8px';
            wrapper.style.padding = '12px 8px';
            wrapper.style.margin = '16px 0';
            wrapper.style.minWidth = '120px';
            tagObjs.forEach(({ tag, type }) => {
                const btn = document.createElement('button');
                btn.type = 'button';
                btn.className = 'rapidbooru-sidebar-tag-btn';
                btn.textContent = tag;
                btn.dataset.tag = tag;
                btn.dataset.category = type;
                btn.style.background = tagColors[type].normal;
                btn.style.color = '#fff';
                btn.style.border = 'none';
                btn.style.borderRadius = '4px';
                btn.style.padding = '6px 10px';
                btn.style.fontSize = '13px';
                btn.style.textAlign = 'left';
                btn.style.cursor = 'pointer';
                btn.style.transition = 'background 0.2s';
                btn.style.userSelect = 'none';
                btn.style.boxShadow = 'none';
                btn.style.position = 'relative';
                btn.style.margin = '0 0 4px 0';
                btn.style.width = 'auto';
                // 좌클릭: 선택/해제
                btn.addEventListener('click', function(e) {
                    if (e.button !== 0) return;
                    e.preventDefault();
                    if (btn.classList.contains('selected')) {
                        btn.classList.remove('selected');
                        btn.style.background = tagColors[type].normal;
                        const idx = tagGroupSelectedTags.indexOf(tag);
                        if (idx > -1) tagGroupSelectedTags.splice(idx, 1);
                    } else {
                        btn.classList.add('selected');
                        btn.style.background = tagColors[type].selected;
                        tagGroupSelectedTags.push(tag);
                    }
                    tagGroupSelectedTags = [...new Set(tagGroupSelectedTags)];
                });
                // 가운데 클릭: 새 탭으로 검색
                btn.addEventListener('mousedown', function(e) {
                    if (e.button === 1) {
                        e.preventDefault();
                        const url = `https://danbooru.donmai.us/posts?tags=${encodeURIComponent(tag.replace(/\s/g, '_'))}`;
                        window.open(url, '_blank');
                    }
                });
                // 우클릭: 태그 프리뷰
                btn.addEventListener('contextmenu', function(e) {
                    e.preventDefault();
                    if (typeof createTagPreview === 'function') createTagPreview(tag);
                });
                wrapper.appendChild(btn);
            });
            return wrapper;
        }
        // 기존 <ul>을 버튼 컨테이너로 교체 (본문 내에서만)
        ulList.forEach(ul => {
            // <ul> 내 <li> -> <a> 추출
            const tagObjs = Array.from(ul.querySelectorAll('li a')).map(a => ({
                tag: a.textContent.trim(),
                type: getTagType(a)
            })).filter(obj => obj.tag.length > 0);
            // 컨테이너 생성
            const btnContainer = createTagGroupButtonContainer(tagObjs);
            ul.parentNode.insertBefore(btnContainer, ul);
            ul.remove();
        });
        // Copy Selected Tags 버튼 생성 (본문 맨 위)
        if (!mainContent.querySelector('.rapidbooru-taggroup-copy-btn')) {
            const copyBtn = document.createElement('button');
            copyBtn.type = 'button';
            copyBtn.textContent = 'Copy Selected Tags';
            copyBtn.className = 'rapidbooru-copy-btn rapidbooru-taggroup-copy-btn';
            copyBtn.style.margin = '0 0 18px 0';
            copyBtn.style.display = 'block';
            copyBtn.style.fontSize = '15px';
            copyBtn.addEventListener('click', function() {
                if (tagGroupSelectedTags.length > 0) {
                    const str = tagGroupSelectedTags.join(', ');
                    navigator.clipboard.writeText(str).then(() => {
                        copyBtn.textContent = 'Copied!';
                        copyBtn.classList.add('copied');
                        setTimeout(() => {
                            copyBtn.textContent = 'Copy Selected Tags';
                            copyBtn.classList.remove('copied');
                        }, 1500);
                    });
                }
            });
            // 본문 맨 앞에 삽입
            mainContent.insertBefore(copyBtn, mainContent.firstChild);
        }
        // 스타일 추가 (카테고리별 버튼 색상)
        if (!document.getElementById('rapidbooru-taggroup-style')) {
            const style = document.createElement('style');
            style.id = 'rapidbooru-taggroup-style';
            style.textContent = `
                .rapidbooru-sidebar-tag-btn.selected[data-category="artist"] { background: #7a0a2c !important; }
                .rapidbooru-sidebar-tag-btn[data-category="artist"] { background: #dd5555 !important; }
                .rapidbooru-sidebar-tag-btn.selected[data-category="copyright"] { background: #2d0766 !important; }
                .rapidbooru-sidebar-tag-btn[data-category="copyright"] { background: #8454cc !important; }
                .rapidbooru-sidebar-tag-btn.selected[data-category="character"] { background: #04472d !important; }
                .rapidbooru-sidebar-tag-btn[data-category="character"] { background: #2ab367 !important; }
                .rapidbooru-sidebar-tag-btn.selected[data-category="general"] { background: #10164d !important; }
                .rapidbooru-sidebar-tag-btn[data-category="general"] { background: #47799c !important; }
                .rapidbooru-sidebar-tag-btn.selected[data-category="meta"] { background: #1f1c03 !important; }
                .rapidbooru-sidebar-tag-btn[data-category="meta"] { background: #79722a !important; }
                .rapidbooru-sidebar-tag-btn { outline: none; }
                .rapidbooru-sidebar-tag-btn:active { filter: brightness(0.95); }
            `;
            document.head.appendChild(style);
        }
    }

    // [추가] I'm Feeling Lucky 버튼 생성 및 기능
    function addLuckyButton() {
        // 메인 페이지에서만 표시
        if (window.location.pathname !== '/' && window.location.pathname !== '/posts') return;
        if (document.getElementById('rapidbooru-lucky-btn')) return;

        const luckyBtn = document.createElement('button');
        luckyBtn.id = 'rapidbooru-lucky-btn';
        luckyBtn.textContent = "I'm Feeling Lucky!";
        luckyBtn.style.position = 'fixed';
        luckyBtn.style.top = '20px';
        luckyBtn.style.right = '20px';
        luckyBtn.style.zIndex = '10003';
        luckyBtn.style.width = '180px';
        luckyBtn.style.height = '50px';
        luckyBtn.style.background = 'var(--rapidbooru-accent-color, #8454cc)';
        luckyBtn.style.color = 'var(--rapidbooru-text-color, #fff)';
        luckyBtn.style.border = 'none';
        luckyBtn.style.borderRadius = '25px';
        luckyBtn.style.boxShadow = '0 4px 8px rgba(0,0,0,0.2)';
        luckyBtn.style.fontWeight = 'bold';
        luckyBtn.style.fontSize = '16px';
        luckyBtn.style.cursor = 'pointer';
        luckyBtn.style.display = 'flex';
        luckyBtn.style.alignItems = 'center';
        luckyBtn.style.justifyContent = 'center';
        luckyBtn.style.transition = 'all 0.3s';
        luckyBtn.style.gap = '8px';

        luckyBtn.addEventListener('mouseenter', () => {
            luckyBtn.style.background = 'var(--rapidbooru-accent-hover-color, #56687a)';
        });
        luckyBtn.addEventListener('mouseleave', () => {
            luckyBtn.style.background = 'var(--rapidbooru-accent-color, #8454cc)';
        });

        luckyBtn.onclick = async function() {
            luckyBtn.disabled = true;
            luckyBtn.textContent = 'Loading...';
            try {
                // 최신 포스트 ID 가져오기
                const resp = await fetch('https://danbooru.donmai.us/posts.json?limit=1&only=id');
                const data = await resp.json();
                if (data && data.length > 0 && data[0].id) {
                    let luckyIndex = data[0].id;
                    // 100만 개 전 범위 내 난수
                    const min = Math.max(1, luckyIndex - 2000000);
                    luckyIndex = Math.floor(Math.random() * (luckyIndex - min + 1)) + min;
                    window.open(`https://danbooru.donmai.us/posts/${luckyIndex}`, '_blank');
                } else {
                    alert('최신 포스트 ID를 가져올 수 없습니다.');
                }
            } catch (e) {
                alert('네트워크 오류로 시도에 실패했습니다.');
            }
            luckyBtn.disabled = false;
            luckyBtn.textContent = "I'm Feeling Lucky!";
        };
        document.body.appendChild(luckyBtn);
    }

    // 태그를 복사하는 함수
    function copyTags(tags) {
        const tagsText = tags.map(t => t.replace(/_/g, ' ')).join(', ');
        navigator.clipboard.writeText(tagsText).then(() => {
            alert('Tags copied to clipboard: ' + tagsText);
        }, (err) => {
            console.error('Error copying tags: ', err);
        });
    }

    // [추가] 사이드바 태그 버튼형 리스트 기능
    function setupSidebarTagButtonList() {
        const path = window.location.pathname;
        if (
            path === '/' ||
            path.startsWith('/posts') ||
            path.startsWith('/wiki_pages')
        ) {
            // 사이드바 컨테이너(태그 리스트의 부모)를 강제로 찾음
            let sidebar = document.querySelector('.sidebar') || document.querySelector('.aside') || document.querySelector('#sidebar') || document.querySelector('.side-menu') || document.body;
            // 기존 태그 리스트(ul, .tag-list 등) 완전히 숨기기
            const tagListCandidates = sidebar.querySelectorAll('.tag-list, .sidebar-section .tag-list, #tag-list, ul[data-category], .sidebar-section, .sidebar');
            tagListCandidates.forEach(el => {
                el.style.display = 'none';
                el.style.visibility = 'hidden';
                el.style.height = '0';
                el.style.margin = '0';
                el.style.padding = '0';
            });
            // 실제 태그 리스트 컨테이너를 찾음 (최초로 발견되는 것)
            let tagListContainer = null;
            for (const el of tagListCandidates) {
                if (el.matches('.tag-list, .sidebar-section .tag-list, #tag-list, ul[data-category]')) {
                    tagListContainer = el;
                    break;
                }
            }
            // 이미 생성된 경우 중복 생성 방지
            if (document.getElementById('rapidbooru-sidebar-taglist')) return;
            // 태그 정보 추출 함수 (카테고리별)
            function extractSidebarTags() {
                const categories = { artist: [], copyright: [], character: [], general: [], meta: [] };
                // ul[data-category] 우선
                const uls = sidebar.querySelectorAll('ul[data-category]');
                if (uls.length > 0) {
                    uls.forEach(ul => {
                        const cat = ul.getAttribute('data-category');
                        let key = '';
                        if (cat === '0') key = 'general';
                        else if (cat === '1') key = 'artist';
                        else if (cat === '3') key = 'copyright';
                        else if (cat === '4') key = 'character';
                        else if (cat === '5') key = 'meta';
                        else return;
                        ul.querySelectorAll('li').forEach(li => {
                            // 실제 태그명과 카운트 파싱 (danbooru 구조에 맞춤)
                            const tagA = li.querySelector('a.search-tag');
                            const countSpan = li.querySelector('span.post-count');
                            if (!tagA) return;
                            const tag = tagA.textContent.trim();
                            const count = countSpan ? countSpan.textContent.trim() : '';
                            if (tag) categories[key].push({ tag, count });
                        });
                    });
                } else {
                    // li.tag-type-x
                    sidebar.querySelectorAll('li, .tag-type-0, .tag-type-1, .tag-type-3, .tag-type-4, .tag-type-5').forEach(li => {
                        let key = '';
                        if (li.classList.contains('tag-type-0')) key = 'general';
                        else if (li.classList.contains('tag-type-1')) key = 'artist';
                        else if (li.classList.contains('tag-type-3')) key = 'copyright';
                        else if (li.classList.contains('tag-type-4')) key = 'character';
                        else if (li.classList.contains('tag-type-5')) key = 'meta';
                        else return;
                        const tagA = li.querySelector('a.search-tag');
                        const countSpan = li.querySelector('span.post-count');
                        if (!tagA) return;
                        const tag = tagA.textContent.trim();
                        const count = countSpan ? countSpan.textContent.trim() : '';
                        if (tag) categories[key].push({ tag, count });
                    });
                }
                return categories;
            }
            // 태그 버튼 생성 함수
            function createSidebarTagButtons(categories) {
                const wrapper = document.createElement('div');
                wrapper.style.display = 'flex';
                wrapper.style.flexDirection = 'column';
                wrapper.style.gap = '0px';
                ['artist', 'copyright', 'character', 'general', 'meta'].forEach(cat => {
                    categories[cat].forEach(({ tag, count }) => {
                        const btn = document.createElement('button');
                        btn.type = 'button';
                        btn.className = 'rapidbooru-sidebar-tag-btn';
                        btn.textContent = tag;
                        btn.dataset.tag = tag;
                        btn.dataset.category = cat;
                        btn.style.background = tagColors[cat].normal;
                        btn.style.color = '#ffffff';
                        btn.style.border = 'none';
                        btn.style.borderRadius = '4px';
                        btn.style.margin = '0 0 4px 0';
                        btn.style.padding = '6px 10px';
                        btn.style.fontSize = '13px';
                        btn.style.textAlign = 'left';
                        btn.style.cursor = 'pointer';
                        btn.style.transition = 'background 0.2s';
                        btn.style.userSelect = 'none';
                        btn.style.width = '100%';
                        btn.style.boxShadow = 'none';
                        btn.style.position = 'relative';
                        // 태그 오른쪽 끝에 count 표시
                        if (count) {
                            const countSpan = document.createElement('span');
                            countSpan.textContent = count;
                            countSpan.style.position = 'absolute';
                            countSpan.style.right = '12px';
                            countSpan.style.top = '50%';
                            countSpan.style.transform = 'translateY(-50%)';
                            countSpan.style.color = '#ffffff';
                            countSpan.style.fontSize = '12px';
                            countSpan.style.pointerEvents = 'none';
                            btn.appendChild(countSpan);
                        }
                        // 좌클릭: 선택/해제
                        btn.addEventListener('click', function(e) {
                            if (e.button !== 0) return;
                            e.preventDefault();
                            if (btn.classList.contains('selected')) {
                                btn.classList.remove('selected');
                                btn.style.background = tagColors[cat].normal;
                                const idx = sidebarSelectedTags.indexOf(tag);
                                if (idx > -1) sidebarSelectedTags.splice(idx, 1);
                            } else {
                                btn.classList.add('selected');
                                btn.style.background = tagColors[cat].selected;
                                sidebarSelectedTags.push(tag);
                            }
                            sidebarSelectedTags = [...new Set(sidebarSelectedTags)];
                        });
                        // 가운데 클릭: 새 탭으로 검색
                        btn.addEventListener('mousedown', function(e) {
                            if (e.button === 1) {
                                e.preventDefault();
                                const url = `https://danbooru.donmai.us/posts?tags=${encodeURIComponent(tag.replace(/\s/g, '_'))}`;
                                window.open(url, '_blank');
                            }
                        });
                        // 우클릭: 태그 프리뷰
                        btn.addEventListener('contextmenu', function(e) {
                            e.preventDefault();
                            createTagPreview(tag);
                        });
                        // 드래그 다중 선택 지원
                        btn.addEventListener('mouseenter', function(e) {
                            if (window.__rapidbooru_sidebar_dragging) {
                                if (!btn.classList.contains('selected')) {
                                    btn.classList.add('selected');
                                    btn.style.background = tagColors[cat].selected;
                                    sidebarSelectedTags.push(tag);
                                    sidebarSelectedTags = [...new Set(sidebarSelectedTags)];
                                } else {
                                    btn.classList.remove('selected');
                                    btn.style.background = tagColors[cat].normal;
                                    const idx = sidebarSelectedTags.indexOf(tag);
                                    if (idx > -1) sidebarSelectedTags.splice(idx, 1);
                                }
                            }
                        });
                        wrapper.appendChild(btn);
                    });
                });
                return wrapper;
            }

            // 사이드바에 삽입할 컨테이너 생성
            const sidebarBox = document.createElement('div');
            sidebarBox.id = 'rapidbooru-sidebar-taglist';
            sidebarBox.style.margin = '24px 0 0 0';
            sidebarBox.style.padding = '12px 8px 12px 8px';
            sidebarBox.style.background = '#474756'; // 배경색 지정
            sidebarBox.style.borderRadius = '8px';
            sidebarBox.style.boxShadow = '0 2px 8px rgba(0,0,0,0.04)';
            sidebarBox.style.display = 'flex';
            sidebarBox.style.flexDirection = 'column';
            sidebarBox.style.alignItems = 'stretch';
            sidebarBox.style.maxHeight = '70vh';
            sidebarBox.style.overflowY = 'auto';
            sidebarBox.style.minWidth = '120px';

            // 버튼 컨테이너(Select All, Copy)
            const topBtnBox = document.createElement('div');
            topBtnBox.style.display = 'flex';
            topBtnBox.style.gap = '8px';
            topBtnBox.style.marginBottom = '12px';

            // Select All 버튼
            const selectAllBtn = document.createElement('button');
            selectAllBtn.type = 'button';
            selectAllBtn.textContent = 'Select All';
            selectAllBtn.className = 'rapidbooru-copy-btn';
            selectAllBtn.style.background = 'linear-gradient(135deg, #56687a 0%, #3c4a58 100%)';
            selectAllBtn.style.flexGrow = '1';
            selectAllBtn.style.fontSize = '13px';
            selectAllBtn.style.padding = '6px 0';
            selectAllBtn.addEventListener('click', function() {
                const btns = sidebarBox.querySelectorAll('.rapidbooru-sidebar-tag-btn');
                const shouldSelectAll = Array.from(btns).some(btn => !btn.classList.contains('selected'));
                btns.forEach(btn => {
                    const tag = btn.dataset.tag;
                    const cat = btn.dataset.category;
                    if (shouldSelectAll) {
                        if (!btn.classList.contains('selected')) {
                            btn.classList.add('selected');
                            btn.style.background = tagColors[cat].selected;
                            sidebarSelectedTags.push(tag);
                        }
                    } else {
                        if (btn.classList.contains('selected')) {
                            btn.classList.remove('selected');
                            btn.style.background = tagColors[cat].normal;
                            const idx = sidebarSelectedTags.indexOf(tag);
                            if (idx > -1) sidebarSelectedTags.splice(idx, 1);
                        }
                    }
                });
                sidebarSelectedTags = [...new Set(sidebarSelectedTags)];
                selectAllBtn.textContent = shouldSelectAll ? 'Deselect All' : 'Select All';
            });

            // Copy Selected Tags 버튼
            const copyBtn = document.createElement('button');
            copyBtn.type = 'button';
            copyBtn.textContent = 'Copy Selected Tags';
            copyBtn.className = 'rapidbooru-copy-btn';
            copyBtn.style.flexGrow = '1';
            copyBtn.style.fontSize = '13px';
            copyBtn.style.padding = '6px 0';
            copyBtn.addEventListener('click', function() {
                if (sidebarSelectedTags.length > 0) {
                    const str = sidebarSelectedTags.join(', ');
                    navigator.clipboard.writeText(str).then(() => {
                        copyBtn.textContent = 'Copied!';
                        copyBtn.classList.add('copied');
                        setTimeout(() => {
                            copyBtn.textContent = 'Copy Selected Tags';
                            copyBtn.classList.remove('copied');
                        }, 1500);
                    });
                }
            });

            topBtnBox.appendChild(selectAllBtn);
            topBtnBox.appendChild(copyBtn);

            // 태그 버튼 리스트 생성
            const categories = extractSidebarTags();
            const tagBtnList = createSidebarTagButtons(categories);

            // 드래그 다중 선택 지원
            sidebarBox.addEventListener('mousedown', function(e) {
                if (e.target.classList.contains('rapidbooru-sidebar-tag-btn') && e.button === 0) {
                    window.__rapidbooru_sidebar_dragging = true;
                }
            });
            sidebarBox.addEventListener('mouseup', function() {
                window.__rapidbooru_sidebar_dragging = false;
            });
            sidebarBox.addEventListener('mouseleave', function() {
                window.__rapidbooru_sidebar_dragging = false;
            });

            // 조립
            sidebarBox.appendChild(topBtnBox);
            sidebarBox.appendChild(tagBtnList);

            // 사이드바에 삽입 (기존 태그 리스트 바로 위에)
            if (tagListContainer && tagListContainer.parentNode) {
                tagListContainer.parentNode.insertBefore(sidebarBox, tagListContainer);
            } else {
                // 태그 리스트가 없으면 sidebar 맨 앞에 삽입
                sidebar.insertBefore(sidebarBox, sidebar.firstChild);
            }

            // 스타일 추가 (카테고리별 버튼 색상)
            const style = document.createElement('style');
            style.textContent = `
                .rapidbooru-sidebar-tag-btn.selected[data-category="artist"] { background: #7a0a2c !important; }
                .rapidbooru-sidebar-tag-btn[data-category="artist"] { background: #dd5555 !important; }
                .rapidbooru-sidebar-tag-btn.selected[data-category="copyright"] { background: #2d0766 !important; }
                .rapidbooru-sidebar-tag-btn[data-category="copyright"] { background: #8454cc !important; }
                .rapidbooru-sidebar-tag-btn.selected[data-category="character"] { background: #04472d !important; }
                .rapidbooru-sidebar-tag-btn[data-category="character"] { background: #2ab367 !important; }
                .rapidbooru-sidebar-tag-btn.selected[data-category="general"] { background: #10164d !important; }
                .rapidbooru-sidebar-tag-btn[data-category="general"] { background: #47799c !important; }
                .rapidbooru-sidebar-tag-btn.selected[data-category="meta"] { background: #1f1c03 !important; }
                .rapidbooru-sidebar-tag-btn[data-category="meta"] { background: #79722a !important; }
                .rapidbooru-sidebar-tag-btn { outline: none; }
                .rapidbooru-sidebar-tag-btn:active { filter: brightness(0.95); }
            `;
            document.head.appendChild(style);
        }
    }

    // [수정] 태그 그룹 페이지용 태그 버튼 컨테이너 기능 (본문만 변환, Copy 버튼 위치 개선)
    function setupTagGroupPageTagButtons() {
        // 태그 그룹 페이지인지 확인
        if (!/^\/wiki_pages\/tag_group%3A/i.test(window.location.pathname)) return;
        // 본문 컨테이너(id/class 모두 대응)
        const mainContent = document.querySelector('#wiki-page-body.prose') || document.querySelector('.wiki-page-body') || document.querySelector('.content') || document.body;
        if (!mainContent) return;
        // 본문 내 <ul>만 수집 (직계/하위 모두)
        const ulList = Array.from(mainContent.querySelectorAll('ul'));
        if (ulList.length === 0) return;
        // 선택된 태그 임시 리스트
        let tagGroupSelectedTags = [];
        // 스타일 재사용
        const tagColors = {
            artist: { normal: '#dd5555', selected: '#7a0a2c' },
            copyright: { normal: '#8454cc', selected: '#2d0766' },
            character: { normal: '#2ab367', selected: '#04472d' },
            general: { normal: '#47799c', selected: '#10164d' },
            meta: { normal: '#79722a', selected: '#1f1c03' }
        };
        // 태그 타입 추출 함수
        function getTagType(a) {
            if (a.classList.contains('tag-type-1')) return 'artist';
            if (a.classList.contains('tag-type-3')) return 'copyright';
            if (a.classList.contains('tag-type-4')) return 'character';
            if (a.classList.contains('tag-type-5')) return 'meta';
            return 'general';
        }
        // 태그 버튼 컨테이너 생성 함수
        function createTagGroupButtonContainer(tagObjs) {
            const wrapper = document.createElement('div');
            wrapper.style.display = 'flex';
            wrapper.style.flexWrap = 'wrap';
            wrapper.style.gap = '6px';
            wrapper.style.background = '#474756';
            wrapper.style.borderRadius = '8px';
            wrapper.style.padding = '12px 8px';
            wrapper.style.margin = '16px 0';
            wrapper.style.minWidth = '120px';
            tagObjs.forEach(({ tag, type }) => {
                const btn = document.createElement('button');
                btn.type = 'button';
                btn.className = 'rapidbooru-sidebar-tag-btn';
                btn.textContent = tag;
                btn.dataset.tag = tag;
                btn.dataset.category = type;
                btn.style.background = tagColors[type].normal;
                btn.style.color = '#fff';
                btn.style.border = 'none';
                btn.style.borderRadius = '4px';
                btn.style.padding = '6px 10px';
                btn.style.fontSize = '13px';
                btn.style.textAlign = 'left';
                btn.style.cursor = 'pointer';
                btn.style.transition = 'background 0.2s';
                btn.style.userSelect = 'none';
                btn.style.boxShadow = 'none';
                btn.style.position = 'relative';
                btn.style.margin = '0 0 4px 0';
                btn.style.width = 'auto';
                // 좌클릭: 선택/해제
                btn.addEventListener('click', function(e) {
                    if (e.button !== 0) return;
                    e.preventDefault();
                    if (btn.classList.contains('selected')) {
                        btn.classList.remove('selected');
                        btn.style.background = tagColors[type].normal;
                        const idx = tagGroupSelectedTags.indexOf(tag);
                        if (idx > -1) tagGroupSelectedTags.splice(idx, 1);
                    } else {
                        btn.classList.add('selected');
                        btn.style.background = tagColors[type].selected;
                        tagGroupSelectedTags.push(tag);
                    }
                    tagGroupSelectedTags = [...new Set(tagGroupSelectedTags)];
                });
                // 가운데 클릭: 새 탭으로 검색
                btn.addEventListener('mousedown', function(e) {
                    if (e.button === 1) {
                        e.preventDefault();
                        const url = `https://danbooru.donmai.us/posts?tags=${encodeURIComponent(tag.replace(/\s/g, '_'))}`;
                        window.open(url, '_blank');
                    }
                });
                // 우클릭: 태그 프리뷰
                btn.addEventListener('contextmenu', function(e) {
                    e.preventDefault();
                    if (typeof createTagPreview === 'function') createTagPreview(tag);
                });
                wrapper.appendChild(btn);
            });
            return wrapper;
        }
        // 기존 <ul>을 버튼 컨테이너로 교체 (본문 내에서만)
        ulList.forEach(ul => {
            // <ul> 내 <li> -> <a> 추출
            const tagObjs = Array.from(ul.querySelectorAll('li a')).map(a => ({
                tag: a.textContent.trim(),
                type: getTagType(a)
            })).filter(obj => obj.tag.length > 0);
            // 컨테이너 생성
            const btnContainer = createTagGroupButtonContainer(tagObjs);
            ul.parentNode.insertBefore(btnContainer, ul);
            ul.remove();
        });
        // Copy Selected Tags 버튼 생성 (본문 맨 위)
        if (!mainContent.querySelector('.rapidbooru-taggroup-copy-btn')) {
            const copyBtn = document.createElement('button');
            copyBtn.type = 'button';
            copyBtn.textContent = 'Copy Selected Tags';
            copyBtn.className = 'rapidbooru-copy-btn rapidbooru-taggroup-copy-btn';
            copyBtn.style.margin = '0 0 18px 0';
            copyBtn.style.display = 'block';
            copyBtn.style.fontSize = '15px';
            copyBtn.addEventListener('click', function() {
                if (tagGroupSelectedTags.length > 0) {
                    const str = tagGroupSelectedTags.join(', ');
                    navigator.clipboard.writeText(str).then(() => {
                        copyBtn.textContent = 'Copied!';
                        copyBtn.classList.add('copied');
                        setTimeout(() => {
                            copyBtn.textContent = 'Copy Selected Tags';
                            copyBtn.classList.remove('copied');
                        }, 1500);
                    });
                }
            });
            // 본문 맨 앞에 삽입
            mainContent.insertBefore(copyBtn, mainContent.firstChild);
        }
        // 스타일 추가 (카테고리별 버튼 색상)
        if (!document.getElementById('rapidbooru-taggroup-style')) {
            const style = document.createElement('style');
            style.id = 'rapidbooru-taggroup-style';
            style.textContent = `
                .rapidbooru-sidebar-tag-btn.selected[data-category="artist"] { background: #7a0a2c !important; }
                .rapidbooru-sidebar-tag-btn[data-category="artist"] { background: #dd5555 !important; }
                .rapidbooru-sidebar-tag-btn.selected[data-category="copyright"] { background: #2d0766 !important; }
                .rapidbooru-sidebar-tag-btn[data-category="copyright"] { background: #8454cc !important; }
                .rapidbooru-sidebar-tag-btn.selected[data-category="character"] { background: #04472d !important; }
                .rapidbooru-sidebar-tag-btn[data-category="character"] { background: #2ab367 !important; }
                .rapidbooru-sidebar-tag-btn.selected[data-category="general"] { background: #10164d !important; }
                .rapidbooru-sidebar-tag-btn[data-category="general"] { background: #47799c !important; }
                .rapidbooru-sidebar-tag-btn.selected[data-category="meta"] { background: #1f1c03 !important; }
                .rapidbooru-sidebar-tag-btn[data-category="meta"] { background: #79722a !important; }
                .rapidbooru-sidebar-tag-btn { outline: none; }
                .rapidbooru-sidebar-tag-btn:active { filter: brightness(0.95); }
            `;
            document.head.appendChild(style);
        }
    }

    // [추가] 테마 및 기능 설정
    const rapidbooruSettings = {
        '--rapidbooru-bg-color': '#2a2a2a',
        '--rapidbooru-secondary-bg-color': '#1a1a1a',
        '--rapidbooru-accent-color': '#667eea',
        '--rapidbooru-accent-hover-color': '#5a6fd8',
        '--rapidbooru-text-color': '#ffffff',
        '--rapidbooru-border-color': '#444',
        'searchOrder': 'Jaccard',
    };

    function applySettings(settings) {
        const styleId = 'rapidbooru-theme-styles';
        let styleElement = document.getElementById(styleId);
        if (!styleElement) {
            styleElement = document.createElement('style');
            styleElement.id = styleId;
            document.head.appendChild(styleElement);
        }
        const cssVariables = Object.entries(settings)
            .filter(([key]) => key.startsWith('--'))
            .map(([key, value]) => `${key}: ${value};`)
            .join('\n');
        styleElement.textContent = `:root { ${cssVariables} }`;
    }

    function saveSettings(settings) {
        Object.assign(rapidbooruSettings, settings); // Update global settings object
        localStorage.setItem('rapidbooru_settings', JSON.stringify(rapidbooruSettings));
        applySettings(rapidbooruSettings);
    }

    function loadSettings() {
        const savedSettings = localStorage.getItem('rapidbooru_settings');
        if (savedSettings) {
            try {
                Object.assign(rapidbooruSettings, JSON.parse(savedSettings));
            } catch (e) {
                console.error('Rapidbooru: Failed to parse settings', e);
                localStorage.removeItem('rapidbooru_settings');
            }
        }
        applySettings(rapidbooruSettings);
    }

    function createSettingsPanel() {
        const panelId = 'rapidbooru-settings-panel';
        if (document.getElementById(panelId)) return;

        const panel = document.createElement('div');
        panel.id = panelId;
        panel.className = 'rapidbooru-overlay';
        panel.style.display = 'none'; // Initially hidden
        panel.style.zIndex = '10003'; // Ensure panel is on top of the button

        const content = document.createElement('div');
        content.className = 'rapidbooru-preview';
        content.style.flexDirection = 'column';
        content.style.width = '400px';
        content.style.height = 'auto';
        content.style.padding = '20px';
        content.style.background = 'var(--rapidbooru-bg-color)';
        content.style.color = 'var(--rapidbooru-text-color)';

        const title = document.createElement('h3');
        title.textContent = 'Settings';
        title.style.textAlign = 'center';
        title.style.marginBottom = '20px';

        const hidePanel = () => {
            panel.classList.remove('show'); // Start fade-out animation
            // After transition, hide the element completely
            setTimeout(() => {
                panel.style.display = 'none';
            }, 300); // Must match CSS transition duration
        };

        const form = document.createElement('div');
        form.style.display = 'grid';
        form.style.gridTemplateColumns = 'auto 1fr';
        form.style.gap = '15px';
        form.style.alignItems = 'center';

        const createColorInput = (label, key) => {
            const labelEl = document.createElement('label');
            labelEl.textContent = label;

            const inputEl = document.createElement('input');
            inputEl.type = 'color';
            inputEl.value = rapidbooruSettings[key];
            inputEl.dataset.key = key;
            inputEl.style.width = '100px';
            inputEl.style.height = '40px';
            inputEl.style.border = 'none';
            inputEl.style.padding = '0';
            inputEl.style.background = 'none';
            inputEl.style.cursor = 'pointer';

            form.appendChild(labelEl);
            form.appendChild(inputEl);
        };

        createColorInput('프리뷰 창 배경', '--rapidbooru-bg-color');
        createColorInput('프리뷰 창 사이드', '--rapidbooru-secondary-bg-color');
        createColorInput('메인 버튼1', '--rapidbooru-accent-color');
        createColorInput('메인 버튼2', '--rapidbooru-accent-hover-color');
        createColorInput('글자', '--rapidbooru-text-color');
        createColorInput('테두리', '--rapidbooru-border-color');

        // [추가] 검색 방식 드롭다운
        const createSelectInput = (label, key, options) => {
            const labelEl = document.createElement('label');
            labelEl.textContent = label;

            const selectEl = document.createElement('select');
            selectEl.dataset.key = key;
            selectEl.style.width = '100px';
            selectEl.style.height = '40px';
            selectEl.style.padding = '5px';
            selectEl.style.background = 'var(--rapidbooru-secondary-bg-color)';
            selectEl.style.color = 'var(--rapidbooru-text-color)';
            selectEl.style.border = `1px solid var(--rapidbooru-border-color)`;
            selectEl.style.borderRadius = '4px';

            options.forEach(opt => {
                const optionEl = document.createElement('option');
                optionEl.value = opt;
                optionEl.textContent = opt;
                selectEl.appendChild(optionEl);
            });

            form.appendChild(labelEl);
            form.appendChild(selectEl);
        };

        createSelectInput('검색 방식', 'searchOrder', ['Jaccard', 'Frequency']);

        const buttonContainer = document.createElement('div');
        buttonContainer.style.display = 'flex';
        buttonContainer.style.justifyContent = 'flex-end';
        buttonContainer.style.gap = '10px';
        buttonContainer.style.marginTop = '20px';

        const saveBtn = document.createElement('button');
        saveBtn.textContent = 'Save';
        saveBtn.className = 'rapidbooru-btn';
        saveBtn.onclick = () => {
            const newSettings = { ...rapidbooruSettings };
            form.querySelectorAll('[data-key]').forEach(input => {
                newSettings[input.dataset.key] = input.value;
            });
            saveSettings(newSettings);
            hidePanel();
        };

        const closeBtn = document.createElement('button');
        closeBtn.textContent = 'Close';
        closeBtn.className = 'rapidbooru-btn';
        closeBtn.style.background = '#aaa';
        closeBtn.onclick = () => {
            hidePanel();
        };

        buttonContainer.appendChild(closeBtn);
        buttonContainer.appendChild(saveBtn);

        // [여기서부터 추가] 초기화 버튼
        const resetBtn = document.createElement('button');
        resetBtn.type = 'button';
        resetBtn.className = 'rapidbooru-btn';
        resetBtn.style.position = 'absolute';
        resetBtn.style.left = '24px';
        resetBtn.style.bottom = '24px';
        resetBtn.style.background = '#e74c3c';
        resetBtn.style.color = '#fff';
        resetBtn.style.display = 'flex';
        resetBtn.style.alignItems = 'center';
        resetBtn.style.gap = '6px';
        resetBtn.innerHTML = `
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" style="vertical-align:middle;">
                <path d="M12 5V2L7 7l5 5V8c3.31 0 6 2.69 6 6 0 3.31-2.69 6-6 6s-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z" fill="currentColor"/>
            </svg>
            Reset
        `;
        // 기본값 정의
        const rapidbooruDefaultSettings = {
            '--rapidbooru-bg-color': '#2a2a2a',
            '--rapidbooru-secondary-bg-color': '#1a1a1a',
            '--rapidbooru-accent-color': '#667eea',
            '--rapidbooru-accent-hover-color': '#5a6fd8',
            '--rapidbooru-text-color': '#ffffff',
            '--rapidbooru-border-color': '#444',
            'searchOrder': 'Jaccard',
        };
        resetBtn.onclick = () => {
            saveSettings({ ...rapidbooruDefaultSettings });
            // 폼 값도 즉시 반영
            Object.entries(rapidbooruDefaultSettings).forEach(([key, value]) => {
                const input = panel.querySelector(`[data-key="${key}"]`);
                if (input) input.value = value;
            });
        };
        // content에 상대적 위치를 위해 position:relative 적용
        content.style.position = 'relative';
        content.appendChild(resetBtn);
        // [여기까지 추가]

        content.appendChild(title);
        content.appendChild(form);
        content.appendChild(buttonContainer);
        panel.appendChild(content);

        panel.onclick = (e) => {
            if (e.target === panel) {
                hidePanel();
            }
        };

        document.body.appendChild(panel);
    }

    function createSettingsButton() {
        const btn = document.createElement('button');
        btn.id = 'rapidbooru-settings-btn';
        btn.title = 'Rapidbooru Settings';
        btn.innerHTML = `<svg width="24" height="24" viewBox="0 0 24 24" fill="white"><path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c.04.32.07.65.07.98s-.03.66-.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z" fill="currentColor"/>
        </svg>`;

        btn.onclick = () => {
            const panel = document.getElementById('rapidbooru-settings-panel');
            if (panel) {
                panel.style.display = 'flex'; // Make it visible
                setTimeout(() => panel.classList.add('show'), 10); // Add 'show' to trigger fade-in
                // Populate form with current settings from the global object
                Object.entries(rapidbooruSettings).forEach(([key, value]) => {
                    const input = panel.querySelector(`[data-key="${key}"]`);
                    if (input) {
                        input.value = value;
                    }
                });
            }
        };

        document.body.appendChild(btn);
    }

    // 초기화
    function init() {
        loadSettings();
        addStyles();
        addLuckyButton();
        setupImagePreview();
        setupTagPreview();
        setupRelatedTagsFeature();
        setupSidebarTagButtonList(); // [추가] 사이드바 태그 버튼형 리스트
        setupTagGroupPageTagButtons(); // [추가] 태그 그룹 페이지용 태그 버튼 컨테이너
        createSettingsPanel();
        createSettingsButton();
        console.log('Rapidbooru script loaded');
    }

    // DOM이 로드되면 초기화
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

})();