M3Unator - Web Directory Playlist Creator

Create M3U/M3U8 playlists from directory listing pages. Automatically finds video and audio files in web server indexes.

// ==UserScript==
// @name         M3Unator - Web Directory Playlist Creator
// @namespace    https://github.com/hasanbeder/M3Unator
// @version      1.0.2
// @description  Create M3U/M3U8 playlists from directory listing pages. Automatically finds video and audio files in web server indexes.
// @author       Hasan Beder
// @license      GPL-3.0
// @match        *://*/*
// @grant        GM_addStyle
// @icon         data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNmNWMyZTciIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cG9seWdvbiBwb2ludHM9IjIzIDcgMTYgMTIgMjMgMTcgMjMgNyIvPjxyZWN0IHg9IjEiIHk9IjUiIHdpZHRoPSIxNSIgaGVpZ2h0PSIxNCIgcng9IjIiIHJ5PSIyIi8+PC9zdmc+
// @homepageURL  https://github.com/hasanbeder/M3Unator
// @supportURL   https://github.com/hasanbeder/M3Unator/issues
// @run-at       document-end
// @noframes     true
// ==/UserScript==

(function() {
    'use strict';

    if (!document.title.includes('Index of') && !document.querySelector('div#table-list')) {
        console.log('This page is not an Index page, M3Unator disabled.');
        return;
    }

    function parseLiteSpeedDirectory() {
        const links = [];
        const rows = document.querySelectorAll('#table-content tr');
        
        rows.forEach(row => {
            const linkElement = row.querySelector('a');
            if (linkElement && !linkElement.textContent.includes('Parent Directory')) {
                const href = linkElement.getAttribute('href');
                if (href) {
                    links.push(new URL(href, window.location.href).href);
                }
            }
        });
        
        return links;
    }

    // Add LiteSpeed support to the existing getDirectoryLinks function
    function getDirectoryLinks() {
        const links = [];
        
        // LiteSpeed directory listing
        if (document.querySelector('div#table-list')) {
            const rows = document.querySelectorAll('#table-content tr');
            rows.forEach(row => {
                const linkElement = row.querySelector('a');
                if (linkElement && !linkElement.textContent.includes('Parent Directory')) {
                    const href = linkElement.getAttribute('href');
                    if (href) {
                        links.push(new URL(href, window.location.href).href);
                    }
                }
            });
            return links;
        }
        
        // Apache/Nginx style directory listing
        const anchors = document.querySelectorAll('a');
        anchors.forEach(anchor => {
            if (!anchor.textContent.includes('Parent Directory')) {
                const href = anchor.getAttribute('href');
                if (href && !href.startsWith('?') && !href.startsWith('/')) {
                    links.push(new URL(href, window.location.href).href);
                }
            }
        });
        
        return links;
    }

    GM_addStyle(`
        @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');

        [class^="M3Unator"] {
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
        }

        .M3Unator-title {
            font-weight: 700;
            letter-spacing: -0.02em;
        }

        .M3Unator-input-group label {
            font-weight: 500;
            letter-spacing: -0.01em;
        }

        .M3Unator-input {
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
            font-size: 0.9375rem;
            letter-spacing: -0.01em;
        }

        .M3Unator-button {
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
            font-weight: 600;
            letter-spacing: -0.01em;
        }

        .M3Unator-control-btn {
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
            font-weight: 500;
            letter-spacing: -0.01em;
        }

        .M3Unator-log {
            font-family: 'SF Mono', Consolas, 'Liberation Mono', Menlo, monospace;
            font-size: 0.8125rem;
            letter-spacing: -0.01em;
            line-height: 1.5;
        }

        .M3Unator-log-counter {
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
            font-weight: 600;
            letter-spacing: -0.01em;
        }

        .M3Unator-container {
            position: fixed;
            inset: 0;
            background: rgba(0, 0, 0, 0.75);
            backdrop-filter: blur(8px);
            display: none;
            place-items: center;
            padding: 1rem;
            z-index: 9999;
        }

        .M3Unator-container[data-visible="true"] {
            display: grid;
        }

        .M3Unator-overlay {
            position: fixed;
            inset: 0;
            background: transparent;
            z-index: 9998;
        }

        body.modal-open {
            overflow: hidden;
            pointer-events: none; /* Prevent background clicks */
        }

        body.modal-open .M3Unator-container,
        body.modal-open .M3Unator-popup {
            pointer-events: all; /* Allow clicks on modal content */
        }

        .M3Unator-popup {
            background: #11111b;
            color: #cdd6f4;
            width: 100%;
            max-width: 480px;
            border-radius: 12px;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
            overflow: hidden;
            animation: slideUp 0.3s ease;
            position: absolute;
        }

        .M3Unator-header {
            padding: 1.25rem 1.618rem;
            background: #1e1e2e;
            color: #cdd6f4;
            display: flex;
            align-items: center;
            justify-content: space-between;
            cursor: move;
            user-select: none;
            border-bottom: 1px solid #313244;
        }

        .M3Unator-title {
            display: flex;
            align-items: center;
            gap: 0.75rem;
            margin: 0;
            font-size: 1.25rem;
            font-weight: 600;
            line-height: 1;
        }

        .M3Unator-title svg {
            width: 24px;
            height: 24px;
            color: #f5c2e7;
            filter: drop-shadow(0 0 8px rgba(245, 194, 231, 0.4));
            flex-shrink: 0;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-top: 1px;
        }

        .M3Unator-title span {
            display: flex;
            align-items: center;
            line-height: 24px;
            background: linear-gradient(90deg,
                #f5c2e7,
                #cba6f7,
                #89b4fa,
                #a6e3a1,
                #f5c2e7
            );
            background-size: 300% auto;
            -webkit-background-clip: text;
            background-clip: text;
            -webkit-text-fill-color: transparent;
            animation: gradient 3s linear infinite;
        }

        .M3Unator-close {
            background: rgba(203, 166, 247, 0.1);
            border: none;
            color: #cba6f7;
            width: 32px;
            height: 32px;
            border-radius: 8px;
            display: grid;
            place-items: center;
            cursor: pointer;
            transition: all 0.2s ease;
        }

        .M3Unator-close:hover {
            background: rgba(203, 166, 247, 0.2);
            transform: rotate(360deg);
        }

        .M3Unator-close svg {
            width: 18px;
            height: 18px;
        }

        .M3Unator-content {
            padding: 0.75rem;
            display: flex;
            flex-direction: column;
            gap: 0.75rem;
        }

        .M3Unator-input-group {
            margin-bottom: 0;
        }

        .M3Unator-input-group label {
            display: block;
            margin-bottom: 0.5rem;
            font-weight: 500;
            color: #bac2de;
        }

        .M3Unator-input {
            width: 100%;
            height: 42px; /* Same height as Create Playlist button */
            padding: 0 12px;
            border: 1px solid #45475a;
            border-radius: 8px;
            background: #1e1e2e;
            color: #f5c2e7;
            font-size: 14px;
            transition: all 0.2s ease;
            box-sizing: border-box;
        }

        .M3Unator-input:focus {
            outline: none;
            border-color: #f5c2e7;
            box-shadow: 0 0 0 2px rgba(245, 194, 231, 0.1);
        }

        .M3Unator-input::placeholder {
            color: #6c7086;
            opacity: 1;
        }

        .M3Unator-toggle-container {
            position: relative;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .M3Unator-toggle-container input[type="checkbox"] {
            display: none;
        }

        .M3Unator-toggle-container span {
            width: 48px;
            height: 48px;
            background: #1e1e2e;
            border: 2px solid #45475a;
            border-radius: 12px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            position: relative;
        }

        .M3Unator-toggle-container svg {
            width: 24px;
            height: 24px;
            opacity: 0.7;
            transition: all 0.3s ease;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }

        .M3Unator-toggle-container input[type="checkbox"]:checked + span {
            background: rgba(203, 166, 247, 0.1);
            border-color: #cba6f7;
            box-shadow: 0 0 20px rgba(203, 166, 247, 0.2);
        }

        .M3Unator-toggle-container input[type="checkbox"]:checked + span svg {
            opacity: 1;
            color: #cba6f7;
            filter: drop-shadow(0 0 8px rgba(203, 166, 247, 0.4));
        }

        .M3Unator-toggle-container span:hover {
            background: #313244;
            transform: translateY(-2px);
        }

        .M3Unator-toggle-container span:active {
            transform: translateY(1px);
        }

        .M3Unator-toggle-container input[type="checkbox"]:checked + span:hover {
            background: rgba(203, 166, 247, 0.2);
        }

        .M3Unator-toggle-container span:active {
            transform: translateY(1px);
        }

        .M3Unator-toggle-container svg {
            width: 24px;
            height: 24px;
            opacity: 0.8;
            transition: all 0.2s ease;
        }

        .M3Unator-toggle-container input[type="checkbox"]:checked + span svg {
            opacity: 1;
            color: #cba6f7;
        }

        .M3Unator-toggle-group {
            display: flex;
            gap: 0.75rem;
            margin: 0.75rem 0;
            justify-content: center;
            background: rgba(30, 30, 46, 0.4);
            padding: 0.75rem;
            border-radius: 12px;
            backdrop-filter: blur(8px);
        }

        [title]:hover::after {
            content: attr(title);
            position: absolute;
            bottom: calc(100% + 5px);
            left: 50%;
            transform: translateX(-50%);
            padding: 0.5rem 0.75rem;
            background: rgba(30, 30, 46, 0.95);
            color: #cdd6f4;
            font-size: 0.875rem;
            white-space: nowrap;
            border-radius: 6px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
            z-index: 1000;
            border: 1px solid #313244;
            text-align: center;
            backdrop-filter: blur(8px);
            pointer-events: none;
        }

        .M3Unator-button {
            width: 100%;
            height: 42px;
            padding: 0 16px;
            border: none;
            border-radius: 8px;
            background: #f5c2e7;
            color: #1e1e2e;
            font-weight: 600;
            font-size: 14px;
            cursor: pointer;
            transition: all 0.2s ease;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
        }

        .M3Unator-button:hover {
            background: #f5c2e7;
            transform: translateY(-1px);
            box-shadow: 0 4px 12px rgba(245, 194, 231, 0.2);
        }

        .M3Unator-button:active {
            transform: translateY(0);
        }

        .M3Unator-button:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }

        .M3Unator-launcher {
            position: fixed;
            top: 1rem;
            right: 1.618rem;
            height: 48px;
            padding: 0 1.25rem;
            border-radius: 12px;
            background: rgba(30, 30, 46, 0.95);
            border: 2px solid #313244;
            cursor: pointer;
            box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
            display: flex;
            align-items: center;
            gap: 0.75rem;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            z-index: 9998;
            backdrop-filter: blur(12px);
        }

        .M3Unator-launcher:hover {
            background: rgba(30, 30, 46, 0.98);
            border-color: #45475a;
            transform: translateY(-2px);
            box-shadow: 0 12px 32px rgba(0, 0, 0, 0.3);
        }

        .M3Unator-launcher svg {
            width: 24px;
            height: 24px;
            color: #f5c2e7;
            filter: drop-shadow(0 0 8px rgba(245, 194, 231, 0.4));
        }

        .M3Unator-launcher span {
            font-weight: 600;
            font-size: 0.95rem;
            background: linear-gradient(90deg,
                #f5c2e7,
                #cba6f7,
                #89b4fa,
                #a6e3a1,
                #f5c2e7
            );
            background-size: 300% auto;
            -webkit-background-clip: text;
            background-clip: text;
            -webkit-text-fill-color: transparent;
            animation: gradient 3s linear infinite;
        }

        @keyframes gradient {
            0% { background-position: 0% 50%; filter: hue-rotate(0deg); }
            50% { background-position: 100% 50%; filter: hue-rotate(180deg); }
            100% { background-position: 0% 50%; filter: hue-rotate(360deg); }
        }

        .M3Unator-dropdown {
            position: relative;
            width: 100%;
        }

        .M3Unator-dropdown-button {
            width: 100%;
            padding: 0.618rem;
            background: #1e1e2e;
            border: 1px solid #313244;
            border-radius: 8px;
            color: #cdd6f4;
            font-size: 0.875rem;
            text-align: left;
            cursor: pointer;
            transition: all 0.2s ease;
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .M3Unator-dropdown-button:hover {
            border-color: #45475a;
            background: rgba(30, 30, 46, 0.8);
        }

        .M3Unator-dropdown-button svg {
            width: 16px;
            height: 16px;
            min-width: 16px;
            min-height: 16px;
            transition: transform 0.2s ease;
        }

        .M3Unator-dropdown.active .M3Unator-dropdown-button {
            border-color: #cba6f7;
            border-radius: 8px 8px 0 0;
        }

        .M3Unator-dropdown.active .M3Unator-dropdown-button svg {
            transform: rotate(180deg);
        }

        .M3Unator-dropdown-menu {
            position: absolute;
            top: 100%;
            left: 0;
            right: 0;
            background: #1e1e2e;
            border: 1px solid #cba6f7;
            border-top: none;
            border-radius: 0 0 8px 8px;
            overflow: hidden;
            z-index: 1000;
            display: none;
            animation: dropdownSlide 0.2s ease;
            user-select: none;
        }

        .M3Unator-dropdown.active .M3Unator-dropdown-menu {
            display: block;
        }

        .M3Unator-dropdown-item {
            padding: 0.618rem;
            color: #cdd6f4;
            cursor: pointer;
            transition: all 0.2s ease;
            user-select: none;
        }

        .M3Unator-dropdown-item:hover {
            background: rgba(203, 166, 247, 0.1);
        }

        .M3Unator-dropdown-item.selected {
            background: rgba(203, 166, 247, 0.1);
            color: #cba6f7;
        }

        @keyframes slideUp {
            from { transform: translateY(20px); opacity: 0; }
            to { transform: translateY(0); opacity: 1; }
        }

        .M3Unator-log {
            margin-top: 0.75rem;
            max-height: calc(100vh - 70vh);
            font-size: 0.8125rem;
            line-height: 1.4;
        }

        .M3Unator-log:empty {
            display: none;
        }

        .M3Unator-log-entry {
            padding: 0.25rem 0.5rem;
            border-bottom: 1px solid #313244;
        }

        .M3Unator-log-entry:last-child {
            border-bottom: none;
        }

        .M3Unator-log-entry.success {
            color: #94e2d5;
        }

        .M3Unator-log-entry.error {
            color: #f38ba8;
        }

        .M3Unator-log-entry.warning {
            color: #fab387;
        }

        .M3Unator-log-counter {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            background: rgba(245, 194, 231, 0.1);
            color: #f5c2e7;
            padding: 0.25rem 0.75rem;
            border-radius: 8px;
            font-size: 0.875rem;
            font-weight: 500;
            margin-left: 0.75rem;
            min-width: 3rem;
            text-align: center;
        }

        @keyframes gradient {
            0% { background-position: 0% 50%; filter: hue-rotate(0deg); }
            50% { background-position: 100% 50%; filter: hue-rotate(180deg); }
            100% { background-position: 0% 50%; filter: hue-rotate(360deg); }
        }

        .M3Unator-title span.text {
            display: inline-block;
            position: relative;
            padding: 0 0.25rem;
        }

        .M3Unator-title.scanning span.text {
            background: linear-gradient(90deg,
                #f5c2e7,
                #cba6f7,
                #89b4fa,
                #a6e3a1,
                #f5c2e7
            );
            background-size: 300% auto;
            -webkit-background-clip: text;
            background-clip: text;
            -webkit-text-fill-color: transparent;
            animation: gradient 3s linear infinite;
            font-weight: 700;
            letter-spacing: 0.5px;
        }

        .M3Unator-title.scanning span.text::after {
            content: '';
            position: absolute;
            bottom: -2px;
            left: 0;
            width: 100%;
            height: 2px;
            background: inherit;
            animation: gradient 3s linear infinite;
        }

        .M3Unator-title.scanning svg {
            animation: morphAnimation 2s ease-in-out infinite;
            filter: drop-shadow(0 0 8px rgba(203, 166, 247, 0.5));
        }

        @keyframes morphAnimation {
            0% {
                transform: scale(1);
                opacity: 1;
            }
            50% {
                transform: scale(1.2);
                opacity: 0.7;
            }
            100% {
                transform: scale(1);
                opacity: 1;
            }
        }

        .M3Unator-controls {
            display: none;
            gap: 0.75rem;
            margin: 0.75rem 0;
            justify-content: center;
        }

        .M3Unator-controls.active {
            display: flex;
        }

        .M3Unator-control-btn {
            display: none;
            padding: 0.75rem 1.5rem;
            border-radius: 12px;
            font-weight: 600;
            font-size: 0.95rem;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            align-items: center;
            gap: 0.75rem;
            min-width: 160px;
            justify-content: center;
            background: rgba(30, 30, 46, 0.6);
            backdrop-filter: blur(8px);
            width: 160px;
        }

        .M3Unator-control-btn:hover {
            background: #313244;
            transform: translateY(-1px);
        }

        .M3Unator-control-btn:active {
            transform: translateY(1px);
        }

        .M3Unator-control-btn.pause {
            border-color: #fab387;
            color: #fab387;
        }

        .M3Unator-control-btn.pause:hover {
            background: rgba(250, 179, 135, 0.1);
        }

        .M3Unator-control-btn.resume {
            border-color: #94e2d5;
            color: #94e2d5;
        }

        .M3Unator-control-btn.resume:hover {
            background: rgba(148, 226, 213, 0.1);
        }

        .M3Unator-control-btn.cancel {
            border-color: #f38ba8;
            color: #f38ba8;
        }

        .M3Unator-control-btn.cancel:hover {
            background: rgba(243, 139, 168, 0.1);
        }

        .M3Unator-control-btn svg {
            width: 14px;
            height: 14px;
        }

        .M3Unator-button {
            width: 100%;
            padding: 0 1rem;
            background: #f5c2e7;
            color: #11111b;
            border: none;
            border-radius: 6px;
            font-weight: 600;
            font-size: 0.875rem;
            cursor: pointer;
            transition: all 0.2s ease;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 0.375rem;
            height: 48px;
            min-height: 48px;
            line-height: 1;
        }

        .M3Unator-spinner {
            width: 20px;
            height: 20px;
            border: 2px solid rgba(17, 17, 27, 0.3);
            border-radius: 50%;
            border-top-color: #11111b;
            animation: spin 0.6s linear infinite;
            margin-right: 0;
            flex-shrink: 0;
        }

        .M3Unator-toast-container {
            position: fixed;
            bottom: 24px;
            left: 50%;
            transform: translateX(-50%);
            z-index: 999999;
            pointer-events: none;
            display: flex;
            flex-direction: column;
            align-items: center;
            width: auto;
        }

        .M3Unator-toast {
            display: flex;
            align-items: center;
            gap: 12px;
            padding: 12px 24px;
            border-radius: 12px;
            margin-bottom: 12px;
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
            font-size: 14px;
            font-weight: 500;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
            background: rgba(17, 17, 27, 0.95);
            border: 2px solid;
            pointer-events: all;
            min-width: 300px;
            max-width: 500px;
            backdrop-filter: blur(16px);
            will-change: transform, opacity;
            animation: none;
            transform-origin: center bottom;
        }

        .M3Unator-toast.show {
            animation: toastBounceIn 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
        }

        .M3Unator-toast.removing {
            animation: toastBounceOut 0.5s cubic-bezier(0.55, 0.085, 0.68, 0.53) forwards;
        }

        @keyframes toastBounceIn {
            0% {
                opacity: 0;
                transform: scale(0.3) translateY(2000px);
            }
            60% {
                opacity: 1;
                transform: scale(1.1) translateY(-20px);
            }
            75% {
                transform: scale(0.95) translateY(10px);
            }
            90% {
                transform: scale(1.02) translateY(-5px);
            }
            100% {
                transform: scale(1) translateY(0);
            }
        }

        @keyframes toastBounceOut {
            0% {
                transform: scale(1) translateY(0);
                opacity: 1;
            }
            20% {
                transform: scale(1.1) translateY(-20px);
                opacity: 0.8;
            }
            100% {
                transform: scale(0.3) translateY(2000px);
                opacity: 0;
            }
        }

        .M3Unator-toast svg {
            width: 20px;
            height: 20px;
            flex-shrink: 0;
            filter: drop-shadow(0 0 4px currentColor);
            animation: iconPop 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
            opacity: 0;
            transform: scale(0.5);
        }

        @keyframes iconPop {
            0% {
                opacity: 0;
                transform: scale(0.5) rotate(-180deg);
            }
            100% {
                opacity: 1;
                transform: scale(1) rotate(0deg);
            }
        }

        .M3Unator-toast span {
            opacity: 0;
            transform: translateX(-10px);
            animation: textSlide 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
            animation-delay: 0.15s;
        }

        @keyframes textSlide {
            0% {
                opacity: 0;
                transform: translateX(-10px);
            }
            100% {
                opacity: 1;
                transform: translateX(0);
            }
        }

        .M3Unator-input-row {
            display: flex;
            gap: 0.75rem;
            margin-bottom: 0.75rem;
        }

        .M3Unator-input-row .M3Unator-input-group {
            margin-bottom: 0;
        }

        .M3Unator-input-row .M3Unator-input-group:first-child {
            flex: 2;
        }

        .M3Unator-input-row .M3Unator-input-group:last-child {
            flex: 1;
        }

        .M3Unator-social {
            display: flex;
            gap: 8px;
            margin-right: 8px;
        }

        .M3Unator-social a {
            width: 32px;
            height: 32px;
            border-radius: 8px;
            display: grid;
            place-items: center;
            color: #cdd6f4;
            background: rgba(205, 214, 244, 0.1);
            transition: all 0.2s ease;
        }

        .M3Unator-social a:hover {
            background: rgba(205, 214, 244, 0.2);
            transform: rotate(360deg);
        }

        .M3Unator-social svg {
            width: 18px;
            height: 18px;
        }

        .M3Unator-advanced-settings {
            margin-top: 1rem;
            padding: 1rem;
            background: rgba(30, 30, 46, 0.5);
            border: 1px solid #313244;
            border-radius: 8px;
            display: none;
        }

        .M3Unator-advanced-settings.active {
            display: block;
            animation: fadeIn 0.3s ease;
        }

        .M3Unator-advanced-toggle {
            width: 100%;
            padding: 0.75rem;
            background: #1e1e2e;
            border: 1px solid #313244;
            border-radius: 8px;
            color: #cdd6f4;
            font-size: 0.875rem;
            font-weight: 500;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: space-between;
            transition: all 0.2s ease;
        }

        .M3Unator-advanced-toggle:hover {
            background: #313244;
        }

        .M3Unator-advanced-toggle svg {
            width: 16px;
            height: 16px;
            transition: transform 0.2s ease;
        }

        .M3Unator-advanced-toggle.active svg {
            transform: rotate(180deg);
        }

        .M3Unator-depth-slider {
            -webkit-appearance: none;
            width: 100%;
            height: 4px;
            border-radius: 2px;
            background: #313244;
            outline: none;
            margin: 1rem 0;
        }

        .M3Unator-depth-slider::-webkit-slider-thumb {
            -webkit-appearance: none;
            appearance: none;
            width: 16px;
            height: 16px;
            border-radius: 50%;
            background: #cba6f7;
            cursor: pointer;
            transition: all 0.2s ease;
        }

        .M3Unator-depth-slider::-webkit-slider-thumb:hover {
            transform: scale(1.2);
        }

        .M3Unator-depth-value {
            text-align: center;
            font-size: 0.875rem;
            color: #cdd6f4;
            margin-top: 0.5rem;
        }

        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(-10px); }
            to { opacity: 1; transform: translateY(0); }
        }

        .M3Unator-depth-settings {
            margin-top: 0.75rem;
            margin-left: 1.75rem;
            padding: 0.75rem;
            background: rgba(30, 30, 46, 0.3);
            border-left: 2px solid #cba6f7;
            border-radius: 0 8px 8px 0;
            display: none;
            animation: slideDown 0.3s ease;
        }

        .M3Unator-depth-settings.active {
            display: block;
        }

        .M3Unator-depth-input {
            position: relative;
            display: flex;
            align-items: center;
            gap: 0.75rem;
            margin-top: 0.5rem;
        }

        .M3Unator-depth-input input[type="number"] {
            width: 64px;
            padding: 0.25rem 0.375rem;
            border: 1px solid #45475a;
            border-radius: 4px;
            background: rgba(30, 30, 46, 0.8);
            color: #cdd6f4;
            font-size: 0.875rem;
            text-align: center;
            margin: 0 0 0 0.5rem;
        }

        .M3Unator-depth-input input[type="number"]:focus {
            outline: none;
            border-color: #cba6f7;
            box-shadow: 0 0 0 2px rgba(203, 166, 247, 0.2);
        }

        .M3Unator-depth-input input[type="number"]::-webkit-inner-spin-button {
            opacity: 1;
            background: #313244;
            border-left: 1px solid #45475a;
            border-radius: 0 4px 4px 0;
            cursor: pointer;
        }

        .M3Unator-depth-toggle {
            display: flex;
            align-items: center;
            gap: 0.5rem;
            padding: 0.5rem;
            background: #1e1e2e;
            border: 1px solid #45475a;
            border-radius: 6px;
            color: #cdd6f4;
            font-size: 0.875rem;
            cursor: pointer;
            transition: all 0.2s ease;
        }

        .M3Unator-depth-toggle:hover {
            background: #313244;
            border-color: #cba6f7;
        }

        .M3Unator-depth-toggle.active {
            background: rgba(203, 166, 247, 0.1);
            border-color: #cba6f7;
            color: #cba6f7;
        }

        @keyframes slideDown {
            from { opacity: 0; transform: translateY(-10px); }
            to { opacity: 1; transform: translateY(0); }
        }

        .M3Unator-stats-bar {
            margin: 0.75rem 0;
            padding: 0.5rem;
            background: rgba(30, 30, 46, 0.5);
            border: 1px solid #313244;
            border-radius: 8px;
            display: none;
        }

        .M3Unator-stats-bar.active {
            display: block;
        }

        .M3Unator-stats {
            display: flex;
            align-items: center;
            justify-content: space-around;
            gap: 0.382rem;
            padding: 0.25rem;
        }

        .M3Unator-stat {
            display: inline-flex;
            align-items: center;
            gap: 0.25rem;
            font-size: 0.75rem;
            color: #cdd6f4;
            cursor: help;
            min-width: 40px;
            justify-content: flex-start;
            padding: 0 0.25rem;
            position: relative;
        }

        .M3Unator-stat span {
            min-width: 16px;
            text-align: right;
            font-variant-numeric: tabular-nums;
            font-size: 0.7rem;
            font-weight: 500;
        }

        .M3Unator-stat svg {
            opacity: 0.8;
            flex-shrink: 0;
            width: 14px;
            height: 14px;
        }

        .M3Unator-stat.video {
            color: #94e2d5;
        }

        .M3Unator-stat.audio {
            color: #89b4fa;
        }

        .M3Unator-stat.dir {
            color: #cba6f7;
        }

        .M3Unator-stat.error {
            color: #f38ba8;
        }

        .M3Unator-stat.depth {
            color: #a6e3a1;
            transition: color 0.3s ease;
        }

        .M3Unator-stat.depth[data-progress="high"] {
            color: #f38ba8;
        }

        .M3Unator-stat.depth[data-progress="medium"] {
            color: #fab387;
        }

        .M3Unator-stat.depth[data-progress="low"] {
            color: #f9e2af;
        }

        .M3Unator-stat:hover::after {
            content: attr(title);
            position: absolute;
            bottom: calc(100% + 5px);
            left: 50%;
            transform: translateX(-50%);
            padding: 0.5rem 0.75rem;
            background: rgba(30, 30, 46, 0.95);
            color: #cdd6f4;
            font-size: 0.875rem;
            white-space: nowrap;
            border-radius: 6px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
            z-index: 1000;
            border: 1px solid #313244;
            text-align: center;
            backdrop-filter: blur(8px);
            pointer-events: none;
        }

        .M3Unator-spinner {
            width: 20px;
            height: 20px;
            border: 2px solid rgba(17, 17, 27, 0.3);
            border-radius: 50%;
            border-top-color: #11111b;
            animation: spin 0.6s linear infinite;
            margin-right: 0;
            flex-shrink: 0;
        }

        @keyframes spin {
            to { transform: rotate(360deg); }
        }

        .M3Unator-toast {
            animation: toastSlideUp 0.2s ease forwards;
        }

        .M3Unator-toast.removing {
            animation: toastSlideDown 0.2s ease forwards;
        }

        .M3Unator-popup {
            animation: slideUp 0.2s ease;
        }

        .M3Unator-stats-bar {
            animation: fadeIn 0.2s ease;
        }

        .M3Unator-log {
            transition: max-height 0.3s ease;
        }

        .M3Unator-log.collapsed {
            max-height: 0;
            overflow: hidden;
        }

        .M3Unator-log-toggle {
            width: 100%;
            padding: 0.5rem 0.75rem;
            background: rgba(203, 166, 247, 0.05);
            border: none;
            color: #cdd6f4;
            display: flex;
            align-items: center;
            justify-content: space-between;
            cursor: pointer;
            transition: all 0.2s ease;
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
            font-size: 0.875rem;
            font-weight: 500;
            border-radius: 6px;
        }

        .M3Unator-log-toggle:hover {
            background: rgba(203, 166, 247, 0.1);
        }

        .M3Unator-activity-indicator {
            width: 14px;
            height: 14px;
            border-radius: 50%;
            background: #45475a;  /* Darker gray */
            margin-left: auto;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        }

        .M3Unator-activity-indicator.active {
            background: #89dceb;  /* Brighter blue */
            box-shadow: 0 0 0 3px rgba(137, 220, 235, 0.2);
            animation: pulseActive 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
        }

        .M3Unator-activity-indicator.paused {
            background: #f9e2af;  /* More visible yellow */
            box-shadow: 0 0 0 3px rgba(249, 226, 175, 0.2);
        }

        .M3Unator-activity-indicator.error {
            background: #f38ba8;  /* Current red is good */
            box-shadow: 0 0 0 3px rgba(243, 139, 168, 0.2);
        }

        .M3Unator-activity-indicator.completed {
            background: #94e2d5;  /* Brighter green-turquoise */
            box-shadow: 0 0 0 3px rgba(148, 226, 213, 0.2);
        }

        @keyframes pulseActive {
            0% {
                box-shadow: 0 0 0 0 rgba(137, 220, 235, 0.4);
            }
            70% {
                box-shadow: 0 0 0 8px rgba(137, 220, 235, 0);
            }
            100% {
                box-shadow: 0 0 0 0 rgba(137, 220, 235, 0);
            }
        }

        @keyframes pulsePaused {
            0% {
                box-shadow: 0 0 0 0 rgba(249, 226, 175, 0.4);
            }
            70% {
                box-shadow: 0 0 0 8px rgba(249, 226, 175, 0);
            }
            100% {
                box-shadow: 0 0 0 0 rgba(249, 226, 175, 0);
            }
        }

        @keyframes completeScale {
            0% {
                transform: scale(0.8);
                opacity: 0.5;
            }
            50% {
                transform: scale(1.2);
            }
            100% {
                transform: scale(1);
                opacity: 1;
            }
        }

        .M3Unator-toggle-container span svg .infinity-icon {
            opacity: 0.5;
            transition: opacity 0.2s ease;
            transform: scale(0.6) translateY(4px);
            transform-origin: center;
            stroke-width: 1.5;
        }

        .M3Unator-toggle-container input[type="checkbox"]:checked + span svg .infinity-icon {
            opacity: 1;
        }

        .M3Unator-depth-controls {
            background: rgba(30, 30, 46, 0.4);
            backdrop-filter: blur(8px);
            border: 1px solid #313244;
            border-radius: 8px;
            padding: 0.618rem;
            margin-top: 1rem;
            display: none;
        }

        .M3Unator-depth-controls.active {
            display: block;
        }

        .M3Unator-radio-group {
            display: flex;
            gap: 0.75rem;
            justify-content: center;
            background: rgba(30, 30, 46, 0.6);
            padding: 0.5rem;
            border-radius: 6px;
        }

        .M3Unator-radio {
            display: flex;
            align-items: center;
            gap: 0.5rem;
            cursor: pointer;
            padding: 0.5rem;
            border-radius: 4px;
            transition: all 0.2s ease;
            background: transparent;
            border: 1px solid transparent;
        }

        .M3Unator-radio:hover {
            background: rgba(203, 166, 247, 0.1);
        }

        .M3Unator-radio input[type="radio"] {
            display: none;
        }

        .M3Unator-radio .radio-mark {
            width: 16px;
            height: 16px;
            border: 1.5px solid #45475a;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.2s ease;
            flex-shrink: 0;
            background: rgba(30, 30, 46, 0.6);
            position: relative;
        }

        .M3Unator-radio input[type="radio"]:checked + .radio-mark {
            border-color: #cba6f7;
            background: rgba(203, 166, 247, 0.1);
        }

        .M3Unator-radio input[type="radio"]:checked + .radio-mark::after {
            content: '';
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background: #cba6f7;
            position: absolute;
        }

        .M3Unator-radio .radio-label {
            color: #cdd6f4;
            font-size: 0.875rem;
            user-select: none;
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }

        .M3Unator-depth-input {
            width: 64px;
            padding: 0.25rem 0.375rem;
            border: 1px solid #45475a;
            border-radius: 4px;
            background: rgba(30, 30, 46, 0.8);
            color: #cdd6f4;
            font-size: 0.875rem;
            text-align: center;
            transition: all 0.2s ease;
            -moz-appearance: textfield;
            margin-top: -1px;
            display: inline-flex;
            align-items: center;
            height: 28px;
        }

        .M3Unator-depth-input::-webkit-outer-spin-button,
        .M3Unator-depth-input::-webkit-inner-spin-button {
            -webkit-appearance: inner-spin-button;
            opacity: 1;
            background: #313244;
            border-left: 1px solid #45475a;
            border-radius: 0 4px 4px 0;
            cursor: pointer;
            height: 100%;
            position: absolute;
            right: 0;
            top: 0;
        }

        .M3Unator-depth-input:focus {
            outline: none;
            border-color: #cba6f7;
            box-shadow: 0 0 0 2px rgba(203, 166, 247, 0.2);
        }

        .M3Unator-depth-input:disabled {
            opacity: 0.5;
            cursor: not-allowed;
            background: rgba(30, 30, 46, 0.4);
        }

        .M3Unator-radio .radio-label {
            display: flex;
            align-items: center;
            gap: 0.5rem;
            color: #cdd6f4;
            font-size: 0.875rem;
            user-select: none;
        }

        .M3Unator-url-container {
            display: flex;
            align-items: center;
            background: rgba(30, 30, 46, 0.6);
            border: 1px solid #313244;
            border-radius: 6px;
            padding: 0.618rem;
            margin-bottom: 1rem;
            transition: all 0.2s ease;
        }

        .M3Unator-url-container:hover {
            border-color: #45475a;
        }

        .M3Unator-url-icon {
            color: #6c7086;
            margin-right: 0.618rem;
            flex-shrink: 0;
        }

        .M3Unator-url-input {
            flex: 1;
            background: transparent;
            border: none;
            color: #cdd6f4;
            font-size: 0.875rem;
            padding: 0;
            margin: 0;
            width: 100%;
        }

        .M3Unator-url-input:focus {
            outline: none;
        }

        .M3Unator-url-copy {
            background: transparent;
            border: none;
            color: #6c7086;
            padding: 0.382rem;
            margin-left: 0.618rem;
            cursor: pointer;
            border-radius: 4px;
            transition: all 0.2s ease;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .M3Unator-url-copy:hover {
            color: #cdd6f4;
            background: rgba(205, 214, 244, 0.1);
        }

        .M3Unator-url-copy.copied {
            color: #a6e3a1;
            animation: copyPulse 0.3s ease;
        }

        @keyframes copyPulse {
            0% { transform: scale(1); }
            50% { transform: scale(1.2); }
            100% { transform: scale(1); }
        }

        .M3Unator-toggle-group {
            display: flex;
            gap: 1.25rem;
            margin: 1.5rem 0;
            justify-content: center;
            background: rgba(30, 30, 46, 0.4);
            padding: 1.25rem;
            border-radius: 16px;
            backdrop-filter: blur(8px);
        }

        .M3Unator-toggle-container {
            position: relative;
        }

        .M3Unator-toggle-container span {
            width: 64px;
            height: 64px;
            background: #1e1e2e;
            border: 2px solid #45475a;
            border-radius: 16px;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .M3Unator-toggle-container input[type="checkbox"]:checked + span {
            background: rgba(203, 166, 247, 0.1);
            border-color: #cba6f7;
            box-shadow: 0 0 20px rgba(203, 166, 247, 0.2);
            transform: translateY(-2px);
        }

        .M3Unator-toggle-container span:hover {
            background: #313244;
            transform: translateY(-2px);
            box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
        }

        .M3Unator-toggle-container svg {
            width: 32px;
            height: 32px;
            opacity: 0.7;
            transition: all 0.3s ease;
        }

        .M3Unator-toggle-container input[type="checkbox"]:checked + span svg {
            opacity: 1;
            color: #cba6f7;
            filter: drop-shadow(0 0 8px rgba(203, 166, 247, 0.4));
        }

        .M3Unator-progress {
            background: rgba(30, 30, 46, 0.6);
            border-radius: 12px;
            padding: 1rem;
            margin: 1rem 0;
            backdrop-filter: blur(8px);
            border: 1px solid rgba(203, 166, 247, 0.2);
        }

        .M3Unator-progress-text {
            color: #f5c2e7;
            font-weight: 600;
            text-align: center;
            margin-bottom: 0.5rem;
            font-size: 1.1rem;
        }

        .M3Unator-progress-spinner {
            width: 24px;
            height: 24px;
            border: 3px solid rgba(245, 194, 231, 0.1);
            border-top-color: #f5c2e7;
            border-radius: 50%;
            animation: spin 1s linear infinite;
            margin: 0 auto;
        }

        .M3Unator-controls {
            display: flex;
            gap: 0.75rem;
            margin: 0.75rem 0;
            justify-content: center;
        }

        .M3Unator-control-btn {
            display: none;
            padding: 0.75rem 1.5rem;
            border-radius: 12px;
            font-weight: 600;
            font-size: 0.95rem;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            align-items: center;
            gap: 0.75rem;
            min-width: 160px;
            justify-content: center;
            background: rgba(30, 30, 46, 0.6);
            backdrop-filter: blur(8px);
            width: 160px;
        }

        .M3Unator-control-btn.pause {
            background: rgba(250, 179, 135, 0.1);
            border: 2px solid #fab387;
            color: #fab387;
        }

        .M3Unator-control-btn.resume {
            background: rgba(148, 226, 213, 0.1);
            border: 2px solid #94e2d5;
            color: #94e2d5;
        }

        .M3Unator-control-btn.cancel {
            background: rgba(243, 139, 168, 0.1);
            border: 2px solid #f38ba8;
            color: #f38ba8;
        }

        .M3Unator-control-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
        }

        .M3Unator-control-btn svg {
            width: 20px;
            height: 20px;
        }

        .M3Unator-layers-icon {
            width: 20px;
            height: 20px;
            margin-right: 0.5rem;
        }

        .M3Unator-input:-webkit-autofill,
        .M3Unator-input:-webkit-autofill:hover,
        .M3Unator-input:-webkit-autofill:focus,
        .M3Unator-input:-webkit-autofill:active {
            -webkit-text-fill-color: #cdd6f4 !important;
            -webkit-box-shadow: 0 0 0 30px #1e1e2e inset !important;
            box-shadow: 0 0 0 30px #1e1e2e inset !important;
            background-color: #1e1e2e !important;
            color: #cdd6f4 !important;
            caret-color: #cdd6f4 !important;
            transition: background-color 5000s ease-in-out 0s !important;
            text-decoration: none !important;
            -webkit-text-decoration: none !important;
        }

        .M3Unator-input:-moz-autofill,
        .M3Unator-input:-moz-autofill-preview {
            background-color: #1e1e2e !important;
            color: #cdd6f4 !important;
            text-decoration: none !important;
        }

        .M3Unator-input:-ms-input-placeholder {
            background-color: #1e1e2e !important;
            color: #cdd6f4 !important;
            text-decoration: none !important;
        }

        .M3Unator-log-container {
            margin: 0;
        }

        .M3Unator-log-toggle {
            width: 100%;
            padding: 0.5rem 0.75rem;
            background: rgba(203, 166, 247, 0.05);
            border: none;
            color: #cdd6f4;
            display: flex;
            align-items: center;
            justify-content: space-between;
            cursor: pointer;
            transition: all 0.2s ease;
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
            font-size: 0.875rem;
            font-weight: 500;
            border-radius: 6px;
        }

        .M3Unator-log-toggle:hover {
            background: rgba(203, 166, 247, 0.1);
        }

        .M3Unator-activity-indicator {
            width: 14px;
            height: 14px;
            border-radius: 50%;
            background: #45475a;  /* Darker gray */
            margin-left: auto;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        }

        .M3Unator-activity-indicator.active {
            background: #89dceb;  /* Brighter blue */
            box-shadow: 0 0 0 3px rgba(137, 220, 235, 0.2);
            animation: pulseActive 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
        }

        .M3Unator-activity-indicator.paused {
            background: #f9e2af;  /* More visible yellow */
            box-shadow: 0 0 0 3px rgba(249, 226, 175, 0.2);
        }

        .M3Unator-activity-indicator.error {
            background: #f38ba8;  /* Current red is good */
            box-shadow: 0 0 0 3px rgba(243, 139, 168, 0.2);
        }

        .M3Unator-activity-indicator.completed {
            background: #94e2d5;  /* Brighter green-turquoise */
            box-shadow: 0 0 0 3px rgba(148, 226, 213, 0.2);
        }

        @keyframes pulseActive {
            0% {
                box-shadow: 0 0 0 0 rgba(137, 220, 235, 0.4);
            }
            70% {
                box-shadow: 0 0 0 8px rgba(137, 220, 235, 0);
            }
            100% {
                box-shadow: 0 0 0 0 rgba(137, 220, 235, 0);
            }
        }

        @keyframes pulsePaused {
            0% {
                box-shadow: 0 0 0 0 rgba(249, 226, 175, 0.4);
            }
            70% {
                box-shadow: 0 0 0 8px rgba(249, 226, 175, 0);
            }
            100% {
                box-shadow: 0 0 0 0 rgba(249, 226, 175, 0);
            }
        }

        @keyframes completeScale {
            0% {
                transform: scale(0.8);
                opacity: 0.5;
            }
            50% {
                transform: scale(1.2);
            }
            100% {
                transform: scale(1);
                opacity: 1;
            }
        }

        .M3Unator-log-toggle:hover .M3Unator-activity-indicator {
            background: #6c7086;
            animation: none;
        }

        .M3Unator-log-toggle.active .M3Unator-activity-indicator {
            background: #6c7086;
            animation: none;
        }

        .M3Unator-log-toggle .toggle-text {
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }

        .M3Unator-log {
            height: 0;
            max-height: 0;
            overflow: hidden;
            transition: all 0.3s ease;
            background: #11111b;
            padding: 0;
            border-top: none;
            margin: 0;
        }

        .M3Unator-log.expanded {
            height: auto;
            max-height: 300px;
            padding: 0.75rem;
            border-top: 1px solid #313244;
            overflow-y: auto;
        }

        .M3Unator-log-entry {
            padding: 0.25rem 0.5rem;
            border-bottom: 1px solid rgba(49, 50, 68, 0.5);
            font-size: 0.875rem;
        }

        .M3Unator-log-entry:last-child {
            border-bottom: none;
        }

        .M3Unator-log-time {
            color: #6c7086;
            margin-right: 0.5rem;
        }

        .M3Unator-log-entry.success {
            color: #94e2d5;
        }

        .M3Unator-log-entry.error {
            color: #f38ba8;
        }

        .M3Unator-log-entry.warning {
            color: #fab387;
        }

        .M3Unator-log-entry.info {
            color: #89b4fa;
        }

        .M3Unator-log-entry.final {
            color: #a6e3a1;
            font-weight: 500;
        }

        .M3Unator-log {
            margin-top: 0.75rem;
            max-height: calc(100vh - 70vh);
            font-size: 0.8125rem;
            line-height: 1.4;
        }

        .M3Unator-log-entry {
            padding: 0.25rem 0.5rem;
            border-radius: 4px;
        }

        .M3Unator-log-toggle {
            padding: 10px 12px;
            height: 42px;
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .M3Unator-log-counter {
            padding: 0.125rem 0.375rem;
            font-size: 0.75rem;
            border-radius: 4px;
        }

        .M3Unator-log-time {
            font-size: 0.75rem;
            opacity: 0.7;
            margin-right: 0.5rem;
        }
    `);

    GM_addStyle(`
        .M3Unator-popup {
            position: fixed;
            background: #11111b;
            color: #cdd6f4;
            width: 100%;
            max-width: 480px;
            border-radius: 12px;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
            overflow: hidden;
            animation: slideUp 0.3s ease;
            z-index: 9999;
        }

        .M3Unator-header {
            padding: 1rem 1.25rem;
            background: #1e1e2e;
            color: #cdd6f4;
            display: flex;
            align-items: center;
            justify-content: space-between;
            cursor: move;
            user-select: none;
            border-bottom: 1px solid #313244;
        }

        .M3Unator-container {
            position: fixed;
            inset: 0;
            background: rgba(0, 0, 0, 0.75);
            backdrop-filter: blur(8px);
            display: none;
            place-items: center;
            z-index: 9999;
        }
    `);

    GM_addStyle(`
        /* Info Modal Styles */
        .info-modal {
            display: none;
            position: fixed;
            inset: 0;
            background: rgba(0, 0, 0, 0.75);
            backdrop-filter: blur(8px);
            z-index: 10000;
        }

        .info-modal-content {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: #1e1e2e;
            border: 1px solid #45475a;
            border-radius: 12px;
            width: 90%;
            max-width: 600px;
            color: #cdd6f4;
        }

        .info-modal-header {
            padding: 1rem 1.5rem;
            border-bottom: 1px solid #45475a;
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .info-modal-header h3 {
            margin: 0;
            color: #f5c2e7;
            font-size: 1.25rem;
        }

        .info-modal-body {
            padding: 1.5rem;
            line-height: 1.6;
        }

        .info-modal-body p {
            margin: 0 0 1rem;
        }

        .info-modal-body h4 {
            margin: 1.5rem 0 0.75rem;
            color: #f5c2e7;
        }

        .info-modal-body ul {
            margin: 0.75rem 0;
            padding-left: 1.5rem;
        }

        .info-modal-body li {
            margin: 0.5rem 0;
        }

        .info-modal-body a {
            color: #89b4fa;
            text-decoration: none;
        }

        .info-modal-body a:hover {
            text-decoration: underline;
        }

        .info-close {
            cursor: pointer;
            color: #6c7086;
            transition: color 0.2s ease;
        }

        .info-close:hover {
            color: #f5c2e7;
        }
    `);

    GM_addStyle(`
        .m3unator-input-group {
            position: relative;
            width: 100%;
        }

        .m3unator-input {
            width: 100%;
            padding-right: 80px !important;
            transition: all 0.2s ease;
        }

        .m3unator-dropdown {
            position: absolute;
            right: 8px;
            top: 50%;
            transform: translateY(-50%);
            display: none;
            z-index: 1;
            width: 70px;
        }

        .m3unator-dropdown.active {
            display: block;
        }

        .m3unator-dropdown-button {
            width: 100%;
            padding: 4px 8px;
            border-radius: 6px;
            background: rgba(30, 30, 46, 0.6);
            border: 1px solid rgba(69, 71, 90, 0.6);
            color: #f5c2e7;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 4px;
            transition: all 0.2s ease;
        }

        .m3unator-dropdown-button:hover {
            background: rgba(30, 30, 46, 0.8);
            border-color: rgba(69, 71, 90, 0.8);
        }

        .m3unator-dropdown-menu {
            position: absolute;
            top: 100%;
            right: 0;
            width: 100%;
            margin-top: 4px;
            background: rgba(30, 30, 46, 0.95);
            border: 1px solid rgba(69, 71, 90, 0.6);
            border-radius: 6px;
            padding: 4px;
            display: none;
        }

        .m3unator-dropdown.active .m3unator-dropdown-menu {
            display: block;
        }

        .m3unator-dropdown-item {
            padding: 0.618rem;
            color: #cdd6f4;
            cursor: pointer;
            transition: all 0.2s ease;
            user-select: none;
        }

        .m3unator-dropdown-item:hover {
            background: rgba(203, 166, 247, 0.1);
        }

        .m3unator-dropdown-item.selected {
            background: rgba(203, 166, 247, 0.1);
            color: #cba6f7;
        }
    `);

    GM_addStyle(`
        .M3Unator-container {
            max-width: 400px;
            width: 100%;
            background: none;
            backdrop-filter: none;
        }

        .M3Unator-popup {
            background: #1e1e2e;
            border-radius: 12px;
            box-shadow: 0 4px 24px rgba(0, 0, 0, 0.2);
            border: 1px solid rgba(69, 71, 90, 0.6);
        }

        .M3Unator-content {
            padding: 0.75rem;
            display: flex;
            flex-direction: column;
            gap: 0.75rem;
            max-width: 100%;
            overflow: hidden;
            background: none;
        }

        .M3Unator-header {
            padding: 0.75rem;
            display: flex;
            align-items: center;
            justify-content: space-between;
            background: none;
            border-bottom: 1px solid rgba(69, 71, 90, 0.6);
        }

        .M3Unator-input {
            width: 100%;
            min-width: 0;
            padding: 8px 80px 8px 12px;
            box-sizing: border-box;
            transition: all 0.2s ease;
            background: #1e1e2e;
            border: 1px solid rgba(69, 71, 90, 0.6);
            border-radius: 6px;
            color: #f5c2e7;
            font-size: 14px;
        }

        .M3Unator-dropdown-button {
            width: 100%;
            padding: 4px 8px;
            border-radius: 6px;
            background: #1e1e2e;
            border: 1px solid rgba(69, 71, 90, 0.6);
            color: #f5c2e7;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 4px;
            transition: all 0.2s ease;
            box-sizing: border-box;
            font-size: 14px;
            font-family: monospace;
        }

        .M3Unator-dropdown-button span {
            min-width: 40px;
            text-align: left;
        }

        .M3Unator-dropdown-button svg {
            width: 16px;
            height: 16px;
            min-width: 16px;
            min-height: 16px;
            margin-left: auto;
        }

        .M3Unator-dropdown-menu {
            position: absolute;
            top: 100%;
            right: 0;
            width: 100%;
            margin-top: 4px;
            background: #1e1e2e;
            border: 1px solid rgba(69, 71, 90, 0.6);
            border-radius: 6px;
            padding: 4px;
            display: none;
            box-sizing: border-box;
            z-index: 9999;
        }
    `);

    GM_addStyle(`
        .M3Unator-content {
            padding: 0.75rem;
            display: flex;
            flex-direction: column;
            gap: 12px;
        }

        .M3Unator-toggle-group {
            margin: 0;
            display: flex;
            gap: 0.75rem;
            justify-content: center;
            background: rgba(30, 30, 46, 0.4);
            padding: 0.75rem;
            border-radius: 12px;
        }

        .M3Unator-button {
            margin: 0;
        }

        .M3Unator-log-container {
            margin: 0;
        }

        .M3Unator-stats-bar {
            margin: 0;
        }
    `);

    GM_addStyle(`
        /* Dropdown Styles */
        .M3Unator-dropdown {
            position: relative;
            display: none;
        }

        .M3Unator-dropdown-button {
            width: 100%;
            padding: 4px 8px;
            border-radius: 6px;
            background: #1e1e2e;
            border: 1px solid rgba(69, 71, 90, 0.6);
            color: #f5c2e7;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 4px;
            transition: all 0.2s ease;
            box-sizing: border-box;
            font-size: 14px;
            font-family: monospace;
        }

        .M3Unator-dropdown-button span {
            min-width: 40px;
            text-align: left;
        }

        .M3Unator-dropdown-button svg {
            width: 16px;
            height: 16px;
            min-width: 16px;
            min-height: 16px;
            margin-left: auto;
            transition: transform 0.2s ease;
        }

        .M3Unator-dropdown.active .M3Unator-dropdown-button svg {
            transform: rotate(180deg);
        }

        .M3Unator-dropdown-menu {
            position: absolute;
            top: 100%;
            left: 0;
            right: 0;
            margin-top: 4px;
            background: #1e1e2e;
            border: 1px solid rgba(69, 71, 90, 0.6);
            border-radius: 6px;
            overflow: hidden;
            z-index: 1000;
            display: none;
        }

        .M3Unator-dropdown.active .M3Unator-dropdown-menu {
            display: block;
        }

        .M3Unator-dropdown-item {
            padding: 6px 12px;
            color: #f5c2e7;
            cursor: pointer;
            transition: all 0.2s ease;
            font-family: monospace;
        }

        .M3Unator-dropdown-item:hover {
            background: rgba(69, 71, 90, 0.3);
        }

        .M3Unator-dropdown-item:not(:last-child) {
            border-bottom: 1px solid rgba(69, 71, 90, 0.3);
        }

        /* Input Styles */
        .M3Unator-input {
            width: 100%;
            height: 42px;
            padding: 0 12px;
            border: 1px solid #45475a;
            border-radius: 8px;
            background: #1e1e2e;
            color: #f5c2e7;
            font-size: 14px;
            transition: all 0.2s ease;
            box-sizing: border-box;
        }

        .M3Unator-input:focus {
            outline: none;
            border-color: #f5c2e7;
            box-shadow: 0 0 0 2px rgba(245, 194, 231, 0.1);
        }

        /* Button Styles */
        .M3Unator-button {
            height: 42px;
            padding: 0 16px;
            border: none;
            border-radius: 8px;
            background: #f5c2e7;
            color: #1e1e2e;
            font-weight: 600;
            font-size: 14px;
            cursor: pointer;
            transition: all 0.2s ease;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
        }

        /* Toggle Container Styles */
        .M3Unator-toggle-container {
            position: relative;
            display: flex;
            align-items: center;
            gap: 0.5rem;
            transition: all 0.2s ease;
        }

        /* Control Button Styles */
        .M3Unator-control-btn {
            padding: 0.75rem 1.5rem;
            border-radius: 12px;
            font-weight: 600;
            font-size: 0.95rem;
            min-width: 160px;
            background: rgba(30, 30, 46, 0.6);
            backdrop-filter: blur(8px);
        }

        .M3Unator-control-btn.pause {
            border-color: #fab387;
            color: #fab387;
        }

        .M3Unator-control-btn.resume {
            border-color: #94e2d5;
            color: #94e2d5;
        }

        .M3Unator-control-btn.cancel {
            border-color: #f38ba8;
            color: #f38ba8;
        }

        /* Stats Styles */
        .M3Unator-stat {
            display: inline-flex;
            align-items: center;
            gap: 0.382rem;
            font-size: 0.875rem;
            cursor: help;
            min-width: 52px;
            padding: 0 0.382rem;
        }
    `);

    GM_addStyle(`
        .M3Unator-toast.success {
            color: #a6e3a1;
            border-color: #a6e3a1;
            background: linear-gradient(rgba(17, 17, 27, 0.95), rgba(17, 17, 27, 0.95)), rgba(166, 227, 161, 0.1);
        }

        .M3Unator-toast.error {
            color: #f38ba8;
            border-color: #f38ba8;
            background: linear-gradient(rgba(17, 17, 27, 0.95), rgba(17, 17, 27, 0.95)), rgba(243, 139, 168, 0.1);
        }

        .M3Unator-toast.warning {
            color: #fab387;
            border-color: #fab387;
            background: linear-gradient(rgba(17, 17, 27, 0.95), rgba(17, 17, 27, 0.95)), rgba(250, 179, 135, 0.1);
        }
    `);

    class LogCache {
        constructor(maxSize = 100) {
            this.maxSize = maxSize;
            this.logs = [];
            this.stats = {
                totalLogs: 0,
                skippedLogs: 0
            };
        }

        add(message, type = '') {
            const timestamp = new Date().toLocaleTimeString();
            this.logs.push({ message, type, timestamp });
            this.stats.totalLogs++;
            
            if (this.logs.length > this.maxSize) {
                this.logs.shift();
                this.stats.skippedLogs++;
            }
        }

        getSummary() {
            return {
                logs: [...this.logs],
                stats: { ...this.stats }
            };
        }

        clear() {
            this.logs = [];
            this.stats.totalLogs = 0;
            this.stats.skippedLogs = 0;
        }
    }

    class PlaylistGenerator {
        constructor() {
            this.initialStats = {
                directories: {
                    total: 0,
                    depth: 0
                },
                files: {
                    video: {
                        total: 0,
                        current: 0
                    },
                    audio: {
                        total: 0,
                        current: 0
                    }
                },
                errors: {
                    total: 0,
                    skipped: 0
                },
                totalFiles: 0
            };

            this.videoFormats = [
                '.mp4', '.mkv', '.avi', '.webm', '.mov', '.flv', '.wmv', 
                '.m4v', '.mpg', '.mpeg', '.3gp', '.vob', '.ts', '.mts',
                '.m2ts', '.divx', '.xvid', '.asf', '.ogv', '.rm', '.rmvb',
                '.wtv', '.qt', '.hevc', '.f4v', '.swf', '.vro', '.ogx',
                '.drc', '.gifv', '.mxf', '.roq', '.nsv'
            ];

            this.audioFormats = [
                '.mp3', '.m4a', '.wav', '.flac', '.aac', '.ogg', '.wma',
                '.opus', '.aiff', '.ape', '.mka', '.ac3', '.dts', '.m4b',
                '.m4p', '.m4r', '.mid', '.midi', '.mp2', '.mpa', '.mpc',
                '.ra', '.tta', '.voc', '.vox', '.amr', '.awb', '.dsf',
                '.dff', '.alac', '.wv', '.oga', '.sln', '.aif', '.pcm'
            ];

            // Create Map for file extensions
            this.extensionMap = new Map();

            // Add video extensions to Map
            this.videoFormats.forEach(ext => {
                this.extensionMap.set(ext.slice(1), 'video'); // .mp4 -> mp4
            });

            // Add audio extensions to Map
            this.audioFormats.forEach(ext => {
                this.extensionMap.set(ext.slice(1), 'audio'); // .mp3 -> mp3
            });

            this.domElements = {};

            this.state = {
                isGenerating: false,
                isPaused: false,
                selectedFormat: 'm3u',
                includeVideo: false,
                includeAudio: false,
                maxEntries: 1000000,
                timeoutMs: 5000,
                retryCount: 2,
                maxDepth: 0,
                maxSeenUrls: 5000,
                stats: { ...this.initialStats }
            };

            this.sortOptions = { numeric: true, sensitivity: 'base' };

            this.entries = [];
            this.seenUrls = new Set();
            this.toastQueue = [];
            this.isProcessingToast = false;

            this.icons = {
                video: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <polygon points="23 7 16 12 23 17 23 7"/>
                    <rect x="1" y="5" width="15" height="14" rx="2" ry="2"/>
                </svg>`,
                audio: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <path d="M9 18V5l12-2v13"/>
                    <circle cx="6" cy="18" r="3"/>
                    <circle cx="18" cy="16" r="3"/>
                </svg>`,
                folder: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>
                </svg>`,
                info: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <circle cx="12" cy="12" r="10"/>
                    <line x1="12" y1="16" x2="12" y2="12"/>
                    <line x1="12" y1="8" x2="12.01" y2="8"/>
                </svg>`,
                file: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/>
                    <polyline points="13 2 13 9 20 9"/>
                </svg>`,
                download: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
                    <polyline points="7 10 12 15 17 10"/>
                    <line x1="12" y1="15" x2="12" y2="3"/>
                </svg>`,
                close: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <line x1="18" y1="6" x2="6" y2="18"/>
                    <line x1="6" y1="6" x2="18" y2="18"/>
                </svg>`,
                pause: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <rect x="6" y="4" width="4" height="16"/>
                    <rect x="14" y="4" width="4" height="16"/>
                </svg>`,
                resume: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <polygon points="5 3 19 12 5 21 5 3"/>
                </svg>`,
                cancel: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <circle cx="12" cy="12" r="10"/>
                    <line x1="15" y1="9" x2="9" y2="15"/>
                    <line x1="9" y1="9" x2="15" y2="15"/>
                </svg>`,
                success: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/>
                    <polyline points="22 4 12 14.01 9 11.01"/>
                </svg>`,
                error: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <circle cx="12" cy="12" r="10"/>
                    <line x1="12" y1="8" x2="12" y2="12"/>
                    <line x1="12" y1="16" x2="12.01" y2="16"/>
                </svg>`,
                warning: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
                    <line x1="12" y1="9" x2="12" y2="13"/>
                    <line x1="12" y1="17" x2="12.01" y2="17"/>
                </svg>`,
                github: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
                    <path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
                </svg>`,
                twitter: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
                    <path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
                </svg>`,
                chevronDown: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <polyline points="6 9 12 15 18 9"/>
                </svg>`,
                layers: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <polygon points="12 2 2 7 12 12 22 7 12 2"/>
                    <polyline points="2 17 12 22 22 17"/>
                    <polyline points="2 12 12 17 22 12"/>
                </svg>`,
                logToggle: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
                </svg>`
            };

            this.templates = {
                toggleButton: (id, title, icon, checked = false) => `
                    <div class="M3Unator-toggle-container">
                        <label>
                            <input type="checkbox" id="${id}" ${checked ? 'checked' : ''}>
                            <span title="${title}">${icon}</span>
                        </label>
                    </div>
                `,
                controlButton: (type, icon, text) => `
                    <button class="M3Unator-control-btn ${type}">
                        ${icon}
                        <span>${text}</span>
                    </button>
                `,
                statsItem: (icon, id, title, className = '') => `
                    <span class="M3Unator-stat ${className}" title="${title}">
                        ${icon}
                        <span id="${id}">0</span>
                    </span>
                `
            };

            this.baseStyles = `
                .M3Unator-btn-base {
                    border: none;
                    border-radius: 8px;
                    font-family: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
                    font-weight: 600;
                    cursor: pointer;
                    transition: all 0.2s ease;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    gap: 0.5rem;
                }

                .M3Unator-toggle-base {
                    position: relative;
                    display: flex;
                    align-items: center;
                    gap: 0.5rem;
                    transition: all 0.2s ease;
                }

                .M3Unator-control-base {
                    padding: 0.75rem 1.5rem;
                    border-radius: 12px;
                    font-weight: 600;
                    font-size: 0.95rem;
                    min-width: 160px;
                    background: rgba(30, 30, 46, 0.6);
                    backdrop-filter: blur(8px);
                }

                .M3Unator-stat-base {
                    display: inline-flex;
                    align-items: center;
                    gap: 0.382rem;
                    font-size: 0.875rem;
                    cursor: help;
                    min-width: 52px;
                    padding: 0 0.382rem;
                }

                .M3Unator-icon-base {
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    width: 24px;
                    height: 24px;
                    transition: all 0.2s ease;
                }
            `;

            GM_addStyle(this.baseStyles);

            this.updateActivityIndicator = (status) => {
                const indicator = this.domElements.activityIndicator;
                if (!indicator) return;
                
                // Remove all classes first
                indicator.classList.remove('active', 'paused', 'cancelled', 'completed');
                
                // Status check
                if (this.state.isGenerating) {
                    if (this.state.isPaused) {
                        indicator.classList.add('paused');
                    } else {
                        indicator.classList.add('active');
                    }
                } else if (status === 'cancelled') {
                    indicator.classList.add('cancelled');
                } else if (status === 'completed') {
                    indicator.classList.add('completed');
                }
            };

            this.logCache = new LogCache(100);
        }

        createComponent(type, props) {
            switch (type) {
                case 'toggle':
                    return this.templates.toggleButton(
                        props.id,
                        props.title,
                        props.icon,
                        props.checked
                    );
                case 'control':
                    return this.templates.controlButton(
                        props.type,
                        props.icon,
                        props.text
                    );
                case 'stats':
                    return `
                        <span class="M3Unator-stat ${props.class}" title="${props.title}">
                            ${props.icon}
                            <span id="${props.id}">0</span>
                        </span>
                    `;
                default:
                    return '';
            }
        }

        async init() {
            const container = document.createElement('div');
            container.className = 'M3Unator-container';

            const toggleButtons = [
                {
                    id: 'includeVideo',
                    title: 'Video (.mp4, .mkv)',
                    icon: this.icons.video,
                    checked: true
                },
                {
                    id: 'includeAudio',
                    title: 'Audio (.mp3, .m4a)',
                    icon: this.icons.audio,
                    checked: true
                },
                {
                    id: 'recursiveSearch',
                    title: 'Scan Subdirectories',
                    icon: this.icons.folder,
                    checked: true
                }
            ].map(props => this.createComponent('toggle', props)).join('');

            const controlButtons = [
                {
                    type: 'pause',
                    icon: this.icons.pause,
                    text: 'Pause'
                },
                {
                    type: 'resume',
                    icon: this.icons.resume,
                    text: 'Resume'
                },
                {
                    type: 'cancel',
                    icon: this.icons.cancel,
                    text: 'Cancel'
                }
            ].map(props => this.createComponent('control', props)).join('');

            const statsItems = [
                {
                    icon: this.icons.file,
                    id: 'totalFiles',
                    title: 'Total Files',
                    class: ''
                },
                {
                    icon: this.icons.video,
                    id: 'videoFiles',
                    title: 'Video (.mp4, .mkv)',
                    class: 'video'
                },
                {
                    icon: this.icons.audio,
                    id: 'audioFiles',
                    title: 'Audio (.mp3, .m4a)',
                    class: 'audio'
                },
                {
                    icon: this.icons.folder,
                    id: 'directories',
                    title: 'Subdirectories',
                    class: 'dir'
                },
                {
                    icon: this.icons.layers,
                    id: 'depthLevel',
                    title: 'Depth Level',
                    class: 'depth'
                },
                {
                    icon: this.icons.error,
                    id: 'errors',
                    title: 'Error',
                    class: 'error'
                }
            ].map(props => this.createComponent('stats', props)).join('');

            container.innerHTML = `
                <div class="M3Unator-popup">
                    <div class="M3Unator-header">
                        <h3 class="M3Unator-title">
                            ${this.icons.video}
                            <span>M3Unator</span>
                        </h3>
                        <div style="display: flex; align-items: center;">
                            <div class="M3Unator-social">
                                <a class="info-link">
                                    ${this.icons.info}
                                </a>
                                <a href="https://github.com/hasanbeder/M3Unator" target="_blank" rel="noopener noreferrer" class="github-icon">
                                    ${this.icons.github}
                                </a>
                                <a href="https://x.com/hasanbeder" target="_blank" rel="noopener noreferrer">
                                    ${this.icons.twitter}
                                </a>
                            </div>
                            <button class="M3Unator-close">${this.icons.close}</button>
                        </div>
                    </div>
                    <div class="info-modal">
                        <div class="info-modal-content">
                            <div class="info-modal-header">
                                <h3>About M3Unator</h3>
                                <span class="info-close">${this.icons.close}</span>
                            </div>
                            <div class="info-modal-body">
                                <p><strong>M3Unator v1.0.2</strong> - The Ultimate Web Directory Playlist Creator</p>
                                <p>Create M3U/M3U8 playlists effortlessly from any web directory. Experience ultrafast scanning and intelligent media detection.</p>
                                <h4>Key Features:</h4>
                                <ul>
                                    <li>⚡ Ultrafast directory scanning with parallel processing</li>
                                    <li>🎥 Comprehensive media support (MP4, MKV, MP3, FLAC, etc.)</li>
                                    <li>🔍 Smart recursive directory scanning</li>
                                    <li>🛡️ Enhanced error handling and stability</li>
                                    <li>🌙 Modern dark theme interface</li>
                                </ul>
                                <p>For updates and more information, visit the <a href="https://github.com/hasanbeder/M3Unator" target="_blank">GitHub repository</a>.</p>
                            </div>
                        </div>
                    </div>
                    <div class="M3Unator-content">
                        <div class="M3Unator-input-row">
                            <div class="M3Unator-input-group">
                                <input type="text" 
                                    id="playlistName" 
                                    class="M3Unator-input"
                                    placeholder="Playlist Name" 
                                    required
                                    spellcheck="false"
                                    autocomplete="off"
                                    autocorrect="off"
                                    autocapitalize="off">

                                <div class="M3Unator-dropdown">
                                    <button type="button" class="M3Unator-dropdown-button">
                                        <span>.m3u</span>
                                        ${this.icons.chevronDown}
                                    </button>
                                    <div class="M3Unator-dropdown-menu">
                                        <div class="M3Unator-dropdown-item selected" data-value="m3u">.m3u</div>
                                        <div class="M3Unator-dropdown-divider"></div>
                                        <div class="M3Unator-dropdown-item" data-value="m3u8">.m3u8</div>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <div class="M3Unator-toggle-group">
                            ${toggleButtons}
                        </div>

                        <div class="M3Unator-depth-controls">
                            <div class="M3Unator-radio-group">
                                <label class="M3Unator-radio">
                                    <input type="radio" name="depthType" value="current" id="currentDepth">
                                    <span class="radio-mark"></span>
                                    <span class="radio-label">Current directory</span>
                                </label>
                                <label class="M3Unator-radio">
                                    <input type="radio" name="depthType" value="custom" id="customDepth">
                                    <span class="radio-mark"></span>
                                    <span class="radio-label">Custom depth:</span>
                                    <input type="number" 
                                        id="maxDepth" 
                                        value="1" 
                                        min="1" 
                                        max="99" 
                                        class="M3Unator-depth-input"
                                        title="Subdirectory scan depth" 
                                        style="width: 64px;"
                                        inputmode="numeric"
                                        pattern="[0-9]*">
                                </label>
                            </div>
                        </div>

                        <button class="M3Unator-button" id="generateBtn">
                            ${this.icons.download}
                            <span>Create Playlist</span>
                        </button>

                        <div class="M3Unator-controls">
                            ${controlButtons}
                        </div>

                        <div class="M3Unator-stats-bar">
                            <div class="M3Unator-stats">
                                ${statsItems}
                            </div>
                        </div>

                        <div class="M3Unator-log-container">
                            <button class="M3Unator-log-toggle">
                                <div class="toggle-text">
                                    ${this.icons.logToggle}
                                    <span>Recent Activity</span>
                                </div>
                                <div class="M3Unator-activity-indicator"></div>
                            </button>
                            <div id="scanLog" class="M3Unator-log collapsed"></div>
                        </div>
                    </div>

                    <style>
                        .M3Unator-container {
                            max-width: 400px;
                            width: 100%;
                            background: transparent;
                            backdrop-filter: none;
                        }

                        .M3Unator-popup {
                            background: #1e1e2e;
                            border-radius: 12px;
                            box-shadow: 0 4px 24px rgba(0, 0, 0, 0.2);
                            border: 1px solid rgba(69, 71, 90, 0.6);
                        }

                        .info-modal {
                            display: none;
                            position: fixed;
                            top: 0;
                            left: 0;
                            width: 100%;
                            height: 100%;
                            background: rgba(0, 0, 0, 0.75);
                            z-index: 99999;
                        }

                        .info-content {
                            position: absolute;
                            top: 50%;
                            left: 50%;
                            transform: translate(-50%, -50%);
                            background: #1e1e2e;
                            padding: 2rem;
                            border-radius: 12px;
                            max-width: 600px;
                            width: 90%;
                            max-height: 80vh;
                            overflow-y: auto;
                            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
                            border: 1px solid rgba(69, 71, 90, 0.6);
                        }

                        .M3Unator-content {
                            padding: 0.75rem;
                            display: flex;
                            flex-direction: column;
                            gap: 0.75rem;
                            max-width: 100%;
                            overflow: hidden;
                        }

                        .M3Unator-input-row {
                            display: flex;
                            width: 100%;
                            position: relative;
                            max-width: 100%;
                            overflow: visible;
                        }

                        .M3Unator-input-group {
                            flex: 1;
                            min-width: 0;
                            position: relative;
                        }

                        .M3Unator-input {
                            width: 100%;
                            min-width: 0;
                            padding-right: 80px;
                            box-sizing: border-box;
                            transition: all 0.2s ease;
                            background: rgba(30, 30, 46, 0.6);
                            border: 1px solid rgba(69, 71, 90, 0.6);
                            border-radius: 6px;
                            color: #f5c2e7;
                            padding: 8px 80px 8px 12px;
                            font-size: 14px;
                        }

                        .M3Unator-dropdown {
                            position: absolute;
                            right: 8px;
                            top: 50%;
                            transform: translateY(-50%);
                            width: 70px;
                            z-index: 9999;
                            display: none;
                        }

                        .M3Unator-dropdown.active {
                            display: block;
                        }

                        .M3Unator-dropdown-button {
                            width: 100%;
                            padding: 4px 8px;
                            border-radius: 6px;
                            background: rgba(30, 30, 46, 0.8);
                            border: 1px solid rgba(69, 71, 90, 0.6);
                            color: #f5c2e7;
                            cursor: pointer;
                            display: flex;
                            align-items: center;
                            justify-content: space-between;
                            gap: 4px;
                            transition: all 0.2s ease;
                            box-sizing: border-box;
                            font-size: 14px;
                        }

                        .M3Unator-dropdown-button:hover {
                            background: rgba(30, 30, 46, 0.9);
                            border-color: rgba(69, 71, 90, 0.8);
                        }

                        .M3Unator-dropdown-menu {
                            position: absolute;
                            top: 100%;
                            right: 0;
                            width: 100%;
                            margin-top: 4px;
                            background: rgba(30, 30, 46, 0.95);
                            border: 1px solid rgba(69, 71, 90, 0.6);
                            border-radius: 6px;
                            padding: 4px;
                            display: none;
                            box-sizing: border-box;
                            z-index: 9999;
                        }

                        .M3Unator-dropdown.active .M3Unator-dropdown-menu {
                            display: block;
                        }

                        .M3Unator-dropdown-item {
                            padding: 8px 12px;
                            cursor: pointer;
                            border-radius: 4px;
                            transition: all 0.2s ease;
                            text-align: center;
                            font-size: 14px;
                            font-family: monospace;
                            color: #cdd6f4;
                        }

                        .M3Unator-dropdown-divider {
                            height: 1px;
                            background: rgba(69, 71, 90, 0.6);
                            margin: 6px 0;
                        }

                        .M3Unator-dropdown-menu {
                            position: absolute;
                            top: 100%;
                            right: 0;
                            width: 100%;
                            margin-top: 4px;
                            background: #1e1e2e;
                            border: 1px solid rgba(69, 71, 90, 0.6);
                            border-radius: 6px;
                            padding: 6px;
                            display: none;
                            box-sizing: border-box;
                            z-index: 9999;
                        }

                        .M3Unator-dropdown-button {
                            width: 100%;
                            padding: 4px 8px;
                            border-radius: 6px;
                            background: #1e1e2e;
                            border: 1px solid rgba(69, 71, 90, 0.6);
                            color: #f5c2e7;
                            cursor: pointer;
                            display: flex;
                            align-items: center;
                            justify-content: space-between;
                            gap: 4px;
                            transition: all 0.2s ease;
                            box-sizing: border-box;
                            font-size: 14px;
                            font-family: monospace;
                        }

                        .M3Unator-dropdown-item:hover {
                            background: rgba(203, 166, 247, 0.1);
                            color: #f5c2e7;
                        }

                        .M3Unator-dropdown-item.selected {
                            background: rgba(203, 166, 247, 0.1);
                            color: #cba6f7;
                        }
                    </style>
                </div>
            `;

            document.body.appendChild(container);
            const launcher = document.createElement('button');
            launcher.className = 'M3Unator-launcher';
            launcher.innerHTML = `
                ${this.icons.video}
                <span>M3Unator</span>
            `;
            
            document.body.appendChild(launcher);
            const popup = container.querySelector('.M3Unator-popup');
            const header = container.querySelector('.M3Unator-header');
            this.makeDraggable(popup, header);
            const statsBar = container.querySelector('.M3Unator-stats-bar');
            if (statsBar) {
                statsBar.style.display = 'block';
            }

            this.domElements = {
                container,
                popup: container.querySelector('.M3Unator-popup'),
                header: container.querySelector('.M3Unator-header'),
                closeBtn: container.querySelector('.M3Unator-close'),
                generateBtn: container.querySelector('#generateBtn'),
                playlistInput: container.querySelector('#playlistName'),
                includeVideo: container.querySelector('#includeVideo'),
                includeAudio: container.querySelector('#includeAudio'),
                recursiveSearch: container.querySelector('#recursiveSearch'),
                controls: container.querySelector('.M3Unator-controls'),
                scanLog: container.querySelector('#scanLog'),
                statsBar: container.querySelector('.M3Unator-stats-bar'),
                dropdown: container.querySelector('.M3Unator-dropdown'),
                launcher,
                stats: {
                    totalFiles: container.querySelector('#totalFiles'),
                    videoFiles: container.querySelector('#videoFiles'),
                    audioFiles: container.querySelector('#audioFiles'),
                    directories: container.querySelector('#directories'),
                    depthLevel: container.querySelector('#depthLevel'),
                    errors: container.querySelector('#errors')
                },
                depthControls: container.querySelector('.M3Unator-depth-controls'),
                currentDepth: container.querySelector('#currentDepth'),
                customDepth: container.querySelector('#customDepth'),
                maxDepth: container.querySelector('#maxDepth'),
                logToggle: container.querySelector('.M3Unator-log-toggle'),
                logCounter: container.querySelector('.M3Unator-log-counter'),
                activityIndicator: container.querySelector('.M3Unator-activity-indicator'),
            };

            launcher.onclick = () => {
                this.domElements.container.setAttribute('data-visible', 'true');
                const overlay = document.createElement('div');
                overlay.className = 'M3Unator-overlay';
                document.body.appendChild(overlay);
                
                const popup = this.domElements.popup;
                const rect = popup.getBoundingClientRect();
                const centerX = (window.innerWidth - rect.width) / 2;
                const centerY = (window.innerHeight - rect.height) / 2;
                popup.style.left = `${centerX}px`;
                popup.style.top = `${centerY}px`;
            };

            document.querySelector('.M3Unator-close').onclick = () => {
                if (this.state.isGenerating) {
                this.state.isGenerating = false;
                this.state.isPaused = false;
                    this.reset({ isCancelled: true, enableToggles: true });
                    this.showToast('Scan cancelled', 'warning');
                }
                this.domElements.container.removeAttribute('data-visible');
                const overlay = document.querySelector('.M3Unator-overlay');
                if (overlay) overlay.remove();
            };

            this.setupPopupHandlers();

            this.updateCounter(0);

            this.domElements.logToggle.addEventListener('click', () => {
                const log = this.domElements.scanLog;
                const toggle = this.domElements.logToggle;
                
                if (log.classList.contains('expanded')) {
                    log.classList.remove('expanded');
                    toggle.classList.remove('active');
                } else {
                    log.classList.add('expanded');
                    toggle.classList.add('active');
                    log.scrollTop = log.scrollHeight;
                }
            });

            this.domElements.scanLog.classList.remove('expanded');
            this.domElements.logToggle.classList.remove('active');

            this.logCount = 0;
        }

        updateStyles() {
            GM_addStyle(`
                .M3Unator-toggle-container {
                    @extend .M3Unator-toggle-base;
                }

                .M3Unator-control-btn {
                    @extend .M3Unator-control-base;
                }

                .M3Unator-stat {
                    @extend .M3Unator-stat-base;
                }

                .M3Unator-toggle-container span {
                    @extend .M3Unator-icon-base;
                    background: #1e1e2e;
                    border: 2px solid #45475a;
                    border-radius: 16px;
                }

                .M3Unator-control-btn.pause {
                    border-color: #fab387;
                    color: #fab387;
                }

                .M3Unator-control-btn.resume {
                    border-color: #94e2d5;
                    color: #94e2d5;
                }

                .M3Unator-control-btn.cancel {
                    border-color: #f38ba8;
                    color: #f38ba8;
                }

            `);
        }

        makeDraggable(element, handle) {
            let isDragging = false;
            let currentX;
            let currentY;
            let initialX;
            let initialY;
            let xOffset = 0;
            let yOffset = 0;

            const centerWindow = () => {
                const rect = element.getBoundingClientRect();
                const centerX = (window.innerWidth - rect.width) / 2;
                const centerY = (window.innerHeight - rect.height) / 2;
                
                element.style.left = `${centerX}px`;
                element.style.top = `${centerY}px`;
                
                xOffset = centerX;
                yOffset = centerY;
                
                element.style.transform = 'none';
            };

            centerWindow();

            const getPosition = (e) => {
                return {
                    x: e.type.includes('touch') ? e.touches[0].clientX : e.clientX,
                    y: e.type.includes('touch') ? e.touches[0].clientY : e.clientY
                };
            };

            const dragStart = (e) => {
                if (e.target === handle || handle.contains(e.target)) {
                    e.preventDefault();
                    const pos = getPosition(e);
                    
                    isDragging = true;
                    
                    const rect = element.getBoundingClientRect();
                    xOffset = rect.left;
                    yOffset = rect.top;
                    
                    initialX = pos.x - xOffset;
                    initialY = pos.y - yOffset;

                    handle.style.cursor = 'grabbing';
                }
            };

            const drag = (e) => {
                if (isDragging) {
                    e.preventDefault();
                    const pos = getPosition(e);

                    currentX = pos.x - initialX;
                    currentY = pos.y - initialY;

                    const rect = element.getBoundingClientRect();
                    const maxX = window.innerWidth - rect.width;
                    const maxY = window.innerHeight - rect.height;

                    currentX = Math.min(Math.max(0, currentX), maxX);
                    currentY = Math.min(Math.max(0, currentY), maxY);

                    element.style.left = `${currentX}px`;
                    element.style.top = `${currentY}px`;
                    
                    xOffset = currentX;
                    yOffset = currentY;
                }
            };

            const dragEnd = () => {
                if (isDragging) {
                    isDragging = false;
                    handle.style.cursor = 'grab';
                }
            };

            handle.addEventListener('mousedown', dragStart);
            document.addEventListener('mousemove', drag);
            document.addEventListener('mouseup', dragEnd);

            handle.addEventListener('touchstart', dragStart, { passive: false });
            document.addEventListener('touchmove', drag, { passive: false });
            document.addEventListener('touchend', dragEnd);

            window.addEventListener('resize', () => {
                if (!isDragging) {
                    centerWindow();
                }
            });

            handle.style.cursor = 'grab';
            handle.style.userSelect = 'none';
            handle.style.touchAction = 'none';

            element.style.position = 'fixed';
            element.style.margin = '0';
            element.style.touchAction = 'none';
            element.style.transition = 'none';
        }

        showToast(message, type = 'success', duration = 3000) {
            let toastContainer = document.querySelector('.M3Unator-toast-container');
            if (!toastContainer) {
                toastContainer = document.createElement('div');
                toastContainer.className = 'M3Unator-toast-container';
                document.body.appendChild(toastContainer);
            }

            // Remove previous toasts
            const existingToasts = toastContainer.querySelectorAll('.M3Unator-toast');
            existingToasts.forEach(toast => {
                toast.classList.add('removing');
                setTimeout(() => toast.remove(), 300);
            });

            const toast = document.createElement('div');
            toast.className = `M3Unator-toast ${type}`;
            
            const icon = this.icons[type] || this.icons.info;
            toast.innerHTML = `${icon}<span>${message}</span>`;
            
            toastContainer.appendChild(toast);
            
            // Force a reflow to ensure the animation plays
            void toast.offsetWidth;
            
            // Add show class to trigger animation
            requestAnimationFrame(() => {
                toast.classList.add('show');
            });

            setTimeout(() => {
                toast.classList.add('removing');
                toast.classList.remove('show');
                setTimeout(() => {
                    if (toast.parentNode === toastContainer) {
                        toast.remove();
                    }
                    if (toastContainer.children.length === 0) {
                        toastContainer.remove();
                    }
                }, 300);
            }, duration);
        }

        setupPopupHandlers() {
            const generateBtn = this.domElements.generateBtn;
            const playlistInput = this.domElements.playlistInput;
            const includeVideo = this.domElements.includeVideo;
            const includeAudio = this.domElements.includeAudio;
            const recursiveSearch = this.domElements.recursiveSearch;
            const controls = this.domElements.controls;

            const dropdown = this.domElements.dropdown;
            const dropdownButton = dropdown.querySelector('.M3Unator-dropdown-button');
            const dropdownItems = dropdown.querySelectorAll('.M3Unator-dropdown-item');

            const controlButtons = controls.querySelectorAll('.M3Unator-control-btn');
            const pauseBtn = controlButtons[0];
            const resumeBtn = controlButtons[1];
            const cancelBtn = controlButtons[2];

            dropdownButton.addEventListener('click', () => {
                dropdown.classList.toggle('active');
            });

            document.addEventListener('click', (e) => {
                if (!dropdown.contains(e.target)) {
                    dropdown.classList.remove('active');
                }
            });

            dropdownItems.forEach(item => {
                item.addEventListener('click', () => {
                    dropdownItems.forEach(i => i.classList.remove('selected'));
                    item.classList.add('selected');
                    dropdownButton.querySelector('span').textContent = item.textContent;
                    this.state.selectedFormat = item.dataset.value;
                    dropdown.classList.remove('active');
                });
            });

            recursiveSearch.checked = true;
            this.state.recursiveSearch = true;
            includeVideo.checked = true;
            includeAudio.checked = true;
            this.state.includeVideo = true;
            this.state.includeAudio = true;

            includeVideo.addEventListener('change', (e) => {
                this.state.includeVideo = e.target.checked;
                this.addLogEntry(
                    e.target.checked ? 
                    'Video files will be included' : 
                    'Video files will not be included',
                    'info'
                );
            });

            includeAudio.addEventListener('change', (e) => {
                this.state.includeAudio = e.target.checked;
                this.addLogEntry(
                    e.target.checked ? 
                    'Audio files will be included' : 
                    'Audio files will not be included',
                    'info'
                );
            });

                const currentDepth = this.domElements.currentDepth;
                const customDepth = this.domElements.customDepth;
                const maxDepth = this.domElements.maxDepth;
            const depthControls = this.domElements.depthControls;

            depthControls.style.display = 'none';
            depthControls.classList.remove('active');
            this.state.maxDepth = -1;

            currentDepth.checked = true;
            customDepth.checked = false;
            maxDepth.disabled = true;
            maxDepth.value = '1';

            recursiveSearch.addEventListener('change', (e) => {
                if (!e.target.checked) {
                    depthControls.style.display = 'block';
                    depthControls.classList.add('active');
                    
                    currentDepth.checked = true;
                    customDepth.checked = false;
                    maxDepth.disabled = true;
                    this.state.maxDepth = 0;
                    
                    this.addLogEntry('Directory scanning disabled, only current directory will be scanned', 'info');
                } else {
                    depthControls.style.display = 'none';
                    depthControls.classList.remove('active');
                    
                    this.state.maxDepth = -1;
                    this.state.recursiveSearch = true;
                    
                    this.addLogEntry('Directory scanning active, all directories will be scanned', 'info');
                }
            });

            this.domElements.currentDepth.addEventListener('change', (e) => {
                if (e.target.checked && !recursiveSearch.checked) {
                    this.state.maxDepth = 0;
                    this.domElements.maxDepth.disabled = true;
                    this.addLogEntry('Only current directory will be scanned', 'info');
                }
            });

            this.domElements.customDepth.addEventListener('change', (e) => {
                if (e.target.checked && !recursiveSearch.checked) {
                    const depthValue = parseInt(this.domElements.maxDepth.value) || 1;
                    this.state.maxDepth = depthValue;
                    this.domElements.maxDepth.disabled = false;
                    this.addLogEntry(
                        `Directory scanning depth: ${depthValue} ` +
                        `(current directory + ${depthValue} sublevels)`, 
                        'info'
                    );
                }
            });

            this.domElements.maxDepth.addEventListener('input', (e) => {
                if (this.domElements.customDepth.checked && !recursiveSearch.checked) {
                    const value = Math.min(99, Math.max(1, parseInt(e.target.value) || 1));
                    e.target.value = value;
                    this.state.maxDepth = value;
                    this.addLogEntry(
                        `Directory scanning depth updated: ${value} ` +
                        `(current directory + ${value} sublevels)`, 
                        'info'
                    );
                }
            });

            pauseBtn.addEventListener('click', () => {
                this.state.isPaused = true;
                this.updateActivityIndicator('paused');
                pauseBtn.style.display = 'none';
                resumeBtn.style.display = 'flex';
                
                generateBtn.innerHTML = `
                    <div class="M3Unator-spinner" style="animation-play-state: paused;"></div>
                    <span>Scan paused</span>
                `;
                
                this.showToast('Scan paused', 'warning');
                this.addLogEntry('Scan paused...', 'warning');
            });

            resumeBtn.addEventListener('click', () => {
                this.state.isPaused = false;
                this.updateActivityIndicator('active');
                resumeBtn.style.display = 'none';
                pauseBtn.style.display = 'flex';
                
                generateBtn.innerHTML = `
                    <div class="M3Unator-spinner"></div>
                    <span>Creating...</span>
                `;
                
                this.showToast('Scan resumed', 'success');
                this.addLogEntry('Scan in progress...', 'success');
            });

            cancelBtn.addEventListener('click', () => {
                this.state.isGenerating = false;
                this.state.isPaused = false;
                this.updateActivityIndicator('cancelled');
                
                setTimeout(() => {
                    this.reset({ isCancelled: true, enableToggles: true });
                this.showToast('Scan cancelled', 'warning');
                }, 100);
            });

            generateBtn.addEventListener('click', async () => {
                const playlistName = this.sanitizeInput(playlistInput.value.trim());

                if (!playlistName) {
                    this.showToast('Please enter a valid playlist name', 'warning');
                    playlistInput.focus();
                    return;
                }

                if (!this.state.includeVideo && !this.state.includeAudio) {
                    this.showToast('Please select at least one media type', 'warning');
                    return;
                }

                try {
                    this.entries = [];
                    this.seenUrls.clear();
                    this.logCount = 0;
                    if (this.domElements.scanLog) {
                        this.domElements.scanLog.innerHTML = '';
                    }
                    this.state.stats = JSON.parse(JSON.stringify(this.initialStats));

                    this.state.isGenerating = true;
                    this.state.isPaused = false;
                    this.updateActivityIndicator('active');
                    this.showToast('Scan started', 'success');
                    
                    generateBtn.disabled = true;
                    generateBtn.innerHTML = `
                        <div class="M3Unator-spinner"></div>
                        <span>Creating...</span>
                    `;

                    this.domElements.includeVideo.disabled = true;
                    this.domElements.includeAudio.disabled = true;
                    this.domElements.recursiveSearch.disabled = true;
                    this.domElements.currentDepth.disabled = true;
                    this.domElements.customDepth.disabled = true;
                    this.domElements.maxDepth.disabled = true;

                    controls.style.display = 'flex';
                    controls.classList.add('active');
                    
                    if (pauseBtn) {
                        pauseBtn.style.display = 'flex';
                        resumeBtn.style.display = 'none';
                        cancelBtn.style.display = 'flex';
                    }

                    this.domElements.statsBar.style.display = 'block';
                    this.domElements.statsBar.classList.add('active');

                    const entries = await this.scanDirectory(window.location.href, '', 0);

                    if (!this.state.isGenerating) {
                        return;
                    }

                    if (entries.length === 0) {
                        this.state.isGenerating = false;
                        this.updateActivityIndicator('cancelled');
                        this.showToast('No media files found', 'error');
                        this.reset({ isCancelled: true });
                        return;
                    }

                    this.addLogEntry(`Total ${entries.length} files found.`, 'success');
                    this.updateCounter(entries.length);

                    const content = this.createPlaylist(entries);
                    const fileName = `${playlistName}.${this.state.selectedFormat}`;

                    const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
                    const url = URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url;
                    a.download = fileName;
                    document.body.appendChild(a);
                    a.click();
                    document.body.removeChild(a);
                    URL.revokeObjectURL(url);

                    this.showToast(`Playlist "${fileName}" created successfully`, 'success');
                    this.updateActivityIndicator('completed');
                    this.reset({ keepLogs: true, keepUI: true, enableToggles: true });

                } catch (error) {
                    this.state.isGenerating = false;
                    this.state.isPaused = false;
                    this.updateActivityIndicator('cancelled');
                    console.error('Error creating playlist:', error);
                    this.addLogEntry(`Error: ${error.message}`, 'error');
                    this.showToast('Error creating playlist', 'error');
                    this.reset({ isCancelled: true });
                }
            });
        }

        reset(options = {}) {
            const {
                isCancelled = false,
                uiOnly = false,
                keepLogs = false,
                keepUI = false,
                enableToggles = false,
                wasGenerating = this.state.isGenerating
            } = options;

            // Save current state before updating
            const wasPaused = this.state.isPaused;
            
            this.state.isGenerating = false;
            this.state.isPaused = false;
            
            // Update activity indicator
            if (isCancelled || wasPaused) {
                this.updateActivityIndicator('cancelled');
            } else if (wasGenerating) {
                this.updateActivityIndicator('completed');
            } else {
                this.updateActivityIndicator(null);
            }
            
            if (!uiOnly) {
                this.entries = [];
                this.seenUrls.clear();
                
                if (!keepLogs) {
                    this.logCount = 0;
                    if (this.domElements.scanLog) {
                        this.domElements.scanLog.innerHTML = '';
                    }
                    if (this.domElements.logCounter) {
                        this.domElements.logCounter.textContent = '0';
                    }
                }

                if (wasGenerating && !isCancelled) {
                    const stats = this.domElements.stats;
                    const summary = [
                        `Scan completed:`,
                        `• Video files: ${stats.videoFiles.textContent}`,
                        `• Audio files: ${stats.audioFiles.textContent}`,
                        `• Scanned directories: ${stats.directories.textContent}`,
                        `• Maximum depth: ${stats.depthLevel.textContent}`,
                        stats.errors.textContent > 0 ? `• Errors: ${stats.errors.textContent} (${this.state.stats.errors.skipped} skipped)` : null
                    ].filter(Boolean).join('\n');

                    this.addLogEntry(summary, 'final');
                }
            }
            
            const elements = this.domElements;
            
            if (elements.generateBtn) {
                elements.generateBtn.disabled = false;
                elements.generateBtn.innerHTML = `${this.icons.download}<span>Create Playlist</span>`;
            }

            if (elements.controls) {
                elements.controls.style.display = 'none';
                elements.controls.classList.remove('active');
                
                const pauseBtn = elements.controls.querySelector('.M3Unator-control-btn.pause');
                const resumeBtn = elements.controls.querySelector('.M3Unator-control-btn.resume');
                const cancelBtn = elements.controls.querySelector('.M3Unator-control-btn.cancel');
                
                if (pauseBtn) pauseBtn.style.display = 'none';
                if (resumeBtn) resumeBtn.style.display = 'none';
                if (cancelBtn) cancelBtn.style.display = 'none';
            }

            if (enableToggles) {
                if (elements.includeVideo) elements.includeVideo.disabled = false;
                if (elements.includeAudio) elements.includeAudio.disabled = false;
                if (elements.recursiveSearch) elements.recursiveSearch.disabled = false;
                if (elements.currentDepth) elements.currentDepth.disabled = false;
                if (elements.customDepth) elements.customDepth.disabled = false;
                if (elements.maxDepth) elements.maxDepth.disabled = elements.customDepth ? !elements.customDepth.checked : true;
            }
            
            if (uiOnly) return;

            if (isCancelled) {
                this.state.stats = JSON.parse(JSON.stringify(this.initialStats));

                if (!keepLogs) {
                    if (elements.scanLog) {
                        elements.scanLog.innerHTML = '';
                        elements.scanLog.classList.add('collapsed');
                    }

                    if (elements.logToggle) {
                        elements.logToggle.classList.remove('active');
                    }

                    if (this.domElements.stats) {
                        Object.entries(this.domElements.stats).forEach(([key, element]) => {
                            if (element) {
                                element.textContent = '0';
                                const statContainer = element.closest('.M3Unator-stat');
                                if (statContainer) {
                                    statContainer.style.opacity = '0.5';
                                    if (key === 'depthLevel') {
                                        statContainer.dataset.progress = '';
                                        statContainer.title = 'Depth Level: 0';
                                    }
                                }
                            }
                        });
                    }
                }
            }

            if (elements.recursiveSearch) {
                elements.recursiveSearch.checked = true;
                this.state.recursiveSearch = true;
                this.state.maxDepth = -1;
            }

            if (elements.currentDepth) {
                elements.currentDepth.checked = false;
            }

            if (elements.customDepth) {
                elements.customDepth.checked = false;
            }

            if (elements.maxDepth) {
                elements.maxDepth.disabled = true;
                elements.maxDepth.value = '1';
            }

            if (elements.depthControls) {
                elements.depthControls.classList.remove('active');
            }
        }

        handleError(error, context = '') {
            let userMessage = 'An error occurred';
            let logMessage = error.message;
            let type = 'error';

            switch (true) {
                case error.name === 'AbortError':
                    userMessage = 'Server not responding, operation timed out';
                    logMessage = `Timeout: ${context}`;
                    type = 'warning';
                    break;

                case error.message.includes('HTTP error'):
                    const status = error.message.match(/\d+/)?.[0];
                    switch (status) {
                        case '403':
                            userMessage = 'Access denied to this directory';
                            break;
                        case '404':
                            userMessage = 'Directory or file not found';
                            break;
                        case '429':
                            userMessage = 'Too many requests, please wait a while';
                            break;
                        case '500':
                        case '502':
                        case '503':
                            userMessage = 'Server is currently unable to respond, please try again later';
                            break;
                        default:
                            userMessage = 'Error communicating with server';
                    }
                    logMessage = `${error.message} (${context})`;
                    break;

                case error.message.includes('decode'):
                    userMessage = 'Filename or path could not be read';
                    logMessage = `Decode error: ${context} - ${error.message}`;
                    type = 'warning';
                    break;

                case error.message.includes('NetworkError'):
                    userMessage = 'Network connection error, please check your connection';
                    logMessage = `Network error: ${context}`;
                    break;

                case error.message.includes('SecurityError'):
                    userMessage = 'Operation not allowed due to security restrictions';
                    logMessage = `Security error: ${context}`;
                    break;

                default:
                    userMessage = 'Unexpected error occurred';
                    logMessage = `${error.name}: ${error.message} (${context})`;
            }

            console.error(`[${context}]`, error);

            this.showToast(userMessage, type);

            this.addLogEntry(logMessage, type);

            this.state.stats.errors.total++;
        }

        async fetchWithRetry(url, options = {}, retries = 3) {
            let lastError;
            for (let i = 0; i < retries; i++) {
                try {
                    const response = await fetch(url, {
                        ...options,
                        headers: {
                            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
                            'Accept-Language': 'en-US,en;q=0.9',
                            'Connection': 'keep-alive',
                            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
                        },
                        timeout: options.timeout || 30000,
                        signal: options.signal
                    });

                    if (!response.ok) {
                        throw new Error(`HTTP error! Status: ${response.status}`);
                    }

                    const text = await response.text();
                    return {
                        decodedText: text,
                        status: response.status,
                        ok: response.ok
                    };
                } catch (error) {
                    lastError = error;
                    if (error.name === 'AbortError' || error.message.includes('404')) {
                        throw error; // Throw these errors immediately
                    }
                    if (i < retries - 1) {
                        await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
                        continue;
                    }
                }
            }
            throw lastError;
        }

        sanitizeInput(input) {
            if (!input || typeof input !== 'string') {
                return '';
            }

            const sanitized = input
                .replace(/[<>:"\/\\|?*\x00-\x1F]/g, '')
                .trim()
                .replace(/[\x00-\x1F\x7F]/g, '')
                .replace(/[\u200B-\u200D\uFEFF]/g, '')
                .replace(/[^\w\s\-_.()[\]{}#@!$%^&+=]/g, '');

            if (!sanitized) {
                return 'playlist';
            }

            if (sanitized.length > 255) {
                return sanitized.slice(0, 255);
            }

            return sanitized;
        }

        decodeString(str, type = 'both') {
            if (!str) return str;
            
            try {
                let decoded = str;
                
                if (type === 'html' || type === 'both') {
                    decoded = decoded.replace(/&amp;/g, '&')
                     .replace(/&lt;/g, '<')
                     .replace(/&gt;/g, '>')
                     .replace(/&quot;/g, '"')
                     .replace(/&#039;/g, "'")
                     .replace(/&#x27;/g, "'")
                     .replace(/&#x2F;/g, "/");
        }

                if (type === 'url' || type === 'both') {
            try {
                        decoded = decodeURIComponent(decoded);
            } catch (e) {
                        decoded = decoded.replace(/%([0-9A-F]{2})/gi, (match, hex) => {
                    try {
                        return String.fromCharCode(parseInt(hex, 16));
                    } catch {
                        return match;
                    }
                });
                    }
                }
                
                return decoded;
            } catch (error) {
                console.warn('Decode error:', error);
                return str;
            }
        }

        extractFileInfo(path) {
            try {
                const decodedPath = this.decodeString(path);
                const parts = decodedPath.split('/');
                const fileName = parts.pop() || '';
                const dirPath = parts.join('/');
                
                return {
                    fileName,
                    dirPath,
                    original: {
                        fileName: path.split('/').pop() || '',
                        dirPath: path.split('/').slice(0, -1).join('/')
                    }
                };
            } catch (error) {
                this.handleError(error, `Path decode error: ${path}`);
                const parts = path.split('/');
                return {
                    fileName: parts.pop() || '',
                    dirPath: parts.join('/'),
                    original: {
                        fileName: parts.pop() || '',
                        dirPath: parts.join('/')
                    }
                };
            }
        }

        normalizeUrl(url) {
            let normalized = url.replace(/([^:]\/)\/+/g, "$1");
            return normalized.endsWith('/') ? normalized : normalized + '/';
        }

        isMediaFile(fileName, type) {
            const lowerFileName = fileName.toLowerCase();
            return type === 'video'
                ? this.videoFormats.some(ext => lowerFileName.endsWith(ext))
                : this.audioFormats.some(ext => lowerFileName.endsWith(ext));
        }

        resetCurrentStats() {
            this.state.stats.files.video.current = 0;
            this.state.stats.files.audio.current = 0;
        }

        updateFileStats(type) {
            this.state.stats.files[type].total++;
            this.state.stats.files[type].current++;
        }

        getCurrentStatsText() {
            const { video, audio } = this.state.stats.files;
            const details = [];

            if (video.current > 0) details.push(`${video.current} video`);
            if (audio.current > 0) details.push(`${audio.current} audio`);

            return details.join(' and ');
        }

        async scanDirectory(url, currentPath = '', depth = 0) {
            try {
                this.resetCurrentStats();

                if (!this.state.isGenerating || this.entries.length >= this.state.maxEntries) {
                    return this.entries;
                }

                while (this.state.isPaused && this.state.isGenerating) {
                    await new Promise(resolve => setTimeout(resolve, 100));
                }

                // Encode special characters properly
                const normalizedUrl = this.normalizeUrl(url).replace(/#/g, '%23')
                    .replace(/\s+/g, '%20')
                    .replace(/\[/g, '%5B')
                    .replace(/\]/g, '%5D')
                    .replace(/'/g, '%27')
                    .replace(/"/g, '%22');

                if (depth > this.state.stats.directories.depth) {
                    this.state.stats.directories.depth = depth;
                }

                this.state.stats.directories.total++;

                this.addLogEntry(`Scanning directory (level ${depth}): ${decodeURIComponent(normalizedUrl)}`);

                if (this.seenUrls.has(normalizedUrl)) {
                    this.addLogEntry(`This directory was previously scanned: ${decodeURIComponent(normalizedUrl)}`);
                    return this.entries;
                }

                this.seenUrls.add(normalizedUrl);
                if (this.seenUrls.size > this.state.maxSeenUrls) {
                    const keepCount = Math.floor(this.state.maxSeenUrls * 0.75);
                    const urlsArray = Array.from(this.seenUrls);
                    const keepUrls = urlsArray.slice(-keepCount);
                    this.seenUrls = new Set(keepUrls);
                    this.addLogEntry(
                        `Cache cleared (${urlsArray.length} -> ${keepUrls.length})`,
                        'info'
                    );
                }

                let response;
                try {
                    response = await this.fetchWithRetry(normalizedUrl, {
                        signal: null, // Remove cancel signal
                        timeout: 30000 // 30 second timeout
                    });
                } catch (error) {
                    if (error.name === 'AbortError') {
                        this.addLogEntry(`Request cancelled: ${decodeURIComponent(normalizedUrl)}`, 'warning');
                    } else if (error.message.includes('404')) {
                        this.addLogEntry(`Directory not found: ${decodeURIComponent(normalizedUrl)}`, 'warning');
                    } else {
                        this.addLogEntry(`Connection error: ${error.message}`, 'error');
                    }
                    return this.entries;
                }

                const html = response.decodedText;
                const parser = new DOMParser();
                const doc = parser.parseFromString(html, 'text/html');
                
                const isLiteSpeed = doc.querySelector('div#table-list') !== null;
                let hrefs = [];
                
                if (isLiteSpeed) {
                    const rows = doc.querySelectorAll('#table-content tr');
                    rows.forEach(row => {
                        const linkElement = row.querySelector('a');
                        if (linkElement && !linkElement.textContent.includes('Parent Directory')) {
                            const href = linkElement.getAttribute('href');
                            if (href) hrefs.push(href);
                        }
                    });
                } else {
                    const hrefRegex = /href="([^"]+)"/gi;
                    const matches = html.matchAll(hrefRegex);
                    hrefs = Array.from(matches, m => m[1]).filter(href =>
                        href &&
                        !href.startsWith('?') &&
                        !href.startsWith('/') &&
                        href !== '../' &&
                        !href.includes('Parent Directory')
                    );
                }

                // Separate directories and files
                const directories = [];
                const files = [];

                for (const href of hrefs) {
                    if (href.endsWith('/')) {
                        directories.push(href);
                    } else {
                        files.push(href);
                    }
                }

                // Process files in batches
                const batchSize = 100; // Increased from 50 to 100
                for (let i = 0; i < files.length; i += batchSize) {
                    if (!this.state.isGenerating || this.entries.length >= this.state.maxEntries) break;

                    const batch = files.slice(i, i + batchSize);
                    const batchProgress = {
                        total: batch.length,
                        processed: 0,
                        success: 0,
                        errors: 0
                    };

                    // Use Set for better performance
                    const processedUrls = new Set();

                    await Promise.all(batch.map(async href => {
                        try {
                            // Skip if URL was previously processed
                            const fullUrl = new URL(href, normalizedUrl).toString();
                            if (processedUrls.has(fullUrl)) return;
                            processedUrls.add(fullUrl);

                            const decodedHref = this.decodeString(href);
                            const { fileName } = this.extractFileInfo(decodedHref);
                            const fullPath = currentPath ? `${currentPath}/${fileName}` : fileName;

                            this.state.stats.totalFiles = (this.state.stats.totalFiles || 0) + 1;

                            // Check file type using Map
                            const mediaType = this.isMediaFileOptimized(fileName);
                            
                            if (mediaType && ((mediaType === 'video' && this.state.includeVideo) || 
                                            (mediaType === 'audio' && this.state.includeAudio))) {
                                if (mediaType === 'video') {
                                    this.updateFileStats('video');
                                } else {
                                    this.updateFileStats('audio');
                                }

                                this.entries.push({
                                    title: fullPath,
                                    url: fullUrl
                                });
                                batchProgress.success++;
                            }
                        } catch (error) {
                            console.error('URL processing error:', error);
                            this.state.stats.errors.total++;
                            batchProgress.errors++;
                        } finally {
                            batchProgress.processed++;
                            
                            // Update progress every 20 operations (instead of 10)
                            if (batchProgress.processed % 20 === 0 || batchProgress.processed === batchProgress.total) {
                                const progress = Math.floor((batchProgress.processed / batchProgress.total) * 100);
                                this.addLogEntry(
                                    `Batch Processing: ${progress}% (${batchProgress.processed}/${batchProgress.total}, ` +
                                    `Success: ${batchProgress.success}, Error: ${batchProgress.errors})`,
                                    'info'
                                );
                            }
                        }
                    }));

                    // Increase interval for memory cleanup
                    if (i > 0 && i % (batchSize * 20) === 0) {
                        global.gc && global.gc();
                    }
                }

                // Scan directories in parallel
                const shouldScanSubdir = 
                    this.state.maxDepth === -1 ||
                    (this.state.maxDepth > 0 && depth < this.state.maxDepth);

                if (shouldScanSubdir && directories.length > 0) {
                    const parallelLimit = 15; // Parallel limit increased to 15
                    const queue = [...directories];
                    const activeRequests = new Set();
                    
                    while (queue.length > 0 || activeRequests.size > 0) {
                        // Start new request if there are items in queue and active request limit is not reached
                        while (queue.length > 0 && activeRequests.size < parallelLimit) {
                            const dir = queue.shift();
                            try {
                                const decodedDir = this.decodeString(dir);
                                const fullUrl = new URL(decodedDir, normalizedUrl).toString();
                                const { fileName } = this.extractFileInfo(decodedDir);
                                const fullPath = currentPath ? `${currentPath}/${fileName}` : fileName;

                                const promise = this.scanDirectory(fullUrl, fullPath, depth + 1)
                                    .finally(() => {
                                        activeRequests.delete(promise);
                                    });

                                activeRequests.add(promise);
                                this.addLogEntry(`Entering subdirectory: ${fullPath}`);
                            } catch (error) {
                                console.error('Directory scanning error:', error);
                                this.state.stats.errors.total++;
                            }
                        }

                        // Wait for one of the active requests to complete
                        if (activeRequests.size > 0) {
                            await Promise.race(activeRequests);
                        }
                    }
                }

                this.updateCounter(this.state.stats.totalFiles);
                return this.entries;

            } catch (error) {
                this.state.stats.errors.total++;
                this.addLogEntry(`Scan error (${currentPath || url}): ${error.message}`, 'error');
                return this.entries;
            }
        }

        createPlaylist(entries) {
            let content = '#EXTM3U\n';
            
            const decodedEntries = entries.map(entry => {
                try {
                    let title = this.decodeString(entry.title);
                    const depth = (title.match(/\//g) || []).length;
                    const isVideo = this.videoFormats.some(ext => title.toLowerCase().endsWith(ext));
                    const isAudio = this.audioFormats.some(ext => title.toLowerCase().endsWith(ext));
                    
                    return {
                        ...entry,
                        decodedTitle: title,
                        depth: depth,
                        isVideo: isVideo,
                        isAudio: isAudio
                    };
                } catch (error) {
                    return {
                        ...entry,
                        decodedTitle: entry.title,
                        depth: 0,
                        isVideo: false,
                        isAudio: false
                    };
                }
            });

            const videoEntries = decodedEntries.filter(entry => entry.isVideo);
            const audioEntries = decodedEntries.filter(entry => entry.isAudio);

            const apacheSort = (a, b) => {
                if (a.depth !== b.depth) {
                    return a.depth - b.depth;
                }

                const aStartsWithNumber = /^\d/.test(a.decodedTitle);
                const bStartsWithNumber = /^\d/.test(b.decodedTitle);
                
                if (aStartsWithNumber !== bStartsWithNumber) {
                    return aStartsWithNumber ? -1 : 1;
                }

                return a.decodedTitle.localeCompare(b.decodedTitle, undefined, {
                    numeric: true,
                    sensitivity: 'base'
                });
            };

            const sortedVideoEntries = videoEntries.sort(apacheSort);
            const sortedAudioEntries = audioEntries.sort(apacheSort);

            const sortedEntries = [...sortedVideoEntries, ...sortedAudioEntries];

            sortedEntries.forEach(entry => {
                content += `#EXTINF:-1,${entry.decodedTitle}\n${entry.url}\n`;
            });

            return content;
        }

        addLogEntry(message, type = '') {
            if ((this.state.isPaused || !this.state.isGenerating) && type !== 'final') {
                return;
            }

            let decodedMessage = message;
            try {
                if (message.includes('http')) {
                    const urlRegex = /(https?:\/\/[^\s]+)/g;
                    decodedMessage = message.replace(urlRegex, (url) => {
                        try {
                            return decodeURIComponent(url);
                        } catch (e) {
                            return url;
                        }
                    });
                }
            } catch (error) {
                console.warn('Decode error:', error);
            }

            // Add only to cache
            this.logCache.add(decodedMessage, type);

            // Update UI every 10 logs
            if (this.logCache.stats.totalLogs % 10 === 0) {
                this.updateLogUI();
            }
        }

        updateLogUI() {
            const scanLog = this.domElements.scanLog;
            if (!scanLog) return;

            // Add throttle for performance
            if (this._updateLogUITimeout) {
                clearTimeout(this._updateLogUITimeout);
            }

            this._updateLogUITimeout = setTimeout(() => {
                requestAnimationFrame(() => {
                    const wasAtBottom = Math.abs(scanLog.scrollHeight - scanLog.clientHeight - scanLog.scrollTop) < 50;
                    
                    // Use fragment to minimize DOM manipulation
                    const fragment = document.createDocumentFragment();
                    
                    // Show last 50 logs (instead of 100)
                    const recentLogs = this.logCache.logs.slice(-50);
                    
                    recentLogs.forEach(log => {
                        const div = document.createElement('div');
                        div.className = `M3Unator-log-entry ${log.type}`;
                        div.innerHTML = `
                            <span class="M3Unator-log-time">${log.timestamp}</span>
                            <span class="M3Unator-log-content">${log.message}</span>
                        `;
                        fragment.appendChild(div);
                    });

                    scanLog.innerHTML = '';
                    scanLog.appendChild(fragment);

                    if (wasAtBottom) {
                        scanLog.scrollTop = scanLog.scrollHeight;
                    }
                });
            }, 100); // 100ms throttle
        }

        generateScanReport() {
            const stats = this.state.stats;
            const logCache = this.logCache;
            
            const summary = [
                `📊 Scan Summary`,
                `───────────────`,
                `📁 Total Files: ${stats.totalFiles}`,
                `🎥 Video Files: ${stats.files.video.total}`,
                `🎵 Audio Files: ${stats.files.audio.total}`,
                `📂 Directories: ${stats.directories.total}`,
                `↕️ Maximum Depth: ${stats.directories.depth}`,
                stats.errors.total > 0 ? 
                    `⚠️ Errors: ${stats.errors.total} (${stats.errors.skipped} skipped)` : 
                    null,
                ``,
                `📝 Log Statistics`,
                `───────────────`,
                `Total Logs: ${logCache.stats.totalLogs}`,
                logCache.stats.skippedLogs > 0 ? 
                    `Skipped Logs: ${logCache.stats.skippedLogs}` :
                    null,
                ``,
                `🔍 Last ${logCache.maxSize} Log Entries`,
                `───────────────`,
                ...logCache.logs.map(log => 
                    `[${log.timestamp}] ${log.type === 'error' ? '❌' : 
                                       log.type === 'warning' ? '⚠️' : 
                                       log.type === 'success' ? '✅' : 'ℹ️'} ${log.message}`)
            ].filter(Boolean).join('\n');

            return summary;
        }

        updateCounter(count) {
            if (!this.domElements.stats || !this.domElements.statsBar) {
                return;
            }

            const stats = this.state.stats;
            const elements = this.domElements.stats;
            const statsBar = this.domElements.statsBar;

            statsBar.style.display = 'block';
            
            const updates = {
                'totalFiles': count,
                'videoFiles': stats.files.video.total,
                'audioFiles': stats.files.audio.total,
                'directories': stats.directories.total,
                'depthLevel': stats.directories.depth,
                'errors': stats.errors.total
            };

            Object.entries(updates).forEach(([key, value]) => {
                const element = elements[key];
                if (element) {
                    element.textContent = value;
                    
                    const statContainer = element.closest('.M3Unator-stat');
                    if (statContainer) {
                        statContainer.style.opacity = value > 0 ? '1' : '0.5';
                        
                        if (key === 'depthLevel') {
                            const maxDepth = this.state.maxDepth || 0;
                            if (maxDepth > 0) {
                                const progress = (value / maxDepth) * 100;
                                statContainer.dataset.progress = 
                                    progress >= 100 ? 'high' :
                                    progress >= 75 ? 'medium' :
                                    progress >= 50 ? 'low' : '';
                                
                                statContainer.title = `Depth Level: ${value}/${maxDepth}`;
                            } else {
                                statContainer.dataset.progress = '';
                                statContainer.title = `Depth Level: ${value}`;
                            }
                        }
                    }
                }
            });
        }

        // Add new method for file type checking
        isMediaFileOptimized(fileName) {
            const extension = fileName.toLowerCase().split('.').pop();
            return this.extensionMap.get(extension);
        }
    }

    const generator = new PlaylistGenerator();
    generator.init();

    // Event listeners for info modal
    document.querySelector('.info-link').addEventListener('click', () => {
        document.querySelector('.info-modal').style.display = 'block';
        document.body.classList.add('modal-open');
    });

    document.querySelector('.info-close').addEventListener('click', () => {
        document.querySelector('.info-modal').style.display = 'none';
        document.body.classList.remove('modal-open');
    });

    window.addEventListener('click', (event) => {
        const modal = document.querySelector('.info-modal');
        if (event.target === modal) {
            modal.style.display = 'none';
            document.body.classList.remove('modal-open');
        }
    });

    // Event listener for playlist name input
    generator.domElements.playlistInput.addEventListener('input', (e) => {
        const dropdown = e.target.parentElement.querySelector('.M3Unator-dropdown');
        if (e.target.value.trim()) {
            dropdown.style.display = 'block';
        } else {
            dropdown.style.display = 'none';
        }
    });
})();