{"id":2732,"date":"2026-04-19T11:30:55","date_gmt":"2026-04-19T11:30:55","guid":{"rendered":"https:\/\/primetoolhub.com\/?page_id=2732"},"modified":"2026-07-24T12:21:51","modified_gmt":"2026-07-24T12:21:51","slug":"free-ai-text-summarizer-tldr-generator","status":"publish","type":"page","link":"https:\/\/schoolict.net\/tools\/free-ai-text-summarizer-tldr-generator\/","title":{"rendered":"Free AI Text Summarizer &amp; TL;DR Generator (100% Offline)"},"content":{"rendered":"<div class=\"pth-hero-section\">\n<div class=\"pth-hero-content\">\n<h2>Free AI Text Summarizer &#038; TL;DR Generator (100% Offline)<\/h2>\n<p>Summarize long articles and documents instantly with our 100% offline free AI text summarizer. Generates accurate TL;DRs securely in your browser.<\/p>\n<div id=\"pth-toc-placeholder\"><\/div>\n<\/p>\n<\/div>\n<div class=\"pth-hero-image\">\n    <img data-no-lazy=\"1\"\n         src=\"https:\/\/schoolict.net\/tools\/wp-content\/uploads\/2026\/04\/AI-text-summarizer-800x447.jpeg\"\n         width=\"800\"\n         height=\"447\"\n         alt=\"AI text summarizer\"\n         fetchpriority=\"high\"\n         loading=\"eager\"\n         decoding=\"async\"\n         style=\"width:100%; height:auto; display:block;\">\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\udd34-why-most-summarizers-stop-too-early\">\ud83d\udd34 Why Most Summarizers Stop Too Early<\/a><ul><li><a href=\"#tab-1-\ud83d\udce5-input-everything-starts-here\">Tab 1 \u2014 \ud83d\udce5 Input: Everything Starts Here<\/a><\/li><li><a href=\"#focus-keywords-and-tone-modes\">Focus Keywords and Tone Modes<\/a><\/li><li><a href=\"#\ud83d\udfe1-tab-2-\ud83d\udccb-sections-structured-intelligence-extraction\">\ud83d\udfe1 Tab 2 \u2014 \ud83d\udccb Sections: Structured Intelligence Extraction<\/a><\/li><li><a href=\"#tab-3-\ud83c\udfaf-summary-result-gauge-and-compare\">Tab 3 \u2014 \ud83c\udfaf Summary: Result, Gauge, and Compare<\/a><\/li><li><a href=\"#\ud83d\udfe2-tab-4-\ud83d\udd0d-analyzer-four-deep-text-metrics\">\ud83d\udfe2 Tab 4 \u2014 \ud83d\udd0d Analyzer: Four Deep Text Metrics<\/a><\/li><li><a href=\"#tab-5-\u270d\ufe0f-rewriter-five-modes-with-diff-highlighting\">Tab 5 \u2014 \u270d\ufe0f Rewriter: Five Modes with Diff Highlighting<\/a><\/li><li><a href=\"#tab-6-\ud83d\udce4-export-hub-six-formats-four-copy-modes\">Tab 6 \u2014 \ud83d\udce4 Export Hub: Six Formats, Four Copy Modes<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n\n\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.11.174\/pdf.min.js\" data-no-optimize=\"1\" data-no-minify=\"1\" data-cfasync=\"false\"><\/script>\r\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\/html2pdf.js\/0.10.1\/html2pdf.bundle.min.js\" data-no-optimize=\"1\" data-no-minify=\"1\" data-cfasync=\"false\"><\/script>\r\n\r\n<style>\r\n\/* ============================================================\r\n   PTH AI TEXT SUMMARIZER & INTELLIGENCE HUB \u2014 v5.0 PRO\r\n   All-in-One: Summarize \u00b7 Analyze \u00b7 Rewrite \u00b7 Export\r\n   PTH v3.0 Compliant \u00b7 WCAG 2.1 AA \u00b7 100% Offline AI\r\n   ============================================================ *\/\r\n\r\n#pth-sum-wrapper {\r\n  font-family: 'Inter', system-ui, sans-serif;\r\n  max-width: 1500px; margin: 0 auto; box-sizing: border-box;\r\n  background: #f1f5f9; padding: 24px; border-radius: 20px;\r\n  color: #1e293b; position: relative;\r\n}\r\n#pth-sum-wrapper * { box-sizing: border-box; min-width: 0; }\r\n\r\n\/* Dark Mode *\/\r\n#pth-sum-wrapper.pth-dark { background: #0f172a; color: #e2e8f0; }\r\n#pth-sum-wrapper.pth-dark .pth-card { background: #1e293b; border-color: #334155; }\r\n#pth-sum-wrapper.pth-dark .pth-top-bar { background: #1e293b; border-color: #334155; }\r\n#pth-sum-wrapper.pth-dark .pth-tab-bar { background: #1e293b; border-color: #334155; }\r\n#pth-sum-wrapper.pth-dark .pth-tab-btn { color: #94a3b8; }\r\n#pth-sum-wrapper.pth-dark .pth-tab-btn.active { background: #0f172a; color: #e2e8f0; border-bottom-color: #0f172a; }\r\n#pth-sum-wrapper.pth-dark .pth-tab-wrap { background: #1e293b; border-color: #334155; }\r\n#pth-sum-wrapper.pth-dark .pth-textarea,\r\n#pth-sum-wrapper.pth-dark .pth-input { background: #1e293b; color: #e2e8f0; border-color: #475569; }\r\n#pth-sum-wrapper.pth-dark .pth-stat-item { background: #263548; border-color: #334155; }\r\n#pth-sum-wrapper.pth-dark .pth-section-chip { background: #263548; border-color: #334155; color: #94a3b8; }\r\n#pth-sum-wrapper.pth-dark .pth-length-btn,\r\n#pth-sum-wrapper.pth-dark .pth-format-btn,\r\n#pth-sum-wrapper.pth-dark .pth-tone-btn { background: #263548; border-color: #334155; color: #94a3b8; }\r\n#pth-sum-wrapper.pth-dark .pth-length-btn.active,\r\n#pth-sum-wrapper.pth-dark .pth-format-btn.active,\r\n#pth-sum-wrapper.pth-dark .pth-tone-btn.active { background: rgba(59,130,246,0.15); border-color: #3b82f6; color: #93c5fd; }\r\n#pth-sum-wrapper.pth-dark .pth-result-box { background: #0c2a1e; border-color: #34d399; }\r\n#pth-sum-wrapper.pth-dark .pth-result-text { color: #a7f3d0; }\r\n#pth-sum-wrapper.pth-dark .pth-history-item { background: #263548; border-color: #334155; }\r\n#pth-sum-wrapper.pth-dark .pth-export-card { background: #263548; border-color: #334155; }\r\n#pth-sum-wrapper.pth-dark .pth-export-card:hover { border-color: #3b82f6; }\r\n#pth-sum-wrapper.pth-dark .pth-rewrite-box { background: #1e293b; border-color: #475569; color: #e2e8f0; }\r\n#pth-sum-wrapper.pth-dark .pth-compare-col { background: #1e293b; border-color: #334155; }\r\n#pth-sum-wrapper.pth-dark .pth-heatmap-word.pth-ht-high { background: rgba(16,185,129,0.35); }\r\n#pth-sum-wrapper.pth-dark .pth-heatmap-word.pth-ht-med { background: rgba(245,158,11,0.25); }\r\n#pth-sum-wrapper.pth-dark .pth-kw-row:hover { background: #263548; }\r\n#pth-sum-wrapper.pth-dark .pth-analysis-chip { background: #263548; border-color: #334155; }\r\n#pth-sum-wrapper.pth-dark .pth-gauge-wrap { background: #263548; }\r\n#pth-sum-wrapper.pth-dark .pth-diff-changed { background: rgba(234,179,8,0.25); }\r\n\r\n\/* \u2500\u2500 Top Bar \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-top-bar {\r\n  background: #ffffff; border: 1px solid #e2e8f0; padding: 18px 24px;\r\n  border-radius: 14px; display: flex; justify-content: space-between;\r\n  align-items: center; margin-bottom: 22px;\r\n  box-shadow: 0 2px 8px rgba(0,0,0,0.06); flex-wrap: wrap; gap: 12px;\r\n}\r\n#pth-sum-wrapper .pth-tool-title {\r\n  font-size: 1.5rem; font-weight: 900; color: #0f172a; margin: 0;\r\n  display: flex; align-items: center; gap: 10px; letter-spacing: -0.5px;\r\n}\r\n#pth-sum-wrapper .pth-subtitle { font-size: 0.82rem; color: #334155; font-weight: 600; margin-top: 3px; display: block; }\r\n#pth-sum-wrapper .pth-version-badge { font-size: 0.68rem; background: linear-gradient(135deg,#3b82f6,#1d4ed8); color: #fff; padding: 3px 10px; border-radius: 999px; font-weight: 800; white-space: nowrap; }\r\n#pth-sum-wrapper .pth-status-offline { font-size: 0.68rem; background: #1e3a5f; color: #93c5fd; border: 1px solid #3b82f6; padding: 2px 8px; border-radius: 4px; font-weight: 700; white-space: nowrap; }\r\n#pth-sum-wrapper .pth-top-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }\r\n\r\n\/* \u2500\u2500 Layout \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-layout { display: grid; grid-template-columns: 1fr 320px; gap: 20px; align-items: start; }\r\n#pth-sum-wrapper .pth-layout.pth-full-width { grid-template-columns: 1fr; }\r\n#pth-sum-wrapper .pth-layout.pth-full-width .pth-sidebar-col { display: none; }\r\n@media(max-width:1100px){ #pth-sum-wrapper .pth-layout { grid-template-columns: 1fr; } }\r\n#pth-sum-wrapper .pth-sidebar-col { position: sticky; top: 20px; }\r\n\r\n\/* \u2500\u2500 Card \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-card {\r\n  background: #ffffff; border: 1px solid #e2e8f0; border-radius: 14px;\r\n  padding: 20px; margin-bottom: 18px; box-shadow: 0 2px 6px rgba(0,0,0,0.04);\r\n}\r\n#pth-sum-wrapper .pth-card-title {\r\n  font-size: 1rem; font-weight: 800; color: #0f172a; margin: 0 0 14px;\r\n  display: flex; align-items: center; gap: 8px; padding-bottom: 12px;\r\n  border-bottom: 2px solid #e2e8f0; flex-wrap: wrap;\r\n}\r\n\r\n\/* \u2500\u2500 Tab System \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-tab-bar {\r\n  display: flex; background: #ffffff; border: 1px solid #e2e8f0;\r\n  border-radius: 12px 12px 0 0; overflow-x: auto; border-bottom: none;\r\n  padding: 4px 4px 0; gap: 2px;\r\n}\r\n#pth-sum-wrapper .pth-tab-btn {\r\n  padding: 10px 15px; font-size: 0.8rem; font-weight: 800; color: #334155;\r\n  background: transparent; border: 1px solid transparent; border-bottom: none;\r\n  border-radius: 8px 8px 0 0; cursor: pointer; white-space: nowrap;\r\n  transition: 0.15s; font-family: 'Inter',sans-serif;\r\n}\r\n#pth-sum-wrapper .pth-tab-btn:hover { background: #f8fafc; color: #0f172a; }\r\n#pth-sum-wrapper .pth-tab-btn.active {\r\n  background: #ffffff; color: #1d4ed8; border-color: #e2e8f0;\r\n  border-bottom-color: #ffffff; font-weight: 900; position: relative; bottom: -1px;\r\n}\r\n#pth-sum-wrapper .pth-tab-wrap {\r\n  background: #ffffff; border: 1px solid #e2e8f0;\r\n  border-radius: 0 0 12px 12px; padding: 20px; min-height: 460px;\r\n}\r\n#pth-sum-wrapper .pth-tab-panel { display: none; }\r\n#pth-sum-wrapper .pth-tab-panel.active { display: block; }\r\n\r\n\/* \u2500\u2500 Buttons \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-btn {\r\n  padding: 10px 18px; border-radius: 8px; font-weight: 800; font-size: 0.88rem;\r\n  cursor: pointer; transition: all 0.2s; display: inline-flex; align-items: center;\r\n  justify-content: center; gap: 6px; border: none; font-family: 'Inter',sans-serif;\r\n  white-space: nowrap;\r\n}\r\n#pth-sum-wrapper .pth-btn-primary { background: #2563eb; color: #fff; box-shadow: 0 3px 10px rgba(37,99,235,0.3); }\r\n#pth-sum-wrapper .pth-btn-primary:hover:not(:disabled) { background: #1d4ed8; transform: translateY(-1px); }\r\n#pth-sum-wrapper .pth-btn-success { background: linear-gradient(135deg,#10b981,#047857); color: #fff; box-shadow: 0 4px 12px rgba(16,185,129,0.3); width: 100%; font-size: 1rem; padding: 15px; }\r\n#pth-sum-wrapper .pth-btn-success:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(16,185,129,0.4); }\r\n#pth-sum-wrapper .pth-btn-success:disabled { background: #94a3b8; cursor: not-allowed; transform: none; box-shadow: none; }\r\n#pth-sum-wrapper .pth-btn-warning { background: linear-gradient(135deg,#f59e0b,#d97706); color: #fff; box-shadow: 0 3px 10px rgba(245,158,11,0.3); }\r\n#pth-sum-wrapper .pth-btn-warning:hover { transform: translateY(-1px); }\r\n#pth-sum-wrapper .pth-btn-secondary { background: #f1f5f9; color: #1e293b; border: 1.5px solid #e2e8f0; }\r\n#pth-sum-wrapper .pth-btn-secondary:hover { background: #e2e8f0; }\r\n#pth-sum-wrapper .pth-btn-danger { background: #dc2626; color: #fff; }\r\n#pth-sum-wrapper .pth-btn-sm { padding: 7px 13px; font-size: 0.8rem; border-radius: 7px; }\r\n#pth-sum-wrapper .pth-btn:disabled { opacity: 0.45; cursor: not-allowed; transform: none !important; }\r\n#pth-sum-wrapper .pth-sample-btn { background: #ecfdf5; color: #047857; border: 1px solid #6ee7b7; font-size: 0.78rem; padding: 5px 12px; border-radius: 6px; font-weight: 700; cursor: pointer; transition: 0.2s; display: inline-flex; align-items: center; gap: 5px; }\r\n#pth-sum-wrapper .pth-sample-btn:hover { background: #d1fae5; }\r\n\r\n\/* \u2500\u2500 Form \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-label { font-size: 0.75rem; font-weight: 800; color: #334155; margin-bottom: 6px; display: block; text-transform: uppercase; letter-spacing: 0.5px; }\r\n#pth-sum-wrapper .pth-textarea { width: 100%; padding: 14px; border: 1.5px solid #cbd5e1; border-radius: 10px; font-size: 0.92rem; background: #fff; font-family: 'Inter',sans-serif; color: #1e293b; outline: none; resize: vertical; line-height: 1.7; transition: 0.2s; }\r\n#pth-sum-wrapper .pth-textarea:focus { border-color: #3b82f6; box-shadow: 0 0 0 3px rgba(59,130,246,0.12); }\r\n#pth-sum-wrapper .pth-input { width: 100%; padding: 10px 13px; border: 1.5px solid #cbd5e1; border-radius: 8px; font-size: 0.88rem; outline: none; transition: 0.2s; font-family: 'Inter',sans-serif; color: #1e293b; background: #fff; }\r\n#pth-sum-wrapper .pth-input:focus { border-color: #3b82f6; box-shadow: 0 0 0 3px rgba(59,130,246,0.1); }\r\n#pth-sum-wrapper .pth-char-count { font-size: 0.75rem; color: #334155; text-align: right; margin-top: 5px; font-weight: 600; }\r\n\r\n\/* \u2500\u2500 Stats Grid \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-stats-grid { display: grid; grid-template-columns: repeat(auto-fit,minmax(100px,1fr)); gap: 10px; margin: 14px 0; }\r\n#pth-sum-wrapper .pth-stat-item { background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 10px; padding: 12px; text-align: center; }\r\n#pth-sum-wrapper .pth-stat-value { font-size: 1.2rem; font-weight: 900; color: #0f172a; display: block; }\r\n#pth-sum-wrapper .pth-stat-label { font-size: 0.68rem; color: #334155; font-weight: 700; text-transform: uppercase; letter-spacing: 0.4px; }\r\n\r\n\/* \u2500\u2500 Section Chips \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-chips-wrap { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 14px; }\r\n#pth-sum-wrapper .pth-section-chip { padding: 7px 13px; background: #f8fafc; border: 1.5px solid #e2e8f0; border-radius: 20px; cursor: pointer; font-size: 0.8rem; font-weight: 700; color: #334155; transition: 0.2s; white-space: nowrap; font-family: 'Inter',sans-serif; }\r\n#pth-sum-wrapper .pth-section-chip:hover { border-color: #8b5cf6; color: #5b21b6; background: #f5f3ff; }\r\n#pth-sum-wrapper .pth-section-chip.active { background: #f5f3ff; border-color: #8b5cf6; color: #5b21b6; }\r\n#pth-sum-wrapper .pth-active-tag { display: inline-flex; align-items: center; gap: 5px; background: #ede9fe; border: 1px solid #c4b5fd; border-radius: 20px; padding: 4px 12px; font-size: 0.78rem; font-weight: 700; color: #6d28d9; }\r\n#pth-sum-wrapper .pth-remove-tag-btn { background: none; border: none; cursor: pointer; color: #7c3aed; font-size: 0.9rem; padding: 0; line-height: 1; font-weight: 900; }\r\n#pth-sum-wrapper .pth-remove-tag-btn:hover { color: #dc2626; }\r\n\r\n\/* \u2500\u2500 Length \/ Format \/ Tone Selectors \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-sel-row { display: flex; gap: 7px; flex-wrap: wrap; }\r\n#pth-sum-wrapper .pth-length-btn,\r\n#pth-sum-wrapper .pth-format-btn,\r\n#pth-sum-wrapper .pth-tone-btn { flex: 1; min-width: 80px; padding: 9px 8px; background: #f8fafc; border: 1.5px solid #e2e8f0; border-radius: 8px; cursor: pointer; text-align: center; font-weight: 700; font-size: 0.8rem; color: #334155; transition: 0.2s; font-family: 'Inter',sans-serif; white-space: nowrap; }\r\n#pth-sum-wrapper .pth-length-btn.active { background: #eff6ff; border-color: #3b82f6; color: #1d4ed8; }\r\n#pth-sum-wrapper .pth-format-btn.active { background: #f0fdf4; border-color: #10b981; color: #047857; }\r\n#pth-sum-wrapper .pth-tone-btn.active { background: #fdf4ff; border-color: #a855f7; color: #7e22ce; }\r\n\r\n\/* \u2500\u2500 Progress \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-progress-area { background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 10px; padding: 18px; margin-top: 16px; display: none; text-align: center; }\r\n#pth-sum-wrapper .pth-progress-status { font-weight: 800; color: #1e293b; margin-bottom: 10px; font-size: 0.92rem; }\r\n#pth-sum-wrapper .pth-first-time-warn { background: #fffbeb; border: 1px solid #fde68a; color: #92400e; padding: 11px 14px; border-radius: 8px; font-size: 0.82rem; font-weight: 700; margin-bottom: 12px; text-align: left; line-height: 1.5; display: none; }\r\n#pth-sum-wrapper .pth-prog-bar-wrap { width: 100%; height: 6px; background: #e2e8f0; border-radius: 4px; overflow: hidden; margin-bottom: 8px; }\r\n#pth-sum-wrapper .pth-prog-bar { height: 100%; background: linear-gradient(90deg,#3b82f6,#8b5cf6); width: 0%; transition: width 0.3s ease; border-radius: 4px; }\r\n#pth-sum-wrapper .pth-prog-details { font-size: 0.75rem; color: #334155; font-family: 'Courier New',monospace; }\r\n#pth-sum-wrapper .pth-spinner { display: inline-block; width: 15px; height: 15px; border: 2.5px solid rgba(59,130,246,0.3); border-radius: 50%; border-top-color: #3b82f6; animation: pthSpin 1s linear infinite; vertical-align: middle; margin-right: 7px; }\r\n@keyframes pthSpin { to { transform: rotate(360deg); } }\r\n\r\n\/* \u2500\u2500 Result Box \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-result-box { display: none; background: #f0fdf4; border: 2px solid #34d399; border-radius: 12px; padding: 20px; margin-top: 20px; }\r\n#pth-sum-wrapper .pth-result-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; padding-bottom: 12px; border-bottom: 1px solid #a7f3d0; flex-wrap: wrap; gap: 10px; }\r\n#pth-sum-wrapper .pth-result-metrics { display: flex; gap: 18px; flex-wrap: wrap; margin-bottom: 14px; font-size: 0.85rem; font-weight: 700; color: #047857; }\r\n#pth-sum-wrapper .pth-result-text { font-size: 1rem; line-height: 1.75; color: #065f46; }\r\n#pth-sum-wrapper .pth-section-result { margin-bottom: 12px; padding: 13px 15px; background: #fff; border-radius: 10px; border-left: 4px solid #8b5cf6; }\r\n#pth-sum-wrapper .pth-section-result-title { font-weight: 800; color: #5b21b6; font-size: 0.82rem; margin-bottom: 7px; text-transform: uppercase; letter-spacing: 0.5px; }\r\n#pth-sum-wrapper .pth-section-result-content { font-size: 0.92rem; color: #1e293b; line-height: 1.65; }\r\n#pth-sum-wrapper .pth-mode-badge { display: inline-flex; align-items: center; gap: 5px; background: #f5f3ff; border: 1px solid #c4b5fd; border-radius: 20px; padding: 2px 9px; font-size: 0.72rem; font-weight: 700; color: #7c3aed; }\r\n\r\n\/* \u2500\u2500 Gauge \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-gauge-wrap { background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 12px; padding: 14px; text-align: center; }\r\n#pth-sum-wrapper .pth-gauge-svg { display: block; margin: 0 auto; }\r\n#pth-sum-wrapper .pth-gauge-label { font-size: 0.7rem; font-weight: 800; color: #334155; text-transform: uppercase; letter-spacing: 0.4px; margin-top: 4px; }\r\n\r\n\/* \u2500\u2500 Focus Keywords \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-kw-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }\r\n#pth-sum-wrapper .pth-kw-pill { display: inline-flex; align-items: center; gap: 5px; background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 20px; padding: 3px 10px; font-size: 0.78rem; font-weight: 700; color: #1d4ed8; }\r\n#pth-sum-wrapper .pth-kw-pill-remove { background: none; border: none; cursor: pointer; color: #3b82f6; font-weight: 900; font-size: 0.85rem; padding: 0; }\r\n#pth-sum-wrapper .pth-kw-pill-remove:hover { color: #dc2626; }\r\n\r\n\/* \u2500\u2500 Heatmap \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-heatmap-area { line-height: 1.85; font-size: 0.9rem; color: #1e293b; }\r\n#pth-sum-wrapper .pth-heatmap-sent { display: inline; }\r\n#pth-sum-wrapper .pth-heatmap-word { display: inline; padding: 1px 2px; border-radius: 3px; transition: 0.15s; }\r\n#pth-sum-wrapper .pth-ht-high { background: rgba(16,185,129,0.25); }\r\n#pth-sum-wrapper .pth-ht-med { background: rgba(245,158,11,0.18); }\r\n\r\n\/* \u2500\u2500 Text Analyzer \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-analysis-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }\r\n#pth-sum-wrapper .pth-analysis-chip { background: #f8fafc; border: 1.5px solid #e2e8f0; border-radius: 8px; padding: 8px 12px; text-align: center; }\r\n#pth-sum-wrapper .pth-analysis-chip-val { font-size: 1.1rem; font-weight: 900; color: #1d4ed8; display: block; }\r\n#pth-sum-wrapper .pth-analysis-chip-lbl { font-size: 0.65rem; color: #334155; font-weight: 700; text-transform: uppercase; }\r\n#pth-sum-wrapper .pth-kw-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }\r\n#pth-sum-wrapper .pth-kw-table th { text-align: left; padding: 8px 10px; background: #f1f5f9; color: #334155; font-weight: 800; font-size: 0.72rem; text-transform: uppercase; border-bottom: 2px solid #e2e8f0; }\r\n#pth-sum-wrapper .pth-kw-row td { padding: 7px 10px; border-bottom: 1px solid #f1f5f9; color: #1e293b; font-weight: 500; }\r\n#pth-sum-wrapper .pth-kw-row:hover { background: #f8fafc; }\r\n#pth-sum-wrapper .pth-kw-bar-cell { width: 120px; }\r\n#pth-sum-wrapper .pth-kw-bar-bg { height: 6px; background: #e2e8f0; border-radius: 3px; overflow: hidden; }\r\n#pth-sum-wrapper .pth-kw-bar-fill { height: 100%; background: linear-gradient(90deg,#3b82f6,#8b5cf6); border-radius: 3px; }\r\n#pth-sum-wrapper .pth-readability-arc { margin: 10px 0; }\r\n#pth-sum-wrapper .pth-dup-sent { background: #fef9c3; border: 1px solid #fde047; border-radius: 6px; padding: 7px 10px; font-size: 0.82rem; color: #92400e; margin-bottom: 6px; }\r\n\r\n\/* \u2500\u2500 Rewriter \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-rewrite-box { background: #f8fafc; border: 1.5px solid #e2e8f0; border-radius: 10px; padding: 16px; min-height: 180px; font-size: 0.92rem; line-height: 1.75; color: #1e293b; }\r\n#pth-sum-wrapper .pth-diff-changed { background: rgba(234,179,8,0.2); border-radius: 3px; padding: 1px 2px; }\r\n#pth-sum-wrapper .pth-compare-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }\r\n@media(max-width:700px){ #pth-sum-wrapper .pth-compare-grid { grid-template-columns: 1fr; } }\r\n#pth-sum-wrapper .pth-compare-col { background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 10px; padding: 14px; }\r\n#pth-sum-wrapper .pth-compare-label { font-size: 0.72rem; font-weight: 800; color: #334155; text-transform: uppercase; letter-spacing: 0.4px; margin-bottom: 8px; }\r\n\r\n\/* \u2500\u2500 Export Hub \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-export-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 12px; margin-bottom: 18px; }\r\n@media(max-width:600px){ #pth-sum-wrapper .pth-export-grid { grid-template-columns: repeat(2,1fr); } }\r\n#pth-sum-wrapper .pth-export-card { background: #f8fafc; border: 2px solid #e2e8f0; border-radius: 12px; padding: 16px; text-align: center; cursor: pointer; transition: all 0.2s; }\r\n#pth-sum-wrapper .pth-export-card:hover:not(.disabled) { transform: translateY(-3px); box-shadow: 0 6px 16px rgba(0,0,0,0.08); border-color: #3b82f6; }\r\n#pth-sum-wrapper .pth-export-card.disabled { opacity: 0.4; cursor: not-allowed; }\r\n#pth-sum-wrapper .pth-export-icon { font-size: 1.8rem; display: block; margin-bottom: 6px; }\r\n#pth-sum-wrapper .pth-export-name { font-size: 0.82rem; font-weight: 800; color: #0f172a; display: block; }\r\n#pth-sum-wrapper .pth-export-desc { font-size: 0.68rem; color: #334155; margin-top: 2px; display: block; }\r\n\r\n\/* \u2500\u2500 Sidebar \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-history-item { padding: 12px 14px; background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 8px; margin-bottom: 10px; cursor: pointer; transition: 0.2s; }\r\n#pth-sum-wrapper .pth-history-item:hover { border-color: #3b82f6; background: #eff6ff; }\r\n#pth-sum-wrapper .pth-history-text { font-size: 0.8rem; color: #1e293b; line-height: 1.5; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }\r\n#pth-sum-wrapper .pth-history-meta { font-size: 0.68rem; color: #334155; margin-top: 4px; font-weight: 700; }\r\n\r\n\/* \u2500\u2500 Instant TLDR Banner \u2500\u2500 *\/\r\n#pth-sum-wrapper .pth-instant-tldr { display: none; background: linear-gradient(135deg,#eff6ff,#f0fdf4); border: 1.5px solid #bfdbfe; border-radius: 10px; padding: 14px 16px; margin-bottom: 16px; }\r\n#pth-sum-wrapper .pth-instant-tldr-label { font-size: 0.7rem; font-weight: 800; color: #1d4ed8; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 5px; }\r\n#pth-sum-wrapper .pth-instant-tldr-text { font-size: 0.92rem; color: #1e293b; font-weight: 600; line-height: 1.65; }\r\n\r\n\/* \u2500\u2500 Language Modal \u2500\u2500 *\/\r\n#pth-lang-modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 99999; display: none; justify-content: center; align-items: center; backdrop-filter: blur(3px); }\r\n#pth-lang-modal-overlay.active { display: flex; }\r\n#pth-lang-modal-overlay .pth-lm-inner { background: #fff; width: 100%; max-width: 680px; border-radius: 16px; padding: 26px; max-height: 90vh; overflow-y: auto; }\r\n#pth-lang-modal-overlay .pth-lm-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 6px; margin-top: 14px; }\r\n#pth-lang-modal-overlay .pth-lm-btn { display: flex; align-items: center; gap: 9px; background: transparent; border: 1px solid transparent; padding: 8px 11px; border-radius: 8px; cursor: pointer; transition: 0.15s; color: #0f172a; font-size: 0.85rem; font-family: 'Inter',sans-serif; }\r\n#pth-lang-modal-overlay .pth-lm-btn:hover { background: #f8fafc; }\r\n#pth-lang-modal-overlay .pth-lm-btn.active { background: #eff6ff; border-color: #bfdbfe; }\r\n\r\n\/* \u2500\u2500 Toast \u2500\u2500 *\/\r\n#pth-sum-toast { position: fixed; bottom: 22px; right: 22px; background: #1e293b; color: #fff; padding: 12px 22px; border-radius: 10px; font-weight: 800; font-size: 0.88rem; box-shadow: 0 10px 30px rgba(0,0,0,0.3); z-index: 99999; display: none; align-items: center; gap: 10px; max-width: 320px; }\r\n#pth-sum-toast.show { display: flex; animation: pthSlideIn 0.3s ease; }\r\n@keyframes pthSlideIn { from{opacity:0;transform:translateY(24px);}to{opacity:1;transform:translateY(0);} }\r\n<\/style>\r\n\r\n<!-- Toast -->\r\n<div id=\"pth-sum-toast\">\u2705 Done!<\/div>\r\n\r\n<!-- Language Modal -->\r\n<div id=\"pth-lang-modal-overlay\">\r\n  <div class=\"pth-lm-inner\">\r\n    <div style=\"display:flex;justify-content:space-between;align-items:center;margin-bottom:4px;\">\r\n      <h3 style=\"margin:0;color:#0f172a;font-size:1.1rem;\">\ud83c\udf10 Select Source Language<\/h3>\r\n      <button id=\"pth-lm-close\" style=\"background:none;border:none;font-size:1.2rem;cursor:pointer;color:#334155;\" aria-label=\"Close\">\u2715<\/button>\r\n    <\/div>\r\n    <input type=\"text\" id=\"pth-lm-search\" class=\"pth-input\" placeholder=\"Search language...\" style=\"margin-top:10px;\" aria-label=\"Search language\">\r\n    <div class=\"pth-lm-grid\" id=\"pth-lm-grid\"><\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<!-- WRAPPER -->\r\n<div id=\"pth-sum-wrapper\">\r\n\r\n  <!-- Top Bar -->\r\n  <div class=\"pth-top-bar\">\r\n    <div>\r\n      <h2 class=\"pth-tool-title\">\r\n        \ud83d\udcdd AI Text Summarizer & Intelligence Hub\r\n        <span class=\"pth-version-badge\">v5.0 PRO<\/span>\r\n        <span class=\"pth-status-offline\">\ud83d\udd12 100% Offline<\/span>\r\n      <\/h2>\r\n      <span class=\"pth-subtitle\">Summarize \u00b7 Analyze \u00b7 Rewrite \u00b7 Export \u2014 All-in-One Offline AI<\/span>\r\n    <\/div>\r\n    <div class=\"pth-top-actions\">\r\n      <button class=\"pth-sample-btn\" id=\"pth-load-sample-btn\" aria-label=\"Load sample text\">\ud83d\udca1 Load Sample<\/button>\r\n      <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-dark-btn\" aria-label=\"Toggle dark mode\">\ud83c\udf19 Dark<\/button>\r\n      <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-fw-btn\" aria-label=\"Toggle full width\">\u26f6 Full Width<\/button>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"pth-layout\" id=\"pth-sum-layout\">\r\n\r\n    <!-- MAIN COL -->\r\n    <div class=\"pth-main-col\">\r\n\r\n      <!-- Tab Bar -->\r\n      <div class=\"pth-tab-bar\" id=\"pth-tab-bar\" role=\"tablist\">\r\n        <button class=\"pth-tab-btn active\" data-tab=\"input\" role=\"tab\" aria-selected=\"true\">\ud83d\udce5 Input<\/button>\r\n        <button class=\"pth-tab-btn\" data-tab=\"sections\" role=\"tab\" aria-selected=\"false\">\ud83d\udccb Sections<\/button>\r\n        <button class=\"pth-tab-btn\" data-tab=\"summary\" role=\"tab\" aria-selected=\"false\">\ud83c\udfaf Summary<\/button>\r\n        <button class=\"pth-tab-btn\" data-tab=\"analyzer\" role=\"tab\" aria-selected=\"false\">\ud83d\udd0d Analyzer<\/button>\r\n        <button class=\"pth-tab-btn\" data-tab=\"rewriter\" role=\"tab\" aria-selected=\"false\">\u270d\ufe0f Rewriter<\/button>\r\n        <button class=\"pth-tab-btn\" data-tab=\"export\" role=\"tab\" aria-selected=\"false\">\ud83d\udce4 Export Hub<\/button>\r\n      <\/div>\r\n\r\n      <div class=\"pth-tab-wrap\">\r\n\r\n        <!-- \u2500\u2500 TAB 1: INPUT \u2500\u2500 -->\r\n        <div class=\"pth-tab-panel active\" id=\"pth-panel-input\">\r\n\r\n          <!-- Instant TL;DR Banner -->\r\n          <div class=\"pth-instant-tldr\" id=\"pth-instant-tldr\">\r\n            <div class=\"pth-instant-tldr-label\">\u26a1 Instant TL;DR (no AI download needed)<\/div>\r\n            <div class=\"pth-instant-tldr-text\" id=\"pth-instant-tldr-text\">\u2014<\/div>\r\n          <\/div>\r\n\r\n          <!-- Input Source Row -->\r\n          <div style=\"display:flex;gap:8px;flex-wrap:wrap;margin-bottom:12px;align-items:center;\">\r\n            <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-paste-btn\" aria-label=\"Paste from clipboard\">\ud83d\udccb Paste<\/button>\r\n            <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-upload-btn\" aria-label=\"Upload document\">\ud83d\udcc2 Upload File<\/button>\r\n            <input type=\"file\" id=\"pth-doc-file\" accept=\".txt,.pdf,.doc,.docx\" style=\"display:none;\" aria-label=\"Document file input\">\r\n            <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-clean-btn\" aria-label=\"Clean text\">\ud83e\uddf9 Clean Text<\/button>\r\n            <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-lang-trigger-btn\" aria-label=\"Select source language\">\ud83c\udf10 <span id=\"pth-cur-lang-label\">English<\/span> \u25be<\/button>\r\n            <input type=\"hidden\" id=\"pth-src-lang\" value=\"en\">\r\n            <div style=\"display:flex;flex:1;min-width:200px;\">\r\n              <input type=\"text\" id=\"pth-url-input\" class=\"pth-input\" placeholder=\"https:\/\/paste-url-to-fetch...\" style=\"border-radius:8px 0 0 8px;border-right:none;\" aria-label=\"URL to fetch text from\">\r\n              <button class=\"pth-btn pth-btn-primary pth-btn-sm\" id=\"pth-fetch-url-btn\" style=\"border-radius:0 8px 8px 0;\" aria-label=\"Fetch URL content\">\ud83d\udd17 Fetch<\/button>\r\n            <\/div>\r\n          <\/div>\r\n\r\n          <!-- Dual Text Boxes -->\r\n          <div style=\"display:grid;grid-template-columns:1fr auto 1fr;gap:14px;align-items:start;background:#eff6ff;padding:16px;border-radius:12px;border:1px solid #bfdbfe;margin-bottom:16px;\">\r\n            <div>\r\n              <label class=\"pth-label\" for=\"pth-native-text\">Source Text (Any Language)<\/label>\r\n              <textarea id=\"pth-native-text\" class=\"pth-textarea\" style=\"min-height:220px;\" placeholder=\"Paste or type text here in any language...\" aria-label=\"Source text input\"><\/textarea>\r\n            <\/div>\r\n            <div style=\"display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding-top:24px;\">\r\n              <button class=\"pth-btn pth-btn-primary\" id=\"pth-translate-btn\" style=\"border-radius:50%;width:52px;height:52px;padding:0;font-size:1.3rem;\" title=\"Translate to English\" aria-label=\"Translate to English\">\u27a1\ufe0f<\/button>\r\n              <span style=\"font-size:0.65rem;color:#334155;font-weight:700;text-align:center;\">Translate<\/span>\r\n            <\/div>\r\n            <div>\r\n              <label class=\"pth-label\" for=\"pth-source-text\">English Text (Ready for AI)<\/label>\r\n              <textarea id=\"pth-source-text\" class=\"pth-textarea\" style=\"min-height:220px;\" placeholder=\"English text for summarization...\" aria-label=\"English text for summarization\"><\/textarea>\r\n            <\/div>\r\n          <\/div>\r\n\r\n          <!-- Stats -->\r\n          <div class=\"pth-stats-grid\" id=\"pth-input-stats\">\r\n            <div class=\"pth-stat-item\"><span class=\"pth-stat-value\" id=\"pth-stat-words\" style=\"color:#1d4ed8;\">0<\/span><span class=\"pth-stat-label\">Words<\/span><\/div>\r\n            <div class=\"pth-stat-item\"><span class=\"pth-stat-value\" id=\"pth-stat-chars\" style=\"color:#5b21b6;\">0<\/span><span class=\"pth-stat-label\">Chars<\/span><\/div>\r\n            <div class=\"pth-stat-item\"><span class=\"pth-stat-value\" id=\"pth-stat-sents\" style=\"color:#047857;\">0<\/span><span class=\"pth-stat-label\">Sentences<\/span><\/div>\r\n            <div class=\"pth-stat-item\"><span class=\"pth-stat-value\" id=\"pth-stat-read\" style=\"color:#92400e;\">0m<\/span><span class=\"pth-stat-label\">Read Time<\/span><\/div>\r\n          <\/div>\r\n\r\n          <!-- Heatmap -->\r\n          <div id=\"pth-heatmap-wrap\" style=\"display:none;margin-top:14px;\">\r\n            <div style=\"font-size:0.72rem;font-weight:800;color:#334155;text-transform:uppercase;letter-spacing:0.4px;margin-bottom:7px;\">\r\n              \ud83c\udf21\ufe0f Sentence Importance Heatmap\r\n              <span style=\"font-weight:500;font-size:0.65rem;color:#64748b;margin-left:6px;\">\r\n                <span style=\"background:rgba(16,185,129,0.25);padding:1px 5px;border-radius:3px;\">High<\/span>\r\n                <span style=\"background:rgba(245,158,11,0.18);padding:1px 5px;border-radius:3px;margin-left:3px;\">Medium<\/span>\r\n              <\/span>\r\n            <\/div>\r\n            <div class=\"pth-heatmap-area\" id=\"pth-heatmap-content\"><\/div>\r\n          <\/div>\r\n\r\n          <!-- Focus Keywords -->\r\n          <div style=\"margin-top:16px;\">\r\n            <label class=\"pth-label\">\ud83d\udccc Focus Keywords (AI prioritizes these sentences)<\/label>\r\n            <div style=\"display:flex;gap:8px;align-items:center;\">\r\n              <input type=\"text\" id=\"pth-kw-input\" class=\"pth-input\" style=\"flex:1;\" placeholder=\"e.g. climate change, revenue...\" aria-label=\"Focus keyword input\">\r\n              <button class=\"pth-btn pth-btn-primary pth-btn-sm\" id=\"pth-kw-add-btn\" aria-label=\"Add keyword\">\uff0b Add<\/button>\r\n              <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-kw-clear-btn\" aria-label=\"Clear keywords\">\u2715 Clear<\/button>\r\n            <\/div>\r\n            <div class=\"pth-kw-pills\" id=\"pth-kw-pills\"><\/div>\r\n          <\/div>\r\n\r\n          <!-- Settings Row -->\r\n          <div style=\"display:grid;grid-template-columns:1fr 1fr 1fr;gap:14px;margin-top:18px;\" id=\"pth-settings-grid\">\r\n            <div>\r\n              <label class=\"pth-label\">Length<\/label>\r\n              <div class=\"pth-sel-row\" id=\"pth-length-sel\">\r\n                <button class=\"pth-length-btn active\" data-length=\"short\" aria-pressed=\"true\">\u26a1 Short<\/button>\r\n                <button class=\"pth-length-btn\" data-length=\"medium\" aria-pressed=\"false\">\ud83d\udcc4 Medium<\/button>\r\n                <button class=\"pth-length-btn\" data-length=\"long\" aria-pressed=\"false\">\ud83d\udcda Detailed<\/button>\r\n              <\/div>\r\n            <\/div>\r\n            <div>\r\n              <label class=\"pth-label\">Format<\/label>\r\n              <div class=\"pth-sel-row\" id=\"pth-format-sel\">\r\n                <button class=\"pth-format-btn active\" data-format=\"paragraph\" aria-pressed=\"true\">\ud83d\udcdd Paragraph<\/button>\r\n                <button class=\"pth-format-btn\" data-format=\"bullet\" aria-pressed=\"false\">\u2022 Bullets<\/button>\r\n              <\/div>\r\n            <\/div>\r\n            <div>\r\n              <label class=\"pth-label\">Tone<\/label>\r\n              <div class=\"pth-sel-row\" id=\"pth-tone-sel\">\r\n                <button class=\"pth-tone-btn active\" data-tone=\"neutral\" aria-pressed=\"true\">\u2696\ufe0f Neutral<\/button>\r\n                <button class=\"pth-tone-btn\" data-tone=\"professional\" aria-pressed=\"false\">\ud83d\udcbc Pro<\/button>\r\n                <button class=\"pth-tone-btn\" data-tone=\"simple\" aria-pressed=\"false\">\ud83e\uddd2 Simple<\/button>\r\n                <button class=\"pth-tone-btn\" data-tone=\"academic\" aria-pressed=\"false\">\ud83c\udf93 Academic<\/button>\r\n                <button class=\"pth-tone-btn\" data-tone=\"social\" aria-pressed=\"false\">\ud83d\udcf1 Social<\/button>\r\n              <\/div>\r\n            <\/div>\r\n          <\/div>\r\n\r\n          <!-- Generate Button -->\r\n          <button class=\"pth-btn pth-btn-success\" id=\"pth-generate-btn\" style=\"margin-top:18px;\" disabled aria-label=\"Generate AI summary\">\u2728 Generate AI Summary (100% Offline)<\/button>\r\n\r\n          <!-- Progress -->\r\n          <div class=\"pth-progress-area\" id=\"pth-progress-area\">\r\n            <div class=\"pth-progress-status\" id=\"pth-progress-status\"><span class=\"pth-spinner\"><\/span> Initializing AI...<\/div>\r\n            <div class=\"pth-first-time-warn\" id=\"pth-first-time-warn\">\u26a0\ufe0f <strong>First-time setup:<\/strong> Downloading AI NLP model (~240 MB). This is a one-time process \u2014 all future summaries run instantly offline.<\/div>\r\n            <div class=\"pth-prog-bar-wrap\" id=\"pth-prog-bar-wrap\" style=\"display:none;\"><div class=\"pth-prog-bar\" id=\"pth-prog-bar\"><\/div><\/div>\r\n            <div class=\"pth-prog-details\" id=\"pth-prog-details\">Loading Xenova\/distilbart-cnn-12-6...<\/div>\r\n          <\/div>\r\n        <\/div>\r\n\r\n        <!-- \u2500\u2500 TAB 2: SECTIONS \u2500\u2500 -->\r\n        <div class=\"pth-tab-panel\" id=\"pth-panel-sections\">\r\n          <p style=\"font-size:0.85rem;color:#334155;font-weight:600;margin:0 0 14px;\">Select preset focus areas or add custom ones. When active, the AI produces a structured sectioned report instead of a standard summary.<\/p>\r\n\r\n          <label class=\"pth-label\">Quick-Add Preset Sections<\/label>\r\n          <div class=\"pth-chips-wrap\" id=\"pth-preset-chips\">\r\n            <button class=\"pth-section-chip\" data-section=\"Key Points\" aria-pressed=\"false\">\ud83c\udfaf Key Points<\/button>\r\n            <button class=\"pth-section-chip\" data-section=\"Action Items\" aria-pressed=\"false\">\u2705 Action Items<\/button>\r\n            <button class=\"pth-section-chip\" data-section=\"Dates & Deadlines\" aria-pressed=\"false\">\ud83d\udcc5 Dates & Deadlines<\/button>\r\n            <button class=\"pth-section-chip\" data-section=\"People & Orgs\" aria-pressed=\"false\">\ud83d\udc65 People & Orgs<\/button>\r\n            <button class=\"pth-section-chip\" data-section=\"Financial Data\" aria-pressed=\"false\">\ud83d\udcb0 Financial Data<\/button>\r\n            <button class=\"pth-section-chip\" data-section=\"Risks & Issues\" aria-pressed=\"false\">\u26a0\ufe0f Risks & Issues<\/button>\r\n            <button class=\"pth-section-chip\" data-section=\"Decisions Made\" aria-pressed=\"false\">\u2696\ufe0f Decisions Made<\/button>\r\n            <button class=\"pth-section-chip\" data-section=\"Recommendations\" aria-pressed=\"false\">\ud83d\udca1 Recommendations<\/button>\r\n            <button class=\"pth-section-chip\" data-section=\"Technical Details\" aria-pressed=\"false\">\ud83d\udd27 Technical Details<\/button>\r\n            <button class=\"pth-section-chip\" data-section=\"Background Context\" aria-pressed=\"false\">\ud83d\udcd6 Background Context<\/button>\r\n            <button class=\"pth-section-chip\" data-section=\"Statistics & Numbers\" aria-pressed=\"false\">\ud83d\udcca Statistics & Numbers<\/button>\r\n            <button class=\"pth-section-chip\" data-section=\"Conclusions\" aria-pressed=\"false\">\ud83c\udfc1 Conclusions<\/button>\r\n          <\/div>\r\n\r\n          <div style=\"display:flex;gap:8px;margin:14px 0;\">\r\n            <input type=\"text\" id=\"pth-custom-sec-input\" class=\"pth-input\" placeholder=\"Add custom section (e.g. Legal Clauses, Budget Analysis...)\" style=\"flex:1;\" aria-label=\"Custom section name\">\r\n            <button class=\"pth-btn pth-btn-primary pth-btn-sm\" id=\"pth-add-sec-btn\" aria-label=\"Add custom section\">\uff0b Add<\/button>\r\n            <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-clear-secs-btn\" aria-label=\"Clear all sections\">\u2715 Clear All<\/button>\r\n          <\/div>\r\n\r\n          <div id=\"pth-active-secs-wrap\" style=\"display:none;\">\r\n            <label class=\"pth-label\" style=\"color:#5b21b6;\">Active Sections <span style=\"font-size:0.68rem;font-weight:500;color:#64748b;\">\u2014 click \u00d7 to remove<\/span><\/label>\r\n            <div style=\"display:flex;flex-wrap:wrap;gap:7px;margin-top:6px;\" id=\"pth-active-secs-list\"><\/div>\r\n          <\/div>\r\n\r\n          <div style=\"background:#f5f3ff;border:1px solid #ddd6fe;border-radius:10px;padding:14px;margin-top:16px;\">\r\n            <p style=\"font-size:0.82rem;color:#5b21b6;font-weight:700;margin:0 0 6px;\">\ud83d\udca1 How Custom Sections Work<\/p>\r\n            <p style=\"font-size:0.82rem;color:#6d28d9;font-weight:500;margin:0;line-height:1.6;\">Each section uses keyword-intelligence to extract relevant sentences from your text \u2014 <strong>instant, 100% offline, zero AI model needed<\/strong>. When sections are active, click Generate to produce a structured sectioned report. Mix presets + custom sections for maximum control.<\/p>\r\n          <\/div>\r\n        <\/div>\r\n\r\n        <!-- \u2500\u2500 TAB 3: SUMMARY \u2500\u2500 -->\r\n        <div class=\"pth-tab-panel\" id=\"pth-panel-summary\">\r\n          <div id=\"pth-summary-empty\" style=\"text-align:center;color:#334155;font-weight:600;padding:80px 0;\">\r\n            <span style=\"font-size:2.5rem;display:block;margin-bottom:10px;\">\u2728<\/span>\r\n            Generate a summary from the Input tab first.\r\n          <\/div>\r\n\r\n          <div id=\"pth-result-box\" class=\"pth-result-box\" style=\"display:none;margin-top:0;\">\r\n            <div class=\"pth-result-header\">\r\n              <div style=\"display:flex;align-items:center;flex-wrap:wrap;gap:8px;\">\r\n                <h3 style=\"margin:0;color:#065f46;font-size:1rem;font-weight:800;\">\ud83c\udfaf Generated Summary<\/h3>\r\n                <span id=\"pth-result-mode-badge\" class=\"pth-mode-badge\" style=\"display:none;\">\ud83d\udccb Sectioned<\/span>\r\n                <span id=\"pth-result-tone-badge\" class=\"pth-mode-badge\" style=\"display:none;background:#fdf4ff;border-color:#e9d5ff;color:#7e22ce;\"><\/span>\r\n              <\/div>\r\n              <div style=\"display:flex;gap:7px;flex-wrap:wrap;\">\r\n                <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-regenerate-btn\" aria-label=\"Regenerate summary\">\ud83d\udd04 Regen<\/button>\r\n                <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-save-compare-btn\" aria-label=\"Save for comparison\">\ud83d\udcbe Save v1<\/button>\r\n                <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-translate-native-btn\" aria-label=\"Translate to native language\">\ud83c\udf10 Translate<\/button>\r\n                <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-copy-result-btn\" aria-label=\"Copy result\">\ud83d\udccb Copy<\/button>\r\n                <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-print-btn\" aria-label=\"Print result\">\ud83d\udda8\ufe0f Print<\/button>\r\n              <\/div>\r\n            <\/div>\r\n            <div class=\"pth-result-metrics\" id=\"pth-result-metrics\">\r\n              <span><strong id=\"pth-res-words\">0<\/strong> words<\/span>\r\n              <span><strong id=\"pth-compression\">0%<\/strong> compression<\/span>\r\n              <span><strong id=\"pth-res-readtime\">0 min<\/strong> read<\/span>\r\n            <\/div>\r\n\r\n            <!-- Compression Gauge -->\r\n            <div class=\"pth-gauge-wrap\" style=\"margin-bottom:14px;\">\r\n              <svg class=\"pth-gauge-svg\" width=\"120\" height=\"68\" viewBox=\"0 0 120 68\" aria-label=\"Compression gauge\">\r\n                <path d=\"M10,60 A50,50 0 0,1 110,60\" fill=\"none\" stroke=\"#e2e8f0\" stroke-width=\"10\" stroke-linecap=\"round\"\/>\r\n                <path id=\"pth-gauge-arc\" d=\"M10,60 A50,50 0 0,1 110,60\" fill=\"none\" stroke=\"#3b82f6\" stroke-width=\"10\" stroke-linecap=\"round\" stroke-dasharray=\"157\" stroke-dashoffset=\"157\"\/>\r\n                <text id=\"pth-gauge-pct\" x=\"60\" y=\"58\" text-anchor=\"middle\" font-size=\"16\" font-weight=\"800\" fill=\"#1d4ed8\">0%<\/text>\r\n              <\/svg>\r\n              <div class=\"pth-gauge-label\">Compression Ratio<\/div>\r\n            <\/div>\r\n\r\n            <div class=\"pth-result-text\" id=\"pth-result-content\"><\/div>\r\n            <div id=\"pth-reverse-trans-out\" style=\"display:none;margin-top:10px;padding:12px;background:#fff;border:1px dashed #6ee7b7;border-radius:8px;color:#047857;font-size:0.92rem;line-height:1.65;font-weight:500;\"><\/div>\r\n          <\/div>\r\n\r\n          <!-- Version Compare -->\r\n          <div id=\"pth-compare-wrap\" style=\"display:none;margin-top:16px;\">\r\n            <div style=\"font-size:0.75rem;font-weight:800;color:#334155;text-transform:uppercase;letter-spacing:0.4px;margin-bottom:10px;\">\ud83d\udd01 Version Comparison<\/div>\r\n            <div class=\"pth-compare-grid\">\r\n              <div class=\"pth-compare-col\">\r\n                <div class=\"pth-compare-label\">Version 1<\/div>\r\n                <div id=\"pth-compare-v1\" style=\"font-size:0.88rem;color:#1e293b;line-height:1.7;\"><\/div>\r\n              <\/div>\r\n              <div class=\"pth-compare-col\">\r\n                <div class=\"pth-compare-label\">Version 2 (Current)<\/div>\r\n                <div id=\"pth-compare-v2\" style=\"font-size:0.88rem;color:#1e293b;line-height:1.7;\"><\/div>\r\n              <\/div>\r\n            <\/div>\r\n          <\/div>\r\n        <\/div>\r\n\r\n        <!-- \u2500\u2500 TAB 4: ANALYZER \u2500\u2500 -->\r\n        <div class=\"pth-tab-panel\" id=\"pth-panel-analyzer\">\r\n          <div id=\"pth-analyzer-empty\" style=\"text-align:center;color:#334155;font-weight:600;padding:80px 0;\">\r\n            <span style=\"font-size:2.5rem;display:block;margin-bottom:10px;\">\ud83d\udd0d<\/span>\r\n            Load text in the Input tab to run deep analysis.\r\n          <\/div>\r\n          <div id=\"pth-analyzer-content\" style=\"display:none;\">\r\n            <div class=\"pth-analysis-chips\" id=\"pth-analysis-chips\">\r\n              <div class=\"pth-analysis-chip\"><span class=\"pth-analysis-chip-val\" id=\"pth-an-flesch\" style=\"color:#1d4ed8;\">\u2014<\/span><span class=\"pth-analysis-chip-lbl\">Flesch Score<\/span><\/div>\r\n              <div class=\"pth-analysis-chip\"><span class=\"pth-analysis-chip-val\" id=\"pth-an-grade\" style=\"color:#5b21b6;\">\u2014<\/span><span class=\"pth-analysis-chip-lbl\">Grade Level<\/span><\/div>\r\n              <div class=\"pth-analysis-chip\"><span class=\"pth-analysis-chip-val\" id=\"pth-an-avglen\" style=\"color:#047857;\">\u2014<\/span><span class=\"pth-analysis-chip-lbl\">Avg Sent Len<\/span><\/div>\r\n              <div class=\"pth-analysis-chip\"><span class=\"pth-analysis-chip-val\" id=\"pth-an-unique\" style=\"color:#92400e;\">\u2014<\/span><span class=\"pth-analysis-chip-lbl\">Unique Words<\/span><\/div>\r\n              <div class=\"pth-analysis-chip\"><span class=\"pth-analysis-chip-val\" id=\"pth-an-vocab\" style=\"color:#7e22ce;\">\u2014<\/span><span class=\"pth-analysis-chip-lbl\">Vocab Richness<\/span><\/div>\r\n            <\/div>\r\n\r\n            <div style=\"font-size:0.72rem;font-weight:800;color:#334155;text-transform:uppercase;letter-spacing:0.4px;margin-bottom:8px;\">\ud83c\udfc6 Top 12 Keywords by Density<\/div>\r\n            <table class=\"pth-kw-table\" id=\"pth-kw-table\" aria-label=\"Keyword density table\">\r\n              <thead><tr><th>#<\/th><th>Keyword<\/th><th>Count<\/th><th>Density<\/th><th class=\"pth-kw-bar-cell\">Frequency<\/th><\/tr><\/thead>\r\n              <tbody id=\"pth-kw-tbody\"><\/tbody>\r\n            <\/table>\r\n\r\n            <div style=\"font-size:0.72rem;font-weight:800;color:#334155;text-transform:uppercase;letter-spacing:0.4px;margin:16px 0 8px;\">\u26a0\ufe0f Duplicate \/ Near-Duplicate Sentences<\/div>\r\n            <div id=\"pth-dup-sents\"><\/div>\r\n\r\n            <div style=\"font-size:0.72rem;font-weight:800;color:#334155;text-transform:uppercase;letter-spacing:0.4px;margin:16px 0 8px;\">\ud83d\udcca Sentence Length Distribution<\/div>\r\n            <div id=\"pth-sent-dist\" style=\"display:flex;flex-wrap:wrap;gap:5px;align-items:flex-end;height:80px;margin-bottom:6px;\"><\/div>\r\n            <div style=\"font-size:0.68rem;color:#334155;font-weight:600;\">Each bar = one sentence \u00b7 Height = word count<\/div>\r\n          <\/div>\r\n        <\/div>\r\n\r\n        <!-- \u2500\u2500 TAB 5: REWRITER \u2500\u2500 -->\r\n        <div class=\"pth-tab-panel\" id=\"pth-panel-rewriter\">\r\n          <p style=\"font-size:0.85rem;color:#334155;font-weight:600;margin:0 0 14px;\">Load the generated summary or paste any text, choose a rewrite mode, and get an offline-rewritten version with change highlights.<\/p>\r\n          <div style=\"display:flex;gap:8px;flex-wrap:wrap;margin-bottom:14px;\">\r\n            <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-rw-load-btn\" aria-label=\"Load summary into rewriter\">\ud83d\udce5 Load Summary<\/button>\r\n            <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-rw-load-source-btn\" aria-label=\"Load source text into rewriter\">\ud83d\udcc4 Load Source Text<\/button>\r\n          <\/div>\r\n          <label class=\"pth-label\">Rewrite Mode<\/label>\r\n          <div class=\"pth-sel-row\" id=\"pth-rw-mode-sel\" style=\"margin-bottom:14px;flex-wrap:wrap;\">\r\n            <button class=\"pth-tone-btn active\" data-mode=\"paraphrase\" aria-pressed=\"true\">\ud83d\udd04 Paraphrase<\/button>\r\n            <button class=\"pth-tone-btn\" data-mode=\"simplify\" aria-pressed=\"false\">\ud83e\uddd2 Simplify<\/button>\r\n            <button class=\"pth-tone-btn\" data-mode=\"formalize\" aria-pressed=\"false\">\ud83d\udcbc Formalize<\/button>\r\n            <button class=\"pth-tone-btn\" data-mode=\"shorten\" aria-pressed=\"false\">\u2702\ufe0f Shorten<\/button>\r\n            <button class=\"pth-tone-btn\" data-mode=\"expand\" aria-pressed=\"false\">\ud83d\udcc8 Expand<\/button>\r\n          <\/div>\r\n          <div style=\"display:grid;grid-template-columns:1fr 1fr;gap:14px;\">\r\n            <div>\r\n              <label class=\"pth-label\" for=\"pth-rw-input\">Input Text<\/label>\r\n              <textarea id=\"pth-rw-input\" class=\"pth-textarea\" style=\"min-height:220px;\" placeholder=\"Paste or load text to rewrite...\" aria-label=\"Text to rewrite\"><\/textarea>\r\n            <\/div>\r\n            <div>\r\n              <label class=\"pth-label\">Rewritten Output <span id=\"pth-diff-badge\" style=\"display:none;font-size:0.65rem;background:rgba(234,179,8,0.2);color:#92400e;padding:1px 6px;border-radius:4px;font-weight:700;\">Changes highlighted<\/span><\/label>\r\n              <div class=\"pth-rewrite-box\" id=\"pth-rw-output\">Rewritten text appears here...<\/div>\r\n            <\/div>\r\n          <\/div>\r\n          <div style=\"display:flex;gap:8px;margin-top:12px;flex-wrap:wrap;\">\r\n            <button class=\"pth-btn pth-btn-warning\" id=\"pth-rw-generate-btn\" aria-label=\"Generate rewrite\">\u270d\ufe0f Rewrite (Offline AI)<\/button>\r\n            <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-rw-copy-btn\" aria-label=\"Copy rewritten text\">\ud83d\udccb Copy Result<\/button>\r\n            <div class=\"pth-prog-bar-wrap\" id=\"pth-rw-prog-wrap\" style=\"display:none;flex:1;align-self:center;\"><div class=\"pth-prog-bar\" id=\"pth-rw-prog-bar\"><\/div><\/div>\r\n          <\/div>\r\n        <\/div>\r\n\r\n        <!-- \u2500\u2500 TAB 6: EXPORT HUB \u2500\u2500 -->\r\n        <div class=\"pth-tab-panel\" id=\"pth-panel-export\">\r\n          <p style=\"font-size:0.85rem;color:#334155;font-weight:600;margin:0 0 16px;\">All export formats in one place. Summary must be generated first.<\/p>\r\n          <div class=\"pth-export-grid\" id=\"pth-export-grid\">\r\n            <div class=\"pth-export-card disabled\" id=\"pth-exp-txt\" role=\"button\" tabindex=\"0\" aria-label=\"Export as plain text\">\r\n              <span class=\"pth-export-icon\">\ud83d\udcc4<\/span>\r\n              <span class=\"pth-export-name\">.TXT<\/span>\r\n              <span class=\"pth-export-desc\">Plain text summary<\/span>\r\n            <\/div>\r\n            <div class=\"pth-export-card disabled\" id=\"pth-exp-pdf\" role=\"button\" tabindex=\"0\" aria-label=\"Export as PDF\">\r\n              <span class=\"pth-export-icon\">\ud83d\udccb<\/span>\r\n              <span class=\"pth-export-name\">.PDF<\/span>\r\n              <span class=\"pth-export-desc\">Formatted document<\/span>\r\n            <\/div>\r\n            <div class=\"pth-export-card disabled\" id=\"pth-exp-md\" role=\"button\" tabindex=\"0\" aria-label=\"Export as Markdown\">\r\n              <span class=\"pth-export-icon\">\u2b07\ufe0f<\/span>\r\n              <span class=\"pth-export-name\">.MD<\/span>\r\n              <span class=\"pth-export-desc\">Markdown format<\/span>\r\n            <\/div>\r\n            <div class=\"pth-export-card disabled\" id=\"pth-exp-json\" role=\"button\" tabindex=\"0\" aria-label=\"Export as JSON\">\r\n              <span class=\"pth-export-icon\">\ud83d\uddc2\ufe0f<\/span>\r\n              <span class=\"pth-export-name\">.JSON<\/span>\r\n              <span class=\"pth-export-desc\">Structured data<\/span>\r\n            <\/div>\r\n            <div class=\"pth-export-card disabled\" id=\"pth-exp-srt\" role=\"button\" tabindex=\"0\" aria-label=\"Export as SRT subtitle\">\r\n              <span class=\"pth-export-icon\">\ud83d\udcfa<\/span>\r\n              <span class=\"pth-export-name\">.SRT<\/span>\r\n              <span class=\"pth-export-desc\">Video subtitle file<\/span>\r\n            <\/div>\r\n            <div class=\"pth-export-card disabled\" id=\"pth-exp-email\" role=\"button\" tabindex=\"0\" aria-label=\"Export as email-ready text\">\r\n              <span class=\"pth-export-icon\">\ud83d\udce7<\/span>\r\n              <span class=\"pth-export-name\">Email<\/span>\r\n              <span class=\"pth-export-desc\">Email-ready format<\/span>\r\n            <\/div>\r\n          <\/div>\r\n          <div style=\"font-size:0.72rem;font-weight:800;color:#334155;text-transform:uppercase;letter-spacing:0.4px;margin-bottom:10px;\">\ud83d\udccb Quick Copy Formats<\/div>\r\n          <div style=\"display:flex;flex-wrap:wrap;gap:8px;\">\r\n            <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-copy-plain\" aria-label=\"Copy plain text\">\ud83d\udcc4 Plain Text<\/button>\r\n            <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-copy-markdown\" aria-label=\"Copy as markdown\">\u2b07\ufe0f Markdown<\/button>\r\n            <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-copy-email\" aria-label=\"Copy as email\">\ud83d\udce7 Email Format<\/button>\r\n            <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-copy-social\" aria-label=\"Copy social media version\">\ud83d\udcf1 Social (280 chars)<\/button>\r\n          <\/div>\r\n        <\/div>\r\n\r\n      <\/div><!-- end tab-wrap -->\r\n    <\/div><!-- end main-col -->\r\n\r\n    <!-- SIDEBAR -->\r\n    <div class=\"pth-sidebar-col\" id=\"pth-sum-sidebar\">\r\n\r\n      <div class=\"pth-card\" style=\"background:#f0fdf4;border-color:#6ee7b7;\">\r\n        <h3 class=\"pth-card-title\" style=\"color:#065f46;border-bottom-color:#a7f3d0;font-size:0.95rem;\">\ud83d\udd12 100% Private<\/h3>\r\n        <p style=\"font-size:0.82rem;color:#047857;font-weight:500;margin:0;line-height:1.6;\">Web Workers + WASM \u2014 your documents never leave your browser. No server, no API, no account.<\/p>\r\n      <\/div>\r\n\r\n      <div class=\"pth-card\">\r\n        <h3 class=\"pth-card-title\" style=\"font-size:0.95rem;\">\ud83d\udcca Compression Meter<\/h3>\r\n        <div class=\"pth-gauge-wrap\">\r\n          <svg class=\"pth-gauge-svg\" width=\"110\" height=\"64\" viewBox=\"0 0 120 68\" aria-label=\"Sidebar compression gauge\">\r\n            <path d=\"M10,60 A50,50 0 0,1 110,60\" fill=\"none\" stroke=\"#e2e8f0\" stroke-width=\"10\" stroke-linecap=\"round\"\/>\r\n            <path id=\"pth-gauge-arc-sidebar\" d=\"M10,60 A50,50 0 0,1 110,60\" fill=\"none\" stroke=\"#10b981\" stroke-width=\"10\" stroke-linecap=\"round\" stroke-dasharray=\"157\" stroke-dashoffset=\"157\"\/>\r\n            <text id=\"pth-gauge-pct-sidebar\" x=\"60\" y=\"58\" text-anchor=\"middle\" font-size=\"15\" font-weight=\"800\" fill=\"#047857\">0%<\/text>\r\n          <\/svg>\r\n          <div class=\"pth-gauge-label\">Input \u2192 Output Reduction<\/div>\r\n        <\/div>\r\n      <\/div>\r\n\r\n      <div class=\"pth-card\">\r\n        <h3 class=\"pth-card-title\" style=\"font-size:0.95rem;\">\ud83d\udd52 Recent Summaries<\/h3>\r\n        <div id=\"pth-history-list\" style=\"max-height:320px;overflow-y:auto;\">\r\n          <p style=\"font-size:0.8rem;color:#334155;font-style:italic;text-align:center;margin:20px 0;\">No history yet.<\/p>\r\n        <\/div>\r\n        <button class=\"pth-btn pth-btn-secondary pth-btn-sm\" id=\"pth-clear-history-btn\" style=\"width:100%;margin-top:10px;display:none;\" aria-label=\"Clear history\">\ud83d\uddd1\ufe0f Clear History<\/button>\r\n      <\/div>\r\n\r\n      <div class=\"pth-card\">\r\n        <h3 class=\"pth-card-title\" style=\"font-size:0.95rem;\">\ud83d\udfe6 Pro Use Cases<\/h3>\r\n        <ul style=\"font-size:0.82rem;line-height:1.7;padding-left:0;list-style:none;margin:0;color:#1e293b;font-weight:500;\">\r\n          <li style=\"margin-bottom:8px;\">\ud83d\udfe6 Legal document review<\/li>\r\n          <li style=\"margin-bottom:8px;\">\ud83d\udfe9 Executive briefings<\/li>\r\n          <li style=\"margin-bottom:8px;\">\ud83d\udfe8 Academic research<\/li>\r\n          <li style=\"margin-bottom:8px;\">\ud83d\udfea Content marketing<\/li>\r\n          <li>\ud83d\udfe5 News article digest<\/li>\r\n        <\/ul>\r\n      <\/div>\r\n\r\n    <\/div><!-- end sidebar -->\r\n\r\n  <\/div><!-- end layout -->\r\n<\/div><!-- end wrapper -->\r\n\r\n<script data-no-optimize=\"1\" data-no-minify=\"1\" data-cfasync=\"false\">\r\nif (typeof pdfjsLib !== 'undefined') {\r\n    pdfjsLib.GlobalWorkerOptions.workerSrc = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/3.11.174\/pdf.worker.min.js';\r\n}\r\n(function () {\r\n    \"use strict\";\r\n\r\n    window.pthSummarizerApp = {\r\n        initialized: false,\r\n        worker: null,\r\n        isModelReady: false,\r\n        currentLength: 'short',\r\n        currentFormat: 'paragraph',\r\n        currentTone: 'neutral',\r\n        currentRwMode: 'paraphrase',\r\n        selectedSections: [],\r\n        focusKeywords: [],\r\n        summaryHistory: [],\r\n        compareV1: '',\r\n        currentSummary: '',\r\n        currentSourceText: '',\r\n        UI: {},\r\n\r\n        LANG_MAP: [\r\n            {code:'en',name:'English',flag:'\ud83c\uddfa\ud83c\uddf8'},{code:'si',name:'Sinhala (\u0dc3\u0dd2\u0d82\u0dc4\u0dbd)',flag:'\ud83c\uddf1\ud83c\uddf0'},\r\n            {code:'ta',name:'Tamil (\u0ba4\u0bae\u0bbf\u0bb4\u0bcd)',flag:'\ud83c\uddee\ud83c\uddf3'},{code:'hi',name:'Hindi (\u0939\u093f\u0928\u094d\u0926\u0940)',flag:'\ud83c\uddee\ud83c\uddf3'},\r\n            {code:'es',name:'Espa\u00f1ol',flag:'\ud83c\uddea\ud83c\uddf8'},{code:'fr',name:'Fran\u00e7ais',flag:'\ud83c\uddeb\ud83c\uddf7'},\r\n            {code:'de',name:'Deutsch',flag:'\ud83c\udde9\ud83c\uddea'},{code:'pt',name:'Portugu\u00eas',flag:'\ud83c\uddf5\ud83c\uddf9'},\r\n            {code:'it',name:'Italiano',flag:'\ud83c\uddee\ud83c\uddf9'},{code:'ru',name:'Russian',flag:'\ud83c\uddf7\ud83c\uddfa'},\r\n            {code:'zh-CN',name:'Chinese (\u7b80\u4f53)',flag:'\ud83c\udde8\ud83c\uddf3'},{code:'ja',name:'Japanese (\u65e5\u672c\u8a9e)',flag:'\ud83c\uddef\ud83c\uddf5'},\r\n            {code:'ko',name:'Korean (\ud55c\uad6d\uc5b4)',flag:'\ud83c\uddf0\ud83c\uddf7'},{code:'ar',name:'Arabic (\u0627\u0644\u0639\u0631\u0628\u064a\u0629)',flag:'\ud83c\uddf8\ud83c\udde6'},\r\n            {code:'bn',name:'Bengali (\u09ac\u09be\u0982\u09b2\u09be)',flag:'\ud83c\udde7\ud83c\udde9'},{code:'id',name:'Bahasa Indonesia',flag:'\ud83c\uddee\ud83c\udde9'},\r\n            {code:'ms',name:'Bahasa Melayu',flag:'\ud83c\uddf2\ud83c\uddfe'},{code:'th',name:'Thai (\u0e20\u0e32\u0e29\u0e32\u0e44\u0e17\u0e22)',flag:'\ud83c\uddf9\ud83c\udded'},\r\n            {code:'vi',name:'Ti\u1ebfng Vi\u1ec7t',flag:'\ud83c\uddfb\ud83c\uddf3'},{code:'pl',name:'Polski',flag:'\ud83c\uddf5\ud83c\uddf1'}\r\n        ],\r\n\r\n        SECTION_KEYWORDS: {\r\n            'Key Points':['main','key','important','primary','significant','major','critical','essential','fundamental','central','highlight','notable','crucial','vital','core'],\r\n            'Action Items':['should','must','need','require','action','task','implement','complete','assign','follow','execute','perform','responsible','step','process','workflow','priority','todo','plan'],\r\n            'Dates & Deadlines':['date','deadline','schedule','year','month','week','day','quarter','by','until','when','time','period','due','expire','launch','release','since','before','after','2024','2025','2026','fiscal','annual'],\r\n            'People & Orgs':['said','according','team','company','organization','manager','director','president','ceo','founder','group','department','committee','board','staff','employee','official','spokesperson','researcher','author','expert'],\r\n            'Financial Data':['revenue','profit','cost','budget','million','billion','thousand','dollar','percent','%','growth','sales','income','expense','fund','investment','price','fee','rate','tax','loss','earning','capital','asset','equity','debt'],\r\n            'Risks & Issues':['risk','issue','problem','challenge','concern','threat','vulnerability','fail','error','danger','obstacle','limit','constraint','difficulty','complication','barrier','defect','gap','shortage','delay','crisis','incident'],\r\n            'Decisions Made':['decided','decision','approved','agreed','resolved','determined','concluded','chosen','selected','voted','confirmed','adopted','endorsed','ratified','finalized','established','passed','authorized','signed','ruled'],\r\n            'Recommendations':['recommend','suggest','propose','advise','should consider','best practice','improve','strategy','plan','approach','solution','initiative','direction','guideline','policy','framework','prioritize','focus on','invest'],\r\n            'Technical Details':['system','software','hardware','algorithm','protocol','api','database','server','network','code','version','platform','framework','library','interface','component','architecture','deployment','configuration','specification'],\r\n            'Background Context':['history','background','originally','founded','established','previously','context','overview','introduction','began','started','created','developed','evolved','traditionally','historically','formerly','since'],\r\n            'Statistics & Numbers':['percent','%','number','total','count','amount','ratio','rate','average','median','mean','sum','increase','decrease','more than','less than','compared','survey','study','data','statistic','figure','metric'],\r\n            'Conclusions':['conclusion','therefore','result','outcome','finding','summary','overall','ultimately','final','end','closing','takeaway','lesson','impact','effect','implication']\r\n        },\r\n\r\n        TONE_PREFIXES: {\r\n            neutral: '',\r\n            professional: 'Write in a formal, professional, executive-level tone: ',\r\n            simple: 'Explain in very simple language, like explaining to a 10-year-old: ',\r\n            academic: 'Write in an academic, scholarly tone with formal language: ',\r\n            social: 'Write in a casual, engaging, social media friendly tone under 280 chars: '\r\n        },\r\n\r\n        LENGTHS: { short:{max:50,min:20}, medium:{max:100,min:40}, long:{max:200,min:80} },\r\n\r\n        SAMPLE_TEXT: \"Historically, our company, PrimeTech Global, has relied on legacy servers established in 2018. According to our CEO, John Smith, and Lead Systems Manager, Sarah Connor, this outdated infrastructure has caused significant performance bottlenecks. In the third quarter, the company reported total revenue of $4.5 million, representing 15 percent growth compared to the previous year. However, server maintenance costs surged to $850,000 annually, negatively impacting profit margins. There is a severe risk of a complete database outage if we do not upgrade the system. The existing SQL database and legacy API framework are vulnerable to cyber attacks. The board has officially approved a comprehensive cloud migration project. The new platform will launch on October 15, 2026. All departments must complete their transition by December 1, 2026. The engineering team must implement new SSL security protocols immediately. Security experts recommend adopting a multi-cloud strategy as a best practice to improve network uptime. Ultimately, this transition will resolve hardware limitations, protect client data, and secure long-term success.\",\r\n\r\n        init: function () {\r\n            this.cacheDOM();\r\n\r\n            \/\/ --- BUG FIX: Move Modals and Toasts to document.body to prevent WP Theme CSS conflicts ---\r\n            if (this.UI.langOverlay) {\r\n                document.body.appendChild(this.UI.langOverlay);\r\n            }\r\n            if (this.UI.toast) {\r\n                document.body.appendChild(this.UI.toast);\r\n            }\r\n            \/\/ ----------------------------------------------------------------------------------\r\n\r\n            this.buildLangGrid();\r\n            this.attachEvents();\r\n        },\r\n\r\n        cacheDOM: function () {\r\n            var g = function (id) { return document.getElementById(id); };\r\n            this.UI = {\r\n                wrapper: g('pth-sum-wrapper'), layout: g('pth-sum-layout'),\r\n                fwBtn: g('pth-fw-btn'), darkBtn: g('pth-dark-btn'),\r\n                sampleBtn: g('pth-load-sample-btn'), tabBar: g('pth-tab-bar'),\r\n                nativeText: g('pth-native-text'), sourceText: g('pth-source-text'),\r\n                translateBtn: g('pth-translate-btn'), langTriggerBtn: g('pth-lang-trigger-btn'),\r\n                curLangLabel: g('pth-cur-lang-label'), srcLang: g('pth-src-lang'),\r\n                langOverlay: g('pth-lang-modal-overlay'), lmClose: g('pth-lm-close'),\r\n                lmSearch: g('pth-lm-search'), lmGrid: g('pth-lm-grid'),\r\n                pasteBtn: g('pth-paste-btn'), uploadBtn: g('pth-upload-btn'),\r\n                docFile: g('pth-doc-file'), cleanBtn: g('pth-clean-btn'),\r\n                urlInput: g('pth-url-input'), fetchUrlBtn: g('pth-fetch-url-btn'),\r\n                statWords: g('pth-stat-words'), statChars: g('pth-stat-chars'),\r\n                statSents: g('pth-stat-sents'), statRead: g('pth-stat-read'),\r\n                instantTldr: g('pth-instant-tldr'), instantTldrText: g('pth-instant-tldr-text'),\r\n                heatmapWrap: g('pth-heatmap-wrap'), heatmapContent: g('pth-heatmap-content'),\r\n                kwInput: g('pth-kw-input'), kwAddBtn: g('pth-kw-add-btn'),\r\n                kwClearBtn: g('pth-kw-clear-btn'), kwPills: g('pth-kw-pills'),\r\n                generateBtn: g('pth-generate-btn'),\r\n                progressArea: g('pth-progress-area'), progressStatus: g('pth-progress-status'),\r\n                firstTimeWarn: g('pth-first-time-warn'),\r\n                progBarWrap: g('pth-prog-bar-wrap'), progBar: g('pth-prog-bar'),\r\n                progDetails: g('pth-prog-details'),\r\n                presetChips: g('pth-preset-chips'), customSecInput: g('pth-custom-sec-input'),\r\n                addSecBtn: g('pth-add-sec-btn'), clearSecsBtn: g('pth-clear-secs-btn'),\r\n                activeSecsWrap: g('pth-active-secs-wrap'), activeSecsList: g('pth-active-secs-list'),\r\n                summaryEmpty: g('pth-summary-empty'), resultBox: g('pth-result-box'),\r\n                resultContent: g('pth-result-content'), resultMetrics: g('pth-result-metrics'),\r\n                resWords: g('pth-res-words'), compression: g('pth-compression'),\r\n                resReadtime: g('pth-res-readtime'),\r\n                resultModeBadge: g('pth-result-mode-badge'), resultToneBadge: g('pth-result-tone-badge'),\r\n                regenerateBtn: g('pth-regenerate-btn'), saveCompareBtn: g('pth-save-compare-btn'),\r\n                translateNativeBtn: g('pth-translate-native-btn'),\r\n                copyResultBtn: g('pth-copy-result-btn'), printBtn: g('pth-print-btn'),\r\n                reverseTransOut: g('pth-reverse-trans-out'),\r\n                gaugeArc: g('pth-gauge-arc'), gaugePct: g('pth-gauge-pct'),\r\n                gaugeArcSidebar: g('pth-gauge-arc-sidebar'), gaugePctSidebar: g('pth-gauge-pct-sidebar'),\r\n                compareWrap: g('pth-compare-wrap'), compareV1: g('pth-compare-v1'), compareV2: g('pth-compare-v2'),\r\n                analyzerEmpty: g('pth-analyzer-empty'), analyzerContent: g('pth-analyzer-content'),\r\n                anFlesch: g('pth-an-flesch'), anGrade: g('pth-an-grade'),\r\n                anAvglen: g('pth-an-avglen'), anUnique: g('pth-an-unique'), anVocab: g('pth-an-vocab'),\r\n                kwTbody: g('pth-kw-tbody'), dupSents: g('pth-dup-sents'), sentDist: g('pth-sent-dist'),\r\n                rwLoadBtn: g('pth-rw-load-btn'), rwLoadSourceBtn: g('pth-rw-load-source-btn'),\r\n                rwInput: g('pth-rw-input'), rwOutput: g('pth-rw-output'),\r\n                rwGenerateBtn: g('pth-rw-generate-btn'), rwCopyBtn: g('pth-rw-copy-btn'),\r\n                rwProgWrap: g('pth-rw-prog-wrap'), rwProgBar: g('pth-rw-prog-bar'),\r\n                diffBadge: g('pth-diff-badge'),\r\n                expTxt: g('pth-exp-txt'), expPdf: g('pth-exp-pdf'), expMd: g('pth-exp-md'),\r\n                expJson: g('pth-exp-json'), expSrt: g('pth-exp-srt'), expEmail: g('pth-exp-email'),\r\n                copyPlain: g('pth-copy-plain'), copyMarkdown: g('pth-copy-markdown'),\r\n                copyEmail: g('pth-copy-email'), copySocial: g('pth-copy-social'),\r\n                historyList: g('pth-history-list'), clearHistoryBtn: g('pth-clear-history-btn'),\r\n                toast: g('pth-sum-toast')\r\n            };\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 UTILS \u2500\u2500\u2500 *\/\r\n        showToast: function (msg, type) {\r\n            if (!this.UI.toast) return;\r\n            var icons = { success: '\u2705', error: '\u274c', info: '\u2139\ufe0f' };\r\n            this.UI.toast.innerHTML = (icons[type] || '\u2705') + ' ' + msg;\r\n            this.UI.toast.classList.add('show');\r\n            clearTimeout(this._toastTimer);\r\n            var self = this;\r\n            this._toastTimer = setTimeout(function () { self.UI.toast.classList.remove('show'); }, 3500);\r\n        },\r\n        bindEv: function (el, ev, fn) { if (el) el.addEventListener(ev, fn); },\r\n        getText: function () { return (this.UI.sourceText ? this.UI.sourceText.value.trim() : '') || (this.UI.nativeText ? this.UI.nativeText.value.trim() : ''); },\r\n        countWords: function (t) { return t.trim() ? t.trim().split(\/\\s+\/).filter(Boolean).length : 0; },\r\n        getSentences: function (t) { return t.match(\/[^.!?]+[.!?]*\/g) || [t]; },\r\n        countSyllables: function (w) { w = w.toLowerCase().replace(\/[^a-z]\/g, ''); var c = w.match(\/[aeiouy]+\/g); return c ? c.length : 1; },\r\n\r\n        \/* \u2500\u2500\u2500 TABS \u2500\u2500\u2500 *\/\r\n        switchTab: function (tab) {\r\n            if (!this.UI.tabBar) return;\r\n            this.UI.tabBar.querySelectorAll('.pth-tab-btn').forEach(function (b) {\r\n                var active = b.getAttribute('data-tab') === tab;\r\n                b.classList.toggle('active', active);\r\n                b.setAttribute('aria-selected', active ? 'true' : 'false');\r\n            });\r\n            ['input', 'sections', 'summary', 'analyzer', 'rewriter', 'export'].forEach(function (p) {\r\n                var el = document.getElementById('pth-panel-' + p);\r\n                if (el) el.classList.toggle('active', p === tab);\r\n            });\r\n            if (tab === 'analyzer') this.runAnalyzer();\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 STATS & HEATMAP \u2500\u2500\u2500 *\/\r\n        updateStats: function () {\r\n            var t = this.getText();\r\n            if (!t) { this.UI.instantTldr.style.display = 'none'; this.UI.heatmapWrap.style.display = 'none'; return; }\r\n            var w = this.countWords(t), ch = t.length;\r\n            var sents = this.getSentences(t).filter(function (s) { return s.trim().length > 0; });\r\n            var rm = Math.ceil(w \/ 200);\r\n            if (this.UI.statWords) this.UI.statWords.textContent = w.toLocaleString();\r\n            if (this.UI.statChars) this.UI.statChars.textContent = ch.toLocaleString();\r\n            if (this.UI.statSents) this.UI.statSents.textContent = sents.length;\r\n            if (this.UI.statRead) this.UI.statRead.textContent = rm + 'm';\r\n            if (this.UI.generateBtn) this.UI.generateBtn.disabled = w < 20;\r\n            this.showInstantTldr(t, sents);\r\n            this.renderHeatmap(t, sents);\r\n        },\r\n        showInstantTldr: function (t, sents) {\r\n            if (!sents || sents.length < 2) return;\r\n            var first = sents[0].trim(), last = sents[sents.length - 1].trim();\r\n            var tldr = first + (last !== first ? ' ... ' + last : '');\r\n            if (this.UI.instantTldrText) this.UI.instantTldrText.textContent = tldr;\r\n            if (this.UI.instantTldr) this.UI.instantTldr.style.display = 'block';\r\n        },\r\n        renderHeatmap: function (t, sents) {\r\n            if (!this.UI.heatmapContent || !sents || sents.length < 3) { if (this.UI.heatmapWrap) this.UI.heatmapWrap.style.display = 'none'; return; }\r\n            var self = this;\r\n            var sw = { the: 1, a: 1, an: 1, and: 1, or: 1, but: 1, in: 1, on: 1, to: 1, is: 1, are: 1, it: 1, this: 1, of: 1, for: 1, as: 1, by: 1, was: 1, be: 1, at: 1, with: 1, from: 1, that: 1, have: 1, not: 1, been: 1, they: 1, their: 1, we: 1, he: 1, she: 1, you: 1, i: 1, if: 1, our: 1, has: 1 };\r\n            var tf = {};\r\n            t.toLowerCase().split(\/\\s+\/).forEach(function (w) { var c = w.replace(\/[^a-z]\/g, ''); if (c.length > 3 && !sw[c]) tf[c] = (tf[c] || 0) + 1; });\r\n            var kws = self.focusKeywords.map(function (k) { return k.toLowerCase(); });\r\n            var scores = sents.map(function (s) {\r\n                var ws = s.toLowerCase().split(\/\\s+\/);\r\n                var sc = ws.reduce(function (a, w) { var c = w.replace(\/[^a-z]\/g, ''); return a + (tf[c] || 0); }, 0);\r\n                if (kws.length) { kws.forEach(function (k) { if (s.toLowerCase().indexOf(k) >= 0) sc += 15; }); }\r\n                return sc;\r\n            });\r\n            var maxSc = Math.max.apply(null, scores) || 1;\r\n            var html = '';\r\n            sents.forEach(function (s, i) {\r\n                var ratio = scores[i] \/ maxSc;\r\n                var cls = ratio > 0.65 ? 'pth-ht-high' : ratio > 0.35 ? 'pth-ht-med' : '';\r\n                html += '<span class=\"pth-heatmap-sent ' + cls + '\">' + s.replace(\/<\/g, '<').replace(\/>\/g, '>') + ' <\/span>';\r\n            });\r\n            this.UI.heatmapContent.innerHTML = html;\r\n            if (this.UI.heatmapWrap) this.UI.heatmapWrap.style.display = 'block';\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 CLEAN TEXT \u2500\u2500\u2500 *\/\r\n        cleanText: function () {\r\n            var ta = this.UI.nativeText;\r\n            if (!ta || !ta.value.trim()) { this.showToast('No text to clean!', 'error'); return; }\r\n            var t = ta.value;\r\n            t = t.replace(\/<[^>]+>\/g, ' ');\r\n            t = t.replace(\/&[a-z]+;\/gi, ' ');\r\n            t = t.replace(\/\\u201c|\\u201d\/g, '\"').replace(\/\\u2018|\\u2019\/g, \"'\");\r\n            t = t.replace(\/\\s{2,}\/g, ' ').replace(\/\\n{3,}\/g, '\\n\\n').trim();\r\n            ta.value = t;\r\n            if (this.UI.sourceText && !this.UI.sourceText.value.trim()) this.UI.sourceText.value = t;\r\n            this.updateStats();\r\n            this.showToast('Text cleaned!');\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 LANG GRID \u2500\u2500\u2500 *\/\r\n        buildLangGrid: function () {\r\n            if (!this.UI.lmGrid) return;\r\n            var self = this;\r\n            this.UI.lmGrid.innerHTML = '';\r\n            this.LANG_MAP.forEach(function (l) {\r\n                var b = document.createElement('button');\r\n                b.className = 'pth-lm-btn' + (l.code === 'en' ? ' active' : '');\r\n                b.setAttribute('data-code', l.code);\r\n                b.setAttribute('data-name', l.name);\r\n                b.innerHTML = '<span style=\"font-size:1.2rem;\">' + l.flag + '<\/span> ' + l.name;\r\n                b.addEventListener('click', function () {\r\n                    self.UI.lmGrid.querySelectorAll('.pth-lm-btn').forEach(function (x) { x.classList.remove('active'); });\r\n                    b.classList.add('active');\r\n                    if (self.UI.srcLang) self.UI.srcLang.value = l.code;\r\n                    if (self.UI.curLangLabel) self.UI.curLangLabel.textContent = l.name.split(' ')[0];\r\n                    if (self.UI.langOverlay) self.UI.langOverlay.classList.remove('active');\r\n                });\r\n                self.UI.lmGrid.appendChild(b);\r\n            });\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 TRANSLATE \u2500\u2500\u2500 *\/\r\n        chunkText: function (text, limit) {\r\n            var chunks = [], sents = text.match(\/[^.!?\\n]+[.!?\\n]*\/g) || [text], cur = '';\r\n            sents.forEach(function (s) {\r\n                if ((cur + s).length > limit && cur.length > 0) { chunks.push(cur.trim()); cur = ''; }\r\n                cur += s + ' ';\r\n            });\r\n            if (cur.trim()) chunks.push(cur.trim());\r\n            return chunks;\r\n        },\r\n        translateToEnglish: async function () {\r\n            var src = this.UI.nativeText ? this.UI.nativeText.value.trim() : '';\r\n            if (!src) { this.showToast('No source text!', 'error'); return; }\r\n            var lang = this.UI.srcLang ? this.UI.srcLang.value : 'en';\r\n            if (lang === 'en') { if (this.UI.sourceText) this.UI.sourceText.value = src; this.updateStats(); return; }\r\n            this.showToast('Translating...', 'info');\r\n            if (this.UI.translateBtn) this.UI.translateBtn.textContent = '\u23f3';\r\n            var chunks = this.chunkText(src, 4500), results = [], self = this;\r\n            try {\r\n                for (var i = 0; i < chunks.length; i++) {\r\n                    var r = await fetch('https:\/\/translate.googleapis.com\/translate_a\/single?client=gtx&sl=' + lang + '&tl=en&dt=t', { method: 'POST', headers: { 'Content-Type': 'application\/x-www-form-urlencoded' }, body: 'q=' + encodeURIComponent(chunks[i]) });\r\n                    var d = await r.json();\r\n                    results.push(d[0].map(function (p) { return p[0]; }).join(''));\r\n                }\r\n                if (self.UI.sourceText) self.UI.sourceText.value = results.join('\\n');\r\n                self.updateStats();\r\n                self.showToast('Translated!');\r\n            } catch (e) { self.showToast('Translation failed', 'error'); }\r\n            finally { if (self.UI.translateBtn) self.UI.translateBtn.textContent = '\u27a1\ufe0f'; }\r\n        },\r\n        translateNative: async function () {\r\n            var summary = this.currentSummary;\r\n            var lang = this.UI.srcLang ? this.UI.srcLang.value : 'en';\r\n            if (!summary) { this.showToast('No summary to translate!', 'error'); return; }\r\n            if (lang === 'en') { this.showToast('Source is already English.', 'info'); return; }\r\n            this.showToast('Translating summary...', 'info');\r\n            var self = this;\r\n            try {\r\n                var r = await fetch('https:\/\/translate.googleapis.com\/translate_a\/single?client=gtx&sl=en&tl=' + lang + '&dt=t', { method: 'POST', headers: { 'Content-Type': 'application\/x-www-form-urlencoded' }, body: 'q=' + encodeURIComponent(summary) });\r\n                var d = await r.json();\r\n                var translated = d[0].map(function (p) { return p[0]; }).join('');\r\n                if (self.UI.reverseTransOut) { self.UI.reverseTransOut.textContent = translated; self.UI.reverseTransOut.style.display = 'block'; }\r\n                self.showToast('Translated!');\r\n            } catch (e) { self.showToast('Translation failed', 'error'); }\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 FETCH URL \u2500\u2500\u2500 *\/\r\n        fetchUrl: async function () {\r\n            var url = this.UI.urlInput ? this.UI.urlInput.value.trim() : '';\r\n            if (!url || !url.startsWith('http')) { this.showToast('Enter a valid URL!', 'error'); return; }\r\n            this.showToast('Fetching...', 'info');\r\n            try {\r\n                var r = await fetch('https:\/\/api.allorigins.win\/get?url=' + encodeURIComponent(url));\r\n                var d = await r.json();\r\n                var tmp = document.createElement('div');\r\n                tmp.innerHTML = d.contents;\r\n                ['script', 'style', 'nav', 'header', 'footer', 'aside'].forEach(function (t) { tmp.querySelectorAll(t).forEach(function (el) { el.remove(); }); });\r\n                var text = (tmp.textContent || tmp.innerText || '').replace(\/\\s{2,}\/g, ' ').trim().substring(0, 8000);\r\n                if (this.UI.nativeText) this.UI.nativeText.value = text;\r\n                if (this.UI.sourceText) this.UI.sourceText.value = text;\r\n                this.updateStats();\r\n                this.showToast('Content fetched!');\r\n            } catch (e) { this.showToast('Fetch failed \u2014 try copying text manually.', 'error'); }\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 FOCUS KEYWORDS \u2500\u2500\u2500 *\/\r\n        addKeyword: function () {\r\n            var v = this.UI.kwInput ? this.UI.kwInput.value.trim() : '';\r\n            if (!v || this.focusKeywords.indexOf(v) >= 0) return;\r\n            this.focusKeywords.push(v);\r\n            if (this.UI.kwInput) this.UI.kwInput.value = '';\r\n            this.renderKwPills();\r\n            if (this.getText()) this.renderHeatmap(this.getText(), this.getSentences(this.getText()));\r\n        },\r\n        renderKwPills: function () {\r\n            if (!this.UI.kwPills) return;\r\n            var self = this;\r\n            this.UI.kwPills.innerHTML = '';\r\n            this.focusKeywords.forEach(function (kw) {\r\n                var span = document.createElement('span');\r\n                span.className = 'pth-kw-pill';\r\n                span.innerHTML = kw + '<button class=\"pth-kw-pill-remove\" aria-label=\"Remove keyword ' + kw + '\">\u00d7<\/button>';\r\n                span.querySelector('.pth-kw-pill-remove').addEventListener('click', function () {\r\n                    self.focusKeywords = self.focusKeywords.filter(function (k) { return k !== kw; });\r\n                    self.renderKwPills();\r\n                });\r\n                self.UI.kwPills.appendChild(span);\r\n            });\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 SECTIONS \u2500\u2500\u2500 *\/\r\n        addSection: function (name) {\r\n            if (!name || this.selectedSections.indexOf(name) >= 0) return;\r\n            this.selectedSections.push(name);\r\n            this.renderActiveSections();\r\n        },\r\n        removeSection: function (name) {\r\n            this.selectedSections = this.selectedSections.filter(function (s) { return s !== name; });\r\n            this.renderActiveSections();\r\n            if (this.UI.presetChips) {\r\n                var chip = this.UI.presetChips.querySelector('[data-section=\"' + name + '\"]');\r\n                if (chip) { chip.classList.remove('active'); chip.setAttribute('aria-pressed', 'false'); }\r\n            }\r\n        },\r\n        renderActiveSections: function () {\r\n            var wrap = this.UI.activeSecsWrap, list = this.UI.activeSecsList;\r\n            if (!wrap || !list) return;\r\n            wrap.style.display = this.selectedSections.length ? 'block' : 'none';\r\n            var self = this;\r\n            list.innerHTML = '';\r\n            this.selectedSections.forEach(function (s) {\r\n                var tag = document.createElement('span');\r\n                tag.className = 'pth-active-tag';\r\n                tag.innerHTML = s + '<button class=\"pth-remove-tag-btn\" data-sec=\"' + s + '\" aria-label=\"Remove section ' + s + '\">\u00d7<\/button>';\r\n                tag.querySelector('.pth-remove-tag-btn').addEventListener('click', function () { self.removeSection(s); });\r\n                list.appendChild(tag);\r\n            });\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 SECTION EXTRACTOR \u2500\u2500\u2500 *\/\r\n        extractSection: function (text, sectionName) {\r\n            var sents = text.split(\/(?<=[.!?])\\s+\/).filter(function (s) { return s.trim().length > 20; });\r\n            var kws = this.SECTION_KEYWORDS[sectionName] || sectionName.toLowerCase().replace(\/[^a-z\\s]\/g, '').split(\/\\s+\/).filter(function (w) { return w.length > 2; });\r\n            var kw_set = {}; kws.forEach(function (k) { kw_set[k] = 1; });\r\n            var self = this;\r\n            var scored = sents.map(function (s) {\r\n                var words = s.toLowerCase().split(\/\\s+\/);\r\n                var score = words.reduce(function (a, w) { return a + (kw_set[w.replace(\/[^a-z]\/g, '')] ? 1 : 0); }, 0);\r\n                if (self.focusKeywords.length) { self.focusKeywords.forEach(function (kw) { if (s.toLowerCase().indexOf(kw.toLowerCase()) >= 0) score += 3; }); }\r\n                return { text: s.trim(), score: score };\r\n            }).filter(function (s) { return s.score > 0 && s.text.split(\/\\s+\/).length > 4; })\r\n              .sort(function (a, b) { return b.score - a.score; })\r\n              .slice(0, 4)\r\n              .map(function (s) { return s.text; });\r\n            return scored.join(' ') || 'No specific content found for this section.';\r\n        },\r\n        generateSectioned: function (text) {\r\n            var self = this;\r\n            var html = '';\r\n            this.selectedSections.forEach(function (sec) {\r\n                var content = self.extractSection(text, sec);\r\n                html += '<div class=\"pth-section-result\"><div class=\"pth-section-result-title\">' + sec + '<\/div><div class=\"pth-section-result-content\">' + content + '<\/div><\/div>';\r\n            });\r\n            return html;\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 GAUGE \u2500\u2500\u2500 *\/\r\n        updateGauge: function (pct) {\r\n            var offset = 157 - (pct \/ 100) * 157;\r\n            var color = pct > 70 ? '#10b981' : pct > 40 ? '#f59e0b' : '#3b82f6';\r\n            [this.UI.gaugeArc, this.UI.gaugeArcSidebar].forEach(function (arc) { if (arc) { arc.style.strokeDashoffset = offset; arc.style.stroke = color; } });\r\n            [this.UI.gaugePct, this.UI.gaugePctSidebar].forEach(function (el) { if (el) { el.textContent = pct + '%'; el.style.fill = color; } });\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 WORKER SETUP \u2500\u2500\u2500 *\/\r\n        setupWorker: function () {\r\n            if (this.worker) return;\r\n            var self = this;\r\n            var wLines = [\r\n                \"import { pipeline, env } from 'https:\/\/cdn.jsdelivr.net\/npm\/@xenova\/transformers@2.16.0';\",\r\n                \"env.allowLocalModels = false;\",\r\n                \"var pipe = null;\",\r\n                \"self.onmessage = async function(e) {\",\r\n                \"  if (e.data.type === 'load') {\",\r\n                \"    try {\",\r\n                \"      pipe = await pipeline('summarization', 'Xenova\/distilbart-cnn-12-6', {progress_callback: function(d){ self.postMessage({type:'progress',data:JSON.parse(JSON.stringify(d))}); }});\",\r\n                \"      self.postMessage({type:'loaded'});\",\r\n                \"    } catch(err) { self.postMessage({type:'error',error:err.message}); }\",\r\n                \"  } else if (e.data.type === 'summarize') {\",\r\n                \"    try {\",\r\n                \"      var text = e.data.prefix + e.data.text;\",\r\n                \"      var out = await pipe(text, {max_length: e.data.max_length, min_length: e.data.min_length, do_sample: false});\",\r\n                \"      self.postMessage({type:'complete',result:out[0].summary_text});\",\r\n                \"    } catch(err) { self.postMessage({type:'error',error:err.message}); }\",\r\n                \"  }\"\r\n                , \"};\"\r\n            ];\r\n            var blob = new Blob([wLines.join('\\n')], { type: 'application\/javascript' });\r\n            this.worker = new Worker(URL.createObjectURL(blob), { type: 'module' });\r\n            this.worker.onmessage = function (e) {\r\n                var t = e.data.type;\r\n                if (t === 'progress') {\r\n                    if (e.data.data && e.data.data.status === 'downloading') {\r\n                        var pct = e.data.data.total ? Math.round((e.data.data.loaded \/ e.data.data.total) * 100) : 50;\r\n                        if (self.UI.progBar) self.UI.progBar.style.width = pct + '%';\r\n                        if (self.UI.progDetails) self.UI.progDetails.textContent = 'Downloading AI model... ' + pct + '%';\r\n                        if (self.UI.progBarWrap) self.UI.progBarWrap.style.display = 'block';\r\n                    }\r\n                } else if (t === 'loaded') {\r\n                    self.isModelReady = true;\r\n                    if (self.UI.firstTimeWarn) self.UI.firstTimeWarn.style.display = 'none';\r\n                    self.doSummarize();\r\n                } else if (t === 'complete') {\r\n                    self.finishSummary(e.data.result);\r\n                } else if (t === 'error') {\r\n                    self.showToast('AI error: ' + e.data.error, 'error');\r\n                    self.resetProgress();\r\n                }\r\n            };\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 GENERATE \u2500\u2500\u2500 *\/\r\n        generate: function () {\r\n            var text = this.getText();\r\n            if (!text || this.countWords(text) < 20) { this.showToast('Need at least 20 words!', 'error'); return; }\r\n            this.currentSourceText = text;\r\n            if (this.selectedSections.length > 0) {\r\n                var html = this.generateSectioned(text);\r\n                this.finishSummary(html, true);\r\n                return;\r\n            }\r\n            if (this.UI.generateBtn) { this.UI.generateBtn.disabled = true; this.UI.generateBtn.textContent = '\u23f3 Processing...'; }\r\n            if (this.UI.progressArea) this.UI.progressArea.style.display = 'block';\r\n            if (this.UI.progressStatus) this.UI.progressStatus.innerHTML = '<span class=\"pth-spinner\"><\/span> Loading AI Engine...';\r\n            if (!this.isModelReady) { if (this.UI.firstTimeWarn) this.UI.firstTimeWarn.style.display = 'block'; }\r\n            this.setupWorker();\r\n            if (this.isModelReady) this.doSummarize();\r\n            else this.worker.postMessage({ type: 'load' });\r\n        },\r\n        doSummarize: function () {\r\n            var text = this.currentSourceText;\r\n            if (this.focusKeywords.length > 0) {\r\n                var sents = this.getSentences(text), kws = this.focusKeywords, self = this;\r\n                var priority = sents.filter(function (s) { return kws.some(function (k) { return s.toLowerCase().indexOf(k.toLowerCase()) >= 0; }); });\r\n                var rest = sents.filter(function (s) { return !priority.includes(s); });\r\n                text = priority.concat(rest).join(' ');\r\n            }\r\n            var len = this.LENGTHS[this.currentLength];\r\n            var prefix = this.TONE_PREFIXES[this.currentTone] || '';\r\n            if (this.currentFormat === 'bullet') prefix = 'Summarize as bullet points: ' + prefix;\r\n            if (this.UI.progressStatus) this.UI.progressStatus.innerHTML = '<span class=\"pth-spinner\"><\/span> Generating summary...';\r\n            this.worker.postMessage({ type: 'summarize', text: text.substring(0, 4000), prefix: prefix, max_length: len.max, min_length: len.min });\r\n        },\r\n        finishSummary: function (result, isSectioned) {\r\n            this.currentSummary = result;\r\n            var srcWords = this.countWords(this.currentSourceText);\r\n            var resWords = this.countWords(result.replace(\/<[^>]+>\/g, ''));\r\n            var compression = srcWords > 0 ? Math.round((1 - resWords \/ srcWords) * 100) : 0;\r\n            if (this.UI.resWords) this.UI.resWords.textContent = resWords;\r\n            if (this.UI.compression) this.UI.compression.textContent = compression + '%';\r\n            if (this.UI.resReadtime) this.UI.resReadtime.textContent = Math.ceil(resWords \/ 200) + ' min';\r\n            this.updateGauge(compression);\r\n            if (isSectioned) {\r\n                if (this.UI.resultContent) this.UI.resultContent.innerHTML = result;\r\n                if (this.UI.resultModeBadge) this.UI.resultModeBadge.style.display = 'inline-flex';\r\n            } else {\r\n                var formatted = this.currentFormat === 'bullet'\r\n                    ? result.split(\/\\.\\s+\/).filter(function (s) { return s.trim().length > 3; }).map(function (s) { return '<li style=\"margin-bottom:8px;\">' + s.trim() + (s.endsWith('.') ? '' : '.') + '<\/li>'; }).join('')\r\n                    : result;\r\n                if (this.UI.resultContent) {\r\n                    if (this.currentFormat === 'bullet') {\r\n                        this.UI.resultContent.innerHTML = '<ul style=\"padding-left:20px;margin:0;\">' + formatted + '<\/ul>';\r\n                    } else {\r\n                        this.UI.resultContent.textContent = formatted;\r\n                    }\r\n                }\r\n                if (this.UI.resultModeBadge) this.UI.resultModeBadge.style.display = 'none';\r\n            }\r\n            if (this.UI.resultToneBadge && this.currentTone !== 'neutral') {\r\n                var toneLabels = { professional: '\ud83d\udcbc Professional', simple: '\ud83e\uddd2 Simple', academic: '\ud83c\udf93 Academic', social: '\ud83d\udcf1 Social' };\r\n                this.UI.resultToneBadge.textContent = toneLabels[this.currentTone] || '';\r\n                this.UI.resultToneBadge.style.display = 'inline-flex';\r\n            } else if (this.UI.resultToneBadge) { this.UI.resultToneBadge.style.display = 'none'; }\r\n            if (this.UI.resultBox) this.UI.resultBox.style.display = 'block';\r\n            if (this.UI.summaryEmpty) this.UI.summaryEmpty.style.display = 'none';\r\n            this.enableExports();\r\n            this.addToHistory(result.replace(\/<[^>]+>\/g, '').substring(0, 120));\r\n            this.resetProgress();\r\n            this.switchTab('summary');\r\n            this.showToast('Summary ready!');\r\n        },\r\n        resetProgress: function () {\r\n            if (this.UI.progressArea) this.UI.progressArea.style.display = 'none';\r\n            if (this.UI.generateBtn) { this.UI.generateBtn.disabled = false; this.UI.generateBtn.textContent = '\u2728 Generate AI Summary (100% Offline)'; }\r\n            if (this.UI.progBar) this.UI.progBar.style.width = '0%';\r\n            if (this.UI.progBarWrap) this.UI.progBarWrap.style.display = 'none';\r\n        },\r\n        enableExports: function () {\r\n            var cards = ['pth-exp-txt', 'pth-exp-pdf', 'pth-exp-md', 'pth-exp-json', 'pth-exp-srt', 'pth-exp-email'];\r\n            cards.forEach(function (id) { var el = document.getElementById(id); if (el) el.classList.remove('disabled'); });\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 ANALYZER \u2500\u2500\u2500 *\/\r\n        runAnalyzer: function () {\r\n            var text = this.getText();\r\n            if (!text || this.countWords(text) < 10) { if (this.UI.analyzerEmpty) this.UI.analyzerEmpty.style.display = 'block'; if (this.UI.analyzerContent) this.UI.analyzerContent.style.display = 'none'; return; }\r\n            if (this.UI.analyzerEmpty) this.UI.analyzerEmpty.style.display = 'none';\r\n            if (this.UI.analyzerContent) this.UI.analyzerContent.style.display = 'block';\r\n            var self = this;\r\n            var sents = this.getSentences(text).filter(function (s) { return s.trim().length > 5; });\r\n            var words = text.toLowerCase().split(\/\\s+\/).filter(function (w) { return w.replace(\/[^a-z]\/g, '').length > 0; });\r\n            var totalWords = words.length;\r\n            var totalSyls = words.reduce(function (a, w) { return a + self.countSyllables(w); }, 0);\r\n            var avgSentLen = sents.length ? (totalWords \/ sents.length).toFixed(1) : 0;\r\n            var flesch = Math.round(206.835 - 1.015 * (totalWords \/ (sents.length || 1)) - 84.6 * (totalSyls \/ (totalWords || 1)));\r\n            flesch = Math.max(0, Math.min(100, flesch));\r\n            var grade = flesch >= 70 ? 'Easy' : flesch >= 50 ? 'Standard' : flesch >= 30 ? 'Difficult' : 'Expert';\r\n            var uniqueSet = {}; words.forEach(function (w) { var c = w.replace(\/[^a-z]\/g, ''); if (c) uniqueSet[c] = 1; });\r\n            var uniqueCount = Object.keys(uniqueSet).length;\r\n            var vocabRichness = totalWords ? Math.round((uniqueCount \/ totalWords) * 100) : 0;\r\n            if (this.UI.anFlesch) this.UI.anFlesch.textContent = flesch;\r\n            if (this.UI.anGrade) this.UI.anGrade.textContent = grade;\r\n            if (this.UI.anAvglen) this.UI.anAvglen.textContent = avgSentLen;\r\n            if (this.UI.anUnique) this.UI.anUnique.textContent = uniqueCount.toLocaleString();\r\n            if (this.UI.anVocab) this.UI.anVocab.textContent = vocabRichness + '%';\r\n            \/* Keyword Table *\/\r\n            var sw = { the: 1, a: 1, an: 1, and: 1, or: 1, but: 1, in: 1, on: 1, to: 1, is: 1, are: 1, it: 1, this: 1, that: 1, of: 1, for: 1, as: 1, by: 1, was: 1, be: 1, at: 1, with: 1, from: 1, have: 1, not: 1, been: 1, they: 1, their: 1, we: 1, he: 1, she: 1, you: 1, i: 1, if: 1, our: 1, has: 1, which: 1, will: 1, all: 1, can: 1, one: 1, its: 1 };\r\n            var freq = {};\r\n            words.forEach(function (w) { var c = w.replace(\/[^a-z]\/g, ''); if (c.length > 2 && !sw[c]) freq[c] = (freq[c] || 0) + 1; });\r\n            var top = Object.keys(freq).map(function (k) { return [k, freq[k]]; }).sort(function (a, b) { return b[1] - a[1]; }).slice(0, 12);\r\n            var maxFreq = top.length ? top[0][1] : 1;\r\n            if (this.UI.kwTbody) {\r\n                this.UI.kwTbody.innerHTML = '';\r\n                top.forEach(function (pair, idx) {\r\n                    var density = ((pair[1] \/ totalWords) * 100).toFixed(2);\r\n                    var barWidth = Math.round((pair[1] \/ maxFreq) * 100);\r\n                    var tr = document.createElement('tr'); tr.className = 'pth-kw-row';\r\n                    tr.innerHTML = '<td style=\"color:#334155;font-size:0.78rem;\">' + (idx + 1) + '<\/td><td style=\"font-weight:700;color:#0f172a;\">' + pair[0] + '<\/td><td style=\"color:#1d4ed8;font-weight:700;\">' + pair[1] + '<\/td><td style=\"color:#334155;\">' + density + '%<\/td><td class=\"pth-kw-bar-cell\"><div class=\"pth-kw-bar-bg\"><div class=\"pth-kw-bar-fill\" style=\"width:' + barWidth + '%;\"><\/div><\/div><\/td>';\r\n                    self.UI.kwTbody.appendChild(tr);\r\n                });\r\n            }\r\n            \/* Duplicate Sentences *\/\r\n            if (this.UI.dupSents) {\r\n                this.UI.dupSents.innerHTML = '';\r\n                var seen = {}, dups = [];\r\n                sents.forEach(function (s) { var k = s.toLowerCase().trim().substring(0, 60); if (seen[k]) dups.push(s.trim()); else seen[k] = 1; });\r\n                if (!dups.length) {\r\n                    this.UI.dupSents.innerHTML = '<p style=\"font-size:0.82rem;color:#047857;font-weight:600;\">\u2705 No duplicate sentences detected.<\/p>';\r\n                } else {\r\n                    dups.slice(0, 5).forEach(function (d) {\r\n                        var div = document.createElement('div'); div.className = 'pth-dup-sent';\r\n                        div.textContent = '\u26a0\ufe0f ' + d.substring(0, 120) + (d.length > 120 ? '...' : '');\r\n                        self.UI.dupSents.appendChild(div);\r\n                    });\r\n                }\r\n            }\r\n            \/* Sentence Length Distribution *\/\r\n            if (this.UI.sentDist) {\r\n                this.UI.sentDist.innerHTML = '';\r\n                var maxLen = Math.max.apply(null, sents.map(function (s) { return s.split(\/\\s+\/).length; })) || 1;\r\n                sents.slice(0, 40).forEach(function (s, i) {\r\n                    var wc = s.split(\/\\s+\/).length;\r\n                    var h = Math.max(4, Math.round((wc \/ maxLen) * 70));\r\n                    var color = wc > 30 ? '#dc2626' : wc > 15 ? '#f59e0b' : '#10b981';\r\n                    var bar = document.createElement('div');\r\n                    bar.style.cssText = 'width:10px;height:' + h + 'px;background:' + color + ';border-radius:2px 2px 0 0;cursor:help;flex-shrink:0;';\r\n                    bar.title = 'Sentence ' + (i + 1) + ': ' + wc + ' words';\r\n                    self.UI.sentDist.appendChild(bar);\r\n                });\r\n            }\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 REWRITER \u2500\u2500\u2500 *\/\r\n        runRewrite: function () {\r\n            var text = this.UI.rwInput ? this.UI.rwInput.value.trim() : '';\r\n            if (!text) { this.showToast('Load or paste text to rewrite!', 'error'); return; }\r\n            var modePrefixes = {\r\n                paraphrase: 'Rewrite the following text differently while keeping the same meaning: ',\r\n                simplify: 'Rewrite the following in very simple, easy-to-understand language: ',\r\n                formalize: 'Rewrite the following in formal, professional language: ',\r\n                shorten: 'Summarize and shorten the following text significantly: ',\r\n                expand: 'Expand and elaborate on the following text with more detail: '\r\n            };\r\n            var prefix = modePrefixes[this.currentRwMode] || '';\r\n            if (this.UI.rwProgWrap) this.UI.rwProgWrap.style.display = 'block';\r\n            if (this.UI.rwGenerateBtn) { this.UI.rwGenerateBtn.disabled = true; this.UI.rwGenerateBtn.textContent = '\u23f3 Rewriting...'; }\r\n            var self = this;\r\n            this.setupWorker();\r\n            var doRewrite = function () {\r\n                var len = self.LENGTHS['medium'];\r\n                self.worker.postMessage({ type: 'summarize', text: text.substring(0, 3500), prefix: prefix, max_length: len.max, min_length: len.min });\r\n                var origHandler = self.worker.onmessage;\r\n                self.worker.onmessage = function (e) {\r\n                    if (e.data.type === 'complete') {\r\n                        var result = e.data.result;\r\n                        self.renderRewriteWithDiff(text, result);\r\n                        if (self.UI.rwProgWrap) self.UI.rwProgWrap.style.display = 'none';\r\n                        if (self.UI.rwGenerateBtn) { self.UI.rwGenerateBtn.disabled = false; self.UI.rwGenerateBtn.textContent = '\u270d\ufe0f Rewrite (Offline AI)'; }\r\n                        self.showToast('Rewrite complete!');\r\n                        self.worker.onmessage = origHandler;\r\n                    } else if (e.data.type === 'error') {\r\n                        self.showToast('Rewrite failed: ' + e.data.error, 'error');\r\n                        if (self.UI.rwProgWrap) self.UI.rwProgWrap.style.display = 'none';\r\n                        if (self.UI.rwGenerateBtn) { self.UI.rwGenerateBtn.disabled = false; self.UI.rwGenerateBtn.textContent = '\u270d\ufe0f Rewrite (Offline AI)'; }\r\n                        self.worker.onmessage = origHandler;\r\n                    } else { origHandler(e); }\r\n                };\r\n            };\r\n            if (!this.isModelReady) {\r\n                this.worker.postMessage({ type: 'load' });\r\n                var origH = this.worker.onmessage;\r\n                this.worker.onmessage = function (e) {\r\n                    if (e.data.type === 'loaded') { self.isModelReady = true; doRewrite(); }\r\n                    else if (e.data.type === 'error') { self.showToast('AI load failed', 'error'); self.worker.onmessage = origH; }\r\n                    else origH(e);\r\n                };\r\n            } else { doRewrite(); }\r\n        },\r\n        renderRewriteWithDiff: function (original, rewritten) {\r\n            if (this.UI.rwOutput) {\r\n                var origWords = original.toLowerCase().split(\/\\s+\/);\r\n                var newWords = rewritten.split(\/\\s+\/);\r\n                var origSet = {}; origWords.forEach(function (w) { origSet[w.replace(\/[^a-z]\/g, '')] = 1; });\r\n                var html = newWords.map(function (w) {\r\n                    var clean = w.toLowerCase().replace(\/[^a-z]\/g, '');\r\n                    return origSet[clean] ? w : '<span class=\"pth-diff-changed\">' + w + '<\/span>';\r\n                }).join(' ');\r\n                this.UI.rwOutput.innerHTML = html;\r\n                if (this.UI.diffBadge) this.UI.diffBadge.style.display = 'inline';\r\n            }\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 HISTORY \u2500\u2500\u2500 *\/\r\n        addToHistory: function (preview) {\r\n            this.summaryHistory.unshift({ text: preview, time: new Date().toLocaleTimeString(), length: this.currentLength, tone: this.currentTone });\r\n            if (this.summaryHistory.length > 10) this.summaryHistory.pop();\r\n            this.renderHistory();\r\n        },\r\n        renderHistory: function () {\r\n            if (!this.UI.historyList) return;\r\n            if (!this.summaryHistory.length) { this.UI.historyList.innerHTML = '<p style=\"font-size:0.8rem;color:#334155;font-style:italic;text-align:center;margin:20px 0;\">No history yet.<\/p>'; if (this.UI.clearHistoryBtn) this.UI.clearHistoryBtn.style.display = 'none'; return; }\r\n            if (this.UI.clearHistoryBtn) this.UI.clearHistoryBtn.style.display = 'block';\r\n            var self = this;\r\n            this.UI.historyList.innerHTML = '';\r\n            this.summaryHistory.forEach(function (h, i) {\r\n                var item = document.createElement('div');\r\n                item.className = 'pth-history-item';\r\n                item.innerHTML = '<div class=\"pth-history-text\">' + h.text + '...<\/div><div class=\"pth-history-meta\">' + h.time + ' \u00b7 ' + h.length + ' \u00b7 ' + h.tone + '<\/div>';\r\n                item.addEventListener('click', function () {\r\n                    if (self.UI.resultContent) self.UI.resultContent.textContent = h.text;\r\n                    if (self.UI.resultBox) self.UI.resultBox.style.display = 'block';\r\n                    if (self.UI.summaryEmpty) self.UI.summaryEmpty.style.display = 'none';\r\n                    self.switchTab('summary');\r\n                });\r\n                self.UI.historyList.appendChild(item);\r\n            });\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 EXPORT \u2500\u2500\u2500 *\/\r\n        downloadFile: function (content, name, mime) {\r\n            var a = document.createElement('a');\r\n            a.href = URL.createObjectURL(new Blob([content], { type: mime }));\r\n            a.download = name; a.click();\r\n            this.showToast(name + ' saved!');\r\n        },\r\n        getSummaryText: function () { return this.UI.resultContent ? (this.UI.resultContent.textContent || this.UI.resultContent.innerText || '') : this.currentSummary; },\r\n        buildMarkdown: function () {\r\n            var t = this.getSummaryText();\r\n            return '# AI Summary\\n\\n**Generated:** ' + new Date().toLocaleString() + '\\n\\n**Compression:** ' + (this.UI.compression ? this.UI.compression.textContent : '0%') + '\\n\\n---\\n\\n' + t;\r\n        },\r\n        buildJSON: function () {\r\n            return JSON.stringify({ generated: new Date().toISOString(), length: this.currentLength, format: this.currentFormat, tone: this.currentTone, sections: this.selectedSections, focusKeywords: this.focusKeywords, compression: this.UI.compression ? this.UI.compression.textContent : '0%', summary: this.getSummaryText() }, null, 2);\r\n        },\r\n        buildSRT: function () {\r\n            var t = this.getSummaryText();\r\n            var sents = t.match(\/[^.!?]+[.!?]*\/g) || [t];\r\n            var r = '', ts = 0;\r\n            sents.forEach(function (s, i) {\r\n                if (!s.trim()) return;\r\n                var dur = Math.max(3, Math.ceil(s.split(\/\\s+\/).length \/ 3));\r\n                var fmt = function (sec) { var h = Math.floor(sec \/ 3600), m = Math.floor((sec % 3600) \/ 60), s2 = sec % 60; return [String(h).padStart(2, '0'), String(m).padStart(2, '0'), String(s2).padStart(2, '0') + ',000'].join(':'); };\r\n                r += (i + 1) + '\\n' + fmt(ts) + ' --> ' + fmt(ts + dur) + '\\n' + s.trim() + '\\n\\n';\r\n                ts += dur;\r\n            });\r\n            return r;\r\n        },\r\n        buildEmail: function () {\r\n            var t = this.getSummaryText();\r\n            return 'Subject: AI-Generated Summary\\n\\nHello,\\n\\nPlease find the AI-generated summary below:\\n\\n---\\n\\n' + t + '\\n\\n---\\n\\nGenerated on ' + new Date().toLocaleString() + ' using PTH AI Text Summarizer.\\n\\nBest regards';\r\n        },\r\n        exportPDF: function () {\r\n            if (typeof html2pdf === 'undefined') { this.showToast('PDF library not ready', 'error'); return; }\r\n            var e = document.createElement('div');\r\n            e.style.cssText = 'padding:40px;font-family:sans-serif;color:#1e293b;';\r\n            e.innerHTML = '<h2 style=\"color:#1d4ed8;margin-bottom:8px;\">AI Summary Report<\/h2><p style=\"color:#334155;font-size:13px;margin-bottom:20px;\">Generated: ' + new Date().toLocaleString() + ' \u00b7 Compression: ' + (this.UI.compression ? this.UI.compression.textContent : '') + '<\/p><hr style=\"margin-bottom:20px;\"><div style=\"font-size:15px;line-height:1.8;\">' + (this.UI.resultContent ? this.UI.resultContent.innerHTML : '') + '<\/div>';\r\n            html2pdf().set({ margin: 1, filename: 'PTH_Summary.pdf', image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2 }, jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' } }).from(e).save();\r\n            this.showToast('PDF exported!');\r\n        },\r\n        copyToClipboard: function (text, label) {\r\n            navigator.clipboard.writeText(text).catch(function () {});\r\n            this.showToast(label + ' copied!');\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 EVENTS \u2500\u2500\u2500 *\/\r\n        attachEvents: function () {\r\n            var self = this;\r\n\r\n            \/* Layout *\/\r\n            this.bindEv(this.UI.fwBtn, 'click', function () {\r\n                if (self.UI.layout) {\r\n                    self.UI.layout.classList.toggle('pth-full-width');\r\n                    self.UI.fwBtn.textContent = self.UI.layout.classList.contains('pth-full-width') ? '\u25c0 Split' : '\u26f6 Full Width';\r\n                }\r\n            });\r\n            this.bindEv(this.UI.darkBtn, 'click', function () {\r\n                if (self.UI.wrapper) {\r\n                    self.UI.wrapper.classList.toggle('pth-dark');\r\n                    self.UI.darkBtn.textContent = self.UI.wrapper.classList.contains('pth-dark') ? '\u2600\ufe0f Light' : '\ud83c\udf19 Dark';\r\n                }\r\n            });\r\n\r\n            \/* Tabs *\/\r\n            if (this.UI.tabBar) {\r\n                this.UI.tabBar.querySelectorAll('.pth-tab-btn').forEach(function (btn) {\r\n                    btn.addEventListener('click', function () { self.switchTab(btn.getAttribute('data-tab')); });\r\n                });\r\n            }\r\n\r\n            \/* Sample *\/\r\n            this.bindEv(this.UI.sampleBtn, 'click', function () {\r\n                if (self.UI.nativeText) self.UI.nativeText.value = self.SAMPLE_TEXT;\r\n                if (self.UI.sourceText) self.UI.sourceText.value = self.SAMPLE_TEXT;\r\n                self.updateStats();\r\n                self.showToast('Sample loaded!');\r\n            });\r\n\r\n            \/* Input *\/\r\n            this.bindEv(this.UI.pasteBtn, 'click', async function () {\r\n                try { var t = await navigator.clipboard.readText(); if (self.UI.nativeText) self.UI.nativeText.value = t; if (self.UI.sourceText) self.UI.sourceText.value = t; self.updateStats(); self.showToast('Pasted!'); } catch (e) { self.showToast('Clipboard denied \u2014 paste manually.', 'error'); }\r\n            });\r\n            this.bindEv(this.UI.cleanBtn, 'click', function () { self.cleanText(); });\r\n            this.bindEv(this.UI.nativeText, 'input', function () {\r\n                if (self.UI.sourceText && !self.UI.sourceText.value.trim()) self.UI.sourceText.value = self.UI.nativeText.value;\r\n                self.updateStats();\r\n            });\r\n            this.bindEv(this.UI.sourceText, 'input', function () { self.updateStats(); });\r\n\r\n            \/* File Upload *\/\r\n            this.bindEv(this.UI.uploadBtn, 'click', function () { if (self.UI.docFile) self.UI.docFile.click(); });\r\n            this.bindEv(this.UI.docFile, 'change', async function (e) {\r\n                var file = e.target.files[0]; if (!file) return;\r\n                var ext = file.name.split('.').pop().toLowerCase();\r\n                if (ext === 'txt') {\r\n                    var t = await file.text();\r\n                    if (self.UI.nativeText) self.UI.nativeText.value = t;\r\n                    if (self.UI.sourceText) self.UI.sourceText.value = t;\r\n                    self.updateStats(); self.showToast('TXT loaded!');\r\n                } else if (ext === 'pdf' && typeof pdfjsLib !== 'undefined') {\r\n                    var ab = await file.arrayBuffer();\r\n                    var pdf = await pdfjsLib.getDocument({ data: ab }).promise;\r\n                    var text = '';\r\n                    for (var i = 1; i <= pdf.numPages; i++) { var page = await pdf.getPage(i); var tc = await page.getTextContent(); text += tc.items.map(function (item) { return item.str; }).join(' ') + '\\n'; }\r\n                    if (self.UI.nativeText) self.UI.nativeText.value = text;\r\n                    if (self.UI.sourceText) self.UI.sourceText.value = text;\r\n                    self.updateStats(); self.showToast('PDF loaded!');\r\n                } else if ((ext === 'doc' || ext === 'docx') && typeof mammoth !== 'undefined') {\r\n                    var ab2 = await file.arrayBuffer();\r\n                    var result = await mammoth.extractRawText({ arrayBuffer: ab2 });\r\n                    if (self.UI.nativeText) self.UI.nativeText.value = result.value;\r\n                    if (self.UI.sourceText) self.UI.sourceText.value = result.value;\r\n                    self.updateStats(); self.showToast('Word doc loaded!');\r\n                } else { self.showToast('Unsupported file type.', 'error'); }\r\n                if (self.UI.docFile) self.UI.docFile.value = '';\r\n            });\r\n\r\n            \/* URL Fetch *\/\r\n            this.bindEv(this.UI.fetchUrlBtn, 'click', function () { self.fetchUrl(); });\r\n\r\n            \/* Language Modal *\/\r\n            this.bindEv(this.UI.langTriggerBtn, 'click', function () { if (self.UI.langOverlay) self.UI.langOverlay.classList.add('active'); });\r\n            this.bindEv(this.UI.lmClose, 'click', function () { if (self.UI.langOverlay) self.UI.langOverlay.classList.remove('active'); });\r\n            this.bindEv(this.UI.lmSearch, 'input', function () {\r\n                var q = self.UI.lmSearch.value.toLowerCase();\r\n                if (self.UI.lmGrid) self.UI.lmGrid.querySelectorAll('.pth-lm-btn').forEach(function (b) {\r\n                    b.style.display = b.textContent.toLowerCase().indexOf(q) >= 0 ? '' : 'none';\r\n                });\r\n            });\r\n            this.bindEv(this.UI.translateBtn, 'click', function () { self.translateToEnglish(); });\r\n\r\n            \/* Focus Keywords *\/\r\n            this.bindEv(this.UI.kwAddBtn, 'click', function () { self.addKeyword(); });\r\n            this.bindEv(this.UI.kwInput, 'keydown', function (e) { if (e.key === 'Enter') { e.preventDefault(); self.addKeyword(); } });\r\n            this.bindEv(this.UI.kwClearBtn, 'click', function () { self.focusKeywords = []; self.renderKwPills(); });\r\n\r\n            \/* Length \/ Format \/ Tone *\/\r\n            document.querySelectorAll('#pth-length-sel .pth-length-btn').forEach(function (btn) {\r\n                btn.addEventListener('click', function () {\r\n                    document.querySelectorAll('#pth-length-sel .pth-length-btn').forEach(function (b) { b.classList.remove('active'); b.setAttribute('aria-pressed', 'false'); });\r\n                    btn.classList.add('active'); btn.setAttribute('aria-pressed', 'true');\r\n                    self.currentLength = btn.getAttribute('data-length');\r\n                });\r\n            });\r\n            document.querySelectorAll('#pth-format-sel .pth-format-btn').forEach(function (btn) {\r\n                btn.addEventListener('click', function () {\r\n                    document.querySelectorAll('#pth-format-sel .pth-format-btn').forEach(function (b) { b.classList.remove('active'); b.setAttribute('aria-pressed', 'false'); });\r\n                    btn.classList.add('active'); btn.setAttribute('aria-pressed', 'true');\r\n                    self.currentFormat = btn.getAttribute('data-format');\r\n                });\r\n            });\r\n            document.querySelectorAll('#pth-tone-sel .pth-tone-btn').forEach(function (btn) {\r\n                btn.addEventListener('click', function () {\r\n                    document.querySelectorAll('#pth-tone-sel .pth-tone-btn').forEach(function (b) { b.classList.remove('active'); b.setAttribute('aria-pressed', 'false'); });\r\n                    btn.classList.add('active'); btn.setAttribute('aria-pressed', 'true');\r\n                    self.currentTone = btn.getAttribute('data-tone');\r\n                });\r\n            });\r\n\r\n            \/* Sections Tab *\/\r\n            if (this.UI.presetChips) {\r\n                this.UI.presetChips.querySelectorAll('.pth-section-chip').forEach(function (chip) {\r\n                    chip.addEventListener('click', function () {\r\n                        var sec = chip.getAttribute('data-section');\r\n                        if (chip.classList.contains('active')) { self.removeSection(sec); chip.classList.remove('active'); chip.setAttribute('aria-pressed', 'false'); }\r\n                        else { self.addSection(sec); chip.classList.add('active'); chip.setAttribute('aria-pressed', 'true'); }\r\n                    });\r\n                });\r\n            }\r\n            this.bindEv(this.UI.addSecBtn, 'click', function () {\r\n                var v = self.UI.customSecInput ? self.UI.customSecInput.value.trim() : '';\r\n                if (!v) return; self.addSection(v);\r\n                if (self.UI.customSecInput) self.UI.customSecInput.value = '';\r\n            });\r\n            this.bindEv(this.UI.clearSecsBtn, 'click', function () {\r\n                self.selectedSections = [];\r\n                self.renderActiveSections();\r\n                if (self.UI.presetChips) self.UI.presetChips.querySelectorAll('.pth-section-chip').forEach(function (c) { c.classList.remove('active'); c.setAttribute('aria-pressed', 'false'); });\r\n            });\r\n\r\n            \/* Generate *\/\r\n            this.bindEv(this.UI.generateBtn, 'click', function () { self.generate(); });\r\n\r\n            \/* Summary Tab *\/\r\n            this.bindEv(this.UI.regenerateBtn, 'click', function () { self.generate(); });\r\n            this.bindEv(this.UI.saveCompareBtn, 'click', function () {\r\n                self.compareV1 = self.getSummaryText();\r\n                if (self.UI.compareV1) self.UI.compareV1.textContent = self.compareV1;\r\n                if (self.UI.compareWrap) self.UI.compareWrap.style.display = 'block';\r\n                self.showToast('Version 1 saved!');\r\n            });\r\n            this.bindEv(this.UI.translateNativeBtn, 'click', function () { self.translateNative(); });\r\n            this.bindEv(this.UI.copyResultBtn, 'click', function () { self.copyToClipboard(self.getSummaryText(), 'Summary'); });\r\n            this.bindEv(this.UI.printBtn, 'click', function () {\r\n                var w = window.open('', '_blank');\r\n                w.document.write('<pre style=\"font-family:sans-serif;padding:40px;white-space:pre-wrap;font-size:15px;\">' + self.getSummaryText() + '<\/pre>');\r\n                w.document.close(); w.print();\r\n            });\r\n\r\n            \/* Rewriter *\/\r\n            this.bindEv(this.UI.rwLoadBtn, 'click', function () {\r\n                var t = self.getSummaryText();\r\n                if (!t) { self.showToast('Generate a summary first!', 'error'); return; }\r\n                if (self.UI.rwInput) self.UI.rwInput.value = t;\r\n                self.switchTab('rewriter');\r\n            });\r\n            this.bindEv(this.UI.rwLoadSourceBtn, 'click', function () {\r\n                var t = self.getText();\r\n                if (!t) { self.showToast('Load source text first!', 'error'); return; }\r\n                if (self.UI.rwInput) self.UI.rwInput.value = t.substring(0, 2000);\r\n            });\r\n            document.querySelectorAll('#pth-rw-mode-sel .pth-tone-btn').forEach(function (btn) {\r\n                btn.addEventListener('click', function () {\r\n                    document.querySelectorAll('#pth-rw-mode-sel .pth-tone-btn').forEach(function (b) { b.classList.remove('active'); b.setAttribute('aria-pressed', 'false'); });\r\n                    btn.classList.add('active'); btn.setAttribute('aria-pressed', 'true');\r\n                    self.currentRwMode = btn.getAttribute('data-mode');\r\n                });\r\n            });\r\n            this.bindEv(this.UI.rwGenerateBtn, 'click', function () { self.runRewrite(); });\r\n            this.bindEv(this.UI.rwCopyBtn, 'click', function () {\r\n                var t = self.UI.rwOutput ? (self.UI.rwOutput.textContent || '') : '';\r\n                self.copyToClipboard(t, 'Rewrite');\r\n            });\r\n\r\n            \/* Export Hub *\/\r\n            this.bindEv(this.UI.expTxt, 'click', function () { if (self.UI.expTxt.classList.contains('disabled')) return; self.downloadFile(self.getSummaryText(), 'PTH_Summary.txt', 'text\/plain'); });\r\n            this.bindEv(this.UI.expPdf, 'click', function () { if (self.UI.expPdf.classList.contains('disabled')) return; self.exportPDF(); });\r\n            this.bindEv(this.UI.expMd, 'click', function () { if (self.UI.expMd.classList.contains('disabled')) return; self.downloadFile(self.buildMarkdown(), 'PTH_Summary.md', 'text\/markdown'); });\r\n            this.bindEv(this.UI.expJson, 'click', function () { if (self.UI.expJson.classList.contains('disabled')) return; self.downloadFile(self.buildJSON(), 'PTH_Summary.json', 'application\/json'); });\r\n            this.bindEv(this.UI.expSrt, 'click', function () { if (self.UI.expSrt.classList.contains('disabled')) return; self.downloadFile(self.buildSRT(), 'PTH_Summary.srt', 'text\/plain'); });\r\n            this.bindEv(this.UI.expEmail, 'click', function () { if (self.UI.expEmail.classList.contains('disabled')) return; self.downloadFile(self.buildEmail(), 'PTH_Summary_Email.txt', 'text\/plain'); });\r\n            this.bindEv(this.UI.copyPlain, 'click', function () { self.copyToClipboard(self.getSummaryText(), 'Plain text'); });\r\n            this.bindEv(this.UI.copyMarkdown, 'click', function () { self.copyToClipboard(self.buildMarkdown(), 'Markdown'); });\r\n            this.bindEv(this.UI.copyEmail, 'click', function () { self.copyToClipboard(self.buildEmail(), 'Email format'); });\r\n            this.bindEv(this.UI.copySocial, 'click', function () { self.copyToClipboard(self.getSummaryText().substring(0, 280), 'Social (280 chars)'); });\r\n\r\n            \/* History *\/\r\n            this.bindEv(this.UI.clearHistoryBtn, 'click', function () { self.summaryHistory = []; self.renderHistory(); });\r\n\r\n            \/* Keyboard *\/\r\n            document.addEventListener('keydown', function (e) {\r\n                var inEdit = document.activeElement && (document.activeElement.tagName === 'TEXTAREA' || document.activeElement.tagName === 'INPUT');\r\n                if (e.ctrlKey && e.key === 'Enter') { e.preventDefault(); if (self.UI.generateBtn && !self.UI.generateBtn.disabled) self.generate(); }\r\n                if (e.ctrlKey && e.key.toLowerCase() === 'f' && !inEdit) { e.preventDefault(); if (self.UI.fwBtn) self.UI.fwBtn.click(); }\r\n            });\r\n        }\r\n    };\r\n\r\n    \/* 4-Layer Bootstrap *\/\r\n    function runInit() {\r\n        if (!window.pthSummarizerApp.initialized && document.getElementById('pth-sum-wrapper')) {\r\n            window.pthSummarizerApp.initialized = true;\r\n            window.pthSummarizerApp.init();\r\n        }\r\n    }\r\n    runInit();\r\n    document.addEventListener('DOMContentLoaded', runInit);\r\n    window.addEventListener('load', function () { setTimeout(runInit, 50); });\r\n    var _pthMO = new MutationObserver(function () { runInit(); });\r\n    _pthMO.observe(document.body, { childList: true, subtree: true });\r\n    setTimeout(function () { _pthMO.disconnect(); }, 10000);\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(260px,1fr));gap:20px;margin:32px 0}\n.pth-feat-box{background:#f8fafc;border:1px solid #e2e8f0;border-radius:14px;padding:22px 24px}\n.pth-feat-title{font-size:1.05rem;font-weight:800;color:#0f172a;margin:0 0 10px;display:flex;align-items:center;gap:8px}\n.pth-feat-text{font-size:0.92rem;color:#1e293b;font-weight:500;line-height:1.7;margin:0}\n.pth-steps-wrap{margin:36px 0}\n.pth-steps-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px;margin-top:16px}\n.pth-step-item{background:#ffffff;border:1px solid #e2e8f0;border-radius:12px;padding:18px 20px;display:flex;flex-direction:column;gap:8px}\n.pth-step-num{width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg,#3b82f6,#1d4ed8);color:#fff;font-weight:900;font-size:0.95rem;display:flex;align-items:center;justify-content:center;flex-shrink:0}\n.pth-step-name{font-size:0.9rem;font-weight:800;color:#0f172a}\n.pth-step-desc{font-size:0.82rem;color:#334155;font-weight:500;line-height:1.6;margin:0}\n<\/style>\n \n<div class=\"pth-feature-wrap\">\n \n  <div class=\"pth-feat-box\">\n    <p class=\"pth-feat-title\">\ud83d\udfe2 6-Tab All-in-One Intelligence Hub<\/p>\n    <p class=\"pth-feat-text\">One upload, six specialized tools. The <strong>\ud83d\udce5 Input<\/strong> tab handles text paste, PDF\/DOCX upload, and URL fetching. Switch to <strong>\ud83d\udd0d Analyzer<\/strong> for Flesch readability scores, keyword density tables, and sentence distribution charts. The <strong>\u270d\ufe0f Rewriter<\/strong> tab offers five rewrite modes with live diff highlighting. Every feature operates on the same source text \u2014 no re-uploading, no switching apps, no wasted time.<\/p>\n  <\/div>\n \n  <div class=\"pth-feat-box\">\n    <p class=\"pth-feat-title\">\ud83d\udd35 Offline AI with Tone &amp; Focus Control<\/p>\n    <p class=\"pth-feat-text\">The Xenova DistilBART model (~240 MB, downloads once) generates summaries entirely in your browser. Five <strong>Tone Modes<\/strong> shape the output: <strong>Neutral<\/strong>, <strong>Professional<\/strong>, <strong>Simple (ELI5)<\/strong>, <strong>Academic<\/strong>, and <strong>Social Media<\/strong>. Pin up to five <strong>Focus Keywords<\/strong> and the AI pre-filters your text so keyword-containing sentences are prioritized \u2014 giving you summaries that actually highlight what matters to you.<\/p>\n  <\/div>\n \n  <div class=\"pth-feat-box\">\n    <p class=\"pth-feat-title\">\ud83d\udfe3 Export Hub \u2014 6 Formats + 4 Copy Modes<\/p>\n    <p class=\"pth-feat-text\">The <strong>\ud83d\udce4 Export Hub<\/strong> tab consolidates every output format: <strong>.TXT<\/strong> for plain notes, <strong>.PDF<\/strong> for formal documents, <strong>.MD<\/strong> for Markdown editors, <strong>.JSON<\/strong> for structured data, <strong>.SRT<\/strong> for video subtitles, and <strong>Email<\/strong> for ready-to-send correspondence. Four Smart Copy Modes let you copy as Plain Text, Markdown, Email Format, or Social Media (280 chars) \u2014 all without saving a file.<\/p>\n  <\/div>\n \n<\/div>\n \n<div class=\"pth-steps-wrap\">\n  <h2 style=\"font-size:1.3rem;font-weight:800;color:#0f172a;margin:0 0 4px;\">How to Use the AI Text Summarizer<\/h2>\n  <p style=\"font-size:0.88rem;color:#334155;font-weight:500;margin:0 0 16px;\">Four steps from raw text to polished summary, analysis, and export.<\/p>\n  <div class=\"pth-steps-grid\">\n \n    <div class=\"pth-step-item\">\n      <div class=\"pth-step-num\">1<\/div>\n      <div class=\"pth-step-name\">Load Your Text<\/div>\n      <p class=\"pth-step-desc\">In the <strong>\ud83d\udce5 Input<\/strong> tab, paste text directly, click <strong>\ud83d\udcc2 Upload File<\/strong> to load a .TXT, .PDF, or .DOCX, or paste a URL and hit <strong>\ud83d\udd17 Fetch<\/strong>. For non-English text, click <strong>\ud83c\udf10 English \u25be<\/strong> to set your source language then hit <strong>\u27a1\ufe0f<\/strong> to translate to English first.<\/p>\n    <\/div>\n \n    <div class=\"pth-step-item\">\n      <div class=\"pth-step-num\">2<\/div>\n      <div class=\"pth-step-name\">Set Tone &amp; Focus<\/div>\n      <p class=\"pth-step-desc\">Choose your <strong>Length<\/strong> (Short \/ Medium \/ Detailed), <strong>Format<\/strong> (Paragraph \/ Bullets), and <strong>Tone<\/strong> (Neutral \/ Professional \/ Simple \/ Academic \/ Social). Add <strong>Focus Keywords<\/strong> to pin the AI&#8217;s attention on specific topics. Then click <strong>\u2728 Generate AI Summary<\/strong>.<\/p>\n    <\/div>\n \n    <div class=\"pth-step-item\">\n      <div class=\"pth-step-num\">3<\/div>\n      <div class=\"pth-step-name\">Review &amp; Analyze<\/div>\n      <p class=\"pth-step-desc\">The <strong>\ud83c\udfaf Summary<\/strong> tab shows your result with the animated <strong>Compression Gauge<\/strong>. Switch to <strong>\ud83d\udd0d Analyzer<\/strong> to check the Flesch readability score, top keyword frequency table, duplicate sentence alerts, and sentence length distribution bars \u2014 all from the same source text.<\/p>\n    <\/div>\n \n    <div class=\"pth-step-item\">\n      <div class=\"pth-step-num\">4<\/div>\n      <div class=\"pth-step-name\">Rewrite &amp; Export<\/div>\n      <p class=\"pth-step-desc\">Head to <strong>\u270d\ufe0f Rewriter<\/strong>, click <strong>\ud83d\udce5 Load Summary<\/strong>, choose a rewrite mode (Paraphrase \/ Simplify \/ Formalize \/ Shorten \/ Expand), and hit <strong>\u270d\ufe0f Rewrite<\/strong>. Changed words highlight in yellow. Then go to <strong>\ud83d\udce4 Export Hub<\/strong> and download in any of six formats.<\/p>\n    <\/div>\n \n  <\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Last updated: June 2026<\/p>\n\n\n\n<h2 id=\"\ud83d\udd34-why-most-summarizers-stop-too-early\" class=\"wp-block-heading\">\ud83d\udd34 Why Most Summarizers Stop Too Early<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A typical AI summarizer does one thing: it returns a shorter version of what you gave it. That is useful for about thirty seconds \u2014 until you realize the output is in the wrong tone for your audience, you need to check keyword density before publishing, you want a subtitle file for your video, or you need to email the result without reformatting it by hand. The PTH AI Text Summarizer and Intelligence Hub v5.0 PRO was built because every one of those follow-up tasks deserved its own tab in a single tool.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Version 5.0 is a full rebuild from v4.3. The flat card layout is replaced by a six-tab workspace. The Google Translate widget dependency is removed \u2014 replaced with a direct chunked API call. A new Text Analyzer tab, a Rewriter tab with five modes, a dedicated Export Hub, tone selection, focus keywords, a compression gauge, and a sentence heatmap are all added as first-class features \u2014 not afterthoughts bolted onto a summarizer.<\/p>\n\n\n\n<h3 id=\"tab-1-\ud83d\udce5-input-everything-starts-here\" class=\"wp-block-heading\">Tab 1 \u2014 \ud83d\udce5 Input: Everything Starts Here<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The Input tab accepts text four ways.&nbsp;<strong>\ud83d\udccb Paste<\/strong>&nbsp;reads from your clipboard.&nbsp;<strong>\ud83d\udcc2 Upload File<\/strong>&nbsp;opens a file picker supporting .TXT, .PDF (via PDF.js), and .DOC\/.DOCX (via Mammoth.js).&nbsp;<strong>\ud83d\udd17 Fetch<\/strong>&nbsp;retrieves the text content of any public URL using the AllOrigins proxy, stripping scripts, styles, navigation, and footer elements automatically. You can also type directly into either text box.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The dual text box layout separates source text from English text. If your source is in Sinhala, Arabic, Japanese, or any of the twenty supported languages, click the language selector, set your language, then hit the \u27a1\ufe0f button. The tool splits the text into chunks under 4,500 characters and translates each chunk via the Google Translate API, then joins the results into the English box \u2014 ready for summarization without any character limit errors.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<strong>\ud83e\uddf9 Clean Text<\/strong>&nbsp;button pre-processes your source: it strips HTML tags, decodes common HTML entities, normalizes smart quotes to straight quotes, and collapses multiple spaces and line breaks. Run this before summarizing any text copied from a web page or exported from an email client \u2014 it eliminates the junk that causes AI models to waste tokens on formatting noise.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Below the text boxes, the&nbsp;<strong>\u26a1 Instant TL;DR<\/strong>&nbsp;banner appears automatically once text is loaded \u2014 no AI model download required. It extracts the first and last sentence of the source text and displays them as a fast preview of the document&#8217;s opening claim and closing conclusion. For short articles, this alone is often sufficient.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<strong>\ud83c\udf21\ufe0f Sentence Importance Heatmap<\/strong>&nbsp;renders below the stats row when text is detected. Each sentence is highlighted based on a TF-IDF style score \u2014 sentences with the highest concentration of high-frequency non-stopwords glow green. Medium-importance sentences are amber. Low-importance sentences stay unhighlighted. This is a visual preview of what the AI will prioritize, before you spend time waiting for the model to run. Add Focus Keywords and the heatmap updates immediately \u2014 keyword-containing sentences jump to green.<\/p>\n\n\n\n<h3 id=\"focus-keywords-and-tone-modes\" class=\"wp-block-heading\">Focus Keywords and Tone Modes<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\ud83d\udccc Focus Keywords<\/strong>&nbsp;are the single most useful addition in v5.0 for professional users. Type a keyword and press Enter or click&nbsp;<strong>\uff0b Add<\/strong>&nbsp;\u2014 it becomes a blue pill badge below the input. Add up to five. When you hit Generate, the tool reorders your sentences before sending them to the AI: sentences containing your focus keywords move to the front of the input array. Since DistilBART is an extractive-abstractive model that weights early content more heavily, this effectively tells the model what to emphasize without needing a custom prompt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Five&nbsp;<strong>Tone Modes<\/strong>&nbsp;inject a prefix instruction into the AI prompt.&nbsp;<strong>\u2696\ufe0f Neutral<\/strong>&nbsp;sends no prefix \u2014 standard output.&nbsp;<strong>\ud83d\udcbc Professional<\/strong>&nbsp;prefixes &#8220;Write in a formal, professional, executive-level tone.&#8221;&nbsp;<strong>\ud83e\uddd2 Simple<\/strong>&nbsp;prefixes &#8220;Explain in very simple language, like explaining to a 10-year-old.&#8221;&nbsp;<strong>\ud83c\udf93 Academic<\/strong>&nbsp;prefixes &#8220;Write in an academic, scholarly tone with formal language.&#8221;&nbsp;<strong>\ud83d\udcf1 Social<\/strong>&nbsp;prefixes &#8220;Write in a casual, engaging, social media friendly tone under 280 chars.&#8221; The tone badge appears in the Summary tab result header so you always know which mode produced the current output.<\/p>\n\n\n\n<h3 id=\"\ud83d\udfe1-tab-2-\ud83d\udccb-sections-structured-intelligence-extraction\" class=\"wp-block-heading\">\ud83d\udfe1 Tab 2 \u2014 \ud83d\udccb Sections: Structured Intelligence Extraction<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The Sections tab replaces the standard summary with a structured sectioned report. Twelve preset chips cover the most common document intelligence needs:&nbsp;<strong>\ud83c\udfaf Key Points<\/strong>,&nbsp;<strong>\u2705 Action Items<\/strong>,&nbsp;<strong>\ud83d\udcc5 Dates &amp; Deadlines<\/strong>,&nbsp;<strong>\ud83d\udc65 People &amp; Orgs<\/strong>,&nbsp;<strong>\ud83d\udcb0 Financial Data<\/strong>,&nbsp;<strong>\u26a0\ufe0f Risks &amp; Issues<\/strong>,&nbsp;<strong>\u2696\ufe0f Decisions Made<\/strong>,&nbsp;<strong>\ud83d\udca1 Recommendations<\/strong>,&nbsp;<strong>\ud83d\udd27 Technical Details<\/strong>,&nbsp;<strong>\ud83d\udcd6 Background Context<\/strong>,&nbsp;<strong>\ud83d\udcca Statistics &amp; Numbers<\/strong>, and&nbsp;<strong>\ud83c\udfc1 Conclusions<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Each section uses keyword-intelligence extraction \u2014 no AI model download needed. Every sentence in the source text is scored against a keyword dictionary for that section. The top four scoring sentences (minimum five words, minimum one keyword match) are returned as the section content. Financial Data, for example, scores sentences containing &#8220;revenue&#8221;, &#8220;profit&#8221;, &#8220;million&#8221;, &#8220;billion&#8221;, &#8220;percent&#8221;, &#8220;budget&#8221;, and twenty-eight other financial terms. Click a chip, it turns purple and active. Click multiple chips to build a multi-section report. Add a completely custom section \u2014 type &#8220;Legal Clauses&#8221; or &#8220;Safety Requirements&#8221; and click&nbsp;<strong>\uff0b Add<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When sections are active, the Generate button produces the structured report instantly \u2014 no waiting for the AI model. This is important: for legal review, executive briefings, or meeting minutes analysis, sections are often faster and more precise than the AI model because they pull exact matching sentences rather than generating abstractions. Use sections when you need verbatim extraction; use the AI model with tone modes when you need rewritten prose.<\/p>\n\n\n\n<h3 id=\"tab-3-\ud83c\udfaf-summary-result-gauge-and-compare\" class=\"wp-block-heading\">Tab 3 \u2014 \ud83c\udfaf Summary: Result, Gauge, and Compare<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The Summary tab is where results appear after clicking Generate. The result header shows the word count, compression percentage, and estimated read time. Below the metrics, an animated&nbsp;<strong>SVG Compression Gauge<\/strong>&nbsp;renders as a radial arc \u2014 blue for low compression, amber for medium, green for high. The same gauge appears in the sidebar for at-a-glance reference without switching tabs. A compression of 78% means you reduced a 1,000-word document to roughly 220 words.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<strong>\ud83d\udcbe Save v1<\/strong>&nbsp;button stores the current summary as Version 1. Generate a second summary with different settings \u2014 different length, different tone, different sections \u2014 then both appear side by side in the&nbsp;<strong>\ud83d\udd01 Version Comparison<\/strong>&nbsp;panel below the result. This is the workflow for A\/B testing summary approaches: short neutral vs. detailed professional, or sectioned extraction vs. AI prose.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<strong>\ud83c\udf10 Translate<\/strong>&nbsp;button in the Summary tab runs the reverse translation \u2014 it takes the English AI output and translates it to the source language you selected in the Input tab. This is the end-to-end workflow for multilingual content: paste French \u2192 translate to English \u2192 summarize \u2192 translate back to French. The translated result appears in a dashed green box below the English summary.<\/p>\n\n\n\n<h3 id=\"\ud83d\udfe2-tab-4-\ud83d\udd0d-analyzer-four-deep-text-metrics\" class=\"wp-block-heading\">\ud83d\udfe2 Tab 4 \u2014 \ud83d\udd0d Analyzer: Four Deep Text Metrics<\/h3>\n\n\n<figure class=\"pth-article-figure pth-img-left\" style=\"float:left; width:700px; max-width:100%; margin:4px 28px 16px 0; clear:left;\"><img decoding=\"async\" src=\"https:\/\/schoolict.net\/tools\/wp-content\/uploads\/2026\/07\/Four-Deep-Text-Metrics-800x447.jpeg\" alt=\"Four Deep Text Metrics\" width=\"700\" height=\"394\" loading=\"lazy\" data-no-lazy=\"1\" class=\"pth-article-img\" style=\"width:100%;height:auto;display:block;border-radius:10px;border:1px solid #e2e8f0;\"><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The Analyzer tab runs automatically when you switch to it with source text loaded. All analysis is client-side and takes under 200ms on any modern device.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Flesch Reading Ease Score<\/strong>&nbsp;is calculated using the standard formula: 206.835 minus 1.015 times the average words per sentence, minus 84.6 times the average syllables per word. The result (0\u2013100) is translated to a grade label \u2014 Easy (70+), Standard (50\u201370), Difficult (30\u201350), or Expert (below 30). A company memo should target 60\u201370. An academic paper typically lands at 20\u201340. A social media post should be 80+. Knowing this number before publishing lets you adjust the rewrite mode accordingly.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Top 12 Keywords by Density<\/strong>&nbsp;renders as a sortable table with five columns: rank, keyword, count, density percentage, and a colored frequency bar. Stop words (the, a, an, in, is, are, of, for, to, etc.) are excluded. This table tells you instantly which terms dominate your document \u2014 useful for SEO analysis, ensuring your intended keywords actually appear at the right frequency, and detecting when a document has drifted from its stated topic. A 5,000-word report where &#8220;risk&#8221; appears 41 times at 1.2% density is quantifiably different from one where it appears twice.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Duplicate \/ Near-Duplicate Sentences<\/strong>&nbsp;flags any sentence whose first 60 characters match another sentence in the document. This catches copy-paste errors, repeated boilerplate paragraphs, and accidentally duplicated meeting minutes entries. Each duplicate is displayed in an amber alert box. If no duplicates are found, a green confirmation shows instead.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Sentence Length Distribution<\/strong>&nbsp;renders as a horizontal bar chart \u2014 one thin vertical bar per sentence (up to 40 sentences), height proportional to word count, color-coded green (under 15 words), amber (15\u201330 words), or red (over 30 words). A document with mostly red bars is dense and hard to skim. A document with all green bars may lack depth. The ideal mix for professional content is mostly green with some amber. Red bars indicate candidates for the&nbsp;<strong>\u2702\ufe0f Shorten<\/strong>&nbsp;mode in the Rewriter tab.<\/p>\n\n\n\n<h3 id=\"tab-5-\u270d\ufe0f-rewriter-five-modes-with-diff-highlighting\" class=\"wp-block-heading\">Tab 5 \u2014 \u270d\ufe0f Rewriter: Five Modes with Diff Highlighting<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The Rewriter tab uses the same DistilBART model as the summarizer, with a different prefix instruction to shape the output. Click&nbsp;<strong>\ud83d\udce5 Load Summary<\/strong>&nbsp;to import the current result, or&nbsp;<strong>\ud83d\udcc4 Load Source Text<\/strong>&nbsp;to rewrite the original. Five modes cover the standard rewriting needs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\ud83d\udd04 Paraphrase<\/strong>&nbsp;rewrites with the same meaning using different vocabulary and sentence structure.&nbsp;<strong>\ud83e\uddd2 Simplify<\/strong>&nbsp;reduces sentence complexity and substitutes difficult words for common ones \u2014 the correct choice when the Flesch score is below 40 and the audience is non-specialist.&nbsp;<strong>\ud83d\udcbc Formalize<\/strong>&nbsp;replaces casual language with professional alternatives, tightens contractions, and restructures passive voice constructions.&nbsp;<strong>\u2702\ufe0f Shorten<\/strong>&nbsp;aggressively condenses \u2014 useful when you need to cut a 150-word paragraph to 60 words without losing the core meaning.&nbsp;<strong>\ud83d\udcc8 Expand<\/strong>&nbsp;adds elaboration and supporting detail \u2014 useful when the AI summary is too brief and needs to be padded for a formal document.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After rewriting, the output panel shows the result with&nbsp;<strong>changed words highlighted in yellow<\/strong>. This diff is generated by comparing each word in the output against the vocabulary of the original input \u2014 words not present in the original are marked. This lets you immediately see how aggressively the model changed the text, verify that no key terms were dropped, and catch hallucinated additions before publishing.<\/p>\n\n\n\n<h3 id=\"tab-6-\ud83d\udce4-export-hub-six-formats-four-copy-modes\" class=\"wp-block-heading\">Tab 6 \u2014 \ud83d\udce4 Export Hub: Six Formats, Four Copy Modes<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The Export Hub tab puts all download and clipboard actions in one organized grid. Six export cards become clickable once a summary is generated.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>.TXT<\/strong>&nbsp;is plain text, clean and minimal.&nbsp;<strong>.PDF<\/strong>&nbsp;generates a formatted document using html2pdf.js \u2014 title, generation timestamp, compression percentage, a horizontal rule, and the summary in readable paragraphs at letter size.&nbsp;<strong>.MD<\/strong>&nbsp;produces a Markdown file with a heading, metadata block (date, compression), and the summary body \u2014 paste directly into Notion, Obsidian, GitHub README files, or any Markdown editor.&nbsp;<strong>.JSON<\/strong>&nbsp;exports a structured object with generation timestamp, length setting, format, tone, active sections, focus keywords, compression percentage, and the summary text \u2014 ready for any downstream script or API.&nbsp;<strong>.SRT<\/strong>&nbsp;converts the summary into a subtitle file by splitting on sentence boundaries, assigning each sentence a duration based on word count, and formatting with SRT timestamp syntax \u2014 useful for adding AI-generated video summaries as captions.&nbsp;<strong>Email<\/strong>&nbsp;wraps the summary in a proper email template with a subject line, greeting, separator, summary body, and signature placeholder.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Four Quick Copy Modes handle clipboard workflows without files.&nbsp;<strong>\ud83d\udcc4 Plain Text<\/strong>&nbsp;copies the summary prose.&nbsp;<strong>\u2b07\ufe0f Markdown<\/strong>&nbsp;copies the full Markdown format with heading and metadata.&nbsp;<strong>\ud83d\udce7 Email Format<\/strong>&nbsp;copies the email template for direct pasting into Gmail, Outlook, or any email client.&nbsp;<strong>\ud83d\udcf1 Social (280 chars)<\/strong>&nbsp;copies the first 280 characters of the summary \u2014 the exact character limit for X (formerly Twitter) posts. See also the&nbsp;PTH AI Offline Transcription Studio&nbsp;for converting audio to text before running it through this summarizer.<\/p>\n\n\n\n<style>\n.pth-faq-section{margin-top:50px;margin-bottom:40px;font-family:inherit}\n.pth-faq-header{font-size:1.8rem;font-weight:800;color:#0f172a;margin-bottom:25px;border-bottom:2px solid #e2e8f0;padding-bottom:10px;display:flex;align-items:center;gap:10px}\n.pth-faq-grid{display:grid;grid-template-columns:100%;gap:20px}\n@media(min-width:768px){.pth-faq-grid{grid-template-columns:repeat(2,1fr)}}\n@media(min-width:1024px){.pth-faq-grid{grid-template-columns:repeat(3,1fr)}}\n.pth-faq-card{background:#f8fafc;padding:24px;border-radius:12px;border:1px solid #e2e8f0;transition:transform .2s ease;break-inside:avoid}\n.pth-faq-card:hover{transform:translateY(-3px);box-shadow:0 4px 12px rgba(0,0,0,.05)}\n.pth-faq-q{color:#0f172a;font-size:1rem;font-weight:700;margin:0 0 12px;line-height:1.4}\n.pth-faq-a{margin:0;font-size:.95rem;color:#1e293b;line-height:1.6;font-weight:500}\n<\/style>\n \n<div class=\"pth-faq-section\">\n  <h2 class=\"pth-faq-header\">\u2753 Frequently Asked Questions<\/h2>\n  <div class=\"pth-faq-grid\">\n \n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Does the AI work without internet after the first use?<\/p>\n      <p class=\"pth-faq-a\">Yes. The DistilBART model downloads once to your browser cache \u2014 about 240 MB on first use. After that, every summarization, rewrite, and analysis runs 100% offline with zero server contact. Close the browser, turn off Wi-Fi, and it still works on the cached model.<\/p>\n    <\/div>\n \n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">What file types can I upload for summarization?<\/p>\n      <p class=\"pth-faq-a\">The tool accepts <strong>.TXT<\/strong> (plain text), <strong>.PDF<\/strong> (processed via PDF.js page-by-page text extraction), <strong>.DOC<\/strong>, and <strong>.DOCX<\/strong> (processed via Mammoth.js raw text extraction). Image-based PDFs (scanned documents without a text layer) cannot be extracted \u2014 use an OCR tool first to convert them to text.<\/p>\n    <\/div>\n \n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">What is the difference between Sections mode and AI Summary mode?<\/p>\n      <p class=\"pth-faq-a\">Sections mode uses keyword-intelligence to extract exact matching sentences from your text \u2014 instant, offline, no model download. AI Summary mode uses the DistilBART neural network to generate new abstractive prose. Use Sections when you need verbatim extraction (legal review, meeting minutes, financial reports). Use AI Summary when you need rewritten, coherent prose output.<\/p>\n    <\/div>\n \n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">How do Focus Keywords change the AI output?<\/p>\n      <p class=\"pth-faq-a\">When you add a focus keyword, the tool reorders your input sentences before sending to the AI \u2014 sentences containing that keyword move to the front of the text array. Since the DistilBART model weights earlier content more heavily in its attention mechanism, this biases the summary toward your keyword topics without modifying the model or requiring a custom prompt.<\/p>\n    <\/div>\n \n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">What does the Flesch Reading Ease score mean?<\/p>\n      <p class=\"pth-faq-a\">The Flesch score (0\u2013100) measures how easy a text is to read. Scores above 70 are Easy (plain English, short sentences). Scores of 50\u201370 are Standard (business writing). Scores of 30\u201350 are Difficult (academic). Below 30 is Expert (scientific or legal writing). Use this score to decide which Rewrite mode to apply \u2014 Simplify for high-difficulty text, Formalize for overly casual text.<\/p>\n    <\/div>\n \n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Can I summarize text in languages other than English?<\/p>\n      <p class=\"pth-faq-a\">Yes. The workflow is: set your source language using the language selector, paste the non-English text in the left box, click \u27a1\ufe0f to translate to English (appears in the right box), then click Generate. The AI summarizes the English version. Use the Translate button in the Summary tab to convert the English summary back to your original language.<\/p>\n    <\/div>\n \n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">How does the Rewriter&#8217;s diff highlighting work?<\/p>\n      <p class=\"pth-faq-a\">After rewriting, the tool compares each word in the output against the full vocabulary set of the original input text. Words that appear in the output but were not in the original input are highlighted in yellow. This shows which words the AI introduced \u2014 it is not a character-level diff, but a vocabulary-level diff, which is more useful for reviewing content changes.<\/p>\n    <\/div>\n \n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">What is the .SRT export used for?<\/p>\n      <p class=\"pth-faq-a\">The .SRT export converts your AI summary into a subtitle file by splitting the text on sentence boundaries, estimating each sentence&#8217;s duration based on word count (roughly 3 words per second), and formatting with SRT timestamp syntax. Upload this to YouTube, import into DaVinci Resolve or Premiere Pro, or use it with any SRT-compatible video player to add text overlays.<\/p>\n    <\/div>\n \n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">How does Version Compare work?<\/p>\n      <p class=\"pth-faq-a\">Generate a summary, then click <strong>\ud83d\udcbe Save v1<\/strong> to store it. Change your settings (different length, tone, or sections) and generate again. Both versions appear side by side in the Version Comparison panel below the result \u2014 Version 1 on the left, the current result on the right. This is the fastest way to compare a short neutral summary against a detailed professional one.<\/p>\n    <\/div>\n \n  <\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Free AI Text Summarizer &#038; TL;DR Generator (100% Offline) Summarize long articles and documents instantly with our 100% offline free AI text summarizer. Generates accurate TL;DRs securely in your browser. \ud83d\udfe2 6-Tab All-in-One Intelligence Hub One upload, six specialized tools. The \ud83d\udce5 Input tab handles text paste, PDF\/DOCX upload, and URL fetching. Switch to \ud83d\udd0d &#8230; <a title=\"Free AI Text Summarizer &amp; TL;DR Generator (100% Offline)\" class=\"read-more\" href=\"https:\/\/schoolict.net\/tools\/free-ai-text-summarizer-tldr-generator\/\" aria-label=\"Read more about Free AI Text Summarizer &amp; TL;DR Generator (100% Offline)\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":2739,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2732","page","type-page","status-publish","has-post-thumbnail"],"_links":{"self":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages\/2732","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=2732"}],"version-history":[{"count":1,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages\/2732\/revisions"}],"predecessor-version":[{"id":6759,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages\/2732\/revisions\/6759"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/media\/2739"}],"wp:attachment":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/media?parent=2732"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}