{"version":3,"file":"static/js/926.eb288b1d.chunk.js","mappings":";iGAeA,IAAIA,EAAkB,UAOtBC,EAAOC,QAUP,SAAoBC,GAClB,IAOIC,EAPAC,EAAM,GAAKF,EACXG,EAAQN,EAAgBO,KAAKF,GAEjC,IAAKC,EACH,OAAOD,EAIT,IAAIG,EAAO,GACPC,EAAQ,EACRC,EAAY,EAEhB,IAAKD,EAAQH,EAAMG,MAAOA,EAAQJ,EAAIM,OAAQF,IAAS,CACrD,OAAQJ,EAAIO,WAAWH,IACrB,KAAK,GACHL,EAAS,SACT,MACF,KAAK,GACHA,EAAS,QACT,MACF,KAAK,GACHA,EAAS,QACT,MACF,KAAK,GACHA,EAAS,OACT,MACF,KAAK,GACHA,EAAS,OACT,MACF,QACE,SAGAM,IAAcD,IAChBD,GAAQH,EAAIQ,UAAUH,EAAWD,IAGnCC,EAAYD,EAAQ,EACpBD,GAAQJ,CACV,CAEA,OAAOM,IAAcD,EACjBD,EAAOH,EAAIQ,UAAUH,EAAWD,GAChCD,CACN,wDC/DMM,EAAkD,CACvDC,EAAG,CACFC,QAASC,EACTC,MAAM,EACNC,KAAMF,KAEPG,QAAS,CACRC,QAAS,CACR,KACA,KACA,KACA,KACA,KACA,KACA,UACA,UACA,QACA,UACA,MACA,SACA,UAEDH,MAAM,GAEPI,MAAO,CACNC,SAAU,CAAC,QAAS,WAErBC,GAAI,CACHL,KAAMF,EACNQ,MAAM,GAEPC,KAAM,CACLV,QACCC,KAQFU,OAAQ,CACPX,QAhD2B,EAiD3BG,KAAMF,KAEPW,QAAS,CACRZ,QAvDuB,EAwDvBa,OAAQ,CAAC,UAEVC,IAAK,CACJD,OAAQ,CAAC,YACTJ,MAAM,GAEPM,SAAU,CACTR,SAAU,CAAC,OACXM,OAAQ,CAAC,UAEVG,QAAS,CACRT,SAAU,CAAC,WACXJ,KAAMF,IAEPgB,GAAI,CACHjB,QAvEuB,EAwEvBa,OAAQ,CAAC,OAEVK,GAAI,CACHX,SAAU,CAAC,KAAM,MACjBJ,KA5EuB,GA8ExBgB,GAAI,CACHnB,QA/EuB,EAgFvBK,QAAS,CAAC,SAAU,UACpBQ,OAAQ,CAAC,OAEVO,WAAY,CACXpB,QApFuB,EAqFvBa,OAAQ,CAAC,WAEVQ,OAAQ,CACPhB,QAAS,CAAC,SAAU,WAErBiB,OAAQ,CACPjB,QAAS,CAAC,SAAU,WAErBkB,GAAI,CACHpB,KA9FuB,EA+FvBM,MAAM,GAEPe,IAAK,CACJf,MAAM,GAEPgB,GAAI,CACHzB,QArGuB,EAsGvBa,OAAQ,CAAC,KAAM,KAAM,SAEtBa,KAAM,CACLxB,MAAM,GAEPyB,GAAI,CACHpB,SAAU,CAAC,MACXJ,KA7GuB,GA+GxByB,QAAS,CACRrB,SAAU,CAAC,SAAU,OACrBJ,KAAMF,IAEP4B,GAAI,CACHhB,OAAQ,CAAC,OAAQ,QAElBiB,GAAI,CACHjB,OAAQ,CAAC,OAAQ,QAElBkB,GAAI,CACH/B,QAvH2B,EAwH3Ba,OAAQ,CAAC,OAAQ,QAElBmB,IAAK,CACJhC,QA3H2B,EA4H3Ba,OAAQ,CAAC,SAEVoB,KAAM,CACL1B,SAAU,CAAC,KAAM,KAAM,KAAM,QAE9B2B,OAAQ,CACPrB,OAAQ,CAAC,QAAS,QAAS,WAC3BJ,MAAM,GAEP0B,QAAS,CACRnC,QAtI2B,EAuI3Ba,OAAQ,CAAC,YAEVuB,MAAO,CACN7B,SAAU,CAAC,UAAW,WAAY,QAAS,QAAS,QAAS,MAC7DJ,KA9IuB,GAgJxBkC,MAAO,CACNxB,OAAQ,CAAC,SACTN,SAAU,CAAC,OAEZ+B,GAAI,CACHtC,QArJuB,EAsJvBa,OAAQ,CAAC,OAEV0B,MAAO,CACN1B,OAAQ,CAAC,SACTN,SAAU,CAAC,OAEZiC,GAAI,CACHxC,QA7JuB,EA8JvBa,OAAQ,CAAC,OAEV4B,MAAO,CACN5B,OAAQ,CAAC,SACTN,SAAU,CAAC,OAEZmC,GAAI,CACH7B,OAAQ,CAAC,QAAS,QAAS,QAAS,SACpCN,SAAU,CAAC,KAAM,OAElBoC,MAAO,CACN9B,OAAQ,CAAC,QAAS,SAClBJ,MAAM,GAEPmC,GAAI,CACHrC,SAAU,CAAC,MACXJ,KA9KuB,GAgLxB0C,MAAO,CACNtC,SAAU,CAAC,QAAS,WAErBuC,IAAK,CACJ3C,KAAMF,EACNQ,MAAM,IAIR,SAASsC,EAAoBC,GAC5B,OAAQC,IACPnD,EAAWmD,GAAW,IAClBD,KACAlD,EAAWmD,GAFf,CAKD,CAED,CAAC,UAAW,OAAQ,MAAO,SAAU,IAAK,OAAOC,QAChDH,EAAoB,CACnB/C,QApMuB,EAqMvBG,KAAMF,MAIR,CACC,OACA,IACA,MACA,MACA,OACA,OACA,OACA,MACA,KACA,IACA,MACA,OACA,IACA,OACA,OACA,SACA,MACA,MACA,OACA,IACA,OACCiD,QACDH,EAAoB,CACnB/C,QA9N2B,EA+N3BG,KAAMF,MAIR,CAAC,IAAK,OAAOiD,QACZH,EAAoB,CACnB/C,QArO2B,EAsO3BG,KAAMF,MAIR,CAAC,IAAK,QAAS,OAAQ,MAAO,OAAOiD,QACpCH,EAAoB,CACnB/C,QA5O2B,EA6O3BG,KAAMF,KAIR,CAAC,UAAW,QAAS,SAAU,SAAU,MAAO,UAAW,cAAciD,QACxEH,EAAoB,CACnB/C,QAtPuB,EAuPvBG,KAAMF,MAIR,CAAC,KAAM,KAAM,KAAM,KAAM,KAAM,MAAMiD,QACpCH,EAAoB,CACnB/C,QA1P2B,EA2P3BG,KAAMF,MAIR,CAAC,QAAS,SAAU,SAAU,MAAO,SAASiD,QAC7CH,EAAoB,CACnB5C,KAAMF,YAKKkD,EAAkBC,OAAOC,OAAOvD,GAGhCwD,EAAkB,CAC9B,SACA,OACA,OACA,UACA,QACA,QACA,WACA,OACA,OACA,OACA,OACA,WACA,SACA,SACA,QACA,SAGYC,EAAmBH,OAAOI,KAAKL,GAAMM,QAChDC,GAAgB,WAARA,GAA4B,WAARA,IAYjBC,EAAwBP,OAAOC,OAAO,CAClDO,IAT2B,EAU3BC,KAV2B,EAW3BC,MAX2B,EAY3BC,QAViC,EAWjCC,SAV+B,EAW/BC,SAd2B,EAe3BC,QAZ+B,EAa/BC,SAb+B,EAc/BC,IAjB2B,EAkB3BC,OAlB2B,EAmB3BC,KAnB2B,EAoB3BC,GApB2B,EAqB3BC,KArB2B,EAsB3BC,MAtB2B,EAuB3BC,KAvB2B,EAwB3BC,QAxB2B,EAyB3BC,KAtB+B,EAuB/BC,MA1B2B,EA2B3BC,MAxB+B,EAyB/BC,OA5B2B,EA6B3BC,IA7B2B,EA8B3BC,KA9B2B,EA+B3BC,QA7BiC,EA8BjCC,MAhC2B,EAiC3BC,MAjC2B,EAkC3BC,KAhCiC,EAiCjCC,MAjCiC,EAkCjCC,MAhC6B,EAiC7BC,IArC2B,EAsC3BC,QAtC2B,EAuC3BC,OAvC2B,EAwC3BC,OAxC2B,EAyC3BC,MAzC2B,EA0C3BzF,KA1C2B,EA2C3B0F,MA3C2B,IA+CfC,EAA8C1C,OAAOC,OAAO,CACxES,MAAO,YACPC,QAAS,UACTE,SAAU,WACViB,QAAS,UACTO,QAAS,UACTC,OAAQ,2NC3VF,SAASK,EAAT,GAMU,IANO,WACvBC,EAAa,CAAC,EADS,UAEvBC,EAFuB,SAGvB1F,EAAW,KAHY,UAIvB2F,GAAY,EAJW,QAKvBjD,GALM,EAON,MAAMkD,EAAMlD,EAEZ,OAAOiD,EACNE,EAAAA,cAACD,EAAD,GAAKF,UAAWA,GAAeD,IAE/BI,EAAAA,cAACD,EAAD,GAAKF,UAAWA,GAAeD,GAC7BzF,EAGH,CCjBM,MAAM8F,EAIZC,UACCC,EACAC,GAGA,OAAOA,CACP,CAKDC,KAAKF,EAAcE,GAClB,OAAOA,CACP,oLCdK,MAAMC,UAAoBL,EACvBC,UACRC,EACAC,GAYA,MAVa,UAATD,GACHnD,OAAOI,KAAKgD,GAAOtD,SAASyD,IACvBC,OAAOJ,EAAMG,IAAMrH,MAAMuH,WAErBL,EAAMG,EACb,IAKIH,CACP,ECWF,MAEMM,EAAgB,uCAChBC,EAAa,2CAGlB,aAEC,wBAAOC,QAAP,8BAID,gEAGAC,MAAAA,EAEAC,YAAM,2LAENC,IAAAA,EAIAnH,EAAO,uBAIPoH,EAAQ,sBAIRC,EAAQ,uBAERC,EAAW,KAEVC,iBACAH,GAICI,EAAUC,KAAU,qCAIrBD,EAAgBJ,KAAAA,gBAAhB,GAEAI,EAAgB,KAAhB,kBAEAA,EAAe,qBAAcE,GAO/B,uDACCC,KAAAA,UAAAA,EAIC,eAAYC,KAAQC,gBAClB,GAAD,IAMD,6DAED,uBACD,iCACA,CAUEF,sBAAAA,EAAAA,GAED,mGACD,CAICG,iBAAc3I,EAAgB4I,GAE7B,OAAM,kFAAER,oBAUP,MAAKA,EAAkCS,CAAAA,GACtC,MACAT,gBAGD,EAAUU,EACT,OAgEHA,OA/DG,KAZiC,wHAiBlC,OACwB3I,IAAAA,KAAjB,oBAAwB4I,OAC9B,MAAkBF,GAGlB,KAAIvI,IAAW,gBACd0I,MAAAA,MACA1I,EAAAA,eAEDH,EAAI4I,MACHC,EAIA1H,KAAK4G,KAELe,GACAC,EACC9H,EAAUjB,EADW,mBAGrBiI,EAAO,IAENY,GAFMG,EAAAA,MAAAA,EAAAA,IAHRJ,GARDC,GAiBO,gFACNA,KAAAA,UAAe,EA3B+CC,GAAAA,EA+B/DC,EAAAA,GAAAA,sBACIL,MAAO,IAACO,KACXD,EACAH,IAAAA,KAAAA,YAIAA,GAAAA,EAKGH,EAAQO,QACZD,EAAgBH,EAAkBG,EAAlC,WACAH,EAAAA,IAGEC,EAAJE,EAAwB,sBAEvB,CAKF,WACDA,EAAAA,EAAAA,EACA,IACgBP,IAAfE,EACMF,0BAULE,eAAIF,EAAsBpI,GACzB,WAAOoI,UAAAS,EAA+BA,YAZmCT,EAAAA,OAAAA,EAAAA,SAAAA,OAAAA,mCA0BzE,qDAKD,kBAED,gCAID,gCAEUU,QAAF,uBAAUC,CAOhBC,kBAAc,gBAGdC,EAAAA,qBAGAA,KAAAA,MAGA,sDAED,SAID,8BAIE,uCAFAA,EAAaA,EACJC,QAAP,MAAkB,SACdC,EASNC,gBAAWzJ,GACV,MAEC,MAHFwJ,GAGE,4DAGD,aAKF,oEACD,uDAME,OAJF,aAEUE,EAAAA,UAAAA,KAAAA,kBAAAA,KAAAA,MAAAA,WAAAA,IAAAA,GAAAA,IAEJC,EAQHC,kBAAM,GAAE3C,MAAAA,gBAAMC,GAAR,KAAkB2C,MAClB,EAAU5C,CAAAA,EAChB,MAAM9C,EAGN,OAnRH,IAmRO,EAAC,UAAmB,6CAMxB,MACE2F,KAKD7C,EAAAA,MAlB2CC,uBAsBxC6C,EAA2BD,EAAO,IAAezF,EAAK2F,GAG1D,IAAI7F,KAAM8F,OAAKC,GACdH,OASA,0BJtCuB,IIsCvB,uKJpC4B,II8C7B,EACAA,GAAAA,EJhD+B,MIkDhCA,EAAOrD,OAAP,sBJhD4B,IIiD5B,IAEDqD,EAAAA,OAAAA,6DAOOI,KAGDzD,GAtDH,IAuDA0D,CAQJJ,sBAAAA,GACA,WAOGpJ,wCANFyJ,MAAAA,EAAa1G,EAA6B,SAC1B,kBACJuD,GADI,sBAEdxG,EAAS2G,EAFK,yDAGdtG,IAEIqJ,CACJzG,iBAQD,MAAIE,EAAKF,CACR1C,SACC,GACAP,QAAO,EACPiD,QAAAA,GAHMpC,OAAP,GAKAX,MAAAA,aAEDC,KAAOyJ,EACPnJ,MAAAA,eAKK,IAA6B,KAClC,KACIwC,WAKCqB,CACH,WAeF,2EAED,mFAKE,iCAFqC,oEAMtC,OAAO,CACP,iHAYA,CAODuF,QACC,YAAM,UAILC,KAJK,qFAKLC,CAQAF,UAAIpD,EAAAsB,GACH,MAAM,OACNU,EAAAA,qCAGAuB,EAAIC,UACHjK,EAAAA,uBACAiK,GACA,KARkC,oBA4HrC,qCA9GG,GApcL,IAocK,YACA,MAfkChH,EAAAA,EAAAA,SAAAA,qCAkB/B1C,cAEJ0J,EAAa,IAKZ1J,MAAAA,EAAW2J,KAAKL,iBAAoB7G,EAApC,SAIA,OAGA,MAC+E2D,GAAAA,KAAAA,GAAAA,KAAAA,aAAAA,IAAAA,CAAF,KAA5E,YAEA,6DAnCiC,mBA4ClC,0BAMD,YAlDmC3G,EAAAA,KAAAA,EAAAA,aAAAA,EAAAA,CAgDnC2G,SAQCuD,KAAK7C,SAAL,EADC,EAMApE,GAAAA,KAAAA,OAAAA,IAAAA,GADkC,OASlCkH,GAAAA,GAAYC,GAAZnH,OAAAA,IAAAA,KAAAA,aAAAA,KAAAA,IAAAA,KAAAA,eAAAA,EAAAA,GAqCAgH,EAAY,8CArCZhH,CACA,MAEDjD,KAAAA,UAAAA,EAGE,MACAO,EAAY2J,KAAKL,kBAAoB7G,GAKvC,GACAC,WAlFkC,oBAgG1B6E,EAAAA,2BAET9H,EAEO,6BACNiK,IAAAA,KAAU,UACV,0DA3hBCI,gBAmiBJ,MAAOrK,EAAP,oBACA,wCAGF,iBACAA,EAAAA,IAAAA,KAAAA,OAECsK,KAGE,aAIGC,EASFD,cAAM,EAAW,GACjB,IAPsC,2BAWtCE,MAAAA,EAAA,WAGAC,EAAOA,yBAGR,MAAM,OAAElK,EAAF,QAAYyH,EAAZ,gBAA6CK,EAOlDmC,EAAWxC,IAHZwC,EAMO,iCAKL,yBAEDE,EAEAF,MAAMG,GApCgC,WA6CvCF,GAAIG,EAvD6EF,EAAAA,EAAAA,yCA2D9ED,MAAK9K,EAAS8K,EAAG,0CA3D6D,EAiEjFC,EAAAA,EAAAA,MAAAA,EAAAA,GAAAA,OACAF,EAAAA,KAAAA,EAAAA,cAAAA,KAAAA,cAAAA,EAAAA,MAAAA,EAAAA,OAAAA,EAAAA,OAAAA,GAAAA,IAGAC,EAAAA,EAAAA,MAAAA,GCxoBF,mBDsCmBD,EAAAA,KAAAA,GCtCbA,IAAAA,EAAAA,OACLxE,GADK,IAILhG,EAJK,+BAKL6K,EALK,GAQCL,CARD,EAeLM,SAAAA,EAAW,GACX,IAFDC,mBAKC/E,EAAU,UACT8E,EAAAA,iBACAE,EAAAA,QACDhL,EAAAA,6BAEDiL,EAAKH,QACJA,EACAI,OAAAA,KAEGA,EAAQ,yDACX,oBACA,WAGDJ,EAAAA,MACU,CAAwB,QAAW7E,IAAAA,EAA5C,qCACE6E,EAAAA,OAFH,IAKAA,EAAAA,EC9CD,CAWEK,OAJD,IACCnF,EADK,GAILmF,EAJK/E,EAAAA,cAAAA,EAAAA,SAAAA,KAAAA,GASUA,EAAAA,cATV,GAULgF,WAAAA,EACAnI,UAAUgD,EACViF,QAASxH,GACT,EAbK,CAkBN,SAAM2H,EAAAA,oBAGNC,EAAYpI,UACX+C,EAAI+B,QACHuD,EAAAA,GAAAA,eACAJ,GAAAA,EAAAA,kCAEDN,EAAYW,KAAAA,QACXH,EAAAA,GAAAA,SACAjE,EAAAA,GAAAA,aAPFoE,EAtBkD,kCAiClDvI,EAAY,OAAGsI,OACdL,GAAMO,QAEN,EACC,EAAUhE,EAAU,KACpB,oBAED,0BAIKiE,EAAM,+DAMXL,EAAgBM,KAAMC,EAAQC,aAAY,QACzC,IAKD,QAAOA,EAAP,eATD,QAmBUX,OAAR,QAND,YAQC,EAASjI,IAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GAGX","sources":["../node_modules/escape-html/index.js","../node_modules/interweave/src/constants.ts","../node_modules/interweave/src/Element.tsx","../node_modules/interweave/src/Filter.ts","../node_modules/interweave/src/StyleFilter.ts","../node_modules/interweave/src/Parser.ts","../node_modules/interweave/src/Markup.tsx","../node_modules/interweave/src/Interweave.tsx"],"sourcesContent":["/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n","/* eslint-disable no-bitwise, no-magic-numbers, sort-keys */\n\nimport { ConfigMap, FilterMap, NodeConfig } from './types';\n\n// https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories\nexport const TYPE_FLOW = 1;\nexport const TYPE_SECTION = 1 << 1;\nexport const TYPE_HEADING = 1 << 2;\nexport const TYPE_PHRASING = 1 << 3;\nexport const TYPE_EMBEDDED = 1 << 4;\nexport const TYPE_INTERACTIVE = 1 << 5;\nexport const TYPE_PALPABLE = 1 << 6;\n\n// https://developer.mozilla.org/en-US/docs/Web/HTML/Element\nconst tagConfigs: Record> = {\n\ta: {\n\t\tcontent: TYPE_FLOW | TYPE_PHRASING,\n\t\tself: false,\n\t\ttype: TYPE_FLOW | TYPE_PHRASING | TYPE_INTERACTIVE | TYPE_PALPABLE,\n\t},\n\taddress: {\n\t\tinvalid: [\n\t\t\t'h1',\n\t\t\t'h2',\n\t\t\t'h3',\n\t\t\t'h4',\n\t\t\t'h5',\n\t\t\t'h6',\n\t\t\t'address',\n\t\t\t'article',\n\t\t\t'aside',\n\t\t\t'section',\n\t\t\t'div',\n\t\t\t'header',\n\t\t\t'footer',\n\t\t],\n\t\tself: false,\n\t},\n\taudio: {\n\t\tchildren: ['track', 'source'],\n\t},\n\tbr: {\n\t\ttype: TYPE_FLOW | TYPE_PHRASING,\n\t\tvoid: true,\n\t},\n\tbody: {\n\t\tcontent:\n\t\t\tTYPE_FLOW |\n\t\t\tTYPE_SECTION |\n\t\t\tTYPE_HEADING |\n\t\t\tTYPE_PHRASING |\n\t\t\tTYPE_EMBEDDED |\n\t\t\tTYPE_INTERACTIVE |\n\t\t\tTYPE_PALPABLE,\n\t},\n\tbutton: {\n\t\tcontent: TYPE_PHRASING,\n\t\ttype: TYPE_FLOW | TYPE_PHRASING | TYPE_INTERACTIVE | TYPE_PALPABLE,\n\t},\n\tcaption: {\n\t\tcontent: TYPE_FLOW,\n\t\tparent: ['table'],\n\t},\n\tcol: {\n\t\tparent: ['colgroup'],\n\t\tvoid: true,\n\t},\n\tcolgroup: {\n\t\tchildren: ['col'],\n\t\tparent: ['table'],\n\t},\n\tdetails: {\n\t\tchildren: ['summary'],\n\t\ttype: TYPE_FLOW | TYPE_INTERACTIVE | TYPE_PALPABLE,\n\t},\n\tdd: {\n\t\tcontent: TYPE_FLOW,\n\t\tparent: ['dl'],\n\t},\n\tdl: {\n\t\tchildren: ['dt', 'dd'],\n\t\ttype: TYPE_FLOW,\n\t},\n\tdt: {\n\t\tcontent: TYPE_FLOW,\n\t\tinvalid: ['footer', 'header'],\n\t\tparent: ['dl'],\n\t},\n\tfigcaption: {\n\t\tcontent: TYPE_FLOW,\n\t\tparent: ['figure'],\n\t},\n\tfooter: {\n\t\tinvalid: ['footer', 'header'],\n\t},\n\theader: {\n\t\tinvalid: ['footer', 'header'],\n\t},\n\thr: {\n\t\ttype: TYPE_FLOW,\n\t\tvoid: true,\n\t},\n\timg: {\n\t\tvoid: true,\n\t},\n\tli: {\n\t\tcontent: TYPE_FLOW,\n\t\tparent: ['ul', 'ol', 'menu'],\n\t},\n\tmain: {\n\t\tself: false,\n\t},\n\tol: {\n\t\tchildren: ['li'],\n\t\ttype: TYPE_FLOW,\n\t},\n\tpicture: {\n\t\tchildren: ['source', 'img'],\n\t\ttype: TYPE_FLOW | TYPE_PHRASING | TYPE_EMBEDDED,\n\t},\n\trb: {\n\t\tparent: ['ruby', 'rtc'],\n\t},\n\trp: {\n\t\tparent: ['ruby', 'rtc'],\n\t},\n\trt: {\n\t\tcontent: TYPE_PHRASING,\n\t\tparent: ['ruby', 'rtc'],\n\t},\n\trtc: {\n\t\tcontent: TYPE_PHRASING,\n\t\tparent: ['ruby'],\n\t},\n\truby: {\n\t\tchildren: ['rb', 'rp', 'rt', 'rtc'],\n\t},\n\tsource: {\n\t\tparent: ['audio', 'video', 'picture'],\n\t\tvoid: true,\n\t},\n\tsummary: {\n\t\tcontent: TYPE_PHRASING,\n\t\tparent: ['details'],\n\t},\n\ttable: {\n\t\tchildren: ['caption', 'colgroup', 'thead', 'tbody', 'tfoot', 'tr'],\n\t\ttype: TYPE_FLOW,\n\t},\n\ttbody: {\n\t\tparent: ['table'],\n\t\tchildren: ['tr'],\n\t},\n\ttd: {\n\t\tcontent: TYPE_FLOW,\n\t\tparent: ['tr'],\n\t},\n\ttfoot: {\n\t\tparent: ['table'],\n\t\tchildren: ['tr'],\n\t},\n\tth: {\n\t\tcontent: TYPE_FLOW,\n\t\tparent: ['tr'],\n\t},\n\tthead: {\n\t\tparent: ['table'],\n\t\tchildren: ['tr'],\n\t},\n\ttr: {\n\t\tparent: ['table', 'tbody', 'thead', 'tfoot'],\n\t\tchildren: ['th', 'td'],\n\t},\n\ttrack: {\n\t\tparent: ['audio', 'video'],\n\t\tvoid: true,\n\t},\n\tul: {\n\t\tchildren: ['li'],\n\t\ttype: TYPE_FLOW,\n\t},\n\tvideo: {\n\t\tchildren: ['track', 'source'],\n\t},\n\twbr: {\n\t\ttype: TYPE_FLOW | TYPE_PHRASING,\n\t\tvoid: true,\n\t},\n};\n\nfunction createConfigBuilder(config: Partial): (tagName: string) => void {\n\treturn (tagName: string) => {\n\t\ttagConfigs[tagName] = {\n\t\t\t...config,\n\t\t\t...tagConfigs[tagName],\n\t\t};\n\t};\n}\n\n['address', 'main', 'div', 'figure', 'p', 'pre'].forEach(\n\tcreateConfigBuilder({\n\t\tcontent: TYPE_FLOW,\n\t\ttype: TYPE_FLOW | TYPE_PALPABLE,\n\t}),\n);\n\n[\n\t'abbr',\n\t'b',\n\t'bdi',\n\t'bdo',\n\t'cite',\n\t'code',\n\t'data',\n\t'dfn',\n\t'em',\n\t'i',\n\t'kbd',\n\t'mark',\n\t'q',\n\t'ruby',\n\t'samp',\n\t'strong',\n\t'sub',\n\t'sup',\n\t'time',\n\t'u',\n\t'var',\n].forEach(\n\tcreateConfigBuilder({\n\t\tcontent: TYPE_PHRASING,\n\t\ttype: TYPE_FLOW | TYPE_PHRASING | TYPE_PALPABLE,\n\t}),\n);\n\n['p', 'pre'].forEach(\n\tcreateConfigBuilder({\n\t\tcontent: TYPE_PHRASING,\n\t\ttype: TYPE_FLOW | TYPE_PALPABLE,\n\t}),\n);\n\n['s', 'small', 'span', 'del', 'ins'].forEach(\n\tcreateConfigBuilder({\n\t\tcontent: TYPE_PHRASING,\n\t\ttype: TYPE_FLOW | TYPE_PHRASING,\n\t}),\n);\n\n['article', 'aside', 'footer', 'header', 'nav', 'section', 'blockquote'].forEach(\n\tcreateConfigBuilder({\n\t\tcontent: TYPE_FLOW,\n\t\ttype: TYPE_FLOW | TYPE_SECTION | TYPE_PALPABLE,\n\t}),\n);\n\n['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].forEach(\n\tcreateConfigBuilder({\n\t\tcontent: TYPE_PHRASING,\n\t\ttype: TYPE_FLOW | TYPE_HEADING | TYPE_PALPABLE,\n\t}),\n);\n\n['audio', 'canvas', 'iframe', 'img', 'video'].forEach(\n\tcreateConfigBuilder({\n\t\ttype: TYPE_FLOW | TYPE_PHRASING | TYPE_EMBEDDED | TYPE_PALPABLE,\n\t}),\n);\n\n// Disable this map from being modified\nexport const TAGS: ConfigMap = Object.freeze(tagConfigs);\n\n// Tags that should never be allowed, even if the allow list is disabled\nexport const BANNED_TAG_LIST = [\n\t'applet',\n\t'base',\n\t'body',\n\t'command',\n\t'embed',\n\t'frame',\n\t'frameset',\n\t'head',\n\t'html',\n\t'link',\n\t'meta',\n\t'noscript',\n\t'object',\n\t'script',\n\t'style',\n\t'title',\n];\n\nexport const ALLOWED_TAG_LIST = Object.keys(TAGS).filter(\n\t(tag) => tag !== 'canvas' && tag !== 'iframe',\n);\n\n// Filters apply to HTML attributes\nexport const FILTER_ALLOW = 1;\nexport const FILTER_DENY = 2;\nexport const FILTER_CAST_NUMBER = 3;\nexport const FILTER_CAST_BOOL = 4;\nexport const FILTER_NO_CAST = 5;\n\n// Attributes not listed here will be denied\n// https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes\nexport const ATTRIBUTES: FilterMap = Object.freeze({\n\talt: FILTER_ALLOW,\n\tcite: FILTER_ALLOW,\n\tclass: FILTER_ALLOW,\n\tcolspan: FILTER_CAST_NUMBER,\n\tcontrols: FILTER_CAST_BOOL,\n\tdatetime: FILTER_ALLOW,\n\tdefault: FILTER_CAST_BOOL,\n\tdisabled: FILTER_CAST_BOOL,\n\tdir: FILTER_ALLOW,\n\theight: FILTER_ALLOW,\n\thref: FILTER_ALLOW,\n\tid: FILTER_ALLOW,\n\tkind: FILTER_ALLOW,\n\tlabel: FILTER_ALLOW,\n\tlang: FILTER_ALLOW,\n\tloading: FILTER_ALLOW,\n\tloop: FILTER_CAST_BOOL,\n\tmedia: FILTER_ALLOW,\n\tmuted: FILTER_CAST_BOOL,\n\tposter: FILTER_ALLOW,\n\trel: FILTER_ALLOW,\n\trole: FILTER_ALLOW,\n\trowspan: FILTER_CAST_NUMBER,\n\tscope: FILTER_ALLOW,\n\tsizes: FILTER_ALLOW,\n\tspan: FILTER_CAST_NUMBER,\n\tstart: FILTER_CAST_NUMBER,\n\tstyle: FILTER_NO_CAST,\n\tsrc: FILTER_ALLOW,\n\tsrclang: FILTER_ALLOW,\n\tsrcset: FILTER_ALLOW,\n\ttarget: FILTER_ALLOW,\n\ttitle: FILTER_ALLOW,\n\ttype: FILTER_ALLOW,\n\twidth: FILTER_ALLOW,\n});\n\n// Attributes to camel case for React props\nexport const ATTRIBUTES_TO_PROPS: Record = Object.freeze({\n\tclass: 'className',\n\tcolspan: 'colSpan',\n\tdatetime: 'dateTime',\n\trowspan: 'rowSpan',\n\tsrclang: 'srcLang',\n\tsrcset: 'srcSet',\n});\n","import React from 'react';\nimport { ElementProps } from './types';\n\nexport function Element({\n\tattributes = {},\n\tclassName,\n\tchildren = null,\n\tselfClose = false,\n\ttagName,\n}: ElementProps) {\n\tconst Tag = tagName as 'span';\n\n\treturn selfClose ? (\n\t\t\n\t) : (\n\t\t\n\t\t\t{children}\n\t\t\n\t);\n}\n","import { ElementAttributes, FilterInterface } from './types';\n\nexport class Filter implements FilterInterface {\n\t/**\n\t * Filter and clean an HTML attribute value.\n\t */\n\tattribute(\n\t\tname: K,\n\t\tvalue: ElementAttributes[K],\n\t): ElementAttributes[K] | null | undefined {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\treturn value;\n\t}\n\n\t/**\n\t * Filter and clean an HTML node.\n\t */\n\tnode(name: string, node: HTMLElement): HTMLElement | null {\n\t\treturn node;\n\t}\n}\n","import { Filter } from './Filter';\nimport { ElementAttributes } from './types';\n\nconst INVALID_STYLES = /(url|image|image-set)\\(/i;\n\nexport class StyleFilter extends Filter {\n\toverride attribute(\n\t\tname: K,\n\t\tvalue: ElementAttributes[K],\n\t): ElementAttributes[K] {\n\t\tif (name === 'style') {\n\t\t\tObject.keys(value).forEach((key) => {\n\t\t\t\tif (String(value[key]).match(INVALID_STYLES)) {\n\t\t\t\t\t// eslint-disable-next-line no-param-reassign\n\t\t\t\t\tdelete value[key];\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\treturn value;\n\t}\n}\n","/* eslint-disable no-bitwise, no-cond-assign, complexity, @typescript-eslint/no-unsafe-return */\n\nimport React from 'react';\nimport escapeHtml from 'escape-html';\nimport {\n\tALLOWED_TAG_LIST,\n\tATTRIBUTES,\n\tATTRIBUTES_TO_PROPS,\n\tBANNED_TAG_LIST,\n\tFILTER_CAST_BOOL,\n\tFILTER_CAST_NUMBER,\n\tFILTER_DENY,\n\tFILTER_NO_CAST,\n\tTAGS,\n} from './constants';\nimport { Element } from './Element';\nimport { StyleFilter } from './StyleFilter';\nimport {\n\tAttributes,\n\tAttributeValue,\n\tChildrenNode,\n\tElementAttributes,\n\tElementProps,\n\tFilterInterface,\n\tMatcherElementsMap,\n\tMatcherInterface,\n\tNode,\n\tNodeConfig,\n\tParserProps,\n} from './types';\n\nconst ELEMENT_NODE = 1;\nconst TEXT_NODE = 3;\nconst INVALID_ROOTS = /^<(!doctype|(html|head|body)(\\s|>))/i;\nconst ALLOWED_ATTRS = /^(aria-|data-|\\w+:)/iu;\nconst OPEN_TOKEN = /{{{(\\w+)\\/?}}}/;\n\nfunction createDocument() {\n\t// Maybe SSR? Just do nothing instead of crashing!\n\tif (typeof window === 'undefined' || typeof document === 'undefined') {\n\t\treturn undefined;\n\t}\n\n\treturn document.implementation.createHTMLDocument('Interweave');\n}\n\nexport class Parser {\n\tallowed: Set;\n\n\tbanned: Set;\n\n\tblocked: Set;\n\n\tcontainer?: HTMLElement;\n\n\tcontent: Node[] = [];\n\n\tprops: ParserProps;\n\n\tmatchers: MatcherInterface[];\n\n\tfilters: FilterInterface[];\n\n\tkeyIndex: number;\n\n\tconstructor(\n\t\tmarkup: string,\n\t\tprops: ParserProps = {},\n\t\tmatchers: MatcherInterface[] = [],\n\t\tfilters: FilterInterface[] = [],\n\t) {\n\t\tif (__DEV__ && markup && typeof markup !== 'string') {\n\t\t\tthrow new TypeError('Interweave parser requires a valid string.');\n\t\t}\n\n\t\tthis.props = props;\n\t\tthis.matchers = matchers;\n\t\tthis.filters = [...filters, new StyleFilter()];\n\t\tthis.keyIndex = -1;\n\t\tthis.container = this.createContainer(markup || '');\n\t\tthis.allowed = new Set(props.allowList ?? ALLOWED_TAG_LIST);\n\t\tthis.banned = new Set(BANNED_TAG_LIST);\n\t\tthis.blocked = new Set(props.blockList);\n\t}\n\n\t/**\n\t * Loop through and apply all registered attribute filters.\n\t */\n\tapplyAttributeFilters(\n\t\tname: K,\n\t\tvalue: ElementAttributes[K],\n\t): ElementAttributes[K] {\n\t\treturn this.filters.reduce(\n\t\t\t(nextValue, filter) =>\n\t\t\t\tnextValue !== null && typeof filter.attribute === 'function'\n\t\t\t\t\t? filter.attribute(name, nextValue)\n\t\t\t\t\t: nextValue,\n\t\t\tvalue,\n\t\t);\n\t}\n\n\t/**\n\t * Loop through and apply all registered node filters.\n\t */\n\tapplyNodeFilters(name: string, node: HTMLElement | null): HTMLElement | null {\n\t\t// Allow null to be returned\n\t\treturn this.filters.reduce(\n\t\t\t(nextNode, filter) =>\n\t\t\t\tnextNode !== null && typeof filter.node === 'function'\n\t\t\t\t\t? filter.node(name, nextNode)\n\t\t\t\t\t: nextNode,\n\t\t\tnode,\n\t\t);\n\t}\n\n\t/**\n\t * Loop through and apply all registered matchers to the string.\n\t * If a match is found, create a React element, and build a new array.\n\t * This array allows React to interpolate and render accordingly.\n\t */\n\tapplyMatchers(string: string, parentConfig: NodeConfig): ChildrenNode {\n\t\tconst elements: MatcherElementsMap = {};\n\t\tconst { props } = this;\n\t\tlet matchedString = string;\n\t\tlet elementIndex = 0;\n\t\tlet parts = null;\n\n\t\tthis.matchers.forEach((matcher) => {\n\t\t\tconst tagName = matcher.asTag().toLowerCase();\n\t\t\tconst config = this.getTagConfig(tagName);\n\n\t\t\t// Skip matchers that have been disabled from props or are not supported\n\t\t\tif ((props as Record)[matcher.inverseName] || !this.isTagAllowed(tagName)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Skip matchers in which the child cannot be rendered\n\t\t\tif (!this.canRenderChild(parentConfig, config)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Continuously trigger the matcher until no matches are found\n\t\t\tlet tokenizedString = '';\n\n\t\t\twhile (matchedString && (parts = matcher.match(matchedString))) {\n\t\t\t\tconst { index, length, match, valid, void: isVoid, ...partProps } = parts;\n\t\t\t\tconst tokenName = matcher.propName + String(elementIndex);\n\n\t\t\t\t// Piece together a new string with interpolated tokens\n\t\t\t\tif (index > 0) {\n\t\t\t\t\ttokenizedString += matchedString.slice(0, index);\n\t\t\t\t}\n\n\t\t\t\tif (valid) {\n\t\t\t\t\ttokenizedString += isVoid\n\t\t\t\t\t\t? `{{{${tokenName}/}}}`\n\t\t\t\t\t\t: `{{{${tokenName}}}}${match}{{{/${tokenName}}}}`;\n\n\t\t\t\t\tthis.keyIndex += 1;\n\n\t\t\t\t\telementIndex += 1;\n\t\t\t\t\telements[tokenName] = {\n\t\t\t\t\t\tchildren: match,\n\t\t\t\t\t\tmatcher,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\t...props,\n\t\t\t\t\t\t\t...partProps,\n\t\t\t\t\t\t\tkey: this.keyIndex,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\ttokenizedString += match;\n\t\t\t\t}\n\n\t\t\t\t// Reduce the string being matched against,\n\t\t\t\t// otherwise we end up in an infinite loop!\n\t\t\t\tif (matcher.greedy) {\n\t\t\t\t\tmatchedString = tokenizedString + matchedString.slice(index + length);\n\t\t\t\t\ttokenizedString = '';\n\t\t\t\t} else {\n\t\t\t\t\t// eslint-disable-next-line unicorn/explicit-length-check\n\t\t\t\t\tmatchedString = matchedString.slice(index + (length || match.length));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Update the matched string with the tokenized string,\n\t\t\t// so that the next matcher can apply to it.\n\t\t\tif (!matcher.greedy) {\n\t\t\t\tmatchedString = tokenizedString + matchedString;\n\t\t\t}\n\t\t});\n\n\t\tif (elementIndex === 0) {\n\t\t\treturn string;\n\t\t}\n\n\t\treturn this.replaceTokens(matchedString, elements);\n\t}\n\n\t/**\n\t * Determine whether the child can be rendered within the parent.\n\t */\n\tcanRenderChild(parentConfig: NodeConfig, childConfig: NodeConfig): boolean {\n\t\tif (!parentConfig.tagName || !childConfig.tagName) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// No children\n\t\tif (parentConfig.void) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Valid children\n\t\tif (parentConfig.children.length > 0) {\n\t\t\treturn parentConfig.children.includes(childConfig.tagName);\n\t\t}\n\n\t\tif (parentConfig.invalid.length > 0 && parentConfig.invalid.includes(childConfig.tagName)) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Valid parent\n\t\tif (childConfig.parent.length > 0) {\n\t\t\treturn childConfig.parent.includes(parentConfig.tagName);\n\t\t}\n\n\t\t// Self nesting\n\t\tif (!parentConfig.self && parentConfig.tagName === childConfig.tagName) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Content category type\n\t\treturn Boolean(parentConfig && parentConfig.content & childConfig.type);\n\t}\n\n\t/**\n\t * Convert line breaks in a string to HTML `
` tags.\n\t * If the string contains HTML, we should not convert anything,\n\t * as line breaks should be handled by `
`s in the markup itself.\n\t */\n\tconvertLineBreaks(markup: string): string {\n\t\tconst { noHtml, disableLineBreaks } = this.props;\n\n\t\tif (noHtml || disableLineBreaks || markup.match(/<((?:\\/[ a-z]+)|(?:[ a-z]+\\/))>/gi)) {\n\t\t\treturn markup;\n\t\t}\n\n\t\t// Replace carriage returns\n\t\tlet nextMarkup = markup.replace(/\\r\\n/g, '\\n');\n\n\t\t// Replace long line feeds\n\t\tnextMarkup = nextMarkup.replace(/\\n{3,}/g, '\\n\\n\\n');\n\n\t\t// Replace line feeds with `
`s\n\t\tnextMarkup = nextMarkup.replace(/\\n/g, '
');\n\n\t\treturn nextMarkup;\n\t}\n\n\t/**\n\t * Create a detached HTML document that allows for easy HTML\n\t * parsing while not triggering scripts or loading external\n\t * resources.\n\t */\n\tcreateContainer(markup: string): HTMLElement | undefined {\n\t\tconst factory =\n\t\t\t(typeof global !== 'undefined' && global.INTERWEAVE_SSR_POLYFILL) || createDocument;\n\t\tconst doc = factory();\n\n\t\tif (!doc) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst tag = this.props.containerTagName ?? 'body';\n\t\tconst el = tag === 'body' || tag === 'fragment' ? doc.body : doc.createElement(tag);\n\n\t\tif (markup.match(INVALID_ROOTS)) {\n\t\t\tif (__DEV__) {\n\t\t\t\tthrow new Error('HTML documents as Interweave content are not supported.');\n\t\t\t}\n\t\t} else {\n\t\t\tel.innerHTML = this.convertLineBreaks(this.props.escapeHtml ? escapeHtml(markup) : markup);\n\t\t}\n\n\t\treturn el;\n\t}\n\n\t/**\n\t * Convert an elements attribute map to an object map.\n\t * Returns null if no attributes are defined.\n\t */\n\textractAttributes(node: HTMLElement): Attributes | null {\n\t\tconst { allowAttributes } = this.props;\n\t\tconst attributes: Attributes = {};\n\t\tlet count = 0;\n\n\t\tif (node.nodeType !== ELEMENT_NODE || !node.attributes) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// @ts-expect-error Cant type iterator\n\t\t[...node.attributes].forEach((attr: Attr) => {\n\t\t\tconst { name, value } = attr;\n\t\t\tconst newName = name.toLowerCase();\n\t\t\tconst filter = ATTRIBUTES[newName] || ATTRIBUTES[name];\n\n\t\t\t// Verify the node is safe from attacks\n\t\t\tif (!this.isSafe(node)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Do not allow denied attributes, excluding ARIA attributes\n\t\t\t// Do not allow events or XSS injections\n\t\t\tif (\n\t\t\t\t!newName.match(ALLOWED_ATTRS) &&\n\t\t\t\t((!allowAttributes && (!filter || filter === FILTER_DENY)) ||\n\t\t\t\t\tnewName.startsWith('on') ||\n\t\t\t\t\tvalue.replace(/(\\s|\\0|�([9AD]);)/, '').match(/(javascript|vbscript|livescript|xss):/i))\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Apply attribute filters\n\t\t\tlet newValue: AttributeValue = newName === 'style' ? this.extractStyleAttribute(node) : value;\n\n\t\t\t// Cast to boolean\n\t\t\tif (filter === FILTER_CAST_BOOL) {\n\t\t\t\tnewValue = true;\n\n\t\t\t\t// Cast to number\n\t\t\t} else if (filter === FILTER_CAST_NUMBER) {\n\t\t\t\tnewValue = Number.parseFloat(String(newValue));\n\n\t\t\t\t// Cast to string\n\t\t\t} else if (filter !== FILTER_NO_CAST) {\n\t\t\t\tnewValue = String(newValue);\n\t\t\t}\n\n\t\t\tattributes[ATTRIBUTES_TO_PROPS[newName] || newName] = this.applyAttributeFilters(\n\t\t\t\tnewName as keyof ElementAttributes,\n\t\t\t\tnewValue,\n\t\t\t) as AttributeValue;\n\t\t\tcount += 1;\n\t\t});\n\n\t\tif (count === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn attributes;\n\t}\n\n\t/**\n\t * Extract the style attribute as an object and remove values that allow for attack vectors.\n\t */\n\textractStyleAttribute(node: HTMLElement): object {\n\t\tconst styles: Record = {};\n\n\t\t// eslint-disable-next-line unicorn/prefer-spread\n\t\tArray.from(node.style).forEach((key) => {\n\t\t\tconst value = node.style[key as keyof CSSStyleDeclaration];\n\n\t\t\tif (typeof value === 'string' || typeof value === 'number') {\n\t\t\t\tstyles[key.replace(/-([a-z])/g, (match, letter) => String(letter).toUpperCase())] = value;\n\t\t\t}\n\t\t});\n\n\t\treturn styles;\n\t}\n\n\t/**\n\t * Return configuration for a specific tag.\n\t */\n\tgetTagConfig(tagName: string): NodeConfig {\n\t\tconst common = {\n\t\t\tchildren: [],\n\t\t\tcontent: 0,\n\t\t\tinvalid: [],\n\t\t\tparent: [],\n\t\t\tself: true,\n\t\t\ttagName: '',\n\t\t\ttype: 0,\n\t\t\tvoid: false,\n\t\t};\n\n\t\t// Only spread when a tag config exists,\n\t\t// otherwise we use the empty `tagName`\n\t\t// for parent config inheritance.\n\t\tif (TAGS[tagName]) {\n\t\t\treturn {\n\t\t\t\t...common,\n\t\t\t\t...TAGS[tagName],\n\t\t\t\ttagName,\n\t\t\t};\n\t\t}\n\n\t\treturn common;\n\t}\n\n\t/**\n\t * Verify that a node is safe from XSS and injection attacks.\n\t */\n\tisSafe(node: HTMLElement): boolean {\n\t\t// URLs should only support HTTP, email and phone numbers\n\t\tif (typeof HTMLAnchorElement !== 'undefined' && node instanceof HTMLAnchorElement) {\n\t\t\tconst href = node.getAttribute('href');\n\n\t\t\t// Fragment protocols start with about:\n\t\t\t// So let's just allow them\n\t\t\tif (href?.startsWith('#')) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tconst protocol = node.protocol.toLowerCase();\n\n\t\t\treturn (\n\t\t\t\tprotocol === ':' ||\n\t\t\t\tprotocol === 'http:' ||\n\t\t\t\tprotocol === 'https:' ||\n\t\t\t\tprotocol === 'mailto:' ||\n\t\t\t\tprotocol === 'tel:'\n\t\t\t);\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Verify that an HTML tag is allowed to render.\n\t */\n\tisTagAllowed(tagName: string): boolean {\n\t\tif (this.banned.has(tagName) || this.blocked.has(tagName)) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n\t\treturn this.props.allowElements || this.allowed.has(tagName);\n\t}\n\n\t/**\n\t * Parse the markup by injecting it into a detached document,\n\t * while looping over all child nodes and generating an\n\t * array to interpolate into JSX.\n\t */\n\tparse(): Node[] {\n\t\tif (!this.container) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn this.parseNode(this.container, this.getTagConfig(this.container.nodeName.toLowerCase()));\n\t}\n\n\t/**\n\t * Loop over the nodes children and generate a\n\t * list of text nodes and React elements.\n\t */\n\tparseNode(parentNode: HTMLElement, parentConfig: NodeConfig): Node[] {\n\t\tconst {\n\t\t\tnoHtml,\n\t\t\tnoHtmlExceptMatchers,\n\t\t\tallowElements,\n\t\t\ttransform,\n\t\t\ttransformOnlyAllowList,\n\t\t} = this.props;\n\t\tlet content: Node[] = [];\n\t\tlet mergedText = '';\n\n\t\t// @ts-expect-error Cant type iterator\n\t\t[...parentNode.childNodes].forEach((node: ChildNode) => {\n\t\t\t// Create React elements from HTML elements\n\t\t\tif (node.nodeType === ELEMENT_NODE) {\n\t\t\t\tconst tagName = node.nodeName.toLowerCase();\n\t\t\t\tconst config = this.getTagConfig(tagName);\n\n\t\t\t\t// Persist any previous text\n\t\t\t\tif (mergedText) {\n\t\t\t\t\tcontent.push(mergedText);\n\t\t\t\t\tmergedText = '';\n\t\t\t\t}\n\n\t\t\t\t// Apply node filters first\n\t\t\t\tconst nextNode = this.applyNodeFilters(tagName, node as HTMLElement);\n\n\t\t\t\tif (!nextNode) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Apply transformation second\n\t\t\t\tlet children;\n\n\t\t\t\tif (transform && !(transformOnlyAllowList && !this.isTagAllowed(tagName))) {\n\t\t\t\t\tthis.keyIndex += 1;\n\t\t\t\t\tconst key = this.keyIndex;\n\n\t\t\t\t\t// Must occur after key is set\n\t\t\t\t\tchildren = this.parseNode(nextNode, config);\n\n\t\t\t\t\tconst transformed = transform(nextNode, children, config);\n\n\t\t\t\t\tif (transformed === null) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof transformed !== 'undefined') {\n\t\t\t\t\t\tcontent.push(React.cloneElement(transformed as React.ReactElement, { key }));\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Reset as we're not using the transformation\n\t\t\t\t\tthis.keyIndex = key - 1;\n\t\t\t\t}\n\n\t\t\t\t// Never allow these tags (except via a transformer)\n\t\t\t\tif (this.banned.has(tagName)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Only render when the following criteria is met:\n\t\t\t\t// - HTML has not been disabled\n\t\t\t\t// - Tag is allowed\n\t\t\t\t// - Child is valid within the parent\n\t\t\t\tif (\n\t\t\t\t\t!(noHtml || (noHtmlExceptMatchers && tagName !== 'br')) &&\n\t\t\t\t\tthis.isTagAllowed(tagName) &&\n\t\t\t\t\t(allowElements || this.canRenderChild(parentConfig, config))\n\t\t\t\t) {\n\t\t\t\t\tthis.keyIndex += 1;\n\n\t\t\t\t\t// Build the props as it makes it easier to test\n\t\t\t\t\tconst attributes = this.extractAttributes(nextNode);\n\t\t\t\t\tconst elementProps: ElementProps = {\n\t\t\t\t\t\ttagName,\n\t\t\t\t\t};\n\n\t\t\t\t\tif (attributes) {\n\t\t\t\t\t\telementProps.attributes = attributes;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (config.void) {\n\t\t\t\t\t\telementProps.selfClose = config.void;\n\t\t\t\t\t}\n\n\t\t\t\t\tcontent.push(\n\t\t\t\t\t\tReact.createElement(\n\t\t\t\t\t\t\tElement,\n\t\t\t\t\t\t\t{ ...elementProps, key: this.keyIndex },\n\t\t\t\t\t\t\tchildren ?? this.parseNode(nextNode, config),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\t// Render the children of the current element only.\n\t\t\t\t\t// Important: If the current element is not allowed,\n\t\t\t\t\t// use the parent element for the next scope.\n\t\t\t\t} else {\n\t\t\t\t\tcontent = [\n\t\t\t\t\t\t...content,\n\t\t\t\t\t\t...this.parseNode(nextNode, config.tagName ? config : parentConfig),\n\t\t\t\t\t];\n\t\t\t\t}\n\n\t\t\t\t// Apply matchers if a text node\n\t\t\t} else if (node.nodeType === TEXT_NODE) {\n\t\t\t\tconst text =\n\t\t\t\t\tnoHtml && !noHtmlExceptMatchers\n\t\t\t\t\t\t? node.textContent\n\t\t\t\t\t\t: // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n\t\t\t\t\t\t this.applyMatchers(node.textContent || '', parentConfig);\n\n\t\t\t\tif (Array.isArray(text)) {\n\t\t\t\t\tcontent = [...content, ...text];\n\t\t\t\t} else {\n\t\t\t\t\tmergedText += text!;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tif (mergedText) {\n\t\t\tcontent.push(mergedText);\n\t\t}\n\n\t\treturn content;\n\t}\n\n\t/**\n\t * Deconstruct the string into an array, by replacing custom tokens with React elements,\n\t * so that React can render it correctly.\n\t */\n\treplaceTokens(tokenizedString: string, elements: MatcherElementsMap): ChildrenNode {\n\t\tif (!tokenizedString.includes('{{{')) {\n\t\t\treturn tokenizedString;\n\t\t}\n\n\t\tconst nodes: Node[] = [];\n\t\tlet text = tokenizedString;\n\t\tlet open: RegExpMatchArray | null = null;\n\n\t\t// Find an open token tag\n\t\twhile ((open = text.match(OPEN_TOKEN))) {\n\t\t\tconst [match, tokenName] = open;\n\t\t\tconst startIndex = open.index!;\n\t\t\tconst isVoid = match.includes('/');\n\n\t\t\tif (__DEV__ && !elements[tokenName]) {\n\t\t\t\tthrow new Error(`Token \"${tokenName}\" found but no matching element to replace with.`);\n\t\t\t}\n\n\t\t\t// Extract the previous non-token text\n\t\t\tif (startIndex > 0) {\n\t\t\t\tnodes.push(text.slice(0, startIndex));\n\n\t\t\t\t// Reduce text so that the closing tag will be found after the opening\n\t\t\t\ttext = text.slice(startIndex);\n\t\t\t}\n\n\t\t\tconst { children, matcher, props: elementProps } = elements[tokenName];\n\t\t\tlet endIndex: number;\n\n\t\t\t// Use tag as-is if void\n\t\t\tif (isVoid) {\n\t\t\t\tendIndex = match.length;\n\n\t\t\t\tnodes.push(matcher.createElement(children, elementProps));\n\n\t\t\t\t// Find the closing tag if not void\n\t\t\t} else {\n\t\t\t\tconst close = text.match(new RegExp(`{{{/${tokenName}}}}`))!;\n\n\t\t\t\tif (__DEV__ && !close) {\n\t\t\t\t\tthrow new Error(`Closing token missing for interpolated element \"${tokenName}\".`);\n\t\t\t\t}\n\n\t\t\t\tendIndex = close.index! + close[0].length;\n\n\t\t\t\tnodes.push(\n\t\t\t\t\tmatcher.createElement(\n\t\t\t\t\t\tthis.replaceTokens(text.slice(match.length, close.index), elements),\n\t\t\t\t\t\telementProps,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Reduce text for the next interation\n\t\t\ttext = text.slice(endIndex);\n\t\t}\n\n\t\t// Extra the remaining text\n\t\tif (text.length > 0) {\n\t\t\tnodes.push(text);\n\t\t}\n\n\t\t// Reduce to a string if possible\n\t\tif (nodes.length === 0) {\n\t\t\treturn '';\n\t\t}\n\t\tif (nodes.length === 1 && typeof nodes[0] === 'string') {\n\t\t\treturn nodes[0];\n\t\t}\n\n\t\treturn nodes;\n\t}\n}\n","/* eslint-disable react/jsx-fragments */\n\nimport React from 'react';\nimport { Element } from './Element';\nimport { Parser } from './Parser';\nimport { MarkupProps } from './types';\n\nexport function Markup(props: MarkupProps) {\n\tconst {\n\t\tattributes,\n\t\tclassName,\n\t\tcontainerTagName,\n\t\tcontent,\n\t\temptyContent,\n\t\tparsedContent,\n\t\ttagName,\n\t\tnoWrap: baseNoWrap,\n\t} = props;\n\tconst tag = containerTagName ?? tagName ?? 'span';\n\tconst noWrap = tag === 'fragment' ? true : baseNoWrap;\n\tlet mainContent;\n\n\tif (parsedContent) {\n\t\tmainContent = parsedContent;\n\t} else {\n\t\tconst markup = new Parser(content ?? '', props).parse();\n\n\t\tif (markup.length > 0) {\n\t\t\tmainContent = markup;\n\t\t}\n\t}\n\n\tif (!mainContent) {\n\t\tmainContent = emptyContent;\n\t}\n\n\tif (noWrap) {\n\t\t// eslint-disable-next-line react/jsx-no-useless-fragment\n\t\treturn {mainContent};\n\t}\n\n\treturn (\n\t\t\n\t\t\t{mainContent}\n\t\t\n\t);\n}\n","/* eslint-disable promise/prefer-await-to-callbacks */\nimport React from 'react';\nimport { Markup } from './Markup';\nimport { Parser } from './Parser';\nimport { InterweaveProps } from './types';\n\nexport function Interweave(props: InterweaveProps) {\n\tconst {\n\t\tattributes,\n\t\tclassName,\n\t\tcontent = '',\n\t\tdisableFilters = false,\n\t\tdisableMatchers = false,\n\t\temptyContent = null,\n\t\tfilters = [],\n\t\tmatchers = [],\n\t\tonAfterParse = null,\n\t\tonBeforeParse = null,\n\t\ttagName = 'span',\n\t\tnoWrap = false,\n\t\t...parserProps\n\t} = props;\n\tconst allMatchers = disableMatchers ? [] : matchers;\n\tconst allFilters = disableFilters ? [] : filters;\n\tconst beforeCallbacks = onBeforeParse ? [onBeforeParse] : [];\n\tconst afterCallbacks = onAfterParse ? [onAfterParse] : [];\n\n\t// Inherit callbacks from matchers\n\tallMatchers.forEach((matcher) => {\n\t\tif (matcher.onBeforeParse) {\n\t\t\tbeforeCallbacks.push(matcher.onBeforeParse.bind(matcher));\n\t\t}\n\n\t\tif (matcher.onAfterParse) {\n\t\t\tafterCallbacks.push(matcher.onAfterParse.bind(matcher));\n\t\t}\n\t});\n\n\t// Trigger before callbacks\n\tconst markup = beforeCallbacks.reduce((string, callback) => {\n\t\tconst nextString = callback(string, props);\n\n\t\tif (__DEV__ && typeof nextString !== 'string') {\n\t\t\tthrow new TypeError('Interweave `onBeforeParse` must return a valid HTML string.');\n\t\t}\n\n\t\treturn nextString;\n\t}, content ?? '');\n\n\t// Parse the markup\n\tconst parser = new Parser(markup, parserProps, allMatchers, allFilters);\n\n\t// Trigger after callbacks\n\tconst nodes = afterCallbacks.reduce((parserNodes, callback) => {\n\t\tconst nextNodes = callback(parserNodes, props);\n\n\t\tif (__DEV__ && !Array.isArray(nextNodes)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t'Interweave `onAfterParse` must return an array of strings and React elements.',\n\t\t\t);\n\t\t}\n\n\t\treturn nextNodes;\n\t}, parser.parse());\n\n\treturn (\n\t\t\n\t);\n}\n"],"names":["matchHtmlRegExp","module","exports","string","escape","str","match","exec","html","index","lastIndex","length","charCodeAt","substring","tagConfigs","a","content","TYPE_FLOW","self","type","address","invalid","audio","children","br","void","body","button","caption","parent","col","colgroup","details","dd","dl","dt","figcaption","footer","header","hr","img","li","main","ol","picture","rb","rp","rt","rtc","ruby","source","summary","table","tbody","td","tfoot","th","thead","tr","track","ul","video","wbr","createConfigBuilder","config","tagName","forEach","TAGS","Object","freeze","BANNED_TAG_LIST","ALLOWED_TAG_LIST","keys","filter","tag","ATTRIBUTES","alt","cite","class","colspan","controls","datetime","default","disabled","dir","height","href","id","kind","label","lang","loading","loop","media","muted","poster","rel","role","rowspan","scope","sizes","span","start","style","src","srclang","srcset","target","title","width","ATTRIBUTES_TO_PROPS","Element","attributes","className","selfClose","Tag","React","Filter","attribute","name","value","node","StyleFilter","key","String","INVALID_STYLES","ALLOWED_ATTRS","OPEN_TOKEN","undefined","allowed","banned","blocked","matchers","keyIndex","constructor","props","_defineProperty","TypeError","allowList","applyAttributeFilters","filters","reduce","applyMatchers","parentConfig","matcher","canRenderChild","valid","tokenizedString","elementIndex","elements","matchedString","greedy","childConfig","noHtml","disableLineBreaks","convertLineBreaks","nextMarkup","global","doc","createContainer","allowAttributes","count","extractAttributes","attr","newName","newValue","extractStyleAttribute","isSafe","FILTER_CAST_BOOL","from","styles","getTagConfig","common","parseNode","transform","transformOnlyAllowList","allowElements","mergedText","this","elementProps","noHtmlExceptMatchers","INVALID_ROOTS","replaceTokens","open","nodes","text","endIndex","push","isVoid","emptyContent","mainContent","_ref","containerTagName","parsedContent","noWrap","disableFilters","onBeforeParse","afterCallbacks","allMatchers","beforeCallbacks","onAfterParse","nextString","parser","Array","isArray","nextNodes"],"sourceRoot":""}