quikdown 1.1.1 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -3
- package/dist/quikdown.cjs +5 -5
- package/dist/quikdown.dark.css +1 -1
- package/dist/quikdown.esm.js +5 -5
- package/dist/quikdown.esm.min.js +2 -2
- package/dist/quikdown.esm.min.js.map +1 -1
- package/dist/quikdown.light.css +1 -1
- package/dist/quikdown.umd.js +5 -5
- package/dist/quikdown.umd.min.js +2 -2
- package/dist/quikdown.umd.min.js.map +1 -1
- package/dist/quikdown_ast.cjs +513 -0
- package/dist/quikdown_ast.d.ts +227 -0
- package/dist/quikdown_ast.esm.js +511 -0
- package/dist/quikdown_ast.esm.min.js +8 -0
- package/dist/quikdown_ast.esm.min.js.map +1 -0
- package/dist/quikdown_ast.umd.js +519 -0
- package/dist/quikdown_ast.umd.min.js +8 -0
- package/dist/quikdown_ast.umd.min.js.map +1 -0
- package/dist/quikdown_ast_html.cjs +1058 -0
- package/dist/quikdown_ast_html.d.ts +68 -0
- package/dist/quikdown_ast_html.esm.js +1056 -0
- package/dist/quikdown_ast_html.esm.min.js +8 -0
- package/dist/quikdown_ast_html.esm.min.js.map +1 -0
- package/dist/quikdown_ast_html.umd.js +1064 -0
- package/dist/quikdown_ast_html.umd.min.js +8 -0
- package/dist/quikdown_ast_html.umd.min.js.map +1 -0
- package/dist/quikdown_bd.cjs +12 -12
- package/dist/quikdown_bd.esm.js +12 -12
- package/dist/quikdown_bd.esm.min.js +2 -2
- package/dist/quikdown_bd.esm.min.js.map +1 -1
- package/dist/quikdown_bd.umd.js +12 -12
- package/dist/quikdown_bd.umd.min.js +2 -2
- package/dist/quikdown_bd.umd.min.js.map +1 -1
- package/dist/quikdown_edit.cjs +434 -58
- package/dist/quikdown_edit.d.ts +110 -132
- package/dist/quikdown_edit.esm.js +434 -58
- package/dist/quikdown_edit.esm.min.js +3 -3
- package/dist/quikdown_edit.esm.min.js.map +1 -1
- package/dist/quikdown_edit.umd.js +434 -58
- package/dist/quikdown_edit.umd.min.js +3 -3
- package/dist/quikdown_edit.umd.min.js.map +1 -1
- package/dist/quikdown_json.cjs +556 -0
- package/dist/quikdown_json.d.ts +48 -0
- package/dist/quikdown_json.esm.js +554 -0
- package/dist/quikdown_json.esm.min.js +8 -0
- package/dist/quikdown_json.esm.min.js.map +1 -0
- package/dist/quikdown_json.umd.js +562 -0
- package/dist/quikdown_json.umd.min.js +8 -0
- package/dist/quikdown_json.umd.min.js.map +1 -0
- package/dist/quikdown_yaml.cjs +717 -0
- package/dist/quikdown_yaml.d.ts +51 -0
- package/dist/quikdown_yaml.esm.js +715 -0
- package/dist/quikdown_yaml.esm.min.js +8 -0
- package/dist/quikdown_yaml.esm.min.js.map +1 -0
- package/dist/quikdown_yaml.umd.js +723 -0
- package/dist/quikdown_yaml.umd.min.js +8 -0
- package/dist/quikdown_yaml.umd.min.js.map +1 -0
- package/package.json +91 -38
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Quikdown Editor - Drop-in Markdown Parser
|
|
3
|
-
* @version 1.
|
|
3
|
+
* @version 1.2.2
|
|
4
4
|
* @license BSD-2-Clause
|
|
5
5
|
* @copyright DeftIO 2025
|
|
6
6
|
*/
|
|
7
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).QuikdownEditor=t()}(this,function(){"use strict";const e="quikdown-",t="§CB",n={"&":"&","<":"<",">":">",'"':""","'":"'"},o={h1:"font-size:2em;font-weight:600;margin:.67em 0;text-align:left",h2:"font-size:1.5em;font-weight:600;margin:.83em 0",h3:"font-size:1.25em;font-weight:600;margin:1em 0",h4:"font-size:1em;font-weight:600;margin:1.33em 0",h5:"font-size:.875em;font-weight:600;margin:1.67em 0",h6:"font-size:.85em;font-weight:600;margin:2em 0",pre:"background:#f4f4f4;padding:10px;border-radius:4px;overflow-x:auto;margin:1em 0",code:"background:#f0f0f0;padding:2px 4px;border-radius:3px;font-family:monospace",blockquote:"border-left:4px solid #ddd;margin-left:0;padding-left:1em",table:"border-collapse:collapse;width:100%;margin:1em 0",th:"border:1px solid #ddd;padding:8px;background-color:#f2f2f2;font-weight:bold;text-align:left",td:"border:1px solid #ddd;padding:8px;text-align:left",hr:"border:none;border-top:1px solid #ddd;margin:1em 0",img:"max-width:100%;height:auto",a:"color:#06c;text-decoration:underline",strong:"font-weight:bold",em:"font-style:italic",del:"text-decoration:line-through",ul:"margin:.5em 0;padding-left:2em",ol:"margin:.5em 0;padding-left:2em",li:"margin:.25em 0","task-item":"list-style:none","task-checkbox":"margin-right:.5em"};function r(r,a={}){if(!r||"string"!=typeof r)return"";const{fence_plugin:l,inline_styles:s=!1,bidirectional:c=!1,lazy_linefeeds:d=!1}=a,h=function(t,n){return function(o,r=""){if(t){let e=n[o];return e||r?(r&&r.includes("text-align")&&e&&e.includes("text-align")&&(e=e.replace(/text-align:[^;]+;?/,"").trim(),e&&!e.endsWith(";")&&(e+=";")),` style="${r?e?`${e}${r}`:r:e}"`):""}{const t=` class="${e}${o}"`;return r?`${t} style="${r}"`:t}}}(s,o);function u(e){return e.replace(/[&<>"']/g,e=>n[e])}const p=c?e=>` data-qd="${u(e)}"`:()=>"";function m(e,t=!1){if(!e)return"";if(t)return e;const n=e.trim(),o=n.toLowerCase(),r=["javascript:","vbscript:","data:"];for(const e of r)if(o.startsWith(e))return"data:"===e&&o.startsWith("data:image/")?n:"#";return n}let g=r;const f=[],w=[];g=g.replace(/^(```|~~~)([^\n]*)\n([\s\S]*?)^\1$/gm,(e,n,o,r)=>{const a=`${t}${f.length}§`,i=o?o.trim():"";return l&&l.render&&"function"==typeof l.render?f.push({lang:i,code:r.trimEnd(),custom:!0,fence:n,hasReverse:!!l.reverse}):f.push({lang:i,code:u(r.trimEnd()),custom:!1,fence:n}),a}),g=g.replace(/`([^`]+)`/g,(e,t)=>{const n=`§IC${w.length}§`;return w.push(u(t)),n}),g=u(g),g=function(e,t){const n=e.split("\n"),o=[];let r=!1,a=[];for(let e=0;e<n.length;e++){const l=n[e].trim();if(l.includes("|")&&(l.startsWith("|")||/[^\\|]/.test(l)))r||(r=!0,a=[]),a.push(l);else{if(r){const e=i(a,t);e?o.push(e):o.push(...a),r=!1,a=[]}o.push(n[e])}}if(r&&a.length>0){const e=i(a,t);e?o.push(e):o.push(...a)}return o.join("\n")}(g,h),g=g.replace(/^(#{1,6})\s+(.+?)\s*#*$/gm,(e,t,n)=>{const o=t.length;return`<h${o}${h("h"+o)}${p(t)}>${n}</h${o}>`}),g=g.replace(/^>\s+(.+)$/gm,`<blockquote${h("blockquote")}>$1</blockquote>`),g=g.replace(/<\/blockquote>\n<blockquote>/g,"\n"),g=g.replace(/^---+\s*$/gm,`<hr${h("hr")}>`),g=function(t,n,o,r){const a=t.split("\n"),i=[];let l=[];const s=e=>e.replace(/[&<>"']/g,e=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[e])),c=r?e=>` data-qd="${s(e)}"`:()=>"";for(let t=0;t<a.length;t++){const r=a[t],s=r.match(/^(\s*)([*\-+]|\d+\.)\s+(.+)$/);if(s){const[,t,r,a]=s,d=Math.floor(t.length/2),h=/^\d+\./.test(r),u=h?"ol":"ul";let p=a,m="";const g=a.match(/^\[([x ])\]\s+(.*)$/i);if(g&&!h){const[,t,n]=g,r="x"===t.toLowerCase();p=`<input type="checkbox"${o?' style="margin-right:.5em"':` class="${e}task-checkbox"`}${r?" checked":""} disabled> ${n}`,m=o?' style="list-style:none"':` class="${e}task-item"`}for(;l.length>d+1;){const e=l.pop();i.push(`</${e.type}>`)}if(l.length===d)l.push({type:u,level:d}),i.push(`<${u}${n(u)}>`);else if(l.length===d+1){const e=l[l.length-1];e.type!==u&&(i.push(`</${e.type}>`),l.pop(),l.push({type:u,level:d}),i.push(`<${u}${n(u)}>`))}const f=m||n("li");i.push(`<li${f}${c(r)}>${p}</li>`)}else{for(;l.length>0;){const e=l.pop();i.push(`</${e.type}>`)}i.push(r)}}for(;l.length>0;){const e=l.pop();i.push(`</${e.type}>`)}return i.join("\n")}(g,h,s,c),g=g.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,(e,t,n)=>{const o=m(n,a.allow_unsafe_urls),r=c&&t?` data-qd-alt="${u(t)}"`:"",i=c?` data-qd-src="${u(n)}"`:"";return`<img${h("img")} src="${o}" alt="${t}"${r}${i}${p("!")}>`}),g=g.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(e,t,n)=>{const o=m(n,a.allow_unsafe_urls),r=/^https?:\/\//i.test(o)?' rel="noopener noreferrer"':"",i=c?` data-qd-text="${u(t)}"`:"";return`<a${h("a")} href="${o}"${r}${i}${p("[")}>${t}</a>`}),g=g.replace(/(^|\s)(https?:\/\/[^\s<]+)/g,(e,t,n)=>{const o=m(n,a.allow_unsafe_urls);return`${t}<a${h("a")} href="${o}" rel="noopener noreferrer">${n}</a>`});if([[/\*\*(.+?)\*\*/g,"strong","**"],[/__(.+?)__/g,"strong","__"],[/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,"em","*"],[/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g,"em","_"],[/~~(.+?)~~/g,"del","~~"]].forEach(([e,t,n])=>{g=g.replace(e,`<${t}${h(t)}${p(n)}>$1</${t}>`)}),d){const e=[];let t=0;g=g.replace(/<(table|[uo]l)[^>]*>[\s\S]*?<\/\1>/g,n=>(e[t]=n,`§B${t++}§`)),g=g.replace(/\n\n+/g,"§P§").replace(/(<\/(?:h[1-6]|blockquote|pre)>)\n/g,"$1§N§").replace(/(<(?:h[1-6]|blockquote|pre|hr)[^>]*>)\n/g,"$1§N§").replace(/\n(<(?:h[1-6]|blockquote|pre|hr)[^>]*>)/g,"§N§$1").replace(/\n(§B\d+§)/g,"§N§$1").replace(/(§B\d+§)\n/g,"$1§N§").replace(/\n/g,`<br${h("br")}>`).replace(/§N§/g,"\n").replace(/§P§/g,"</p><p>"),e.forEach((e,t)=>g=g.replace(`§B${t}§`,e)),g="<p>"+g+"</p>"}else g=g.replace(/ $/gm,`<br${h("br")}>`),g=g.replace(/\n\n+/g,(e,t)=>g.substring(0,t).match(/<\/(h[1-6]|blockquote|ul|ol|table|pre|hr)>$/)?"<p>":"</p><p>"),g="<p>"+g+"</p>";return[[/<p><\/p>/g,""],[/<p>(<h[1-6][^>]*>)/g,"$1"],[/(<\/h[1-6]>)<\/p>/g,"$1"],[/<p>(<blockquote[^>]*>)/g,"$1"],[/(<\/blockquote>)<\/p>/g,"$1"],[/<p>(<ul[^>]*>|<ol[^>]*>)/g,"$1"],[/(<\/ul>|<\/ol>)<\/p>/g,"$1"],[/<p>(<hr[^>]*>)<\/p>/g,"$1"],[/<p>(<table[^>]*>)/g,"$1"],[/(<\/table>)<\/p>/g,"$1"],[/<p>(<pre[^>]*>)/g,"$1"],[/(<\/pre>)<\/p>/g,"$1"],[new RegExp(`<p>(${t}\\d+§)</p>`,"g"),"$1"]].forEach(([e,t])=>{g=g.replace(e,t)}),g=g.replace(/(<\/(?:h[1-6]|blockquote|ul|ol|table|pre|hr)>)\n([^<])/g,"$1\n<p>$2"),f.forEach((e,n)=>{let o;if(e.custom&&l&&l.render)if(o=l.render(e.code,e.lang),void 0===o){const t=!s&&e.lang?` class="language-${e.lang}"`:"",n=s?h("code"):t,r=c&&e.lang?` data-qd-lang="${u(e.lang)}"`:"",a=c?` data-qd-fence="${u(e.fence)}"`:"";o=`<pre${h("pre")}${a}${r}><code${n}>${u(e.code)}</code></pre>`}else c&&(o=o.replace(/^<(\w+)/,`<$1 data-qd-fence="${u(e.fence)}" data-qd-lang="${u(e.lang)}" data-qd-source="${u(e.code)}"`));else{const t=!s&&e.lang?` class="language-${e.lang}"`:"",n=s?h("code"):t,r=c&&e.lang?` data-qd-lang="${u(e.lang)}"`:"",a=c?` data-qd-fence="${u(e.fence)}"`:"";o=`<pre${h("pre")}${a}${r}><code${n}>${e.code}</code></pre>`}const r=`${t}${n}§`;g=g.replace(r,o)}),w.forEach((e,t)=>{const n=`§IC${t}§`;g=g.replace(n,`<code${h("code")}${p("`")}>${e}</code>`)}),g.trim()}function a(e,t){return[[/\*\*(.+?)\*\*/g,"strong"],[/__(.+?)__/g,"strong"],[/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,"em"],[/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g,"em"],[/~~(.+?)~~/g,"del"],[/`([^`]+)`/g,"code"]].forEach(([n,o])=>{e=e.replace(n,`<${o}${t(o)}>$1</${o}>`)}),e}function i(e,t){if(e.length<2)return null;let n=-1;for(let t=1;t<e.length;t++)if(/^\|?[\s\-:|]+\|?$/.test(e[t])&&e[t].includes("-")){n=t;break}if(-1===n)return null;const o=e.slice(0,n),r=e.slice(n+1),i=e[n].trim().replace(/^\|/,"").replace(/\|$/,"").split("|").map(e=>{const t=e.trim();return t.startsWith(":")&&t.endsWith(":")?"center":t.endsWith(":")?"right":"left"});let l=`<table${t("table")}>\n`;return l+=`<thead${t("thead")}>\n`,o.forEach(e=>{l+=`<tr${t("tr")}>\n`;e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,n)=>{const o=i[n]&&"left"!==i[n]?`text-align:${i[n]}`:"",r=a(e.trim(),t);l+=`<th${t("th",o)}>${r}</th>\n`}),l+="</tr>\n"}),l+="</thead>\n",r.length>0&&(l+=`<tbody${t("tbody")}>\n`,r.forEach(e=>{l+=`<tr${t("tr")}>\n`;e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,n)=>{const o=i[n]&&"left"!==i[n]?`text-align:${i[n]}`:"",r=a(e.trim(),t);l+=`<td${t("td",o)}>${r}</td>\n`}),l+="</tr>\n"}),l+="</tbody>\n"),l+="</table>",l}function l(e,t={}){return r(e,{...t,bidirectional:!0})}async function s(e,t=!1){return new Promise((n,o)=>{const r=(new XMLSerializer).serializeToString(e),a=document.createElement("canvas"),i=a.getContext("2d"),l=new Image,s=e.closest(".mermaid")||e.classList.contains("mermaid"),c=e.getAttribute("width")&&e.getAttribute("height");let d,h;s||!c?(d=e.clientWidth||e.viewBox&&e.viewBox.baseVal.width||parseFloat(e.getAttribute("width"))||400,h=e.clientHeight||e.viewBox&&e.viewBox.baseVal.height||parseFloat(e.getAttribute("height"))||300):(d=parseFloat(e.getAttribute("width"))||e.viewBox&&e.viewBox.baseVal.width||e.clientWidth||400,h=parseFloat(e.getAttribute("height"))||e.viewBox&&e.viewBox.baseVal.height||e.clientHeight||300);let u=r;if(d&&h){const e=document.createElement("div");e.innerHTML=r;const t=e.querySelector("svg");t&&(t.setAttribute("width",d.toString()),t.setAttribute("height",h.toString()),u=(new XMLSerializer).serializeToString(t))}a.width=2*d,a.height=2*h,i.scale(2,2),l.onload=()=>{try{t&&(i.fillStyle="white",i.fillRect(0,0,a.width,a.height)),i.drawImage(l,0,0,d,h),a.toBlob(e=>{n(e)},"image/png",1)}catch(e){o(e)}},l.onerror=o;const p=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(u)}`;l.src=p})}async function c(e){try{if(!e._map)return console.warn("No map found on container"),null;const t=e.getBoundingClientRect(),n=Math.round(t.width),o=Math.round(t.height);if(0===n||0===o)return console.warn("Map container has zero dimensions"),null;const r=document.createElement("canvas"),a=window.devicePixelRatio||1;r.width=n*a,r.height=o*a,r.style.width=n+"px",r.style.height=o+"px";const i=r.getContext("2d");i.scale(a,a),i.fillStyle="#FFFFFF",i.fillRect(0,0,n,o);const l=e.querySelectorAll(".leaflet-tile"),s=[];for(const e of l)s.push(new Promise(n=>{const o=new Image;o.crossOrigin="anonymous",o.onload=()=>{try{const n=e.getBoundingClientRect(),r=n.left-t.left,a=n.top-t.top;i.drawImage(o,r,a,n.width,n.height)}catch(e){console.warn("Failed to draw tile:",e)}n()},o.onerror=()=>{console.warn("Failed to load tile:",e.src),n()},o.src=e.src}));await Promise.all(s);const c=e.querySelectorAll("svg:not(.leaflet-attribution-flag)");for(const e of c)if(!e.closest(".leaflet-control"))try{const n=e.getBoundingClientRect(),o=n.left-t.left,r=n.top-t.top,a=(new XMLSerializer).serializeToString(e),l=new Blob([a],{type:"image/svg+xml;charset=utf-8"}),s=URL.createObjectURL(l);await new Promise((e,t)=>{const a=new Image;a.onload=()=>{i.drawImage(a,o,r,n.width,n.height),URL.revokeObjectURL(s),e()},a.onerror=()=>{URL.revokeObjectURL(s),t(new Error("Failed to load SVG overlay"))},a.src=s})}catch(e){console.warn("Failed to draw SVG overlay:",e)}const d=e.querySelectorAll(".leaflet-marker-icon");for(const e of d)try{const n=new Image;n.crossOrigin="anonymous",await new Promise(o=>{n.onload=()=>{const r=e.getBoundingClientRect(),a=r.left-t.left,l=r.top-t.top;i.drawImage(n,a,l,r.width,r.height),o()},n.onerror=o,n.src=e.src})}catch(e){console.warn("Failed to draw marker icon:",e)}return r.toDataURL("image/png",1)}catch(e){return console.error("Failed to rasterize GeoJSON map:",e),null}}async function d(e){if(!e)throw new Error("No preview panel available");const t=e.querySelectorAll(".math-display");if(t.length>0){if(Array.from(t).some(e=>!e.querySelector("mjx-container"))&&window.MathJax&&window.MathJax.typesetPromise)try{await window.MathJax.typesetPromise(Array.from(t))}catch(e){console.warn("MathJax typesetting failed:",e)}}const n=e.cloneNode(!0);try{n.querySelectorAll("strong, b").forEach(e=>{e.style.fontWeight="bold"}),n.querySelectorAll("em, i").forEach(e=>{e.style.fontStyle="italic"}),n.querySelectorAll("del, s, strike").forEach(e=>{e.style.textDecoration="line-through"}),n.querySelectorAll("u").forEach(e=>{e.style.textDecoration="underline"}),n.querySelectorAll("code:not(pre code)").forEach(e=>{e.style.backgroundColor="#f4f4f4",e.style.padding="2px 4px",e.style.borderRadius="3px",e.style.fontFamily="monospace",e.style.fontSize="0.9em"}),n.querySelectorAll("h1").forEach(e=>{e.style.fontSize="2em",e.style.fontWeight="bold",e.style.marginTop="0.67em",e.style.marginBottom="0.67em"}),n.querySelectorAll("h2").forEach(e=>{e.style.fontSize="1.5em",e.style.fontWeight="bold",e.style.marginTop="0.83em",e.style.marginBottom="0.83em"}),n.querySelectorAll("h3").forEach(e=>{e.style.fontSize="1.17em",e.style.fontWeight="bold",e.style.marginTop="1em",e.style.marginBottom="1em"}),n.querySelectorAll("h4").forEach(e=>{e.style.fontSize="1em",e.style.fontWeight="bold",e.style.marginTop="1.33em",e.style.marginBottom="1.33em"}),n.querySelectorAll("h5").forEach(e=>{e.style.fontSize="0.83em",e.style.fontWeight="bold",e.style.marginTop="1.67em",e.style.marginBottom="1.67em"}),n.querySelectorAll("h6").forEach(e=>{e.style.fontSize="0.67em",e.style.fontWeight="bold",e.style.marginTop="2.33em",e.style.marginBottom="2.33em"}),n.querySelectorAll("blockquote").forEach(e=>{e.style.borderLeft="4px solid #ddd",e.style.marginLeft="0",e.style.paddingLeft="1em",e.style.color="#666"}),n.querySelectorAll("hr").forEach(e=>{e.style.border="none",e.style.borderTop="1px solid #ccc",e.style.margin="1em 0"}),n.querySelectorAll("table").forEach(e=>{e.style.borderCollapse="collapse",e.style.width="100%",e.style.marginBottom="1em"}),n.querySelectorAll("th").forEach(e=>{e.style.border="1px solid #ccc",e.style.padding="8px",e.style.textAlign="left",e.style.backgroundColor="#f0f0f0",e.style.fontWeight="bold"}),n.querySelectorAll("td").forEach(e=>{e.style.border="1px solid #ccc",e.style.padding="8px",e.style.textAlign="left"}),n.querySelectorAll("a").forEach(e=>{e.style.color="#0066cc",e.style.textDecoration="underline"}),n.querySelectorAll("pre code").forEach(e=>{const t=e.parentElement;e.classList.contains("hljs")&&(e.querySelectorAll(".hljs-keyword").forEach(e=>{e.style.color="#d73a49",e.style.fontWeight="bold"}),e.querySelectorAll(".hljs-string").forEach(e=>{e.style.color="#032f62"}),e.querySelectorAll(".hljs-number").forEach(e=>{e.style.color="#005cc5"}),e.querySelectorAll(".hljs-comment").forEach(e=>{e.style.color="#6a737d",e.style.fontStyle="italic"}),e.querySelectorAll(".hljs-function").forEach(e=>{e.style.color="#6f42c1"}),e.querySelectorAll(".hljs-class").forEach(e=>{e.style.color="#6f42c1"}),e.querySelectorAll(".hljs-title").forEach(e=>{e.style.color="#6f42c1"}),e.querySelectorAll(".hljs-built_in").forEach(e=>{e.style.color="#005cc5"}),e.querySelectorAll(".hljs-literal").forEach(e=>{e.style.color="#005cc5"}),e.querySelectorAll(".hljs-meta").forEach(e=>{e.style.color="#005cc5"}),e.querySelectorAll(".hljs-attr").forEach(e=>{e.style.color="#22863a"}),e.querySelectorAll(".hljs-variable").forEach(e=>{e.style.color="#e36209"}),e.querySelectorAll(".hljs-regexp").forEach(e=>{e.style.color="#032f62"}),e.querySelectorAll(".hljs-selector-class").forEach(e=>{e.style.color="#22863a"}),e.querySelectorAll(".hljs-selector-id").forEach(e=>{e.style.color="#6f42c1"}),e.querySelectorAll(".hljs-selector-tag").forEach(e=>{e.style.color="#22863a"}),e.querySelectorAll(".hljs-tag").forEach(e=>{e.style.color="#22863a"}),e.querySelectorAll(".hljs-name").forEach(e=>{e.style.color="#22863a"}),e.querySelectorAll(".hljs-attribute").forEach(e=>{e.style.color="#6f42c1"}));const n=document.createElement("table");n.style.width="100%",n.style.borderCollapse="collapse",n.style.border="none",n.style.marginBottom="1em";const o=document.createElement("tr"),r=document.createElement("td");r.style.backgroundColor="#f7f7f7",r.style.padding="12px",r.style.fontFamily='Consolas, Monaco, "Courier New", monospace',r.style.fontSize="14px",r.style.lineHeight="1.4",r.style.whiteSpace="pre",r.style.overflowX="auto",r.style.border="1px solid #ddd",r.style.borderRadius="4px",r.innerHTML=e.innerHTML,o.appendChild(r),n.appendChild(o),t.parentNode.replaceChild(n,t)});const t=n.querySelectorAll("img");for(const e of t){!e.width&&e.naturalWidth&&(e.width=e.naturalWidth),!e.height&&e.naturalHeight&&(e.height=e.naturalHeight);const t=800,n=600;if(e.width>t||e.height>n){const o=Math.min(t/e.width,n/e.height);e.width=Math.round(e.width*o),e.height=Math.round(e.height*o)}if(e.width&&(e.setAttribute("width",e.width.toString()),e.style.width=e.width+"px"),e.height&&(e.setAttribute("height",e.height.toString()),e.style.height=e.height+"px"),e.getAttribute("v:shapes")||e.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),e.src&&!e.src.startsWith("data:"))try{const t=await fetch(e.src),n=await t.blob(),o=2097152;if(n.size>o){console.warn("Image too large for inline data URL:",e.src,"Size:",n.size);continue}const r=await new Promise(e=>{const t=new FileReader;t.onloadend=()=>e(t.result),t.readAsDataURL(n)});e.src=r}catch(t){console.warn("Failed to convert image to data URL:",e.src,t)}}const o=n.querySelectorAll(".qde-stl-container");for(const t of o){try{const n=t.dataset.stlId,o=e.querySelector(`.qde-stl-container[data-stl-id="${n}"]`);if(o){const e=o.querySelector("canvas");if(e&&e.width>0&&e.height>0)try{const n=o._threeRenderer,r=o._threeScene,a=o._threeCamera;n&&r&&a&&n.render(r,a);const i=e.toDataURL("image/png",1),l=document.createElement("img");l.src=i;const s=e.width/2,c=e.height/2;l.width=s,l.height=c,l.setAttribute("width",s.toString()),l.setAttribute("height",c.toString()),l.style.width=s+"px",l.style.height=c+"px",l.style.maxWidth="none",l.style.maxHeight="none",l.style.border="1px solid #ddd",l.style.borderRadius="4px",l.style.margin="0.5em 0",l.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),l.alt="STL 3D Model",t.parentNode.replaceChild(l,t);continue}catch(e){console.warn("Failed to convert STL canvas to image (likely WebGL context issue):",e)}else console.warn("No valid canvas found in STL container")}else console.warn("Could not find original STL container")}catch(e){console.error("Error processing STL container for copy:",e)}const n=document.createElement("div");n.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",n.textContent="[STL 3D Model - Interactive content not available in copy]",t.parentNode.replaceChild(n,t)}const r=n.querySelectorAll(".mermaid");for(const e of r){const t=e.querySelector("svg");if(t)try{const n=await s(t),o=await new Promise(e=>{const t=new FileReader;t.onloadend=()=>e(t.result),t.readAsDataURL(n)}),r=document.createElement("img");r.src=o;const a=t.closest(".mermaid")||t.classList.contains("mermaid"),i=t.getAttribute("width")&&t.getAttribute("height");let l,c;a||!i?(l=t.clientWidth||t.viewBox&&t.viewBox.baseVal.width||parseFloat(t.getAttribute("width"))||400,c=t.clientHeight||t.viewBox&&t.viewBox.baseVal.height||parseFloat(t.getAttribute("height"))||300):(l=parseFloat(t.getAttribute("width"))||t.viewBox&&t.viewBox.baseVal.width||t.clientWidth||400,c=parseFloat(t.getAttribute("height"))||t.viewBox&&t.viewBox.baseVal.height||t.clientHeight||300),r.width=l,r.height=c,r.setAttribute("width",l.toString()),r.setAttribute("height",c.toString()),r.style.width=l+"px",r.style.height=c+"px",r.style.maxWidth="none",r.style.maxHeight="none",r.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),r.alt="Mermaid Diagram",e.parentNode.replaceChild(r,e)}catch(e){console.warn("Failed to convert Mermaid diagram:",e)}}const a=n.querySelectorAll(".qde-chart-container");for(const t of a){try{const n=t.dataset.chartId,o=e.querySelector(`.qde-chart-container[data-chart-id="${n}"]`);if(o){const e=o.querySelector("canvas");if(e&&e.width>0&&e.height>0)try{const n=e.toDataURL("image/png",1),o=document.createElement("img");o.src=n;const r=e.width,a=e.height;o.width=r,o.height=a,o.setAttribute("width",r.toString()),o.setAttribute("height",a.toString()),o.style.width=r+"px",o.style.height=a+"px",o.style.maxWidth="none",o.style.maxHeight="none",o.style.margin="0.5em 0",o.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),o.alt="Chart",t.parentNode.replaceChild(o,t);continue}catch(e){console.warn("Failed to convert chart canvas to image:",e)}}}catch(e){console.warn("Error processing chart container:",e)}const n=document.createElement("div");n.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",n.textContent="[Chart - Interactive content not available in copy]",t.parentNode.replaceChild(n,t)}const i=n.querySelectorAll(".qde-svg-container svg");for(const e of i)try{const t=await s(e),n=await new Promise(e=>{const n=new FileReader;n.onloadend=()=>e(n.result),n.readAsDataURL(t)}),o=document.createElement("img");o.src=n;let r,a;e.getAttribute("width")&&e.getAttribute("height")?(r=parseFloat(e.getAttribute("width"))||e.viewBox&&e.viewBox.baseVal.width||e.clientWidth||400,a=parseFloat(e.getAttribute("height"))||e.viewBox&&e.viewBox.baseVal.height||e.clientHeight||300):(r=e.clientWidth||e.viewBox&&e.viewBox.baseVal.width||parseFloat(e.getAttribute("width"))||400,a=e.clientHeight||e.viewBox&&e.viewBox.baseVal.height||parseFloat(e.getAttribute("height"))||300),o.width=r,o.height=a,o.setAttribute("width",r.toString()),o.setAttribute("height",a.toString()),o.style.width=r+"px",o.style.height=a+"px",o.style.maxWidth="none",o.style.maxHeight="none",o.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),o.alt="SVG Image",e.parentNode.replaceChild(o,e)}catch(e){console.warn("Failed to convert SVG to image:",e)}const l=Array.from(n.querySelectorAll(".math-display"));if(l.length>0)for(const e of l)try{const t=e.querySelector("svg");if(!t){console.warn("No SVG found in math element, skipping");continue}const n=(new XMLSerializer).serializeToString(t),o=new Blob([n],{type:"image/svg+xml;charset=utf-8"}),r=URL.createObjectURL(o),a=new Image,i=await new Promise((e,n)=>{a.onload=function(){const n=document.createElement("canvas");let o,i;try{o=t.width.baseVal.value,i=t.height.baseVal.value}catch(e){t.viewBox&&t.viewBox.baseVal?(o=t.viewBox.baseVal.width,i=t.viewBox.baseVal.height):(o=a.naturalWidth||a.width||200,i=a.naturalHeight||a.height||50)}let l=.04,s=o*l,c=i*l;if(s>150||c>45){const e=150/s,t=45/c;l*=Math.min(e,t)}o*=l,i*=l;n.width=2*o,n.height=2*i,n.style.width=o+"px",n.style.height=i+"px";const d=n.getContext("2d");d.scale(2,2),d.fillStyle="#FFFFFF",d.fillRect(0,0,o,i),d.drawImage(a,0,0,o,i),URL.revokeObjectURL(r),e(n.toDataURL("image/png"))},a.onerror=()=>{URL.revokeObjectURL(r),n(new Error("Failed to load SVG image"))},a.src=r}),l=document.createElement("img");l.src=i;const s=new Image;s.src=i,await new Promise(e=>{s.onload=e,s.onerror=e,setTimeout(e,100)});const c=s.naturalWidth/2,d=s.naturalHeight/2;l.width=c,l.height=d,l.style.cssText=`display:inline-block;margin:0.5em 0;width:${c}px;height:${d}px;vertical-align:middle;`,l.alt="Math equation",e.parentNode.replaceChild(l,e)}catch(e){console.error("Failed to convert math element to image:",e)}const d=n.querySelectorAll(".geojson-container");if(d.length>0)for(const t of d)try{const n=t.getAttribute("data-original-source");if(!n){console.warn("No original source found for GeoJSON container");continue}let o=null;const r=e.querySelectorAll(".geojson-container");for(const e of r)if(e.getAttribute("data-original-source")===n){o=e;break}if(!o){console.warn("Could not find live GeoJSON container");const e=document.createElement("div");e.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",e.textContent="[GeoJSON Map - Interactive content not available in copy]",t.parentNode.replaceChild(e,t);continue}if(!o._map){console.warn("Map not initialized yet");const e=document.createElement("div");e.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",e.textContent="[GeoJSON Map - Still loading]",t.parentNode.replaceChild(e,t);continue}const a=await c(o);if(a){const e=document.createElement("img");e.src=a,e.style.cssText="width: 100%; height: 300px; border: 1px solid #ddd; border-radius: 4px; margin: 0.5em 0;",e.alt="GeoJSON Map",t.parentNode.replaceChild(e,t)}else{const e=document.createElement("div");e.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",e.textContent="[GeoJSON Map - Interactive content not available in copy]",t.parentNode.replaceChild(e,t)}}catch(e){console.error("Failed to process GeoJSON container:",e);const n=document.createElement("div");n.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",n.textContent="[GeoJSON Map - Interactive content not available in copy]",t.parentNode.replaceChild(n,t)}const h=n.querySelectorAll('[data-qd-lang="geojson"]');for(const t of h)try{const n=t.id,o=n?e.querySelector(`#${n}`):null;if(!o)continue;const r=o.querySelector(".leaflet-container");if(!r)continue;const a=Math.max(1,window.devicePixelRatio||1),i=r.clientWidth||600,l=r.clientHeight||400,s=document.createElement("canvas");s.width=Math.round(i*a),s.height=Math.round(l*a);const c=s.getContext("2d");c.scale(a,a),c.fillStyle="#FFFFFF",c.fillRect(0,0,i,l);const d=r.getBoundingClientRect(),h=Array.from(r.querySelectorAll("img.leaflet-tile"));for(const e of h)try{const t=e.getBoundingClientRect(),n=Math.round(t.left-d.left),o=Math.round(t.top-d.top),r=Math.round(t.width),a=Math.round(t.height),i=!(t.right<=d.left||t.left>=d.right||t.bottom<=d.top||t.top>=d.bottom),l=window.getComputedStyle(e);r>0&&a>0&&i&&"none"!==l.display&&"hidden"!==l.visibility&&c.drawImage(e,n,o,r+1,a+1)}catch(e){console.warn("Failed to draw tile:",e)}const u=o.querySelectorAll(".leaflet-overlay-pane svg");for(const e of u)try{const t=(new XMLSerializer).serializeToString(e),n="data:image/svg+xml;charset=utf-8,"+encodeURIComponent(t),o=new Image;await new Promise(e=>{o.onload=e,o.onerror=e,o.src=n});const r=e.getBoundingClientRect(),a=Math.round(r.left-d.left),i=Math.round(r.top-d.top),l=Math.round(r.width),s=Math.round(r.height),h=!(r.right<=d.left||r.left>=d.right||r.bottom<=d.top||r.top>=d.bottom);l>0&&s>0&&h&&c.drawImage(o,a,i,l,s)}catch(e){console.warn("Failed to draw overlay SVG:",e)}const p=o.querySelectorAll(".leaflet-marker-pane img.leaflet-marker-icon");for(const e of p)try{const t=e.getBoundingClientRect(),n=Math.round(t.left-d.left),o=Math.round(t.top-d.top),r=Math.round(t.width),a=Math.round(t.height),i=!(t.right<=d.left||t.left>=d.right||t.bottom<=d.top||t.top>=d.bottom),l=window.getComputedStyle(e);r>0&&a>0&&i&&"none"!==l.display&&"hidden"!==l.visibility&&c.drawImage(e,n,o,r,a)}catch(e){console.warn("Failed to draw marker icon:",e)}let m="";try{m=s.toDataURL("image/png",1)}catch(e){console.warn("Map canvas tainted; falling back to placeholder")}const g=document.createElement("img");m?(g.src=m,g.width=i,g.height=l,g.setAttribute("width",String(i)),g.setAttribute("height",String(l)),g.style.width=i+"px",g.style.height=l+"px",g.style.display="block",g.style.border="1px solid #ddd",g.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),g.alt="Map"):(g.alt="Map",g.style.width=i+"px",g.style.height=l+"px",g.style.border="1px solid #ddd",g.style.backgroundColor="#f0f0f0"),t.parentNode.replaceChild(g,t)}catch(e){console.warn("Failed to process map container:",e)}const u=n.querySelectorAll(".qde-html-container");for(const e of u)try{const t=e.getAttribute("data-qd-source"),n=e.querySelector("pre");if(t){const n=document.createElement("div");n.innerHTML=t;const o=n.querySelectorAll("img");for(const e of o){const t=e.getAttribute("width"),n=e.getAttribute("height");if(t&&(e.width=parseInt(t),e.style.width=t.includes("%")?t:`${e.width}px`),n&&(e.height=parseInt(n),e.style.height=n.includes("%")?n:`${e.height}px`),e.src&&!e.src.startsWith("data:"))try{const o=document.createElement("canvas"),r=o.getContext("2d"),a=new Image;a.crossOrigin="anonymous",await new Promise((i,l)=>{if(a.onload=function(){let l=0,s=0;if(t&&!t.includes("%")&&(l=parseInt(t)),n&&!n.includes("%")&&(s=parseInt(n)),l>0&&0===s){if(a.naturalWidth>0){const e=a.naturalHeight/a.naturalWidth;s=Math.round(l*e)}}else if(s>0&&0===l){if(a.naturalHeight>0){const e=a.naturalWidth/a.naturalHeight;l=Math.round(s*e)}}else 0===l&&0===s&&(l=a.naturalWidth||250,s=a.naturalHeight||200);o.width=l,o.height=s,r.drawImage(a,0,0,l,s);const c=o.toDataURL("image/png",1);e.src=c,e.width=l,e.height=s,e.setAttribute("width",l.toString()),e.setAttribute("height",s.toString()),e.style.width=l+"px",e.style.height=s+"px",i()},a.onerror=function(){console.warn("Failed to load HTML fence image:",e.src),l(new Error("Image load failed"))},e.src.startsWith("http")||e.src.startsWith("//"))a.src=e.src;else{const t=new Image;t.src=e.src,a.src=t.src}})}catch(t){console.warn("Failed to convert HTML fence image:",e.src,t)}e.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9))}e.innerHTML=n.innerHTML}else if(!n){const t=e.querySelectorAll("img");for(const e of t){const t=e.getAttribute("width"),n=e.getAttribute("height");if(t&&(e.width=parseInt(t),e.style.width=t.includes("%")?t:`${e.width}px`),n&&(e.height=parseInt(n),e.style.height=n.includes("%")?n:`${e.height}px`),e.src&&!e.src.startsWith("data:"))try{const t=document.createElement("canvas"),n=t.getContext("2d"),o=new Image;o.crossOrigin="anonymous",await new Promise((r,a)=>{if(o.onload=function(){let a=e.width||0,i=e.height||0;if(a&&!i){const e=o.naturalHeight/o.naturalWidth;i=Math.round(a*e)}else if(i&&!a){const e=o.naturalWidth/o.naturalHeight;a=Math.round(i*e)}else a||i||(a=o.naturalWidth||250,i=o.naturalHeight||Math.round(o.naturalHeight/o.naturalWidth*250));t.width=a,t.height=i,n.drawImage(o,0,0,a,i);const l=t.toDataURL("image/png",1);e.src=l,e.width=a,e.height=i,e.setAttribute("width",a.toString()),e.setAttribute("height",i.toString()),e.style.width=a+"px",e.style.height=i+"px",r()},o.onerror=function(){console.warn("Failed to load HTML fence image:",e.src),a(new Error("Image load failed"))},e.src.startsWith("http")||e.src.startsWith("//"))o.src=e.src;else{const t=new Image;t.src=e.src,o.src=t.src}})}catch(t){console.warn("Failed to convert HTML fence image:",e.src,t)}e.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9))}}}catch(e){console.warn("Failed to process HTML container:",e)}const p=n.innerHTML,m=`\n <!DOCTYPE html>\n <html xmlns:v="urn:schemas-microsoft-com:vml"\n xmlns:o="urn:schemas-microsoft-com:office:office"\n xmlns:w="urn:schemas-microsoft-com:office:word">\n <head>\n <meta charset="utf-8">\n <style>\n /* Table styling */\n table { border-collapse: collapse; width: 100%; margin-bottom: 1em; }\n th, td { border: 1px solid #ccc; padding: 8px; text-align: left; }\n th { background-color: #f0f0f0; font-weight: bold; }\n \n /* Code block styling */\n pre { background-color: #f4f4f4; padding: 1em; border-radius: 4px; overflow-x: auto; }\n code { font-family: monospace; background-color: #f4f4f4; padding: 0.2em 0.4em; border-radius: 3px; }\n \n /* Image handling */\n img { display: block; max-width: 100%; height: auto; margin: 0.5em 0; }\n \n /* Blockquote */\n blockquote { border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666; }\n \n /* Math equations centered like squibview */\n .math-display { text-align: center; margin: 1em 0; }\n .math-display img { display: inline-block; margin: 0 auto; }\n </style>\n </head>\n <body>\x3c!--StartFragment--\x3e${p}\x3c!--EndFragment--\x3e</body>\n </html>`,g=n.textContent||n.innerText||"";if("macos"===function(){const e=navigator.platform?.toLowerCase()||"",t=navigator.userAgent?.toLowerCase()||"";return e.includes("mac")||t.includes("mac")?"macos":t.includes("windows")?"windows":t.includes("linux")?"linux":"unknown"}())try{return await navigator.clipboard.write([new ClipboardItem({"text/html":new Blob([m],{type:"text/html"}),"text/plain":new Blob([g],{type:"text/plain"})})]),{success:!0,html:m,text:g}}catch(e){if(console.warn("Modern clipboard API failed, trying Safari fallback:",e),function(e){let t,n;try{t=document.createElement("div"),t.style.position="fixed",t.style.left="-9999px",t.style.top="0",t.style.width="1px",t.style.height="1px",t.style.overflow="hidden",t.innerHTML=e,document.body.appendChild(t);const o=document.createRange();o.selectNodeContents(t);const r=window.getSelection();r.removeAllRanges(),r.addRange(o),n=document.execCommand("copy"),r.removeAllRanges()}catch(e){console.error("Fallback copy failed:",e),n=!1}finally{t&&t.parentNode&&document.body.removeChild(t)}return n}(p))return{success:!0,html:m,text:g};throw new Error("Fallback copy failed")}else{const e=document.createElement("div");e.style.position="fixed",e.style.left="-9999px",e.style.top="0",e.innerHTML=p,document.body.appendChild(e);try{return await navigator.clipboard.write([new ClipboardItem({"text/html":new Blob([m],{type:"text/html"}),"text/plain":new Blob([g],{type:"text/plain"})})]),{success:!0,html:m,text:g}}catch(t){console.warn("Modern clipboard API failed, trying execCommand fallback:",t);const n=window.getSelection(),o=document.createRange();o.selectNodeContents(e),n.removeAllRanges(),n.addRange(o);if(!document.execCommand("copy"))throw new Error("Fallback copy failed");return{success:!0,html:m,text:g}}finally{e&&e.parentNode&&document.body.removeChild(e)}}}catch(e){throw console.error("Failed to copy rendered content:",e),e}}
|
|
7
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).QuikdownEditor=t()}(this,function(){"use strict";const e="quikdown-",t="§CB",n={"&":"&","<":"<",">":">",'"':""","'":"'"},o={h1:"font-size:2em;font-weight:600;margin:.67em 0;text-align:left",h2:"font-size:1.5em;font-weight:600;margin:.83em 0",h3:"font-size:1.25em;font-weight:600;margin:1em 0",h4:"font-size:1em;font-weight:600;margin:1.33em 0",h5:"font-size:.875em;font-weight:600;margin:1.67em 0",h6:"font-size:.85em;font-weight:600;margin:2em 0",pre:"background:#f4f4f4;padding:10px;border-radius:4px;overflow-x:auto;margin:1em 0",code:"background:#f0f0f0;padding:2px 4px;border-radius:3px;font-family:monospace",blockquote:"border-left:4px solid #ddd;margin-left:0;padding-left:1em",table:"border-collapse:collapse;width:100%;margin:1em 0",th:"border:1px solid #ddd;padding:8px;background-color:#f2f2f2;font-weight:bold;text-align:left",td:"border:1px solid #ddd;padding:8px;text-align:left",hr:"border:none;border-top:1px solid #ddd;margin:1em 0",img:"max-width:100%;height:auto",a:"color:#06c;text-decoration:underline",strong:"font-weight:bold",em:"font-style:italic",del:"text-decoration:line-through",ul:"margin:.5em 0;padding-left:2em",ol:"margin:.5em 0;padding-left:2em",li:"margin:.25em 0","task-item":"list-style:none","task-checkbox":"margin-right:.5em"};function r(r,a={}){if(!r||"string"!=typeof r)return"";const{fence_plugin:s,inline_styles:l=!1,bidirectional:c=!1,lazy_linefeeds:d=!1}=a,h=function(t,n){return function(o,r=""){if(t){let e=n[o];return e||r?(r&&r.includes("text-align")&&e&&e.includes("text-align")&&(e=e.replace(/text-align:[^;]+;?/,"").trim(),e&&!e.endsWith(";")&&(e+=";")),` style="${r?e?`${e}${r}`:r:e}"`):""}{const t=` class="${e}${o}"`;return r?`${t} style="${r}"`:t}}}(l,o);function u(e){return e.replace(/[&<>"']/g,e=>n[e])}const p=c?e=>` data-qd="${u(e)}"`:()=>"";function m(e,t=!1){if(!e)return"";if(t)return e;const n=e.trim(),o=n.toLowerCase(),r=["javascript:","vbscript:","data:"];for(const e of r)if(o.startsWith(e))return"data:"===e&&o.startsWith("data:image/")?n:"#";return n}let g=r;const f=[],w=[];g=g.replace(/^(```|~~~)([^\n]*)\n([\s\S]*?)^\1$/gm,(e,n,o,r)=>{const a=`${t}${f.length}§`,i=o?o.trim():"";return s&&s.render&&"function"==typeof s.render?f.push({lang:i,code:r.trimEnd(),custom:!0,fence:n,hasReverse:!!s.reverse}):f.push({lang:i,code:u(r.trimEnd()),custom:!1,fence:n}),a}),g=g.replace(/`([^`]+)`/g,(e,t)=>{const n=`§IC${w.length}§`;return w.push(u(t)),n}),g=u(g),g=function(e,t){const n=e.split("\n"),o=[];let r=!1,a=[];for(let e=0;e<n.length;e++){const s=n[e].trim();if(s.includes("|")&&(s.startsWith("|")||/[^\\|]/.test(s)))r||(r=!0,a=[]),a.push(s);else{if(r){const e=i(a,t);e?o.push(e):o.push(...a),r=!1,a=[]}o.push(n[e])}}if(r&&a.length>0){const e=i(a,t);e?o.push(e):o.push(...a)}return o.join("\n")}(g,h),g=g.replace(/^(#{1,6})\s+(.+?)\s*#*$/gm,(e,t,n)=>{const o=t.length;return`<h${o}${h("h"+o)}${p(t)}>${n}</h${o}>`}),g=g.replace(/^>\s+(.+)$/gm,`<blockquote${h("blockquote")}>$1</blockquote>`),g=g.replace(/<\/blockquote>\n<blockquote>/g,"\n"),g=g.replace(/^---+\s*$/gm,`<hr${h("hr")}>`),g=function(t,n,o,r){const a=t.split("\n"),i=[],s=[],l=e=>e.replace(/[&<>"']/g,e=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[e])),c=r?e=>` data-qd="${l(e)}"`:()=>"";for(let t=0;t<a.length;t++){const r=a[t],l=r.match(/^(\s*)([*\-+]|\d+\.)\s+(.+)$/);if(l){const[,t,r,a]=l,d=Math.floor(t.length/2),h=/^\d+\./.test(r),u=h?"ol":"ul";let p=a,m="";const g=a.match(/^\[([x ])\]\s+(.*)$/i);if(g&&!h){const[,t,n]=g,r="x"===t.toLowerCase();p=`<input type="checkbox"${o?' style="margin-right:.5em"':` class="${e}task-checkbox"`}${r?" checked":""} disabled> ${n}`,m=o?' style="list-style:none"':` class="${e}task-item"`}for(;s.length>d+1;){const e=s.pop();i.push(`</${e.type}>`)}if(s.length===d)s.push({type:u,level:d}),i.push(`<${u}${n(u)}>`);else if(s.length===d+1){const e=s[s.length-1];e.type!==u&&(i.push(`</${e.type}>`),s.pop(),s.push({type:u,level:d}),i.push(`<${u}${n(u)}>`))}const f=m||n("li");i.push(`<li${f}${c(r)}>${p}</li>`)}else{for(;s.length>0;){const e=s.pop();i.push(`</${e.type}>`)}i.push(r)}}for(;s.length>0;){const e=s.pop();i.push(`</${e.type}>`)}return i.join("\n")}(g,h,l,c),g=g.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,(e,t,n)=>{const o=m(n,a.allow_unsafe_urls),r=c&&t?` data-qd-alt="${u(t)}"`:"",i=c?` data-qd-src="${u(n)}"`:"";return`<img${h("img")} src="${o}" alt="${t}"${r}${i}${p("!")}>`}),g=g.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(e,t,n)=>{const o=m(n,a.allow_unsafe_urls),r=/^https?:\/\//i.test(o)?' rel="noopener noreferrer"':"",i=c?` data-qd-text="${u(t)}"`:"";return`<a${h("a")} href="${o}"${r}${i}${p("[")}>${t}</a>`}),g=g.replace(/(^|\s)(https?:\/\/[^\s<]+)/g,(e,t,n)=>{const o=m(n,a.allow_unsafe_urls);return`${t}<a${h("a")} href="${o}" rel="noopener noreferrer">${n}</a>`});if([[/\*\*(.+?)\*\*/g,"strong","**"],[/__(.+?)__/g,"strong","__"],[/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,"em","*"],[/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g,"em","_"],[/~~(.+?)~~/g,"del","~~"]].forEach(([e,t,n])=>{g=g.replace(e,`<${t}${h(t)}${p(n)}>$1</${t}>`)}),d){const e=[];let t=0;g=g.replace(/<(table|[uo]l)[^>]*>[\s\S]*?<\/\1>/g,n=>(e[t]=n,`§B${t++}§`)),g=g.replace(/\n\n+/g,"§P§").replace(/(<\/(?:h[1-6]|blockquote|pre)>)\n/g,"$1§N§").replace(/(<(?:h[1-6]|blockquote|pre|hr)[^>]*>)\n/g,"$1§N§").replace(/\n(<(?:h[1-6]|blockquote|pre|hr)[^>]*>)/g,"§N§$1").replace(/\n(§B\d+§)/g,"§N§$1").replace(/(§B\d+§)\n/g,"$1§N§").replace(/\n/g,`<br${h("br")}>`).replace(/§N§/g,"\n").replace(/§P§/g,"</p><p>"),e.forEach((e,t)=>g=g.replace(`§B${t}§`,e)),g="<p>"+g+"</p>"}else g=g.replace(/ {2}$/gm,`<br${h("br")}>`),g=g.replace(/\n\n+/g,(e,t)=>g.substring(0,t).match(/<\/(h[1-6]|blockquote|ul|ol|table|pre|hr)>$/)?"<p>":"</p><p>"),g="<p>"+g+"</p>";return[[/<p><\/p>/g,""],[/<p>(<h[1-6][^>]*>)/g,"$1"],[/(<\/h[1-6]>)<\/p>/g,"$1"],[/<p>(<blockquote[^>]*>)/g,"$1"],[/(<\/blockquote>)<\/p>/g,"$1"],[/<p>(<ul[^>]*>|<ol[^>]*>)/g,"$1"],[/(<\/ul>|<\/ol>)<\/p>/g,"$1"],[/<p>(<hr[^>]*>)<\/p>/g,"$1"],[/<p>(<table[^>]*>)/g,"$1"],[/(<\/table>)<\/p>/g,"$1"],[/<p>(<pre[^>]*>)/g,"$1"],[/(<\/pre>)<\/p>/g,"$1"],[new RegExp(`<p>(${t}\\d+§)</p>`,"g"),"$1"]].forEach(([e,t])=>{g=g.replace(e,t)}),g=g.replace(/(<\/(?:h[1-6]|blockquote|ul|ol|table|pre|hr)>)\n([^<])/g,"$1\n<p>$2"),f.forEach((e,n)=>{let o;if(e.custom&&s&&s.render)if(o=s.render(e.code,e.lang),void 0===o){const t=!l&&e.lang?` class="language-${e.lang}"`:"",n=l?h("code"):t,r=c&&e.lang?` data-qd-lang="${u(e.lang)}"`:"",a=c?` data-qd-fence="${u(e.fence)}"`:"";o=`<pre${h("pre")}${a}${r}><code${n}>${u(e.code)}</code></pre>`}else c&&(o=o.replace(/^<(\w+)/,`<$1 data-qd-fence="${u(e.fence)}" data-qd-lang="${u(e.lang)}" data-qd-source="${u(e.code)}"`));else{const t=!l&&e.lang?` class="language-${e.lang}"`:"",n=l?h("code"):t,r=c&&e.lang?` data-qd-lang="${u(e.lang)}"`:"",a=c?` data-qd-fence="${u(e.fence)}"`:"";o=`<pre${h("pre")}${a}${r}><code${n}>${e.code}</code></pre>`}const r=`${t}${n}§`;g=g.replace(r,o)}),w.forEach((e,t)=>{const n=`§IC${t}§`;g=g.replace(n,`<code${h("code")}${p("`")}>${e}</code>`)}),g.trim()}function a(e,t){return[[/\*\*(.+?)\*\*/g,"strong"],[/__(.+?)__/g,"strong"],[/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g,"em"],[/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g,"em"],[/~~(.+?)~~/g,"del"],[/`([^`]+)`/g,"code"]].forEach(([n,o])=>{e=e.replace(n,`<${o}${t(o)}>$1</${o}>`)}),e}function i(e,t){if(e.length<2)return null;let n=-1;for(let t=1;t<e.length;t++)if(/^\|?[\s\-:|]+\|?$/.test(e[t])&&e[t].includes("-")){n=t;break}if(-1===n)return null;const o=e.slice(0,n),r=e.slice(n+1),i=e[n].trim().replace(/^\|/,"").replace(/\|$/,"").split("|").map(e=>{const t=e.trim();return t.startsWith(":")&&t.endsWith(":")?"center":t.endsWith(":")?"right":"left"});let s=`<table${t("table")}>\n`;return s+=`<thead${t("thead")}>\n`,o.forEach(e=>{s+=`<tr${t("tr")}>\n`;e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,n)=>{const o=i[n]&&"left"!==i[n]?`text-align:${i[n]}`:"",r=a(e.trim(),t);s+=`<th${t("th",o)}>${r}</th>\n`}),s+="</tr>\n"}),s+="</thead>\n",r.length>0&&(s+=`<tbody${t("tbody")}>\n`,r.forEach(e=>{s+=`<tr${t("tr")}>\n`;e.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").forEach((e,n)=>{const o=i[n]&&"left"!==i[n]?`text-align:${i[n]}`:"",r=a(e.trim(),t);s+=`<td${t("td",o)}>${r}</td>\n`}),s+="</tr>\n"}),s+="</tbody>\n"),s+="</table>",s}function s(e,t={}){return r(e,{...t,bidirectional:!0})}async function l(e,t=!1){return new Promise((n,o)=>{const r=(new XMLSerializer).serializeToString(e),a=document.createElement("canvas"),i=a.getContext("2d"),s=new Image,l=e.closest(".mermaid")||e.classList.contains("mermaid"),c=e.getAttribute("width")&&e.getAttribute("height");let d,h;l||!c?(d=e.clientWidth||e.viewBox&&e.viewBox.baseVal.width||parseFloat(e.getAttribute("width"))||400,h=e.clientHeight||e.viewBox&&e.viewBox.baseVal.height||parseFloat(e.getAttribute("height"))||300):(d=parseFloat(e.getAttribute("width"))||e.viewBox&&e.viewBox.baseVal.width||e.clientWidth||400,h=parseFloat(e.getAttribute("height"))||e.viewBox&&e.viewBox.baseVal.height||e.clientHeight||300);let u=r;if(d&&h){const e=document.createElement("div");e.innerHTML=r;const t=e.querySelector("svg");t&&(t.setAttribute("width",d.toString()),t.setAttribute("height",h.toString()),u=(new XMLSerializer).serializeToString(t))}a.width=2*d,a.height=2*h,i.scale(2,2),s.onload=()=>{try{t&&(i.fillStyle="white",i.fillRect(0,0,a.width,a.height)),i.drawImage(s,0,0,d,h),a.toBlob(e=>{n(e)},"image/png",1)}catch(e){o(e)}},s.onerror=o;const p=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(u)}`;s.src=p})}async function c(e){try{if(!e._map)return console.warn("No map found on container"),null;const t=e.getBoundingClientRect(),n=Math.round(t.width),o=Math.round(t.height);if(0===n||0===o)return console.warn("Map container has zero dimensions"),null;const r=document.createElement("canvas"),a=window.devicePixelRatio||1;r.width=n*a,r.height=o*a,r.style.width=n+"px",r.style.height=o+"px";const i=r.getContext("2d");i.scale(a,a),i.fillStyle="#FFFFFF",i.fillRect(0,0,n,o);const s=e.querySelectorAll(".leaflet-tile"),l=[];for(const e of s)l.push(new Promise(n=>{const o=new Image;o.crossOrigin="anonymous",o.onload=()=>{try{const n=e.getBoundingClientRect(),r=n.left-t.left,a=n.top-t.top;i.drawImage(o,r,a,n.width,n.height)}catch(e){console.warn("Failed to draw tile:",e)}n()},o.onerror=()=>{console.warn("Failed to load tile:",e.src),n()},o.src=e.src}));await Promise.all(l);const c=e.querySelectorAll("svg:not(.leaflet-attribution-flag)");for(const e of c)if(!e.closest(".leaflet-control"))try{const n=e.getBoundingClientRect(),o=n.left-t.left,r=n.top-t.top,a=(new XMLSerializer).serializeToString(e),s=new Blob([a],{type:"image/svg+xml;charset=utf-8"}),l=URL.createObjectURL(s);await new Promise((e,t)=>{const a=new Image;a.onload=()=>{i.drawImage(a,o,r,n.width,n.height),URL.revokeObjectURL(l),e()},a.onerror=()=>{URL.revokeObjectURL(l),t(new Error("Failed to load SVG overlay"))},a.src=l})}catch(e){console.warn("Failed to draw SVG overlay:",e)}const d=e.querySelectorAll(".leaflet-marker-icon");for(const e of d)try{const n=new Image;n.crossOrigin="anonymous",await new Promise(o=>{n.onload=()=>{const r=e.getBoundingClientRect(),a=r.left-t.left,s=r.top-t.top;i.drawImage(n,a,s,r.width,r.height),o()},n.onerror=o,n.src=e.src})}catch(e){console.warn("Failed to draw marker icon:",e)}return r.toDataURL("image/png",1)}catch(e){return console.error("Failed to rasterize GeoJSON map:",e),null}}async function d(e){if(!e)throw new Error("No preview panel available");const t=e.querySelectorAll(".math-display");if(t.length>0){if(Array.from(t).some(e=>!e.querySelector("mjx-container"))&&window.MathJax&&window.MathJax.typesetPromise)try{await window.MathJax.typesetPromise(Array.from(t))}catch(e){console.warn("MathJax typesetting failed:",e)}}const n=e.cloneNode(!0);try{n.querySelectorAll("strong, b").forEach(e=>{e.style.fontWeight="bold"}),n.querySelectorAll("em, i").forEach(e=>{e.style.fontStyle="italic"}),n.querySelectorAll("del, s, strike").forEach(e=>{e.style.textDecoration="line-through"}),n.querySelectorAll("u").forEach(e=>{e.style.textDecoration="underline"}),n.querySelectorAll("code:not(pre code)").forEach(e=>{e.style.backgroundColor="#f4f4f4",e.style.padding="2px 4px",e.style.borderRadius="3px",e.style.fontFamily="monospace",e.style.fontSize="0.9em"}),n.querySelectorAll("h1").forEach(e=>{e.style.fontSize="2em",e.style.fontWeight="bold",e.style.marginTop="0.67em",e.style.marginBottom="0.67em"}),n.querySelectorAll("h2").forEach(e=>{e.style.fontSize="1.5em",e.style.fontWeight="bold",e.style.marginTop="0.83em",e.style.marginBottom="0.83em"}),n.querySelectorAll("h3").forEach(e=>{e.style.fontSize="1.17em",e.style.fontWeight="bold",e.style.marginTop="1em",e.style.marginBottom="1em"}),n.querySelectorAll("h4").forEach(e=>{e.style.fontSize="1em",e.style.fontWeight="bold",e.style.marginTop="1.33em",e.style.marginBottom="1.33em"}),n.querySelectorAll("h5").forEach(e=>{e.style.fontSize="0.83em",e.style.fontWeight="bold",e.style.marginTop="1.67em",e.style.marginBottom="1.67em"}),n.querySelectorAll("h6").forEach(e=>{e.style.fontSize="0.67em",e.style.fontWeight="bold",e.style.marginTop="2.33em",e.style.marginBottom="2.33em"}),n.querySelectorAll("blockquote").forEach(e=>{e.style.borderLeft="4px solid #ddd",e.style.marginLeft="0",e.style.paddingLeft="1em",e.style.color="#666"}),n.querySelectorAll("hr").forEach(e=>{e.style.border="none",e.style.borderTop="1px solid #ccc",e.style.margin="1em 0"}),n.querySelectorAll("table").forEach(e=>{e.style.borderCollapse="collapse",e.style.width="100%",e.style.marginBottom="1em"}),n.querySelectorAll("th").forEach(e=>{e.style.border="1px solid #ccc",e.style.padding="8px",e.style.textAlign="left",e.style.backgroundColor="#f0f0f0",e.style.fontWeight="bold"}),n.querySelectorAll("td").forEach(e=>{e.style.border="1px solid #ccc",e.style.padding="8px",e.style.textAlign="left"}),n.querySelectorAll("a").forEach(e=>{e.style.color="#0066cc",e.style.textDecoration="underline"}),n.querySelectorAll("pre code").forEach(e=>{const t=e.parentElement;e.classList.contains("hljs")&&(e.querySelectorAll(".hljs-keyword").forEach(e=>{e.style.color="#d73a49",e.style.fontWeight="bold"}),e.querySelectorAll(".hljs-string").forEach(e=>{e.style.color="#032f62"}),e.querySelectorAll(".hljs-number").forEach(e=>{e.style.color="#005cc5"}),e.querySelectorAll(".hljs-comment").forEach(e=>{e.style.color="#6a737d",e.style.fontStyle="italic"}),e.querySelectorAll(".hljs-function").forEach(e=>{e.style.color="#6f42c1"}),e.querySelectorAll(".hljs-class").forEach(e=>{e.style.color="#6f42c1"}),e.querySelectorAll(".hljs-title").forEach(e=>{e.style.color="#6f42c1"}),e.querySelectorAll(".hljs-built_in").forEach(e=>{e.style.color="#005cc5"}),e.querySelectorAll(".hljs-literal").forEach(e=>{e.style.color="#005cc5"}),e.querySelectorAll(".hljs-meta").forEach(e=>{e.style.color="#005cc5"}),e.querySelectorAll(".hljs-attr").forEach(e=>{e.style.color="#22863a"}),e.querySelectorAll(".hljs-variable").forEach(e=>{e.style.color="#e36209"}),e.querySelectorAll(".hljs-regexp").forEach(e=>{e.style.color="#032f62"}),e.querySelectorAll(".hljs-selector-class").forEach(e=>{e.style.color="#22863a"}),e.querySelectorAll(".hljs-selector-id").forEach(e=>{e.style.color="#6f42c1"}),e.querySelectorAll(".hljs-selector-tag").forEach(e=>{e.style.color="#22863a"}),e.querySelectorAll(".hljs-tag").forEach(e=>{e.style.color="#22863a"}),e.querySelectorAll(".hljs-name").forEach(e=>{e.style.color="#22863a"}),e.querySelectorAll(".hljs-attribute").forEach(e=>{e.style.color="#6f42c1"}));const n=document.createElement("table");n.style.width="100%",n.style.borderCollapse="collapse",n.style.border="none",n.style.marginBottom="1em";const o=document.createElement("tr"),r=document.createElement("td");r.style.backgroundColor="#f7f7f7",r.style.padding="12px",r.style.fontFamily='Consolas, Monaco, "Courier New", monospace',r.style.fontSize="14px",r.style.lineHeight="1.4",r.style.whiteSpace="pre",r.style.overflowX="auto",r.style.border="1px solid #ddd",r.style.borderRadius="4px",r.innerHTML=e.innerHTML,o.appendChild(r),n.appendChild(o),t.parentNode.replaceChild(n,t)});const t=n.querySelectorAll("img");for(const e of t){!e.width&&e.naturalWidth&&(e.width=e.naturalWidth),!e.height&&e.naturalHeight&&(e.height=e.naturalHeight);const t=800,n=600;if(e.width>t||e.height>n){const o=Math.min(t/e.width,n/e.height);e.width=Math.round(e.width*o),e.height=Math.round(e.height*o)}if(e.width&&(e.setAttribute("width",e.width.toString()),e.style.width=e.width+"px"),e.height&&(e.setAttribute("height",e.height.toString()),e.style.height=e.height+"px"),e.getAttribute("v:shapes")||e.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),e.src&&!e.src.startsWith("data:"))try{const t=await fetch(e.src),n=await t.blob(),o=2097152;if(n.size>o){console.warn("Image too large for inline data URL:",e.src,"Size:",n.size);continue}const r=await new Promise(e=>{const t=new FileReader;t.onloadend=()=>e(t.result),t.readAsDataURL(n)});e.src=r}catch(t){console.warn("Failed to convert image to data URL:",e.src,t)}}const o=n.querySelectorAll(".qde-stl-container");for(const t of o){try{const n=t.dataset.stlId,o=e.querySelector(`.qde-stl-container[data-stl-id="${n}"]`);if(o){const e=o.querySelector("canvas");if(e&&e.width>0&&e.height>0)try{const n=o._threeRenderer,r=o._threeScene,a=o._threeCamera;n&&r&&a&&n.render(r,a);const i=e.toDataURL("image/png",1),s=document.createElement("img");s.src=i;const l=e.width/2,c=e.height/2;s.width=l,s.height=c,s.setAttribute("width",l.toString()),s.setAttribute("height",c.toString()),s.style.width=l+"px",s.style.height=c+"px",s.style.maxWidth="none",s.style.maxHeight="none",s.style.border="1px solid #ddd",s.style.borderRadius="4px",s.style.margin="0.5em 0",s.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),s.alt="STL 3D Model",t.parentNode.replaceChild(s,t);continue}catch(e){console.warn("Failed to convert STL canvas to image (likely WebGL context issue):",e)}else console.warn("No valid canvas found in STL container")}else console.warn("Could not find original STL container")}catch(e){console.error("Error processing STL container for copy:",e)}const n=document.createElement("div");n.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",n.textContent="[STL 3D Model - Interactive content not available in copy]",t.parentNode.replaceChild(n,t)}const r=n.querySelectorAll(".mermaid");for(const e of r){const t=e.querySelector("svg");if(t)try{const n=await l(t),o=await new Promise(e=>{const t=new FileReader;t.onloadend=()=>e(t.result),t.readAsDataURL(n)}),r=document.createElement("img");r.src=o;const a=t.closest(".mermaid")||t.classList.contains("mermaid"),i=t.getAttribute("width")&&t.getAttribute("height");let s,c;a||!i?(s=t.clientWidth||t.viewBox&&t.viewBox.baseVal.width||parseFloat(t.getAttribute("width"))||400,c=t.clientHeight||t.viewBox&&t.viewBox.baseVal.height||parseFloat(t.getAttribute("height"))||300):(s=parseFloat(t.getAttribute("width"))||t.viewBox&&t.viewBox.baseVal.width||t.clientWidth||400,c=parseFloat(t.getAttribute("height"))||t.viewBox&&t.viewBox.baseVal.height||t.clientHeight||300),r.width=s,r.height=c,r.setAttribute("width",s.toString()),r.setAttribute("height",c.toString()),r.style.width=s+"px",r.style.height=c+"px",r.style.maxWidth="none",r.style.maxHeight="none",r.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),r.alt="Mermaid Diagram",e.parentNode.replaceChild(r,e)}catch(e){console.warn("Failed to convert Mermaid diagram:",e)}}const a=n.querySelectorAll(".qde-chart-container");for(const t of a){try{const n=t.dataset.chartId,o=e.querySelector(`.qde-chart-container[data-chart-id="${n}"]`);if(o){const e=o.querySelector("canvas");if(e&&e.width>0&&e.height>0)try{const n=e.toDataURL("image/png",1),o=document.createElement("img");o.src=n;const r=e.width,a=e.height;o.width=r,o.height=a,o.setAttribute("width",r.toString()),o.setAttribute("height",a.toString()),o.style.width=r+"px",o.style.height=a+"px",o.style.maxWidth="none",o.style.maxHeight="none",o.style.margin="0.5em 0",o.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),o.alt="Chart",t.parentNode.replaceChild(o,t);continue}catch(e){console.warn("Failed to convert chart canvas to image:",e)}}}catch(e){console.warn("Error processing chart container:",e)}const n=document.createElement("div");n.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",n.textContent="[Chart - Interactive content not available in copy]",t.parentNode.replaceChild(n,t)}const i=n.querySelectorAll(".qde-svg-container svg");for(const e of i)try{const t=await l(e),n=await new Promise(e=>{const n=new FileReader;n.onloadend=()=>e(n.result),n.readAsDataURL(t)}),o=document.createElement("img");o.src=n;let r,a;e.getAttribute("width")&&e.getAttribute("height")?(r=parseFloat(e.getAttribute("width"))||e.viewBox&&e.viewBox.baseVal.width||e.clientWidth||400,a=parseFloat(e.getAttribute("height"))||e.viewBox&&e.viewBox.baseVal.height||e.clientHeight||300):(r=e.clientWidth||e.viewBox&&e.viewBox.baseVal.width||parseFloat(e.getAttribute("width"))||400,a=e.clientHeight||e.viewBox&&e.viewBox.baseVal.height||parseFloat(e.getAttribute("height"))||300),o.width=r,o.height=a,o.setAttribute("width",r.toString()),o.setAttribute("height",a.toString()),o.style.width=r+"px",o.style.height=a+"px",o.style.maxWidth="none",o.style.maxHeight="none",o.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),o.alt="SVG Image",e.parentNode.replaceChild(o,e)}catch(e){console.warn("Failed to convert SVG to image:",e)}const s=Array.from(n.querySelectorAll(".math-display"));if(s.length>0)for(const e of s)try{const t=e.querySelector("svg");if(!t){console.warn("No SVG found in math element, skipping");continue}const n=(new XMLSerializer).serializeToString(t),o=new Blob([n],{type:"image/svg+xml;charset=utf-8"}),r=URL.createObjectURL(o),a=new Image,i=await new Promise((e,n)=>{a.onload=function(){const n=document.createElement("canvas");let o,i;try{o=t.width.baseVal.value,i=t.height.baseVal.value}catch(e){t.viewBox&&t.viewBox.baseVal?(o=t.viewBox.baseVal.width,i=t.viewBox.baseVal.height):(o=a.naturalWidth||a.width||200,i=a.naturalHeight||a.height||50)}let s=.04;const l=o*s,c=i*s;if(l>150||c>45){const e=150/l,t=45/c;s*=Math.min(e,t)}o*=s,i*=s;n.width=2*o,n.height=2*i,n.style.width=o+"px",n.style.height=i+"px";const d=n.getContext("2d");d.scale(2,2),d.fillStyle="#FFFFFF",d.fillRect(0,0,o,i),d.drawImage(a,0,0,o,i),URL.revokeObjectURL(r),e(n.toDataURL("image/png"))},a.onerror=()=>{URL.revokeObjectURL(r),n(new Error("Failed to load SVG image"))},a.src=r}),s=document.createElement("img");s.src=i;const l=new Image;l.src=i,await new Promise(e=>{l.onload=e,l.onerror=e,setTimeout(e,100)});const c=l.naturalWidth/2,d=l.naturalHeight/2;s.width=c,s.height=d,s.style.cssText=`display:inline-block;margin:0.5em 0;width:${c}px;height:${d}px;vertical-align:middle;`,s.alt="Math equation",e.parentNode.replaceChild(s,e)}catch(e){console.error("Failed to convert math element to image:",e)}const d=n.querySelectorAll(".geojson-container");if(d.length>0)for(const t of d)try{const n=t.getAttribute("data-original-source");if(!n){console.warn("No original source found for GeoJSON container");continue}let o=null;const r=e.querySelectorAll(".geojson-container");for(const e of r)if(e.getAttribute("data-original-source")===n){o=e;break}if(!o){console.warn("Could not find live GeoJSON container");const e=document.createElement("div");e.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",e.textContent="[GeoJSON Map - Interactive content not available in copy]",t.parentNode.replaceChild(e,t);continue}if(!o._map){console.warn("Map not initialized yet");const e=document.createElement("div");e.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",e.textContent="[GeoJSON Map - Still loading]",t.parentNode.replaceChild(e,t);continue}const a=await c(o);if(a){const e=document.createElement("img");e.src=a,e.style.cssText="width: 100%; height: 300px; border: 1px solid #ddd; border-radius: 4px; margin: 0.5em 0;",e.alt="GeoJSON Map",t.parentNode.replaceChild(e,t)}else{const e=document.createElement("div");e.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",e.textContent="[GeoJSON Map - Interactive content not available in copy]",t.parentNode.replaceChild(e,t)}}catch(e){console.error("Failed to process GeoJSON container:",e);const n=document.createElement("div");n.style.cssText="padding: 12px; background-color: #f0f0f0; border: 1px solid #ccc; text-align: center; margin: 0.5em 0; border-radius: 4px;",n.textContent="[GeoJSON Map - Interactive content not available in copy]",t.parentNode.replaceChild(n,t)}const h=n.querySelectorAll('[data-qd-lang="geojson"]');for(const t of h)try{const n=t.id,o=n?e.querySelector(`#${n}`):null;if(!o)continue;const r=o.querySelector(".leaflet-container");if(!r)continue;const a=Math.max(1,window.devicePixelRatio||1),i=r.clientWidth||600,s=r.clientHeight||400,l=document.createElement("canvas");l.width=Math.round(i*a),l.height=Math.round(s*a);const c=l.getContext("2d");c.scale(a,a),c.fillStyle="#FFFFFF",c.fillRect(0,0,i,s);const d=r.getBoundingClientRect(),h=Array.from(r.querySelectorAll("img.leaflet-tile"));for(const e of h)try{const t=e.getBoundingClientRect(),n=Math.round(t.left-d.left),o=Math.round(t.top-d.top),r=Math.round(t.width),a=Math.round(t.height),i=!(t.right<=d.left||t.left>=d.right||t.bottom<=d.top||t.top>=d.bottom),s=window.getComputedStyle(e);r>0&&a>0&&i&&"none"!==s.display&&"hidden"!==s.visibility&&c.drawImage(e,n,o,r+1,a+1)}catch(e){console.warn("Failed to draw tile:",e)}const u=o.querySelectorAll(".leaflet-overlay-pane svg");for(const e of u)try{const t=(new XMLSerializer).serializeToString(e),n="data:image/svg+xml;charset=utf-8,"+encodeURIComponent(t),o=new Image;await new Promise(e=>{o.onload=e,o.onerror=e,o.src=n});const r=e.getBoundingClientRect(),a=Math.round(r.left-d.left),i=Math.round(r.top-d.top),s=Math.round(r.width),l=Math.round(r.height),h=!(r.right<=d.left||r.left>=d.right||r.bottom<=d.top||r.top>=d.bottom);s>0&&l>0&&h&&c.drawImage(o,a,i,s,l)}catch(e){console.warn("Failed to draw overlay SVG:",e)}const p=o.querySelectorAll(".leaflet-marker-pane img.leaflet-marker-icon");for(const e of p)try{const t=e.getBoundingClientRect(),n=Math.round(t.left-d.left),o=Math.round(t.top-d.top),r=Math.round(t.width),a=Math.round(t.height),i=!(t.right<=d.left||t.left>=d.right||t.bottom<=d.top||t.top>=d.bottom),s=window.getComputedStyle(e);r>0&&a>0&&i&&"none"!==s.display&&"hidden"!==s.visibility&&c.drawImage(e,n,o,r,a)}catch(e){console.warn("Failed to draw marker icon:",e)}let m="";try{m=l.toDataURL("image/png",1)}catch(e){console.warn("Map canvas tainted; falling back to placeholder")}const g=document.createElement("img");m?(g.src=m,g.width=i,g.height=s,g.setAttribute("width",String(i)),g.setAttribute("height",String(s)),g.style.width=i+"px",g.style.height=s+"px",g.style.display="block",g.style.border="1px solid #ddd",g.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9)),g.alt="Map"):(g.alt="Map",g.style.width=i+"px",g.style.height=s+"px",g.style.border="1px solid #ddd",g.style.backgroundColor="#f0f0f0"),t.parentNode.replaceChild(g,t)}catch(e){console.warn("Failed to process map container:",e)}const u=n.querySelectorAll(".qde-html-container");for(const e of u)try{const t=e.getAttribute("data-qd-source"),n=e.querySelector("pre");if(t){const n=document.createElement("div");n.innerHTML=t;const o=n.querySelectorAll("img");for(const e of o){const t=e.getAttribute("width"),n=e.getAttribute("height");if(t&&(e.width=parseInt(t),e.style.width=t.includes("%")?t:`${e.width}px`),n&&(e.height=parseInt(n),e.style.height=n.includes("%")?n:`${e.height}px`),e.src&&!e.src.startsWith("data:"))try{const o=document.createElement("canvas"),r=o.getContext("2d"),a=new Image;a.crossOrigin="anonymous",await new Promise((i,s)=>{if(a.onload=function(){let s=0,l=0;if(t&&!t.includes("%")&&(s=parseInt(t)),n&&!n.includes("%")&&(l=parseInt(n)),s>0&&0===l){if(a.naturalWidth>0){const e=a.naturalHeight/a.naturalWidth;l=Math.round(s*e)}}else if(l>0&&0===s){if(a.naturalHeight>0){const e=a.naturalWidth/a.naturalHeight;s=Math.round(l*e)}}else 0===s&&0===l&&(s=a.naturalWidth||250,l=a.naturalHeight||200);o.width=s,o.height=l,r.drawImage(a,0,0,s,l);const c=o.toDataURL("image/png",1);e.src=c,e.width=s,e.height=l,e.setAttribute("width",s.toString()),e.setAttribute("height",l.toString()),e.style.width=s+"px",e.style.height=l+"px",i()},a.onerror=function(){console.warn("Failed to load HTML fence image:",e.src),s(new Error("Image load failed"))},e.src.startsWith("http")||e.src.startsWith("//"))a.src=e.src;else{const t=new Image;t.src=e.src,a.src=t.src}})}catch(t){console.warn("Failed to convert HTML fence image:",e.src,t)}e.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9))}e.innerHTML=n.innerHTML}else if(!n){const t=e.querySelectorAll("img");for(const e of t){const t=e.getAttribute("width"),n=e.getAttribute("height");if(t&&(e.width=parseInt(t),e.style.width=t.includes("%")?t:`${e.width}px`),n&&(e.height=parseInt(n),e.style.height=n.includes("%")?n:`${e.height}px`),e.src&&!e.src.startsWith("data:"))try{const t=document.createElement("canvas"),n=t.getContext("2d"),o=new Image;o.crossOrigin="anonymous",await new Promise((r,a)=>{if(o.onload=function(){let a=e.width||0,i=e.height||0;if(a&&!i){const e=o.naturalHeight/o.naturalWidth;i=Math.round(a*e)}else if(i&&!a){const e=o.naturalWidth/o.naturalHeight;a=Math.round(i*e)}else a||i||(a=o.naturalWidth||250,i=o.naturalHeight||Math.round(o.naturalHeight/o.naturalWidth*250));t.width=a,t.height=i,n.drawImage(o,0,0,a,i);const s=t.toDataURL("image/png",1);e.src=s,e.width=a,e.height=i,e.setAttribute("width",a.toString()),e.setAttribute("height",i.toString()),e.style.width=a+"px",e.style.height=i+"px",r()},o.onerror=function(){console.warn("Failed to load HTML fence image:",e.src),a(new Error("Image load failed"))},e.src.startsWith("http")||e.src.startsWith("//"))o.src=e.src;else{const t=new Image;t.src=e.src,o.src=t.src}})}catch(t){console.warn("Failed to convert HTML fence image:",e.src,t)}e.setAttribute("v:shapes","image"+Math.random().toString(36).substr(2,9))}}}catch(e){console.warn("Failed to process HTML container:",e)}const p=n.innerHTML,m=`\n <!DOCTYPE html>\n <html xmlns:v="urn:schemas-microsoft-com:vml"\n xmlns:o="urn:schemas-microsoft-com:office:office"\n xmlns:w="urn:schemas-microsoft-com:office:word">\n <head>\n <meta charset="utf-8">\n <style>\n /* Table styling */\n table { border-collapse: collapse; width: 100%; margin-bottom: 1em; }\n th, td { border: 1px solid #ccc; padding: 8px; text-align: left; }\n th { background-color: #f0f0f0; font-weight: bold; }\n \n /* Code block styling */\n pre { background-color: #f4f4f4; padding: 1em; border-radius: 4px; overflow-x: auto; }\n code { font-family: monospace; background-color: #f4f4f4; padding: 0.2em 0.4em; border-radius: 3px; }\n \n /* Image handling */\n img { display: block; max-width: 100%; height: auto; margin: 0.5em 0; }\n \n /* Blockquote */\n blockquote { border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666; }\n \n /* Math equations centered like squibview */\n .math-display { text-align: center; margin: 1em 0; }\n .math-display img { display: inline-block; margin: 0 auto; }\n </style>\n </head>\n <body>\x3c!--StartFragment--\x3e${p}\x3c!--EndFragment--\x3e</body>\n </html>`,g=n.textContent||n.innerText||"";if("macos"===function(){const e=navigator.platform?.toLowerCase()||"",t=navigator.userAgent?.toLowerCase()||"";return e.includes("mac")||t.includes("mac")?"macos":t.includes("windows")?"windows":t.includes("linux")?"linux":"unknown"}())try{return await navigator.clipboard.write([new ClipboardItem({"text/html":new Blob([m],{type:"text/html"}),"text/plain":new Blob([g],{type:"text/plain"})})]),{success:!0,html:m,text:g}}catch(e){if(console.warn("Modern clipboard API failed, trying Safari fallback:",e),function(e){let t,n;try{t=document.createElement("div"),t.style.position="fixed",t.style.left="-9999px",t.style.top="0",t.style.width="1px",t.style.height="1px",t.style.overflow="hidden",t.innerHTML=e,document.body.appendChild(t);const o=document.createRange();o.selectNodeContents(t);const r=window.getSelection();r.removeAllRanges(),r.addRange(o),n=document.execCommand("copy"),r.removeAllRanges()}catch(e){console.error("Fallback copy failed:",e),n=!1}finally{t&&t.parentNode&&document.body.removeChild(t)}return n}(p))return{success:!0,html:m,text:g};throw new Error("Fallback copy failed")}else{const e=document.createElement("div");e.style.position="fixed",e.style.left="-9999px",e.style.top="0",e.innerHTML=p,document.body.appendChild(e);try{return await navigator.clipboard.write([new ClipboardItem({"text/html":new Blob([m],{type:"text/html"}),"text/plain":new Blob([g],{type:"text/plain"})})]),{success:!0,html:m,text:g}}catch(t){console.warn("Modern clipboard API failed, trying execCommand fallback:",t);const n=window.getSelection(),o=document.createRange();o.selectNodeContents(e),n.removeAllRanges(),n.addRange(o);if(!document.execCommand("copy"))throw new Error("Fallback copy failed");return{success:!0,html:m,text:g}}finally{e&&e.parentNode&&document.body.removeChild(e)}}}catch(e){throw console.error("Failed to copy rendered content:",e),e}}
|
|
8
8
|
/**
|
|
9
9
|
* Quikdown Editor - A drop-in markdown editor control
|
|
10
10
|
* @version 1.0.5
|
|
11
11
|
* @license BSD-2-Clause
|
|
12
|
-
*/r.emitStyles=function(e="quikdown-",t="light"){const n=o,r={"#f4f4f4":"#2a2a2a","#f0f0f0":"#2a2a2a","#f2f2f2":"#2a2a2a","#ddd":"#3a3a3a","#06c":"#6db3f2",_textColor:"#e0e0e0"},a={_textColor:"#333"};let i="";for(const[o,l]of Object.entries(n)){let n=l;if("dark"===t&&r){for(const[e,t]of Object.entries(r))e.startsWith("_")||(n=n.replace(new RegExp(e,"g"),t));["h1","h2","h3","h4","h5","h6","td","li","blockquote"].includes(o)&&(n+=`;color:${r._textColor}`)}else if("light"===t&&a){["h1","h2","h3","h4","h5","h6","td","li","blockquote"].includes(o)&&(n+=`;color:${a._textColor}`)}i+=`.${e}${o} { ${n} }\n`}return i},r.configure=function(e){return function(t){return r(t,e)}},r.version="1.1.1","undefined"!=typeof module&&module.exports&&(module.exports=r),"undefined"!=typeof window&&(window.quikdown=r),Object.keys(r).forEach(e=>{l[e]=r[e]}),l.toMarkdown=function(e,t={}){let n;if("string"==typeof e)n=document.createElement("div"),n.innerHTML=e;else{if(!(e instanceof Element))return"";n=e}function o(e,n={}){if(e.nodeType===Node.TEXT_NODE)return e.textContent;if(e.nodeType!==Node.ELEMENT_NODE)return"";const a=e.tagName.toLowerCase(),i=e.getAttribute("data-qd");let l="";for(let t of e.childNodes)l+=o(t,{parentTag:a,...n});switch(a){case"h1":case"h2":case"h3":case"h4":case"h5":case"h6":const n=parseInt(a[1]);return`${i||"#".repeat(n)} ${l.trim()}\n\n`;case"strong":case"b":if(!l)return"";const o=i||"**";return`${o}${l}${o}`;case"em":case"i":if(!l)return"";const s=i||"*";return`${s}${l}${s}`;case"del":case"s":case"strike":if(!l)return"";const c=i||"~~";return`${c}${l}${c}`;case"code":if(!l)return"";const d=i||"`";return`${d}${l}${d}`;case"pre":const h=e.getAttribute("data-qd-fence")||i||"```",u=e.getAttribute("data-qd-lang")||"";if(t.fence_plugin&&t.fence_plugin.reverse&&u)try{const n=t.fence_plugin.reverse(e);if(n&&n.content){const e=n.fence||h;return`${e}${n.lang||u}\n${n.content}\n${e}\n\n`}}catch(e){console.warn("Fence reverse handler error:",e)}const p=e.getAttribute("data-qd-source");if(p)return`${h}${u}\n${p}\n${h}\n\n`;const m=e.querySelector("code");return`${h}${u}\n${(m?m.textContent:l).trimEnd()}\n${h}\n\n`;case"blockquote":const g=i||">";return l.trim().split("\n").map(e=>`${g} ${e}`).join("\n")+"\n\n";case"hr":return`${i||"---"}\n\n`;case"br":return`${i||" "}\n`;case"a":const f=e.getAttribute("data-qd-text")||l.trim(),w=e.getAttribute("href")||"";return f!==w||i?`[${f}](${w})`:`<${w}>`;case"img":return`${i||"!"}[${e.getAttribute("data-qd-alt")||e.getAttribute("alt")||""}](${e.getAttribute("data-qd-src")||e.getAttribute("src")||""})`;case"ul":case"ol":return r(e,"ol"===a)+"\n";case"li":case"span":default:return l;case"table":return function(e){let t="";const n=e.getAttribute("data-qd-align"),o=n?n.split(","):[],r=e.querySelector("thead");if(r){const e=r.querySelector("tr");if(e){const n=[];for(let t of e.querySelectorAll("th"))n.push(t.textContent.trim());t+="| "+n.join(" | ")+" |\n";t+="| "+n.map((e,t)=>{const n=o[t]||"left";return"center"===n?":---:":"right"===n?"---:":"---"}).join(" | ")+" |\n"}}const a=e.querySelector("tbody");if(a)for(let e of a.querySelectorAll("tr")){const n=[];for(let t of e.querySelectorAll("td"))n.push(t.textContent.trim());n.length>0&&(t+="| "+n.join(" | ")+" |\n")}return t.trim()}(e)+"\n\n";case"p":if(l.trim()){const e=l.split("\n");let t=l.trim();if(e.length>1){let n=0;for(let t=e.length-1;t>=0&&""===e[t].trim();t--)n++;if(n>0)return t+="\n ",t+"\n"}return t+"\n\n"}return"";case"div":const y=e.getAttribute("data-qd-lang"),b=e.getAttribute("data-qd-fence");if(y&&t.fence_plugin&&t.fence_plugin.reverse)try{const n=t.fence_plugin.reverse(e);if(n&&n.content){const e=n.fence||b||"```";return`${e}${n.lang||y}\n${n.content}\n${e}\n\n`}}catch(e){console.warn("Fence reverse handler error:",e)}const x=e.getAttribute("data-qd-source");if(x&&b)return`${b}${y||""}\n${x}\n${b}\n\n`;if(e.classList&&e.classList.contains("mermaid-container")){const t=e.getAttribute("data-qd-fence")||"```",n=e.getAttribute("data-qd-lang")||"mermaid",o=e.getAttribute("data-qd-source");if(o){const e=document.createElement("textarea");e.innerHTML=o;return`${t}${n}\n${e.value}\n${t}\n\n`}const r=e.querySelector("pre.mermaid");if(r){const e=r.getAttribute("data-qd-source");if(e){const o=document.createElement("textarea");o.innerHTML=e;return`${t}${n}\n${o.value}\n${t}\n\n`}}const a=e.querySelector(".mermaid-source");if(a){const e=document.createElement("div");e.innerHTML=a.innerHTML;return`${t}${n}\n${e.textContent}\n${t}\n\n`}const i=e.querySelector(".mermaid");if(i&&i.textContent.includes("graph"))return`${t}${n}\n${i.textContent.trim()}\n${t}\n\n`}if(e.classList&&e.classList.contains("mermaid")){const t=e.getAttribute("data-qd-fence")||"```";return`${t}${e.getAttribute("data-qd-lang")||"mermaid"}\n${e.textContent.trim()}\n${t}\n\n`}return l}}function r(e,t,n=0){let a="",i=1;const l=" ".repeat(n);for(let s of e.children){if("LI"!==s.tagName)continue;let e=s.getAttribute("data-qd")||(t?`${i}.`:"-");const c=s.querySelector('input[type="checkbox"]');if(c){const t=c.checked?"x":" ";e="-";let n="";for(let e of s.childNodes)e.nodeType===Node.TEXT_NODE?n+=e.textContent:e.tagName&&"INPUT"!==e.tagName&&(n+=o(e));a+=`${l}${e} [${t}] ${n.trim()}\n`}else{let t="";for(let e of s.childNodes)"UL"===e.tagName||"OL"===e.tagName?t+=r(e,"OL"===e.tagName,n+1):t+=o(e);a+=`${l}${e} ${t.trim()}\n`}i++}return a}let a=o(n);return a=a.replace(/\n{3,}/g,"\n\n"),a=a.trim(),a},l.configure=function(e){return function(t){return l(t,e)}},"undefined"!=typeof module&&module.exports&&(module.exports=l),"undefined"!=typeof window&&(window.quikdown_bd=l);const h={mode:"split",showToolbar:!0,showRemoveHR:!1,theme:"auto",lazy_linefeeds:!1,inline_styles:!1,debounceDelay:20,placeholder:"Start typing markdown...",plugins:{highlightjs:!1,mermaid:!1},customFences:{},enableComplexFences:!0};class u{constructor(e,t={}){if(this.container="string"==typeof e?document.querySelector(e):e,!this.container)throw new Error("QuikdownEditor: Invalid container");this.options={...h,...t},this._markdown="",this._html="",this.currentMode=this.options.mode,this.updateTimer=null,this.initPromise=this.init()}async init(){await this.loadPlugins(),this.buildUI(),this.attachEvents(),this.applyTheme(),this.setMode(this.currentMode),this.options.initialContent&&this.setMarkdown(this.options.initialContent)}buildUI(){this.container.innerHTML="",this.container.classList.add("qde-container"),this.options.showToolbar&&(this.toolbar=this.createToolbar(),this.container.appendChild(this.toolbar)),this.editorArea=document.createElement("div"),this.editorArea.className="qde-editor",this.sourcePanel=document.createElement("div"),this.sourcePanel.className="qde-source",this.sourceTextarea=document.createElement("textarea"),this.sourceTextarea.className="qde-textarea",this.sourceTextarea.placeholder=this.options.placeholder,this.sourcePanel.appendChild(this.sourceTextarea),this.previewPanel=document.createElement("div"),this.previewPanel.className="qde-preview",this.previewPanel.contentEditable=!0,this.editorArea.appendChild(this.sourcePanel),this.editorArea.appendChild(this.previewPanel),this.container.appendChild(this.editorArea),this.injectStyles()}createToolbar(){const e=document.createElement("div");e.className="qde-toolbar";const t={source:"Source",split:"Split",preview:"Rendered"};["source","split","preview"].forEach(n=>{const o=document.createElement("button");o.className="qde-btn",o.dataset.mode=n,o.textContent=t[n],o.title=`Switch to ${t[n]} view`,e.appendChild(o)});const n=document.createElement("span");n.className="qde-spacer",e.appendChild(n);if([{action:"copy-markdown",text:"Copy MD",title:"Copy markdown to clipboard"},{action:"copy-html",text:"Copy HTML",title:"Copy HTML to clipboard"},{action:"copy-rendered",text:"Copy Rendered",title:"Copy rich text to clipboard"}].forEach(({action:t,text:n,title:o})=>{const r=document.createElement("button");r.className="qde-btn",r.dataset.action=t,r.textContent=n,r.title=o,e.appendChild(r)}),this.options.showRemoveHR){const t=document.createElement("button");t.className="qde-btn",t.dataset.action="remove-hr",t.textContent="Remove HR",t.title="Remove all horizontal rules (---) from markdown",e.appendChild(t)}return e}injectStyles(){if(document.getElementById("qde-styles"))return;const e=document.createElement("style");e.id="qde-styles",e.textContent='\n .qde-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n border: 1px solid #ddd;\n border-radius: 4px;\n overflow: hidden;\n background: white;\n }\n \n .qde-toolbar {\n display: flex;\n align-items: center;\n padding: 8px;\n background: #f5f5f5;\n border-bottom: 1px solid #ddd;\n gap: 4px;\n }\n \n .qde-btn {\n padding: 6px 12px;\n border: 1px solid #ccc;\n background: white;\n border-radius: 3px;\n cursor: pointer;\n font-size: 14px;\n transition: all 0.2s;\n }\n \n .qde-btn:hover {\n background: #e9e9e9;\n border-color: #999;\n }\n \n .qde-btn.active {\n background: #007bff;\n color: white;\n border-color: #0056b3;\n }\n \n .qde-spacer {\n flex: 1;\n }\n \n .qde-editor {\n display: flex;\n flex: 1;\n overflow: hidden;\n }\n \n .qde-source, .qde-preview {\n flex: 1;\n overflow: auto;\n padding: 16px;\n }\n \n .qde-source {\n border-right: 1px solid #ddd;\n }\n \n .qde-textarea {\n width: 100%;\n height: 100%;\n border: none;\n outline: none;\n resize: none;\n font-family: \'Monaco\', \'Courier New\', monospace;\n font-size: 14px;\n line-height: 1.5;\n }\n \n .qde-preview {\n font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, sans-serif;\n font-size: 16px;\n line-height: 1.6;\n outline: none;\n cursor: text; /* Standard text cursor */\n }\n \n /* Fence-specific styles */\n .qde-svg-container {\n max-width: 100%;\n overflow: auto;\n }\n \n .qde-svg-container svg {\n max-width: 100%;\n height: auto;\n }\n \n .qde-html-container {\n /* HTML containers inherit background */\n margin: 12px 0;\n }\n \n .qde-math-container {\n text-align: center;\n margin: 16px 0;\n overflow-x: auto;\n }\n \n /* All tables in preview (both regular markdown and CSV) */\n .qde-preview table {\n width: 100%;\n border-collapse: collapse;\n margin: 12px 0;\n font-size: 14px;\n }\n \n .qde-preview table th,\n .qde-preview table td {\n border: 1px solid #ddd;\n padding: 8px;\n }\n \n /* Support for alignment classes from quikdown */\n .qde-preview .quikdown-left { text-align: left; }\n .qde-preview .quikdown-center { text-align: center; }\n .qde-preview .quikdown-right { text-align: right; }\n \n .qde-preview table th {\n background: #f5f5f5;\n font-weight: bold;\n }\n \n .qde-preview table tr:nth-child(even) {\n background: #f9f9f9;\n }\n \n /* Specific to CSV-generated tables */\n .qde-data-table {\n /* Can add specific CSV table styles here if needed */\n }\n \n .qde-json {\n /* Let highlight.js handle styling */\n overflow-x: auto;\n }\n \n .qde-error {\n background: #fee;\n border: 1px solid #fcc;\n color: #c00;\n padding: 8px;\n border-radius: 4px;\n font-family: monospace;\n font-size: 12px;\n }\n \n /* Read-only complex fence blocks in preview */\n .qde-preview [contenteditable="false"] {\n cursor: auto; /* Use automatic cursor (arrow for non-text) */\n user-select: text;\n position: relative;\n }\n \n /* Ensure proper cursor for editable text elements */\n .qde-preview p,\n .qde-preview h1,\n .qde-preview h2,\n .qde-preview h3,\n .qde-preview h4,\n .qde-preview h5,\n .qde-preview h6,\n .qde-preview li,\n .qde-preview td,\n .qde-preview th,\n .qde-preview blockquote,\n .qde-preview pre[contenteditable="true"],\n .qde-preview code[contenteditable="true"] {\n cursor: text;\n }\n \n \n /* Non-editable complex renderers */\n .qde-preview .qde-svg-container[contenteditable="false"],\n .qde-preview .qde-html-container[contenteditable="false"],\n .qde-preview .qde-math-container[contenteditable="false"],\n .qde-preview .mermaid[contenteditable="false"] {\n opacity: 0.98;\n }\n \n /* Subtle hover effect for read-only blocks */\n .qde-preview [contenteditable="false"]:hover::after {\n content: "Read-only";\n position: absolute;\n top: 2px;\n right: 2px;\n font-size: 10px;\n color: #999;\n background: rgba(255, 255, 255, 0.9);\n padding: 2px 4px;\n border-radius: 2px;\n pointer-events: none;\n }\n \n /* Fix list padding in preview */\n .qde-preview ul,\n .qde-preview ol {\n padding-left: 2em;\n margin: 0.5em 0;\n }\n \n .qde-preview li {\n margin: 0.25em 0;\n }\n \n /* Mode-specific visibility */\n .qde-mode-source .qde-preview { display: none; }\n .qde-mode-source .qde-source { border-right: none; }\n .qde-mode-preview .qde-source { display: none; }\n .qde-mode-split .qde-source,\n .qde-mode-split .qde-preview { display: block; }\n \n /* Dark theme */\n .qde-dark {\n background: #1e1e1e;\n color: #e0e0e0;\n }\n \n .qde-dark .qde-toolbar {\n background: #2d2d2d;\n border-color: #444;\n }\n \n .qde-dark .qde-btn {\n background: #3a3a3a;\n color: #e0e0e0;\n border-color: #555;\n }\n \n .qde-dark .qde-btn:hover {\n background: #4a4a4a;\n }\n \n .qde-dark .qde-source {\n border-color: #444;\n }\n \n .qde-dark .qde-textarea {\n background: #1e1e1e;\n color: #e0e0e0;\n }\n \n .qde-dark .qde-preview {\n background: #1e1e1e;\n color: #e0e0e0;\n }\n \n /* Dark mode table styles */\n .qde-dark .qde-preview table th,\n .qde-dark .qde-preview table td {\n border-color: #3a3a3a;\n }\n \n .qde-dark .qde-preview table th {\n background: #2d2d2d;\n }\n \n .qde-dark .qde-preview table tr:nth-child(even) {\n background: #252525;\n }\n \n /* Mobile responsive */\n @media (max-width: 768px) {\n .qde-mode-split .qde-editor {\n flex-direction: column;\n }\n \n .qde-mode-split .qde-source {\n border-right: none;\n border-bottom: 1px solid #ddd;\n }\n }\n ',document.head.appendChild(e)}attachEvents(){this.sourceTextarea.addEventListener("input",()=>{this.handleSourceInput()}),this.previewPanel.addEventListener("input",()=>{this.handlePreviewInput()}),this.toolbar&&this.toolbar.addEventListener("click",e=>{const t=e.target.closest(".qde-btn");t&&(t.dataset.mode?this.setMode(t.dataset.mode):t.dataset.action&&this.handleAction(t.dataset.action))}),document.addEventListener("keydown",e=>{if(e.ctrlKey||e.metaKey)switch(e.key){case"1":e.preventDefault(),this.setMode("source");break;case"2":e.preventDefault(),this.setMode("split");break;case"3":e.preventDefault(),this.setMode("preview")}})}handleSourceInput(){clearTimeout(this.updateTimer),this.updateTimer=setTimeout(()=>{this.updateFromMarkdown(this.sourceTextarea.value)},this.options.debounceDelay)}handlePreviewInput(){clearTimeout(this.updateTimer),this.updateTimer=setTimeout(()=>{this.updateFromHTML()},this.options.debounceDelay)}updateFromMarkdown(e){if(this._markdown=e||"",this._markdown.trim()){if(this._html=l(e,{fence_plugin:this.createFencePlugin(),lazy_linefeeds:this.options.lazy_linefeeds,inline_styles:this.options.inline_styles}),"source"!==this.currentMode&&(this.previewPanel.innerHTML=this._html,this.makeFencesNonEditable(),window.MathJax&&window.MathJax.typesetPromise)){const e=this.previewPanel.querySelectorAll(".math-display");e.length>0&&(e.forEach(e=>{}),window.MathJax.typesetPromise(Array.from(e)).then(()=>{e.forEach(e=>{e.querySelector("mjx-container")})}).catch(e=>{console.warn("MathJax batch processing failed:",e)}))}}else this._html="","source"!==this.currentMode&&(this.previewPanel.innerHTML='<div style="color: #999; font-style: italic; padding: 16px;">Start typing markdown in the source panel...</div>');this.options.onChange&&this.options.onChange(this._markdown,this._html)}updateFromHTML(){const e=this.previewPanel.cloneNode(!0);this.preprocessSpecialElements(e),this._html=this.previewPanel.innerHTML,this._markdown=l.toMarkdown(e,{fence_plugin:this.createFencePlugin()}),"preview"!==this.currentMode&&(this.sourceTextarea.value=this._markdown),this.options.onChange&&this.options.onChange(this._markdown,this._html)}preprocessSpecialElements(e){if(!e)return;e.querySelectorAll('[contenteditable="false"][data-qd-source]').forEach(e=>{const t=e.getAttribute("data-qd-source"),n=e.getAttribute("data-qd-fence")||"```",o=e.getAttribute("data-qd-lang")||"",r=document.createElement("pre");r.setAttribute("data-qd-fence",n),o&&r.setAttribute("data-qd-lang",o);const a=document.createElement("code");a.textContent=t,r.appendChild(a),e.parentNode.replaceChild(r,e)});e.querySelectorAll("table.qde-csv-table[data-qd-lang]").forEach(e=>{const t=e.getAttribute("data-qd-lang");if(!t||!["csv","psv","tsv"].includes(t))return;const n="csv"===t?",":"psv"===t?"|":"\t";let o="";const r=[];e.querySelectorAll("thead th").forEach(e=>{const t=e.textContent.trim(),o=t.includes(n)||t.includes('"')||t.includes("\n");r.push(o?`"${t.replace(/"/g,'""')}"`:t)}),o+=r.join(n)+"\n";e.querySelectorAll("tbody tr").forEach(e=>{const t=[];e.querySelectorAll("td").forEach(e=>{const o=e.textContent.trim(),r=o.includes(n)||o.includes('"')||o.includes("\n");t.push(r?`"${o.replace(/"/g,'""')}"`:o)}),o+=t.join(n)+"\n"});const a=document.createElement("pre");a.setAttribute("data-qd-fence","```"),a.setAttribute("data-qd-lang",t);const i=document.createElement("code");i.textContent=o.trim(),a.appendChild(i),e.parentNode.replaceChild(a,e)})}createFencePlugin(){return{render:(e,t)=>{if(this.options.customFences&&this.options.customFences[t])try{return this.options.customFences[t](e,t)}catch(n){return console.error(`Custom fence plugin error for ${t}:`,n),`<pre><code class="language-${t}">${this.escapeHtml(e)}</code></pre>`}if(!!this.options.enableComplexFences)switch(t){case"svg":return this.renderSVG(e);case"html":return this.renderHTML(e);case"math":case"tex":case"latex":return this.renderMath(e,t);case"csv":case"psv":case"tsv":return this.renderTable(e,t);case"json":case"json5":return this.renderJSON(e,t);case"katex":return this.renderMath(e,"katex");case"mermaid":if(window.mermaid)return this.renderMermaid(e);break;case"geojson":return this.renderGeoJSON(e);case"stl":return this.renderSTL(e)}if(window.hljs&&t&&hljs.getLanguage(t)){return`<pre data-qd-fence="\`\`\`" data-qd-lang="${t}"><code class="hljs language-${t}">${hljs.highlight(e,{language:t}).value}</code></pre>`}},reverse:e=>{const t=e.getAttribute("data-qd-lang")||"";let n="";if(e.querySelector("code.hljs")){const t=e.querySelector("code.hljs");n=t.textContent||t.innerText||""}else if(e.querySelector("code")){const t=e.querySelector("code");n=t.textContent||t.innerText||""}else n=e.textContent||e.innerText||"";return{content:n,lang:t,fence:"```"}}}}renderSVG(e){try{const t=(new DOMParser).parseFromString(e,"image/svg+xml");if(t.querySelector("parsererror"))throw new Error("Invalid SVG");const n=t.documentElement;n.querySelectorAll("script").forEach(e=>e.remove());const o=document.createTreeWalker(n,NodeFilter.SHOW_ELEMENT);let r;for(;r=o.nextNode();)for(let e=r.attributes.length-1;e>=0;e--){const t=r.attributes[e];(t.name.startsWith("on")||t.value.includes("javascript:"))&&r.removeAttribute(t.name)}const a=document.createElement("div");return a.className="qde-svg-container",a.contentEditable="false",a.setAttribute("data-qd-fence","```"),a.setAttribute("data-qd-lang","svg"),a.setAttribute("data-qd-source",e),a.innerHTML=(new XMLSerializer).serializeToString(n),a.outerHTML}catch(e){const t=document.createElement("pre");return t.className="qde-error",t.contentEditable="false",t.setAttribute("data-qd-fence","```"),t.setAttribute("data-qd-lang","svg"),t.textContent=`Invalid SVG: ${e.message}`,t.outerHTML}}renderHTML(e){const t=`html-${Date.now()}-${Math.random().toString(36).substr(2,9)}`;if(window.DOMPurify){const t=DOMPurify.sanitize(e),n=document.createElement("div");return n.className="qde-html-container",n.contentEditable="false",n.setAttribute("data-qd-fence","```"),n.setAttribute("data-qd-lang","html"),n.setAttribute("data-qd-source",e),n.innerHTML=t,n.outerHTML}this.lazyLoadLibrary("DOMPurify",()=>window.DOMPurify,"https://unpkg.com/dompurify/dist/purify.min.js").then(n=>{if(n){const n=document.getElementById(t);if(n){const t=DOMPurify.sanitize(e);n.innerHTML=t,n.setAttribute("data-qd-source",e),n.setAttribute("data-qd-fence","```"),n.setAttribute("data-qd-lang","html")}}});const n=document.createElement("div");n.id=t,n.className="qde-html-container",n.contentEditable="false",n.setAttribute("data-qd-fence","```"),n.setAttribute("data-qd-lang","html"),n.setAttribute("data-qd-source",e);const o=document.createElement("pre");return o.textContent=e,n.appendChild(o),n.outerHTML}renderMath(e,t){const n=`math-${Math.random().toString(36).substring(2,15)}`,o=document.createElement("div");o.id=n,o.className="math-display",o.contentEditable="false",o.setAttribute("data-source-type","math");const r=e.replace(/\r?\n/g," ").replace(/\s+/g," ").trim();return o.textContent=`$$${r}$$`,o.style.textAlign="center",o.style.margin="1em 0",window.MathJax&&window.MathJax.typesetPromise||this.ensureMathJaxLoaded(),o.outerHTML}ensureMathJaxLoaded(){if(void 0===window.MathJax&&!window.mathJaxLoading){window.mathJaxLoading=!0,window.MathJax||(window.MathJax={loader:{load:["input/tex","output/svg"]},tex:{packages:{"[+]":["ams"]},inlineMath:[["$","$"],["\\(","\\)"]],displayMath:[["$$","$$"],["\\[","\\]"]],processEscapes:!0,processEnvironments:!0},options:{renderActions:{addMenu:[]},ignoreHtmlClass:"tex2jax_ignore",processHtmlClass:"tex2jax_process"},svg:{fontCache:"none"},startup:{typeset:!1}});const e=document.createElement("script");e.src="https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-svg.js",e.async=!0,e.onload=()=>{if(window.mathJaxLoading=!1,window.MathJax&&window.MathJax.typesetPromise){const e=document.querySelectorAll(".math-display");e.length>0&&window.MathJax.typesetPromise(Array.from(e)).catch(e=>{console.warn("Initial MathJax processing failed:",e)})}},e.onerror=()=>{window.mathJaxLoading=!1,console.error("Failed to load MathJax")},document.head.appendChild(e)}}renderTable(e,t){const n=this.escapeHtml(e);try{const o="csv"===t?",":"psv"===t?"|":"\t",r=e.trim().split("\n");if(0===r.length)return`<pre data-qd-fence="\`\`\`" data-qd-lang="${t}" data-qd-source="${n}">${n}</pre>`;let a=`<table class="qde-data-table qde-csv-table" data-qd-fence="\`\`\`" data-qd-lang="${t}">`;const i=this.parseCSVLine(r[0],o);if(a+="<thead><tr>",i.forEach(e=>{a+=`<th>${this.escapeHtml(e.trim())}</th>`}),a+="</tr></thead>",r.length>1){a+="<tbody>";for(let e=1;e<r.length;e++){const t=this.parseCSVLine(r[e],o);a+="<tr>",t.forEach(e=>{a+=`<td>${this.escapeHtml(e.trim())}</td>`}),a+="</tr>"}a+="</tbody>"}return a+="</table>",a}catch(e){return`<pre data-qd-fence="\`\`\`" data-qd-lang="${t}" data-qd-source="${n}">${n}</pre>`}}parseCSVLine(e,t){const n=[];let o="",r=!1;for(let a=0;a<e.length;a++){const i=e[a],l=e[a+1];'"'===i?r&&'"'===l?(o+='"',a++):r=!r:i!==t||r?o+=i:(n.push(o),o="")}return n.push(o),n}renderJSON(e,t){if(window.hljs&&hljs.getLanguage("json"))try{let n=e;try{const t=JSON.parse(e);n=JSON.stringify(t,null,2)}catch(e){}return`<pre class="qde-json" data-qd-fence="\`\`\`" data-qd-lang="${t}"><code class="hljs language-json">${hljs.highlight(n,{language:"json"}).value}</code></pre>`}catch(e){}return`<pre class="qde-json" data-qd-fence="\`\`\`" data-qd-lang="${t}">${this.escapeHtml(e)}</pre>`}renderGeoJSON(e){const t=`map-${Math.random().toString(36).substr(2,15)}`,n=()=>{const n=document.getElementById(t+"-container");if(n&&window.L)try{const o=JSON.parse(e),r=document.createElement("div");r.id=t,r.style.cssText="width: 100%; height: 300px;",n.innerHTML="",n.appendChild(r);const a=L.map(t);n._map=a;const i=L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",{attribution:"",crossOrigin:"anonymous"});i.addTo(a);const l=L.geoJSON(o);l.addTo(a),l.getBounds().isValid()?a.fitBounds(l.getBounds()):a.setView([0,0],2),n._tileLayer=i,n._geoJsonLayer=l,i.on("load",()=>{n.setAttribute("data-tiles-loaded","true")})}catch(e){n.innerHTML=`<pre class="qde-error">GeoJSON error: ${this.escapeHtml(e.message)}</pre>`}};window.L?setTimeout(n,0):(window._qde_leaflet_loading||(window._qde_leaflet_loading=this.lazyLoadLibrary("Leaflet",()=>window.L,"https://unpkg.com/leaflet@1.9.4/dist/leaflet.js","https://unpkg.com/leaflet@1.9.4/dist/leaflet.css").catch(e=>(console.warn("Failed to load Leaflet:",e),window._qde_leaflet_loading=null,!1))),window._qde_leaflet_loading.then(e=>{if(e)n();else{const e=document.getElementById(id);e&&(e.innerHTML='<div style="padding: 20px; text-align: center; color: #666;">Failed to load map library</div>')}}).catch(()=>{}));const o=document.createElement("div");return o.className="geojson-container",o.id=t+"-container",o.style.cssText="width: 100%; height: 300px; border: 1px solid #ddd; border-radius: 4px; margin: 0.5em 0; background: #f0f0f0;",o.contentEditable="false",o.setAttribute("data-source-type","geojson"),o.setAttribute("data-original-source",this.escapeHtml(e)),o.setAttribute("data-qd-fence","```"),o.setAttribute("data-qd-lang","geojson"),o.setAttribute("data-qd-source",e),o.textContent="Loading map...",o.outerHTML}renderSTL(e){const t=`qde-stl-viewer-${Date.now()}-${Math.random().toString(36).substr(2,9)}`;return setTimeout(()=>{const n=document.getElementById(t);if(n)if(void 0!==window.THREE)try{const t=window.THREE,o=new t.Scene;o.background=new t.Color(15790320);const r=new t.PerspectiveCamera(75,n.clientWidth/400,.1,1e3),a=new t.WebGLRenderer({antialias:!0});a.setSize(n.clientWidth,400),n.innerHTML="",n.appendChild(a.domElement),n._threeScene=o,n._threeCamera=r,n._threeRenderer=a;const i=this.parseSTL(e),l=new t.MeshLambertMaterial({color:26367}),s=new t.Mesh(i,l);o.add(s);const c=new t.AmbientLight(4210752,.6);o.add(c);const d=new t.DirectionalLight(16777215,.8);d.position.set(1,1,1).normalize(),o.add(d);const h=(new t.Box3).setFromObject(s),u=h.getCenter(new t.Vector3),p=h.getSize(new t.Vector3),m=Math.max(p.x,p.y,p.z);r.position.set(u.x+m,u.y+m,u.z+m),r.lookAt(u);const g=()=>{requestAnimationFrame(g),s.rotation.y+=.01,a.render(o,r)};g()}catch(e){console.error("STL rendering error:",e),n.innerHTML=`<pre class="qde-error">STL error: ${this.escapeHtml(e.message)}</pre>`}else n.innerHTML='<div style="padding: 20px; text-align: center; color: #666;">Three.js library not loaded. Add <script src="https://unpkg.com/three@0.147.0/build/three.min.js"></script> to your HTML.</div>'},0),`<div id="${t}" class="qde-stl-container" data-stl-id="${t}" data-qd-fence="\`\`\`" data-qd-lang="stl" data-qd-source="${this.escapeHtml(e)}" contenteditable="false" style="height: 400px; background: #f0f0f0; display: flex; align-items: center; justify-content: center;">Loading 3D model...</div>`}parseSTL(e){const t=window.THREE,n=new t.BufferGeometry,o=[],r=[],a=e.split("\n");let i=null;for(let e of a)if(e=e.trim(),e.startsWith("facet normal")){const t=e.split(/\s+/);i=[parseFloat(t[2]),parseFloat(t[3]),parseFloat(t[4])]}else if(e.startsWith("vertex")){const t=e.split(/\s+/);o.push(parseFloat(t[1]),parseFloat(t[2]),parseFloat(t[3])),i&&r.push(i[0],i[1],i[2])}return n.setAttribute("position",new t.Float32BufferAttribute(o,3)),n.setAttribute("normal",new t.Float32BufferAttribute(r,3)),n}renderMermaid(e){const t=`mermaid-${Date.now()}-${Math.random().toString(36).substr(2,9)}`;setTimeout(()=>{const n=document.getElementById(t);n&&window.mermaid&&mermaid.render(t+"-svg",e).then(e=>{n.innerHTML=e.svg}).catch(e=>{n.innerHTML=`<pre>Error rendering diagram: ${e.message}</pre>`})},0);const n=document.createElement("div");return n.id=t,n.className="mermaid",n.contentEditable="false",n.setAttribute("data-qd-source",e),n.setAttribute("data-qd-fence","```"),n.setAttribute("data-qd-lang","mermaid"),n.textContent="Loading diagram...",n.outerHTML}escapeHtml(e){return(e??"").replace(/[&"'<>]/g,e=>({"&":"&",'"':""","'":"'","<":"<",">":">"}[e]))}makeFencesNonEditable(){this.previewPanel}async loadPlugins(){const e=[];this.options.plugins.highlightjs&&!window.hljs&&e.push(this.loadScript("https://unpkg.com/@highlightjs/cdn-assets/highlight.min.js"),this.loadCSS("https://unpkg.com/@highlightjs/cdn-assets/styles/github.min.css")),this.options.plugins.mermaid&&!window.mermaid&&e.push(this.loadScript("https://unpkg.com/mermaid/dist/mermaid.min.js").then(()=>{window.mermaid&&mermaid.initialize({startOnLoad:!1})})),await Promise.all(e)}async lazyLoadLibrary(e,t,n,o=null){if(t())return!0;try{const e=[];return n&&e.push(this.loadScript(n)),o&&e.push(this.loadCSS(o)),await Promise.all(e),t()}catch(t){return console.error(`Failed to load ${e}:`,t),!1}}loadScript(e){return new Promise((t,n)=>{const o=document.createElement("script");o.src=e,o.onload=t,o.onerror=n,document.head.appendChild(o)})}loadCSS(e){return new Promise(t=>{const n=document.createElement("link");n.rel="stylesheet",n.href=e,n.onload=t,document.head.appendChild(n),setTimeout(t,1e3)})}applyTheme(){const e=this.options.theme;if("auto"===e){const e=window.matchMedia("(prefers-color-scheme: dark)").matches;this.container.classList.toggle("qde-dark",e),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",e=>{this.container.classList.toggle("qde-dark",e.matches)})}else this.container.classList.toggle("qde-dark","dark"===e)}setLazyLinefeeds(e){this.options.lazy_linefeeds=e,this._markdown&&this.updateFromMarkdown(this._markdown)}getLazyLinefeeds(){return this.options.lazy_linefeeds}setDebounceDelay(e){this.options.debounceDelay=Math.max(0,e)}getDebounceDelay(){return this.options.debounceDelay}setMode(e){["source","preview","split"].includes(e)&&(this.currentMode=e,this.container.className=`qde-container qde-mode-${e}`,this.toolbar&&this.toolbar.querySelectorAll(".qde-btn[data-mode]").forEach(t=>{t.classList.toggle("active",t.dataset.mode===e)}),this.container.classList.contains("qde-dark")&&this.container.classList.add("qde-dark"),"source"!==e&&setTimeout(()=>this.makeFencesNonEditable(),0),this.options.onModeChange&&this.options.onModeChange(e))}handleAction(e){switch(e){case"copy-markdown":this.copy("markdown");break;case"copy-html":this.copy("html");break;case"copy-rendered":this.copyRendered();break;case"remove-hr":this.removeHR()}}async copy(e){const t="markdown"===e?this._markdown:this._html;try{await navigator.clipboard.writeText(t);const n=this.toolbar.querySelector(`[data-action="copy-${e}"]`);if(n){const e=n.textContent;n.textContent="Copied!",setTimeout(()=>{n.textContent=e},1500)}}catch(e){console.error("Failed to copy:",e)}}get markdown(){return this._markdown}set markdown(e){this.setMarkdown(e)}get html(){return this._html}get mode(){return this.currentMode}async setMarkdown(e){this.initPromise&&await this.initPromise,this._markdown=e,this.sourceTextarea&&(this.sourceTextarea.value=e),this.updateFromMarkdown(e)}getMarkdown(){return this._markdown}getHTML(){return this._html}async removeHR(){const e=this._markdown.split("\n").filter(e=>{const t=e.trim();return!/^[-_*](\s*[-_*]){2,}\s*$/.test(t)}).join("\n");await this.setMarkdown(e);const t=this.toolbar?.querySelector('[data-action="remove-hr"]');if(t){const e=t.textContent;t.textContent="Removed!",setTimeout(()=>{t.textContent=e},1500)}}async copyRendered(){try{if((await d(this.previewPanel)).success){const e=this.toolbar?.querySelector('[data-action="copy-rendered"]');if(e){const t=e.textContent;e.textContent="Copied!",setTimeout(()=>{e.textContent=t},1500)}}}catch(e){console.error("Failed to copy rendered content:",e)}}destroy(){clearTimeout(this.updateTimer),this.container.innerHTML="",this.container.classList.remove("qde-container","qde-dark");if(0===document.querySelectorAll(".qde-container").length){const e=document.getElementById("qde-styles");e&&e.remove()}}}return"undefined"!=typeof module&&module.exports&&(module.exports=u),"undefined"!=typeof window&&(window.QuikdownEditor=u),u});
|
|
12
|
+
*/r.emitStyles=function(e="quikdown-",t="light"){const n=o,r={"#f4f4f4":"#2a2a2a","#f0f0f0":"#2a2a2a","#f2f2f2":"#2a2a2a","#ddd":"#3a3a3a","#06c":"#6db3f2",_textColor:"#e0e0e0"},a={_textColor:"#333"};let i="";for(const[o,s]of Object.entries(n)){let n=s;if("dark"===t&&r){for(const[e,t]of Object.entries(r))e.startsWith("_")||(n=n.replace(new RegExp(e,"g"),t));["h1","h2","h3","h4","h5","h6","td","li","blockquote"].includes(o)&&(n+=`;color:${r._textColor}`)}else if("light"===t&&a){["h1","h2","h3","h4","h5","h6","td","li","blockquote"].includes(o)&&(n+=`;color:${a._textColor}`)}i+=`.${e}${o} { ${n} }\n`}return i},r.configure=function(e){return function(t){return r(t,e)}},r.version="1.2.2","undefined"!=typeof module&&module.exports&&(module.exports=r),"undefined"!=typeof window&&(window.quikdown=r),Object.keys(r).forEach(e=>{s[e]=r[e]}),s.toMarkdown=function(e,t={}){let n;if("string"==typeof e)n=document.createElement("div"),n.innerHTML=e;else{if(!(e instanceof Element))return"";n=e}function o(e,n={}){if(e.nodeType===Node.TEXT_NODE)return e.textContent;if(e.nodeType!==Node.ELEMENT_NODE)return"";const a=e.tagName.toLowerCase(),i=e.getAttribute("data-qd");let s="";for(const t of e.childNodes)s+=o(t,{parentTag:a,...n});switch(a){case"h1":case"h2":case"h3":case"h4":case"h5":case"h6":const n=parseInt(a[1]);return`${i||"#".repeat(n)} ${s.trim()}\n\n`;case"strong":case"b":if(!s)return"";const o=i||"**";return`${o}${s}${o}`;case"em":case"i":if(!s)return"";const l=i||"*";return`${l}${s}${l}`;case"del":case"s":case"strike":if(!s)return"";const c=i||"~~";return`${c}${s}${c}`;case"code":if(!s)return"";const d=i||"`";return`${d}${s}${d}`;case"pre":const h=e.getAttribute("data-qd-fence")||i||"```",u=e.getAttribute("data-qd-lang")||"";if(t.fence_plugin&&t.fence_plugin.reverse&&u)try{const n=t.fence_plugin.reverse(e);if(n&&n.content){const e=n.fence||h;return`${e}${n.lang||u}\n${n.content}\n${e}\n\n`}}catch(e){console.warn("Fence reverse handler error:",e)}const p=e.getAttribute("data-qd-source");if(p)return`${h}${u}\n${p}\n${h}\n\n`;const m=e.querySelector("code");return`${h}${u}\n${(m?m.textContent:s).trimEnd()}\n${h}\n\n`;case"blockquote":const g=i||">";return s.trim().split("\n").map(e=>`${g} ${e}`).join("\n")+"\n\n";case"hr":return`${i||"---"}\n\n`;case"br":return`${i||" "}\n`;case"a":const f=e.getAttribute("data-qd-text")||s.trim(),w=e.getAttribute("href")||"";return f!==w||i?`[${f}](${w})`:`<${w}>`;case"img":return`${i||"!"}[${e.getAttribute("data-qd-alt")||e.getAttribute("alt")||""}](${e.getAttribute("data-qd-src")||e.getAttribute("src")||""})`;case"ul":case"ol":return r(e,"ol"===a)+"\n";case"li":case"span":default:return s;case"table":return function(e){let t="";const n=e.getAttribute("data-qd-align"),o=n?n.split(","):[],r=e.querySelector("thead");if(r){const e=r.querySelector("tr");if(e){const n=[];for(const t of e.querySelectorAll("th"))n.push(t.textContent.trim());t+="| "+n.join(" | ")+" |\n";t+="| "+n.map((e,t)=>{const n=o[t]||"left";return"center"===n?":---:":"right"===n?"---:":"---"}).join(" | ")+" |\n"}}const a=e.querySelector("tbody");if(a)for(const e of a.querySelectorAll("tr")){const n=[];for(const t of e.querySelectorAll("td"))n.push(t.textContent.trim());n.length>0&&(t+="| "+n.join(" | ")+" |\n")}return t.trim()}(e)+"\n\n";case"p":if(s.trim()){const e=s.split("\n");let t=s.trim();if(e.length>1){let n=0;for(let t=e.length-1;t>=0&&""===e[t].trim();t--)n++;if(n>0)return t+="\n ",t+"\n"}return t+"\n\n"}return"";case"div":const y=e.getAttribute("data-qd-lang"),b=e.getAttribute("data-qd-fence");if(y&&t.fence_plugin&&t.fence_plugin.reverse)try{const n=t.fence_plugin.reverse(e);if(n&&n.content){const e=n.fence||b||"```";return`${e}${n.lang||y}\n${n.content}\n${e}\n\n`}}catch(e){console.warn("Fence reverse handler error:",e)}const x=e.getAttribute("data-qd-source");if(x&&b)return`${b}${y||""}\n${x}\n${b}\n\n`;if(e.classList&&e.classList.contains("mermaid-container")){const t=e.getAttribute("data-qd-fence")||"```",n=e.getAttribute("data-qd-lang")||"mermaid",o=e.getAttribute("data-qd-source");if(o){const e=document.createElement("textarea");e.innerHTML=o;return`${t}${n}\n${e.value}\n${t}\n\n`}const r=e.querySelector("pre.mermaid");if(r){const e=r.getAttribute("data-qd-source");if(e){const o=document.createElement("textarea");o.innerHTML=e;return`${t}${n}\n${o.value}\n${t}\n\n`}}const a=e.querySelector(".mermaid-source");if(a){const e=document.createElement("div");e.innerHTML=a.innerHTML;return`${t}${n}\n${e.textContent}\n${t}\n\n`}const i=e.querySelector(".mermaid");if(i&&i.textContent.includes("graph"))return`${t}${n}\n${i.textContent.trim()}\n${t}\n\n`}if(e.classList&&e.classList.contains("mermaid")){const t=e.getAttribute("data-qd-fence")||"```";return`${t}${e.getAttribute("data-qd-lang")||"mermaid"}\n${e.textContent.trim()}\n${t}\n\n`}return s}}function r(e,t,n=0){let a="",i=1;const s=" ".repeat(n);for(const l of e.children){if("LI"!==l.tagName)continue;let e=l.getAttribute("data-qd")||(t?`${i}.`:"-");const c=l.querySelector('input[type="checkbox"]');if(c){const t=c.checked?"x":" ";e="-";let n="";for(const e of l.childNodes)e.nodeType===Node.TEXT_NODE?n+=e.textContent:e.tagName&&"INPUT"!==e.tagName&&(n+=o(e));a+=`${s}${e} [${t}] ${n.trim()}\n`}else{let t="";for(const e of l.childNodes)"UL"===e.tagName||"OL"===e.tagName?t+=r(e,"OL"===e.tagName,n+1):t+=o(e);a+=`${s}${e} ${t.trim()}\n`}i++}return a}let a=o(n);return a=a.replace(/\n{3,}/g,"\n\n"),a=a.trim(),a},s.configure=function(e){return function(t){return s(t,e)}},"undefined"!=typeof module&&module.exports&&(module.exports=s),"undefined"!=typeof window&&(window.quikdown_bd=s);const h={mode:"split",showToolbar:!0,showRemoveHR:!1,showLazyLinefeeds:!1,theme:"auto",lazy_linefeeds:!1,inline_styles:!1,debounceDelay:20,placeholder:"Start typing markdown...",plugins:{highlightjs:!1,mermaid:!1},customFences:{},enableComplexFences:!0,showUndoRedo:!1,undoStackSize:100};class u{constructor(e,t={}){if(this.container="string"==typeof e?document.querySelector(e):e,!this.container)throw new Error("QuikdownEditor: Invalid container");this.options={...h,...t},this._markdown="",this._html="",this.currentMode=this.options.mode,this.updateTimer=null,this._undoStack=[],this._redoStack=[],this._isUndoRedo=!1,this.initPromise=this.init()}async init(){await this.loadPlugins(),this.buildUI(),this.attachEvents(),this.applyTheme(),this.setMode(this.currentMode),this.options.initialContent&&this.setMarkdown(this.options.initialContent)}buildUI(){this.container.innerHTML="",this.container.classList.add("qde-container"),this.options.showToolbar&&(this.toolbar=this.createToolbar(),this.container.appendChild(this.toolbar)),this.editorArea=document.createElement("div"),this.editorArea.className="qde-editor",this.sourcePanel=document.createElement("div"),this.sourcePanel.className="qde-source",this.sourceTextarea=document.createElement("textarea"),this.sourceTextarea.className="qde-textarea",this.sourceTextarea.placeholder=this.options.placeholder,this.sourcePanel.appendChild(this.sourceTextarea),this.previewPanel=document.createElement("div"),this.previewPanel.className="qde-preview",this.previewPanel.contentEditable=!0,this.editorArea.appendChild(this.sourcePanel),this.editorArea.appendChild(this.previewPanel),this.container.appendChild(this.editorArea),this.injectStyles()}createToolbar(){const e=document.createElement("div");e.className="qde-toolbar";const t={source:"Source",split:"Split",preview:"Rendered"};if(["source","split","preview"].forEach(n=>{const o=document.createElement("button");o.className="qde-btn",o.dataset.mode=n,o.textContent=t[n],o.title=`Switch to ${t[n]} view`,e.appendChild(o)}),this.options.showUndoRedo){const t=document.createElement("button");t.className="qde-btn disabled",t.dataset.action="undo",t.textContent="Undo",t.title="Undo (Ctrl+Z)",e.appendChild(t);const n=document.createElement("button");n.className="qde-btn disabled",n.dataset.action="redo",n.textContent="Redo",n.title="Redo (Ctrl+Shift+Z / Ctrl+Y)",e.appendChild(n)}const n=document.createElement("span");n.className="qde-spacer",e.appendChild(n);if([{action:"copy-markdown",text:"Copy MD",title:"Copy markdown to clipboard"},{action:"copy-html",text:"Copy HTML",title:"Copy HTML to clipboard"},{action:"copy-rendered",text:"Copy Rendered",title:"Copy rich text to clipboard"}].forEach(({action:t,text:n,title:o})=>{const r=document.createElement("button");r.className="qde-btn",r.dataset.action=t,r.textContent=n,r.title=o,e.appendChild(r)}),this.options.showRemoveHR){const t=document.createElement("button");t.className="qde-btn",t.dataset.action="remove-hr",t.textContent="Remove HR",t.title="Remove all horizontal rules (---) from markdown",e.appendChild(t)}if(this.options.showLazyLinefeeds){const t=document.createElement("button");t.className="qde-btn",t.dataset.action="lazy-linefeeds",t.textContent="Fix Linefeeds",t.title="Convert single newlines to paragraph breaks (one-time transform)",e.appendChild(t)}return e}injectStyles(){if(document.getElementById("qde-styles"))return;const e=document.createElement("style");e.id="qde-styles",e.textContent='\n .qde-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n border: 1px solid #ddd;\n border-radius: 4px;\n overflow: hidden;\n background: white;\n }\n \n .qde-toolbar {\n display: flex;\n align-items: center;\n padding: 8px;\n background: #f5f5f5;\n border-bottom: 1px solid #ddd;\n gap: 4px;\n }\n \n .qde-btn {\n padding: 6px 12px;\n border: 1px solid #ccc;\n background: white;\n border-radius: 3px;\n cursor: pointer;\n font-size: 14px;\n transition: all 0.2s;\n }\n \n .qde-btn:hover {\n background: #e9e9e9;\n border-color: #999;\n }\n \n .qde-btn.active {\n background: #007bff;\n color: white;\n border-color: #0056b3;\n }\n\n .qde-btn.disabled {\n opacity: 0.4;\n pointer-events: none;\n }\n \n .qde-spacer {\n flex: 1;\n }\n \n .qde-editor {\n display: flex;\n flex: 1;\n overflow: hidden;\n }\n \n .qde-source, .qde-preview {\n flex: 1;\n overflow: auto;\n padding: 16px;\n }\n \n .qde-source {\n border-right: 1px solid #ddd;\n }\n \n .qde-textarea {\n width: 100%;\n height: 100%;\n border: none;\n outline: none;\n resize: none;\n font-family: \'Monaco\', \'Courier New\', monospace;\n font-size: 14px;\n line-height: 1.5;\n }\n \n .qde-preview {\n font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, sans-serif;\n font-size: 16px;\n line-height: 1.6;\n outline: none;\n cursor: text; /* Standard text cursor */\n }\n \n /* Fence-specific styles */\n .qde-svg-container {\n max-width: 100%;\n overflow: auto;\n }\n \n .qde-svg-container svg {\n max-width: 100%;\n height: auto;\n }\n \n .qde-html-container {\n /* HTML containers inherit background */\n margin: 12px 0;\n }\n \n .qde-math-container {\n text-align: center;\n margin: 16px 0;\n overflow-x: auto;\n }\n \n /* All tables in preview (both regular markdown and CSV) */\n .qde-preview table {\n width: 100%;\n border-collapse: collapse;\n margin: 12px 0;\n font-size: 14px;\n }\n \n .qde-preview table th,\n .qde-preview table td {\n border: 1px solid #ddd;\n padding: 8px;\n }\n \n /* Support for alignment classes from quikdown */\n .qde-preview .quikdown-left { text-align: left; }\n .qde-preview .quikdown-center { text-align: center; }\n .qde-preview .quikdown-right { text-align: right; }\n \n .qde-preview table th {\n background: #f5f5f5;\n font-weight: bold;\n }\n \n .qde-preview table tr:nth-child(even) {\n background: #f9f9f9;\n }\n \n /* Specific to CSV-generated tables */\n .qde-data-table {\n /* Can add specific CSV table styles here if needed */\n }\n \n .qde-json {\n /* Let highlight.js handle styling */\n overflow-x: auto;\n }\n \n .qde-error {\n background: #fee;\n border: 1px solid #fcc;\n color: #c00;\n padding: 8px;\n border-radius: 4px;\n font-family: monospace;\n font-size: 12px;\n }\n \n /* Read-only complex fence blocks in preview */\n .qde-preview [contenteditable="false"] {\n cursor: auto; /* Use automatic cursor (arrow for non-text) */\n user-select: text;\n position: relative;\n }\n \n /* Ensure proper cursor for editable text elements */\n .qde-preview p,\n .qde-preview h1,\n .qde-preview h2,\n .qde-preview h3,\n .qde-preview h4,\n .qde-preview h5,\n .qde-preview h6,\n .qde-preview li,\n .qde-preview td,\n .qde-preview th,\n .qde-preview blockquote,\n .qde-preview pre[contenteditable="true"],\n .qde-preview code[contenteditable="true"] {\n cursor: text;\n }\n \n \n /* Non-editable complex renderers */\n .qde-preview .qde-svg-container[contenteditable="false"],\n .qde-preview .qde-html-container[contenteditable="false"],\n .qde-preview .qde-math-container[contenteditable="false"],\n .qde-preview .mermaid[contenteditable="false"] {\n opacity: 0.98;\n }\n \n /* Subtle hover effect for read-only blocks */\n .qde-preview [contenteditable="false"]:hover::after {\n content: "Read-only";\n position: absolute;\n top: 2px;\n right: 2px;\n font-size: 10px;\n color: #999;\n background: rgba(255, 255, 255, 0.9);\n padding: 2px 4px;\n border-radius: 2px;\n pointer-events: none;\n }\n \n /* Fix list padding in preview */\n .qde-preview ul,\n .qde-preview ol {\n padding-left: 2em;\n margin: 0.5em 0;\n }\n \n .qde-preview li {\n margin: 0.25em 0;\n }\n \n /* Mode-specific visibility */\n .qde-mode-source .qde-preview { display: none; }\n .qde-mode-source .qde-source { border-right: none; }\n .qde-mode-preview .qde-source { display: none; }\n .qde-mode-split .qde-source,\n .qde-mode-split .qde-preview { display: block; }\n \n /* Dark theme */\n .qde-dark {\n background: #1e1e1e;\n color: #e0e0e0;\n }\n \n .qde-dark .qde-toolbar {\n background: #2d2d2d;\n border-color: #444;\n }\n \n .qde-dark .qde-btn {\n background: #3a3a3a;\n color: #e0e0e0;\n border-color: #555;\n }\n \n .qde-dark .qde-btn:hover {\n background: #4a4a4a;\n }\n \n .qde-dark .qde-source {\n border-color: #444;\n }\n \n .qde-dark .qde-textarea {\n background: #1e1e1e;\n color: #e0e0e0;\n }\n \n .qde-dark .qde-preview {\n background: #1e1e1e;\n color: #e0e0e0;\n }\n \n /* Dark mode table styles */\n .qde-dark .qde-preview table th,\n .qde-dark .qde-preview table td {\n border-color: #3a3a3a;\n }\n \n .qde-dark .qde-preview table th {\n background: #2d2d2d;\n }\n \n .qde-dark .qde-preview table tr:nth-child(even) {\n background: #252525;\n }\n \n /* Mobile responsive */\n @media (max-width: 768px) {\n .qde-mode-split .qde-editor {\n flex-direction: column;\n }\n \n .qde-mode-split .qde-source {\n border-right: none;\n border-bottom: 1px solid #ddd;\n }\n }\n ',document.head.appendChild(e)}attachEvents(){this.sourceTextarea.addEventListener("input",()=>{this.handleSourceInput()}),this.previewPanel.addEventListener("input",()=>{this.handlePreviewInput()}),this.toolbar&&this.toolbar.addEventListener("click",e=>{const t=e.target.closest(".qde-btn");t&&(t.dataset.mode?this.setMode(t.dataset.mode):t.dataset.action&&this.handleAction(t.dataset.action))}),document.addEventListener("keydown",e=>{if(e.ctrlKey||e.metaKey)switch(e.key){case"1":e.preventDefault(),this.setMode("source");break;case"2":e.preventDefault(),this.setMode("split");break;case"3":e.preventDefault(),this.setMode("preview");break;case"z":case"Z":e.shiftKey?(e.preventDefault(),this.redo()):(e.preventDefault(),this.undo());break;case"y":case"Y":e.preventDefault(),this.redo()}})}handleSourceInput(){clearTimeout(this.updateTimer),this.updateTimer=setTimeout(()=>{this.updateFromMarkdown(this.sourceTextarea.value)},this.options.debounceDelay)}handlePreviewInput(){clearTimeout(this.updateTimer),this.updateTimer=setTimeout(()=>{this.updateFromHTML()},this.options.debounceDelay)}updateFromMarkdown(e){if(this._isUndoRedo||this._pushUndoState(e||""),this._isUndoRedo=!1,this._markdown=e||"",this._markdown.trim()){if(this._html=s(e,{fence_plugin:this.createFencePlugin(),lazy_linefeeds:this.options.lazy_linefeeds,inline_styles:this.options.inline_styles}),"source"!==this.currentMode&&(this.previewPanel.innerHTML=this._html,this.makeFencesNonEditable(),window.MathJax&&window.MathJax.typesetPromise)){const e=this.previewPanel.querySelectorAll(".math-display");e.length>0&&window.MathJax.typesetPromise(Array.from(e)).catch(e=>{console.warn("MathJax batch processing failed:",e)})}}else this._html="","source"!==this.currentMode&&(this.previewPanel.innerHTML='<div style="color: #999; font-style: italic; padding: 16px;">Start typing markdown in the source panel...</div>');this.options.onChange&&this.options.onChange(this._markdown,this._html)}updateFromHTML(){const e=this.previewPanel.cloneNode(!0);this.preprocessSpecialElements(e),this._html=this.previewPanel.innerHTML,this._markdown=s.toMarkdown(e,{fence_plugin:this.createFencePlugin()}),"preview"!==this.currentMode&&(this.sourceTextarea.value=this._markdown),this.options.onChange&&this.options.onChange(this._markdown,this._html)}preprocessSpecialElements(e){if(!e)return;e.querySelectorAll('[contenteditable="false"][data-qd-source]').forEach(e=>{const t=e.getAttribute("data-qd-source"),n=e.getAttribute("data-qd-fence")||"```",o=e.getAttribute("data-qd-lang")||"",r=document.createElement("pre");r.setAttribute("data-qd-fence",n),o&&r.setAttribute("data-qd-lang",o);const a=document.createElement("code");a.textContent=t,r.appendChild(a),e.parentNode.replaceChild(r,e)});e.querySelectorAll("table.qde-csv-table[data-qd-lang]").forEach(e=>{const t=e.getAttribute("data-qd-lang");if(!t||!["csv","psv","tsv"].includes(t))return;const n="csv"===t?",":"psv"===t?"|":"\t";let o="";const r=[];e.querySelectorAll("thead th").forEach(e=>{const t=e.textContent.trim(),o=t.includes(n)||t.includes('"')||t.includes("\n");r.push(o?`"${t.replace(/"/g,'""')}"`:t)}),o+=r.join(n)+"\n";e.querySelectorAll("tbody tr").forEach(e=>{const t=[];e.querySelectorAll("td").forEach(e=>{const o=e.textContent.trim(),r=o.includes(n)||o.includes('"')||o.includes("\n");t.push(r?`"${o.replace(/"/g,'""')}"`:o)}),o+=t.join(n)+"\n"});const a=document.createElement("pre");a.setAttribute("data-qd-fence","```"),a.setAttribute("data-qd-lang",t);const i=document.createElement("code");i.textContent=o.trim(),a.appendChild(i),e.parentNode.replaceChild(a,e)})}createFencePlugin(){return{render:(e,t)=>{if(this.options.customFences&&this.options.customFences[t])try{return this.options.customFences[t](e,t)}catch(n){return console.error(`Custom fence plugin error for ${t}:`,n),`<pre><code class="language-${t}">${this.escapeHtml(e)}</code></pre>`}if(!!this.options.enableComplexFences)switch(t){case"svg":return this.renderSVG(e);case"html":return this.renderHTML(e);case"math":case"tex":case"latex":return this.renderMath(e,t);case"csv":case"psv":case"tsv":return this.renderTable(e,t);case"json":case"json5":return this.renderJSON(e,t);case"katex":return this.renderMath(e,"katex");case"mermaid":if(window.mermaid)return this.renderMermaid(e);break;case"geojson":return this.renderGeoJSON(e);case"stl":return this.renderSTL(e)}if(window.hljs&&t&&hljs.getLanguage(t)){return`<pre data-qd-fence="\`\`\`" data-qd-lang="${t}"><code class="hljs language-${t}">${hljs.highlight(e,{language:t}).value}</code></pre>`}},reverse:e=>{const t=e.getAttribute("data-qd-lang")||"";let n="";if(e.querySelector("code.hljs")){const t=e.querySelector("code.hljs");n=t.textContent||t.innerText||""}else if(e.querySelector("code")){const t=e.querySelector("code");n=t.textContent||t.innerText||""}else n=e.textContent||e.innerText||"";return{content:n,lang:t,fence:"```"}}}}renderSVG(e){try{const t=(new DOMParser).parseFromString(e,"image/svg+xml");if(t.querySelector("parsererror"))throw new Error("Invalid SVG");const n=t.documentElement;n.querySelectorAll("script").forEach(e=>e.remove());const o=document.createTreeWalker(n,NodeFilter.SHOW_ELEMENT);let r;for(;r=o.nextNode();)for(let e=r.attributes.length-1;e>=0;e--){const t=r.attributes[e];(t.name.startsWith("on")||t.value.includes("javascript:"))&&r.removeAttribute(t.name)}const a=document.createElement("div");return a.className="qde-svg-container",a.contentEditable="false",a.setAttribute("data-qd-fence","```"),a.setAttribute("data-qd-lang","svg"),a.setAttribute("data-qd-source",e),a.innerHTML=(new XMLSerializer).serializeToString(n),a.outerHTML}catch(e){const t=document.createElement("pre");return t.className="qde-error",t.contentEditable="false",t.setAttribute("data-qd-fence","```"),t.setAttribute("data-qd-lang","svg"),t.textContent=`Invalid SVG: ${e.message}`,t.outerHTML}}renderHTML(e){const t=`html-${Date.now()}-${Math.random().toString(36).substr(2,9)}`;if(window.DOMPurify){const t=DOMPurify.sanitize(e),n=document.createElement("div");return n.className="qde-html-container",n.contentEditable="false",n.setAttribute("data-qd-fence","```"),n.setAttribute("data-qd-lang","html"),n.setAttribute("data-qd-source",e),n.innerHTML=t,n.outerHTML}this.lazyLoadLibrary("DOMPurify",()=>window.DOMPurify,"https://unpkg.com/dompurify/dist/purify.min.js").then(n=>{if(n){const n=document.getElementById(t);if(n){const t=DOMPurify.sanitize(e);n.innerHTML=t,n.setAttribute("data-qd-source",e),n.setAttribute("data-qd-fence","```"),n.setAttribute("data-qd-lang","html")}}});const n=document.createElement("div");n.id=t,n.className="qde-html-container",n.contentEditable="false",n.setAttribute("data-qd-fence","```"),n.setAttribute("data-qd-lang","html"),n.setAttribute("data-qd-source",e);const o=document.createElement("pre");return o.textContent=e,n.appendChild(o),n.outerHTML}renderMath(e,t){const n=`math-${Math.random().toString(36).substring(2,15)}`,o=document.createElement("div");o.id=n,o.className="math-display",o.contentEditable="false",o.setAttribute("data-source-type","math");const r=e.replace(/\r?\n/g," ").replace(/\s+/g," ").trim();return o.textContent=`$$${r}$$`,o.style.textAlign="center",o.style.margin="1em 0",window.MathJax&&window.MathJax.typesetPromise||this.ensureMathJaxLoaded(),o.outerHTML}ensureMathJaxLoaded(){if(void 0===window.MathJax&&!window.mathJaxLoading){window.mathJaxLoading=!0,window.MathJax||(window.MathJax={loader:{load:["input/tex","output/svg"]},tex:{packages:{"[+]":["ams"]},inlineMath:[["$","$"],["\\(","\\)"]],displayMath:[["$$","$$"],["\\[","\\]"]],processEscapes:!0,processEnvironments:!0},options:{renderActions:{addMenu:[]},ignoreHtmlClass:"tex2jax_ignore",processHtmlClass:"tex2jax_process"},svg:{fontCache:"none"},startup:{typeset:!1}});const e=document.createElement("script");e.src="https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-svg.js",e.async=!0,e.onload=()=>{if(window.mathJaxLoading=!1,window.MathJax&&window.MathJax.typesetPromise){const e=document.querySelectorAll(".math-display");e.length>0&&window.MathJax.typesetPromise(Array.from(e)).catch(e=>{console.warn("Initial MathJax processing failed:",e)})}},e.onerror=()=>{window.mathJaxLoading=!1,console.error("Failed to load MathJax")},document.head.appendChild(e)}}renderTable(e,t){const n=this.escapeHtml(e);try{const o="csv"===t?",":"psv"===t?"|":"\t",r=e.trim().split("\n");if(0===r.length)return`<pre data-qd-fence="\`\`\`" data-qd-lang="${t}" data-qd-source="${n}">${n}</pre>`;let a=`<table class="qde-data-table qde-csv-table" data-qd-fence="\`\`\`" data-qd-lang="${t}">`;const i=this.parseCSVLine(r[0],o);if(a+="<thead><tr>",i.forEach(e=>{a+=`<th>${this.escapeHtml(e.trim())}</th>`}),a+="</tr></thead>",r.length>1){a+="<tbody>";for(let e=1;e<r.length;e++){const t=this.parseCSVLine(r[e],o);a+="<tr>",t.forEach(e=>{a+=`<td>${this.escapeHtml(e.trim())}</td>`}),a+="</tr>"}a+="</tbody>"}return a+="</table>",a}catch(e){return`<pre data-qd-fence="\`\`\`" data-qd-lang="${t}" data-qd-source="${n}">${n}</pre>`}}parseCSVLine(e,t){const n=[];let o="",r=!1;for(let a=0;a<e.length;a++){const i=e[a],s=e[a+1];'"'===i?r&&'"'===s?(o+='"',a++):r=!r:i!==t||r?o+=i:(n.push(o),o="")}return n.push(o),n}renderJSON(e,t){if(window.hljs&&hljs.getLanguage("json"))try{let n=e;try{const t=JSON.parse(e);n=JSON.stringify(t,null,2)}catch(e){}return`<pre class="qde-json" data-qd-fence="\`\`\`" data-qd-lang="${t}"><code class="hljs language-json">${hljs.highlight(n,{language:"json"}).value}</code></pre>`}catch(e){}return`<pre class="qde-json" data-qd-fence="\`\`\`" data-qd-lang="${t}">${this.escapeHtml(e)}</pre>`}renderGeoJSON(e){const t=`map-${Math.random().toString(36).substr(2,15)}`,n=()=>{const n=document.getElementById(t+"-container");if(n&&window.L)try{const o=JSON.parse(e),r=document.createElement("div");r.id=t,r.style.cssText="width: 100%; height: 300px;",n.innerHTML="",n.appendChild(r);const a=L.map(t);n._map=a;const i=L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",{attribution:"",crossOrigin:"anonymous"});i.addTo(a);const s=L.geoJSON(o);s.addTo(a),s.getBounds().isValid()?a.fitBounds(s.getBounds()):a.setView([0,0],2),n._tileLayer=i,n._geoJsonLayer=s,i.on("load",()=>{n.setAttribute("data-tiles-loaded","true")})}catch(e){n.innerHTML=`<pre class="qde-error">GeoJSON error: ${this.escapeHtml(e.message)}</pre>`}};window.L?setTimeout(n,0):(window._qde_leaflet_loading||(window._qde_leaflet_loading=this.lazyLoadLibrary("Leaflet",()=>window.L,"https://unpkg.com/leaflet@1.9.4/dist/leaflet.js","https://unpkg.com/leaflet@1.9.4/dist/leaflet.css").catch(e=>(console.warn("Failed to load Leaflet:",e),window._qde_leaflet_loading=null,!1))),window._qde_leaflet_loading.then(e=>{if(e)n();else{const e=document.getElementById(t+"-container");e&&(e.innerHTML='<div style="padding: 20px; text-align: center; color: #666;">Failed to load map library</div>')}}).catch(()=>{}));const o=document.createElement("div");return o.className="geojson-container",o.id=t+"-container",o.style.cssText="width: 100%; height: 300px; border: 1px solid #ddd; border-radius: 4px; margin: 0.5em 0; background: #f0f0f0;",o.contentEditable="false",o.setAttribute("data-source-type","geojson"),o.setAttribute("data-original-source",this.escapeHtml(e)),o.setAttribute("data-qd-fence","```"),o.setAttribute("data-qd-lang","geojson"),o.setAttribute("data-qd-source",e),o.textContent="Loading map...",o.outerHTML}renderSTL(e){const t=`qde-stl-viewer-${Date.now()}-${Math.random().toString(36).substr(2,9)}`;return setTimeout(()=>{const n=document.getElementById(t);if(n)if(void 0!==window.THREE)try{const t=window.THREE,o=new t.Scene;o.background=new t.Color(15790320);const r=new t.PerspectiveCamera(75,n.clientWidth/400,.1,1e3),a=new t.WebGLRenderer({antialias:!0});a.setSize(n.clientWidth,400),n.innerHTML="",n.appendChild(a.domElement),n._threeScene=o,n._threeCamera=r,n._threeRenderer=a;const i=this.parseSTL(e),s=new t.MeshLambertMaterial({color:26367}),l=new t.Mesh(i,s);o.add(l);const c=new t.AmbientLight(4210752,.6);o.add(c);const d=new t.DirectionalLight(16777215,.8);d.position.set(1,1,1).normalize(),o.add(d);const h=(new t.Box3).setFromObject(l),u=h.getCenter(new t.Vector3),p=h.getSize(new t.Vector3),m=Math.max(p.x,p.y,p.z);r.position.set(u.x+m,u.y+m,u.z+m),r.lookAt(u);const g=()=>{requestAnimationFrame(g),l.rotation.y+=.01,a.render(o,r)};g()}catch(e){console.error("STL rendering error:",e),n.innerHTML=`<pre class="qde-error">STL error: ${this.escapeHtml(e.message)}</pre>`}else n.innerHTML='<div style="padding: 20px; text-align: center; color: #666;">Three.js library not loaded. Add <script src="https://unpkg.com/three@0.147.0/build/three.min.js"></script> to your HTML.</div>'},0),`<div id="${t}" class="qde-stl-container" data-stl-id="${t}" data-qd-fence="\`\`\`" data-qd-lang="stl" data-qd-source="${this.escapeHtml(e)}" contenteditable="false" style="height: 400px; background: #f0f0f0; display: flex; align-items: center; justify-content: center;">Loading 3D model...</div>`}parseSTL(e){const t=window.THREE,n=new t.BufferGeometry,o=[],r=[],a=e.split("\n");let i=null;for(let e of a)if(e=e.trim(),e.startsWith("facet normal")){const t=e.split(/\s+/);i=[parseFloat(t[2]),parseFloat(t[3]),parseFloat(t[4])]}else if(e.startsWith("vertex")){const t=e.split(/\s+/);o.push(parseFloat(t[1]),parseFloat(t[2]),parseFloat(t[3])),i&&r.push(i[0],i[1],i[2])}return n.setAttribute("position",new t.Float32BufferAttribute(o,3)),n.setAttribute("normal",new t.Float32BufferAttribute(r,3)),n}renderMermaid(e){const t=`mermaid-${Date.now()}-${Math.random().toString(36).substr(2,9)}`;setTimeout(()=>{const n=document.getElementById(t);n&&window.mermaid&&mermaid.render(t+"-svg",e).then(e=>{n.innerHTML=e.svg}).catch(e=>{n.innerHTML=`<pre>Error rendering diagram: ${e.message}</pre>`})},0);const n=document.createElement("div");return n.id=t,n.className="mermaid",n.contentEditable="false",n.setAttribute("data-qd-source",e),n.setAttribute("data-qd-fence","```"),n.setAttribute("data-qd-lang","mermaid"),n.textContent="Loading diagram...",n.outerHTML}escapeHtml(e){return(e??"").replace(/[&"'<>]/g,e=>({"&":"&",'"':""","'":"'","<":"<",">":">"}[e]))}makeFencesNonEditable(){this.previewPanel}async loadPlugins(){const e=[];this.options.plugins.highlightjs&&!window.hljs&&e.push(this.loadScript("https://unpkg.com/@highlightjs/cdn-assets/highlight.min.js"),this.loadCSS("https://unpkg.com/@highlightjs/cdn-assets/styles/github.min.css")),this.options.plugins.mermaid&&!window.mermaid&&e.push(this.loadScript("https://unpkg.com/mermaid/dist/mermaid.min.js").then(()=>{window.mermaid&&mermaid.initialize({startOnLoad:!1})})),await Promise.all(e)}async lazyLoadLibrary(e,t,n,o=null){if(t())return!0;try{const e=[];return n&&e.push(this.loadScript(n)),o&&e.push(this.loadCSS(o)),await Promise.all(e),t()}catch(t){return console.error(`Failed to load ${e}:`,t),!1}}loadScript(e){return new Promise((t,n)=>{const o=document.createElement("script");o.src=e,o.onload=t,o.onerror=n,document.head.appendChild(o)})}loadCSS(e){return new Promise(t=>{const n=document.createElement("link");n.rel="stylesheet",n.href=e,n.onload=t,document.head.appendChild(n),setTimeout(t,1e3)})}applyTheme(){const e=this.options.theme;if(this._autoThemeListener&&(window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change",this._autoThemeListener),this._autoThemeListener=null),"auto"===e){const e=window.matchMedia("(prefers-color-scheme: dark)");this.container.classList.toggle("qde-dark",e.matches),this._autoThemeListener=e=>{this.container.classList.toggle("qde-dark",e.matches)},e.addEventListener("change",this._autoThemeListener)}else this.container.classList.toggle("qde-dark","dark"===e)}setTheme(e){["light","dark","auto"].includes(e)&&(this.options.theme=e,this.applyTheme())}getTheme(){return this.options.theme}setLazyLinefeeds(e){this.options.lazy_linefeeds=e,this._markdown&&this.updateFromMarkdown(this._markdown)}getLazyLinefeeds(){return this.options.lazy_linefeeds}setDebounceDelay(e){this.options.debounceDelay=Math.max(0,e)}getDebounceDelay(){return this.options.debounceDelay}setMode(e){["source","preview","split"].includes(e)&&(this.currentMode=e,this.container.className=`qde-container qde-mode-${e}`,this.toolbar&&this.toolbar.querySelectorAll(".qde-btn[data-mode]").forEach(t=>{t.classList.toggle("active",t.dataset.mode===e)}),this.container.classList.contains("qde-dark")&&this.container.classList.add("qde-dark"),"source"!==e&&setTimeout(()=>this.makeFencesNonEditable(),0),this.options.onModeChange&&this.options.onModeChange(e))}_pushUndoState(e){if(e===this._markdown)return;this._undoStack.push(this._markdown);const t=this.options.undoStackSize||100;this._undoStack.length>t&&this._undoStack.splice(0,this._undoStack.length-t),this._redoStack=[],this._updateUndoButtons()}undo(){if(!this.canUndo())return;this._redoStack.push(this._markdown);const e=this._undoStack.pop();this._isUndoRedo=!0,this._markdown=e,this.sourceTextarea&&(this.sourceTextarea.value=e),this.updateFromMarkdown(e),this._updateUndoButtons()}redo(){if(!this.canRedo())return;this._undoStack.push(this._markdown);const e=this._redoStack.pop();this._isUndoRedo=!0,this._markdown=e,this.sourceTextarea&&(this.sourceTextarea.value=e),this.updateFromMarkdown(e),this._updateUndoButtons()}canUndo(){return this._undoStack.length>0}canRedo(){return this._redoStack.length>0}clearHistory(){this._undoStack=[],this._redoStack=[],this._updateUndoButtons()}_updateUndoButtons(){if(!this.toolbar)return;const e=this.toolbar.querySelector('[data-action="undo"]'),t=this.toolbar.querySelector('[data-action="redo"]');e&&e.classList.toggle("disabled",!this.canUndo()),t&&t.classList.toggle("disabled",!this.canRedo())}handleAction(e){switch(e){case"copy-markdown":this.copy("markdown");break;case"copy-html":this.copy("html");break;case"copy-rendered":this.copyRendered();break;case"remove-hr":this.removeHR();break;case"lazy-linefeeds":this.convertLazyLinefeeds();break;case"undo":this.undo();break;case"redo":this.redo()}}async copy(e){const t="markdown"===e?this._markdown:this._html;try{await navigator.clipboard.writeText(t);const n=this.toolbar.querySelector(`[data-action="copy-${e}"]`);if(n){const e=n.textContent;n.textContent="Copied!",setTimeout(()=>{n.textContent=e},1500)}}catch(e){console.error("Failed to copy:",e)}}get markdown(){return this._markdown}set markdown(e){this.setMarkdown(e)}get html(){return this._html}get mode(){return this.currentMode}async setMarkdown(e){this.initPromise&&await this.initPromise,this._markdown=e,this.sourceTextarea&&(this.sourceTextarea.value=e),this.updateFromMarkdown(e)}getMarkdown(){return this._markdown}getHTML(){return this._html}async removeHR(){const e=u.removeHRFromMarkdown(this._markdown);await this.setMarkdown(e);const t=this.toolbar?.querySelector('[data-action="remove-hr"]');if(t){const e=t.textContent;t.textContent="Removed!",setTimeout(()=>{t.textContent=e},1500)}}static removeHRFromMarkdown(e){const t=(e||"").split("\n"),n=[];let o=!1,r=null,a=0;for(let e=0;e<t.length;e++){const i=t[e],s=i.trim(),l=s.match(/^(`{3,}|~{3,})/);if(l){const e=l[1][0],t=l[1].length;if(!o){o=!0,r=e,a=t,n.push(i);continue}if(e===r&&t>=a&&/^(`{3,}|~{3,})\s*$/.test(s)){o=!1,r=null,a=0,n.push(i);continue}}if(o){n.push(i);continue}if(/^\|.*\|$/.test(s)||/^[-| :]+$/.test(s)&&s.includes("|")){n.push(i);continue}if(/^[-_*](\s*[-_*]){2,}\s*$/.test(s)){const o=e>0?t[e-1].trim():"",r=e<t.length-1?t[e+1].trim():"";if(p(o)||p(r)){n.push(i);continue}continue}n.push(i)}return n.join("\n")}async convertLazyLinefeeds(){const e=u.convertLazyLinefeeds(this._markdown);await this.setMarkdown(e);const t=this.toolbar?.querySelector('[data-action="lazy-linefeeds"]');if(t){const e=t.textContent;t.textContent="Converted!",setTimeout(()=>{t.textContent=e},1500)}}static convertLazyLinefeeds(e){const t=(e||"").split("\n"),n=[];let o=!1,r=null,a=0,i=!1;for(let e=0;e<t.length;e++){const s=t[e],l=s.trim(),c=l.match(/^(`{3,}|~{3,})/);if(c){const e=c[1][0],t=c[1].length;if(!o){o=!0,r=e,a=t,n.push(s);continue}if(e===r&&t>=a&&/^(`{3,}|~{3,})\s*$/.test(l)){o=!1,r=null,a=0,n.push(s);continue}}if(o){n.push(s);continue}if(/^<[a-zA-Z]/.test(l)&&(i=!0),i){n.push(s),(/>$/.test(l)||""===l)&&(i=!1);continue}if(""===l){0!==n.length&&""===n[n.length-1].trim()||n.push(s);continue}if(/^#{1,6}\s/.test(l)||/^[-_*](\s*[-_*]){2,}\s*$/.test(l)||/^(\d+\.|-|\*|\+)\s/.test(l)||/^>/.test(l)||/^\|/.test(l))n.push(s);else{if(n.length>0){const e=n[n.length-1].trim();""===e||/^#{1,6}\s/.test(e)||/^[-_*](\s*[-_*]){2,}\s*$/.test(e)||/^(\d+\.|-|\*|\+)\s/.test(e)||/^>/.test(e)||/^\|/.test(e)||/^(`{3,}|~{3,})/.test(e)||n.push("")}n.push(s)}}return n.join("\n")}async copyRendered(){try{if((await d(this.previewPanel)).success){const e=this.toolbar?.querySelector('[data-action="copy-rendered"]');if(e){const t=e.textContent;e.textContent="Copied!",setTimeout(()=>{e.textContent=t},1500)}}}catch(e){console.error("Failed to copy rendered content:",e)}}destroy(){clearTimeout(this.updateTimer),this.container.innerHTML="",this.container.classList.remove("qde-container","qde-dark");if(0===document.querySelectorAll(".qde-container").length){const e=document.getElementById("qde-styles");e&&e.remove()}}}function p(e){return e.includes("|")}return"undefined"!=typeof module&&module.exports&&(module.exports=u),"undefined"!=typeof window&&(window.QuikdownEditor=u),u});
|
|
13
13
|
//# sourceMappingURL=quikdown_edit.umd.min.js.map
|