Uncaught SyntaxError: missing ) after argument list. Fix all of this types of errors then send the fully working full codes. Complete this and make this Work. Fix the UI desigs too. Review the whole codes and fix all of the issues, problems, edge cases. Bottle necks, memory leaks, can be better, what ifs. <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Light Novels Gallery</title>
    
    <!-- Essential Libraries -->
    <script src="https://cdn.jsdelivr.net/npm/dexie@3.2.4/dist/dexie.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/fuse.js@7.0.0"></script>
    
    <style>
        /* Core styles remain same as before, adding new styles for search and optimization */
        .search-container {
            width: 100%;
            max-width: 600px;
            margin: 20px auto;
            position: relative;
        }

        .search-input {
            width: 100%;
            padding: 12px 20px;
            border: 2px solid #bb86fc;
            border-radius: 25px;
            background: #1f1b24;
            color: #ffffff;
            font-size: 16px;
            transition: all 0.3s ease;
        }

        .search-input:focus {
            outline: none;
            box-shadow: 0 0 10px rgba(187, 134, 252, 0.3);
        }

        .search-results {
            position: absolute;
            top: 100%;
            left: 0;
            right: 0;
            background: #1f1b24;
            border-radius: 8px;
            margin-top: 5px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            z-index: 1000;
            max-height: 300px;
            overflow-y: auto;
        }

        .search-result-item {
            padding: 10px 15px;
            cursor: pointer;
            transition: background-color 0.2s ease;
        }

        .search-result-item:hover {
            background-color: #2d2736;
        }

        .placeholder-img {
            background: linear-gradient(45deg, #1f1b24 25%, #2d2736 25%, #2d2736 50%, #1f1b24 50%, #1f1b24 75%, #2d2736 75%, #2d2736);
            background-size: 20px 20px;
            animation: moveBackground 1s linear infinite;
        }

        @keyframes moveBackground {
            0% {
                background-position: 0 0;
            }
            100% {
                background-position: 20px 20px;
            }
        }

        .scroll-top {
            position: fixed;
            bottom: 20px;
            right: 20px;
            background: #bb86fc;
            color: #000;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            opacity: 0;
            transition: opacity 0.3s ease;
            z-index: 1000;
        }

        .scroll-top.visible {
            opacity: 1;
        }

        /* Improved loading animation */
        .loading-skeleton {
            background: linear-gradient(90deg, #1f1b24 25%, #2d2736 50%, #1f1b24 75%);
            background-size: 200% 100%;
            animation: loading 1.5s infinite;
        }

        @keyframes loading {
            0% {
                background-position: 200% 0;
            }
            100% {
                background-position: -200% 0;
            }
        }

        .error-message {
            background: #cf6679;
            color: #000;
            padding: 10px 20px;
            border-radius: 4px;
            margin: 10px 0;
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .retry-button {
            background: #03dac6;
            border: none;
            padding: 5px 15px;
            border-radius: 4px;
            cursor: pointer;
            transition: background-color 0.2s ease;
        }

        .retry-button:hover {
            background: #018786;
        }
    </style>
</head>
<body>
    <div class="search-container">
        <input type="text" class="search-input" placeholder="Search light novels..." id="searchInput">
        <div class="search-results" id="searchResults"></div>
    </div>

    <div id="loading" class="loading">
        <div class="spinner">
            <div class="bounce1"></div>
            <div class="bounce2"></div>
            <div class="bounce3"></div>
        </div>
        Loading...
    </div>

    <h2 class="section-title">New Updates</h2>
    <div id="updates" class="container"></div>
    
    <h2 class="section-title">Popular Light Novels</h2>
    <div id="popular" class="container"></div>

    <button id="scrollTop" class="scroll-top" aria-label="Scroll to top">↑</button>

<script>
// Initialize Dexie with optimized schema
const db = new Dexie('LightNovelsDB');
db.version(2).stores({
    updates: '++id, title, link, imageUrl, date, downloadLinks, timestamp',
    popular: '++id, title, link, imageUrl, timestamp',
    metadata: 'key, value'
});

// Constants
const BATCH_SIZE = 20;
const DATA_EXPIRY = 1000 * 60 * 60; // 1 hour
const PLACEHOLDER_IMAGE = 'data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="200" height="300" viewBox="0 0 200 300"%3E%3Crect width="100%25" height="100%25" fill="%231f1b24"/%3E%3Ctext x="50%25" y="50%25" dominant-baseline="middle" text-anchor="middle" fill="%23bb86fc"%3ENo Image%3C/text%3E%3C/svg%3E';

// State management
const state = {
    updates: [],
    popular: [],
    currentBatch: { updates: 0, popular: 0 },
    loading: false,
    searchIndex: null
};

// Initialize Fuse.js for fuzzy search
function initializeSearch(data) {
    const options = {
        keys: ['title'],
        threshold: 0.3,
        distance: 100
    };
    state.searchIndex = new Fuse([...state.updates, ...state.popular], options);
}

// Utility functions
const debounce = (fn, delay) => {
    let timeoutId;
    return (...args) => {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => fn(...args), delay);
    };
};

function isDataExpired(timestamp) {
    return !timestamp || Date.now() - timestamp > DATA_EXPIRY;
}

async function fetchWithTimeout(url, timeout = 5000) {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), timeout);
    
    try {
        const response = await fetch(url, {
            signal: controller.signal
        });
        clearTimeout(timeoutId);
        if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
        return await response.text();
    } catch (error) {
        clearTimeout(timeoutId);
        throw error;
    }
}

