1import{i as e}from"./chunks/image-upload-AE2LEsDe.js";const t=3e5,n=72e5,o=288e5,a=18e5;let i=!1,r=!1,s=null;const l=Date.now(),c="undefined"!=typeof window?window.appVersion:null;function d(){i||window.location.pathname.includes("/admin")||window.location.pathname.includes("/login")||window.location.pathname.includes("/register")||(i=!0,console.log(`Version check initialized (v2). Loaded version: ${c||"(none)"}`),c?(setInterval(()=>{document.hidden||m()},t),document.addEventListener("visibilitychange",()=>{document.hidden||r||m()})):console.warn("window.appVersion not set; version polling disabled, stale-timer fallback only"),setInterval(()=>{if(r)return;const e=Date.now()-l;if(e>o){const t=Math.round(e/36e5);console.log(`Page open ${t}h; showing stale-page banner`),u("stale")}},a))}async function m(){if(!r)try{const e=await fetch("/api/version",{method:"GET",credentials:"same-origin",cache:"no-store"});if(!e.ok)return;const t=await e.json(),n=t&&t.version;if(!n)return;n!==c&&(console.log(`Version mismatch: loaded=${c}, current=${n}`),u("version"))}catch(e){}}function u(e){if(r)return;r=!0,s&&(clearTimeout(s),s=null);let t=document.getElementById("stale-page-notification");t||(t=function(){const e=document.createElement("div");e.id="stale-page-notification",e.innerHTML='\n <div class="alert alert-info shadow-lg border-0" style="margin: 0; border-radius: 8px; position: relative; padding-right: 50px;">\n <button class="btn-close position-absolute" id="dismiss-stale-btn"\n style="top: 8px; right: 8px; background: none; border: none; font-size: 1.2rem;\n opacity: 0.6; cursor: pointer; padding: 4px; line-height: 1;">\n <i class="bi bi-x" style="font-size: 1rem;"></i>\n </button>\n <div class="d-flex align-items-center">\n <i class="bi bi-arrow-clockwise me-3 text-primary" style="font-size: 1.2rem;"></i>\n <div class="flex-grow-1 pe-2" data-banner-body></div>\n <div class="ms-2">\n <button class="btn btn-primary btn-sm" id="refresh-stale-btn">\n <i class="bi bi-arrow-clockwise me-1"></i>Refresh\n </button>\n </div>\n </div>\n </div>\n ',e.addEventListener("click",function(e){e.target.closest("#refresh-stale-btn")?window.location.reload():e.target.closest("#dismiss-stale-btn")&&function(){const e=document.getElementById("stale-page-notification");if(!e)return void(r=!1);e.classList.remove("show"),setTimeout(()=>{e.style.display="none"},300),r=!1,s=setTimeout(()=>{c?m():Date.now()-l>o&&u("stale")},n)}()}),Object.assign(e.style,{position:"fixed",top:"20px",right:"20px",zIndex:"9999",maxWidth:"400px",display:"none",opacity:"0",transform:"translateY(-20px)",transition:"all 0.3s ease"});const t=document.createElement("style");return t.textContent="\n #stale-page-notification.show {\n opacity: 1 !important;\n transform: translateY(0) !important;\n }\n @media (max-width: 576px) {\n #stale-page-notification {\n left: 10px;\n right: 10px;\n max-width: none;\n }\n }\n ",document.head.appendChild(t),e}(),document.body.appendChild(t));const a=t.querySelector("[data-banner-body]");a&&(a.innerHTML="version"===e?"<strong>A new version is available</strong><br><small>Please refresh to load the latest features and fixes.</small>":"<strong>Page Session Expired</strong><br><small>This page has been open for a while. Please refresh to ensure everything works correctly.</small>"),t.style.display="block",setTimeout(()=>t.classList.add("show"),100)}function p(e){return{business:"Documents",resume:"Résumé",coverletter:"Cover Letter",basictemplate:"Base Template",custom:"My Templates"}[e]||e.charAt(0).toUpperCase()+e.slice(1)}function f(e){return{custom:0,basictemplate:1,business:2,resume:3,coverletter:4}[e]??99}function g(e,t,n,o={}){const{isLockedFn:a=()=>!1,onLockedClick:i=null,defaultCategory:r=null,categoryOrder:s=["custom","basictemplate","business","resume","coverletter"],onHover:l=null,onHoverEnd:c=null}=o;if(e.innerHTML="",!t||0===t.length){const t=document.createElement("li");return t.className="dropdown-item text-muted text-center py-4",t.textContent="No templates available",void e.appendChild(t)}const d=[...new Set(t.map(e=>e.category))].sort((e,t)=>
1f(e)-f(t));let m=r;m||(m=d.includes("custom")?"custom":"all");const u=document.createElement("li");u.className="dropdown-header sticky-top bg-white py-2 px-2",u.style.borderBottom="1px solid #dee2e6",u.style.zIndex="10";const g=document.createElement("div");g.className="d-flex flex-wrap gap-1",g.style.margin="0 -2px";const b=y("all","All","all"===m);g.appendChild(b),d.forEach(e=>{const n=t.filter(t=>t.category===e).length,o=y(e,p(e),m===e,n);g.appendChild(o)}),u.appendChild(g),e.appendChild(u);const h=document.createElement("div");function w(e){h.innerHTML="";const o="all"===e?t:t.filter(t=>t.category===e);if(0===o.length){const e=document.createElement("div");return e.className="text-center text-muted py-4",e.innerHTML='<i class="bi bi-inbox" style="font-size: 2rem;"></i><br><small>No templates in this category</small>',void h.appendChild(e)}o.forEach(t=>{const o=document.createElement("div"),r=a(t),s=function(e,t,n={}){const{isLocked:o=!1,showCategory:a=!1,imageWidth:i="135px",imageHeight:r="180px",onHover:s=null,onHoverEnd:l=null}=n,c=document.createElement("div");c.className="template-item d-flex align-items-center p-2",c.dataset.templateId=e.id,o&&(c.style.opacity="0.6",c.style.position="relative");const d=document.createElement("div");d.className="template-image-container",d.style.width=i,d.style.height=r,d.style.overflow="hidden",d.style.marginRight="10px",d.style.borderRadius="4px",d.style.transition="transform 0.3s ease",d.style.position="relative",d.style.flexShrink="0";const m=document.createElement("img");if(m.src=e.image_url,m.alt=e.alt_text||e.title,m.style.width="100%",m.style.height="100%",m.style.objectFit="cover",m.style.transition="transform 0.3s ease",m.loading="lazy",o&&(m.style.filter="grayscale(20%)"),d.appendChild(m),o){const e=document.createElement("div");e.style.position="absolute",e.style.top="50%",e.style.left="50%",e.style.transform="translate(-50%, -50%)",e.style.backgroundColor="rgba(0, 0, 0, 0.85)",e.style.color="#FFD700",e.style.width="35px",e.style.height="35px",e.style.borderRadius="50%",e.style.display="flex",e.style.alignItems="center",e.style.justifyContent="center",e.style.fontSize="18px",e.innerHTML='<i class="bi bi-lock-fill"></i>',d.appendChild(e)}const u=document.createElement("div");u.style.display="flex",u.style.flexDirection="column";const f=document.createElement("span");if(f.textContent=e.title,f.style.fontWeight="500",u.appendChild(f),a&&e.category){const t=document.createElement("span");t.style.fontSize="11px",t.style.color="#6c757d",t.style.marginTop="2px",t.textContent=p(e.category),u.appendChild(t)}if(o){const e=document.createElement("span");e.style.marginTop="4px",e.style.fontSize="10px",e.style.padding="2px 8px",e.style.background="linear-gradient(135deg, #667eea 0%, #764ba2 100%)",e.style.color="white",e.style.borderRadius="10px",e.style.fontWeight="bold",e.style.display="inline-block",e.style.width="fit-content",e.textContent="PREMIUM",u.appendChild(e)}return c.appendChild(d),c.appendChild(u),c.style.cursor="pointer",c.style.transition="background-color 0.2s",c.addEventListener("mouseover",()=>{c.style.backgroundColor="#f8f9fa",m.style.transform="scale(1.15)",s&&!o&&s(e)}),c.addEventListener("mouseout",()=>{c.style.backgroundColor="",m.style.transform="scale(1)",l&&l(e)}),c.addEventListener("click",n=>{n.preventDefault(),n.stopPropagation(),t&&t(e)}),c}(t,e=>{r&&i?i(e):r||n(e)},{isLocked:r,showCategory:"all"===e,onHover:l,onHoverEnd:c});o.appendChild(s),h.appendChild(o)})}h.id="templateListContainer",h.style.maxHeight="350px",h.style.overflowY="auto",e.appendChild(h),g.querySelectorAll(".category-pill").forEach(e=>{e.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation();const n=e.dataset.category;g.querySelectorAll(".category-pill").forEach(t=>{const n=t.dataset.category,o=t===e;o?t.classList.add("active"):t.classList.remove("active"),o?(t.style.background="linear-gradient(135deg, #8B5CF6, #EC4899)",t.style.borderColor="#8B5CF6",t.style.color="#fff"):"custom"===n?(t.style.background="linear-gradient(135deg, #f3e8ff, #fce7f3)",t.style.borderColor="#d8b4fe",t.style.color="#7c3aed"):(t.style.background="#fff",t.style.borderColor="#dee2e6",t.style.color="#495057")}),w(n)})}),w(m)}function y(e,t,n=!1,o=null){const a=document.createElement("button");
1return a.type="button",a.className="category-pill btn btn-sm "+(n?"active":""),a.dataset.category=e,a.style.padding="4px 10px",a.style.fontSize="12px",a.style.borderRadius="20px",a.style.border="1px solid #dee2e6",a.style.transition="all 0.2s ease",a.style.whiteSpace="nowrap",n?(a.style.background="linear-gradient(135deg, #8B5CF6, #EC4899)",a.style.borderColor="#8B5CF6",a.style.color="#fff"):"custom"===e?(a.style.background="linear-gradient(135deg, #f3e8ff, #fce7f3)",a.style.borderColor="#d8b4fe",a.style.color="#7c3aed"):(a.style.backgroundColor="#fff",a.style.color="#495057"),null!==o&&o>0?a.innerHTML=`${t} <span style="opacity: 0.7; font-size: 10px;">(${o})</span>`:a.textContent=t,a.addEventListener("mouseover",()=>{a.classList.contains("active")||(a.style.background="custom"===e?"linear-gradient(135deg, #ede9fe, #fdf2f8)":"#e9ecef")}),a.addEventListener("mouseout",()=>{a.classList.contains("active")||(a.style.background="custom"===e?"linear-gradient(135deg, #f3e8ff, #fce7f3)":"#fff")}),a}function b(e,t){"function"==typeof gtag&>ag("event","video_play",{event_category:"Videos",event_label:e,video_id:t})}function h(){document.querySelectorAll(".video-card").forEach(function(e){e.addEventListener("click",function(e){if("A"!==e.target.tagName&&!e.target.closest("a")&&!this.classList.contains("playing")){e.preventDefault();var t=this.getAttribute("data-youtube-id");if(t){this.querySelector(".card-body").appendChild(function(e,t){var n=document.createElement("div");n.className=t;var o="https://www.youtube-nocookie.com/embed/"+e+"?autoplay=1&rel=0&modestbranding=1",a=document.createElement("iframe");return a.src=o,a.setAttribute("allow","autoplay; encrypted-media; clipboard-write"),a.setAttribute("allowfullscreen",""),a.setAttribute("loading","lazy"),n.appendChild(a),n}(t,"video-embed-container"));var n=this.querySelector(".video-placeholder").closest(".col-md-4");n&&(n.style.display="none");var o=this.querySelector(".col-md-8");o&&(o.className=o.className.replace("col-md-8","col-md-12")),this.classList.add("playing"),this.style.cursor="default";var a=this.querySelector(".card-title");b(a?a.textContent.trim():t,t)}else{var i=this.getAttribute("data-video-url");i&&(window.location.href=i)}}}),e.addEventListener("keydown",function(e){"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.click())}),e.setAttribute("tabindex","0"),e.setAttribute("role","button"),e.setAttribute("aria-label","Play video: "+e.querySelector(".card-title").textContent)})}function w(){var e;(e=document.querySelectorAll(".hero-video-self")).length&&e.forEach(function(e){var t=e.querySelector("video");if(t){var n=!1;e.addEventListener("click",function(){if(t.paused){var e=t.play();e&&"function"==typeof e.catch&&e.catch(function(){})}else t.pause()}),t.addEventListener("play",function(){e.classList.add("is-playing"),n||(n=!0,b("Format Magic demo","self-hosted-demo"))}),t.addEventListener("pause",function(){e.classList.remove("is-playing")})}}),h()}document.addEventListener("DOMContentLoaded",function(){let t=!1;d(),w();function n(e,t,n,o,a){e.style.transition="opacity "+n+"ms ease",e.style.opacity="0",setTimeout(function(){e.textContent=t,e.style.fontWeight=o?"bold":"",e.style.color=o?"#4169E1":"",e.style.opacity="1",a&&setTimeout(a,n)},n)}const o=document.getElementById("optionsDashboardHeader");if(o){const e=new IntersectionObserver(t=>{t.forEach(t=>{if(t.isIntersecting){const o=document.getElementById("formattingOptionsHint");if(o){const a=o.textContent;let i=0;function r(){i>=2||n(o,"Modifiable after initial formatting",400,!0,function(){setTimeout(function(){n(o,a,400,!1,function(){i++,i<2&&setTimeout(r,1e3)})},2500)})}setTimeout(r,2e3)}e.unobserve(t.target)}})},{threshold:.5});e.observe(o)}const a=document.querySelector(".sample-text-hint-trigger");if(a){const e=new IntersectionObserver(t=>{t.forEach(t=>{t.isIntersecting&&(t.target.classList.remove("sample-text-hint-trigger"),t.target.classList.add("sample-text-hint"),e.unobserve(t.target))})},{threshold:.5});e.observe(a)}function i(e){const t=e;let n=e.replace(/\\x00/g,"");return t!==n&&(Array.from(t).filter((e,t)=>
1n[t]!==e),t.includes("\\x00")&&console.warn("Removed null bytes for security.")),n}window.initTOCDetection&&window.initTOCDetection(),window.sanitizeInput=i,function(){const e=document.getElementById("limitReachedModal");if(e){const n=e.querySelector('a[href="/subscribe"]');n&&n.addEventListener("click",function(){t=!0});const o=e.querySelector('a[href="/login"]');o&&o.addEventListener("click",function(){t=!0})}const n=document.getElementById("errorModal");if(n){const e=n.querySelector('a[href="/manage-subscription"]');e&&e.addEventListener("click",function(){t=!0})}}();const r=document.getElementById("browse-button");r&&r.addEventListener("click",()=>{document.getElementById("fileInput").click()});const s=document.getElementById("token-dashboard-header");s&&s.addEventListener("click",()=>{toggleDashboard("token")});const l=document.getElementById("options-dashboard-header");l&&l.addEventListener("click",()=>{toggleDashboard("options")});const c=document.getElementById("documents-dashboard-header");c&&c.addEventListener("click",()=>{toggleDashboard("documents")});const m=document.getElementById("subscription-container");m&&m.addEventListener("click",e=>{if(e.target.classList.contains("subscribe-button")){const t=e.target.dataset.tierId;t&&async function(e){try{const t=await fetch(`/change-subscription/${e}`,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include"}),n=await t.json();if(!t.ok)throw new Error(n.message||`HTTP error! status: ${t.status}`);if(n.redirect){const e=new URL(n.redirect,window.location.origin);"/register"===e.pathname&&e.searchParams.set("source","home_pricing"),window.location.href=e.toString()}else{const e=document.getElementById("subscription-message");e.innerHTML=`<div class="alert alert-info">${n.message}</div>`,e.style.display="block",updateSubscriptionStatus()}}catch(e){console.error("Error:",e);const t=document.getElementById("error-message");t.innerHTML=`<div class="alert alert-danger">An error occurred: ${e.message}</div>`,t.style.display="block"}}(t)}});const u=document.getElementById("userInput");u&&u.addEventListener("input",function(e){if(-1===e.target.value.indexOf("\\x00"))return;const t=i(e.target.value);if(t!==e.target.value){const n=e.target.selectionStart;e.target.value=t,e.target.setSelectionRange(n-1,n-1),console.warn("Removed potentially problematic characters during input.")}});var p=document.getElementById("format-magic-button");p&&p.addEventListener("click",async function(e){if(!window.__wordMode||!window.__wordMode.active){if($()){if(!confirm("You have unsaved changes in your current document. If you continue with Format Magic, your changes will be lost.\n\nClick 'Create PDF' first to save your work, or click OK to proceed without saving."))return void e.preventDefault()}window.dataLayer=window.dataLayer||[],dataLayer.push({event:"format_magic_clicked",event_category:"Button",event_label:"Format Magic Button Clicked"}),document.getElementById("formattedContentContainer").style.display="block";try{await h(),tinymce.get("mytextarea-editor")&&tinymce.remove("#mytextarea-editor"),await A();const e=tinymce.get("mytextarea-editor");e&&e.setContent('\n <p style="text-align: center; margin: 20px auto; font-weight: bold;">\n <span style="color: #ffffff; background-color: #180cc9; padding: 10px 15px; display: inline-block;">Your formatted text will appear here when processing has completed.<br><br>You can edit the output, or go straight to creating the PDF in the next step below once processing has finished.</span>\n </p>\n ');const t=document.getElementById("mytextarea-editor").parentNode;t&&(delete t.dataset.currentTemplateId,delete t.dataset.currentTaskId)}catch(e){console.error("Error initializing TinyMCE:",e)}}});document.querySelectorAll(".pin-accordion").forEach(e=>{const t=e.dataset.targetId;if(!t)return;const n=document.getElementById(t),o=document.querySelector(`button[data-bs-target="#${t}"]`);if(!n||!o)return;const a=`accordionPinned_${t}`,i=`accordionOpen_${t}`;!function(){if("true"===localStorage.getItem(a)){e.classList.replace("bi-pin","bi-pin-fill");"true"===localStorage.getItem(i)?n.classList.contains("show")||(n.classList.add("show"),o.classList.remove("collapsed"),o.setAttribute("aria-expanded","true")):n.classList.contains("show")&&(n.classList.remove("show"),o.classList.add("collapsed"),o.setAttribute("aria-expanded","fal
1se"))}else e.classList.replace("bi-pin-fill","bi-pin")}(),e.addEventListener("click",function(t){t.stopPropagation();if("true"===localStorage.getItem(a))localStorage.removeItem(a),localStorage.removeItem(i),e.classList.replace("bi-pin-fill","bi-pin");else{localStorage.setItem(a,"true");const t=n.classList.contains("show");localStorage.setItem(i,t),e.classList.replace("bi-pin","bi-pin-fill")}}),n.addEventListener("show.bs.collapse",function(){"true"===localStorage.getItem(a)&&localStorage.setItem(i,"true")}),n.addEventListener("hide.bs.collapse",function(){"true"===localStorage.getItem(a)&&localStorage.setItem(i,"false")})});const f=document.getElementById("regenerate-pdf-options-button"),y=document.getElementById("regenerate-pdf-options-wrapper");if(f){const e=f.innerHTML;let t=null,n=null,o=!1;const a=["addPageNumbers","addCoverPage","generateToc","tocMaxLevel","landscapeMode","portraitMode"],i=function(){const e={};return a.forEach(t=>{const n=document.getElementById(t);n&&("checkbox"===n.type||"radio"===n.type?e[t]=n.checked:e[t]=n.value)}),e},r=function(){if(!n)return!1;const e=i();return Object.keys(e).some(t=>e[t]!==n[t])},s=function(){if(!y)return;const e=document.getElementById("mytextarea-editor")?.parentNode,t=!(!e||!e.dataset.currentTaskId)&&r()&&!o;y.style.display=t?"":"none"};f.addEventListener("click",function(){const n=document.getElementById("generate-pdf-button-main");n&&!n.disabled&&(f.disabled=!0,f.innerHTML='<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span>Generating PDF...',t&&t.disconnect(),t=new MutationObserver(function(){const o=n.innerHTML;f.innerHTML=o,f.disabled=n.disabled,o.includes("PDF Generated Successfully")&&(f.innerHTML="PDF Generated Successfully - see below"),o.includes("Create PDF and Save Document File")&&(f.innerHTML="PDF Generated Successfully - see below",t.disconnect(),t=null,setTimeout(function(){f.innerHTML=e,f.disabled=!1,s()},2500))}),t.observe(n,{childList:!0,subtree:!0,characterData:!0,attributes:!0,attributeFilter:["disabled"]}),n.click())});let l=!1;const c=function(){if(l)return;const e=document.getElementById("formattingOptionsHint");e&&(e.textContent="Cover Page | TOC | Page Orientation... â adjust here to re-create PDF",l=!0)},d=function(){n=i(),o=!1,t||s()},m=document.getElementById("mytextarea-editor");if(m&&m.parentNode){const e=m.parentNode;e.dataset.currentTaskId&&(d(),c());new MutationObserver(function(){e.dataset.currentTaskId&&(d(),c())}).observe(e,{attributes:!0,attributeFilter:["data-current-task-id"]})}const u=document.getElementById("generate-pdf-button-main");if(u){new MutationObserver(function(){u.innerHTML.includes("PDF Generated Successfully")&&d()}).observe(u,{childList:!0,subtree:!0,characterData:!0})}a.forEach(e=>{const t=document.getElementById(e);t&&t.addEventListener("change",s)});const p=document.getElementById("userInput");p&&p.addEventListener("input",function(){o=!0,s()})}const b=document.getElementById("generate-pdf-button-main");async function h(){if(!window.tinymce)return new Promise((e,t)=>{const n=document.createElement("script");n.src="/static/tinymce/tinymce.min.js",n.referrerpolicy="origin",n.onload=e,n.onerror=t,document.head.appendChild(n)})}function v(e){const t={Letter:{top:.9,right:.8,bottom:.7,left:.8},A4:{top:.9,right:.8,bottom:.7,left:.8},Legal:{top:.8,right:.8,bottom:.8,left:.8},A3:{top:1,right:1.2,bottom:1,left:1.2},"6x9":{top:.4,right:.5,bottom:.4,left:.5}};return t[e]||t.Letter}function x(e){const t=`formatmagic-custom-padding-${e}`,n=localStorage.getItem(t);if(n)try{return JSON.parse(n)}catch(e){}return null}function k(e){const t=`formatmagic-custom-padding-${e}`;localStorage.removeItem(t)}function _(e){if(function(e){const t=x(e),n="true"===localStorage.getItem("formatmagic-user-chose-page-size");return null!==t||n}(e))return!0;const t=function(){const e=localStorage.getItem("formatmagic-country-detected");if(e)try{return JSON.parse(e).defaultPageSize}catch(e){return null}return null}();return t&&e===t}function E(){localStorage.setItem("formatmagic-user-chose-page-size","true")}function S(){localStorage.removeItem("formatmagic-user-chose-page-size")}async function C(e,t){try{(await fetch(`/api/templates/${e}/update-page-rule`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({pageCSS:t})})).ok||console.error("Failed to update page rule in document")}catch(e){console.error("Error updating page rule:",e)}}function L(e,t,n=!1){if(_(t)){const n=function(e){const t={Letter:{size:"size: 8.5in 11in !important;"}
1,A4:{size:"size: A4 !important;"},Legal:{size:"size: 8.5in 14in !important;"},A3:{size:"size: A3 !important;"},"6x9":{size:"size: 6in 9in !important;"}},n=t[e]||t.Letter;let o;const a=x(e);if(a)o=`padding: ${a.top}in ${a.right}in ${a.bottom}in ${a.left}in !important;`;else{const t=v(e);o=`padding: ${t.top}in ${t.right}in ${t.bottom}in ${t.left}in !important;`}return`\n /* Dynamic page size with ${a?"custom":"optimized"} margins - overrides template defaults */\n @page {\n ${o}\n margin: 0 !important;\n ${n.size}\n }\n `}(t),o=e.getDoc(),a=o.head,i=a.querySelector("#format-magic-page-size");i&&i.remove();const r=o.createElement("style");r.id="format-magic-page-size",r.innerHTML=n,a.appendChild(r),function(e,t){const n=document.getElementById("mytextarea-editor").parentNode.dataset.currentTaskId;n&&C(n,t)}(0,n)}else{const t=e.getDoc().head.querySelector("#format-magic-page-size");t&&t.remove(),function(){const e=document.getElementById("mytextarea-editor").parentNode.dataset.currentTaskId;e&&C(e,"")}()}const o=document.getElementById("mytextarea-editor").parentNode;o&&(o.dataset.currentPageSize=t),n||localStorage.setItem("formatmagic-page-size",t),e.nodeChanged()}function M(e){const t=document.getElementById("mytextarea-editor").parentNode;if(t&&t.dataset.currentPageSize)return t.dataset.currentPageSize;const n=e.getDoc().head.querySelector("#format-magic-page-size");if(n){const e=n.innerHTML;if(e.includes("8.5in 11in"))return"Letter";if(e.includes("size: A4"))return"A4";if(e.includes("8.5in 14in"))return"Legal";if(e.includes("size: A3"))return"A3"}return"Letter"}function T(e,t){setTimeout(()=>{try{const n=e.getContainer();let o=!1;const a=['[title="Page Size"]','[aria-label="Page Size"]','button[title*="Page Size"]','button[aria-label*="Page Size"]','[data-mce-name="pageSize"]'];for(const e of a){const a=n.querySelector(e);if(a){const e=a.querySelector(".tox-tbtn__text, .tox-split-button__text, span");if(e){e.textContent=t,o=!0;break}if(a.textContent.includes("Letter")||a.textContent.includes("A4")||a.textContent.includes("Legal")||a.textContent.includes("A3")){a.innerHTML=a.innerHTML.replace(/Letter|A4|Legal|A3/,t),o=!0;break}}}if(!o){const e=n.querySelectorAll("button");for(const n of e)if(n.textContent.includes("Letter")||n.textContent.includes("A4")||n.textContent.includes("Legal")||n.textContent.includes("A3")||n.innerHTML.includes("Letter")||n.innerHTML.includes("A4")){n.textContent=t,o=!0;break}}}catch(e){console.error("Error updating page size button text:",e)}},150)}function B(e,t){const n=v(t),o=x(t)||n;e.windowManager.open({title:`Custom Margins for ${t}`,body:{type:"panel",items:[{type:"htmlpanel",html:'<p style="margin: 0 0 10px 0; color: #666; font-size: 14px;">Fine-tune page margins for printing/binding needs. Leave blank to use defaults.</p>'},{type:"grid",columns:2,items:[{type:"input",name:"paddingTop",label:"Top (in)",placeholder:n.top.toString()},{type:"input",name:"paddingRight",label:"Right (in)",placeholder:n.right.toString()},{type:"input",name:"paddingBottom",label:"Bottom (in)",placeholder:n.bottom.toString()},{type:"input",name:"paddingLeft",label:"Left (in)",placeholder:n.left.toString()}]}]},buttons:[{type:"cancel",text:"Cancel"},{type:"custom",text:"Reset to Defaults",name:"reset",primary:!1},{type:"submit",text:"Apply Custom Margins",primary:!0}],initialData:{paddingTop:o.top.toString(),paddingRight:o.right.toString(),paddingBottom:o.bottom.toString(),paddingLeft:o.left.toString()},onAction:function(n,o){"reset"===o.name&&(k(t),S(),L(e,t),n.close())},onSubmit:function(o){const a=o.getData(),i={top:parseFloat(a.paddingTop)||n.top,right:parseFloat(a.paddingRight)||n.right,bottom:parseFloat(a.paddingBottom)||n.bottom,left:parseFloat(a.paddingLeft)||n.left};if(!Object.values(i).every(e=>e>=0&&e<=4))return void e.notificationManager.open({text:"Please enter valid margin values between 0 and 4 inches.",type:"error"});const r=Math.abs(i.top-n.top)<.01&&Math.abs(i.right-n.right)<.01&&Math.abs(i.bottom-n.bottom)<.01&&Math.abs(i.left-n.left)<.01;r?(k(t),S()):function(e,t){const n=`formatmagic-custom-padding-${e}`;localStorage.setItem(n,JSON.stringify(t))}(t,i),L(e,t),o.close();const s=r?`â
Margins for ${t} reset to defaults`:`â
Custom margins applied to ${t}: ${i.top}/${i.right}/${i.bottom}/${i.left}in`;e.notificationManager.open({text:s,type:"success",timeout:3e3})}})}function I(e){!async function(e){const t=function(e){try{const t=e.getDoc(),n=t.getElementById("format-magic-page-size");if(n&&n.innerHTML){if(n.innerHTML.includes("size: A4"))return"A4";if(n.innerHTML.includes("size: 8.5in 11in"))return"Letter";if(n.innerHTML.includes("size: 8.5in 14in"))return"Legal";if(n.innerHTML.includes("size: A3"))return"A3";if(n.innerHTML.includes("size: 6in 9in"))return"6x9"}const o=t.querySelectorAll("style");for(const e of o){const t=e.innerHTML;if(t.includes("@page")){if(t.match(/size:\s*A3/i))return"A3";if(t.match(/size:\s*A4/i))return"A4";if(t.match(/size:\s*8\.5in\s+11in/))return"Letter";if(t.match(/size:\s*8\.5in\s+14in/))return"Legal";if(t.match(/size:\s*6in\s+9in/))return"6x9"}}}catch(e){}return null}(e);if(t){S(),console.log(`ð Document has embedded page size: ${t} - using template defaults`);const n=document.getElementById("mytextarea-editor").parentNode;return n&&(n.dataset.currentPageSize=t),void P(e,t)}let n=localStorage.getItem("formatmagic-page-size");if(n)return S(),_(n)&&L(e,n),void P(e,n);if(S(),localStorage.getItem("formatmagic-country-detected")){n=JSON.parse(localStorage.getItem("formatmagic-country-detected")).defaultPageSize}else try{const e=await fetch("/api/detect-country"),t=await e.json();localStorage.setItem("formatmagic-country-detected",JSON.stringify(t)),n=t.defaultPageSize}catch(e){n="Letter"}L(e,n),P(e,n)}(e)}function P(e,t){setTimeout(()=>{e.currentPageSizeText=t,e.pageSizeButtonAPI&&e.pageSizeButtonAPI.setText(t),T(e,t)},200)}function A(){return new Promise(t=>{tinymce.init({selector:"#mytextarea-editor",menubar:!0,license_key:"gpl",toolbar_mode:"wrap",promotion:!1,branding:!1,content_style:'\n body { padding-top: 60px; }\n .tox-tinymce { border-top-left-radius: 0 !important; border-top-right-radius: 0 !important; }\n\n /* Form line styles for TinyMCE editor */\n .form-field {\n display: inline-block;\n margin-right: 25px;\n vertical-align: bottom;\n }\n .form-field-line {\n display: inline-block;\n border-bottom: 1px solid #333;\n min-height: 1.2em;\n vertical-align: bottom;\n }\n .form-field-line::after {\n content: "\\00a0";\n }\n .form-field-line.short { min-width: 80px; }\n .form-field-line.medium { min-width: 150px; }\n .form-field-line.long { min-width: 250px; }\n .form-field-line.full { width: 100%; display: block; margin: 0; }\n figure.image { text-align: center; }\n figure.image figcaption { text-align: center; }\n\n /* Editor-only visual cue for the cover page area so users\n can see they\'re editing inside it. Does not appear in\n the final PDF â WeasyPrint never sees this stylesheet.\n Extra bottom padding gives the user a click target\n below the content. Using currentColor for the outline\n and label ensures they pick up the template\'s text\n colour, so the cue stays visible on light and dark\n templates alike without any detection logic. */\n .cover-page {\n background-color: transparent;\n border: 2px dashed currentColor;\n padding: 12px 12px 48px 12px;\n margin: 12px 0;\n border-radius: 4px;\n position: relative;\n }\n .cover-page::before {\n content: "Cover Page (you can change the words and add images here)";\n display: block;\n font-size: 11px;\n color: currentColor;\n opacity: 0.6;\n font-style: italic;\n margin-bottom: 8px;\n font-family: -apple-system, system-ui, sans-serif;\n }\n .cover-page p,\n .cover-page .cover-page-subtitles {\n text-align: center;\n }\n /* Mirror the atpagesettings rule so empty spacer\n paragraphs (e.g. <p></p>
1 after TinyMCE serialization\n strips the bogus <br>) render as a blank line in the\n editor, matching how WeasyPrint renders them in the\n final PDF. */\n .cover-page p:empty::before {\n content: "\\200B";\n }\n /* Editor-only "Click to add subtitle" hint for empty\n subtitle paragraphs. Higher specificity overrides the\n \\200B rule above. Vanishes the moment the user types\n (the <p> is no longer :empty). Never appears in the\n PDF â WeasyPrint doesn\'t load this stylesheet. */\n .cover-page p.cover-page-subtitles:empty::before {\n content: "Click to add a subtitle (optional)";\n color: currentColor;\n opacity: 0.5;\n font-style: italic;\n }\n /* Only show the hint on the FIRST subtitle paragraph.\n Any empty subtitle paragraph that has a preceding\n subtitle sibling (whether empty or filled) gets the\n hint suppressed â otherwise users who press Enter to\n add space below typed subtitles see the hint repeat. */\n .cover-page p.cover-page-subtitles ~ p.cover-page-subtitles:empty::before {\n content: "\\200B";\n color: inherit;\n font-style: normal;\n }\n\n /* Editor-only visual cue for the TOC area. Mirrors the\n cover-page treatment so users see that the TOC is a\n special block. The note explains that direct edits\n are overwritten â the TOC is always regenerated from\n the document\'s headings. Not part of the PDF output. */\n #toc {\n background-color: transparent;\n border: 2px dashed currentColor;\n padding: 12px;\n margin: 12px 0;\n border-radius: 4px;\n position: relative;\n }\n #toc::before {\n content: "Table of Contents (auto-generated from your headings based on your formatting options)";\n display: block;\n font-size: 11px;\n color: currentColor;\n opacity: 0.6;\n font-style: italic;\n margin-bottom: 8px;\n font-family: -apple-system, system-ui, sans-serif;\n }\n /* Click-to-remove control injected into the cover page and\n TOC blocks. Editor-only: it carries data-mce-bogus="all"\n so it never appears in getContent(), the saved HTML, or\n the PDF. Sits in the block\'s top-right corner (both\n blocks are position: relative). Turns red on hover to\n signal deletion. */\n .section-remove {\n position: absolute;\n top: 6px;\n right: 6px;\n width: 20px;\n height: 20px;\n line-height: 18px;\n text-align: center;\n border-radius: 50%;\n background-color: rgba(128, 128, 128, 0.2);\n color: currentColor;\n opacity: 0.55;\n font-size: 15px;\n font-style: normal;\n font-weight: normal;\n font-family: -apple-system, system-ui, sans-serif;\n cursor: pointer;\n user-select: none;\n z-index: 2;\n }\n .section-remove:hover {\n opacity: 1;\n background-color: rgba(220, 53, 69, 0.85);\n color: #fff;\n }\n ',pagebreak_separator:'<hr class="page-break">',pagebreak_split_block:!0,forced_root_block:"p",force_p_newlines:!0,end_container_on_empty_block:!0,iframe:!0,sandbox:!0,readonly:!1,security:{sandbox:{plugins:!0,scripts:!0,same_origin:!0}},content_css_cors:!0,content_css:"https://fonts.googleapis.com/css2?family=Abril+Fatface&family=Anton&family=Archivo+Black&family=Bangers&family=Barlow+Condensed:wght@400;500;600;700&family=Bebas+Neue&family=Comfortaa:wght@400;500;600;700&family=Cormorant+Garamond:wght@400;500;600;700&family=Crimson+Text:wght@400;600;700&family=DM+Sans:wght@400;500;600;700&family=EB+Garamond:wght@400;500;600;
1700&family=Fira+Mono:wght@400;500;700&family=Fjalla+One&family=Fredoka+One&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&family=Lato:wght@400;700&family=Libre+Baskerville:wght@400;700&family=Lobster&family=Lora:wght@400;500;600;700&family=Manrope:wght@400;500;600;700&family=Merriweather:wght@400;700&family=Montserrat:wght@400;500;600;700&family=Mulish:wght@400;500;600;700&family=Nunito:wght@400;500;600;700&family=Open+Sans:wght@400;500;600;700&family=Oswald:wght@400;500;600;700&family=PT+Serif:wght@400;700&family=Pacifico&family=Playfair+Display:wght@400;500;600;700&family=Poppins:wght@400;500;600;700&family=Press+Start+2P&family=Quicksand:wght@400;500;600;700&family=Raleway:wght@400;500;600;700&family=Roboto:wght@400;500;700&family=Roboto+Mono:wght@400;500;700&family=Roboto+Slab:wght@400;500;600;700&family=Source+Code+Pro:wght@400;500;600;700&family=Source+Sans+Pro:wght@400;600;700&family=Source+Serif+Pro:wght@400;600;700&family=Spectral:wght@400;500;600;700&family=Teko:wght@400;500;600;700&family=Ubuntu:wght@400;500;700&family=VT323&family=Work+Sans:wght@400;500;600;700&display=swap",font_family_formats:["Montserrat='Montserrat', sans-serif","Roboto='Roboto', sans-serif","Open Sans='Open Sans', sans-serif","Lato='Lato', sans-serif","Poppins='Poppins', sans-serif","Inter='Inter', sans-serif","Source Sans Pro='Source Sans Pro', sans-serif","Nunito='Nunito', sans-serif","Work Sans='Work Sans', sans-serif","Raleway='Raleway', sans-serif","Ubuntu='Ubuntu', sans-serif","Quicksand='Quicksand', sans-serif","Mulish='Mulish', sans-serif","DM Sans='DM Sans', sans-serif","Manrope='Manrope', sans-serif","Oswald='Oswald', sans-serif","Bebas Neue='Bebas Neue', sans-serif","Anton='Anton', sans-serif","Archivo Black='Archivo Black', sans-serif","Barlow Condensed='Barlow Condensed', sans-serif","Fjalla One='Fjalla One', sans-serif","Teko='Teko', sans-serif","Playfair Display='Playfair Display', serif","Merriweather='Merriweather', serif","Lora='Lora', serif","PT Serif='PT Serif', serif","Crimson Text='Crimson Text', serif","EB Garamond='EB Garamond', serif","Libre Baskerville='Libre Baskerville', serif","Source Serif Pro='Source Serif Pro', serif","Cormorant Garamond='Cormorant Garamond', serif","Spectral='Spectral', serif","Roboto Slab='Roboto Slab', serif","Pacifico='Pacifico', cursive","Bangers='Bangers', cursive","Fredoka One='Fredoka One', cursive","Comfortaa='Comfortaa', cursive","Abril Fatface='Abril Fatface', cursive","Lobster='Lobster', cursive","Press Start 2P='Press Start 2P', cursive","Roboto Mono='Roboto Mono', monospace","Source Code Pro='Source Code Pro', monospace","Fira Mono='Fira Mono', monospace","JetBrains Mono='JetBrains Mono', monospace","VT323='VT323', monospace","Arial=Arial, sans-serif","Helvetica='Helvetica Neue', Helvetica, sans-serif","Georgia=Georgia, serif","Times New Roman='Times New Roman', serif","Verdana=Verdana, sans-serif","Trebuchet MS='Trebuchet MS', sans-serif"].join(";"),font_size_formats:"8pt 9pt 10pt 11pt 12pt 13pt 14pt 16pt 18pt 20pt 22pt 24pt 28pt 32pt 36pt 48pt 72pt",line_height_formats:"1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2 2.5 3",plugins:["anchor autolink charmap codesample emoticons fullscreen image link lists media searchreplace table visualblocks wordcount pagebreak code preview visualchars"].join(" "),style_formats:[{title:"Normal",selector:"*",attributes:{class:""},remove_similar:!0,block:"p"},{title:"Highlight Block",block:"div",classes:"highlight-block",preview:!1,remove_similar:!0}],toolbar:["undo redo fullscreen | blocks fontfamily fontsize bodyTextSize styles | bold italic underline strikethrough |",null!==window.currentUserId?"link table imageLibrary |":"link table |","align lineheight | numlist bullist indent outdent | emoticons charmap removeformat | formline | pagebreak | pageSize"].join(" "),formats:{removeformat:[{selector:"b,strong,em,i,font,u,strike,s,sub,sup,dfn,code,samp,kbd,var,cite,mark,q,del,ins,small,h1,h2,h3,h4,h5,h6,blockquote",remove:"all",split:!0,block_expand:!0,expand:!1,deep:!0},{selector:"span",attributes:["style","class"],remove:"empty",split:!0,expand:!1,deep:!0},{selector:"*",attributes:["style","class"],split:!1,expand:!1,deep:!0}]},image_caption:!0,image_title:!0,automatic_uploads:!0,images_upload_url:"/api/upload-image",images_upload_credentials:!0,image_uploadtab:!0,image_advtab:!0,images_file_types:"jpeg,jpg,png,gif,bmp,tif,t
1iff,webp,svg",image_default_style:"display: block; margin-left: auto; margin-right: auto;",image_style_formats:[{title:"Responsive",value:{style:{"max-width":"100%",height:"auto"}}}],valid_elements:"*[*]",valid_children:"+body[style],+html[style]",keep_styles:!0,preserve_cdata:!0,force_hex_style_colors:!0,theme_advanced_styles:"",verify_html:!1,cleanup:!1,convert_urls:!1,remove_script_host:!1,document_base_url:window.location.origin,height:window.matchMedia("(max-width: 575.98px), ((max-width: 1024px) and (max-height: 575.98px))").matches?"70svh":850,setup:function(n){if(!document.getElementById("tinymce-google-fonts")){const e=document.createElement("link");e.id="tinymce-google-fonts",e.rel="stylesheet",e.href="https://fonts.googleapis.com/css2?family=Abril+Fatface&family=Anton&family=Archivo+Black&family=Bangers&family=Barlow+Condensed:wght@400;600&family=Bebas+Neue&family=Comfortaa:wght@400;600&family=Cormorant+Garamond:wght@400;600&family=Crimson+Text:wght@400;600&family=DM+Sans:wght@400;600&family=EB+Garamond:wght@400;
1600&family=Fira+Mono:wght@400;500&family=Fjalla+One&family=Fredoka+One&family=Inter:wght@400;600&family=JetBrains+Mono:wght@400;500&family=Lato:wght@400;700&family=Libre+Baskerville:wght@400;700&family=Lobster&family=Lora:wght@400;600&family=Manrope:wght@400;600&family=Merriweather:wght@400;700&family=Montserrat:wght@400;600&family=Mulish:wght@400;600&family=Nunito:wght@400;600&family=Open+Sans:wght@400;600&family=Oswald:wght@400;600&family=PT+Serif:wght@400;700&family=Pacifico&family=Playfair+Display:wght@400;600&family=Poppins:wght@400;600&family=Press+Start+2P&family=Quicksand:wght@400;600&family=Raleway:wght@400;600&family=Roboto:wght@400;500&family=Roboto+Mono:wght@400;500&family=Roboto+Slab:wght@400;600&family=Source+Code+Pro:wght@400;500&family=Source+Sans+Pro:wght@400;600&family=Source+Serif+Pro:wght@400;600&family=Spectral:wght@400;600&family=Teko:wght@400;600&family=Ubuntu:wght@400;500&family=VT323&family=Work+Sans:wght@400;600&display=swap",document.head.appendChild(e)}if(!document.getElementById("tinymce-font-dropdown-styles")){const e=document.createElement("style");e.id="tinymce-font-dropdown-styles",e.textContent='\n /* Style TinyMCE font dropdown items with their actual fonts */\n .tox-collection__item[title="Montserrat"] .tox-collection__item-label { font-family: \'Montserrat\', sans-serif !important; }\n .tox-collection__item[title="Roboto"] .tox-collection__item-label { font-family: \'Roboto\', sans-serif !important; }\n .tox-collection__item[title="Open Sans"] .tox-collection__item-label { font-family: \'Open Sans\', sans-serif !important; }\n .tox-collection__item[title="Lato"] .tox-collection__item-label { font-family: \'Lato\', sans-serif !important; }\n .tox-collection__item[title="Poppins"] .tox-collection__item-label { font-family: \'Poppins\', sans-serif !important; }\n .tox-collection__item[title="Inter"] .tox-collection__item-label { font-family: \'Inter\', sans-serif !important; }\n .tox-collection__item[title="Source Sans Pro"] .tox-collection__item-label { font-family: \'Source Sans Pro\', sans-serif !important; }\n .tox-collection__item[title="Nunito"] .tox-collection__item-label { font-family: \'Nunito\', sans-serif !important; }\n .tox-collection__item[title="Work Sans"] .tox-collection__item-label { font-family: \'Work Sans\', sans-serif !important; }\n .tox-collection__item[title="Raleway"] .tox-collection__item-label { font-family: \'Raleway\', sans-serif !important; }\n .tox-collection__item[title="Ubuntu"] .tox-collection__item-label { font-family: \'Ubuntu\', sans-serif !important; }\n .tox-collection__item[title="Quicksand"] .tox-collection__item-label { font-family: \'Quicksand\', sans-serif !important; }\n .tox-collection__item[title="Mulish"] .tox-collection__item-label { font-family: \'Mulish\', sans-serif !important; }\n .tox-collection__item[title="DM Sans"] .tox-collection__item-label { font-family: \'DM Sans\', sans-serif !important; }\n .tox-collection__item[title="Manrope"] .tox-collection__item-label { font-family: \'Manrope\', sans-serif !important; }\n .tox-collection__item[title="Oswald"] .tox-collection__item-label { font-family: \'Oswald\', sans-serif !important; }\n .tox-collection__item[title="Bebas Neue"] .tox-collection__item-label { font-family: \'Bebas Neue\', sans-serif !important; }\n .tox-collection__item[title="Anton"] .tox-collection__item-label { font-family: \'Anton\', sans-serif !important; }\n .tox-collection__item[title="Archivo Black"] .tox-collection__item-label { font-family: \'Archivo Black\', sans-serif !important; }\n .tox-collection__item[title="Barlow Condensed"] .tox-collection__item-label { font-family: \'Barlow Condensed\', sans-serif !important; }\n .tox-collection__item[title="Fjalla One"] .tox-collection__item-label { font-family: \'Fjalla One\', sans-serif !important; }\n .tox-collection__item[title="Teko"] .tox-collection__item-label { font-family: \'Teko\', sans-serif !important; }\n .tox-collection__item[title="Playfair Display"] .tox-collection__item-label { font-family: \'Playfair Display\', serif !important; }\n .tox-collection__item[title="Merriweather"] .tox-collection__item-label { font-family: \'Merriweather\', serif !important; }\n .tox-collection__item[title="Lora"] .tox-collection__item-label { font-family: \'Lora\', serif !important; }\n .tox-collection__item[title="PT Serif"] .tox-collection__item-label { font-family: \'PT Serif\', serif !important; }\n .tox-collection__item[title="Crimson Text"] .tox-collection__item-label { font-family: \'Crimson Text\', serif !important; }\n .tox-collection__item[title="EB Garamond"] .tox-collection__item-label { font-family: \'EB Garamond\', serif !important; }\n .tox-collection__item[title="Libre Baskerville"] .tox-collection__item-label { font-family: \'Libre Baskerville\', serif !important; }\n .tox-collection__item[title="Source Serif Pro"] .tox-collection__item-label { font-family: \'Source Serif Pro\', serif !important; }\n .tox-collection__item[title="Cormorant Garamond"] .tox-collection__item-label { font-family: \'Cormorant Garamond\', serif !important; }\n .tox-collection__item[title="Spectral"] .tox-collection__item-label { font-family: \'Spectral\', serif !important; }\n .tox-collection__item[title="Roboto Slab"] .tox-collection__item-label { font-family: \'Roboto Slab\', serif !important; }\n .tox-collection__item[title="Pacifico"] .tox-collection__item-label { font-family: \'Pacifico\', cursive !important; }\n .tox-collection__item[title="Bangers"] .tox-collection__item-label { font-family: \'Bangers\', cursive !important; }\n .tox-collection__item[title="Fredoka One"] .tox-collection__item-label { font-family: \'Fredoka One\', cursive !important; }\n .tox-collection__item[title="Comfortaa"] .tox-collection__item-label { font-family: \'Comfortaa\', cursive !important; }\n .tox-collection__item[title="Abril Fatface"] .tox-collection__item-label { font-family: \'Abril Fatface\', cursive !important; }\n .tox-collection__item[title="Lobster"] .tox-collection__item-label { font-family: \'Lobster\', cursive !important; }\n .tox-collection__item[title="Press Start 2P"] .tox-collection__item-label { font-family: \'Press Start 2P\', cursive !important; font-size: 9px !important; }\n .tox-collection__item[title="Roboto Mono"] .tox-collection__item-label { font-family: \'Roboto Mono\', monospace !important; }\n .tox-collection__item[title="Source Code Pro"] .tox-collection__item-label { font-family: \'Source Code Pro\', monospace !important; }\n .tox-collection__item[title="Fira Mono"] .tox-collection__item-label { font-family: \'Fira Mono\', monospace !important; }\n .tox-collection__item[title="JetBrains Mono"] .tox-collection__item-label { font-family: \'JetBrains Mono\', monospace !important; }\n .tox-collection__item[title="VT323"] .tox-collection__item-label { font-family: \'VT323\', monospace !important; }\n .tox-collection__item[title="Arial"] .tox-collection__item-label { font-family: Arial, sans-serif !important; }\n .tox-collection__item[title="Helvetica"] .tox-collection__item-label { font-family: \'Helvetica Neue\', Helvetica, sans-serif !important; }\n .tox-collection__item[title="Georgia"] .tox-collection__item-label { font-family: Georgia, serif !important; }\n .tox-collection__item[title="Times New Roman"] .tox-collection__item-label { font-family: \'Times New Roman\', serif !important; }\n .tox-collection__item[title="Verdana"] .tox-collection__item-label { font-family: Verdana, sans-serif !important; }\n .tox-collection__item[title="Trebuchet MS"] .tox-collection__item-label { font-family: \'Trebuchet MS\', sans-serif !important; }\n ',document.head.appendChild(e)}function o(e){return function(...t){const n=t.map(e=>"string"==typeof e?e:String(e)).join(" ");
1n.includes("fm_star_icon54x40.png")||n.includes("file:///var/www/wsbcharts/static/images/fm_star_icon54x40.png")||e.apply(console,t)}}function a(e,t){let o=e.getAttribute("style")||"";const a={};o&&o.split(";").forEach(e=>{const t=e.indexOf(":");if(t>0){const n=e.substring(0,t).trim(),o=e.substring(t+1).trim();n&&o&&(a[n]=o)}});const i={borderRadius:"border-radius",boxShadow:"box-shadow",marginLeft:"margin-left",marginRight:"margin-right",borderBottom:"border-bottom"};Object.keys(t).forEach(e=>{a[i[e]||e]=t[e]}),a.display||(a.display="block"),a["margin-left"]||a.margin||(a["margin-left"]="auto"),a["margin-right"]||a.margin||(a["margin-right"]="auto");const r=Object.keys(a).map(e=>`${e}: ${a[e]}`).join("; ");n.undoManager.transact(function(){n.selection.select(e),n.dom.setAttrib(e,"style",r),n.nodeChanged()})}function i(){const e=n.selection.getNode();if(e.classList&&e.classList.contains("form-field-line"))return e;return n.dom.getParent(e,".form-field-line")||null}function r(e,t){["short","medium","long","full"].forEach(t=>e.classList.remove(t)),e.classList.add(t),"full"===t?(e.style.display="block",e.style.width="100%"):(e.style.display="inline-block",e.style.width=""),n.nodeChanged()}console.error=o(console.error),console.warn=o(console.warn),console.info=o(console.info),n.on("NodeChange",function(e){n.getBody().querySelectorAll("img:not([data-fm-styled])").forEach(function(e){n.dom.setAttrib(e,"data-fm-styled","true");const t=new Image;t.onload=function(){const t=this.naturalWidth;this.naturalHeight;let o="";t>700&&(o="width: 700px; height: auto;");const a="display: block; margin-left: auto; margin-right: auto;",i=o?`${a} ${o}`:a;n.undoManager.transact(function(){n.dom.setAttrib(e,"style",i),n.nodeChanged()})},t.src=e.src});n.getBody().querySelectorAll('img:not([style*="margin"])').forEach(e=>{e.style.marginLeft||e.style.marginRight||e.style.float||(e.style.display="block",e.style.marginLeft="auto",e.style.marginRight="auto")})}),n.ui.registry.addMenuButton("bodyTextSize",{text:"Body Size",tooltip:"Change body text size (paragraphs and lists only)",fetch:function(e){e(["8pt","9pt","10pt","11pt","12pt","13pt","14pt","16pt","18pt"].map(function(e){return{type:"menuitem",text:e,onAction:function(){var t=n.getBody().querySelectorAll("p, li, ul, ol");n.undoManager.transact(function(){t.forEach(function(t){t.closest("h1, h2, h3, h4, h5, h6")||(t.style.fontSize=e)}),n.nodeChanged()})}}}))}}),n.ui.registry.addMenuButton("formline",{text:"Form Line",tooltip:"Insert form lines for fill-in fields",fetch:function(e){e([{type:"menuitem",text:"Short line (dates, initials)",onAction:function(){const e=i();e?r(e,"short"):n.insertContent('<span class="form-field-line short"></span> ')}},{type:"menuitem",text:"Medium line (names)",onAction:function(){const e=i();e?r(e,"medium"):n.insertContent('<span class="form-field-line medium"></span> ')}},{type:"menuitem",text:"Long line (addresses)",onAction:function(){const e=i();e?r(e,"long"):n.insertContent('<span class="form-field-line long"></span> ')}},{type:"menuitem",text:"Full width line",onAction:function(){const e=i();e?r(e,"full"):n.insertContent('<div class="form-field-line full"></div>')}},{type:"separator"},{type:"menuitem",text:"Remove form line",onAction:function(){const e=i();e&&(n.dom.remove(e),n.nodeChanged())}},{type:"separator"},{type:"menuitem",text:"Insert 3 answer lines",onAction:function(){n.insertContent('<div class="form-field-line full"></div><div class="form-field-line full"></div><div class="form-field-line full"></div>')}}])}}),n.on("dblclick",function(e){const t=e.target;if(t.classList&&t.classList.contains("form-field-line")){const e=["short","medium","long","full"],o=e.find(e=>t.classList.contains(e))||"medium",a=(e.indexOf(o)+1)%e.length;e.forEach(e=>t.classList.remove(e)),t.classList.add(e[a]),"full"===e[a]?(t.style.display="block",t.style.width="100%"):(t.style.display="inline-block",t.style.width=""),n.nodeChanged()}}),n.ui.registry.addMenuButton("imageStyleButton",{icon:"highlight-bg-color",tooltip:"Image Styles (Select image first)",fetch:function(e){const t=n.selection.getNode();"IMG"===t.tagName?e([{type:"menuitem",text:"Remove All Styles",onAction:function(){const e=t.style.width,n=t.style.height;t.removeAttribute("style"),t.removeAttribute("class"),t.style.display="block",t.style.marginLeft="auto",t.style.marginRight="auto",e&&(t.style.width=e),n&&(t.style.height=n)}},{type:"separator"},{type:"menuitem",text:"ð Rounded Corners",onAction:function(){a(t,{borderRadius:"8px"})}},{type:"menuitem",text:"â Circular",onAction:function(){a(t,{borderRadius:"50%"})}},{type:"menuitem",text:"ð Drop Shadow",onAction:function(){a(t,{outline:"5px solid #ccc",outlineOffset:"3px"})}},{type:"menuitem",text:"ð¼ï¸ Border Frame",onAction:function(){a(t,{border:"2px s
1olid #ddd",padding:"4px"})}},{type:"menuitem",text:"⨠Rounded + Shadow",onAction:function(){a(t,{borderRadius:"12px",borderRight:"6px solid #bbb",borderBottom:"6px solid #bbb",borderLeft:"3px solid #eee",borderTop:"3px solid #eee",margin:"15px auto"})}},{type:"menuitem",text:"ð¸ Polaroid",onAction:function(){a(t,{border:"10px solid white",borderBottom:"40px solid white",borderRight:"12px solid #ddd",borderBottomColor:"#ddd",transform:"rotate(-2deg)",margin:"20px auto",display:"inline-block"})}}]):e([{type:"menuitem",text:"Select an image first",enabled:!1}])}}),n.currentPageSizeText=localStorage.getItem("formatmagic-page-size")||"Letter",n.ui.registry.addMenuButton("pageSize",{text:n.currentPageSizeText,tooltip:"Page Size",onSetup:function(e){return n.pageSizeButtonAPI=e,setTimeout(()=>{e.setText(n.currentPageSizeText)},50),function(){}},fetch:function(e){const t=M(n)||"Letter",o=[{type:"menuitem",text:'ð Letter (8.5" à 11")',onAction:function(){E(),L(n,"Letter"),n.currentPageSizeText="Letter",n.pageSizeButtonAPI&&n.pageSizeButtonAPI.setText("Letter"),T(n,"Letter")}},{type:"menuitem",text:'ð A4 (8.27" à 11.69")',onAction:function(){E(),L(n,"A4"),n.currentPageSizeText="A4",n.pageSizeButtonAPI&&n.pageSizeButtonAPI.setText("A4"),T(n,"A4")}},{type:"menuitem",text:'ð Legal (8.5" à 14")',onAction:function(){E(),L(n,"Legal"),n.currentPageSizeText="Legal",n.pageSizeButtonAPI&&n.pageSizeButtonAPI.setText("Legal"),T(n,"Legal")}},{type:"menuitem",text:'ð A3 (11.69" à 16.54")',onAction:function(){E(),L(n,"A3"),n.currentPageSizeText="A3",n.pageSizeButtonAPI&&n.pageSizeButtonAPI.setText("A3"),T(n,"A3")}},{type:"menuitem",text:'ð 6" à 9" (Book Size)',onAction:function(){E(),L(n,"6x9"),n.currentPageSizeText="6x9",n.pageSizeButtonAPI&&n.pageSizeButtonAPI.setText("6x9"),T(n,"6x9")}},{type:"separator"},{type:"menuitem",text:"âï¸ Customize Margins...",onAction:function(){B(n,t)}},{type:"separator"},{type:"menuitem",text:`Current: ${t}`,enabled:!1}],a=x(t);a&&o.push({type:"menuitem",text:`ð Custom Margins: ${a.top}/${a.right}/${a.bottom}/${a.left}in`,enabled:!1}),e(o)}}),null!==window.currentUserId&&n.ui.registry.addButton("imageLibrary",{icon:"image",tooltip:"Image Library",onAction:function(){const t=window.parent.document.getElementById("imageLibraryModal");if(t){const n=new bootstrap.Modal(t),o=t.querySelector("#deleteSelectedImagesBtn");o&&!o.dataset.listenerAttached&&(o.addEventListener("click",async()=>{const e=[...t.querySelectorAll(".image-select-checkbox:checked"),...t.querySelectorAll(".image-list-checkbox:checked")].map(e=>e.dataset.imageId);0!==e.length&&confirm(`Are you sure you want to permanently delete ${e.length} image(s)? This action cannot be undone.`)&&await bulkDeleteImages(e)}),o.dataset.listenerAttached="true"),e(),n.show(),fetchUserImages(),initializeImageSearch()}else console.error("Image Library Modal HTML not found in the main document."),alert("Error: Could not find the Image Library component.")}}),n.on("init",function(){t(n)}),n.on("KeyUp Change",function(){const e=n.getContent().length,t=n.originalCharCount;if(e-t>5e3){if(!document.getElementById("tinyMCEWarning")){const e=document.createElement("div");e.id="tinyMCEWarning",e.className="warning-message d-block mt-2",e.style.color="red",e.textContent="Warning: You have reached the maximum allowed additional text. The editor is meant for minor modifications only.",n.getContainer().parentNode.insertBefore(e,n.getContainer().nextSibling)}n.setContent(n.getContent().substring(0,t+5e3))}else{const e=document.getElementById("tinyMCEWarning");e&&e.remove()}}),n.on("init",function(){I(n)});const s=function(){const e=n.getBody();if(!e)return;const t=e.querySelectorAll(".cover-page");if(t.length<2)return;const o=n.selection.getBookmark(2,!0),a=t[0],i=t[t.length-1];let r=a.nextSibling,s=!1;for(;r&&!s;){const e=r.nextSibling,t=r===i;if(1===r.nodeType&&r.classList&&r.classList.contains("cover-page")){for(;r.firstChild;)a.appendChild(r.firstChild);r.remove()}else a.appendChild(r);t&&(s=!0),r=e}n.selection.moveToBookmark(o)};n.on("input",s),n.on("BeforeGetContent",s),n.on("keydown",function(e){if(13!==e.keyCode)return;if(e.shiftKey||e.ctrlKey||e.metaKey||e.altKey)return;const t=n.selection.getRng();if(!t.collapsed)return;let o=t.startContainer;const a=3===o.nodeType?o.parentNode:o;if(!a||!a.closest)return;const i=a.closest(".cover-page");if(!i)return;let r=a;for(;r&&r.parentNode!==i;)r=r.parentNode;if(!r||!r.parentNode)return;e.preventDefault();const s=n.getDoc(),l=!r.textContent.length;let c=!1,d=!1;if(!l){const e=s.createRange();e.setStart(r,0),e.setEnd(t.endContainer,t.endOffset),c=0===e.toString().length;const n=s.createRange();n.setStart(t.endContainer,t.endOffset),r.lastChild?n.setEndAfter(r.lastChild):n.setEnd(r,0),d=0===n.toString().length}if(c&&!l){const e=s.createElement("p");e.innerHTML='<br data-mce-bogus="1">',r.before(e)}else{const e=l||d?"p":r.tagName,o=s.createElement(e);
1if("p"===r.tagName.toLowerCase()&&r.className?o.className=r.className:l||d||!r.className||(o.className=r.className),l||d)o.innerHTML='<br data-mce-bogus="1">',r.after(o);else{const e=s.createRange();e.setStart(t.endContainer,t.endOffset),r.lastChild?e.setEndAfter(r.lastChild):e.setEnd(r,0);const n=e.extractContents();n.textContent.length>0||n.querySelector("img, br, hr")?o.appendChild(n):o.innerHTML='<br data-mce-bogus="1">',r.after(o)}n.selection.setCursorLocation(o,0)}n.undoManager.add()}),n.on("keydown",function(e){if(8!==e.keyCode)return;if(e.shiftKey||e.ctrlKey||e.metaKey||e.altKey)return;const t=n.selection.getRng();if(!t.collapsed)return;let o=t.startContainer;const a=3===o.nodeType?o.parentNode:o;if(!a||!a.closest)return;const i=a.closest(".cover-page");if(!i)return;let r=a;for(;r&&r.parentNode!==i;)r=r.parentNode;if(!r||!r.parentNode)return;const s=n.getDoc().createRange();if(s.setStart(r,0),s.setEnd(t.endContainer,t.endOffset),0!==s.toString().length)return;const l=r.previousElementSibling;if(!l)return void e.preventDefault();!l.textContent.length&&!l.querySelector("img, hr")&&(e.preventDefault(),l.remove(),n.undoManager.add())});const l=function(){const e=n.getBody();if(!e)return;[{selector:".cover-page",type:"cover"},{selector:"#toc",type:"toc"}].forEach(function(t){e.querySelectorAll(t.selector).forEach(function(e){e.querySelectorAll(".section-remove").forEach(function(e){e.remove()});const o=n.getDoc().createElement("span");o.className="section-remove",o.setAttribute("contenteditable","false"),o.setAttribute("data-mce-bogus","all"),o.setAttribute("data-section",t.type),o.setAttribute("title","Remove this section"),o.innerHTML="×",e.appendChild(o)})})};n.on("init",l),n.on("SetContent",l),n.on("click",function(e){const t=e.target&&e.target.closest?e.target.closest(".section-remove"):null;if(!t)return;e.preventDefault(),e.stopPropagation();const o=t.getAttribute("data-section"),a="cover"===o?t.closest(".cover-page"):t.closest("#toc");if(!a)return;n.undoManager.transact(function(){n.dom.remove(a)});const i=document.getElementById("cover"===o?"addCoverPage":"generateToc");i&&i.checked&&(i.checked=!1,i.dispatchEvent(new Event("change",{bubbles:!0}))),n.nodeChanged()}),[{id:"addCoverPage",selector:".cover-page"},{id:"generateToc",selector:"#toc"}].forEach(function(e){const t=document.getElementById(e.id);t&&!t.dataset.sectionSyncBound&&(t.dataset.sectionSyncBound="true",t.addEventListener("click",function(){if(t.checked)return;const n=window.tinymce?window.tinymce.get("mytextarea-editor"):null,o=n&&n.getBody();if(!o)return;const a=o.querySelectorAll(e.selector);a.length&&(n.undoManager.transact(function(){a.forEach(function(e){n.dom.remove(e)})}),n.nodeChanged())}))})}}),function(){const e=document.getElementById("templateDropdownMenu"),t=document.getElementById("templateDropdownButton");if(!e||!t)return;function n(){window.isProcessing?(t.disabled=!0,t.innerHTML="<span>Please wait document processing...</span>"):(t.disabled=!1,"<span>Please wait document processing...</span>"===t.innerHTML&&(t.innerHTML="<span>Select a template...</span>"))}async function o(){try{window.__templatesPromise||(window.__templatesPromise=fetch("/api/templates").then(e=>e.json()));const n=(await window.__templatesPromise).filter(e=>"business"===e.category||"resume"===e.category||"basictemplate"===e.category);let o=[];if(window.userSubscription&&window.userSubscription.isLoggedIn)try{const e=await fetch("/api/custom-templates/");if(e.ok){o=(await e.json()).map(e=>({id:e.template_id,title:e.name,category:"custom",image_url:e.image_url,alt_text:e.name,source:"custom"}))}}catch(e){console.log("Could not fetch custom templates")}const a=[...o,...n];g(e,a,e=>{const n=tinymce.get("mytextarea-editor");if(n){!async function(e,t){try{e.setProgressState(!0);const n=e.getContent();e.setContent('<p style="text-align: center; font-style: italic;">Applying new style...</p>');const o=document.getElementById("mytextarea-editor").parentNode,a=o.dataset.currentTaskId;if(!a)throw new Error("No active document task ID found to apply new template to.");o.dataset.currentTemplateId=t;const i=await fetch(`/api/templates/${t}/css`);if(!i.ok)throw new Error("Failed to fetch new template style.");const r=await i.json();if(!r.css)throw new Error("No CSS received from server.");await async function(e,t,n=null){try{const o=`/api/templates/${e}/update-css`,a={css:t};n&&(a.template_id=n);const i=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a),credentials:"include"});if(!i.ok){const e=await i.text();throw console.error(`Failed to update CSS via ${o}:`,e),new Error(`Failed to update document CSS: ${e}`)}await i.json()}catch(e){console.error("Error updating document CSS:",e)}}(a,r.css,t);const s=e.getDoc(),l=s.head,c=l.querySelector("#format-magic-page-size");let d=null;c&&(d=c.innerHTML);
1l.querySelectorAll("style").forEach(e=>e.remove());const m=s.createElement("style");if(m.id="custom-template-style",m.innerHTML=r.css,l.appendChild(m),d){const t=s.createElement("style");t.id="format-magic-page-size",t.innerHTML=d,l.appendChild(t);const n=M(e)||"Letter";e.currentPageSizeText=n,e.pageSizeButtonAPI&&e.pageSizeButtonAPI.setText(n),T(e,n)}e.setContent(n),e.execCommand("mceRepaint"),F()}catch(t){console.error("Error applying template:",t),e.setProgressState(!1),alert(`Failed to apply template: ${t.message}`)}finally{e.setProgressState(!1)}}(n,e.id,!1);const o=function(e){const t=document.createElement("div");t.className="d-flex align-items-center justify-content-between w-100";const n=document.createElement("div");n.className="d-flex align-items-center";const o=document.createElement("img");o.src=e.image_url,o.alt=e.alt_text||e.title,o.style.width="40px",o.style.height="50px",o.style.objectFit="cover",o.style.marginRight="10px",o.style.borderRadius="3px";const a=document.createElement("span");return a.textContent=e.title,n.appendChild(o),n.appendChild(a),t.appendChild(n),t}(e);t.innerHTML="",t.appendChild(o)}},{isLockedFn:e=>"basictemplate"===e.category&&window.userSubscription&&!window.userSubscription.isPaying,onLockedClick:()=>{!function(){const e=document.getElementById("appModal"),t=document.getElementById("appModalLabel"),n=document.getElementById("appModalBody"),o=document.getElementById("appModalFooter");if(!e)return void console.error("Modal element not found");t.textContent="Premium Feature",n.innerHTML='\n <div class="text-center">\n <div class="mb-3">\n <i class="bi bi-lock-fill" style="font-size: 48px; color: #FFD700;"></i>\n </div>\n <h5 class="mb-3">Base Template</h5>\n <p class="mb-3">\n The Base Template provide a clean and simple format for building custom templates.\n </p>\n <p class="text-muted">\n <strong>This feature is available on all paid plans.</strong>\n </p>\n </div>\n ',o.innerHTML='\n <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Maybe Later</button>\n <a href="/manage-subscription" class="btn btn-primary">\n <i class="bi bi-star-fill me-2"></i>Upgrade Now\n </a>\n ';new bootstrap.Modal(e).show()}()},defaultCategory:o.length>0?"custom":"business"})}catch(t){console.error("Error fetching templates:",t),e.innerHTML='<li class="dropdown-item">Error loading templates</li>'}}n(),o();const a=setInterval(()=>{n()},500);window.addEventListener("unload",()=>{clearInterval(a)})}()})}b?b.addEventListener("click",async function(){fetch("/api/pdf-diagnostic",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({event:"pdf_handler_executed"}),credentials:"include"}).catch(()=>{}),window.dataLayer=window.dataLayer||[],dataLayer.push({event:"generate_pdf_clicked",event_category:"Button",event_label:"Generate PDF Button Clicked"});const e=this,t=e.innerHTML;try{const t=document.getElementById("mytextarea-editor").parentNode,n=t.dataset.currentTaskId;if(!n)throw new Error("No task ID found. Please try refreshing the page.");const o="true"===t.dataset.isSharedDocument,a=!o||document.getElementById("updateSharedVersion").checked;e.disabled=!0,e.innerHTML='<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span>Generating PDF...';let i=tinymce.get("mytextarea-editor").getContent();const r=(new DOMParser).parseFromString(i,"text/html");r.querySelectorAll("img").forEach(e=>{const t=e.getAttribute("width"),n=e.getAttribute("height");t?(e.style.setProperty("width",`${t}px`,"important"),e.style.setProperty("height","auto","important")):n&&e.style.setProperty("height",`${n}px`,"important")}),i=r.body.innerHTML;const s=tinymce.get("mytextarea-editor"),l=s?M(s):"Letter",c=x(l),d="true"===localStorage.getItem("formatmagic-user-chose-page-size"),m=await fetch("/generate-pdf",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({edited_content:i,task_id:n,addPageNumbers:document.getElementById("addPageNumbers").checked,addCoverPage:!!document.getElementById("addCoverPage")&&document.getElementById("addCoverPage").checked,generateToc:!!document.getElementById("generateToc")&&document.getElementById("generateToc").checked,tocMaxLevel:parseInt(document.getElementById("tocMaxLevel")?.value,10)||3,landscapeMode:document.getElementById("landscapeMode").checked,pageSize:l,customPadding:c,userExplicitlyChosePageSize:d,update_shared:a}),credentials:"include"});if(!m.ok){const e=await m.json();throw console.error("Server response:",e),new Error(e.detail||`Server error: ${m.status}`)}const u=await m.json();if(u.refreshed_content){const e=tinymce.get("mytextarea-editor");e&&e.setContent(u.refreshed_content,{format:"raw"})}if(!u.pdf_task_id)throw new Error("No PDF task ID received");{const n=document.getElementById("pdfGenerationNotification");if(n&&(n.innerHTML='\n <div class="d-flex align-items-center justify-content-center">\n <div class="spinner-border spinner-border-sm text-primary me-2" role="status">
1\n <span class="visually-hidden">Loading...</span>\n </div>\n <span>Preparing your PDF...</span>\n </div>\n ',n.className="alert alert-info",n.style.display="block"),window.ensurePdfMode&&await window.ensurePdfMode(),await getPDF(u.pdf_task_id,u.original_task_id),F(),e.innerHTML="PDF Generated Successfully",setTimeout(()=>{const e=document.getElementById("pdfGenerationNotification");e&&(e.style.display="none",e.className="alert alert-info",e.innerHTML='\n <div class="d-flex align-items-center justify-content-center">\n <div class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></div>\n <span>Generating your PDF. Please wait...</span>\n </div>\n ')},4e3),o&&a){const e=tinymce.get("mytextarea-editor");if(e){const n=e.getContent();t.dataset.originalContentHash=j(n);const o=document.getElementById("shared-content-warning");o&&(o.style.display="none")}}z(),setTimeout(async()=>{try{const e=document.getElementById("documentsDashboardCollapse");if(e&&!e.classList.contains("show")){const e=await fetch("/api/documents");if(e.ok){const t=await e.json();if(t&&1===t.length){const e=document.querySelector('[data-bs-target="#documentsDashboardCollapse"]');e&&e.click()}}}}catch(e){console.log("Error checking for auto-open:",e)}},200)}}catch(t){console.error("PDF generation error:",t),console.error("Error stack:",t.stack),e.innerHTML="Error Generating PDF";const n=document.getElementById("pdfGenerationNotification");n&&(n.style.display="none",n.className="alert alert-info",n.innerHTML='\n <div class="d-flex align-items-center justify-content-center">\n <div class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></div>\n <span>Generating your PDF. Please wait...</span>\n </div>\n '),window.alert("Failed to generate PDF: "+(t.message||"Unknown error occurred"))}finally{setTimeout(()=>{e.disabled=!1,e.innerHTML=t},2e3)}}):console.error("PDF generation button not found");let D=null;function $(){if("undefined"==typeof tinymce)return!1;const e=tinymce.get("word-editor");if(e&&e.initialized&&!e.destroyed)try{if(e.isDirty())return!0}catch(e){console.warn("Error checking Word editor state:",e)}const t=tinymce.get("mytextarea-editor");if(!t)return!1;if(!t.initialized||t.destroyed)return!1;try{const e=j(t.getContent());return null!==D&&e!==D}catch(e){return console.warn("Error checking for unsaved changes:",e),!1}}function F(){const e=tinymce.get("mytextarea-editor");e&&(D=j(e.getContent()))}window.markContentAsSaved=F,window.hasUnsavedChanges=$,window.addEventListener("beforeunload",e=>!t&&isProcessing?(e.preventDefault(),e.returnValue="Changes you made may not be saved."):!t&&$()?(e.preventDefault(),e.returnValue="You have unsaved changes in your document. Create a PDF to save your work."):void 0);const H=document.getElementById("document-list-container"),N=document.getElementById("documentsDashboardCollapse");async function z(){const e=document.getElementById("document-list-container");if(e){e.innerHTML='<div class="text-center"><div class="spinner-border" role="status"><span class="visually-hidden">Loading...</span></div></div>';try{const t=await fetch("/api/documents");if(t.ok){const n=await t.json();n&&n.length>0?function(e){const t=document.getElementById("document-list-container");if(!t)return;const n=`\n <div class="mb-3">\n <div class="input-group input-group-sm">\n <span class="input-group-text">\n <i class="bi bi-search"></i>\n </span>\n <input type="text" class="form-control" id="document-search-input" placeholder="Search documents by title...">\n <button class="btn btn-outline-secondary" type="button" id="clear-search-btn" style="display: none;">\n <i class="bi bi-x-lg"></i>\n </button>\n </div>\n <div id="search-results-info" class="text-muted small mt-1" style="display: none;"></div>\n </div>\n <div id="bulk-action-bar" class="d-flex justify-content-between align-items-center p-2 border-bottom" style="display: none;">\n <div>\n <input class="form-check-input" type="checkbox" id="select-all-checkbox">\n <label class="form-check-label ms-2" for="select-all-checkbox">Select All</label>\n </div>\n <button type="button" class="btn btn-danger btn-sm" id="bulk-delete-btn">\n <i class="bi bi-trash-fill"></i> Delete Selected\n </button>\n </div>\n <div class="list-group list-group-flush" style="max-height: 250px; overflow-y: auto;">\n ${e.map(e=>`\n <div class="list-group-item d-flex justify-content-between align-items-center" data-task-id="${e.task_id}">\n <div class="form-check">\n <input class="form-check-input document-checkbox" type="checkbox" value="${e.task_id}">\n </div>\n <div class="flex-grow-1 ms-2 me-2 text-truncate text-start">
1\n <span class="document-title text-truncate d-block">\n <h6 class="mb-0 d-inline text-truncate">${R(e.title)||"Untitled Document"}</h6>${e.native_word?' <span class="badge bg-primary align-text-bottom">Word</span>':""}\n </span>\n <span class="edit-title-form" style="display: none;">\n <input type="text" class="form-control form-control-sm" value="${R(e.title)||"Untitled Document"}" maxlength="60">\n <small class="char-counter text-muted ms-2"></small>\n </span>\n ${e.share_url?`\n <div class="input-group input-group-sm mt-1">\n <span class="input-group-text bg-transparent border-end-0">\n <i class="bi bi-share-fill text-success"></i>\n </span>\n <input type="text" class="form-control form-control-sm border-start-0" value="${e.share_url}" readonly>\n <button class="btn btn-outline-secondary copy-document-link-btn" type="button" title="Copy share link">\n <i class="bi bi-clipboard"></i>\n </button>\n </div>\n `:""}\n <small class="text-muted ms-2">${new Date(e.created_at).toLocaleDateString()}</small>\n </div>\n <div class="flex-shrink-0">\n \x3c!-- Desktop buttons (hidden on small screens) --\x3e\n <span class="document-actions d-none d-md-inline">\n <button type="button" class="btn btn-sm load-document-btn" data-task-id="${e.task_id}" data-native-word="${e.native_word?"true":"false"}">Load</button>\n ${e.native_word?`<a href="/api/native-word/download/${e.task_id}" class="btn btn-outline-primary btn-sm ms-1" title="Download Word"><i class="bi bi-file-word"></i></a><button type="button" class="btn btn-outline-danger btn-sm ms-1 native-word-pdf-btn" data-task-id="${e.task_id}" title="Download PDF"><i class="bi bi-file-pdf"></i></button>`:""}\n ${e.has_pdf?`<a href="/download/document/${e.task_id}" class="btn btn-outline-danger btn-sm ms-1 download-pdf-btn" data-task-id="${e.task_id}" title="Download PDF"><i class="bi bi-file-pdf"></i></a>`:""}\n ${window.featureFlags?.wordConversionEnabled?e.has_word?e.word_stale?`<span class="btn-group ms-1">\n <a href="/api/word/download/${e.task_id}" class="btn btn-outline-warning btn-sm download-word-btn" data-task-id="${e.task_id}" title="Download Word (outdated â PDF has changed)"><i class="bi bi-file-word"></i><i class="bi bi-exclamation-triangle ms-1" style="font-size: 0.65rem;"></i></a>\n <button type="button" class="btn btn-outline-warning btn-sm recreate-word-btn" data-task-id="${e.task_id}" title="Convert to Word from latest PDF"><i class="bi bi-arrow-clockwise"></i></button>\n </span>`:`<a href="/api/word/download/${e.task_id}" class="btn btn-outline-primary btn-sm ms-1 download-word-btn" data-task-id="${e.task_id}" title="Download Word"><i class="bi bi-file-word"></i></a>`:e.has_pdf?`<button type="button" class="btn btn-outline-secondary btn-sm ms-1 convert-word-btn" data-task-id="${e.task_id}" title="Convert to Word"><i class="bi bi-file-word"></i><i class="bi bi-plus" style="font-size: 0.65rem; vertical-align: top;"></i></button>`:"":""}\n <button type="button" class="btn btn-sm rename-document-btn ms-1" data-task-id="${e.task_id}">Rename</button>\n ${e.share_url?`<button type="button" class="btn btn-sm share-document-btn btn-shared ms-1" data-task-id="${e.task_id}" data-native-word="${e.native_word?"true":"false"}"${e.share_stale?' title="Your share link does not include your latest changes - click to update it"':""}>Shared${e.share_stale?'<i class="bi bi-exclamation-triangle-fill text-warning ms-1" style="font-size: 0.65rem;"></i>':""}</button>`:`<button type="button" class="btn btn-sm share-document-btn ms-1" data-task-id="${e.task_id}" data-native-word="${e.native_word?"true":"false"}">Share</button>`}\n ${e.has_pdf||e.has_word?`\n <div class="btn-group ms-1">\n <button type="button" class="btn btn-danger btn-sm delete-document-btn" data-task-id="${e.task_id}">Delete</button>\n <button type="button" class="btn btn-danger btn-sm dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
1\n <span class="visually-hidden">Toggle delete options</span>\n </button>\n <ul class="dropdown-menu dropdown-menu-end">\n <li><button class="dropdown-item delete-document-btn" type="button" data-task-id="${e.task_id}">\n <i class="bi bi-trash me-2"></i>Delete All\n </button></li>\n ${e.has_pdf?`<li><button class="dropdown-item delete-pdf-btn" type="button" data-task-id="${e.task_id}">\n <i class="bi bi-file-pdf me-2 text-danger"></i>Delete PDF\n </button></li>`:""}\n ${e.has_word?`<li><button class="dropdown-item delete-word-btn" type="button" data-task-id="${e.task_id}">\n <i class="bi bi-file-word me-2 text-primary"></i>Delete Word\n </button></li>`:""}\n </ul>\n </div>`:`\n <button type="button" class="btn btn-danger btn-sm delete-document-btn ms-1" data-task-id="${e.task_id}">Delete</button>`}\n </span>\n\n \x3c!-- Mobile dropdown (hidden on medium+ screens) --\x3e\n <div class="dropdown d-md-none">\n <button class="btn btn-outline-secondary btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">\n <i class="bi bi-three-dots-vertical"></i>\n </button>\n <ul class="dropdown-menu dropdown-menu-end">\n <li><button class="dropdown-item load-document-btn" type="button" data-task-id="${e.task_id}" data-native-word="${e.native_word?"true":"false"}">\n <i class="bi bi-folder-open me-2"></i>Load\n </button></li>\n ${e.native_word?`<li><a class="dropdown-item" href="/api/native-word/download/${e.task_id}">\n <i class="bi bi-file-word me-2 text-primary"></i>Download Word\n </a></li><li><button class="dropdown-item native-word-pdf-btn" type="button" data-task-id="${e.task_id}">\n <i class="bi bi-file-pdf me-2 text-danger"></i>Download PDF\n </button></li>`:""}\n ${e.has_pdf?`<li><a class="dropdown-item" href="/download/document/${e.task_id}">\n <i class="bi bi-file-pdf me-2 text-danger"></i>Download PDF\n </a></li>`:""}\n ${window.featureFlags?.wordConversionEnabled&&e.has_
1word?`<li><a class="dropdown-item" href="/api/word/download/${e.task_id}">\n <i class="bi bi-file-word me-2 ${e.word_stale?"text-warning":"text-primary"}"></i>Download Word${e.word_stale?" (outdated)":""}\n </a></li>`:""}\n ${window.featureFlags?.wordConversionEnabled&&e.has_word&&e.word_stale?`<li><button class="dropdown-item recreate-word-btn" type="button" data-task-id="${e.task_id}">\n <i class="bi bi-arrow-clockwise me-2 text-warning"></i>Convert to Word from latest PDF\n </button></li>`:""}\n ${window.featureFlags?.wordConversionEnabled&&e.has_pdf&&!e.has_word?`<li><button class="dropdown-item convert-word-btn" type="button" data-task-id="${e.task_id}">\n <i class="bi bi-file-word me-2 text-secondary"></i>Convert to Word\n </button></li>`:""}\n <li><button class="dropdown-item rename-document-btn" type="button" data-task-id="${e.task_id}">\n <i class="bi bi-pencil me-2"></i>Rename\n </button></li>\n <li><button class="dropdown-item share-document-btn" type="button" data-task-id="${e.task_id}" data-native-word="${e.native_word?"true":"false"}">\n <i class="bi bi-share me-2"></i>${e.share_url?"Shared":"Share"}${e.share_stale?' <i class="bi bi-exclamation-triangle-fill text-warning" style="font-size: 0.65rem;" title="Your share link does not include your latest changes - click to update it"></i>':""}\n </button></li>\n <li><hr class="dropdown-divider"></li>\n <li><button class="dropdown-item text-danger delete-document-btn" type="button" data-task-id="${e.task_id}">\n <i class="bi bi-trash me-2"></i>Delete All\n </button></li>\n ${e.has_pdf?`<li><button class="dropdown-item delete-pdf-btn" type="button" data-task-id="${e.task_id}">\n <i class="bi bi-file-pdf me-2 text-danger"></i>Delete PDF\n </button></li>`:""}\n ${e.has_word?`<li><button class="dropdown-item delete-word-btn" type="button" data-task-id="${e.task_id}">\n <i class="bi bi-file-word me-2 text-primary"></i>Delete Word\n </button></li>`:""}\n </ul>\n </div>\n \n <span class="edit-actions" style="display: none;">\n <button type="button" class="btn btn-success btn-sm save-title-btn">Save</button>\n <button type="button" class="btn btn-secondary btn-sm cancel-edit-btn ms-1">Cancel</button>\n </span>\n </div>\n </div>\n `).join("")}\n </div>\n `;t.innerHTML=n,function(){const e=document.getElementById("document-search-input"),t=document.getElementById("clear-search-btn"),n=document.getElementById("search-results-info");if(!e)return;e.addEventListener("input",function(){const e=this.value.trim().toLowerCase();O(e),e?t.style.display="block":(t.style.display="none",n.style.display="none")}),t.addEventListener("click",function(){e.value="",t.style.display="none",n.style.display="none",O(""),e.focus()}),e.addEventListener("keydown",function(e){"Escape"===e.key&&(this.value="",t.style.display="none",n.style.display="none",O(""))})}()}(n):e.innerHTML='<p class="text-center text-muted mt-3">You do not have any saved documents. Ensure the Save Documents check box above is selected in order to save your documents.</p>'}else e.innerHTML='<p class="text-center text-danger mt-3">Could not load documents.</p>'}catch(t){console.error("Error fetching documents:",t),e.innerHTML='<p class="text-center text-danger mt-3">Error fetching documents.</p>'}}}function O(e){const t=document.querySelectorAll(".list-group-item[data-task-id]"),n=document.getElementById("search-results-info");let o=0,a=t.length;t.forEach(t=>{const n=t.querySelector(".document-title h6");if(!n)return;const a=n.textContent.toLowerCase();!e||a.includes(e)?(t.classList.remove("hidden"),o++):t.classList.add("hidden")}),e?(0===o?(n.textContent="No documents found",n.className="text-danger small mt-1"):o===a?(n.textContent=`Showing all ${a} document${1===a?"":"s"}`,n.className="text-muted small mt-1"):(n.textContent=`Showing ${o} of ${a} document${1===a?"":"s"}`,n.className="text-success small mt-1"),n.style.display="block"):n.style.display="none"}function R(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function q(e,t){const n=e.querySelector(".document-title"),o=e.querySelector(".edit-title-form"),a=e.querySelector(".document-actions"),i=e.querySelector(".edit-actions");
1if(n.style.display=t?"none":"inline",o.style.display=t?"inline-block":"none",a.style.display=t?"none":"inline-block",i.style.display=t?"inline-block":"none",!t){const e=n.querySelector("h6").textContent;o.querySelector("input").value=e}}function j(e){let t=0;for(let n=0;n<e.length;n++)t=(t<<5)-t+e.charCodeAt(n),t|=0;return t.toString()}async function W(e,t,n){const o="pdf"===t?"PDF":"Word document",a=document.getElementById("appModal"),i=bootstrap.Modal.getInstance(a)||new bootstrap.Modal(a);document.getElementById("appModalLabel").textContent=`Delete ${o}`,document.getElementById("appModalBody").innerHTML=`<p>Are you sure you want to delete the ${o} for this document? The document itself will not be deleted.</p>`,document.getElementById("appModalFooter").style.display="flex";let r=document.getElementById("appModalPrimaryBtn");r.textContent="Delete",r.className="btn btn-danger";const s=r.cloneNode(!0);r.parentNode.replaceChild(s,r),r=s,r.addEventListener("click",async function(){r.disabled=!0,r.innerHTML='<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Deleting...';try{const n=await fetch(`/api/documents/${e}/${t}`,{method:"DELETE",credentials:"include"});if(!n.ok){const e=await n.json().catch(()=>({detail:`Failed to delete ${o}.`}));throw new Error(e.detail)}i.hide(),z()}catch(e){const t=document.createElement("div");t.className="alert alert-danger mt-3",t.textContent=`Error: ${e.message}`,document.getElementById("appModalBody").appendChild(t),r.disabled=!1,r.textContent="Delete"}},{once:!0}),a.addEventListener("hidden.bs.modal",function e(){let t=document.getElementById("appModalPrimaryBtn");t.disabled=!1,t.textContent="Save Changes",t.className="btn btn-primary";const n=document.getElementById("appModalBody").querySelector(".alert-danger");n&&n.remove(),a.removeEventListener("hidden.bs.modal",e)},{once:!0}),i.show()}async function G(e,t){window.featureFlags?.wordConversionAcknowledged?await U(e,t):window.showWordAcknowledgmentModal(async()=>{await U(e,t)})}async function U(e,t){const n=t.innerHTML;t.innerHTML='<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>',t.disabled=!0;try{const o=await fetch(`/api/word/convert/${e}`,{method:"POST",credentials:"include"});if(o.ok){const t=document.createElement("a");t.href=`/api/word/download/${e}`,t.click(),z()}else{const e=await o.json().catch(()=>({detail:"Failed to convert to Word."}));alert(`Error: ${e.detail}`),t.innerHTML=n,t.disabled=!1}}catch(e){console.error("Error converting to Word:",e),alert("An error occurred while converting to Word."),t.innerHTML=n,t.disabled=!1}}N&&N.addEventListener("show.bs.collapse",function(){z()}),window.fetchUserDocuments=z,H&&(H.addEventListener("input",function(e){const t=e.target;if(t.matches(".edit-title-form input")){const e=t.closest(".edit-title-form");if(e){const n=e.querySelector(".char-counter"),o=t.value.length,a=t.maxLength;n&&(n.textContent=`${o}/${a}`,n.style.color=o>a?"red":"")}}}),H.addEventListener("click",function(e){const t=e.target.closest(".load-document-btn");if(t){const e=t.dataset.taskId;e&&("true"===t.dataset.nativeWord?function(e,t){const n=document.getElementById("outputTypeWord");if(!n)return void alert("Word output is not available right now.");n.checked||(n.checked=!0,n.dispatchEvent(new Event("change",{bubbles:!0})));document.querySelectorAll(".load-document-btn").forEach(e=>{e.classList.remove("btn-success"),e.classList.add("btn-primary"),e.innerHTML="Load",e.disabled=!1}),t&&(t.innerHTML='<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span>Loading...',t.disabled=!0);const o=e=>{t&&(t.disabled=!1,e?(t.classList.remove("btn-primary"),t.classList.add("btn-success"),t.innerHTML="Loaded"):t.innerHTML="Load")},a=Date.now();!function t(){window.__wordMode&&window.__wordMode.openSaved?Promise.resolve(window.__wordMode.openSaved(e)).then(e=>o(!0===e)).catch(()=>o(!1)):Date.now()-a<1e4?setTimeout(t,100):(o(!1),alert("Word mode could not be loaded. Please try again."))}()}(e,t):async function(e,t){if($()){if(!confirm("You have unsaved changes in your current document. If you load a different document, your changes will be lost.\n\nClick 'Create PDF' first to save your work, or click OK to proceed without saving."))return}const n=document.getElementById("outputTypePdf");n&&!n.checked&&(n.checked=!0,n.dispatchEvent(new Event("change",{bubbles:!0})));const o="Load";
1document.querySelectorAll(".load-document-btn").forEach(e=>{e.classList.remove("btn-success"),e.classList.add("btn-primary"),e.innerHTML=o,e.disabled=!1}),t&&(t.innerHTML='<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span>Loading...',t.disabled=!0);try{await h(),tinymce.get("mytextarea-editor")&&tinymce.remove("#mytextarea-editor"),await A();const n=await fetch(`/api/documents/${e}`);if(!n.ok)throw new Error(`Failed to fetch document. Status: ${n.status}`);const o=await n.json(),a=(new DOMParser).parseFromString(o.html_content,"text/html"),i=a.querySelector("style")?.innerHTML||"",r=a.body.innerHTML,s=tinymce.get("mytextarea-editor");if(!s)throw new Error("TinyMCE editor instance not found after attempting to initialize.");{const n=s.getDoc();let o=n.getElementById("custom-doc-style");o||(o=n.createElement("style"),o.id="custom-doc-style",n.head.appendChild(o)),o.innerHTML=i;const a=await window.replaceImageMarkers(r);s.setContent(a),F();const l=document.getElementById("mytextarea-editor").parentNode;if(l){l.dataset.currentTaskId=e,l.dataset.isLoadedDocument="true";const t=document.querySelector(`.list-group-item[data-task-id="${e}"]`);if(t){const e=t.querySelector(".share-document-btn"),n=e&&e.classList.contains("btn-success");l.dataset.isSharedDocument=n?"true":"false";const o=document.getElementById("shared-document-controls");if(o&&(o.style.display=n?"block":"none"),n){const e=s.getContent();l.dataset.originalContentHash=j(e);const t=document.getElementById("shared-content-warning");t&&(t.style.display="none"),s.on("change",function(){const e=j(s.getContent())!==l.dataset.originalContentHash,t=document.getElementById("shared-content-warning");if(t&&(t.style.display=e?"block":"none"),e){const e=document.getElementById("updateSharedVersion");e&&(e.checked=!0)}})}}}document.getElementById("formattedContentContainer").style.display="block";const c=document.getElementById("reviseOutputCollapse");if(c){(bootstrap.Collapse.getInstance(c)||new bootstrap.Collapse(c)).show()}t&&(t.classList.remove("btn-primary"),t.classList.add("btn-success"),t.innerHTML="Loaded",t.disabled=!1)}}catch(e){console.error("Error loading document:",e),alert("An error occurred while loading the document. Please try again."),t&&(t.innerHTML=o,t.disabled=!1)}}(e,t))}const n=e.target.closest(".rename-document-btn");if(n){const e=n.closest(".list-group-item");q(e,!0);const t=e.querySelector(".edit-title-form input");t&&t.dispatchEvent(new Event("input",{bubbles:!0}))}const o=e.target.closest(".save-title-btn");if(o){const e=o.closest(".list-group-item"),t=e.querySelector(".edit-title-form input").value;!async function(e,t,n){const o=t.trim();if(!o)return void alert("Document title cannot be empty.");if(o.length>60)return void alert("Document title cannot exceed 60 characters.");try{const t=await fetch(`/api/documents/${e}/rename`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({title:o}),credentials:"include"});if(!t.ok){const e=await t.json();throw new Error(e.detail||"Failed to update title")}const a=await t.json();n.querySelector(".document-title h6").textContent=R(a.title),q(n,!1)}catch(e){console.error("Error updating document title:",e),alert(`Error: ${e.message}`),q(n,!1)}}(e.dataset.taskId,t,e)}const a=e.target.closest(".cancel-edit-btn");if(a){q(a.closest(".list-group-item"),!1)}const i=e.target.closest(".delete-document-btn");if(i){const e=i.dataset.taskId;e&&async function(e,t){const n=document.getElementById("appModal"),o=bootstrap.Modal.getInstance(n)||new bootstrap.Modal(n);document.getElementById("appModalLabel").textContent="Confirm Deletion",document.getElementById("appModalBody").innerHTML="<p>Are you sure you want to delete this document? This action cannot be undone.</p>",document.getElementById("appModalFooter").style.display="flex";let a=document.getElementById("appModalPrimaryBtn");a.textContent="Delete",a.className="btn btn-danger";const i=a.cloneNode(!0);a.parentNode.replaceChild(i,a),a=i,a.addEventListener("click",async function(){a.disabled=!0,a.innerHTML='<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Deleting...';try{const n=await fetch(`/api/documents/${e}`,{method:"DELETE",headers:{},credentials:"include"});if(!n.ok){const e=await n.json().catch(()=>({detail:"Failed to delete document."}));throw new Error(e.detail)}o.hide(),t.closest(".list-group-item").remove()}catch(e){const t=document.createElement("div");t.className="alert alert-danger mt-3",t.textContent=`Error: ${e.message}`,document.getElementById("appModalBody").appendChild(t),a.disabled=!1,a.textContent="Delete"}},{once:!0}),n.addEventListener("hidden.bs.modal",function e(){let t=document.getElementById("appModalPrimaryBtn");t.disabled=!1,t.textContent="Save Changes",t.className="btn btn-primary";const o=document.getElementById("appModalBody").querySelector(".alert-danger");o&&o.remove(),n.removeEventListener("hidden.bs.modal",e)},{once:!0}),o.show()}(e,i)}const r=e.target.closest(".delete-pdf-btn");if(r){const e=r.dataset.taskId;e&&W(e,"pdf")}const s=e.target.closest(".delete-word-btn");if(s){const e=s.dataset.taskId;e&&W(e,"word")}const l=e.target.closest(".recreate-word-btn");if(l&&window.featureFlags?.wordConversionEnabled){const e=l.dataset.taskId;e&&G(e,l)}
1const c=e.target.closest(".convert-word-btn");if(c&&window.featureFlags?.wordConversionEnabled){const e=c.dataset.taskId;e&&G(e,c)}const d=e.target.closest(".share-document-btn");if(d){const e=d.dataset.taskId;e&&async function(e,t){const n=t.innerHTML;t.innerHTML='<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>',t.disabled=!0;try{if("true"===t.dataset.nativeWord&&window.__wordMode?.isCurrent?.(e)){if(!await window.__wordMode.persistEdits(e))return}const n=await fetch(`/api/documents/${e}/share`,{method:"POST",headers:{},credentials:"include"});if(!n.ok){const e=await n.json().catch(()=>({detail:"Failed to create share link."}));throw new Error(e.detail)}const o=(await n.json()).share_url,a=document.getElementById("appModal"),i=new bootstrap.Modal(a);document.getElementById("appModalLabel").textContent="Share Your Document";document.getElementById("appModalBody").innerHTML=`\n <p class="text-muted">Anyone with this link can view the generated PDF.</p>\n <div class="input-group mb-3">\n <input type="text" class="form-control" value="${o}" id="shareLinkInput" readonly>\n <button class="btn btn-outline-secondary" type="button" id="copyShareLinkBtn">\n <i class="bi bi-clipboard"></i> Copy\n </button>\n </div>\n <div class="alert alert-warning mt-3" role="alert">\n <i class="bi bi-exclamation-triangle-fill me-2"></i>\n <strong>Important:</strong> ${"true"===t.dataset.nativeWord?"This link shares a PDF snapshot of your document as it is right now. If you edit the document later, click Share again to refresh the link with your latest changes.":"This link shares the most recently generated PDF. If you've edited the content since last creating the PDF, those changes won't appear. Please generate a new PDF to ensure the link is up-to-date."}\n </div>\n `;const r=document.getElementById("appModalFooter");r.style.display="none",i.show(),document.getElementById("copyShareLinkBtn").addEventListener("click",function(){document.getElementById("shareLinkInput").select(),document.execCommand("copy"),this.innerHTML='<i class="bi bi-check-lg"></i> Copied!',setTimeout(()=>{this.innerHTML='<i class="bi bi-clipboard"></i> Copy'},2e3)}),a.addEventListener("hidden.bs.modal",()=>{r.style.display="flex",z()},{once:!0})}catch(e){console.error("Error sharing document:",e),alert(`An error occurred: ${e.message}`)}finally{t.innerHTML=n,t.disabled=!1}}(e,d)}const m=e.target.closest(".native-word-pdf-btn");if(m){const e=m.dataset.taskId;e&&async function(e,t){const n=t.innerHTML;t.innerHTML='<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>',t.disabled=!0;try{if(window.__wordMode?.isCurrent?.(e))return void await window.__wordMode.downloadPdf(e);const t=await fetch(`/api/native-word/download/${e}?format=pdf`,{credentials:"include"});if(!t.ok){const e=await t.json().catch(()=>({detail:"PDF conversion failed. Please try again."}));throw new Error(e.detail)}const n=await t.blob(),o=URL.createObjectURL(n),a=document.createElement("a");a.href=o;let i="formatted-document.pdf";const r=t.headers.get("Content-Disposition");if(r){const e=r.match(/filename\*=UTF-8''(.+?)(?:;|$)/i),t=r.match(/filename="?([^";]+)"?/);if(e)try{i=decodeURIComponent(e[1])}catch(e){}else t&&(i=t[1])}a.download=i,a.click(),URL.revokeObjectURL(o)}catch(e){console.error("Error downloading PDF:",e),alert(`An error occurred: ${e.message}`)}finally{t.innerHTML=n,t.disabled=!1}}(e,m)}const u=e.target.closest(".copy-document-link-btn");if(u){const e=u.previousElementSibling.value;e&&navigator.clipboard.writeText(e).then(()=>{const e=u.innerHTML;u.innerHTML='<i class="bi bi-check-lg"></i>',u.disabled=!0,setTimeout(()=>{u.innerHTML=e,u.disabled=!1},2e3)}).catch(e=>{console.error("Failed to copy share link: ",e),alert("Failed to copy link.")})}})),window.showWordAcknowledgmentModal=function(e){const t=document.getElementById("appModal");if(!t)return void e();const n=bootstrap.Modal.getInstance(t)||new bootstrap.Modal(t);document.getElementById("appModalLabel").textContent="Word Conversion â Before You Start",document.getElementById("appModalBody").innerHTML='\n <p>Word conversions preserve your document\'s visual formatting, but they work differently from documents built natively in Word. A few things to know:</p>\n <ul class="mb-3">\n <li><strong>Heading styles</strong> may not appear in Word\'s Styles picker, so you can\'t add new headings from the ribbon. <strong>Workaround:</strong> copy and paste an existing heading, then edit the text directly.</li>\n <li><strong>Decorative elements</strong> (gradients, borders, shapes) are embedded as images and can\'t be edited as text</li>\n <li><strong>Complex layouts</strong> may not reflow perfectly when edited</li>\n <li>For best results, use these documents for <strong>sharing and light editing</strong> rather than as working templates</li>\n <li><strong>Third-party processing</strong> â your PDF is sent to <a href="https://acrobat.adobe.com/link/acrobat/pdf-to-word?x_api_client_id=adobe_com&x_api_client_location=pdf_to_word" target="_blank" rel="noopener noreferrer">Adobe\'s PDF Services</a> for conversion</li>\n </ul>\n <p class="mb-3"><a href="/word-conversion-info" target="_blank">Read full details</a></p>\n <div class="form-check">\n <input class="form-check-input" type="checkbox" id="wordAcknowledgeCheck">\n <label class="form-check-label" for="wordAcknowledgeCheck">\n I understand these limitations\n </label>\n </div>\n ';const o=document.getElementById("appModalFooter");o.style.display="flex";let a=document.getElementById("appModalPrimaryBtn");const i=a.cloneNode(!0);a.parentNode.replaceChild(i,a),a=i,a.textContent="Convert to Word",a.className="btn btn-primary",a.disabled=!0,document.getElementById("wordAcknowledgeCheck").addEventListener("change",function(){a.disabled=!this.checked}),a.addEventListener("click",async function(){a.disabled=!0,a.innerHTML='<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Saving...';try{await fetch("/api/word/acknowledge",{method:"POST",credentials:"include"}),window.featureFlags.wordConversionAcknowledged=!0}catch(e){console.warn("Failed to save acknowledgment:",e)}n.hide(),await e()},{once:!0});const r=o.querySelector(".btn-secondary");r&&(r.textContent="Cancel"),t.addEventListener("hidden.bs.modal",function e(){const n=document.getElementById("appModalPrimaryBtn");n&&(n.textContent="Save changes",n.className="btn btn-primary",n.disabled=!1);const o=document.getElementById("appModalFooter")?.querySelector(".btn-outline-secondary, .btn-secondary");o&&(o.textContent="Close",o.className="btn btn-secondary"),t.removeEventListener("hidden.bs.modal",e)},{once:!0}),n.show()};const V=document.getElementById("generateToc"),J=document.getElementById("tocMaxLevelContainer");if(V&&J){const e=function(){J.style.display=V.checked?"block":"none"};V.addEventListener("change",e),e()}H&&(H.addEventListener("change",function(e){const t=e.target;(t.matches("#select-all-checkbox")||t.matches(".document-checkbox"))&&setTimeout(()=>{!function(e){const t=document.getElementById("document-list-container");if(!t)return;const n=t.querySelector("#bulk-action-bar"),o=t.querySelector("#select-all-checkbox"),a=Array.from(t.querySelectorAll(".document-checkbox"));
1e&&e.target===o&&a.forEach(e=>{e.checked=o.checked});const i=a.filter(e=>e.checked).length;o.checked=i===a.length&&a.length>0,i>0?(n.style.display="flex",t.querySelectorAll(".list-group-item").forEach(e=>{const t=e.querySelector(".document-actions");t&&(t.style.display="none")})):(n.style.display="none",t.querySelectorAll(".list-group-item").forEach(e=>{const t=e.querySelector(".document-actions");t&&(t.style.display="inline-block")}))}(e)},0)}),H.addEventListener("click",function(e){e.target.matches("#bulk-delete-btn")&&async function(){const e=document.getElementById("document-list-container"),t=Array.from(e.querySelectorAll(".document-checkbox:checked")).map(e=>e.value);if(0===t.length)return void alert("Please select documents to delete.");const n=document.getElementById("appModal"),o=bootstrap.Modal.getInstance(n)||new bootstrap.Modal(n);document.getElementById("appModalLabel").textContent="Confirm Deletion",document.getElementById("appModalBody").innerHTML=`<p>Are you sure you want to delete <strong>${t.length} document(s)</strong>? This action cannot be undone.</p>`,document.getElementById("appModalFooter").style.display="flex";let a=document.getElementById("appModalPrimaryBtn");a.textContent="Delete",a.className="btn btn-danger";const i=a.cloneNode(!0);a.parentNode.replaceChild(i,a),a=i,a.addEventListener("click",async function(){a.disabled=!0,a.innerHTML='<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Deleting...';try{const e=await fetch("/api/documents/bulk-delete",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({task_ids:t}),credentials:"include"});if(!e.ok){const t=await e.json();throw new Error(t.detail||"Failed to delete documents.")}o.hide(),z()}catch(e){const t=document.createElement("div");t.className="alert alert-danger mt-3",t.textContent=`Error: ${e.message}`,document.getElementById("appModalBody").appendChild(t),a.disabled=!1,a.textContent="Delete"}},{once:!0}),n.addEventListener("hidden.bs.modal",function e(){let t=document.getElementById("appModalPrimaryBtn");t.disabled=!1,t.textContent="Save Changes",t.className="btn btn-primary";const o=document.getElementById("appModalBody").querySelector(".alert-danger");o&&o.remove(),n.removeEventListener("hidden.bs.modal",e)},{once:!0}),o.show()}()})),function(){const e=document.getElementById("delete-all-data-btn");e&&e.addEventListener("click",()=>{const e=document.getElementById("appModal"),t=bootstrap.Modal.getInstance(e)||new bootstrap.Modal(e);document.getElementById("appModalLabel").textContent="Confirm Permanent Deletion",document.getElementById("appModalBody").innerHTML="\n <p><strong>This is a permanent action and cannot be undone.</strong></p>\n <p>Are you absolutely sure you want to delete all of your documents and uploaded images?</p>\n <p>Your subscription will not be affected.</p>\n ",document.getElementById("appModalFooter").style.display="flex";let n=document.getElementById("appModalPrimaryBtn");n.textContent="Yes, Delete Everything",n.className="btn btn-danger";const o=n.cloneNode(!0);n.parentNode.replaceChild(o,n),n=o,n.addEventListener("click",async function(){n.disabled=!0,n.innerHTML='<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Deleting...';try{const e=await fetch("/api/user/delete-all-data",{method:"DELETE",headers:{},credentials:"include"});if(!e.ok){const t=await e.json();throw new Error(t.detail||"Failed to delete data.")}document.getElementById("appModalBody").innerHTML='<p class="text-success">All your data has been successfully deleted.</p>',n.style.display="none",setTimeout(()=>{t.hide(),location.reload()},3e3)}catch(e){document.getElementById("appModalBody").innerHTML=`<p class="text-danger">Error: ${e.message}</p>`,n.disabled=!1,n.textContent="Yes, Delete Everything"}}),t.show()})}();const Y=document.getElementById("refresh-css-button");Y&&Y.addEventListener("click",async function(){const e=document.getElementById("mytextarea-editor")?.parentNode,t=e?.dataset?.currentTaskId;if(!t)return void showModal("Error","No document loaded. Please format or load a document first.");const n=Y.innerHTML;Y.disabled=!0,Y.innerHTML='<span class="spinner-border spinner-border-sm me-2"></span>Reloading CSS...';try{const e=await fetch(`/api/templates/${t}/refresh-css-from-template`,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include"});if(!e.ok){const t=await e.json();throw new Error(t.detail||"Failed to refresh CSS")}const n=await e.json(),o=tinymce.get("mytextarea-editor");if(o){const e=await fetch(`/api/documents/${t}`);if(e.ok){const t=await e.json(),a=(new DOMParser).parseFromString(t.html_content,"text/html"),i=a.querySelector("style")?.innerHTML||"",r=o.getDoc();let s=r.getElementById("custom-doc-style");s||(s=r.createElement("style"),s.id="custom-doc-style",r.head.appendChild(s)),s.innerHTML=i,showModal("Success",`â
CSS refreshed from template: ${n.template}<br><br>The editor now displays the updated styles. Click "Create PDF" to generate a new PDF with the updated CSS.`)}}else showModal("Success",`â
CSS refreshed from template: ${n.template}<br><br>Click "Create PDF" to generate a new PDF with the updated CSS.`)}catch(e){console.error("Error refreshing CSS:",e),showModal("Error",`Failed to refresh CSS: ${e.message}`)}finally{Y.disabled=!1,Y.innerHTML=n}})});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.