support markdown in notes when using showNotesPanel #4091 #6332

Signed-off-by: si458 <simonsmith5521@gmail.com>

si458 committed Aug 27, 2024 at 15:24 UTC b4323223ccedaf5c0ee6574e2c92fec46748cdbc
7 files changed +4092 -4
public/scripts/marked-min.js new
+11
@@ -0,0 +1,11 @@
1 +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).marked={})}(this,function(n){"use strict";function e(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}function t(e){n.defaults=e}n.defaults=e();const s=/[&<>"']/,Q=new RegExp(s.source,"g"),r=/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,B=new RegExp(r.source,"g"),M={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"},i=e=>M[e];function l(e,t){if(t){if(s.test(e))return e.replace(Q,i)}else if(r.test(e))return e.replace(B,i);return e}const O=/(^|[^\[])\^/g;function a(e,t){let s="string"==typeof e?e:e.source;t=t||"";const r={replace:(e,t)=>{let n="string"==typeof t?t:t.source;return n=n.replace(O,"$1"),s=s.replace(e,n),r},getRegex:()=>new RegExp(s,t)};return r}function o(e){try{e=encodeURI(e).replace(/%25/g,"%")}catch{return null}return e}var c={exec:()=>null};function h(e,t){const n=e.replace(/\|/g,(e,t,n)=>{let s=!1,r=t;for(;0<=--r&&"\\"===n[r];)s=!s;return s?"|":" |"}),s=n.split(/ \|/);let r=0;if(s[0].trim()||s.shift(),0<s.length&&!s[s.length-1].trim()&&s.pop(),t)if(s.length>t)s.splice(t);else for(;s.length<t;)s.push("");for(;r<s.length;r++)s[r]=s[r].trim().replace(/\\\|/g,"|");return s}function u(e,t,n){var s=e.length;if(0===s)return"";let r=0;for(;r<s;){var i=e.charAt(s-r-1);if(i!==t||n){if(i===t||!n)break;r++}else r++}return e.slice(0,s-r)}function j(e,t,n,s){var r=t.href,t=t.title?l(t.title):null,i=e[1].replace(/\\([\[\]])/g,"$1");return"!"!==e[0].charAt(0)?(s.state.inLink=!0,e={type:"link",raw:n,href:r,title:t,text:i,tokens:s.inlineTokens(i)},s.state.inLink=!1,e):{type:"image",raw:n,href:r,title:t,text:l(i)}}class m{options;rules;lexer;constructor(e){this.options=e||n.defaults}space(e){e=this.rules.block.newline.exec(e);if(e&&0<e[0].length)return{type:"space",raw:e[0]}}code(e){const t=this.rules.block.code.exec(e);if(t)return e=t[0].replace(/^ {1,4}/gm,""),{type:"code",raw:t[0],codeBlockStyle:"indented",text:this.options.pedantic?e:u(e,"\n")}}fences(e){const t=this.rules.block.fences.exec(e);var n;if(t)return n=function(e,t){if(null===(e=e.match(/^(\s+)(?:```)/)))return t;const n=e[1];return t.split("\n").map(e=>{var t=e.match(/^\s+/);if(null===t)return e;var[t]=t;return t.length>=n.length?e.slice(n.length):e}).join("\n")}(e=t[0],t[3]||""),{type:"code",raw:e,lang:t[2]&&t[2].trim().replace(this.rules.inline.anyPunctuation,"$1"),text:n}}heading(e){const t=this.rules.block.heading.exec(e);if(t){let e=t[2].trim();if(/#$/.test(e)){const n=u(e,"#");!this.options.pedantic&&n&&!/ $/.test(n)||(e=n.trim())}return{type:"heading",raw:t[0],depth:t[1].length,text:e,tokens:this.lexer.inline(e)}}}hr(e){e=this.rules.block.hr.exec(e);if(e)return{type:"hr",raw:u(e[0],"\n")}}blockquote(e){e=this.rules.block.blockquote.exec(e);if(e){let n=u(e[0],"\n").split("\n"),s="",r="";const o=[];for(;0<n.length;){let e=!1;const c=[];let t;for(t=0;t<n.length;t++)if(/^ {0,3}>/.test(n[t]))c.push(n[t]),e=!0;else{if(e)break;c.push(n[t])}n=n.slice(t);const h=c.join("\n");var i=h.replace(/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,"\n $1").replace(/^ {0,3}>[ \t]?/gm,""),l=(s=s?s+`
2 +`+h:h,r=r?r+`
3 +`+i:i,this.lexer.state.top);if(this.lexer.state.top=!0,this.lexer.blockTokens(i,o,!0),this.lexer.state.top=l,0===n.length)break;i=o[o.length-1];if("code"===i?.type)break;if("blockquote"===i?.type){var l=i,a=l.raw+"\n"+n.join("\n"),a=this.blockquote(a);o[o.length-1]=a,s=s.substring(0,s.length-l.raw.length)+a.raw,r=r.substring(0,r.length-l.text.length)+a.text;break}if("list"===i?.type){l=i;const p=l.raw+"\n"+n.join("\n");a=this.list(p);o[o.length-1]=a,s=s.substring(0,s.length-i.raw.length)+a.raw,r=r.substring(0,r.length-l.raw.length)+a.raw,n=p.substring(o[o.length-1].raw.length).split("\n")}}return{type:"blockquote",raw:s,tokens:o,text:r}}}list(h){let p=this.rules.block.list.exec(h);if(p){let e=p[1].trim();var t=1<e.length;const g={type:"list",raw:"",ordered:t,start:t?+e.slice(0,-1):"",loose:!1,items:[]},k=(e=t?"\\d{1,9}\\"+e.slice(-1):"\\"+e,this.options.pedantic&&(e=t?e:"[*+-]"),new RegExp(`^( {0,3}${e})((?:[ ][^\\n]*)?(?:\\n|$))`));let c=!1;for(;h;){let e=!1,t="",n="";if(!(p=k.exec(h)))break;if(this.rules.block.hr.test(h))break;t=p[0],h=h.substring(t.length);let s=p[2].split("\n",1)[0].replace(/^\t+/,e=>" ".repeat(3*e.length)),r=h.split("\n",1)[0],i=!s.trim(),l=0;if(this.options.pedantic?(l=2,n=s.trimStart()):i?l=p[1].length+1:(l=4<(l=p[2].search(/[^ ]/))?1:l,n=s.slice(l),l+=p[1].length),i&&/^ *$/.test(r)&&(t+=r+"\n",h=h.substring(r.length+1),e=!0),!e){const f=new RegExp(`^ {0,${Math.min(3,l-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`),d=new RegExp(`^ {0,${Math.min(3,l-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),x=new RegExp(`^ {0,${Math.min(3,l-1)}}(?:\`\`\`|~~~)`),b=new RegExp(`^ {0,${Math.min(3,l-1)}}#`);for(;h;){var u=h.split("\n",1)[0];if(r=u,this.options.pedantic&&(r=r.replace(/^ {1,4}(?=( {4})*[^ ])/g," ")),x.test(r))break;if(b.test(r))break;if(f.test(r))break;if(d.test(h))break;if(r.search(/[^ ]/)>=l||!r.trim())n+="\n"+r.slice(l);else{if(i)break;if(4<=s.search(/[^ ]/))break;if(x.test(s))break;if(b.test(s))break;if(d.test(s))break;n+="\n"+r}i||r.trim()||(i=!0),t+=u+"\n",h=h.substring(u.length+1),s=r.slice(l)}}g.loose||(c?g.loose=!0:/\n *\n *$/.test(t)&&(c=!0));let a=null,o;this.options.gfm&&(a=/^\[[ xX]\] /.exec(n))&&(o="[ ] "!==a[0],n=n.replace(/^\[[ xX]\] +/,"")),g.items.push({type:"list_item",raw:t,task:!!a,checked:o,loose:!1,text:n,tokens:[]}),g.raw+=t}g.items[g.items.length-1].raw=g.items[g.items.length-1].raw.trimEnd(),g.items[g.items.length-1].text=g.items[g.items.length-1].text.trimEnd(),g.raw=g.raw.trimEnd();for(let e=0;e<g.items.length;e++)if(this.lexer.state.top=!1,g.items[e].tokens=this.lexer.blockTokens(g.items[e].text,[]),!g.loose){const s=g.items[e].tokens.filter(e=>"space"===e.type);var n=0<s.length&&s.some(e=>/\n.*\n/.test(e.raw));g.loose=n}if(g.loose)for(let e=0;e<g.items.length;e++)g.items[e].loose=!0;return g}}html(e){e=this.rules.block.html.exec(e);if(e)return{type:"html",block:!0,raw:e[0],pre:"pre"===e[1]||"script"===e[1]||"style"===e[1],text:e[0]}}def(e){const t=this.rules.block.def.exec(e);var n,s;if(t)return e=t[1].toLowerCase().replace(/\s+/g," "),n=t[2]?t[2].replace(/^<(.*)>$/,"$1").replace(this.rules.inline.anyPunctuation,"$1"):"",s=t[3]&&t[3].substring(1,t[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"),{type:"def",tag:e,raw:t[0],href:n,title:s}}table(e){const t=this.rules.block.table.exec(e);if(t&&/[:|]/.test(t[2])){var n=h(t[1]),e=t[2].replace(/^\||\| *$/g,"").split("|"),s=t[3]&&t[3].trim()?t[3].replace(/\n[ \t]*$/,"").split("\n"):[];const r={type:"table",raw:t[0],header:[],align:[],rows:[]};if(n.length===e.length){for(const i of e)/^ *-+: *$/.test(i)?r.align.push("right"):/^ *:-+: *$/.test(i)?r.align.push("center"):/^ *:-+ *$/.test(i)?r.align.push("left"):r.align.push(null);for(let e=0;e<n.length;e++)r.header.push({text:n[e],tokens:this.lexer.inline(n[e]),header:!0,align:r.align[e]});for(const l of s)r.rows.push(h(l,r.header.length).map((e,t)=>({text:e,tokens:this.lexer.inline(e),header:!1,align:r.align[t]})));return r}}}lheading(e){const t=this.rules.block.lheading.exec(e);if(t)return{type:"heading",raw:t[0],depth:"="===t[2].charAt(0)?1:2,text:t[1],tokens:this.lexer.inline(t[1])}}paragraph(e){const t=this.rules.block.paragraph.exec(e);if(t)return e="\n"===t[1].charAt(t[1].length-1)?t[1].slice(0,-1):t[1],{type:"paragraph",raw:t[0],text:e,tokens:this.lexer.inline(e)}}text(e){e=this.rules.block.text.exec(e);if(e)return{type:"text",raw:e[0],text:e[0],tokens:this.lexer.inline(e[0])}}escape(e){e=this.rules.inline.escape.exec(e);if(e)return{type:"escape",raw:e[0],text:l(e[1])}}tag(e){e=this.rules.inline.tag.exec(e);if(e)return!this.lexer.state.inLink&&/^<a /i.test(e[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&/^<\/a>/i.test(e[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&/^<(pre|code|kbd|script)(\s|>)/i.test(e[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(e[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:e[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:e[0]}}link(n){const s=this.rules.inline.link.exec(n);if(s){const i=s[2].trim();if(!this.options.pedantic&&/^</.test(i)){if(!/>$/.test(i))return;n=u(i.slice(0,-1),"\\");if((i.length-n.length)%2==0)return}else{var r,n=function(t,n){if(-1===t.indexOf(n[1]))return-1;let s=0;for(let e=0;e<t.length;e++)if("\\"===t[e])e++;else if(t[e]===n[0])s++;else if(t[e]===n[1]&&--s<0)return e;return-1}(s[2],"()");-1<n&&(r=(0===s[0].indexOf("!")?5:4)+s[1].length+n,s[2]=s[2].substring(0,n),s[0]=s[0].substring(0,r).trim(),s[3]="")}let e=s[2],t="";return this.options.pedantic?(n=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(e))&&(e=n[1],t=n[3]):t=s[3]?s[3].slice(1,-1):"",e=e.trim(),/^</.test(e)&&(e=this.options.pedantic&&!/>$/.test(i)?e.slice(1):e.slice(1,-1)),j(s,{href:e&&e.replace(this.rules.inline.anyPunctuation,"$1"),title:t&&t.replace(this.rules.inline.anyPunctuation,"$1")},s[0],this.lexer)}}reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){const s=(n[2]||n[1]).replace(/\s+/g," ");e=t[s.toLowerCase()];return e?j(n,e,n[0],this.lexer):{type:"text",raw:t=n[0].charAt(0),text:t}}}emStrong(r,i,e=""){let l=this.rules.inline.emStrongLDelim.exec(r);if(l&&((!l[3]||!e.match(/[\p{L}\p{N}]/u))&&(!(l[1]||l[2]||"")||!e||this.rules.inline.punctuation.exec(e)))){var a=[...l[0]].length-1;let e,t,n=a,s=0;const c="*"===l[0][0]?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(c.lastIndex=0,i=i.slice(-1*r.length+a);null!=(l=c.exec(i));)if(e=l[1]||l[2]||l[3]||l[4]||l[5]||l[6])if(t=[...e].length,l[3]||l[4])n+=t;else if((l[5]||l[6])&&a%3&&!((a+t)%3))s+=t;else if(!(0<(n-=t))){t=Math.min(t,t+n+s);var o=[...l[0]][0].length;const h=r.slice(0,a+l.index+o+t);if(Math.min(a,t)%2)return o=h.slice(1,-1),{type:"em",raw:h,text:o,tokens:this.lexer.inlineTokens(o)};o=h.slice(2,-2);return{type:"strong",raw:h,text:o,tokens:this.lexer.inlineTokens(o)}}}}codespan(t){const n=this.rules.inline.code.exec(t);if(n){let e=n[2].replace(/\n/g," ");var t=/[^ ]/.test(e),s=/^ /.test(e)&&/ $/.test(e);return e=l(e=t&&s?e.substring(1,e.length-1):e,!0),{type:"codespan",raw:n[0],text:e}}}br(e){e=this.rules.inline.br.exec(e);if(e)return{type:"br",raw:e[0]}}del(e){e=this.rules.inline.del.exec(e);if(e)return{type:"del",raw:e[0],text:e[2],tokens:this.lexer.inlineTokens(e[2])}}autolink(n){n=this.rules.inline.autolink.exec(n);if(n){let e,t;return t="@"===n[2]?"mailto:"+(e=l(n[1])):e=l(n[1]),{type:"link",raw:n[0],text:e,href:t,tokens:[{type:"text",raw:e,text:e}]}}}url(e){let n;if(n=this.rules.inline.url.exec(e)){let e,t;if("@"===n[2])e=l(n[0]),t="mailto:"+e;else{for(var s;s=n[0],n[0]=this.rules.inline._backpedal.exec(n[0])?.[0]??"",s!==n[0];);e=l(n[0]),t="www."===n[1]?"http://"+n[0]:n[0]}return{type:"link",raw:n[0],text:e,href:t,tokens:[{type:"text",raw:e,text:e}]}}}inlineText(t){t=this.rules.inline.text.exec(t);if(t){let e;return e=this.lexer.state.inRawBlock?t[0]:l(t[0]),{type:"text",raw:t[0],text:e}}}}var p=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,g=/(?:[*+-]|\d{1,9}[.)])/,k=a(/^(?!bull |blockCode|fences|blockquote|heading|html)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html))+?)\n {0,3}(=+|-+) *(?:\n+|$)/).replace(/bull/g,g).replace(/blockCode/g,/ {4}/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).getRegex(),f=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,d=/(?!\s*\])(?:\\.|[^\[\]\\])+/,x=a(/^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/).replace("label",d).replace("title",/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),g=a(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,g).getRegex(),b="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",w=/<!--(?:-?>|[\s\S]*?(?:-->|$))/,y=a("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))","i").replace("comment",w).replace("tag",b).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),$=a(f).replace("hr",p).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",b).getRegex(),x={blockquote:a(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph",$).getRegex(),code:/^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,def:x,fences:/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,hr:p,html:y,lheading:k,list:g,newline:/^(?: *(?:\n|$))+/,paragraph:$,table:c,text:/^[^\n]+/},y=a("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr",p).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",b).getRegex(),g={...x,table:y,paragraph:a(f).replace("hr",p).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("table",y).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",b).getRegex()},$={...x,html:a("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:\"[^\"]*\"|'[^']*'|\\s[^'\"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",w).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:c,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:a(f).replace("hr",p).replace("heading"," *#{1,6} *[^\n]").replace("lheading",k).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},y=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,b=/^( {2,}|\\)\n(?!\s*$)/,f="\\p{P}\\p{S}",p=a(/^((?![*_])[\spunctuation])/,"u").replace(/punctuation/g,f).getRegex(),k=a(/^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/,"u").replace(/punct/g,f).getRegex(),D=a("^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)[punct](\\*+)(?=[\\s]|$)|[^punct\\s](\\*+)(?!\\*)(?=[punct\\s]|$)|(?!\\*)[punct\\s](\\*+)(?=[^punct\\s])|[\\s](\\*+)(?!\\*)(?=[punct])|(?!\\*)[punct](\\*+)(?!\\*)(?=[punct])|[^punct\\s](\\*+)(?=[^punct\\s])","gu").replace(/punct/g,f).getRegex(),z=a("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\\s]|$)|[^punct\\s](_+)(?!_)(?=[punct\\s]|$)|(?!_)[punct\\s](_+)(?=[^punct\\s])|[\\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])","gu").replace(/punct/g,f).getRegex(),f=a(/\\([punct])/,"gu").replace(/punct/g,f).getRegex(),C=a(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),w=a(w).replace("(?:--\x3e|$)","--\x3e").getRegex(),w=a("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment",w).replace("attribute",/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),v=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,T=a(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/).replace("label",v).replace("href",/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/).replace("title",/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),R=a(/^!?\[(label)\]\[(ref)\]/).replace("label",v).replace("ref",d).getRegex(),d=a(/^!?\[(ref)\](?:\[\])?/).replace("ref",d).getRegex(),f={_backpedal:c,anyPunctuation:f,autolink:C,blockSkip:/\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g,br:b,code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,del:c,emStrongLDelim:k,emStrongRDelimAst:D,emStrongRDelimUnd:z,escape:y,link:T,nolink:d,punctuation:p,reflink:R,reflinkSearch:a("reflink|nolink(?!\\()","g").replace("reflink",R).replace("nolink",d).getRegex(),tag:w,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,url:c},C={...f,link:a(/^!?\[(label)\]\((.*?)\)/).replace("label",v).getRegex(),reflink:a(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",v).getRegex()},k={...f,escape:a(y).replace("])","~|])").getRegex(),url:a(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,"i").replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/},D={...k,br:a(b).replace("{2,}","*").getRegex(),text:a(k.text).replace("\\b_","\\b_| {2,}\\n").replace(/\{2,\}/g,"*").getRegex()};const _={normal:x,gfm:g,pedantic:$},A={normal:f,gfm:k,breaks:D,pedantic:C};class S{tokens;options;state;tokenizer;inlineQueue;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||n.defaults,this.options.tokenizer=this.options.tokenizer||new m,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,(this.tokenizer.lexer=this).inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};const t={block:_.normal,inline:A.normal};this.options.pedantic?(t.block=_.pedantic,t.inline=A.pedantic):this.options.gfm&&(t.block=_.gfm,this.options.breaks?t.inline=A.breaks:t.inline=A.gfm),this.tokenizer.rules=t}static get rules(){return{block:_,inline:A}}static lex(e,t){const n=new S(t);return n.lex(e)}static lexInline(e,t){const n=new S(t);return n.inlineTokens(e)}lex(e){e=e.replace(/\r\n|\r/g,"\n"),this.blockTokens(e,this.tokens);for(let e=0;e<this.inlineQueue.length;e++){var t=this.inlineQueue[e];this.inlineTokens(t.src,t.tokens)}return this.inlineQueue=[],this.tokens}blockTokens(s,t=[],e=!1){s=this.options.pedantic?s.replace(/\t/g," ").replace(/^ +$/gm,""):s.replace(/^( *)(\t+)/gm,(e,t,n)=>t+" ".repeat(n.length));let n,r,i;for(;s;)if(!(this.options.extensions&&this.options.extensions.block&&this.options.extensions.block.some(e=>!!(n=e.call({lexer:this},s,t))&&(s=s.substring(n.raw.length),t.push(n),!0))))if(n=this.tokenizer.space(s))s=s.substring(n.raw.length),1===n.raw.length&&0<t.length?t[t.length-1].raw+="\n":t.push(n);else if(n=this.tokenizer.code(s))s=s.substring(n.raw.length),!(r=t[t.length-1])||"paragraph"!==r.type&&"text"!==r.type?t.push(n):(r.raw+="\n"+n.raw,r.text+="\n"+n.text,this.inlineQueue[this.inlineQueue.length-1].src=r.text);else if(n=this.tokenizer.fences(s))s=s.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.heading(s))s=s.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.hr(s))s=s.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.blockquote(s))s=s.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.list(s))s=s.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.html(s))s=s.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.def(s))s=s.substring(n.raw.length),!(r=t[t.length-1])||"paragraph"!==r.type&&"text"!==r.type?this.tokens.links[n.tag]||(this.tokens.links[n.tag]={href:n.href,title:n.title}):(r.raw+="\n"+n.raw,r.text+="\n"+n.raw,this.inlineQueue[this.inlineQueue.length-1].src=r.text);else if(n=this.tokenizer.table(s))s=s.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.lheading(s))s=s.substring(n.raw.length),t.push(n);else{if(i=s,this.options.extensions&&this.options.extensions.startBlock){let t=1/0;const a=s.slice(1);let n;this.options.extensions.startBlock.forEach(e=>{"number"==typeof(n=e.call({lexer:this},a))&&0<=n&&(t=Math.min(t,n))}),t<1/0&&0<=t&&(i=s.substring(0,t+1))}if(this.state.top&&(n=this.tokenizer.paragraph(i)))r=t[t.length-1],e&&"paragraph"===r?.type?(r.raw+="\n"+n.raw,r.text+="\n"+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=r.text):t.push(n),e=i.length!==s.length,s=s.substring(n.raw.length);else if(n=this.tokenizer.text(s))s=s.substring(n.raw.length),(r=t[t.length-1])&&"text"===r.type?(r.raw+="\n"+n.raw,r.text+="\n"+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=r.text):t.push(n);else if(s){var l="Infinite loop on byte: "+s.charCodeAt(0);if(this.options.silent){console.error(l);break}throw new Error(l)}}return this.state.top=!0,t}inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}inlineTokens(s,t=[]){let n,e,r,i=s,l,a,o;if(this.tokens.links){const h=Object.keys(this.tokens.links);if(0<h.length)for(;null!=(l=this.tokenizer.rules.inline.reflinkSearch.exec(i));)h.includes(l[0].slice(l[0].lastIndexOf("[")+1,-1))&&(i=i.slice(0,l.index)+"["+"a".repeat(l[0].length-2)+"]"+i.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;null!=(l=this.tokenizer.rules.inline.blockSkip.exec(i));)i=i.slice(0,l.index)+"["+"a".repeat(l[0].length-2)+"]"+i.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);for(;null!=(l=this.tokenizer.rules.inline.anyPunctuation.exec(i));)i=i.slice(0,l.index)+"++"+i.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);for(;s;)if(a||(o=""),a=!1,!(this.options.extensions&&this.options.extensions.inline&&this.options.extensions.inline.some(e=>!!(n=e.call({lexer:this},s,t))&&(s=s.substring(n.raw.length),t.push(n),!0))))if(n=this.tokenizer.escape(s))s=s.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.tag(s))s=s.substring(n.raw.length),(e=t[t.length-1])&&"text"===n.type&&"text"===e.type?(e.raw+=n.raw,e.text+=n.text):t.push(n);else if(n=this.tokenizer.link(s))s=s.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.reflink(s,this.tokens.links))s=s.substring(n.raw.length),(e=t[t.length-1])&&"text"===n.type&&"text"===e.type?(e.raw+=n.raw,e.text+=n.text):t.push(n);else if(n=this.tokenizer.emStrong(s,i,o))s=s.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.codespan(s))s=s.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.br(s))s=s.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.del(s))s=s.substring(n.raw.length),t.push(n);else if(n=this.tokenizer.autolink(s))s=s.substring(n.raw.length),t.push(n);else if(!this.state.inLink&&(n=this.tokenizer.url(s)))s=s.substring(n.raw.length),t.push(n);else{if(r=s,this.options.extensions&&this.options.extensions.startInline){let t=1/0;const p=s.slice(1);let n;this.options.extensions.startInline.forEach(e=>{"number"==typeof(n=e.call({lexer:this},p))&&0<=n&&(t=Math.min(t,n))}),t<1/0&&0<=t&&(r=s.substring(0,t+1))}if(n=this.tokenizer.inlineText(r))s=s.substring(n.raw.length),"_"!==n.raw.slice(-1)&&(o=n.raw.slice(-1)),a=!0,(e=t[t.length-1])&&"text"===e.type?(e.raw+=n.raw,e.text+=n.text):t.push(n);else if(s){var c="Infinite loop on byte: "+s.charCodeAt(0);if(this.options.silent){console.error(c);break}throw new Error(c)}}return t}}class I{options;parser;constructor(e){this.options=e||n.defaults}space(e){return""}code({text:e,lang:t,escaped:n}){t=(t||"").match(/^\S*/)?.[0],e=e.replace(/\n$/,"")+"\n";return t?'<pre><code class="language-'+l(t)+'">'+(n?e:l(e,!0))+"</code></pre>\n":"<pre><code>"+(n?e:l(e,!0))+"</code></pre>\n"}blockquote({tokens:e}){return`<blockquote>
4 +${this.parser.parse(e)}</blockquote>
5 +`}html({text:e}){return e}heading({tokens:e,depth:t}){return`<h${t}>${this.parser.parseInline(e)}</h${t}>
6 +`}hr(e){return"<hr>\n"}list(t){var e=t.ordered,n=t.start;let s="";for(let e=0;e<t.items.length;e++){var r=t.items[e];s+=this.listitem(r)}var i=e?"ol":"ul";return"<"+i+(e&&1!==n?' start="'+n+'"':"")+">\n"+s+"</"+i+">\n"}listitem(e){let t="";var n;return e.task&&(n=this.checkbox({checked:!!e.checked}),e.loose?0<e.tokens.length&&"paragraph"===e.tokens[0].type?(e.tokens[0].text=n+" "+e.tokens[0].text,e.tokens[0].tokens&&0<e.tokens[0].tokens.length&&"text"===e.tokens[0].tokens[0].type&&(e.tokens[0].tokens[0].text=n+" "+e.tokens[0].tokens[0].text)):e.tokens.unshift({type:"text",raw:n+" ",text:n+" "}):t+=n+" "),`<li>${t+=this.parser.parse(e.tokens,!!e.loose)}</li>
7 +`}checkbox({checked:e}){return"<input "+(e?'checked="" ':"")+'disabled="" type="checkbox">'}paragraph({tokens:e}){return`<p>${this.parser.parseInline(e)}</p>
8 +`}table(t){var e="";let n="";for(let e=0;e<t.header.length;e++)n+=this.tablecell(t.header[e]);e+=this.tablerow({text:n});let s="";for(let e=0;e<t.rows.length;e++){var r=t.rows[e];n="";for(let e=0;e<r.length;e++)n+=this.tablecell(r[e]);s+=this.tablerow({text:n})}return"<table>\n<thead>\n"+e+"</thead>\n"+(s=s&&`<tbody>${s}</tbody>`)+"</table>\n"}tablerow({text:e}){return`<tr>
9 +${e}</tr>
10 +`}tablecell(e){var t=this.parser.parseInline(e.tokens),n=e.header?"th":"td";return(e.align?`<${n} align="${e.align}">`:`<${n}>`)+t+`</${n}>
11 +`}strong({tokens:e}){return`<strong>${this.parser.parseInline(e)}</strong>`}em({tokens:e}){return`<em>${this.parser.parseInline(e)}</em>`}codespan({text:e}){return`<code>${e}</code>`}br(e){return"<br>"}del({tokens:e}){return`<del>${this.parser.parseInline(e)}</del>`}link({href:e,title:t,tokens:n}){var n=this.parser.parseInline(n),s=o(e);if(null===s)return n;let r='<a href="'+(e=s)+'"';return t&&(r+=' title="'+t+'"'),r+=">"+n+"</a>"}image({href:e,title:t,text:n}){var s=o(e);if(null===s)return n;let r=`<img src="${e=s}" alt="${n}"`;return t&&(r+=` title="${t}"`),r+=">"}text(e){return"tokens"in e&&e.tokens?this.parser.parseInline(e.tokens):e.text}}class E{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return""+e}image({text:e}){return""+e}br(){return""}}class q{options;renderer;textRenderer;constructor(e){this.options=e||n.defaults,this.options.renderer=this.options.renderer||new I,this.renderer=this.options.renderer,this.renderer.options=this.options,(this.renderer.parser=this).textRenderer=new E}static parse(e,t){const n=new q(t);return n.parse(e)}static parseInline(e,t){const n=new q(t);return n.parseInline(e)}parse(n,s=!0){let r="";for(let t=0;t<n.length;t++){var e=n[t];if(this.options.extensions&&this.options.extensions.renderers&&this.options.extensions.renderers[e.type]){var i=e,l=this.options.extensions.renderers[i.type].call({parser:this},i);if(!1!==l||!["space","hr","heading","code","table","blockquote","list","html","paragraph","text"].includes(i.type)){r+=l||"";continue}}var a=e;switch(a.type){case"space":r+=this.renderer.space(a);continue;case"hr":r+=this.renderer.hr(a);continue;case"heading":r+=this.renderer.heading(a);continue;case"code":r+=this.renderer.code(a);continue;case"table":r+=this.renderer.table(a);continue;case"blockquote":r+=this.renderer.blockquote(a);continue;case"list":r+=this.renderer.list(a);continue;case"html":r+=this.renderer.html(a);continue;case"paragraph":r+=this.renderer.paragraph(a);continue;case"text":{var o;let e=this.renderer.text(a);for(;t+1<n.length&&"text"===n[t+1].type;)o=n[++t],e+="\n"+this.renderer.text(o);r+=s?this.renderer.paragraph({type:"paragraph",raw:e,text:e,tokens:[{type:"text",raw:e,text:e}]}):e;continue}default:var c='Token with "'+a.type+'" type was not found.';if(this.options.silent)return console.error(c),"";throw new Error(c)}}return r}parseInline(t,n){n=n||this.renderer;let s="";for(let e=0;e<t.length;e++){var r=t[e];if(this.options.extensions&&this.options.extensions.renderers&&this.options.extensions.renderers[r.type]){var i=this.options.extensions.renderers[r.type].call({parser:this},r);if(!1!==i||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(r.type)){s+=i||"";continue}}var l=r;switch(l.type){case"escape":s+=n.text(l);break;case"html":s+=n.html(l);break;case"link":s+=n.link(l);break;case"image":s+=n.image(l);break;case"strong":s+=n.strong(l);break;case"em":s+=n.em(l);break;case"codespan":s+=n.codespan(l);break;case"br":s+=n.br(l);break;case"del":s+=n.del(l);break;case"text":s+=n.text(l);break;default:var a='Token with "'+l.type+'" type was not found.';if(this.options.silent)return console.error(a),"";throw new Error(a)}}return s}}class Z{options;constructor(e){this.options=e||n.defaults}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}}class H{defaults=e();options=this.setOptions;parse=this.parseMarkdown(S.lex,q.parse);parseInline=this.parseMarkdown(S.lexInline,q.parseInline);Parser=q;Renderer=I;TextRenderer=E;Lexer=S;Tokenizer=m;Hooks=Z;constructor(...e){this.use(...e)}walkTokens(e,t){let n=[];for(const r of e)switch(n=n.concat(t.call(this,r)),r.type){case"table":var s=r;for(const i of s.header)n=n.concat(this.walkTokens(i.tokens,t));for(const l of s.rows)for(const a of l)n=n.concat(this.walkTokens(a.tokens,t));break;case"list":s=r;n=n.concat(this.walkTokens(s.items,t));break;default:{const o=r;this.defaults.extensions?.childTokens?.[o.type]?this.defaults.extensions.childTokens[o.type].forEach(e=>{e=o[e].flat(1/0);n=n.concat(this.walkTokens(e,t))}):o.tokens&&(n=n.concat(this.walkTokens(o.tokens,t)))}}return n}use(...e){const w=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(e=>{const t={...e};if(t.async=this.defaults.async||t.async||!1,e.extensions&&(e.extensions.forEach(n=>{if(!n.name)throw new Error("extension name required");if("renderer"in n){const s=w.renderers[n.name];s?w.renderers[n.name]=function(...e){let t=n.renderer.apply(this,e);return t=!1===t?s.apply(this,e):t}:w.renderers[n.name]=n.renderer}if("tokenizer"in n){if(!n.level||"block"!==n.level&&"inline"!==n.level)throw new Error("extension level must be 'block' or 'inline'");const e=w[n.level];e?e.unshift(n.tokenizer):w[n.level]=[n.tokenizer],n.start&&("block"===n.level?w.startBlock?w.startBlock.push(n.start):w.startBlock=[n.start]:"inline"===n.level&&(w.startInline?w.startInline.push(n.start):w.startInline=[n.start]))}"childTokens"in n&&n.childTokens&&(w.childTokens[n.name]=n.childTokens)}),t.extensions=w),e.renderer){const i=this.defaults.renderer||new I(this.defaults);for(const l in e.renderer){if(!(l in i))throw new Error(`renderer '${l}' does not exist`);if(!["options","parser"].includes(l)){var n=l;const a=e.renderer[n],o=i[n];i[n]=(...e)=>{let t=a.apply(i,e);return(t=!1===t?o.apply(i,e):t)||""}}}t.renderer=i}if(e.tokenizer){const c=this.defaults.tokenizer||new m(this.defaults);for(const h in e.tokenizer){if(!(h in c))throw new Error(`tokenizer '${h}' does not exist`);if(!["options","rules","lexer"].includes(h)){var s=h;const p=e.tokenizer[s],u=c[s];c[s]=(...e)=>{let t=p.apply(c,e);return t=!1===t?u.apply(c,e):t}}}t.tokenizer=c}if(e.hooks){const g=this.defaults.hooks||new Z;for(const k in e.hooks){if(!(k in g))throw new Error(`hook '${k}' does not exist`);if("options"!==k){var r=k;const f=e.hooks[r],d=g[r];Z.passThroughHooks.has(k)?g[r]=e=>{if(this.defaults.async)return Promise.resolve(f.call(g,e)).then(e=>d.call(g,e));e=f.call(g,e);return d.call(g,e)}:g[r]=(...e)=>{let t=f.apply(g,e);return t=!1===t?d.apply(g,e):t}}}t.hooks=g}if(e.walkTokens){const x=this.defaults.walkTokens,b=e.walkTokens;t.walkTokens=function(e){let t=[];return t.push(b.call(this,e)),t=x?t.concat(x.call(this,e)):t}}this.defaults={...this.defaults,...t}}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return S.lex(e,t??this.defaults)}parser(e,t){return q.parse(e,t??this.defaults)}parseMarkdown(r,i){return(n,e)=>{e={...e};const s={...this.defaults,...e},t=this.onError(!!s.silent,!!s.async);if(!0===this.defaults.async&&!1===e.async)return t(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(null==n)return t(new Error("marked(): input parameter is undefined or null"));if("string"!=typeof n)return t(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(n)+", string expected"));if(s.hooks&&(s.hooks.options=s),s.async)return Promise.resolve(s.hooks?s.hooks.preprocess(n):n).then(e=>r(e,s)).then(e=>s.hooks?s.hooks.processAllTokens(e):e).then(e=>s.walkTokens?Promise.all(this.walkTokens(e,s.walkTokens)).then(()=>e):e).then(e=>i(e,s)).then(e=>s.hooks?s.hooks.postprocess(e):e).catch(t);try{s.hooks&&(n=s.hooks.preprocess(n));let e=r(n,s),t=(s.hooks&&(e=s.hooks.processAllTokens(e)),s.walkTokens&&this.walkTokens(e,s.walkTokens),i(e,s));return t=s.hooks?s.hooks.postprocess(t):t}catch(e){return t(e)}}}onError(n,s){return e=>{var t;if(e.message+="\nPlease report this to https://github.com/markedjs/marked.",n)return t="<p>An error occurred:</p><pre>"+l(e.message+"",!0)+"</pre>",s?Promise.resolve(t):t;if(s)return Promise.reject(e);throw e}}}const P=new H;function L(e,t){return P.parse(e,t)}L.options=L.setOptions=function(e){return P.setOptions(e),t(L.defaults=P.defaults),L},L.getDefaults=e,L.defaults=n.defaults,L.use=function(...e){return P.use(...e),t(L.defaults=P.defaults),L},L.walkTokens=function(e,t){return P.walkTokens(e,t)},L.parseInline=P.parseInline,L.Parser=q,L.parser=q.parse,L.Renderer=I,L.TextRenderer=E,L.Lexer=S,L.lexer=S.lex,L.Tokenizer=m,L.Hooks=Z;z=(L.parse=L).options,T=L.setOptions,p=L.use,R=L.walkTokens,d=L.parseInline,w=L,c=q.parse,v=S.lex;n.Hooks=Z,n.Lexer=S,n.Marked=H,n.Parser=q,n.Renderer=I,n.TextRenderer=E,n.Tokenizer=m,n.getDefaults=e,n.lexer=v,n.marked=L,n.options=z,n.parse=w,n.parseInline=d,n.parser=c,n.setOptions=T,n.use=p,n.walkTokens=R});
\ No newline at end of file
public/scripts/marked.js new
+2506
@@ -0,0 +1,2506 @@
1 +/**
2 + * marked v14.0.0 - a markdown parser
3 + * Copyright (c) 2011-2024, Christopher Jeffrey. (MIT Licensed)
4 + * https://github.com/markedjs/marked
5 + */
6 +
7 +/**
8 + * DO NOT EDIT THIS FILE
9 + * The code in this file is generated from files in ./src/
10 + */
11 +
12 +(function (global, factory) {
13 + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
14 + typeof define === 'function' && define.amd ? define(['exports'], factory) :
15 + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.marked = {}));
16 +})(this, (function (exports) { 'use strict';
17 +
18 + /**
19 + * Gets the original marked default options.
20 + */
21 + function _getDefaults() {
22 + return {
23 + async: false,
24 + breaks: false,
25 + extensions: null,
26 + gfm: true,
27 + hooks: null,
28 + pedantic: false,
29 + renderer: null,
30 + silent: false,
31 + tokenizer: null,
32 + walkTokens: null,
33 + };
34 + }
35 + exports.defaults = _getDefaults();
36 + function changeDefaults(newDefaults) {
37 + exports.defaults = newDefaults;
38 + }
39 +
40 + /**
41 + * Helpers
42 + */
43 + const escapeTest = /[&<>"']/;
44 + const escapeReplace = new RegExp(escapeTest.source, 'g');
45 + const escapeTestNoEncode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/;
46 + const escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, 'g');
47 + const escapeReplacements = {
48 + '&': '&amp;',
49 + '<': '&lt;',
50 + '>': '&gt;',
51 + '"': '&quot;',
52 + "'": '&#39;',
53 + };
54 + const getEscapeReplacement = (ch) => escapeReplacements[ch];
55 + function escape$1(html, encode) {
56 + if (encode) {
57 + if (escapeTest.test(html)) {
58 + return html.replace(escapeReplace, getEscapeReplacement);
59 + }
60 + }
61 + else {
62 + if (escapeTestNoEncode.test(html)) {
63 + return html.replace(escapeReplaceNoEncode, getEscapeReplacement);
64 + }
65 + }
66 + return html;
67 + }
68 + const caret = /(^|[^\[])\^/g;
69 + function edit(regex, opt) {
70 + let source = typeof regex === 'string' ? regex : regex.source;
71 + opt = opt || '';
72 + const obj = {
73 + replace: (name, val) => {
74 + let valSource = typeof val === 'string' ? val : val.source;
75 + valSource = valSource.replace(caret, '$1');
76 + source = source.replace(name, valSource);
77 + return obj;
78 + },
79 + getRegex: () => {
80 + return new RegExp(source, opt);
81 + },
82 + };
83 + return obj;
84 + }
85 + function cleanUrl(href) {
86 + try {
87 + href = encodeURI(href).replace(/%25/g, '%');
88 + }
89 + catch {
90 + return null;
91 + }
92 + return href;
93 + }
94 + const noopTest = { exec: () => null };
95 + function splitCells(tableRow, count) {
96 + // ensure that every cell-delimiting pipe has a space
97 + // before it to distinguish it from an escaped pipe
98 + const row = tableRow.replace(/\|/g, (match, offset, str) => {
99 + let escaped = false;
100 + let curr = offset;
101 + while (--curr >= 0 && str[curr] === '\\')
102 + escaped = !escaped;
103 + if (escaped) {
104 + // odd number of slashes means | is escaped
105 + // so we leave it alone
106 + return '|';
107 + }
108 + else {
109 + // add space before unescaped |
110 + return ' |';
111 + }
112 + }), cells = row.split(/ \|/);
113 + let i = 0;
114 + // First/last cell in a row cannot be empty if it has no leading/trailing pipe
115 + if (!cells[0].trim()) {
116 + cells.shift();
117 + }
118 + if (cells.length > 0 && !cells[cells.length - 1].trim()) {
119 + cells.pop();
120 + }
121 + if (count) {
122 + if (cells.length > count) {
123 + cells.splice(count);
124 + }
125 + else {
126 + while (cells.length < count)
127 + cells.push('');
128 + }
129 + }
130 + for (; i < cells.length; i++) {
131 + // leading or trailing whitespace is ignored per the gfm spec
132 + cells[i] = cells[i].trim().replace(/\\\|/g, '|');
133 + }
134 + return cells;
135 + }
136 + /**
137 + * Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
138 + * /c*$/ is vulnerable to REDOS.
139 + *
140 + * @param str
141 + * @param c
142 + * @param invert Remove suffix of non-c chars instead. Default falsey.
143 + */
144 + function rtrim(str, c, invert) {
145 + const l = str.length;
146 + if (l === 0) {
147 + return '';
148 + }
149 + // Length of suffix matching the invert condition.
150 + let suffLen = 0;
151 + // Step left until we fail to match the invert condition.
152 + while (suffLen < l) {
153 + const currChar = str.charAt(l - suffLen - 1);
154 + if (currChar === c && !invert) {
155 + suffLen++;
156 + }
157 + else if (currChar !== c && invert) {
158 + suffLen++;
159 + }
160 + else {
161 + break;
162 + }
163 + }
164 + return str.slice(0, l - suffLen);
165 + }
166 + function findClosingBracket(str, b) {
167 + if (str.indexOf(b[1]) === -1) {
168 + return -1;
169 + }
170 + let level = 0;
171 + for (let i = 0; i < str.length; i++) {
172 + if (str[i] === '\\') {
173 + i++;
174 + }
175 + else if (str[i] === b[0]) {
176 + level++;
177 + }
178 + else if (str[i] === b[1]) {
179 + level--;
180 + if (level < 0) {
181 + return i;
182 + }
183 + }
184 + }
185 + return -1;
186 + }
187 +
188 + function outputLink(cap, link, raw, lexer) {
189 + const href = link.href;
190 + const title = link.title ? escape$1(link.title) : null;
191 + const text = cap[1].replace(/\\([\[\]])/g, '$1');
192 + if (cap[0].charAt(0) !== '!') {
193 + lexer.state.inLink = true;
194 + const token = {
195 + type: 'link',
196 + raw,
197 + href,
198 + title,
199 + text,
200 + tokens: lexer.inlineTokens(text),
201 + };
202 + lexer.state.inLink = false;
203 + return token;
204 + }
205 + return {
206 + type: 'image',
207 + raw,
208 + href,
209 + title,
210 + text: escape$1(text),
211 + };
212 + }
213 + function indentCodeCompensation(raw, text) {
214 + const matchIndentToCode = raw.match(/^(\s+)(?:```)/);
215 + if (matchIndentToCode === null) {
216 + return text;
217 + }
218 + const indentToCode = matchIndentToCode[1];
219 + return text
220 + .split('\n')
221 + .map(node => {
222 + const matchIndentInNode = node.match(/^\s+/);
223 + if (matchIndentInNode === null) {
224 + return node;
225 + }
226 + const [indentInNode] = matchIndentInNode;
227 + if (indentInNode.length >= indentToCode.length) {
228 + return node.slice(indentToCode.length);
229 + }
230 + return node;
231 + })
232 + .join('\n');
233 + }
234 + /**
235 + * Tokenizer
236 + */
237 + class _Tokenizer {
238 + options;
239 + rules; // set by the lexer
240 + lexer; // set by the lexer
241 + constructor(options) {
242 + this.options = options || exports.defaults;
243 + }
244 + space(src) {
245 + const cap = this.rules.block.newline.exec(src);
246 + if (cap && cap[0].length > 0) {
247 + return {
248 + type: 'space',
249 + raw: cap[0],
250 + };
251 + }
252 + }
253 + code(src) {
254 + const cap = this.rules.block.code.exec(src);
255 + if (cap) {
256 + const text = cap[0].replace(/^ {1,4}/gm, '');
257 + return {
258 + type: 'code',
259 + raw: cap[0],
260 + codeBlockStyle: 'indented',
261 + text: !this.options.pedantic
262 + ? rtrim(text, '\n')
263 + : text,
264 + };
265 + }
266 + }
267 + fences(src) {
268 + const cap = this.rules.block.fences.exec(src);
269 + if (cap) {
270 + const raw = cap[0];
271 + const text = indentCodeCompensation(raw, cap[3] || '');
272 + return {
273 + type: 'code',
274 + raw,
275 + lang: cap[2] ? cap[2].trim().replace(this.rules.inline.anyPunctuation, '$1') : cap[2],
276 + text,
277 + };
278 + }
279 + }
280 + heading(src) {
281 + const cap = this.rules.block.heading.exec(src);
282 + if (cap) {
283 + let text = cap[2].trim();
284 + // remove trailing #s
285 + if (/#$/.test(text)) {
286 + const trimmed = rtrim(text, '#');
287 + if (this.options.pedantic) {
288 + text = trimmed.trim();
289 + }
290 + else if (!trimmed || / $/.test(trimmed)) {
291 + // CommonMark requires space before trailing #s
292 + text = trimmed.trim();
293 + }
294 + }
295 + return {
296 + type: 'heading',
297 + raw: cap[0],
298 + depth: cap[1].length,
299 + text,
300 + tokens: this.lexer.inline(text),
301 + };
302 + }
303 + }
304 + hr(src) {
305 + const cap = this.rules.block.hr.exec(src);
306 + if (cap) {
307 + return {
308 + type: 'hr',
309 + raw: rtrim(cap[0], '\n'),
310 + };
311 + }
312 + }
313 + blockquote(src) {
314 + const cap = this.rules.block.blockquote.exec(src);
315 + if (cap) {
316 + let lines = rtrim(cap[0], '\n').split('\n');
317 + let raw = '';
318 + let text = '';
319 + const tokens = [];
320 + while (lines.length > 0) {
321 + let inBlockquote = false;
322 + const currentLines = [];
323 + let i;
324 + for (i = 0; i < lines.length; i++) {
325 + // get lines up to a continuation
326 + if (/^ {0,3}>/.test(lines[i])) {
327 + currentLines.push(lines[i]);
328 + inBlockquote = true;
329 + }
330 + else if (!inBlockquote) {
331 + currentLines.push(lines[i]);
332 + }
333 + else {
334 + break;
335 + }
336 + }
337 + lines = lines.slice(i);
338 + const currentRaw = currentLines.join('\n');
339 + const currentText = currentRaw
340 + // precede setext continuation with 4 spaces so it isn't a setext
341 + .replace(/\n {0,3}((?:=+|-+) *)(?=\n|$)/g, '\n $1')
342 + .replace(/^ {0,3}>[ \t]?/gm, '');
343 + raw = raw ? `${raw}\n${currentRaw}` : currentRaw;
344 + text = text ? `${text}\n${currentText}` : currentText;
345 + // parse blockquote lines as top level tokens
346 + // merge paragraphs if this is a continuation
347 + const top = this.lexer.state.top;
348 + this.lexer.state.top = true;
349 + this.lexer.blockTokens(currentText, tokens, true);
350 + this.lexer.state.top = top;
351 + // if there is no continuation then we are done
352 + if (lines.length === 0) {
353 + break;
354 + }
355 + const lastToken = tokens[tokens.length - 1];
356 + if (lastToken?.type === 'code') {
357 + // blockquote continuation cannot be preceded by a code block
358 + break;
359 + }
360 + else if (lastToken?.type === 'blockquote') {
361 + // include continuation in nested blockquote
362 + const oldToken = lastToken;
363 + const newText = oldToken.raw + '\n' + lines.join('\n');
364 + const newToken = this.blockquote(newText);
365 + tokens[tokens.length - 1] = newToken;
366 + raw = raw.substring(0, raw.length - oldToken.raw.length) + newToken.raw;
367 + text = text.substring(0, text.length - oldToken.text.length) + newToken.text;
368 + break;
369 + }
370 + else if (lastToken?.type === 'list') {
371 + // include continuation in nested list
372 + const oldToken = lastToken;
373 + const newText = oldToken.raw + '\n' + lines.join('\n');
374 + const newToken = this.list(newText);
375 + tokens[tokens.length - 1] = newToken;
376 + raw = raw.substring(0, raw.length - lastToken.raw.length) + newToken.raw;
377 + text = text.substring(0, text.length - oldToken.raw.length) + newToken.raw;
378 + lines = newText.substring(tokens[tokens.length - 1].raw.length).split('\n');
379 + continue;
380 + }
381 + }
382 + return {
383 + type: 'blockquote',
384 + raw,
385 + tokens,
386 + text,
387 + };
388 + }
389 + }
390 + list(src) {
391 + let cap = this.rules.block.list.exec(src);
392 + if (cap) {
393 + let bull = cap[1].trim();
394 + const isordered = bull.length > 1;
395 + const list = {
396 + type: 'list',
397 + raw: '',
398 + ordered: isordered,
399 + start: isordered ? +bull.slice(0, -1) : '',
400 + loose: false,
401 + items: [],
402 + };
403 + bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`;
404 + if (this.options.pedantic) {
405 + bull = isordered ? bull : '[*+-]';
406 + }
407 + // Get next list item
408 + const itemRegex = new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`);
409 + let endsWithBlankLine = false;
410 + // Check if current bullet point can start a new List Item
411 + while (src) {
412 + let endEarly = false;
413 + let raw = '';
414 + let itemContents = '';
415 + if (!(cap = itemRegex.exec(src))) {
416 + break;
417 + }
418 + if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?)
419 + break;
420 + }
421 + raw = cap[0];
422 + src = src.substring(raw.length);
423 + let line = cap[2].split('\n', 1)[0].replace(/^\t+/, (t) => ' '.repeat(3 * t.length));
424 + let nextLine = src.split('\n', 1)[0];
425 + let blankLine = !line.trim();
426 + let indent = 0;
427 + if (this.options.pedantic) {
428 + indent = 2;
429 + itemContents = line.trimStart();
430 + }
431 + else if (blankLine) {
432 + indent = cap[1].length + 1;
433 + }
434 + else {
435 + indent = cap[2].search(/[^ ]/); // Find first non-space char
436 + indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent
437 + itemContents = line.slice(indent);
438 + indent += cap[1].length;
439 + }
440 + if (blankLine && /^ *$/.test(nextLine)) { // Items begin with at most one blank line
441 + raw += nextLine + '\n';
442 + src = src.substring(nextLine.length + 1);
443 + endEarly = true;
444 + }
445 + if (!endEarly) {
446 + const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`);
447 + const hrRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`);
448 + const fencesBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`);
449 + const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`);
450 + // Check if following lines should be included in List Item
451 + while (src) {
452 + const rawLine = src.split('\n', 1)[0];
453 + nextLine = rawLine;
454 + // Re-align to follow commonmark nesting rules
455 + if (this.options.pedantic) {
456 + nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' ');
457 + }
458 + // End list item if found code fences
459 + if (fencesBeginRegex.test(nextLine)) {
460 + break;
461 + }
462 + // End list item if found start of new heading
463 + if (headingBeginRegex.test(nextLine)) {
464 + break;
465 + }
466 + // End list item if found start of new bullet
467 + if (nextBulletRegex.test(nextLine)) {
468 + break;
469 + }
470 + // Horizontal rule found
471 + if (hrRegex.test(src)) {
472 + break;
473 + }
474 + if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) { // Dedent if possible
475 + itemContents += '\n' + nextLine.slice(indent);
476 + }
477 + else {
478 + // not enough indentation
479 + if (blankLine) {
480 + break;
481 + }
482 + // paragraph continuation unless last line was a different block level element
483 + if (line.search(/[^ ]/) >= 4) { // indented code block
484 + break;
485 + }
486 + if (fencesBeginRegex.test(line)) {
487 + break;
488 + }
489 + if (headingBeginRegex.test(line)) {
490 + break;
491 + }
492 + if (hrRegex.test(line)) {
493 + break;
494 + }
495 + itemContents += '\n' + nextLine;
496 + }
497 + if (!blankLine && !nextLine.trim()) { // Check if current line is blank
498 + blankLine = true;
499 + }
500 + raw += rawLine + '\n';
501 + src = src.substring(rawLine.length + 1);
502 + line = nextLine.slice(indent);
503 + }
504 + }
505 + if (!list.loose) {
506 + // If the previous item ended with a blank line, the list is loose
507 + if (endsWithBlankLine) {
508 + list.loose = true;
509 + }
510 + else if (/\n *\n *$/.test(raw)) {
511 + endsWithBlankLine = true;
512 + }
513 + }
514 + let istask = null;
515 + let ischecked;
516 + // Check for task list items
517 + if (this.options.gfm) {
518 + istask = /^\[[ xX]\] /.exec(itemContents);
519 + if (istask) {
520 + ischecked = istask[0] !== '[ ] ';
521 + itemContents = itemContents.replace(/^\[[ xX]\] +/, '');
522 + }
523 + }
524 + list.items.push({
525 + type: 'list_item',
526 + raw,
527 + task: !!istask,
528 + checked: ischecked,
529 + loose: false,
530 + text: itemContents,
531 + tokens: [],
532 + });
533 + list.raw += raw;
534 + }
535 + // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
536 + list.items[list.items.length - 1].raw = list.items[list.items.length - 1].raw.trimEnd();
537 + list.items[list.items.length - 1].text = list.items[list.items.length - 1].text.trimEnd();
538 + list.raw = list.raw.trimEnd();
539 + // Item child tokens handled here at end because we needed to have the final item to trim it first
540 + for (let i = 0; i < list.items.length; i++) {
541 + this.lexer.state.top = false;
542 + list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
543 + if (!list.loose) {
544 + // Check if list should be loose
545 + const spacers = list.items[i].tokens.filter(t => t.type === 'space');
546 + const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => /\n.*\n/.test(t.raw));
547 + list.loose = hasMultipleLineBreaks;
548 + }
549 + }
550 + // Set all items to loose if list is loose
551 + if (list.loose) {
552 + for (let i = 0; i < list.items.length; i++) {
553 + list.items[i].loose = true;
554 + }
555 + }
556 + return list;
557 + }
558 + }
559 + html(src) {
560 + const cap = this.rules.block.html.exec(src);
561 + if (cap) {
562 + const token = {
563 + type: 'html',
564 + block: true,
565 + raw: cap[0],
566 + pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',
567 + text: cap[0],
568 + };
569 + return token;
570 + }
571 + }
572 + def(src) {
573 + const cap = this.rules.block.def.exec(src);
574 + if (cap) {
575 + const tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
576 + const href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline.anyPunctuation, '$1') : '';
577 + const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline.anyPunctuation, '$1') : cap[3];
578 + return {
579 + type: 'def',
580 + tag,
581 + raw: cap[0],
582 + href,
583 + title,
584 + };
585 + }
586 + }
587 + table(src) {
588 + const cap = this.rules.block.table.exec(src);
589 + if (!cap) {
590 + return;
591 + }
592 + if (!/[:|]/.test(cap[2])) {
593 + // delimiter row must have a pipe (|) or colon (:) otherwise it is a setext heading
594 + return;
595 + }
596 + const headers = splitCells(cap[1]);
597 + const aligns = cap[2].replace(/^\||\| *$/g, '').split('|');
598 + const rows = cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : [];
599 + const item = {
600 + type: 'table',
601 + raw: cap[0],
602 + header: [],
603 + align: [],
604 + rows: [],
605 + };
606 + if (headers.length !== aligns.length) {
607 + // header and align columns must be equal, rows can be different.
608 + return;
609 + }
610 + for (const align of aligns) {
611 + if (/^ *-+: *$/.test(align)) {
612 + item.align.push('right');
613 + }
614 + else if (/^ *:-+: *$/.test(align)) {
615 + item.align.push('center');
616 + }
617 + else if (/^ *:-+ *$/.test(align)) {
618 + item.align.push('left');
619 + }
620 + else {
621 + item.align.push(null);
622 + }
623 + }
624 + for (let i = 0; i < headers.length; i++) {
625 + item.header.push({
626 + text: headers[i],
627 + tokens: this.lexer.inline(headers[i]),
628 + header: true,
629 + align: item.align[i],
630 + });
631 + }
632 + for (const row of rows) {
633 + item.rows.push(splitCells(row, item.header.length).map((cell, i) => {
634 + return {
635 + text: cell,
636 + tokens: this.lexer.inline(cell),
637 + header: false,
638 + align: item.align[i],
639 + };
640 + }));
641 + }
642 + return item;
643 + }
644 + lheading(src) {
645 + const cap = this.rules.block.lheading.exec(src);
646 + if (cap) {
647 + return {
648 + type: 'heading',
649 + raw: cap[0],
650 + depth: cap[2].charAt(0) === '=' ? 1 : 2,
651 + text: cap[1],
652 + tokens: this.lexer.inline(cap[1]),
653 + };
654 + }
655 + }
656 + paragraph(src) {
657 + const cap = this.rules.block.paragraph.exec(src);
658 + if (cap) {
659 + const text = cap[1].charAt(cap[1].length - 1) === '\n'
660 + ? cap[1].slice(0, -1)
661 + : cap[1];
662 + return {
663 + type: 'paragraph',
664 + raw: cap[0],
665 + text,
666 + tokens: this.lexer.inline(text),
667 + };
668 + }
669 + }
670 + text(src) {
671 + const cap = this.rules.block.text.exec(src);
672 + if (cap) {
673 + return {
674 + type: 'text',
675 + raw: cap[0],
676 + text: cap[0],
677 + tokens: this.lexer.inline(cap[0]),
678 + };
679 + }
680 + }
681 + escape(src) {
682 + const cap = this.rules.inline.escape.exec(src);
683 + if (cap) {
684 + return {
685 + type: 'escape',
686 + raw: cap[0],
687 + text: escape$1(cap[1]),
688 + };
689 + }
690 + }
691 + tag(src) {
692 + const cap = this.rules.inline.tag.exec(src);
693 + if (cap) {
694 + if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {
695 + this.lexer.state.inLink = true;
696 + }
697 + else if (this.lexer.state.inLink && /^<\/a>/i.test(cap[0])) {
698 + this.lexer.state.inLink = false;
699 + }
700 + if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
701 + this.lexer.state.inRawBlock = true;
702 + }
703 + else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
704 + this.lexer.state.inRawBlock = false;
705 + }
706 + return {
707 + type: 'html',
708 + raw: cap[0],
709 + inLink: this.lexer.state.inLink,
710 + inRawBlock: this.lexer.state.inRawBlock,
711 + block: false,
712 + text: cap[0],
713 + };
714 + }
715 + }
716 + link(src) {
717 + const cap = this.rules.inline.link.exec(src);
718 + if (cap) {
719 + const trimmedUrl = cap[2].trim();
720 + if (!this.options.pedantic && /^</.test(trimmedUrl)) {
721 + // commonmark requires matching angle brackets
722 + if (!(/>$/.test(trimmedUrl))) {
723 + return;
724 + }
725 + // ending angle bracket cannot be escaped
726 + const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\');
727 + if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
728 + return;
729 + }
730 + }
731 + else {
732 + // find closing parenthesis
733 + const lastParenIndex = findClosingBracket(cap[2], '()');
734 + if (lastParenIndex > -1) {
735 + const start = cap[0].indexOf('!') === 0 ? 5 : 4;
736 + const linkLen = start + cap[1].length + lastParenIndex;
737 + cap[2] = cap[2].substring(0, lastParenIndex);
738 + cap[0] = cap[0].substring(0, linkLen).trim();
739 + cap[3] = '';
740 + }
741 + }
742 + let href = cap[2];
743 + let title = '';
744 + if (this.options.pedantic) {
745 + // split pedantic href and title
746 + const link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
747 + if (link) {
748 + href = link[1];
749 + title = link[3];
750 + }
751 + }
752 + else {
753 + title = cap[3] ? cap[3].slice(1, -1) : '';
754 + }
755 + href = href.trim();
756 + if (/^</.test(href)) {
757 + if (this.options.pedantic && !(/>$/.test(trimmedUrl))) {
758 + // pedantic allows starting angle bracket without ending angle bracket
759 + href = href.slice(1);
760 + }
761 + else {
762 + href = href.slice(1, -1);
763 + }
764 + }
765 + return outputLink(cap, {
766 + href: href ? href.replace(this.rules.inline.anyPunctuation, '$1') : href,
767 + title: title ? title.replace(this.rules.inline.anyPunctuation, '$1') : title,
768 + }, cap[0], this.lexer);
769 + }
770 + }
771 + reflink(src, links) {
772 + let cap;
773 + if ((cap = this.rules.inline.reflink.exec(src))
774 + || (cap = this.rules.inline.nolink.exec(src))) {
775 + const linkString = (cap[2] || cap[1]).replace(/\s+/g, ' ');
776 + const link = links[linkString.toLowerCase()];
777 + if (!link) {
778 + const text = cap[0].charAt(0);
779 + return {
780 + type: 'text',
781 + raw: text,
782 + text,
783 + };
784 + }
785 + return outputLink(cap, link, cap[0], this.lexer);
786 + }
787 + }
788 + emStrong(src, maskedSrc, prevChar = '') {
789 + let match = this.rules.inline.emStrongLDelim.exec(src);
790 + if (!match)
791 + return;
792 + // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
793 + if (match[3] && prevChar.match(/[\p{L}\p{N}]/u))
794 + return;
795 + const nextChar = match[1] || match[2] || '';
796 + if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {
797 + // unicode Regex counts emoji as 1 char; spread into array for proper count (used multiple times below)
798 + const lLength = [...match[0]].length - 1;
799 + let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
800 + const endReg = match[0][0] === '*' ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
801 + endReg.lastIndex = 0;
802 + // Clip maskedSrc to same section of string as src (move to lexer?)
803 + maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
804 + while ((match = endReg.exec(maskedSrc)) != null) {
805 + rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
806 + if (!rDelim)
807 + continue; // skip single * in __abc*abc__
808 + rLength = [...rDelim].length;
809 + if (match[3] || match[4]) { // found another Left Delim
810 + delimTotal += rLength;
811 + continue;
812 + }
813 + else if (match[5] || match[6]) { // either Left or Right Delim
814 + if (lLength % 3 && !((lLength + rLength) % 3)) {
815 + midDelimTotal += rLength;
816 + continue; // CommonMark Emphasis Rules 9-10
817 + }
818 + }
819 + delimTotal -= rLength;
820 + if (delimTotal > 0)
821 + continue; // Haven't found enough closing delimiters
822 + // Remove extra characters. *a*** -> *a*
823 + rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
824 + // char length can be >1 for unicode characters;
825 + const lastCharLength = [...match[0]][0].length;
826 + const raw = src.slice(0, lLength + match.index + lastCharLength + rLength);
827 + // Create `em` if smallest delimiter has odd char count. *a***
828 + if (Math.min(lLength, rLength) % 2) {
829 + const text = raw.slice(1, -1);
830 + return {
831 + type: 'em',
832 + raw,
833 + text,
834 + tokens: this.lexer.inlineTokens(text),
835 + };
836 + }
837 + // Create 'strong' if smallest delimiter has even char count. **a***
838 + const text = raw.slice(2, -2);
839 + return {
840 + type: 'strong',
841 + raw,
842 + text,
843 + tokens: this.lexer.inlineTokens(text),
844 + };
845 + }
846 + }
847 + }
848 + codespan(src) {
849 + const cap = this.rules.inline.code.exec(src);
850 + if (cap) {
851 + let text = cap[2].replace(/\n/g, ' ');
852 + const hasNonSpaceChars = /[^ ]/.test(text);
853 + const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);
854 + if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
855 + text = text.substring(1, text.length - 1);
856 + }
857 + text = escape$1(text, true);
858 + return {
859 + type: 'codespan',
860 + raw: cap[0],
861 + text,
862 + };
863 + }
864 + }
865 + br(src) {
866 + const cap = this.rules.inline.br.exec(src);
867 + if (cap) {
868 + return {
869 + type: 'br',
870 + raw: cap[0],
871 + };
872 + }
873 + }
874 + del(src) {
875 + const cap = this.rules.inline.del.exec(src);
876 + if (cap) {
877 + return {
878 + type: 'del',
879 + raw: cap[0],
880 + text: cap[2],
881 + tokens: this.lexer.inlineTokens(cap[2]),
882 + };
883 + }
884 + }
885 + autolink(src) {
886 + const cap = this.rules.inline.autolink.exec(src);
887 + if (cap) {
888 + let text, href;
889 + if (cap[2] === '@') {
890 + text = escape$1(cap[1]);
891 + href = 'mailto:' + text;
892 + }
893 + else {
894 + text = escape$1(cap[1]);
895 + href = text;
896 + }
897 + return {
898 + type: 'link',
899 + raw: cap[0],
900 + text,
901 + href,
902 + tokens: [
903 + {
904 + type: 'text',
905 + raw: text,
906 + text,
907 + },
908 + ],
909 + };
910 + }
911 + }
912 + url(src) {
913 + let cap;
914 + if (cap = this.rules.inline.url.exec(src)) {
915 + let text, href;
916 + if (cap[2] === '@') {
917 + text = escape$1(cap[0]);
918 + href = 'mailto:' + text;
919 + }
920 + else {
921 + // do extended autolink path validation
922 + let prevCapZero;
923 + do {
924 + prevCapZero = cap[0];
925 + cap[0] = this.rules.inline._backpedal.exec(cap[0])?.[0] ?? '';
926 + } while (prevCapZero !== cap[0]);
927 + text = escape$1(cap[0]);
928 + if (cap[1] === 'www.') {
929 + href = 'http://' + cap[0];
930 + }
931 + else {
932 + href = cap[0];
933 + }
934 + }
935 + return {
936 + type: 'link',
937 + raw: cap[0],
938 + text,
939 + href,
940 + tokens: [
941 + {
942 + type: 'text',
943 + raw: text,
944 + text,
945 + },
946 + ],
947 + };
948 + }
949 + }
950 + inlineText(src) {
951 + const cap = this.rules.inline.text.exec(src);
952 + if (cap) {
953 + let text;
954 + if (this.lexer.state.inRawBlock) {
955 + text = cap[0];
956 + }
957 + else {
958 + text = escape$1(cap[0]);
959 + }
960 + return {
961 + type: 'text',
962 + raw: cap[0],
963 + text,
964 + };
965 + }
966 + }
967 + }
968 +
969 + /**
970 + * Block-Level Grammar
971 + */
972 + const newline = /^(?: *(?:\n|$))+/;
973 + const blockCode = /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/;
974 + const fences = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
975 + const hr = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
976 + const heading = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
977 + const bullet = /(?:[*+-]|\d{1,9}[.)])/;
978 + const lheading = edit(/^(?!bull |blockCode|fences|blockquote|heading|html)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html))+?)\n {0,3}(=+|-+) *(?:\n+|$)/)
979 + .replace(/bull/g, bullet) // lists can interrupt
980 + .replace(/blockCode/g, / {4}/) // indented code blocks can interrupt
981 + .replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/) // fenced code blocks can interrupt
982 + .replace(/blockquote/g, / {0,3}>/) // blockquote can interrupt
983 + .replace(/heading/g, / {0,3}#{1,6}/) // ATX heading can interrupt
984 + .replace(/html/g, / {0,3}<[^\n>]+>\n/) // block html can interrupt
985 + .getRegex();
986 + const _paragraph = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
987 + const blockText = /^[^\n]+/;
988 + const _blockLabel = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
989 + const def = edit(/^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/)
990 + .replace('label', _blockLabel)
991 + .replace('title', /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/)
992 + .getRegex();
993 + const list = edit(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/)
994 + .replace(/bull/g, bullet)
995 + .getRegex();
996 + const _tag = 'address|article|aside|base|basefont|blockquote|body|caption'
997 + + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'
998 + + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'
999 + + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'
1000 + + '|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title'
1001 + + '|tr|track|ul';
1002 + const _comment = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
1003 + const html = edit('^ {0,3}(?:' // optional indentation
1004 + + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
1005 + + '|comment[^\\n]*(\\n+|$)' // (2)
1006 + + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
1007 + + '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
1008 + + '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
1009 + + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6)
1010 + + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag
1011 + + '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag
1012 + + ')', 'i')
1013 + .replace('comment', _comment)
1014 + .replace('tag', _tag)
1015 + .replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
1016 + .getRegex();
1017 + const paragraph = edit(_paragraph)
1018 + .replace('hr', hr)
1019 + .replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
1020 + .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs
1021 + .replace('|table', '')
1022 + .replace('blockquote', ' {0,3}>')
1023 + .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
1024 + .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
1025 + .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
1026 + .replace('tag', _tag) // pars can be interrupted by type (6) html blocks
1027 + .getRegex();
1028 + const blockquote = edit(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/)
1029 + .replace('paragraph', paragraph)
1030 + .getRegex();
1031 + /**
1032 + * Normal Block Grammar
1033 + */
1034 + const blockNormal = {
1035 + blockquote,
1036 + code: blockCode,
1037 + def,
1038 + fences,
1039 + heading,
1040 + hr,
1041 + html,
1042 + lheading,
1043 + list,
1044 + newline,
1045 + paragraph,
1046 + table: noopTest,
1047 + text: blockText,
1048 + };
1049 + /**
1050 + * GFM Block Grammar
1051 + */
1052 + const gfmTable = edit('^ *([^\\n ].*)\\n' // Header
1053 + + ' {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)' // Align
1054 + + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)') // Cells
1055 + .replace('hr', hr)
1056 + .replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
1057 + .replace('blockquote', ' {0,3}>')
1058 + .replace('code', ' {4}[^\\n]')
1059 + .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
1060 + .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
1061 + .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
1062 + .replace('tag', _tag) // tables can be interrupted by type (6) html blocks
1063 + .getRegex();
1064 + const blockGfm = {
1065 + ...blockNormal,
1066 + table: gfmTable,
1067 + paragraph: edit(_paragraph)
1068 + .replace('hr', hr)
1069 + .replace('heading', ' {0,3}#{1,6}(?:\\s|$)')
1070 + .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs
1071 + .replace('table', gfmTable) // interrupt paragraphs with table
1072 + .replace('blockquote', ' {0,3}>')
1073 + .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
1074 + .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
1075 + .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
1076 + .replace('tag', _tag) // pars can be interrupted by type (6) html blocks
1077 + .getRegex(),
1078 + };
1079 + /**
1080 + * Pedantic grammar (original John Gruber's loose markdown specification)
1081 + */
1082 + const blockPedantic = {
1083 + ...blockNormal,
1084 + html: edit('^ *(?:comment *(?:\\n|\\s*$)'
1085 + + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
1086 + + '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))')
1087 + .replace('comment', _comment)
1088 + .replace(/tag/g, '(?!(?:'
1089 + + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'
1090 + + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'
1091 + + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b')
1092 + .getRegex(),
1093 + def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
1094 + heading: /^(#{1,6})(.*)(?:\n+|$)/,
1095 + fences: noopTest, // fences not supported
1096 + lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
1097 + paragraph: edit(_paragraph)
1098 + .replace('hr', hr)
1099 + .replace('heading', ' *#{1,6} *[^\n]')
1100 + .replace('lheading', lheading)
1101 + .replace('|table', '')
1102 + .replace('blockquote', ' {0,3}>')
1103 + .replace('|fences', '')
1104 + .replace('|list', '')
1105 + .replace('|html', '')
1106 + .replace('|tag', '')
1107 + .getRegex(),
1108 + };
1109 + /**
1110 + * Inline-Level Grammar
1111 + */
1112 + const escape = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
1113 + const inlineCode = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
1114 + const br = /^( {2,}|\\)\n(?!\s*$)/;
1115 + const inlineText = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
1116 + // list of unicode punctuation marks, plus any missing characters from CommonMark spec
1117 + const _punctuation = '\\p{P}\\p{S}';
1118 + const punctuation = edit(/^((?![*_])[\spunctuation])/, 'u')
1119 + .replace(/punctuation/g, _punctuation).getRegex();
1120 + // sequences em should skip over [title](link), `code`, <html>
1121 + const blockSkip = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g;
1122 + const emStrongLDelim = edit(/^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/, 'u')
1123 + .replace(/punct/g, _punctuation)
1124 + .getRegex();
1125 + const emStrongRDelimAst = edit('^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)' // Skip orphan inside strong
1126 + + '|[^*]+(?=[^*])' // Consume to delim
1127 + + '|(?!\\*)[punct](\\*+)(?=[\\s]|$)' // (1) #*** can only be a Right Delimiter
1128 + + '|[^punct\\s](\\*+)(?!\\*)(?=[punct\\s]|$)' // (2) a***#, a*** can only be a Right Delimiter
1129 + + '|(?!\\*)[punct\\s](\\*+)(?=[^punct\\s])' // (3) #***a, ***a can only be Left Delimiter
1130 + + '|[\\s](\\*+)(?!\\*)(?=[punct])' // (4) ***# can only be Left Delimiter
1131 + + '|(?!\\*)[punct](\\*+)(?!\\*)(?=[punct])' // (5) #***# can be either Left or Right Delimiter
1132 + + '|[^punct\\s](\\*+)(?=[^punct\\s])', 'gu') // (6) a***a can be either Left or Right Delimiter
1133 + .replace(/punct/g, _punctuation)
1134 + .getRegex();
1135 + // (6) Not allowed for _
1136 + const emStrongRDelimUnd = edit('^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)' // Skip orphan inside strong
1137 + + '|[^_]+(?=[^_])' // Consume to delim
1138 + + '|(?!_)[punct](_+)(?=[\\s]|$)' // (1) #___ can only be a Right Delimiter
1139 + + '|[^punct\\s](_+)(?!_)(?=[punct\\s]|$)' // (2) a___#, a___ can only be a Right Delimiter
1140 + + '|(?!_)[punct\\s](_+)(?=[^punct\\s])' // (3) #___a, ___a can only be Left Delimiter
1141 + + '|[\\s](_+)(?!_)(?=[punct])' // (4) ___# can only be Left Delimiter
1142 + + '|(?!_)[punct](_+)(?!_)(?=[punct])', 'gu') // (5) #___# can be either Left or Right Delimiter
1143 + .replace(/punct/g, _punctuation)
1144 + .getRegex();
1145 + const anyPunctuation = edit(/\\([punct])/, 'gu')
1146 + .replace(/punct/g, _punctuation)
1147 + .getRegex();
1148 + const autolink = edit(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/)
1149 + .replace('scheme', /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/)
1150 + .replace('email', /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/)
1151 + .getRegex();
1152 + const _inlineComment = edit(_comment).replace('(?:-->|$)', '-->').getRegex();
1153 + const tag = edit('^comment'
1154 + + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
1155 + + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
1156 + + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
1157 + + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
1158 + + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>') // CDATA section
1159 + .replace('comment', _inlineComment)
1160 + .replace('attribute', /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/)
1161 + .getRegex();
1162 + const _inlineLabel = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
1163 + const link = edit(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/)
1164 + .replace('label', _inlineLabel)
1165 + .replace('href', /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/)
1166 + .replace('title', /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/)
1167 + .getRegex();
1168 + const reflink = edit(/^!?\[(label)\]\[(ref)\]/)
1169 + .replace('label', _inlineLabel)
1170 + .replace('ref', _blockLabel)
1171 + .getRegex();
1172 + const nolink = edit(/^!?\[(ref)\](?:\[\])?/)
1173 + .replace('ref', _blockLabel)
1174 + .getRegex();
1175 + const reflinkSearch = edit('reflink|nolink(?!\\()', 'g')
1176 + .replace('reflink', reflink)
1177 + .replace('nolink', nolink)
1178 + .getRegex();
1179 + /**
1180 + * Normal Inline Grammar
1181 + */
1182 + const inlineNormal = {
1183 + _backpedal: noopTest, // only used for GFM url
1184 + anyPunctuation,
1185 + autolink,
1186 + blockSkip,
1187 + br,
1188 + code: inlineCode,
1189 + del: noopTest,
1190 + emStrongLDelim,
1191 + emStrongRDelimAst,
1192 + emStrongRDelimUnd,
1193 + escape,
1194 + link,
1195 + nolink,
1196 + punctuation,
1197 + reflink,
1198 + reflinkSearch,
1199 + tag,
1200 + text: inlineText,
1201 + url: noopTest,
1202 + };
1203 + /**
1204 + * Pedantic Inline Grammar
1205 + */
1206 + const inlinePedantic = {
1207 + ...inlineNormal,
1208 + link: edit(/^!?\[(label)\]\((.*?)\)/)
1209 + .replace('label', _inlineLabel)
1210 + .getRegex(),
1211 + reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
1212 + .replace('label', _inlineLabel)
1213 + .getRegex(),
1214 + };
1215 + /**
1216 + * GFM Inline Grammar
1217 + */
1218 + const inlineGfm = {
1219 + ...inlineNormal,
1220 + escape: edit(escape).replace('])', '~|])').getRegex(),
1221 + url: edit(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, 'i')
1222 + .replace('email', /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/)
1223 + .getRegex(),
1224 + _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
1225 + del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
1226 + text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/,
1227 + };
1228 + /**
1229 + * GFM + Line Breaks Inline Grammar
1230 + */
1231 + const inlineBreaks = {
1232 + ...inlineGfm,
1233 + br: edit(br).replace('{2,}', '*').getRegex(),
1234 + text: edit(inlineGfm.text)
1235 + .replace('\\b_', '\\b_| {2,}\\n')
1236 + .replace(/\{2,\}/g, '*')
1237 + .getRegex(),
1238 + };
1239 + /**
1240 + * exports
1241 + */
1242 + const block = {
1243 + normal: blockNormal,
1244 + gfm: blockGfm,
1245 + pedantic: blockPedantic,
1246 + };
1247 + const inline = {
1248 + normal: inlineNormal,
1249 + gfm: inlineGfm,
1250 + breaks: inlineBreaks,
1251 + pedantic: inlinePedantic,
1252 + };
1253 +
1254 + /**
1255 + * Block Lexer
1256 + */
1257 + class _Lexer {
1258 + tokens;
1259 + options;
1260 + state;
1261 + tokenizer;
1262 + inlineQueue;
1263 + constructor(options) {
1264 + // TokenList cannot be created in one go
1265 + this.tokens = [];
1266 + this.tokens.links = Object.create(null);
1267 + this.options = options || exports.defaults;
1268 + this.options.tokenizer = this.options.tokenizer || new _Tokenizer();
1269 + this.tokenizer = this.options.tokenizer;
1270 + this.tokenizer.options = this.options;
1271 + this.tokenizer.lexer = this;
1272 + this.inlineQueue = [];
1273 + this.state = {
1274 + inLink: false,
1275 + inRawBlock: false,
1276 + top: true,
1277 + };
1278 + const rules = {
1279 + block: block.normal,
1280 + inline: inline.normal,
1281 + };
1282 + if (this.options.pedantic) {
1283 + rules.block = block.pedantic;
1284 + rules.inline = inline.pedantic;
1285 + }
1286 + else if (this.options.gfm) {
1287 + rules.block = block.gfm;
1288 + if (this.options.breaks) {
1289 + rules.inline = inline.breaks;
1290 + }
1291 + else {
1292 + rules.inline = inline.gfm;
1293 + }
1294 + }
1295 + this.tokenizer.rules = rules;
1296 + }
1297 + /**
1298 + * Expose Rules
1299 + */
1300 + static get rules() {
1301 + return {
1302 + block,
1303 + inline,
1304 + };
1305 + }
1306 + /**
1307 + * Static Lex Method
1308 + */
1309 + static lex(src, options) {
1310 + const lexer = new _Lexer(options);
1311 + return lexer.lex(src);
1312 + }
1313 + /**
1314 + * Static Lex Inline Method
1315 + */
1316 + static lexInline(src, options) {
1317 + const lexer = new _Lexer(options);
1318 + return lexer.inlineTokens(src);
1319 + }
1320 + /**
1321 + * Preprocessing
1322 + */
1323 + lex(src) {
1324 + src = src
1325 + .replace(/\r\n|\r/g, '\n');
1326 + this.blockTokens(src, this.tokens);
1327 + for (let i = 0; i < this.inlineQueue.length; i++) {
1328 + const next = this.inlineQueue[i];
1329 + this.inlineTokens(next.src, next.tokens);
1330 + }
1331 + this.inlineQueue = [];
1332 + return this.tokens;
1333 + }
1334 + blockTokens(src, tokens = [], lastParagraphClipped = false) {
1335 + if (this.options.pedantic) {
1336 + src = src.replace(/\t/g, ' ').replace(/^ +$/gm, '');
1337 + }
1338 + else {
1339 + src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => {
1340 + return leading + ' '.repeat(tabs.length);
1341 + });
1342 + }
1343 + let token;
1344 + let lastToken;
1345 + let cutSrc;
1346 + while (src) {
1347 + if (this.options.extensions
1348 + && this.options.extensions.block
1349 + && this.options.extensions.block.some((extTokenizer) => {
1350 + if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
1351 + src = src.substring(token.raw.length);
1352 + tokens.push(token);
1353 + return true;
1354 + }
1355 + return false;
1356 + })) {
1357 + continue;
1358 + }
1359 + // newline
1360 + if (token = this.tokenizer.space(src)) {
1361 + src = src.substring(token.raw.length);
1362 + if (token.raw.length === 1 && tokens.length > 0) {
1363 + // if there's a single \n as a spacer, it's terminating the last line,
1364 + // so move it there so that we don't get unnecessary paragraph tags
1365 + tokens[tokens.length - 1].raw += '\n';
1366 + }
1367 + else {
1368 + tokens.push(token);
1369 + }
1370 + continue;
1371 + }
1372 + // code
1373 + if (token = this.tokenizer.code(src)) {
1374 + src = src.substring(token.raw.length);
1375 + lastToken = tokens[tokens.length - 1];
1376 + // An indented code block cannot interrupt a paragraph.
1377 + if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
1378 + lastToken.raw += '\n' + token.raw;
1379 + lastToken.text += '\n' + token.text;
1380 + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
1381 + }
1382 + else {
1383 + tokens.push(token);
1384 + }
1385 + continue;
1386 + }
1387 + // fences
1388 + if (token = this.tokenizer.fences(src)) {
1389 + src = src.substring(token.raw.length);
1390 + tokens.push(token);
1391 + continue;
1392 + }
1393 + // heading
1394 + if (token = this.tokenizer.heading(src)) {
1395 + src = src.substring(token.raw.length);
1396 + tokens.push(token);
1397 + continue;
1398 + }
1399 + // hr
1400 + if (token = this.tokenizer.hr(src)) {
1401 + src = src.substring(token.raw.length);
1402 + tokens.push(token);
1403 + continue;
1404 + }
1405 + // blockquote
1406 + if (token = this.tokenizer.blockquote(src)) {
1407 + src = src.substring(token.raw.length);
1408 + tokens.push(token);
1409 + continue;
1410 + }
1411 + // list
1412 + if (token = this.tokenizer.list(src)) {
1413 + src = src.substring(token.raw.length);
1414 + tokens.push(token);
1415 + continue;
1416 + }
1417 + // html
1418 + if (token = this.tokenizer.html(src)) {
1419 + src = src.substring(token.raw.length);
1420 + tokens.push(token);
1421 + continue;
1422 + }
1423 + // def
1424 + if (token = this.tokenizer.def(src)) {
1425 + src = src.substring(token.raw.length);
1426 + lastToken = tokens[tokens.length - 1];
1427 + if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
1428 + lastToken.raw += '\n' + token.raw;
1429 + lastToken.text += '\n' + token.raw;
1430 + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
1431 + }
1432 + else if (!this.tokens.links[token.tag]) {
1433 + this.tokens.links[token.tag] = {
1434 + href: token.href,
1435 + title: token.title,
1436 + };
1437 + }
1438 + continue;
1439 + }
1440 + // table (gfm)
1441 + if (token = this.tokenizer.table(src)) {
1442 + src = src.substring(token.raw.length);
1443 + tokens.push(token);
1444 + continue;
1445 + }
1446 + // lheading
1447 + if (token = this.tokenizer.lheading(src)) {
1448 + src = src.substring(token.raw.length);
1449 + tokens.push(token);
1450 + continue;
1451 + }
1452 + // top-level paragraph
1453 + // prevent paragraph consuming extensions by clipping 'src' to extension start
1454 + cutSrc = src;
1455 + if (this.options.extensions && this.options.extensions.startBlock) {
1456 + let startIndex = Infinity;
1457 + const tempSrc = src.slice(1);
1458 + let tempStart;
1459 + this.options.extensions.startBlock.forEach((getStartIndex) => {
1460 + tempStart = getStartIndex.call({ lexer: this }, tempSrc);
1461 + if (typeof tempStart === 'number' && tempStart >= 0) {
1462 + startIndex = Math.min(startIndex, tempStart);
1463 + }
1464 + });
1465 + if (startIndex < Infinity && startIndex >= 0) {
1466 + cutSrc = src.substring(0, startIndex + 1);
1467 + }
1468 + }
1469 + if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
1470 + lastToken = tokens[tokens.length - 1];
1471 + if (lastParagraphClipped && lastToken?.type === 'paragraph') {
1472 + lastToken.raw += '\n' + token.raw;
1473 + lastToken.text += '\n' + token.text;
1474 + this.inlineQueue.pop();
1475 + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
1476 + }
1477 + else {
1478 + tokens.push(token);
1479 + }
1480 + lastParagraphClipped = (cutSrc.length !== src.length);
1481 + src = src.substring(token.raw.length);
1482 + continue;
1483 + }
1484 + // text
1485 + if (token = this.tokenizer.text(src)) {
1486 + src = src.substring(token.raw.length);
1487 + lastToken = tokens[tokens.length - 1];
1488 + if (lastToken && lastToken.type === 'text') {
1489 + lastToken.raw += '\n' + token.raw;
1490 + lastToken.text += '\n' + token.text;
1491 + this.inlineQueue.pop();
1492 + this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
1493 + }
1494 + else {
1495 + tokens.push(token);
1496 + }
1497 + continue;
1498 + }
1499 + if (src) {
1500 + const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
1501 + if (this.options.silent) {
1502 + console.error(errMsg);
1503 + break;
1504 + }
1505 + else {
1506 + throw new Error(errMsg);
1507 + }
1508 + }
1509 + }
1510 + this.state.top = true;
1511 + return tokens;
1512 + }
1513 + inline(src, tokens = []) {
1514 + this.inlineQueue.push({ src, tokens });
1515 + return tokens;
1516 + }
1517 + /**
1518 + * Lexing/Compiling
1519 + */
1520 + inlineTokens(src, tokens = []) {
1521 + let token, lastToken, cutSrc;
1522 + // String with links masked to avoid interference with em and strong
1523 + let maskedSrc = src;
1524 + let match;
1525 + let keepPrevChar, prevChar;
1526 + // Mask out reflinks
1527 + if (this.tokens.links) {
1528 + const links = Object.keys(this.tokens.links);
1529 + if (links.length > 0) {
1530 + while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
1531 + if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
1532 + maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
1533 + }
1534 + }
1535 + }
1536 + }
1537 + // Mask out other blocks
1538 + while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
1539 + maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
1540 + }
1541 + // Mask out escaped characters
1542 + while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) {
1543 + maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
1544 + }
1545 + while (src) {
1546 + if (!keepPrevChar) {
1547 + prevChar = '';
1548 + }
1549 + keepPrevChar = false;
1550 + // extensions
1551 + if (this.options.extensions
1552 + && this.options.extensions.inline
1553 + && this.options.extensions.inline.some((extTokenizer) => {
1554 + if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
1555 + src = src.substring(token.raw.length);
1556 + tokens.push(token);
1557 + return true;
1558 + }
1559 + return false;
1560 + })) {
1561 + continue;
1562 + }
1563 + // escape
1564 + if (token = this.tokenizer.escape(src)) {
1565 + src = src.substring(token.raw.length);
1566 + tokens.push(token);
1567 + continue;
1568 + }
1569 + // tag
1570 + if (token = this.tokenizer.tag(src)) {
1571 + src = src.substring(token.raw.length);
1572 + lastToken = tokens[tokens.length - 1];
1573 + if (lastToken && token.type === 'text' && lastToken.type === 'text') {
1574 + lastToken.raw += token.raw;
1575 + lastToken.text += token.text;
1576 + }
1577 + else {
1578 + tokens.push(token);
1579 + }
1580 + continue;
1581 + }
1582 + // link
1583 + if (token = this.tokenizer.link(src)) {
1584 + src = src.substring(token.raw.length);
1585 + tokens.push(token);
1586 + continue;
1587 + }
1588 + // reflink, nolink
1589 + if (token = this.tokenizer.reflink(src, this.tokens.links)) {
1590 + src = src.substring(token.raw.length);
1591 + lastToken = tokens[tokens.length - 1];
1592 + if (lastToken && token.type === 'text' && lastToken.type === 'text') {
1593 + lastToken.raw += token.raw;
1594 + lastToken.text += token.text;
1595 + }
1596 + else {
1597 + tokens.push(token);
1598 + }
1599 + continue;
1600 + }
1601 + // em & strong
1602 + if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
1603 + src = src.substring(token.raw.length);
1604 + tokens.push(token);
1605 + continue;
1606 + }
1607 + // code
1608 + if (token = this.tokenizer.codespan(src)) {
1609 + src = src.substring(token.raw.length);
1610 + tokens.push(token);
1611 + continue;
1612 + }
1613 + // br
1614 + if (token = this.tokenizer.br(src)) {
1615 + src = src.substring(token.raw.length);
1616 + tokens.push(token);
1617 + continue;
1618 + }
1619 + // del (gfm)
1620 + if (token = this.tokenizer.del(src)) {
1621 + src = src.substring(token.raw.length);
1622 + tokens.push(token);
1623 + continue;
1624 + }
1625 + // autolink
1626 + if (token = this.tokenizer.autolink(src)) {
1627 + src = src.substring(token.raw.length);
1628 + tokens.push(token);
1629 + continue;
1630 + }
1631 + // url (gfm)
1632 + if (!this.state.inLink && (token = this.tokenizer.url(src))) {
1633 + src = src.substring(token.raw.length);
1634 + tokens.push(token);
1635 + continue;
1636 + }
1637 + // text
1638 + // prevent inlineText consuming extensions by clipping 'src' to extension start
1639 + cutSrc = src;
1640 + if (this.options.extensions && this.options.extensions.startInline) {
1641 + let startIndex = Infinity;
1642 + const tempSrc = src.slice(1);
1643 + let tempStart;
1644 + this.options.extensions.startInline.forEach((getStartIndex) => {
1645 + tempStart = getStartIndex.call({ lexer: this }, tempSrc);
1646 + if (typeof tempStart === 'number' && tempStart >= 0) {
1647 + startIndex = Math.min(startIndex, tempStart);
1648 + }
1649 + });
1650 + if (startIndex < Infinity && startIndex >= 0) {
1651 + cutSrc = src.substring(0, startIndex + 1);
1652 + }
1653 + }
1654 + if (token = this.tokenizer.inlineText(cutSrc)) {
1655 + src = src.substring(token.raw.length);
1656 + if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started
1657 + prevChar = token.raw.slice(-1);
1658 + }
1659 + keepPrevChar = true;
1660 + lastToken = tokens[tokens.length - 1];
1661 + if (lastToken && lastToken.type === 'text') {
1662 + lastToken.raw += token.raw;
1663 + lastToken.text += token.text;
1664 + }
1665 + else {
1666 + tokens.push(token);
1667 + }
1668 + continue;
1669 + }
1670 + if (src) {
1671 + const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
1672 + if (this.options.silent) {
1673 + console.error(errMsg);
1674 + break;
1675 + }
1676 + else {
1677 + throw new Error(errMsg);
1678 + }
1679 + }
1680 + }
1681 + return tokens;
1682 + }
1683 + }
1684 +
1685 + /**
1686 + * Renderer
1687 + */
1688 + class _Renderer {
1689 + options;
1690 + parser; // set by the parser
1691 + constructor(options) {
1692 + this.options = options || exports.defaults;
1693 + }
1694 + space(token) {
1695 + return '';
1696 + }
1697 + code({ text, lang, escaped }) {
1698 + const langString = (lang || '').match(/^\S*/)?.[0];
1699 + const code = text.replace(/\n$/, '') + '\n';
1700 + if (!langString) {
1701 + return '<pre><code>'
1702 + + (escaped ? code : escape$1(code, true))
1703 + + '</code></pre>\n';
1704 + }
1705 + return '<pre><code class="language-'
1706 + + escape$1(langString)
1707 + + '">'
1708 + + (escaped ? code : escape$1(code, true))
1709 + + '</code></pre>\n';
1710 + }
1711 + blockquote({ tokens }) {
1712 + const body = this.parser.parse(tokens);
1713 + return `<blockquote>\n${body}</blockquote>\n`;
1714 + }
1715 + html({ text }) {
1716 + return text;
1717 + }
1718 + heading({ tokens, depth }) {
1719 + return `<h${depth}>${this.parser.parseInline(tokens)}</h${depth}>\n`;
1720 + }
1721 + hr(token) {
1722 + return '<hr>\n';
1723 + }
1724 + list(token) {
1725 + const ordered = token.ordered;
1726 + const start = token.start;
1727 + let body = '';
1728 + for (let j = 0; j < token.items.length; j++) {
1729 + const item = token.items[j];
1730 + body += this.listitem(item);
1731 + }
1732 + const type = ordered ? 'ol' : 'ul';
1733 + const startAttr = (ordered && start !== 1) ? (' start="' + start + '"') : '';
1734 + return '<' + type + startAttr + '>\n' + body + '</' + type + '>\n';
1735 + }
1736 + listitem(item) {
1737 + let itemBody = '';
1738 + if (item.task) {
1739 + const checkbox = this.checkbox({ checked: !!item.checked });
1740 + if (item.loose) {
1741 + if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
1742 + item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
1743 + if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
1744 + item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;
1745 + }
1746 + }
1747 + else {
1748 + item.tokens.unshift({
1749 + type: 'text',
1750 + raw: checkbox + ' ',
1751 + text: checkbox + ' ',
1752 + });
1753 + }
1754 + }
1755 + else {
1756 + itemBody += checkbox + ' ';
1757 + }
1758 + }
1759 + itemBody += this.parser.parse(item.tokens, !!item.loose);
1760 + return `<li>${itemBody}</li>\n`;
1761 + }
1762 + checkbox({ checked }) {
1763 + return '<input '
1764 + + (checked ? 'checked="" ' : '')
1765 + + 'disabled="" type="checkbox">';
1766 + }
1767 + paragraph({ tokens }) {
1768 + return `<p>${this.parser.parseInline(tokens)}</p>\n`;
1769 + }
1770 + table(token) {
1771 + let header = '';
1772 + // header
1773 + let cell = '';
1774 + for (let j = 0; j < token.header.length; j++) {
1775 + cell += this.tablecell(token.header[j]);
1776 + }
1777 + header += this.tablerow({ text: cell });
1778 + let body = '';
1779 + for (let j = 0; j < token.rows.length; j++) {
1780 + const row = token.rows[j];
1781 + cell = '';
1782 + for (let k = 0; k < row.length; k++) {
1783 + cell += this.tablecell(row[k]);
1784 + }
1785 + body += this.tablerow({ text: cell });
1786 + }
1787 + if (body)
1788 + body = `<tbody>${body}</tbody>`;
1789 + return '<table>\n'
1790 + + '<thead>\n'
1791 + + header
1792 + + '</thead>\n'
1793 + + body
1794 + + '</table>\n';
1795 + }
1796 + tablerow({ text }) {
1797 + return `<tr>\n${text}</tr>\n`;
1798 + }
1799 + tablecell(token) {
1800 + const content = this.parser.parseInline(token.tokens);
1801 + const type = token.header ? 'th' : 'td';
1802 + const tag = token.align
1803 + ? `<${type} align="${token.align}">`
1804 + : `<${type}>`;
1805 + return tag + content + `</${type}>\n`;
1806 + }
1807 + /**
1808 + * span level renderer
1809 + */
1810 + strong({ tokens }) {
1811 + return `<strong>${this.parser.parseInline(tokens)}</strong>`;
1812 + }
1813 + em({ tokens }) {
1814 + return `<em>${this.parser.parseInline(tokens)}</em>`;
1815 + }
1816 + codespan({ text }) {
1817 + return `<code>${text}</code>`;
1818 + }
1819 + br(token) {
1820 + return '<br>';
1821 + }
1822 + del({ tokens }) {
1823 + return `<del>${this.parser.parseInline(tokens)}</del>`;
1824 + }
1825 + link({ href, title, tokens }) {
1826 + const text = this.parser.parseInline(tokens);
1827 + const cleanHref = cleanUrl(href);
1828 + if (cleanHref === null) {
1829 + return text;
1830 + }
1831 + href = cleanHref;
1832 + let out = '<a href="' + href + '"';
1833 + if (title) {
1834 + out += ' title="' + title + '"';
1835 + }
1836 + out += '>' + text + '</a>';
1837 + return out;
1838 + }
1839 + image({ href, title, text }) {
1840 + const cleanHref = cleanUrl(href);
1841 + if (cleanHref === null) {
1842 + return text;
1843 + }
1844 + href = cleanHref;
1845 + let out = `<img src="${href}" alt="${text}"`;
1846 + if (title) {
1847 + out += ` title="${title}"`;
1848 + }
1849 + out += '>';
1850 + return out;
1851 + }
1852 + text(token) {
1853 + return 'tokens' in token && token.tokens ? this.parser.parseInline(token.tokens) : token.text;
1854 + }
1855 + }
1856 +
1857 + /**
1858 + * TextRenderer
1859 + * returns only the textual part of the token
1860 + */
1861 + class _TextRenderer {
1862 + // no need for block level renderers
1863 + strong({ text }) {
1864 + return text;
1865 + }
1866 + em({ text }) {
1867 + return text;
1868 + }
1869 + codespan({ text }) {
1870 + return text;
1871 + }
1872 + del({ text }) {
1873 + return text;
1874 + }
1875 + html({ text }) {
1876 + return text;
1877 + }
1878 + text({ text }) {
1879 + return text;
1880 + }
1881 + link({ text }) {
1882 + return '' + text;
1883 + }
1884 + image({ text }) {
1885 + return '' + text;
1886 + }
1887 + br() {
1888 + return '';
1889 + }
1890 + }
1891 +
1892 + /**
1893 + * Parsing & Compiling
1894 + */
1895 + class _Parser {
1896 + options;
1897 + renderer;
1898 + textRenderer;
1899 + constructor(options) {
1900 + this.options = options || exports.defaults;
1901 + this.options.renderer = this.options.renderer || new _Renderer();
1902 + this.renderer = this.options.renderer;
1903 + this.renderer.options = this.options;
1904 + this.renderer.parser = this;
1905 + this.textRenderer = new _TextRenderer();
1906 + }
1907 + /**
1908 + * Static Parse Method
1909 + */
1910 + static parse(tokens, options) {
1911 + const parser = new _Parser(options);
1912 + return parser.parse(tokens);
1913 + }
1914 + /**
1915 + * Static Parse Inline Method
1916 + */
1917 + static parseInline(tokens, options) {
1918 + const parser = new _Parser(options);
1919 + return parser.parseInline(tokens);
1920 + }
1921 + /**
1922 + * Parse Loop
1923 + */
1924 + parse(tokens, top = true) {
1925 + let out = '';
1926 + for (let i = 0; i < tokens.length; i++) {
1927 + const anyToken = tokens[i];
1928 + // Run any renderer extensions
1929 + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[anyToken.type]) {
1930 + const genericToken = anyToken;
1931 + const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken);
1932 + if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(genericToken.type)) {
1933 + out += ret || '';
1934 + continue;
1935 + }
1936 + }
1937 + const token = anyToken;
1938 + switch (token.type) {
1939 + case 'space': {
1940 + out += this.renderer.space(token);
1941 + continue;
1942 + }
1943 + case 'hr': {
1944 + out += this.renderer.hr(token);
1945 + continue;
1946 + }
1947 + case 'heading': {
1948 + out += this.renderer.heading(token);
1949 + continue;
1950 + }
1951 + case 'code': {
1952 + out += this.renderer.code(token);
1953 + continue;
1954 + }
1955 + case 'table': {
1956 + out += this.renderer.table(token);
1957 + continue;
1958 + }
1959 + case 'blockquote': {
1960 + out += this.renderer.blockquote(token);
1961 + continue;
1962 + }
1963 + case 'list': {
1964 + out += this.renderer.list(token);
1965 + continue;
1966 + }
1967 + case 'html': {
1968 + out += this.renderer.html(token);
1969 + continue;
1970 + }
1971 + case 'paragraph': {
1972 + out += this.renderer.paragraph(token);
1973 + continue;
1974 + }
1975 + case 'text': {
1976 + let textToken = token;
1977 + let body = this.renderer.text(textToken);
1978 + while (i + 1 < tokens.length && tokens[i + 1].type === 'text') {
1979 + textToken = tokens[++i];
1980 + body += '\n' + this.renderer.text(textToken);
1981 + }
1982 + if (top) {
1983 + out += this.renderer.paragraph({
1984 + type: 'paragraph',
1985 + raw: body,
1986 + text: body,
1987 + tokens: [{ type: 'text', raw: body, text: body }],
1988 + });
1989 + }
1990 + else {
1991 + out += body;
1992 + }
1993 + continue;
1994 + }
1995 + default: {
1996 + const errMsg = 'Token with "' + token.type + '" type was not found.';
1997 + if (this.options.silent) {
1998 + console.error(errMsg);
1999 + return '';
2000 + }
2001 + else {
2002 + throw new Error(errMsg);
2003 + }
2004 + }
2005 + }
2006 + }
2007 + return out;
2008 + }
2009 + /**
2010 + * Parse Inline Tokens
2011 + */
2012 + parseInline(tokens, renderer) {
2013 + renderer = renderer || this.renderer;
2014 + let out = '';
2015 + for (let i = 0; i < tokens.length; i++) {
2016 + const anyToken = tokens[i];
2017 + // Run any renderer extensions
2018 + if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[anyToken.type]) {
2019 + const ret = this.options.extensions.renderers[anyToken.type].call({ parser: this }, anyToken);
2020 + if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(anyToken.type)) {
2021 + out += ret || '';
2022 + continue;
2023 + }
2024 + }
2025 + const token = anyToken;
2026 + switch (token.type) {
2027 + case 'escape': {
2028 + out += renderer.text(token);
2029 + break;
2030 + }
2031 + case 'html': {
2032 + out += renderer.html(token);
2033 + break;
2034 + }
2035 + case 'link': {
2036 + out += renderer.link(token);
2037 + break;
2038 + }
2039 + case 'image': {
2040 + out += renderer.image(token);
2041 + break;
2042 + }
2043 + case 'strong': {
2044 + out += renderer.strong(token);
2045 + break;
2046 + }
2047 + case 'em': {
2048 + out += renderer.em(token);
2049 + break;
2050 + }
2051 + case 'codespan': {
2052 + out += renderer.codespan(token);
2053 + break;
2054 + }
2055 + case 'br': {
2056 + out += renderer.br(token);
2057 + break;
2058 + }
2059 + case 'del': {
2060 + out += renderer.del(token);
2061 + break;
2062 + }
2063 + case 'text': {
2064 + out += renderer.text(token);
2065 + break;
2066 + }
2067 + default: {
2068 + const errMsg = 'Token with "' + token.type + '" type was not found.';
2069 + if (this.options.silent) {
2070 + console.error(errMsg);
2071 + return '';
2072 + }
2073 + else {
2074 + throw new Error(errMsg);
2075 + }
2076 + }
2077 + }
2078 + }
2079 + return out;
2080 + }
2081 + }
2082 +
2083 + class _Hooks {
2084 + options;
2085 + constructor(options) {
2086 + this.options = options || exports.defaults;
2087 + }
2088 + static passThroughHooks = new Set([
2089 + 'preprocess',
2090 + 'postprocess',
2091 + 'processAllTokens',
2092 + ]);
2093 + /**
2094 + * Process markdown before marked
2095 + */
2096 + preprocess(markdown) {
2097 + return markdown;
2098 + }
2099 + /**
2100 + * Process HTML after marked is finished
2101 + */
2102 + postprocess(html) {
2103 + return html;
2104 + }
2105 + /**
2106 + * Process all tokens before walk tokens
2107 + */
2108 + processAllTokens(tokens) {
2109 + return tokens;
2110 + }
2111 + }
2112 +
2113 + class Marked {
2114 + defaults = _getDefaults();
2115 + options = this.setOptions;
2116 + parse = this.parseMarkdown(_Lexer.lex, _Parser.parse);
2117 + parseInline = this.parseMarkdown(_Lexer.lexInline, _Parser.parseInline);
2118 + Parser = _Parser;
2119 + Renderer = _Renderer;
2120 + TextRenderer = _TextRenderer;
2121 + Lexer = _Lexer;
2122 + Tokenizer = _Tokenizer;
2123 + Hooks = _Hooks;
2124 + constructor(...args) {
2125 + this.use(...args);
2126 + }
2127 + /**
2128 + * Run callback for every token
2129 + */
2130 + walkTokens(tokens, callback) {
2131 + let values = [];
2132 + for (const token of tokens) {
2133 + values = values.concat(callback.call(this, token));
2134 + switch (token.type) {
2135 + case 'table': {
2136 + const tableToken = token;
2137 + for (const cell of tableToken.header) {
2138 + values = values.concat(this.walkTokens(cell.tokens, callback));
2139 + }
2140 + for (const row of tableToken.rows) {
2141 + for (const cell of row) {
2142 + values = values.concat(this.walkTokens(cell.tokens, callback));
2143 + }
2144 + }
2145 + break;
2146 + }
2147 + case 'list': {
2148 + const listToken = token;
2149 + values = values.concat(this.walkTokens(listToken.items, callback));
2150 + break;
2151 + }
2152 + default: {
2153 + const genericToken = token;
2154 + if (this.defaults.extensions?.childTokens?.[genericToken.type]) {
2155 + this.defaults.extensions.childTokens[genericToken.type].forEach((childTokens) => {
2156 + const tokens = genericToken[childTokens].flat(Infinity);
2157 + values = values.concat(this.walkTokens(tokens, callback));
2158 + });
2159 + }
2160 + else if (genericToken.tokens) {
2161 + values = values.concat(this.walkTokens(genericToken.tokens, callback));
2162 + }
2163 + }
2164 + }
2165 + }
2166 + return values;
2167 + }
2168 + use(...args) {
2169 + const extensions = this.defaults.extensions || { renderers: {}, childTokens: {} };
2170 + args.forEach((pack) => {
2171 + // copy options to new object
2172 + const opts = { ...pack };
2173 + // set async to true if it was set to true before
2174 + opts.async = this.defaults.async || opts.async || false;
2175 + // ==-- Parse "addon" extensions --== //
2176 + if (pack.extensions) {
2177 + pack.extensions.forEach((ext) => {
2178 + if (!ext.name) {
2179 + throw new Error('extension name required');
2180 + }
2181 + if ('renderer' in ext) { // Renderer extensions
2182 + const prevRenderer = extensions.renderers[ext.name];
2183 + if (prevRenderer) {
2184 + // Replace extension with func to run new extension but fall back if false
2185 + extensions.renderers[ext.name] = function (...args) {
2186 + let ret = ext.renderer.apply(this, args);
2187 + if (ret === false) {
2188 + ret = prevRenderer.apply(this, args);
2189 + }
2190 + return ret;
2191 + };
2192 + }
2193 + else {
2194 + extensions.renderers[ext.name] = ext.renderer;
2195 + }
2196 + }
2197 + if ('tokenizer' in ext) { // Tokenizer Extensions
2198 + if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {
2199 + throw new Error("extension level must be 'block' or 'inline'");
2200 + }
2201 + const extLevel = extensions[ext.level];
2202 + if (extLevel) {
2203 + extLevel.unshift(ext.tokenizer);
2204 + }
2205 + else {
2206 + extensions[ext.level] = [ext.tokenizer];
2207 + }
2208 + if (ext.start) { // Function to check for start of token
2209 + if (ext.level === 'block') {
2210 + if (extensions.startBlock) {
2211 + extensions.startBlock.push(ext.start);
2212 + }
2213 + else {
2214 + extensions.startBlock = [ext.start];
2215 + }
2216 + }
2217 + else if (ext.level === 'inline') {
2218 + if (extensions.startInline) {
2219 + extensions.startInline.push(ext.start);
2220 + }
2221 + else {
2222 + extensions.startInline = [ext.start];
2223 + }
2224 + }
2225 + }
2226 + }
2227 + if ('childTokens' in ext && ext.childTokens) { // Child tokens to be visited by walkTokens
2228 + extensions.childTokens[ext.name] = ext.childTokens;
2229 + }
2230 + });
2231 + opts.extensions = extensions;
2232 + }
2233 + // ==-- Parse "overwrite" extensions --== //
2234 + if (pack.renderer) {
2235 + const renderer = this.defaults.renderer || new _Renderer(this.defaults);
2236 + for (const prop in pack.renderer) {
2237 + if (!(prop in renderer)) {
2238 + throw new Error(`renderer '${prop}' does not exist`);
2239 + }
2240 + if (['options', 'parser'].includes(prop)) {
2241 + // ignore options property
2242 + continue;
2243 + }
2244 + const rendererProp = prop;
2245 + const rendererFunc = pack.renderer[rendererProp];
2246 + const prevRenderer = renderer[rendererProp];
2247 + // Replace renderer with func to run extension, but fall back if false
2248 + renderer[rendererProp] = (...args) => {
2249 + let ret = rendererFunc.apply(renderer, args);
2250 + if (ret === false) {
2251 + ret = prevRenderer.apply(renderer, args);
2252 + }
2253 + return ret || '';
2254 + };
2255 + }
2256 + opts.renderer = renderer;
2257 + }
2258 + if (pack.tokenizer) {
2259 + const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);
2260 + for (const prop in pack.tokenizer) {
2261 + if (!(prop in tokenizer)) {
2262 + throw new Error(`tokenizer '${prop}' does not exist`);
2263 + }
2264 + if (['options', 'rules', 'lexer'].includes(prop)) {
2265 + // ignore options, rules, and lexer properties
2266 + continue;
2267 + }
2268 + const tokenizerProp = prop;
2269 + const tokenizerFunc = pack.tokenizer[tokenizerProp];
2270 + const prevTokenizer = tokenizer[tokenizerProp];
2271 + // Replace tokenizer with func to run extension, but fall back if false
2272 + // @ts-expect-error cannot type tokenizer function dynamically
2273 + tokenizer[tokenizerProp] = (...args) => {
2274 + let ret = tokenizerFunc.apply(tokenizer, args);
2275 + if (ret === false) {
2276 + ret = prevTokenizer.apply(tokenizer, args);
2277 + }
2278 + return ret;
2279 + };
2280 + }
2281 + opts.tokenizer = tokenizer;
2282 + }
2283 + // ==-- Parse Hooks extensions --== //
2284 + if (pack.hooks) {
2285 + const hooks = this.defaults.hooks || new _Hooks();
2286 + for (const prop in pack.hooks) {
2287 + if (!(prop in hooks)) {
2288 + throw new Error(`hook '${prop}' does not exist`);
2289 + }
2290 + if (prop === 'options') {
2291 + // ignore options property
2292 + continue;
2293 + }
2294 + const hooksProp = prop;
2295 + const hooksFunc = pack.hooks[hooksProp];
2296 + const prevHook = hooks[hooksProp];
2297 + if (_Hooks.passThroughHooks.has(prop)) {
2298 + // @ts-expect-error cannot type hook function dynamically
2299 + hooks[hooksProp] = (arg) => {
2300 + if (this.defaults.async) {
2301 + return Promise.resolve(hooksFunc.call(hooks, arg)).then(ret => {
2302 + return prevHook.call(hooks, ret);
2303 + });
2304 + }
2305 + const ret = hooksFunc.call(hooks, arg);
2306 + return prevHook.call(hooks, ret);
2307 + };
2308 + }
2309 + else {
2310 + // @ts-expect-error cannot type hook function dynamically
2311 + hooks[hooksProp] = (...args) => {
2312 + let ret = hooksFunc.apply(hooks, args);
2313 + if (ret === false) {
2314 + ret = prevHook.apply(hooks, args);
2315 + }
2316 + return ret;
2317 + };
2318 + }
2319 + }
2320 + opts.hooks = hooks;
2321 + }
2322 + // ==-- Parse WalkTokens extensions --== //
2323 + if (pack.walkTokens) {
2324 + const walkTokens = this.defaults.walkTokens;
2325 + const packWalktokens = pack.walkTokens;
2326 + opts.walkTokens = function (token) {
2327 + let values = [];
2328 + values.push(packWalktokens.call(this, token));
2329 + if (walkTokens) {
2330 + values = values.concat(walkTokens.call(this, token));
2331 + }
2332 + return values;
2333 + };
2334 + }
2335 + this.defaults = { ...this.defaults, ...opts };
2336 + });
2337 + return this;
2338 + }
2339 + setOptions(opt) {
2340 + this.defaults = { ...this.defaults, ...opt };
2341 + return this;
2342 + }
2343 + lexer(src, options) {
2344 + return _Lexer.lex(src, options ?? this.defaults);
2345 + }
2346 + parser(tokens, options) {
2347 + return _Parser.parse(tokens, options ?? this.defaults);
2348 + }
2349 + parseMarkdown(lexer, parser) {
2350 + // eslint-disable-next-line @typescript-eslint/no-explicit-any
2351 + const parse = (src, options) => {
2352 + const origOpt = { ...options };
2353 + const opt = { ...this.defaults, ...origOpt };
2354 + const throwError = this.onError(!!opt.silent, !!opt.async);
2355 + // throw error if an extension set async to true but parse was called with async: false
2356 + if (this.defaults.async === true && origOpt.async === false) {
2357 + return throwError(new Error('marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.'));
2358 + }
2359 + // throw error in case of non string input
2360 + if (typeof src === 'undefined' || src === null) {
2361 + return throwError(new Error('marked(): input parameter is undefined or null'));
2362 + }
2363 + if (typeof src !== 'string') {
2364 + return throwError(new Error('marked(): input parameter is of type '
2365 + + Object.prototype.toString.call(src) + ', string expected'));
2366 + }
2367 + if (opt.hooks) {
2368 + opt.hooks.options = opt;
2369 + }
2370 + if (opt.async) {
2371 + return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src)
2372 + .then(src => lexer(src, opt))
2373 + .then(tokens => opt.hooks ? opt.hooks.processAllTokens(tokens) : tokens)
2374 + .then(tokens => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens)
2375 + .then(tokens => parser(tokens, opt))
2376 + .then(html => opt.hooks ? opt.hooks.postprocess(html) : html)
2377 + .catch(throwError);
2378 + }
2379 + try {
2380 + if (opt.hooks) {
2381 + src = opt.hooks.preprocess(src);
2382 + }
2383 + let tokens = lexer(src, opt);
2384 + if (opt.hooks) {
2385 + tokens = opt.hooks.processAllTokens(tokens);
2386 + }
2387 + if (opt.walkTokens) {
2388 + this.walkTokens(tokens, opt.walkTokens);
2389 + }
2390 + let html = parser(tokens, opt);
2391 + if (opt.hooks) {
2392 + html = opt.hooks.postprocess(html);
2393 + }
2394 + return html;
2395 + }
2396 + catch (e) {
2397 + return throwError(e);
2398 + }
2399 + };
2400 + return parse;
2401 + }
2402 + onError(silent, async) {
2403 + return (e) => {
2404 + e.message += '\nPlease report this to https://github.com/markedjs/marked.';
2405 + if (silent) {
2406 + const msg = '<p>An error occurred:</p><pre>'
2407 + + escape$1(e.message + '', true)
2408 + + '</pre>';
2409 + if (async) {
2410 + return Promise.resolve(msg);
2411 + }
2412 + return msg;
2413 + }
2414 + if (async) {
2415 + return Promise.reject(e);
2416 + }
2417 + throw e;
2418 + };
2419 + }
2420 + }
2421 +
2422 + const markedInstance = new Marked();
2423 + function marked(src, opt) {
2424 + return markedInstance.parse(src, opt);
2425 + }
2426 + /**
2427 + * Sets the default options.
2428 + *
2429 + * @param options Hash of options
2430 + */
2431 + marked.options =
2432 + marked.setOptions = function (options) {
2433 + markedInstance.setOptions(options);
2434 + marked.defaults = markedInstance.defaults;
2435 + changeDefaults(marked.defaults);
2436 + return marked;
2437 + };
2438 + /**
2439 + * Gets the original marked default options.
2440 + */
2441 + marked.getDefaults = _getDefaults;
2442 + marked.defaults = exports.defaults;
2443 + /**
2444 + * Use Extension
2445 + */
2446 + marked.use = function (...args) {
2447 + markedInstance.use(...args);
2448 + marked.defaults = markedInstance.defaults;
2449 + changeDefaults(marked.defaults);
2450 + return marked;
2451 + };
2452 + /**
2453 + * Run callback for every token
2454 + */
2455 + marked.walkTokens = function (tokens, callback) {
2456 + return markedInstance.walkTokens(tokens, callback);
2457 + };
2458 + /**
2459 + * Compiles markdown to HTML without enclosing `p` tag.
2460 + *
2461 + * @param src String of markdown source to be compiled
2462 + * @param options Hash of options
2463 + * @return String of compiled HTML
2464 + */
2465 + marked.parseInline = markedInstance.parseInline;
2466 + /**
2467 + * Expose
2468 + */
2469 + marked.Parser = _Parser;
2470 + marked.parser = _Parser.parse;
2471 + marked.Renderer = _Renderer;
2472 + marked.TextRenderer = _TextRenderer;
2473 + marked.Lexer = _Lexer;
2474 + marked.lexer = _Lexer.lex;
2475 + marked.Tokenizer = _Tokenizer;
2476 + marked.Hooks = _Hooks;
2477 + marked.parse = marked;
2478 + const options = marked.options;
2479 + const setOptions = marked.setOptions;
2480 + const use = marked.use;
2481 + const walkTokens = marked.walkTokens;
2482 + const parseInline = marked.parseInline;
2483 + const parse = marked;
2484 + const parser = _Parser.parse;
2485 + const lexer = _Lexer.lex;
2486 +
2487 + exports.Hooks = _Hooks;
2488 + exports.Lexer = _Lexer;
2489 + exports.Marked = Marked;
2490 + exports.Parser = _Parser;
2491 + exports.Renderer = _Renderer;
2492 + exports.TextRenderer = _TextRenderer;
2493 + exports.Tokenizer = _Tokenizer;
2494 + exports.getDefaults = _getDefaults;
2495 + exports.lexer = lexer;
2496 + exports.marked = marked;
2497 + exports.options = options;
2498 + exports.parse = parse;
2499 + exports.parseInline = parseInline;
2500 + exports.parser = parser;
2501 + exports.setOptions = setOptions;
2502 + exports.use = use;
2503 + exports.walkTokens = walkTokens;
2504 +
2505 +}));
2506 +//# sourceMappingURL=marked.umd.js.map
public/scripts/purify-min.js new
+3
@@ -0,0 +1,3 @@
1 +/*! @license DOMPurify 3.1.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.1.6/LICENSE */
2 +!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).DOMPurify=t()}(this,(function(){"use strict";const{entries:e,setPrototypeOf:t,isFrozen:n,getPrototypeOf:o,getOwnPropertyDescriptor:r}=Object;let{freeze:i,seal:a,create:l}=Object,{apply:c,construct:s}="undefined"!=typeof Reflect&&Reflect;i||(i=function(e){return e}),a||(a=function(e){return e}),c||(c=function(e,t,n){return e.apply(t,n)}),s||(s=function(e,t){return new e(...t)});const u=b(Array.prototype.forEach),m=b(Array.prototype.pop),p=b(Array.prototype.push),f=b(String.prototype.toLowerCase),d=b(String.prototype.toString),h=b(String.prototype.match),g=b(String.prototype.replace),T=b(String.prototype.indexOf),y=b(String.prototype.trim),E=b(Object.prototype.hasOwnProperty),_=b(RegExp.prototype.test),A=(N=TypeError,function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return s(N,t)});var N;function b(e){return function(t){for(var n=arguments.length,o=new Array(n>1?n-1:0),r=1;r<n;r++)o[r-1]=arguments[r];return c(e,t,o)}}function S(e,o){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:f;t&&t(e,null);let i=o.length;for(;i--;){let t=o[i];if("string"==typeof t){const e=r(t);e!==t&&(n(o)||(o[i]=e),t=e)}e[t]=!0}return e}function R(e){for(let t=0;t<e.length;t++){E(e,t)||(e[t]=null)}return e}function w(t){const n=l(null);for(const[o,r]of e(t)){E(t,o)&&(Array.isArray(r)?n[o]=R(r):r&&"object"==typeof r&&r.constructor===Object?n[o]=w(r):n[o]=r)}return n}function C(e,t){for(;null!==e;){const n=r(e,t);if(n){if(n.get)return b(n.get);if("function"==typeof n.value)return b(n.value)}e=o(e)}return function(){return null}}const L=i(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),D=i(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),v=i(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),O=i(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),x=i(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),k=i(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),M=i(["#text"]),I=i(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","popover","popovertarget","popovertargetaction","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","wrap","xmlns","slot"]),U=i(["accent-height","accumulate","additive","alignment-baseline","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),P=i(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),F=i(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),H=a(/\{\{[\w\W]*|[\w\W]*\}\}/gm),z=a(/<%[\w\W]*|[\w\W]*%>/gm),B=a(/\${[\w\W]*}/gm),W=a(/^data-[\-\w.\u00B7-\uFFFF]/),G=a(/^aria-[\-\w]+$/),Y=a(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),j=a(/^(?:\w+script|data):/i),X=a(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),q=a(/^html$/i),$=a(/^[a-z][.\w]*(-[.\w]+)+$/i);var K=Object.freeze({__proto__:null,MUSTACHE_EXPR:H,ERB_EXPR:z,TMPLIT_EXPR:B,DATA_ATTR:W,ARIA_ATTR:G,IS_ALLOWED_URI:Y,IS_SCRIPT_OR_DATA:j,ATTR_WHITESPACE:X,DOCTYPE_NAME:q,CUSTOM_ELEMENT:$});const V=1,Z=3,J=7,Q=8,ee=9,te=function(){return"undefined"==typeof window?null:window};var ne=function t(){let n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:te();const o=e=>t(e);if(o.version="3.1.6",o.removed=[],!n||!n.document||n.document.nodeType!==ee)return o.isSupported=!1,o;let{document:r}=n;const a=r,c=a.currentScript,{DocumentFragment:s,HTMLTemplateElement:N,Node:b,Element:R,NodeFilter:H,NamedNodeMap:z=n.NamedNodeMap||n.MozNamedAttrMap,HTMLFormElement:B,DOMParser:W,trustedTypes:G}=n,j=R.prototype,X=C(j,"cloneNode"),$=C(j,"remove"),ne=C(j,"nextSibling"),oe=C(j,"childNodes"),re=C(j,"parentNode");if("function"==typeof N){const e=r.createElement("template");e.content&&e.content.ownerDocument&&(r=e.content.ownerDocument)}let ie,ae="";const{implementation:le,createNodeIterator:ce,createDocumentFragment:se,getElementsByTagName:ue}=r,{importNode:me}=a;let pe={};o.isSupported="function"==typeof e&&"function"==typeof re&&le&&void 0!==le.createHTMLDocument;const{MUSTACHE_EXPR:fe,ERB_EXPR:de,TMPLIT_EXPR:he,DATA_ATTR:ge,ARIA_ATTR:Te,IS_SCRIPT_OR_DATA:ye,ATTR_WHITESPACE:Ee,CUSTOM_ELEMENT:_e}=K;let{IS_ALLOWED_URI:Ae}=K,Ne=null;const be=S({},[...L,...D,...v,...x,...M]);let Se=null;const Re=S({},[...I,...U,...P,...F]);let we=Object.seal(l(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),Ce=null,Le=null,De=!0,ve=!0,Oe=!1,xe=!0,ke=!1,Me=!0,Ie=!1,Ue=!1,Pe=!1,Fe=!1,He=!1,ze=!1,Be=!0,We=!1,Ge=!0,Ye=!1,je={},Xe=null;const qe=S({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let $e=null;const Ke=S({},["audio","video","img","source","image","track"]);let Ve=null;const Ze=S({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Je="http://www.w3.org/1998/Math/MathML",Qe="http://www.w3.org/2000/svg",et="http://www.w3.org/1999/xhtml";let tt=et,nt=!1,ot=null;const rt=S({},[Je,Qe,et],d);let it=null;const at=["application/xhtml+xml","text/html"];let lt=null,ct=null;const st=r.createElement("form"),ut=function(e){return e instanceof RegExp||e instanceof Function},mt=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!ct||ct!==e){if(e&&"object"==typeof e||(e={}),e=w(e),it=-1===at.indexOf(e.PARSER_MEDIA_TYPE)?"text/html":e.PARSER_MEDIA_TYPE,lt="application/xhtml+xml"===it?d:f,Ne=E(e,"ALLOWED_TAGS")?S({},e.ALLOWED_TAGS,lt):be,Se=E(e,"ALLOWED_ATTR")?S({},e.ALLOWED_ATTR,lt):Re,ot=E(e,"ALLOWED_NAMESPACES")?S({},e.ALLOWED_NAMESPACES,d):rt,Ve=E(e,"ADD_URI_SAFE_ATTR")?S(w(Ze),e.ADD_URI_SAFE_ATTR,lt):Ze,$e=E(e,"ADD_DATA_URI_TAGS")?S(w(Ke),e.ADD_DATA_URI_TAGS,lt):Ke,Xe=E(e,"FORBID_CONTENTS")?S({},e.FORBID_CONTENTS,lt):qe,Ce=E(e,"FORBID_TAGS")?S({},e.FORBID_TAGS,lt):{},Le=E(e,"FORBID_ATTR")?S({},e.FORBID_ATTR,lt):{},je=!!E(e,"USE_PROFILES")&&e.USE_PROFILES,De=!1!==e.ALLOW_ARIA_ATTR,ve=!1!==e.ALLOW_DATA_ATTR,Oe=e.ALLOW_UNKNOWN_PROTOCOLS||!1,xe=!1!==e.ALLOW_SELF_CLOSE_IN_ATTR,ke=e.SAFE_FOR_TEMPLATES||!1,Me=!1!==e.SAFE_FOR_XML,Ie=e.WHOLE_DOCUMENT||!1,Fe=e.RETURN_DOM||!1,He=e.RETURN_DOM_FRAGMENT||!1,ze=e.RETURN_TRUSTED_TYPE||!1,Pe=e.FORCE_BODY||!1,Be=!1!==e.SANITIZE_DOM,We=e.SANITIZE_NAMED_PROPS||!1,Ge=!1!==e.KEEP_CONTENT,Ye=e.IN_PLACE||!1,Ae=e.ALLOWED_URI_REGEXP||Y,tt=e.NAMESPACE||et,we=e.CUSTOM_ELEMENT_HANDLING||{},e.CUSTOM_ELEMENT_HANDLING&&ut(e.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(we.tagNameCheck=e.CUSTOM_ELEMENT_HANDLING.tagNameCheck),e.CUSTOM_ELEMENT_HANDLING&&ut(e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(we.attributeNameCheck=e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),e.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(we.allowCustomizedBuiltInElements=e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),ke&&(ve=!1),He&&(Fe=!0),je&&(Ne=S({},M),Se=[],!0===je.html&&(S(Ne,L),S(Se,I)),!0===je.svg&&(S(Ne,D),S(Se,U),S(Se,F)),!0===je.svgFilters&&(S(Ne,v),S(Se,U),S(Se,F)),!0===je.mathMl&&(S(Ne,x),S(Se,P),S(Se,F))),e.ADD_TAGS&&(Ne===be&&(Ne=w(Ne)),S(Ne,e.ADD_TAGS,lt)),e.ADD_ATTR&&(Se===Re&&(Se=w(Se)),S(Se,e.ADD_ATTR,lt)),e.ADD_URI_SAFE_ATTR&&S(Ve,e.ADD_URI_SAFE_ATTR,lt),e.FORBID_CONTENTS&&(Xe===qe&&(Xe=w(Xe)),S(Xe,e.FORBID_CONTENTS,lt)),Ge&&(Ne["#text"]=!0),Ie&&S(Ne,["html","head","body"]),Ne.table&&(S(Ne,["tbody"]),delete Ce.tbody),e.TRUSTED_TYPES_POLICY){if("function"!=typeof e.TRUSTED_TYPES_POLICY.createHTML)throw A('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof e.TRUSTED_TYPES_POLICY.createScriptURL)throw A('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');ie=e.TRUSTED_TYPES_POLICY,ae=ie.createHTML("")}else void 0===ie&&(ie=function(e,t){if("object"!=typeof e||"function"!=typeof e.createPolicy)return null;let n=null;const o="data-tt-policy-suffix";t&&t.hasAttribute(o)&&(n=t.getAttribute(o));const r="dompurify"+(n?"#"+n:"");try{return e.createPolicy(r,{createHTML:e=>e,createScriptURL:e=>e})}catch(e){return console.warn("TrustedTypes policy "+r+" could not be created."),null}}(G,c)),null!==ie&&"string"==typeof ae&&(ae=ie.createHTML(""));i&&i(e),ct=e}},pt=S({},["mi","mo","mn","ms","mtext"]),ft=S({},["foreignobject","annotation-xml"]),dt=S({},["title","style","font","a","script"]),ht=S({},[...D,...v,...O]),gt=S({},[...x,...k]),Tt=function(e){p(o.removed,{element:e});try{re(e).removeChild(e)}catch(t){$(e)}},yt=function(e,t){try{p(o.removed,{attribute:t.getAttributeNode(e),from:t})}catch(e){p(o.removed,{attribute:null,from:t})}if(t.removeAttribute(e),"is"===e&&!Se[e])if(Fe||He)try{Tt(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},Et=function(e){let t=null,n=null;if(Pe)e="<remove></remove>"+e;else{const t=h(e,/^[\r\n\t ]+/);n=t&&t[0]}"application/xhtml+xml"===it&&tt===et&&(e='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+e+"</body></html>");const o=ie?ie.createHTML(e):e;if(tt===et)try{t=(new W).parseFromString(o,it)}catch(e){}if(!t||!t.documentElement){t=le.createDocument(tt,"template",null);try{t.documentElement.innerHTML=nt?ae:o}catch(e){}}const i=t.body||t.documentElement;return e&&n&&i.insertBefore(r.createTextNode(n),i.childNodes[0]||null),tt===et?ue.call(t,Ie?"html":"body")[0]:Ie?t.documentElement:i},_t=function(e){return ce.call(e.ownerDocument||e,e,H.SHOW_ELEMENT|H.SHOW_COMMENT|H.SHOW_TEXT|H.SHOW_PROCESSING_INSTRUCTION|H.SHOW_CDATA_SECTION,null)},At=function(e){return e instanceof B&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||!(e.attributes instanceof z)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore||"function"!=typeof e.hasChildNodes)},Nt=function(e){return"function"==typeof b&&e instanceof b},bt=function(e,t,n){pe[e]&&u(pe[e],(e=>{e.call(o,t,n,ct)}))},St=function(e){let t=null;if(bt("beforeSanitizeElements",e,null),At(e))return Tt(e),!0;const n=lt(e.nodeName);if(bt("uponSanitizeElement",e,{tagName:n,allowedTags:Ne}),e.hasChildNodes()&&!Nt(e.firstElementChild)&&_(/<[/\w]/g,e.innerHTML)&&_(/<[/\w]/g,e.textContent))return Tt(e),!0;if(e.nodeType===J)return Tt(e),!0;if(Me&&e.nodeType===Q&&_(/<[/\w]/g,e.data))return Tt(e),!0;if(!Ne[n]||Ce[n]){if(!Ce[n]&&wt(n)){if(we.tagNameCheck instanceof RegExp&&_(we.tagNameCheck,n))return!1;if(we.tagNameCheck instanceof Function&&we.tagNameCheck(n))return!1}if(Ge&&!Xe[n]){const t=re(e)||e.parentNode,n=oe(e)||e.childNodes;if(n&&t){for(let o=n.length-1;o>=0;--o){const r=X(n[o],!0);r.__removalCount=(e.__removalCount||0)+1,t.insertBefore(r,ne(e))}}}return Tt(e),!0}return e instanceof R&&!function(e){let t=re(e);t&&t.tagName||(t={namespaceURI:tt,tagName:"template"});const n=f(e.tagName),o=f(t.tagName);return!!ot[e.namespaceURI]&&(e.namespaceURI===Qe?t.namespaceURI===et?"svg"===n:t.namespaceURI===Je?"svg"===n&&("annotation-xml"===o||pt[o]):Boolean(ht[n]):e.namespaceURI===Je?t.namespaceURI===et?"math"===n:t.namespaceURI===Qe?"math"===n&&ft[o]:Boolean(gt[n]):e.namespaceURI===et?!(t.namespaceURI===Qe&&!ft[o])&&!(t.namespaceURI===Je&&!pt[o])&&!gt[n]&&(dt[n]||!ht[n]):!("application/xhtml+xml"!==it||!ot[e.namespaceURI]))}(e)?(Tt(e),!0):"noscript"!==n&&"noembed"!==n&&"noframes"!==n||!_(/<\/no(script|embed|frames)/i,e.innerHTML)?(ke&&e.nodeType===Z&&(t=e.textContent,u([fe,de,he],(e=>{t=g(t,e," ")})),e.textContent!==t&&(p(o.removed,{element:e.cloneNode()}),e.textContent=t)),bt("afterSanitizeElements",e,null),!1):(Tt(e),!0)},Rt=function(e,t,n){if(Be&&("id"===t||"name"===t)&&(n in r||n in st))return!1;if(ve&&!Le[t]&&_(ge,t));else if(De&&_(Te,t));else if(!Se[t]||Le[t]){if(!(wt(e)&&(we.tagNameCheck instanceof RegExp&&_(we.tagNameCheck,e)||we.tagNameCheck instanceof Function&&we.tagNameCheck(e))&&(we.attributeNameCheck instanceof RegExp&&_(we.attributeNameCheck,t)||we.attributeNameCheck instanceof Function&&we.attributeNameCheck(t))||"is"===t&&we.allowCustomizedBuiltInElements&&(we.tagNameCheck instanceof RegExp&&_(we.tagNameCheck,n)||we.tagNameCheck instanceof Function&&we.tagNameCheck(n))))return!1}else if(Ve[t]);else if(_(Ae,g(n,Ee,"")));else if("src"!==t&&"xlink:href"!==t&&"href"!==t||"script"===e||0!==T(n,"data:")||!$e[e]){if(Oe&&!_(ye,g(n,Ee,"")));else if(n)return!1}else;return!0},wt=function(e){return"annotation-xml"!==e&&h(e,_e)},Ct=function(e){bt("beforeSanitizeAttributes",e,null);const{attributes:t}=e;if(!t)return;const n={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:Se};let r=t.length;for(;r--;){const i=t[r],{name:a,namespaceURI:l,value:c}=i,s=lt(a);let p="value"===a?c:y(c);if(n.attrName=s,n.attrValue=p,n.keepAttr=!0,n.forceKeepAttr=void 0,bt("uponSanitizeAttribute",e,n),p=n.attrValue,Me&&_(/((--!?|])>)|<\/(style|title)/i,p)){yt(a,e);continue}if(n.forceKeepAttr)continue;if(yt(a,e),!n.keepAttr)continue;if(!xe&&_(/\/>/i,p)){yt(a,e);continue}ke&&u([fe,de,he],(e=>{p=g(p,e," ")}));const f=lt(e.nodeName);if(Rt(f,s,p)){if(!We||"id"!==s&&"name"!==s||(yt(a,e),p="user-content-"+p),ie&&"object"==typeof G&&"function"==typeof G.getAttributeType)if(l);else switch(G.getAttributeType(f,s)){case"TrustedHTML":p=ie.createHTML(p);break;case"TrustedScriptURL":p=ie.createScriptURL(p)}try{l?e.setAttributeNS(l,a,p):e.setAttribute(a,p),At(e)?Tt(e):m(o.removed)}catch(e){}}}bt("afterSanitizeAttributes",e,null)},Lt=function e(t){let n=null;const o=_t(t);for(bt("beforeSanitizeShadowDOM",t,null);n=o.nextNode();)bt("uponSanitizeShadowNode",n,null),St(n)||(n.content instanceof s&&e(n.content),Ct(n));bt("afterSanitizeShadowDOM",t,null)};return o.sanitize=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=null,r=null,i=null,l=null;if(nt=!e,nt&&(e="\x3c!--\x3e"),"string"!=typeof e&&!Nt(e)){if("function"!=typeof e.toString)throw A("toString is not a function");if("string"!=typeof(e=e.toString()))throw A("dirty is not a string, aborting")}if(!o.isSupported)return e;if(Ue||mt(t),o.removed=[],"string"==typeof e&&(Ye=!1),Ye){if(e.nodeName){const t=lt(e.nodeName);if(!Ne[t]||Ce[t])throw A("root node is forbidden and cannot be sanitized in-place")}}else if(e instanceof b)n=Et("\x3c!----\x3e"),r=n.ownerDocument.importNode(e,!0),r.nodeType===V&&"BODY"===r.nodeName||"HTML"===r.nodeName?n=r:n.appendChild(r);else{if(!Fe&&!ke&&!Ie&&-1===e.indexOf("<"))return ie&&ze?ie.createHTML(e):e;if(n=Et(e),!n)return Fe?null:ze?ae:""}n&&Pe&&Tt(n.firstChild);const c=_t(Ye?e:n);for(;i=c.nextNode();)St(i)||(i.content instanceof s&&Lt(i.content),Ct(i));if(Ye)return e;if(Fe){if(He)for(l=se.call(n.ownerDocument);n.firstChild;)l.appendChild(n.firstChild);else l=n;return(Se.shadowroot||Se.shadowrootmode)&&(l=me.call(a,l,!0)),l}let m=Ie?n.outerHTML:n.innerHTML;return Ie&&Ne["!doctype"]&&n.ownerDocument&&n.ownerDocument.doctype&&n.ownerDocument.doctype.name&&_(q,n.ownerDocument.doctype.name)&&(m="<!DOCTYPE "+n.ownerDocument.doctype.name+">\n"+m),ke&&u([fe,de,he],(e=>{m=g(m,e," ")})),ie&&ze?ie.createHTML(m):m},o.setConfig=function(){mt(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),Ue=!0},o.clearConfig=function(){ct=null,Ue=!1},o.isValidAttribute=function(e,t,n){ct||mt({});const o=lt(e),r=lt(t);return Rt(o,r,n)},o.addHook=function(e,t){"function"==typeof t&&(pe[e]=pe[e]||[],p(pe[e],t))},o.removeHook=function(e){if(pe[e])return m(pe[e])},o.removeHooks=function(e){pe[e]&&(pe[e]=[])},o.removeAllHooks=function(){pe={}},o}();return ne}));
3 +//# sourceMappingURL=purify.min.js.map
public/scripts/purify.js new
+1563
@@ -0,0 +1,1563 @@
1 +/*! @license DOMPurify 3.1.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.1.6/LICENSE */
2 +
3 +(function (global, factory) {
4 + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
5 + typeof define === 'function' && define.amd ? define(factory) :
6 + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.DOMPurify = factory());
7 + })(this, (function () { 'use strict';
8 +
9 + const {
10 + entries,
11 + setPrototypeOf,
12 + isFrozen,
13 + getPrototypeOf,
14 + getOwnPropertyDescriptor
15 + } = Object;
16 + let {
17 + freeze,
18 + seal,
19 + create
20 + } = Object; // eslint-disable-line import/no-mutable-exports
21 + let {
22 + apply,
23 + construct
24 + } = typeof Reflect !== 'undefined' && Reflect;
25 + if (!freeze) {
26 + freeze = function freeze(x) {
27 + return x;
28 + };
29 + }
30 + if (!seal) {
31 + seal = function seal(x) {
32 + return x;
33 + };
34 + }
35 + if (!apply) {
36 + apply = function apply(fun, thisValue, args) {
37 + return fun.apply(thisValue, args);
38 + };
39 + }
40 + if (!construct) {
41 + construct = function construct(Func, args) {
42 + return new Func(...args);
43 + };
44 + }
45 + const arrayForEach = unapply(Array.prototype.forEach);
46 + const arrayPop = unapply(Array.prototype.pop);
47 + const arrayPush = unapply(Array.prototype.push);
48 + const stringToLowerCase = unapply(String.prototype.toLowerCase);
49 + const stringToString = unapply(String.prototype.toString);
50 + const stringMatch = unapply(String.prototype.match);
51 + const stringReplace = unapply(String.prototype.replace);
52 + const stringIndexOf = unapply(String.prototype.indexOf);
53 + const stringTrim = unapply(String.prototype.trim);
54 + const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
55 + const regExpTest = unapply(RegExp.prototype.test);
56 + const typeErrorCreate = unconstruct(TypeError);
57 +
58 + /**
59 + * Creates a new function that calls the given function with a specified thisArg and arguments.
60 + *
61 + * @param {Function} func - The function to be wrapped and called.
62 + * @returns {Function} A new function that calls the given function with a specified thisArg and arguments.
63 + */
64 + function unapply(func) {
65 + return function (thisArg) {
66 + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
67 + args[_key - 1] = arguments[_key];
68 + }
69 + return apply(func, thisArg, args);
70 + };
71 + }
72 +
73 + /**
74 + * Creates a new function that constructs an instance of the given constructor function with the provided arguments.
75 + *
76 + * @param {Function} func - The constructor function to be wrapped and called.
77 + * @returns {Function} A new function that constructs an instance of the given constructor function with the provided arguments.
78 + */
79 + function unconstruct(func) {
80 + return function () {
81 + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
82 + args[_key2] = arguments[_key2];
83 + }
84 + return construct(func, args);
85 + };
86 + }
87 +
88 + /**
89 + * Add properties to a lookup table
90 + *
91 + * @param {Object} set - The set to which elements will be added.
92 + * @param {Array} array - The array containing elements to be added to the set.
93 + * @param {Function} transformCaseFunc - An optional function to transform the case of each element before adding to the set.
94 + * @returns {Object} The modified set with added elements.
95 + */
96 + function addToSet(set, array) {
97 + let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase;
98 + if (setPrototypeOf) {
99 + // Make 'in' and truthy checks like Boolean(set.constructor)
100 + // independent of any properties defined on Object.prototype.
101 + // Prevent prototype setters from intercepting set as a this value.
102 + setPrototypeOf(set, null);
103 + }
104 + let l = array.length;
105 + while (l--) {
106 + let element = array[l];
107 + if (typeof element === 'string') {
108 + const lcElement = transformCaseFunc(element);
109 + if (lcElement !== element) {
110 + // Config presets (e.g. tags.js, attrs.js) are immutable.
111 + if (!isFrozen(array)) {
112 + array[l] = lcElement;
113 + }
114 + element = lcElement;
115 + }
116 + }
117 + set[element] = true;
118 + }
119 + return set;
120 + }
121 +
122 + /**
123 + * Clean up an array to harden against CSPP
124 + *
125 + * @param {Array} array - The array to be cleaned.
126 + * @returns {Array} The cleaned version of the array
127 + */
128 + function cleanArray(array) {
129 + for (let index = 0; index < array.length; index++) {
130 + const isPropertyExist = objectHasOwnProperty(array, index);
131 + if (!isPropertyExist) {
132 + array[index] = null;
133 + }
134 + }
135 + return array;
136 + }
137 +
138 + /**
139 + * Shallow clone an object
140 + *
141 + * @param {Object} object - The object to be cloned.
142 + * @returns {Object} A new object that copies the original.
143 + */
144 + function clone(object) {
145 + const newObject = create(null);
146 + for (const [property, value] of entries(object)) {
147 + const isPropertyExist = objectHasOwnProperty(object, property);
148 + if (isPropertyExist) {
149 + if (Array.isArray(value)) {
150 + newObject[property] = cleanArray(value);
151 + } else if (value && typeof value === 'object' && value.constructor === Object) {
152 + newObject[property] = clone(value);
153 + } else {
154 + newObject[property] = value;
155 + }
156 + }
157 + }
158 + return newObject;
159 + }
160 +
161 + /**
162 + * This method automatically checks if the prop is function or getter and behaves accordingly.
163 + *
164 + * @param {Object} object - The object to look up the getter function in its prototype chain.
165 + * @param {String} prop - The property name for which to find the getter function.
166 + * @returns {Function} The getter function found in the prototype chain or a fallback function.
167 + */
168 + function lookupGetter(object, prop) {
169 + while (object !== null) {
170 + const desc = getOwnPropertyDescriptor(object, prop);
171 + if (desc) {
172 + if (desc.get) {
173 + return unapply(desc.get);
174 + }
175 + if (typeof desc.value === 'function') {
176 + return unapply(desc.value);
177 + }
178 + }
179 + object = getPrototypeOf(object);
180 + }
181 + function fallbackValue() {
182 + return null;
183 + }
184 + return fallbackValue;
185 + }
186 +
187 + const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);
188 +
189 + // SVG
190 + const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
191 + const svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);
192 +
193 + // List of SVG elements that are disallowed by default.
194 + // We still need to know them so that we can do namespace
195 + // checks properly in case one wants to add them to
196 + // allow-list.
197 + const svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']);
198 + const mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']);
199 +
200 + // Similarly to SVG, we want to know all MathML elements,
201 + // even those that we disallow by default.
202 + const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
203 + const text = freeze(['#text']);
204 +
205 + const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns', 'slot']);
206 + const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
207 + const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);
208 + const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
209 +
210 + // eslint-disable-next-line unicorn/better-regex
211 + const MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
212 + const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm);
213 + const TMPLIT_EXPR = seal(/\${[\w\W]*}/gm);
214 + const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]/); // eslint-disable-line no-useless-escape
215 + const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
216 + const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
217 + );
218 + const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
219 + const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
220 + );
221 + const DOCTYPE_NAME = seal(/^html$/i);
222 + const CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
223 +
224 + var EXPRESSIONS = /*#__PURE__*/Object.freeze({
225 + __proto__: null,
226 + MUSTACHE_EXPR: MUSTACHE_EXPR,
227 + ERB_EXPR: ERB_EXPR,
228 + TMPLIT_EXPR: TMPLIT_EXPR,
229 + DATA_ATTR: DATA_ATTR,
230 + ARIA_ATTR: ARIA_ATTR,
231 + IS_ALLOWED_URI: IS_ALLOWED_URI,
232 + IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,
233 + ATTR_WHITESPACE: ATTR_WHITESPACE,
234 + DOCTYPE_NAME: DOCTYPE_NAME,
235 + CUSTOM_ELEMENT: CUSTOM_ELEMENT
236 + });
237 +
238 + // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
239 + const NODE_TYPE = {
240 + element: 1,
241 + attribute: 2,
242 + text: 3,
243 + cdataSection: 4,
244 + entityReference: 5,
245 + // Deprecated
246 + entityNode: 6,
247 + // Deprecated
248 + progressingInstruction: 7,
249 + comment: 8,
250 + document: 9,
251 + documentType: 10,
252 + documentFragment: 11,
253 + notation: 12 // Deprecated
254 + };
255 + const getGlobal = function getGlobal() {
256 + return typeof window === 'undefined' ? null : window;
257 + };
258 +
259 + /**
260 + * Creates a no-op policy for internal use only.
261 + * Don't export this function outside this module!
262 + * @param {TrustedTypePolicyFactory} trustedTypes The policy factory.
263 + * @param {HTMLScriptElement} purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).
264 + * @return {TrustedTypePolicy} The policy created (or null, if Trusted Types
265 + * are not supported or creating the policy failed).
266 + */
267 + const _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {
268 + if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') {
269 + return null;
270 + }
271 +
272 + // Allow the callers to control the unique policy name
273 + // by adding a data-tt-policy-suffix to the script element with the DOMPurify.
274 + // Policy creation with duplicate names throws in Trusted Types.
275 + let suffix = null;
276 + const ATTR_NAME = 'data-tt-policy-suffix';
277 + if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {
278 + suffix = purifyHostElement.getAttribute(ATTR_NAME);
279 + }
280 + const policyName = 'dompurify' + (suffix ? '#' + suffix : '');
281 + try {
282 + return trustedTypes.createPolicy(policyName, {
283 + createHTML(html) {
284 + return html;
285 + },
286 + createScriptURL(scriptUrl) {
287 + return scriptUrl;
288 + }
289 + });
290 + } catch (_) {
291 + // Policy creation failed (most likely another DOMPurify script has
292 + // already run). Skip creating the policy, as this will only cause errors
293 + // if TT are enforced.
294 + console.warn('TrustedTypes policy ' + policyName + ' could not be created.');
295 + return null;
296 + }
297 + };
298 + function createDOMPurify() {
299 + let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
300 + const DOMPurify = root => createDOMPurify(root);
301 +
302 + /**
303 + * Version label, exposed for easier checks
304 + * if DOMPurify is up to date or not
305 + */
306 + DOMPurify.version = '3.1.6';
307 +
308 + /**
309 + * Array of elements that DOMPurify removed during sanitation.
310 + * Empty if nothing was removed.
311 + */
312 + DOMPurify.removed = [];
313 + if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document) {
314 + // Not running in a browser, provide a factory function
315 + // so that you can pass your own Window
316 + DOMPurify.isSupported = false;
317 + return DOMPurify;
318 + }
319 + let {
320 + document
321 + } = window;
322 + const originalDocument = document;
323 + const currentScript = originalDocument.currentScript;
324 + const {
325 + DocumentFragment,
326 + HTMLTemplateElement,
327 + Node,
328 + Element,
329 + NodeFilter,
330 + NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,
331 + HTMLFormElement,
332 + DOMParser,
333 + trustedTypes
334 + } = window;
335 + const ElementPrototype = Element.prototype;
336 + const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');
337 + const remove = lookupGetter(ElementPrototype, 'remove');
338 + const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');
339 + const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');
340 + const getParentNode = lookupGetter(ElementPrototype, 'parentNode');
341 +
342 + // As per issue #47, the web-components registry is inherited by a
343 + // new document created via createHTMLDocument. As per the spec
344 + // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)
345 + // a new empty registry is used when creating a template contents owner
346 + // document, so we use that as our parent document to ensure nothing
347 + // is inherited.
348 + if (typeof HTMLTemplateElement === 'function') {
349 + const template = document.createElement('template');
350 + if (template.content && template.content.ownerDocument) {
351 + document = template.content.ownerDocument;
352 + }
353 + }
354 + let trustedTypesPolicy;
355 + let emptyHTML = '';
356 + const {
357 + implementation,
358 + createNodeIterator,
359 + createDocumentFragment,
360 + getElementsByTagName
361 + } = document;
362 + const {
363 + importNode
364 + } = originalDocument;
365 + let hooks = {};
366 +
367 + /**
368 + * Expose whether this browser supports running the full DOMPurify.
369 + */
370 + DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;
371 + const {
372 + MUSTACHE_EXPR,
373 + ERB_EXPR,
374 + TMPLIT_EXPR,
375 + DATA_ATTR,
376 + ARIA_ATTR,
377 + IS_SCRIPT_OR_DATA,
378 + ATTR_WHITESPACE,
379 + CUSTOM_ELEMENT
380 + } = EXPRESSIONS;
381 + let {
382 + IS_ALLOWED_URI: IS_ALLOWED_URI$1
383 + } = EXPRESSIONS;
384 +
385 + /**
386 + * We consider the elements and attributes below to be safe. Ideally
387 + * don't add any new ones but feel free to remove unwanted ones.
388 + */
389 +
390 + /* allowed element names */
391 + let ALLOWED_TAGS = null;
392 + const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);
393 +
394 + /* Allowed attribute names */
395 + let ALLOWED_ATTR = null;
396 + const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);
397 +
398 + /*
399 + * Configure how DOMPUrify should handle custom elements and their attributes as well as customized built-in elements.
400 + * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)
401 + * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)
402 + * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.
403 + */
404 + let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
405 + tagNameCheck: {
406 + writable: true,
407 + configurable: false,
408 + enumerable: true,
409 + value: null
410 + },
411 + attributeNameCheck: {
412 + writable: true,
413 + configurable: false,
414 + enumerable: true,
415 + value: null
416 + },
417 + allowCustomizedBuiltInElements: {
418 + writable: true,
419 + configurable: false,
420 + enumerable: true,
421 + value: false
422 + }
423 + }));
424 +
425 + /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
426 + let FORBID_TAGS = null;
427 +
428 + /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
429 + let FORBID_ATTR = null;
430 +
431 + /* Decide if ARIA attributes are okay */
432 + let ALLOW_ARIA_ATTR = true;
433 +
434 + /* Decide if custom data attributes are okay */
435 + let ALLOW_DATA_ATTR = true;
436 +
437 + /* Decide if unknown protocols are okay */
438 + let ALLOW_UNKNOWN_PROTOCOLS = false;
439 +
440 + /* Decide if self-closing tags in attributes are allowed.
441 + * Usually removed due to a mXSS issue in jQuery 3.0 */
442 + let ALLOW_SELF_CLOSE_IN_ATTR = true;
443 +
444 + /* Output should be safe for common template engines.
445 + * This means, DOMPurify removes data attributes, mustaches and ERB
446 + */
447 + let SAFE_FOR_TEMPLATES = false;
448 +
449 + /* Output should be safe even for XML used within HTML and alike.
450 + * This means, DOMPurify removes comments when containing risky content.
451 + */
452 + let SAFE_FOR_XML = true;
453 +
454 + /* Decide if document with <html>... should be returned */
455 + let WHOLE_DOCUMENT = false;
456 +
457 + /* Track whether config is already set on this instance of DOMPurify. */
458 + let SET_CONFIG = false;
459 +
460 + /* Decide if all elements (e.g. style, script) must be children of
461 + * document.body. By default, browsers might move them to document.head */
462 + let FORCE_BODY = false;
463 +
464 + /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html
465 + * string (or a TrustedHTML object if Trusted Types are supported).
466 + * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead
467 + */
468 + let RETURN_DOM = false;
469 +
470 + /* Decide if a DOM `DocumentFragment` should be returned, instead of a html
471 + * string (or a TrustedHTML object if Trusted Types are supported) */
472 + let RETURN_DOM_FRAGMENT = false;
473 +
474 + /* Try to return a Trusted Type object instead of a string, return a string in
475 + * case Trusted Types are not supported */
476 + let RETURN_TRUSTED_TYPE = false;
477 +
478 + /* Output should be free from DOM clobbering attacks?
479 + * This sanitizes markups named with colliding, clobberable built-in DOM APIs.
480 + */
481 + let SANITIZE_DOM = true;
482 +
483 + /* Achieve full DOM Clobbering protection by isolating the namespace of named
484 + * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.
485 + *
486 + * HTML/DOM spec rules that enable DOM Clobbering:
487 + * - Named Access on Window (§7.3.3)
488 + * - DOM Tree Accessors (§3.1.5)
489 + * - Form Element Parent-Child Relations (§4.10.3)
490 + * - Iframe srcdoc / Nested WindowProxies (§4.8.5)
491 + * - HTMLCollection (§4.2.10.2)
492 + *
493 + * Namespace isolation is implemented by prefixing `id` and `name` attributes
494 + * with a constant string, i.e., `user-content-`
495 + */
496 + let SANITIZE_NAMED_PROPS = false;
497 + const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';
498 +
499 + /* Keep element content when removing element? */
500 + let KEEP_CONTENT = true;
501 +
502 + /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead
503 + * of importing it into a new Document and returning a sanitized copy */
504 + let IN_PLACE = false;
505 +
506 + /* Allow usage of profiles like html, svg and mathMl */
507 + let USE_PROFILES = {};
508 +
509 + /* Tags to ignore content of when KEEP_CONTENT is true */
510 + let FORBID_CONTENTS = null;
511 + const DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']);
512 +
513 + /* Tags that are safe for data: URIs */
514 + let DATA_URI_TAGS = null;
515 + const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);
516 +
517 + /* Attributes safe for values like "javascript:" */
518 + let URI_SAFE_ATTRIBUTES = null;
519 + const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);
520 + const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
521 + const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
522 + const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
523 + /* Document namespace */
524 + let NAMESPACE = HTML_NAMESPACE;
525 + let IS_EMPTY_INPUT = false;
526 +
527 + /* Allowed XHTML+XML namespaces */
528 + let ALLOWED_NAMESPACES = null;
529 + const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
530 +
531 + /* Parsing of strict XHTML documents */
532 + let PARSER_MEDIA_TYPE = null;
533 + const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
534 + const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
535 + let transformCaseFunc = null;
536 +
537 + /* Keep a reference to config to pass to hooks */
538 + let CONFIG = null;
539 +
540 + /* Ideally, do not touch anything below this line */
541 + /* ______________________________________________ */
542 +
543 + const formElement = document.createElement('form');
544 + const isRegexOrFunction = function isRegexOrFunction(testValue) {
545 + return testValue instanceof RegExp || testValue instanceof Function;
546 + };
547 +
548 + /**
549 + * _parseConfig
550 + *
551 + * @param {Object} cfg optional config literal
552 + */
553 + // eslint-disable-next-line complexity
554 + const _parseConfig = function _parseConfig() {
555 + let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
556 + if (CONFIG && CONFIG === cfg) {
557 + return;
558 + }
559 +
560 + /* Shield configuration object from tampering */
561 + if (!cfg || typeof cfg !== 'object') {
562 + cfg = {};
563 + }
564 +
565 + /* Shield configuration object from prototype pollution */
566 + cfg = clone(cfg);
567 + PARSER_MEDIA_TYPE =
568 + // eslint-disable-next-line unicorn/prefer-includes
569 + SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
570 +
571 + // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
572 + transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;
573 +
574 + /* Set configuration parameters */
575 + ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
576 + ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
577 + ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
578 + URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES),
579 + // eslint-disable-line indent
580 + cfg.ADD_URI_SAFE_ATTR,
581 + // eslint-disable-line indent
582 + transformCaseFunc // eslint-disable-line indent
583 + ) // eslint-disable-line indent
584 + : DEFAULT_URI_SAFE_ATTRIBUTES;
585 + DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS),
586 + // eslint-disable-line indent
587 + cfg.ADD_DATA_URI_TAGS,
588 + // eslint-disable-line indent
589 + transformCaseFunc // eslint-disable-line indent
590 + ) // eslint-disable-line indent
591 + : DEFAULT_DATA_URI_TAGS;
592 + FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
593 + FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {};
594 + FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};
595 + USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false;
596 + ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
597 + ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
598 + ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
599 + ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true
600 + SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false
601 + SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true
602 + WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
603 + RETURN_DOM = cfg.RETURN_DOM || false; // Default false
604 + RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
605 + RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false
606 + FORCE_BODY = cfg.FORCE_BODY || false; // Default false
607 + SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
608 + SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false
609 + KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
610 + IN_PLACE = cfg.IN_PLACE || false; // Default false
611 + IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;
612 + NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;
613 + CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};
614 + if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) {
615 + CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;
616 + }
617 + if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) {
618 + CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;
619 + }
620 + if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') {
621 + CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;
622 + }
623 + if (SAFE_FOR_TEMPLATES) {
624 + ALLOW_DATA_ATTR = false;
625 + }
626 + if (RETURN_DOM_FRAGMENT) {
627 + RETURN_DOM = true;
628 + }
629 +
630 + /* Parse profile info */
631 + if (USE_PROFILES) {
632 + ALLOWED_TAGS = addToSet({}, text);
633 + ALLOWED_ATTR = [];
634 + if (USE_PROFILES.html === true) {
635 + addToSet(ALLOWED_TAGS, html$1);
636 + addToSet(ALLOWED_ATTR, html);
637 + }
638 + if (USE_PROFILES.svg === true) {
639 + addToSet(ALLOWED_TAGS, svg$1);
640 + addToSet(ALLOWED_ATTR, svg);
641 + addToSet(ALLOWED_ATTR, xml);
642 + }
643 + if (USE_PROFILES.svgFilters === true) {
644 + addToSet(ALLOWED_TAGS, svgFilters);
645 + addToSet(ALLOWED_ATTR, svg);
646 + addToSet(ALLOWED_ATTR, xml);
647 + }
648 + if (USE_PROFILES.mathMl === true) {
649 + addToSet(ALLOWED_TAGS, mathMl$1);
650 + addToSet(ALLOWED_ATTR, mathMl);
651 + addToSet(ALLOWED_ATTR, xml);
652 + }
653 + }
654 +
655 + /* Merge configuration parameters */
656 + if (cfg.ADD_TAGS) {
657 + if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
658 + ALLOWED_TAGS = clone(ALLOWED_TAGS);
659 + }
660 + addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
661 + }
662 + if (cfg.ADD_ATTR) {
663 + if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
664 + ALLOWED_ATTR = clone(ALLOWED_ATTR);
665 + }
666 + addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
667 + }
668 + if (cfg.ADD_URI_SAFE_ATTR) {
669 + addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
670 + }
671 + if (cfg.FORBID_CONTENTS) {
672 + if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
673 + FORBID_CONTENTS = clone(FORBID_CONTENTS);
674 + }
675 + addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
676 + }
677 +
678 + /* Add #text in case KEEP_CONTENT is set to true */
679 + if (KEEP_CONTENT) {
680 + ALLOWED_TAGS['#text'] = true;
681 + }
682 +
683 + /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */
684 + if (WHOLE_DOCUMENT) {
685 + addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);
686 + }
687 +
688 + /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */
689 + if (ALLOWED_TAGS.table) {
690 + addToSet(ALLOWED_TAGS, ['tbody']);
691 + delete FORBID_TAGS.tbody;
692 + }
693 + if (cfg.TRUSTED_TYPES_POLICY) {
694 + if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {
695 + throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');
696 + }
697 + if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {
698 + throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
699 + }
700 +
701 + // Overwrite existing TrustedTypes policy.
702 + trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
703 +
704 + // Sign local variables required by `sanitize`.
705 + emptyHTML = trustedTypesPolicy.createHTML('');
706 + } else {
707 + // Uninitialized policy, attempt to initialize the internal dompurify policy.
708 + if (trustedTypesPolicy === undefined) {
709 + trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
710 + }
711 +
712 + // If creating the internal policy succeeded sign internal variables.
713 + if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {
714 + emptyHTML = trustedTypesPolicy.createHTML('');
715 + }
716 + }
717 +
718 + // Prevent further manipulation of configuration.
719 + // Not available in IE8, Safari 5, etc.
720 + if (freeze) {
721 + freeze(cfg);
722 + }
723 + CONFIG = cfg;
724 + };
725 + const MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']);
726 + const HTML_INTEGRATION_POINTS = addToSet({}, ['foreignobject', 'annotation-xml']);
727 +
728 + // Certain elements are allowed in both SVG and HTML
729 + // namespace. We need to specify them explicitly
730 + // so that they don't get erroneously deleted from
731 + // HTML namespace.
732 + const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);
733 +
734 + /* Keep track of all possible SVG and MathML tags
735 + * so that we can perform the namespace checks
736 + * correctly. */
737 + const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);
738 + const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
739 +
740 + /**
741 + * @param {Element} element a DOM element whose namespace is being checked
742 + * @returns {boolean} Return false if the element has a
743 + * namespace that a spec-compliant parser would never
744 + * return. Return true otherwise.
745 + */
746 + const _checkValidNamespace = function _checkValidNamespace(element) {
747 + let parent = getParentNode(element);
748 +
749 + // In JSDOM, if we're inside shadow DOM, then parentNode
750 + // can be null. We just simulate parent in this case.
751 + if (!parent || !parent.tagName) {
752 + parent = {
753 + namespaceURI: NAMESPACE,
754 + tagName: 'template'
755 + };
756 + }
757 + const tagName = stringToLowerCase(element.tagName);
758 + const parentTagName = stringToLowerCase(parent.tagName);
759 + if (!ALLOWED_NAMESPACES[element.namespaceURI]) {
760 + return false;
761 + }
762 + if (element.namespaceURI === SVG_NAMESPACE) {
763 + // The only way to switch from HTML namespace to SVG
764 + // is via <svg>. If it happens via any other tag, then
765 + // it should be killed.
766 + if (parent.namespaceURI === HTML_NAMESPACE) {
767 + return tagName === 'svg';
768 + }
769 +
770 + // The only way to switch from MathML to SVG is via`
771 + // svg if parent is either <annotation-xml> or MathML
772 + // text integration points.
773 + if (parent.namespaceURI === MATHML_NAMESPACE) {
774 + return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
775 + }
776 +
777 + // We only allow elements that are defined in SVG
778 + // spec. All others are disallowed in SVG namespace.
779 + return Boolean(ALL_SVG_TAGS[tagName]);
780 + }
781 + if (element.namespaceURI === MATHML_NAMESPACE) {
782 + // The only way to switch from HTML namespace to MathML
783 + // is via <math>. If it happens via any other tag, then
784 + // it should be killed.
785 + if (parent.namespaceURI === HTML_NAMESPACE) {
786 + return tagName === 'math';
787 + }
788 +
789 + // The only way to switch from SVG to MathML is via
790 + // <math> and HTML integration points
791 + if (parent.namespaceURI === SVG_NAMESPACE) {
792 + return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];
793 + }
794 +
795 + // We only allow elements that are defined in MathML
796 + // spec. All others are disallowed in MathML namespace.
797 + return Boolean(ALL_MATHML_TAGS[tagName]);
798 + }
799 + if (element.namespaceURI === HTML_NAMESPACE) {
800 + // The only way to switch from SVG to HTML is via
801 + // HTML integration points, and from MathML to HTML
802 + // is via MathML text integration points
803 + if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
804 + return false;
805 + }
806 + if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
807 + return false;
808 + }
809 +
810 + // We disallow tags that are specific for MathML
811 + // or SVG and should never appear in HTML namespace
812 + return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
813 + }
814 +
815 + // For XHTML and XML documents that support custom namespaces
816 + if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) {
817 + return true;
818 + }
819 +
820 + // The code should never reach this place (this means
821 + // that the element somehow got namespace that is not
822 + // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).
823 + // Return false just in case.
824 + return false;
825 + };
826 +
827 + /**
828 + * _forceRemove
829 + *
830 + * @param {Node} node a DOM node
831 + */
832 + const _forceRemove = function _forceRemove(node) {
833 + arrayPush(DOMPurify.removed, {
834 + element: node
835 + });
836 + try {
837 + // eslint-disable-next-line unicorn/prefer-dom-node-remove
838 + getParentNode(node).removeChild(node);
839 + } catch (_) {
840 + remove(node);
841 + }
842 + };
843 +
844 + /**
845 + * _removeAttribute
846 + *
847 + * @param {String} name an Attribute name
848 + * @param {Node} node a DOM node
849 + */
850 + const _removeAttribute = function _removeAttribute(name, node) {
851 + try {
852 + arrayPush(DOMPurify.removed, {
853 + attribute: node.getAttributeNode(name),
854 + from: node
855 + });
856 + } catch (_) {
857 + arrayPush(DOMPurify.removed, {
858 + attribute: null,
859 + from: node
860 + });
861 + }
862 + node.removeAttribute(name);
863 +
864 + // We void attribute values for unremovable "is"" attributes
865 + if (name === 'is' && !ALLOWED_ATTR[name]) {
866 + if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
867 + try {
868 + _forceRemove(node);
869 + } catch (_) {}
870 + } else {
871 + try {
872 + node.setAttribute(name, '');
873 + } catch (_) {}
874 + }
875 + }
876 + };
877 +
878 + /**
879 + * _initDocument
880 + *
881 + * @param {String} dirty a string of dirty markup
882 + * @return {Document} a DOM, filled with the dirty markup
883 + */
884 + const _initDocument = function _initDocument(dirty) {
885 + /* Create a HTML document */
886 + let doc = null;
887 + let leadingWhitespace = null;
888 + if (FORCE_BODY) {
889 + dirty = '<remove></remove>' + dirty;
890 + } else {
891 + /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */
892 + const matches = stringMatch(dirty, /^[\r\n\t ]+/);
893 + leadingWhitespace = matches && matches[0];
894 + }
895 + if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) {
896 + // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)
897 + dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + '</body></html>';
898 + }
899 + const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
900 + /*
901 + * Use the DOMParser API by default, fallback later if needs be
902 + * DOMParser not work for svg when has multiple root element.
903 + */
904 + if (NAMESPACE === HTML_NAMESPACE) {
905 + try {
906 + doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
907 + } catch (_) {}
908 + }
909 +
910 + /* Use createHTMLDocument in case DOMParser is not available */
911 + if (!doc || !doc.documentElement) {
912 + doc = implementation.createDocument(NAMESPACE, 'template', null);
913 + try {
914 + doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;
915 + } catch (_) {
916 + // Syntax error if dirtyPayload is invalid xml
917 + }
918 + }
919 + const body = doc.body || doc.documentElement;
920 + if (dirty && leadingWhitespace) {
921 + body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);
922 + }
923 +
924 + /* Work on whole document or just its body */
925 + if (NAMESPACE === HTML_NAMESPACE) {
926 + return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
927 + }
928 + return WHOLE_DOCUMENT ? doc.documentElement : body;
929 + };
930 +
931 + /**
932 + * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.
933 + *
934 + * @param {Node} root The root element or node to start traversing on.
935 + * @return {NodeIterator} The created NodeIterator
936 + */
937 + const _createNodeIterator = function _createNodeIterator(root) {
938 + return createNodeIterator.call(root.ownerDocument || root, root,
939 + // eslint-disable-next-line no-bitwise
940 + NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null);
941 + };
942 +
943 + /**
944 + * _isClobbered
945 + *
946 + * @param {Node} elm element to check for clobbering attacks
947 + * @return {Boolean} true if clobbered, false if safe
948 + */
949 + const _isClobbered = function _isClobbered(elm) {
950 + return elm instanceof HTMLFormElement && (typeof elm.nodeName !== 'string' || typeof elm.textContent !== 'string' || typeof elm.removeChild !== 'function' || !(elm.attributes instanceof NamedNodeMap) || typeof elm.removeAttribute !== 'function' || typeof elm.setAttribute !== 'function' || typeof elm.namespaceURI !== 'string' || typeof elm.insertBefore !== 'function' || typeof elm.hasChildNodes !== 'function');
951 + };
952 +
953 + /**
954 + * Checks whether the given object is a DOM node.
955 + *
956 + * @param {Node} object object to check whether it's a DOM node
957 + * @return {Boolean} true is object is a DOM node
958 + */
959 + const _isNode = function _isNode(object) {
960 + return typeof Node === 'function' && object instanceof Node;
961 + };
962 +
963 + /**
964 + * _executeHook
965 + * Execute user configurable hooks
966 + *
967 + * @param {String} entryPoint Name of the hook's entry point
968 + * @param {Node} currentNode node to work on with the hook
969 + * @param {Object} data additional hook parameters
970 + */
971 + const _executeHook = function _executeHook(entryPoint, currentNode, data) {
972 + if (!hooks[entryPoint]) {
973 + return;
974 + }
975 + arrayForEach(hooks[entryPoint], hook => {
976 + hook.call(DOMPurify, currentNode, data, CONFIG);
977 + });
978 + };
979 +
980 + /**
981 + * _sanitizeElements
982 + *
983 + * @protect nodeName
984 + * @protect textContent
985 + * @protect removeChild
986 + *
987 + * @param {Node} currentNode to check for permission to exist
988 + * @return {Boolean} true if node was killed, false if left alive
989 + */
990 + const _sanitizeElements = function _sanitizeElements(currentNode) {
991 + let content = null;
992 +
993 + /* Execute a hook if present */
994 + _executeHook('beforeSanitizeElements', currentNode, null);
995 +
996 + /* Check if element is clobbered or can clobber */
997 + if (_isClobbered(currentNode)) {
998 + _forceRemove(currentNode);
999 + return true;
1000 + }
1001 +
1002 + /* Now let's check the element's type and name */
1003 + const tagName = transformCaseFunc(currentNode.nodeName);
1004 +
1005 + /* Execute a hook if present */
1006 + _executeHook('uponSanitizeElement', currentNode, {
1007 + tagName,
1008 + allowedTags: ALLOWED_TAGS
1009 + });
1010 +
1011 + /* Detect mXSS attempts abusing namespace confusion */
1012 + if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w]/g, currentNode.innerHTML) && regExpTest(/<[/\w]/g, currentNode.textContent)) {
1013 + _forceRemove(currentNode);
1014 + return true;
1015 + }
1016 +
1017 + /* Remove any occurrence of processing instructions */
1018 + if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {
1019 + _forceRemove(currentNode);
1020 + return true;
1021 + }
1022 +
1023 + /* Remove any kind of possibly harmful comments */
1024 + if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) {
1025 + _forceRemove(currentNode);
1026 + return true;
1027 + }
1028 +
1029 + /* Remove element if anything forbids its presence */
1030 + if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
1031 + /* Check if we have a custom element to handle */
1032 + if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
1033 + if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
1034 + return false;
1035 + }
1036 + if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
1037 + return false;
1038 + }
1039 + }
1040 +
1041 + /* Keep content except for bad-listed elements */
1042 + if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
1043 + const parentNode = getParentNode(currentNode) || currentNode.parentNode;
1044 + const childNodes = getChildNodes(currentNode) || currentNode.childNodes;
1045 + if (childNodes && parentNode) {
1046 + const childCount = childNodes.length;
1047 + for (let i = childCount - 1; i >= 0; --i) {
1048 + const childClone = cloneNode(childNodes[i], true);
1049 + childClone.__removalCount = (currentNode.__removalCount || 0) + 1;
1050 + parentNode.insertBefore(childClone, getNextSibling(currentNode));
1051 + }
1052 + }
1053 + }
1054 + _forceRemove(currentNode);
1055 + return true;
1056 + }
1057 +
1058 + /* Check whether element has a valid namespace */
1059 + if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {
1060 + _forceRemove(currentNode);
1061 + return true;
1062 + }
1063 +
1064 + /* Make sure that older browsers don't get fallback-tag mXSS */
1065 + if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) {
1066 + _forceRemove(currentNode);
1067 + return true;
1068 + }
1069 +
1070 + /* Sanitize element content to be template-safe */
1071 + if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
1072 + /* Get the element's text content */
1073 + content = currentNode.textContent;
1074 + arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
1075 + content = stringReplace(content, expr, ' ');
1076 + });
1077 + if (currentNode.textContent !== content) {
1078 + arrayPush(DOMPurify.removed, {
1079 + element: currentNode.cloneNode()
1080 + });
1081 + currentNode.textContent = content;
1082 + }
1083 + }
1084 +
1085 + /* Execute a hook if present */
1086 + _executeHook('afterSanitizeElements', currentNode, null);
1087 + return false;
1088 + };
1089 +
1090 + /**
1091 + * _isValidAttribute
1092 + *
1093 + * @param {string} lcTag Lowercase tag name of containing element.
1094 + * @param {string} lcName Lowercase attribute name.
1095 + * @param {string} value Attribute value.
1096 + * @return {Boolean} Returns true if `value` is valid, otherwise false.
1097 + */
1098 + // eslint-disable-next-line complexity
1099 + const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
1100 + /* Make sure attribute cannot clobber */
1101 + if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
1102 + return false;
1103 + }
1104 +
1105 + /* Allow valid data-* attributes: At least one character after "-"
1106 + (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
1107 + XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
1108 + We don't need to check the value; it's always URI safe. */
1109 + if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
1110 + if (
1111 + // First condition does a very basic check if a) it's basically a valid custom element tagname AND
1112 + // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
1113 + // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
1114 + _isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)) ||
1115 + // Alternative, second condition checks if it's an `is`-attribute, AND
1116 + // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
1117 + lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else {
1118 + return false;
1119 + }
1120 + /* Check value is safe. First, is attr inert? If so, is safe */
1121 + } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if (value) {
1122 + return false;
1123 + } else ;
1124 + return true;
1125 + };
1126 +
1127 + /**
1128 + * _isBasicCustomElement
1129 + * checks if at least one dash is included in tagName, and it's not the first char
1130 + * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name
1131 + *
1132 + * @param {string} tagName name of the tag of the node to sanitize
1133 + * @returns {boolean} Returns true if the tag name meets the basic criteria for a custom element, otherwise false.
1134 + */
1135 + const _isBasicCustomElement = function _isBasicCustomElement(tagName) {
1136 + return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT);
1137 + };
1138 +
1139 + /**
1140 + * _sanitizeAttributes
1141 + *
1142 + * @protect attributes
1143 + * @protect nodeName
1144 + * @protect removeAttribute
1145 + * @protect setAttribute
1146 + *
1147 + * @param {Node} currentNode to sanitize
1148 + */
1149 + const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
1150 + /* Execute a hook if present */
1151 + _executeHook('beforeSanitizeAttributes', currentNode, null);
1152 + const {
1153 + attributes
1154 + } = currentNode;
1155 +
1156 + /* Check if we have attributes; if not we might have a text node */
1157 + if (!attributes) {
1158 + return;
1159 + }
1160 + const hookEvent = {
1161 + attrName: '',
1162 + attrValue: '',
1163 + keepAttr: true,
1164 + allowedAttributes: ALLOWED_ATTR
1165 + };
1166 + let l = attributes.length;
1167 +
1168 + /* Go backwards over all attributes; safely remove bad ones */
1169 + while (l--) {
1170 + const attr = attributes[l];
1171 + const {
1172 + name,
1173 + namespaceURI,
1174 + value: attrValue
1175 + } = attr;
1176 + const lcName = transformCaseFunc(name);
1177 + let value = name === 'value' ? attrValue : stringTrim(attrValue);
1178 +
1179 + /* Execute a hook if present */
1180 + hookEvent.attrName = lcName;
1181 + hookEvent.attrValue = value;
1182 + hookEvent.keepAttr = true;
1183 + hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set
1184 + _executeHook('uponSanitizeAttribute', currentNode, hookEvent);
1185 + value = hookEvent.attrValue;
1186 +
1187 + /* Work around a security issue with comments inside attributes */
1188 + if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title)/i, value)) {
1189 + _removeAttribute(name, currentNode);
1190 + continue;
1191 + }
1192 +
1193 + /* Did the hooks approve of the attribute? */
1194 + if (hookEvent.forceKeepAttr) {
1195 + continue;
1196 + }
1197 +
1198 + /* Remove attribute */
1199 + _removeAttribute(name, currentNode);
1200 +
1201 + /* Did the hooks approve of the attribute? */
1202 + if (!hookEvent.keepAttr) {
1203 + continue;
1204 + }
1205 +
1206 + /* Work around a security issue in jQuery 3.0 */
1207 + if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) {
1208 + _removeAttribute(name, currentNode);
1209 + continue;
1210 + }
1211 +
1212 + /* Sanitize attribute content to be template-safe */
1213 + if (SAFE_FOR_TEMPLATES) {
1214 + arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
1215 + value = stringReplace(value, expr, ' ');
1216 + });
1217 + }
1218 +
1219 + /* Is `value` valid for this attribute? */
1220 + const lcTag = transformCaseFunc(currentNode.nodeName);
1221 + if (!_isValidAttribute(lcTag, lcName, value)) {
1222 + continue;
1223 + }
1224 +
1225 + /* Full DOM Clobbering protection via namespace isolation,
1226 + * Prefix id and name attributes with `user-content-`
1227 + */
1228 + if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {
1229 + // Remove the attribute with this value
1230 + _removeAttribute(name, currentNode);
1231 +
1232 + // Prefix the value and later re-create the attribute with the sanitized value
1233 + value = SANITIZE_NAMED_PROPS_PREFIX + value;
1234 + }
1235 +
1236 + /* Handle attributes that require Trusted Types */
1237 + if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') {
1238 + if (namespaceURI) ; else {
1239 + switch (trustedTypes.getAttributeType(lcTag, lcName)) {
1240 + case 'TrustedHTML':
1241 + {
1242 + value = trustedTypesPolicy.createHTML(value);
1243 + break;
1244 + }
1245 + case 'TrustedScriptURL':
1246 + {
1247 + value = trustedTypesPolicy.createScriptURL(value);
1248 + break;
1249 + }
1250 + }
1251 + }
1252 + }
1253 +
1254 + /* Handle invalid data-* attribute set by try-catching it */
1255 + try {
1256 + if (namespaceURI) {
1257 + currentNode.setAttributeNS(namespaceURI, name, value);
1258 + } else {
1259 + /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
1260 + currentNode.setAttribute(name, value);
1261 + }
1262 + if (_isClobbered(currentNode)) {
1263 + _forceRemove(currentNode);
1264 + } else {
1265 + arrayPop(DOMPurify.removed);
1266 + }
1267 + } catch (_) {}
1268 + }
1269 +
1270 + /* Execute a hook if present */
1271 + _executeHook('afterSanitizeAttributes', currentNode, null);
1272 + };
1273 +
1274 + /**
1275 + * _sanitizeShadowDOM
1276 + *
1277 + * @param {DocumentFragment} fragment to iterate over recursively
1278 + */
1279 + const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) {
1280 + let shadowNode = null;
1281 + const shadowIterator = _createNodeIterator(fragment);
1282 +
1283 + /* Execute a hook if present */
1284 + _executeHook('beforeSanitizeShadowDOM', fragment, null);
1285 + while (shadowNode = shadowIterator.nextNode()) {
1286 + /* Execute a hook if present */
1287 + _executeHook('uponSanitizeShadowNode', shadowNode, null);
1288 +
1289 + /* Sanitize tags and elements */
1290 + if (_sanitizeElements(shadowNode)) {
1291 + continue;
1292 + }
1293 +
1294 + /* Deep shadow DOM detected */
1295 + if (shadowNode.content instanceof DocumentFragment) {
1296 + _sanitizeShadowDOM(shadowNode.content);
1297 + }
1298 +
1299 + /* Check attributes, sanitize if necessary */
1300 + _sanitizeAttributes(shadowNode);
1301 + }
1302 +
1303 + /* Execute a hook if present */
1304 + _executeHook('afterSanitizeShadowDOM', fragment, null);
1305 + };
1306 +
1307 + /**
1308 + * Sanitize
1309 + * Public method providing core sanitation functionality
1310 + *
1311 + * @param {String|Node} dirty string or DOM node
1312 + * @param {Object} cfg object
1313 + */
1314 + // eslint-disable-next-line complexity
1315 + DOMPurify.sanitize = function (dirty) {
1316 + let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1317 + let body = null;
1318 + let importedNode = null;
1319 + let currentNode = null;
1320 + let returnNode = null;
1321 + /* Make sure we have a string to sanitize.
1322 + DO NOT return early, as this will return the wrong type if
1323 + the user has requested a DOM object rather than a string */
1324 + IS_EMPTY_INPUT = !dirty;
1325 + if (IS_EMPTY_INPUT) {
1326 + dirty = '<!-->';
1327 + }
1328 +
1329 + /* Stringify, in case dirty is an object */
1330 + if (typeof dirty !== 'string' && !_isNode(dirty)) {
1331 + if (typeof dirty.toString === 'function') {
1332 + dirty = dirty.toString();
1333 + if (typeof dirty !== 'string') {
1334 + throw typeErrorCreate('dirty is not a string, aborting');
1335 + }
1336 + } else {
1337 + throw typeErrorCreate('toString is not a function');
1338 + }
1339 + }
1340 +
1341 + /* Return dirty HTML if DOMPurify cannot run */
1342 + if (!DOMPurify.isSupported) {
1343 + return dirty;
1344 + }
1345 +
1346 + /* Assign config vars */
1347 + if (!SET_CONFIG) {
1348 + _parseConfig(cfg);
1349 + }
1350 +
1351 + /* Clean up removed elements */
1352 + DOMPurify.removed = [];
1353 +
1354 + /* Check if dirty is correctly typed for IN_PLACE */
1355 + if (typeof dirty === 'string') {
1356 + IN_PLACE = false;
1357 + }
1358 + if (IN_PLACE) {
1359 + /* Do some early pre-sanitization to avoid unsafe root nodes */
1360 + if (dirty.nodeName) {
1361 + const tagName = transformCaseFunc(dirty.nodeName);
1362 + if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
1363 + throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');
1364 + }
1365 + }
1366 + } else if (dirty instanceof Node) {
1367 + /* If dirty is a DOM element, append to an empty document to avoid
1368 + elements being stripped by the parser */
1369 + body = _initDocument('<!---->');
1370 + importedNode = body.ownerDocument.importNode(dirty, true);
1371 + if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') {
1372 + /* Node is already a body, use as is */
1373 + body = importedNode;
1374 + } else if (importedNode.nodeName === 'HTML') {
1375 + body = importedNode;
1376 + } else {
1377 + // eslint-disable-next-line unicorn/prefer-dom-node-append
1378 + body.appendChild(importedNode);
1379 + }
1380 + } else {
1381 + /* Exit directly if we have nothing to do */
1382 + if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&
1383 + // eslint-disable-next-line unicorn/prefer-includes
1384 + dirty.indexOf('<') === -1) {
1385 + return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty;
1386 + }
1387 +
1388 + /* Initialize the document to work on */
1389 + body = _initDocument(dirty);
1390 +
1391 + /* Check we have a DOM node from the data */
1392 + if (!body) {
1393 + return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';
1394 + }
1395 + }
1396 +
1397 + /* Remove first element node (ours) if FORCE_BODY is set */
1398 + if (body && FORCE_BODY) {
1399 + _forceRemove(body.firstChild);
1400 + }
1401 +
1402 + /* Get node iterator */
1403 + const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);
1404 +
1405 + /* Now start iterating over the created document */
1406 + while (currentNode = nodeIterator.nextNode()) {
1407 + /* Sanitize tags and elements */
1408 + if (_sanitizeElements(currentNode)) {
1409 + continue;
1410 + }
1411 +
1412 + /* Shadow DOM detected, sanitize it */
1413 + if (currentNode.content instanceof DocumentFragment) {
1414 + _sanitizeShadowDOM(currentNode.content);
1415 + }
1416 +
1417 + /* Check attributes, sanitize if necessary */
1418 + _sanitizeAttributes(currentNode);
1419 + }
1420 +
1421 + /* If we sanitized `dirty` in-place, return it. */
1422 + if (IN_PLACE) {
1423 + return dirty;
1424 + }
1425 +
1426 + /* Return sanitized string or DOM */
1427 + if (RETURN_DOM) {
1428 + if (RETURN_DOM_FRAGMENT) {
1429 + returnNode = createDocumentFragment.call(body.ownerDocument);
1430 + while (body.firstChild) {
1431 + // eslint-disable-next-line unicorn/prefer-dom-node-append
1432 + returnNode.appendChild(body.firstChild);
1433 + }
1434 + } else {
1435 + returnNode = body;
1436 + }
1437 + if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {
1438 + /*
1439 + AdoptNode() is not used because internal state is not reset
1440 + (e.g. the past names map of a HTMLFormElement), this is safe
1441 + in theory but we would rather not risk another attack vector.
1442 + The state that is cloned by importNode() is explicitly defined
1443 + by the specs.
1444 + */
1445 + returnNode = importNode.call(originalDocument, returnNode, true);
1446 + }
1447 + return returnNode;
1448 + }
1449 + let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
1450 +
1451 + /* Serialize doctype if allowed */
1452 + if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
1453 + serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\n' + serializedHTML;
1454 + }
1455 +
1456 + /* Sanitize final string template-safe */
1457 + if (SAFE_FOR_TEMPLATES) {
1458 + arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => {
1459 + serializedHTML = stringReplace(serializedHTML, expr, ' ');
1460 + });
1461 + }
1462 + return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
1463 + };
1464 +
1465 + /**
1466 + * Public method to set the configuration once
1467 + * setConfig
1468 + *
1469 + * @param {Object} cfg configuration object
1470 + */
1471 + DOMPurify.setConfig = function () {
1472 + let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1473 + _parseConfig(cfg);
1474 + SET_CONFIG = true;
1475 + };
1476 +
1477 + /**
1478 + * Public method to remove the configuration
1479 + * clearConfig
1480 + *
1481 + */
1482 + DOMPurify.clearConfig = function () {
1483 + CONFIG = null;
1484 + SET_CONFIG = false;
1485 + };
1486 +
1487 + /**
1488 + * Public method to check if an attribute value is valid.
1489 + * Uses last set config, if any. Otherwise, uses config defaults.
1490 + * isValidAttribute
1491 + *
1492 + * @param {String} tag Tag name of containing element.
1493 + * @param {String} attr Attribute name.
1494 + * @param {String} value Attribute value.
1495 + * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.
1496 + */
1497 + DOMPurify.isValidAttribute = function (tag, attr, value) {
1498 + /* Initialize shared config vars if necessary. */
1499 + if (!CONFIG) {
1500 + _parseConfig({});
1501 + }
1502 + const lcTag = transformCaseFunc(tag);
1503 + const lcName = transformCaseFunc(attr);
1504 + return _isValidAttribute(lcTag, lcName, value);
1505 + };
1506 +
1507 + /**
1508 + * AddHook
1509 + * Public method to add DOMPurify hooks
1510 + *
1511 + * @param {String} entryPoint entry point for the hook to add
1512 + * @param {Function} hookFunction function to execute
1513 + */
1514 + DOMPurify.addHook = function (entryPoint, hookFunction) {
1515 + if (typeof hookFunction !== 'function') {
1516 + return;
1517 + }
1518 + hooks[entryPoint] = hooks[entryPoint] || [];
1519 + arrayPush(hooks[entryPoint], hookFunction);
1520 + };
1521 +
1522 + /**
1523 + * RemoveHook
1524 + * Public method to remove a DOMPurify hook at a given entryPoint
1525 + * (pops it from the stack of hooks if more are present)
1526 + *
1527 + * @param {String} entryPoint entry point for the hook to remove
1528 + * @return {Function} removed(popped) hook
1529 + */
1530 + DOMPurify.removeHook = function (entryPoint) {
1531 + if (hooks[entryPoint]) {
1532 + return arrayPop(hooks[entryPoint]);
1533 + }
1534 + };
1535 +
1536 + /**
1537 + * RemoveHooks
1538 + * Public method to remove all DOMPurify hooks at a given entryPoint
1539 + *
1540 + * @param {String} entryPoint entry point for the hooks to remove
1541 + */
1542 + DOMPurify.removeHooks = function (entryPoint) {
1543 + if (hooks[entryPoint]) {
1544 + hooks[entryPoint] = [];
1545 + }
1546 + };
1547 +
1548 + /**
1549 + * RemoveAllHooks
1550 + * Public method to remove all DOMPurify hooks
1551 + */
1552 + DOMPurify.removeAllHooks = function () {
1553 + hooks = {};
1554 + };
1555 + return DOMPurify;
1556 + }
1557 + var purify = createDOMPurify();
1558 +
1559 + return purify;
1560 +
1561 + }));
1562 + //# sourceMappingURL=purify.js.map
1563 +
\ No newline at end of file
public/scripts/purify.js.map new
+1
@@ -0,0 +1 @@
1 +{"version":3,"file":"purify.js","sources":["../src/utils.js","../src/tags.js","../src/attrs.js","../src/regexp.js","../src/purify.js"],"sourcesContent":["const {\n entries,\n setPrototypeOf,\n isFrozen,\n getPrototypeOf,\n getOwnPropertyDescriptor,\n} = Object;\n\nlet { freeze, seal, create } = Object; // eslint-disable-line import/no-mutable-exports\nlet { apply, construct } = typeof Reflect !== 'undefined' && Reflect;\n\nif (!freeze) {\n freeze = function (x) {\n return x;\n };\n}\n\nif (!seal) {\n seal = function (x) {\n return x;\n };\n}\n\nif (!apply) {\n apply = function (fun, thisValue, args) {\n return fun.apply(thisValue, args);\n };\n}\n\nif (!construct) {\n construct = function (Func, args) {\n return new Func(...args);\n };\n}\n\nconst arrayForEach = unapply(Array.prototype.forEach);\nconst arrayIndexOf = unapply(Array.prototype.indexOf);\nconst arrayPop = unapply(Array.prototype.pop);\nconst arrayPush = unapply(Array.prototype.push);\nconst arraySlice = unapply(Array.prototype.slice);\n\nconst stringToLowerCase = unapply(String.prototype.toLowerCase);\nconst stringToString = unapply(String.prototype.toString);\nconst stringMatch = unapply(String.prototype.match);\nconst stringReplace = unapply(String.prototype.replace);\nconst stringIndexOf = unapply(String.prototype.indexOf);\nconst stringTrim = unapply(String.prototype.trim);\n\nconst objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);\n\nconst regExpTest = unapply(RegExp.prototype.test);\n\nconst typeErrorCreate = unconstruct(TypeError);\n\n/**\n * Creates a new function that calls the given function with a specified thisArg and arguments.\n *\n * @param {Function} func - The function to be wrapped and called.\n * @returns {Function} A new function that calls the given function with a specified thisArg and arguments.\n */\nfunction unapply(func) {\n return (thisArg, ...args) => apply(func, thisArg, args);\n}\n\n/**\n * Creates a new function that constructs an instance of the given constructor function with the provided arguments.\n *\n * @param {Function} func - The constructor function to be wrapped and called.\n * @returns {Function} A new function that constructs an instance of the given constructor function with the provided arguments.\n */\nfunction unconstruct(func) {\n return (...args) => construct(func, args);\n}\n\n/**\n * Add properties to a lookup table\n *\n * @param {Object} set - The set to which elements will be added.\n * @param {Array} array - The array containing elements to be added to the set.\n * @param {Function} transformCaseFunc - An optional function to transform the case of each element before adding to the set.\n * @returns {Object} The modified set with added elements.\n */\nfunction addToSet(set, array, transformCaseFunc = stringToLowerCase) {\n if (setPrototypeOf) {\n // Make 'in' and truthy checks like Boolean(set.constructor)\n // independent of any properties defined on Object.prototype.\n // Prevent prototype setters from intercepting set as a this value.\n setPrototypeOf(set, null);\n }\n\n let l = array.length;\n while (l--) {\n let element = array[l];\n if (typeof element === 'string') {\n const lcElement = transformCaseFunc(element);\n if (lcElement !== element) {\n // Config presets (e.g. tags.js, attrs.js) are immutable.\n if (!isFrozen(array)) {\n array[l] = lcElement;\n }\n\n element = lcElement;\n }\n }\n\n set[element] = true;\n }\n\n return set;\n}\n\n/**\n * Clean up an array to harden against CSPP\n *\n * @param {Array} array - The array to be cleaned.\n * @returns {Array} The cleaned version of the array\n */\nfunction cleanArray(array) {\n for (let index = 0; index < array.length; index++) {\n const isPropertyExist = objectHasOwnProperty(array, index);\n\n if (!isPropertyExist) {\n array[index] = null;\n }\n }\n\n return array;\n}\n\n/**\n * Shallow clone an object\n *\n * @param {Object} object - The object to be cloned.\n * @returns {Object} A new object that copies the original.\n */\nfunction clone(object) {\n const newObject = create(null);\n\n for (const [property, value] of entries(object)) {\n const isPropertyExist = objectHasOwnProperty(object, property);\n\n if (isPropertyExist) {\n if (Array.isArray(value)) {\n newObject[property] = cleanArray(value);\n } else if (\n value &&\n typeof value === 'object' &&\n value.constructor === Object\n ) {\n newObject[property] = clone(value);\n } else {\n newObject[property] = value;\n }\n }\n }\n\n return newObject;\n}\n\n/**\n * This method automatically checks if the prop is function or getter and behaves accordingly.\n *\n * @param {Object} object - The object to look up the getter function in its prototype chain.\n * @param {String} prop - The property name for which to find the getter function.\n * @returns {Function} The getter function found in the prototype chain or a fallback function.\n */\nfunction lookupGetter(object, prop) {\n while (object !== null) {\n const desc = getOwnPropertyDescriptor(object, prop);\n\n if (desc) {\n if (desc.get) {\n return unapply(desc.get);\n }\n\n if (typeof desc.value === 'function') {\n return unapply(desc.value);\n }\n }\n\n object = getPrototypeOf(object);\n }\n\n function fallbackValue() {\n return null;\n }\n\n return fallbackValue;\n}\n\nexport {\n // Array\n arrayForEach,\n arrayIndexOf,\n arrayPop,\n arrayPush,\n arraySlice,\n // Object\n entries,\n freeze,\n getPrototypeOf,\n getOwnPropertyDescriptor,\n isFrozen,\n setPrototypeOf,\n seal,\n clone,\n create,\n objectHasOwnProperty,\n // RegExp\n regExpTest,\n // String\n stringIndexOf,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringToString,\n stringTrim,\n // Errors\n typeErrorCreate,\n // Other\n lookupGetter,\n addToSet,\n // Reflect\n unapply,\n unconstruct,\n};\n","import { freeze } from './utils.js';\n\nexport const html = freeze([\n 'a',\n 'abbr',\n 'acronym',\n 'address',\n 'area',\n 'article',\n 'aside',\n 'audio',\n 'b',\n 'bdi',\n 'bdo',\n 'big',\n 'blink',\n 'blockquote',\n 'body',\n 'br',\n 'button',\n 'canvas',\n 'caption',\n 'center',\n 'cite',\n 'code',\n 'col',\n 'colgroup',\n 'content',\n 'data',\n 'datalist',\n 'dd',\n 'decorator',\n 'del',\n 'details',\n 'dfn',\n 'dialog',\n 'dir',\n 'div',\n 'dl',\n 'dt',\n 'element',\n 'em',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'font',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'head',\n 'header',\n 'hgroup',\n 'hr',\n 'html',\n 'i',\n 'img',\n 'input',\n 'ins',\n 'kbd',\n 'label',\n 'legend',\n 'li',\n 'main',\n 'map',\n 'mark',\n 'marquee',\n 'menu',\n 'menuitem',\n 'meter',\n 'nav',\n 'nobr',\n 'ol',\n 'optgroup',\n 'option',\n 'output',\n 'p',\n 'picture',\n 'pre',\n 'progress',\n 'q',\n 'rp',\n 'rt',\n 'ruby',\n 's',\n 'samp',\n 'section',\n 'select',\n 'shadow',\n 'small',\n 'source',\n 'spacer',\n 'span',\n 'strike',\n 'strong',\n 'style',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'template',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'time',\n 'tr',\n 'track',\n 'tt',\n 'u',\n 'ul',\n 'var',\n 'video',\n 'wbr',\n]);\n\n// SVG\nexport const svg = freeze([\n 'svg',\n 'a',\n 'altglyph',\n 'altglyphdef',\n 'altglyphitem',\n 'animatecolor',\n 'animatemotion',\n 'animatetransform',\n 'circle',\n 'clippath',\n 'defs',\n 'desc',\n 'ellipse',\n 'filter',\n 'font',\n 'g',\n 'glyph',\n 'glyphref',\n 'hkern',\n 'image',\n 'line',\n 'lineargradient',\n 'marker',\n 'mask',\n 'metadata',\n 'mpath',\n 'path',\n 'pattern',\n 'polygon',\n 'polyline',\n 'radialgradient',\n 'rect',\n 'stop',\n 'style',\n 'switch',\n 'symbol',\n 'text',\n 'textpath',\n 'title',\n 'tref',\n 'tspan',\n 'view',\n 'vkern',\n]);\n\nexport const svgFilters = freeze([\n 'feBlend',\n 'feColorMatrix',\n 'feComponentTransfer',\n 'feComposite',\n 'feConvolveMatrix',\n 'feDiffuseLighting',\n 'feDisplacementMap',\n 'feDistantLight',\n 'feDropShadow',\n 'feFlood',\n 'feFuncA',\n 'feFuncB',\n 'feFuncG',\n 'feFuncR',\n 'feGaussianBlur',\n 'feImage',\n 'feMerge',\n 'feMergeNode',\n 'feMorphology',\n 'feOffset',\n 'fePointLight',\n 'feSpecularLighting',\n 'feSpotLight',\n 'feTile',\n 'feTurbulence',\n]);\n\n// List of SVG elements that are disallowed by default.\n// We still need to know them so that we can do namespace\n// checks properly in case one wants to add them to\n// allow-list.\nexport const svgDisallowed = freeze([\n 'animate',\n 'color-profile',\n 'cursor',\n 'discard',\n 'font-face',\n 'font-face-format',\n 'font-face-name',\n 'font-face-src',\n 'font-face-uri',\n 'foreignobject',\n 'hatch',\n 'hatchpath',\n 'mesh',\n 'meshgradient',\n 'meshpatch',\n 'meshrow',\n 'missing-glyph',\n 'script',\n 'set',\n 'solidcolor',\n 'unknown',\n 'use',\n]);\n\nexport const mathMl = freeze([\n 'math',\n 'menclose',\n 'merror',\n 'mfenced',\n 'mfrac',\n 'mglyph',\n 'mi',\n 'mlabeledtr',\n 'mmultiscripts',\n 'mn',\n 'mo',\n 'mover',\n 'mpadded',\n 'mphantom',\n 'mroot',\n 'mrow',\n 'ms',\n 'mspace',\n 'msqrt',\n 'mstyle',\n 'msub',\n 'msup',\n 'msubsup',\n 'mtable',\n 'mtd',\n 'mtext',\n 'mtr',\n 'munder',\n 'munderover',\n 'mprescripts',\n]);\n\n// Similarly to SVG, we want to know all MathML elements,\n// even those that we disallow by default.\nexport const mathMlDisallowed = freeze([\n 'maction',\n 'maligngroup',\n 'malignmark',\n 'mlongdiv',\n 'mscarries',\n 'mscarry',\n 'msgroup',\n 'mstack',\n 'msline',\n 'msrow',\n 'semantics',\n 'annotation',\n 'annotation-xml',\n 'mprescripts',\n 'none',\n]);\n\nexport const text = freeze(['#text']);\n","import { freeze } from './utils.js';\n\nexport const html = freeze([\n 'accept',\n 'action',\n 'align',\n 'alt',\n 'autocapitalize',\n 'autocomplete',\n 'autopictureinpicture',\n 'autoplay',\n 'background',\n 'bgcolor',\n 'border',\n 'capture',\n 'cellpadding',\n 'cellspacing',\n 'checked',\n 'cite',\n 'class',\n 'clear',\n 'color',\n 'cols',\n 'colspan',\n 'controls',\n 'controlslist',\n 'coords',\n 'crossorigin',\n 'datetime',\n 'decoding',\n 'default',\n 'dir',\n 'disabled',\n 'disablepictureinpicture',\n 'disableremoteplayback',\n 'download',\n 'draggable',\n 'enctype',\n 'enterkeyhint',\n 'face',\n 'for',\n 'headers',\n 'height',\n 'hidden',\n 'high',\n 'href',\n 'hreflang',\n 'id',\n 'inputmode',\n 'integrity',\n 'ismap',\n 'kind',\n 'label',\n 'lang',\n 'list',\n 'loading',\n 'loop',\n 'low',\n 'max',\n 'maxlength',\n 'media',\n 'method',\n 'min',\n 'minlength',\n 'multiple',\n 'muted',\n 'name',\n 'nonce',\n 'noshade',\n 'novalidate',\n 'nowrap',\n 'open',\n 'optimum',\n 'pattern',\n 'placeholder',\n 'playsinline',\n 'popover',\n 'popovertarget',\n 'popovertargetaction',\n 'poster',\n 'preload',\n 'pubdate',\n 'radiogroup',\n 'readonly',\n 'rel',\n 'required',\n 'rev',\n 'reversed',\n 'role',\n 'rows',\n 'rowspan',\n 'spellcheck',\n 'scope',\n 'selected',\n 'shape',\n 'size',\n 'sizes',\n 'span',\n 'srclang',\n 'start',\n 'src',\n 'srcset',\n 'step',\n 'style',\n 'summary',\n 'tabindex',\n 'title',\n 'translate',\n 'type',\n 'usemap',\n 'valign',\n 'value',\n 'width',\n 'wrap',\n 'xmlns',\n 'slot',\n]);\n\nexport const svg = freeze([\n 'accent-height',\n 'accumulate',\n 'additive',\n 'alignment-baseline',\n 'ascent',\n 'attributename',\n 'attributetype',\n 'azimuth',\n 'basefrequency',\n 'baseline-shift',\n 'begin',\n 'bias',\n 'by',\n 'class',\n 'clip',\n 'clippathunits',\n 'clip-path',\n 'clip-rule',\n 'color',\n 'color-interpolation',\n 'color-interpolation-filters',\n 'color-profile',\n 'color-rendering',\n 'cx',\n 'cy',\n 'd',\n 'dx',\n 'dy',\n 'diffuseconstant',\n 'direction',\n 'display',\n 'divisor',\n 'dur',\n 'edgemode',\n 'elevation',\n 'end',\n 'fill',\n 'fill-opacity',\n 'fill-rule',\n 'filter',\n 'filterunits',\n 'flood-color',\n 'flood-opacity',\n 'font-family',\n 'font-size',\n 'font-size-adjust',\n 'font-stretch',\n 'font-style',\n 'font-variant',\n 'font-weight',\n 'fx',\n 'fy',\n 'g1',\n 'g2',\n 'glyph-name',\n 'glyphref',\n 'gradientunits',\n 'gradienttransform',\n 'height',\n 'href',\n 'id',\n 'image-rendering',\n 'in',\n 'in2',\n 'k',\n 'k1',\n 'k2',\n 'k3',\n 'k4',\n 'kerning',\n 'keypoints',\n 'keysplines',\n 'keytimes',\n 'lang',\n 'lengthadjust',\n 'letter-spacing',\n 'kernelmatrix',\n 'kernelunitlength',\n 'lighting-color',\n 'local',\n 'marker-end',\n 'marker-mid',\n 'marker-start',\n 'markerheight',\n 'markerunits',\n 'markerwidth',\n 'maskcontentunits',\n 'maskunits',\n 'max',\n 'mask',\n 'media',\n 'method',\n 'mode',\n 'min',\n 'name',\n 'numoctaves',\n 'offset',\n 'operator',\n 'opacity',\n 'order',\n 'orient',\n 'orientation',\n 'origin',\n 'overflow',\n 'paint-order',\n 'path',\n 'pathlength',\n 'patterncontentunits',\n 'patterntransform',\n 'patternunits',\n 'points',\n 'preservealpha',\n 'preserveaspectratio',\n 'primitiveunits',\n 'r',\n 'rx',\n 'ry',\n 'radius',\n 'refx',\n 'refy',\n 'repeatcount',\n 'repeatdur',\n 'restart',\n 'result',\n 'rotate',\n 'scale',\n 'seed',\n 'shape-rendering',\n 'specularconstant',\n 'specularexponent',\n 'spreadmethod',\n 'startoffset',\n 'stddeviation',\n 'stitchtiles',\n 'stop-color',\n 'stop-opacity',\n 'stroke-dasharray',\n 'stroke-dashoffset',\n 'stroke-linecap',\n 'stroke-linejoin',\n 'stroke-miterlimit',\n 'stroke-opacity',\n 'stroke',\n 'stroke-width',\n 'style',\n 'surfacescale',\n 'systemlanguage',\n 'tabindex',\n 'targetx',\n 'targety',\n 'transform',\n 'transform-origin',\n 'text-anchor',\n 'text-decoration',\n 'text-rendering',\n 'textlength',\n 'type',\n 'u1',\n 'u2',\n 'unicode',\n 'values',\n 'viewbox',\n 'visibility',\n 'version',\n 'vert-adv-y',\n 'vert-origin-x',\n 'vert-origin-y',\n 'width',\n 'word-spacing',\n 'wrap',\n 'writing-mode',\n 'xchannelselector',\n 'ychannelselector',\n 'x',\n 'x1',\n 'x2',\n 'xmlns',\n 'y',\n 'y1',\n 'y2',\n 'z',\n 'zoomandpan',\n]);\n\nexport const mathMl = freeze([\n 'accent',\n 'accentunder',\n 'align',\n 'bevelled',\n 'close',\n 'columnsalign',\n 'columnlines',\n 'columnspan',\n 'denomalign',\n 'depth',\n 'dir',\n 'display',\n 'displaystyle',\n 'encoding',\n 'fence',\n 'frame',\n 'height',\n 'href',\n 'id',\n 'largeop',\n 'length',\n 'linethickness',\n 'lspace',\n 'lquote',\n 'mathbackground',\n 'mathcolor',\n 'mathsize',\n 'mathvariant',\n 'maxsize',\n 'minsize',\n 'movablelimits',\n 'notation',\n 'numalign',\n 'open',\n 'rowalign',\n 'rowlines',\n 'rowspacing',\n 'rowspan',\n 'rspace',\n 'rquote',\n 'scriptlevel',\n 'scriptminsize',\n 'scriptsizemultiplier',\n 'selection',\n 'separator',\n 'separators',\n 'stretchy',\n 'subscriptshift',\n 'supscriptshift',\n 'symmetric',\n 'voffset',\n 'width',\n 'xmlns',\n]);\n\nexport const xml = freeze([\n 'xlink:href',\n 'xml:id',\n 'xlink:title',\n 'xml:space',\n 'xmlns:xlink',\n]);\n","import { seal } from './utils.js';\n\n// eslint-disable-next-line unicorn/better-regex\nexport const MUSTACHE_EXPR = seal(/\\{\\{[\\w\\W]*|[\\w\\W]*\\}\\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode\nexport const ERB_EXPR = seal(/<%[\\w\\W]*|[\\w\\W]*%>/gm);\nexport const TMPLIT_EXPR = seal(/\\${[\\w\\W]*}/gm);\nexport const DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]/); // eslint-disable-line no-useless-escape\nexport const ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\nexport const IS_ALLOWED_URI = seal(\n /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nexport const IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nexport const ATTR_WHITESPACE = seal(\n /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\nexport const DOCTYPE_NAME = seal(/^html$/i);\nexport const CUSTOM_ELEMENT = seal(/^[a-z][.\\w]*(-[.\\w]+)+$/i);\n","import * as TAGS from './tags.js';\nimport * as ATTRS from './attrs.js';\nimport * as EXPRESSIONS from './regexp.js';\nimport {\n addToSet,\n clone,\n entries,\n freeze,\n arrayForEach,\n arrayPop,\n arrayPush,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringToString,\n stringIndexOf,\n stringTrim,\n regExpTest,\n typeErrorCreate,\n lookupGetter,\n create,\n objectHasOwnProperty,\n} from './utils.js';\n\n// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType\nconst NODE_TYPE = {\n element: 1,\n attribute: 2,\n text: 3,\n cdataSection: 4,\n entityReference: 5, // Deprecated\n entityNode: 6, // Deprecated\n progressingInstruction: 7,\n comment: 8,\n document: 9,\n documentType: 10,\n documentFragment: 11,\n notation: 12, // Deprecated\n};\n\nconst getGlobal = function () {\n return typeof window === 'undefined' ? null : window;\n};\n\n/**\n * Creates a no-op policy for internal use only.\n * Don't export this function outside this module!\n * @param {TrustedTypePolicyFactory} trustedTypes The policy factory.\n * @param {HTMLScriptElement} purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).\n * @return {TrustedTypePolicy} The policy created (or null, if Trusted Types\n * are not supported or creating the policy failed).\n */\nconst _createTrustedTypesPolicy = function (trustedTypes, purifyHostElement) {\n if (\n typeof trustedTypes !== 'object' ||\n typeof trustedTypes.createPolicy !== 'function'\n ) {\n return null;\n }\n\n // Allow the callers to control the unique policy name\n // by adding a data-tt-policy-suffix to the script element with the DOMPurify.\n // Policy creation with duplicate names throws in Trusted Types.\n let suffix = null;\n const ATTR_NAME = 'data-tt-policy-suffix';\n if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {\n suffix = purifyHostElement.getAttribute(ATTR_NAME);\n }\n\n const policyName = 'dompurify' + (suffix ? '#' + suffix : '');\n\n try {\n return trustedTypes.createPolicy(policyName, {\n createHTML(html) {\n return html;\n },\n createScriptURL(scriptUrl) {\n return scriptUrl;\n },\n });\n } catch (_) {\n // Policy creation failed (most likely another DOMPurify script has\n // already run). Skip creating the policy, as this will only cause errors\n // if TT are enforced.\n console.warn(\n 'TrustedTypes policy ' + policyName + ' could not be created.'\n );\n return null;\n }\n};\n\nfunction createDOMPurify(window = getGlobal()) {\n const DOMPurify = (root) => createDOMPurify(root);\n\n /**\n * Version label, exposed for easier checks\n * if DOMPurify is up to date or not\n */\n DOMPurify.version = VERSION;\n\n /**\n * Array of elements that DOMPurify removed during sanitation.\n * Empty if nothing was removed.\n */\n DOMPurify.removed = [];\n\n if (\n !window ||\n !window.document ||\n window.document.nodeType !== NODE_TYPE.document\n ) {\n // Not running in a browser, provide a factory function\n // so that you can pass your own Window\n DOMPurify.isSupported = false;\n\n return DOMPurify;\n }\n\n let { document } = window;\n\n const originalDocument = document;\n const currentScript = originalDocument.currentScript;\n const {\n DocumentFragment,\n HTMLTemplateElement,\n Node,\n Element,\n NodeFilter,\n NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,\n HTMLFormElement,\n DOMParser,\n trustedTypes,\n } = window;\n\n const ElementPrototype = Element.prototype;\n\n const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');\n const remove = lookupGetter(ElementPrototype, 'remove');\n const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');\n const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');\n const getParentNode = lookupGetter(ElementPrototype, 'parentNode');\n\n // As per issue #47, the web-components registry is inherited by a\n // new document created via createHTMLDocument. As per the spec\n // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)\n // a new empty registry is used when creating a template contents owner\n // document, so we use that as our parent document to ensure nothing\n // is inherited.\n if (typeof HTMLTemplateElement === 'function') {\n const template = document.createElement('template');\n if (template.content && template.content.ownerDocument) {\n document = template.content.ownerDocument;\n }\n }\n\n let trustedTypesPolicy;\n let emptyHTML = '';\n\n const {\n implementation,\n createNodeIterator,\n createDocumentFragment,\n getElementsByTagName,\n } = document;\n const { importNode } = originalDocument;\n\n let hooks = {};\n\n /**\n * Expose whether this browser supports running the full DOMPurify.\n */\n DOMPurify.isSupported =\n typeof entries === 'function' &&\n typeof getParentNode === 'function' &&\n implementation &&\n implementation.createHTMLDocument !== undefined;\n\n const {\n MUSTACHE_EXPR,\n ERB_EXPR,\n TMPLIT_EXPR,\n DATA_ATTR,\n ARIA_ATTR,\n IS_SCRIPT_OR_DATA,\n ATTR_WHITESPACE,\n CUSTOM_ELEMENT,\n } = EXPRESSIONS;\n\n let { IS_ALLOWED_URI } = EXPRESSIONS;\n\n /**\n * We consider the elements and attributes below to be safe. Ideally\n * don't add any new ones but feel free to remove unwanted ones.\n */\n\n /* allowed element names */\n let ALLOWED_TAGS = null;\n const DEFAULT_ALLOWED_TAGS = addToSet({}, [\n ...TAGS.html,\n ...TAGS.svg,\n ...TAGS.svgFilters,\n ...TAGS.mathMl,\n ...TAGS.text,\n ]);\n\n /* Allowed attribute names */\n let ALLOWED_ATTR = null;\n const DEFAULT_ALLOWED_ATTR = addToSet({}, [\n ...ATTRS.html,\n ...ATTRS.svg,\n ...ATTRS.mathMl,\n ...ATTRS.xml,\n ]);\n\n /*\n * Configure how DOMPUrify should handle custom elements and their attributes as well as customized built-in elements.\n * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)\n * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)\n * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.\n */\n let CUSTOM_ELEMENT_HANDLING = Object.seal(\n create(null, {\n tagNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n attributeNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n allowCustomizedBuiltInElements: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: false,\n },\n })\n );\n\n /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */\n let FORBID_TAGS = null;\n\n /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */\n let FORBID_ATTR = null;\n\n /* Decide if ARIA attributes are okay */\n let ALLOW_ARIA_ATTR = true;\n\n /* Decide if custom data attributes are okay */\n let ALLOW_DATA_ATTR = true;\n\n /* Decide if unknown protocols are okay */\n let ALLOW_UNKNOWN_PROTOCOLS = false;\n\n /* Decide if self-closing tags in attributes are allowed.\n * Usually removed due to a mXSS issue in jQuery 3.0 */\n let ALLOW_SELF_CLOSE_IN_ATTR = true;\n\n /* Output should be safe for common template engines.\n * This means, DOMPurify removes data attributes, mustaches and ERB\n */\n let SAFE_FOR_TEMPLATES = false;\n\n /* Output should be safe even for XML used within HTML and alike.\n * This means, DOMPurify removes comments when containing risky content.\n */\n let SAFE_FOR_XML = true;\n\n /* Decide if document with <html>... should be returned */\n let WHOLE_DOCUMENT = false;\n\n /* Track whether config is already set on this instance of DOMPurify. */\n let SET_CONFIG = false;\n\n /* Decide if all elements (e.g. style, script) must be children of\n * document.body. By default, browsers might move them to document.head */\n let FORCE_BODY = false;\n\n /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported).\n * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead\n */\n let RETURN_DOM = false;\n\n /* Decide if a DOM `DocumentFragment` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported) */\n let RETURN_DOM_FRAGMENT = false;\n\n /* Try to return a Trusted Type object instead of a string, return a string in\n * case Trusted Types are not supported */\n let RETURN_TRUSTED_TYPE = false;\n\n /* Output should be free from DOM clobbering attacks?\n * This sanitizes markups named with colliding, clobberable built-in DOM APIs.\n */\n let SANITIZE_DOM = true;\n\n /* Achieve full DOM Clobbering protection by isolating the namespace of named\n * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.\n *\n * HTML/DOM spec rules that enable DOM Clobbering:\n * - Named Access on Window (§7.3.3)\n * - DOM Tree Accessors (§3.1.5)\n * - Form Element Parent-Child Relations (§4.10.3)\n * - Iframe srcdoc / Nested WindowProxies (§4.8.5)\n * - HTMLCollection (§4.2.10.2)\n *\n * Namespace isolation is implemented by prefixing `id` and `name` attributes\n * with a constant string, i.e., `user-content-`\n */\n let SANITIZE_NAMED_PROPS = false;\n const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';\n\n /* Keep element content when removing element? */\n let KEEP_CONTENT = true;\n\n /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead\n * of importing it into a new Document and returning a sanitized copy */\n let IN_PLACE = false;\n\n /* Allow usage of profiles like html, svg and mathMl */\n let USE_PROFILES = {};\n\n /* Tags to ignore content of when KEEP_CONTENT is true */\n let FORBID_CONTENTS = null;\n const DEFAULT_FORBID_CONTENTS = addToSet({}, [\n 'annotation-xml',\n 'audio',\n 'colgroup',\n 'desc',\n 'foreignobject',\n 'head',\n 'iframe',\n 'math',\n 'mi',\n 'mn',\n 'mo',\n 'ms',\n 'mtext',\n 'noembed',\n 'noframes',\n 'noscript',\n 'plaintext',\n 'script',\n 'style',\n 'svg',\n 'template',\n 'thead',\n 'title',\n 'video',\n 'xmp',\n ]);\n\n /* Tags that are safe for data: URIs */\n let DATA_URI_TAGS = null;\n const DEFAULT_DATA_URI_TAGS = addToSet({}, [\n 'audio',\n 'video',\n 'img',\n 'source',\n 'image',\n 'track',\n ]);\n\n /* Attributes safe for values like \"javascript:\" */\n let URI_SAFE_ATTRIBUTES = null;\n const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, [\n 'alt',\n 'class',\n 'for',\n 'id',\n 'label',\n 'name',\n 'pattern',\n 'placeholder',\n 'role',\n 'summary',\n 'title',\n 'value',\n 'style',\n 'xmlns',\n ]);\n\n const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n /* Document namespace */\n let NAMESPACE = HTML_NAMESPACE;\n let IS_EMPTY_INPUT = false;\n\n /* Allowed XHTML+XML namespaces */\n let ALLOWED_NAMESPACES = null;\n const DEFAULT_ALLOWED_NAMESPACES = addToSet(\n {},\n [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE],\n stringToString\n );\n\n /* Parsing of strict XHTML documents */\n let PARSER_MEDIA_TYPE = null;\n const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];\n const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';\n let transformCaseFunc = null;\n\n /* Keep a reference to config to pass to hooks */\n let CONFIG = null;\n\n /* Ideally, do not touch anything below this line */\n /* ______________________________________________ */\n\n const formElement = document.createElement('form');\n\n const isRegexOrFunction = function (testValue) {\n return testValue instanceof RegExp || testValue instanceof Function;\n };\n\n /**\n * _parseConfig\n *\n * @param {Object} cfg optional config literal\n */\n // eslint-disable-next-line complexity\n const _parseConfig = function (cfg = {}) {\n if (CONFIG && CONFIG === cfg) {\n return;\n }\n\n /* Shield configuration object from tampering */\n if (!cfg || typeof cfg !== 'object') {\n cfg = {};\n }\n\n /* Shield configuration object from prototype pollution */\n cfg = clone(cfg);\n\n PARSER_MEDIA_TYPE =\n // eslint-disable-next-line unicorn/prefer-includes\n SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1\n ? DEFAULT_PARSER_MEDIA_TYPE\n : cfg.PARSER_MEDIA_TYPE;\n\n // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.\n transformCaseFunc =\n PARSER_MEDIA_TYPE === 'application/xhtml+xml'\n ? stringToString\n : stringToLowerCase;\n\n /* Set configuration parameters */\n ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS')\n ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc)\n : DEFAULT_ALLOWED_TAGS;\n ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR')\n ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc)\n : DEFAULT_ALLOWED_ATTR;\n ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES')\n ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString)\n : DEFAULT_ALLOWED_NAMESPACES;\n URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR')\n ? addToSet(\n clone(DEFAULT_URI_SAFE_ATTRIBUTES), // eslint-disable-line indent\n cfg.ADD_URI_SAFE_ATTR, // eslint-disable-line indent\n transformCaseFunc // eslint-disable-line indent\n ) // eslint-disable-line indent\n : DEFAULT_URI_SAFE_ATTRIBUTES;\n DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS')\n ? addToSet(\n clone(DEFAULT_DATA_URI_TAGS), // eslint-disable-line indent\n cfg.ADD_DATA_URI_TAGS, // eslint-disable-line indent\n transformCaseFunc // eslint-disable-line indent\n ) // eslint-disable-line indent\n : DEFAULT_DATA_URI_TAGS;\n FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS')\n ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc)\n : DEFAULT_FORBID_CONTENTS;\n FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS')\n ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc)\n : {};\n FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR')\n ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc)\n : {};\n USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES')\n ? cfg.USE_PROFILES\n : false;\n ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true\n ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true\n ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false\n ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true\n SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false\n SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true\n WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false\n RETURN_DOM = cfg.RETURN_DOM || false; // Default false\n RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false\n RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false\n FORCE_BODY = cfg.FORCE_BODY || false; // Default false\n SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true\n SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false\n KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true\n IN_PLACE = cfg.IN_PLACE || false; // Default false\n IS_ALLOWED_URI = cfg.ALLOWED_URI_REGEXP || EXPRESSIONS.IS_ALLOWED_URI;\n NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;\n CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};\n if (\n cfg.CUSTOM_ELEMENT_HANDLING &&\n isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)\n ) {\n CUSTOM_ELEMENT_HANDLING.tagNameCheck =\n cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;\n }\n\n if (\n cfg.CUSTOM_ELEMENT_HANDLING &&\n isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)\n ) {\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck =\n cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;\n }\n\n if (\n cfg.CUSTOM_ELEMENT_HANDLING &&\n typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements ===\n 'boolean'\n ) {\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements =\n cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;\n }\n\n if (SAFE_FOR_TEMPLATES) {\n ALLOW_DATA_ATTR = false;\n }\n\n if (RETURN_DOM_FRAGMENT) {\n RETURN_DOM = true;\n }\n\n /* Parse profile info */\n if (USE_PROFILES) {\n ALLOWED_TAGS = addToSet({}, TAGS.text);\n ALLOWED_ATTR = [];\n if (USE_PROFILES.html === true) {\n addToSet(ALLOWED_TAGS, TAGS.html);\n addToSet(ALLOWED_ATTR, ATTRS.html);\n }\n\n if (USE_PROFILES.svg === true) {\n addToSet(ALLOWED_TAGS, TAGS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n\n if (USE_PROFILES.svgFilters === true) {\n addToSet(ALLOWED_TAGS, TAGS.svgFilters);\n addToSet(ALLOWED_ATTR, ATTRS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n\n if (USE_PROFILES.mathMl === true) {\n addToSet(ALLOWED_TAGS, TAGS.mathMl);\n addToSet(ALLOWED_ATTR, ATTRS.mathMl);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n }\n\n /* Merge configuration parameters */\n if (cfg.ADD_TAGS) {\n if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n\n addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);\n }\n\n if (cfg.ADD_ATTR) {\n if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n\n addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);\n }\n\n if (cfg.ADD_URI_SAFE_ATTR) {\n addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);\n }\n\n if (cfg.FORBID_CONTENTS) {\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\n }\n\n addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);\n }\n\n /* Add #text in case KEEP_CONTENT is set to true */\n if (KEEP_CONTENT) {\n ALLOWED_TAGS['#text'] = true;\n }\n\n /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */\n if (WHOLE_DOCUMENT) {\n addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);\n }\n\n /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */\n if (ALLOWED_TAGS.table) {\n addToSet(ALLOWED_TAGS, ['tbody']);\n delete FORBID_TAGS.tbody;\n }\n\n if (cfg.TRUSTED_TYPES_POLICY) {\n if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {\n throw typeErrorCreate(\n 'TRUSTED_TYPES_POLICY configuration option must provide a \"createHTML\" hook.'\n );\n }\n\n if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {\n throw typeErrorCreate(\n 'TRUSTED_TYPES_POLICY configuration option must provide a \"createScriptURL\" hook.'\n );\n }\n\n // Overwrite existing TrustedTypes policy.\n trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;\n\n // Sign local variables required by `sanitize`.\n emptyHTML = trustedTypesPolicy.createHTML('');\n } else {\n // Uninitialized policy, attempt to initialize the internal dompurify policy.\n if (trustedTypesPolicy === undefined) {\n trustedTypesPolicy = _createTrustedTypesPolicy(\n trustedTypes,\n currentScript\n );\n }\n\n // If creating the internal policy succeeded sign internal variables.\n if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {\n emptyHTML = trustedTypesPolicy.createHTML('');\n }\n }\n\n // Prevent further manipulation of configuration.\n // Not available in IE8, Safari 5, etc.\n if (freeze) {\n freeze(cfg);\n }\n\n CONFIG = cfg;\n };\n\n const MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, [\n 'mi',\n 'mo',\n 'mn',\n 'ms',\n 'mtext',\n ]);\n\n const HTML_INTEGRATION_POINTS = addToSet({}, [\n 'foreignobject',\n 'annotation-xml',\n ]);\n\n // Certain elements are allowed in both SVG and HTML\n // namespace. We need to specify them explicitly\n // so that they don't get erroneously deleted from\n // HTML namespace.\n const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, [\n 'title',\n 'style',\n 'font',\n 'a',\n 'script',\n ]);\n\n /* Keep track of all possible SVG and MathML tags\n * so that we can perform the namespace checks\n * correctly. */\n const ALL_SVG_TAGS = addToSet({}, [\n ...TAGS.svg,\n ...TAGS.svgFilters,\n ...TAGS.svgDisallowed,\n ]);\n const ALL_MATHML_TAGS = addToSet({}, [\n ...TAGS.mathMl,\n ...TAGS.mathMlDisallowed,\n ]);\n\n /**\n * @param {Element} element a DOM element whose namespace is being checked\n * @returns {boolean} Return false if the element has a\n * namespace that a spec-compliant parser would never\n * return. Return true otherwise.\n */\n const _checkValidNamespace = function (element) {\n let parent = getParentNode(element);\n\n // In JSDOM, if we're inside shadow DOM, then parentNode\n // can be null. We just simulate parent in this case.\n if (!parent || !parent.tagName) {\n parent = {\n namespaceURI: NAMESPACE,\n tagName: 'template',\n };\n }\n\n const tagName = stringToLowerCase(element.tagName);\n const parentTagName = stringToLowerCase(parent.tagName);\n\n if (!ALLOWED_NAMESPACES[element.namespaceURI]) {\n return false;\n }\n\n if (element.namespaceURI === SVG_NAMESPACE) {\n // The only way to switch from HTML namespace to SVG\n // is via <svg>. If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'svg';\n }\n\n // The only way to switch from MathML to SVG is via`\n // svg if parent is either <annotation-xml> or MathML\n // text integration points.\n if (parent.namespaceURI === MATHML_NAMESPACE) {\n return (\n tagName === 'svg' &&\n (parentTagName === 'annotation-xml' ||\n MATHML_TEXT_INTEGRATION_POINTS[parentTagName])\n );\n }\n\n // We only allow elements that are defined in SVG\n // spec. All others are disallowed in SVG namespace.\n return Boolean(ALL_SVG_TAGS[tagName]);\n }\n\n if (element.namespaceURI === MATHML_NAMESPACE) {\n // The only way to switch from HTML namespace to MathML\n // is via <math>. If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'math';\n }\n\n // The only way to switch from SVG to MathML is via\n // <math> and HTML integration points\n if (parent.namespaceURI === SVG_NAMESPACE) {\n return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];\n }\n\n // We only allow elements that are defined in MathML\n // spec. All others are disallowed in MathML namespace.\n return Boolean(ALL_MATHML_TAGS[tagName]);\n }\n\n if (element.namespaceURI === HTML_NAMESPACE) {\n // The only way to switch from SVG to HTML is via\n // HTML integration points, and from MathML to HTML\n // is via MathML text integration points\n if (\n parent.namespaceURI === SVG_NAMESPACE &&\n !HTML_INTEGRATION_POINTS[parentTagName]\n ) {\n return false;\n }\n\n if (\n parent.namespaceURI === MATHML_NAMESPACE &&\n !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]\n ) {\n return false;\n }\n\n // We disallow tags that are specific for MathML\n // or SVG and should never appear in HTML namespace\n return (\n !ALL_MATHML_TAGS[tagName] &&\n (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName])\n );\n }\n\n // For XHTML and XML documents that support custom namespaces\n if (\n PARSER_MEDIA_TYPE === 'application/xhtml+xml' &&\n ALLOWED_NAMESPACES[element.namespaceURI]\n ) {\n return true;\n }\n\n // The code should never reach this place (this means\n // that the element somehow got namespace that is not\n // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).\n // Return false just in case.\n return false;\n };\n\n /**\n * _forceRemove\n *\n * @param {Node} node a DOM node\n */\n const _forceRemove = function (node) {\n arrayPush(DOMPurify.removed, { element: node });\n\n try {\n // eslint-disable-next-line unicorn/prefer-dom-node-remove\n getParentNode(node).removeChild(node);\n } catch (_) {\n remove(node);\n }\n };\n\n /**\n * _removeAttribute\n *\n * @param {String} name an Attribute name\n * @param {Node} node a DOM node\n */\n const _removeAttribute = function (name, node) {\n try {\n arrayPush(DOMPurify.removed, {\n attribute: node.getAttributeNode(name),\n from: node,\n });\n } catch (_) {\n arrayPush(DOMPurify.removed, {\n attribute: null,\n from: node,\n });\n }\n\n node.removeAttribute(name);\n\n // We void attribute values for unremovable \"is\"\" attributes\n if (name === 'is' && !ALLOWED_ATTR[name]) {\n if (RETURN_DOM || RETURN_DOM_FRAGMENT) {\n try {\n _forceRemove(node);\n } catch (_) {}\n } else {\n try {\n node.setAttribute(name, '');\n } catch (_) {}\n }\n }\n };\n\n /**\n * _initDocument\n *\n * @param {String} dirty a string of dirty markup\n * @return {Document} a DOM, filled with the dirty markup\n */\n const _initDocument = function (dirty) {\n /* Create a HTML document */\n let doc = null;\n let leadingWhitespace = null;\n\n if (FORCE_BODY) {\n dirty = '<remove></remove>' + dirty;\n } else {\n /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */\n const matches = stringMatch(dirty, /^[\\r\\n\\t ]+/);\n leadingWhitespace = matches && matches[0];\n }\n\n if (\n PARSER_MEDIA_TYPE === 'application/xhtml+xml' &&\n NAMESPACE === HTML_NAMESPACE\n ) {\n // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)\n dirty =\n '<html xmlns=\"http://www.w3.org/1999/xhtml\"><head></head><body>' +\n dirty +\n '</body></html>';\n }\n\n const dirtyPayload = trustedTypesPolicy\n ? trustedTypesPolicy.createHTML(dirty)\n : dirty;\n /*\n * Use the DOMParser API by default, fallback later if needs be\n * DOMParser not work for svg when has multiple root element.\n */\n if (NAMESPACE === HTML_NAMESPACE) {\n try {\n doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);\n } catch (_) {}\n }\n\n /* Use createHTMLDocument in case DOMParser is not available */\n if (!doc || !doc.documentElement) {\n doc = implementation.createDocument(NAMESPACE, 'template', null);\n try {\n doc.documentElement.innerHTML = IS_EMPTY_INPUT\n ? emptyHTML\n : dirtyPayload;\n } catch (_) {\n // Syntax error if dirtyPayload is invalid xml\n }\n }\n\n const body = doc.body || doc.documentElement;\n\n if (dirty && leadingWhitespace) {\n body.insertBefore(\n document.createTextNode(leadingWhitespace),\n body.childNodes[0] || null\n );\n }\n\n /* Work on whole document or just its body */\n if (NAMESPACE === HTML_NAMESPACE) {\n return getElementsByTagName.call(\n doc,\n WHOLE_DOCUMENT ? 'html' : 'body'\n )[0];\n }\n\n return WHOLE_DOCUMENT ? doc.documentElement : body;\n };\n\n /**\n * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.\n *\n * @param {Node} root The root element or node to start traversing on.\n * @return {NodeIterator} The created NodeIterator\n */\n const _createNodeIterator = function (root) {\n return createNodeIterator.call(\n root.ownerDocument || root,\n root,\n // eslint-disable-next-line no-bitwise\n NodeFilter.SHOW_ELEMENT |\n NodeFilter.SHOW_COMMENT |\n NodeFilter.SHOW_TEXT |\n NodeFilter.SHOW_PROCESSING_INSTRUCTION |\n NodeFilter.SHOW_CDATA_SECTION,\n null\n );\n };\n\n /**\n * _isClobbered\n *\n * @param {Node} elm element to check for clobbering attacks\n * @return {Boolean} true if clobbered, false if safe\n */\n const _isClobbered = function (elm) {\n return (\n elm instanceof HTMLFormElement &&\n (typeof elm.nodeName !== 'string' ||\n typeof elm.textContent !== 'string' ||\n typeof elm.removeChild !== 'function' ||\n !(elm.attributes instanceof NamedNodeMap) ||\n typeof elm.removeAttribute !== 'function' ||\n typeof elm.setAttribute !== 'function' ||\n typeof elm.namespaceURI !== 'string' ||\n typeof elm.insertBefore !== 'function' ||\n typeof elm.hasChildNodes !== 'function')\n );\n };\n\n /**\n * Checks whether the given object is a DOM node.\n *\n * @param {Node} object object to check whether it's a DOM node\n * @return {Boolean} true is object is a DOM node\n */\n const _isNode = function (object) {\n return typeof Node === 'function' && object instanceof Node;\n };\n\n /**\n * _executeHook\n * Execute user configurable hooks\n *\n * @param {String} entryPoint Name of the hook's entry point\n * @param {Node} currentNode node to work on with the hook\n * @param {Object} data additional hook parameters\n */\n const _executeHook = function (entryPoint, currentNode, data) {\n if (!hooks[entryPoint]) {\n return;\n }\n\n arrayForEach(hooks[entryPoint], (hook) => {\n hook.call(DOMPurify, currentNode, data, CONFIG);\n });\n };\n\n /**\n * _sanitizeElements\n *\n * @protect nodeName\n * @protect textContent\n * @protect removeChild\n *\n * @param {Node} currentNode to check for permission to exist\n * @return {Boolean} true if node was killed, false if left alive\n */\n const _sanitizeElements = function (currentNode) {\n let content = null;\n\n /* Execute a hook if present */\n _executeHook('beforeSanitizeElements', currentNode, null);\n\n /* Check if element is clobbered or can clobber */\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Now let's check the element's type and name */\n const tagName = transformCaseFunc(currentNode.nodeName);\n\n /* Execute a hook if present */\n _executeHook('uponSanitizeElement', currentNode, {\n tagName,\n allowedTags: ALLOWED_TAGS,\n });\n\n /* Detect mXSS attempts abusing namespace confusion */\n if (\n currentNode.hasChildNodes() &&\n !_isNode(currentNode.firstElementChild) &&\n regExpTest(/<[/\\w]/g, currentNode.innerHTML) &&\n regExpTest(/<[/\\w]/g, currentNode.textContent)\n ) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Remove any occurrence of processing instructions */\n if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Remove any kind of possibly harmful comments */\n if (\n SAFE_FOR_XML &&\n currentNode.nodeType === NODE_TYPE.comment &&\n regExpTest(/<[/\\w]/g, currentNode.data)\n ) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Remove element if anything forbids its presence */\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n /* Check if we have a custom element to handle */\n if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {\n if (\n CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)\n ) {\n return false;\n }\n\n if (\n CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)\n ) {\n return false;\n }\n }\n\n /* Keep content except for bad-listed elements */\n if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {\n const parentNode = getParentNode(currentNode) || currentNode.parentNode;\n const childNodes = getChildNodes(currentNode) || currentNode.childNodes;\n\n if (childNodes && parentNode) {\n const childCount = childNodes.length;\n\n for (let i = childCount - 1; i >= 0; --i) {\n const childClone = cloneNode(childNodes[i], true);\n childClone.__removalCount = (currentNode.__removalCount || 0) + 1;\n parentNode.insertBefore(childClone, getNextSibling(currentNode));\n }\n }\n }\n\n _forceRemove(currentNode);\n return true;\n }\n\n /* Check whether element has a valid namespace */\n if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Make sure that older browsers don't get fallback-tag mXSS */\n if (\n (tagName === 'noscript' ||\n tagName === 'noembed' ||\n tagName === 'noframes') &&\n regExpTest(/<\\/no(script|embed|frames)/i, currentNode.innerHTML)\n ) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Sanitize element content to be template-safe */\n if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {\n /* Get the element's text content */\n content = currentNode.textContent;\n\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], (expr) => {\n content = stringReplace(content, expr, ' ');\n });\n\n if (currentNode.textContent !== content) {\n arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });\n currentNode.textContent = content;\n }\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeElements', currentNode, null);\n\n return false;\n };\n\n /**\n * _isValidAttribute\n *\n * @param {string} lcTag Lowercase tag name of containing element.\n * @param {string} lcName Lowercase attribute name.\n * @param {string} value Attribute value.\n * @return {Boolean} Returns true if `value` is valid, otherwise false.\n */\n // eslint-disable-next-line complexity\n const _isValidAttribute = function (lcTag, lcName, value) {\n /* Make sure attribute cannot clobber */\n if (\n SANITIZE_DOM &&\n (lcName === 'id' || lcName === 'name') &&\n (value in document || value in formElement)\n ) {\n return false;\n }\n\n /* Allow valid data-* attributes: At least one character after \"-\"\n (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)\n XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)\n We don't need to check the value; it's always URI safe. */\n if (\n ALLOW_DATA_ATTR &&\n !FORBID_ATTR[lcName] &&\n regExpTest(DATA_ATTR, lcName)\n ) {\n // This attribute is safe\n } else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) {\n // This attribute is safe\n /* Otherwise, check the name is permitted */\n } else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {\n if (\n // First condition does a very basic check if a) it's basically a valid custom element tagname AND\n // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck\n (_isBasicCustomElement(lcTag) &&\n ((CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag)) ||\n (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag))) &&\n ((CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName)) ||\n (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)))) ||\n // Alternative, second condition checks if it's an `is`-attribute, AND\n // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n (lcName === 'is' &&\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements &&\n ((CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value)) ||\n (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))))\n ) {\n // If user has supplied a regexp or function in CUSTOM_ELEMENT_HANDLING.tagNameCheck, we need to also allow derived custom elements using the same tagName test.\n // Additionally, we need to allow attributes passing the CUSTOM_ELEMENT_HANDLING.attributeNameCheck user has configured, as custom elements can define these at their own discretion.\n } else {\n return false;\n }\n /* Check value is safe. First, is attr inert? If so, is safe */\n } else if (URI_SAFE_ATTRIBUTES[lcName]) {\n // This attribute is safe\n /* Check no script, data or unknown possibly unsafe URI\n unless we know URI values are safe for that attribute */\n } else if (\n regExpTest(IS_ALLOWED_URI, stringReplace(value, ATTR_WHITESPACE, ''))\n ) {\n // This attribute is safe\n /* Keep image data URIs alive if src/xlink:href is allowed */\n /* Further prevent gadget XSS for dynamically built script tags */\n } else if (\n (lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') &&\n lcTag !== 'script' &&\n stringIndexOf(value, 'data:') === 0 &&\n DATA_URI_TAGS[lcTag]\n ) {\n // This attribute is safe\n /* Allow unknown protocols: This provides support for links that\n are handled by protocol handlers which may be unknown ahead of\n time, e.g. fb:, spotify: */\n } else if (\n ALLOW_UNKNOWN_PROTOCOLS &&\n !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))\n ) {\n // This attribute is safe\n /* Check for binary attributes */\n } else if (value) {\n return false;\n } else {\n // Binary attributes are safe at this point\n /* Anything else, presume unsafe, do not add it back */\n }\n\n return true;\n };\n\n /**\n * _isBasicCustomElement\n * checks if at least one dash is included in tagName, and it's not the first char\n * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name\n *\n * @param {string} tagName name of the tag of the node to sanitize\n * @returns {boolean} Returns true if the tag name meets the basic criteria for a custom element, otherwise false.\n */\n const _isBasicCustomElement = function (tagName) {\n return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT);\n };\n\n /**\n * _sanitizeAttributes\n *\n * @protect attributes\n * @protect nodeName\n * @protect removeAttribute\n * @protect setAttribute\n *\n * @param {Node} currentNode to sanitize\n */\n const _sanitizeAttributes = function (currentNode) {\n /* Execute a hook if present */\n _executeHook('beforeSanitizeAttributes', currentNode, null);\n\n const { attributes } = currentNode;\n\n /* Check if we have attributes; if not we might have a text node */\n if (!attributes) {\n return;\n }\n\n const hookEvent = {\n attrName: '',\n attrValue: '',\n keepAttr: true,\n allowedAttributes: ALLOWED_ATTR,\n };\n let l = attributes.length;\n\n /* Go backwards over all attributes; safely remove bad ones */\n while (l--) {\n const attr = attributes[l];\n const { name, namespaceURI, value: attrValue } = attr;\n const lcName = transformCaseFunc(name);\n\n let value = name === 'value' ? attrValue : stringTrim(attrValue);\n\n /* Execute a hook if present */\n hookEvent.attrName = lcName;\n hookEvent.attrValue = value;\n hookEvent.keepAttr = true;\n hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set\n _executeHook('uponSanitizeAttribute', currentNode, hookEvent);\n value = hookEvent.attrValue;\n\n /* Work around a security issue with comments inside attributes */\n if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\\/(style|title)/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Did the hooks approve of the attribute? */\n if (hookEvent.forceKeepAttr) {\n continue;\n }\n\n /* Remove attribute */\n _removeAttribute(name, currentNode);\n\n /* Did the hooks approve of the attribute? */\n if (!hookEvent.keepAttr) {\n continue;\n }\n\n /* Work around a security issue in jQuery 3.0 */\n if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\\/>/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Sanitize attribute content to be template-safe */\n if (SAFE_FOR_TEMPLATES) {\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], (expr) => {\n value = stringReplace(value, expr, ' ');\n });\n }\n\n /* Is `value` valid for this attribute? */\n const lcTag = transformCaseFunc(currentNode.nodeName);\n if (!_isValidAttribute(lcTag, lcName, value)) {\n continue;\n }\n\n /* Full DOM Clobbering protection via namespace isolation,\n * Prefix id and name attributes with `user-content-`\n */\n if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {\n // Remove the attribute with this value\n _removeAttribute(name, currentNode);\n\n // Prefix the value and later re-create the attribute with the sanitized value\n value = SANITIZE_NAMED_PROPS_PREFIX + value;\n }\n\n /* Handle attributes that require Trusted Types */\n if (\n trustedTypesPolicy &&\n typeof trustedTypes === 'object' &&\n typeof trustedTypes.getAttributeType === 'function'\n ) {\n if (namespaceURI) {\n /* Namespaces are not yet supported, see https://bugs.chromium.org/p/chromium/issues/detail?id=1305293 */\n } else {\n switch (trustedTypes.getAttributeType(lcTag, lcName)) {\n case 'TrustedHTML': {\n value = trustedTypesPolicy.createHTML(value);\n break;\n }\n\n case 'TrustedScriptURL': {\n value = trustedTypesPolicy.createScriptURL(value);\n break;\n }\n\n default: {\n break;\n }\n }\n }\n }\n\n /* Handle invalid data-* attribute set by try-catching it */\n try {\n if (namespaceURI) {\n currentNode.setAttributeNS(namespaceURI, name, value);\n } else {\n /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. \"x-schema\". */\n currentNode.setAttribute(name, value);\n }\n\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n } else {\n arrayPop(DOMPurify.removed);\n }\n } catch (_) {}\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeAttributes', currentNode, null);\n };\n\n /**\n * _sanitizeShadowDOM\n *\n * @param {DocumentFragment} fragment to iterate over recursively\n */\n const _sanitizeShadowDOM = function (fragment) {\n let shadowNode = null;\n const shadowIterator = _createNodeIterator(fragment);\n\n /* Execute a hook if present */\n _executeHook('beforeSanitizeShadowDOM', fragment, null);\n\n while ((shadowNode = shadowIterator.nextNode())) {\n /* Execute a hook if present */\n _executeHook('uponSanitizeShadowNode', shadowNode, null);\n\n /* Sanitize tags and elements */\n if (_sanitizeElements(shadowNode)) {\n continue;\n }\n\n /* Deep shadow DOM detected */\n if (shadowNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(shadowNode.content);\n }\n\n /* Check attributes, sanitize if necessary */\n _sanitizeAttributes(shadowNode);\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeShadowDOM', fragment, null);\n };\n\n /**\n * Sanitize\n * Public method providing core sanitation functionality\n *\n * @param {String|Node} dirty string or DOM node\n * @param {Object} cfg object\n */\n // eslint-disable-next-line complexity\n DOMPurify.sanitize = function (dirty, cfg = {}) {\n let body = null;\n let importedNode = null;\n let currentNode = null;\n let returnNode = null;\n /* Make sure we have a string to sanitize.\n DO NOT return early, as this will return the wrong type if\n the user has requested a DOM object rather than a string */\n IS_EMPTY_INPUT = !dirty;\n if (IS_EMPTY_INPUT) {\n dirty = '<!-->';\n }\n\n /* Stringify, in case dirty is an object */\n if (typeof dirty !== 'string' && !_isNode(dirty)) {\n if (typeof dirty.toString === 'function') {\n dirty = dirty.toString();\n if (typeof dirty !== 'string') {\n throw typeErrorCreate('dirty is not a string, aborting');\n }\n } else {\n throw typeErrorCreate('toString is not a function');\n }\n }\n\n /* Return dirty HTML if DOMPurify cannot run */\n if (!DOMPurify.isSupported) {\n return dirty;\n }\n\n /* Assign config vars */\n if (!SET_CONFIG) {\n _parseConfig(cfg);\n }\n\n /* Clean up removed elements */\n DOMPurify.removed = [];\n\n /* Check if dirty is correctly typed for IN_PLACE */\n if (typeof dirty === 'string') {\n IN_PLACE = false;\n }\n\n if (IN_PLACE) {\n /* Do some early pre-sanitization to avoid unsafe root nodes */\n if (dirty.nodeName) {\n const tagName = transformCaseFunc(dirty.nodeName);\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n throw typeErrorCreate(\n 'root node is forbidden and cannot be sanitized in-place'\n );\n }\n }\n } else if (dirty instanceof Node) {\n /* If dirty is a DOM element, append to an empty document to avoid\n elements being stripped by the parser */\n body = _initDocument('<!---->');\n importedNode = body.ownerDocument.importNode(dirty, true);\n if (\n importedNode.nodeType === NODE_TYPE.element &&\n importedNode.nodeName === 'BODY'\n ) {\n /* Node is already a body, use as is */\n body = importedNode;\n } else if (importedNode.nodeName === 'HTML') {\n body = importedNode;\n } else {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n body.appendChild(importedNode);\n }\n } else {\n /* Exit directly if we have nothing to do */\n if (\n !RETURN_DOM &&\n !SAFE_FOR_TEMPLATES &&\n !WHOLE_DOCUMENT &&\n // eslint-disable-next-line unicorn/prefer-includes\n dirty.indexOf('<') === -1\n ) {\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE\n ? trustedTypesPolicy.createHTML(dirty)\n : dirty;\n }\n\n /* Initialize the document to work on */\n body = _initDocument(dirty);\n\n /* Check we have a DOM node from the data */\n if (!body) {\n return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';\n }\n }\n\n /* Remove first element node (ours) if FORCE_BODY is set */\n if (body && FORCE_BODY) {\n _forceRemove(body.firstChild);\n }\n\n /* Get node iterator */\n const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);\n\n /* Now start iterating over the created document */\n while ((currentNode = nodeIterator.nextNode())) {\n /* Sanitize tags and elements */\n if (_sanitizeElements(currentNode)) {\n continue;\n }\n\n /* Shadow DOM detected, sanitize it */\n if (currentNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(currentNode.content);\n }\n\n /* Check attributes, sanitize if necessary */\n _sanitizeAttributes(currentNode);\n }\n\n /* If we sanitized `dirty` in-place, return it. */\n if (IN_PLACE) {\n return dirty;\n }\n\n /* Return sanitized string or DOM */\n if (RETURN_DOM) {\n if (RETURN_DOM_FRAGMENT) {\n returnNode = createDocumentFragment.call(body.ownerDocument);\n\n while (body.firstChild) {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n returnNode.appendChild(body.firstChild);\n }\n } else {\n returnNode = body;\n }\n\n if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {\n /*\n AdoptNode() is not used because internal state is not reset\n (e.g. the past names map of a HTMLFormElement), this is safe\n in theory but we would rather not risk another attack vector.\n The state that is cloned by importNode() is explicitly defined\n by the specs.\n */\n returnNode = importNode.call(originalDocument, returnNode, true);\n }\n\n return returnNode;\n }\n\n let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;\n\n /* Serialize doctype if allowed */\n if (\n WHOLE_DOCUMENT &&\n ALLOWED_TAGS['!doctype'] &&\n body.ownerDocument &&\n body.ownerDocument.doctype &&\n body.ownerDocument.doctype.name &&\n regExpTest(EXPRESSIONS.DOCTYPE_NAME, body.ownerDocument.doctype.name)\n ) {\n serializedHTML =\n '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\\n' + serializedHTML;\n }\n\n /* Sanitize final string template-safe */\n if (SAFE_FOR_TEMPLATES) {\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], (expr) => {\n serializedHTML = stringReplace(serializedHTML, expr, ' ');\n });\n }\n\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE\n ? trustedTypesPolicy.createHTML(serializedHTML)\n : serializedHTML;\n };\n\n /**\n * Public method to set the configuration once\n * setConfig\n *\n * @param {Object} cfg configuration object\n */\n DOMPurify.setConfig = function (cfg = {}) {\n _parseConfig(cfg);\n SET_CONFIG = true;\n };\n\n /**\n * Public method to remove the configuration\n * clearConfig\n *\n */\n DOMPurify.clearConfig = function () {\n CONFIG = null;\n SET_CONFIG = false;\n };\n\n /**\n * Public method to check if an attribute value is valid.\n * Uses last set config, if any. Otherwise, uses config defaults.\n * isValidAttribute\n *\n * @param {String} tag Tag name of containing element.\n * @param {String} attr Attribute name.\n * @param {String} value Attribute value.\n * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.\n */\n DOMPurify.isValidAttribute = function (tag, attr, value) {\n /* Initialize shared config vars if necessary. */\n if (!CONFIG) {\n _parseConfig({});\n }\n\n const lcTag = transformCaseFunc(tag);\n const lcName = transformCaseFunc(attr);\n return _isValidAttribute(lcTag, lcName, value);\n };\n\n /**\n * AddHook\n * Public method to add DOMPurify hooks\n *\n * @param {String} entryPoint entry point for the hook to add\n * @param {Function} hookFunction function to execute\n */\n DOMPurify.addHook = function (entryPoint, hookFunction) {\n if (typeof hookFunction !== 'function') {\n return;\n }\n\n hooks[entryPoint] = hooks[entryPoint] || [];\n arrayPush(hooks[entryPoint], hookFunction);\n };\n\n /**\n * RemoveHook\n * Public method to remove a DOMPurify hook at a given entryPoint\n * (pops it from the stack of hooks if more are present)\n *\n * @param {String} entryPoint entry point for the hook to remove\n * @return {Function} removed(popped) hook\n */\n DOMPurify.removeHook = function (entryPoint) {\n if (hooks[entryPoint]) {\n return arrayPop(hooks[entryPoint]);\n }\n };\n\n /**\n * RemoveHooks\n * Public method to remove all DOMPurify hooks at a given entryPoint\n *\n * @param {String} entryPoint entry point for the hooks to remove\n */\n DOMPurify.removeHooks = function (entryPoint) {\n if (hooks[entryPoint]) {\n hooks[entryPoint] = [];\n }\n };\n\n /**\n * RemoveAllHooks\n * Public method to remove all DOMPurify hooks\n */\n DOMPurify.removeAllHooks = function () {\n hooks = {};\n };\n\n return DOMPurify;\n}\n\nexport default createDOMPurify();\n"],"names":["entries","setPrototypeOf","isFrozen","getPrototypeOf","getOwnPropertyDescriptor","Object","freeze","seal","create","apply","construct","Reflect","x","fun","thisValue","args","Func","arrayForEach","unapply","Array","prototype","forEach","arrayPop","pop","arrayPush","push","stringToLowerCase","String","toLowerCase","stringToString","toString","stringMatch","match","stringReplace","replace","stringIndexOf","indexOf","stringTrim","trim","objectHasOwnProperty","hasOwnProperty","regExpTest","RegExp","test","typeErrorCreate","unconstruct","TypeError","func","thisArg","_len","arguments","length","_key","_len2","_key2","addToSet","set","array","transformCaseFunc","undefined","l","element","lcElement","cleanArray","index","isPropertyExist","clone","object","newObject","property","value","isArray","constructor","lookupGetter","prop","desc","get","fallbackValue","html","svg","svgFilters","svgDisallowed","mathMl","mathMlDisallowed","text","xml","MUSTACHE_EXPR","ERB_EXPR","TMPLIT_EXPR","DATA_ATTR","ARIA_ATTR","IS_ALLOWED_URI","IS_SCRIPT_OR_DATA","ATTR_WHITESPACE","DOCTYPE_NAME","CUSTOM_ELEMENT","NODE_TYPE","attribute","cdataSection","entityReference","entityNode","progressingInstruction","comment","document","documentType","documentFragment","notation","getGlobal","window","_createTrustedTypesPolicy","trustedTypes","purifyHostElement","createPolicy","suffix","ATTR_NAME","hasAttribute","getAttribute","policyName","createHTML","createScriptURL","scriptUrl","_","console","warn","createDOMPurify","DOMPurify","root","version","VERSION","removed","nodeType","isSupported","originalDocument","currentScript","DocumentFragment","HTMLTemplateElement","Node","Element","NodeFilter","NamedNodeMap","MozNamedAttrMap","HTMLFormElement","DOMParser","ElementPrototype","cloneNode","remove","getNextSibling","getChildNodes","getParentNode","template","createElement","content","ownerDocument","trustedTypesPolicy","emptyHTML","implementation","createNodeIterator","createDocumentFragment","getElementsByTagName","importNode","hooks","createHTMLDocument","EXPRESSIONS","ALLOWED_TAGS","DEFAULT_ALLOWED_TAGS","TAGS","ALLOWED_ATTR","DEFAULT_ALLOWED_ATTR","ATTRS","CUSTOM_ELEMENT_HANDLING","tagNameCheck","writable","configurable","enumerable","attributeNameCheck","allowCustomizedBuiltInElements","FORBID_TAGS","FORBID_ATTR","ALLOW_ARIA_ATTR","ALLOW_DATA_ATTR","ALLOW_UNKNOWN_PROTOCOLS","ALLOW_SELF_CLOSE_IN_ATTR","SAFE_FOR_TEMPLATES","SAFE_FOR_XML","WHOLE_DOCUMENT","SET_CONFIG","FORCE_BODY","RETURN_DOM","RETURN_DOM_FRAGMENT","RETURN_TRUSTED_TYPE","SANITIZE_DOM","SANITIZE_NAMED_PROPS","SANITIZE_NAMED_PROPS_PREFIX","KEEP_CONTENT","IN_PLACE","USE_PROFILES","FORBID_CONTENTS","DEFAULT_FORBID_CONTENTS","DATA_URI_TAGS","DEFAULT_DATA_URI_TAGS","URI_SAFE_ATTRIBUTES","DEFAULT_URI_SAFE_ATTRIBUTES","MATHML_NAMESPACE","SVG_NAMESPACE","HTML_NAMESPACE","NAMESPACE","IS_EMPTY_INPUT","ALLOWED_NAMESPACES","DEFAULT_ALLOWED_NAMESPACES","PARSER_MEDIA_TYPE","SUPPORTED_PARSER_MEDIA_TYPES","DEFAULT_PARSER_MEDIA_TYPE","CONFIG","formElement","isRegexOrFunction","testValue","Function","_parseConfig","cfg","ADD_URI_SAFE_ATTR","ADD_DATA_URI_TAGS","ALLOWED_URI_REGEXP","ADD_TAGS","ADD_ATTR","table","tbody","TRUSTED_TYPES_POLICY","MATHML_TEXT_INTEGRATION_POINTS","HTML_INTEGRATION_POINTS","COMMON_SVG_AND_HTML_ELEMENTS","ALL_SVG_TAGS","ALL_MATHML_TAGS","_checkValidNamespace","parent","tagName","namespaceURI","parentTagName","Boolean","_forceRemove","node","removeChild","_removeAttribute","name","getAttributeNode","from","removeAttribute","setAttribute","_initDocument","dirty","doc","leadingWhitespace","matches","dirtyPayload","parseFromString","documentElement","createDocument","innerHTML","body","insertBefore","createTextNode","childNodes","call","_createNodeIterator","SHOW_ELEMENT","SHOW_COMMENT","SHOW_TEXT","SHOW_PROCESSING_INSTRUCTION","SHOW_CDATA_SECTION","_isClobbered","elm","nodeName","textContent","attributes","hasChildNodes","_isNode","_executeHook","entryPoint","currentNode","data","hook","_sanitizeElements","allowedTags","firstElementChild","_isBasicCustomElement","parentNode","childCount","i","childClone","__removalCount","expr","_isValidAttribute","lcTag","lcName","_sanitizeAttributes","hookEvent","attrName","attrValue","keepAttr","allowedAttributes","attr","forceKeepAttr","getAttributeType","setAttributeNS","_sanitizeShadowDOM","fragment","shadowNode","shadowIterator","nextNode","sanitize","importedNode","returnNode","appendChild","firstChild","nodeIterator","shadowroot","shadowrootmode","serializedHTML","outerHTML","doctype","setConfig","clearConfig","isValidAttribute","tag","addHook","hookFunction","removeHook","removeHooks","removeAllHooks"],"mappings":";;;;;;;;EAAA,MAAM;IACJA,OAAO;IACPC,cAAc;IACdC,QAAQ;IACRC,cAAc;EACdC,EAAAA,wBAAAA;EACF,CAAC,GAAGC,MAAM,CAAA;EAEV,IAAI;IAAEC,MAAM;IAAEC,IAAI;EAAEC,EAAAA,MAAAA;EAAO,CAAC,GAAGH,MAAM,CAAC;EACtC,IAAI;IAAEI,KAAK;EAAEC,EAAAA,SAAAA;EAAU,CAAC,GAAG,OAAOC,OAAO,KAAK,WAAW,IAAIA,OAAO,CAAA;EAEpE,IAAI,CAACL,MAAM,EAAE;EACXA,EAAAA,MAAM,GAAG,SAAAA,MAAUM,CAAAA,CAAC,EAAE;EACpB,IAAA,OAAOA,CAAC,CAAA;KACT,CAAA;EACH,CAAA;EAEA,IAAI,CAACL,IAAI,EAAE;EACTA,EAAAA,IAAI,GAAG,SAAAA,IAAUK,CAAAA,CAAC,EAAE;EAClB,IAAA,OAAOA,CAAC,CAAA;KACT,CAAA;EACH,CAAA;EAEA,IAAI,CAACH,KAAK,EAAE;IACVA,KAAK,GAAG,SAAAA,KAAUI,CAAAA,GAAG,EAAEC,SAAS,EAAEC,IAAI,EAAE;EACtC,IAAA,OAAOF,GAAG,CAACJ,KAAK,CAACK,SAAS,EAAEC,IAAI,CAAC,CAAA;KAClC,CAAA;EACH,CAAA;EAEA,IAAI,CAACL,SAAS,EAAE;EACdA,EAAAA,SAAS,GAAG,SAAAA,SAAAA,CAAUM,IAAI,EAAED,IAAI,EAAE;EAChC,IAAA,OAAO,IAAIC,IAAI,CAAC,GAAGD,IAAI,CAAC,CAAA;KACzB,CAAA;EACH,CAAA;EAEA,MAAME,YAAY,GAAGC,OAAO,CAACC,KAAK,CAACC,SAAS,CAACC,OAAO,CAAC,CAAA;EAErD,MAAMC,QAAQ,GAAGJ,OAAO,CAACC,KAAK,CAACC,SAAS,CAACG,GAAG,CAAC,CAAA;EAC7C,MAAMC,SAAS,GAAGN,OAAO,CAACC,KAAK,CAACC,SAAS,CAACK,IAAI,CAAC,CAAA;EAG/C,MAAMC,iBAAiB,GAAGR,OAAO,CAACS,MAAM,CAACP,SAAS,CAACQ,WAAW,CAAC,CAAA;EAC/D,MAAMC,cAAc,GAAGX,OAAO,CAACS,MAAM,CAACP,SAAS,CAACU,QAAQ,CAAC,CAAA;EACzD,MAAMC,WAAW,GAAGb,OAAO,CAACS,MAAM,CAACP,SAAS,CAACY,KAAK,CAAC,CAAA;EACnD,MAAMC,aAAa,GAAGf,OAAO,CAACS,MAAM,CAACP,SAAS,CAACc,OAAO,CAAC,CAAA;EACvD,MAAMC,aAAa,GAAGjB,OAAO,CAACS,MAAM,CAACP,SAAS,CAACgB,OAAO,CAAC,CAAA;EACvD,MAAMC,UAAU,GAAGnB,OAAO,CAACS,MAAM,CAACP,SAAS,CAACkB,IAAI,CAAC,CAAA;EAEjD,MAAMC,oBAAoB,GAAGrB,OAAO,CAACb,MAAM,CAACe,SAAS,CAACoB,cAAc,CAAC,CAAA;EAErE,MAAMC,UAAU,GAAGvB,OAAO,CAACwB,MAAM,CAACtB,SAAS,CAACuB,IAAI,CAAC,CAAA;EAEjD,MAAMC,eAAe,GAAGC,WAAW,CAACC,SAAS,CAAC,CAAA;;EAE9C;EACA;EACA;EACA;EACA;EACA;EACA,SAAS5B,OAAOA,CAAC6B,IAAI,EAAE;EACrB,EAAA,OAAO,UAACC,OAAO,EAAA;MAAA,KAAAC,IAAAA,IAAA,GAAAC,SAAA,CAAAC,MAAA,EAAKpC,IAAI,OAAAI,KAAA,CAAA8B,IAAA,GAAAA,CAAAA,GAAAA,IAAA,WAAAG,IAAA,GAAA,CAAA,EAAAA,IAAA,GAAAH,IAAA,EAAAG,IAAA,EAAA,EAAA;EAAJrC,MAAAA,IAAI,CAAAqC,IAAA,GAAAF,CAAAA,CAAAA,GAAAA,SAAA,CAAAE,IAAA,CAAA,CAAA;EAAA,KAAA;EAAA,IAAA,OAAK3C,KAAK,CAACsC,IAAI,EAAEC,OAAO,EAAEjC,IAAI,CAAC,CAAA;EAAA,GAAA,CAAA;EACzD,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS8B,WAAWA,CAACE,IAAI,EAAE;IACzB,OAAO,YAAA;EAAA,IAAA,KAAA,IAAAM,KAAA,GAAAH,SAAA,CAAAC,MAAA,EAAIpC,IAAI,GAAAI,IAAAA,KAAA,CAAAkC,KAAA,GAAAC,KAAA,GAAA,CAAA,EAAAA,KAAA,GAAAD,KAAA,EAAAC,KAAA,EAAA,EAAA;EAAJvC,MAAAA,IAAI,CAAAuC,KAAA,CAAAJ,GAAAA,SAAA,CAAAI,KAAA,CAAA,CAAA;EAAA,KAAA;EAAA,IAAA,OAAK5C,SAAS,CAACqC,IAAI,EAAEhC,IAAI,CAAC,CAAA;EAAA,GAAA,CAAA;EAC3C,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASwC,QAAQA,CAACC,GAAG,EAAEC,KAAK,EAAyC;EAAA,EAAA,IAAvCC,iBAAiB,GAAAR,SAAA,CAAAC,MAAA,GAAA,CAAA,IAAAD,SAAA,CAAA,CAAA,CAAA,KAAAS,SAAA,GAAAT,SAAA,CAAA,CAAA,CAAA,GAAGxB,iBAAiB,CAAA;EACjE,EAAA,IAAIzB,cAAc,EAAE;EAClB;EACA;EACA;EACAA,IAAAA,cAAc,CAACuD,GAAG,EAAE,IAAI,CAAC,CAAA;EAC3B,GAAA;EAEA,EAAA,IAAII,CAAC,GAAGH,KAAK,CAACN,MAAM,CAAA;IACpB,OAAOS,CAAC,EAAE,EAAE;EACV,IAAA,IAAIC,OAAO,GAAGJ,KAAK,CAACG,CAAC,CAAC,CAAA;EACtB,IAAA,IAAI,OAAOC,OAAO,KAAK,QAAQ,EAAE;EAC/B,MAAA,MAAMC,SAAS,GAAGJ,iBAAiB,CAACG,OAAO,CAAC,CAAA;QAC5C,IAAIC,SAAS,KAAKD,OAAO,EAAE;EACzB;EACA,QAAA,IAAI,CAAC3D,QAAQ,CAACuD,KAAK,CAAC,EAAE;EACpBA,UAAAA,KAAK,CAACG,CAAC,CAAC,GAAGE,SAAS,CAAA;EACtB,SAAA;EAEAD,QAAAA,OAAO,GAAGC,SAAS,CAAA;EACrB,OAAA;EACF,KAAA;EAEAN,IAAAA,GAAG,CAACK,OAAO,CAAC,GAAG,IAAI,CAAA;EACrB,GAAA;EAEA,EAAA,OAAOL,GAAG,CAAA;EACZ,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA,SAASO,UAAUA,CAACN,KAAK,EAAE;EACzB,EAAA,KAAK,IAAIO,KAAK,GAAG,CAAC,EAAEA,KAAK,GAAGP,KAAK,CAACN,MAAM,EAAEa,KAAK,EAAE,EAAE;EACjD,IAAA,MAAMC,eAAe,GAAG1B,oBAAoB,CAACkB,KAAK,EAAEO,KAAK,CAAC,CAAA;MAE1D,IAAI,CAACC,eAAe,EAAE;EACpBR,MAAAA,KAAK,CAACO,KAAK,CAAC,GAAG,IAAI,CAAA;EACrB,KAAA;EACF,GAAA;EAEA,EAAA,OAAOP,KAAK,CAAA;EACd,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA,SAASS,KAAKA,CAACC,MAAM,EAAE;EACrB,EAAA,MAAMC,SAAS,GAAG5D,MAAM,CAAC,IAAI,CAAC,CAAA;IAE9B,KAAK,MAAM,CAAC6D,QAAQ,EAAEC,KAAK,CAAC,IAAItE,OAAO,CAACmE,MAAM,CAAC,EAAE;EAC/C,IAAA,MAAMF,eAAe,GAAG1B,oBAAoB,CAAC4B,MAAM,EAAEE,QAAQ,CAAC,CAAA;EAE9D,IAAA,IAAIJ,eAAe,EAAE;EACnB,MAAA,IAAI9C,KAAK,CAACoD,OAAO,CAACD,KAAK,CAAC,EAAE;EACxBF,QAAAA,SAAS,CAACC,QAAQ,CAAC,GAAGN,UAAU,CAACO,KAAK,CAAC,CAAA;EACzC,OAAC,MAAM,IACLA,KAAK,IACL,OAAOA,KAAK,KAAK,QAAQ,IACzBA,KAAK,CAACE,WAAW,KAAKnE,MAAM,EAC5B;EACA+D,QAAAA,SAAS,CAACC,QAAQ,CAAC,GAAGH,KAAK,CAACI,KAAK,CAAC,CAAA;EACpC,OAAC,MAAM;EACLF,QAAAA,SAAS,CAACC,QAAQ,CAAC,GAAGC,KAAK,CAAA;EAC7B,OAAA;EACF,KAAA;EACF,GAAA;EAEA,EAAA,OAAOF,SAAS,CAAA;EAClB,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASK,YAAYA,CAACN,MAAM,EAAEO,IAAI,EAAE;IAClC,OAAOP,MAAM,KAAK,IAAI,EAAE;EACtB,IAAA,MAAMQ,IAAI,GAAGvE,wBAAwB,CAAC+D,MAAM,EAAEO,IAAI,CAAC,CAAA;EAEnD,IAAA,IAAIC,IAAI,EAAE;QACR,IAAIA,IAAI,CAACC,GAAG,EAAE;EACZ,QAAA,OAAO1D,OAAO,CAACyD,IAAI,CAACC,GAAG,CAAC,CAAA;EAC1B,OAAA;EAEA,MAAA,IAAI,OAAOD,IAAI,CAACL,KAAK,KAAK,UAAU,EAAE;EACpC,QAAA,OAAOpD,OAAO,CAACyD,IAAI,CAACL,KAAK,CAAC,CAAA;EAC5B,OAAA;EACF,KAAA;EAEAH,IAAAA,MAAM,GAAGhE,cAAc,CAACgE,MAAM,CAAC,CAAA;EACjC,GAAA;IAEA,SAASU,aAAaA,GAAG;EACvB,IAAA,OAAO,IAAI,CAAA;EACb,GAAA;EAEA,EAAA,OAAOA,aAAa,CAAA;EACtB;;EC1LO,MAAMC,MAAI,GAAGxE,MAAM,CAAC,CACzB,GAAG,EACH,MAAM,EACN,SAAS,EACT,SAAS,EACT,MAAM,EACN,SAAS,EACT,OAAO,EACP,OAAO,EACP,GAAG,EACH,KAAK,EACL,KAAK,EACL,KAAK,EACL,OAAO,EACP,YAAY,EACZ,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,MAAM,EACN,MAAM,EACN,KAAK,EACL,UAAU,EACV,SAAS,EACT,MAAM,EACN,UAAU,EACV,IAAI,EACJ,WAAW,EACX,KAAK,EACL,SAAS,EACT,KAAK,EACL,QAAQ,EACR,KAAK,EACL,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,GAAG,EACH,KAAK,EACL,OAAO,EACP,KAAK,EACL,KAAK,EACL,OAAO,EACP,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,KAAK,EACL,MAAM,EACN,SAAS,EACT,MAAM,EACN,UAAU,EACV,OAAO,EACP,KAAK,EACL,MAAM,EACN,IAAI,EACJ,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,GAAG,EACH,SAAS,EACT,KAAK,EACL,UAAU,EACV,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,GAAG,EACH,MAAM,EACN,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,KAAK,EACL,SAAS,EACT,KAAK,EACL,OAAO,EACP,OAAO,EACP,IAAI,EACJ,UAAU,EACV,UAAU,EACV,OAAO,EACP,IAAI,EACJ,OAAO,EACP,MAAM,EACN,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,GAAG,EACH,IAAI,EACJ,KAAK,EACL,OAAO,EACP,KAAK,CACN,CAAC,CAAA;;EAEF;EACO,MAAMyE,KAAG,GAAGzE,MAAM,CAAC,CACxB,KAAK,EACL,GAAG,EACH,UAAU,EACV,aAAa,EACb,cAAc,EACd,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,QAAQ,EACR,UAAU,EACV,MAAM,EACN,MAAM,EACN,SAAS,EACT,QAAQ,EACR,MAAM,EACN,GAAG,EACH,OAAO,EACP,UAAU,EACV,OAAO,EACP,OAAO,EACP,MAAM,EACN,gBAAgB,EAChB,QAAQ,EACR,MAAM,EACN,UAAU,EACV,OAAO,EACP,MAAM,EACN,SAAS,EACT,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,MAAM,EACN,MAAM,EACN,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,UAAU,EACV,OAAO,EACP,MAAM,EACN,OAAO,EACP,MAAM,EACN,OAAO,CACR,CAAC,CAAA;EAEK,MAAM0E,UAAU,GAAG1E,MAAM,CAAC,CAC/B,SAAS,EACT,eAAe,EACf,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,SAAS,EACT,SAAS,EACT,aAAa,EACb,cAAc,EACd,UAAU,EACV,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,QAAQ,EACR,cAAc,CACf,CAAC,CAAA;;EAEF;EACA;EACA;EACA;EACO,MAAM2E,aAAa,GAAG3E,MAAM,CAAC,CAClC,SAAS,EACT,eAAe,EACf,QAAQ,EACR,SAAS,EACT,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,eAAe,EACf,OAAO,EACP,WAAW,EACX,MAAM,EACN,cAAc,EACd,WAAW,EACX,SAAS,EACT,eAAe,EACf,QAAQ,EACR,KAAK,EACL,YAAY,EACZ,SAAS,EACT,KAAK,CACN,CAAC,CAAA;EAEK,MAAM4E,QAAM,GAAG5E,MAAM,CAAC,CAC3B,MAAM,EACN,UAAU,EACV,QAAQ,EACR,SAAS,EACT,OAAO,EACP,QAAQ,EACR,IAAI,EACJ,YAAY,EACZ,eAAe,EACf,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,SAAS,EACT,UAAU,EACV,OAAO,EACP,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,MAAM,EACN,MAAM,EACN,SAAS,EACT,QAAQ,EACR,KAAK,EACL,OAAO,EACP,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,aAAa,CACd,CAAC,CAAA;;EAEF;EACA;EACO,MAAM6E,gBAAgB,GAAG7E,MAAM,CAAC,CACrC,SAAS,EACT,aAAa,EACb,YAAY,EACZ,UAAU,EACV,WAAW,EACX,SAAS,EACT,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,MAAM,CACP,CAAC,CAAA;EAEK,MAAM8E,IAAI,GAAG9E,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;;ECrR9B,MAAMwE,IAAI,GAAGxE,MAAM,CAAC,CACzB,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,KAAK,EACL,gBAAgB,EAChB,cAAc,EACd,sBAAsB,EACtB,UAAU,EACV,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,SAAS,EACT,aAAa,EACb,aAAa,EACb,SAAS,EACT,MAAM,EACN,OAAO,EACP,OAAO,EACP,OAAO,EACP,MAAM,EACN,SAAS,EACT,UAAU,EACV,cAAc,EACd,QAAQ,EACR,aAAa,EACb,UAAU,EACV,UAAU,EACV,SAAS,EACT,KAAK,EACL,UAAU,EACV,yBAAyB,EACzB,uBAAuB,EACvB,UAAU,EACV,WAAW,EACX,SAAS,EACT,cAAc,EACd,MAAM,EACN,KAAK,EACL,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,MAAM,EACN,UAAU,EACV,IAAI,EACJ,WAAW,EACX,WAAW,EACX,OAAO,EACP,MAAM,EACN,OAAO,EACP,MAAM,EACN,MAAM,EACN,SAAS,EACT,MAAM,EACN,KAAK,EACL,KAAK,EACL,WAAW,EACX,OAAO,EACP,QAAQ,EACR,KAAK,EACL,WAAW,EACX,UAAU,EACV,OAAO,EACP,MAAM,EACN,OAAO,EACP,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,MAAM,EACN,SAAS,EACT,SAAS,EACT,aAAa,EACb,aAAa,EACb,SAAS,EACT,eAAe,EACf,qBAAqB,EACrB,QAAQ,EACR,SAAS,EACT,SAAS,EACT,YAAY,EACZ,UAAU,EACV,KAAK,EACL,UAAU,EACV,KAAK,EACL,UAAU,EACV,MAAM,EACN,MAAM,EACN,SAAS,EACT,YAAY,EACZ,OAAO,EACP,UAAU,EACV,OAAO,EACP,MAAM,EACN,OAAO,EACP,MAAM,EACN,SAAS,EACT,OAAO,EACP,KAAK,EACL,QAAQ,EACR,MAAM,EACN,OAAO,EACP,SAAS,EACT,UAAU,EACV,OAAO,EACP,WAAW,EACX,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,OAAO,EACP,MAAM,EACN,OAAO,EACP,MAAM,CACP,CAAC,CAAA;EAEK,MAAMyE,GAAG,GAAGzE,MAAM,CAAC,CACxB,eAAe,EACf,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,QAAQ,EACR,eAAe,EACf,eAAe,EACf,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,OAAO,EACP,MAAM,EACN,IAAI,EACJ,OAAO,EACP,MAAM,EACN,eAAe,EACf,WAAW,EACX,WAAW,EACX,OAAO,EACP,qBAAqB,EACrB,6BAA6B,EAC7B,eAAe,EACf,iBAAiB,EACjB,IAAI,EACJ,IAAI,EACJ,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,iBAAiB,EACjB,WAAW,EACX,SAAS,EACT,SAAS,EACT,KAAK,EACL,UAAU,EACV,WAAW,EACX,KAAK,EACL,MAAM,EACN,cAAc,EACd,WAAW,EACX,QAAQ,EACR,aAAa,EACb,aAAa,EACb,eAAe,EACf,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,cAAc,EACd,aAAa,EACb,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,YAAY,EACZ,UAAU,EACV,eAAe,EACf,mBAAmB,EACnB,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,iBAAiB,EACjB,IAAI,EACJ,KAAK,EACL,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,WAAW,EACX,YAAY,EACZ,UAAU,EACV,MAAM,EACN,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,cAAc,EACd,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,KAAK,EACL,MAAM,EACN,OAAO,EACP,QAAQ,EACR,MAAM,EACN,KAAK,EACL,MAAM,EACN,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,SAAS,EACT,OAAO,EACP,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,UAAU,EACV,aAAa,EACb,MAAM,EACN,YAAY,EACZ,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,EACd,QAAQ,EACR,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,MAAM,EACN,aAAa,EACb,WAAW,EACX,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,MAAM,EACN,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,cAAc,EACd,aAAa,EACb,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,QAAQ,EACR,cAAc,EACd,OAAO,EACP,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,SAAS,EACT,SAAS,EACT,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,eAAe,EACf,eAAe,EACf,OAAO,EACP,cAAc,EACd,MAAM,EACN,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,GAAG,EACH,YAAY,CACb,CAAC,CAAA;EAEK,MAAM4E,MAAM,GAAG5E,MAAM,CAAC,CAC3B,QAAQ,EACR,aAAa,EACb,OAAO,EACP,UAAU,EACV,OAAO,EACP,cAAc,EACd,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,OAAO,EACP,KAAK,EACL,SAAS,EACT,cAAc,EACd,UAAU,EACV,OAAO,EACP,OAAO,EACP,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,aAAa,EACb,SAAS,EACT,SAAS,EACT,eAAe,EACf,UAAU,EACV,UAAU,EACV,MAAM,EACN,UAAU,EACV,UAAU,EACV,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,WAAW,EACX,WAAW,EACX,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,OAAO,EACP,OAAO,CACR,CAAC,CAAA;EAEK,MAAM+E,GAAG,GAAG/E,MAAM,CAAC,CACxB,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,WAAW,EACX,aAAa,CACd,CAAC;;EC3WF;EACO,MAAMgF,aAAa,GAAG/E,IAAI,CAAC,2BAA2B,CAAC,CAAC;EACxD,MAAMgF,QAAQ,GAAGhF,IAAI,CAAC,uBAAuB,CAAC,CAAA;EAC9C,MAAMiF,WAAW,GAAGjF,IAAI,CAAC,eAAe,CAAC,CAAA;EACzC,MAAMkF,SAAS,GAAGlF,IAAI,CAAC,4BAA4B,CAAC,CAAC;EACrD,MAAMmF,SAAS,GAAGnF,IAAI,CAAC,gBAAgB,CAAC,CAAC;EACzC,MAAMoF,cAAc,GAAGpF,IAAI,CAChC,2FAA2F;EAC7F,CAAC,CAAA;EACM,MAAMqF,iBAAiB,GAAGrF,IAAI,CAAC,uBAAuB,CAAC,CAAA;EACvD,MAAMsF,eAAe,GAAGtF,IAAI,CACjC,6DAA6D;EAC/D,CAAC,CAAA;EACM,MAAMuF,YAAY,GAAGvF,IAAI,CAAC,SAAS,CAAC,CAAA;EACpC,MAAMwF,cAAc,GAAGxF,IAAI,CAAC,0BAA0B,CAAC;;;;;;;;;;;;;;;;ECQ9D;EACA,MAAMyF,SAAS,GAAG;EAChBnC,EAAAA,OAAO,EAAE,CAAC;EACVoC,EAAAA,SAAS,EAAE,CAAC;EACZb,EAAAA,IAAI,EAAE,CAAC;EACPc,EAAAA,YAAY,EAAE,CAAC;EACfC,EAAAA,eAAe,EAAE,CAAC;EAAE;EACpBC,EAAAA,UAAU,EAAE,CAAC;EAAE;EACfC,EAAAA,sBAAsB,EAAE,CAAC;EACzBC,EAAAA,OAAO,EAAE,CAAC;EACVC,EAAAA,QAAQ,EAAE,CAAC;EACXC,EAAAA,YAAY,EAAE,EAAE;EAChBC,EAAAA,gBAAgB,EAAE,EAAE;IACpBC,QAAQ,EAAE,EAAE;EACd,CAAC,CAAA;EAED,MAAMC,SAAS,GAAG,SAAZA,SAASA,GAAe;EAC5B,EAAA,OAAO,OAAOC,MAAM,KAAK,WAAW,GAAG,IAAI,GAAGA,MAAM,CAAA;EACtD,CAAC,CAAA;;EAED;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAMC,yBAAyB,GAAG,SAA5BA,yBAAyBA,CAAaC,YAAY,EAAEC,iBAAiB,EAAE;IAC3E,IACE,OAAOD,YAAY,KAAK,QAAQ,IAChC,OAAOA,YAAY,CAACE,YAAY,KAAK,UAAU,EAC/C;EACA,IAAA,OAAO,IAAI,CAAA;EACb,GAAA;;EAEA;EACA;EACA;IACA,IAAIC,MAAM,GAAG,IAAI,CAAA;IACjB,MAAMC,SAAS,GAAG,uBAAuB,CAAA;IACzC,IAAIH,iBAAiB,IAAIA,iBAAiB,CAACI,YAAY,CAACD,SAAS,CAAC,EAAE;EAClED,IAAAA,MAAM,GAAGF,iBAAiB,CAACK,YAAY,CAACF,SAAS,CAAC,CAAA;EACpD,GAAA;IAEA,MAAMG,UAAU,GAAG,WAAW,IAAIJ,MAAM,GAAG,GAAG,GAAGA,MAAM,GAAG,EAAE,CAAC,CAAA;IAE7D,IAAI;EACF,IAAA,OAAOH,YAAY,CAACE,YAAY,CAACK,UAAU,EAAE;QAC3CC,UAAUA,CAACxC,IAAI,EAAE;EACf,QAAA,OAAOA,IAAI,CAAA;SACZ;QACDyC,eAAeA,CAACC,SAAS,EAAE;EACzB,QAAA,OAAOA,SAAS,CAAA;EAClB,OAAA;EACF,KAAC,CAAC,CAAA;KACH,CAAC,OAAOC,CAAC,EAAE;EACV;EACA;EACA;MACAC,OAAO,CAACC,IAAI,CACV,sBAAsB,GAAGN,UAAU,GAAG,wBACxC,CAAC,CAAA;EACD,IAAA,OAAO,IAAI,CAAA;EACb,GAAA;EACF,CAAC,CAAA;EAED,SAASO,eAAeA,GAAuB;EAAA,EAAA,IAAtBhB,MAAM,GAAA1D,SAAA,CAAAC,MAAA,GAAAD,CAAAA,IAAAA,SAAA,CAAAS,CAAAA,CAAAA,KAAAA,SAAA,GAAAT,SAAA,CAAGyD,CAAAA,CAAAA,GAAAA,SAAS,EAAE,CAAA;EAC3C,EAAA,MAAMkB,SAAS,GAAIC,IAAI,IAAKF,eAAe,CAACE,IAAI,CAAC,CAAA;;EAEjD;EACF;EACA;EACA;IACED,SAAS,CAACE,OAAO,GAAGC,OAAO,CAAA;;EAE3B;EACF;EACA;EACA;IACEH,SAAS,CAACI,OAAO,GAAG,EAAE,CAAA;EAEtB,EAAA,IACE,CAACrB,MAAM,IACP,CAACA,MAAM,CAACL,QAAQ,IAChBK,MAAM,CAACL,QAAQ,CAAC2B,QAAQ,KAAKlC,SAAS,CAACO,QAAQ,EAC/C;EACA;EACA;MACAsB,SAAS,CAACM,WAAW,GAAG,KAAK,CAAA;EAE7B,IAAA,OAAON,SAAS,CAAA;EAClB,GAAA;IAEA,IAAI;EAAEtB,IAAAA,QAAAA;EAAS,GAAC,GAAGK,MAAM,CAAA;IAEzB,MAAMwB,gBAAgB,GAAG7B,QAAQ,CAAA;EACjC,EAAA,MAAM8B,aAAa,GAAGD,gBAAgB,CAACC,aAAa,CAAA;IACpD,MAAM;MACJC,gBAAgB;MAChBC,mBAAmB;MACnBC,IAAI;MACJC,OAAO;MACPC,UAAU;EACVC,IAAAA,YAAY,GAAG/B,MAAM,CAAC+B,YAAY,IAAI/B,MAAM,CAACgC,eAAe;MAC5DC,eAAe;MACfC,SAAS;EACThC,IAAAA,YAAAA;EACF,GAAC,GAAGF,MAAM,CAAA;EAEV,EAAA,MAAMmC,gBAAgB,GAAGN,OAAO,CAACrH,SAAS,CAAA;EAE1C,EAAA,MAAM4H,SAAS,GAAGvE,YAAY,CAACsE,gBAAgB,EAAE,WAAW,CAAC,CAAA;EAC7D,EAAA,MAAME,MAAM,GAAGxE,YAAY,CAACsE,gBAAgB,EAAE,QAAQ,CAAC,CAAA;EACvD,EAAA,MAAMG,cAAc,GAAGzE,YAAY,CAACsE,gBAAgB,EAAE,aAAa,CAAC,CAAA;EACpE,EAAA,MAAMI,aAAa,GAAG1E,YAAY,CAACsE,gBAAgB,EAAE,YAAY,CAAC,CAAA;EAClE,EAAA,MAAMK,aAAa,GAAG3E,YAAY,CAACsE,gBAAgB,EAAE,YAAY,CAAC,CAAA;;EAElE;EACA;EACA;EACA;EACA;EACA;EACA,EAAA,IAAI,OAAOR,mBAAmB,KAAK,UAAU,EAAE;EAC7C,IAAA,MAAMc,QAAQ,GAAG9C,QAAQ,CAAC+C,aAAa,CAAC,UAAU,CAAC,CAAA;MACnD,IAAID,QAAQ,CAACE,OAAO,IAAIF,QAAQ,CAACE,OAAO,CAACC,aAAa,EAAE;EACtDjD,MAAAA,QAAQ,GAAG8C,QAAQ,CAACE,OAAO,CAACC,aAAa,CAAA;EAC3C,KAAA;EACF,GAAA;EAEA,EAAA,IAAIC,kBAAkB,CAAA;IACtB,IAAIC,SAAS,GAAG,EAAE,CAAA;IAElB,MAAM;MACJC,cAAc;MACdC,kBAAkB;MAClBC,sBAAsB;EACtBC,IAAAA,oBAAAA;EACF,GAAC,GAAGvD,QAAQ,CAAA;IACZ,MAAM;EAAEwD,IAAAA,UAAAA;EAAW,GAAC,GAAG3B,gBAAgB,CAAA;IAEvC,IAAI4B,KAAK,GAAG,EAAE,CAAA;;EAEd;EACF;EACA;EACEnC,EAAAA,SAAS,CAACM,WAAW,GACnB,OAAOnI,OAAO,KAAK,UAAU,IAC7B,OAAOoJ,aAAa,KAAK,UAAU,IACnCO,cAAc,IACdA,cAAc,CAACM,kBAAkB,KAAKtG,SAAS,CAAA;IAEjD,MAAM;MACJ2B,aAAa;MACbC,QAAQ;MACRC,WAAW;MACXC,SAAS;MACTC,SAAS;MACTE,iBAAiB;MACjBC,eAAe;EACfE,IAAAA,cAAAA;EACF,GAAC,GAAGmE,WAAW,CAAA;IAEf,IAAI;EAAEvE,oBAAAA,gBAAAA;EAAe,GAAC,GAAGuE,WAAW,CAAA;;EAEpC;EACF;EACA;EACA;;EAEE;IACA,IAAIC,YAAY,GAAG,IAAI,CAAA;EACvB,EAAA,MAAMC,oBAAoB,GAAG7G,QAAQ,CAAC,EAAE,EAAE,CACxC,GAAG8G,MAAS,EACZ,GAAGA,KAAQ,EACX,GAAGA,UAAe,EAClB,GAAGA,QAAW,EACd,GAAGA,IAAS,CACb,CAAC,CAAA;;EAEF;IACA,IAAIC,YAAY,GAAG,IAAI,CAAA;EACvB,EAAA,MAAMC,oBAAoB,GAAGhH,QAAQ,CAAC,EAAE,EAAE,CACxC,GAAGiH,IAAU,EACb,GAAGA,GAAS,EACZ,GAAGA,MAAY,EACf,GAAGA,GAAS,CACb,CAAC,CAAA;;EAEF;EACF;EACA;EACA;EACA;EACA;IACE,IAAIC,uBAAuB,GAAGpK,MAAM,CAACE,IAAI,CACvCC,MAAM,CAAC,IAAI,EAAE;EACXkK,IAAAA,YAAY,EAAE;EACZC,MAAAA,QAAQ,EAAE,IAAI;EACdC,MAAAA,YAAY,EAAE,KAAK;EACnBC,MAAAA,UAAU,EAAE,IAAI;EAChBvG,MAAAA,KAAK,EAAE,IAAA;OACR;EACDwG,IAAAA,kBAAkB,EAAE;EAClBH,MAAAA,QAAQ,EAAE,IAAI;EACdC,MAAAA,YAAY,EAAE,KAAK;EACnBC,MAAAA,UAAU,EAAE,IAAI;EAChBvG,MAAAA,KAAK,EAAE,IAAA;OACR;EACDyG,IAAAA,8BAA8B,EAAE;EAC9BJ,MAAAA,QAAQ,EAAE,IAAI;EACdC,MAAAA,YAAY,EAAE,KAAK;EACnBC,MAAAA,UAAU,EAAE,IAAI;EAChBvG,MAAAA,KAAK,EAAE,KAAA;EACT,KAAA;EACF,GAAC,CACH,CAAC,CAAA;;EAED;IACA,IAAI0G,WAAW,GAAG,IAAI,CAAA;;EAEtB;IACA,IAAIC,WAAW,GAAG,IAAI,CAAA;;EAEtB;IACA,IAAIC,eAAe,GAAG,IAAI,CAAA;;EAE1B;IACA,IAAIC,eAAe,GAAG,IAAI,CAAA;;EAE1B;IACA,IAAIC,uBAAuB,GAAG,KAAK,CAAA;;EAEnC;EACF;IACE,IAAIC,wBAAwB,GAAG,IAAI,CAAA;;EAEnC;EACF;EACA;IACE,IAAIC,kBAAkB,GAAG,KAAK,CAAA;;EAE9B;EACF;EACA;IACE,IAAIC,YAAY,GAAG,IAAI,CAAA;;EAEvB;IACA,IAAIC,cAAc,GAAG,KAAK,CAAA;;EAE1B;IACA,IAAIC,UAAU,GAAG,KAAK,CAAA;;EAEtB;EACF;IACE,IAAIC,UAAU,GAAG,KAAK,CAAA;;EAEtB;EACF;EACA;EACA;IACE,IAAIC,UAAU,GAAG,KAAK,CAAA;;EAEtB;EACF;IACE,IAAIC,mBAAmB,GAAG,KAAK,CAAA;;EAE/B;EACF;IACE,IAAIC,mBAAmB,GAAG,KAAK,CAAA;;EAE/B;EACF;EACA;IACE,IAAIC,YAAY,GAAG,IAAI,CAAA;;EAEvB;EACF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;IACE,IAAIC,oBAAoB,GAAG,KAAK,CAAA;IAChC,MAAMC,2BAA2B,GAAG,eAAe,CAAA;;EAEnD;IACA,IAAIC,YAAY,GAAG,IAAI,CAAA;;EAEvB;EACF;IACE,IAAIC,QAAQ,GAAG,KAAK,CAAA;;EAEpB;IACA,IAAIC,YAAY,GAAG,EAAE,CAAA;;EAErB;IACA,IAAIC,eAAe,GAAG,IAAI,CAAA;IAC1B,MAAMC,uBAAuB,GAAG9I,QAAQ,CAAC,EAAE,EAAE,CAC3C,gBAAgB,EAChB,OAAO,EACP,UAAU,EACV,MAAM,EACN,eAAe,EACf,MAAM,EACN,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,SAAS,EACT,UAAU,EACV,UAAU,EACV,WAAW,EACX,QAAQ,EACR,OAAO,EACP,KAAK,EACL,UAAU,EACV,OAAO,EACP,OAAO,EACP,OAAO,EACP,KAAK,CACN,CAAC,CAAA;;EAEF;IACA,IAAI+I,aAAa,GAAG,IAAI,CAAA;IACxB,MAAMC,qBAAqB,GAAGhJ,QAAQ,CAAC,EAAE,EAAE,CACzC,OAAO,EACP,OAAO,EACP,KAAK,EACL,QAAQ,EACR,OAAO,EACP,OAAO,CACR,CAAC,CAAA;;EAEF;IACA,IAAIiJ,mBAAmB,GAAG,IAAI,CAAA;EAC9B,EAAA,MAAMC,2BAA2B,GAAGlJ,QAAQ,CAAC,EAAE,EAAE,CAC/C,KAAK,EACL,OAAO,EACP,KAAK,EACL,IAAI,EACJ,OAAO,EACP,MAAM,EACN,SAAS,EACT,aAAa,EACb,MAAM,EACN,SAAS,EACT,OAAO,EACP,OAAO,EACP,OAAO,EACP,OAAO,CACR,CAAC,CAAA;IAEF,MAAMmJ,gBAAgB,GAAG,oCAAoC,CAAA;IAC7D,MAAMC,aAAa,GAAG,4BAA4B,CAAA;IAClD,MAAMC,cAAc,GAAG,8BAA8B,CAAA;EACrD;IACA,IAAIC,SAAS,GAAGD,cAAc,CAAA;IAC9B,IAAIE,cAAc,GAAG,KAAK,CAAA;;EAE1B;IACA,IAAIC,kBAAkB,GAAG,IAAI,CAAA;EAC7B,EAAA,MAAMC,0BAA0B,GAAGzJ,QAAQ,CACzC,EAAE,EACF,CAACmJ,gBAAgB,EAAEC,aAAa,EAAEC,cAAc,CAAC,EACjD/K,cACF,CAAC,CAAA;;EAED;IACA,IAAIoL,iBAAiB,GAAG,IAAI,CAAA;EAC5B,EAAA,MAAMC,4BAA4B,GAAG,CAAC,uBAAuB,EAAE,WAAW,CAAC,CAAA;IAC3E,MAAMC,yBAAyB,GAAG,WAAW,CAAA;IAC7C,IAAIzJ,iBAAiB,GAAG,IAAI,CAAA;;EAE5B;IACA,IAAI0J,MAAM,GAAG,IAAI,CAAA;;EAEjB;EACA;;EAEA,EAAA,MAAMC,WAAW,GAAG9G,QAAQ,CAAC+C,aAAa,CAAC,MAAM,CAAC,CAAA;EAElD,EAAA,MAAMgE,iBAAiB,GAAG,SAApBA,iBAAiBA,CAAaC,SAAS,EAAE;EAC7C,IAAA,OAAOA,SAAS,YAAY7K,MAAM,IAAI6K,SAAS,YAAYC,QAAQ,CAAA;KACpE,CAAA;;EAED;EACF;EACA;EACA;EACA;EACE;EACA,EAAA,MAAMC,YAAY,GAAG,SAAfA,YAAYA,GAAuB;EAAA,IAAA,IAAVC,GAAG,GAAAxK,SAAA,CAAAC,MAAA,GAAA,CAAA,IAAAD,SAAA,CAAA,CAAA,CAAA,KAAAS,SAAA,GAAAT,SAAA,CAAA,CAAA,CAAA,GAAG,EAAE,CAAA;EACrC,IAAA,IAAIkK,MAAM,IAAIA,MAAM,KAAKM,GAAG,EAAE;EAC5B,MAAA,OAAA;EACF,KAAA;;EAEA;EACA,IAAA,IAAI,CAACA,GAAG,IAAI,OAAOA,GAAG,KAAK,QAAQ,EAAE;QACnCA,GAAG,GAAG,EAAE,CAAA;EACV,KAAA;;EAEA;EACAA,IAAAA,GAAG,GAAGxJ,KAAK,CAACwJ,GAAG,CAAC,CAAA;MAEhBT,iBAAiB;EACf;EACAC,IAAAA,4BAA4B,CAAC9K,OAAO,CAACsL,GAAG,CAACT,iBAAiB,CAAC,KAAK,CAAC,CAAC,GAC9DE,yBAAyB,GACzBO,GAAG,CAACT,iBAAiB,CAAA;;EAE3B;EACAvJ,IAAAA,iBAAiB,GACfuJ,iBAAiB,KAAK,uBAAuB,GACzCpL,cAAc,GACdH,iBAAiB,CAAA;;EAEvB;MACAyI,YAAY,GAAG5H,oBAAoB,CAACmL,GAAG,EAAE,cAAc,CAAC,GACpDnK,QAAQ,CAAC,EAAE,EAAEmK,GAAG,CAACvD,YAAY,EAAEzG,iBAAiB,CAAC,GACjD0G,oBAAoB,CAAA;MACxBE,YAAY,GAAG/H,oBAAoB,CAACmL,GAAG,EAAE,cAAc,CAAC,GACpDnK,QAAQ,CAAC,EAAE,EAAEmK,GAAG,CAACpD,YAAY,EAAE5G,iBAAiB,CAAC,GACjD6G,oBAAoB,CAAA;MACxBwC,kBAAkB,GAAGxK,oBAAoB,CAACmL,GAAG,EAAE,oBAAoB,CAAC,GAChEnK,QAAQ,CAAC,EAAE,EAAEmK,GAAG,CAACX,kBAAkB,EAAElL,cAAc,CAAC,GACpDmL,0BAA0B,CAAA;EAC9BR,IAAAA,mBAAmB,GAAGjK,oBAAoB,CAACmL,GAAG,EAAE,mBAAmB,CAAC,GAChEnK,QAAQ,CACNW,KAAK,CAACuI,2BAA2B,CAAC;EAAE;EACpCiB,IAAAA,GAAG,CAACC,iBAAiB;EAAE;EACvBjK,IAAAA,iBAAiB;EACnB,KAAC;EAAC,MACF+I,2BAA2B,CAAA;EAC/BH,IAAAA,aAAa,GAAG/J,oBAAoB,CAACmL,GAAG,EAAE,mBAAmB,CAAC,GAC1DnK,QAAQ,CACNW,KAAK,CAACqI,qBAAqB,CAAC;EAAE;EAC9BmB,IAAAA,GAAG,CAACE,iBAAiB;EAAE;EACvBlK,IAAAA,iBAAiB;EACnB,KAAC;EAAC,MACF6I,qBAAqB,CAAA;MACzBH,eAAe,GAAG7J,oBAAoB,CAACmL,GAAG,EAAE,iBAAiB,CAAC,GAC1DnK,QAAQ,CAAC,EAAE,EAAEmK,GAAG,CAACtB,eAAe,EAAE1I,iBAAiB,CAAC,GACpD2I,uBAAuB,CAAA;MAC3BrB,WAAW,GAAGzI,oBAAoB,CAACmL,GAAG,EAAE,aAAa,CAAC,GAClDnK,QAAQ,CAAC,EAAE,EAAEmK,GAAG,CAAC1C,WAAW,EAAEtH,iBAAiB,CAAC,GAChD,EAAE,CAAA;MACNuH,WAAW,GAAG1I,oBAAoB,CAACmL,GAAG,EAAE,aAAa,CAAC,GAClDnK,QAAQ,CAAC,EAAE,EAAEmK,GAAG,CAACzC,WAAW,EAAEvH,iBAAiB,CAAC,GAChD,EAAE,CAAA;EACNyI,IAAAA,YAAY,GAAG5J,oBAAoB,CAACmL,GAAG,EAAE,cAAc,CAAC,GACpDA,GAAG,CAACvB,YAAY,GAChB,KAAK,CAAA;EACTjB,IAAAA,eAAe,GAAGwC,GAAG,CAACxC,eAAe,KAAK,KAAK,CAAC;EAChDC,IAAAA,eAAe,GAAGuC,GAAG,CAACvC,eAAe,KAAK,KAAK,CAAC;EAChDC,IAAAA,uBAAuB,GAAGsC,GAAG,CAACtC,uBAAuB,IAAI,KAAK,CAAC;EAC/DC,IAAAA,wBAAwB,GAAGqC,GAAG,CAACrC,wBAAwB,KAAK,KAAK,CAAC;EAClEC,IAAAA,kBAAkB,GAAGoC,GAAG,CAACpC,kBAAkB,IAAI,KAAK,CAAC;EACrDC,IAAAA,YAAY,GAAGmC,GAAG,CAACnC,YAAY,KAAK,KAAK,CAAC;EAC1CC,IAAAA,cAAc,GAAGkC,GAAG,CAAClC,cAAc,IAAI,KAAK,CAAC;EAC7CG,IAAAA,UAAU,GAAG+B,GAAG,CAAC/B,UAAU,IAAI,KAAK,CAAC;EACrCC,IAAAA,mBAAmB,GAAG8B,GAAG,CAAC9B,mBAAmB,IAAI,KAAK,CAAC;EACvDC,IAAAA,mBAAmB,GAAG6B,GAAG,CAAC7B,mBAAmB,IAAI,KAAK,CAAC;EACvDH,IAAAA,UAAU,GAAGgC,GAAG,CAAChC,UAAU,IAAI,KAAK,CAAC;EACrCI,IAAAA,YAAY,GAAG4B,GAAG,CAAC5B,YAAY,KAAK,KAAK,CAAC;EAC1CC,IAAAA,oBAAoB,GAAG2B,GAAG,CAAC3B,oBAAoB,IAAI,KAAK,CAAC;EACzDE,IAAAA,YAAY,GAAGyB,GAAG,CAACzB,YAAY,KAAK,KAAK,CAAC;EAC1CC,IAAAA,QAAQ,GAAGwB,GAAG,CAACxB,QAAQ,IAAI,KAAK,CAAC;EACjCvG,IAAAA,gBAAc,GAAG+H,GAAG,CAACG,kBAAkB,IAAI3D,cAA0B,CAAA;EACrE2C,IAAAA,SAAS,GAAGa,GAAG,CAACb,SAAS,IAAID,cAAc,CAAA;EAC3CnC,IAAAA,uBAAuB,GAAGiD,GAAG,CAACjD,uBAAuB,IAAI,EAAE,CAAA;EAC3D,IAAA,IACEiD,GAAG,CAACjD,uBAAuB,IAC3B6C,iBAAiB,CAACI,GAAG,CAACjD,uBAAuB,CAACC,YAAY,CAAC,EAC3D;EACAD,MAAAA,uBAAuB,CAACC,YAAY,GAClCgD,GAAG,CAACjD,uBAAuB,CAACC,YAAY,CAAA;EAC5C,KAAA;EAEA,IAAA,IACEgD,GAAG,CAACjD,uBAAuB,IAC3B6C,iBAAiB,CAACI,GAAG,CAACjD,uBAAuB,CAACK,kBAAkB,CAAC,EACjE;EACAL,MAAAA,uBAAuB,CAACK,kBAAkB,GACxC4C,GAAG,CAACjD,uBAAuB,CAACK,kBAAkB,CAAA;EAClD,KAAA;EAEA,IAAA,IACE4C,GAAG,CAACjD,uBAAuB,IAC3B,OAAOiD,GAAG,CAACjD,uBAAuB,CAACM,8BAA8B,KAC/D,SAAS,EACX;EACAN,MAAAA,uBAAuB,CAACM,8BAA8B,GACpD2C,GAAG,CAACjD,uBAAuB,CAACM,8BAA8B,CAAA;EAC9D,KAAA;EAEA,IAAA,IAAIO,kBAAkB,EAAE;EACtBH,MAAAA,eAAe,GAAG,KAAK,CAAA;EACzB,KAAA;EAEA,IAAA,IAAIS,mBAAmB,EAAE;EACvBD,MAAAA,UAAU,GAAG,IAAI,CAAA;EACnB,KAAA;;EAEA;EACA,IAAA,IAAIQ,YAAY,EAAE;QAChBhC,YAAY,GAAG5G,QAAQ,CAAC,EAAE,EAAE8G,IAAS,CAAC,CAAA;EACtCC,MAAAA,YAAY,GAAG,EAAE,CAAA;EACjB,MAAA,IAAI6B,YAAY,CAACrH,IAAI,KAAK,IAAI,EAAE;EAC9BvB,QAAAA,QAAQ,CAAC4G,YAAY,EAAEE,MAAS,CAAC,CAAA;EACjC9G,QAAAA,QAAQ,CAAC+G,YAAY,EAAEE,IAAU,CAAC,CAAA;EACpC,OAAA;EAEA,MAAA,IAAI2B,YAAY,CAACpH,GAAG,KAAK,IAAI,EAAE;EAC7BxB,QAAAA,QAAQ,CAAC4G,YAAY,EAAEE,KAAQ,CAAC,CAAA;EAChC9G,QAAAA,QAAQ,CAAC+G,YAAY,EAAEE,GAAS,CAAC,CAAA;EACjCjH,QAAAA,QAAQ,CAAC+G,YAAY,EAAEE,GAAS,CAAC,CAAA;EACnC,OAAA;EAEA,MAAA,IAAI2B,YAAY,CAACnH,UAAU,KAAK,IAAI,EAAE;EACpCzB,QAAAA,QAAQ,CAAC4G,YAAY,EAAEE,UAAe,CAAC,CAAA;EACvC9G,QAAAA,QAAQ,CAAC+G,YAAY,EAAEE,GAAS,CAAC,CAAA;EACjCjH,QAAAA,QAAQ,CAAC+G,YAAY,EAAEE,GAAS,CAAC,CAAA;EACnC,OAAA;EAEA,MAAA,IAAI2B,YAAY,CAACjH,MAAM,KAAK,IAAI,EAAE;EAChC3B,QAAAA,QAAQ,CAAC4G,YAAY,EAAEE,QAAW,CAAC,CAAA;EACnC9G,QAAAA,QAAQ,CAAC+G,YAAY,EAAEE,MAAY,CAAC,CAAA;EACpCjH,QAAAA,QAAQ,CAAC+G,YAAY,EAAEE,GAAS,CAAC,CAAA;EACnC,OAAA;EACF,KAAA;;EAEA;MACA,IAAIkD,GAAG,CAACI,QAAQ,EAAE;QAChB,IAAI3D,YAAY,KAAKC,oBAAoB,EAAE;EACzCD,QAAAA,YAAY,GAAGjG,KAAK,CAACiG,YAAY,CAAC,CAAA;EACpC,OAAA;QAEA5G,QAAQ,CAAC4G,YAAY,EAAEuD,GAAG,CAACI,QAAQ,EAAEpK,iBAAiB,CAAC,CAAA;EACzD,KAAA;MAEA,IAAIgK,GAAG,CAACK,QAAQ,EAAE;QAChB,IAAIzD,YAAY,KAAKC,oBAAoB,EAAE;EACzCD,QAAAA,YAAY,GAAGpG,KAAK,CAACoG,YAAY,CAAC,CAAA;EACpC,OAAA;QAEA/G,QAAQ,CAAC+G,YAAY,EAAEoD,GAAG,CAACK,QAAQ,EAAErK,iBAAiB,CAAC,CAAA;EACzD,KAAA;MAEA,IAAIgK,GAAG,CAACC,iBAAiB,EAAE;QACzBpK,QAAQ,CAACiJ,mBAAmB,EAAEkB,GAAG,CAACC,iBAAiB,EAAEjK,iBAAiB,CAAC,CAAA;EACzE,KAAA;MAEA,IAAIgK,GAAG,CAACtB,eAAe,EAAE;QACvB,IAAIA,eAAe,KAAKC,uBAAuB,EAAE;EAC/CD,QAAAA,eAAe,GAAGlI,KAAK,CAACkI,eAAe,CAAC,CAAA;EAC1C,OAAA;QAEA7I,QAAQ,CAAC6I,eAAe,EAAEsB,GAAG,CAACtB,eAAe,EAAE1I,iBAAiB,CAAC,CAAA;EACnE,KAAA;;EAEA;EACA,IAAA,IAAIuI,YAAY,EAAE;EAChB9B,MAAAA,YAAY,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;EAC9B,KAAA;;EAEA;EACA,IAAA,IAAIqB,cAAc,EAAE;QAClBjI,QAAQ,CAAC4G,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;EAClD,KAAA;;EAEA;MACA,IAAIA,YAAY,CAAC6D,KAAK,EAAE;EACtBzK,MAAAA,QAAQ,CAAC4G,YAAY,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;QACjC,OAAOa,WAAW,CAACiD,KAAK,CAAA;EAC1B,KAAA;MAEA,IAAIP,GAAG,CAACQ,oBAAoB,EAAE;QAC5B,IAAI,OAAOR,GAAG,CAACQ,oBAAoB,CAAC5G,UAAU,KAAK,UAAU,EAAE;UAC7D,MAAM1E,eAAe,CACnB,6EACF,CAAC,CAAA;EACH,OAAA;QAEA,IAAI,OAAO8K,GAAG,CAACQ,oBAAoB,CAAC3G,eAAe,KAAK,UAAU,EAAE;UAClE,MAAM3E,eAAe,CACnB,kFACF,CAAC,CAAA;EACH,OAAA;;EAEA;QACA6G,kBAAkB,GAAGiE,GAAG,CAACQ,oBAAoB,CAAA;;EAE7C;EACAxE,MAAAA,SAAS,GAAGD,kBAAkB,CAACnC,UAAU,CAAC,EAAE,CAAC,CAAA;EAC/C,KAAC,MAAM;EACL;QACA,IAAImC,kBAAkB,KAAK9F,SAAS,EAAE;EACpC8F,QAAAA,kBAAkB,GAAG5C,yBAAyB,CAC5CC,YAAY,EACZuB,aACF,CAAC,CAAA;EACH,OAAA;;EAEA;QACA,IAAIoB,kBAAkB,KAAK,IAAI,IAAI,OAAOC,SAAS,KAAK,QAAQ,EAAE;EAChEA,QAAAA,SAAS,GAAGD,kBAAkB,CAACnC,UAAU,CAAC,EAAE,CAAC,CAAA;EAC/C,OAAA;EACF,KAAA;;EAEA;EACA;EACA,IAAA,IAAIhH,MAAM,EAAE;QACVA,MAAM,CAACoN,GAAG,CAAC,CAAA;EACb,KAAA;EAEAN,IAAAA,MAAM,GAAGM,GAAG,CAAA;KACb,CAAA;EAED,EAAA,MAAMS,8BAA8B,GAAG5K,QAAQ,CAAC,EAAE,EAAE,CAClD,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,OAAO,CACR,CAAC,CAAA;EAEF,EAAA,MAAM6K,uBAAuB,GAAG7K,QAAQ,CAAC,EAAE,EAAE,CAC3C,eAAe,EACf,gBAAgB,CACjB,CAAC,CAAA;;EAEF;EACA;EACA;EACA;EACA,EAAA,MAAM8K,4BAA4B,GAAG9K,QAAQ,CAAC,EAAE,EAAE,CAChD,OAAO,EACP,OAAO,EACP,MAAM,EACN,GAAG,EACH,QAAQ,CACT,CAAC,CAAA;;EAEF;EACF;EACA;IACE,MAAM+K,YAAY,GAAG/K,QAAQ,CAAC,EAAE,EAAE,CAChC,GAAG8G,KAAQ,EACX,GAAGA,UAAe,EAClB,GAAGA,aAAkB,CACtB,CAAC,CAAA;EACF,EAAA,MAAMkE,eAAe,GAAGhL,QAAQ,CAAC,EAAE,EAAE,CACnC,GAAG8G,QAAW,EACd,GAAGA,gBAAqB,CACzB,CAAC,CAAA;;EAEF;EACF;EACA;EACA;EACA;EACA;EACE,EAAA,MAAMmE,oBAAoB,GAAG,SAAvBA,oBAAoBA,CAAa3K,OAAO,EAAE;EAC9C,IAAA,IAAI4K,MAAM,GAAGrF,aAAa,CAACvF,OAAO,CAAC,CAAA;;EAEnC;EACA;EACA,IAAA,IAAI,CAAC4K,MAAM,IAAI,CAACA,MAAM,CAACC,OAAO,EAAE;EAC9BD,MAAAA,MAAM,GAAG;EACPE,QAAAA,YAAY,EAAE9B,SAAS;EACvB6B,QAAAA,OAAO,EAAE,UAAA;SACV,CAAA;EACH,KAAA;EAEA,IAAA,MAAMA,OAAO,GAAGhN,iBAAiB,CAACmC,OAAO,CAAC6K,OAAO,CAAC,CAAA;EAClD,IAAA,MAAME,aAAa,GAAGlN,iBAAiB,CAAC+M,MAAM,CAACC,OAAO,CAAC,CAAA;EAEvD,IAAA,IAAI,CAAC3B,kBAAkB,CAAClJ,OAAO,CAAC8K,YAAY,CAAC,EAAE;EAC7C,MAAA,OAAO,KAAK,CAAA;EACd,KAAA;EAEA,IAAA,IAAI9K,OAAO,CAAC8K,YAAY,KAAKhC,aAAa,EAAE;EAC1C;EACA;EACA;EACA,MAAA,IAAI8B,MAAM,CAACE,YAAY,KAAK/B,cAAc,EAAE;UAC1C,OAAO8B,OAAO,KAAK,KAAK,CAAA;EAC1B,OAAA;;EAEA;EACA;EACA;EACA,MAAA,IAAID,MAAM,CAACE,YAAY,KAAKjC,gBAAgB,EAAE;EAC5C,QAAA,OACEgC,OAAO,KAAK,KAAK,KAChBE,aAAa,KAAK,gBAAgB,IACjCT,8BAA8B,CAACS,aAAa,CAAC,CAAC,CAAA;EAEpD,OAAA;;EAEA;EACA;EACA,MAAA,OAAOC,OAAO,CAACP,YAAY,CAACI,OAAO,CAAC,CAAC,CAAA;EACvC,KAAA;EAEA,IAAA,IAAI7K,OAAO,CAAC8K,YAAY,KAAKjC,gBAAgB,EAAE;EAC7C;EACA;EACA;EACA,MAAA,IAAI+B,MAAM,CAACE,YAAY,KAAK/B,cAAc,EAAE;UAC1C,OAAO8B,OAAO,KAAK,MAAM,CAAA;EAC3B,OAAA;;EAEA;EACA;EACA,MAAA,IAAID,MAAM,CAACE,YAAY,KAAKhC,aAAa,EAAE;EACzC,QAAA,OAAO+B,OAAO,KAAK,MAAM,IAAIN,uBAAuB,CAACQ,aAAa,CAAC,CAAA;EACrE,OAAA;;EAEA;EACA;EACA,MAAA,OAAOC,OAAO,CAACN,eAAe,CAACG,OAAO,CAAC,CAAC,CAAA;EAC1C,KAAA;EAEA,IAAA,IAAI7K,OAAO,CAAC8K,YAAY,KAAK/B,cAAc,EAAE;EAC3C;EACA;EACA;QACA,IACE6B,MAAM,CAACE,YAAY,KAAKhC,aAAa,IACrC,CAACyB,uBAAuB,CAACQ,aAAa,CAAC,EACvC;EACA,QAAA,OAAO,KAAK,CAAA;EACd,OAAA;QAEA,IACEH,MAAM,CAACE,YAAY,KAAKjC,gBAAgB,IACxC,CAACyB,8BAA8B,CAACS,aAAa,CAAC,EAC9C;EACA,QAAA,OAAO,KAAK,CAAA;EACd,OAAA;;EAEA;EACA;EACA,MAAA,OACE,CAACL,eAAe,CAACG,OAAO,CAAC,KACxBL,4BAA4B,CAACK,OAAO,CAAC,IAAI,CAACJ,YAAY,CAACI,OAAO,CAAC,CAAC,CAAA;EAErE,KAAA;;EAEA;MACA,IACEzB,iBAAiB,KAAK,uBAAuB,IAC7CF,kBAAkB,CAAClJ,OAAO,CAAC8K,YAAY,CAAC,EACxC;EACA,MAAA,OAAO,IAAI,CAAA;EACb,KAAA;;EAEA;EACA;EACA;EACA;EACA,IAAA,OAAO,KAAK,CAAA;KACb,CAAA;;EAED;EACF;EACA;EACA;EACA;EACE,EAAA,MAAMG,YAAY,GAAG,SAAfA,YAAYA,CAAaC,IAAI,EAAE;EACnCvN,IAAAA,SAAS,CAACqG,SAAS,CAACI,OAAO,EAAE;EAAEpE,MAAAA,OAAO,EAAEkL,IAAAA;EAAK,KAAC,CAAC,CAAA;MAE/C,IAAI;EACF;EACA3F,MAAAA,aAAa,CAAC2F,IAAI,CAAC,CAACC,WAAW,CAACD,IAAI,CAAC,CAAA;OACtC,CAAC,OAAOtH,CAAC,EAAE;QACVwB,MAAM,CAAC8F,IAAI,CAAC,CAAA;EACd,KAAA;KACD,CAAA;;EAED;EACF;EACA;EACA;EACA;EACA;IACE,MAAME,gBAAgB,GAAG,SAAnBA,gBAAgBA,CAAaC,IAAI,EAAEH,IAAI,EAAE;MAC7C,IAAI;EACFvN,MAAAA,SAAS,CAACqG,SAAS,CAACI,OAAO,EAAE;EAC3BhC,QAAAA,SAAS,EAAE8I,IAAI,CAACI,gBAAgB,CAACD,IAAI,CAAC;EACtCE,QAAAA,IAAI,EAAEL,IAAAA;EACR,OAAC,CAAC,CAAA;OACH,CAAC,OAAOtH,CAAC,EAAE;EACVjG,MAAAA,SAAS,CAACqG,SAAS,CAACI,OAAO,EAAE;EAC3BhC,QAAAA,SAAS,EAAE,IAAI;EACfmJ,QAAAA,IAAI,EAAEL,IAAAA;EACR,OAAC,CAAC,CAAA;EACJ,KAAA;EAEAA,IAAAA,IAAI,CAACM,eAAe,CAACH,IAAI,CAAC,CAAA;;EAE1B;MACA,IAAIA,IAAI,KAAK,IAAI,IAAI,CAAC5E,YAAY,CAAC4E,IAAI,CAAC,EAAE;QACxC,IAAIvD,UAAU,IAAIC,mBAAmB,EAAE;UACrC,IAAI;YACFkD,YAAY,CAACC,IAAI,CAAC,CAAA;EACpB,SAAC,CAAC,OAAOtH,CAAC,EAAE,EAAC;EACf,OAAC,MAAM;UACL,IAAI;EACFsH,UAAAA,IAAI,CAACO,YAAY,CAACJ,IAAI,EAAE,EAAE,CAAC,CAAA;EAC7B,SAAC,CAAC,OAAOzH,CAAC,EAAE,EAAC;EACf,OAAA;EACF,KAAA;KACD,CAAA;;EAED;EACF;EACA;EACA;EACA;EACA;EACE,EAAA,MAAM8H,aAAa,GAAG,SAAhBA,aAAaA,CAAaC,KAAK,EAAE;EACrC;MACA,IAAIC,GAAG,GAAG,IAAI,CAAA;MACd,IAAIC,iBAAiB,GAAG,IAAI,CAAA;EAE5B,IAAA,IAAIhE,UAAU,EAAE;QACd8D,KAAK,GAAG,mBAAmB,GAAGA,KAAK,CAAA;EACrC,KAAC,MAAM;EACL;EACA,MAAA,MAAMG,OAAO,GAAG5N,WAAW,CAACyN,KAAK,EAAE,aAAa,CAAC,CAAA;EACjDE,MAAAA,iBAAiB,GAAGC,OAAO,IAAIA,OAAO,CAAC,CAAC,CAAC,CAAA;EAC3C,KAAA;EAEA,IAAA,IACE1C,iBAAiB,KAAK,uBAAuB,IAC7CJ,SAAS,KAAKD,cAAc,EAC5B;EACA;EACA4C,MAAAA,KAAK,GACH,gEAAgE,GAChEA,KAAK,GACL,gBAAgB,CAAA;EACpB,KAAA;MAEA,MAAMI,YAAY,GAAGnG,kBAAkB,GACnCA,kBAAkB,CAACnC,UAAU,CAACkI,KAAK,CAAC,GACpCA,KAAK,CAAA;EACT;EACJ;EACA;EACA;MACI,IAAI3C,SAAS,KAAKD,cAAc,EAAE;QAChC,IAAI;UACF6C,GAAG,GAAG,IAAI3G,SAAS,EAAE,CAAC+G,eAAe,CAACD,YAAY,EAAE3C,iBAAiB,CAAC,CAAA;EACxE,OAAC,CAAC,OAAOxF,CAAC,EAAE,EAAC;EACf,KAAA;;EAEA;EACA,IAAA,IAAI,CAACgI,GAAG,IAAI,CAACA,GAAG,CAACK,eAAe,EAAE;QAChCL,GAAG,GAAG9F,cAAc,CAACoG,cAAc,CAAClD,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,CAAA;QAChE,IAAI;UACF4C,GAAG,CAACK,eAAe,CAACE,SAAS,GAAGlD,cAAc,GAC1CpD,SAAS,GACTkG,YAAY,CAAA;SACjB,CAAC,OAAOnI,CAAC,EAAE;EACV;EAAA,OAAA;EAEJ,KAAA;MAEA,MAAMwI,IAAI,GAAGR,GAAG,CAACQ,IAAI,IAAIR,GAAG,CAACK,eAAe,CAAA;MAE5C,IAAIN,KAAK,IAAIE,iBAAiB,EAAE;EAC9BO,MAAAA,IAAI,CAACC,YAAY,CACf3J,QAAQ,CAAC4J,cAAc,CAACT,iBAAiB,CAAC,EAC1CO,IAAI,CAACG,UAAU,CAAC,CAAC,CAAC,IAAI,IACxB,CAAC,CAAA;EACH,KAAA;;EAEA;MACA,IAAIvD,SAAS,KAAKD,cAAc,EAAE;EAChC,MAAA,OAAO9C,oBAAoB,CAACuG,IAAI,CAC9BZ,GAAG,EACHjE,cAAc,GAAG,MAAM,GAAG,MAC5B,CAAC,CAAC,CAAC,CAAC,CAAA;EACN,KAAA;EAEA,IAAA,OAAOA,cAAc,GAAGiE,GAAG,CAACK,eAAe,GAAGG,IAAI,CAAA;KACnD,CAAA;;EAED;EACF;EACA;EACA;EACA;EACA;EACE,EAAA,MAAMK,mBAAmB,GAAG,SAAtBA,mBAAmBA,CAAaxI,IAAI,EAAE;MAC1C,OAAO8B,kBAAkB,CAACyG,IAAI,CAC5BvI,IAAI,CAAC0B,aAAa,IAAI1B,IAAI,EAC1BA,IAAI;EACJ;MACAY,UAAU,CAAC6H,YAAY,GACrB7H,UAAU,CAAC8H,YAAY,GACvB9H,UAAU,CAAC+H,SAAS,GACpB/H,UAAU,CAACgI,2BAA2B,GACtChI,UAAU,CAACiI,kBAAkB,EAC/B,IACF,CAAC,CAAA;KACF,CAAA;;EAED;EACF;EACA;EACA;EACA;EACA;EACE,EAAA,MAAMC,YAAY,GAAG,SAAfA,YAAYA,CAAaC,GAAG,EAAE;EAClC,IAAA,OACEA,GAAG,YAAYhI,eAAe,KAC7B,OAAOgI,GAAG,CAACC,QAAQ,KAAK,QAAQ,IAC/B,OAAOD,GAAG,CAACE,WAAW,KAAK,QAAQ,IACnC,OAAOF,GAAG,CAAC7B,WAAW,KAAK,UAAU,IACrC,EAAE6B,GAAG,CAACG,UAAU,YAAYrI,YAAY,CAAC,IACzC,OAAOkI,GAAG,CAACxB,eAAe,KAAK,UAAU,IACzC,OAAOwB,GAAG,CAACvB,YAAY,KAAK,UAAU,IACtC,OAAOuB,GAAG,CAAClC,YAAY,KAAK,QAAQ,IACpC,OAAOkC,GAAG,CAACX,YAAY,KAAK,UAAU,IACtC,OAAOW,GAAG,CAACI,aAAa,KAAK,UAAU,CAAC,CAAA;KAE7C,CAAA;;EAED;EACF;EACA;EACA;EACA;EACA;EACE,EAAA,MAAMC,OAAO,GAAG,SAAVA,OAAOA,CAAa/M,MAAM,EAAE;EAChC,IAAA,OAAO,OAAOqE,IAAI,KAAK,UAAU,IAAIrE,MAAM,YAAYqE,IAAI,CAAA;KAC5D,CAAA;;EAED;EACF;EACA;EACA;EACA;EACA;EACA;EACA;IACE,MAAM2I,YAAY,GAAG,SAAfA,YAAYA,CAAaC,UAAU,EAAEC,WAAW,EAAEC,IAAI,EAAE;EAC5D,IAAA,IAAI,CAACtH,KAAK,CAACoH,UAAU,CAAC,EAAE;EACtB,MAAA,OAAA;EACF,KAAA;EAEAnQ,IAAAA,YAAY,CAAC+I,KAAK,CAACoH,UAAU,CAAC,EAAGG,IAAI,IAAK;QACxCA,IAAI,CAAClB,IAAI,CAACxI,SAAS,EAAEwJ,WAAW,EAAEC,IAAI,EAAElE,MAAM,CAAC,CAAA;EACjD,KAAC,CAAC,CAAA;KACH,CAAA;;EAED;EACF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACE,EAAA,MAAMoE,iBAAiB,GAAG,SAApBA,iBAAiBA,CAAaH,WAAW,EAAE;MAC/C,IAAI9H,OAAO,GAAG,IAAI,CAAA;;EAElB;EACA4H,IAAAA,YAAY,CAAC,wBAAwB,EAAEE,WAAW,EAAE,IAAI,CAAC,CAAA;;EAEzD;EACA,IAAA,IAAIT,YAAY,CAACS,WAAW,CAAC,EAAE;QAC7BvC,YAAY,CAACuC,WAAW,CAAC,CAAA;EACzB,MAAA,OAAO,IAAI,CAAA;EACb,KAAA;;EAEA;EACA,IAAA,MAAM3C,OAAO,GAAGhL,iBAAiB,CAAC2N,WAAW,CAACP,QAAQ,CAAC,CAAA;;EAEvD;EACAK,IAAAA,YAAY,CAAC,qBAAqB,EAAEE,WAAW,EAAE;QAC/C3C,OAAO;EACP+C,MAAAA,WAAW,EAAEtH,YAAAA;EACf,KAAC,CAAC,CAAA;;EAEF;EACA,IAAA,IACEkH,WAAW,CAACJ,aAAa,EAAE,IAC3B,CAACC,OAAO,CAACG,WAAW,CAACK,iBAAiB,CAAC,IACvCjP,UAAU,CAAC,SAAS,EAAE4O,WAAW,CAACrB,SAAS,CAAC,IAC5CvN,UAAU,CAAC,SAAS,EAAE4O,WAAW,CAACN,WAAW,CAAC,EAC9C;QACAjC,YAAY,CAACuC,WAAW,CAAC,CAAA;EACzB,MAAA,OAAO,IAAI,CAAA;EACb,KAAA;;EAEA;EACA,IAAA,IAAIA,WAAW,CAACnJ,QAAQ,KAAKlC,SAAS,CAACK,sBAAsB,EAAE;QAC7DyI,YAAY,CAACuC,WAAW,CAAC,CAAA;EACzB,MAAA,OAAO,IAAI,CAAA;EACb,KAAA;;EAEA;EACA,IAAA,IACE9F,YAAY,IACZ8F,WAAW,CAACnJ,QAAQ,KAAKlC,SAAS,CAACM,OAAO,IAC1C7D,UAAU,CAAC,SAAS,EAAE4O,WAAW,CAACC,IAAI,CAAC,EACvC;QACAxC,YAAY,CAACuC,WAAW,CAAC,CAAA;EACzB,MAAA,OAAO,IAAI,CAAA;EACb,KAAA;;EAEA;MACA,IAAI,CAAClH,YAAY,CAACuE,OAAO,CAAC,IAAI1D,WAAW,CAAC0D,OAAO,CAAC,EAAE;EAClD;QACA,IAAI,CAAC1D,WAAW,CAAC0D,OAAO,CAAC,IAAIiD,qBAAqB,CAACjD,OAAO,CAAC,EAAE;EAC3D,QAAA,IACEjE,uBAAuB,CAACC,YAAY,YAAYhI,MAAM,IACtDD,UAAU,CAACgI,uBAAuB,CAACC,YAAY,EAAEgE,OAAO,CAAC,EACzD;EACA,UAAA,OAAO,KAAK,CAAA;EACd,SAAA;EAEA,QAAA,IACEjE,uBAAuB,CAACC,YAAY,YAAY8C,QAAQ,IACxD/C,uBAAuB,CAACC,YAAY,CAACgE,OAAO,CAAC,EAC7C;EACA,UAAA,OAAO,KAAK,CAAA;EACd,SAAA;EACF,OAAA;;EAEA;EACA,MAAA,IAAIzC,YAAY,IAAI,CAACG,eAAe,CAACsC,OAAO,CAAC,EAAE;UAC7C,MAAMkD,UAAU,GAAGxI,aAAa,CAACiI,WAAW,CAAC,IAAIA,WAAW,CAACO,UAAU,CAAA;UACvE,MAAMxB,UAAU,GAAGjH,aAAa,CAACkI,WAAW,CAAC,IAAIA,WAAW,CAACjB,UAAU,CAAA;UAEvE,IAAIA,UAAU,IAAIwB,UAAU,EAAE;EAC5B,UAAA,MAAMC,UAAU,GAAGzB,UAAU,CAACjN,MAAM,CAAA;EAEpC,UAAA,KAAK,IAAI2O,CAAC,GAAGD,UAAU,GAAG,CAAC,EAAEC,CAAC,IAAI,CAAC,EAAE,EAAEA,CAAC,EAAE;cACxC,MAAMC,UAAU,GAAG/I,SAAS,CAACoH,UAAU,CAAC0B,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;cACjDC,UAAU,CAACC,cAAc,GAAG,CAACX,WAAW,CAACW,cAAc,IAAI,CAAC,IAAI,CAAC,CAAA;cACjEJ,UAAU,CAAC1B,YAAY,CAAC6B,UAAU,EAAE7I,cAAc,CAACmI,WAAW,CAAC,CAAC,CAAA;EAClE,WAAA;EACF,SAAA;EACF,OAAA;QAEAvC,YAAY,CAACuC,WAAW,CAAC,CAAA;EACzB,MAAA,OAAO,IAAI,CAAA;EACb,KAAA;;EAEA;MACA,IAAIA,WAAW,YAAY5I,OAAO,IAAI,CAAC+F,oBAAoB,CAAC6C,WAAW,CAAC,EAAE;QACxEvC,YAAY,CAACuC,WAAW,CAAC,CAAA;EACzB,MAAA,OAAO,IAAI,CAAA;EACb,KAAA;;EAEA;MACA,IACE,CAAC3C,OAAO,KAAK,UAAU,IACrBA,OAAO,KAAK,SAAS,IACrBA,OAAO,KAAK,UAAU,KACxBjM,UAAU,CAAC,6BAA6B,EAAE4O,WAAW,CAACrB,SAAS,CAAC,EAChE;QACAlB,YAAY,CAACuC,WAAW,CAAC,CAAA;EACzB,MAAA,OAAO,IAAI,CAAA;EACb,KAAA;;EAEA;MACA,IAAI/F,kBAAkB,IAAI+F,WAAW,CAACnJ,QAAQ,KAAKlC,SAAS,CAACZ,IAAI,EAAE;EACjE;QACAmE,OAAO,GAAG8H,WAAW,CAACN,WAAW,CAAA;QAEjC9P,YAAY,CAAC,CAACqE,aAAa,EAAEC,QAAQ,EAAEC,WAAW,CAAC,EAAGyM,IAAI,IAAK;UAC7D1I,OAAO,GAAGtH,aAAa,CAACsH,OAAO,EAAE0I,IAAI,EAAE,GAAG,CAAC,CAAA;EAC7C,OAAC,CAAC,CAAA;EAEF,MAAA,IAAIZ,WAAW,CAACN,WAAW,KAAKxH,OAAO,EAAE;EACvC/H,QAAAA,SAAS,CAACqG,SAAS,CAACI,OAAO,EAAE;EAAEpE,UAAAA,OAAO,EAAEwN,WAAW,CAACrI,SAAS,EAAC;EAAE,SAAC,CAAC,CAAA;UAClEqI,WAAW,CAACN,WAAW,GAAGxH,OAAO,CAAA;EACnC,OAAA;EACF,KAAA;;EAEA;EACA4H,IAAAA,YAAY,CAAC,uBAAuB,EAAEE,WAAW,EAAE,IAAI,CAAC,CAAA;EAExD,IAAA,OAAO,KAAK,CAAA;KACb,CAAA;;EAED;EACF;EACA;EACA;EACA;EACA;EACA;EACA;EACE;IACA,MAAMa,iBAAiB,GAAG,SAApBA,iBAAiBA,CAAaC,KAAK,EAAEC,MAAM,EAAE9N,KAAK,EAAE;EACxD;EACA,IAAA,IACEwH,YAAY,KACXsG,MAAM,KAAK,IAAI,IAAIA,MAAM,KAAK,MAAM,CAAC,KACrC9N,KAAK,IAAIiC,QAAQ,IAAIjC,KAAK,IAAI+I,WAAW,CAAC,EAC3C;EACA,MAAA,OAAO,KAAK,CAAA;EACd,KAAA;;EAEA;EACJ;EACA;EACA;EACI,IAAA,IACElC,eAAe,IACf,CAACF,WAAW,CAACmH,MAAM,CAAC,IACpB3P,UAAU,CAACgD,SAAS,EAAE2M,MAAM,CAAC,EAC7B,CAED,MAAM,IAAIlH,eAAe,IAAIzI,UAAU,CAACiD,SAAS,EAAE0M,MAAM,CAAC,EAAE,CAG5D,MAAM,IAAI,CAAC9H,YAAY,CAAC8H,MAAM,CAAC,IAAInH,WAAW,CAACmH,MAAM,CAAC,EAAE;EACvD,MAAA;EACE;EACA;EACA;EACCT,MAAAA,qBAAqB,CAACQ,KAAK,CAAC,KACzB1H,uBAAuB,CAACC,YAAY,YAAYhI,MAAM,IACtDD,UAAU,CAACgI,uBAAuB,CAACC,YAAY,EAAEyH,KAAK,CAAC,IACtD1H,uBAAuB,CAACC,YAAY,YAAY8C,QAAQ,IACvD/C,uBAAuB,CAACC,YAAY,CAACyH,KAAK,CAAE,CAAC,KAC/C1H,uBAAuB,CAACK,kBAAkB,YAAYpI,MAAM,IAC5DD,UAAU,CAACgI,uBAAuB,CAACK,kBAAkB,EAAEsH,MAAM,CAAC,IAC7D3H,uBAAuB,CAACK,kBAAkB,YAAY0C,QAAQ,IAC7D/C,uBAAuB,CAACK,kBAAkB,CAACsH,MAAM,CAAE,CAAC;EAC1D;EACA;EACCA,MAAAA,MAAM,KAAK,IAAI,IACd3H,uBAAuB,CAACM,8BAA8B,KACpDN,uBAAuB,CAACC,YAAY,YAAYhI,MAAM,IACtDD,UAAU,CAACgI,uBAAuB,CAACC,YAAY,EAAEpG,KAAK,CAAC,IACtDmG,uBAAuB,CAACC,YAAY,YAAY8C,QAAQ,IACvD/C,uBAAuB,CAACC,YAAY,CAACpG,KAAK,CAAE,CAAE,EACpD,CAGD,MAAM;EACL,QAAA,OAAO,KAAK,CAAA;EACd,OAAA;EACA;EACF,KAAC,MAAM,IAAIkI,mBAAmB,CAAC4F,MAAM,CAAC,EAAE,CAIvC,MAAM,IACL3P,UAAU,CAACkD,gBAAc,EAAE1D,aAAa,CAACqC,KAAK,EAAEuB,eAAe,EAAE,EAAE,CAAC,CAAC,EACrE,CAID,MAAM,IACL,CAACuM,MAAM,KAAK,KAAK,IAAIA,MAAM,KAAK,YAAY,IAAIA,MAAM,KAAK,MAAM,KACjED,KAAK,KAAK,QAAQ,IAClBhQ,aAAa,CAACmC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IACnCgI,aAAa,CAAC6F,KAAK,CAAC,EACpB,CAKD,MAAM,IACL/G,uBAAuB,IACvB,CAAC3I,UAAU,CAACmD,iBAAiB,EAAE3D,aAAa,CAACqC,KAAK,EAAEuB,eAAe,EAAE,EAAE,CAAC,CAAC,EACzE,CAGD,MAAM,IAAIvB,KAAK,EAAE;EAChB,MAAA,OAAO,KAAK,CAAA;EACd,KAAC,MAAM,CAEL;EAGF,IAAA,OAAO,IAAI,CAAA;KACZ,CAAA;;EAED;EACF;EACA;EACA;EACA;EACA;EACA;EACA;EACE,EAAA,MAAMqN,qBAAqB,GAAG,SAAxBA,qBAAqBA,CAAajD,OAAO,EAAE;MAC/C,OAAOA,OAAO,KAAK,gBAAgB,IAAI3M,WAAW,CAAC2M,OAAO,EAAE3I,cAAc,CAAC,CAAA;KAC5E,CAAA;;EAED;EACF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACE,EAAA,MAAMsM,mBAAmB,GAAG,SAAtBA,mBAAmBA,CAAahB,WAAW,EAAE;EACjD;EACAF,IAAAA,YAAY,CAAC,0BAA0B,EAAEE,WAAW,EAAE,IAAI,CAAC,CAAA;MAE3D,MAAM;EAAEL,MAAAA,UAAAA;EAAW,KAAC,GAAGK,WAAW,CAAA;;EAElC;MACA,IAAI,CAACL,UAAU,EAAE;EACf,MAAA,OAAA;EACF,KAAA;EAEA,IAAA,MAAMsB,SAAS,GAAG;EAChBC,MAAAA,QAAQ,EAAE,EAAE;EACZC,MAAAA,SAAS,EAAE,EAAE;EACbC,MAAAA,QAAQ,EAAE,IAAI;EACdC,MAAAA,iBAAiB,EAAEpI,YAAAA;OACpB,CAAA;EACD,IAAA,IAAI1G,CAAC,GAAGoN,UAAU,CAAC7N,MAAM,CAAA;;EAEzB;MACA,OAAOS,CAAC,EAAE,EAAE;EACV,MAAA,MAAM+O,IAAI,GAAG3B,UAAU,CAACpN,CAAC,CAAC,CAAA;QAC1B,MAAM;UAAEsL,IAAI;UAAEP,YAAY;EAAErK,QAAAA,KAAK,EAAEkO,SAAAA;EAAU,OAAC,GAAGG,IAAI,CAAA;EACrD,MAAA,MAAMP,MAAM,GAAG1O,iBAAiB,CAACwL,IAAI,CAAC,CAAA;QAEtC,IAAI5K,KAAK,GAAG4K,IAAI,KAAK,OAAO,GAAGsD,SAAS,GAAGnQ,UAAU,CAACmQ,SAAS,CAAC,CAAA;;EAEhE;QACAF,SAAS,CAACC,QAAQ,GAAGH,MAAM,CAAA;QAC3BE,SAAS,CAACE,SAAS,GAAGlO,KAAK,CAAA;QAC3BgO,SAAS,CAACG,QAAQ,GAAG,IAAI,CAAA;EACzBH,MAAAA,SAAS,CAACM,aAAa,GAAGjP,SAAS,CAAC;EACpCwN,MAAAA,YAAY,CAAC,uBAAuB,EAAEE,WAAW,EAAEiB,SAAS,CAAC,CAAA;QAC7DhO,KAAK,GAAGgO,SAAS,CAACE,SAAS,CAAA;;EAE3B;QACA,IAAIjH,YAAY,IAAI9I,UAAU,CAAC,+BAA+B,EAAE6B,KAAK,CAAC,EAAE;EACtE2K,QAAAA,gBAAgB,CAACC,IAAI,EAAEmC,WAAW,CAAC,CAAA;EACnC,QAAA,SAAA;EACF,OAAA;;EAEA;QACA,IAAIiB,SAAS,CAACM,aAAa,EAAE;EAC3B,QAAA,SAAA;EACF,OAAA;;EAEA;EACA3D,MAAAA,gBAAgB,CAACC,IAAI,EAAEmC,WAAW,CAAC,CAAA;;EAEnC;EACA,MAAA,IAAI,CAACiB,SAAS,CAACG,QAAQ,EAAE;EACvB,QAAA,SAAA;EACF,OAAA;;EAEA;QACA,IAAI,CAACpH,wBAAwB,IAAI5I,UAAU,CAAC,MAAM,EAAE6B,KAAK,CAAC,EAAE;EAC1D2K,QAAAA,gBAAgB,CAACC,IAAI,EAAEmC,WAAW,CAAC,CAAA;EACnC,QAAA,SAAA;EACF,OAAA;;EAEA;EACA,MAAA,IAAI/F,kBAAkB,EAAE;UACtBrK,YAAY,CAAC,CAACqE,aAAa,EAAEC,QAAQ,EAAEC,WAAW,CAAC,EAAGyM,IAAI,IAAK;YAC7D3N,KAAK,GAAGrC,aAAa,CAACqC,KAAK,EAAE2N,IAAI,EAAE,GAAG,CAAC,CAAA;EACzC,SAAC,CAAC,CAAA;EACJ,OAAA;;EAEA;EACA,MAAA,MAAME,KAAK,GAAGzO,iBAAiB,CAAC2N,WAAW,CAACP,QAAQ,CAAC,CAAA;QACrD,IAAI,CAACoB,iBAAiB,CAACC,KAAK,EAAEC,MAAM,EAAE9N,KAAK,CAAC,EAAE;EAC5C,QAAA,SAAA;EACF,OAAA;;EAEA;EACN;EACA;QACM,IAAIyH,oBAAoB,KAAKqG,MAAM,KAAK,IAAI,IAAIA,MAAM,KAAK,MAAM,CAAC,EAAE;EAClE;EACAnD,QAAAA,gBAAgB,CAACC,IAAI,EAAEmC,WAAW,CAAC,CAAA;;EAEnC;UACA/M,KAAK,GAAG0H,2BAA2B,GAAG1H,KAAK,CAAA;EAC7C,OAAA;;EAEA;EACA,MAAA,IACEmF,kBAAkB,IAClB,OAAO3C,YAAY,KAAK,QAAQ,IAChC,OAAOA,YAAY,CAAC+L,gBAAgB,KAAK,UAAU,EACnD;EACA,QAAA,IAAIlE,YAAY,EAAE,CAEjB,MAAM;EACL,UAAA,QAAQ7H,YAAY,CAAC+L,gBAAgB,CAACV,KAAK,EAAEC,MAAM,CAAC;EAClD,YAAA,KAAK,aAAa;EAAE,cAAA;EAClB9N,gBAAAA,KAAK,GAAGmF,kBAAkB,CAACnC,UAAU,CAAChD,KAAK,CAAC,CAAA;EAC5C,gBAAA,MAAA;EACF,eAAA;EAEA,YAAA,KAAK,kBAAkB;EAAE,cAAA;EACvBA,gBAAAA,KAAK,GAAGmF,kBAAkB,CAAClC,eAAe,CAACjD,KAAK,CAAC,CAAA;EACjD,gBAAA,MAAA;EACF,eAAA;EAKF,WAAA;EACF,SAAA;EACF,OAAA;;EAEA;QACA,IAAI;EACF,QAAA,IAAIqK,YAAY,EAAE;YAChB0C,WAAW,CAACyB,cAAc,CAACnE,YAAY,EAAEO,IAAI,EAAE5K,KAAK,CAAC,CAAA;EACvD,SAAC,MAAM;EACL;EACA+M,UAAAA,WAAW,CAAC/B,YAAY,CAACJ,IAAI,EAAE5K,KAAK,CAAC,CAAA;EACvC,SAAA;EAEA,QAAA,IAAIsM,YAAY,CAACS,WAAW,CAAC,EAAE;YAC7BvC,YAAY,CAACuC,WAAW,CAAC,CAAA;EAC3B,SAAC,MAAM;EACL/P,UAAAA,QAAQ,CAACuG,SAAS,CAACI,OAAO,CAAC,CAAA;EAC7B,SAAA;EACF,OAAC,CAAC,OAAOR,CAAC,EAAE,EAAC;EACf,KAAA;;EAEA;EACA0J,IAAAA,YAAY,CAAC,yBAAyB,EAAEE,WAAW,EAAE,IAAI,CAAC,CAAA;KAC3D,CAAA;;EAED;EACF;EACA;EACA;EACA;EACE,EAAA,MAAM0B,kBAAkB,GAAG,SAArBA,kBAAkBA,CAAaC,QAAQ,EAAE;MAC7C,IAAIC,UAAU,GAAG,IAAI,CAAA;EACrB,IAAA,MAAMC,cAAc,GAAG5C,mBAAmB,CAAC0C,QAAQ,CAAC,CAAA;;EAEpD;EACA7B,IAAAA,YAAY,CAAC,yBAAyB,EAAE6B,QAAQ,EAAE,IAAI,CAAC,CAAA;EAEvD,IAAA,OAAQC,UAAU,GAAGC,cAAc,CAACC,QAAQ,EAAE,EAAG;EAC/C;EACAhC,MAAAA,YAAY,CAAC,wBAAwB,EAAE8B,UAAU,EAAE,IAAI,CAAC,CAAA;;EAExD;EACA,MAAA,IAAIzB,iBAAiB,CAACyB,UAAU,CAAC,EAAE;EACjC,QAAA,SAAA;EACF,OAAA;;EAEA;EACA,MAAA,IAAIA,UAAU,CAAC1J,OAAO,YAAYjB,gBAAgB,EAAE;EAClDyK,QAAAA,kBAAkB,CAACE,UAAU,CAAC1J,OAAO,CAAC,CAAA;EACxC,OAAA;;EAEA;QACA8I,mBAAmB,CAACY,UAAU,CAAC,CAAA;EACjC,KAAA;;EAEA;EACA9B,IAAAA,YAAY,CAAC,wBAAwB,EAAE6B,QAAQ,EAAE,IAAI,CAAC,CAAA;KACvD,CAAA;;EAED;EACF;EACA;EACA;EACA;EACA;EACA;EACE;EACAnL,EAAAA,SAAS,CAACuL,QAAQ,GAAG,UAAU5D,KAAK,EAAY;EAAA,IAAA,IAAV9B,GAAG,GAAAxK,SAAA,CAAAC,MAAA,GAAA,CAAA,IAAAD,SAAA,CAAA,CAAA,CAAA,KAAAS,SAAA,GAAAT,SAAA,CAAA,CAAA,CAAA,GAAG,EAAE,CAAA;MAC5C,IAAI+M,IAAI,GAAG,IAAI,CAAA;MACf,IAAIoD,YAAY,GAAG,IAAI,CAAA;MACvB,IAAIhC,WAAW,GAAG,IAAI,CAAA;MACtB,IAAIiC,UAAU,GAAG,IAAI,CAAA;EACrB;EACJ;EACA;MACIxG,cAAc,GAAG,CAAC0C,KAAK,CAAA;EACvB,IAAA,IAAI1C,cAAc,EAAE;EAClB0C,MAAAA,KAAK,GAAG,OAAO,CAAA;EACjB,KAAA;;EAEA;MACA,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAI,CAAC0B,OAAO,CAAC1B,KAAK,CAAC,EAAE;EAChD,MAAA,IAAI,OAAOA,KAAK,CAAC1N,QAAQ,KAAK,UAAU,EAAE;EACxC0N,QAAAA,KAAK,GAAGA,KAAK,CAAC1N,QAAQ,EAAE,CAAA;EACxB,QAAA,IAAI,OAAO0N,KAAK,KAAK,QAAQ,EAAE;YAC7B,MAAM5M,eAAe,CAAC,iCAAiC,CAAC,CAAA;EAC1D,SAAA;EACF,OAAC,MAAM;UACL,MAAMA,eAAe,CAAC,4BAA4B,CAAC,CAAA;EACrD,OAAA;EACF,KAAA;;EAEA;EACA,IAAA,IAAI,CAACiF,SAAS,CAACM,WAAW,EAAE;EAC1B,MAAA,OAAOqH,KAAK,CAAA;EACd,KAAA;;EAEA;MACA,IAAI,CAAC/D,UAAU,EAAE;QACfgC,YAAY,CAACC,GAAG,CAAC,CAAA;EACnB,KAAA;;EAEA;MACA7F,SAAS,CAACI,OAAO,GAAG,EAAE,CAAA;;EAEtB;EACA,IAAA,IAAI,OAAOuH,KAAK,KAAK,QAAQ,EAAE;EAC7BtD,MAAAA,QAAQ,GAAG,KAAK,CAAA;EAClB,KAAA;EAEA,IAAA,IAAIA,QAAQ,EAAE;EACZ;QACA,IAAIsD,KAAK,CAACsB,QAAQ,EAAE;EAClB,QAAA,MAAMpC,OAAO,GAAGhL,iBAAiB,CAAC8L,KAAK,CAACsB,QAAQ,CAAC,CAAA;UACjD,IAAI,CAAC3G,YAAY,CAACuE,OAAO,CAAC,IAAI1D,WAAW,CAAC0D,OAAO,CAAC,EAAE;YAClD,MAAM9L,eAAe,CACnB,yDACF,CAAC,CAAA;EACH,SAAA;EACF,OAAA;EACF,KAAC,MAAM,IAAI4M,KAAK,YAAYhH,IAAI,EAAE;EAChC;EACN;EACMyH,MAAAA,IAAI,GAAGV,aAAa,CAAC,SAAS,CAAC,CAAA;QAC/B8D,YAAY,GAAGpD,IAAI,CAACzG,aAAa,CAACO,UAAU,CAACyF,KAAK,EAAE,IAAI,CAAC,CAAA;EACzD,MAAA,IACE6D,YAAY,CAACnL,QAAQ,KAAKlC,SAAS,CAACnC,OAAO,IAC3CwP,YAAY,CAACvC,QAAQ,KAAK,MAAM,EAChC;EACA;EACAb,QAAAA,IAAI,GAAGoD,YAAY,CAAA;EACrB,OAAC,MAAM,IAAIA,YAAY,CAACvC,QAAQ,KAAK,MAAM,EAAE;EAC3Cb,QAAAA,IAAI,GAAGoD,YAAY,CAAA;EACrB,OAAC,MAAM;EACL;EACApD,QAAAA,IAAI,CAACsD,WAAW,CAACF,YAAY,CAAC,CAAA;EAChC,OAAA;EACF,KAAC,MAAM;EACL;EACA,MAAA,IACE,CAAC1H,UAAU,IACX,CAACL,kBAAkB,IACnB,CAACE,cAAc;EACf;QACAgE,KAAK,CAACpN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EACzB;UACA,OAAOqH,kBAAkB,IAAIoC,mBAAmB,GAC5CpC,kBAAkB,CAACnC,UAAU,CAACkI,KAAK,CAAC,GACpCA,KAAK,CAAA;EACX,OAAA;;EAEA;EACAS,MAAAA,IAAI,GAAGV,aAAa,CAACC,KAAK,CAAC,CAAA;;EAE3B;QACA,IAAI,CAACS,IAAI,EAAE;UACT,OAAOtE,UAAU,GAAG,IAAI,GAAGE,mBAAmB,GAAGnC,SAAS,GAAG,EAAE,CAAA;EACjE,OAAA;EACF,KAAA;;EAEA;MACA,IAAIuG,IAAI,IAAIvE,UAAU,EAAE;EACtBoD,MAAAA,YAAY,CAACmB,IAAI,CAACuD,UAAU,CAAC,CAAA;EAC/B,KAAA;;EAEA;MACA,MAAMC,YAAY,GAAGnD,mBAAmB,CAACpE,QAAQ,GAAGsD,KAAK,GAAGS,IAAI,CAAC,CAAA;;EAEjE;EACA,IAAA,OAAQoB,WAAW,GAAGoC,YAAY,CAACN,QAAQ,EAAE,EAAG;EAC9C;EACA,MAAA,IAAI3B,iBAAiB,CAACH,WAAW,CAAC,EAAE;EAClC,QAAA,SAAA;EACF,OAAA;;EAEA;EACA,MAAA,IAAIA,WAAW,CAAC9H,OAAO,YAAYjB,gBAAgB,EAAE;EACnDyK,QAAAA,kBAAkB,CAAC1B,WAAW,CAAC9H,OAAO,CAAC,CAAA;EACzC,OAAA;;EAEA;QACA8I,mBAAmB,CAAChB,WAAW,CAAC,CAAA;EAClC,KAAA;;EAEA;EACA,IAAA,IAAInF,QAAQ,EAAE;EACZ,MAAA,OAAOsD,KAAK,CAAA;EACd,KAAA;;EAEA;EACA,IAAA,IAAI7D,UAAU,EAAE;EACd,MAAA,IAAIC,mBAAmB,EAAE;UACvB0H,UAAU,GAAGzJ,sBAAsB,CAACwG,IAAI,CAACJ,IAAI,CAACzG,aAAa,CAAC,CAAA;UAE5D,OAAOyG,IAAI,CAACuD,UAAU,EAAE;EACtB;EACAF,UAAAA,UAAU,CAACC,WAAW,CAACtD,IAAI,CAACuD,UAAU,CAAC,CAAA;EACzC,SAAA;EACF,OAAC,MAAM;EACLF,QAAAA,UAAU,GAAGrD,IAAI,CAAA;EACnB,OAAA;EAEA,MAAA,IAAI3F,YAAY,CAACoJ,UAAU,IAAIpJ,YAAY,CAACqJ,cAAc,EAAE;EAC1D;EACR;EACA;EACA;EACA;EACA;EACA;UACQL,UAAU,GAAGvJ,UAAU,CAACsG,IAAI,CAACjI,gBAAgB,EAAEkL,UAAU,EAAE,IAAI,CAAC,CAAA;EAClE,OAAA;EAEA,MAAA,OAAOA,UAAU,CAAA;EACnB,KAAA;MAEA,IAAIM,cAAc,GAAGpI,cAAc,GAAGyE,IAAI,CAAC4D,SAAS,GAAG5D,IAAI,CAACD,SAAS,CAAA;;EAErE;EACA,IAAA,IACExE,cAAc,IACdrB,YAAY,CAAC,UAAU,CAAC,IACxB8F,IAAI,CAACzG,aAAa,IAClByG,IAAI,CAACzG,aAAa,CAACsK,OAAO,IAC1B7D,IAAI,CAACzG,aAAa,CAACsK,OAAO,CAAC5E,IAAI,IAC/BzM,UAAU,CAACyH,YAAwB,EAAE+F,IAAI,CAACzG,aAAa,CAACsK,OAAO,CAAC5E,IAAI,CAAC,EACrE;EACA0E,MAAAA,cAAc,GACZ,YAAY,GAAG3D,IAAI,CAACzG,aAAa,CAACsK,OAAO,CAAC5E,IAAI,GAAG,KAAK,GAAG0E,cAAc,CAAA;EAC3E,KAAA;;EAEA;EACA,IAAA,IAAItI,kBAAkB,EAAE;QACtBrK,YAAY,CAAC,CAACqE,aAAa,EAAEC,QAAQ,EAAEC,WAAW,CAAC,EAAGyM,IAAI,IAAK;UAC7D2B,cAAc,GAAG3R,aAAa,CAAC2R,cAAc,EAAE3B,IAAI,EAAE,GAAG,CAAC,CAAA;EAC3D,OAAC,CAAC,CAAA;EACJ,KAAA;MAEA,OAAOxI,kBAAkB,IAAIoC,mBAAmB,GAC5CpC,kBAAkB,CAACnC,UAAU,CAACsM,cAAc,CAAC,GAC7CA,cAAc,CAAA;KACnB,CAAA;;EAED;EACF;EACA;EACA;EACA;EACA;IACE/L,SAAS,CAACkM,SAAS,GAAG,YAAoB;EAAA,IAAA,IAAVrG,GAAG,GAAAxK,SAAA,CAAAC,MAAA,GAAA,CAAA,IAAAD,SAAA,CAAA,CAAA,CAAA,KAAAS,SAAA,GAAAT,SAAA,CAAA,CAAA,CAAA,GAAG,EAAE,CAAA;MACtCuK,YAAY,CAACC,GAAG,CAAC,CAAA;EACjBjC,IAAAA,UAAU,GAAG,IAAI,CAAA;KAClB,CAAA;;EAED;EACF;EACA;EACA;EACA;IACE5D,SAAS,CAACmM,WAAW,GAAG,YAAY;EAClC5G,IAAAA,MAAM,GAAG,IAAI,CAAA;EACb3B,IAAAA,UAAU,GAAG,KAAK,CAAA;KACnB,CAAA;;EAED;EACF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;IACE5D,SAAS,CAACoM,gBAAgB,GAAG,UAAUC,GAAG,EAAEvB,IAAI,EAAErO,KAAK,EAAE;EACvD;MACA,IAAI,CAAC8I,MAAM,EAAE;QACXK,YAAY,CAAC,EAAE,CAAC,CAAA;EAClB,KAAA;EAEA,IAAA,MAAM0E,KAAK,GAAGzO,iBAAiB,CAACwQ,GAAG,CAAC,CAAA;EACpC,IAAA,MAAM9B,MAAM,GAAG1O,iBAAiB,CAACiP,IAAI,CAAC,CAAA;EACtC,IAAA,OAAOT,iBAAiB,CAACC,KAAK,EAAEC,MAAM,EAAE9N,KAAK,CAAC,CAAA;KAC/C,CAAA;;EAED;EACF;EACA;EACA;EACA;EACA;EACA;EACEuD,EAAAA,SAAS,CAACsM,OAAO,GAAG,UAAU/C,UAAU,EAAEgD,YAAY,EAAE;EACtD,IAAA,IAAI,OAAOA,YAAY,KAAK,UAAU,EAAE;EACtC,MAAA,OAAA;EACF,KAAA;MAEApK,KAAK,CAACoH,UAAU,CAAC,GAAGpH,KAAK,CAACoH,UAAU,CAAC,IAAI,EAAE,CAAA;EAC3C5P,IAAAA,SAAS,CAACwI,KAAK,CAACoH,UAAU,CAAC,EAAEgD,YAAY,CAAC,CAAA;KAC3C,CAAA;;EAED;EACF;EACA;EACA;EACA;EACA;EACA;EACA;EACEvM,EAAAA,SAAS,CAACwM,UAAU,GAAG,UAAUjD,UAAU,EAAE;EAC3C,IAAA,IAAIpH,KAAK,CAACoH,UAAU,CAAC,EAAE;EACrB,MAAA,OAAO9P,QAAQ,CAAC0I,KAAK,CAACoH,UAAU,CAAC,CAAC,CAAA;EACpC,KAAA;KACD,CAAA;;EAED;EACF;EACA;EACA;EACA;EACA;EACEvJ,EAAAA,SAAS,CAACyM,WAAW,GAAG,UAAUlD,UAAU,EAAE;EAC5C,IAAA,IAAIpH,KAAK,CAACoH,UAAU,CAAC,EAAE;EACrBpH,MAAAA,KAAK,CAACoH,UAAU,CAAC,GAAG,EAAE,CAAA;EACxB,KAAA;KACD,CAAA;;EAED;EACF;EACA;EACA;IACEvJ,SAAS,CAAC0M,cAAc,GAAG,YAAY;MACrCvK,KAAK,GAAG,EAAE,CAAA;KACX,CAAA;EAED,EAAA,OAAOnC,SAAS,CAAA;EAClB,CAAA;AAEA,eAAeD,eAAe,EAAE;;;;;;;;"}
\ No newline at end of file
public/scripts/purify.min.js.map new
+1
@@ -0,0 +1 @@
1 +{"version":3,"file":"purify.min.js","sources":["../src/utils.js","../src/tags.js","../src/attrs.js","../src/regexp.js","../src/purify.js"],"sourcesContent":["const {\n entries,\n setPrototypeOf,\n isFrozen,\n getPrototypeOf,\n getOwnPropertyDescriptor,\n} = Object;\n\nlet { freeze, seal, create } = Object; // eslint-disable-line import/no-mutable-exports\nlet { apply, construct } = typeof Reflect !== 'undefined' && Reflect;\n\nif (!freeze) {\n freeze = function (x) {\n return x;\n };\n}\n\nif (!seal) {\n seal = function (x) {\n return x;\n };\n}\n\nif (!apply) {\n apply = function (fun, thisValue, args) {\n return fun.apply(thisValue, args);\n };\n}\n\nif (!construct) {\n construct = function (Func, args) {\n return new Func(...args);\n };\n}\n\nconst arrayForEach = unapply(Array.prototype.forEach);\nconst arrayIndexOf = unapply(Array.prototype.indexOf);\nconst arrayPop = unapply(Array.prototype.pop);\nconst arrayPush = unapply(Array.prototype.push);\nconst arraySlice = unapply(Array.prototype.slice);\n\nconst stringToLowerCase = unapply(String.prototype.toLowerCase);\nconst stringToString = unapply(String.prototype.toString);\nconst stringMatch = unapply(String.prototype.match);\nconst stringReplace = unapply(String.prototype.replace);\nconst stringIndexOf = unapply(String.prototype.indexOf);\nconst stringTrim = unapply(String.prototype.trim);\n\nconst objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);\n\nconst regExpTest = unapply(RegExp.prototype.test);\n\nconst typeErrorCreate = unconstruct(TypeError);\n\n/**\n * Creates a new function that calls the given function with a specified thisArg and arguments.\n *\n * @param {Function} func - The function to be wrapped and called.\n * @returns {Function} A new function that calls the given function with a specified thisArg and arguments.\n */\nfunction unapply(func) {\n return (thisArg, ...args) => apply(func, thisArg, args);\n}\n\n/**\n * Creates a new function that constructs an instance of the given constructor function with the provided arguments.\n *\n * @param {Function} func - The constructor function to be wrapped and called.\n * @returns {Function} A new function that constructs an instance of the given constructor function with the provided arguments.\n */\nfunction unconstruct(func) {\n return (...args) => construct(func, args);\n}\n\n/**\n * Add properties to a lookup table\n *\n * @param {Object} set - The set to which elements will be added.\n * @param {Array} array - The array containing elements to be added to the set.\n * @param {Function} transformCaseFunc - An optional function to transform the case of each element before adding to the set.\n * @returns {Object} The modified set with added elements.\n */\nfunction addToSet(set, array, transformCaseFunc = stringToLowerCase) {\n if (setPrototypeOf) {\n // Make 'in' and truthy checks like Boolean(set.constructor)\n // independent of any properties defined on Object.prototype.\n // Prevent prototype setters from intercepting set as a this value.\n setPrototypeOf(set, null);\n }\n\n let l = array.length;\n while (l--) {\n let element = array[l];\n if (typeof element === 'string') {\n const lcElement = transformCaseFunc(element);\n if (lcElement !== element) {\n // Config presets (e.g. tags.js, attrs.js) are immutable.\n if (!isFrozen(array)) {\n array[l] = lcElement;\n }\n\n element = lcElement;\n }\n }\n\n set[element] = true;\n }\n\n return set;\n}\n\n/**\n * Clean up an array to harden against CSPP\n *\n * @param {Array} array - The array to be cleaned.\n * @returns {Array} The cleaned version of the array\n */\nfunction cleanArray(array) {\n for (let index = 0; index < array.length; index++) {\n const isPropertyExist = objectHasOwnProperty(array, index);\n\n if (!isPropertyExist) {\n array[index] = null;\n }\n }\n\n return array;\n}\n\n/**\n * Shallow clone an object\n *\n * @param {Object} object - The object to be cloned.\n * @returns {Object} A new object that copies the original.\n */\nfunction clone(object) {\n const newObject = create(null);\n\n for (const [property, value] of entries(object)) {\n const isPropertyExist = objectHasOwnProperty(object, property);\n\n if (isPropertyExist) {\n if (Array.isArray(value)) {\n newObject[property] = cleanArray(value);\n } else if (\n value &&\n typeof value === 'object' &&\n value.constructor === Object\n ) {\n newObject[property] = clone(value);\n } else {\n newObject[property] = value;\n }\n }\n }\n\n return newObject;\n}\n\n/**\n * This method automatically checks if the prop is function or getter and behaves accordingly.\n *\n * @param {Object} object - The object to look up the getter function in its prototype chain.\n * @param {String} prop - The property name for which to find the getter function.\n * @returns {Function} The getter function found in the prototype chain or a fallback function.\n */\nfunction lookupGetter(object, prop) {\n while (object !== null) {\n const desc = getOwnPropertyDescriptor(object, prop);\n\n if (desc) {\n if (desc.get) {\n return unapply(desc.get);\n }\n\n if (typeof desc.value === 'function') {\n return unapply(desc.value);\n }\n }\n\n object = getPrototypeOf(object);\n }\n\n function fallbackValue() {\n return null;\n }\n\n return fallbackValue;\n}\n\nexport {\n // Array\n arrayForEach,\n arrayIndexOf,\n arrayPop,\n arrayPush,\n arraySlice,\n // Object\n entries,\n freeze,\n getPrototypeOf,\n getOwnPropertyDescriptor,\n isFrozen,\n setPrototypeOf,\n seal,\n clone,\n create,\n objectHasOwnProperty,\n // RegExp\n regExpTest,\n // String\n stringIndexOf,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringToString,\n stringTrim,\n // Errors\n typeErrorCreate,\n // Other\n lookupGetter,\n addToSet,\n // Reflect\n unapply,\n unconstruct,\n};\n","import { freeze } from './utils.js';\n\nexport const html = freeze([\n 'a',\n 'abbr',\n 'acronym',\n 'address',\n 'area',\n 'article',\n 'aside',\n 'audio',\n 'b',\n 'bdi',\n 'bdo',\n 'big',\n 'blink',\n 'blockquote',\n 'body',\n 'br',\n 'button',\n 'canvas',\n 'caption',\n 'center',\n 'cite',\n 'code',\n 'col',\n 'colgroup',\n 'content',\n 'data',\n 'datalist',\n 'dd',\n 'decorator',\n 'del',\n 'details',\n 'dfn',\n 'dialog',\n 'dir',\n 'div',\n 'dl',\n 'dt',\n 'element',\n 'em',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'font',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'head',\n 'header',\n 'hgroup',\n 'hr',\n 'html',\n 'i',\n 'img',\n 'input',\n 'ins',\n 'kbd',\n 'label',\n 'legend',\n 'li',\n 'main',\n 'map',\n 'mark',\n 'marquee',\n 'menu',\n 'menuitem',\n 'meter',\n 'nav',\n 'nobr',\n 'ol',\n 'optgroup',\n 'option',\n 'output',\n 'p',\n 'picture',\n 'pre',\n 'progress',\n 'q',\n 'rp',\n 'rt',\n 'ruby',\n 's',\n 'samp',\n 'section',\n 'select',\n 'shadow',\n 'small',\n 'source',\n 'spacer',\n 'span',\n 'strike',\n 'strong',\n 'style',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'template',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'time',\n 'tr',\n 'track',\n 'tt',\n 'u',\n 'ul',\n 'var',\n 'video',\n 'wbr',\n]);\n\n// SVG\nexport const svg = freeze([\n 'svg',\n 'a',\n 'altglyph',\n 'altglyphdef',\n 'altglyphitem',\n 'animatecolor',\n 'animatemotion',\n 'animatetransform',\n 'circle',\n 'clippath',\n 'defs',\n 'desc',\n 'ellipse',\n 'filter',\n 'font',\n 'g',\n 'glyph',\n 'glyphref',\n 'hkern',\n 'image',\n 'line',\n 'lineargradient',\n 'marker',\n 'mask',\n 'metadata',\n 'mpath',\n 'path',\n 'pattern',\n 'polygon',\n 'polyline',\n 'radialgradient',\n 'rect',\n 'stop',\n 'style',\n 'switch',\n 'symbol',\n 'text',\n 'textpath',\n 'title',\n 'tref',\n 'tspan',\n 'view',\n 'vkern',\n]);\n\nexport const svgFilters = freeze([\n 'feBlend',\n 'feColorMatrix',\n 'feComponentTransfer',\n 'feComposite',\n 'feConvolveMatrix',\n 'feDiffuseLighting',\n 'feDisplacementMap',\n 'feDistantLight',\n 'feDropShadow',\n 'feFlood',\n 'feFuncA',\n 'feFuncB',\n 'feFuncG',\n 'feFuncR',\n 'feGaussianBlur',\n 'feImage',\n 'feMerge',\n 'feMergeNode',\n 'feMorphology',\n 'feOffset',\n 'fePointLight',\n 'feSpecularLighting',\n 'feSpotLight',\n 'feTile',\n 'feTurbulence',\n]);\n\n// List of SVG elements that are disallowed by default.\n// We still need to know them so that we can do namespace\n// checks properly in case one wants to add them to\n// allow-list.\nexport const svgDisallowed = freeze([\n 'animate',\n 'color-profile',\n 'cursor',\n 'discard',\n 'font-face',\n 'font-face-format',\n 'font-face-name',\n 'font-face-src',\n 'font-face-uri',\n 'foreignobject',\n 'hatch',\n 'hatchpath',\n 'mesh',\n 'meshgradient',\n 'meshpatch',\n 'meshrow',\n 'missing-glyph',\n 'script',\n 'set',\n 'solidcolor',\n 'unknown',\n 'use',\n]);\n\nexport const mathMl = freeze([\n 'math',\n 'menclose',\n 'merror',\n 'mfenced',\n 'mfrac',\n 'mglyph',\n 'mi',\n 'mlabeledtr',\n 'mmultiscripts',\n 'mn',\n 'mo',\n 'mover',\n 'mpadded',\n 'mphantom',\n 'mroot',\n 'mrow',\n 'ms',\n 'mspace',\n 'msqrt',\n 'mstyle',\n 'msub',\n 'msup',\n 'msubsup',\n 'mtable',\n 'mtd',\n 'mtext',\n 'mtr',\n 'munder',\n 'munderover',\n 'mprescripts',\n]);\n\n// Similarly to SVG, we want to know all MathML elements,\n// even those that we disallow by default.\nexport const mathMlDisallowed = freeze([\n 'maction',\n 'maligngroup',\n 'malignmark',\n 'mlongdiv',\n 'mscarries',\n 'mscarry',\n 'msgroup',\n 'mstack',\n 'msline',\n 'msrow',\n 'semantics',\n 'annotation',\n 'annotation-xml',\n 'mprescripts',\n 'none',\n]);\n\nexport const text = freeze(['#text']);\n","import { freeze } from './utils.js';\n\nexport const html = freeze([\n 'accept',\n 'action',\n 'align',\n 'alt',\n 'autocapitalize',\n 'autocomplete',\n 'autopictureinpicture',\n 'autoplay',\n 'background',\n 'bgcolor',\n 'border',\n 'capture',\n 'cellpadding',\n 'cellspacing',\n 'checked',\n 'cite',\n 'class',\n 'clear',\n 'color',\n 'cols',\n 'colspan',\n 'controls',\n 'controlslist',\n 'coords',\n 'crossorigin',\n 'datetime',\n 'decoding',\n 'default',\n 'dir',\n 'disabled',\n 'disablepictureinpicture',\n 'disableremoteplayback',\n 'download',\n 'draggable',\n 'enctype',\n 'enterkeyhint',\n 'face',\n 'for',\n 'headers',\n 'height',\n 'hidden',\n 'high',\n 'href',\n 'hreflang',\n 'id',\n 'inputmode',\n 'integrity',\n 'ismap',\n 'kind',\n 'label',\n 'lang',\n 'list',\n 'loading',\n 'loop',\n 'low',\n 'max',\n 'maxlength',\n 'media',\n 'method',\n 'min',\n 'minlength',\n 'multiple',\n 'muted',\n 'name',\n 'nonce',\n 'noshade',\n 'novalidate',\n 'nowrap',\n 'open',\n 'optimum',\n 'pattern',\n 'placeholder',\n 'playsinline',\n 'popover',\n 'popovertarget',\n 'popovertargetaction',\n 'poster',\n 'preload',\n 'pubdate',\n 'radiogroup',\n 'readonly',\n 'rel',\n 'required',\n 'rev',\n 'reversed',\n 'role',\n 'rows',\n 'rowspan',\n 'spellcheck',\n 'scope',\n 'selected',\n 'shape',\n 'size',\n 'sizes',\n 'span',\n 'srclang',\n 'start',\n 'src',\n 'srcset',\n 'step',\n 'style',\n 'summary',\n 'tabindex',\n 'title',\n 'translate',\n 'type',\n 'usemap',\n 'valign',\n 'value',\n 'width',\n 'wrap',\n 'xmlns',\n 'slot',\n]);\n\nexport const svg = freeze([\n 'accent-height',\n 'accumulate',\n 'additive',\n 'alignment-baseline',\n 'ascent',\n 'attributename',\n 'attributetype',\n 'azimuth',\n 'basefrequency',\n 'baseline-shift',\n 'begin',\n 'bias',\n 'by',\n 'class',\n 'clip',\n 'clippathunits',\n 'clip-path',\n 'clip-rule',\n 'color',\n 'color-interpolation',\n 'color-interpolation-filters',\n 'color-profile',\n 'color-rendering',\n 'cx',\n 'cy',\n 'd',\n 'dx',\n 'dy',\n 'diffuseconstant',\n 'direction',\n 'display',\n 'divisor',\n 'dur',\n 'edgemode',\n 'elevation',\n 'end',\n 'fill',\n 'fill-opacity',\n 'fill-rule',\n 'filter',\n 'filterunits',\n 'flood-color',\n 'flood-opacity',\n 'font-family',\n 'font-size',\n 'font-size-adjust',\n 'font-stretch',\n 'font-style',\n 'font-variant',\n 'font-weight',\n 'fx',\n 'fy',\n 'g1',\n 'g2',\n 'glyph-name',\n 'glyphref',\n 'gradientunits',\n 'gradienttransform',\n 'height',\n 'href',\n 'id',\n 'image-rendering',\n 'in',\n 'in2',\n 'k',\n 'k1',\n 'k2',\n 'k3',\n 'k4',\n 'kerning',\n 'keypoints',\n 'keysplines',\n 'keytimes',\n 'lang',\n 'lengthadjust',\n 'letter-spacing',\n 'kernelmatrix',\n 'kernelunitlength',\n 'lighting-color',\n 'local',\n 'marker-end',\n 'marker-mid',\n 'marker-start',\n 'markerheight',\n 'markerunits',\n 'markerwidth',\n 'maskcontentunits',\n 'maskunits',\n 'max',\n 'mask',\n 'media',\n 'method',\n 'mode',\n 'min',\n 'name',\n 'numoctaves',\n 'offset',\n 'operator',\n 'opacity',\n 'order',\n 'orient',\n 'orientation',\n 'origin',\n 'overflow',\n 'paint-order',\n 'path',\n 'pathlength',\n 'patterncontentunits',\n 'patterntransform',\n 'patternunits',\n 'points',\n 'preservealpha',\n 'preserveaspectratio',\n 'primitiveunits',\n 'r',\n 'rx',\n 'ry',\n 'radius',\n 'refx',\n 'refy',\n 'repeatcount',\n 'repeatdur',\n 'restart',\n 'result',\n 'rotate',\n 'scale',\n 'seed',\n 'shape-rendering',\n 'specularconstant',\n 'specularexponent',\n 'spreadmethod',\n 'startoffset',\n 'stddeviation',\n 'stitchtiles',\n 'stop-color',\n 'stop-opacity',\n 'stroke-dasharray',\n 'stroke-dashoffset',\n 'stroke-linecap',\n 'stroke-linejoin',\n 'stroke-miterlimit',\n 'stroke-opacity',\n 'stroke',\n 'stroke-width',\n 'style',\n 'surfacescale',\n 'systemlanguage',\n 'tabindex',\n 'targetx',\n 'targety',\n 'transform',\n 'transform-origin',\n 'text-anchor',\n 'text-decoration',\n 'text-rendering',\n 'textlength',\n 'type',\n 'u1',\n 'u2',\n 'unicode',\n 'values',\n 'viewbox',\n 'visibility',\n 'version',\n 'vert-adv-y',\n 'vert-origin-x',\n 'vert-origin-y',\n 'width',\n 'word-spacing',\n 'wrap',\n 'writing-mode',\n 'xchannelselector',\n 'ychannelselector',\n 'x',\n 'x1',\n 'x2',\n 'xmlns',\n 'y',\n 'y1',\n 'y2',\n 'z',\n 'zoomandpan',\n]);\n\nexport const mathMl = freeze([\n 'accent',\n 'accentunder',\n 'align',\n 'bevelled',\n 'close',\n 'columnsalign',\n 'columnlines',\n 'columnspan',\n 'denomalign',\n 'depth',\n 'dir',\n 'display',\n 'displaystyle',\n 'encoding',\n 'fence',\n 'frame',\n 'height',\n 'href',\n 'id',\n 'largeop',\n 'length',\n 'linethickness',\n 'lspace',\n 'lquote',\n 'mathbackground',\n 'mathcolor',\n 'mathsize',\n 'mathvariant',\n 'maxsize',\n 'minsize',\n 'movablelimits',\n 'notation',\n 'numalign',\n 'open',\n 'rowalign',\n 'rowlines',\n 'rowspacing',\n 'rowspan',\n 'rspace',\n 'rquote',\n 'scriptlevel',\n 'scriptminsize',\n 'scriptsizemultiplier',\n 'selection',\n 'separator',\n 'separators',\n 'stretchy',\n 'subscriptshift',\n 'supscriptshift',\n 'symmetric',\n 'voffset',\n 'width',\n 'xmlns',\n]);\n\nexport const xml = freeze([\n 'xlink:href',\n 'xml:id',\n 'xlink:title',\n 'xml:space',\n 'xmlns:xlink',\n]);\n","import { seal } from './utils.js';\n\n// eslint-disable-next-line unicorn/better-regex\nexport const MUSTACHE_EXPR = seal(/\\{\\{[\\w\\W]*|[\\w\\W]*\\}\\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode\nexport const ERB_EXPR = seal(/<%[\\w\\W]*|[\\w\\W]*%>/gm);\nexport const TMPLIT_EXPR = seal(/\\${[\\w\\W]*}/gm);\nexport const DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]/); // eslint-disable-line no-useless-escape\nexport const ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\nexport const IS_ALLOWED_URI = seal(\n /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nexport const IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nexport const ATTR_WHITESPACE = seal(\n /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\nexport const DOCTYPE_NAME = seal(/^html$/i);\nexport const CUSTOM_ELEMENT = seal(/^[a-z][.\\w]*(-[.\\w]+)+$/i);\n","import * as TAGS from './tags.js';\nimport * as ATTRS from './attrs.js';\nimport * as EXPRESSIONS from './regexp.js';\nimport {\n addToSet,\n clone,\n entries,\n freeze,\n arrayForEach,\n arrayPop,\n arrayPush,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringToString,\n stringIndexOf,\n stringTrim,\n regExpTest,\n typeErrorCreate,\n lookupGetter,\n create,\n objectHasOwnProperty,\n} from './utils.js';\n\n// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType\nconst NODE_TYPE = {\n element: 1,\n attribute: 2,\n text: 3,\n cdataSection: 4,\n entityReference: 5, // Deprecated\n entityNode: 6, // Deprecated\n progressingInstruction: 7,\n comment: 8,\n document: 9,\n documentType: 10,\n documentFragment: 11,\n notation: 12, // Deprecated\n};\n\nconst getGlobal = function () {\n return typeof window === 'undefined' ? null : window;\n};\n\n/**\n * Creates a no-op policy for internal use only.\n * Don't export this function outside this module!\n * @param {TrustedTypePolicyFactory} trustedTypes The policy factory.\n * @param {HTMLScriptElement} purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).\n * @return {TrustedTypePolicy} The policy created (or null, if Trusted Types\n * are not supported or creating the policy failed).\n */\nconst _createTrustedTypesPolicy = function (trustedTypes, purifyHostElement) {\n if (\n typeof trustedTypes !== 'object' ||\n typeof trustedTypes.createPolicy !== 'function'\n ) {\n return null;\n }\n\n // Allow the callers to control the unique policy name\n // by adding a data-tt-policy-suffix to the script element with the DOMPurify.\n // Policy creation with duplicate names throws in Trusted Types.\n let suffix = null;\n const ATTR_NAME = 'data-tt-policy-suffix';\n if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {\n suffix = purifyHostElement.getAttribute(ATTR_NAME);\n }\n\n const policyName = 'dompurify' + (suffix ? '#' + suffix : '');\n\n try {\n return trustedTypes.createPolicy(policyName, {\n createHTML(html) {\n return html;\n },\n createScriptURL(scriptUrl) {\n return scriptUrl;\n },\n });\n } catch (_) {\n // Policy creation failed (most likely another DOMPurify script has\n // already run). Skip creating the policy, as this will only cause errors\n // if TT are enforced.\n console.warn(\n 'TrustedTypes policy ' + policyName + ' could not be created.'\n );\n return null;\n }\n};\n\nfunction createDOMPurify(window = getGlobal()) {\n const DOMPurify = (root) => createDOMPurify(root);\n\n /**\n * Version label, exposed for easier checks\n * if DOMPurify is up to date or not\n */\n DOMPurify.version = VERSION;\n\n /**\n * Array of elements that DOMPurify removed during sanitation.\n * Empty if nothing was removed.\n */\n DOMPurify.removed = [];\n\n if (\n !window ||\n !window.document ||\n window.document.nodeType !== NODE_TYPE.document\n ) {\n // Not running in a browser, provide a factory function\n // so that you can pass your own Window\n DOMPurify.isSupported = false;\n\n return DOMPurify;\n }\n\n let { document } = window;\n\n const originalDocument = document;\n const currentScript = originalDocument.currentScript;\n const {\n DocumentFragment,\n HTMLTemplateElement,\n Node,\n Element,\n NodeFilter,\n NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,\n HTMLFormElement,\n DOMParser,\n trustedTypes,\n } = window;\n\n const ElementPrototype = Element.prototype;\n\n const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');\n const remove = lookupGetter(ElementPrototype, 'remove');\n const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');\n const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');\n const getParentNode = lookupGetter(ElementPrototype, 'parentNode');\n\n // As per issue #47, the web-components registry is inherited by a\n // new document created via createHTMLDocument. As per the spec\n // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)\n // a new empty registry is used when creating a template contents owner\n // document, so we use that as our parent document to ensure nothing\n // is inherited.\n if (typeof HTMLTemplateElement === 'function') {\n const template = document.createElement('template');\n if (template.content && template.content.ownerDocument) {\n document = template.content.ownerDocument;\n }\n }\n\n let trustedTypesPolicy;\n let emptyHTML = '';\n\n const {\n implementation,\n createNodeIterator,\n createDocumentFragment,\n getElementsByTagName,\n } = document;\n const { importNode } = originalDocument;\n\n let hooks = {};\n\n /**\n * Expose whether this browser supports running the full DOMPurify.\n */\n DOMPurify.isSupported =\n typeof entries === 'function' &&\n typeof getParentNode === 'function' &&\n implementation &&\n implementation.createHTMLDocument !== undefined;\n\n const {\n MUSTACHE_EXPR,\n ERB_EXPR,\n TMPLIT_EXPR,\n DATA_ATTR,\n ARIA_ATTR,\n IS_SCRIPT_OR_DATA,\n ATTR_WHITESPACE,\n CUSTOM_ELEMENT,\n } = EXPRESSIONS;\n\n let { IS_ALLOWED_URI } = EXPRESSIONS;\n\n /**\n * We consider the elements and attributes below to be safe. Ideally\n * don't add any new ones but feel free to remove unwanted ones.\n */\n\n /* allowed element names */\n let ALLOWED_TAGS = null;\n const DEFAULT_ALLOWED_TAGS = addToSet({}, [\n ...TAGS.html,\n ...TAGS.svg,\n ...TAGS.svgFilters,\n ...TAGS.mathMl,\n ...TAGS.text,\n ]);\n\n /* Allowed attribute names */\n let ALLOWED_ATTR = null;\n const DEFAULT_ALLOWED_ATTR = addToSet({}, [\n ...ATTRS.html,\n ...ATTRS.svg,\n ...ATTRS.mathMl,\n ...ATTRS.xml,\n ]);\n\n /*\n * Configure how DOMPUrify should handle custom elements and their attributes as well as customized built-in elements.\n * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)\n * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)\n * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.\n */\n let CUSTOM_ELEMENT_HANDLING = Object.seal(\n create(null, {\n tagNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n attributeNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n allowCustomizedBuiltInElements: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: false,\n },\n })\n );\n\n /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */\n let FORBID_TAGS = null;\n\n /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */\n let FORBID_ATTR = null;\n\n /* Decide if ARIA attributes are okay */\n let ALLOW_ARIA_ATTR = true;\n\n /* Decide if custom data attributes are okay */\n let ALLOW_DATA_ATTR = true;\n\n /* Decide if unknown protocols are okay */\n let ALLOW_UNKNOWN_PROTOCOLS = false;\n\n /* Decide if self-closing tags in attributes are allowed.\n * Usually removed due to a mXSS issue in jQuery 3.0 */\n let ALLOW_SELF_CLOSE_IN_ATTR = true;\n\n /* Output should be safe for common template engines.\n * This means, DOMPurify removes data attributes, mustaches and ERB\n */\n let SAFE_FOR_TEMPLATES = false;\n\n /* Output should be safe even for XML used within HTML and alike.\n * This means, DOMPurify removes comments when containing risky content.\n */\n let SAFE_FOR_XML = true;\n\n /* Decide if document with <html>... should be returned */\n let WHOLE_DOCUMENT = false;\n\n /* Track whether config is already set on this instance of DOMPurify. */\n let SET_CONFIG = false;\n\n /* Decide if all elements (e.g. style, script) must be children of\n * document.body. By default, browsers might move them to document.head */\n let FORCE_BODY = false;\n\n /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported).\n * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead\n */\n let RETURN_DOM = false;\n\n /* Decide if a DOM `DocumentFragment` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported) */\n let RETURN_DOM_FRAGMENT = false;\n\n /* Try to return a Trusted Type object instead of a string, return a string in\n * case Trusted Types are not supported */\n let RETURN_TRUSTED_TYPE = false;\n\n /* Output should be free from DOM clobbering attacks?\n * This sanitizes markups named with colliding, clobberable built-in DOM APIs.\n */\n let SANITIZE_DOM = true;\n\n /* Achieve full DOM Clobbering protection by isolating the namespace of named\n * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.\n *\n * HTML/DOM spec rules that enable DOM Clobbering:\n * - Named Access on Window (§7.3.3)\n * - DOM Tree Accessors (§3.1.5)\n * - Form Element Parent-Child Relations (§4.10.3)\n * - Iframe srcdoc / Nested WindowProxies (§4.8.5)\n * - HTMLCollection (§4.2.10.2)\n *\n * Namespace isolation is implemented by prefixing `id` and `name` attributes\n * with a constant string, i.e., `user-content-`\n */\n let SANITIZE_NAMED_PROPS = false;\n const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';\n\n /* Keep element content when removing element? */\n let KEEP_CONTENT = true;\n\n /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead\n * of importing it into a new Document and returning a sanitized copy */\n let IN_PLACE = false;\n\n /* Allow usage of profiles like html, svg and mathMl */\n let USE_PROFILES = {};\n\n /* Tags to ignore content of when KEEP_CONTENT is true */\n let FORBID_CONTENTS = null;\n const DEFAULT_FORBID_CONTENTS = addToSet({}, [\n 'annotation-xml',\n 'audio',\n 'colgroup',\n 'desc',\n 'foreignobject',\n 'head',\n 'iframe',\n 'math',\n 'mi',\n 'mn',\n 'mo',\n 'ms',\n 'mtext',\n 'noembed',\n 'noframes',\n 'noscript',\n 'plaintext',\n 'script',\n 'style',\n 'svg',\n 'template',\n 'thead',\n 'title',\n 'video',\n 'xmp',\n ]);\n\n /* Tags that are safe for data: URIs */\n let DATA_URI_TAGS = null;\n const DEFAULT_DATA_URI_TAGS = addToSet({}, [\n 'audio',\n 'video',\n 'img',\n 'source',\n 'image',\n 'track',\n ]);\n\n /* Attributes safe for values like \"javascript:\" */\n let URI_SAFE_ATTRIBUTES = null;\n const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, [\n 'alt',\n 'class',\n 'for',\n 'id',\n 'label',\n 'name',\n 'pattern',\n 'placeholder',\n 'role',\n 'summary',\n 'title',\n 'value',\n 'style',\n 'xmlns',\n ]);\n\n const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n /* Document namespace */\n let NAMESPACE = HTML_NAMESPACE;\n let IS_EMPTY_INPUT = false;\n\n /* Allowed XHTML+XML namespaces */\n let ALLOWED_NAMESPACES = null;\n const DEFAULT_ALLOWED_NAMESPACES = addToSet(\n {},\n [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE],\n stringToString\n );\n\n /* Parsing of strict XHTML documents */\n let PARSER_MEDIA_TYPE = null;\n const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];\n const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';\n let transformCaseFunc = null;\n\n /* Keep a reference to config to pass to hooks */\n let CONFIG = null;\n\n /* Ideally, do not touch anything below this line */\n /* ______________________________________________ */\n\n const formElement = document.createElement('form');\n\n const isRegexOrFunction = function (testValue) {\n return testValue instanceof RegExp || testValue instanceof Function;\n };\n\n /**\n * _parseConfig\n *\n * @param {Object} cfg optional config literal\n */\n // eslint-disable-next-line complexity\n const _parseConfig = function (cfg = {}) {\n if (CONFIG && CONFIG === cfg) {\n return;\n }\n\n /* Shield configuration object from tampering */\n if (!cfg || typeof cfg !== 'object') {\n cfg = {};\n }\n\n /* Shield configuration object from prototype pollution */\n cfg = clone(cfg);\n\n PARSER_MEDIA_TYPE =\n // eslint-disable-next-line unicorn/prefer-includes\n SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1\n ? DEFAULT_PARSER_MEDIA_TYPE\n : cfg.PARSER_MEDIA_TYPE;\n\n // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.\n transformCaseFunc =\n PARSER_MEDIA_TYPE === 'application/xhtml+xml'\n ? stringToString\n : stringToLowerCase;\n\n /* Set configuration parameters */\n ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS')\n ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc)\n : DEFAULT_ALLOWED_TAGS;\n ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR')\n ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc)\n : DEFAULT_ALLOWED_ATTR;\n ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES')\n ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString)\n : DEFAULT_ALLOWED_NAMESPACES;\n URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR')\n ? addToSet(\n clone(DEFAULT_URI_SAFE_ATTRIBUTES), // eslint-disable-line indent\n cfg.ADD_URI_SAFE_ATTR, // eslint-disable-line indent\n transformCaseFunc // eslint-disable-line indent\n ) // eslint-disable-line indent\n : DEFAULT_URI_SAFE_ATTRIBUTES;\n DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS')\n ? addToSet(\n clone(DEFAULT_DATA_URI_TAGS), // eslint-disable-line indent\n cfg.ADD_DATA_URI_TAGS, // eslint-disable-line indent\n transformCaseFunc // eslint-disable-line indent\n ) // eslint-disable-line indent\n : DEFAULT_DATA_URI_TAGS;\n FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS')\n ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc)\n : DEFAULT_FORBID_CONTENTS;\n FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS')\n ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc)\n : {};\n FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR')\n ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc)\n : {};\n USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES')\n ? cfg.USE_PROFILES\n : false;\n ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true\n ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true\n ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false\n ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true\n SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false\n SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true\n WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false\n RETURN_DOM = cfg.RETURN_DOM || false; // Default false\n RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false\n RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false\n FORCE_BODY = cfg.FORCE_BODY || false; // Default false\n SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true\n SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false\n KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true\n IN_PLACE = cfg.IN_PLACE || false; // Default false\n IS_ALLOWED_URI = cfg.ALLOWED_URI_REGEXP || EXPRESSIONS.IS_ALLOWED_URI;\n NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;\n CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {};\n if (\n cfg.CUSTOM_ELEMENT_HANDLING &&\n isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)\n ) {\n CUSTOM_ELEMENT_HANDLING.tagNameCheck =\n cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;\n }\n\n if (\n cfg.CUSTOM_ELEMENT_HANDLING &&\n isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)\n ) {\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck =\n cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;\n }\n\n if (\n cfg.CUSTOM_ELEMENT_HANDLING &&\n typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements ===\n 'boolean'\n ) {\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements =\n cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;\n }\n\n if (SAFE_FOR_TEMPLATES) {\n ALLOW_DATA_ATTR = false;\n }\n\n if (RETURN_DOM_FRAGMENT) {\n RETURN_DOM = true;\n }\n\n /* Parse profile info */\n if (USE_PROFILES) {\n ALLOWED_TAGS = addToSet({}, TAGS.text);\n ALLOWED_ATTR = [];\n if (USE_PROFILES.html === true) {\n addToSet(ALLOWED_TAGS, TAGS.html);\n addToSet(ALLOWED_ATTR, ATTRS.html);\n }\n\n if (USE_PROFILES.svg === true) {\n addToSet(ALLOWED_TAGS, TAGS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n\n if (USE_PROFILES.svgFilters === true) {\n addToSet(ALLOWED_TAGS, TAGS.svgFilters);\n addToSet(ALLOWED_ATTR, ATTRS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n\n if (USE_PROFILES.mathMl === true) {\n addToSet(ALLOWED_TAGS, TAGS.mathMl);\n addToSet(ALLOWED_ATTR, ATTRS.mathMl);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n }\n\n /* Merge configuration parameters */\n if (cfg.ADD_TAGS) {\n if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n\n addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);\n }\n\n if (cfg.ADD_ATTR) {\n if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n\n addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);\n }\n\n if (cfg.ADD_URI_SAFE_ATTR) {\n addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);\n }\n\n if (cfg.FORBID_CONTENTS) {\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\n }\n\n addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);\n }\n\n /* Add #text in case KEEP_CONTENT is set to true */\n if (KEEP_CONTENT) {\n ALLOWED_TAGS['#text'] = true;\n }\n\n /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */\n if (WHOLE_DOCUMENT) {\n addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);\n }\n\n /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */\n if (ALLOWED_TAGS.table) {\n addToSet(ALLOWED_TAGS, ['tbody']);\n delete FORBID_TAGS.tbody;\n }\n\n if (cfg.TRUSTED_TYPES_POLICY) {\n if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {\n throw typeErrorCreate(\n 'TRUSTED_TYPES_POLICY configuration option must provide a \"createHTML\" hook.'\n );\n }\n\n if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {\n throw typeErrorCreate(\n 'TRUSTED_TYPES_POLICY configuration option must provide a \"createScriptURL\" hook.'\n );\n }\n\n // Overwrite existing TrustedTypes policy.\n trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;\n\n // Sign local variables required by `sanitize`.\n emptyHTML = trustedTypesPolicy.createHTML('');\n } else {\n // Uninitialized policy, attempt to initialize the internal dompurify policy.\n if (trustedTypesPolicy === undefined) {\n trustedTypesPolicy = _createTrustedTypesPolicy(\n trustedTypes,\n currentScript\n );\n }\n\n // If creating the internal policy succeeded sign internal variables.\n if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') {\n emptyHTML = trustedTypesPolicy.createHTML('');\n }\n }\n\n // Prevent further manipulation of configuration.\n // Not available in IE8, Safari 5, etc.\n if (freeze) {\n freeze(cfg);\n }\n\n CONFIG = cfg;\n };\n\n const MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, [\n 'mi',\n 'mo',\n 'mn',\n 'ms',\n 'mtext',\n ]);\n\n const HTML_INTEGRATION_POINTS = addToSet({}, [\n 'foreignobject',\n 'annotation-xml',\n ]);\n\n // Certain elements are allowed in both SVG and HTML\n // namespace. We need to specify them explicitly\n // so that they don't get erroneously deleted from\n // HTML namespace.\n const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, [\n 'title',\n 'style',\n 'font',\n 'a',\n 'script',\n ]);\n\n /* Keep track of all possible SVG and MathML tags\n * so that we can perform the namespace checks\n * correctly. */\n const ALL_SVG_TAGS = addToSet({}, [\n ...TAGS.svg,\n ...TAGS.svgFilters,\n ...TAGS.svgDisallowed,\n ]);\n const ALL_MATHML_TAGS = addToSet({}, [\n ...TAGS.mathMl,\n ...TAGS.mathMlDisallowed,\n ]);\n\n /**\n * @param {Element} element a DOM element whose namespace is being checked\n * @returns {boolean} Return false if the element has a\n * namespace that a spec-compliant parser would never\n * return. Return true otherwise.\n */\n const _checkValidNamespace = function (element) {\n let parent = getParentNode(element);\n\n // In JSDOM, if we're inside shadow DOM, then parentNode\n // can be null. We just simulate parent in this case.\n if (!parent || !parent.tagName) {\n parent = {\n namespaceURI: NAMESPACE,\n tagName: 'template',\n };\n }\n\n const tagName = stringToLowerCase(element.tagName);\n const parentTagName = stringToLowerCase(parent.tagName);\n\n if (!ALLOWED_NAMESPACES[element.namespaceURI]) {\n return false;\n }\n\n if (element.namespaceURI === SVG_NAMESPACE) {\n // The only way to switch from HTML namespace to SVG\n // is via <svg>. If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'svg';\n }\n\n // The only way to switch from MathML to SVG is via`\n // svg if parent is either <annotation-xml> or MathML\n // text integration points.\n if (parent.namespaceURI === MATHML_NAMESPACE) {\n return (\n tagName === 'svg' &&\n (parentTagName === 'annotation-xml' ||\n MATHML_TEXT_INTEGRATION_POINTS[parentTagName])\n );\n }\n\n // We only allow elements that are defined in SVG\n // spec. All others are disallowed in SVG namespace.\n return Boolean(ALL_SVG_TAGS[tagName]);\n }\n\n if (element.namespaceURI === MATHML_NAMESPACE) {\n // The only way to switch from HTML namespace to MathML\n // is via <math>. If it happens via any other tag, then\n // it should be killed.\n if (parent.namespaceURI === HTML_NAMESPACE) {\n return tagName === 'math';\n }\n\n // The only way to switch from SVG to MathML is via\n // <math> and HTML integration points\n if (parent.namespaceURI === SVG_NAMESPACE) {\n return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];\n }\n\n // We only allow elements that are defined in MathML\n // spec. All others are disallowed in MathML namespace.\n return Boolean(ALL_MATHML_TAGS[tagName]);\n }\n\n if (element.namespaceURI === HTML_NAMESPACE) {\n // The only way to switch from SVG to HTML is via\n // HTML integration points, and from MathML to HTML\n // is via MathML text integration points\n if (\n parent.namespaceURI === SVG_NAMESPACE &&\n !HTML_INTEGRATION_POINTS[parentTagName]\n ) {\n return false;\n }\n\n if (\n parent.namespaceURI === MATHML_NAMESPACE &&\n !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]\n ) {\n return false;\n }\n\n // We disallow tags that are specific for MathML\n // or SVG and should never appear in HTML namespace\n return (\n !ALL_MATHML_TAGS[tagName] &&\n (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName])\n );\n }\n\n // For XHTML and XML documents that support custom namespaces\n if (\n PARSER_MEDIA_TYPE === 'application/xhtml+xml' &&\n ALLOWED_NAMESPACES[element.namespaceURI]\n ) {\n return true;\n }\n\n // The code should never reach this place (this means\n // that the element somehow got namespace that is not\n // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).\n // Return false just in case.\n return false;\n };\n\n /**\n * _forceRemove\n *\n * @param {Node} node a DOM node\n */\n const _forceRemove = function (node) {\n arrayPush(DOMPurify.removed, { element: node });\n\n try {\n // eslint-disable-next-line unicorn/prefer-dom-node-remove\n getParentNode(node).removeChild(node);\n } catch (_) {\n remove(node);\n }\n };\n\n /**\n * _removeAttribute\n *\n * @param {String} name an Attribute name\n * @param {Node} node a DOM node\n */\n const _removeAttribute = function (name, node) {\n try {\n arrayPush(DOMPurify.removed, {\n attribute: node.getAttributeNode(name),\n from: node,\n });\n } catch (_) {\n arrayPush(DOMPurify.removed, {\n attribute: null,\n from: node,\n });\n }\n\n node.removeAttribute(name);\n\n // We void attribute values for unremovable \"is\"\" attributes\n if (name === 'is' && !ALLOWED_ATTR[name]) {\n if (RETURN_DOM || RETURN_DOM_FRAGMENT) {\n try {\n _forceRemove(node);\n } catch (_) {}\n } else {\n try {\n node.setAttribute(name, '');\n } catch (_) {}\n }\n }\n };\n\n /**\n * _initDocument\n *\n * @param {String} dirty a string of dirty markup\n * @return {Document} a DOM, filled with the dirty markup\n */\n const _initDocument = function (dirty) {\n /* Create a HTML document */\n let doc = null;\n let leadingWhitespace = null;\n\n if (FORCE_BODY) {\n dirty = '<remove></remove>' + dirty;\n } else {\n /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */\n const matches = stringMatch(dirty, /^[\\r\\n\\t ]+/);\n leadingWhitespace = matches && matches[0];\n }\n\n if (\n PARSER_MEDIA_TYPE === 'application/xhtml+xml' &&\n NAMESPACE === HTML_NAMESPACE\n ) {\n // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)\n dirty =\n '<html xmlns=\"http://www.w3.org/1999/xhtml\"><head></head><body>' +\n dirty +\n '</body></html>';\n }\n\n const dirtyPayload = trustedTypesPolicy\n ? trustedTypesPolicy.createHTML(dirty)\n : dirty;\n /*\n * Use the DOMParser API by default, fallback later if needs be\n * DOMParser not work for svg when has multiple root element.\n */\n if (NAMESPACE === HTML_NAMESPACE) {\n try {\n doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);\n } catch (_) {}\n }\n\n /* Use createHTMLDocument in case DOMParser is not available */\n if (!doc || !doc.documentElement) {\n doc = implementation.createDocument(NAMESPACE, 'template', null);\n try {\n doc.documentElement.innerHTML = IS_EMPTY_INPUT\n ? emptyHTML\n : dirtyPayload;\n } catch (_) {\n // Syntax error if dirtyPayload is invalid xml\n }\n }\n\n const body = doc.body || doc.documentElement;\n\n if (dirty && leadingWhitespace) {\n body.insertBefore(\n document.createTextNode(leadingWhitespace),\n body.childNodes[0] || null\n );\n }\n\n /* Work on whole document or just its body */\n if (NAMESPACE === HTML_NAMESPACE) {\n return getElementsByTagName.call(\n doc,\n WHOLE_DOCUMENT ? 'html' : 'body'\n )[0];\n }\n\n return WHOLE_DOCUMENT ? doc.documentElement : body;\n };\n\n /**\n * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.\n *\n * @param {Node} root The root element or node to start traversing on.\n * @return {NodeIterator} The created NodeIterator\n */\n const _createNodeIterator = function (root) {\n return createNodeIterator.call(\n root.ownerDocument || root,\n root,\n // eslint-disable-next-line no-bitwise\n NodeFilter.SHOW_ELEMENT |\n NodeFilter.SHOW_COMMENT |\n NodeFilter.SHOW_TEXT |\n NodeFilter.SHOW_PROCESSING_INSTRUCTION |\n NodeFilter.SHOW_CDATA_SECTION,\n null\n );\n };\n\n /**\n * _isClobbered\n *\n * @param {Node} elm element to check for clobbering attacks\n * @return {Boolean} true if clobbered, false if safe\n */\n const _isClobbered = function (elm) {\n return (\n elm instanceof HTMLFormElement &&\n (typeof elm.nodeName !== 'string' ||\n typeof elm.textContent !== 'string' ||\n typeof elm.removeChild !== 'function' ||\n !(elm.attributes instanceof NamedNodeMap) ||\n typeof elm.removeAttribute !== 'function' ||\n typeof elm.setAttribute !== 'function' ||\n typeof elm.namespaceURI !== 'string' ||\n typeof elm.insertBefore !== 'function' ||\n typeof elm.hasChildNodes !== 'function')\n );\n };\n\n /**\n * Checks whether the given object is a DOM node.\n *\n * @param {Node} object object to check whether it's a DOM node\n * @return {Boolean} true is object is a DOM node\n */\n const _isNode = function (object) {\n return typeof Node === 'function' && object instanceof Node;\n };\n\n /**\n * _executeHook\n * Execute user configurable hooks\n *\n * @param {String} entryPoint Name of the hook's entry point\n * @param {Node} currentNode node to work on with the hook\n * @param {Object} data additional hook parameters\n */\n const _executeHook = function (entryPoint, currentNode, data) {\n if (!hooks[entryPoint]) {\n return;\n }\n\n arrayForEach(hooks[entryPoint], (hook) => {\n hook.call(DOMPurify, currentNode, data, CONFIG);\n });\n };\n\n /**\n * _sanitizeElements\n *\n * @protect nodeName\n * @protect textContent\n * @protect removeChild\n *\n * @param {Node} currentNode to check for permission to exist\n * @return {Boolean} true if node was killed, false if left alive\n */\n const _sanitizeElements = function (currentNode) {\n let content = null;\n\n /* Execute a hook if present */\n _executeHook('beforeSanitizeElements', currentNode, null);\n\n /* Check if element is clobbered or can clobber */\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Now let's check the element's type and name */\n const tagName = transformCaseFunc(currentNode.nodeName);\n\n /* Execute a hook if present */\n _executeHook('uponSanitizeElement', currentNode, {\n tagName,\n allowedTags: ALLOWED_TAGS,\n });\n\n /* Detect mXSS attempts abusing namespace confusion */\n if (\n currentNode.hasChildNodes() &&\n !_isNode(currentNode.firstElementChild) &&\n regExpTest(/<[/\\w]/g, currentNode.innerHTML) &&\n regExpTest(/<[/\\w]/g, currentNode.textContent)\n ) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Remove any occurrence of processing instructions */\n if (currentNode.nodeType === NODE_TYPE.progressingInstruction) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Remove any kind of possibly harmful comments */\n if (\n SAFE_FOR_XML &&\n currentNode.nodeType === NODE_TYPE.comment &&\n regExpTest(/<[/\\w]/g, currentNode.data)\n ) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Remove element if anything forbids its presence */\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n /* Check if we have a custom element to handle */\n if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {\n if (\n CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)\n ) {\n return false;\n }\n\n if (\n CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)\n ) {\n return false;\n }\n }\n\n /* Keep content except for bad-listed elements */\n if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {\n const parentNode = getParentNode(currentNode) || currentNode.parentNode;\n const childNodes = getChildNodes(currentNode) || currentNode.childNodes;\n\n if (childNodes && parentNode) {\n const childCount = childNodes.length;\n\n for (let i = childCount - 1; i >= 0; --i) {\n const childClone = cloneNode(childNodes[i], true);\n childClone.__removalCount = (currentNode.__removalCount || 0) + 1;\n parentNode.insertBefore(childClone, getNextSibling(currentNode));\n }\n }\n }\n\n _forceRemove(currentNode);\n return true;\n }\n\n /* Check whether element has a valid namespace */\n if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Make sure that older browsers don't get fallback-tag mXSS */\n if (\n (tagName === 'noscript' ||\n tagName === 'noembed' ||\n tagName === 'noframes') &&\n regExpTest(/<\\/no(script|embed|frames)/i, currentNode.innerHTML)\n ) {\n _forceRemove(currentNode);\n return true;\n }\n\n /* Sanitize element content to be template-safe */\n if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {\n /* Get the element's text content */\n content = currentNode.textContent;\n\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], (expr) => {\n content = stringReplace(content, expr, ' ');\n });\n\n if (currentNode.textContent !== content) {\n arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });\n currentNode.textContent = content;\n }\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeElements', currentNode, null);\n\n return false;\n };\n\n /**\n * _isValidAttribute\n *\n * @param {string} lcTag Lowercase tag name of containing element.\n * @param {string} lcName Lowercase attribute name.\n * @param {string} value Attribute value.\n * @return {Boolean} Returns true if `value` is valid, otherwise false.\n */\n // eslint-disable-next-line complexity\n const _isValidAttribute = function (lcTag, lcName, value) {\n /* Make sure attribute cannot clobber */\n if (\n SANITIZE_DOM &&\n (lcName === 'id' || lcName === 'name') &&\n (value in document || value in formElement)\n ) {\n return false;\n }\n\n /* Allow valid data-* attributes: At least one character after \"-\"\n (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)\n XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)\n We don't need to check the value; it's always URI safe. */\n if (\n ALLOW_DATA_ATTR &&\n !FORBID_ATTR[lcName] &&\n regExpTest(DATA_ATTR, lcName)\n ) {\n // This attribute is safe\n } else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) {\n // This attribute is safe\n /* Otherwise, check the name is permitted */\n } else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {\n if (\n // First condition does a very basic check if a) it's basically a valid custom element tagname AND\n // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck\n (_isBasicCustomElement(lcTag) &&\n ((CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag)) ||\n (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag))) &&\n ((CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName)) ||\n (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName)))) ||\n // Alternative, second condition checks if it's an `is`-attribute, AND\n // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck\n (lcName === 'is' &&\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements &&\n ((CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp &&\n regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value)) ||\n (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function &&\n CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))))\n ) {\n // If user has supplied a regexp or function in CUSTOM_ELEMENT_HANDLING.tagNameCheck, we need to also allow derived custom elements using the same tagName test.\n // Additionally, we need to allow attributes passing the CUSTOM_ELEMENT_HANDLING.attributeNameCheck user has configured, as custom elements can define these at their own discretion.\n } else {\n return false;\n }\n /* Check value is safe. First, is attr inert? If so, is safe */\n } else if (URI_SAFE_ATTRIBUTES[lcName]) {\n // This attribute is safe\n /* Check no script, data or unknown possibly unsafe URI\n unless we know URI values are safe for that attribute */\n } else if (\n regExpTest(IS_ALLOWED_URI, stringReplace(value, ATTR_WHITESPACE, ''))\n ) {\n // This attribute is safe\n /* Keep image data URIs alive if src/xlink:href is allowed */\n /* Further prevent gadget XSS for dynamically built script tags */\n } else if (\n (lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') &&\n lcTag !== 'script' &&\n stringIndexOf(value, 'data:') === 0 &&\n DATA_URI_TAGS[lcTag]\n ) {\n // This attribute is safe\n /* Allow unknown protocols: This provides support for links that\n are handled by protocol handlers which may be unknown ahead of\n time, e.g. fb:, spotify: */\n } else if (\n ALLOW_UNKNOWN_PROTOCOLS &&\n !regExpTest(IS_SCRIPT_OR_DATA, stringReplace(value, ATTR_WHITESPACE, ''))\n ) {\n // This attribute is safe\n /* Check for binary attributes */\n } else if (value) {\n return false;\n } else {\n // Binary attributes are safe at this point\n /* Anything else, presume unsafe, do not add it back */\n }\n\n return true;\n };\n\n /**\n * _isBasicCustomElement\n * checks if at least one dash is included in tagName, and it's not the first char\n * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name\n *\n * @param {string} tagName name of the tag of the node to sanitize\n * @returns {boolean} Returns true if the tag name meets the basic criteria for a custom element, otherwise false.\n */\n const _isBasicCustomElement = function (tagName) {\n return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT);\n };\n\n /**\n * _sanitizeAttributes\n *\n * @protect attributes\n * @protect nodeName\n * @protect removeAttribute\n * @protect setAttribute\n *\n * @param {Node} currentNode to sanitize\n */\n const _sanitizeAttributes = function (currentNode) {\n /* Execute a hook if present */\n _executeHook('beforeSanitizeAttributes', currentNode, null);\n\n const { attributes } = currentNode;\n\n /* Check if we have attributes; if not we might have a text node */\n if (!attributes) {\n return;\n }\n\n const hookEvent = {\n attrName: '',\n attrValue: '',\n keepAttr: true,\n allowedAttributes: ALLOWED_ATTR,\n };\n let l = attributes.length;\n\n /* Go backwards over all attributes; safely remove bad ones */\n while (l--) {\n const attr = attributes[l];\n const { name, namespaceURI, value: attrValue } = attr;\n const lcName = transformCaseFunc(name);\n\n let value = name === 'value' ? attrValue : stringTrim(attrValue);\n\n /* Execute a hook if present */\n hookEvent.attrName = lcName;\n hookEvent.attrValue = value;\n hookEvent.keepAttr = true;\n hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set\n _executeHook('uponSanitizeAttribute', currentNode, hookEvent);\n value = hookEvent.attrValue;\n\n /* Work around a security issue with comments inside attributes */\n if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\\/(style|title)/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Did the hooks approve of the attribute? */\n if (hookEvent.forceKeepAttr) {\n continue;\n }\n\n /* Remove attribute */\n _removeAttribute(name, currentNode);\n\n /* Did the hooks approve of the attribute? */\n if (!hookEvent.keepAttr) {\n continue;\n }\n\n /* Work around a security issue in jQuery 3.0 */\n if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\\/>/i, value)) {\n _removeAttribute(name, currentNode);\n continue;\n }\n\n /* Sanitize attribute content to be template-safe */\n if (SAFE_FOR_TEMPLATES) {\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], (expr) => {\n value = stringReplace(value, expr, ' ');\n });\n }\n\n /* Is `value` valid for this attribute? */\n const lcTag = transformCaseFunc(currentNode.nodeName);\n if (!_isValidAttribute(lcTag, lcName, value)) {\n continue;\n }\n\n /* Full DOM Clobbering protection via namespace isolation,\n * Prefix id and name attributes with `user-content-`\n */\n if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {\n // Remove the attribute with this value\n _removeAttribute(name, currentNode);\n\n // Prefix the value and later re-create the attribute with the sanitized value\n value = SANITIZE_NAMED_PROPS_PREFIX + value;\n }\n\n /* Handle attributes that require Trusted Types */\n if (\n trustedTypesPolicy &&\n typeof trustedTypes === 'object' &&\n typeof trustedTypes.getAttributeType === 'function'\n ) {\n if (namespaceURI) {\n /* Namespaces are not yet supported, see https://bugs.chromium.org/p/chromium/issues/detail?id=1305293 */\n } else {\n switch (trustedTypes.getAttributeType(lcTag, lcName)) {\n case 'TrustedHTML': {\n value = trustedTypesPolicy.createHTML(value);\n break;\n }\n\n case 'TrustedScriptURL': {\n value = trustedTypesPolicy.createScriptURL(value);\n break;\n }\n\n default: {\n break;\n }\n }\n }\n }\n\n /* Handle invalid data-* attribute set by try-catching it */\n try {\n if (namespaceURI) {\n currentNode.setAttributeNS(namespaceURI, name, value);\n } else {\n /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. \"x-schema\". */\n currentNode.setAttribute(name, value);\n }\n\n if (_isClobbered(currentNode)) {\n _forceRemove(currentNode);\n } else {\n arrayPop(DOMPurify.removed);\n }\n } catch (_) {}\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeAttributes', currentNode, null);\n };\n\n /**\n * _sanitizeShadowDOM\n *\n * @param {DocumentFragment} fragment to iterate over recursively\n */\n const _sanitizeShadowDOM = function (fragment) {\n let shadowNode = null;\n const shadowIterator = _createNodeIterator(fragment);\n\n /* Execute a hook if present */\n _executeHook('beforeSanitizeShadowDOM', fragment, null);\n\n while ((shadowNode = shadowIterator.nextNode())) {\n /* Execute a hook if present */\n _executeHook('uponSanitizeShadowNode', shadowNode, null);\n\n /* Sanitize tags and elements */\n if (_sanitizeElements(shadowNode)) {\n continue;\n }\n\n /* Deep shadow DOM detected */\n if (shadowNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(shadowNode.content);\n }\n\n /* Check attributes, sanitize if necessary */\n _sanitizeAttributes(shadowNode);\n }\n\n /* Execute a hook if present */\n _executeHook('afterSanitizeShadowDOM', fragment, null);\n };\n\n /**\n * Sanitize\n * Public method providing core sanitation functionality\n *\n * @param {String|Node} dirty string or DOM node\n * @param {Object} cfg object\n */\n // eslint-disable-next-line complexity\n DOMPurify.sanitize = function (dirty, cfg = {}) {\n let body = null;\n let importedNode = null;\n let currentNode = null;\n let returnNode = null;\n /* Make sure we have a string to sanitize.\n DO NOT return early, as this will return the wrong type if\n the user has requested a DOM object rather than a string */\n IS_EMPTY_INPUT = !dirty;\n if (IS_EMPTY_INPUT) {\n dirty = '<!-->';\n }\n\n /* Stringify, in case dirty is an object */\n if (typeof dirty !== 'string' && !_isNode(dirty)) {\n if (typeof dirty.toString === 'function') {\n dirty = dirty.toString();\n if (typeof dirty !== 'string') {\n throw typeErrorCreate('dirty is not a string, aborting');\n }\n } else {\n throw typeErrorCreate('toString is not a function');\n }\n }\n\n /* Return dirty HTML if DOMPurify cannot run */\n if (!DOMPurify.isSupported) {\n return dirty;\n }\n\n /* Assign config vars */\n if (!SET_CONFIG) {\n _parseConfig(cfg);\n }\n\n /* Clean up removed elements */\n DOMPurify.removed = [];\n\n /* Check if dirty is correctly typed for IN_PLACE */\n if (typeof dirty === 'string') {\n IN_PLACE = false;\n }\n\n if (IN_PLACE) {\n /* Do some early pre-sanitization to avoid unsafe root nodes */\n if (dirty.nodeName) {\n const tagName = transformCaseFunc(dirty.nodeName);\n if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {\n throw typeErrorCreate(\n 'root node is forbidden and cannot be sanitized in-place'\n );\n }\n }\n } else if (dirty instanceof Node) {\n /* If dirty is a DOM element, append to an empty document to avoid\n elements being stripped by the parser */\n body = _initDocument('<!---->');\n importedNode = body.ownerDocument.importNode(dirty, true);\n if (\n importedNode.nodeType === NODE_TYPE.element &&\n importedNode.nodeName === 'BODY'\n ) {\n /* Node is already a body, use as is */\n body = importedNode;\n } else if (importedNode.nodeName === 'HTML') {\n body = importedNode;\n } else {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n body.appendChild(importedNode);\n }\n } else {\n /* Exit directly if we have nothing to do */\n if (\n !RETURN_DOM &&\n !SAFE_FOR_TEMPLATES &&\n !WHOLE_DOCUMENT &&\n // eslint-disable-next-line unicorn/prefer-includes\n dirty.indexOf('<') === -1\n ) {\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE\n ? trustedTypesPolicy.createHTML(dirty)\n : dirty;\n }\n\n /* Initialize the document to work on */\n body = _initDocument(dirty);\n\n /* Check we have a DOM node from the data */\n if (!body) {\n return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';\n }\n }\n\n /* Remove first element node (ours) if FORCE_BODY is set */\n if (body && FORCE_BODY) {\n _forceRemove(body.firstChild);\n }\n\n /* Get node iterator */\n const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body);\n\n /* Now start iterating over the created document */\n while ((currentNode = nodeIterator.nextNode())) {\n /* Sanitize tags and elements */\n if (_sanitizeElements(currentNode)) {\n continue;\n }\n\n /* Shadow DOM detected, sanitize it */\n if (currentNode.content instanceof DocumentFragment) {\n _sanitizeShadowDOM(currentNode.content);\n }\n\n /* Check attributes, sanitize if necessary */\n _sanitizeAttributes(currentNode);\n }\n\n /* If we sanitized `dirty` in-place, return it. */\n if (IN_PLACE) {\n return dirty;\n }\n\n /* Return sanitized string or DOM */\n if (RETURN_DOM) {\n if (RETURN_DOM_FRAGMENT) {\n returnNode = createDocumentFragment.call(body.ownerDocument);\n\n while (body.firstChild) {\n // eslint-disable-next-line unicorn/prefer-dom-node-append\n returnNode.appendChild(body.firstChild);\n }\n } else {\n returnNode = body;\n }\n\n if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {\n /*\n AdoptNode() is not used because internal state is not reset\n (e.g. the past names map of a HTMLFormElement), this is safe\n in theory but we would rather not risk another attack vector.\n The state that is cloned by importNode() is explicitly defined\n by the specs.\n */\n returnNode = importNode.call(originalDocument, returnNode, true);\n }\n\n return returnNode;\n }\n\n let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;\n\n /* Serialize doctype if allowed */\n if (\n WHOLE_DOCUMENT &&\n ALLOWED_TAGS['!doctype'] &&\n body.ownerDocument &&\n body.ownerDocument.doctype &&\n body.ownerDocument.doctype.name &&\n regExpTest(EXPRESSIONS.DOCTYPE_NAME, body.ownerDocument.doctype.name)\n ) {\n serializedHTML =\n '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\\n' + serializedHTML;\n }\n\n /* Sanitize final string template-safe */\n if (SAFE_FOR_TEMPLATES) {\n arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], (expr) => {\n serializedHTML = stringReplace(serializedHTML, expr, ' ');\n });\n }\n\n return trustedTypesPolicy && RETURN_TRUSTED_TYPE\n ? trustedTypesPolicy.createHTML(serializedHTML)\n : serializedHTML;\n };\n\n /**\n * Public method to set the configuration once\n * setConfig\n *\n * @param {Object} cfg configuration object\n */\n DOMPurify.setConfig = function (cfg = {}) {\n _parseConfig(cfg);\n SET_CONFIG = true;\n };\n\n /**\n * Public method to remove the configuration\n * clearConfig\n *\n */\n DOMPurify.clearConfig = function () {\n CONFIG = null;\n SET_CONFIG = false;\n };\n\n /**\n * Public method to check if an attribute value is valid.\n * Uses last set config, if any. Otherwise, uses config defaults.\n * isValidAttribute\n *\n * @param {String} tag Tag name of containing element.\n * @param {String} attr Attribute name.\n * @param {String} value Attribute value.\n * @return {Boolean} Returns true if `value` is valid. Otherwise, returns false.\n */\n DOMPurify.isValidAttribute = function (tag, attr, value) {\n /* Initialize shared config vars if necessary. */\n if (!CONFIG) {\n _parseConfig({});\n }\n\n const lcTag = transformCaseFunc(tag);\n const lcName = transformCaseFunc(attr);\n return _isValidAttribute(lcTag, lcName, value);\n };\n\n /**\n * AddHook\n * Public method to add DOMPurify hooks\n *\n * @param {String} entryPoint entry point for the hook to add\n * @param {Function} hookFunction function to execute\n */\n DOMPurify.addHook = function (entryPoint, hookFunction) {\n if (typeof hookFunction !== 'function') {\n return;\n }\n\n hooks[entryPoint] = hooks[entryPoint] || [];\n arrayPush(hooks[entryPoint], hookFunction);\n };\n\n /**\n * RemoveHook\n * Public method to remove a DOMPurify hook at a given entryPoint\n * (pops it from the stack of hooks if more are present)\n *\n * @param {String} entryPoint entry point for the hook to remove\n * @return {Function} removed(popped) hook\n */\n DOMPurify.removeHook = function (entryPoint) {\n if (hooks[entryPoint]) {\n return arrayPop(hooks[entryPoint]);\n }\n };\n\n /**\n * RemoveHooks\n * Public method to remove all DOMPurify hooks at a given entryPoint\n *\n * @param {String} entryPoint entry point for the hooks to remove\n */\n DOMPurify.removeHooks = function (entryPoint) {\n if (hooks[entryPoint]) {\n hooks[entryPoint] = [];\n }\n };\n\n /**\n * RemoveAllHooks\n * Public method to remove all DOMPurify hooks\n */\n DOMPurify.removeAllHooks = function () {\n hooks = {};\n };\n\n return DOMPurify;\n}\n\nexport default createDOMPurify();\n"],"names":["entries","setPrototypeOf","isFrozen","getPrototypeOf","getOwnPropertyDescriptor","Object","freeze","seal","create","apply","construct","Reflect","x","fun","thisValue","args","Func","arrayForEach","unapply","Array","prototype","forEach","arrayPop","pop","arrayPush","push","stringToLowerCase","String","toLowerCase","stringToString","toString","stringMatch","match","stringReplace","replace","stringIndexOf","indexOf","stringTrim","trim","objectHasOwnProperty","hasOwnProperty","regExpTest","RegExp","test","typeErrorCreate","func","TypeError","_len2","arguments","length","_key2","thisArg","_len","_key","addToSet","set","array","transformCaseFunc","undefined","l","element","lcElement","cleanArray","index","clone","object","newObject","property","value","isArray","constructor","lookupGetter","prop","desc","get","html","svg","svgFilters","svgDisallowed","mathMl","mathMlDisallowed","text","xml","MUSTACHE_EXPR","ERB_EXPR","TMPLIT_EXPR","DATA_ATTR","ARIA_ATTR","IS_ALLOWED_URI","IS_SCRIPT_OR_DATA","ATTR_WHITESPACE","DOCTYPE_NAME","CUSTOM_ELEMENT","NODE_TYPE","getGlobal","window","purify","createDOMPurify","DOMPurify","root","version","VERSION","removed","document","nodeType","isSupported","originalDocument","currentScript","DocumentFragment","HTMLTemplateElement","Node","Element","NodeFilter","NamedNodeMap","MozNamedAttrMap","HTMLFormElement","DOMParser","trustedTypes","ElementPrototype","cloneNode","remove","getNextSibling","getChildNodes","getParentNode","template","createElement","content","ownerDocument","trustedTypesPolicy","emptyHTML","implementation","createNodeIterator","createDocumentFragment","getElementsByTagName","importNode","hooks","createHTMLDocument","EXPRESSIONS","ALLOWED_TAGS","DEFAULT_ALLOWED_TAGS","TAGS","ALLOWED_ATTR","DEFAULT_ALLOWED_ATTR","ATTRS","CUSTOM_ELEMENT_HANDLING","tagNameCheck","writable","configurable","enumerable","attributeNameCheck","allowCustomizedBuiltInElements","FORBID_TAGS","FORBID_ATTR","ALLOW_ARIA_ATTR","ALLOW_DATA_ATTR","ALLOW_UNKNOWN_PROTOCOLS","ALLOW_SELF_CLOSE_IN_ATTR","SAFE_FOR_TEMPLATES","SAFE_FOR_XML","WHOLE_DOCUMENT","SET_CONFIG","FORCE_BODY","RETURN_DOM","RETURN_DOM_FRAGMENT","RETURN_TRUSTED_TYPE","SANITIZE_DOM","SANITIZE_NAMED_PROPS","KEEP_CONTENT","IN_PLACE","USE_PROFILES","FORBID_CONTENTS","DEFAULT_FORBID_CONTENTS","DATA_URI_TAGS","DEFAULT_DATA_URI_TAGS","URI_SAFE_ATTRIBUTES","DEFAULT_URI_SAFE_ATTRIBUTES","MATHML_NAMESPACE","SVG_NAMESPACE","HTML_NAMESPACE","NAMESPACE","IS_EMPTY_INPUT","ALLOWED_NAMESPACES","DEFAULT_ALLOWED_NAMESPACES","PARSER_MEDIA_TYPE","SUPPORTED_PARSER_MEDIA_TYPES","CONFIG","formElement","isRegexOrFunction","testValue","Function","_parseConfig","cfg","ADD_URI_SAFE_ATTR","ADD_DATA_URI_TAGS","ALLOWED_URI_REGEXP","ADD_TAGS","ADD_ATTR","table","tbody","TRUSTED_TYPES_POLICY","createHTML","createScriptURL","purifyHostElement","createPolicy","suffix","ATTR_NAME","hasAttribute","getAttribute","policyName","scriptUrl","_","console","warn","_createTrustedTypesPolicy","MATHML_TEXT_INTEGRATION_POINTS","HTML_INTEGRATION_POINTS","COMMON_SVG_AND_HTML_ELEMENTS","ALL_SVG_TAGS","ALL_MATHML_TAGS","_forceRemove","node","removeChild","_removeAttribute","name","attribute","getAttributeNode","from","removeAttribute","setAttribute","_initDocument","dirty","doc","leadingWhitespace","matches","dirtyPayload","parseFromString","documentElement","createDocument","innerHTML","body","insertBefore","createTextNode","childNodes","call","_createNodeIterator","SHOW_ELEMENT","SHOW_COMMENT","SHOW_TEXT","SHOW_PROCESSING_INSTRUCTION","SHOW_CDATA_SECTION","_isClobbered","elm","nodeName","textContent","attributes","namespaceURI","hasChildNodes","_isNode","_executeHook","entryPoint","currentNode","data","hook","_sanitizeElements","tagName","allowedTags","firstElementChild","_isBasicCustomElement","parentNode","i","childClone","__removalCount","parent","parentTagName","Boolean","_checkValidNamespace","expr","_isValidAttribute","lcTag","lcName","_sanitizeAttributes","hookEvent","attrName","attrValue","keepAttr","allowedAttributes","attr","forceKeepAttr","getAttributeType","setAttributeNS","_sanitizeShadowDOM","fragment","shadowNode","shadowIterator","nextNode","sanitize","importedNode","returnNode","appendChild","firstChild","nodeIterator","shadowroot","shadowrootmode","serializedHTML","outerHTML","doctype","setConfig","clearConfig","isValidAttribute","tag","addHook","hookFunction","removeHook","removeHooks","removeAllHooks"],"mappings":"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ACA,QACA,SACA,KACA,OACA,MACA,OACA,UACA,OACA,WACA,QACA,MACA,OACA,KACA,WACA,SACA,SACA,IACA,UACA,MACA,WACA,IACA,KACA,KACA,OACA,IACA,OACA,UACA,SACA,SACA,QACA,SACA,SACA,OACA,SACA,SACA,QACA,MACA,UACA,MACA,QACA,QACA,KACA,WACA,WACA,QACA,KACA,QACA,OACA,KACA,QACA,KACA,IACA,KACA,MACA,QACA,QAIWsE,EAAMtE,EAAO,CACxB,MACA,IACA,WACA,cACA,eACA,eACA,gBACA,mBACA,SACA,WACA,OACA,OACA,UACA,SACA,OACA,IACA,QACA,WACA,QACA,QACA,OACA,iBACA,SACA,OACA,WACA,QACA,OACA,UACA,UACA,WACA,iBACA,OACA,OACA,QACA,SACA,SACA,OACA,WACA,QACA,OACA,QACA,OACA,UAGWuE,EAAavE,EAAO,CAC/B,UACA,gBACA,sBACA,cACA,mBACA,oBACA,oBACA,iBACA,eACA,UACA,UACA,UACA,UACA,UACA,iBACA,UACA,UACA,cACA,eACA,WACA,eACA,qBACA,cACA,SACA,iBAOWwE,EAAgBxE,EAAO,CAClC,UACA,gBACA,SACA,UACA,YACA,mBACA,iBACA,gBACA,gBACA,gBACA,QACA,YACA,OACA,eACA,YACA,UACA,gBACA,SACA,MACA,aACA,UACA,QAGWyE,EAASzE,EAAO,CAC3B,OACA,WACA,SACA,UACA,QACA,SACA,KACA,aACA,gBACA,KACA,KACA,QACA,UACA,WACA,QACA,OACA,KACA,SACA,QACA,SACA,OACA,OACA,UACA,SACA,MACA,QACA,MACA,SACA,aACA,gBAKW0E,EAAmB1E,EAAO,CACrC,UACA,cACA,aACA,WACA,YACA,UACA,UACA,SACA,SACA,QACA,YACA,aACA,iBACA,cACA,SAGW2E,EAAO3E,EAAO,CAAC,UCrRfqE,EAAOrE,EAAO,CACzB,SACA,SACA,QACA,MACA,iBACA,eACA,uBACA,WACA,aACA,UACA,SACA,UACA,cACA,cACA,UACA,OACA,QACA,QACA,QACA,OACA,UACA,WACA,eACA,SACA,cACA,WACA,WACA,UACA,MACA,WACA,0BACA,wBACA,WACA,YACA,UACA,eACA,OACA,MACA,UACA,SACA,SACA,OACA,OACA,WACA,KACA,YACA,YACA,QACA,OACA,QACA,OACA,OACA,UACA,OACA,MACA,MACA,YACA,QACA,SACA,MACA,YACA,WACA,QACA,OACA,QACA,UACA,aACA,SACA,OACA,UACA,UACA,cACA,cACA,UACA,gBACA,sBACA,SACA,UACA,UACA,aACA,WACA,MACA,WACA,MACA,WACA,OACA,OACA,UACA,aACA,QACA,WACA,QACA,OACA,QACA,OACA,UACA,QACA,MACA,SACA,OACA,QACA,UACA,WACA,QACA,YACA,OACA,SACA,SACA,QACA,QACA,OACA,QACA,SAGWsE,EAAMtE,EAAO,CACxB,gBACA,aACA,WACA,qBACA,SACA,gBACA,gBACA,UACA,gBACA,iBACA,QACA,OACA,KACA,QACA,OACA,gBACA,YACA,YACA,QACA,sBACA,8BACA,gBACA,kBACA,KACA,KACA,IACA,KACA,KACA,kBACA,YACA,UACA,UACA,MACA,WACA,YACA,MACA,OACA,eACA,YACA,SACA,cACA,cACA,gBACA,cACA,YACA,mBACA,eACA,aACA,eACA,cACA,KACA,KACA,KACA,KACA,aACA,WACA,gBACA,oBACA,SACA,OACA,KACA,kBACA,KACA,MACA,IACA,KACA,KACA,KACA,KACA,UACA,YACA,aACA,WACA,OACA,eACA,iBACA,eACA,mBACA,iBACA,QACA,aACA,aACA,eACA,eACA,cACA,cACA,mBACA,YACA,MACA,OACA,QACA,SACA,OACA,MACA,OACA,aACA,SACA,WACA,UACA,QACA,SACA,cACA,SACA,WACA,cACA,OACA,aACA,sBACA,mBACA,eACA,SACA,gBACA,sBACA,iBACA,IACA,KACA,KACA,SACA,OACA,OACA,cACA,YACA,UACA,SACA,SACA,QACA,OACA,kBACA,mBACA,mBACA,eACA,cACA,eACA,cACA,aACA,eACA,mBACA,oBACA,iBACA,kBACA,oBACA,iBACA,SACA,eACA,QACA,eACA,iBACA,WACA,UACA,UACA,YACA,mBACA,cACA,kBACA,iBACA,aACA,OACA,KACA,KACA,UACA,SACA,UACA,aACA,UACA,aACA,gBACA,gBACA,QACA,eACA,OACA,eACA,mBACA,mBACA,IACA,KACA,KACA,QACA,IACA,KACA,KACA,IACA,eAGWyE,EAASzE,EAAO,CAC3B,SACA,cACA,QACA,WACA,QACA,eACA,cACA,aACA,aACA,QACA,MACA,UACA,eACA,WACA,QACA,QACA,SACA,OACA,KACA,UACA,SACA,gBACA,SACA,SACA,iBACA,YACA,WACA,cACA,UACA,UACA,gBACA,WACA,WACA,OACA,WACA,WACA,aACA,UACA,SACA,SACA,cACA,gBACA,uBACA,YACA,YACA,aACA,WACA,iBACA,iBACA,YACA,UACA,QACA,UAGW4E,EAAM5E,EAAO,CACxB,aACA,SACA,cACA,YACA,gBCzWW6E,EAAgB5E,EAAK,6BACrB6E,EAAW7E,EAAK,yBAChB8E,EAAc9E,EAAK,iBACnB+E,EAAY/E,EAAK,8BACjBgF,EAAYhF,EAAK,kBACjBiF,EAAiBjF,EAC5B,6FAEWkF,EAAoBlF,EAAK,yBACzBmF,EAAkBnF,EAC7B,+DAEWoF,EAAepF,EAAK,WACpBqF,EAAiBrF,EAAK,0NCSnC,MAAMsF,EACK,EADLA,EAGE,EAHFA,EAOoB,EAPpBA,EAQK,EARLA,GASM,EAMNC,GAAY,WAChB,MAAyB,oBAAXC,OAAyB,KAAOA,MAChD,EAonDA,IAAAC,GAnkDA,SAASC,IAAsC,IAAtBF,EAAM/C,UAAAC,OAAAD,QAAAU,IAAAV,UAAAU,GAAAV,UAAG8C,GAAAA,KAChC,MAAMI,EAAaC,GAASF,EAAgBE,GAc5C,GARAD,EAAUE,QAAUC,QAMpBH,EAAUI,QAAU,IAGjBP,IACAA,EAAOQ,UACRR,EAAOQ,SAASC,WAAaX,GAM7B,OAFAK,EAAUO,aAAc,EAEjBP,EAGT,IAAIK,SAAEA,GAAaR,EAEn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"}
\ No newline at end of file
views/default.handlebars
+7 -4
@@ -47,6 +47,8 @@
47 <script keeplink=1 type="text/javascript" src="scripts/filesaver.min.js"></script>
48 <script keeplink=1 type="text/javascript" src="scripts/ol{{{min}}}.js"></script>
49 <script keeplink=1 type="text/javascript" src="scripts/ol3-contextmenu{{{min}}}.js"></script>
50 + <script keeplink=1 type="text/javascript" src="scripts/purify{{{min}}}.js"></script>
51 + <script keeplink=1 type="text/javascript" src="scripts/marked{{{min}}}.js"></script>
52 <title>{{{title}}}</title>
53 </head>
54 <body id="body" oncontextmenu="handleContextMenu(event)" style="display:none;min-width:495px" onload="if (typeof(startup) !== 'undefined') startup();">
@@ -630,7 +632,7 @@
632 </thead>
633 <tbody>
634 <tr>
633 - <td><textarea id=notesPanelArea readonly style=width:300px;height:200px;resize:none;overflow-y:scroll></textarea></td>
635 + <td><div id=notesPanelArea style=width:300px;height:200px;resize:none;overflow-y:scroll></div></td>
636 </tr>
637 </tbody>
638 </table>
@@ -2970,7 +2972,7 @@
2972 focusTextBox('d2devNotes');
2973 }
2974 }else{
2973 - if (message.notes) { QH('notesPanelArea', decodeURIComponent(message.notes)); } else { QH('notesPanelArea', ''); }
2975 + Q('notesPanelArea').innerHTML = (message.notes && marked && DOMPurify) ? DOMPurify.sanitize(marked.parse(decodeURIComponent(message.notes), { breaks: true }), { USE_PROFILES: { html: true } }) : '';
2976 if (showNotesPanel && message.notes) { QV('notesPanel',true); }else{ QV('notesPanel', false); }
2977 }
2978 break;
@@ -8153,13 +8155,14 @@
8155 if (xxdialogMode) return;
8156 if (noteid == null) { noteid = encodeURIComponentEx('p'+userinfo._id); }
8157 var x = '<textarea id=d2devNotes ro=' + readonly + ' noteid=' + noteid + ' readonly style=background-color:#fcf3cf;width:100%;height:200px;resize:none;overflow-y:scroll></textarea>';
8156 - if (noteid.startsWith('node%2F%2F')) { x += '<span style=font-size:10px>' + "Device group notes can be viewed and changed by other device group administrators." + '<span>'; }
8158 + if (noteid.startsWith('node%2F%2F')) { x += ' <span style=font-size:10px>' + "Device group notes can be viewed and changed by other device group administrators." + '</span>'; }
8159 + if (showNotesPanel) { x += ' <span style=font-size:10px><a target=_blank href=\'https://www.markdownguide.org/cheat-sheet/\'>' + "Markdown syntax supported" + '</a></span>'; }
8160 setDialogMode(2, "Notes", 3, showNotesEx, x, noteid);
8161 meshserver.send({ action: 'getNotes', id: decodeURIComponent(noteid) });
8162 }
8163
8164 function showNotesEx(buttons, tag) {
8162 - QH('notesPanelArea', Q('d2devNotes').value);
8165 + Q('notesPanelArea').innerHTML = (marked && DOMPurify) ? DOMPurify.sanitize(marked.parse(Q('d2devNotes').value, { breaks: true }), { USE_PROFILES: { html: true } }) : Q('d2devNotes').value;
8166 meshserver.send({ action: 'setNotes', id: decodeURIComponent(tag), notes: encodeURIComponentEx(Q('d2devNotes').value) });
8167 if (showNotesPanel && Q('d2devNotes').value != '') { QV('notesPanel',true); }else{ QV('notesPanel', false); }
8168 }