Greasy Fork

Greasy Fork is available in English.

아카라이브 미리보기 이미지, 모두 열기

아카라이브 미리보기 이미지 생성, 모두 열기 생성, 그 외 잡다한 기능..

当前为 2024-12-28 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         아카라이브 미리보기 이미지, 모두 열기
// @version      1.31
// @icon         https://www.google.com/s2/favicons?sz=64&domain=arca.live
// @description  아카라이브 미리보기 이미지 생성, 모두 열기 생성, 그 외 잡다한 기능..
// @author       ChatGPT
// @match        https://arca.live/b/*
// @match        https://arca.live/u/scrap_list
// @grant        GM_registerMenuCommand
// @grant        GM_unregisterMenuCommand
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_xmlhttpRequest
// @require      https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js
// @namespace Violentmonkey Scripts
// ==/UserScript==

(function() {
    'use strict';

    var config = {
        openAllButton: true,
        downAllButton: false,
        countImages: true,
        compressFiles: true,
        originalImage: false,
        downNumber: false,
        thumbnail: true,
        thumbWidth: 100,
        thumbHeight: 62,
        thumbHover: true,
        thumbBlur: true,
        blurAmount: 2,
        origThumb: true,
        thumbHoverBest: true,
        closeButton: false,
        bookmarkButton: true,
        downButton: false,
        scrapList: true,
        filterBold: true,
        test01: false,
        test02: false
    };

    function handleSettings() {
        var descriptions = {
            openAllButton: '모두 열기 버튼 생성',
            downAllButton: '모든 이미지 다운로드 버튼 생성',
            countImages: '모든 이미지의 총 개수를 구하고 진행률 표시',
            compressFiles: '모든 이미지를 압축해서 다운로드',
            originalImage: '원본 이미지로 다운로드(체크 해제시 webp저장)',
            downNumber: '게시글 번호를 누르면 해당 게시글 이미지 다운로드',
            thumbnail: '미리보기 이미지 생성',
            thumbWidth: '미리보기 이미지 너비',
            thumbHeight: '미리보기 이미지 높이',
            thumbHover: '미리보기 이미지 마우스 오버시 보이게',
            thumbBlur: '블러 효과를 적용할지 여부',
            blurAmount: '블러 효과의 정도',
            origThumb: '유머채널 개념글 미리보기 이미지 클릭 시 원본 이미지 불러오기',
            thumbHoverBest: '개념글 미리보기 이미지 마우스 오버시 보이게',
            closeButton: '하단 우측 창닫기 버튼 생성',
            bookmarkButton: '하단 우측 스크랩 버튼 생성',
            downButton: '하단 우측 다운로드 버튼 생성',
            scrapList: '스크랩한 게시글 채널별, 탭별 필터링',
            filterBold: '필터링한 게시글 볼드체로 변경',
            test01: '미리보기 이미지 마우스 오버시 해당 게시글 다른 이미지 가져오기',
            test02: '미리보기 이미지를 해당 게시글 다른 이미지로 대체'
        };

        var mainConfigKeys = Object.keys(descriptions).filter(key =>
            !['thumbWidth', 'thumbHeight', 'thumbHover', 'thumbBlur', 'blurAmount', 'origThumb'].includes(key)
        );

        function saveConfig() {
            for (var key in config) {
                if (config.hasOwnProperty(key)) {
                    GM_setValue(key, config[key]);
                }
            }
        }

        function loadConfig() {
            for (var key in config) {
                if (config.hasOwnProperty(key)) {
                    config[key] = GM_getValue(key, config[key]);
                }
            }
        }

        function createThumbnailSettingsWindow() {
            var existingSettingsWindow = document.getElementById('thumbnailSettingsWindow');
            if (existingSettingsWindow) {
                existingSettingsWindow.remove();
            }

            var settingsWindow = document.createElement('div');
            settingsWindow.id = 'thumbnailSettingsWindow';
            settingsWindow.style.position = 'fixed';
            settingsWindow.style.top = '50%';
            settingsWindow.style.left = '50%';
            settingsWindow.style.transform = 'translate(-50%, -50%)';
            settingsWindow.style.width = '250px';
            settingsWindow.style.padding = '20px';
            settingsWindow.style.background = '#ffffff';
            settingsWindow.style.border = '1px solid #cccccc';
            settingsWindow.style.borderRadius = '10px';
            settingsWindow.style.boxShadow = '0px 0px 10px rgba(0, 0, 0, 0.3)';
            settingsWindow.style.zIndex = '9999';
            settingsWindow.style.textAlign = 'left';
            settingsWindow.style.display = 'flex';
            settingsWindow.style.flexDirection = 'column';
            settingsWindow.style.alignItems = 'center';

            var settingsTitle = document.createElement('div');
            settingsTitle.innerHTML = 'Thumbnail';
            settingsTitle.style.fontSize = '24px';
            settingsTitle.style.fontWeight = 'bold';
            settingsTitle.style.marginBottom = '10px';
            settingsTitle.style.textAlign = 'center'; // Add this line to center-align the title
            settingsWindow.appendChild(settingsTitle);

            var keys = ['thumbWidth', 'thumbHeight', 'thumbHover', 'thumbBlur', 'blurAmount', 'origThumb'];

            keys.forEach(function(key) {
                var configDiv = document.createElement('div');
                configDiv.style.marginBottom = '5px';
                configDiv.style.display = 'flex';
                configDiv.style.alignItems = 'center';

                var label = document.createElement('label');
                label.innerHTML = key + ': ';
                label.style.marginRight = '5px';
                label.style.marginBottom = '3px';
                label.title = descriptions[key];

                var input = document.createElement('input');
                input.type = (typeof config[key] === 'boolean') ? 'checkbox' : 'text';
                input.value = config[key];
                input.checked = config[key];
                if (input.type === 'text') {
                    input.style.width = '40px';
                    input.style.height = '20px';
                    input.style.padding = '0 5px';
                }
                input.addEventListener('input', (function(key) {
                    return function(event) {
                        if (key === 'blurAmount') {
                            event.target.value = event.target.value.replace(/\D/g, '');
                        }
                        config[key] = event.target.type === 'checkbox' ? event.target.checked : event.target.value;
                    };
                })(key));

                configDiv.appendChild(label);
                configDiv.appendChild(input);
                settingsWindow.appendChild(configDiv);
            });

            var buttonContainer = document.createElement('div');
            buttonContainer.style.display = 'flex';
            buttonContainer.style.marginTop = '10px';

            var confirmButton = document.createElement('button');
            confirmButton.innerHTML = '확인';
            confirmButton.style.marginRight = '15px';
            confirmButton.style.border = '1px solid #cccccc';
            confirmButton.style.borderRadius = '5px';
            confirmButton.addEventListener('click', function() {
                saveConfig();
                settingsWindow.remove();
                location.reload();
            });
            confirmButton.addEventListener('mouseover', function() {
                confirmButton.style.background = '#007bff';
                confirmButton.style.color = '#ffffff';
            });
            confirmButton.addEventListener('mouseout', function() {
                confirmButton.style.background = '';
                confirmButton.style.color = '#000000';
            });
            buttonContainer.appendChild(confirmButton);

            var cancelButton = document.createElement('button');
            cancelButton.innerHTML = '취소';
            cancelButton.style.border = '1px solid #cccccc';
            cancelButton.style.borderRadius = '5px';
            cancelButton.addEventListener('click', function() {
                settingsWindow.remove();
            });
            cancelButton.addEventListener('mouseover', function() {
                cancelButton.style.background = '#ff0000';
                cancelButton.style.color = '#ffffff';
            });
            cancelButton.addEventListener('mouseout', function() {
                cancelButton.style.background = '';
                cancelButton.style.color = '#000000';
            });
            buttonContainer.appendChild(cancelButton);

            settingsWindow.appendChild(buttonContainer);
            document.body.appendChild(settingsWindow);
        }

        function createLinkSettingsWindow() {
            var existingLinkSettingsWindow = document.getElementById('linkSettingsWindow');
            if (existingLinkSettingsWindow) {
                existingLinkSettingsWindow.remove();
            }

            var linkSettingsWindow = document.createElement('div');
            linkSettingsWindow.id = 'linkSettingsWindow';
            linkSettingsWindow.style.position = 'fixed';
            linkSettingsWindow.style.top = '50%';
            linkSettingsWindow.style.left = '50%';
            linkSettingsWindow.style.transform = 'translate(-50%, -50%)';
            linkSettingsWindow.style.width = '400px';
            linkSettingsWindow.style.padding = '20px';
            linkSettingsWindow.style.background = '#ffffff';
            linkSettingsWindow.style.border = '1px solid #cccccc';
            linkSettingsWindow.style.borderRadius = '10px';
            linkSettingsWindow.style.boxShadow = '0px 0px 10px rgba(0, 0, 0, 0.3)';
            linkSettingsWindow.style.zIndex = '9999';
            linkSettingsWindow.style.textAlign = 'left';
            linkSettingsWindow.style.display = 'flex';
            linkSettingsWindow.style.flexDirection = 'column';
            linkSettingsWindow.style.alignItems = 'center';

            var title = document.createElement('div');
            title.innerHTML = 'Filter Link';
            title.style.fontSize = '24px';
            title.style.fontWeight = 'bold';
            title.style.marginBottom = '20px';
            title.style.textAlign = 'center';
            linkSettingsWindow.appendChild(title);

            var linkListContainer = document.createElement('div');
            linkListContainer.style.marginBottom = '10px';
            linkSettingsWindow.appendChild(linkListContainer);

            // Load saved links and display them
            var savedLinks = GM_getValue('savedLinks', []);

            var rowContainer = document.createElement('div');
            rowContainer.style.display = 'flex';
            rowContainer.style.flexWrap = 'wrap';
            rowContainer.style.justifyContent = 'center';  // 가로 중앙 정렬
            rowContainer.style.alignItems = 'center';  // 세로 중앙 정렬
            rowContainer.style.gap = '10px'; // Adds spacing between items
            linkListContainer.appendChild(rowContainer);

            savedLinks.forEach(function (link, index) {
                var linkDiv = document.createElement('div');
                linkDiv.style.display = 'flex';
                linkDiv.style.flexDirection = 'column';
                linkDiv.style.alignItems = 'center';
                linkDiv.style.marginBottom = '10px';
                linkDiv.style.width = '60px'; // Ensure all items have a fixed width to align properly

                // Create a small thumbnail image
                var thumbnail = document.createElement('img');
                thumbnail.src = link; // Set the link as the image source
                thumbnail.style.width = '50px'; // Adjust thumbnail width
                thumbnail.style.height = '50px'; // Adjust thumbnail height
                thumbnail.style.objectFit = 'cover'; // Ensure the image fits nicely
                thumbnail.style.marginBottom = '5px';

                // Add click event to set the link in the input field
                thumbnail.addEventListener('click', function () {
                    var linkInput = document.querySelector('#linkInput'); // 입력창 선택
                    if (linkInput) {
                        linkInput.value = link; // 클릭된 이미지의 링크를 입력창에 설정
                    }
                });

                var deleteButton = document.createElement('button');
                deleteButton.textContent = 'Delete';
                deleteButton.style.border = '1px solid #cccccc';
                deleteButton.style.borderRadius = '5px';
                deleteButton.style.marginTop = '5px';
                deleteButton.style.fontSize = '12px';
                deleteButton.addEventListener('click', function () {
                    savedLinks.splice(index, 1);
                    GM_setValue('savedLinks', savedLinks);
                    createLinkSettingsWindow();
                });

                linkDiv.appendChild(thumbnail);
                linkDiv.appendChild(deleteButton);
                rowContainer.appendChild(linkDiv);
            });

            var addLinkContainer = document.createElement('div');
            addLinkContainer.style.display = 'flex';
            addLinkContainer.style.alignItems = 'center';

            var linkInput = document.createElement('input');
            linkInput.type = 'text';
            linkInput.id = 'linkInput'; // 입력창에 id를 추가
            linkInput.placeholder = 'Add new link';
            linkInput.style.flex = '1';
            linkInput.style.marginRight = '10px';
            linkInput.style.padding = '5px';
            addLinkContainer.appendChild(linkInput);

            var addLinkButton = document.createElement('button');
            addLinkButton.textContent = 'Add';
            addLinkButton.style.border = '1px solid #cccccc';
            addLinkButton.style.borderRadius = '5px';
            addLinkButton.addEventListener('click', function () {
                var newLink = linkInput.value.trim();
                if (newLink && !savedLinks.includes(newLink)) {
                    savedLinks.push(newLink);
                    GM_setValue('savedLinks', savedLinks);
                    createLinkSettingsWindow();
                }
            });

            addLinkContainer.appendChild(linkInput);
            addLinkContainer.appendChild(addLinkButton);
            linkSettingsWindow.appendChild(addLinkContainer);

            var tooltip = document.createElement('div');
            tooltip.innerHTML = '제외할 이미지 링크를 입력하세요';
            tooltip.style.fontSize = '12px';
            tooltip.style.marginTop = '15px';
            tooltip.style.marginBottom = '5px';
            tooltip.style.color = 'gray';
            linkSettingsWindow.appendChild(tooltip);

            var buttonContainer = document.createElement('div');
            buttonContainer.style.display = 'flex';
            buttonContainer.style.marginTop = '10px';

            var confirmButton = document.createElement('button');
            confirmButton.innerHTML = '확인';
            confirmButton.style.marginRight = '15px';
            confirmButton.style.border = '1px solid #cccccc';
            confirmButton.style.borderRadius = '5px';
            confirmButton.addEventListener('click', function() {
                saveConfig();
                linkSettingsWindow.remove();
            });
            confirmButton.addEventListener('mouseover', function() {
                confirmButton.style.background = '#007bff';
                confirmButton.style.color = '#ffffff';
            });
            confirmButton.addEventListener('mouseout', function() {
                confirmButton.style.background = '';
                confirmButton.style.color = '#000000';
            });
            buttonContainer.appendChild(confirmButton);

            var cancelButton = document.createElement('button');
            cancelButton.innerHTML = '취소';
            cancelButton.style.border = '1px solid #cccccc';
            cancelButton.style.borderRadius = '5px';
            cancelButton.addEventListener('click', function() {
                linkSettingsWindow.remove();
            });
            cancelButton.addEventListener('mouseover', function() {
                cancelButton.style.background = '#ff0000';
                cancelButton.style.color = '#ffffff';
            });
            cancelButton.addEventListener('mouseout', function() {
                cancelButton.style.background = '';
                cancelButton.style.color = '#000000';
            });
            buttonContainer.appendChild(cancelButton);

            linkSettingsWindow.appendChild(buttonContainer);

            document.body.appendChild(linkSettingsWindow);
        }

        function createSettingsWindow() {
            var existingSettingsWindow = document.getElementById('settingsWindow');
            if (existingSettingsWindow) {
                existingSettingsWindow.remove();
            }

            var settingsWindow = document.createElement('div');
            settingsWindow.id = 'settingsWindow';
            settingsWindow.style.position = 'fixed';
            settingsWindow.style.top = '50%';
            settingsWindow.style.left = '50%';
            settingsWindow.style.transform = 'translate(-50%, -50%)';
            settingsWindow.style.width = '250px';
            settingsWindow.style.padding = '20px';
            settingsWindow.style.background = '#ffffff';
            settingsWindow.style.border = '1px solid #cccccc';
            settingsWindow.style.borderRadius = '10px';
            settingsWindow.style.boxShadow = '0px 0px 10px rgba(0, 0, 0, 0.3)';
            settingsWindow.style.zIndex = '9999';
            settingsWindow.style.textAlign = 'left';
            settingsWindow.style.display = 'flex';
            settingsWindow.style.flexDirection = 'column';
            settingsWindow.style.alignItems = 'center';

            var settingsTitle = document.createElement('div');
            settingsTitle.innerHTML = 'Settings';
            settingsTitle.style.fontSize = '24px';
            settingsTitle.style.fontWeight = 'bold';
            settingsTitle.style.marginBottom = '10px';
            settingsWindow.appendChild(settingsTitle);

            mainConfigKeys.forEach(function(key) {
                var configDiv = document.createElement('div');
                configDiv.style.marginBottom = '5px';
                configDiv.style.display = 'flex';
                configDiv.style.alignItems = 'center';

                var label = document.createElement('label');
                label.innerHTML = key + ': ';
                label.style.marginRight = '5px';
                label.style.marginBottom = '3px';
                label.title = descriptions[key];

                var input = document.createElement('input');
                input.type = (typeof config[key] === 'boolean') ? 'checkbox' : 'text';
                input.value = config[key];
                input.checked = config[key];
                if (input.type === 'text') {
                    input.style.width = '40px';
                    input.style.height = '20px';
                    input.style.padding = '0 5px';
                }
                input.addEventListener('input', (function(key) {
                    return function(event) {
                        config[key] = event.target.type === 'checkbox' ? event.target.checked : event.target.value;
                    };
                })(key));

                configDiv.appendChild(label);
                configDiv.appendChild(input);

                if (key === 'thumbnail' || key === 'test01') {
                    var settingsIcon = document.createElement('span');
                    settingsIcon.innerHTML = '⚙️';
                    settingsIcon.style.cursor = 'pointer';
                    settingsIcon.style.marginLeft = '3px';
                    settingsIcon.style.marginBottom = '2px';
                    settingsIcon.addEventListener('click', function() {
                        if (key === 'thumbnail') {
                            createThumbnailSettingsWindow();
                        } else if (key === 'test01') {
                            createLinkSettingsWindow();
                        }
                    });
                    configDiv.appendChild(settingsIcon);
                }

                settingsWindow.appendChild(configDiv);
            });

            var tooltip = document.createElement('div');
            tooltip.innerHTML = '마우스를 올리면 설명이 나옵니다';
            tooltip.style.fontSize = '12px';
            tooltip.style.marginTop = '5px';
            tooltip.style.marginBottom = '10px';
            tooltip.style.color = 'gray';
            settingsWindow.appendChild(tooltip);

            var buttonContainer = document.createElement('div');
            buttonContainer.style.display = 'flex';
            buttonContainer.style.marginTop = '10px';

            var confirmButton = document.createElement('button');
            confirmButton.innerHTML = '확인';
            confirmButton.style.marginRight = '15px';
            confirmButton.style.border = '1px solid #cccccc';
            confirmButton.style.borderRadius = '5px';
            confirmButton.addEventListener('click', function() {
                saveConfig();
                settingsWindow.remove();
                location.reload();
            });
            confirmButton.addEventListener('mouseover', function() {
                confirmButton.style.background = '#007bff';
                confirmButton.style.color = '#ffffff';
            });
            confirmButton.addEventListener('mouseout', function() {
                confirmButton.style.background = '';
                confirmButton.style.color = '#000000';
            });
            buttonContainer.appendChild(confirmButton);

            var cancelButton = document.createElement('button');
            cancelButton.innerHTML = '취소';
            cancelButton.style.border = '1px solid #cccccc';
            cancelButton.style.borderRadius = '5px';
            cancelButton.addEventListener('click', function() {
                settingsWindow.remove();
            });
            cancelButton.addEventListener('mouseover', function() {
                cancelButton.style.background = '#ff0000';
                cancelButton.style.color = '#ffffff';
            });
            cancelButton.addEventListener('mouseout', function() {
                cancelButton.style.background = '';
                cancelButton.style.color = '#000000';
            });
            buttonContainer.appendChild(cancelButton);

            settingsWindow.appendChild(buttonContainer);
            document.body.appendChild(settingsWindow);
        }

        loadConfig();

        GM_registerMenuCommand('설정', function() {
            createSettingsWindow();
        });
    }

    function arcaLiveScrapList() {
        // Add the filter div before the list header
        const header = document.querySelector('.list-table ');
        const filterContainerDiv = document.createElement('div');
        filterContainerDiv.style.display = 'flex';
        filterContainerDiv.style.marginBottom = '10px';

        // 페이징 요소의 HTML을 가져옵니다.
        const paginationHTML = document.querySelector('.pagination.justify-content-center');
        if (paginationHTML) {
            // 새로운 div 요소를 생성하고 HTML 코드를 삽입합니다.
            const newDiv = document.createElement('div');
            newDiv.innerHTML = paginationHTML.outerHTML;

            // 헤더 요소 앞에 새로운 HTML 코드를 추가합니다.
            header.parentNode.insertBefore(newDiv, header);
        }

        // Create filter div
        const filterDiv = document.createElement('div');
        filterDiv.className = 'filterDiv'; // 클래스 이름을 여기에 추가하세요
        filterDiv.style.display = 'flex';
        filterDiv.style.marginRight = '10px';

        // Create "모두 열기" button
        const openLinksButton = document.createElement('a');
        openLinksButton.className = 'btn btn-sm btn-primary float-left';
        openLinksButton.href = '#';
        openLinksButton.innerHTML = '<span class="ion-android-list" style="margin-right: 5px;"></span><span> 모두 열기 </span>';
        openLinksButton.style.display = 'flex'; // flexbox 사용
        openLinksButton.style.alignItems = 'center'; // 세로축 중앙 정렬
        openLinksButton.style.justifyContent = 'center'; // 가로축 중앙 정렬
        filterContainerDiv.appendChild(openLinksButton);

        // Create channel filter
        const channelFilter = document.createElement('select');
        channelFilter.className = 'form-control select-list-type';
        channelFilter.name = 'sort';
        channelFilter.style.width = 'auto'; // 채널 필터의 폭을 150px로 지정합니다.
        const defaultChannelOption = document.createElement('option');
        defaultChannelOption.value = '';
        defaultChannelOption.text = '채널 선택';
        channelFilter.appendChild(defaultChannelOption);
        filterDiv.appendChild(channelFilter);

        // Create tab filter
        const tabFilter = document.createElement('select');
        tabFilter.className = 'form-control select-list-type';
        tabFilter.name = 'sort';
        tabFilter.style.width = 'auto'; // 채널 필터의 폭을 150px로 지정합니다.
        const defaultTabOption = document.createElement('option');
        defaultTabOption.value = '';
        defaultTabOption.text = '탭 선택';
        tabFilter.appendChild(defaultTabOption);
        filterDiv.appendChild(tabFilter);

        filterContainerDiv.appendChild(filterDiv);
        header.parentNode.insertBefore(filterContainerDiv, header);

        // Collect channels and tabs
        const posts = document.querySelectorAll('.vrow.column.filtered, .vrow.column');
        const channelTabMap = {};

        posts.forEach(post => {
            const badges = post.querySelectorAll('.badge');
            if (badges.length >= 2) {
                const channel = badges[0].textContent.trim();
                const tab = badges[1].textContent.trim();
                if (!channelTabMap[channel]) {
                    channelTabMap[channel] = new Set();
                }
                channelTabMap[channel].add(tab);
            }
        });

        // Populate channel filter
        Object.keys(channelTabMap).forEach(channel => {
            const option = document.createElement('option');
            option.value = channel;
            option.text = channel;
            channelFilter.appendChild(option);
        });

        // Update tab filter based on selected channel
        function updateTabFilter() {
            const selectedChannel = channelFilter.value;
            tabFilter.innerHTML = '';
            const defaultTabOption = document.createElement('option');
            defaultTabOption.value = '';
            defaultTabOption.text = '탭 선택';
            tabFilter.appendChild(defaultTabOption);

            if (selectedChannel && channelTabMap[selectedChannel]) {
                channelTabMap[selectedChannel].forEach(tab => {
                    const option = document.createElement('option');
                    option.value = tab;
                    option.text = tab;
                    tabFilter.appendChild(option);
                });
            }

            filterPosts();
        }

        // Filter posts based on selected channel and tab
        function filterPosts() {
            const selectedChannel = channelFilter.value;
            const selectedTab = tabFilter.value;

            posts.forEach(post => {
                const badges = post.querySelectorAll('.badge');
                if (badges.length >= 2) {
                    const postChannel = badges[0].textContent.trim();
                    const postTab = badges[1].textContent.trim();
                    if ((selectedChannel === '' || postChannel === selectedChannel) &&
                        (selectedTab === '' || postTab === selectedTab)) {
                        post.style.display = '';
                    } else {
                        post.style.display = 'none';
                    }
                }
            });
        }

        // Open visible links in new windows
        function openVisibleLinks(event) {
            event.preventDefault();
            const visiblePosts = document.querySelectorAll('.vrow.column');
            visiblePosts.forEach(post => {
                if (post.style.display !== 'none') {
                    const link = post
                    if (link && link.href) {
                        window.open(link.href, '_blank');
                    }
                }
            });
        }

        channelFilter.addEventListener('change', updateTabFilter);
        tabFilter.addEventListener('change', filterPosts);
        openLinksButton.addEventListener('click', openVisibleLinks);
    }

    function arcaLive() {
        // 모두 열기 버튼 생성
        if (config.openAllButton) {
            var openAllButton = document.createElement('a');
            openAllButton.className = 'btn btn-sm btn-primary float-left';
            openAllButton.href = '#';
            openAllButton.innerHTML = '<span class="ion-android-list"></span><span> 모두 열기 </span>';

            openAllButton.addEventListener('click', function(event) {
                event.preventDefault();
                document.querySelectorAll('a.vrow.column:not(.notice)').forEach(function(element) {
                    var href = element.getAttribute('href');
                    var classes = element.className.split(' ');
                    if (href && !classes.includes('filtered') && !classes.includes('filtered-keyword')) {
                        window.open(href, '_blank');
                    }
                });
            });

            var targetElement = document.querySelector('.form-control.select-list-type');
            targetElement.parentNode.insertBefore(openAllButton, targetElement);
        }

        // 이미지와 동영상 다운로드 버튼 생성
        if (config.downAllButton) {
            var downloadMediaButton = document.createElement('a');
            downloadMediaButton.className = 'btn btn-sm btn-success float-left';
            downloadMediaButton.href = '#';
            downloadMediaButton.innerHTML = '<span class="ion-android-download"></span><span> 다운로드 </span>';
            downloadMediaButton.style.position = 'relative'; // 상대 위치 지정

            // 프로그레스 바 스타일을 가진 div 엘리먼트 추가
            var progressBar = document.createElement('div');
            progressBar.id = 'progress-bar'; // ID 추가
            progressBar.style.position = 'absolute'; // 절대 위치 지정
            progressBar.style.bottom = '5%';
            progressBar.style.left = '0';
            progressBar.style.width = '0%'; // 초기 너비는 0%
            progressBar.style.height = '10%';
            progressBar.style.backgroundColor = 'yellow'; // 프로그레스 바 색상
            progressBar.style.borderRadius = 'inherit';
            progressBar.style.transition = 'width 0.3s ease-in-out'; // 프로그레스 바 애니메이션
            downloadMediaButton.appendChild(progressBar); // 프로그레스 바를 버튼에 추가

            downloadMediaButton.addEventListener('click', async function(event) {
                event.preventDefault();
                var mediaUrls = []; // 다운로드할 미디어 URL을 저장할 배열
                document.querySelectorAll('a.vrow.column:not(.notice)').forEach(function(element) {
                    var href = element.getAttribute('href');
                    var classes = element.className.split(' ');
                    if (href && !classes.includes('filtered') && !classes.includes('filtered-keyword')) {
                        mediaUrls.push(href); // 미디어 URL을 배열에 추가
                    }
                });

                if (config.countImages) {
                    // 페이지의 상단부터 순서대로 다운로드 시작
                    const totalImages = await getTotalImages(mediaUrls);
                    const confirmMessage = `다운로드해야 할 이미지의 총 개수는 ${totalImages}개입니다.
        계속해서 다운로드 하시겠습니까?`;
                    if (confirm(confirmMessage)) {
                        progressBar.style.width = '0%'; // 초기 너비는 0%
                        progressBar.style.backgroundColor = 'yellow'; // 프로그레스 바 색상
                        await downloadMediaSequentially(mediaUrls, totalImages, config.compressFiles); // config.compressFiles 변수 전달
                    }
                } else {
                    // 프로그레스 바를 사용하지 않을 경우에는 다운로드 여부를 확인하는 창 띄우기
                    const confirmMessage = "모든 게시글의 이미지를 한 번에 다운로드합니다.\n계속 진행하시겠습니까?";
                    if (confirm(confirmMessage)) {
                        progressBar.style.width = '0%'; // 초기 너비는 0%
                        progressBar.style.backgroundColor = 'yellow'; // 프로그레스 바 색상
                        await downloadMediaSequentially(mediaUrls, 0, config.compressFiles); // config.compressFiles 변수 전달
                        progressBar.style.width = '100%';
                        progressBar.style.backgroundColor = 'orange'; // 100%일 때 배경색을 주황색으로 변경

                    }
                }
            });

            var targetElement = document.querySelector('.form-control.select-list-type');
            targetElement.parentNode.insertBefore(downloadMediaButton, targetElement);
        }

        async function getTotalImages(urls) {
            let totalImages = 0;
            for (const url of urls) {
                const response = await fetch(url);
                const html = await response.text();
                const doc = new DOMParser().parseFromString(html, "text/html");
                const imageElements = Array.from(doc.querySelectorAll('.article-body img')).filter(img => !img.classList.contains('arca-emoticon'));
                const gifVideoElements = doc.querySelectorAll('video[data-orig="gif"][data-originalurl]');
                totalImages += imageElements.length + gifVideoElements.length;
            }
            return totalImages;
        }

        async function downloadMediaSequentially(urls, totalImages, compressFiles) {
            let totalDownloaded = 0;

            // 프로그레스 바 업데이트 함수
            function updateProgressBar(progress) {
                const progressBar = document.getElementById('progress-bar');
                progressBar.style.width = progress + '%';
                progressBar.innerHTML = progress + '%';
                if (progress === 100) {
                    setTimeout(() => {
                        progressBar.style.backgroundColor = 'orange'; // 100%일 때 배경색을 주황색으로 변경
                    }, 300); // 잠시 딜레이를 주어 애니메이션 완료 후 색상 변경
                }
            }

            async function downloadFile(url, index, type, requestUrl, zip, title) {
                const response = await fetch(url);
                const blob = await response.blob();
                const extension = type === 'img' ? (config.originalImage ? url.split('.').pop().split('?')[0].toLowerCase() : 'webp') : 'gif';
                const numbersFromUrl = requestUrl.match(/\d+/)[0];
                const fileIndex = index + 1; // Index를 1 증가시킴
                // const sanitizedTitle = title.replace(/[^a-zA-Z0-9가-힣\s]/g, '_'); // 파일 이름에 사용할 수 있도록 제목을 정제
                const numberedFileName = compressFiles ? `${title}_${String(fileIndex).padStart(2, '0')}.${extension}` : `${numbersFromUrl}_${String(fileIndex).padStart(2, '0')}.${extension}`;
                if (zip) {
                    zip.file(numberedFileName, blob);
                } else {
                    const link = document.createElement('a');
                    link.href = window.URL.createObjectURL(blob);
                    link.download = numberedFileName;
                    link.click();
                }
            }

            async function processNextUrl() {
                for (let index = 0; index < urls.length; index++) {
                    const url = urls[index];

                    let zip;
                    if (compressFiles) {
                        zip = new JSZip();
                    }
                    const response = await fetch(url);
                    const html = await response.text();
                    const doc = new DOMParser().parseFromString(html, "text/html");

                    const titleElement = doc.querySelector('.title-row .title');
                    let title = '';
                    if (titleElement) {
                        const textNodes = Array.from(titleElement.childNodes)
                            .filter(node => node.nodeType === Node.TEXT_NODE && node.parentElement === titleElement);
                        if (textNodes.length > 0) {
                            title = textNodes.map(node => node.textContent.trim()).join('');
                        }
                    }

                    // arca-emoticon 클래스를 가진 이미지를 제외하고 선택
                    const mediaElements = Array.from(doc.querySelectorAll('.article-body img, .article-body video[data-orig="gif"]')).filter(media => !media.classList.contains('arca-emoticon'));
                    try {
                        if (mediaElements.length > 0) {
                            for (let i = 0; i < mediaElements.length; i++) {
                                const media = mediaElements[i];
                                const mediaType = media.tagName.toLowerCase();
                                const mediaUrl = mediaType === 'img' ? (config.originalImage ? media.getAttribute('src') + "&type=orig" : media.getAttribute('src')) : media.getAttribute('data-originalurl');
                                if (mediaUrl) {
                                    await downloadFile(mediaUrl, i, mediaType, url, zip, title);
                                    totalDownloaded++;
                                    if (config.countImages) {
                                        const progress = Math.round((totalDownloaded / totalImages) * 100);
                                        updateProgressBar(progress);
                                    }
                                }
                            }
                            if (zip) {
                                const content = await zip.generateAsync({ type: 'blob' });
                                const numbersFromUrl = url.match(/\d+/)[0];
                                const zipFileName = `${numbersFromUrl}.zip`;
                                const zipLink = document.createElement('a');
                                zipLink.href = window.URL.createObjectURL(content);
                                zipLink.download = zipFileName;
                                zipLink.click();
                            }
                        }
                    } catch (error) {
                        console.error("Error downloading media:", error);
                    }
                }
            }

            await processNextUrl();
        }

        document.addEventListener("DOMContentLoaded", function() {
            if (config.downNumber) {
                document.querySelectorAll('.vrow.column:not(.notice) .vcol.col-id').forEach(function(link) {
                    link.addEventListener('click', async function(event) {
                        event.preventDefault();  // 기본 동작 방지
                        link.style.color = 'orange'; // 다운로드 시작 시 노란색으로 변경
                        const parentHref = link.closest('.vrow.column').getAttribute('href');
                        await downloadMediaFromUrl(parentHref, config.compressFiles); // compressFiles 변수 전달
                        link.style.color = 'red'; // 다운로드 완료 시 빨간색으로 변경
                    });
                });

                async function downloadMediaFromUrl(url, compressFiles) { // compressFiles 변수 추가
                    const response = await fetch(url);
                    const html = await response.text();
                    const doc = new DOMParser().parseFromString(html, "text/html");
                    const mediaElements = Array.from(doc.querySelectorAll('.article-body img, .article-body video[data-orig="gif"]')).filter(media => !media.classList.contains('arca-emoticon'));
                    let zip;

                    const titleElement = doc.querySelector('.title-row .title');
                    let title = '';
                    if (titleElement) {
                        const textNodes = Array.from(titleElement.childNodes)
                            .filter(node => node.nodeType === Node.TEXT_NODE && node.parentElement === titleElement);
                        if (textNodes.length > 0) {
                            title = textNodes.map(node => node.textContent.trim()).join('');
                        }
                    }

                    async function downloadFile(mediaUrl, index, type) {
                        const response = await fetch(mediaUrl);
                        const blob = await response.blob();
                        const extension = type === 'img' ? (config.originalImage ? mediaUrl.split('.').pop().split('?')[0].toLowerCase() : 'webp') : 'gif';
                        const fileIndex = index + 1;
                        const numbersFromUrl = url.match(/\d+/)[0];
                        // const sanitizedTitle = title.replace(/[^a-zA-Z0-9가-힣\s]/g, '_'); // 파일 이름에 사용할 수 있도록 제목을 정제
                        const numberedFileName = compressFiles ? `${title}_${String(fileIndex).padStart(2, '0')}.${extension}` : `${numbersFromUrl}_${String(fileIndex).padStart(2, '0')}.${extension}`;
                        if (compressFiles) {
                            zip.file(numberedFileName, blob);
                        } else {
                            const link = document.createElement('a');
                            link.href = window.URL.createObjectURL(blob);
                            link.download = numberedFileName;
                            link.click();
                        }
                    }

                    async function processMedia() {
                        for (let i = 0; i < mediaElements.length; i++) {
                            const media = mediaElements[i];
                            const mediaType = media.tagName.toLowerCase();
                            const mediaUrl = mediaType === 'img' ? (config.originalImage ? media.getAttribute('src') + "&type=orig" : media.getAttribute('src')) : media.getAttribute('data-originalurl');
                            if (mediaUrl) {
                                await downloadFile(mediaUrl, i, mediaType);
                            }
                        }
                    }

                    if (compressFiles) {
                        zip = new JSZip();
                    }

                    await processMedia();

                    if (compressFiles) {
                        const content = await zip.generateAsync({ type: 'blob' });
                        const zipFileName = url.match(/\d+/)[0] + '.zip';
                        const zipLink = document.createElement('a');
                        zipLink.href = window.URL.createObjectURL(content);
                        zipLink.download = zipFileName;
                        zipLink.click();
                    }
                }
            }
        });

        function checkBlackEdge(image, callback) {
            var img = new Image();
            img.crossOrigin = 'anonymous';
            img.onload = function() {
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');
                canvas.width = img.width;
                canvas.height = img.height;
                ctx.drawImage(img, 0, 0, img.width, img.height);

                var edgeSize = Math.min(img.width, img.height) * 0.1;
                var imageData = ctx.getImageData(0, 0, img.width, img.height);

                var totalPixels = 0;
                var blackPixels = 0;

                for (var x = 0; x < img.width; x++) {
                    for (var y = 0; y < img.height; y++) {
                        if (x < edgeSize || x >= img.width - edgeSize || y < edgeSize || y >= img.height - edgeSize) {
                            totalPixels++;
                            var index = (y * img.width + x) * 4;
                            var pixelData = [
                                imageData.data[index],     // Red
                                imageData.data[index + 1], // Green
                                imageData.data[index + 2]  // Blue
                            ];
                            if (pixelData[0] === 0 && pixelData[1] === 0 && pixelData[2] === 0) {
                                blackPixels++;
                            }
                        }
                    }
                }

                var blackPercentage = blackPixels / totalPixels;
                if (blackPercentage >= 0.33) {
                    callback(true);
                } else {
                    callback(false);
                }
                // console.log(blackPercentage);
            };
            img.onerror = function() {
                // 이미지 로드 실패 시에도 콜백 호출하여 처리
                callback(false);
            };
            img.src = image.src + "&type=list"; // img.src = image.src + "&type=list";
        }

        function setSecondImg(element, img , type) {
            var href = element.href;
            // GM_xmlhttpRequest를 사용하여 링크의 페이지 내용을 가져옵니다.
            GM_xmlhttpRequest({
                method: "GET",
                url: href,
                onload: function(response) {
                    // 가져온 페이지의 내용을 HTML 요소로 변환합니다.
                    var parser = new DOMParser();
                    var htmlDoc = parser.parseFromString(response.responseText, "text/html");

                    // "fr-view article-content" 클래스를 가진 div 요소를 찾습니다.
                    var contentDiv = htmlDoc.querySelector('div.fr-view.article-content');

                    // console.log(contentDiv);
                    // 모든 p 태그를 가져옵니다.
                    var Tags = contentDiv.querySelectorAll('img, video');

                    var firstTag = null;

                    for (var i = 0; i < Tags.length; i++) {
                        firstTag = Tags[i];
                        if (firstTag.style.width == '2px' && firstTag.style.height == '2px'){
                          break;
                        } else if (firstTag.tagName.toLowerCase() === 'img') {
                            if (!(img.src.split("?")[0] === firstTag.src.split("?")[0])){
                                break;
                            }
                        } else if (firstTag.tagName.toLowerCase() === 'video'){
                          break;
                        }
                    }

                    var videoOriginalSrc = firstTag.getAttribute('data-originalurl');
                    var videoOriginalSrcType = firstTag.getAttribute('data-orig');
                    var videoPosterSrc = firstTag.getAttribute('poster');

                    var changeImgUrl = null;
                    if (firstTag.tagName.toLowerCase() === 'img') {
                        changeImgUrl = firstTag.src + "&type=list";
                    } else if (firstTag.tagName.toLowerCase() === 'video') {
                        if (videoOriginalSrc && !videoOriginalSrcType) {
                            changeImgUrl = videoOriginalSrc + "&type=list";
                        } else if (videoPosterSrc) {
                            changeImgUrl = videoPosterSrc + "&type=list";
                        } else {
                            changeImgUrl = img.src;
                        }
                    } else {
                      // console.log("???");
                    }

                    if(config.test02){
                        img.src = changeImgUrl;
                    }
                    // console.log(firstTag.tagName);
                    element.querySelector('.vrow-preview img').src = changeImgUrl;
                }
            });
        }

        document.addEventListener('DOMContentLoaded', function() {
            if (config.thumbnail) {
                document.querySelectorAll('a.vrow.column:not(.notice)').forEach(function(element) {
                    var vcolId = element.querySelector('.vrow-top .vcol.col-id');
                    var vcolTitle = element.querySelector('.vrow-top .vcol.col-title');
                    vcolId.style.margin = '0';

                    var vcolThumb = element.querySelector('.vcol.col-thumb');
                    if (!vcolThumb) {
                        vcolThumb = document.createElement('span');
                        vcolThumb.className = 'vcol col-thumb';
                        vcolThumb.style.borderRadius = '3px';
                        element.querySelector('.vrow-inner').appendChild(vcolThumb);
                        vcolTitle.parentNode.insertBefore(vcolThumb, vcolTitle);
                    }

                    var vrowPreview = element.querySelector('.vrow-preview');

                    function createThumbnail() {
                        var vrowPreviewImg = vrowPreview ? vrowPreview.querySelector('img') : null;
                        if (!vrowPreviewImg) return;

                        element.style.height = 'auto';
                        element.style.paddingTop = '3.75px';
                        element.style.paddingBottom = '3.75px';

                        var thumbImage = vcolThumb.querySelector('img');
                        if (!thumbImage) {
                            thumbImage = document.createElement('img');
                            thumbImage.src = vrowPreviewImg.src;
                            thumbImage.style.width = config.thumbWidth + 'px';
                            thumbImage.style.height = config.thumbHeight + 'px';
                            thumbImage.style.objectFit = 'cover';

                            vcolId.style.height = config.thumbHeight + 'px';
                            vcolId.style.display = 'flex';
                            vcolId.style.alignItems = 'center'; // 세로 가운데 정렬
                            vcolId.style.justifyContent = 'center'; // 가로 가운데 정렬

                            if (config.test01 || config.test02) {
                                checkBlackEdge(thumbImage, function(hasBlackEdge) {
                                    if (hasBlackEdge) {
                                        setSecondImg(element, thumbImage, true);
                                    }
                                });

                                var savedLinks = GM_getValue('savedLinks', []);
                                function removeQueryString(url) {
                                    var parsedUrl = new URL(url);
                                    return parsedUrl.origin + parsedUrl.pathname;
                                }

                                var cleanSrc = removeQueryString(thumbImage.src);
                                if (savedLinks.some(link => cleanSrc.includes(removeQueryString(link)))) {
                                    setSecondImg(element, thumbImage, true);
                                    console.log("Filtered Image:", vcolId.querySelector('span').textContent, thumbImage.src);
                                }
                            }

                            if (config.thumbBlur) {
                                thumbImage.style.filter = 'blur(' + config.blurAmount + 'px)';
                                thumbImage.addEventListener('mouseenter', function() {
                                    thumbImage.style.filter = 'none';
                                });
                                thumbImage.addEventListener('mouseleave', function() {
                                    thumbImage.style.filter = 'blur(' + config.blurAmount + 'px)';
                                });
                            }

                            vcolThumb.appendChild(thumbImage);

                        }
                        vrowPreview.style.display = 'none';
                        vrowPreview.style.width = '30rem';
                        vrowPreview.style.height = 'auto';
                        vrowPreview.style.top = 'auto';
                        vrowPreview.style.left = '13.5rem';

                        var thumbImageValue = false;
                        thumbImage.addEventListener('mouseenter', function() {
                            if (thumbImageValue == false) {
                                vrowPreviewImg.src = vrowPreviewImg.src.replace("&type=list", '');
                                thumbImageValue = true;
                            }
                            vrowPreview.style.display = null;
                        });
                        thumbImage.addEventListener('mouseleave', function() {
                            vrowPreview.style.display = 'none';
                        });
                    }

                    function tryCreateThumbnail(retryCount) {
                        if (retryCount >= 3) return;
                        setTimeout(function() {
                            if (retryCount === 0) createThumbnail();
                            tryCreateThumbnail(retryCount + 1);
                        }, 100);
                    }
                    tryCreateThumbnail(0);
                });
            }
        });


        // 썸네일 클릭 시 원본 이미지 불러오기
        if (config.origThumb) {
            document.querySelectorAll('a.title.preview-image').forEach(function(link) {
                link.addEventListener('click', function(event) {
                    event.preventDefault();  // 기본 동작 방지
                    var imageUrl = link.querySelector('img').getAttribute('src').replace(/&type=list/g, '');
                    window.location.href = imageUrl;
                });
            });
        }

        // 개념글 미리보기 이미지 마우스 오버시 보이게
        if (config.thumbHoverBest) {
            // 이미지 요소 선택
            var vrowPreviewImgs = document.querySelectorAll('.vrow.hybrid .title.preview-image .vrow-preview img');

            // 각 이미지 요소에 이벤트 추가
            vrowPreviewImgs.forEach(function(vrowPreviewImg) {
                // 이미지에 호버 이벤트 추가
                vrowPreviewImg.addEventListener('mouseenter', function() {
                    // 이미지의 부모 요소 찾기
                    var parentDiv = vrowPreviewImg.closest('.vrow.hybrid');

                    // 복제된 이미지 요소 생성
                    var duplicatevrowPreviewImg = document.createElement('img');
                    duplicatevrowPreviewImg.src = vrowPreviewImg.src.replace('&type=list', '');

                    // 복제된 이미지의 스타일 설정
                    duplicatevrowPreviewImg.style.position = 'absolute';
                    duplicatevrowPreviewImg.style.width = '30rem';
                    duplicatevrowPreviewImg.style.height = 'auto';
                    duplicatevrowPreviewImg.style.top = 'auto';
                    duplicatevrowPreviewImg.style.left = '7.5rem'; // 오른쪽으로 10rem 이동
                    duplicatevrowPreviewImg.style.zIndex = '1';
                    duplicatevrowPreviewImg.style.padding = '5px';
                    duplicatevrowPreviewImg.style.border = '1px solid';
                    duplicatevrowPreviewImg.style.borderRadius = '5px';
                    duplicatevrowPreviewImg.style.boxSizing = 'content-box';
                    duplicatevrowPreviewImg.style.backgroundColor = '#fff'; // 배경색
                    duplicatevrowPreviewImg.style.borderColor = '#bbb'; // 테두리 색상

                    // vrow hybrid 클래스에 align-items: center; 스타일 추가
                    parentDiv.classList.add('hybrid');
                    parentDiv.style.alignItems = 'center'; // 수직 가운데 정렬

                    // 복제된 이미지 요소를 기존 이미지 요소 다음에 추가
                    parentDiv.appendChild(duplicatevrowPreviewImg);

                    // 마우스를 이미지에서 떼었을 때 복제된 이미지 제거
                    vrowPreviewImg.addEventListener('mouseleave', function() {
                        duplicatevrowPreviewImg.remove();
                    });
                });
            });
        }

        if (config.closeButton || config.bookmarkButton || config.downButton) {
            'use strict';

            var navControl = document.querySelector('.nav-control');
            var originalScrapButton = document.querySelector('.scrap-btn');

            // 새로운 리스트 아이템 요소를 생성하는 함수
            function createNewItem(iconClass, clickHandler, hoverHandler) {
                var newItem = document.createElement('li');
                newItem.innerHTML = '<span class="' + iconClass + '"></span>';
                newItem.addEventListener('click', clickHandler);
                if (hoverHandler) {
                    newItem.addEventListener('mouseenter', hoverHandler);
                    newItem.addEventListener('mouseleave', function() {
                        newItem.style.backgroundColor = ''; // 마우스를 뗐을 때 배경색 초기화
                    });
                }
                return newItem;
            }

            // 새로운 아이템을 내비게이션 컨트롤 리스트에 추가하거나 업데이트하는 함수
            function appendOrUpdateItem(newItem) {
                if (navControl) {
                    if (navControl.children.length > 0) {
                        navControl.insertBefore(newItem, navControl.firstElementChild);
                    } else {
                        navControl.appendChild(newItem);
                    }
                } else {
                    console.error('내비게이션 컨트롤 리스트를 찾을 수 없습니다.');
                }
            }

            // 닫기 버튼 클릭 핸들러
            function closeButtonClickHandler() {
                window.close();
            }

            // 닫기 버튼 호버 핸들러
            function closeButtonHoverHandler() {
                this.style.backgroundColor = 'red';
            }

            // 북마크 버튼 클릭 핸들러
            function bookmarkButtonClickHandler() {
                if (originalScrapButton) {
                    originalScrapButton.click();
                } else {
                    console.error('원래의 스크랩 버튼을 찾을 수 없습니다.');
                }
            }

            // 다운로드 버튼 클릭 핸들러
            function downloadButtonClickHandler() {
                if (imageToZipBtn) {
                    imageToZipBtn.click();
                } else {
                    console.error('이미지를 Zip으로 변환하는 버튼을 찾을 수 없습니다.');
                }
            }
            if (config.bookmarkButton) {
                if (originalScrapButton) {
                    var bookmarkButton = createNewItem('ion-android-bookmark', bookmarkButtonClickHandler);
                    appendOrUpdateItem(bookmarkButton);

                    // 북마크 버튼 색상을 업데이트하는 함수
                    function updateButtonColor() {
                        var buttonText = originalScrapButton.querySelector('.result').textContent.trim();
                        bookmarkButton.style.backgroundColor = (buttonText === "스크랩 됨") ? '#007bff' : '';
                    }

                    // 초기 호출 및 MutationObserver 설정
                    updateButtonColor();
                    var observer = new MutationObserver(updateButtonColor);
                    observer.observe(originalScrapButton.querySelector('.result'), { childList: true, subtree: true });
                }
            }

            // 닫기 버튼 생성 및 추가
            if (config.closeButton) {
                var closeButton = createNewItem('ion-close-round', closeButtonClickHandler, closeButtonHoverHandler);
                appendOrUpdateItem(closeButton);
            }

            // DOMContentLoaded 이벤트 사용하여 다운로드 버튼 생성
            document.addEventListener('DOMContentLoaded', function() {
                if (config.downButton) {
                    setTimeout(function() {
                        var imageToZipBtn = document.querySelector('#imageToZipBtn');
                        if (imageToZipBtn) {
                            var downloadButton = createNewItem('ion-android-download', downloadButtonClickHandler);
                            appendOrUpdateItem(downloadButton);
                        }
                    }, 100); // 1000 밀리초 (1초) 지연
                }
            });
        }


        document.addEventListener('DOMContentLoaded', function() {
            // 요소를 찾음
            var targetElement = document.getElementById('imageToZipBtn');
            var downloadButton = document.querySelector('li span.ion-android-download');
            if (targetElement && downloadButton) {
                // 이벤트 핸들러 등록
                targetElement.addEventListener('click', function() {
                    // 0.1초마다 실행되는 함수
                    var intervalId = setInterval(function() {
                        // 요소의 자식 노드 확인
                        var downloadProgress = targetElement.querySelector('.download-progress');
                        if (downloadProgress) {
                            var width = parseFloat(downloadProgress.style.width);
                            // 다운로드 버튼이 있는 리스트 아이템에 아래서 위로 채워지는 효과를 줍니다.
                            downloadButton.parentElement.style.background = `linear-gradient(to top, green ${width}%, transparent ${width}%)`;
                        } else {
                            // downloadProgress가 없으면 intervalId를 사용하여 반복을 중지합니다.
                            downloadButton.parentElement.style.background = `linear-gradient(to top, green 100%, transparent 100%)`;
                            clearInterval(intervalId);
                        }
                    }, 100);
                });
            }
        });
    }

    function filterBold() {
        const filters = document.querySelectorAll('.vrow.column.filtered.filtered-keyword .title');

        filters.forEach(element => {
            // 타이틀의 텍스트를 볼드체로 변경
            element.style.fontWeight = 'bold';
        });
    }

    handleSettings();

    if (config.filterBold) {
        document.addEventListener('DOMContentLoaded', filterBold);
    }

    if (window.location.href.includes('https://arca.live/u/scrap_list')) {
        if (config.scrapList){
            arcaLiveScrapList();
        }
    } else {
        arcaLive();
    }
})();