Make it significantly more robust as possible. Send the fully working full code -- "use strict";const config={proxyUrl:"https://sh.dafeyan784.workers.dev/?target=",targetUrl:"https://jnovels.com/top-light-novels-to-read/",batchSize:40,maxRetries:3,retryDelay:1e3,searchDebounceTime:300,intersectionObserverThreshold:.2,intersectionObserverRootMargin:"250px",errorMessageDisplayTime:5e3,fetchTimeout:1e4,fallbackImage:'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%" height="100%" fill="%23f0f0f0"/%3E%3Ctext x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-family="Arial, sans-serif" font-size="16" fill="%23999"%3EImage not available%3C/text%3E%3C/svg%3E'};class NovelWebsite{constructor(){this.db=new Database,this.elements=this.getElements(),this.state={currentBatch:0,images:[],loadedImages:new Set,isLoading:!1,isPanelOpen:!1,pdfUrlToTextMap:new Map},this.setupEventListeners()}getElements(){return{bookGrid:document.querySelector("#book-grid"),searchInput:document.querySelector("#search-input"),searchButton:document.querySelector("#search-button"),loadingSpinner:document.querySelector(".loading-spinner"),menuBtn:document.querySelector(".menu-btn"),menuPanel:document.querySelector("#menu-panel"),libraryPanel:document.querySelector("#library-panel"),settingsPanel:document.querySelector("#settings-panel"),themeToggle:document.querySelector("#theme-toggle"),errorMessage:document.querySelector("#error-message"),libraryLink:document.querySelector("#library-link"),settingsLink:document.querySelector("#settings-link")}}setupEventListeners(){this.elements.searchInput?.addEventListener("keydown",this.handleSearchKeydown.bind(this)),this.elements.searchButton?.addEventListener("click",this.performSearch.bind(this)),this.elements.menuBtn?.addEventListener("click",()=>this.togglePanel(this.elements.menuPanel)),this.elements.libraryLink?.addEventListener("click",this.handleLibraryLink.bind(this)),this.elements.settingsLink?.addEventListener("click",this.handleSettingsLink.bind(this)),document.addEventListener("click",this.handleDocumentClick.bind(this)),this.elements.themeToggle?.addEventListener("change",this.handleThemeToggle.bind(this)),window.addEventListener("beforeunload",this.handleBeforeUnload.bind(this))}async init(){this.loadSavedTheme(),"undefined"!=typeof AOS&&AOS.init(),await this.fetchAndLoadImages()}loadSavedTheme(){"true"===localStorage.getItem("darkTheme")&&(document.body.classList.add("dark-theme"),this.elements.themeToggle&&(this.elements.themeToggle.checked=!0))}async fetchAndLoadImages(){if(!this.state.isLoading&&!this.state.isPanelOpen){this.state.isLoading=!0,this.toggleLoadingSpinner(!0);try{var e=await this.db.getHtmlContent(1),t=e?e.content:await this.fetchWithTimeout(""+config.proxyUrl+encodeURIComponent(config.targetUrl));t?(e||await this.db.putHtmlContent(1,t),this.extractImagesAndPdfLinks(t),0<this.state.images.length?(await this.loadImages(),this.setupIntersectionObserver()):this.showErrorMessage("No images found. Please check the source.")):this.showErrorMessage("No content fetched. Please try again later.")}catch(e){console.error("Error during fetching or parsing:",e),this.showErrorMessage("Failed to fetch books. Please try again later.")}finally{this.state.isLoading=!1,this.toggleLoadingSpinner(!1)}}}async fetchWithTimeout(e,t={},s=config.fetchTimeout){const r=new AbortController;s=setTimeout(()=>r.abort(),s);try{var n=await fetch(e,{...t,signal:r.signal});if(clearTimeout(s),n.ok)return await n.text();throw new Error("HTTP error! Status: "+n.status)}catch(e){throw clearTimeout(s),console.error("Fetch error:",e),this.showErrorMessage("Network error. Please check your connection and try again."),new Error("Fetch failed: "+e.message)}}extractImagesAndPdfLinks(e){var t;e?(e=(new DOMParser).parseFromString(e,"text/html"),t=Array.from(e.querySelectorAll('img[loading="lazy"][decoding="async"].alignnone')),e.querySelectorAll("a[href]").forEach(e=>{var t;e.href&&"string"==typeof e.href&&(t=e.href.trim(),e=(e.querySelector('span[style="color: #ff6600;"]')||e).textContent?.trim(),t&&e&&this.state.pdfUrlToTextMap.set(t,(this.state.pdfUrlToTextMap.get(t)||[]).concat(e)))}),this.state.images=t.filter(e=>e.src&&!this.state.loadedImages.has(e.src)),t.forEach(e=>this.state.loadedImages.add(e.src))):this.showErrorMessage("Failed to parse HTML content.")}async loadImages(){var e=this.state.currentBatch*config.batchSize,t=Math.min(e+config.batchSize,this.state.images.length),e=this.state.images.slice(e,t);const s=document.createDocumentFragment();0===e.length?this.showErrorMessage("No more images to load."):(await Promise.all(e.map(e=>this.createGridItem(e).then(e=>{e&&s.appendChild(e)}))),this.elements.bookGrid?.appendChild(s),this.state.currentBatch++)}async createGridItem(r,n=0){if(!r||!r.src)return console.error("Invalid image element:",r),null;const a=this.createElement("div",{class:"grid-item","data-aos":"fade-up"}),i=new Image;return i.src=r.src,i.className="lazyload",i.alt="Book Cover",new Promise(e=>{i.onload=()=>{i.style.display="block",e(a)},i.onerror=async()=>{n<config.maxRetries?setTimeout(()=>this.createGridItem(r,n+1).then(e),config.retryDelay):(console.error(`Failed to load image after ${config.maxRetries} retries:`,r.src),i.src=config.fallbackImage,i.onload=()=>e(a),i.onerror=()=>{this.showErrorMessage("Failed to load image: "+r.src),e(null)})},a.appendChild(i);const t=r.closest("a");var s;t?.href&&(i.addEventListener("click",e=>{e.preventDefault(),this.isValidUrl(t.href)?window.open(t.href,"_blank","noopener,noreferrer"):this.showErrorMessage("Invalid link detected.")}),(s=this.state.pdfUrlToTextMap.get(t.href))?.length&&(s=this.createElement("p",{class:"textElement"},s.join(", ")),a.appendChild(s)))})}isValidUrl(e){if("string"!=typeof e)return!1;try{return new URL(e),!0}catch{return!1}}setupIntersectionObserver(){if(this.elements.bookGrid){const t=new IntersectionObserver(e=>{e.some(e=>e.isIntersecting)&&this.state.currentBatch*config.batchSize<this.state.images.length&&!this.state.isLoading&&this.loadImages()},{rootMargin:config.intersectionObserverRootMargin,threshold:config.intersectionObserverThreshold});var e;(e=this.elements.bookGrid.lastElementChild)?t.observe(e):t.disconnect()}}createElement(e,t={},...s){const r=document.createElement(e);return Object.entries(t).forEach(([e,t])=>r.setAttribute(e,t)),s.forEach(e=>{"string"==typeof e?r.textContent=e:e instanceof Node&&r.appendChild(e)}),r}toggleLoadingSpinner(e){this.elements.loadingSpinner&&this.elements.loadingSpinner.classList.toggle("active",e)}showErrorMessage(e){this.elements.errorMessage&&(this.elements.errorMessage.textContent=e,this.elements.errorMessage.classList.add("active"),setTimeout(()=>this.elements.errorMessage.classList.remove("active"),config.errorMessageDisplayTime))}redirectSearchResults(e){var e=this.sanitizeInput(e);e?(e="search-results.html?query="+encodeURIComponent(e),window.open(e,"_blank","noopener,noreferrer")):this.showErrorMessage("Invalid search query.")}sanitizeInput(e){var t;return"string"!=typeof e?"":((t=document.createElement("div")).textContent=e,t.innerHTML)}debounce(t,s){let r;return(...e)=>{clearTimeout(r),r=setTimeout(()=>t.apply(this,e),s)}}performSearch=this.debounce(e=>{e.preventDefault();e=this.elements.searchInput?.value.trim();!e||e.length<3?this.showErrorMessage("Search term must be at least 3 characters long."):100<e.length?this.showErrorMessage("Search term must be less than 100 characters."):this.redirectSearchResults(e)},config.searchDebounceTime);togglePanel(e){e&&(e.classList.toggle("active"),this.state.isPanelOpen=e.classList.contains("active"))}handleDocumentClick(e){e.target.closest(".panel")||e.target.closest(".menu-btn")||([this.elements.menuPanel,this.elements.libraryPanel,this.elements.settingsPanel].forEach(e=>e?.classList.remove("active")),this.state.isPanelOpen=!1)}handleThemeToggle(){document.body.classList.toggle("dark-theme"),localStorage.setItem("darkTheme",document.body.classList.contains("dark-theme"))}handleSearchKeydown(e){"Enter"===e.key&&this.performSearch(e)}handleLibraryLink(){this.elements.menuPanel?.classList.remove("active"),this.togglePanel(this.elements.libraryPanel)}handleSettingsLink(){this.elements.menuPanel?.classList.remove("active"),this.togglePanel(this.elements.settingsPanel)}async handleBeforeUnload(){try{await this.db.clearHtmlContent()}catch(e){console.error("Error clearing database on unload:",e)}}}class Database{constructor(){this.db=new Dexie("NovelDatabase"),this.db.version(1).stores({htmlContent:"++id, content"})}async getHtmlContent(e){try{return await this.db.htmlContent.get(e)||null}catch(e){return console.error("Database read error:",e),null}}async putHtmlContent(e,t){try{await this.db.htmlContent.put({id:e,content:t})}catch(e){console.error("Database write error:",e)}}async clearHtmlContent(){try{await this.db.htmlContent.clear()}catch(e){console.error("Database clear error:",e)}}}document.addEventListener("DOMContentLoaded",()=>{(new NovelWebsite).init()});