WatchPorn Auto Filter Preset Manager

Visually select categories, save presets with file download/upload, glassmorphism UI theme, auto-remove promotional headers, seamless home page integration

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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

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

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         WatchPorn Auto Filter Preset Manager
// @namespace    http://tampermonkey.net/
// @version      1.5
// @description  Visually select categories, save presets with file download/upload, glassmorphism UI theme, auto-remove promotional headers, seamless home page integration
// @author       6969RandomGuy6969
// @match        https://watchporn.to/*
// @icon         https://t2.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=https://watchporn.to/&size=256
// @grant        GM_registerMenuCommand
// ==/UserScript==

(function () {
    'use strict';

    const STORAGE_KEY = 'wp_saved_presets';
    const FAVORITES_KEY = 'wp_favorite_categories';
    const ACTIVE_PRESET_KEY = 'wp_active_preset';

    let filterButton = null;
    let categoryCheckboxes = [];

    // Determine if we're on search page or home page
    const isSearchPage = window.location.pathname.includes('/search/');
    const isHomePage = window.location.pathname === '/' || window.location.pathname === '';

    // Home Page Integration - Seamless Button Replacement
    if (isHomePage) {
        const CONFIG = {
            buttonText: "Filter Preset",
            searchUrl: "https://watchporn.to/search/",
            fallbackSelectors: [
                'a[href*="go.lnkpth.com"]',
                'a[href*="hotdates"]',
                'a[href*="dates"]',
                '.promo-link',
                '.affiliate-link'
            ]
        };

        // Inject seamless styles immediately
        function injectHomePageStyles() {
            if (document.getElementById('home-filter-styles')) return;

            const styleSheet = document.createElement('style');
            styleSheet.id = 'home-filter-styles';
            styleSheet.textContent = `
                .filter-preset-btn {
                    background: rgba(255, 255, 255, 0.1) !important;
                    backdrop-filter: blur(10px) !important;
                    border: 1px solid rgba(255, 255, 255, 0.2) !important;
                    border-radius: 8px !important;
                    padding: 8px 16px !important;
                    color: #fff !important;
                    text-decoration: none !important;
                    transition: all 0.3s ease !important;
                    font-weight: 500 !important;
                    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2) !important;
                    display: inline-block !important;
                }

                .filter-preset-btn:hover {
                    background: rgba(255, 255, 255, 0.2) !important;
                    transform: translateY(-2px) !important;
                    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3) !important;
                }

                .filter-preset-container {
                    opacity: 0;
                    animation: fadeInSmooth 0.5s ease-in-out forwards;
                }

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

                .promo-hiding {
                    opacity: 0 !important;
                    transition: opacity 0.2s ease-out !important;
                }
            `;
            (document.head || document.documentElement).appendChild(styleSheet);
        }

        function findPromoTarget() {
            // Try specific selector first
            let target = document.querySelector('a[href^="https://go.lnkpth.com/aff_f?h=SEJeqF"]');
            if (target) return target;

            // Try fallback selectors
            for (const selector of CONFIG.fallbackSelectors) {
                target = document.querySelector(selector);
                if (target) return target;
            }

            // Try finding by text content
            const links = document.querySelectorAll('a');
            for (const link of links) {
                const text = link.textContent.toLowerCase();
                if (text.includes('hot dates') || text.includes('dates') || text.includes('❤️')) {
                    return link;
                }
            }

            return null;
        }

        function createFallbackHomeButton() {
            const container = document.createElement('div');
            container.className = 'filter-preset-container';
            container.style.cssText = `
                position: fixed;
                top: 20px;
                right: 20px;
                z-index: 10000;
            `;

            const button = document.createElement('a');
            button.href = CONFIG.searchUrl;
            button.target = '_self';
            button.textContent = CONFIG.buttonText;
            button.className = 'filter-preset-btn';

            container.appendChild(button);
            document.body.appendChild(container);

            return button;
        }

        function replacePromoTarget(target) {
            target.classList.add('promo-hiding');

            setTimeout(() => {
                const container = document.createElement('div');
                container.className = 'filter-preset-container';

                const newButton = target.cloneNode(true);
                newButton.textContent = CONFIG.buttonText;
                newButton.href = CONFIG.searchUrl;
                newButton.target = '_self';
                newButton.className = (newButton.className || '') + ' filter-preset-btn';
                newButton.classList.remove('promo-hiding');

                container.appendChild(newButton);
                target.parentNode.replaceChild(container, target);

                console.log('✅ Filter Preset button created on home page');
            }, 200);
        }

function initHomePage() {
    injectHomePageStyles();

    // --- Add Filter Preset button next to Home link (NEW, standalone) ---
    const homeLinkLi = document.querySelector('a#item1')?.parentElement;
    if (homeLinkLi && !document.querySelector('#filter-preset-li')) {
        const li = document.createElement('li');
        li.id = 'filter-preset-li';

        const button = document.createElement('a');
        button.href = CONFIG.searchUrl;
        button.textContent = CONFIG.buttonText;
        button.className = 'filter-preset-btn';
        button.style.cursor = 'pointer';

        li.appendChild(button);
        homeLinkLi.parentNode.insertBefore(li, homeLinkLi.nextSibling);

        console.log('✅ Filter Preset button added next to Home link (independent)');

    }
}


        // Initialize home page functionality
        function homePageReady(fn) {
            if (document.readyState === 'loading') {
                document.addEventListener('DOMContentLoaded', fn);
            } else {
                fn();
            }
        }

        homePageReady(() => {
            initHomePage();

            // Watch for dynamic content changes
            const observer = new MutationObserver((mutations) => {
                let shouldReinit = false;

                mutations.forEach((mutation) => {
                    if (mutation.type === 'childList') {
                        mutation.addedNodes.forEach((node) => {
                            if (node.nodeType === 1) {
                                const hasPromoLink = node.querySelector && (
                                    node.querySelector('a[href*="go.lnkpth.com"]') ||
                                    node.querySelector('a[href*="hotdates"]')
                                );
                                if (hasPromoLink) shouldReinit = true;
                            }
                        });
                    }
                });

                if (shouldReinit && !document.querySelector('.filter-preset-btn')) {
                    setTimeout(initHomePage, 100);
                }
            });

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

        // Backup initialization
        setTimeout(() => {
            if (!document.querySelector('.filter-preset-btn')) {
                console.log('🔄 Home page backup initialization triggered');
                initHomePage();
            }
        }, 2000);
    }

    // Search Page Functionality - Original Script
    if (isSearchPage) {
        // Function to remove promotional headers
        function removePromotionalHeaders() {
            const h1Elements = document.querySelectorAll('h1');
            h1Elements.forEach(h1 => {
                const text = h1.textContent.trim();
                if (text.toLowerCase().includes('videos in') && text.includes(',')) {
                    console.log('Removing promotional header:', text.substring(0, 50) + '...');
                    h1.remove();
                }
            });
        }

        function downloadFile(content, filename) {
            const blob = new Blob([content], { type: 'text/plain' });
            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);
        }

        function waitForCategories(callback) {
            const checkExist = setInterval(() => {
                const categories = document.querySelectorAll('input[id^="category_filter_"]');
                if (categories.length > 0) {
                    clearInterval(checkExist);
                    callback();
                }
            }, 200);
            setTimeout(() => clearInterval(checkExist), 10000);
        }

        function applyCategories(ids) {
            const checkboxes = document.querySelectorAll('input[id^="category_filter_"]');
            checkboxes.forEach(cb => {
                const shouldBeChecked = ids.includes(cb.id);
                if (cb.checked !== shouldBeChecked) cb.click();
            });
            requestAnimationFrame(() => triggerAjaxUpdate(ids));
        }

        function triggerAjaxUpdate(categoryIds = null) {
            let categoryParam = '';
            if (categoryIds) {
                categoryParam = categoryIds.map(id => id.replace('category_filter_', '')).join(',');
            } else {
                const checkedBoxes = document.querySelectorAll('input[id^="category_filter_"]:checked');
                categoryParam = Array.from(checkedBoxes).map(cb => cb.id.replace('category_filter_', '')).join(',');
            }

            const urlParams = new URLSearchParams(window.location.search);
            const query = urlParams.get('q') || '';
            const currentSort = document.querySelector('.sort strong')?.textContent || 'Most Relevant';

            let sortParam = 'relevance';
            if (currentSort.includes('Latest')) sortParam = 'post_date';
            else if (currentSort.includes('Most Viewed')) sortParam = 'video_viewed';
            else if (currentSort.includes('Top Rated')) sortParam = 'rating';
            else if (currentSort.includes('Longest')) sortParam = 'duration';
            else if (currentSort.includes('Most Commented')) sortParam = 'most_commented';
            else if (currentSort.includes('Most Favorited')) sortParam = 'most_favourited';

            const params = `q:${query};category_ids:${categoryParam};sort_by:${sortParam}`;
            const existingSortLink = document.querySelector('a[data-action="ajax"]');

            if (existingSortLink) {
                const tempLink = existingSortLink.cloneNode(true);
                tempLink.setAttribute('data-parameters', params);
                if (window.jQuery && typeof window.jQuery.fn.click === 'function') {
                    window.jQuery(tempLink).click();
                } else {
                    document.querySelector('form[action*="filter"] button[type="submit"]')?.click();
                }
            } else {
                document.querySelector('form[action*="filter"] button[type="submit"]')?.click();
            }

            setTimeout(() => {
                removePromotionalHeaders();
            }, 500);
        }

        function createFilterButton() {
            if (filterButton) return;

            const sortDiv = document.querySelector('.sort');
            if (!sortDiv) return;

            const filterDropdown = document.createElement('div');
            filterDropdown.className = 'wp-filter-dropdown';
            filterDropdown.innerHTML = `<div class="sort"><span></span><strong>Filters</strong></div>`;

            filterDropdown.querySelector('.sort').addEventListener('click', (e) => {
                e.preventDefault();
                e.stopPropagation();
                categoryCheckboxes = Array.from(document.querySelectorAll('input[id^="category_filter_"]'));
                if (categoryCheckboxes.length > 0) createUI(categoryCheckboxes);
            });

            sortDiv.parentNode.insertBefore(filterDropdown, sortDiv);
            filterButton = filterDropdown;

            if (!document.getElementById('wp-persistent-styles')) {
                const style = document.createElement('style');
                style.id = 'wp-persistent-styles';
                style.textContent = `.wp-filter-dropdown{position:relative;display:inline-block;margin-right:10px}.wp-filter-dropdown .sort{position:relative;border-radius:15px;background-color:#212121;color:#fff;font-size:12px;font-weight:500;letter-spacing:0.3px;padding:8px 10px;margin:0 15px 0 0;min-width:140px;transition:background-color 0.3s,border-radius 0.3s;cursor:pointer}.wp-filter-dropdown .sort:hover{background-color:#276fdb}`;
                document.head.appendChild(style);
            }
        }

        function createUI(categoryCheckboxes) {
            const presets = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
            const favorites = JSON.parse(localStorage.getItem(FAVORITES_KEY) || '[]');
            let activePreset = localStorage.getItem(ACTIVE_PRESET_KEY) || '';

            document.querySelector('.wp-overlay')?.remove();

            function showCustomAlert(message) {
                const alertOverlay = document.createElement('div');
                alertOverlay.className = 'wp-custom-dialog-overlay';
                alertOverlay.innerHTML = `
                    <div class="wp-custom-dialog">
                        <div class="wp-dialog-header"></div>
                        <div class="wp-dialog-message">${message}</div>
                        <div class="wp-dialog-buttons">
                            <button class="wp-dialog-btn wp-dialog-ok">OK</button>
                        </div>
                    </div>
                `;
                document.body.appendChild(alertOverlay);
                setTimeout(() => alertOverlay.classList.add('show'), 10);

                alertOverlay.querySelector('.wp-dialog-ok').addEventListener('click', () => {
                    alertOverlay.classList.remove('show');
                    setTimeout(() => alertOverlay.remove(), 300);
                });
            }

            function showCustomConfirm(message, callback) {
                const confirmOverlay = document.createElement('div');
                confirmOverlay.className = 'wp-custom-dialog-overlay';
                confirmOverlay.innerHTML = `
                    <div class="wp-custom-dialog">
                        <div class="wp-dialog-header">Confirm</div>
                        <div class="wp-dialog-message">${message}</div>
                        <div class="wp-dialog-buttons">
                            <button class="wp-dialog-btn wp-dialog-cancel">Cancel</button>
                            <button class="wp-dialog-btn wp-dialog-confirm">Confirm</button>
                        </div>
                    </div>
                `;
                document.body.appendChild(confirmOverlay);
                setTimeout(() => confirmOverlay.classList.add('show'), 10);

                confirmOverlay.querySelector('.wp-dialog-cancel').addEventListener('click', () => {
                    confirmOverlay.classList.remove('show');
                    setTimeout(() => confirmOverlay.remove(), 300);
                    callback(false);
                });

                confirmOverlay.querySelector('.wp-dialog-confirm').addEventListener('click', () => {
                    confirmOverlay.classList.remove('show');
                    setTimeout(() => confirmOverlay.remove(), 300);
                    callback(true);
                });
            }

            function showCustomPrompt(message, callback, defaultValue = '') {
                const promptOverlay = document.createElement('div');
                promptOverlay.className = 'wp-custom-dialog-overlay';
                promptOverlay.innerHTML = `
                    <div class="wp-custom-dialog">
                        <div class="wp-dialog-header"></div>
                        <div class="wp-dialog-message">${message}</div>
                        <input type="text" class="wp-dialog-input" value="${defaultValue}" placeholder="Enter value...">
                        <div class="wp-dialog-buttons">
                            <button class="wp-dialog-btn wp-dialog-cancel">Cancel</button>
                            <button class="wp-dialog-btn wp-dialog-ok">OK</button>
                        </div>
                    </div>
                `;
                document.body.appendChild(promptOverlay);
                setTimeout(() => promptOverlay.classList.add('show'), 10);

                const input = promptOverlay.querySelector('.wp-dialog-input');
                input.focus();
                input.select();

                const handleOk = () => {
                    const value = input.value.trim();
                    promptOverlay.classList.remove('show');
                    setTimeout(() => promptOverlay.remove(), 300);
                    callback(value || null);
                };

                const handleCancel = () => {
                    promptOverlay.classList.remove('show');
                    setTimeout(() => promptOverlay.remove(), 300);
                    callback(null);
                };

                promptOverlay.querySelector('.wp-dialog-ok').addEventListener('click', handleOk);
                promptOverlay.querySelector('.wp-dialog-cancel').addEventListener('click', handleCancel);
                input.addEventListener('keypress', (e) => {
                    if (e.key === 'Enter') handleOk();
                    if (e.key === 'Escape') handleCancel();
                });
            }

            const style = document.createElement('style');
            style.textContent = `.wp-overlay{position:fixed;top:0;left:0;right:0;bottom:0;backdrop-filter:blur(10px);background:rgba(0,0,0,0.3);display:flex;align-items:center;justify-content:center;z-index:9999;opacity:0;transition:opacity 0.3s ease}.wp-overlay.show{opacity:1}.wp-panel{background:rgba(20,20,20,0.95);border:1px solid rgba(255,255,255,0.1);color:#e0e0e0;border-radius:12px;padding:24px;width:580px;max-height:80vh;display:flex;flex-direction:column;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;font-size:14px;box-shadow:0 20px 40px rgba(0,0,0,0.6);transform:translateY(20px);transition:transform 0.3s ease}.wp-overlay.show .wp-panel{transform:translateY(0)}.wp-panel button,.wp-panel select,.wp-panel input[type="text"]{border:1px solid rgba(255,255,255,0.15);border-radius:6px;padding:8px 12px;margin:3px 0;cursor:pointer;background:rgba(40,40,40,0.8);color:#e0e0e0;transition:all 0.2s ease;font-size:13px;font-weight:400;outline:none}.wp-panel button:hover{background:rgba(60,60,60,0.9);border-color:rgba(255,255,255,0.25)}.wp-panel button:active{transform:translateY(1px)}.wp-panel select:hover,.wp-panel input[type="text"]:hover{background:rgba(50,50,50,0.9);border-color:rgba(255,255,255,0.2)}.wp-panel input[type="text"]:focus,.wp-panel select:focus{background:rgba(50,50,50,0.95);border-color:rgba(100,150,200,0.6);box-shadow:0 0 0 2px rgba(100,150,200,0.2)}.wp-panel label{display:flex;align-items:center;margin-bottom:4px;padding:6px 8px;border-radius:4px;transition:background 0.15s ease;cursor:pointer;font-size:13px;width:calc(50% - 4px);box-sizing:border-box}.wp-panel label:hover{background:rgba(255,255,255,0.05)}.wp-panel input[type="checkbox"]{margin-right:10px;accent-color:#4A90E2}.wp-list{overflow-y:auto;max-height:280px;margin:12px 0;border:1px solid rgba(255,255,255,0.1);border-radius:8px;background:rgba(0,0,0,0.4);padding:12px}.wp-list::-webkit-scrollbar{width:6px}.wp-list::-webkit-scrollbar-thumb{background:rgba(255,255,255,0.2);border-radius:3px}.wp-list::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,0.3)}.wp-list::-webkit-scrollbar-track{background:transparent}.wp-categories-grid{display:flex;flex-wrap:wrap;gap:4px;justify-content:space-between}.wp-footer{display:flex;justify-content:space-between;margin-top:auto;padding-top:16px;border-top:1px solid rgba(255,255,255,0.1);gap:8px}.wp-search-container{display:flex;gap:8px;margin-bottom:12px}.wp-search-input{flex:1;margin:0!important}.wp-select-visible-btn{white-space:nowrap;margin:0!important;color:#ffffff!important}.wp-preset-controls{display:flex;justify-content:space-between;margin-bottom:12px;gap:6px}.wp-preset-controls button{flex:1;margin:0;font-size:12px;padding:6px 8px}.wp-header{font-size:18px;font-weight:600;margin-bottom:18px;text-align:center;color:#ffffff}.wp-download-btn{position:relative!important;overflow:visible!important}.wp-download-btn:before{content:'';z-index:-1;position:absolute;display:block;width:110%;height:125%;top:-12.5%;left:-5%;transition:0.3s opacity ease-in-out;filter:blur(10px);opacity:0;background:linear-gradient(60deg,#f79533,#f37055,#ef4e7b,#a166ab,#5073b8,#1098ad,#07b39b,#6fba82)}.wp-download-btn:hover:before{opacity:1!important;transition:0.3s opacity ease-in-out;filter:blur(15px);background:linear-gradient(60deg,#f79533,#f37055,#ef4e7b,#a166ab,#5073b8,#1098ad,#07b39b,#6fba82)!important}.wp-custom-dialog-overlay{position:fixed;top:0;left:0;right:0;bottom:0;backdrop-filter:blur(10px);background:rgba(0,0,0,0.4);display:flex;align-items:center;justify-content:center;z-index:10000;opacity:0;transition:opacity 0.3s ease}.wp-custom-dialog-overlay.show{opacity:1}.wp-custom-dialog{background:rgba(20,20,20,0.95);border:1px solid rgba(255,255,255,0.1);color:#e0e0e0;border-radius:12px;padding:24px;width:400px;max-width:90vw;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;box-shadow:0 20px 40px rgba(0,0,0,0.6);transform:translateY(20px);transition:transform 0.3s ease}.wp-custom-dialog-overlay.show .wp-custom-dialog{transform:translateY(0)}.wp-dialog-header{font-size:18px;font-weight:600;margin-bottom:16px;text-align:center;color:#ffffff}.wp-dialog-message{margin-bottom:20px;line-height:1.5;color:#e0e0e0;white-space:pre-line}.wp-dialog-input{width:100%;border:1px solid rgba(255,255,255,0.15);border-radius:6px;padding:8px 12px;margin:16px 0;background:rgba(40,40,40,0.8);color:#e0e0e0;font-size:14px;outline:none;box-sizing:border-box}.wp-dialog-input:focus{background:rgba(50,50,50,0.95);border-color:rgba(100,150,200,0.6);box-shadow:0 0 0 2px rgba(100,150,200,0.2)}.wp-dialog-buttons{display:flex;gap:10px;justify-content:flex-end}.wp-dialog-btn{border:1px solid rgba(255,255,255,0.15);border-radius:6px;padding:8px 16px;cursor:pointer;background:rgba(40,40,40,0.8);color:#e0e0e0;transition:all 0.2s ease;font-size:13px;font-weight:400;outline:none}.wp-dialog-btn:hover{background:rgba(60,60,60,0.9);border-color:rgba(255,255,255,0.25)}.wp-dialog-btn:active{transform:translateY(1px)}.wp-dialog-confirm{background:rgba(70,130,200,0.8)!important}.wp-dialog-confirm:hover{background:rgba(70,130,200,1)!important}`;
            document.head.appendChild(style);

            const overlay = document.createElement('div');
            overlay.className = 'wp-overlay';
            overlay.innerHTML = `
                <div class="wp-panel">
                    <div class="wp-header">WatchPorn Filter Manager</div>
                    <div class="wp-search-container">
                        <input type="text" placeholder="Search categories..." class="wp-search-input">
                        <button class="wp-select-visible-btn">Select All Visible</button>
                    </div>
                    <select class="wp-preset-select">
                        <option value="">Select a preset...</option>
                    </select>
                    <div class="wp-preset-controls">
                        <button class="wp-save-btn">Save</button>
                        <button class="wp-export-btn">Export</button>
                        <button class="wp-import-btn">Import</button>
                        <button class="wp-delete-btn">Delete</button>
                    </div>
                    <div class="wp-list">
                        <div class="wp-categories-grid"></div>
                    </div>
                    <div class="wp-footer">
                        <button class="wp-uncheck-btn">Uncheck All</button>
                        <button class="wp-download-btn">Download Auto Preview</button>
                        <button class="wp-close-btn">Close</button>
                    </div>
                </div>
            `;

            const panel = overlay.querySelector('.wp-panel');
            const searchInput = panel.querySelector('.wp-search-input');
            const presetSelect = panel.querySelector('.wp-preset-select');
            const form = panel.querySelector('.wp-categories-grid');

            let searchTimeout;

            function rebuildPresetSelect() {
                const currentPresets = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
                presetSelect.innerHTML = '<option value="">Select a preset...</option>';
                Object.keys(currentPresets).forEach(name => {
                    const opt = document.createElement('option');
                    opt.value = name;
                    opt.textContent = name;
                    if (name === activePreset) opt.selected = true;
                    presetSelect.appendChild(opt);
                });
            }

            function buildCategoryList() {
                const sorted = categoryCheckboxes.slice().sort((a, b) =>
                    (favorites.includes(b.id) - favorites.includes(a.id)) || (b.checked - a.checked)
                );

                form.innerHTML = '';
                const fragment = document.createDocumentFragment();

                sorted.forEach(checkbox => {
                    const labelText = checkbox.nextElementSibling?.textContent.trim() ||
                                    checkbox.id.replace('category_filter_', '');

                    const container = document.createElement('label');
                    container.innerHTML = `
                        <input type="checkbox" value="${checkbox.id}" ${checkbox.checked ? 'checked' : ''}>
                        <span>${labelText}</span>
                    `;

                    const cb = container.querySelector('input');
                    cb.addEventListener('change', () => {
                        const target = document.getElementById(cb.value);
                        if (target && target.checked !== cb.checked) target.click();
                        requestAnimationFrame(() => triggerAjaxUpdate());
                    });

                    fragment.appendChild(container);
                });
                form.appendChild(fragment);
            }

            rebuildPresetSelect();
            buildCategoryList();

            // All event listeners from original script...
            panel.querySelector('.wp-select-visible-btn').addEventListener('click', () => {
                form.querySelectorAll('label').forEach(label => {
                    if (label.style.display !== 'none') {
                        const cb = label.querySelector('input[type="checkbox"]');
                        if (cb && !cb.checked) cb.click();
                    }
                });
            });

            panel.querySelector('.wp-save-btn').addEventListener('click', () => {
                showCustomPrompt('Enter preset name:', (presetName) => {
                    if (presetName?.trim()) {
                        const currentPresets = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
                        const selected = Array.from(form.querySelectorAll('input[type="checkbox"]:checked')).map(cb => cb.value);
                        currentPresets[presetName.trim()] = selected;
                        localStorage.setItem(STORAGE_KEY, JSON.stringify(currentPresets));
                        activePreset = presetName.trim();
                        localStorage.setItem(ACTIVE_PRESET_KEY, activePreset);
                        rebuildPresetSelect();
                        presetSelect.value = activePreset;
                        showCustomAlert(`Preset "${presetName.trim()}" saved successfully!`);
                    }
                });
            });

            panel.querySelector('.wp-export-btn').addEventListener('click', () => {
                const name = presetSelect.value;
                if (!name) {
                    showCustomAlert('Please select a preset to export.');
                    return;
                }
                const currentPresets = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
                if (currentPresets[name]) {
                    const exportData = {
                        name, categories: currentPresets[name], version: '2.0',
                        exportDate: new Date().toISOString()
                    };
                    const filename = `watchporn_preset_${name.replace(/[^a-zA-Z0-9]/g, '_')}.txt`;
                    downloadFile(JSON.stringify(exportData, null, 2), filename);
                    showCustomAlert(`Preset "${name}" exported successfully!\nFile: ${filename}`);
                }
            });

            panel.querySelector('.wp-import-btn').addEventListener('click', () => {
                const input = document.createElement('input');
                input.type = 'file';
                input.accept = '.txt';
                input.style.display = 'none';
                input.addEventListener('change', (event) => {
                    const file = event.target.files[0];
                    if (!file) return;
                    const reader = new FileReader();
                    reader.onload = (e) => {
                        try {
                            const importData = JSON.parse(e.target.result);
                            if (!importData.name || !importData.categories || !Array.isArray(importData.categories)) {
                                throw new Error('Invalid preset data');
                            }
                            const currentPresets = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
                            let importName = importData.name;
                            if (currentPresets[importName]) {
                                showCustomPrompt(`Preset "${importName}" already exists. Enter a new name:`, (newName) => {
                                    if (!newName) return;
                                    importName = newName;
                                    processImport();
                                }, importName + '_imported');
                            } else {
                                processImport();
                            }

                            function processImport() {
                                const validCategories = importData.categories.filter(id => document.getElementById(id));
                                if (validCategories.length === 0) {
                                    showCustomAlert('No valid categories found in this preset for the current page.');
                                    return;
                                }
                                if (validCategories.length < importData.categories.length) {
                                    const missing = importData.categories.length - validCategories.length;
                                    showCustomConfirm(`${missing} categories from this preset are not available on this page. Import anyway with ${validCategories.length} categories?`, (confirmed) => {
                                        if (confirmed) finishImport();
                                    });
                                } else {
                                    finishImport();
                                }

                                function finishImport() {
                                    currentPresets[importName] = validCategories;
                                    localStorage.setItem(STORAGE_KEY, JSON.stringify(currentPresets));
                                    localStorage.setItem(ACTIVE_PRESET_KEY, importName);
                                    activePreset = importName;
                                    rebuildPresetSelect();
                                    presetSelect.value = activePreset;
                                    buildCategoryList();
                                    applyCategories(validCategories);
                                    showCustomAlert(`Preset "${importName}" imported and applied successfully with ${validCategories.length} categories!`);
                                }
                            }
                        } catch (error) {
                            showCustomAlert('Invalid preset file. Please check the file and try again.\nError: ' + error.message);
                        }
                    };
                    reader.readAsText(file);
                });
                document.body.appendChild(input);
                input.click();
                document.body.removeChild(input);
            });

            panel.querySelector('.wp-delete-btn').addEventListener('click', () => {
                const name = presetSelect.value;
                if (name) {
                    showCustomConfirm(`Delete preset "${name}"? This action cannot be undone.`, (confirmed) => {
                        if (confirmed) {
                            const currentPresets = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
                            delete currentPresets[name];
                            localStorage.setItem(STORAGE_KEY, JSON.stringify(currentPresets));
                            if (activePreset === name) {
                                activePreset = '';
                                localStorage.setItem(ACTIVE_PRESET_KEY, activePreset);
                            }
                            rebuildPresetSelect();
                            presetSelect.value = '';
                            showCustomAlert(`Preset "${name}" deleted successfully!`);
                        }
                    });
                } else {
                    showCustomAlert('Please select a preset to delete.');
                }
            });

            presetSelect.addEventListener('change', () => {
                const name = presetSelect.value;
                activePreset = name;
                localStorage.setItem(ACTIVE_PRESET_KEY, activePreset);
                if (name) {
                    const currentPresets = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
                    if (currentPresets[name]) {
                        form.querySelectorAll('input[type="checkbox"]').forEach(cb => cb.checked = false);
                        currentPresets[name].forEach(id => {
                            const formCheckbox = form.querySelector(`input[value="${id}"]`);
                            if (formCheckbox) formCheckbox.checked = true;
                        });
                        applyCategories(currentPresets[name]);
                    }
                }
            });

            panel.querySelector('.wp-uncheck-btn').addEventListener('click', () => {
                form.querySelectorAll('input[type="checkbox"]').forEach(cb => {
                    if (cb.checked) cb.click();
                });
            });

            panel.querySelector('.wp-download-btn').addEventListener('click', () => {
                const scriptUrl = 'https://update.sleazyfork.org/scripts/534164/Auto-play%20video%20thumbnails%20for%20sxyprn%2C%20watchporn%2C%20yesporn%2C%20theyarehuge.user.js';
                const tempLink = document.createElement('a');
                tempLink.href = scriptUrl;
                tempLink.download = 'auto-preview-script.user.js';
                tempLink.target = '_blank';
                document.body.appendChild(tempLink);
                tempLink.click();
                document.body.removeChild(tempLink);
                setTimeout(() => {
                    showCustomAlert('Auto Preview script download initiated!\n\nIf the download didn\'t start automatically, the script will open in a new tab.');
                }, 500);
            });

            panel.querySelector('.wp-close-btn').addEventListener('click', () => {
                overlay.classList.remove('show');
                setTimeout(() => overlay.remove(), 300);
            });

            searchInput.addEventListener('input', () => {
                clearTimeout(searchTimeout);
                searchTimeout = setTimeout(() => {
                    const term = searchInput.value.toLowerCase();
                    form.querySelectorAll('label').forEach(label => {
                        const text = label.textContent.toLowerCase();
                        label.style.display = text.includes(term) ? 'flex' : 'none';
                    });
                }, 150);
            });

            document.body.appendChild(overlay);
            setTimeout(() => overlay.classList.add('show'), 10);

            // Auto-apply active preset if exists
            if (activePreset) {
                const currentPresets = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
                if (currentPresets[activePreset]) {
                    setTimeout(() => applyCategories(currentPresets[activePreset]), 1000);
                }
            }
        }

        // Enhanced initialization for search page
        function initializeSearchPage() {
            removePromotionalHeaders();

            waitForCategories(() => {
                const allCheckboxes = Array.from(document.querySelectorAll('input[id^="category_filter_"]'));
                if (allCheckboxes.length > 0) {
                    categoryCheckboxes = allCheckboxes;
                    createFilterButton();

                    // Re-create button on page changes (AJAX updates)
                    const observer = new MutationObserver((mutations) => {
                        mutations.forEach((mutation) => {
                            if (mutation.addedNodes.length > 0) {
                                // Check if sort elements were added/changed
                                const hasSortElements = Array.from(mutation.addedNodes).some(node =>
                                    node.nodeType === 1 && (node.querySelector?.('.sort') || node.classList?.contains('sort'))
                                );
                                if (hasSortElements && !document.querySelector('.wp-filter-dropdown')) {
                                    setTimeout(() => {
                                        filterButton = null; // Reset reference
                                        createFilterButton();
                                    }, 100);
                                }

                                // Check for new promotional headers and remove them
                                const hasNewHeaders = Array.from(mutation.addedNodes).some(node =>
                                    node.nodeType === 1 && (node.tagName === 'H1' || node.querySelector?.('h1'))
                                );
                                if (hasNewHeaders) {
                                    setTimeout(removePromotionalHeaders, 100);
                                }
                            }
                        });
                    });

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

            // Set up periodic cleanup for promotional headers
            setInterval(removePromotionalHeaders, 2000);
        }

        // Initialize search page when ready
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', initializeSearchPage);
        } else {
            initializeSearchPage();
        }
    }

    // Universal initialization for any page not specifically handled
    if (!isSearchPage && !isHomePage) {
        console.log('🔧 WatchPorn Filter Manager loaded on:', window.location.pathname);
    }

})();