{"id":4953,"date":"2026-06-03T16:25:37","date_gmt":"2026-06-03T16:25:37","guid":{"rendered":"https:\/\/primetoolhub.com\/?page_id=4953"},"modified":"2026-08-08T06:30:33","modified_gmt":"2026-08-08T06:30:33","slug":"advanced-offline-document-organizer","status":"publish","type":"page","link":"https:\/\/schoolict.net\/tools\/advanced-offline-document-organizer\/","title":{"rendered":"Advanced Offline Document Organizer (Word, Excel, PDF)"},"content":{"rendered":"<div class=\"pth-hero-section\">\n<div class=\"pth-hero-content\">\n<h2>Advanced Offline Document Viewer &#038; Organizer (Word, Excel, PDF)<\/h2>\n<p>Securely view, extract, and manage files with our free offline document organizer. Read Word, Excel, and PDF files directly in your browser with zero uploads.<\/p>\n<div id=\"pth-toc-placeholder\"><\/div>\n<\/p>\n<\/div>\n<div class=\"pth-hero-image\">\n        <img decoding=\"async\" data-no-lazy=\"1\" width=\"450\" height=\"253\" src=\"https:\/\/schoolict.net\/tools\/wp-content\/uploads\/2026\/06\/Offline-Document-Viewer-800x447.jpeg\" alt=\"offline document viewer\">\n    <\/div>\n<\/div>\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>Table of Contents<\/h2><nav><ul><li><a href=\"#\ud83d\udfe7-client-side-dom-manipulation-and-cpu-processing\">\ud83d\udfe7 Client-Side DOM Manipulation and CPU Processing<\/a><ul><li><a href=\"#\ud83d\udfe8-mathematical-precision-and-data-security\">\ud83d\udfe8 Mathematical Precision and Data Security<\/a><\/li><li><a href=\"#\ud83d\udfe9-expanding-your-local-development-utilities\">\ud83d\udfe9 Expanding Your Local Development Utilities<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n\n\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/mammoth\/1.6.0\/mammoth.browser.min.js\" data-no-optimize=\"1\" data-no-minify=\"1\" data-cfasync=\"false\"><\/script>\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/xlsx\/0.18.5\/xlsx.full.min.js\" data-no-optimize=\"1\" data-no-minify=\"1\" data-cfasync=\"false\"><\/script>\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jszip\/3.10.1\/jszip.min.js\" data-no-optimize=\"1\" data-no-minify=\"1\" data-cfasync=\"false\"><\/script>\r\n\r\n<style>\r\n@import url('https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&family=Crimson+Pro:ital,wght@0,400;0,600;1,400&display=swap');\r\n\r\n\/* =========================================================================\r\n   STRICT SCOPED CSS (ANTI-BLEED) - KEEPS ORIGINAL CLASSES SAFE\r\n========================================================================= *\/\r\n#pth-advdocorg-wrapper {\r\n  --bg:#f0f2f6;--surface:#fff;--s2:#f7f8fb;--s3:#eef0f5;--border:#dde2ec;--bstrong:#c4cad8;\r\n  --text:#111827;--t2:#4b5563;--t3:#9ca3af;\r\n  --blue:#2563eb;--bl:#eff6ff;--bm:#bfdbfe;\r\n  --green:#059669;--gl:#ecfdf5;\r\n  --red:#dc2626;--rl:#fef2f2;\r\n  --amber:#d97706;--al:#fffbeb;\r\n  --purple:#7c3aed;--pl:#f5f3ff;\r\n  --cyan:#0891b2;--cl:#ecfeff;\r\n  --pink:#db2777;--pkl:#fdf2f8;\r\n  --word:#1a56db;--excel:#057a55;--pdf:#c81e1e;\r\n  --ppt:#c2410c;--txt:#6b21a8;--csv:#065f46;\r\n  --json:#92400e;--xml:#1e3a5f;--md:#374151;\r\n  --r:6px;--rl2:10px;--rx:14px;--rxx:18px;\r\n  --sh:0 1px 3px rgba(0,0,0,.07),0 1px 2px rgba(0,0,0,.04);\r\n  --shm:0 4px 12px rgba(0,0,0,.08);\r\n  --shl:0 8px 24px rgba(0,0,0,.1);\r\n  --shx:0 20px 48px rgba(0,0,0,.15);\r\n  --font:'Inter',system-ui,sans-serif;\r\n  --mono:'JetBrains Mono',monospace;\r\n  --serif:'Crimson Pro',Georgia,serif;\r\n  \r\n  font-family:var(--font);background:var(--bg);color:var(--text);font-size:14px;line-height:1.5; text-align:left;\r\n}\r\n\r\n#pth-advdocorg-wrapper *, #pth-advdocorg-wrapper *::before, #pth-advdocorg-wrapper *::after{box-sizing:border-box;margin:0;padding:0}\r\n#pth-advdocorg-wrapper #app{max-width:1600px;margin:0 auto;padding:14px; background:var(--bg); color:var(--text);}\r\n#pth-advdocorg-wrapper ::-webkit-scrollbar{width:5px;height:5px}\r\n#pth-advdocorg-wrapper ::-webkit-scrollbar-track{background:transparent}\r\n#pth-advdocorg-wrapper ::-webkit-scrollbar-thumb{background:var(--border);border-radius:4px}\r\n#pth-advdocorg-wrapper .topbar{display:flex;align-items:center;justify-content:space-between;background:var(--text);color:#fff;border-radius:var(--rx);padding:12px 20px;margin-bottom:13px;box-shadow:var(--shl);flex-wrap:wrap;gap:10px}\r\n#pth-advdocorg-wrapper .brand{display:flex;align-items:center;gap:12px}\r\n#pth-advdocorg-wrapper .brand-icon{width:40px;height:40px;border-radius:var(--r);background:linear-gradient(135deg,#3b82f6,#8b5cf6);display:flex;align-items:center;justify-content:center;font-size:20px;flex-shrink:0}\r\n#pth-advdocorg-wrapper .brand-name{font-size:16px;font-weight:800;letter-spacing:-.3px}\r\n#pth-advdocorg-wrapper .brand-name span{color:#60a5fa}\r\n#pth-advdocorg-wrapper .brand-sub{font-size:11px;color:rgba(255,255,255,.4);margin-top:1px}\r\n#pth-advdocorg-wrapper .pro-badge{background:linear-gradient(90deg,#10b981,#059669);color:#fff;font-size:9px;font-weight:700;padding:2px 7px;border-radius:20px;letter-spacing:.5px;text-transform:uppercase;margin-left:6px}\r\n#pth-advdocorg-wrapper .topbar-right{display:flex;gap:7px;align-items:center;flex-wrap:wrap}\r\n\r\n#pth-advdocorg-wrapper .pth-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:7px 14px;border-radius:var(--r);border:none;font-weight:600;font-size:12px;cursor:pointer;font-family:var(--font);transition:all .16s;white-space:nowrap;line-height:1}\r\n#pth-advdocorg-wrapper .pth-btn:disabled{opacity:.4;cursor:not-allowed;transform:none!important;pointer-events:none}\r\n#pth-advdocorg-wrapper .pth-btn-primary{background:var(--blue);color:#fff;box-shadow:0 2px 6px rgba(37,99,235,.28)}\r\n#pth-advdocorg-wrapper .pth-btn-primary:hover{background:#1d4ed8;transform:translateY(-1px)}\r\n#pth-advdocorg-wrapper .pth-btn-dark{background:var(--text);color:#fff}\r\n#pth-advdocorg-wrapper .pth-btn-dark:hover{background:#1f2937;transform:translateY(-1px)}\r\n#pth-advdocorg-wrapper .pth-btn-success{background:var(--green);color:#fff;box-shadow:0 2px 6px rgba(5,150,105,.28)}\r\n#pth-advdocorg-wrapper .pth-btn-success:hover{background:#047857;transform:translateY(-1px)}\r\n#pth-advdocorg-wrapper .pth-btn-danger{background:var(--rl);color:var(--red);border:1px solid #fecaca}\r\n#pth-advdocorg-wrapper .pth-btn-danger:hover{background:#fee2e2}\r\n#pth-advdocorg-wrapper .pth-btn-secondary{background:var(--s3);color:var(--t2);border:1px solid var(--border)}\r\n#pth-advdocorg-wrapper .pth-btn-secondary:hover{background:var(--border);color:var(--text)}\r\n#pth-advdocorg-wrapper .pth-btn-outline{background:transparent;color:var(--t2);border:1px solid var(--bstrong)}\r\n#pth-advdocorg-wrapper .pth-btn-outline:hover{background:var(--s3);color:var(--text)}\r\n#pth-advdocorg-wrapper .pth-btn-ghost{background:rgba(255,255,255,.1);color:#fff;border:1px solid rgba(255,255,255,.15)}\r\n#pth-advdocorg-wrapper .pth-btn-ghost:hover{background:rgba(255,255,255,.2)}\r\n#pth-advdocorg-wrapper .pth-btn-amber{background:var(--al);color:var(--amber);border:1px solid #fde68a}\r\n#pth-advdocorg-wrapper .pth-btn-amber:hover{background:#fef3c7}\r\n#pth-advdocorg-wrapper .pth-btn-sm{padding:5px 10px;font-size:11px;border-radius:5px}\r\n#pth-advdocorg-wrapper .pth-btn-xs{padding:3px 8px;font-size:10px;border-radius:4px}\r\n#pth-advdocorg-wrapper .pth-btn-icon{padding:6px;width:30px;height:30px}\r\n\r\n#pth-advdocorg-wrapper .stats-bar{display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:9px;margin-bottom:13px}\r\n#pth-advdocorg-wrapper .stat-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--rl2);padding:12px 14px;display:flex;align-items:center;gap:11px;box-shadow:var(--sh)}\r\n#pth-advdocorg-wrapper .stat-icon{font-size:20px;flex-shrink:0}\r\n#pth-advdocorg-wrapper .stat-val{font-size:19px;font-weight:800;color:var(--text);line-height:1;font-variant-numeric:tabular-nums}\r\n#pth-advdocorg-wrapper .stat-lbl{font-size:10px;color:var(--t3);font-weight:600;text-transform:uppercase;letter-spacing:.5px;margin-top:2px}\r\n\r\n#pth-advdocorg-wrapper #dropzone{border:2px dashed var(--bstrong);border-radius:var(--rxx);padding:52px 30px;text-align:center;background:var(--surface);cursor:pointer;transition:all .2s;margin-bottom:13px;box-shadow:var(--sh)}\r\n#pth-advdocorg-wrapper #dropzone:hover,#pth-advdocorg-wrapper #dropzone.dragover{border-color:var(--blue);background:var(--bl)}\r\n#pth-advdocorg-wrapper .drop-icon{font-size:52px;display:block;margin-bottom:14px}\r\n#pth-advdocorg-wrapper .drop-title{font-size:20px;font-weight:800;color:var(--text);margin-bottom:8px;letter-spacing:-.3px}\r\n#pth-advdocorg-wrapper .drop-sub{font-size:13px;color:var(--t2);max-width:500px;margin:0 auto 24px;line-height:1.7}\r\n#pth-advdocorg-wrapper .drop-btns{display:flex;gap:11px;justify-content:center;flex-wrap:wrap;margin-bottom:10px}\r\n#pth-advdocorg-wrapper .badges{display:flex;gap:7px;justify-content:center;flex-wrap:wrap;margin-top:20px}\r\n#pth-advdocorg-wrapper .fbadge{padding:3px 11px;border-radius:20px;font-size:10px;font-weight:700;letter-spacing:.3px}\r\n#pth-advdocorg-wrapper .b-word{background:#eff6ff;color:var(--word);border:1px solid #bfdbfe}\r\n#pth-advdocorg-wrapper .b-excel{background:var(--gl);color:var(--excel);border:1px solid #a7f3d0}\r\n#pth-advdocorg-wrapper .b-pdf{background:var(--rl);color:var(--pdf);border:1px solid #fecaca}\r\n#pth-advdocorg-wrapper .b-ppt{background:#fff7ed;color:var(--ppt);border:1px solid #fed7aa}\r\n#pth-advdocorg-wrapper .b-text{background:var(--pl);color:var(--purple);border:1px solid #ddd6fe}\r\n#pth-advdocorg-wrapper .b-data{background:var(--al);color:var(--amber);border:1px solid #fde68a}\r\n\r\n#pth-advdocorg-wrapper .smart-panel{background:linear-gradient(135deg,rgba(37,99,235,.04),rgba(124,58,237,.04));border:1px solid var(--bm);border-radius:var(--rl2);padding:13px 17px;margin-bottom:13px}\r\n#pth-advdocorg-wrapper .sp-title{font-size:11px;font-weight:700;color:var(--blue);text-transform:uppercase;letter-spacing:.6px;margin-bottom:10px}\r\n#pth-advdocorg-wrapper .smart-row{display:flex;gap:7px;flex-wrap:wrap;align-items:center}\r\n#pth-advdocorg-wrapper .date-filter-row{display:flex;align-items:center;gap:10px;background:var(--surface);border:1px solid var(--border);padding:7px 13px;border-radius:var(--r);width:fit-content;flex-wrap:wrap;gap:8px}\r\n#pth-advdocorg-wrapper .date-lbl{font-size:11px;font-weight:700;color:var(--t3)}\r\n#pth-advdocorg-wrapper .date-inp{border:none;outline:none;font-size:12px;color:var(--t2);font-family:var(--font);background:transparent;cursor:pointer}\r\n#pth-advdocorg-wrapper .date-inp::-webkit-calendar-picker-indicator{cursor:pointer;opacity:.6}\r\n\r\n#pth-advdocorg-wrapper .fts-bar{background:var(--surface);border:1px solid var(--border);border-radius:var(--rl2);padding:13px 17px;margin-bottom:13px;display:none}\r\n#pth-advdocorg-wrapper .fts-bar.open{display:block}\r\n#pth-advdocorg-wrapper .fts-row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}\r\n#pth-advdocorg-wrapper .fts-input{flex:1;min-width:200px;padding:8px 13px;border:1.5px solid var(--border);border-radius:var(--r);font-size:13px;font-family:var(--font);outline:none;background:var(--surface);color:var(--text)}\r\n#pth-advdocorg-wrapper .fts-input:focus{border-color:var(--blue);box-shadow:0 0 0 3px rgba(37,99,235,.1)}\r\n#pth-advdocorg-wrapper .fts-results{margin-top:12px;max-height:280px;overflow-y:auto;display:flex;flex-direction:column;gap:6px}\r\n#pth-advdocorg-wrapper .fts-hit{background:var(--s2);border:1px solid var(--border);border-radius:var(--r);padding:10px 14px;cursor:pointer;transition:.15s}\r\n#pth-advdocorg-wrapper .fts-hit:hover{border-color:var(--blue);background:var(--bl)}\r\n#pth-advdocorg-wrapper .fts-hit-name{font-weight:700;font-size:13px;color:var(--text);margin-bottom:4px}\r\n#pth-advdocorg-wrapper .fts-hit-ctx{font-size:12px;color:var(--t2);line-height:1.6}\r\n#pth-advdocorg-wrapper .fts-hit-ctx mark{background:#fef08a;color:var(--text);border-radius:2px;padding:0 2px}\r\n#pth-advdocorg-wrapper .fts-stats{font-size:11px;color:var(--t3);font-weight:600;padding:4px 0}\r\n\r\n#pth-advdocorg-wrapper .main-layout{display:grid;grid-template-columns:230px 1fr;gap:13px;align-items:start}\r\n#pth-advdocorg-wrapper .main-layout.expanded{grid-template-columns:1fr}\r\n#pth-advdocorg-wrapper .main-layout.compare-mode{grid-template-columns:1fr 1fr}\r\n\r\n#pth-advdocorg-wrapper .sidebar{display:flex;flex-direction:column;gap:11px;position:sticky;top:14px}\r\n#pth-advdocorg-wrapper .panel{background:var(--surface);border:1px solid var(--border);border-radius:var(--rl2);padding:14px;box-shadow:var(--sh)}\r\n#pth-advdocorg-wrapper .ptitle{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.8px;color:var(--t3);margin-bottom:9px;display:flex;align-items:center;justify-content:space-between}\r\n#pth-advdocorg-wrapper .folder-list{max-height:200px;overflow-y:auto}\r\n#pth-advdocorg-wrapper .fi{display:flex;align-items:center;justify-content:space-between;padding:6px 9px;border-radius:5px;cursor:pointer;font-weight:600;font-size:12px;color:var(--t2);transition:.14s;margin-bottom:2px}\r\n#pth-advdocorg-wrapper .fi:hover{background:var(--s3);color:var(--text)}\r\n#pth-advdocorg-wrapper .fi.active{background:var(--bl);color:var(--blue);border:1px solid var(--bm)}\r\n#pth-advdocorg-wrapper .fi-left{display:flex;align-items:center;gap:7px;overflow:hidden}\r\n#pth-advdocorg-wrapper .fi-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\r\n#pth-advdocorg-wrapper .fi-count{background:var(--s3);padding:1px 7px;border-radius:10px;font-size:10px;color:var(--t3);flex-shrink:0}\r\n#pth-advdocorg-wrapper .fi.active .fi-count{background:var(--blue);color:#fff}\r\n#pth-advdocorg-wrapper .fi-star{color:#fbbf24;cursor:pointer;padding:2px 5px;font-size:13px}\r\n#pth-advdocorg-wrapper .empty-hint{font-size:11px;color:var(--t3);padding:5px 4px}\r\n#pth-advdocorg-wrapper .storage-row{border-top:1px solid var(--s3);margin-top:11px;padding-top:11px;display:flex;justify-content:space-between;font-size:11px;font-weight:600;color:var(--t2);margin-bottom:5px}\r\n#pth-advdocorg-wrapper .prog-track{height:4px;background:var(--border);border-radius:3px;overflow:hidden}\r\n#pth-advdocorg-wrapper .prog-fill{height:100%;background:linear-gradient(90deg,var(--blue),var(--purple));border-radius:3px;transition:width .5s}\r\n\r\n#pth-advdocorg-wrapper .recent-item{display:flex;align-items:center;gap:8px;padding:5px 8px;border-radius:5px;cursor:pointer;font-size:12px;color:var(--t2);transition:.14s}\r\n#pth-advdocorg-wrapper .recent-item:hover{background:var(--s3);color:var(--text)}\r\n\r\n#pth-advdocorg-wrapper .gallery-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--rl2);padding:17px;box-shadow:var(--sh)}\r\n#pth-advdocorg-wrapper .toolbar{display:flex;flex-wrap:wrap;gap:7px;align-items:center;padding:11px 13px;background:var(--s2);border:1px solid var(--border);border-radius:var(--r);margin-bottom:11px}\r\n#pth-advdocorg-wrapper .toolbar-title{font-size:15px;font-weight:800;color:var(--text)}\r\n#pth-advdocorg-wrapper .dvdr{width:1px;height:20px;background:var(--border);margin:0 2px;flex-shrink:0}\r\n#pth-advdocorg-wrapper .tr{margin-left:auto;display:flex;gap:6px;align-items:center}\r\n#pth-advdocorg-wrapper .filter-bar{display:flex;gap:6px;flex-wrap:wrap;align-items:center;margin-bottom:12px}\r\n#pth-advdocorg-wrapper .ftag{padding:5px 12px;border-radius:20px;font-size:12px;font-weight:600;cursor:pointer;border:1px solid var(--border);background:var(--surface);color:var(--t3);transition:.14s;font-family:var(--font)}\r\n#pth-advdocorg-wrapper .ftag:hover{border-color:var(--bstrong);color:var(--t2)}\r\n#pth-advdocorg-wrapper .ftag.active{background:var(--blue);color:#fff;border-color:var(--blue)}\r\n#pth-advdocorg-wrapper .sbox{padding:7px 11px;border:1px solid var(--border);border-radius:var(--r);font-size:13px;outline:none;font-family:var(--font);background:var(--surface);color:var(--text);min-width:170px;transition:.15s}\r\n#pth-advdocorg-wrapper .sbox:focus{border-color:var(--blue);box-shadow:0 0 0 3px rgba(37,99,235,.1)}\r\n#pth-advdocorg-wrapper .sselect{padding:6px 9px;border:1px solid var(--border);border-radius:var(--r);font-size:12px;font-family:var(--font);background:var(--surface);color:var(--t2);outline:none;cursor:pointer;font-weight:500}\r\n#pth-advdocorg-wrapper .vtoggle{display:flex;background:var(--s3);border-radius:var(--r);padding:3px;border:1px solid var(--border)}\r\n#pth-advdocorg-wrapper .vbtn{padding:4px 9px;border:none;background:transparent;cursor:pointer;border-radius:4px;color:var(--t3);font-size:13px;transition:.14s}\r\n#pth-advdocorg-wrapper .vbtn.active{background:var(--surface);box-shadow:var(--sh);color:var(--text)}\r\n\r\n#pth-advdocorg-wrapper .fgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(175px,1fr));gap:12px;max-height:58vh;overflow-y:auto;padding-right:4px;padding-bottom:10px}\r\n#pth-advdocorg-wrapper .fgrid.list-view{grid-template-columns:1fr}\r\n#pth-advdocorg-wrapper .fgrid.list-view .fcard{flex-direction:row;height:auto}\r\n#pth-advdocorg-wrapper .fgrid.list-view .card-strip{width:5px;height:auto;min-height:56px;flex-shrink:0}\r\n#pth-advdocorg-wrapper .fgrid.list-view .card-prev{min-height:56px;width:68px;min-width:68px;border-bottom:none;border-right:1px solid var(--border);border-radius:0;padding:8px}\r\n#pth-advdocorg-wrapper .fgrid.list-view .card-info{flex:1;border-top:none;display:flex;align-items:center;justify-content:space-between;padding:0 13px}\r\n#pth-advdocorg-wrapper .fgrid.list-view .card-checkbox{position:static;margin-left:11px}\r\n#pth-advdocorg-wrapper .fgrid.list-view .card-actions{display:flex;gap:5px;flex-shrink:0;margin-right:11px}\r\n#pth-advdocorg-wrapper .gallery-empty{grid-column:1\/-1;text-align:center;padding:60px;border:2px dashed var(--border);border-radius:var(--rl2);color:var(--t3)}\r\n\r\n#pth-advdocorg-wrapper .fcard{background:var(--surface);border:1px solid var(--border);border-radius:var(--rl2);overflow:hidden;position:relative;transition:all .18s;cursor:pointer;display:flex;flex-direction:column}\r\n#pth-advdocorg-wrapper .fcard:hover{border-color:var(--blue);box-shadow:var(--shl);transform:translateY(-2px)}\r\n#pth-advdocorg-wrapper .fcard.selected{border:2px solid var(--blue);box-shadow:0 0 0 3px rgba(37,99,235,.1)}\r\n#pth-advdocorg-wrapper .fcard.starred::after{content:'\u2b50';position:absolute;top:7px;right:7px;font-size:12px;z-index:5}\r\n#pth-advdocorg-wrapper .card-checkbox{position:absolute;top:9px;left:9px;width:17px;height:17px;z-index:10;cursor:pointer;accent-color:var(--blue)}\r\n#pth-advdocorg-wrapper .card-strip{height:4px;width:100%;flex-shrink:0}\r\n#pth-advdocorg-wrapper .s-word{background:linear-gradient(90deg,#2563eb,#1d4ed8)}\r\n#pth-advdocorg-wrapper .s-excel{background:linear-gradient(90deg,#059669,#047857)}\r\n#pth-advdocorg-wrapper .s-pdf{background:linear-gradient(90deg,#dc2626,#b91c1c)}\r\n#pth-advdocorg-wrapper .s-ppt{background:linear-gradient(90deg,#ea580c,#c2410c)}\r\n#pth-advdocorg-wrapper .s-txt{background:linear-gradient(90deg,#7c3aed,#6d28d9)}\r\n#pth-advdocorg-wrapper .s-csv{background:linear-gradient(90deg,#065f46,#064e3b)}\r\n#pth-advdocorg-wrapper .s-json{background:linear-gradient(90deg,#d97706,#b45309)}\r\n#pth-advdocorg-wrapper .s-xml{background:linear-gradient(90deg,#1e40af,#1e3a8a)}\r\n#pth-advdocorg-wrapper .s-md{background:linear-gradient(90deg,#374151,#1f2937)}\r\n#pth-advdocorg-wrapper .s-other{background:linear-gradient(90deg,#6b7280,#4b5563)}\r\n#pth-advdocorg-wrapper .card-prev{flex:1;background:var(--s2);display:flex;align-items:center;justify-content:center;padding:14px;min-height:105px;border-bottom:1px solid var(--border);overflow:hidden;position:relative}\r\n#pth-advdocorg-wrapper .card-ficon{display:flex;flex-direction:column;align-items:center;gap:7px}\r\n#pth-advdocorg-wrapper .card-tlabel{font-size:10px;font-weight:800;letter-spacing:.8px;text-transform:uppercase;padding:2px 7px;border-radius:4px;font-family:var(--mono)}\r\n#pth-advdocorg-wrapper .card-thumb{font-family:var(--mono);font-size:9px;line-height:1.5;color:var(--t2);width:100%;overflow:hidden;max-height:88px;word-break:break-all}\r\n#pth-advdocorg-wrapper .card-tag{position:absolute;bottom:6px;left:6px;display:flex;gap:3px;flex-wrap:wrap}\r\n#pth-advdocorg-wrapper .ctag{padding:1px 5px;border-radius:3px;font-size:9px;font-weight:700}\r\n#pth-advdocorg-wrapper .dup-badge{position:absolute;top:6px;right:6px;background:var(--red);color:#fff;font-size:9px;padding:1px 5px;border-radius:3px;font-weight:800;z-index:5}\r\n#pth-advdocorg-wrapper .card-info{padding:9px 11px;background:var(--surface)}\r\n#pth-advdocorg-wrapper .card-name{font-weight:600;color:var(--text);font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-bottom:4px}\r\n#pth-advdocorg-wrapper .card-meta{display:flex;justify-content:space-between;font-size:10px;color:var(--t3)}\r\n#pth-advdocorg-wrapper .card-ext{font-weight:700;text-transform:uppercase;font-family:var(--mono)}\r\n\r\n#pth-advdocorg-wrapper .tools-panel{background:var(--surface);border:1px solid var(--border);border-radius:var(--rl2);padding:15px;margin-bottom:13px;box-shadow:var(--sh);display:none}\r\n#pth-advdocorg-wrapper .tools-panel.open{display:block}\r\n#pth-advdocorg-wrapper .tgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(255px,1fr));gap:13px;margin-top:11px}\r\n#pth-advdocorg-wrapper .tbox{background:var(--s2);border:1px solid var(--border);border-radius:var(--r);padding:13px}\r\n#pth-advdocorg-wrapper .tbox-title{font-size:12px;font-weight:700;color:var(--t2);margin-bottom:11px;display:flex;align-items:center;gap:7px}\r\n#pth-advdocorg-wrapper .trow{display:flex;gap:7px;align-items:center;margin-bottom:8px}\r\n#pth-advdocorg-wrapper .tlbl{font-size:12px;color:var(--t2);font-weight:500;min-width:72px}\r\n#pth-advdocorg-wrapper .tinput{flex:1;padding:6px 9px;border:1px solid var(--border);border-radius:5px;font-size:12px;font-family:var(--font);outline:none;background:var(--surface);color:var(--text)}\r\n#pth-advdocorg-wrapper .tinput:focus{border-color:var(--blue)}\r\n#pth-advdocorg-wrapper .tresult{background:var(--surface);border:1px solid var(--border);border-radius:5px;padding:9px 11px;margin-top:9px;font-size:11px;max-height:160px;overflow-y:auto}\r\n\r\n#pth-advdocorg-wrapper .overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.68);z-index:99999;align-items:center;justify-content:center;backdrop-filter:blur(4px)}\r\n#pth-advdocorg-wrapper .overlay.open{display:flex}\r\n#pth-advdocorg-wrapper .prev-wrapper{background:var(--s2);width:97%;max-width:1150px;height:93vh;border-radius:var(--rxx);display:flex;flex-direction:column;overflow:hidden;box-shadow:var(--shx);animation:si .2s ease}\r\n@keyframes si{from{opacity:0;transform:scale(.97) translateY(-8px)}to{opacity:1;transform:scale(1) translateY(0)}}\r\n#pth-advdocorg-wrapper .prev-header{padding:13px 20px;background:var(--text);color:#fff;display:flex;justify-content:space-between;align-items:center;gap:11px;flex-wrap:wrap;flex-shrink:0}\r\n#pth-advdocorg-wrapper .prev-finfo{display:flex;align-items:center;gap:11px}\r\n#pth-advdocorg-wrapper .prev-ibox{width:36px;height:36px;border-radius:var(--r);display:flex;align-items:center;justify-content:center;font-size:19px;flex-shrink:0}\r\n#pth-advdocorg-wrapper .prev-fname{font-weight:700;font-size:14px;color:#fff}\r\n#pth-advdocorg-wrapper .prev-fmeta{font-size:11px;color:rgba(255,255,255,.4);margin-top:1px}\r\n#pth-advdocorg-wrapper .prev-actions{display:flex;gap:7px;align-items:center;flex-wrap:wrap}\r\n#pth-advdocorg-wrapper .prev-tabs{display:flex;background:var(--s3);border-bottom:1px solid var(--border);flex-shrink:0;overflow-x:auto}\r\n#pth-advdocorg-wrapper .ptab{padding:9px 17px;font-size:12px;font-weight:600;cursor:pointer;border:none;background:transparent;color:var(--t3);font-family:var(--font);border-bottom:2px solid transparent;transition:.14s;white-space:nowrap}\r\n#pth-advdocorg-wrapper .ptab:hover{color:var(--text);background:var(--surface)}\r\n#pth-advdocorg-wrapper .ptab.active{color:var(--blue);border-bottom-color:var(--blue);background:var(--surface)}\r\n#pth-advdocorg-wrapper .prev-body{flex:1;overflow:hidden;display:flex;position:relative}\r\n#pth-advdocorg-wrapper .ppane{display:none;width:100%;height:100%;overflow:auto}\r\n#pth-advdocorg-wrapper .ppane.active{display:flex}\r\n\r\n#pth-advdocorg-wrapper .doc-wrap{background:#d0d5dd;width:100%;height:100%;overflow-y:auto;padding:26px}\r\n#pth-advdocorg-wrapper .doc-paper{background:#fff;max-width:820px;margin:0 auto;padding:58px 70px;min-height:100%;box-shadow:0 4px 20px rgba(0,0,0,.15);font-family:var(--serif);font-size:15px;line-height:1.88;color:#1a1a1a;unicode-bidi:plaintext}\r\n#pth-advdocorg-wrapper .doc-paper h1{font-size:24px;font-weight:700;margin:0 0 15px;line-height:1.3;color:#111;font-family:var(--font)}\r\n#pth-advdocorg-wrapper .doc-paper h2{font-size:19px;font-weight:600;margin:22px 0 11px;color:#1a1a1a;border-bottom:1px solid #e5e7eb;padding-bottom:5px;font-family:var(--font)}\r\n#pth-advdocorg-wrapper .doc-paper h3{font-size:16px;font-weight:600;margin:16px 0 9px;color:#1f2937;font-family:var(--font)}\r\n#pth-advdocorg-wrapper .doc-paper h4{font-size:14px;font-weight:600;margin:12px 0 7px;font-family:var(--font)}\r\n#pth-advdocorg-wrapper .doc-paper p{margin-bottom:11px}\r\n#pth-advdocorg-wrapper .doc-paper ul,#pth-advdocorg-wrapper .doc-paper ol{margin:7px 0 11px 22px}\r\n#pth-advdocorg-wrapper .doc-paper li{margin-bottom:4px}\r\n#pth-advdocorg-wrapper .doc-paper table{width:100%;border-collapse:collapse;margin:14px 0;font-size:13px}\r\n#pth-advdocorg-wrapper .doc-paper table td,#pth-advdocorg-wrapper .doc-paper table th{border:1px solid #d1d5db;padding:7px 11px}\r\n#pth-advdocorg-wrapper .doc-paper table th{background:#f9fafb;font-weight:600}\r\n#pth-advdocorg-wrapper .doc-paper img{max-width:100%;height:auto;border-radius:4px;margin:8px 0}\r\n#pth-advdocorg-wrapper .doc-paper strong{font-weight:600}\r\n#pth-advdocorg-wrapper .doc-paper em{font-style:italic}\r\n#pth-advdocorg-wrapper .doc-paper a{color:var(--blue)}\r\n#pth-advdocorg-wrapper .doc-paper blockquote{border-left:3px solid var(--blue);padding-left:15px;color:#4b5563;margin:11px 0;font-style:italic}\r\n#pth-advdocorg-wrapper [dir=\"rtl\"] .doc-paper{direction:rtl;text-align:right}\r\n\r\n#pth-advdocorg-wrapper .sheet-wrap{display:flex;flex-direction:column;width:100%;height:100%;overflow:hidden}\r\n#pth-advdocorg-wrapper .sheet-nav{display:flex;background:var(--s3);border-bottom:1px solid var(--border);overflow-x:auto;flex-shrink:0}\r\n#pth-advdocorg-wrapper .stab{padding:7px 15px;font-size:12px;font-weight:600;cursor:pointer;font-family:var(--font);border:none;background:transparent;color:var(--t3);border-bottom:2px solid transparent;white-space:nowrap}\r\n#pth-advdocorg-wrapper .stab.active{color:var(--excel);border-bottom-color:var(--excel);background:var(--surface)}\r\n#pth-advdocorg-wrapper .sheet-tbwrap{overflow:auto;flex:1}\r\n#pth-advdocorg-wrapper .sheet-tbl{border-collapse:collapse;font-size:12px;font-family:var(--mono);background:#fff;width:100%}\r\n#pth-advdocorg-wrapper .sheet-tbl th{background:#f0f4f8;font-weight:700;padding:6px 11px;border:1px solid #d1d5db;position:sticky;top:0;z-index:2;font-family:var(--font);text-align:left;white-space:nowrap;color:#374151}\r\n#pth-advdocorg-wrapper .sheet-tbl td{border:1px solid #e5e7eb;padding:5px 11px;white-space:nowrap;min-width:55px}\r\n#pth-advdocorg-wrapper .sheet-tbl tr:hover td{background:#f8faff}\r\n#pth-advdocorg-wrapper .sheet-tbl tr:nth-child(even) td{background:#fafafa}\r\n\r\n#pth-advdocorg-wrapper .ppt-wrap{background:#1e1e2e;width:100%;height:100%;overflow-y:auto;padding:22px;display:flex;flex-direction:column;gap:16px}\r\n#pth-advdocorg-wrapper .ppt-slide{background:#fff;border-radius:var(--rl2);overflow:hidden;box-shadow:0 4px 16px rgba(0,0,0,.3);max-width:850px;margin:0 auto;width:100%}\r\n#pth-advdocorg-wrapper .ppt-slide-header{padding:10px 18px;background:var(--s3);border-bottom:1px solid var(--border);font-size:11px;font-weight:700;color:var(--t3);text-transform:uppercase;letter-spacing:.6px;display:flex;justify-content:space-between}\r\n#pth-advdocorg-wrapper .ppt-slide-body{padding:28px 34px;min-height:120px}\r\n#pth-advdocorg-wrapper .ppt-title{font-size:22px;font-weight:700;color:var(--text);margin-bottom:12px;font-family:var(--font)}\r\n#pth-advdocorg-wrapper .ppt-body-text{font-size:14px;color:var(--t2);line-height:1.7}\r\n#pth-advdocorg-wrapper .ppt-body-text li{margin-bottom:5px;list-style:disc;margin-left:18px}\r\n#pth-advdocorg-wrapper .ppt-no-content{color:var(--t3);font-style:italic;font-size:13px}\r\n#pth-advdocorg-wrapper .ppt-thumb-bar{display:flex;gap:8px;overflow-x:auto;padding:10px;background:#0f0f1a}\r\n#pth-advdocorg-wrapper .ppt-thumb{background:#fff;border-radius:6px;padding:8px 12px;min-width:120px;cursor:pointer;font-size:10px;font-weight:600;color:var(--text);border:2px solid transparent;flex-shrink:0;transition:.15s}\r\n#pth-advdocorg-wrapper .ppt-thumb:hover,#pth-advdocorg-wrapper .ppt-thumb.active{border-color:#60a5fa}\r\n\r\n#pth-advdocorg-wrapper .pdf-frame{width:100%;height:100%;border:none;display:block}\r\n\r\n#pth-advdocorg-wrapper .code-view{background:#1e1e2e;width:100%;height:100%;overflow:auto;padding:22px}\r\n#pth-advdocorg-wrapper .code-view pre{font-family:var(--mono);font-size:12px;line-height:1.7;color:#cdd6f4;white-space:pre-wrap;word-break:break-word;margin:0}\r\n#pth-advdocorg-wrapper .ln-wrap{display:flex;gap:14px}\r\n#pth-advdocorg-wrapper .ln-col{color:#6c7086;user-select:none;text-align:right;padding-right:8px;border-right:1px solid #313244;min-width:38px;font-family:var(--mono);font-size:12px;line-height:1.7}\r\n#pth-advdocorg-wrapper .code-col{flex:1;font-family:var(--mono);font-size:12px;line-height:1.7;color:#cdd6f4;white-space:pre-wrap;word-break:break-word}\r\n#pth-advdocorg-wrapper .jk{color:#89b4fa} #pth-advdocorg-wrapper .js{color:#a6e3a1} #pth-advdocorg-wrapper .jn{color:#fab387} #pth-advdocorg-wrapper .jb{color:#f38ba8} #pth-advdocorg-wrapper .jnu{color:#cba6f7}\r\n\r\n#pth-advdocorg-wrapper .md-view{background:#fff;width:100%;height:100%;overflow-y:auto;padding:38px 55px;font-family:var(--serif);font-size:16px;line-height:1.8;color:#1a1a1a}\r\n#pth-advdocorg-wrapper .md-view h1{font-size:28px;font-weight:700;margin-bottom:14px;border-bottom:2px solid var(--border);padding-bottom:8px;font-family:var(--font)}\r\n#pth-advdocorg-wrapper .md-view h2{font-size:21px;font-weight:600;margin:20px 0 10px;font-family:var(--font)}\r\n#pth-advdocorg-wrapper .md-view h3{font-size:17px;font-weight:600;margin:15px 0 8px;font-family:var(--font)}\r\n#pth-advdocorg-wrapper .md-view p{margin-bottom:13px}\r\n#pth-advdocorg-wrapper .md-view code{background:#f3f4f6;padding:1px 5px;border-radius:3px;font-family:var(--mono);font-size:12px}\r\n#pth-advdocorg-wrapper .md-view pre{background:#1e1e2e;padding:16px;border-radius:var(--r);margin:12px 0;overflow-x:auto}\r\n#pth-advdocorg-wrapper .md-view pre code{background:none;color:#cdd6f4;font-size:12px}\r\n#pth-advdocorg-wrapper .md-view ul,#pth-advdocorg-wrapper .md-view ol{margin:8px 0 13px 22px}\r\n#pth-advdocorg-wrapper .md-view li{margin-bottom:4px}\r\n#pth-advdocorg-wrapper .md-view blockquote{border-left:3px solid var(--blue);padding-left:14px;color:#6b7280;font-style:italic;margin:11px 0}\r\n#pth-advdocorg-wrapper .md-view table{width:100%;border-collapse:collapse;margin-bottom:15px;font-size:13px}\r\n#pth-advdocorg-wrapper .md-view table th,#pth-advdocorg-wrapper .md-view table td{border:1px solid var(--border);padding:8px 11px}\r\n#pth-advdocorg-wrapper .md-view table th{background:var(--s2);font-weight:600}\r\n#pth-advdocorg-wrapper .md-view a{color:var(--blue)}\r\n\r\n#pth-advdocorg-wrapper .info-tbl{width:100%;border-collapse:collapse;font-size:13px}\r\n#pth-advdocorg-wrapper .info-tbl td{padding:9px 13px;border-bottom:1px solid var(--border);vertical-align:top}\r\n#pth-advdocorg-wrapper .info-tbl td:first-child{font-weight:600;color:var(--t2);width:140px}\r\n#pth-advdocorg-wrapper .info-tbl td:last-child{font-family:var(--mono);font-size:12px}\r\n#pth-advdocorg-wrapper .word-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(100px,1fr));gap:10px;margin-top:14px}\r\n#pth-advdocorg-wrapper .ws-card{background:var(--s2);border:1px solid var(--border);border-radius:var(--r);padding:12px;text-align:center}\r\n#pth-advdocorg-wrapper .ws-val{font-size:22px;font-weight:800;color:var(--blue)}\r\n#pth-advdocorg-wrapper .ws-lbl{font-size:10px;color:var(--t3);font-weight:600;text-transform:uppercase;letter-spacing:.5px;margin-top:3px}\r\n\r\n#pth-advdocorg-wrapper .notes-area{width:100%;height:100%;padding:18px;font-family:var(--font);font-size:13px;border:none;outline:none;resize:none;background:var(--surface);color:var(--text);line-height:1.7}\r\n\r\n#pth-advdocorg-wrapper .compare-pane{background:var(--surface);border:1px solid var(--border);border-radius:var(--rl2);padding:0;overflow:hidden;display:flex;flex-direction:column}\r\n#pth-advdocorg-wrapper .compare-header{padding:11px 15px;background:var(--s3);border-bottom:1px solid var(--border);font-weight:700;font-size:13px;display:flex;justify-content:space-between;align-items:center}\r\n#pth-advdocorg-wrapper .compare-body{flex:1;overflow:auto;height:60vh}\r\n\r\n#pth-advdocorg-wrapper .loading-state{width:100%;height:100%;display:flex;align-items:center;justify-content:center;flex-direction:column;gap:13px;color:var(--t3);background:var(--s2)}\r\n#pth-advdocorg-wrapper .spinner{width:34px;height:34px;border:3px solid var(--border);border-top-color:var(--blue);border-radius:50%;animation:spin .8s linear infinite}\r\n@keyframes spin{to{transform:rotate(360deg)}}\r\n\r\n#pth-advdocorg-wrapper .mini-modal{background:#fff;border-radius:var(--rxx);padding:26px;width:92%;max-width:430px;box-shadow:var(--shx);animation:si .2s ease}\r\n#pth-advdocorg-wrapper .mmt{font-size:17px;font-weight:700;margin-bottom:5px}\r\n#pth-advdocorg-wrapper .mms{font-size:13px;color:var(--t3);margin-bottom:15px}\r\n#pth-advdocorg-wrapper .mmf{display:flex;gap:9px;justify-content:flex-end;margin-top:17px}\r\n#pth-advdocorg-wrapper .mi{width:100%;padding:9px 11px;border:1px solid var(--border);border-radius:5px;font-family:var(--font);font-size:13px;outline:none;margin:10px 0;background:var(--surface);color:var(--text)}\r\n#pth-advdocorg-wrapper .mi:focus{border-color:var(--blue)}\r\n\r\n#pth-advdocorg-wrapper .csv-info{padding:8px 15px;background:var(--s3);border-bottom:1px solid var(--border);font-size:12px;color:var(--t3);font-weight:600;flex-shrink:0}\r\n#pth-advdocorg-wrapper .tag-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:10px;font-size:10px;font-weight:700;margin:2px}\r\n\r\n#pth-advdocorg-wrapper .toast{position:fixed;bottom:22px;left:50%;transform:translateX(-50%) translateY(8px);background:var(--text);color:#fff;padding:10px 22px;border-radius:var(--r);font-size:13px;font-weight:600;z-index:999999;opacity:0;transition:all .22s;box-shadow:var(--shl);pointer-events:none;white-space:nowrap}\r\n#pth-advdocorg-wrapper .toast.show{opacity:1;transform:translateX(-50%) translateY(0)}\r\n\r\n#pth-advdocorg-wrapper .prog-box{background:#fff;border-radius:var(--rxx);padding:34px;text-align:center;min-width:280px;box-shadow:var(--shx)}\r\n#pth-advdocorg-wrapper input[type=file].hid{display:none}\r\n\r\n#pth-advdocorg-wrapper .fullscreen-slide{position:fixed;inset:0;background:#000;z-index:999998;display:none;align-items:center;justify-content:center;flex-direction:column}\r\n#pth-advdocorg-wrapper .fullscreen-slide.open{display:flex}\r\n#pth-advdocorg-wrapper .fs-slide-content{background:#fff;width:90vw;max-width:960px;border-radius:var(--rx);padding:60px 80px;min-height:50vh;display:flex;flex-direction:column;justify-content:center}\r\n#pth-advdocorg-wrapper .fs-nav{display:flex;gap:16px;margin-top:24px;align-items:center}\r\n#pth-advdocorg-wrapper .fs-counter{color:rgba(255,255,255,.6);font-size:14px;font-weight:600}\r\n<\/style>\r\n\r\n<div id=\"pth-advdocorg-wrapper\">\r\n<div class=\"app-container\">\r\n\r\n<div class=\"topbar\">\r\n  <div class=\"brand\">\r\n    <div class=\"brand-icon\">\ud83d\uddc2\ufe0f<\/div>\r\n    <div>\r\n      <div class=\"brand-name\">Document <span>Workspace<\/span><span class=\"pro-badge\">PRO<\/span><\/div>\r\n      <div class=\"brand-sub\">Word \u00b7 Excel \u00b7 PPT \u00b7 PDF \u00b7 Text \u00b7 CSV \u00b7 JSON \u00b7 XML \u00b7 Markdown \u2014 100% Offline<\/div>\r\n    <\/div>\r\n  <\/div>\r\n  <div class=\"topbar-right\">\r\n    <button class=\"pth-btn pth-btn-ghost pth-btn-sm\" id=\"btn-fts-toggle\">\ud83d\udd0d Full-Text Search<\/button>\r\n    <button class=\"pth-btn pth-btn-ghost pth-btn-sm\" id=\"btn-tools-toggle\">\ud83d\udee0\ufe0f Batch Tools<\/button>\r\n    <button class=\"pth-btn pth-btn-ghost pth-btn-sm\" id=\"btn-expand\">\u26f6 Full Width<\/button>\r\n    <button class=\"pth-btn pth-btn-ghost pth-btn-sm\" id=\"btn-compare-mode\">\u29c9 Compare<\/button>\r\n    <button class=\"pth-btn pth-btn-ghost pth-btn-sm\" id=\"btn-restart\">\ud83d\udd04 Restart<\/button>\r\n  <\/div>\r\n<\/div>\r\n\r\n<div id=\"dropzone\">\r\n  <span class=\"drop-icon\">\ud83d\uddc2\ufe0f<\/span>\r\n  <div class=\"drop-title\">Drop Documents, Folders or ZIP Archives<\/div>\r\n  <div class=\"drop-sub\">100% offline \u2014 files never leave your device. Full live preview, full-text search, PPTX slide viewer, date filtering, Unicode\/RTL support, and much more.<\/div>\r\n  <div class=\"drop-btns\">\r\n    <button class=\"pth-btn pth-btn-primary\" id=\"trig-files\">\ud83d\udcc4 Open Files<\/button>\r\n    <button class=\"pth-btn pth-btn-dark\" id=\"trig-folder\">\ud83d\udcc1 Open Folder<\/button>\r\n    <button class=\"pth-btn pth-btn-outline\" id=\"trig-zip\">\ud83d\udce6 Open ZIP<\/button>\r\n  <\/div>\r\n  <div class=\"badges\">\r\n    <span class=\"fbadge b-word\">\ud83d\udcd8 DOCX \u00b7 DOC<\/span>\r\n    <span class=\"fbadge b-excel\">\ud83d\udcd7 XLSX \u00b7 XLS \u00b7 CSV<\/span>\r\n    <span class=\"fbadge b-pdf\">\ud83d\udcd5 PDF<\/span>\r\n    <span class=\"fbadge b-ppt\">\ud83d\udcd9 PPTX \u00b7 PPT<\/span>\r\n    <span class=\"fbadge b-text\">\ud83d\udcdd TXT \u00b7 MD \u00b7 LOG<\/span>\r\n    <span class=\"fbadge b-data\">\ud83d\uddc4\ufe0f JSON \u00b7 XML \u00b7 HTML<\/span>\r\n  <\/div>\r\n<\/div>\r\n\r\n<input type=\"file\" id=\"inp-files\" class=\"hid\" multiple accept=\".docx,.doc,.xlsx,.xls,.csv,.pdf,.txt,.json,.html,.xml,.md,.zip,.pptx,.ppt,.log,.yaml,.yml,.ini,.odt,.ods\">\r\n<input type=\"file\" id=\"inp-folder\" class=\"hid\" multiple webkitdirectory directory>\r\n<input type=\"file\" id=\"inp-zip\" class=\"hid\" accept=\".zip\">\r\n<input type=\"file\" id=\"inp-add\" class=\"hid\" multiple accept=\".docx,.doc,.xlsx,.xls,.csv,.pdf,.txt,.json,.html,.xml,.md,.zip,.pptx,.ppt,.log\">\r\n\r\n<div id=\"workspace\" style=\"display:none\">\r\n\r\n  <div class=\"stats-bar\">\r\n    <div class=\"stat-card\"><div class=\"stat-icon\">\ud83d\uddc2\ufe0f<\/div><div><div class=\"stat-val\" id=\"s-total\">0<\/div><div class=\"stat-lbl\">Total<\/div><\/div><\/div>\r\n    <div class=\"stat-card\"><div class=\"stat-icon\">\ud83d\udcd8<\/div><div><div class=\"stat-val\" id=\"s-word\">0<\/div><div class=\"stat-lbl\">Word<\/div><\/div><\/div>\r\n    <div class=\"stat-card\"><div class=\"stat-icon\">\ud83d\udcd7<\/div><div><div class=\"stat-val\" id=\"s-excel\">0<\/div><div class=\"stat-lbl\">Excel<\/div><\/div><\/div>\r\n    <div class=\"stat-card\"><div class=\"stat-icon\">\ud83d\udcd9<\/div><div><div class=\"stat-val\" id=\"s-ppt\">0<\/div><div class=\"stat-lbl\">PPT<\/div><\/div><\/div>\r\n    <div class=\"stat-card\"><div class=\"stat-icon\">\ud83d\udcd5<\/div><div><div class=\"stat-val\" id=\"s-pdf\">0<\/div><div class=\"stat-lbl\">PDF<\/div><\/div><\/div>\r\n    <div class=\"stat-card\"><div class=\"stat-icon\">\ud83d\uddc4\ufe0f<\/div><div><div class=\"stat-val\" id=\"s-data\">0<\/div><div class=\"stat-lbl\">Data<\/div><\/div><\/div>\r\n    <div class=\"stat-card\"><div class=\"stat-icon\">\ud83d\udcdd<\/div><div><div class=\"stat-val\" id=\"s-text\">0<\/div><div class=\"stat-lbl\">Text<\/div><\/div><\/div>\r\n    <div class=\"stat-card\"><div class=\"stat-icon\">\ud83d\udcbe<\/div><div><div class=\"stat-val\" id=\"s-size\">0<\/div><div class=\"stat-lbl\">Size<\/div><\/div><\/div>\r\n  <\/div>\r\n\r\n  <div class=\"fts-bar\" id=\"fts-bar\">\r\n    <div style=\"font-size:12px;font-weight:700;color:var(--blue);margin-bottom:10px;\">\ud83d\udd0d Full-Text Search \u2014 searches inside document contents<\/div>\r\n    <div class=\"fts-row\">\r\n      <input type=\"text\" class=\"fts-input\" id=\"fts-input\" placeholder=\"Search inside all documents\u2026 e.g. 'invoice total' or 'project name'\">\r\n      <button class=\"pth-btn pth-btn-primary pth-btn-sm\" id=\"btn-fts-go\">Search<\/button>\r\n      <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"btn-fts-clear\">Clear<\/button>\r\n      <span class=\"fts-stats\" id=\"fts-stats\"><\/span>\r\n    <\/div>\r\n    <div class=\"fts-results\" id=\"fts-results\"><\/div>\r\n  <\/div>\r\n\r\n  <div class=\"smart-panel\">\r\n    <div class=\"sp-title\">\u26a1 Smart Auto-Organizer & Filters<\/div>\r\n    <div class=\"smart-row\">\r\n      <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"ao-type\">\ud83d\uddc2\ufe0f By Type<\/button>\r\n      <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"ao-ext\">\ud83d\udd24 By Extension<\/button>\r\n      <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"ao-size\">\ud83d\udcca By Size<\/button>\r\n      <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"ao-alpha\">\ud83d\udd20 Alphabetical<\/button>\r\n      <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"ao-date\">\ud83d\udcc5 By Date<\/button>\r\n      <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"btn-autotag\">\ud83c\udff7\ufe0f Auto-Tag from Content<\/button>\r\n      <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"btn-new-folder\" style=\"margin-left:6px\">\ud83d\udcc1 + Folder<\/button>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"tools-panel\" id=\"tools-panel\">\r\n    <div style=\"font-size:13px;font-weight:700;color:var(--text);margin-bottom:3px\">\ud83d\udee0\ufe0f Batch Tools<\/div>\r\n    <div class=\"tgrid\">\r\n      <div class=\"tbox\">\r\n        <div class=\"tbox-title\">\u270f\ufe0f Batch Rename<\/div>\r\n        <div style=\"font-size:11px;color:var(--t3);margin-bottom:9px\">Tokens: <code style=\"background:var(--s3);padding:1px 4px;border-radius:3px\">{n}<\/code> <code style=\"background:var(--s3);padding:1px 4px;border-radius:3px\">{ext}<\/code> <code style=\"background:var(--s3);padding:1px 4px;border-radius:3px\">{name}<\/code> <code style=\"background:var(--s3);padding:1px 4px;border-radius:3px\">{folder}<\/code> <code style=\"background:var(--s3);padding:1px 4px;border-radius:3px\">{date}<\/code><\/div>\r\n        <div class=\"trow\"><span class=\"tlbl\">Pattern<\/span><input type=\"text\" class=\"tinput\" id=\"rn-pattern\" placeholder=\"Report_{date}_{n}.{ext}\"><\/div>\r\n        <div class=\"trow\"><span class=\"tlbl\">Start #<\/span><input type=\"number\" class=\"tinput\" id=\"rn-start\" value=\"1\" style=\"width:60px\"><span class=\"tlbl\" style=\"margin-left:6px\">Pad<\/span><select class=\"sselect\" id=\"rn-pad\"><option value=\"1\">-<\/option><option value=\"2\">00<\/option><option value=\"3\" selected>000<\/option><\/select><\/div>\r\n        <div style=\"display:flex;gap:7px;margin-top:9px\">\r\n          <button class=\"pth-btn pth-btn-primary pth-btn-sm\" id=\"btn-do-rename\">Rename Selected<\/button>\r\n          <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"btn-prev-rename\">Preview<\/button>\r\n        <\/div>\r\n        <div class=\"tresult\" id=\"rn-preview\" style=\"display:none\"><\/div>\r\n      <\/div>\r\n      <div class=\"tbox\">\r\n        <div class=\"tbox-title\">\ud83d\udd01 Find & Replace in Names<\/div>\r\n        <div class=\"trow\"><span class=\"tlbl\">Find<\/span><input type=\"text\" class=\"tinput\" id=\"fr-find\" placeholder=\"old_prefix_\"><\/div>\r\n        <div class=\"trow\"><span class=\"tlbl\">Replace<\/span><input type=\"text\" class=\"tinput\" id=\"fr-replace\" placeholder=\"new_prefix_\"><\/div>\r\n        <div class=\"trow\"><label style=\"font-size:12px;color:var(--t2);display:flex;align-items:center;gap:6px\"><input type=\"checkbox\" id=\"fr-case\"> Case sensitive<\/label><\/div>\r\n        <div style=\"display:flex;gap:7px;margin-top:7px\">\r\n          <button class=\"pth-btn pth-btn-primary pth-btn-sm\" id=\"btn-fr-sel\">Apply to Selected<\/button>\r\n          <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"btn-fr-all\">Apply to All<\/button>\r\n        <\/div>\r\n      <\/div>\r\n      <div class=\"tbox\">\r\n        <div class=\"tbox-title\">\ud83d\udd17 Merge Files<\/div>\r\n        <div style=\"font-size:11px;color:var(--t3);margin-bottom:10px\">Merges selected text\/CSV\/JSON files into one download.<\/div>\r\n        <div class=\"trow\"><span class=\"tlbl\">Type<\/span>\r\n          <select class=\"sselect tinput\" id=\"merge-type\">\r\n            <option value=\"txt\">Text files (TXT\/MD\/LOG)<\/option>\r\n            <option value=\"csv\">CSV files (stack rows)<\/option>\r\n            <option value=\"json\">JSON files (array merge)<\/option>\r\n          <\/select>\r\n        <\/div>\r\n        <div class=\"trow\"><span class=\"tlbl\">Separator<\/span><input type=\"text\" class=\"tinput\" id=\"merge-sep\" value=\"--- {filename} ---\" style=\"flex:1\"><\/div>\r\n        <button class=\"pth-btn pth-btn-primary pth-btn-sm\" id=\"btn-do-merge\" style=\"margin-top:8px\">Merge Selected<\/button>\r\n      <\/div>\r\n      <div class=\"tbox\">\r\n        <div class=\"tbox-title\">\ud83d\udce6 Export Options<\/div>\r\n        <div class=\"trow\"><span class=\"tlbl\">Scope<\/span>\r\n          <select class=\"sselect tinput\" id=\"exp-scope\">\r\n            <option value=\"selected\">Selected Only<\/option>\r\n            <option value=\"all\">All Files<\/option>\r\n            <option value=\"current\">Current View<\/option>\r\n          <\/select>\r\n        <\/div>\r\n        <div class=\"trow\"><span class=\"tlbl\">Structure<\/span>\r\n          <select class=\"sselect tinput\" id=\"exp-struct\">\r\n            <option value=\"organized\">By Folder<\/option>\r\n            <option value=\"flat\">Flat (root)<\/option>\r\n            <option value=\"type\">By Type<\/option>\r\n            <option value=\"ext\">By Extension<\/option>\r\n          <\/select>\r\n        <\/div>\r\n        <div class=\"trow\"><span class=\"tlbl\">ZIP Name<\/span><input type=\"text\" class=\"tinput\" id=\"exp-name\" value=\"Documents_Export\"><\/div>\r\n        <div style=\"display:flex;gap:7px;margin-top:9px;flex-wrap:wrap\">\r\n          <button class=\"pth-btn pth-btn-success pth-btn-sm\" id=\"btn-do-export\">\ud83d\udce6 Export ZIP<\/button>\r\n          <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"btn-batch-dl\">\u2b07 Batch Download<\/button>\r\n          <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"btn-manifest\">\ud83d\udccb Manifest<\/button>\r\n        <\/div>\r\n        <div class=\"tresult\" id=\"manifest-out\" style=\"display:none\"><\/div>\r\n      <\/div>\r\n      <div class=\"tbox\">\r\n        <div class=\"tbox-title\">\ud83d\udd0d Duplicate Finder<\/div>\r\n        <div id=\"dup-info\" style=\"font-size:12px;color:var(--t3)\">Scan to find files with same name + size.<\/div>\r\n        <div style=\"display:flex;gap:7px;margin-top:11px;flex-wrap:wrap\">\r\n          <button class=\"pth-btn pth-btn-primary pth-btn-sm\" id=\"btn-scan-dups\">\ud83d\udd0d Scan<\/button>\r\n          <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"btn-sel-dups\">\u2611\ufe0f Select<\/button>\r\n          <button class=\"pth-btn pth-btn-danger pth-btn-sm\" id=\"btn-del-dups\">\ud83d\uddd1\ufe0f Delete<\/button>\r\n        <\/div>\r\n        <div id=\"dup-list\" style=\"margin-top:9px;max-height:130px;overflow-y:auto\"><\/div>\r\n      <\/div>\r\n      <div class=\"tbox\">\r\n        <div class=\"tbox-title\">\ud83c\udff7\ufe0f Manual Tags<\/div>\r\n        <div class=\"trow\">\r\n          <input type=\"text\" class=\"tinput\" id=\"tag-name\" placeholder=\"Tag name e.g. Invoice\">\r\n          <select class=\"sselect\" id=\"tag-color\">\r\n            <option value=\"#2563eb\">\ud83d\udd35 Blue<\/option>\r\n            <option value=\"#059669\">\ud83d\udfe2 Green<\/option>\r\n            <option value=\"#dc2626\">\ud83d\udd34 Red<\/option>\r\n            <option value=\"#d97706\">\ud83d\udfe1 Amber<\/option>\r\n            <option value=\"#7c3aed\">\ud83d\udfe3 Purple<\/option>\r\n            <option value=\"#0891b2\">\ud83d\udd35 Cyan<\/option>\r\n          <\/select>\r\n        <\/div>\r\n        <div style=\"display:flex;gap:7px;margin-top:8px\">\r\n          <button class=\"pth-btn pth-btn-primary pth-btn-sm\" id=\"btn-add-tag\">Add to Selected<\/button>\r\n          <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"btn-clear-tags\">Clear All Tags<\/button>\r\n        <\/div>\r\n        <div id=\"tags-cloud\" style=\"margin-top:10px;display:flex;flex-wrap:wrap;gap:4px\"><\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"main-layout\" id=\"main-layout\">\r\n    <div class=\"sidebar\" id=\"sidebar\">\r\n      <div class=\"panel\">\r\n        <div class=\"ptitle\">Document Types<\/div>\r\n        <div class=\"folder-list\" id=\"fl-types\"><\/div>\r\n      <\/div>\r\n      <div class=\"panel\">\r\n        <div class=\"ptitle\">Virtual Folders <button class=\"pth-btn pth-btn-secondary pth-btn-xs\" id=\"btn-nf2\">+<\/button><\/div>\r\n        <div class=\"folder-list\" id=\"fl-custom\"><\/div>\r\n      <\/div>\r\n      <div class=\"panel\">\r\n        <div class=\"ptitle\">By Extension<\/div>\r\n        <div class=\"folder-list\" id=\"fl-ext\"><\/div>\r\n        <div class=\"storage-row\"><span>Storage<\/span><span id=\"stor-lbl\">0 B<\/span><\/div>\r\n        <div class=\"prog-track\"><div class=\"prog-fill\" id=\"stor-fill\" style=\"width:0%\"><\/div><\/div>\r\n      <\/div>\r\n      <div class=\"panel\">\r\n        <div class=\"ptitle\">\u2b50 Favorites<\/div>\r\n        <div class=\"folder-list\" id=\"fl-favs\"><\/div>\r\n      <\/div>\r\n      <div class=\"panel\">\r\n        <div class=\"ptitle\">\ud83d\udd52 Recently Viewed<\/div>\r\n        <div id=\"fl-recent\"><\/div>\r\n      <\/div>\r\n    <\/div>\r\n    <div class=\"gallery-card\">\r\n      <div class=\"toolbar\">\r\n        <span class=\"toolbar-title\" id=\"folder-title\">All Documents<\/span>\r\n        <div class=\"dvdr\"><\/div>\r\n        <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"btn-sel-all\">\u2611\ufe0f Select All<\/button>\r\n        <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"btn-move\" disabled>\ud83d\udcc2 Move<\/button>\r\n        <button class=\"pth-btn pth-btn-danger pth-btn-sm\" id=\"btn-delete\" disabled>\ud83d\uddd1\ufe0f Delete<\/button>\r\n        \r\n        <div class=\"date-filter-row\" style=\"margin-top:0; border:none; padding:0 8px; margin-left:10px;\">\r\n          <span class=\"date-lbl\">\ud83d\udcc5 Date Filter:<\/span>\r\n          <input type=\"date\" id=\"df-start\" class=\"date-inp\" title=\"From\">\r\n          <span style=\"font-size:12px;color:var(--border)\">\u2192<\/span>\r\n          <input type=\"date\" id=\"df-end\" class=\"date-inp\" title=\"To\">\r\n          <select id=\"df-source\" class=\"sselect\" style=\"font-size:11px; padding:2px 4px; margin:0 4px;\">\r\n            <option value=\"modified\">Last Modified<\/option>\r\n            <option value=\"created\">Created Date<\/option>\r\n            <option value=\"detected\">Filename Date<\/option>\r\n          <\/select>\r\n          <button class=\"pth-btn pth-btn-outline pth-btn-xs\" id=\"btn-df-clear\">\u2715 Clear<\/button>\r\n        <\/div>\r\n        <div class=\"tr\">\r\n          <button class=\"pth-btn pth-btn-outline pth-btn-sm\" id=\"btn-add-more\">+ Add Files<\/button>\r\n          <button class=\"pth-btn pth-btn-success pth-btn-sm\" id=\"btn-exp-sel\" disabled>\ud83d\udce6 Export ZIP<\/button>\r\n        <\/div>\r\n      <\/div>\r\n      <div class=\"filter-bar\">\r\n        <button class=\"ftag active\" data-f=\"all\">All<\/button>\r\n        <button class=\"ftag\" data-f=\"word\">\ud83d\udcd8 Word<\/button>\r\n        <button class=\"ftag\" data-f=\"excel\">\ud83d\udcd7 Excel<\/button>\r\n        <button class=\"ftag\" data-f=\"ppt\">\ud83d\udcd9 PPT<\/button>\r\n        <button class=\"ftag\" data-f=\"pdf\">\ud83d\udcd5 PDF<\/button>\r\n        <button class=\"ftag\" data-f=\"text\">\ud83d\udcdd Text<\/button>\r\n        <button class=\"ftag\" data-f=\"data\">\ud83d\uddc4\ufe0f Data<\/button>\r\n        <button class=\"ftag\" data-f=\"starred\">\u2b50 Starred<\/button>\r\n        <input type=\"text\" class=\"sbox\" id=\"sbox\" placeholder=\"\ud83d\udd0d Search filenames\u2026\">\r\n        <select class=\"sselect\" id=\"sort-sel\">\r\n          <option value=\"name-asc\">Name A-Z<\/option>\r\n          <option value=\"name-desc\">Name Z-A<\/option>\r\n          <option value=\"size-desc\">Largest First<\/option>\r\n          <option value=\"size-asc\">Smallest First<\/option>\r\n          <option value=\"type\">By Type<\/option>\r\n          <option value=\"ext\">By Extension<\/option>\r\n          <option value=\"date-desc\">Newest First<\/option>\r\n          <option value=\"date-asc\">Oldest First<\/option>\r\n        <\/select>\r\n        <div class=\"vtoggle\">\r\n          <button class=\"vbtn active\" data-v=\"grid\">\u229e<\/button>\r\n          <button class=\"vbtn\" data-v=\"list\">\u2630<\/button>\r\n        <\/div>\r\n      <\/div>\r\n      <div class=\"fgrid\" id=\"fgrid\"><\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div id=\"compare-panels\" style=\"display:none;gap:13px;margin-top:13px\">\r\n    <div class=\"compare-pane\">\r\n      <div class=\"compare-header\">\r\n        <span id=\"cmp-lbl-a\">Document A \u2014 <span style=\"color:var(--t3)\">click a file to load<\/span><\/span>\r\n        <button class=\"pth-btn pth-btn-secondary pth-btn-xs\" id=\"cmp-clear-a\">\u2715 Clear<\/button>\r\n      <\/div>\r\n      <div class=\"compare-body\" id=\"cmp-body-a\"><div class=\"loading-state\" style=\"height:100%\"><div style=\"font-size:30px\">\ud83d\udc48<\/div><div>Click any file card to load it here<\/div><\/div><\/div>\r\n    <\/div>\r\n    <div class=\"compare-pane\">\r\n      <div class=\"compare-header\">\r\n        <span id=\"cmp-lbl-b\">Document B \u2014 <span style=\"color:var(--t3)\">click a file to load<\/span><\/span>\r\n        <button class=\"pth-btn pth-btn-secondary pth-btn-xs\" id=\"cmp-clear-b\">\u2715 Clear<\/button>\r\n      <\/div>\r\n      <div class=\"compare-body\" id=\"cmp-body-b\"><div class=\"loading-state\" style=\"height:100%\"><div style=\"font-size:30px\">\ud83d\udc49<\/div><div>Click any file card to load it here<\/div><\/div><\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n<\/div><div class=\"overlay\" id=\"modal-prev\">\r\n  <div class=\"prev-wrapper\">\r\n    <div class=\"prev-header\">\r\n      <div class=\"prev-finfo\">\r\n        <div class=\"prev-ibox\" id=\"prev-ibox\">\ud83d\udcc4<\/div>\r\n        <div>\r\n          <div class=\"prev-fname\" id=\"prev-fname\">filename<\/div>\r\n          <div class=\"prev-fmeta\" id=\"prev-fmeta\">0 B<\/div>\r\n        <\/div>\r\n      <\/div>\r\n      <div class=\"prev-actions\">\r\n        <button class=\"pth-btn pth-btn-ghost pth-btn-sm\" id=\"btn-prev-star\">\u2606 Star<\/button>\r\n        <button class=\"pth-btn pth-btn-ghost pth-btn-sm\" id=\"btn-prev-fullscreen\">\u26f6 Fullscreen<\/button>\r\n        <button class=\"pth-btn pth-btn-ghost pth-btn-sm\" id=\"btn-prev-print\">\ud83d\udda8 Print\/PDF<\/button>\r\n        <button class=\"pth-btn pth-btn-ghost pth-btn-sm\" id=\"pp-prev\">\u2039 Prev<\/button>\r\n        <button class=\"pth-btn pth-btn-ghost pth-btn-sm\" id=\"pp-next\">Next \u203a<\/button>\r\n        <button class=\"pth-btn pth-btn-success pth-btn-sm\" id=\"btn-dl-prev\">\u2b07 Download<\/button>\r\n        <button class=\"pth-btn pth-btn-danger pth-btn-sm\" id=\"btn-close-prev\" style=\"background:rgba(220,38,38,.2);color:#fca5a5;border-color:rgba(220,38,38,.3)\">\u2715 Close<\/button>\r\n      <\/div>\r\n    <\/div>\r\n    <div class=\"prev-tabs\" id=\"prev-tabs\"><\/div>\r\n    <div class=\"prev-body\" id=\"prev-body\">\r\n      <div class=\"ppane active\" id=\"ppane-main\">\r\n        <div class=\"loading-state\"><div class=\"spinner\"><\/div><div style=\"font-weight:600\">Rendering document\u2026<\/div><\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<div class=\"overlay\" id=\"modal-folder\">\r\n  <div class=\"mini-modal\">\r\n    <div class=\"mmt\">\ud83d\udcc1 Create Virtual Folder<\/div>\r\n    <div class=\"mms\">Name your new folder to organize documents into.<\/div>\r\n    <input type=\"text\" class=\"mi\" id=\"folder-inp\" placeholder=\"e.g. Q4 Reports 2025\">\r\n    <div class=\"mmf\">\r\n      <button class=\"pth-btn pth-btn-secondary\" id=\"close-fm\">Cancel<\/button>\r\n      <button class=\"pth-btn pth-btn-primary\" id=\"confirm-fm\">Create<\/button>\r\n    <\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<div class=\"overlay\" id=\"modal-move\">\r\n  <div class=\"mini-modal\">\r\n    <div class=\"mmt\">\ud83d\udcc2 Move Selected Files<\/div>\r\n    <div class=\"mms\">Choose destination folder.<\/div>\r\n    <select class=\"mi\" id=\"move-dest\"><\/select>\r\n    <div class=\"mmf\">\r\n      <button class=\"pth-btn pth-btn-secondary\" id=\"close-mm\">Cancel<\/button>\r\n      <button class=\"pth-btn pth-btn-primary\" id=\"confirm-mm\">Move<\/button>\r\n    <\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<div class=\"overlay\" id=\"modal-alert\">\r\n  <div class=\"mini-modal\" style=\"text-align:center\">\r\n    <div style=\"font-size:44px;margin-bottom:9px\" id=\"alrt-icon\">\u26a0\ufe0f<\/div>\r\n    <div class=\"mmt\" id=\"alrt-title\">Alert<\/div>\r\n    <div class=\"mms\" id=\"alrt-msg\"><\/div>\r\n    <button class=\"pth-btn pth-btn-primary\" id=\"alrt-ok\" style=\"width:100%;padding:11px;margin-top:7px\">OK<\/button>\r\n  <\/div>\r\n<\/div>\r\n\r\n<div class=\"overlay\" id=\"modal-prog\">\r\n  <div class=\"prog-box\">\r\n    <div class=\"spinner\" style=\"margin:0 auto 15px\"><\/div>\r\n    <div style=\"font-size:15px;font-weight:700;margin-bottom:5px\" id=\"prog-title\">Processing\u2026<\/div>\r\n    <div style=\"font-size:12px;color:var(--t3)\" id=\"prog-sub\">Please wait.<\/div>\r\n    <div class=\"prog-track\" style=\"margin-top:15px\"><div class=\"prog-fill\" id=\"prog-fill\" style=\"width:0%\"><\/div><\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<div class=\"fullscreen-slide\" id=\"fs-slide\">\r\n  <div class=\"fs-slide-content\" id=\"fs-content\"><\/div>\r\n  <div class=\"fs-nav\">\r\n    <button class=\"pth-btn pth-btn-ghost\" id=\"fs-prev\">\u2039 Previous<\/button>\r\n    <span class=\"fs-counter\" id=\"fs-counter\">1 \/ 1<\/span>\r\n    <button class=\"pth-btn pth-btn-ghost\" id=\"fs-next\">Next \u203a<\/button>\r\n    <button class=\"pth-btn pth-btn-danger pth-btn-sm\" id=\"fs-close\" style=\"margin-left:20px\">\u2715 Exit<\/button>\r\n  <\/div>\r\n<\/div>\r\n\r\n<div class=\"toast\" id=\"toast\"><\/div>\r\n<\/div><\/div>\r\n\r\n<script data-no-optimize=\"1\" data-no-minify=\"1\" data-cfasync=\"false\">\r\n(function(){\r\n'use strict';\r\n\r\nconst S = {\r\n  files:[], customFolders:[], tags:{}, dupIds:new Set(),\r\n  selectedIds:new Set(), starredIds:new Set(), notes:{},\r\n  recentIds:[], fileContent:{},\r\n  currentFolder:'All', filterType:'all', sortMode:'name-asc',\r\n  searchQ:'', viewMode:'grid', fileIdCounter:0,\r\n  prevIds:[], prevIdx:-1, activePrevFile:null,\r\n  compareModeOn:false, compareA:null, compareB:null,\r\n  compareNext:'A',\r\n  ftsActive:false, dateFilterSource:'modified',\r\n  pptSlideState:{}\r\n};\r\n\r\nconst $  = id => document.getElementById(id);\r\nconst on = (id,ev,fn) => { const e=$(id); if(e) e.addEventListener(ev,fn); };\r\nconst qsa = sel => document.querySelectorAll(sel);\r\n\r\nfunction toast(msg, dur=3000){\r\n  const t=$('toast'); t.textContent=msg; t.classList.add('show');\r\n  clearTimeout(t._tid); t._tid=setTimeout(()=>t.classList.remove('show'),dur);\r\n}\r\nfunction showAlert(title,msg,icon='\u26a0\ufe0f'){\r\n  $('alrt-icon').textContent=icon; $('alrt-title').textContent=title; $('alrt-msg').textContent=msg;\r\n  showOv('modal-alert');\r\n}\r\nfunction showOv(id){ $(id).classList.add('open'); }\r\nfunction hideOv(id){ $(id).classList.remove('open'); }\r\nfunction showProg(title,sub,pct=0){\r\n  $('prog-title').textContent=title; $('prog-sub').textContent=sub;\r\n  $('prog-fill').style.width=pct+'%'; showOv('modal-prog');\r\n}\r\nfunction hideProg(){ hideOv('modal-prog'); }\r\nfunction fmtBytes(b){\r\n  if(!b) return '0 B';\r\n  const k=1024,s=['B','KB','MB','GB'];\r\n  const i=Math.floor(Math.log(b)\/Math.log(k));\r\n  return parseFloat((b\/Math.pow(k,i)).toFixed(1))+' '+s[i];\r\n}\r\nfunction getExt(n){ return (n.split('.').pop()||'').toLowerCase(); }\r\nfunction getType(ext){\r\n  if(\/^(docx|doc|odt)$\/.test(ext)) return 'word';\r\n  if(\/^(xlsx|xls|ods)$\/.test(ext)) return 'excel';\r\n  if(\/^(pdf)$\/.test(ext)) return 'pdf';\r\n  if(\/^(pptx|ppt)$\/.test(ext)) return 'ppt';\r\n  if(\/^(csv)$\/.test(ext)) return 'data';\r\n  if(\/^(json|xml|html|htm|yaml|yml)$\/.test(ext)) return 'data';\r\n  if(\/^(txt|md|log|ini|toml)$\/.test(ext)) return 'text';\r\n  return null;\r\n}\r\nfunction typeIcon(type,ext){\r\n  if(type==='word') return '\ud83d\udcd8'; if(type==='excel') return '\ud83d\udcd7';\r\n  if(type==='pdf') return '\ud83d\udcd5'; if(type==='ppt') return '\ud83d\udcd9';\r\n  if(ext==='json') return '\ud83d\udfe0'; if(ext==='csv') return '\ud83d\udfe2';\r\n  if(ext==='xml') return '\ud83d\udd35'; if(ext==='html'||ext==='htm') return '\ud83c\udf10';\r\n  if(ext==='md') return '\u270d\ufe0f'; if(type==='text') return '\ud83d\udcdd'; return '\ud83d\udcc4';\r\n}\r\nfunction stripCls(ext){\r\n  const m={docx:'word',doc:'word',xlsx:'excel',xls:'excel',ods:'excel',\r\n    pdf:'pdf',pptx:'ppt',ppt:'ppt',txt:'txt',md:'md',csv:'csv',\r\n    json:'json',xml:'xml',html:'xml',htm:'xml',log:'txt'};\r\n  return 's-'+(m[ext]||'other');\r\n}\r\nfunction typeLabelStyle(type){\r\n  const m={word:'background:#dbeafe;color:#1e40af',excel:'background:#d1fae5;color:#065f46',\r\n    pdf:'background:#fee2e2;color:#991b1b',ppt:'background:#fff7ed;color:#9a3412',\r\n    data:'background:#fef3c7;color:#92400e',text:'background:#f3e8ff;color:#6b21a8'};\r\n  return m[type]||'background:#f1f5f9;color:#475569';\r\n}\r\nfunction iconBg(type){\r\n  const m={word:'#dbeafe',excel:'#d1fae5',pdf:'#fee2e2',ppt:'#fff7ed',data:'#fef3c7',text:'#f3e8ff'};\r\n  return m[type]||'#f1f5f9';\r\n}\r\nfunction detectDate(name){\r\n  const ps=[\/(\\d{4})[-_](\\d{2})[-_](\\d{2})\/,\/(\\d{4})(\\d{2})(\\d{2})\/];\r\n  for(const p of ps){ const m=name.match(p); if(m){const[y,mo,d]=[+m[1],+m[2],+m[3]]; if(y>1990&&y<2035&&mo>=1&&mo<=12&&d>=1&&d<=31) return new Date(y,mo-1,d);} }\r\n  return null;\r\n}\r\n\r\nasync function addFile(blob, name){\r\n  const ext=getExt(name), type=getType(ext);\r\n  if(!type) return;\r\n  const id='doc_'+(++S.fileIdCounter);\r\n  const rec={id,name,ext,type,size:blob.size,blob,\r\n    url:URL.createObjectURL(blob), folder:'Unsorted',\r\n    tags:[], starred:false, note:'',\r\n    modifiedDate: blob.lastModified ? new Date(blob.lastModified) : null,\r\n    detectedDate: detectDate(name),\r\n    createdDate: null,\r\n    hashKey:name.toLowerCase()+'_'+blob.size,\r\n    thumbText:null, wordStats:null\r\n  };\r\n  if(['txt','csv','json','xml','html','md','log'].includes(ext)&&blob.size<500000){\r\n    const reader=new FileReader();\r\n    reader.onload=e=>{ rec.thumbText=e.target.result.substring(0,160);\r\n      S.fileContent[id]=(e.target.result||'').toLowerCase(); renderGallery(); };\r\n    reader.readAsText(blob.slice(0,600));\r\n  }\r\n  S.files.push(rec);\r\n  if(['docx','xlsx','pptx'].includes(ext)&&typeof JSZip!=='undefined'){\r\n    extractDocMeta(rec);\r\n  }\r\n}\r\n\r\nasync function extractDocMeta(rec){\r\n  try{\r\n    const zip=await JSZip.loadAsync(rec.blob);\r\n    const coreXml=zip.file('docProps\/core.xml');\r\n    if(coreXml){\r\n      const txt=await coreXml.async('text');\r\n      const created=txt.match(\/<dcterms:created[^>]*>([^<]+)\/);\r\n      const modified=txt.match(\/<dcterms:modified[^>]*>([^<]+)\/);\r\n      if(created) rec.createdDate=new Date(created[1]);\r\n      if(modified&&!rec.modifiedDate) rec.modifiedDate=new Date(modified[1]);\r\n    }\r\n    if(rec.ext==='pptx'){\r\n      const slides=await extractPptxSlides(zip);\r\n      S.pptSlideState[rec.id]={slides,currentIdx:0};\r\n      S.fileContent[rec.id]=slides.map(s=>(s.title+' '+s.body.join(' ')).toLowerCase()).join(' ');\r\n    }\r\n    if(rec.ext==='docx'&&typeof mammoth!=='undefined'){\r\n      const ab=await rec.blob.arrayBuffer();\r\n      mammoth.extractRawText({arrayBuffer:ab}).then(r=>{\r\n        S.fileContent[rec.id]=(r.value||'').toLowerCase();\r\n        const text=r.value||'';\r\n        rec.wordStats={words:text.trim().split(\/\\s+\/).filter(w=>w).length,\r\n          chars:text.length, paras:text.split(\/\\n\\n+\/).filter(p=>p.trim()).length};\r\n      }).catch(()=>{});\r\n    }\r\n    if(rec.ext==='xlsx'&&typeof XLSX!=='undefined'){\r\n      const ab=await rec.blob.arrayBuffer();\r\n      const wb=XLSX.read(new Uint8Array(ab),{type:'array'});\r\n      let allText='';\r\n      wb.SheetNames.forEach(sn=>{\r\n        const rows=XLSX.utils.sheet_to_json(wb.Sheets[sn],{header:1,defval:''});\r\n        allText+=rows.map(r=>r.join(' ')).join(' ');\r\n      });\r\n      S.fileContent[rec.id]=allText.toLowerCase();\r\n    }\r\n  }catch(e){}\r\n}\r\n\r\nasync function extractPptxSlides(zip){\r\n  const slides=[];\r\n  const slideFiles=Object.keys(zip.files).filter(p=>\/^ppt\\\/slides\\\/slide\\d+\\.xml$\/.test(p)).sort();\r\n  for(const sf of slideFiles){\r\n    const xml=await zip.file(sf).async('text');\r\n    const titleMatch=xml.match(\/<p:sp[^>]*>(?:(?!<\\\/p:sp>)[\\s\\S])*?<p:ph[^>]*type=\"title\"[^>]*\\\/>[\\s\\S]*?<a:t>([^<]*)<\\\/a:t>\/);\r\n    const allTexts=[...xml.matchAll(\/<a:t>([^<]*)<\\\/a:t>\/g)].map(m=>m[1]).filter(t=>t.trim());\r\n    const title=titleMatch?titleMatch[1]:(allTexts[0]||'(Untitled Slide)');\r\n    const body=allTexts.filter(t=>t!==title).filter(t=>t.trim());\r\n    const slideNum=parseInt((sf.match(\/slide(\\d+)\/)||[,'?'])[1]);\r\n    const bgMatch=xml.match(\/solidFill[\\s\\S]*?val=\"([0-9A-Fa-f]{6})\"\/);\r\n    const bg=bgMatch?'#'+bgMatch[1]:null;\r\n    slides.push({title,body,slideNum,bg});\r\n  }\r\n  return slides;\r\n}\r\n\r\nasync function extractZip(zipBlob){\r\n  if(typeof JSZip==='undefined') throw new Error('JSZip not loaded');\r\n  const zip=await JSZip.loadAsync(zipBlob);\r\n  const ps=[];\r\n  zip.forEach((path,entry)=>{\r\n    if(!entry.dir) ps.push(entry.async('blob').then(b=>{\r\n      Object.defineProperty(b,'name',{value:path.split('\/').pop()});\r\n      Object.defineProperty(b,'lastModified',{value:entry.date?.getTime()||Date.now()});\r\n      return addFile(b,path.split('\/').pop());\r\n    }));\r\n  });\r\n  await Promise.all(ps);\r\n}\r\n\r\nasync function processFiles(fileList){\r\n  const files=Array.from(fileList); if(!files.length) return;\r\n  showProg('Processing Files\u2026',files.length+' items',10);\r\n  for(const f of files){\r\n    if(f.name.toLowerCase().endsWith('.zip')) await extractZip(f);\r\n    else await addFile(f,f.name);\r\n  }\r\n  hideProg(); finalizeLoad();\r\n}\r\n\r\nasync function traverseEntry(entry){\r\n  return new Promise(resolve=>{\r\n    if(entry.isFile) entry.file(async f=>{ if(f.name.toLowerCase().endsWith('.zip')){await extractZip(f);resolve();}else{await addFile(f,f.name);resolve();} });\r\n    else if(entry.isDirectory){ const r=entry.createReader(); r.readEntries(async es=>{ for(const e of es) await traverseEntry(e); resolve(); }); }\r\n    else resolve();\r\n  });\r\n}\r\n\r\nfunction finalizeLoad(){\r\n  if(!S.files.length) return;\r\n  $('dropzone').style.display='none'; $('workspace').style.display='block';\r\n  updateStats(); renderSidebar(); renderGallery();\r\n}\r\n\r\nfunction updateStats(){\r\n  let word=0,excel=0,ppt=0,pdf=0,data=0,text=0,total=0,size=0;\r\n  const seen={};\r\n  S.dupIds.clear();\r\n  for(const f of S.files){\r\n    total++; size+=f.size;\r\n    if(f.type==='word')word++; else if(f.type==='excel')excel++;\r\n    else if(f.type==='ppt')ppt++; else if(f.type==='pdf')pdf++;\r\n    else if(f.type==='data')data++; else if(f.type==='text')text++;\r\n    if(seen[f.hashKey]) S.dupIds.add(f.id); else seen[f.hashKey]=true;\r\n  }\r\n  $('s-total').textContent=total; $('s-word').textContent=word;\r\n  $('s-excel').textContent=excel; $('s-ppt').textContent=ppt;\r\n  $('s-pdf').textContent=pdf; $('s-data').textContent=data;\r\n  $('s-text').textContent=text; $('s-size').textContent=fmtBytes(size);\r\n  $('stor-lbl').textContent=fmtBytes(size);\r\n  $('stor-fill').style.width=Math.min(100,(size\/(5*1024*1024*1024))*100)+'%';\r\n}\r\n\r\nfunction renderSidebar(){\r\n  const counts={All:S.files.length,word:0,excel:0,ppt:0,pdf:0,data:0,text:0,starred:0};\r\n  const extMap={},folderMap={};\r\n  S.customFolders.forEach(f=>{ folderMap[f]=0; });\r\n  for(const f of S.files){\r\n    counts[f.type]=(counts[f.type]||0)+1;\r\n    if(f.starred) counts.starred++;\r\n    extMap[f.ext]=(extMap[f.ext]||0)+1;\r\n    if(S.customFolders.includes(f.folder)) folderMap[f.folder]=(folderMap[f.folder]||0)+1;\r\n  }\r\n  function li(folder,icon,label,count){\r\n    const act=S.currentFolder===folder?'active':'';\r\n    return '<div class=\"fi '+act+'\" data-folder=\"'+folder+'\"><div class=\"fi-left\"><span>'+icon+'<\/span><span class=\"fi-name\">'+label+'<\/span><\/div><span class=\"fi-count\">'+count+'<\/span><\/div>';\r\n  }\r\n  $('fl-types').innerHTML=li('All','\ud83d\uddc2\ufe0f','All Documents',counts.All)+li('word','\ud83d\udcd8','Word',counts.word)+li('excel','\ud83d\udcd7','Excel',counts.excel)+li('ppt','\ud83d\udcd9','PowerPoint',counts.ppt)+li('pdf','\ud83d\udcd5','PDF',counts.pdf)+li('data','\ud83d\uddc4\ufe0f','Data Files',counts.data)+li('text','\ud83d\udcdd','Text Files',counts.text)+li('starred','\u2b50','Starred',counts.starred);\r\n  $('fl-custom').innerHTML=S.customFolders.length?S.customFolders.map(f=>li('folder:'+f,'\ud83d\udcc1',f,folderMap[f]||0)).join(''):'<div class=\"empty-hint\">No custom folders<\/div>';\r\n  const topExts=Object.entries(extMap).sort((a,b)=>b[1]-a[1]).slice(0,10);\r\n  $('fl-ext').innerHTML=topExts.map(e=>li('ext:'+e[0],typeIcon(getType(e[0])||'text',e[0]),'.'+e[0].toUpperCase(),e[1])).join('');\r\n  \r\n  const favFiles=S.files.filter(f=>f.starred);\r\n  $('fl-favs').innerHTML=favFiles.length?favFiles.map(f=>'<div class=\"fi\" data-file-id=\"'+f.id+'\"><div class=\"fi-left\"><span>'+typeIcon(f.type,f.ext)+'<\/span><span class=\"fi-name\">'+f.name+'<\/span><\/div><\/div>').join(''):'<div class=\"empty-hint\">No starred files<\/div>';\r\n  \r\n  const recent=S.recentIds.slice(0,8).map(id=>S.files.find(f=>f.id===id)).filter(Boolean);\r\n  $('fl-recent').innerHTML=recent.length?recent.map(f=>'<div class=\"recent-item\" data-file-id=\"'+f.id+'\">'+typeIcon(f.type,f.ext)+' <span style=\"overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1\">'+f.name+'<\/span><\/div>').join(''):'<div class=\"empty-hint\">None yet<\/div>';\r\n\r\n  qsa('.fi[data-folder]').forEach(el=>el.addEventListener('click',function(){\r\n    S.currentFolder=this.dataset.folder; S.selectedIds.clear();\r\n    $('folder-title').textContent=S.currentFolder.replace('folder:','\ud83d\udcc1 ').replace('ext:','.').replace(\/^(word|excel|ppt|pdf|data|text|starred)$\/,t=>({word:'Word Docs',excel:'Spreadsheets',ppt:'PowerPoint',pdf:'PDFs',data:'Data Files',text:'Text Files',starred:'\u2b50 Starred'}[t]||t));\r\n    renderSidebar(); renderGallery();\r\n  }));\r\n  qsa('.fi[data-file-id], .recent-item[data-file-id]').forEach(el=>el.addEventListener('click',function(){\r\n    openPreview(this.dataset.fileId);\r\n  }));\r\n}\r\n\r\nfunction getDisplayFiles(){\r\n  let files=S.files.filter(f=>{\r\n    if(S.currentFolder==='All') return true;\r\n    if(S.currentFolder==='starred') return f.starred;\r\n    if(['word','excel','ppt','pdf','data','text'].includes(S.currentFolder)) return f.type===S.currentFolder;\r\n    if(S.currentFolder.startsWith('folder:')) return f.folder===S.currentFolder.slice(7);\r\n    if(S.currentFolder.startsWith('ext:')) return f.ext===S.currentFolder.slice(4);\r\n    return true;\r\n  });\r\n  if(S.filterType!=='all'&&S.filterType!=='starred') files=files.filter(f=>f.type===S.filterType);\r\n  if(S.filterType==='starred') files=files.filter(f=>f.starred);\r\n  if(S.searchQ) files=files.filter(f=>f.name.toLowerCase().includes(S.searchQ));\r\n  const ds=$('df-start').value, de=$('df-end').value, src=$('df-source')?.value||'modified';\r\n  if(ds||de){\r\n    const start=ds?new Date(ds):new Date(0);\r\n    const end=de?(()=>{const d=new Date(de);d.setHours(23,59,59,999);return d;})():new Date(8.64e15);\r\n    files=files.filter(f=>{\r\n      let d=null;\r\n      if(src==='modified') d=f.modifiedDate;\r\n      else if(src==='created') d=f.createdDate||f.modifiedDate;\r\n      else if(src==='detected') d=f.detectedDate;\r\n      return d&&d>=start&&d<=end;\r\n    });\r\n  }\r\n  switch(S.sortMode){\r\n    case 'name-desc': files.sort((a,b)=>b.name.localeCompare(a.name)); break;\r\n    case 'size-desc': files.sort((a,b)=>b.size-a.size); break;\r\n    case 'size-asc': files.sort((a,b)=>a.size-b.size); break;\r\n    case 'type': files.sort((a,b)=>a.type.localeCompare(b.type)); break;\r\n    case 'ext': files.sort((a,b)=>a.ext.localeCompare(b.ext)); break;\r\n    case 'date-desc': files.sort((a,b)=>(b.modifiedDate||0)-(a.modifiedDate||0)); break;\r\n    case 'date-asc': files.sort((a,b)=>(a.modifiedDate||0)-(b.modifiedDate||0)); break;\r\n    default: files.sort((a,b)=>a.name.localeCompare(b.name));\r\n  }\r\n  return files;\r\n}\r\n\r\nfunction renderGallery(){\r\n  const grid=$('fgrid');\r\n  grid.className='fgrid'+(S.viewMode==='list'?' list-view':'');\r\n  const display=getDisplayFiles();\r\n  S.prevIds=display.map(f=>f.id);\r\n  const hasSel=S.selectedIds.size>0;\r\n  $('btn-delete').disabled=!hasSel; $('btn-move').disabled=!hasSel; $('btn-exp-sel').disabled=!hasSel;\r\n  $('btn-sel-all').textContent=hasSel?'\u2715 Deselect':'\u2611\ufe0f Select All';\r\n\r\n  if(!display.length){\r\n    grid.innerHTML='<div class=\"gallery-empty\"><div style=\"font-size:40px;margin-bottom:10px\">\ud83d\udced<\/div><div style=\"font-weight:600\">No documents match current filters<\/div><\/div>';\r\n    return;\r\n  }\r\n  const isList=S.viewMode==='list';\r\n  grid.innerHTML=display.map(f=>{\r\n    const sel=S.selectedIds.has(f.id);\r\n    const dup=S.dupIds.has(f.id);\r\n    const icon=typeIcon(f.type,f.ext);\r\n    const tagDots=(f.tags||[]).map(t=>'<span class=\"ctag\" style=\"background:'+(S.tags[t]||'#3b82f6')+'20;color:'+(S.tags[t]||'#3b82f6')+';border:1px solid '+(S.tags[t]||'#3b82f6')+'40\">'+t+'<\/span>').join('');\r\n    let prev;\r\n    if(f.thumbText) prev='<div class=\"card-thumb\">'+f.thumbText.replace(\/<\/g,'&lt;').replace(\/>\/g,'&gt;')+'<\/div>';\r\n    else prev='<div class=\"card-ficon\"><div style=\"font-size:36px\">'+icon+'<\/div><span class=\"card-tlabel\" style=\"'+typeLabelStyle(f.type)+'\">'+f.ext.toUpperCase()+'<\/span><\/div>';\r\n    const dateStr=f.modifiedDate?f.modifiedDate.toLocaleDateString():'';\r\n    \r\n    if(!isList) return '<div class=\"fcard'+(sel?' selected':'')+(f.starred?' starred':'')+'\" data-id=\"'+f.id+'\">'+\r\n      '<div class=\"card-strip '+stripCls(f.ext)+'\"><\/div>'+\r\n      (dup?'<span class=\"dup-badge\">DUP<\/span>':'')+\r\n      '<input type=\"checkbox\" class=\"card-checkbox\"'+(sel?' checked':'')+' data-id=\"'+f.id+'\">'+\r\n      '<div class=\"card-prev ptrig\" data-id=\"'+f.id+'\">'+prev+'<\/div>'+\r\n      (tagDots?'<div class=\"card-tag\">'+tagDots+'<\/div>':'')+\r\n      '<div class=\"card-info\">'+\r\n        '<div class=\"card-name\" title=\"'+f.name+'\">'+f.name+'<\/div>'+\r\n        '<div class=\"card-meta\"><span>'+fmtBytes(f.size)+'<\/span><span class=\"card-ext\">'+f.ext.toUpperCase()+'<\/span><\/div>'+\r\n        (dateStr?'<div style=\"font-size:10px;color:var(--t3);margin-top:3px\">\ud83d\udcc5 '+dateStr+'<\/div>':'')+\r\n      '<\/div>'+\r\n    '<\/div>';\r\n\r\n    return '<div class=\"fcard list-card'+(sel?' selected':'')+(f.starred?' starred':'')+'\" data-id=\"'+f.id+'\">'+\r\n      '<div class=\"card-strip '+stripCls(f.ext)+'\"><\/div>'+\r\n      '<input type=\"checkbox\" class=\"card-checkbox\"'+(sel?' checked':'')+' data-id=\"'+f.id+'\">'+\r\n      '<div class=\"card-prev ptrig\" data-id=\"'+f.id+'\">'+prev+'<\/div>'+\r\n      '<div class=\"card-info\">'+\r\n        '<div>'+\r\n          '<div class=\"card-name\" style=\"font-size:13px\">'+f.name+(dup?'<span style=\"margin-left:7px;background:var(--rl);color:var(--red);font-size:9px;padding:1px 5px;border-radius:3px;font-weight:800\">DUP<\/span>':'')+'<\/div>'+\r\n          '<div style=\"font-size:11px;color:var(--t3);display:flex;gap:12px;margin-top:3px\">'+\r\n            '<span>'+fmtBytes(f.size)+'<\/span><span>'+f.ext.toUpperCase()+'<\/span>'+\r\n            (dateStr?'<span>\ud83d\udcc5 '+dateStr+'<\/span>':'')+\r\n            '<span>\ud83d\udcc1 '+f.folder+'<\/span>'+\r\n          '<\/div>'+\r\n          (tagDots?'<div style=\"margin-top:4px\">'+tagDots+'<\/div>':'')+\r\n        '<\/div>'+\r\n        '<div class=\"card-actions\">'+\r\n          '<button class=\"pth-btn pth-btn-secondary pth-btn-xs ptrig\" data-id=\"'+f.id+'\">\ud83d\udc41 Preview<\/button>'+\r\n          '<button class=\"pth-btn pth-btn-amber pth-btn-xs star-btn\" data-id=\"'+f.id+'\">'+(f.starred?'\u2b50':'\u2606')+'<\/button>'+\r\n        '<\/div>'+\r\n      '<\/div>'+\r\n    '<\/div>';\r\n  }).join('');\r\n\r\n  grid.querySelectorAll('.card-checkbox').forEach(chk=>{\r\n    chk.addEventListener('click',e=>e.stopPropagation());\r\n    chk.addEventListener('change',function(){\r\n      if(this.checked) S.selectedIds.add(this.dataset.id); else S.selectedIds.delete(this.dataset.id);\r\n      this.closest('.fcard').classList.toggle('selected',this.checked);\r\n      $('btn-delete').disabled=S.selectedIds.size===0;\r\n      $('btn-move').disabled=S.selectedIds.size===0;\r\n      $('btn-exp-sel').disabled=S.selectedIds.size===0;\r\n      $('btn-sel-all').textContent=S.selectedIds.size>0?'\u2715 Deselect':'\u2611\ufe0f Select All';\r\n    });\r\n  });\r\n  grid.querySelectorAll('.ptrig').forEach(el=>el.addEventListener('click',e=>{\r\n    e.stopPropagation();\r\n    if(S.compareModeOn){ loadComparePane(el.dataset.id); return; }\r\n    openPreview(el.dataset.id);\r\n  }));\r\n  grid.querySelectorAll('.star-btn').forEach(btn=>btn.addEventListener('click',e=>{\r\n    e.stopPropagation(); toggleStar(btn.dataset.id);\r\n  }));\r\n}\r\n\r\nfunction toggleStar(id){\r\n  const f=S.files.find(x=>x.id===id); if(!f) return;\r\n  f.starred=!f.starred;\r\n  toast(f.starred?'\u2b50 Starred: '+f.name:'\u2606 Unstarred: '+f.name);\r\n  renderSidebar(); renderGallery();\r\n}\r\n\r\nfunction addToRecent(id){\r\n  S.recentIds=S.recentIds.filter(x=>x!==id); S.recentIds.unshift(id);\r\n  if(S.recentIds.length>10) S.recentIds.pop();\r\n}\r\n\r\nfunction openPreview(id){\r\n  S.prevIdx=S.prevIds.indexOf(id);\r\n  if(S.prevIdx===-1){ S.prevIds=[id]; S.prevIdx=0; }\r\n  renderPreview(id); showOv('modal-prev');\r\n}\r\n\r\nfunction renderPreview(id){\r\n  const f=S.files.find(x=>x.id===id); if(!f) return;\r\n  S.activePrevFile=f; addToRecent(id); renderSidebar();\r\n  $('prev-fname').textContent=f.name;\r\n  $('prev-fmeta').textContent=fmtBytes(f.size)+' \u00b7 '+f.ext.toUpperCase()+(f.modifiedDate?' \u00b7 '+f.modifiedDate.toLocaleDateString():'');\r\n  const ib=$('prev-ibox'); ib.textContent=typeIcon(f.type,f.ext); ib.style.background=iconBg(f.type);\r\n  $('btn-prev-star').textContent=f.starred?'\u2b50 Starred':'\u2606 Star';\r\n\r\n  const dlBtn=$('btn-dl-prev'), nb=dlBtn.cloneNode(true); nb.id='btn-dl-prev';\r\n  dlBtn.parentNode.replaceChild(nb,dlBtn);\r\n  nb.addEventListener('click',()=>{ const a=document.createElement('a'); a.href=f.url; a.download=f.name; document.body.appendChild(a); a.click(); document.body.removeChild(a); });\r\n\r\n  const tabs=[{id:'main',label:'\ud83d\udc41 Preview'}];\r\n  if(f.type==='word') tabs.push({id:'raw',label:'\ud83d\udcc4 HTML Source'},{id:'stats',label:'\ud83d\udcca Word Stats'});\r\n  if(f.type==='excel') tabs.push({id:'raw',label:'\ud83d\udcdd Raw CSV'});\r\n  if(f.type==='ppt') tabs.push({id:'slideshow',label:'\ud83c\udfac Slideshow'});\r\n  if(['json','xml','html','txt','md','csv'].includes(f.ext)) tabs.push({id:'raw',label:'\ud83d\udcdd Source'});\r\n  tabs.push({id:'info',label:'\u2139\ufe0f File Info'},{id:'notes',label:'\ud83d\udcd3 Notes'});\r\n  \r\n  $('prev-tabs').innerHTML=tabs.map((t,i)=>'<button class=\"ptab'+(i===0?' active':'')+'\" data-pane=\"'+t.id+'\">'+t.label+'<\/button>').join('');\r\n  $('prev-body').innerHTML=tabs.map((t,i)=>'<div class=\"ppane'+(i===0?' active':'')+'\" id=\"ppane-'+t.id+'\"><\/div>').join('');\r\n\r\n  const infoPaneEl=$('ppane-info');\r\n  if(infoPaneEl){\r\n    const rows=[['Name',f.name],['Extension','.'+f.ext.toUpperCase()],['Type',f.type],['Size',fmtBytes(f.size)+' ('+f.size.toLocaleString()+' bytes)'],['Folder',f.folder],['Last Modified',f.modifiedDate?f.modifiedDate.toLocaleString():'Unknown'],['Created',f.createdDate?f.createdDate.toLocaleString():'Unknown'],['Detected Date',f.detectedDate?f.detectedDate.toLocaleDateString():'Not found'],['Hash',f.hashKey]];\r\n    infoPaneEl.innerHTML='<div style=\"padding:22px;width:100%;overflow:auto\"><table class=\"info-tbl\">'+rows.map(r=>'<tr><td>'+r[0]+'<\/td><td>'+r[1]+'<\/td><\/tr>').join('')+'<\/table><\/div>';\r\n  }\r\n  \r\n  const notesPaneEl=$('ppane-notes');\r\n  if(notesPaneEl){\r\n    notesPaneEl.innerHTML='<textarea class=\"notes-area\" id=\"notes-ta\" placeholder=\"Write notes about this document\u2026\">'+(f.note||'')+'<\/textarea>';\r\n    $('notes-ta')?.addEventListener('input',function(){ f.note=this.value; });\r\n  }\r\n\r\n  $('prev-tabs').querySelectorAll('.ptab').forEach(btn=>{\r\n    btn.addEventListener('click',function(){\r\n      $('prev-tabs').querySelectorAll('.ptab').forEach(b=>b.classList.remove('active'));\r\n      $('prev-body').querySelectorAll('.ppane').forEach(p=>p.classList.remove('active'));\r\n      this.classList.add('active');\r\n      const pane=$('ppane-'+this.dataset.pane);\r\n      if(pane) pane.classList.add('active');\r\n    });\r\n  });\r\n  \r\n  setTimeout(()=>renderDocPreview(f,$('ppane-main'),true),80);\r\n}\r\n\r\nfunction renderDocPreview(f,container,fillRaw=false){\r\n  if(!container) return;\r\n  container.innerHTML='<div class=\"loading-state\"><div class=\"spinner\"><\/div><div style=\"font-weight:600\">Rendering\u2026<\/div><\/div>';\r\n\r\n  if(f.ext==='pdf'){\r\n    container.innerHTML='<iframe src=\"'+f.url+'#toolbar=1&view=FitH\" class=\"pdf-frame\"><\/iframe>';\r\n    return;\r\n  }\r\n\r\n  if(f.type==='word'){\r\n    if(typeof mammoth==='undefined'){ container.innerHTML='<div class=\"loading-state\"><div>Mammoth.js not loaded<\/div><\/div>'; return; }\r\n    if(f.ext==='doc'){ container.innerHTML='<div class=\"loading-state\"><div style=\"font-size:36px\">\u26a0\ufe0f<\/div><div style=\"font-weight:700;margin-bottom:8px\">Binary .doc format not supported in-browser<\/div><div style=\"font-size:13px;color:var(--t3)\">Please convert to .docx format using Microsoft Word, LibreOffice, or Google Docs, then re-upload.<\/div><\/div>'; return; }\r\n    const reader=new FileReader();\r\n    reader.onload=e=>{\r\n      mammoth.convertToHtml({arrayBuffer:e.target.result},{\r\n        styleMap:[\"p[style-name='Title'] => h1:fresh\",\"p[style-name='Heading 1'] => h1:fresh\",\"p[style-name='Heading 2'] => h2:fresh\",\"p[style-name='Heading 3'] => h3:fresh\",\"p[style-name='Heading 4'] => h4:fresh\"],\r\n        convertImage:mammoth.images.imgElement(img=>img.read('base64').then(data=>({src:'data:'+img.contentType+';base64,'+data})))\r\n      }).then(result=>{\r\n        const hasRtl=\/[\\u0600-\\u06FF\\u0590-\\u05FF\\u0750-\\u077F\\u0900-\\u097F\\u0D80-\\u0DFF]\/.test(result.value);\r\n        const dir=hasRtl?'dir=\"rtl\"':'dir=\"ltr\"';\r\n        const html=result.value||'<p style=\"color:var(--t3)\"><em>Document appears empty or uses unsupported formatting.<\/em><\/p>';\r\n        container.innerHTML='<div class=\"doc-wrap\"><div class=\"doc-paper\" '+dir+'>'+html+'<\/div><\/div>';\r\n        if(fillRaw){\r\n          const rawPane=$('ppane-raw');\r\n          if(rawPane) rawPane.innerHTML='<div class=\"code-view\"><pre>'+html.replace(\/<\/g,'&lt;').replace(\/>\/g,'&gt;')+'<\/pre><\/div>';\r\n        }\r\n        const statsPane=$('ppane-stats');\r\n        if(statsPane&&f.wordStats){\r\n          statsPane.innerHTML='<div style=\"padding:24px;width:100%\"><div class=\"word-stats\">'+\r\n            '<div class=\"ws-card\"><div class=\"ws-val\">'+f.wordStats.words.toLocaleString()+'<\/div><div class=\"ws-lbl\">Words<\/div><\/div>'+\r\n            '<div class=\"ws-card\"><div class=\"ws-val\">'+f.wordStats.chars.toLocaleString()+'<\/div><div class=\"ws-lbl\">Characters<\/div><\/div>'+\r\n            '<div class=\"ws-card\"><div class=\"ws-val\">'+f.wordStats.paras.toLocaleString()+'<\/div><div class=\"ws-lbl\">Paragraphs<\/div><\/div>'+\r\n          '<\/div><\/div>';\r\n        } else if(statsPane){\r\n          statsPane.innerHTML='<div style=\"padding:24px;color:var(--t3);font-size:13px\">Word stats will appear after document finishes loading\u2026<\/div>';\r\n        }\r\n      }).catch(err=>{\r\n        container.innerHTML='<div class=\"loading-state\"><div style=\"font-size:36px\">\u274c<\/div><div style=\"font-weight:700;color:var(--red)\">Rendering Error<\/div><div style=\"font-size:12px;margin-top:7px;color:var(--t3)\">'+err.message+'<\/div><\/div>';\r\n      });\r\n    };\r\n    reader.onerror=()=>{ container.innerHTML='<div class=\"loading-state\"><div>Failed to read file<\/div><\/div>'; };\r\n    reader.readAsArrayBuffer(f.blob);\r\n    return;\r\n  }\r\n\r\n  if(f.type==='excel'){\r\n    if(typeof XLSX==='undefined'){ container.innerHTML='<div class=\"loading-state\"><div>SheetJS not loaded<\/div><\/div>'; return; }\r\n    const reader=new FileReader();\r\n    reader.onload=e=>{\r\n      try{\r\n        const wb=XLSX.read(new Uint8Array(e.target.result),{type:'array'});\r\n        const renderSheet=idx=>{\r\n          const ws=wb.Sheets[wb.SheetNames[idx]];\r\n          const rows=XLSX.utils.sheet_to_json(ws,{header:1,defval:''});\r\n          if(!rows.length) return '<div style=\"padding:20px;color:var(--t3)\">Empty sheet<\/div>';\r\n          const hdrs=rows[0], dataRows=rows.slice(1);\r\n          return '<div class=\"sheet-tbwrap\"><table class=\"sheet-tbl\"><thead><tr>'+hdrs.map(h=>'<th>'+String(h).replace(\/<\/g,'&lt;')+'<\/th>').join('')+'<\/tr><\/thead><tbody>'+dataRows.map(r=>'<tr>'+hdrs.map((_,ci)=>'<td>'+String(r[ci]===undefined?'':r[ci]).replace(\/<\/g,'&lt;')+'<\/td>').join('')+'<\/tr>').join('')+'<\/tbody><\/table><\/div>';\r\n        };\r\n        const tabHtml='<div class=\"sheet-nav\">'+wb.SheetNames.map((s,i)=>'<button class=\"stab'+(i===0?' active':'')+'\" data-si=\"'+i+'\">'+s+'<\/button>').join('')+'<\/div>';\r\n        container.innerHTML='<div class=\"sheet-wrap\">'+tabHtml+'<div id=\"sheet-body-'+f.id+'\">'+renderSheet(0)+'<\/div><\/div>';\r\n        container.querySelectorAll('.stab').forEach(btn=>btn.addEventListener('click',function(){\r\n          container.querySelectorAll('.stab').forEach(b=>b.classList.remove('active')); this.classList.add('active');\r\n          const sb=container.querySelector('[id^=\"sheet-body-\"]'); if(sb) sb.innerHTML=renderSheet(parseInt(this.dataset.si));\r\n        }));\r\n        if(fillRaw){\r\n          const rawPane=$('ppane-raw');\r\n          if(rawPane){\r\n            const csv=XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]);\r\n            rawPane.innerHTML='<div class=\"code-view\"><pre>'+csv.replace(\/<\/g,'&lt;')+'<\/pre><\/div>';\r\n          }\r\n        }\r\n      }catch(err){ container.innerHTML='<div class=\"loading-state\"><div style=\"font-size:36px\">\u274c<\/div><div>Error: '+err.message+'<\/div><\/div>'; }\r\n    };\r\n    reader.readAsArrayBuffer(f.blob);\r\n    return;\r\n  }\r\n\r\n  if(f.type==='ppt'){\r\n    const state=S.pptSlideState[f.id];\r\n    if(!state){\r\n      container.innerHTML='<div class=\"loading-state\"><div class=\"spinner\"><\/div><div>Extracting slides\u2026<\/div><\/div>';\r\n      if(typeof JSZip==='undefined'){ container.innerHTML='<div class=\"loading-state\"><div>JSZip not loaded<\/div><\/div>'; return; }\r\n      JSZip.loadAsync(f.blob).then(async zip=>{\r\n        if(f.ext==='ppt'){ container.innerHTML='<div class=\"loading-state\"><div style=\"font-size:36px\">\u26a0\ufe0f<\/div><div style=\"font-weight:700;margin-bottom:8px\">Binary .ppt format not fully supported<\/div><div style=\"font-size:13px;color:var(--t3)\">Please save as .pptx from PowerPoint or LibreOffice for full slide extraction.<\/div><\/div>'; return; }\r\n        const slides=await extractPptxSlides(zip);\r\n        S.pptSlideState[f.id]={slides,currentIdx:0};\r\n        renderPptSlides(f,container);\r\n        const ssPane=$('ppane-slideshow');\r\n        if(ssPane) renderPptFullSlideshow(f,ssPane);\r\n      }).catch(()=>{ container.innerHTML='<div class=\"loading-state\"><div>Could not parse PPTX<\/div><\/div>'; });\r\n      return;\r\n    }\r\n    renderPptSlides(f,container);\r\n    const ssPane=$('ppane-slideshow'); if(ssPane) renderPptFullSlideshow(f,ssPane);\r\n    return;\r\n  }\r\n\r\n  if(f.ext==='csv'){\r\n    const reader=new FileReader();\r\n    reader.onload=e=>{\r\n      const text=e.target.result, sep=text.includes('\\t')?'\\t':',';\r\n      const lines=text.split('\\n').filter(l=>l.trim());\r\n      if(!lines.length){ container.innerHTML='<div class=\"loading-state\">Empty file<\/div>'; return; }\r\n      const rows=lines.map(l=>l.split(sep)), hdrs=rows[0], drows=rows.slice(1);\r\n      container.innerHTML='<div class=\"sheet-wrap\"><div class=\"csv-info\">\ud83d\udcca '+drows.length.toLocaleString()+' rows \u00d7 '+hdrs.length+' columns \u00b7 '+fmtBytes(f.size)+'<\/div><div class=\"sheet-tbwrap\"><table class=\"sheet-tbl\"><thead><tr>'+hdrs.map(h=>'<th>'+(h||'').replace(\/<\/g,'&lt;').replace(\/\"\/g,'').trim()+'<\/th>').join('')+'<\/tr><\/thead><tbody>'+drows.map(r=>'<tr>'+hdrs.map((_,ci)=>'<td>'+((r[ci]||'').replace(\/<\/g,'&lt;').replace(\/\"\/g,'').trim())+'<\/td>').join('')+'<\/tr>').join('')+'<\/tbody><\/table><\/div><\/div>';\r\n      if(fillRaw){ const rp=$('ppane-raw'); if(rp) rp.innerHTML='<div class=\"code-view\"><pre>'+text.replace(\/<\/g,'&lt;')+'<\/pre><\/div>'; }\r\n    };\r\n    reader.readAsText(f.blob); return;\r\n  }\r\n\r\n  if(f.ext==='json'){\r\n    const reader=new FileReader();\r\n    reader.onload=e=>{\r\n      try{\r\n        const parsed=JSON.parse(e.target.result), pretty=JSON.stringify(parsed,null,2);\r\n        const hl=pretty.replace(\/&\/g,'&amp;').replace(\/<\/g,'&lt;').replace(\/>\/g,'&gt;')\r\n          .replace(\/\"([^\"]+)\":\/g,'<span class=\"jk\">\"$1\"<\/span>:')\r\n          .replace(\/: \"([^\"]*)\"\/g,': <span class=\"js\">\"$1\"<\/span>')\r\n          .replace(\/: (\\d+\\.?\\d*)\/g,': <span class=\"jn\">$1<\/span>')\r\n          .replace(\/: (true|false)\/g,': <span class=\"jb\">$1<\/span>')\r\n          .replace(\/: null\/g,': <span class=\"jnu\">null<\/span>');\r\n        container.innerHTML='<div class=\"code-view\"><pre>'+hl+'<\/pre><\/div>';\r\n        if(fillRaw){ const rp=$('ppane-raw'); if(rp) rp.innerHTML='<div class=\"code-view\"><pre>'+pretty.replace(\/<\/g,'&lt;')+'<\/pre><\/div>'; }\r\n      }catch(err){ readAsText(f,container,fillRaw); }\r\n    };\r\n    reader.readAsText(f.blob); return;\r\n  }\r\n\r\n  if(f.ext==='md'){\r\n    const reader=new FileReader();\r\n    reader.onload=e=>{\r\n      container.innerHTML='<div class=\"md-view\">'+parseMd(e.target.result)+'<\/div>';\r\n      if(fillRaw){ const rp=$('ppane-raw'); if(rp) rp.innerHTML='<div class=\"code-view\"><pre>'+e.target.result.replace(\/<\/g,'&lt;')+'<\/pre><\/div>'; }\r\n    };\r\n    reader.readAsText(f.blob); return;\r\n  }\r\n\r\n  if(['html','htm'].includes(f.ext)){\r\n    const reader=new FileReader();\r\n    reader.onload=e=>{\r\n      const blob2=new Blob([e.target.result],{type:'text\/html'});\r\n      container.innerHTML='<iframe src=\"'+URL.createObjectURL(blob2)+'\" style=\"width:100%;height:100%;border:none\"><\/iframe>';\r\n      if(fillRaw){ const rp=$('ppane-raw'); if(rp) rp.innerHTML='<div class=\"code-view\"><pre>'+e.target.result.replace(\/<\/g,'&lt;').replace(\/>\/g,'&gt;')+'<\/pre><\/div>'; }\r\n    };\r\n    reader.readAsText(f.blob); return;\r\n  }\r\n\r\n  if(f.ext==='xml'){\r\n    const reader=new FileReader();\r\n    reader.onload=e=>{\r\n      const fmt=e.target.result.replace(\/><\/g,'>\\n<');\r\n      container.innerHTML='<div class=\"code-view\"><pre>'+fmt.replace(\/<\/g,'&lt;').replace(\/>\/g,'&gt;')+'<\/pre><\/div>';\r\n    };\r\n    reader.readAsText(f.blob); return;\r\n  }\r\n\r\n  readAsText(f,container,fillRaw);\r\n}\r\n\r\nfunction readAsText(f,container,fillRaw){\r\n  const reader=new FileReader();\r\n  reader.onload=e=>{\r\n    const text=e.target.result, lines=text.split('\\n');\r\n    const nums=lines.map((_,i)=>String(i+1)).join('\\n');\r\n    const hasRtl=\/[\\u0600-\\u06FF\\u0590-\\u05FF]\/.test(text);\r\n    container.innerHTML='<div class=\"code-view\"><div class=\"ln-wrap\"><div class=\"ln-col\">'+nums+'<\/div><div class=\"code-col\"'+(hasRtl?' dir=\"rtl\"':'')+'>'+text.replace(\/<\/g,'&lt;').replace(\/>\/g,'&gt;')+'<\/div><\/div><\/div>';\r\n    if(fillRaw){ const rp=$('ppane-raw'); if(rp) rp.innerHTML=container.innerHTML; }\r\n  };\r\n  reader.onerror=()=>{ container.innerHTML='<div class=\"loading-state\"><div>Could not read file<\/div><\/div>'; };\r\n  reader.readAsText(f.blob);\r\n}\r\n\r\nfunction renderPptSlides(f,container){\r\n  const state=S.pptSlideState[f.id]; if(!state) return;\r\n  const {slides}=state;\r\n  if(!slides.length){ container.innerHTML='<div class=\"loading-state\"><div>No slides extracted<\/div><\/div>'; return; }\r\n  const thumbs=slides.map((s,i)=>'<div class=\"ppt-thumb'+(i===state.currentIdx?' active':'')+'\" data-idx=\"'+i+'\">Slide '+s.slideNum+': '+(s.title||'').substring(0,25)+'<\/div>').join('');\r\n  const renderSlide=idx=>{\r\n    const s=slides[idx];\r\n    const bgStyle=s.bg?'background:'+s.bg+';color:'+(isLight(s.bg)?'#111':'#fff'):'';\r\n    return '<div class=\"ppt-slide\"><div class=\"ppt-slide-header\"><span>Slide '+s.slideNum+' of '+slides.length+'<\/span><span>'+f.name+'<\/span><\/div><div class=\"ppt-slide-body\"'+(bgStyle?' style=\"'+bgStyle+'\"':'')+'><div class=\"ppt-title\">'+(s.title||'(No Title)').replace(\/<\/g,'&lt;')+'<\/div><div class=\"ppt-body-text\"><ul>'+s.body.map(b=>'<li>'+b.replace(\/<\/g,'&lt;')+'<\/li>').join('')+'<\/ul>'+(!s.body.length?'<p class=\"ppt-no-content\">This slide has no text content.<\/p>':'')+'<\/div><\/div><\/div>';\r\n  };\r\n  container.innerHTML='<div style=\"display:flex;flex-direction:column;width:100%;height:100%;overflow:hidden\"><div class=\"ppt-thumb-bar\">'+thumbs+'<\/div><div class=\"ppt-wrap\" id=\"ppt-main-'+f.id+'\">'+renderSlide(state.currentIdx)+'<\/div><\/div>';\r\n  container.querySelectorAll('.ppt-thumb').forEach(btn=>btn.addEventListener('click',function(){\r\n    state.currentIdx=parseInt(this.dataset.idx);\r\n    container.querySelectorAll('.ppt-thumb').forEach(b=>b.classList.remove('active'));\r\n    this.classList.add('active');\r\n    const main=container.querySelector('.ppt-wrap'); if(main) main.innerHTML=renderSlide(state.currentIdx);\r\n  }));\r\n}\r\n\r\nfunction renderPptFullSlideshow(f,container){\r\n  const state=S.pptSlideState[f.id]; if(!state||!state.slides.length) return;\r\n  const {slides}=state;\r\n  container.innerHTML='<div class=\"ppt-wrap\">'+slides.map((s,i)=>{\r\n    const bg=s.bg?'background:'+s.bg+';color:'+(isLight(s.bg)?'#111':'#fff'):'';\r\n    return '<div class=\"ppt-slide\"><div class=\"ppt-slide-header\"><span>Slide '+s.slideNum+'<\/span><button class=\"pth-btn pth-btn-secondary pth-btn-xs\" onclick=\"window.fsSlide(\\''+f.id+'\\','+i+')\">\u26f6 Fullscreen<\/button><\/div><div class=\"ppt-slide-body\"'+(bg?' style=\"'+bg+'\"':'')+'><div class=\"ppt-title\">'+(s.title||'').replace(\/<\/g,'&lt;')+'<\/div><div class=\"ppt-body-text\"><ul>'+s.body.map(b=>'<li>'+b.replace(\/<\/g,'&lt;')+'<\/li>').join('')+'<\/ul>'+(!s.body.length?'<p class=\"ppt-no-content\">No text content<\/p>':'')+'<\/div><\/div><\/div>';\r\n  }).join('')+'<\/div>';\r\n}\r\n\r\nfunction isLight(hex){\r\n  const r=parseInt(hex.slice(1,3),16),g=parseInt(hex.slice(3,5),16),b=parseInt(hex.slice(5,7),16);\r\n  return(r*299+g*587+b*114)\/1000>128;\r\n}\r\n\r\nwindow.fsSlide=(fileId,idx)=>{\r\n  const state=S.pptSlideState[fileId]; if(!state) return;\r\n  state.currentIdx=idx; renderFsSlide(state);\r\n  $('fs-slide').classList.add('open');\r\n};\r\n\r\nfunction renderFsSlide(state){\r\n  const s=state.slides[state.currentIdx];\r\n  const bg=s.bg?'background:'+s.bg+';color:'+(isLight(s.bg)?'#111':'#fff'):'';\r\n  $('fs-content').innerHTML='<div style=\"'+bg+';padding:60px 80px;border-radius:14px;min-height:50vh;display:flex;flex-direction:column;justify-content:center\"><div class=\"ppt-title\" style=\"font-size:32px;margin-bottom:18px\">'+(s.title||'').replace(\/<\/g,'&lt;')+'<\/div><ul class=\"ppt-body-text\" style=\"font-size:18px\">'+s.body.map(b=>'<li style=\"margin-bottom:8px\">'+b.replace(\/<\/g,'&lt;')+'<\/li>').join('')+'<\/ul><\/div>';\r\n  $('fs-counter').textContent=(state.currentIdx+1)+' \/ '+state.slides.length;\r\n}\r\n\r\nfunction parseMd(text){\r\n  return text\r\n    .replace(\/&\/g,'&amp;').replace(\/<\/g,'&lt;').replace(\/>\/g,'&gt;')\r\n    .replace(\/^#{6}\\s+(.+)\/gm,'<h6>$1<\/h6>').replace(\/^#{5}\\s+(.+)\/gm,'<h5>$1<\/h5>')\r\n    .replace(\/^#{4}\\s+(.+)\/gm,'<h4>$1<\/h4>').replace(\/^#{3}\\s+(.+)\/gm,'<h3>$1<\/h3>')\r\n    .replace(\/^#{2}\\s+(.+)\/gm,'<h2>$1<\/h2>').replace(\/^#{1}\\s+(.+)\/gm,'<h1>$1<\/h1>')\r\n    .replace(\/\\*\\*(.+?)\\*\\*\/g,'<strong>$1<\/strong>').replace(\/\\*(.+?)\\*\/g,'<em>$1<\/em>')\r\n    .replace(\/~~(.+?)~~\/g,'<del>$1<\/del>')\r\n    .replace(\/`{3}([\\s\\S]*?)`{3}\/g,'<pre><code>$1<\/code><\/pre>')\r\n    .replace(\/`([^`]+)`\/g,'<code>$1<\/code>')\r\n    .replace(\/^>\\s+(.+)\/gm,'<blockquote>$1<\/blockquote>')\r\n    .replace(\/^\\s*[-*]\\s+(.+)\/gm,'<li>$1<\/li>')\r\n    .replace(\/^\\s*\\d+\\.\\s+(.+)\/gm,'<li>$1<\/li>')\r\n    .replace(\/\\[(.+?)\\]\\((.+?)\\)\/g,'<a href=\"$2\" target=\"_blank\">$1<\/a>')\r\n    .replace(\/!\\[(.+?)\\]\\((.+?)\\)\/g,'<img decoding=\"async\" src=\"$2\" alt=\"$1\" style=\"max-width:100%\">')\r\n    .replace(\/^---+$\/gm,'<hr>')\r\n    .replace(\/\\n\\n\/g,'<\/p><p>');\r\n}\r\n\r\nfunction doFTS(){\r\n  const q=($('fts-input').value||'').toLowerCase().trim();\r\n  if(!q){ $('fts-results').innerHTML=''; $('fts-stats').textContent=''; return; }\r\n  const results=[];\r\n  for(const f of S.files){\r\n    const content=S.fileContent[f.id]||'';\r\n    const nameMatch=f.name.toLowerCase().includes(q);\r\n    const contentMatch=content.includes(q);\r\n    if(nameMatch||contentMatch){\r\n      let ctx='';\r\n      if(contentMatch){\r\n        const idx=content.indexOf(q);\r\n        const start=Math.max(0,idx-60), end=Math.min(content.length,idx+q.length+80);\r\n        const snippet=content.slice(start,end).replace(\/<\/g,'&lt;');\r\n        const hl=snippet.replace(new RegExp(q.replace(\/[.*+?^${}()|[\\]\\\\]\/g,'\\\\$&'),'gi'),m=>'<mark>'+m+'<\/mark>');\r\n        ctx=(start>0?'\u2026':'')+hl+(end<content.length?'\u2026':'');\r\n      }\r\n      results.push({f,ctx,nameMatch,contentMatch});\r\n    }\r\n  }\r\n  $('fts-stats').textContent=results.length+' result'+(results.length!==1?'s':'')+' for \"'+q+'\"';\r\n  if(!results.length){ $('fts-results').innerHTML='<div style=\"color:var(--t3);font-size:13px;padding:12px 0\">No matches found.<\/div>'; return; }\r\n  $('fts-results').innerHTML=results.map(r=>'<div class=\"fts-hit\" data-id=\"'+r.f.id+'\"><div class=\"fts-hit-name\">'+typeIcon(r.f.type,r.f.ext)+' '+r.f.name.replace(new RegExp(q.replace(\/[.*+?^${}()|[\\]\\\\]\/g,'\\\\$&'),'gi'),m=>'<mark>'+m+'<\/mark>')+' <span style=\"font-size:10px;color:var(--t3);font-weight:400;margin-left:8px\">'+fmtBytes(r.f.size)+'<\/span><\/div>'+(r.ctx?'<div class=\"fts-hit-ctx\">'+r.ctx+'<\/div>':'')+'<\/div>').join('');\r\n  $('fts-results').querySelectorAll('.fts-hit').forEach(el=>el.addEventListener('click',function(){\r\n    openPreview(this.dataset.id);\r\n  }));\r\n}\r\n\r\nconst AUTO_TAG_RULES=[\r\n  {pattern:\/invoice|bill|payment|amount due|total due\/,tag:'Invoice',color:'#dc2626'},\r\n  {pattern:\/report|analysis|summary|findings|conclusion\/,tag:'Report',color:'#2563eb'},\r\n  {pattern:\/contract|agreement|terms|parties|signed\/,tag:'Contract',color:'#7c3aed'},\r\n  {pattern:\/resume|curriculum vitae|cv|experience|skills|education\/,tag:'Resume\/CV',color:'#059669'},\r\n  {pattern:\/meeting|minutes|agenda|attendees|action items\/,tag:'Meeting',color:'#d97706'},\r\n  {pattern:\/budget|expense|revenue|profit|loss|forecast\/,tag:'Finance',color:'#065f46'},\r\n  {pattern:\/project|milestone|deliverable|timeline|sprint\/,tag:'Project',color:'#0891b2'},\r\n  {pattern:\/policy|procedure|guideline|compliance|regulation\/,tag:'Policy',color:'#374151'},\r\n];\r\n\r\nfunction autoTag(){\r\n  let tagged=0;\r\n  for(const f of S.files){\r\n    const content=S.fileContent[f.id]||''; const combined=(f.name+' '+content).toLowerCase();\r\n    for(const rule of AUTO_TAG_RULES){\r\n      if(rule.pattern.test(combined)){\r\n        S.tags[rule.tag]=S.tags[rule.tag]||rule.color;\r\n        if(!f.tags.includes(rule.tag)){ f.tags.push(rule.tag); tagged++; }\r\n      }\r\n    }\r\n  }\r\n  renderTagsCloud(); renderSidebar(); renderGallery();\r\n  toast('\ud83c\udff7\ufe0f Auto-tagged '+tagged+' file\/tag pairs');\r\n}\r\n\r\nfunction renderTagsCloud(){\r\n  const allTags=Object.keys(S.tags);\r\n  $('tags-cloud').innerHTML=allTags.map(t=>'<span class=\"tag-chip\" style=\"background:'+S.tags[t]+'20;color:'+S.tags[t]+';border:1px solid '+S.tags[t]+'40;cursor:pointer\" data-tag=\"'+t+'\">'+t+' <span style=\"opacity:.6;font-size:9px\">\u2715<\/span><\/span>').join('');\r\n  $('tags-cloud').querySelectorAll('.tag-chip').forEach(chip=>chip.addEventListener('click',function(){\r\n    const tag=this.dataset.tag;\r\n    delete S.tags[tag]; S.files.forEach(f=>{ f.tags=f.tags.filter(t=>t!==tag); });\r\n    renderTagsCloud(); renderGallery();\r\n    toast('\ud83d\uddd1\ufe0f Removed tag: '+tag);\r\n  }));\r\n}\r\n\r\nfunction autoOrganize(mode){\r\n  for(const f of S.files){\r\n    let folder;\r\n    if(mode==='type'){ const m={word:'Word Documents',excel:'Spreadsheets',ppt:'Presentations',pdf:'PDFs',data:'Data Files',text:'Text Files'}; folder=m[f.type]||'Other'; }\r\n    else if(mode==='ext') folder=f.ext.toUpperCase()+' Files';\r\n    else if(mode==='size'){ if(f.size<100*1024) folder='< 100 KB'; else if(f.size<1024*1024) folder='100 KB \u2013 1 MB'; else if(f.size<5*1024*1024) folder='1 \u2013 5 MB'; else folder='> 5 MB'; }\r\n    else if(mode==='alpha') folder=f.name[0].toUpperCase()+' \u2013 Files';\r\n    else if(mode==='date'){\r\n      const d=f.modifiedDate||f.detectedDate;\r\n      if(d){ const mo=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; folder=mo[d.getMonth()]+' '+d.getFullYear(); }\r\n      else folder='Unknown Date';\r\n    }\r\n    if(folder){ f.folder=folder; if(!['Unsorted'].includes(folder)&&!S.customFolders.includes(folder)) S.customFolders.push(folder); }\r\n  }\r\n  updateStats(); renderSidebar(); renderGallery();\r\n  toast('\u26a1 Organized '+S.files.length+' files');\r\n}\r\n\r\nasync function mergeFiles(){\r\n  const type=$('merge-type').value, sep=($('merge-sep').value)||'--- {filename} ---';\r\n  const targets=S.files.filter(f=>S.selectedIds.has(f.id));\r\n  if(targets.length<2) return showAlert('Need 2+ files','Select at least 2 files to merge.','\ud83d\uded1');\r\n\r\n  if(type==='txt'){\r\n    const parts=[];\r\n    for(const f of targets){\r\n      if(!['txt','md','log','html','xml','json'].includes(f.ext)&&f.type!=='text'&&f.type!=='data') continue;\r\n      const text=await new Promise(r=>{ const rd=new FileReader(); rd.onload=e=>r(e.target.result); rd.readAsText(f.blob); });\r\n      parts.push(sep.replace('{filename}',f.name)); parts.push(text);\r\n    }\r\n    const blob=new Blob([parts.join('\\n\\n')],{type:'text\/plain'});\r\n    download(blob,'merged_text.txt'); toast('\ud83d\udd17 Text files merged');\r\n  } else if(type==='csv'){\r\n    let headers=null; const rows=[];\r\n    for(const f of targets){\r\n      if(f.ext!=='csv') continue;\r\n      const text=await new Promise(r=>{ const rd=new FileReader(); rd.onload=e=>r(e.target.result); rd.readAsText(f.blob); });\r\n      const lines=text.split('\\n').filter(l=>l.trim());\r\n      if(!headers){ headers=lines[0]; rows.push(...lines.slice(1)); }\r\n      else rows.push(...lines.slice(1));\r\n    }\r\n    const blob=new Blob([[headers,...rows].join('\\n')],{type:'text\/csv'});\r\n    download(blob,'merged.csv'); toast('\ud83d\udd17 CSVs merged');\r\n  } else if(type==='json'){\r\n    const arrays=[];\r\n    for(const f of targets){\r\n      if(f.ext!=='json') continue;\r\n      const text=await new Promise(r=>{ const rd=new FileReader(); rd.onload=e=>r(e.target.result); rd.readAsText(f.blob); });\r\n      try{ const parsed=JSON.parse(text); arrays.push(...(Array.isArray(parsed)?parsed:[parsed])); }catch(e){}\r\n    }\r\n    const blob=new Blob([JSON.stringify(arrays,null,2)],{type:'application\/json'});\r\n    download(blob,'merged.json'); toast('\ud83d\udd17 JSON files merged');\r\n  }\r\n}\r\n\r\nfunction download(blob,name){ const a=document.createElement('a'); a.href=URL.createObjectURL(blob); a.download=name; document.body.appendChild(a); a.click(); document.body.removeChild(a); }\r\n\r\nfunction batchRename(){\r\n  const pattern=$('rn-pattern').value.trim();\r\n  if(!pattern) return showAlert('Missing Pattern','Enter a rename pattern.','\ud83d\uded1');\r\n  const pad=parseInt($('rn-pad').value)||3, start=parseInt($('rn-start').value)||1;\r\n  const targets=S.files.filter(f=>S.selectedIds.has(f.id));\r\n  if(!targets.length) return showAlert('No Selection','Select files to rename.','\ud83d\uded1');\r\n  let n=start;\r\n  for(const f of targets){\r\n    const base=f.name.lastIndexOf('.')>0?f.name.slice(0,f.name.lastIndexOf('.')):f.name;\r\n    const d=f.modifiedDate||f.detectedDate;\r\n    const dStr=d?d.toISOString().slice(0,10):'undated';\r\n    f.name=pattern.replace('{n}',String(n).padStart(pad,'0')).replace('{ext}',f.ext).replace('{name}',base).replace('{folder}',f.folder.replace(\/[^a-z0-9]\/gi,'_')).replace('{date}',dStr);\r\n    n++;\r\n  }\r\n  S.selectedIds.clear(); renderGallery();\r\n  toast('\u270f\ufe0f Renamed '+(n-start)+' files');\r\n}\r\n\r\nfunction previewRename(){\r\n  const pattern=$('rn-pattern').value.trim(); if(!pattern) return;\r\n  const pad=parseInt($('rn-pad').value)||3, start=parseInt($('rn-start').value)||1;\r\n  const targets=S.files.filter(f=>S.selectedIds.has(f.id)).slice(0,5);\r\n  if(!targets.length){ $('rn-preview').style.display='none'; return; }\r\n  const rows=targets.map((f,i)=>{\r\n    const base=f.name.lastIndexOf('.')>0?f.name.slice(0,f.name.lastIndexOf('.')):f.name;\r\n    const d=f.modifiedDate||f.detectedDate; const dStr=d?d.toISOString().slice(0,10):'undated';\r\n    const n=pattern.replace('{n}',String(start+i).padStart(pad,'0')).replace('{ext}',f.ext).replace('{name}',base).replace('{folder}',f.folder.replace(\/[^a-z0-9]\/gi,'_')).replace('{date}',dStr);\r\n    return '<div style=\"font-size:11px;padding:4px 0;border-bottom:1px solid var(--border)\"><span style=\"color:var(--t3)\">'+f.name+'<\/span> \u2192 <strong style=\"color:var(--blue)\">'+n+'<\/strong><\/div>';\r\n  });\r\n  $('rn-preview').style.display='block';\r\n  $('rn-preview').innerHTML='<div style=\"font-size:10px;font-weight:700;color:var(--t3);margin-bottom:5px\">PREVIEW (first 5):<\/div>'+rows.join('');\r\n}\r\n\r\nfunction findReplace(scope){\r\n  const find=$('fr-find').value, rep=$('fr-replace').value, cs=$('fr-case').checked;\r\n  if(!find) return showAlert('Missing','Enter text to find.','\ud83d\uded1');\r\n  const targets=scope==='selected'?S.files.filter(f=>S.selectedIds.has(f.id)):S.files;\r\n  let c=0;\r\n  for(const f of targets){\r\n    const orig=f.name;\r\n    f.name=cs?f.name.split(find).join(rep):f.name.replace(new RegExp(find.replace(\/[.*+?^${}()|[\\]\\\\]\/g,'\\\\$&'),'gi'),rep);\r\n    if(f.name!==orig) c++;\r\n  }\r\n  renderGallery(); toast('\ud83d\udd01 Replaced in '+c+' filenames');\r\n}\r\n\r\nfunction scanDuplicates(){\r\n  updateStats();\r\n  const groups={};\r\n  for(const f of S.files){ if(!groups[f.hashKey]) groups[f.hashKey]=[]; groups[f.hashKey].push(f); }\r\n  const dupes=Object.values(groups).filter(g=>g.length>1);\r\n  $('dup-info').textContent=dupes.length?'Found '+S.dupIds.size+' duplicates across '+dupes.length+' groups.':'\u2705 No duplicates found!';\r\n  $('dup-list').innerHTML=dupes.map(g=>'<div style=\"background:var(--rl);border-radius:5px;padding:7px 10px;margin-bottom:5px\"><div style=\"font-size:10px;font-weight:700;color:var(--red);margin-bottom:3px\">Duplicate ('+g.length+'\u00d7):<\/div>'+g.map(f=>'<div style=\"font-size:11px;color:var(--t2)\">'+typeIcon(f.type,f.ext)+' '+f.name+' \u2014 '+fmtBytes(f.size)+'<\/div>').join('')+'<\/div>').join('');\r\n  toast('\ud83d\udd0d '+S.dupIds.size+' duplicates found');\r\n}\r\n\r\nasync function exportZip(scope,structure,zipName){\r\n  let files;\r\n  if(scope==='selected') files=S.files.filter(f=>S.selectedIds.has(f.id));\r\n  else if(scope==='current') files=getDisplayFiles();\r\n  else files=S.files;\r\n  if(!files.length) return showAlert('Empty','No files to export.','\ud83d\uded1');\r\n  if(typeof JSZip==='undefined') return showAlert('Error','JSZip not loaded.','\u26a0\ufe0f');\r\n  showProg('Creating ZIP\u2026',files.length+' files',10);\r\n  const zip=new JSZip();\r\n  for(const f of files){\r\n    let path='';\r\n    if(structure==='organized') path=f.folder!=='Unsorted'?f.folder+'\/':'';\r\n    else if(structure==='type') path=({word:'Word',excel:'Excel',ppt:'PowerPoint',pdf:'PDF',data:'Data',text:'Text'}[f.type]||'Other')+'\/';\r\n    else if(structure==='ext') path=f.ext.toUpperCase()+'\/';\r\n    zip.file(path+f.name,f.blob);\r\n  }\r\n  const content=await zip.generateAsync({type:'blob',compression:'STORE'},m=>{ $('prog-fill').style.width=(10+m.percent*.9)+'%'; });\r\n  hideProg();\r\n  const a=document.createElement('a'); a.href=URL.createObjectURL(content);\r\n  a.download=(zipName||'Documents').replace(\/[^a-z0-9_\\-]\/gi,'_')+'.zip';\r\n  document.body.appendChild(a); a.click(); document.body.removeChild(a);\r\n  toast('\ud83d\udce6 Exported '+files.length+' files');\r\n}\r\n\r\nfunction batchDownload(){\r\n  const targets=S.files.filter(f=>S.selectedIds.has(f.id));\r\n  if(!targets.length) return showAlert('No Selection','Select files to download.','\ud83d\uded1');\r\n  if(targets.length>10) return showAlert('Too Many','Batch download is limited to 10 files. Use ZIP export for more.','\u26a0\ufe0f');\r\n  targets.forEach((f,i)=>setTimeout(()=>{ const a=document.createElement('a'); a.href=f.url; a.download=f.name; document.body.appendChild(a); a.click(); document.body.removeChild(a); },i*200));\r\n  toast('\u2b07 Downloading '+targets.length+' files\u2026');\r\n}\r\n\r\nfunction generateManifest(){\r\n  const lines=['# Document Manifest','# Generated: '+new Date().toLocaleString(),'# Total: '+S.files.length+' files',''];\r\n  const byFolder={};\r\n  for(const f of S.files){ if(!byFolder[f.folder]) byFolder[f.folder]=[]; byFolder[f.folder].push(f); }\r\n  for(const folder in byFolder){\r\n    const files = byFolder[folder];\r\n    lines.push('## '+folder+' ('+files.length+' files)');\r\n    for(const f of files) lines.push('  - '+f.name+' ['+fmtBytes(f.size)+'] ['+f.ext.toUpperCase()+']'+(f.tags.length?' ['+f.tags.join(', ')+']':'')+(f.starred?' \u2b50':''));\r\n    lines.push('');\r\n  }\r\n  const text=lines.join('\\n');\r\n  const out=$('manifest-out'); out.style.display='block';\r\n  out.innerHTML='<div style=\"font-size:10px;font-weight:700;color:var(--t3);margin-bottom:5px\">MANIFEST ('+S.files.length+' files)<\/div><pre style=\"font-size:10px;white-space:pre-wrap;max-height:150px;overflow-y:auto;color:var(--t2)\">'+text.slice(0,2500)+(text.length>2500?'\\n\u2026':'')+'<\/pre><button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"btn-dl-manifest\" style=\"margin-top:7px\">\u2b07 Download .txt<\/button>';\r\n  on('btn-dl-manifest','click',()=>{ const blob=new Blob([text],{type:'text\/plain'}); const a=document.createElement('a'); a.href=URL.createObjectURL(blob); a.download='Manifest.txt'; document.body.appendChild(a); a.click(); document.body.removeChild(a); });\r\n}\r\n\r\nfunction loadComparePane(fileId){\r\n  const f=S.files.find(x=>x.id===fileId); if(!f) return;\r\n  const slot=S.compareNext;\r\n  const body=$('cmp-body-'+slot.toLowerCase()); const lbl=$('cmp-lbl-'+slot.toLowerCase());\r\n  if(!body) return;\r\n  lbl.innerHTML=typeIcon(f.type,f.ext)+' '+f.name+' <span style=\"color:var(--t3);font-size:11px\">\u00b7 '+fmtBytes(f.size)+'<\/span>';\r\n  body.innerHTML='<div class=\"loading-state\"><div class=\"spinner\"><\/div><div>Rendering\u2026<\/div><\/div>';\r\n  setTimeout(()=>renderDocPreview(f,body,false),80);\r\n  S.compareNext=slot==='A'?'B':'A';\r\n  toast('\u29c9 Loaded in Pane '+slot);\r\n}\r\n\r\nfunction bindAll(){\r\n  const dz=$('dropzone');\r\n  dz.addEventListener('dragover',e=>{e.preventDefault();dz.classList.add('dragover');});\r\n  dz.addEventListener('dragleave',()=>dz.classList.remove('dragover'));\r\n  dz.addEventListener('drop',async e=>{\r\n    e.preventDefault(); dz.classList.remove('dragover');\r\n    if(e.dataTransfer.items){ showProg('Reading\u2026','Please wait',10); for(const item of Array.from(e.dataTransfer.items)){ const entry=item.webkitGetAsEntry(); if(entry) await traverseEntry(entry); } hideProg(); finalizeLoad(); }\r\n    else processFiles(e.dataTransfer.files);\r\n  });\r\n  on('trig-files','click',()=>$('inp-files').click());\r\n  on('trig-folder','click',()=>$('inp-folder').click());\r\n  on('trig-zip','click',()=>$('inp-zip').click());\r\n  on('inp-files','change',e=>{processFiles(e.target.files);e.target.value='';});\r\n  on('inp-folder','change',e=>{processFiles(e.target.files);e.target.value='';});\r\n  on('inp-zip','change',e=>{if(e.target.files[0])processFiles([e.target.files[0]]);e.target.value='';});\r\n  on('inp-add','change',e=>{processFiles(e.target.files);e.target.value='';});\r\n  on('btn-add-more','click',()=>$('inp-add').click());\r\n\r\n  on('btn-restart','click',()=>{\r\n    if(!S.files.length||confirm('Reset workspace? All data will be lost.')){\r\n      Object.assign(S,{files:[],customFolders:[],tags:{},dupIds:new Set(),selectedIds:new Set(),starredIds:new Set(),notes:{},recentIds:[],fileContent:{},currentFolder:'All',filterType:'all',sortMode:'name-asc',searchQ:'',viewMode:'grid',fileIdCounter:0,prevIds:[],prevIdx:-1,activePrevFile:null,compareModeOn:false,compareA:null,compareB:null,compareNext:'A',pptSlideState:{}});\r\n      $('workspace').style.display='none'; $('dropzone').style.display='block'; toast('\ud83d\udd04 Workspace reset');\r\n    }\r\n  });\r\n  on('btn-expand','click',function(){\r\n    const l=$('main-layout'); l.classList.toggle('expanded');\r\n    this.textContent=l.classList.contains('expanded')?'\u25e8 Split View':'\u26f6 Full Width';\r\n  });\r\n  on('btn-compare-mode','click',function(){\r\n    S.compareModeOn=!S.compareModeOn;\r\n    this.textContent=S.compareModeOn?'\u2715 Exit Compare':'\u29c9 Compare';\r\n    const cp=$('compare-panels'); cp.style.display=S.compareModeOn?'grid':'none';\r\n    if(S.compareModeOn){ cp.style.gridTemplateColumns='1fr 1fr'; toast('\u29c9 Compare mode \u2014 click two documents to compare them side by side'); }\r\n  });\r\n  on('btn-tools-toggle','click',function(){\r\n    const p=$('tools-panel'); p.classList.toggle('open');\r\n    this.textContent=p.classList.contains('open')?'\ud83d\udee0\ufe0f Hide Tools':'\ud83d\udee0\ufe0f Batch Tools';\r\n  });\r\n  on('btn-fts-toggle','click',function(){\r\n    const b=$('fts-bar'); b.classList.toggle('open');\r\n    this.textContent=b.classList.contains('open')?'\u2715 Close Search':'\ud83d\udd0d Full-Text Search';\r\n    if(b.classList.contains('open')) $('fts-input').focus();\r\n  });\r\n\r\n  on('ao-type','click',()=>autoOrganize('type'));\r\n  on('ao-ext','click',()=>autoOrganize('ext'));\r\n  on('ao-size','click',()=>autoOrganize('size'));\r\n  on('ao-alpha','click',()=>autoOrganize('alpha'));\r\n  on('ao-date','click',()=>autoOrganize('date'));\r\n  on('btn-autotag','click',autoTag);\r\n  on('df-start','change',renderGallery);\r\n  on('df-end','change',renderGallery);\r\n  on('df-source','change',renderGallery);\r\n  on('btn-df-clear','click',()=>{ $('df-start').value=''; $('df-end').value=''; renderGallery(); toast('\ud83d\udcc5 Date filter cleared'); });\r\n\r\n  on('btn-new-folder','click',()=>showOv('modal-folder'));\r\n  on('btn-nf2','click',()=>showOv('modal-folder'));\r\n  on('close-fm','click',()=>hideOv('modal-folder'));\r\n  on('confirm-fm','click',()=>{\r\n    const n=$('folder-inp').value.trim(); if(!n) return;\r\n    if(!S.customFolders.includes(n)) S.customFolders.push(n);\r\n    $('folder-inp').value=''; hideOv('modal-folder');\r\n    updateStats(); renderSidebar(); renderGallery(); toast('\ud83d\udcc1 '+n);\r\n  });\r\n  on('folder-inp','keydown',e=>{ if(e.key==='Enter') $('confirm-fm').click(); });\r\n\r\n  on('btn-sel-all','click',()=>{\r\n    if(S.selectedIds.size>0) S.selectedIds.clear();\r\n    else getDisplayFiles().forEach(f=>S.selectedIds.add(f.id));\r\n    renderGallery();\r\n  });\r\n  on('btn-move','click',()=>{\r\n    const sel=$('move-dest');\r\n    sel.innerHTML=[...S.customFolders,'Unsorted','Word Documents','Spreadsheets','Presentations','PDFs','Data Files','Text Files'].map(f=>'<option value=\"'+f+'\">'+f+'<\/option>').join('');\r\n    showOv('modal-move');\r\n  });\r\n  on('close-mm','click',()=>hideOv('modal-move'));\r\n  on('confirm-mm','click',()=>{\r\n    const dest=$('move-dest').value;\r\n    S.files.forEach(f=>{ if(S.selectedIds.has(f.id)) f.folder=dest; });\r\n    S.selectedIds.clear(); hideOv('modal-move');\r\n    updateStats(); renderSidebar(); renderGallery(); toast('\ud83d\udcc2 Moved to '+dest);\r\n  });\r\n  on('btn-delete','click',()=>{\r\n    const c=S.selectedIds.size;\r\n    S.files=S.files.filter(f=>!S.selectedIds.has(f.id));\r\n    S.selectedIds.clear(); updateStats(); renderSidebar(); renderGallery();\r\n    toast('\ud83d\uddd1\ufe0f Deleted '+c+' files');\r\n    if(!S.files.length){ $('workspace').style.display='none'; $('dropzone').style.display='block'; }\r\n  });\r\n  on('btn-exp-sel','click',()=>exportZip('selected','organized','Selected'));\r\n\r\n  qsa('.ftag').forEach(btn=>btn.addEventListener('click',function(){\r\n    qsa('.ftag').forEach(b=>b.classList.remove('active'));\r\n    this.classList.add('active'); S.filterType=this.dataset.f; renderGallery();\r\n  }));\r\n  on('sbox','input',e=>{ S.searchQ=e.target.value.toLowerCase(); renderGallery(); });\r\n  on('sort-sel','change',e=>{ S.sortMode=e.target.value; renderGallery(); });\r\n  qsa('.vbtn').forEach(btn=>btn.addEventListener('click',function(){\r\n    qsa('.vbtn').forEach(b=>b.classList.remove('active'));\r\n    this.classList.add('active'); S.viewMode=this.dataset.v; renderGallery();\r\n  }));\r\n\r\n  on('alrt-ok','click',()=>hideOv('modal-alert'));\r\n\r\n  on('btn-close-prev','click',()=>{ hideOv('modal-prev'); $('prev-body').innerHTML=''; });\r\n  on('pp-prev','click',()=>{ S.prevIdx=(S.prevIdx-1+S.prevIds.length)%S.prevIds.length; renderPreview(S.prevIds[S.prevIdx]); });\r\n  on('pp-next','click',()=>{ S.prevIdx=(S.prevIdx+1)%S.prevIds.length; renderPreview(S.prevIds[S.prevIdx]); });\r\n  on('btn-prev-star','click',()=>{ if(S.activePrevFile){ toggleStar(S.activePrevFile.id); $('btn-prev-star').textContent=S.activePrevFile.starred?'\u2b50 Starred':'\u2606 Star'; } });\r\n  \r\n  on('btn-prev-fullscreen','click',()=>{\r\n    if(S.activePrevFile?.type==='ppt'){\r\n      const state=S.pptSlideState[S.activePrevFile.id];\r\n      if(state){ renderFsSlide(state); $('fs-slide').classList.add('open'); }\r\n    } else {\r\n      const pane=$('ppane-main');\r\n      if(pane&&pane.firstChild&&pane.firstChild.requestFullscreen) pane.firstChild.requestFullscreen();\r\n    }\r\n  });\r\n  \r\n  on('btn-prev-print','click',()=>{\r\n    const pane=$('ppane-main');\r\n    if(!pane) return;\r\n    const html=pane.innerHTML;\r\n    const pw=window.open('','_blank');\r\n    pw.document.write('<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><style> @import url(\"https:\/\/fonts.googleapis.com\/css2?family=Crimson+Pro:ital,wght@0,400;0,600;1,400&family=Inter:wght@400;600;700&display=swap\"); body{font-family:\"Crimson Pro\",Georgia,serif;font-size:15px;line-height:1.8;color:#111;max-width:800px;margin:0 auto;padding:40px} h1,h2,h3,h4{font-family:\"Inter\",sans-serif} table{width:100%;border-collapse:collapse} td,th{border:1px solid #ccc;padding:6px 10px} pre,code{font-family:monospace;font-size:12px;background:#f3f4f6;padding:2px 4px;border-radius:3px} @media print{body{padding:20px}} <\/style><\/head><body>'+html+'<\/body><\/html>');\r\n    pw.document.close(); setTimeout(()=>pw.print(),600);\r\n  });\r\n  \r\n  document.addEventListener('keydown',e=>{\r\n    if($('modal-prev').classList.contains('open')){\r\n      if(e.key==='ArrowLeft') $('pp-prev').click();\r\n      if(e.key==='ArrowRight') $('pp-next').click();\r\n      if(e.key==='Escape') $('btn-close-prev').click();\r\n    }\r\n    if($('fs-slide').classList.contains('open')){\r\n      if(e.key==='ArrowLeft') $('fs-prev').click();\r\n      if(e.key==='ArrowRight') $('fs-next').click();\r\n      if(e.key==='Escape') $('fs-close').click();\r\n    }\r\n  });\r\n\r\n  on('btn-fts-go','click',doFTS);\r\n  on('fts-input','keydown',e=>{ if(e.key==='Enter') doFTS(); });\r\n  on('btn-fts-clear','click',()=>{ $('fts-input').value=''; $('fts-results').innerHTML=''; $('fts-stats').textContent=''; });\r\n\r\n  on('btn-do-rename','click',batchRename);\r\n  on('btn-prev-rename','click',previewRename);\r\n  on('btn-fr-sel','click',()=>findReplace('selected'));\r\n  on('btn-fr-all','click',()=>findReplace('all'));\r\n  on('btn-do-merge','click',mergeFiles);\r\n  on('btn-do-export','click',()=>exportZip($('exp-scope').value,$('exp-struct').value,$('exp-name').value));\r\n  on('btn-batch-dl','click',batchDownload);\r\n  on('btn-manifest','click',generateManifest);\r\n  on('btn-scan-dups','click',scanDuplicates);\r\n  on('btn-sel-dups','click',()=>{ S.dupIds.forEach(id=>S.selectedIds.add(id)); renderGallery(); toast('\u2611\ufe0f Selected '+S.dupIds.size+' duplicates'); });\r\n  on('btn-del-dups','click',()=>{ const c=S.dupIds.size; S.files=S.files.filter(f=>!S.dupIds.has(f.id)); updateStats(); renderSidebar(); renderGallery(); toast('\ud83d\uddd1\ufe0f Removed '+c+' duplicates'); });\r\n  on('btn-add-tag','click',()=>{\r\n    const name=$('tag-name').value.trim(), color=$('tag-color').value;\r\n    if(!name) return;\r\n    S.tags[name]=color;\r\n    S.files.filter(f=>S.selectedIds.has(f.id)).forEach(f=>{ if(!f.tags.includes(name)) f.tags.push(name); });\r\n    renderTagsCloud(); renderGallery(); toast('\ud83c\udff7\ufe0f Tagged '+S.selectedIds.size+' files');\r\n  });\r\n  on('btn-clear-tags','click',()=>{\r\n    Object.keys(S.tags).forEach(t=>delete S.tags[t]);\r\n    S.files.forEach(f=>f.tags=[]);\r\n    renderTagsCloud(); renderGallery(); toast('\ud83d\uddd1\ufe0f All tags cleared');\r\n  });\r\n\r\n  on('cmp-clear-a','click',()=>{ $('cmp-body-a').innerHTML='<div class=\"loading-state\" style=\"height:100%\"><div style=\"font-size:30px\">\ud83d\udc48<\/div><div>Click a file card to load it here<\/div><\/div>'; $('cmp-lbl-a').innerHTML='Document A \u2014 <span style=\"color:var(--t3)\">click a file to load<\/span>'; S.compareNext='A'; });\r\n  on('cmp-clear-b','click',()=>{ $('cmp-body-b').innerHTML='<div class=\"loading-state\" style=\"height:100%\"><div style=\"font-size:30px\">\ud83d\udc49<\/div><div>Click a file card to load it here<\/div><\/div>'; $('cmp-lbl-b').innerHTML='Document B \u2014 <span style=\"color:var(--t3)\">click a file to load<\/span>'; });\r\n\r\n  on('fs-prev','click',()=>{\r\n    const state=S.activePrevFile?S.pptSlideState[S.activePrevFile.id]:null;\r\n    if(!state||!state.slides.length) return;\r\n    state.currentIdx=(state.currentIdx-1+state.slides.length)%state.slides.length;\r\n    renderFsSlide(state);\r\n  });\r\n  on('fs-next','click',()=>{\r\n    const state=S.activePrevFile?S.pptSlideState[S.activePrevFile.id]:null;\r\n    if(!state||!state.slides.length) return;\r\n    state.currentIdx=(state.currentIdx+1)%state.slides.length;\r\n    renderFsSlide(state);\r\n  });\r\n  on('fs-close','click',()=>$('fs-slide').classList.remove('open'));\r\n}\r\n\r\nwindow.pthAdvDocOrgApp = {\r\n  initialized: false,\r\n  init: function() {\r\n    if (this.initialized) return;\r\n    this.initialized = true;\r\n\r\n    \/\/ \ud83d\udd25 BUG FIX: Move all Modals and Toasts to document.body to prevent WP Theme CSS conflicts \ud83d\udd25\r\n    const modalsToMove = [\r\n      'modal-prev', \r\n      'modal-folder', \r\n      'modal-move', \r\n      'modal-alert', \r\n      'modal-prog', \r\n      'fs-slide', \r\n      'toast'\r\n    ];\r\n    \r\n    modalsToMove.forEach(function(id) {\r\n        const el = document.getElementById(id);\r\n        if (el) {\r\n            document.body.appendChild(el);\r\n        }\r\n    });\r\n    \/\/ -------------------------------------------------------------------------------------------\r\n\r\n    bindAll();\r\n  }\r\n};\r\n\r\nfunction runInit() { window.pthAdvDocOrgApp.init(); }\r\n\r\nvar bootAttempts = 0;\r\nvar bootLoader = setInterval(function() {\r\n    if (document.getElementById('pth-advdocorg-wrapper') && !window.pthAdvDocOrgApp.initialized) {\r\n        runInit();\r\n        clearInterval(bootLoader);\r\n    }\r\n    if(++bootAttempts > 50) clearInterval(bootLoader);\r\n}, 100);\r\n\r\nif (document.readyState === 'complete' || document.readyState === 'interactive') { \r\n    setTimeout(runInit, 1); \r\n} else { \r\n    document.addEventListener('DOMContentLoaded', runInit); \r\n    window.addEventListener('load', runInit); \r\n}\r\n\r\n})();\r\n<\/script>\n\n\n\n<style>\n.pth-feature-wrap { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 20px; margin-bottom: 30px; }\n.pth-feat-box { border: 1px solid #e2e8f0; background: #ffffff; padding: 24px; border-radius: 12px; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.02); transition: all 0.3s ease; }\n.pth-feat-box:hover { border-color: #bfdbfe; transform: translateY(-3px); box-shadow: 0 10px 15px -3px rgba(0,0,0,0.05); }\n.pth-feat-title { font-size: 1.1rem; font-weight: 800; color: #0f172a; margin-bottom: 10px; display: flex; align-items: center; gap: 10px; }\n.pth-feat-text { font-size: 0.9rem; color: #475569; line-height: 1.6; margin: 0; }\n.pth-steps-wrap { border: 1px solid #e2e8f0; background: #ffffff; padding: 40px 30px; border-radius: 16px; text-align: center; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.02); margin-bottom: 40px; }\n.pth-steps-title { font-size: 1.2rem; font-weight: 800; color: #1e293b; text-transform: uppercase; margin-bottom: 35px; letter-spacing: 1px; }\n.pth-steps-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 30px; }\n.pth-step-item { display: flex; flex-direction: column; align-items: center; }\n.pth-step-num { width: 45px; height: 45px; background: #3b82f6; color: #ffffff; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 1.2rem; margin-bottom: 15px; box-shadow: 0 4px 10px rgba(59,130,246,0.3); }\n.pth-step-name { font-weight: 800; color: #0f172a; margin-bottom: 8px; font-size: 1.05rem; }\n.pth-step-desc { font-size: 0.9rem; color: #64748b; line-height: 1.5; margin: 0; }\n<\/style>\n<div class=\"pth-feature-wrap\">\n    <div class=\"pth-feat-box\">\n        <div class=\"pth-feat-title\">\u2699\ufe0f Zero-Server Processing<\/div>\n        <p class=\"pth-feat-text\">This offline document organizer executes entirely within your browser environment. Your data never travels across a network, guaranteeing cryptographic-level privacy.<\/p>\n    <\/div>\n    <div class=\"pth-feat-box\">\n        <div class=\"pth-feat-title\">\ud83e\udde0 Advanced Binary Parsing<\/div>\n        <p class=\"pth-feat-text\">Using client-side JavaScript engines, the system translates complex DOCX and XLSX binary arrays into readable DOM elements dynamically.<\/p>\n    <\/div>\n    <div class=\"pth-feat-box\">\n        <div class=\"pth-feat-title\">\ud83d\udce6 Memory-Safe Extraction<\/div>\n        <p class=\"pth-feat-text\">Our offline document organizer handles large ZIP archives by streaming file Blobs into temporary browser memory, minimizing CPU throttling.<\/p>\n    <\/div>\n<\/div>\n<div class=\"pth-steps-wrap\">\n    <div class=\"pth-steps-title\">How to Use the Offline Document Organizer<\/div>\n    <div class=\"pth-steps-grid\">\n        <div class=\"pth-step-item\">\n            <div class=\"pth-step-num\">1<\/div>\n            <div class=\"pth-step-name\">Load Local Files<\/div>\n            <p class=\"pth-step-desc\">Drag and drop your directories, documents, or ZIP archives directly into the interface. The offline document organizer reads the file pointers without uploading.<\/p>\n        <\/div>\n        <div class=\"pth-step-item\">\n            <div class=\"pth-step-num\">2<\/div>\n            <div class=\"pth-step-name\">Trigger Algorithmic Sorting<\/div>\n            <p class=\"pth-step-desc\">Click the Smart Auto-Organizer buttons to distribute files into virtual directories based on MIME types, timestamps, or raw byte sizes.<\/p>\n        <\/div>\n        <div class=\"pth-step-item\">\n            <div class=\"pth-step-num\">3<\/div>\n            <div class=\"pth-step-name\">Render and Preview<\/div>\n            <p class=\"pth-step-desc\">Select any supported file to initiate the local preview engine. The script processes the raw strings and paints them onto the active viewport.<\/p>\n        <\/div>\n        <div class=\"pth-step-item\">\n            <div class=\"pth-step-num\">4<\/div>\n            <div class=\"pth-step-name\">Batch Export Data<\/div>\n            <p class=\"pth-step-desc\">Select your organized nodes and compile them into a new compressed archive securely on your machine before downloading.<\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n\n\n<div id=\"start-seo-article\"><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\ud83d\udfe5 <strong>Deep Technical Architecture of Our System<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Modern web engineering relies heavily on shifting computational workloads from backend servers directly to the client&#8217;s device. Our highly efficient offline document organizer achieves this by executing specialized JavaScript logic strictly within the local memory bounds of your browser. By bypassing external API dependencies, users experience a highly secure environment where sensitive business logic, mathematical tables, and proprietary texts remain isolated from the broader internet.<\/p>\n\n\n\n<h2 id=\"\ud83d\udfe7-client-side-dom-manipulation-and-cpu-processing\" class=\"wp-block-heading\">\ud83d\udfe7 Client-Side DOM Manipulation and CPU Processing<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Understanding how an offline document organizer reads complex proprietary formats requires examining binary array buffers. When you drag a file into the application, the system uses the native interface to read the byte stream, as detailed extensively in the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/File_API\" target=\"_blank\" rel=\"noreferrer noopener\">Mozilla MDN File API documentation<\/a>. Instead of transmitting this payload to a remote PHP or Node.js server, the offline document organizer intercepts the raw data.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For Microsoft Word (.docx) and Excel (.xlsx) files, the application uses sophisticated extraction libraries like Mammoth.js and SheetJS. These engines decompress the internal XML structures of the files, parse the relational node trees, and inject the formatted output directly into the Document Object Model (DOM). This process operates asynchronously to prevent blocking the main rendering thread of your CPU.<\/p>\n\n\n\n<h3 id=\"\ud83d\udfe8-mathematical-precision-and-data-security\" class=\"wp-block-heading\">\ud83d\udfe8 Mathematical Precision and Data Security<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Privacy is highly important when handling financial records or legal contracts. The mathematical advantage of a purely local offline document organizer is that network packet sniffing becomes mathematically impossible. The data extraction happens sequentially:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\ud83d\udfe2 The browser allocates a temporary Blob URL in the active session memory.<\/li>\n\n\n\n<li>\ud83d\udd35 The script reads the ArrayBuffer and converts it to a standard Uint8Array.<\/li>\n\n\n\n<li>\ud83d\udfe3 The parsing algorithm extracts text, skipping malicious executable macros.<\/li>\n\n\n\n<li>\ud83d\udfe4 Upon closing the tab, the garbage collector wipes all traces of the files instantly.<\/li>\n<\/ul>\n\n\n\n<h3 id=\"\ud83d\udfe9-expanding-your-local-development-utilities\" class=\"wp-block-heading\">\ud83d\udfe9 Expanding Your Local Development Utilities<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Constructing a complex offline document organizer requires specific optimizations to ensure compatibility across Chrome, Firefox, and Edge. If you are exploring how client-side data management can streamline your daily workflow, we highly recommend that you explore our <a href=\"https:\/\/schoolict.net\/tools\/free-web-tools-directory-prime-tool-hub\/\">free web tools directory<\/a> for additional high-performance utilities built under similar strict privacy principles.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Advanced Offline Document Viewer &#038; Organizer (Word, Excel, PDF) Securely view, extract, and manage files with our free offline document organizer. Read Word, Excel, and PDF files directly in your browser with zero uploads. \u2699\ufe0f Zero-Server Processing This offline document organizer executes entirely within your browser environment. Your data never travels across a network, guaranteeing &#8230; <a title=\"Advanced Offline Document Organizer (Word, Excel, PDF)\" class=\"read-more\" href=\"https:\/\/schoolict.net\/tools\/advanced-offline-document-organizer\/\" aria-label=\"Read more about Advanced Offline Document Organizer (Word, Excel, PDF)\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":4964,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-4953","page","type-page","status-publish","has-post-thumbnail"],"_links":{"self":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages\/4953","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/comments?post=4953"}],"version-history":[{"count":2,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages\/4953\/revisions"}],"predecessor-version":[{"id":6929,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages\/4953\/revisions\/6929"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/media\/4964"}],"wp:attachment":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/media?parent=4953"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}