// Data fetching and parsing
async function fetchAndParseData(url, isUpdates = false) {
    try {
        const html = await fetchWithTimeout(https://api.codetabs.com/v1/proxy?quest= + encodeURIComponent(url));
        const parser = new DOMParser();
        const doc = parser.parseFromString(html, 'text/html');

        if (isUpdates) {
            return Array.from(doc.querySelectorAll('article'))
                .map(element => {
                    try {
                        return {
                            title: element.querySelector('.post-title a')?.textContent?.trim(),
                            link: element.querySelector('.post-title a')?.href,
                            imageUrl: element.querySelector('.featured-media img')?.src || PLACEHOLDER_IMAGE,
                            date: element.querySelector('.post-date')?.textContent?.trim(),
                            downloadLinks: Array.from(element.querySelectorAll('.post-content p a'))
                                .filter(a => a.textContent.match(/VOLUME|PDF|Download/i))
                                .map(a => ({
                                    href: a.href,
                                    text: a.textContent.trim()
                                })),
                            timestamp: Date.now()
                        };
                    } catch (error) {
                        console.error('Error parsing update:', error);
                        return null;
                    }
                })
                .filter(Boolean);
        } else {
            return Array.from(doc.querySelectorAll('h3 a[href*="jnovels.com"]'))
                .map(element => {
                    try {
                        return {
                            title: element.textContent.trim(),
                            link: element.href,
                            imageUrl: element.closest('div').querySelector('img')?.src || PLACEHOLDER_IMAGE,
                            timestamp: Date.now()
                        };
                    } catch (error) {
                        console.error('Error parsing popular:', error);
                        return null;
                    }
                })
                .filter(Boolean);
        }
    } catch (error) {
        console.error('Fetch error:', error);
        throw error;
    }
}

// Rendering functions
function renderNovel(novel, container) {
    const div = document.createElement('div');
    div.className = 'novel-card';
    div.innerHTML = `
        <a href="${novel.link}" target="_blank" rel="noopener noreferrer">
            <img src="${novel.imageUrl}" 
                 alt="${novel.title}"
                 loading="lazy"
                 onerror="this.src='${PLACEHOLDER_IMAGE}'">
        </a>
        <div class="novel-content">
            <a href="${novel.link}" target="_blank" rel="noopener noreferrer" class="novel-title">
                ${novel.title}
            </a>
            ${novel.date ? `<div class="post-meta">${novel.date}</div>` : ''}
            ${novel.downloadLinks ? `
                <div class="download-links">
                    ${novel.downloadLinks.map(link => `
                        <a href="${link.href}" target="_blank" rel="noopener noreferrer" 
                           class="download-link">${link.text}</a>
                    `).join('')}
                </div>
            ` : ''}
        </div>
    `;
    container.appendChild(div);
}

function renderBatch(type, container) {
    const data = state[type];
    const start = state.currentBatch[type];
    const end = Math.min(start + BATCH_SIZE, data.length);
    
    for (let i = start; i < end; i++) {
        renderNovel(data[i], container);
    }
    state.currentBatch[type] = end;
}

// Scroll handling
const handleScroll = debounce(() => {
    const scrollTop = window.scrollY;
    const windowHeight = window.innerHeight;
    const documentHeight = document.documentElement.scrollHeight;
    
    // Show/hide scroll to top button
    document.getElementById('scrollTop').classList.toggle(
        'visible',
        scrollTop > windowHeight
    );

    // Load more content if near bottom
    if (scrollTop + windowHeight > documentHeight - 500) {
        renderBatch('updates', document.getElementById('updates'));
        renderBatch('popular', document.getElementById('popular'));
    }
}, 100);

// Search implementation
function setupSearch() {
    const searchInput = document.getElementById('searchInput');
    const searchResults = document.getElementById('searchResults');

    searchInput.addEventListener('input', debounce((e) => {
        const query = e.target.value.trim();
        if (!query) {
            searchResults.innerHTML = '';
            return;
        }

        const results = state.searchIndex.search(query);
        searchResults.innerHTML = results
            .slice(0, 5)
            .map(({ item }) => `
                <div class="search-result-item" onclick="location.href='${item.link}'">
                    ${item.title}
                </div>
            `).join('');
    }, 300));
}

// Initialize application
async function init() {
    try {
        // Check if we need to fetch new data
        const metadata = await db.metadata.get('lastUpdate');
        const needsUpdate = isDataExpired(metadata?.value);

        if (needsUpdate) {
            // Fetch new data
            const [updates, popular] = await Promise.all([
                fetchAndParseData(https://jnovels.com/0m-light-novels/?a=light-novels, true),
                fetchAndParseData(https://jnovels.com/top-light-novels-to-read/)
            ]);

            // Store in database
            await db.transaction('rw', [db.updates, db.popular, db.metadata], async () => {
                await db.updates.clear();
                await db.popular.clear();
                await db.updates.bulkAdd(updates);
                await db.popular.bulkAdd(popular);
                await db.metadata.put({ key: 'lastUpdate', value: Date.now() });
            });

            state.updates = updates;
            state.popular = popular;
        } else {
            // Load from database
            state.updates = await db.updates.toArray();
            state.popular = await db.popular.toArray();
        }

        // Initialize search
        initializeSearch([...state.updates, ...state.popular]);

        // Render initial batches
        renderBatch('updates', document.getElementById('updates'));
        renderBatch('popular', document.getElementById('popular'));

        // Setup event listeners
        window.addEventListener('scroll', handleScroll, { passive: true });
        document.getElementById('scrollTop').addEventListener('click', () => {
            window.scrollTo({ top: 0, behavior: 'smooth' });
        });
        setupSearch();

    } catch (error) {
        console.error('Initialization error:', error);
        document.body.innerHTML += `
            <div class="error-message">
                Failed to load content. Please try again.
                <button class="retry-button" onclick="init()">Retry</button>
            </div>
        `;
    } finally {
        document.getElementById('loading').style.display = 'none';
    }
}

// Cleanup function
window.addEventListener('beforeunload', () => {
    window.removeEventListener('scroll', handleScroll);
});

// Start the application
document.addEventListener('DOMContentLoaded', init);
</script>
</body>
</html>