make it so code viewer and settings cover the whole thing when click because its behind give snippet

javascript:(async function() {

  // --- CONFIG ---
  const config = {
    totalDurationMs: 10 * 60 * 1000, // 10 minutes total approx
    updateIntervalMs: 500,
    maxLogLines: 2000,
    codeViewerMaxLines: 5000,
    verbosePrint: true,
  };

  // --- UTILITIES ---
  function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  async function fetchText(url) {
    try {
      const res = await fetch(url, { cache: "no-store" });
      if (!res.ok) return { ok: false, error: `${res.status} ${res.statusText}` };
      const text = await res.text();
      return { ok: true, text };
    } catch (e) {
      return { ok: false, error: e.message };
    }
  }

  function getDoctypeStr() {
    const dt = document.doctype;
    if (!dt) return '';
    return `<!DOCTYPE ${dt.name}${dt.publicId ? ` PUBLIC "${dt.publicId}"` : ''}${dt.systemId ? ` "${dt.systemId}"` : ''}>\n`;
  }

  // Cleans the cloned HTML by removing script and style tags to avoid unwanted execution or duplication of UI
  function cleanClonedHTML(docElement) {
    // Remove all <script> and <style> tags from the clone
    const scripts = docElement.querySelectorAll('script');
    scripts.forEach(el => el.remove());
    const styles = docElement.querySelectorAll('style');
    styles.forEach(el => el.remove());

    // Also remove link tags that might reference CSS (optional, but safer)
    const links = docElement.querySelectorAll('link[rel="stylesheet"]');
    links.forEach(el => el.remove());

    // Remove event handlers (attributes starting with "on")
    const elements = docElement.querySelectorAll('*');
    elements.forEach(el => {
      [...el.attributes].forEach(attr => {
        if (attr.name.startsWith('on')) el.removeAttribute(attr.name);
      });
    });
  }

  // --- UI Setup ---

  // Overlay container
  const overlay = document.createElement('div');
  Object.assign(overlay.style, {
    position: 'fixed',
    top: '0',
    left: '0',
    width: '100vw',
    height: '100vh',
    backgroundColor: '#111',
    color: '#0f0',
    fontFamily: 'Consolas, monospace',
    fontSize: '14px',
    zIndex: '2147483647',
    display: 'flex',
    flexDirection: 'column',
    // Removed userSelect none to allow interaction
  });

  // Header bar
  const header = document.createElement('div');
  Object.assign(header.style, {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    backgroundColor: '#222',
    padding: '5px 10px',
    flexShrink: '0',
  });

  const title = document.createElement('div');
  title.textContent = 'Page Copy Loader v1.0';
  Object.assign(title.style, {
    fontWeight: 'bold',
    fontSize: '16px',
  });
  header.appendChild(title);

  // Controls container
  const controls = document.createElement('div');

  function createButton(text) {
    const b = document.createElement('button');
    b.textContent = text;
    b.style.marginRight = '10px';
    b.style.cursor = 'pointer';
    b.style.fontFamily = 'monospace';
    return b;
  }

  const btnPauseResume = createButton('Pause');
  const btnStop = createButton('Stop');
  const btnCodeViewer = createButton('Current Code Viewer');
  const btnSettings = createButton('Settings');

  controls.appendChild(btnPauseResume);
  controls.appendChild(btnStop);
  controls.appendChild(btnCodeViewer);
  controls.appendChild(btnSettings);

  header.appendChild(controls);
  overlay.appendChild(header);

  // Terminal log area
  const terminal = document.createElement('pre');
  Object.assign(terminal.style, {
    flex: '1',
    margin: '0',
    padding: '10px',
    background: '#000',
    color: '#0f0',
    overflowY: 'auto',
    whiteSpace: 'pre-wrap',
  });
  overlay.appendChild(terminal);

  // Progress bar container
  const progressContainer = document.createElement('div');
  Object.assign(progressContainer.style, {
    width: '100%',
    background: '#222',
    height: '20px',
    borderTop: '2px solid #0f0',
    borderBottom: '2px solid #0f0',
    flexShrink: '0',
  });

  const progressBar = document.createElement('div');
  Object.assign(progressBar.style, {
    width: '0%',
    height: '100%',
    backgroundColor: '#0f0',
    transition: 'width 0.3s linear',
  });

  progressContainer.appendChild(progressBar);
  overlay.appendChild(progressContainer);

  // Command input line
  const inputWrapper = document.createElement('div');
  Object.assign(inputWrapper.style, {
    background: '#111',
    borderTop: '2px solid #0f0',
    padding: '5px 10px',
    flexShrink: '0',
  });

  const commandLabel = document.createElement('label');
  commandLabel.textContent = 'Command: ';
  commandLabel.style.marginRight = '5px';

  const commandInput = document.createElement('input');
  commandInput.type = 'text';
  commandInput.style.width = '60vw';
  commandInput.style.background = '#000';
  commandInput.style.color = '#0f0';
  commandInput.style.border = '1px solid #0f0';
  commandInput.style.fontFamily = 'monospace';
  commandInput.style.fontSize = '14px';
  commandInput.autocomplete = 'off';

  inputWrapper.appendChild(commandLabel);
  inputWrapper.appendChild(commandInput);
  overlay.appendChild(inputWrapper);

  // Code viewer panel (hidden initially)
  const codeViewer = document.createElement('textarea');
  Object.assign(codeViewer.style, {
    position: 'fixed',
    top: '40px',
    right: '10px',
    width: '50vw',
    height: '90vh',
    background: '#111',
    color: '#0f0',
    fontFamily: 'Consolas, monospace',
    fontSize: '12px',
    border: '2px solid #0f0',
    padding: '10px',
    overflow: 'auto',
    resize: 'both',
    zIndex: '2147483650',
    display: 'none',
  });
  document.body.appendChild(codeViewer);

  // Settings panel (hidden initially)
  const settingsPanel = document.createElement('div');
  Object.assign(settingsPanel.style, {
    position: 'fixed',
    top: '50px',
    left: '10px',
    width: '300px',
    height: '400px',
    background: '#111',
    color: '#0f0',
    fontFamily: 'Consolas, monospace',
    fontSize: '13px',
    border: '2px solid #0f0',
    padding: '10px',
    overflow: 'auto',
    zIndex: '2147483650',
    display: 'none',
  });
  settingsPanel.innerHTML = `
    <h3 style="margin-top:0">Settings</h3>
    <label><input type="checkbox" id="verboseToggle" checked> Verbose prints</label><br><br>
    <label>Speed multiplier:<br><input type="range" id="speedSlider" min="0.1" max="5" step="0.1" value="1"></label><br><br>
    <label>Max log lines:<br><input type="number" id="maxLogLines" min="100" max="10000" value="2000"></label><br><br>
    <label>Max code viewer lines:<br><input type="number" id="maxCodeLines" min="1000" max="10000000" value="5000"></label><br><br>
    <button id="closeSettingsBtn">Close Settings</button>
  `;
  document.body.appendChild(settingsPanel);

  // Append overlay to body last
  document.body.appendChild(overlay);

  // --- STATE ---
  let paused = false;
  let stopped = false;
  let progress = 0; // 0-1
  let logLines = [];
  let snapshotBuilder = [];
  let lastCodeUpdateTime = 0;
  let codeViewerIsVisible = false;

  // Settings variables
  let verbosePrint = config.verbosePrint;
  let speedMultiplier = 1;
  let maxLogLines = config.maxLogLines;
  let maxCodeViewerLines = config.codeViewerMaxLines;

  // --- LOGGING ---
  function appendLog(line) {
    if (!verbosePrint && !line.startsWith("!!!")) return; // print errors/warnings always
    if (logLines.length >= maxLogLines) {
      logLines.shift();
    }
    logLines.push(line);
    terminal.textContent = logLines.join('\n');
    terminal.scrollTop = terminal.scrollHeight;
  }

  // --- PROGRESS ---
  function updateProgress(fraction) {
    progress = Math.min(Math.max(fraction, 0), 1);
    progressBar.style.width = (progress * 100) + '%';
  }

  // Simple pretty print HTML - basic indentation (not robust)
  function prettyPrintHTML(htmlString) {
    const tab = '  ';
    let indent = 0;
    return htmlString.split(/>\s*</).map(function(element) {
      if (element.match(/^\/\w/)) indent--;
      let pad = '';
      for (let i = 0; i < indent; i++) pad += tab;
      let line = pad + '<' + element + '>';
      if (element.match(/^<?\w[^>]*[^\/]$/)) indent++;
      return line;
    }).join('\n').replace(/>\n</g, '>\n<');
  }

  // Update code viewer content throttled
  function updateCodeViewer() {
    if (!codeViewerIsVisible) return;
    const now = Date.now();
    if (now - lastCodeUpdateTime < 200) return;
    lastCodeUpdateTime = now;
    let fullCode = snapshotBuilder.join('');
    if (fullCode.length > maxCodeViewerLines * 100) {
      fullCode = fullCode.slice(-maxCodeViewerLines * 100);
    }
    const pretty = prettyPrintHTML(fullCode);
    codeViewer.value = pretty;
    codeViewer.scrollTop = codeViewer.scrollHeight;
  }

  // Append to snapshot string builder and update code viewer
  function appendSnapshot(str) {
    snapshotBuilder.push(str);
    updateCodeViewer();
  }

  function clearCodeViewer() {
    snapshotBuilder = [];
    updateCodeViewer();
  }

  // --- CONTROL HELPERS ---
  function waitWhilePaused() {
    return new Promise(resolve => {
      const interval = setInterval(() => {
        if (stopped) {
          clearInterval(interval);
          resolve(false);
        }
        else if (!paused) {
          clearInterval(interval);
          resolve(true);
        }
        // else remain paused
      }, 100);
    });
  }

  // --- STORAGE DUMP FUNCTIONS ---
  function dumpLocalStorage() {
    appendLog("!!! Dumping localStorage:");
    let count = 0;
    for (let i = 0; i < localStorage.length; i++) {
      const k = localStorage.key(i);
      const v = localStorage.getItem(k);
      appendLog(`  Key: ${k} => Value: ${v ? v.substring(0, 100) : ''}`);
      count++;
      if (count >= 50) break;
    }
    appendLog(`!!! localStorage dumped ${count} items.`);
  }

  function dumpSessionStorage() {
    appendLog("!!! Dumping sessionStorage:");
    let count = 0;
    for (let i = 0; i < sessionStorage.length; i++) {
      const k = sessionStorage.key(i);
      const v = sessionStorage.getItem(k);
      appendLog(`  Key: ${k} => Value: ${v ? v.substring(0, 100) : ''}`);
      count++;
      if (count >= 50) break;
    }
    appendLog(`!!! sessionStorage dumped ${count} items.`);
  }

  function dumpCookies() {
    appendLog("!!! Dumping cookies:");
    const cookies = document.cookie.split(';').filter(c => c.trim().length > 0);
    if (cookies.length === 0) {
      appendLog("  No cookies found.");
      return;
    }
    let count = 0;
    for (const c of cookies) {
      appendLog(`  Cookie: ${c.trim()}`);
      count++;
      if (count >= 50) break;
    }
    appendLog(`!!! Cookies dumped ${count} items.`);
  }

  async function dumpIndexedDB() {
    appendLog("!!! Dumping IndexedDB databases (async)...");
    if (!('indexedDB' in window)) {
      appendLog("  IndexedDB NOT supported in this browser.");
      return;
    }
    if (!('databases' in indexedDB)) {
      appendLog("  Browser does not support indexedDB.databases() API. Skipping.");
      return;
    }
    try {
      const dbs = await indexedDB.databases();
      if (!dbs.length) {
        appendLog("  No IndexedDB databases found.");
        return;
      }
      for (let i = 0; i < dbs.length; i++) {
        const dbInfo = dbs[i];
        appendLog(`  DB #${i + 1}: ${dbInfo.name}`);
        await waitWhilePaused();
        if (stopped) {
          appendLog("!!! Stopped during IndexedDB dump.");
          return;
        }
        try {
          await dumpOneIndexedDB(dbInfo.name);
        } catch (e) {
          appendLog(`  ERROR reading DB ${dbInfo.name}: ${e.message}`);
        }
      }
      appendLog("!!! Finished dumping IndexedDB.");
    } catch (e) {
      appendLog(`  ERROR: ${e.message}`);
    }
  }

  async function dumpOneIndexedDB(name) {
    return new Promise((resolve, reject) => {
      const openReq = indexedDB.open(name);
      openReq.onerror = () => {
        appendLog(`    ERROR opening DB ${name}: ${openReq.error?.message || 'Unknown error'}`);
        reject(openReq.error);
      };
      openReq.onsuccess = async () => {
        const db = openReq.result;
        appendLog(`    Opened DB ${name}, version ${db.version}`);
        const storeNames = Array.from(db.objectStoreNames);
        for (let i = 0; i < storeNames.length; i++) {
          if (stopped) {
            appendLog("!!! Stopped during ObjectStore dump.");
            db.close();
            resolve();
            return;
          }
          await waitWhilePaused();
          appendLog(`    ObjectStore #${i + 1}/${storeNames.length}: ${storeNames[i]}`);
          try {
            await dumpObjectStore(db, storeNames[i]);
          } catch (e) {
            appendLog(`      ERROR accessing ObjectStore ${storeNames[i]}: ${e.message}`);
          }
        }
        db.close();
        resolve();
      };
    });
  }

  async function dumpObjectStore(db, storeName) {
    return new Promise((resolve, reject) => {
      const tx = db.transaction(storeName, "readonly");
      const store = tx.objectStore(storeName);
      const req = store.openCursor();
      let count = 0;
      req.onerror = () => {
        appendLog(`      Cursor error: ${req.error?.message || 'Unknown error'}`);
        reject(req.error);
      };
      req.onsuccess = (e) => {
        const cursor = e.target.result;
        if (cursor) {
          let valstr = "";
          try {
            valstr = JSON.stringify(cursor.value);
          } catch {
            valstr = '[Unserializable value]';
          }
          if (valstr.length > 200) valstr = valstr.slice(0, 200) + '...';
          appendLog(`      Key: ${cursor.key} => Value: ${valstr}`);
          count++;
          if (count >= 30) {
            appendLog(`      Limited output to first 30 entries.`);
            resolve();
            return;
          }
          cursor.continue();
        } else {
          appendLog(`      Finished dumping ObjectStore ${storeName}, ${count} entries.`);
          resolve();
        }
      };
    });
  }

  // --- MAIN PROCESS ---

  btnPauseResume.addEventListener('click', () => {
    paused = !paused;
    appendLog(paused ? "!!! Pausing process." : "!!! Resuming process.");
    btnPauseResume.textContent = paused ? 'Resume' : 'Pause';
  });

  btnStop.addEventListener('click', () => {
    if (!stopped) {
      stopped = true;
      appendLog("!!! Stopping process and cleaning up...");
    }
  });

  btnCodeViewer.addEventListener('click', () => {
    codeViewerIsVisible = !codeViewerIsVisible;
    codeViewer.style.display = codeViewerIsVisible ? 'block' : 'none';
    if (codeViewerIsVisible) updateCodeViewer();
  });

  btnSettings.addEventListener('click', () => {
    settingsPanel.style.display = settingsPanel.style.display === 'none' ? 'block' : 'none';
  });

  const verboseToggle = settingsPanel.querySelector('#verboseToggle');
  verboseToggle.checked = verbosePrint;
  verboseToggle.addEventListener('change', e => {
    verbosePrint = e.target.checked;
    appendLog(`!!! Verbose prints set to ${verbosePrint}`);
  });

  const speedSlider = settingsPanel.querySelector('#speedSlider');
  speedSlider.value = speedMultiplier;
  speedSlider.addEventListener('input', e => {
    speedMultiplier = parseFloat(e.target.value);
    appendLog(`!!! Speed multiplier set to ${speedMultiplier.toFixed(1)}`);
  });

  const maxLogInput = settingsPanel.querySelector('#maxLogLines');
  maxLogInput.value = maxLogLines;
  maxLogInput.addEventListener('change', e => {
    maxLogLines = Math.max(100, Math.min(10000, parseInt(e.target.value) || 2000));
    appendLog(`!!! Max log lines set to ${maxLogLines}`);
  });

  const maxCodeInput = settingsPanel.querySelector('#maxCodeLines');
  maxCodeInput.value = maxCodeViewerLines;
  maxCodeInput.addEventListener('change', e => {
    maxCodeViewerLines = Math.max(1000, Math.min(10000000, parseInt(e.target.value) || 5000));
    appendLog(`!!! Max code viewer lines set to ${maxCodeViewerLines}`);
  });

  const closeSettingsBtn = settingsPanel.querySelector('#closeSettingsBtn');
  closeSettingsBtn.addEventListener('click', () => {
    settingsPanel.style.display = 'none';
  });

  // Command input processing
  commandInput.addEventListener('keyup', e => {
    if (e.key === 'Enter') {
      const cmd = commandInput.value.trim().toLowerCase();
      commandInput.value = "";
      appendLog(`>>> > ${cmd}`);
      processCommand(cmd);
    }
  });

  function processCommand(cmd) {
    switch (cmd) {
      case 'pause':
        if (!paused) {
          paused = true;
          appendLog("!!! Command: pause - process paused");
          btnPauseResume.textContent = 'Resume';
        } else {
          appendLog("!!! Process is already paused.");
        }
        break;
      case 'resume':
        if (paused) {
          paused = false;
          appendLog("!!! Command: resume - process resumed");
          btnPauseResume.textContent = 'Pause';
        } else {
          appendLog("!!! Process is already running.");
        }
        break;
      case 'stop':
        if (!stopped) {
          stopped = true;
          appendLog("!!! Command: stop - process stopping...");
        } else {
          appendLog("!!! Process is already stopped.");
        }
        break;
      case 'help':
        appendLog("!!! Commands available: pause, resume, stop, help");
        break;
      default:
        appendLog(`!!! Unknown command: ${cmd}. Type 'help' for list.`);
        break;
    }
  }

  // --- LONG PROCESS ---
  appendLog("!!! Starting page copying process ...");
  appendLog("!!! You can control the process with the command input below.");
  appendLog("!!! Type 'help' and press Enter for commands.");

  clearCodeViewer();

  async function longProcess() {
    // Clear vars
    snapshotBuilder = [];
    updateCodeViewer();

    // Step 1: Dump storage etc
    appendLog("!!! Step 1: Reading localStorage");
    dumpLocalStorage();
    if (!(await waitWhilePaused())) return;
    await sleep(2000 / speedMultiplier);
    if (stopped) return;

    appendLog("!!! Step 2: Reading sessionStorage");
    dumpSessionStorage();
    if (!(await waitWhilePaused())) return;
    await sleep(2000 / speedMultiplier);
    if (stopped) return;

    appendLog("!!! Step 3: Reading cookies");
    dumpCookies();
    if (!(await waitWhilePaused())) return;
    await sleep(1500 / speedMultiplier);
    if (stopped) return;

    appendLog("!!! Step 4: Reading IndexedDB (may take long)");
    await dumpIndexedDB();
    if (stopped) return;

    // Step 5: Get doctype and clone html
    appendLog("!!! Step 5: Getting DOCTYPE");
    appendSnapshot(getDoctypeStr());
    if (!(await waitWhilePaused())) return;

    appendLog("!!! Step 6: Cloning <html> element");
    const htmlClone = document.documentElement.cloneNode(true);
    cleanClonedHTML(htmlClone);
    appendLog("!!! Removed scripts, styles and event handlers from cloned <html>");

    if (!(await waitWhilePaused())) return;

    // Step 7: Gather CSS
    appendLog("!!! Step 7: Gathering CSS");
    let combinedCSS = '';
    const allStylesheets = Array.from(document.styleSheets);

    for (let i = 0; i < allStylesheets.length; i++) {
      if (stopped) break;
      if (!(await waitWhilePaused())) return;

      const sheet = allStylesheets[i];
      if (sheet.href) {
        appendLog(`!!! Loading external CSS ${i + 1}/${allStylesheets.length}: ${sheet.href}`);
        const res = await fetchText(sheet.href);
        if (res.ok) combinedCSS += `/* CSS from ${sheet.href} */\n${res.text}\n\n`;
        else combinedCSS += `/* ERROR loading CSS ${sheet.href} - ${res.error} */\n\n`;
      } else {
        appendLog(`!!! Reading inline CSS ${i + 1}/${allStylesheets.length}`);
        try {
          let cssText = '';
          for (const rule of sheet.cssRules) cssText += rule.cssText + "\n";
          combinedCSS += `/* Inline CSS */\n${cssText}\n\n`;
        } catch (e) {
          combinedCSS += '/* Inline CSS inaccessible - skipped */\n\n';
          appendLog('!!! Warning: Inline CSS inaccessible due to CORS/restrictions');
        }
      }
      updateProgress((i / allStylesheets.length) * 0.1);
      await sleep(1500 / speedMultiplier);
    }

    if (stopped) return;

    // Step 8: Gather JS
    appendLog("!!! Step 8: Gathering JS");
    let combinedJS = '';
    const scripts = Array.from(document.querySelectorAll('script'));

    for (let i = 0; i < scripts.length; i++) {
      if (stopped) break;
      if (!(await waitWhilePaused())) return;

      const script = scripts[i];
      if (script.src && script.src.trim()) {
        appendLog(`!!! Loading external JS ${i + 1}/${scripts.length}: ${script.src}`);
        const res = await fetchText(script.src);
        if (res.ok) combinedJS += `/* JS from ${script.src} */\n${res.text}\n\n`;
        else combinedJS += `/* ERROR loading JS ${script.src} - ${res.error} */\n\n`;
      } else {
        appendLog(`!!! Reading inline JS ${i + 1}/${scripts.length}`);
        combinedJS += `/* Inline JS */\n${script.textContent}\n\n`;
      }
      updateProgress(0.1 + (i / scripts.length) * 0.1);
      await sleep(1500 / speedMultiplier);
    }

    if (stopped) return;

    // Step 9: Inject CSS and JS into cloned document
    appendLog("!!! Step 9: Injecting CSS and JS into cloned document");
    let head = htmlClone.querySelector('head');
    if (!head) {
      appendLog("!!! Warning: no <head> found, creating one");
      head = document.createElement('head');
      htmlClone.insertBefore(head, htmlClone.firstChild);
    }
    const styleEl = document.createElement('style');
    styleEl.type = 'text/css';
    styleEl.textContent = combinedCSS;
    head.appendChild(styleEl);

    let body = htmlClone.querySelector('body');
    if (!body) {
      appendLog("!!! Warning: no <body> found, creating one");
      body = document.createElement('body');
      htmlClone.appendChild(body);
    }
    const scriptEl = document.createElement('script');
    scriptEl.type = 'text/javascript';
    scriptEl.textContent = combinedJS;
    body.appendChild(scriptEl);

    updateProgress(0.25);

    if (!(await waitWhilePaused())) return;

    // Step 10: Add banner inside body
    appendLog("!!! Step 10: Adding info banner inside snapshot");
    const infoDiv = document.createElement('div');
    infoDiv.textContent = `This page is a copied snapshot created on ${new Date().toLocaleString()}`;
    Object.assign(infoDiv.style, {
      position: 'fixed',
      top: '0',
      left: '0',
      width: '100%',
      backgroundColor: '#0f0',
      color: '#000',
      padding: '8px',
      fontWeight: 'bold',
      textAlign: 'center',
      zIndex: '999999999',
      fontFamily: 'monospace',
    });
    body.insertBefore(infoDiv, body.firstChild);

    await sleep(1500 / speedMultiplier);
    updateProgress(0.3);

    // Step 11: Serialize document and build snapshot progressively
    appendLog("!!! Step 11: Serializing final HTML snapshot progressively");
    let finalHTML = getDoctypeStr() + htmlClone.outerHTML;

    // Split lines for progressive building
    // (actual HTML may not have many newlines, so add some replacement for readability)
    finalHTML = finalHTML.replace(/></g, ">\n<");

    const lines = finalHTML.split(/\r?\n/);
    snapshotBuilder = [];

    for (let i = 0; i < lines.length; i++) {
      if (stopped) break;
      if (!(await waitWhilePaused())) return;

      snapshotBuilder.push(lines[i] + "\n");

      if (i % 50 === 0) updateCodeViewer();

      let fraction = 0.3 + ((i / lines.length) * 0.68);
      updateProgress(fraction);

      await sleep(15 / speedMultiplier); // adjust speed if needed
    }

    updateCodeViewer();

    if (stopped) return;

    // Step 12: Trigger download
    appendLog("!!! Step 12: Preparing to download snapshot...");
    updateProgress(0.99);

    const blobText = snapshotBuilder.join('');
    const blob = new Blob([blobText], { type: 'text/html' });
    const url = URL.createObjectURL(blob);
    const filename = `page-copied-${new Date().toISOString().replace(/[T:.]/g, '-').slice(0, -5)}.html`;

    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);

    appendLog(`!!! Triggering download: ${filename}`);
    a.click();

    setTimeout(() => {
      URL.revokeObjectURL(url);
      a.remove();
      updateProgress(1);
      appendLog("!!! Download complete. Cleaning up overlay...");
      cleanup();
    }, 2500);
  }

  function cleanup() {
    overlay.remove();
    codeViewer.remove();
    settingsPanel.remove();
  }

  // Expose periodic code viewer update
  setInterval(() => {
    if (codeViewerIsVisible) updateCodeViewer();
  }, 1000);

  // Start main process
  longProcess();

})();