Facebook Activity Auto Deleter (2025) - Optimized

Fast and efficient Facebook activity log cleaner with improved item detection and progressive skipping.

질문, 리뷰하거나, 이 스크립트를 신고하세요.
// ==UserScript==
// @name         Facebook Activity Auto Deleter (2025) - Optimized
// @namespace    https://greasyfork.org/en/users/1454546-shawnfrost13
// @version      5.03
// @description  Fast and efficient Facebook activity log cleaner with improved item detection and progressive skipping.
// @author       shawnfrost13 (optimized by Claude)
// @license      MIT
// @match        https://www.facebook.com/*/allactivity*
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function () {
    'use strict';

    // ===== CONFIGURATION =====
    const CONFIG = {
        // Delays (in ms)
        menuClickDelay: 300,      // Time to wait after clicking menu button
        deleteClickDelay: 300,    // Time to wait after clicking delete option
        betweenItemsDelay: 800,   // Random base delay between deletion attempts
        randomDelayMax: 400,      // Additional random delay to avoid detection
        errorCheckDelay: 800,     // How long to wait to check for errors (increased)
        scrollDelay: 1500,        // How long to wait after scrolling
        
        // UI
        uiUpdateInterval: 500,    // How often to update stats display
        
        // Error handling
        maxRetries: 3,            // Maximum retries before skipping item permanently (increased)
        skipIncrement: 1,         // How many items to skip when encountering problems (NEW)
        maxSkipAhead: 5,          // Maximum items to skip ahead at once (NEW)
        
        errorTexts: [             // Text patterns that indicate errors
            "Something went wrong",
            "Please try again",
            "An error occurred",
            "We couldn't process",
            "Action blocked",
            "You're temporarily restricted" // Added this common error
        ],
        
        // Progressive operation (NEW)
        resetSkipCountAfterSuccess: 3, // Reset skip counter after this many successful operations
    };

    // ===== STATE =====
    const STATE = {
        isRunning: false,
        deletionCount: 0,
        skipCount: 0,
        currentItem: null,
        problemItems: new Map(),  // Map of signatures to retry counts
        lastActionTime: 0,        // For monitoring performance
        processingTime: [],       // Track how long each deletion takes
        
        // Progressive operation (NEW)
        consecutiveSuccesses: 0,  // Count consecutive successful deletions
        currentSkipAhead: 1,      // How many items to skip if problems persist
        lastSuccessTimestamp: 0,  // When was the last successful deletion
    };

    // ===== DOM ELEMENT REFERENCES =====
    const DOM = {
        statusDisplay: null,
        statsDisplay: null,
        toggleButton: null,
        resetButton: null,
        speedSlider: null
    };

    // ===== UTILITY FUNCTIONS =====
    function log(message, type = 'info') {
        const prefix = {
            'info': '📋',
            'success': '✅',
            'error': '❌',
            'warn': '⚠️',
            'skip': '⏭️',
            'scroll': '🔄'
        }[type] || '🔹';
        
        console.log(`${prefix} ${message}`);
    }

    function getRandomDelay() {
        return CONFIG.betweenItemsDelay + Math.floor(Math.random() * CONFIG.randomDelayMax);
    }

    function updateStatus(text, type = 'normal') {
        if (!DOM.statusDisplay) return;
        
        // Set color based on type
        const colors = {
            'normal': 'lime',
            'error': '#ff5555',
            'warning': '#ffaa00',
            'success': '#55ff55'
        };
        
        DOM.statusDisplay.textContent = text;
        DOM.statusDisplay.style.color = colors[type] || colors.normal;
    }

    function updateStats() {
        if (!DOM.statsDisplay) return;
        
        // Calculate average processing time
        let avgTime = 0;
        if (STATE.processingTime.length > 0) {
            avgTime = STATE.processingTime.reduce((sum, time) => sum + time, 0) / STATE.processingTime.length;
        }
        
        DOM.statsDisplay.innerHTML = `
            <div style="font-weight:bold;margin-bottom:5px;border-bottom:1px solid #444;padding-bottom:3px;">FB CLEANER STATS</div>
            <div>Deleted: <span style="color:#55ff55">${STATE.deletionCount}</span></div>
            <div>Skipped: <span style="color:#ffaa00">${STATE.skipCount}</span></div>
            <div>Skip Ahead: <span style="color:#55aaff">${STATE.currentSkipAhead}</span></div>
            <div>Avg Time: <span style="color:#55aaff">${Math.round(avgTime)}ms</span></div>
        `;
    }

    // ===== UI CREATION =====
    function createUI() {
        const css = `
            .fb-cleaner-ui {
                position: fixed;
                bottom: 20px;
                right: 20px;
                background: rgba(10, 10, 10, 0.85);
                border: 1px solid #444;
                border-radius: 10px;
                color: white;
                font-family: 'Segoe UI', Tahoma, Geneva, sans-serif;
                z-index: 999999;
                backdrop-filter: blur(5px);
                box-shadow: 0 4px 12px rgba(0,0,0,0.2);
                overflow: hidden;
                transition: all 0.3s ease;
                width: 180px;
            }
            
            .fb-cleaner-header {
                background: #222;
                padding: 8px 12px;
                font-weight: bold;
                border-bottom: 1px solid #444;
                display: flex;
                justify-content: space-between;
                align-items: center;
            }
            
            .fb-cleaner-title {
                font-size: 14px;
                color: #fff;
            }
            
            .fb-cleaner-version {
                font-size: 10px;
                color: #aaa;
                background: #333;
                padding: 2px 6px;
                border-radius: 10px;
            }
            
            .fb-cleaner-body {
                padding: 10px;
            }
            
            .fb-cleaner-status {
                margin-bottom: 10px;
                padding: 5px;
                background: rgba(0,0,0,0.2);
                border-radius: 5px;
                font-size: 13px;
                color: lime;
                min-height: 20px;
            }
            
            .fb-cleaner-stats {
                font-size: 12px;
                margin: 10px 0;
                line-height: 1.5;
            }
            
            .fb-cleaner-button {
                padding: 8px;
                border: none;
                border-radius: 5px;
                cursor: pointer;
                font-weight: bold;
                font-size: 12px;
                transition: all 0.2s;
                width: 100%;
                margin-bottom: 8px;
            }
            
            .fb-cleaner-button:hover {
                transform: translateY(-2px);
                box-shadow: 0 2px 5px rgba(0,0,0,0.2);
            }
            
            .fb-cleaner-button.start {
                background: #4CAF50;
                color: white;
            }
            
            .fb-cleaner-button.pause {
                background: #FF9800;
                color: black;
            }
            
            .fb-cleaner-button.reset {
                background: #f44336;
                color: white;
            }
            
            .fb-cleaner-speed {
                margin-top: 5px;
                display: flex;
                flex-direction: column;
                font-size: 12px;
            }
            
            .fb-cleaner-speed-label {
                display: flex;
                justify-content: space-between;
                margin-bottom: 5px;
            }
            
            .fb-cleaner-slider {
                width: 100%;
                cursor: pointer;
            }
        `;
        
        // Add CSS
        const styleEl = document.createElement('style');
        styleEl.textContent = css;
        document.head.appendChild(styleEl);
        
        // Create main container
        const container = document.createElement('div');
        container.className = 'fb-cleaner-ui';
        
        // Create header
        const header = document.createElement('div');
        header.className = 'fb-cleaner-header';
        
        const title = document.createElement('div');
        title.className = 'fb-cleaner-title';
        title.textContent = 'FB Cleaner';
        
        const version = document.createElement('div');
        version.className = 'fb-cleaner-version';
        version.textContent = 'v5.03';
        
        header.appendChild(title);
        header.appendChild(version);
        
        // Create body
        const body = document.createElement('div');
        body.className = 'fb-cleaner-body';
        
        // Status display
        const status = document.createElement('div');
        status.className = 'fb-cleaner-status';
        status.textContent = 'Ready to start';
        DOM.statusDisplay = status;
        
        // Stats display
        const stats = document.createElement('div');
        stats.className = 'fb-cleaner-stats';
        DOM.statsDisplay = stats;
        
        // Toggle button
        const toggleBtn = document.createElement('button');
        toggleBtn.className = 'fb-cleaner-button start';
        toggleBtn.textContent = '▶️ Start Cleaning';
        toggleBtn.addEventListener('click', toggleRunning);
        DOM.toggleButton = toggleBtn;
        
        // Reset button
        const resetBtn = document.createElement('button');
        resetBtn.className = 'fb-cleaner-button reset';
        resetBtn.textContent = '🔄 Reset Skip List';
        resetBtn.addEventListener('click', () => {
            STATE.problemItems.clear();
            STATE.skipCount = 0;
            STATE.currentSkipAhead = 1;
            updateStatus('Skip list cleared', 'success');
            updateStats();
        });
        DOM.resetButton = resetBtn;
        
        // Speed control
        const speedControl = document.createElement('div');
        speedControl.className = 'fb-cleaner-speed';
        
        const speedLabel = document.createElement('div');
        speedLabel.className = 'fb-cleaner-speed-label';
        
        const speedText = document.createElement('span');
        speedText.textContent = 'Speed:';
        
        const speedValue = document.createElement('span');
        speedValue.textContent = 'Normal';
        
        speedLabel.appendChild(speedText);
        speedLabel.appendChild(speedValue);
        
        const speedSlider = document.createElement('input');
        speedSlider.type = 'range';
        speedSlider.min = '1';
        speedSlider.max = '3';
        speedSlider.value = '2';
        speedSlider.className = 'fb-cleaner-slider';
        
        speedSlider.addEventListener('input', () => {
            const value = parseInt(speedSlider.value);
            const labels = ['Careful', 'Normal', 'Speedy'];
            speedValue.textContent = labels[value - 1];
            
            // Adjust delays based on speed setting
            const multiplier = value === 1 ? 1.5 : value === 2 ? 1 : 0.6;
            CONFIG.menuClickDelay = 300 * multiplier;
            CONFIG.deleteClickDelay = 300 * multiplier;
            CONFIG.betweenItemsDelay = 800 * multiplier;
            CONFIG.errorCheckDelay = 600 * multiplier;
        });
        
        DOM.speedSlider = speedSlider;
        
        speedControl.appendChild(speedLabel);
        speedControl.appendChild(speedSlider);
        
        // Assemble UI
        body.appendChild(status);
        body.appendChild(stats);
        body.appendChild(toggleBtn);
        body.appendChild(resetBtn);
        body.appendChild(speedControl);
        
        container.appendChild(header);
        container.appendChild(body);
        document.body.appendChild(container);
        
        // Initialize stats display
        updateStats();
        
        // Make the UI draggable (simple implementation)
        let isDragging = false;
        let offsetX, offsetY;
        
        header.addEventListener('mousedown', (e) => {
            isDragging = true;
            offsetX = e.clientX - container.getBoundingClientRect().left;
            offsetY = e.clientY - container.getBoundingClientRect().top;
        });
        
        document.addEventListener('mousemove', (e) => {
            if (!isDragging) return;
            
            container.style.left = (e.clientX - offsetX) + 'px';
            container.style.top = (e.clientY - offsetY) + 'px';
            container.style.right = 'auto';
            container.style.bottom = 'auto';
        });
        
        document.addEventListener('mouseup', () => {
            isDragging = false;
        });
    }

    // ===== CORE FUNCTIONALITY =====
    function toggleRunning() {
        STATE.isRunning = !STATE.isRunning;
        
        if (STATE.isRunning) {
            DOM.toggleButton.textContent = '⏸️ Pause Cleaning';
            DOM.toggleButton.className = 'fb-cleaner-button pause';
            updateStatus('Running...', 'normal');
            deleteNext();
        } else {
            DOM.toggleButton.textContent = '▶️ Start Cleaning';
            DOM.toggleButton.className = 'fb-cleaner-button start';
            updateStatus('Paused', 'warning');
        }
    }

    // IMPROVED: More reliable item signature generation
    function getItemSignature(element) {
        if (!element) return null;
        
        // Find the containing item - search wider for containers
        let container = element.closest('[data-visualcompletion="ignore-dynamic"]') || 
                       element.closest('div[role="article"]') ||
                       element.closest('div[data-pagelet*="Feed"]') ||
                       element.closest('[data-testid]') ||  // Added support for more Facebook selectors
                       element.parentElement?.parentElement?.parentElement;
        
        if (!container) {
            container = element.parentElement;
            if (!container) return null;
        }
        
        // Get text content - use less text for the signature to reduce false uniqueness
        let textContent = '';
        try {
            // Try to get first 30 chars of cleaned text content (was 50 before)
            textContent = container.innerText.replace(/\s+/g, ' ').trim().substring(0, 30);
        } catch (e) {
            // Fallback if innerText fails
            textContent = (container.textContent || '').replace(/\s+/g, ' ').trim().substring(0, 30);
        }
        
        // Look for timestamps but don't make them a critical part of the signature
        const timestamp = container.querySelector('abbr[data-utime]');
        const timeValue = timestamp ? timestamp.getAttribute('data-utime').slice(-5) : ''; // Only use last 5 digits
        
        // Use rough position info 
        const rect = container.getBoundingClientRect();
        const posInfo = `${Math.round(rect.width/10)*10}`; // Round to nearest 10px for less sensitivity
        
        return `${textContent}:${posInfo}:${timeValue}`;
    }

    // IMPROVED: Better menu button detection
    function findMenuButtons() {
        // Start with standard buttons
        const standardButtons = Array.from(document.querySelectorAll('[role="button"]')).filter(btn => {
            const label = btn.getAttribute('aria-label') || '';
            return (
                btn.offsetParent !== null &&
                (label.toLowerCase().includes("activity options") ||
                 label.toLowerCase().includes("action options") ||
                 label.toLowerCase().includes("more options") ||  // Added more option keywords
                 label.toLowerCase().includes("menu"))
            );
        });
        
        // If we found standard buttons, return them
        if (standardButtons.length > 0) return standardButtons;
        
        // Fallback to visual detection
        return Array.from(document.querySelectorAll('*')).filter(el => {
            if (!el.offsetParent) return false; // Must be visible
            
            // Look for elements that resemble menu buttons
            const rect = el.getBoundingClientRect();
            const isSquarish = Math.abs(rect.width - rect.height) < 5;
            const isReasonableSize = rect.width >= 20 && rect.width <= 40;
            
            // Check if it's in a reasonable place in the document
            const isInViewport = rect.top >= 0 && rect.top <= window.innerHeight;
            
            // Has some content that might indicate a button
            const hasIconContent = el.innerHTML.includes('svg') || 
                                  el.innerHTML.includes('img') || 
                                  el.textContent.includes('...') ||
                                  el.textContent.includes('⋮');
            
            return isSquarish && isReasonableSize && isInViewport && hasIconContent;
        });
    }

    function checkForErrorPopups() {
        // Check for any error popups or notifications
        for (const errorText of CONFIG.errorTexts) {
            const containsError = Array.from(document.querySelectorAll('body *')).some(
                el => el.offsetParent !== null && // is visible
                      el.innerText && 
                      el.innerText.includes(errorText)
            );
            
            if (containsError) return true;
        }
        
        // Additional check for specific Facebook error elements
        const errorElements = document.querySelectorAll('[role="alert"], [role="status"]');
        for (const el of errorElements) {
            if (el.offsetParent !== null && CONFIG.errorTexts.some(txt => el.innerText.includes(txt))) {
                return true;
            }
        }
        
        return false;
    }

    function closeAllErrorPopups() {
        // Find all close buttons in error popups
        const errorPopups = Array.from(document.querySelectorAll('[role="alert"], [role="dialog"], [role="status"]')).filter(
            popup => CONFIG.errorTexts.some(txt => popup.innerText && popup.innerText.includes(txt))
        );
        
        let closed = false;
        
        errorPopups.forEach(popup => {
            // Look for close buttons
            const closeBtn = popup.querySelector('[aria-label="Close"], [aria-label="Dismiss"], [aria-label="OK"]') || 
                           popup.querySelector('div[role="button"]') ||
                           popup.querySelector('button');
            
            if (closeBtn) {
                closeBtn.click();
                closed = true;
                log("Closed error popup", "info");
            }
        });
        
        return closed;
    }

    // IMPROVED: Smarter handling of problem items
    function markCurrentItemAsProblem() {
        if (!STATE.currentItem) return;
        
        const signature = getItemSignature(STATE.currentItem);
        if (!signature) return;
        
        // Get current count or default to 0
        const currentCount = STATE.problemItems.get(signature) || 0;
        STATE.problemItems.set(signature, currentCount + 1);
        
        // If this is a permanent skip, increment skip counter
        if (currentCount + 1 >= CONFIG.maxRetries) {
            STATE.skipCount++;
            log(`Permanently skipping item: "${signature.substring(0, 30)}..."`, "skip");
            
            // Increase the skip ahead count for progressive skipping
            STATE.currentSkipAhead = Math.min(
                STATE.currentSkipAhead + CONFIG.skipIncrement, 
                CONFIG.maxSkipAhead
            );
            
            // Reset consecutive successes
            STATE.consecutiveSuccesses = 0;
        } else {
            log(`Marking item for retry: "${signature.substring(0, 30)}..."`, "warn");
        }
    }

    function shouldSkipItem(btn) {
        const signature = getItemSignature(btn);
        if (!signature) return false;
        
        const failCount = STATE.problemItems.get(signature) || 0;
        return failCount >= CONFIG.maxRetries;
    }

    function autoConfirmPopups() {
        const dialogs = Array.from(document.querySelectorAll('[role="dialog"], [role="alertdialog"]'));
        
        dialogs.forEach(dialog => {
            // Find the delete button
            const deleteBtn = Array.from(dialog.querySelectorAll('div[role="button"], button'))
                .find(btn => 
                    btn.offsetParent !== null && 
                    (btn.innerText.trim().toLowerCase() === "delete" || 
                     btn.innerText.trim().toLowerCase() === "delete post" ||
                     btn.innerText.trim().toLowerCase() === "delete activity" ||  // Added variants
                     btn.innerText.trim().toLowerCase() === "remove" ||
                     btn.innerText.trim().toLowerCase() === "confirm" ||
                     btn.innerText.trim().toLowerCase() === "ok")
                );
            
            if (deleteBtn) {
                deleteBtn.click();
                log("Auto-confirmed deletion dialog", "success");
            }
        });
    }

    function autoScrollAndRetry() {
        log("Scrolling to load more content", "scroll");
        updateStatus("Scrolling to find more items...", "normal");
        
        // Scroll down
        window.scrollTo({
            top: document.body.scrollHeight,
            behavior: 'smooth'
        });
        
        // Wait and then try again
        setTimeout(deleteNext, CONFIG.scrollDelay);
    }

    function deleteNext() {
        if (!STATE.isRunning) return;
        
        const startTime = performance.now();
        STATE.lastActionTime = startTime;
        
        // Reset current item
        STATE.currentItem = null;
        
        // Clean up any dialogs and popups
        closeAllErrorPopups();
        autoConfirmPopups();
        
        // Find menu buttons
        const buttons = findMenuButtons();
        
        if (buttons.length === 0) {
            updateStatus("No items found, scrolling...", "warning");
            autoScrollAndRetry();
            return;
        }
        
        // Filter out buttons we should skip
        const validButtons = buttons.filter(btn => !shouldSkipItem(btn));
        
        if (validButtons.length === 0) {
            updateStatus("Only skippable items found, scrolling...", "warning");
            autoScrollAndRetry();
            return;
        }
        
        // NEW: Get a button based on the current skip-ahead setting
        let buttonIndex = 0;
        if (STATE.currentSkipAhead > 1 && validButtons.length >= STATE.currentSkipAhead) {
            buttonIndex = STATE.currentSkipAhead - 1; // -1 because array is 0-indexed
            log(`Skipping ahead ${STATE.currentSkipAhead} items due to previous errors`, "skip");
        }
        
        const btn = validButtons[buttonIndex];
        STATE.currentItem = btn;
        
        // Scroll to the button and click it
        btn.scrollIntoView({ block: "center", behavior: "instant" });
        
        setTimeout(() => {
            // Click the menu button
            btn.click();
            log(`Opened menu for item`, "info");
            updateStatus("Opened menu...", "normal");
            
            setTimeout(() => {
                // Find and click the delete option
                const menuItems = Array.from(document.querySelectorAll('[role="menuitem"], [role="button"]'));
                const deleteOption = menuItems.find(el =>
                    el.offsetParent !== null &&  // Must be visible
                    (
                        el.innerText.includes("Move to Recycle bin") ||
                        el.innerText.includes("Delete") ||
                        el.innerText.includes("Remove") ||
                        el.innerText.includes("Unlike") ||
                        el.innerText.includes("Remove reaction") ||
                        el.innerText.includes("Remove tag") ||
                        el.innerText.includes("Hide") ||  // Added more options
                        el.innerText.includes("Remove from profile")
                    )
                );
                
                if (deleteOption) {
                    deleteOption.click();
                    log(`Clicked delete option: "${deleteOption.innerText}"`, "info");
                    updateStatus("Deleting...", "normal");
                    
                    // Check for errors after a short delay
                    setTimeout(() => {
                        if (checkForErrorPopups()) {
                            // Error detected
                            log("Error detected during deletion", "error");
                            updateStatus("Error detected, skipping item", "error");
                            markCurrentItemAsProblem();
                            closeAllErrorPopups();
                            
                            // Record processing time
                            const endTime = performance.now();
                            STATE.processingTime.push(endTime - startTime);
                            
                            // Reset consecutive successes
                            STATE.consecutiveSuccesses = 0;
                            
                            // Move to next item
                            setTimeout(deleteNext, getRandomDelay());
                        } else {
                            // Success!
                            STATE.deletionCount++;
                            STATE.consecutiveSuccesses++;
                            STATE.lastSuccessTimestamp = Date.now();
                            
                            log(`Successfully deleted item #${STATE.deletionCount}`, "success");
                            updateStatus(`Deleted item #${STATE.deletionCount}`, "success");
                            
                            // NEW: Reduce skip-ahead after consecutive successes
                            if (STATE.consecutiveSuccesses >= CONFIG.resetSkipCountAfterSuccess && STATE.currentSkipAhead > 1) {
                                STATE.currentSkipAhead = Math.max(1, STATE.currentSkipAhead - 1);
                                log(`Reduced skip-ahead to ${STATE.currentSkipAhead} after ${STATE.consecutiveSuccesses} successes`, "info");
                                STATE.consecutiveSuccesses = 0; // Reset the counter
                            }
                            
                            // Record processing time
                            const endTime = performance.now();
                            STATE.processingTime.push(endTime - startTime);
                            
                            // Keep only the last 10 times for the average
                            if (STATE.processingTime.length > 10) {
                                STATE.processingTime.shift();
                            }
                            
                            // Move to next item
                            setTimeout(deleteNext, getRandomDelay());
                        }
                    }, CONFIG.errorCheckDelay);
                    
                } else {
                    // No delete option found - click elsewhere to close the menu
                    document.body.click();
                    
                    // Wait a bit and look for confirmation dialogs that might have appeared
                    setTimeout(() => {
                        autoConfirmPopups();
                        
                        // Still no success, mark as problem
                        log("No delete option found", "warn");
                        updateStatus("No delete option found, trying next", "warning");
                        markCurrentItemAsProblem();
                        
                        // Record processing time
                        const endTime = performance.now();
                        STATE.processingTime.push(endTime - startTime);
                        
                        // Move to next item
                        setTimeout(deleteNext, getRandomDelay());
                    }, 300);
                }
            }, CONFIG.menuClickDelay);
        }, 100); // Very short delay after scrolling
    }

    // ===== INITIALIZATION =====
    function initialize() {
        log("Facebook Activity Auto Deleter v5.03 loaded", "info");
        createUI();
        
        // Start periodic update of the UI
        setInterval(updateStats, CONFIG.uiUpdateInterval);
        
        // Set up periodic error popup checker
        setInterval(() => {
            if (STATE.isRunning) {
                closeAllErrorPopups();
                autoConfirmPopups();
            }
        }, 1000);
        
        // NEW: Add occasional complete page refresh to fix stuck states
        setInterval(() => {
            // If running and no successful deletion in 2 minutes, refresh
            if (STATE.isRunning && 
                STATE.lastSuccessTimestamp > 0 && 
                Date.now() - STATE.lastSuccessTimestamp > 120000) {
                
                log("No successful deletions for 2 minutes, refreshing page", "warn");
                updateStatus("Stuck detected, refreshing page...", "warning");
                
                // Save state data to sessionStorage
                sessionStorage.setItem('fbCleanerState', JSON.stringify({
                    deletionCount: STATE.deletionCount,
                    skipCount: STATE.skipCount,
                    problemItems: Array.from(STATE.problemItems.entries())
                }));
                
                // Reload page
                setTimeout(() => {
                    window.location.reload();
                }, 1000);
            }
        }, 30000); // Check every 30 seconds
        
        // Try to restore state from previous session
        try {
            const savedState = sessionStorage.getItem('fbCleanerState');
            if (savedState) {
                const parsedState = JSON.parse(savedState);
                STATE.deletionCount = parsedState.deletionCount || 0;
                STATE.skipCount = parsedState.skipCount || 0;
                
                if (parsedState.problemItems && Array.isArray(parsedState.problemItems)) {
                    STATE.problemItems = new Map(parsedState.problemItems);
                }
                
                log(`Restored state: ${STATE.deletionCount} deleted, ${STATE.skipCount} skipped`, "info");
                updateStats();
                
                // Clear the saved state
                sessionStorage.removeItem('fbCleanerState');
            }
        } catch (err) {
            console.error("Error restoring state:", err);
        }
    }
    
    // Start the script
    initialize();
})();