markdown-to-jsx 9.3.2 → 9.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/html.cjs +85 -85
- package/dist/html.js +85 -85
- package/dist/html.js.map +3 -3
- package/dist/index.cjs +88 -88
- package/dist/index.js +88 -88
- package/dist/index.js.map +3 -3
- package/dist/markdown.cjs +92 -92
- package/dist/markdown.js +92 -92
- package/dist/markdown.js.map +3 -3
- package/dist/native.cjs +102 -102
- package/dist/native.js +94 -94
- package/dist/native.js.map +3 -3
- package/dist/react.cjs +88 -88
- package/dist/react.js +89 -89
- package/dist/react.js.map +3 -3
- package/dist/solid.cjs +94 -94
- package/dist/solid.js +94 -94
- package/dist/solid.js.map +3 -3
- package/dist/vue.cjs +82 -82
- package/dist/vue.js +82 -82
- package/dist/vue.js.map +3 -3
- package/package.json +1 -1
package/dist/markdown.js.map
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
"/**\n * Auto-generated HTML entity mappings for CommonMark compliance\n * Generated from https://html.spec.whatwg.org/entities.json\n * Generated by scripts/generate-entities.ts\n * \n * Simple object mapping entity names to Unicode characters.\n * Stores only lowercase versions when case variants map to the same Unicode (saves ~8.8 KB).\n * Case-sensitive entities (where uppercase/lowercase differ) are stored with both keys.\n */\n\nexport const NAMED_CODES_TO_UNICODE: Record<string, string> = {\n \"af\":\"\",\n \"applyfunction\":\"\",\n \"ic\":\"\",\n \"invisiblecomma\":\"\",\n \"invisibletimes\":\"\",\n \"it\":\"\",\n \"lrm\":\"\",\n \"negativemediumspace\":\"\",\n \"negativethickspace\":\"\",\n \"negativethinspace\":\"\",\n \"negativeverythinspace\":\"\",\n \"nobreak\":\"\",\n \"rlm\":\"\",\n \"shy\":\"\",\n \"zerowidthspace\":\"\",\n \"zwj\":\"\",\n \"zwnj\":\"\",\n \"downbreve\":\"̑\",\n \"tdot\":\"⃛\",\n \"tripledot\":\"⃛\",\n \"dotdot\":\"⃜\",\n \"tab\":\"\t\",\n \"newline\":\"\\n\",\n \"emsp\":\" \",\n \"emsp13\":\" \",\n \"emsp14\":\" \",\n \"ensp\":\" \",\n \"hairsp\":\" \",\n \"mediumspace\":\" \",\n \"puncsp\":\" \",\n \"thinsp\":\" \",\n \"thinspace\":\" \",\n \"verythinspace\":\" \",\n \"nbsp\":\" \",\n \"nonbreakingspace\":\" \",\n \"numsp\":\" \",\n \"thickspace\":\" \",\n \"oline\":\"‾\",\n \"overbar\":\"‾\",\n \"lowbar\":\"_\",\n \"underbar\":\"_\",\n \"dash\":\"‐\",\n \"hyphen\":\"‐\",\n \"ndash\":\"–\",\n \"mdash\":\"—\",\n \"horbar\":\"―\",\n \"comma\":\",\",\n \"semi\":\";\",\n \"bsemi\":\"⁏\",\n \"colon\":\":\",\n \"Colone\":\"⩴\",\n \"excl\":\"!\",\n \"iexcl\":\"¡\",\n \"quest\":\"?\",\n \"iquest\":\"¿\",\n \"period\":\".\",\n \"nldr\":\"‥\",\n \"hellip\":\"…\",\n \"mldr\":\"…\",\n \"centerdot\":\"·\",\n \"middot\":\"·\",\n \"apos\":\"'\",\n \"lsquo\":\"‘\",\n \"opencurlyquote\":\"‘\",\n \"closecurlyquote\":\"’\",\n \"rsquo\":\"’\",\n \"rsquor\":\"’\",\n \"lsquor\":\"‚\",\n \"sbquo\":\"‚\",\n \"lsaquo\":\"‹\",\n \"rsaquo\":\"›\",\n \"quot\":\"\\\"\",\n \"ldquo\":\"“\",\n \"opencurlydoublequote\":\"“\",\n \"closecurlydoublequote\":\"”\",\n \"rdquo\":\"”\",\n \"rdquor\":\"”\",\n \"bdquo\":\"„\",\n \"ldquor\":\"„\",\n \"laquo\":\"«\",\n \"raquo\":\"»\",\n \"lpar\":\"(\",\n \"rpar\":\")\",\n \"lbrack\":\"[\",\n \"lsqb\":\"[\",\n \"rbrack\":\"]\",\n \"rsqb\":\"]\",\n \"lbrace\":\"{\",\n \"lcub\":\"{\",\n \"rbrace\":\"}\",\n \"rcub\":\"}\",\n \"lceil\":\"⌈\",\n \"leftceiling\":\"⌈\",\n \"rceil\":\"⌉\",\n \"rightceiling\":\"⌉\",\n \"leftfloor\":\"⌊\",\n \"lfloor\":\"⌊\",\n \"rfloor\":\"⌋\",\n \"rightfloor\":\"⌋\",\n \"lopar\":\"⦅\",\n \"ropar\":\"⦆\",\n \"lbrke\":\"⦋\",\n \"rbrke\":\"⦌\",\n \"lbrkslu\":\"⦍\",\n \"rbrksld\":\"⦎\",\n \"lbrksld\":\"⦏\",\n \"rbrkslu\":\"⦐\",\n \"langd\":\"⦑\",\n \"rangd\":\"⦒\",\n \"lparlt\":\"⦓\",\n \"rpargt\":\"⦔\",\n \"gtlpar\":\"⦕\",\n \"ltrpar\":\"⦖\",\n \"leftdoublebracket\":\"⟦\",\n \"lobrk\":\"⟦\",\n \"rightdoublebracket\":\"⟧\",\n \"robrk\":\"⟧\",\n \"lang\":\"⟨\",\n \"langle\":\"⟨\",\n \"leftanglebracket\":\"⟨\",\n \"rang\":\"⟩\",\n \"rangle\":\"⟩\",\n \"rightanglebracket\":\"⟩\",\n \"Lang\":\"⟪\",\n \"Rang\":\"⟫\",\n \"loang\":\"⟬\",\n \"roang\":\"⟭\",\n \"lbbrk\":\"❲\",\n \"rbbrk\":\"❳\",\n \"Verbar\":\"‖\",\n \"Vert\":\"‖\",\n \"sect\":\"§\",\n \"para\":\"¶\",\n \"commat\":\"@\",\n \"ast\":\"*\",\n \"midast\":\"*\",\n \"sol\":\"/\",\n \"bsol\":\"\\\\\",\n \"amp\":\"&\",\n \"num\":\"#\",\n \"percnt\":\"%\",\n \"permil\":\"‰\",\n \"pertenk\":\"‱\",\n \"dagger\":\"†\",\n \"Dagger\":\"‡\",\n \"ddagger\":\"‡\",\n \"bull\":\"•\",\n \"bullet\":\"•\",\n \"hybull\":\"⁃\",\n \"prime\":\"′\",\n \"Prime\":\"″\",\n \"tprime\":\"‴\",\n \"qprime\":\"⁗\",\n \"backprime\":\"‵\",\n \"bprime\":\"‵\",\n \"caret\":\"⁁\",\n \"diacriticalgrave\":\"`\",\n \"grave\":\"`\",\n \"acute\":\"´\",\n \"diacriticalacute\":\"´\",\n \"diacriticaltilde\":\"˜\",\n \"tilde\":\"˜\",\n \"hat\":\"^\",\n \"macr\":\"¯\",\n \"strns\":\"¯\",\n \"breve\":\"˘\",\n \"diacriticaldot\":\"˙\",\n \"dot\":\"˙\",\n \"die\":\"¨\",\n \"Dot\":\"¨\",\n \"doubledot\":\"¨\",\n \"uml\":\"¨\",\n \"ring\":\"˚\",\n \"dblac\":\"˝\",\n \"diacriticaldoubleacute\":\"˝\",\n \"cedil\":\"¸\",\n \"cedilla\":\"¸\",\n \"ogon\":\"˛\",\n \"circ\":\"ˆ\",\n \"caron\":\"ˇ\",\n \"hacek\":\"ˇ\",\n \"deg\":\"°\",\n \"copy\":\"©\",\n \"circledr\":\"®\",\n \"reg\":\"®\",\n \"copysr\":\"℗\",\n \"weierp\":\"℘\",\n \"wp\":\"℘\",\n \"rx\":\"℞\",\n \"mho\":\"℧\",\n \"iiota\":\"℩\",\n \"larr\":\"←\",\n \"leftarrow\":\"←\",\n \"shortleftarrow\":\"←\",\n \"slarr\":\"←\",\n \"nlarr\":\"↚\",\n \"nleftarrow\":\"↚\",\n \"rarr\":\"→\",\n \"rightarrow\":\"→\",\n \"shortrightarrow\":\"→\",\n \"srarr\":\"→\",\n \"nrarr\":\"↛\",\n \"nrightarrow\":\"↛\",\n \"shortuparrow\":\"↑\",\n \"uarr\":\"↑\",\n \"uparrow\":\"↑\",\n \"darr\":\"↓\",\n \"downarrow\":\"↓\",\n \"shortdownarrow\":\"↓\",\n \"harr\":\"↔\",\n \"leftrightarrow\":\"↔\",\n \"nharr\":\"↮\",\n \"nleftrightarrow\":\"↮\",\n \"updownarrow\":\"↕\",\n \"varr\":\"↕\",\n \"nwarr\":\"↖\",\n \"nwarrow\":\"↖\",\n \"upperleftarrow\":\"↖\",\n \"nearr\":\"↗\",\n \"nearrow\":\"↗\",\n \"upperrightarrow\":\"↗\",\n \"lowerrightarrow\":\"↘\",\n \"searr\":\"↘\",\n \"searrow\":\"↘\",\n \"lowerleftarrow\":\"↙\",\n \"swarr\":\"↙\",\n \"swarrow\":\"↙\",\n \"rarrw\":\"↝\",\n \"rightsquigarrow\":\"↝\",\n \"nrarrw\":\"↝̸\",\n \"Larr\":\"↞\",\n \"twoheadleftarrow\":\"↞\",\n \"Uarr\":\"↟\",\n \"Rarr\":\"↠\",\n \"twoheadrightarrow\":\"↠\",\n \"Darr\":\"↡\",\n \"larrtl\":\"↢\",\n \"leftarrowtail\":\"↢\",\n \"rarrtl\":\"↣\",\n \"rightarrowtail\":\"↣\",\n \"leftteearrow\":\"↤\",\n \"mapstoleft\":\"↤\",\n \"mapstoup\":\"↥\",\n \"upteearrow\":\"↥\",\n \"map\":\"↦\",\n \"mapsto\":\"↦\",\n \"rightteearrow\":\"↦\",\n \"downteearrow\":\"↧\",\n \"mapstodown\":\"↧\",\n \"hookleftarrow\":\"↩\",\n \"larrhk\":\"↩\",\n \"hookrightarrow\":\"↪\",\n \"rarrhk\":\"↪\",\n \"larrlp\":\"↫\",\n \"looparrowleft\":\"↫\",\n \"looparrowright\":\"↬\",\n \"rarrlp\":\"↬\",\n \"harrw\":\"↭\",\n \"leftrightsquigarrow\":\"↭\",\n \"lsh\":\"↰\",\n \"rsh\":\"↱\",\n \"ldsh\":\"↲\",\n \"rdsh\":\"↳\",\n \"crarr\":\"↵\",\n \"cularr\":\"↶\",\n \"curvearrowleft\":\"↶\",\n \"curarr\":\"↷\",\n \"curvearrowright\":\"↷\",\n \"circlearrowleft\":\"↺\",\n \"olarr\":\"↺\",\n \"circlearrowright\":\"↻\",\n \"orarr\":\"↻\",\n \"leftharpoonup\":\"↼\",\n \"leftvector\":\"↼\",\n \"lharu\":\"↼\",\n \"downleftvector\":\"↽\",\n \"leftharpoondown\":\"↽\",\n \"lhard\":\"↽\",\n \"rightupvector\":\"↾\",\n \"uharr\":\"↾\",\n \"upharpoonright\":\"↾\",\n \"leftupvector\":\"↿\",\n \"uharl\":\"↿\",\n \"upharpoonleft\":\"↿\",\n \"rharu\":\"⇀\",\n \"rightharpoonup\":\"⇀\",\n \"rightvector\":\"⇀\",\n \"downrightvector\":\"⇁\",\n \"rhard\":\"⇁\",\n \"rightharpoondown\":\"⇁\",\n \"dharr\":\"⇂\",\n \"downharpoonright\":\"⇂\",\n \"rightdownvector\":\"⇂\",\n \"dharl\":\"⇃\",\n \"downharpoonleft\":\"⇃\",\n \"leftdownvector\":\"⇃\",\n \"rightarrowleftarrow\":\"⇄\",\n \"rightleftarrows\":\"⇄\",\n \"rlarr\":\"⇄\",\n \"udarr\":\"⇅\",\n \"uparrowdownarrow\":\"⇅\",\n \"leftarrowrightarrow\":\"⇆\",\n \"leftrightarrows\":\"⇆\",\n \"lrarr\":\"⇆\",\n \"leftleftarrows\":\"⇇\",\n \"llarr\":\"⇇\",\n \"upuparrows\":\"⇈\",\n \"uuarr\":\"⇈\",\n \"rightrightarrows\":\"⇉\",\n \"rrarr\":\"⇉\",\n \"ddarr\":\"⇊\",\n \"downdownarrows\":\"⇊\",\n \"leftrightharpoons\":\"⇋\",\n \"lrhar\":\"⇋\",\n \"reverseequilibrium\":\"⇋\",\n \"equilibrium\":\"⇌\",\n \"rightleftharpoons\":\"⇌\",\n \"rlhar\":\"⇌\",\n \"doubleleftarrow\":\"⇐\",\n \"lArr\":\"⇐\",\n \"Leftarrow\":\"⇐\",\n \"nlArr\":\"⇍\",\n \"nLeftarrow\":\"⇍\",\n \"doubleuparrow\":\"⇑\",\n \"uArr\":\"⇑\",\n \"Uparrow\":\"⇑\",\n \"doublerightarrow\":\"⇒\",\n \"implies\":\"⇒\",\n \"rArr\":\"⇒\",\n \"Rightarrow\":\"⇒\",\n \"nrArr\":\"⇏\",\n \"nRightarrow\":\"⇏\",\n \"dArr\":\"⇓\",\n \"doubledownarrow\":\"⇓\",\n \"Downarrow\":\"⇓\",\n \"doubleleftrightarrow\":\"⇔\",\n \"hArr\":\"⇔\",\n \"iff\":\"⇔\",\n \"Leftrightarrow\":\"⇔\",\n \"nhArr\":\"⇎\",\n \"nLeftrightarrow\":\"⇎\",\n \"doubleupdownarrow\":\"⇕\",\n \"Updownarrow\":\"⇕\",\n \"vArr\":\"⇕\",\n \"nwArr\":\"⇖\",\n \"neArr\":\"⇗\",\n \"seArr\":\"⇘\",\n \"swArr\":\"⇙\",\n \"laarr\":\"⇚\",\n \"lleftarrow\":\"⇚\",\n \"raarr\":\"⇛\",\n \"rrightarrow\":\"⇛\",\n \"zigrarr\":\"⇝\",\n \"larrb\":\"⇤\",\n \"leftarrowbar\":\"⇤\",\n \"rarrb\":\"⇥\",\n \"rightarrowbar\":\"⇥\",\n \"downarrowuparrow\":\"⇵\",\n \"duarr\":\"⇵\",\n \"loarr\":\"⇽\",\n \"roarr\":\"⇾\",\n \"hoarr\":\"⇿\",\n \"forall\":\"∀\",\n \"comp\":\"∁\",\n \"complement\":\"∁\",\n \"part\":\"∂\",\n \"partiald\":\"∂\",\n \"npart\":\"∂̸\",\n \"exist\":\"∃\",\n \"exists\":\"∃\",\n \"nexist\":\"∄\",\n \"nexists\":\"∄\",\n \"notexists\":\"∄\",\n \"empty\":\"∅\",\n \"emptyset\":\"∅\",\n \"emptyv\":\"∅\",\n \"varnothing\":\"∅\",\n \"del\":\"∇\",\n \"nabla\":\"∇\",\n \"element\":\"∈\",\n \"in\":\"∈\",\n \"isin\":\"∈\",\n \"isinv\":\"∈\",\n \"notelement\":\"∉\",\n \"notin\":\"∉\",\n \"notinva\":\"∉\",\n \"ni\":\"∋\",\n \"niv\":\"∋\",\n \"reverseelement\":\"∋\",\n \"suchthat\":\"∋\",\n \"notni\":\"∌\",\n \"notniva\":\"∌\",\n \"notreverseelement\":\"∌\",\n \"backepsilon\":\"϶\",\n \"bepsi\":\"϶\",\n \"prod\":\"∏\",\n \"product\":\"∏\",\n \"coprod\":\"∐\",\n \"coproduct\":\"∐\",\n \"sum\":\"∑\",\n \"plus\":\"+\",\n \"plusminus\":\"±\",\n \"plusmn\":\"±\",\n \"pm\":\"±\",\n \"div\":\"÷\",\n \"divide\":\"÷\",\n \"times\":\"×\",\n \"lt\":\"<\",\n \"nless\":\"≮\",\n \"nlt\":\"≮\",\n \"notless\":\"≮\",\n \"nvlt\":\"<⃒\",\n \"equals\":\"=\",\n \"ne\":\"≠\",\n \"notequal\":\"≠\",\n \"bne\":\"=⃥\",\n \"equal\":\"⩵\",\n \"gt\":\">\",\n \"ngt\":\"≯\",\n \"ngtr\":\"≯\",\n \"notgreater\":\"≯\",\n \"nvgt\":\">⃒\",\n \"not\":\"¬\",\n \"verbar\":\"|\",\n \"vert\":\"|\",\n \"verticalline\":\"|\",\n \"brvbar\":\"¦\",\n \"minus\":\"−\",\n \"minusplus\":\"∓\",\n \"mnplus\":\"∓\",\n \"mp\":\"∓\",\n \"dotplus\":\"∔\",\n \"plusdo\":\"∔\",\n \"frasl\":\"⁄\",\n \"backslash\":\"∖\",\n \"setminus\":\"∖\",\n \"setmn\":\"∖\",\n \"smallsetminus\":\"∖\",\n \"ssetmn\":\"∖\",\n \"lowast\":\"∗\",\n \"compfn\":\"∘\",\n \"smallcircle\":\"∘\",\n \"radic\":\"√\",\n \"sqrt\":\"√\",\n \"prop\":\"∝\",\n \"proportional\":\"∝\",\n \"propto\":\"∝\",\n \"varpropto\":\"∝\",\n \"vprop\":\"∝\",\n \"infin\":\"∞\",\n \"angrt\":\"∟\",\n \"ang\":\"∠\",\n \"angle\":\"∠\",\n \"nang\":\"∠⃒\",\n \"angmsd\":\"∡\",\n \"measuredangle\":\"∡\",\n \"angsph\":\"∢\",\n \"mid\":\"∣\",\n \"shortmid\":\"∣\",\n \"smid\":\"∣\",\n \"verticalbar\":\"∣\",\n \"nmid\":\"∤\",\n \"notverticalbar\":\"∤\",\n \"nshortmid\":\"∤\",\n \"nsmid\":\"∤\",\n \"doubleverticalbar\":\"∥\",\n \"par\":\"∥\",\n \"parallel\":\"∥\",\n \"shortparallel\":\"∥\",\n \"spar\":\"∥\",\n \"notdoubleverticalbar\":\"∦\",\n \"npar\":\"∦\",\n \"nparallel\":\"∦\",\n \"nshortparallel\":\"∦\",\n \"nspar\":\"∦\",\n \"and\":\"∧\",\n \"wedge\":\"∧\",\n \"or\":\"∨\",\n \"vee\":\"∨\",\n \"cap\":\"∩\",\n \"caps\":\"∩︀\",\n \"cup\":\"∪\",\n \"cups\":\"∪︀\",\n \"int\":\"∫\",\n \"integral\":\"∫\",\n \"Int\":\"∬\",\n \"iiint\":\"∭\",\n \"tint\":\"∭\",\n \"iiiint\":\"⨌\",\n \"qint\":\"⨌\",\n \"conint\":\"∮\",\n \"contourintegral\":\"∮\",\n \"oint\":\"∮\",\n \"Conint\":\"∯\",\n \"doublecontourintegral\":\"∯\",\n \"cconint\":\"∰\",\n \"cwint\":\"∱\",\n \"clockwisecontourintegral\":\"∲\",\n \"cwconint\":\"∲\",\n \"awconint\":\"∳\",\n \"counterclockwisecontourintegral\":\"∳\",\n \"there4\":\"∴\",\n \"therefore\":\"∴\",\n \"becaus\":\"∵\",\n \"because\":\"∵\",\n \"ratio\":\"∶\",\n \"Colon\":\"∷\",\n \"proportion\":\"∷\",\n \"dotminus\":\"∸\",\n \"minusd\":\"∸\",\n \"mddot\":\"∺\",\n \"homtht\":\"∻\",\n \"sim\":\"∼\",\n \"thicksim\":\"∼\",\n \"thksim\":\"∼\",\n \"Tilde\":\"∼\",\n \"nottilde\":\"≁\",\n \"nsim\":\"≁\",\n \"nvsim\":\"∼⃒\",\n \"backsim\":\"∽\",\n \"bsim\":\"∽\",\n \"race\":\"∽̱\",\n \"ac\":\"∾\",\n \"mstpos\":\"∾\",\n \"ace\":\"∾̳\",\n \"acd\":\"∿\",\n \"verticaltilde\":\"≀\",\n \"wr\":\"≀\",\n \"wreath\":\"≀\",\n \"eqsim\":\"≂\",\n \"equaltilde\":\"≂\",\n \"esim\":\"≂\",\n \"nesim\":\"≂̸\",\n \"notequaltilde\":\"≂̸\",\n \"sime\":\"≃\",\n \"simeq\":\"≃\",\n \"tildeequal\":\"≃\",\n \"nottildeequal\":\"≄\",\n \"nsime\":\"≄\",\n \"nsimeq\":\"≄\",\n \"cong\":\"≅\",\n \"tildefullequal\":\"≅\",\n \"ncong\":\"≇\",\n \"nottildefullequal\":\"≇\",\n \"simne\":\"≆\",\n \"ap\":\"≈\",\n \"approx\":\"≈\",\n \"asymp\":\"≈\",\n \"thickapprox\":\"≈\",\n \"thkap\":\"≈\",\n \"tildetilde\":\"≈\",\n \"nap\":\"≉\",\n \"napprox\":\"≉\",\n \"nottildetilde\":\"≉\",\n \"ape\":\"≊\",\n \"approxeq\":\"≊\",\n \"apid\":\"≋\",\n \"napid\":\"≋̸\",\n \"backcong\":\"≌\",\n \"bcong\":\"≌\",\n \"asympeq\":\"≍\",\n \"CupCap\":\"≍\",\n \"notcupcap\":\"≭\",\n \"nvap\":\"≍⃒\",\n \"bump\":\"≎\",\n \"Bumpeq\":\"≎\",\n \"humpdownhump\":\"≎\",\n \"nbump\":\"≎̸\",\n \"nothumpdownhump\":\"≎̸\",\n \"bumpe\":\"≏\",\n \"bumpeq\":\"≏\",\n \"humpequal\":\"≏\",\n \"nbumpe\":\"≏̸\",\n \"nothumpequal\":\"≏̸\",\n \"doteq\":\"≐\",\n \"dotequal\":\"≐\",\n \"esdot\":\"≐\",\n \"nedot\":\"≐̸\",\n \"doteqdot\":\"≑\",\n \"eDot\":\"≑\",\n \"efdot\":\"≒\",\n \"fallingdotseq\":\"≒\",\n \"erdot\":\"≓\",\n \"risingdotseq\":\"≓\",\n \"assign\":\"≔\",\n \"colone\":\"≔\",\n \"coloneq\":\"≔\",\n \"ecolon\":\"≕\",\n \"eqcolon\":\"≕\",\n \"ecir\":\"≖\",\n \"eqcirc\":\"≖\",\n \"circeq\":\"≗\",\n \"cire\":\"≗\",\n \"wedgeq\":\"≙\",\n \"veeeq\":\"≚\",\n \"triangleq\":\"≜\",\n \"trie\":\"≜\",\n \"equest\":\"≟\",\n \"questeq\":\"≟\",\n \"congruent\":\"≡\",\n \"equiv\":\"≡\",\n \"nequiv\":\"≢\",\n \"notcongruent\":\"≢\",\n \"bnequiv\":\"≡⃥\",\n \"le\":\"≤\",\n \"leq\":\"≤\",\n \"nle\":\"≰\",\n \"nleq\":\"≰\",\n \"notlessequal\":\"≰\",\n \"nvle\":\"≤⃒\",\n \"ge\":\"≥\",\n \"geq\":\"≥\",\n \"greaterequal\":\"≥\",\n \"nge\":\"≱\",\n \"ngeq\":\"≱\",\n \"notgreaterequal\":\"≱\",\n \"nvge\":\"≥⃒\",\n \"lE\":\"≦\",\n \"leqq\":\"≦\",\n \"lessfullequal\":\"≦\",\n \"nlE\":\"≦̸\",\n \"nleqq\":\"≦̸\",\n \"gE\":\"≧\",\n \"geqq\":\"≧\",\n \"greaterfullequal\":\"≧\",\n \"ngE\":\"≧̸\",\n \"ngeqq\":\"≧̸\",\n \"notgreaterfullequal\":\"≧̸\",\n \"lnE\":\"≨\",\n \"lneqq\":\"≨\",\n \"lvertneqq\":\"≨︀\",\n \"lvne\":\"≨︀\",\n \"gnE\":\"≩\",\n \"gneqq\":\"≩\",\n \"gvertneqq\":\"≩︀\",\n \"gvne\":\"≩︀\",\n \"ll\":\"≪\",\n \"Lt\":\"≪\",\n \"nestedlessless\":\"≪\",\n \"nltv\":\"≪̸\",\n \"notlessless\":\"≪̸\",\n \"nLt\":\"≪⃒\",\n \"gg\":\"≫\",\n \"Gt\":\"≫\",\n \"nestedgreatergreater\":\"≫\",\n \"ngtv\":\"≫̸\",\n \"notgreatergreater\":\"≫̸\",\n \"nGt\":\"≫⃒\",\n \"between\":\"≬\",\n \"twixt\":\"≬\",\n \"lesssim\":\"≲\",\n \"lesstilde\":\"≲\",\n \"lsim\":\"≲\",\n \"nlsim\":\"≴\",\n \"notlesstilde\":\"≴\",\n \"greatertilde\":\"≳\",\n \"gsim\":\"≳\",\n \"gtrsim\":\"≳\",\n \"ngsim\":\"≵\",\n \"notgreatertilde\":\"≵\",\n \"lessgreater\":\"≶\",\n \"lessgtr\":\"≶\",\n \"lg\":\"≶\",\n \"notlessgreater\":\"≸\",\n \"ntlg\":\"≸\",\n \"gl\":\"≷\",\n \"greaterless\":\"≷\",\n \"gtrless\":\"≷\",\n \"notgreaterless\":\"≹\",\n \"ntgl\":\"≹\",\n \"pr\":\"≺\",\n \"prec\":\"≺\",\n \"precedes\":\"≺\",\n \"notprecedes\":\"⊀\",\n \"npr\":\"⊀\",\n \"nprec\":\"⊀\",\n \"sc\":\"≻\",\n \"succ\":\"≻\",\n \"succeeds\":\"≻\",\n \"notsucceeds\":\"⊁\",\n \"nsc\":\"⊁\",\n \"nsucc\":\"⊁\",\n \"prcue\":\"≼\",\n \"preccurlyeq\":\"≼\",\n \"precedesslantequal\":\"≼\",\n \"notprecedesslantequal\":\"⋠\",\n \"nprcue\":\"⋠\",\n \"sccue\":\"≽\",\n \"succcurlyeq\":\"≽\",\n \"succeedsslantequal\":\"≽\",\n \"notsucceedsslantequal\":\"⋡\",\n \"nsccue\":\"⋡\",\n \"precedestilde\":\"≾\",\n \"precsim\":\"≾\",\n \"prsim\":\"≾\",\n \"scsim\":\"≿\",\n \"succeedstilde\":\"≿\",\n \"succsim\":\"≿\",\n \"notsucceedstilde\":\"≿̸\",\n \"sub\":\"⊂\",\n \"subset\":\"⊂\",\n \"nsub\":\"⊄\",\n \"notsubset\":\"⊂⃒\",\n \"nsubset\":\"⊂⃒\",\n \"vnsub\":\"⊂⃒\",\n \"sup\":\"⊃\",\n \"superset\":\"⊃\",\n \"supset\":\"⊃\",\n \"nsup\":\"⊅\",\n \"notsuperset\":\"⊃⃒\",\n \"nsupset\":\"⊃⃒\",\n \"vnsup\":\"⊃⃒\",\n \"sube\":\"⊆\",\n \"subseteq\":\"⊆\",\n \"subsetequal\":\"⊆\",\n \"notsubsetequal\":\"⊈\",\n \"nsube\":\"⊈\",\n \"nsubseteq\":\"⊈\",\n \"supe\":\"⊇\",\n \"supersetequal\":\"⊇\",\n \"supseteq\":\"⊇\",\n \"notsupersetequal\":\"⊉\",\n \"nsupe\":\"⊉\",\n \"nsupseteq\":\"⊉\",\n \"subne\":\"⊊\",\n \"subsetneq\":\"⊊\",\n \"varsubsetneq\":\"⊊︀\",\n \"vsubne\":\"⊊︀\",\n \"supne\":\"⊋\",\n \"supsetneq\":\"⊋\",\n \"varsupsetneq\":\"⊋︀\",\n \"vsupne\":\"⊋︀\",\n \"cupdot\":\"⊍\",\n \"unionplus\":\"⊎\",\n \"uplus\":\"⊎\",\n \"sqsub\":\"⊏\",\n \"sqsubset\":\"⊏\",\n \"squaresubset\":\"⊏\",\n \"notsquaresubset\":\"⊏̸\",\n \"sqsup\":\"⊐\",\n \"sqsupset\":\"⊐\",\n \"squaresuperset\":\"⊐\",\n \"notsquaresuperset\":\"⊐̸\",\n \"sqsube\":\"⊑\",\n \"sqsubseteq\":\"⊑\",\n \"squaresubsetequal\":\"⊑\",\n \"notsquaresubsetequal\":\"⋢\",\n \"nsqsube\":\"⋢\",\n \"sqsupe\":\"⊒\",\n \"sqsupseteq\":\"⊒\",\n \"squaresupersetequal\":\"⊒\",\n \"notsquaresupersetequal\":\"⋣\",\n \"nsqsupe\":\"⋣\",\n \"sqcap\":\"⊓\",\n \"sqcaps\":\"⊓︀\",\n \"squareintersection\":\"⊓\",\n \"sqcup\":\"⊔\",\n \"sqcups\":\"⊔︀\",\n \"squareunion\":\"⊔\",\n \"circleplus\":\"⊕\",\n \"oplus\":\"⊕\",\n \"circleminus\":\"⊖\",\n \"ominus\":\"⊖\",\n \"circletimes\":\"⊗\",\n \"otimes\":\"⊗\",\n \"osol\":\"⊘\",\n \"circledot\":\"⊙\",\n \"odot\":\"⊙\",\n \"circledcirc\":\"⊚\",\n \"ocir\":\"⊚\",\n \"circledast\":\"⊛\",\n \"oast\":\"⊛\",\n \"circleddash\":\"⊝\",\n \"odash\":\"⊝\",\n \"boxplus\":\"⊞\",\n \"plusb\":\"⊞\",\n \"boxminus\":\"⊟\",\n \"minusb\":\"⊟\",\n \"boxtimes\":\"⊠\",\n \"timesb\":\"⊠\",\n \"dotsquare\":\"⊡\",\n \"sdotb\":\"⊡\",\n \"righttee\":\"⊢\",\n \"vdash\":\"⊢\",\n \"nvdash\":\"⊬\",\n \"dashv\":\"⊣\",\n \"lefttee\":\"⊣\",\n \"downtee\":\"⊤\",\n \"top\":\"⊤\",\n \"bot\":\"⊥\",\n \"bottom\":\"⊥\",\n \"perp\":\"⊥\",\n \"uptee\":\"⊥\",\n \"models\":\"⊧\",\n \"doublerighttee\":\"⊨\",\n \"vDash\":\"⊨\",\n \"nvDash\":\"⊭\",\n \"Vdash\":\"⊩\",\n \"nVdash\":\"⊮\",\n \"vvdash\":\"⊪\",\n \"VDash\":\"⊫\",\n \"nVDash\":\"⊯\",\n \"prurel\":\"⊰\",\n \"lefttriangle\":\"⊲\",\n \"vartriangleleft\":\"⊲\",\n \"vltri\":\"⊲\",\n \"nltri\":\"⋪\",\n \"notlefttriangle\":\"⋪\",\n \"ntriangleleft\":\"⋪\",\n \"righttriangle\":\"⊳\",\n \"vartriangleright\":\"⊳\",\n \"vrtri\":\"⊳\",\n \"notrighttriangle\":\"⋫\",\n \"nrtri\":\"⋫\",\n \"ntriangleright\":\"⋫\",\n \"lefttriangleequal\":\"⊴\",\n \"ltrie\":\"⊴\",\n \"trianglelefteq\":\"⊴\",\n \"nltrie\":\"⋬\",\n \"notlefttriangleequal\":\"⋬\",\n \"ntrianglelefteq\":\"⋬\",\n \"nvltrie\":\"⊴⃒\",\n \"righttriangleequal\":\"⊵\",\n \"rtrie\":\"⊵\",\n \"trianglerighteq\":\"⊵\",\n \"notrighttriangleequal\":\"⋭\",\n \"nrtrie\":\"⋭\",\n \"ntrianglerighteq\":\"⋭\",\n \"nvrtrie\":\"⊵⃒\",\n \"origof\":\"⊶\",\n \"imof\":\"⊷\",\n \"multimap\":\"⊸\",\n \"mumap\":\"⊸\",\n \"hercon\":\"⊹\",\n \"intcal\":\"⊺\",\n \"intercal\":\"⊺\",\n \"veebar\":\"⊻\",\n \"barvee\":\"⊽\",\n \"angrtvb\":\"⊾\",\n \"lrtri\":\"⊿\",\n \"bigwedge\":\"⋀\",\n \"Wedge\":\"⋀\",\n \"xwedge\":\"⋀\",\n \"bigvee\":\"⋁\",\n \"Vee\":\"⋁\",\n \"xvee\":\"⋁\",\n \"bigcap\":\"⋂\",\n \"intersection\":\"⋂\",\n \"xcap\":\"⋂\",\n \"bigcup\":\"⋃\",\n \"union\":\"⋃\",\n \"xcup\":\"⋃\",\n \"diam\":\"⋄\",\n \"diamond\":\"⋄\",\n \"sdot\":\"⋅\",\n \"sstarf\":\"⋆\",\n \"Star\":\"⋆\",\n \"divideontimes\":\"⋇\",\n \"divonx\":\"⋇\",\n \"bowtie\":\"⋈\",\n \"ltimes\":\"⋉\",\n \"rtimes\":\"⋊\",\n \"leftthreetimes\":\"⋋\",\n \"lthree\":\"⋋\",\n \"rightthreetimes\":\"⋌\",\n \"rthree\":\"⋌\",\n \"backsimeq\":\"⋍\",\n \"bsime\":\"⋍\",\n \"curlyvee\":\"⋎\",\n \"cuvee\":\"⋎\",\n \"curlywedge\":\"⋏\",\n \"cuwed\":\"⋏\",\n \"Sub\":\"⋐\",\n \"Subset\":\"⋐\",\n \"Sup\":\"⋑\",\n \"Supset\":\"⋑\",\n \"Cap\":\"⋒\",\n \"Cup\":\"⋓\",\n \"fork\":\"⋔\",\n \"pitchfork\":\"⋔\",\n \"epar\":\"⋕\",\n \"lessdot\":\"⋖\",\n \"ltdot\":\"⋖\",\n \"gtdot\":\"⋗\",\n \"gtrdot\":\"⋗\",\n \"Ll\":\"⋘\",\n \"nll\":\"⋘̸\",\n \"Gg\":\"⋙\",\n \"ggg\":\"⋙\",\n \"ngg\":\"⋙̸\",\n \"leg\":\"⋚\",\n \"lesg\":\"⋚︀\",\n \"lesseqgtr\":\"⋚\",\n \"lessequalgreater\":\"⋚\",\n \"gel\":\"⋛\",\n \"gesl\":\"⋛︀\",\n \"greaterequalless\":\"⋛\",\n \"gtreqless\":\"⋛\",\n \"cuepr\":\"⋞\",\n \"curlyeqprec\":\"⋞\",\n \"cuesc\":\"⋟\",\n \"curlyeqsucc\":\"⋟\",\n \"lnsim\":\"⋦\",\n \"gnsim\":\"⋧\",\n \"precnsim\":\"⋨\",\n \"prnsim\":\"⋨\",\n \"scnsim\":\"⋩\",\n \"succnsim\":\"⋩\",\n \"vellip\":\"⋮\",\n \"ctdot\":\"⋯\",\n \"utdot\":\"⋰\",\n \"dtdot\":\"⋱\",\n \"disin\":\"⋲\",\n \"isinsv\":\"⋳\",\n \"isins\":\"⋴\",\n \"isindot\":\"⋵\",\n \"notindot\":\"⋵̸\",\n \"notinvc\":\"⋶\",\n \"notinvb\":\"⋷\",\n \"isine\":\"⋹\",\n \"notine\":\"⋹̸\",\n \"nisd\":\"⋺\",\n \"xnis\":\"⋻\",\n \"nis\":\"⋼\",\n \"notnivc\":\"⋽\",\n \"notnivb\":\"⋾\",\n \"barwed\":\"⌅\",\n \"barwedge\":\"⌅\",\n \"Barwed\":\"⌆\",\n \"doublebarwedge\":\"⌆\",\n \"drcrop\":\"⌌\",\n \"dlcrop\":\"⌍\",\n \"urcrop\":\"⌎\",\n \"ulcrop\":\"⌏\",\n \"bnot\":\"⌐\",\n \"profline\":\"⌒\",\n \"profsurf\":\"⌓\",\n \"telrec\":\"⌕\",\n \"target\":\"⌖\",\n \"ulcorn\":\"⌜\",\n \"ulcorner\":\"⌜\",\n \"urcorn\":\"⌝\",\n \"urcorner\":\"⌝\",\n \"dlcorn\":\"⌞\",\n \"llcorner\":\"⌞\",\n \"drcorn\":\"⌟\",\n \"lrcorner\":\"⌟\",\n \"frown\":\"⌢\",\n \"sfrown\":\"⌢\",\n \"smile\":\"⌣\",\n \"ssmile\":\"⌣\",\n \"cylcty\":\"⌭\",\n \"profalar\":\"⌮\",\n \"topbot\":\"⌶\",\n \"ovbar\":\"⌽\",\n \"solbar\":\"⌿\",\n \"angzarr\":\"⍼\",\n \"lmoust\":\"⎰\",\n \"lmoustache\":\"⎰\",\n \"rmoust\":\"⎱\",\n \"rmoustache\":\"⎱\",\n \"overbracket\":\"⎴\",\n \"tbrk\":\"⎴\",\n \"bbrk\":\"⎵\",\n \"underbracket\":\"⎵\",\n \"bbrktbrk\":\"⎶\",\n \"overparenthesis\":\"⏜\",\n \"underparenthesis\":\"⏝\",\n \"overbrace\":\"⏞\",\n \"underbrace\":\"⏟\",\n \"trpezium\":\"⏢\",\n \"elinters\":\"⏧\",\n \"blank\":\"␣\",\n \"boxh\":\"─\",\n \"horizontalline\":\"─\",\n \"boxv\":\"│\",\n \"boxdr\":\"┌\",\n \"boxdl\":\"┐\",\n \"boxur\":\"└\",\n \"boxul\":\"┘\",\n \"boxvr\":\"├\",\n \"boxvl\":\"┤\",\n \"boxhd\":\"┬\",\n \"boxhu\":\"┴\",\n \"boxvh\":\"┼\",\n \"boxH\":\"═\",\n \"boxV\":\"║\",\n \"boxdR\":\"╒\",\n \"boxDr\":\"╓\",\n \"boxDR\":\"╔\",\n \"boxdL\":\"╕\",\n \"boxDl\":\"╖\",\n \"boxDL\":\"╗\",\n \"boxuR\":\"╘\",\n \"boxUr\":\"╙\",\n \"boxUR\":\"╚\",\n \"boxuL\":\"╛\",\n \"boxUl\":\"╜\",\n \"boxUL\":\"╝\",\n \"boxvR\":\"╞\",\n \"boxVr\":\"╟\",\n \"boxVR\":\"╠\",\n \"boxvL\":\"╡\",\n \"boxVl\":\"╢\",\n \"boxVL\":\"╣\",\n \"boxHd\":\"╤\",\n \"boxhD\":\"╥\",\n \"boxHD\":\"╦\",\n \"boxHu\":\"╧\",\n \"boxhU\":\"╨\",\n \"boxHU\":\"╩\",\n \"boxvH\":\"╪\",\n \"boxVh\":\"╫\",\n \"boxVH\":\"╬\",\n \"uhblk\":\"▀\",\n \"lhblk\":\"▄\",\n \"block\":\"█\",\n \"blk14\":\"░\",\n \"blk12\":\"▒\",\n \"blk34\":\"▓\",\n \"squ\":\"□\",\n \"square\":\"□\",\n \"blacksquare\":\"▪\",\n \"filledverysmallsquare\":\"▪\",\n \"squarf\":\"▪\",\n \"squf\":\"▪\",\n \"emptyverysmallsquare\":\"▫\",\n \"rect\":\"▭\",\n \"marker\":\"▮\",\n \"fltns\":\"▱\",\n \"bigtriangleup\":\"△\",\n \"xutri\":\"△\",\n \"blacktriangle\":\"▴\",\n \"utrif\":\"▴\",\n \"triangle\":\"▵\",\n \"utri\":\"▵\",\n \"blacktriangleright\":\"▸\",\n \"rtrif\":\"▸\",\n \"rtri\":\"▹\",\n \"triangleright\":\"▹\",\n \"bigtriangledown\":\"▽\",\n \"xdtri\":\"▽\",\n \"blacktriangledown\":\"▾\",\n \"dtrif\":\"▾\",\n \"dtri\":\"▿\",\n \"triangledown\":\"▿\",\n \"blacktriangleleft\":\"◂\",\n \"ltrif\":\"◂\",\n \"ltri\":\"◃\",\n \"triangleleft\":\"◃\",\n \"loz\":\"◊\",\n \"lozenge\":\"◊\",\n \"cir\":\"○\",\n \"tridot\":\"◬\",\n \"bigcirc\":\"◯\",\n \"xcirc\":\"◯\",\n \"ultri\":\"◸\",\n \"urtri\":\"◹\",\n \"lltri\":\"◺\",\n \"emptysmallsquare\":\"◻\",\n \"filledsmallsquare\":\"◼\",\n \"bigstar\":\"★\",\n \"starf\":\"★\",\n \"star\":\"☆\",\n \"phone\":\"☎\",\n \"female\":\"♀\",\n \"male\":\"♂\",\n \"spades\":\"♠\",\n \"spadesuit\":\"♠\",\n \"clubs\":\"♣\",\n \"clubsuit\":\"♣\",\n \"hearts\":\"♥\",\n \"heartsuit\":\"♥\",\n \"diamondsuit\":\"♦\",\n \"diams\":\"♦\",\n \"sung\":\"♪\",\n \"check\":\"✓\",\n \"checkmark\":\"✓\",\n \"cross\":\"✗\",\n \"malt\":\"✠\",\n \"maltese\":\"✠\",\n \"sext\":\"✶\",\n \"verticalseparator\":\"❘\",\n \"bsolhsub\":\"⟈\",\n \"suphsol\":\"⟉\",\n \"longleftarrow\":\"⟵\",\n \"xlarr\":\"⟵\",\n \"longrightarrow\":\"⟶\",\n \"xrarr\":\"⟶\",\n \"longleftrightarrow\":\"⟷\",\n \"xharr\":\"⟷\",\n \"doublelongleftarrow\":\"⟸\",\n \"Longleftarrow\":\"⟸\",\n \"xlArr\":\"⟸\",\n \"doublelongrightarrow\":\"⟹\",\n \"Longrightarrow\":\"⟹\",\n \"xrArr\":\"⟹\",\n \"doublelongleftrightarrow\":\"⟺\",\n \"Longleftrightarrow\":\"⟺\",\n \"xhArr\":\"⟺\",\n \"longmapsto\":\"⟼\",\n \"xmap\":\"⟼\",\n \"dzigrarr\":\"⟿\",\n \"nvlarr\":\"⤂\",\n \"nvrarr\":\"⤃\",\n \"nvharr\":\"⤄\",\n \"Map\":\"⤅\",\n \"lbarr\":\"⤌\",\n \"bkarow\":\"⤍\",\n \"lBarr\":\"⤎\",\n \"dbkarow\":\"⤏\",\n \"rBarr\":\"⤏\",\n \"drbkarow\":\"⤐\",\n \"rbarr\":\"⤐\",\n \"RBarr\":\"⤐\",\n \"ddotrahd\":\"⤑\",\n \"uparrowbar\":\"⤒\",\n \"downarrowbar\":\"⤓\",\n \"Rarrtl\":\"⤖\",\n \"latail\":\"⤙\",\n \"ratail\":\"⤚\",\n \"lAtail\":\"⤛\",\n \"rAtail\":\"⤜\",\n \"larrfs\":\"⤝\",\n \"rarrfs\":\"⤞\",\n \"larrbfs\":\"⤟\",\n \"rarrbfs\":\"⤠\",\n \"nwarhk\":\"⤣\",\n \"nearhk\":\"⤤\",\n \"hksearow\":\"⤥\",\n \"searhk\":\"⤥\",\n \"hkswarow\":\"⤦\",\n \"swarhk\":\"⤦\",\n \"nwnear\":\"⤧\",\n \"nesear\":\"⤨\",\n \"toea\":\"⤨\",\n \"seswar\":\"⤩\",\n \"tosa\":\"⤩\",\n \"swnwar\":\"⤪\",\n \"rarrc\":\"⤳\",\n \"nrarrc\":\"⤳̸\",\n \"cudarrr\":\"⤵\",\n \"ldca\":\"⤶\",\n \"rdca\":\"⤷\",\n \"cudarrl\":\"⤸\",\n \"larrpl\":\"⤹\",\n \"curarrm\":\"⤼\",\n \"cularrp\":\"⤽\",\n \"rarrpl\":\"⥅\",\n \"harrcir\":\"⥈\",\n \"uarrocir\":\"⥉\",\n \"lurdshar\":\"⥊\",\n \"ldrushar\":\"⥋\",\n \"leftrightvector\":\"⥎\",\n \"rightupdownvector\":\"⥏\",\n \"downleftrightvector\":\"⥐\",\n \"leftupdownvector\":\"⥑\",\n \"leftvectorbar\":\"⥒\",\n \"rightvectorbar\":\"⥓\",\n \"rightupvectorbar\":\"⥔\",\n \"rightdownvectorbar\":\"⥕\",\n \"downleftvectorbar\":\"⥖\",\n \"downrightvectorbar\":\"⥗\",\n \"leftupvectorbar\":\"⥘\",\n \"leftdownvectorbar\":\"⥙\",\n \"leftteevector\":\"⥚\",\n \"rightteevector\":\"⥛\",\n \"rightupteevector\":\"⥜\",\n \"rightdownteevector\":\"⥝\",\n \"downleftteevector\":\"⥞\",\n \"downrightteevector\":\"⥟\",\n \"leftupteevector\":\"⥠\",\n \"leftdownteevector\":\"⥡\",\n \"lhar\":\"⥢\",\n \"uhar\":\"⥣\",\n \"rhar\":\"⥤\",\n \"dhar\":\"⥥\",\n \"luruhar\":\"⥦\",\n \"ldrdhar\":\"⥧\",\n \"ruluhar\":\"⥨\",\n \"rdldhar\":\"⥩\",\n \"lharul\":\"⥪\",\n \"llhard\":\"⥫\",\n \"rharul\":\"⥬\",\n \"lrhard\":\"⥭\",\n \"udhar\":\"⥮\",\n \"upequilibrium\":\"⥮\",\n \"duhar\":\"⥯\",\n \"reverseupequilibrium\":\"⥯\",\n \"roundimplies\":\"⥰\",\n \"erarr\":\"⥱\",\n \"simrarr\":\"⥲\",\n \"larrsim\":\"⥳\",\n \"rarrsim\":\"⥴\",\n \"rarrap\":\"⥵\",\n \"ltlarr\":\"⥶\",\n \"gtrarr\":\"⥸\",\n \"subrarr\":\"⥹\",\n \"suplarr\":\"⥻\",\n \"lfisht\":\"⥼\",\n \"rfisht\":\"⥽\",\n \"ufisht\":\"⥾\",\n \"dfisht\":\"⥿\",\n \"vzigzag\":\"⦚\",\n \"vangrt\":\"⦜\",\n \"angrtvbd\":\"⦝\",\n \"ange\":\"⦤\",\n \"range\":\"⦥\",\n \"dwangle\":\"⦦\",\n \"uwangle\":\"⦧\",\n \"angmsdaa\":\"⦨\",\n \"angmsdab\":\"⦩\",\n \"angmsdac\":\"⦪\",\n \"angmsdad\":\"⦫\",\n \"angmsdae\":\"⦬\",\n \"angmsdaf\":\"⦭\",\n \"angmsdag\":\"⦮\",\n \"angmsdah\":\"⦯\",\n \"bemptyv\":\"⦰\",\n \"demptyv\":\"⦱\",\n \"cemptyv\":\"⦲\",\n \"raemptyv\":\"⦳\",\n \"laemptyv\":\"⦴\",\n \"ohbar\":\"⦵\",\n \"omid\":\"⦶\",\n \"opar\":\"⦷\",\n \"operp\":\"⦹\",\n \"olcross\":\"⦻\",\n \"odsold\":\"⦼\",\n \"olcir\":\"⦾\",\n \"ofcir\":\"⦿\",\n \"olt\":\"⧀\",\n \"ogt\":\"⧁\",\n \"cirscir\":\"⧂\",\n \"cirE\":\"⧃\",\n \"solb\":\"⧄\",\n \"bsolb\":\"⧅\",\n \"boxbox\":\"⧉\",\n \"trisb\":\"⧍\",\n \"rtriltri\":\"⧎\",\n \"lefttrianglebar\":\"⧏\",\n \"notlefttrianglebar\":\"⧏̸\",\n \"righttrianglebar\":\"⧐\",\n \"notrighttrianglebar\":\"⧐̸\",\n \"iinfin\":\"⧜\",\n \"infintie\":\"⧝\",\n \"nvinfin\":\"⧞\",\n \"eparsl\":\"⧣\",\n \"smeparsl\":\"⧤\",\n \"eqvparsl\":\"⧥\",\n \"blacklozenge\":\"⧫\",\n \"lozf\":\"⧫\",\n \"ruledelayed\":\"⧴\",\n \"dsol\":\"⧶\",\n \"bigodot\":\"⨀\",\n \"xodot\":\"⨀\",\n \"bigoplus\":\"⨁\",\n \"xoplus\":\"⨁\",\n \"bigotimes\":\"⨂\",\n \"xotime\":\"⨂\",\n \"biguplus\":\"⨄\",\n \"xuplus\":\"⨄\",\n \"bigsqcup\":\"⨆\",\n \"xsqcup\":\"⨆\",\n \"fpartint\":\"⨍\",\n \"cirfnint\":\"⨐\",\n \"awint\":\"⨑\",\n \"rppolint\":\"⨒\",\n \"scpolint\":\"⨓\",\n \"npolint\":\"⨔\",\n \"pointint\":\"⨕\",\n \"quatint\":\"⨖\",\n \"intlarhk\":\"⨗\",\n \"pluscir\":\"⨢\",\n \"plusacir\":\"⨣\",\n \"simplus\":\"⨤\",\n \"plusdu\":\"⨥\",\n \"plussim\":\"⨦\",\n \"plustwo\":\"⨧\",\n \"mcomma\":\"⨩\",\n \"minusdu\":\"⨪\",\n \"loplus\":\"⨭\",\n \"roplus\":\"⨮\",\n \"Cross\":\"⨯\",\n \"timesd\":\"⨰\",\n \"timesbar\":\"⨱\",\n \"smashp\":\"⨳\",\n \"lotimes\":\"⨴\",\n \"rotimes\":\"⨵\",\n \"otimesas\":\"⨶\",\n \"Otimes\":\"⨷\",\n \"odiv\":\"⨸\",\n \"triplus\":\"⨹\",\n \"triminus\":\"⨺\",\n \"tritime\":\"⨻\",\n \"intprod\":\"⨼\",\n \"iprod\":\"⨼\",\n \"amalg\":\"⨿\",\n \"capdot\":\"⩀\",\n \"ncup\":\"⩂\",\n \"ncap\":\"⩃\",\n \"capand\":\"⩄\",\n \"cupor\":\"⩅\",\n \"cupcap\":\"⩆\",\n \"capcup\":\"⩇\",\n \"cupbrcap\":\"⩈\",\n \"capbrcup\":\"⩉\",\n \"cupcup\":\"⩊\",\n \"capcap\":\"⩋\",\n \"ccups\":\"⩌\",\n \"ccaps\":\"⩍\",\n \"ccupssm\":\"⩐\",\n \"And\":\"⩓\",\n \"Or\":\"⩔\",\n \"andand\":\"⩕\",\n \"oror\":\"⩖\",\n \"orslope\":\"⩗\",\n \"andslope\":\"⩘\",\n \"andv\":\"⩚\",\n \"orv\":\"⩛\",\n \"andd\":\"⩜\",\n \"ord\":\"⩝\",\n \"wedbar\":\"⩟\",\n \"sdote\":\"⩦\",\n \"simdot\":\"⩪\",\n \"congdot\":\"⩭\",\n \"ncongdot\":\"⩭̸\",\n \"easter\":\"⩮\",\n \"apacir\":\"⩯\",\n \"apE\":\"⩰\",\n \"nape\":\"⩰̸\",\n \"eplus\":\"⩱\",\n \"pluse\":\"⩲\",\n \"Esim\":\"⩳\",\n \"ddotseq\":\"⩷\",\n \"eddot\":\"⩷\",\n \"equivdd\":\"⩸\",\n \"ltcir\":\"⩹\",\n \"gtcir\":\"⩺\",\n \"ltquest\":\"⩻\",\n \"gtquest\":\"⩼\",\n \"leqslant\":\"⩽\",\n \"les\":\"⩽\",\n \"lessslantequal\":\"⩽\",\n \"nleqslant\":\"⩽̸\",\n \"nles\":\"⩽̸\",\n \"notlessslantequal\":\"⩽̸\",\n \"geqslant\":\"⩾\",\n \"ges\":\"⩾\",\n \"greaterslantequal\":\"⩾\",\n \"ngeqslant\":\"⩾̸\",\n \"nges\":\"⩾̸\",\n \"notgreaterslantequal\":\"⩾̸\",\n \"lesdot\":\"⩿\",\n \"gesdot\":\"⪀\",\n \"lesdoto\":\"⪁\",\n \"gesdoto\":\"⪂\",\n \"lesdotor\":\"⪃\",\n \"gesdotol\":\"⪄\",\n \"lap\":\"⪅\",\n \"lessapprox\":\"⪅\",\n \"gap\":\"⪆\",\n \"gtrapprox\":\"⪆\",\n \"lne\":\"⪇\",\n \"lneq\":\"⪇\",\n \"gne\":\"⪈\",\n \"gneq\":\"⪈\",\n \"lnap\":\"⪉\",\n \"lnapprox\":\"⪉\",\n \"gnap\":\"⪊\",\n \"gnapprox\":\"⪊\",\n \"lEg\":\"⪋\",\n \"lesseqqgtr\":\"⪋\",\n \"gEl\":\"⪌\",\n \"gtreqqless\":\"⪌\",\n \"lsime\":\"⪍\",\n \"gsime\":\"⪎\",\n \"lsimg\":\"⪏\",\n \"gsiml\":\"⪐\",\n \"lge\":\"⪑\",\n \"gle\":\"⪒\",\n \"lesges\":\"⪓\",\n \"gesles\":\"⪔\",\n \"els\":\"⪕\",\n \"eqslantless\":\"⪕\",\n \"egs\":\"⪖\",\n \"eqslantgtr\":\"⪖\",\n \"elsdot\":\"⪗\",\n \"egsdot\":\"⪘\",\n \"el\":\"⪙\",\n \"eg\":\"⪚\",\n \"siml\":\"⪝\",\n \"simg\":\"⪞\",\n \"simle\":\"⪟\",\n \"simge\":\"⪠\",\n \"lessless\":\"⪡\",\n \"notnestedlessless\":\"⪡̸\",\n \"greatergreater\":\"⪢\",\n \"notnestedgreatergreater\":\"⪢̸\",\n \"glj\":\"⪤\",\n \"gla\":\"⪥\",\n \"ltcc\":\"⪦\",\n \"gtcc\":\"⪧\",\n \"lescc\":\"⪨\",\n \"gescc\":\"⪩\",\n \"smt\":\"⪪\",\n \"lat\":\"⪫\",\n \"smte\":\"⪬\",\n \"smtes\":\"⪬︀\",\n \"late\":\"⪭\",\n \"lates\":\"⪭︀\",\n \"bumpE\":\"⪮\",\n \"pre\":\"⪯\",\n \"precedesequal\":\"⪯\",\n \"preceq\":\"⪯\",\n \"notprecedesequal\":\"⪯̸\",\n \"npre\":\"⪯̸\",\n \"npreceq\":\"⪯̸\",\n \"sce\":\"⪰\",\n \"succeedsequal\":\"⪰\",\n \"succeq\":\"⪰\",\n \"notsucceedsequal\":\"⪰̸\",\n \"nsce\":\"⪰̸\",\n \"nsucceq\":\"⪰̸\",\n \"prE\":\"⪳\",\n \"scE\":\"⪴\",\n \"precneqq\":\"⪵\",\n \"prne\":\"⪵\",\n \"scne\":\"⪶\",\n \"succneqq\":\"⪶\",\n \"prap\":\"⪷\",\n \"precapprox\":\"⪷\",\n \"scap\":\"⪸\",\n \"succapprox\":\"⪸\",\n \"precnapprox\":\"⪹\",\n \"prnap\":\"⪹\",\n \"scnap\":\"⪺\",\n \"succnapprox\":\"⪺\",\n \"Pr\":\"⪻\",\n \"Sc\":\"⪼\",\n \"subdot\":\"⪽\",\n \"supdot\":\"⪾\",\n \"subplus\":\"⪿\",\n \"supplus\":\"⫀\",\n \"submult\":\"⫁\",\n \"supmult\":\"⫂\",\n \"subedot\":\"⫃\",\n \"supedot\":\"⫄\",\n \"subE\":\"⫅\",\n \"subseteqq\":\"⫅\",\n \"nsubE\":\"⫅̸\",\n \"nsubseteqq\":\"⫅̸\",\n \"supE\":\"⫆\",\n \"supseteqq\":\"⫆\",\n \"nsupE\":\"⫆̸\",\n \"nsupseteqq\":\"⫆̸\",\n \"subsim\":\"⫇\",\n \"supsim\":\"⫈\",\n \"subnE\":\"⫋\",\n \"subsetneqq\":\"⫋\",\n \"varsubsetneqq\":\"⫋︀\",\n \"vsubnE\":\"⫋︀\",\n \"supnE\":\"⫌\",\n \"supsetneqq\":\"⫌\",\n \"varsupsetneqq\":\"⫌︀\",\n \"vsupnE\":\"⫌︀\",\n \"csub\":\"⫏\",\n \"csup\":\"⫐\",\n \"csube\":\"⫑\",\n \"csupe\":\"⫒\",\n \"subsup\":\"⫓\",\n \"supsub\":\"⫔\",\n \"subsub\":\"⫕\",\n \"supsup\":\"⫖\",\n \"suphsub\":\"⫗\",\n \"supdsub\":\"⫘\",\n \"forkv\":\"⫙\",\n \"topfork\":\"⫚\",\n \"mlcp\":\"⫛\",\n \"Dashv\":\"⫤\",\n \"doublelefttee\":\"⫤\",\n \"vdashl\":\"⫦\",\n \"barv\":\"⫧\",\n \"vbar\":\"⫨\",\n \"vbarv\":\"⫩\",\n \"Vbar\":\"⫫\",\n \"Not\":\"⫬\",\n \"bNot\":\"⫭\",\n \"rnmid\":\"⫮\",\n \"cirmid\":\"⫯\",\n \"midcir\":\"⫰\",\n \"topcir\":\"⫱\",\n \"nhpar\":\"⫲\",\n \"parsim\":\"⫳\",\n \"parsl\":\"⫽\",\n \"nparsl\":\"⫽⃥\",\n \"flat\":\"♭\",\n \"natur\":\"♮\",\n \"natural\":\"♮\",\n \"sharp\":\"♯\",\n \"curren\":\"¤\",\n \"cent\":\"¢\",\n \"dollar\":\"$\",\n \"pound\":\"£\",\n \"yen\":\"¥\",\n \"euro\":\"€\",\n \"sup1\":\"¹\",\n \"frac12\":\"½\",\n \"half\":\"½\",\n \"frac13\":\"⅓\",\n \"frac14\":\"¼\",\n \"frac15\":\"⅕\",\n \"frac16\":\"⅙\",\n \"frac18\":\"⅛\",\n \"sup2\":\"²\",\n \"frac23\":\"⅔\",\n \"frac25\":\"⅖\",\n \"sup3\":\"³\",\n \"frac34\":\"¾\",\n \"frac35\":\"⅗\",\n \"frac38\":\"⅜\",\n \"frac45\":\"⅘\",\n \"frac56\":\"⅚\",\n \"frac58\":\"⅝\",\n \"frac78\":\"⅞\",\n \"afr\":\"𝔞\",\n \"aopf\":\"𝕒\",\n \"ascr\":\"𝒶\",\n \"Afr\":\"𝔄\",\n \"Aopf\":\"𝔸\",\n \"Ascr\":\"𝒜\",\n \"ordf\":\"ª\",\n \"aacute\":\"á\",\n \"Aacute\":\"Á\",\n \"agrave\":\"à\",\n \"Agrave\":\"À\",\n \"abreve\":\"ă\",\n \"Abreve\":\"Ă\",\n \"acirc\":\"â\",\n \"Acirc\":\"Â\",\n \"aring\":\"å\",\n \"angst\":\"Å\",\n \"Aring\":\"Å\",\n \"auml\":\"ä\",\n \"Auml\":\"Ä\",\n \"atilde\":\"ã\",\n \"Atilde\":\"Ã\",\n \"aogon\":\"ą\",\n \"Aogon\":\"Ą\",\n \"amacr\":\"ā\",\n \"Amacr\":\"Ā\",\n \"aelig\":\"Æ\",\n \"AElig\":\"Æ\",\n \"bfr\":\"𝔟\",\n \"bopf\":\"𝕓\",\n \"bscr\":\"𝒷\",\n \"bernou\":\"ℬ\",\n \"bernoullis\":\"ℬ\",\n \"Bfr\":\"𝔅\",\n \"Bopf\":\"𝔹\",\n \"Bscr\":\"ℬ\",\n \"cfr\":\"𝔠\",\n \"copf\":\"𝕔\",\n \"cscr\":\"𝒸\",\n \"cayleys\":\"ℭ\",\n \"Cfr\":\"ℭ\",\n \"complexes\":\"ℂ\",\n \"Copf\":\"ℂ\",\n \"Cscr\":\"𝒞\",\n \"cacute\":\"ć\",\n \"Cacute\":\"Ć\",\n \"ccirc\":\"ĉ\",\n \"Ccirc\":\"Ĉ\",\n \"ccaron\":\"č\",\n \"Ccaron\":\"Č\",\n \"cdot\":\"ċ\",\n \"Cdot\":\"Ċ\",\n \"ccedil\":\"ç\",\n \"Ccedil\":\"Ç\",\n \"incare\":\"℅\",\n \"dfr\":\"𝔡\",\n \"differentiald\":\"ⅆ\",\n \"dopf\":\"𝕕\",\n \"dscr\":\"𝒹\",\n \"capitaldifferentiald\":\"ⅅ\",\n \"dd\":\"ⅅ\",\n \"DD\":\"ⅅ\",\n \"Dfr\":\"𝔇\",\n \"Dopf\":\"𝔻\",\n \"Dscr\":\"𝒟\",\n \"dcaron\":\"ď\",\n \"Dcaron\":\"Ď\",\n \"dstrok\":\"đ\",\n \"Dstrok\":\"Đ\",\n \"eth\":\"ð\",\n \"ETH\":\"Ð\",\n \"ee\":\"ⅇ\",\n \"efr\":\"𝔢\",\n \"eopf\":\"𝕖\",\n \"escr\":\"ℯ\",\n \"exponentiale\":\"ⅇ\",\n \"Efr\":\"𝔈\",\n \"Eopf\":\"𝔼\",\n \"Escr\":\"ℰ\",\n \"expectation\":\"ℰ\",\n \"eacute\":\"é\",\n \"Eacute\":\"É\",\n \"egrave\":\"è\",\n \"Egrave\":\"È\",\n \"ecirc\":\"ê\",\n \"Ecirc\":\"Ê\",\n \"ecaron\":\"ě\",\n \"Ecaron\":\"Ě\",\n \"euml\":\"ë\",\n \"Euml\":\"Ë\",\n \"edot\":\"ė\",\n \"Edot\":\"Ė\",\n \"eogon\":\"ę\",\n \"Eogon\":\"Ę\",\n \"emacr\":\"ē\",\n \"Emacr\":\"Ē\",\n \"ffr\":\"𝔣\",\n \"fopf\":\"𝕗\",\n \"fscr\":\"𝒻\",\n \"Ffr\":\"𝔉\",\n \"Fopf\":\"𝔽\",\n \"fouriertrf\":\"ℱ\",\n \"Fscr\":\"ℱ\",\n \"fflig\":\"ff\",\n \"ffilig\":\"ffi\",\n \"ffllig\":\"ffl\",\n \"filig\":\"fi\",\n \"fjlig\":\"fj\",\n \"fllig\":\"fl\",\n \"fnof\":\"ƒ\",\n \"gfr\":\"𝔤\",\n \"gopf\":\"𝕘\",\n \"gscr\":\"ℊ\",\n \"Gfr\":\"𝔊\",\n \"Gopf\":\"𝔾\",\n \"Gscr\":\"𝒢\",\n \"gacute\":\"ǵ\",\n \"gbreve\":\"ğ\",\n \"Gbreve\":\"Ğ\",\n \"gcirc\":\"ĝ\",\n \"Gcirc\":\"Ĝ\",\n \"gdot\":\"ġ\",\n \"Gdot\":\"Ġ\",\n \"gcedil\":\"Ģ\",\n \"hfr\":\"𝔥\",\n \"hopf\":\"𝕙\",\n \"hscr\":\"𝒽\",\n \"planckh\":\"ℎ\",\n \"hamilt\":\"ℋ\",\n \"Hfr\":\"ℌ\",\n \"hilbertspace\":\"ℋ\",\n \"Hopf\":\"ℍ\",\n \"Hscr\":\"ℋ\",\n \"poincareplane\":\"ℌ\",\n \"quaternions\":\"ℍ\",\n \"hcirc\":\"ĥ\",\n \"Hcirc\":\"Ĥ\",\n \"hbar\":\"ℏ\",\n \"hslash\":\"ℏ\",\n \"hstrok\":\"ħ\",\n \"planck\":\"ℏ\",\n \"plankv\":\"ℏ\",\n \"Hstrok\":\"Ħ\",\n \"ifr\":\"𝔦\",\n \"ii\":\"ⅈ\",\n \"imaginaryi\":\"ⅈ\",\n \"iopf\":\"𝕚\",\n \"iscr\":\"𝒾\",\n \"Ifr\":\"ℑ\",\n \"im\":\"ℑ\",\n \"image\":\"ℑ\",\n \"imagline\":\"ℐ\",\n \"imagpart\":\"ℑ\",\n \"Iopf\":\"𝕀\",\n \"Iscr\":\"ℐ\",\n \"iacute\":\"í\",\n \"Iacute\":\"Í\",\n \"igrave\":\"ì\",\n \"Igrave\":\"Ì\",\n \"icirc\":\"î\",\n \"Icirc\":\"Î\",\n \"iuml\":\"ï\",\n \"Iuml\":\"Ï\",\n \"itilde\":\"ĩ\",\n \"Itilde\":\"Ĩ\",\n \"idot\":\"İ\",\n \"iogon\":\"į\",\n \"Iogon\":\"Į\",\n \"imacr\":\"ī\",\n \"Imacr\":\"Ī\",\n \"ijlig\":\"IJ\",\n \"IJlig\":\"IJ\",\n \"imath\":\"ı\",\n \"inodot\":\"ı\",\n \"jfr\":\"𝔧\",\n \"jopf\":\"𝕛\",\n \"jscr\":\"𝒿\",\n \"Jfr\":\"𝔍\",\n \"Jopf\":\"𝕁\",\n \"Jscr\":\"𝒥\",\n \"jcirc\":\"ĵ\",\n \"Jcirc\":\"Ĵ\",\n \"jmath\":\"ȷ\",\n \"kfr\":\"𝔨\",\n \"kopf\":\"𝕜\",\n \"kscr\":\"𝓀\",\n \"Kfr\":\"𝔎\",\n \"Kopf\":\"𝕂\",\n \"Kscr\":\"𝒦\",\n \"kcedil\":\"ķ\",\n \"Kcedil\":\"Ķ\",\n \"ell\":\"ℓ\",\n \"lfr\":\"𝔩\",\n \"lopf\":\"𝕝\",\n \"lscr\":\"𝓁\",\n \"lagran\":\"ℒ\",\n \"laplacetrf\":\"ℒ\",\n \"Lfr\":\"𝔏\",\n \"Lopf\":\"𝕃\",\n \"Lscr\":\"ℒ\",\n \"lacute\":\"ĺ\",\n \"Lacute\":\"Ĺ\",\n \"lcaron\":\"ľ\",\n \"Lcaron\":\"Ľ\",\n \"lcedil\":\"ļ\",\n \"Lcedil\":\"Ļ\",\n \"lstrok\":\"ł\",\n \"Lstrok\":\"Ł\",\n \"lmidot\":\"ŀ\",\n \"Lmidot\":\"Ŀ\",\n \"mfr\":\"𝔪\",\n \"mopf\":\"𝕞\",\n \"mscr\":\"𝓂\",\n \"mellintrf\":\"ℳ\",\n \"Mfr\":\"𝔐\",\n \"Mopf\":\"𝕄\",\n \"Mscr\":\"ℳ\",\n \"phmmat\":\"ℳ\",\n \"nfr\":\"𝔫\",\n \"nopf\":\"𝕟\",\n \"nscr\":\"𝓃\",\n \"naturals\":\"ℕ\",\n \"Nfr\":\"𝔑\",\n \"Nopf\":\"ℕ\",\n \"Nscr\":\"𝒩\",\n \"nacute\":\"ń\",\n \"Nacute\":\"Ń\",\n \"ncaron\":\"ň\",\n \"Ncaron\":\"Ň\",\n \"ntilde\":\"ñ\",\n \"Ntilde\":\"Ñ\",\n \"ncedil\":\"ņ\",\n \"Ncedil\":\"Ņ\",\n \"numero\":\"№\",\n \"eng\":\"ŋ\",\n \"ENG\":\"Ŋ\",\n \"ofr\":\"𝔬\",\n \"oopf\":\"𝕠\",\n \"order\":\"ℴ\",\n \"orderof\":\"ℴ\",\n \"oscr\":\"ℴ\",\n \"Ofr\":\"𝔒\",\n \"Oopf\":\"𝕆\",\n \"Oscr\":\"𝒪\",\n \"ordm\":\"º\",\n \"oacute\":\"ó\",\n \"Oacute\":\"Ó\",\n \"ograve\":\"ò\",\n \"Ograve\":\"Ò\",\n \"ocirc\":\"ô\",\n \"Ocirc\":\"Ô\",\n \"ouml\":\"ö\",\n \"Ouml\":\"Ö\",\n \"odblac\":\"ő\",\n \"Odblac\":\"Ő\",\n \"otilde\":\"õ\",\n \"Otilde\":\"Õ\",\n \"oslash\":\"ø\",\n \"Oslash\":\"Ø\",\n \"omacr\":\"ō\",\n \"Omacr\":\"Ō\",\n \"oelig\":\"Œ\",\n \"OElig\":\"Œ\",\n \"pfr\":\"𝔭\",\n \"popf\":\"𝕡\",\n \"pscr\":\"𝓅\",\n \"Pfr\":\"𝔓\",\n \"Popf\":\"ℙ\",\n \"primes\":\"ℙ\",\n \"Pscr\":\"𝒫\",\n \"qfr\":\"𝔮\",\n \"qopf\":\"𝕢\",\n \"qscr\":\"𝓆\",\n \"Qfr\":\"𝔔\",\n \"Qopf\":\"ℚ\",\n \"Qscr\":\"𝒬\",\n \"rationals\":\"ℚ\",\n \"kgreen\":\"ĸ\",\n \"rfr\":\"𝔯\",\n \"ropf\":\"𝕣\",\n \"rscr\":\"𝓇\",\n \"re\":\"ℜ\",\n \"real\":\"ℜ\",\n \"realine\":\"ℛ\",\n \"realpart\":\"ℜ\",\n \"reals\":\"ℝ\",\n \"Rfr\":\"ℜ\",\n \"Ropf\":\"ℝ\",\n \"Rscr\":\"ℛ\",\n \"racute\":\"ŕ\",\n \"Racute\":\"Ŕ\",\n \"rcaron\":\"ř\",\n \"Rcaron\":\"Ř\",\n \"rcedil\":\"ŗ\",\n \"Rcedil\":\"Ŗ\",\n \"sfr\":\"𝔰\",\n \"sopf\":\"𝕤\",\n \"sscr\":\"𝓈\",\n \"Sfr\":\"𝔖\",\n \"Sopf\":\"𝕊\",\n \"Sscr\":\"𝒮\",\n \"circleds\":\"Ⓢ\",\n \"os\":\"Ⓢ\",\n \"sacute\":\"ś\",\n \"Sacute\":\"Ś\",\n \"scirc\":\"ŝ\",\n \"Scirc\":\"Ŝ\",\n \"scaron\":\"š\",\n \"Scaron\":\"Š\",\n \"scedil\":\"ş\",\n \"Scedil\":\"Ş\",\n \"szlig\":\"ß\",\n \"tfr\":\"𝔱\",\n \"topf\":\"𝕥\",\n \"tscr\":\"𝓉\",\n \"Tfr\":\"𝔗\",\n \"Topf\":\"𝕋\",\n \"Tscr\":\"𝒯\",\n \"tcaron\":\"ť\",\n \"Tcaron\":\"Ť\",\n \"tcedil\":\"ţ\",\n \"Tcedil\":\"Ţ\",\n \"trade\":\"™\",\n \"tstrok\":\"ŧ\",\n \"Tstrok\":\"Ŧ\",\n \"ufr\":\"𝔲\",\n \"uopf\":\"𝕦\",\n \"uscr\":\"𝓊\",\n \"Ufr\":\"𝔘\",\n \"Uopf\":\"𝕌\",\n \"Uscr\":\"𝒰\",\n \"uacute\":\"ú\",\n \"Uacute\":\"Ú\",\n \"ugrave\":\"ù\",\n \"Ugrave\":\"Ù\",\n \"ubreve\":\"ŭ\",\n \"Ubreve\":\"Ŭ\",\n \"ucirc\":\"û\",\n \"Ucirc\":\"Û\",\n \"uring\":\"ů\",\n \"Uring\":\"Ů\",\n \"uuml\":\"ü\",\n \"Uuml\":\"Ü\",\n \"udblac\":\"ű\",\n \"Udblac\":\"Ű\",\n \"utilde\":\"ũ\",\n \"Utilde\":\"Ũ\",\n \"uogon\":\"ų\",\n \"Uogon\":\"Ų\",\n \"umacr\":\"ū\",\n \"Umacr\":\"Ū\",\n \"vfr\":\"𝔳\",\n \"vopf\":\"𝕧\",\n \"vscr\":\"𝓋\",\n \"Vfr\":\"𝔙\",\n \"Vopf\":\"𝕍\",\n \"Vscr\":\"𝒱\",\n \"wfr\":\"𝔴\",\n \"wopf\":\"𝕨\",\n \"wscr\":\"𝓌\",\n \"Wfr\":\"𝔚\",\n \"Wopf\":\"𝕎\",\n \"Wscr\":\"𝒲\",\n \"wcirc\":\"ŵ\",\n \"Wcirc\":\"Ŵ\",\n \"xfr\":\"𝔵\",\n \"xopf\":\"𝕩\",\n \"xscr\":\"𝓍\",\n \"Xfr\":\"𝔛\",\n \"Xopf\":\"𝕏\",\n \"Xscr\":\"𝒳\",\n \"yfr\":\"𝔶\",\n \"yopf\":\"𝕪\",\n \"yscr\":\"𝓎\",\n \"Yfr\":\"𝔜\",\n \"Yopf\":\"𝕐\",\n \"Yscr\":\"𝒴\",\n \"yacute\":\"ý\",\n \"Yacute\":\"Ý\",\n \"ycirc\":\"ŷ\",\n \"Ycirc\":\"Ŷ\",\n \"yuml\":\"ÿ\",\n \"Yuml\":\"Ÿ\",\n \"zfr\":\"𝔷\",\n \"zopf\":\"𝕫\",\n \"zscr\":\"𝓏\",\n \"integers\":\"ℤ\",\n \"zeetrf\":\"ℨ\",\n \"Zfr\":\"ℨ\",\n \"Zopf\":\"ℤ\",\n \"Zscr\":\"𝒵\",\n \"zacute\":\"ź\",\n \"Zacute\":\"Ź\",\n \"zcaron\":\"ž\",\n \"Zcaron\":\"Ž\",\n \"zdot\":\"ż\",\n \"Zdot\":\"Ż\",\n \"imped\":\"Ƶ\",\n \"thorn\":\"þ\",\n \"THORN\":\"Þ\",\n \"napos\":\"ʼn\",\n \"alpha\":\"α\",\n \"Alpha\":\"Α\",\n \"beta\":\"β\",\n \"Beta\":\"Β\",\n \"gamma\":\"γ\",\n \"Gamma\":\"Γ\",\n \"delta\":\"δ\",\n \"Delta\":\"Δ\",\n \"epsi\":\"ε\",\n \"epsilon\":\"ε\",\n \"epsiv\":\"ϵ\",\n \"straightepsilon\":\"ϵ\",\n \"varepsilon\":\"ϵ\",\n \"Epsilon\":\"Ε\",\n \"digamma\":\"ϝ\",\n \"gammad\":\"ϝ\",\n \"Gammad\":\"Ϝ\",\n \"zeta\":\"ζ\",\n \"Zeta\":\"Ζ\",\n \"eta\":\"η\",\n \"Eta\":\"Η\",\n \"theta\":\"θ\",\n \"thetasym\":\"ϑ\",\n \"thetav\":\"ϑ\",\n \"vartheta\":\"ϑ\",\n \"Theta\":\"Θ\",\n \"iota\":\"ι\",\n \"Iota\":\"Ι\",\n \"kappa\":\"κ\",\n \"kappav\":\"ϰ\",\n \"varkappa\":\"ϰ\",\n \"Kappa\":\"Κ\",\n \"lambda\":\"λ\",\n \"Lambda\":\"Λ\",\n \"mu\":\"μ\",\n \"micro\":\"µ\",\n \"Mu\":\"Μ\",\n \"nu\":\"ν\",\n \"Nu\":\"Ν\",\n \"xi\":\"ξ\",\n \"Xi\":\"Ξ\",\n \"omicron\":\"ο\",\n \"Omicron\":\"Ο\",\n \"pi\":\"π\",\n \"piv\":\"ϖ\",\n \"varpi\":\"ϖ\",\n \"Pi\":\"Π\",\n \"rho\":\"ρ\",\n \"rhov\":\"ϱ\",\n \"varrho\":\"ϱ\",\n \"Rho\":\"Ρ\",\n \"sigma\":\"σ\",\n \"Sigma\":\"Σ\",\n \"sigmaf\":\"ς\",\n \"sigmav\":\"ς\",\n \"varsigma\":\"ς\",\n \"tau\":\"τ\",\n \"Tau\":\"Τ\",\n \"upsi\":\"υ\",\n \"upsilon\":\"υ\",\n \"Upsilon\":\"Υ\",\n \"Upsi\":\"ϒ\",\n \"upsih\":\"ϒ\",\n \"phi\":\"φ\",\n \"phiv\":\"ϕ\",\n \"straightphi\":\"ϕ\",\n \"varphi\":\"ϕ\",\n \"Phi\":\"Φ\",\n \"chi\":\"χ\",\n \"Chi\":\"Χ\",\n \"psi\":\"ψ\",\n \"Psi\":\"Ψ\",\n \"omega\":\"ω\",\n \"ohm\":\"Ω\",\n \"Omega\":\"Ω\",\n \"acy\":\"а\",\n \"Acy\":\"А\",\n \"bcy\":\"б\",\n \"Bcy\":\"Б\",\n \"vcy\":\"в\",\n \"Vcy\":\"В\",\n \"gcy\":\"г\",\n \"Gcy\":\"Г\",\n \"gjcy\":\"Ѓ\",\n \"GJcy\":\"Ѓ\",\n \"dcy\":\"д\",\n \"Dcy\":\"Д\",\n \"djcy\":\"Ђ\",\n \"DJcy\":\"Ђ\",\n \"iecy\":\"Е\",\n \"IEcy\":\"Е\",\n \"iocy\":\"Ё\",\n \"IOcy\":\"Ё\",\n \"jukcy\":\"є\",\n \"Jukcy\":\"Є\",\n \"zhcy\":\"Ж\",\n \"ZHcy\":\"Ж\",\n \"zcy\":\"з\",\n \"Zcy\":\"З\",\n \"dscy\":\"Ѕ\",\n \"DScy\":\"Ѕ\",\n \"icy\":\"и\",\n \"Icy\":\"И\",\n \"iukcy\":\"і\",\n \"Iukcy\":\"І\",\n \"yicy\":\"Ї\",\n \"YIcy\":\"Ї\",\n \"jcy\":\"й\",\n \"Jcy\":\"Й\",\n \"jsercy\":\"ј\",\n \"Jsercy\":\"Ј\",\n \"kcy\":\"к\",\n \"Kcy\":\"К\",\n \"kjcy\":\"Ќ\",\n \"KJcy\":\"Ќ\",\n \"lcy\":\"л\",\n \"Lcy\":\"Л\",\n \"ljcy\":\"Љ\",\n \"LJcy\":\"Љ\",\n \"mcy\":\"м\",\n \"Mcy\":\"М\",\n \"ncy\":\"н\",\n \"Ncy\":\"Н\",\n \"njcy\":\"Њ\",\n \"NJcy\":\"Њ\",\n \"ocy\":\"о\",\n \"Ocy\":\"О\",\n \"pcy\":\"п\",\n \"Pcy\":\"П\",\n \"rcy\":\"р\",\n \"Rcy\":\"Р\",\n \"scy\":\"с\",\n \"Scy\":\"С\",\n \"tcy\":\"т\",\n \"Tcy\":\"Т\",\n \"tshcy\":\"ћ\",\n \"TSHcy\":\"Ћ\",\n \"ucy\":\"у\",\n \"Ucy\":\"У\",\n \"ubrcy\":\"ў\",\n \"Ubrcy\":\"Ў\",\n \"fcy\":\"ф\",\n \"Fcy\":\"Ф\",\n \"khcy\":\"Х\",\n \"KHcy\":\"Х\",\n \"tscy\":\"Ц\",\n \"TScy\":\"Ц\",\n \"chcy\":\"Ч\",\n \"CHcy\":\"Ч\",\n \"dzcy\":\"Џ\",\n \"DZcy\":\"Џ\",\n \"shcy\":\"Ш\",\n \"SHcy\":\"Ш\",\n \"shchcy\":\"щ\",\n \"SHCHcy\":\"Щ\",\n \"hardcy\":\"ъ\",\n \"HARDcy\":\"Ъ\",\n \"ycy\":\"ы\",\n \"Ycy\":\"Ы\",\n \"softcy\":\"ь\",\n \"SOFTcy\":\"Ь\",\n \"ecy\":\"э\",\n \"Ecy\":\"Э\",\n \"yucy\":\"Ю\",\n \"YUcy\":\"Ю\",\n \"yacy\":\"Я\",\n \"YAcy\":\"Я\",\n \"alefsym\":\"ℵ\",\n \"aleph\":\"ℵ\",\n \"beth\":\"ℶ\",\n \"gimel\":\"ℷ\",\n \"daleth\":\"ℸ\"\n}\n",
|
|
7
7
|
"// Character codes\nexport const CHAR_SPACE = 32\nexport const CHAR_TAB = 9\nexport const CHAR_CR = 13\nexport const CHAR_NEWLINE = 10\nexport const CHAR_BACKTICK = 96\nexport const CHAR_TILDE = 126\nexport const CHAR_BRACKET_OPEN = 91\nexport const CHAR_CARET = 94\nexport const CHAR_GT = 62\nexport const CHAR_HASH = 35\nexport const CHAR_PERCENT = 37\nexport const CHAR_DASH = 45\nexport const CHAR_EQ = 61\nexport const CHAR_BACKSLASH = 92\nexport const CHAR_ASTERISK = 42\nexport const CHAR_UNDERSCORE = 95\nexport const CHAR_LT = 60\nexport const CHAR_AT = 64\nexport const CHAR_BRACKET_CLOSE = 93\nexport const CHAR_EXCLAMATION = 33\nexport const CHAR_AMPERSAND = 38\nexport const CHAR_COLON = 58\nexport const CHAR_F = 70\nexport const CHAR_f = 102\nexport const CHAR_H = 104\nexport const CHAR_W = 119\nexport const CHAR_t = 116\nexport const CHAR_p = 112\nexport const CHAR_s = 115\nexport const CHAR_NBSP = 160\nexport const CHAR_FF = 12\nexport const CHAR_COMMA = 44\nexport const CHAR_SEMICOLON = 59\nexport const CHAR_QUESTION = 63\nexport const CHAR_PERIOD = 46\nexport const CHAR_SLASH = 47\nexport const CHAR_SINGLE_QUOTE = 39\nexport const CHAR_DOUBLE_QUOTE = 34\nexport const CHAR_PLUS = 43\nexport const CHAR_PIPE = 124\nexport const CHAR_BRACE_OPEN = 123 // {\nexport const CHAR_BRACE_CLOSE = 125 // }\nexport const CHAR_x = 120\nexport const CHAR_X = 88\n// Character code ranges for common character classes\nexport const CHAR_DIGIT_0 = 48\nexport const CHAR_DIGIT_9 = 57\nexport const CHAR_A = 65\nexport const CHAR_Z = 90\nexport const CHAR_a = 97\nexport const CHAR_z = 122\nexport const CHAR_ASCII_BOUNDARY = 128\n// Case conversion offset: difference between uppercase and lowercase ASCII letters\nexport const CHAR_CASE_OFFSET = 32 // 'A' (65) to 'a' (97) = 32\n",
|
|
8
8
|
"import { NAMED_CODES_TO_UNICODE as util } from './entities.generated'\nimport * as $ from './constants'\n\n// Parse frontmatter bounds and validate YAML\nexport function parseFrontmatterBounds(\n input: string\n): { endPos: number; hasValidYaml: boolean } | null {\n if (!startsWith(input, '---')) return null\n let pos = 3\n while (pos < input.length && (input[pos] === ' ' || input[pos] === '\\t'))\n pos++\n if (pos >= input.length || input[pos] !== '\\n') return null\n pos++\n\n let hasValidYaml = false\n while (pos < input.length) {\n const lineStart = pos\n while (pos < input.length && input[pos] !== '\\n') pos++\n if (pos >= input.length) break\n const lineEnd = pos++\n if (startsWith(input, '---', lineStart))\n return { endPos: pos, hasValidYaml }\n // Check if line contains ':' anywhere\n // OPTIMIZATION: Use indexOf directly to avoid slice allocation\n const colonIndex = input.indexOf(':', lineStart)\n if (colonIndex !== -1 && colonIndex < lineEnd) hasValidYaml = true\n }\n return null\n}\n\n/**\n * Named HTML entity codes to unicode character mapping\n * Pre-computed from generated entity set\n * Numeric references ({ and «) are fully supported without any mapping.\n * Unknown named entities pass through as literal text (CommonMark-compliant).\n */\nexport const NAMED_CODES_TO_UNICODE: Record<string, string> = util\n\n/**\n * Regex for matching HTML character references (&entity; or { or «)\n * Matches: & followed by entity name or # followed by decimal or hex digits, ending with ;\n */\nexport const HTML_CHAR_CODE_R: RegExp =\n /&([a-zA-Z0-9]+|#[0-9]{1,7}|#x[0-9a-fA-F]{1,6});/gi\n\n/**\n * Regex for determining if markdown content should be rendered as block-level\n * Matches: newlines, list items, headings, indented content, thematic breaks, blockquotes\n */\n// Mapping of lowercase HTML attributes to JSX prop names\n// Shared between React and Solid renderers (Vue uses HTML attributes directly)\nexport const HTML_TO_JSX_MAP: Record<string, string> = {\n class: 'className',\n for: 'htmlFor',\n allowfullscreen: 'allowFullScreen',\n allowtransparency: 'allowTransparency',\n autocomplete: 'autoComplete',\n autofocus: 'autoFocus',\n autoplay: 'autoPlay',\n cellpadding: 'cellPadding',\n cellspacing: 'cellSpacing',\n charset: 'charSet',\n classid: 'classId',\n colspan: 'colSpan',\n contenteditable: 'contentEditable',\n contextmenu: 'contextMenu',\n crossorigin: 'crossOrigin',\n enctype: 'encType',\n formaction: 'formAction',\n formenctype: 'formEncType',\n formmethod: 'formMethod',\n formnovalidate: 'formNoValidate',\n formtarget: 'formTarget',\n frameborder: 'frameBorder',\n hreflang: 'hrefLang',\n inputmode: 'inputMode',\n keyparams: 'keyParams',\n keytype: 'keyType',\n marginheight: 'marginHeight',\n marginwidth: 'marginWidth',\n maxlength: 'maxLength',\n mediagroup: 'mediaGroup',\n minlength: 'minLength',\n novalidate: 'noValidate',\n radiogroup: 'radioGroup',\n readonly: 'readOnly',\n rowspan: 'rowSpan',\n spellcheck: 'spellCheck',\n srcdoc: 'srcDoc',\n srclang: 'srcLang',\n srcset: 'srcSet',\n tabindex: 'tabIndex',\n usemap: 'useMap',\n}\n\n/**\n * Convert HTML attributes to JSX props\n * Maps HTML attribute names (e.g., \"class\", \"for\") to JSX prop names (e.g., \"className\", \"htmlFor\")\n */\nexport function htmlAttrsToJSXProps(\n attrs: Record<string, any>\n): Record<string, any> {\n var jsxProps: Record<string, any> = {}\n\n for (var key in attrs) {\n var keyLower = key.toLowerCase()\n var mappedKey = HTML_TO_JSX_MAP[keyLower]\n jsxProps[mappedKey || key] = attrs[key]\n }\n\n return jsxProps\n}\n\nexport const SHOULD_RENDER_AS_BLOCK_R: RegExp =\n /(\\n|^[-*]\\s|^#|^ {2,}|^-{2,}|^>\\s)/\n\n/**\n * Decode HTML entity references to Unicode characters\n */\nexport function decodeEntityReferences(text: string): string {\n if (text.indexOf('&') === -1) return text\n\n return text.replace(HTML_CHAR_CODE_R, (full, inner) => {\n // Named entity lookup - try exact match, then lowercase fallback\n // The generation script handles uppercase fallbacks for lowercase entities\n const entity =\n NAMED_CODES_TO_UNICODE[inner] ||\n NAMED_CODES_TO_UNICODE[inner.toLowerCase()]\n if (entity) return entity\n\n // Numeric entities\n if (inner[0] === '#') {\n const code =\n inner[1] === 'x' || inner[1] === 'X'\n ? parseInt(inner.slice(2), 16)\n : parseInt(inner.slice(1), 10)\n\n if (code === 0 || (code >= 0xd800 && code <= 0xdfff) || code > 0x10ffff) {\n return '\\uFFFD'\n }\n return code <= 0xffff\n ? String.fromCharCode(code)\n : String.fromCharCode(\n 0xd800 + ((code - 0x10000) >> 10),\n 0xdc00 + ((code - 0x10000) & 0x3ff)\n )\n }\n\n return full\n })\n}\n\nexport const SANITIZE_R: RegExp = /(javascript|vbscript|data(?!:image)):/i\n\nexport function sanitizer(input: string): string | null {\n if (SANITIZE_R.test(input)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Input contains an unsafe JavaScript/VBScript/data expression, it will not be rendered.',\n input\n )\n }\n return null\n }\n\n if (input.indexOf('%') === -1) return input\n\n try {\n const decoded = decodeURIComponent(input).replace(/[^A-Za-z0-9/:]/g, '')\n if (SANITIZE_R.test(decoded)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Input contains an unsafe JavaScript/VBScript/data expression, it will not be rendered.',\n decoded\n )\n }\n return null\n }\n } catch (e) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Input could not be decoded due to malformed syntax or characters, it will not be rendered.',\n input\n )\n }\n return null\n }\n\n return input\n}\n\n// Character replacement lookup table for slugify (Unicode to ASCII)\nvar slugifyReplaceTable: Record<number, string> = {}\nvar codes: number[], i: number\ncodes = [192, 193, 194, 195, 196, 197, 224, 225, 226, 227, 228, 229, 230, 198]\nfor (i = 0; i < codes.length; i++) slugifyReplaceTable[codes[i]] = 'a'\nslugifyReplaceTable[231] = slugifyReplaceTable[199] = 'c'\nslugifyReplaceTable[240] = slugifyReplaceTable[208] = 'd'\ncodes = [200, 201, 202, 203, 233, 232, 234, 235]\nfor (i = 0; i < codes.length; i++) slugifyReplaceTable[codes[i]] = 'e'\ncodes = [207, 239, 206, 238, 205, 237, 204, 236]\nfor (i = 0; i < codes.length; i++) slugifyReplaceTable[codes[i]] = 'i'\nslugifyReplaceTable[209] = slugifyReplaceTable[241] = 'n'\ncodes = [248, 216, 339, 338, 213, 245, 212, 244, 211, 243, 210, 242]\nfor (i = 0; i < codes.length; i++) slugifyReplaceTable[codes[i]] = 'o'\ncodes = [220, 252, 219, 251, 218, 250, 217, 249]\nfor (i = 0; i < codes.length; i++) slugifyReplaceTable[codes[i]] = 'u'\nslugifyReplaceTable[376] =\n slugifyReplaceTable[255] =\n slugifyReplaceTable[221] =\n slugifyReplaceTable[253] =\n 'y'\n\nexport function isAlnumCode(code: number): boolean {\n return (\n (code >= $.CHAR_DIGIT_0 && code <= $.CHAR_DIGIT_9) ||\n (code >= $.CHAR_A && code <= $.CHAR_Z) ||\n (code >= $.CHAR_a && code <= $.CHAR_z)\n )\n}\n\n// based on https://stackoverflow.com/a/18123682/1141611\n// not complete, but probably good enough\nexport function slugify(str: string): string {\n var parts: string[] = []\n for (var i = 0; i < str.length; i++) {\n var code = str.charCodeAt(i)\n if (isAlnumCode(code)) {\n if (code >= $.CHAR_A && code <= $.CHAR_Z) {\n parts.push(String.fromCharCode(code + $.CHAR_CASE_OFFSET))\n } else {\n parts.push(str[i])\n }\n } else if (code === $.CHAR_SPACE || code === $.CHAR_DASH) {\n parts.push('-')\n } else {\n var replacement = slugifyReplaceTable[code]\n if (replacement) parts.push(replacement)\n }\n }\n return parts.join('')\n}\n\n/**\n * Basic string utility functions\n */\nexport function includes(str: string, search: string): boolean {\n return str.indexOf(search) !== -1\n}\n\nexport function startsWith(str: string, prefix: string, pos?: number): boolean {\n return str.startsWith(prefix, pos)\n}\n\nexport function endsWith(str: string, suffix: string, pos?: number): boolean {\n return str.startsWith(\n suffix,\n (pos === undefined ? str.length : pos) - suffix.length\n )\n}\n\n// Known void elements (HTML5 and SVG) that don't require closing tag or />\n// Use Set for O(1) lookups instead of O(n) array.includes()\nexport const VOID_ELEMENTS: Set<string> = new Set([\n // HTML5 void elements\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n // SVG void elements\n 'circle',\n 'ellipse',\n 'line',\n 'path',\n 'polygon',\n 'polyline',\n 'rect',\n 'use',\n 'stop',\n 'animate',\n 'animateTransform',\n 'set',\n])\n\n/** Check if an element is a void element (doesn't require closing tag) */\nexport function isVoidElement(tagName: string): boolean {\n let lowerTag = tagName.toLowerCase()\n if (VOID_ELEMENTS.has(lowerTag)) return true\n // Handle SVG namespace prefixes like svg:circle\n const colonIndex = lowerTag.indexOf(':')\n if (colonIndex !== -1) {\n lowerTag = lowerTag.slice(colonIndex + 1)\n return VOID_ELEMENTS.has(lowerTag)\n }\n return false\n}\n\n/** Attributes that should be sanitized for security */\nexport const ATTRIBUTES_TO_SANITIZE: readonly string[] = [\n 'src',\n 'href',\n 'data',\n 'formAction',\n 'srcDoc',\n 'action',\n]\n\n// Character classification flags (bitfield)\nconst CHAR_WHITESPACE = 1\nconst CHAR_PUNCTUATION = 2\n\n// Inline character type constants\n// const INLINE_CHAR_TYPE_NORMAL = 0\nconst INLINE_CHAR_TYPE_SPECIAL = 1\nconst INLINE_CHAR_TYPE_ESCAPE = 2\nconst INLINE_CHAR_TYPE_DELIMITER = 3\nconst INLINE_CHAR_TYPE_LINK = 4\n\n// Lookup table for ASCII characters (0-127)\nexport const charClassTable: Uint8Array = (function () {\n const t = new Uint8Array(128)\n let i\n t[$.CHAR_TAB] =\n t[$.CHAR_NEWLINE] =\n t[$.CHAR_FF] =\n t[$.CHAR_CR] =\n t[$.CHAR_SPACE] =\n CHAR_WHITESPACE\n for (i = $.CHAR_EXCLAMATION; i <= $.CHAR_SLASH; i++) t[i] = CHAR_PUNCTUATION\n for (i = $.CHAR_COLON; i <= $.CHAR_AT; i++) t[i] = CHAR_PUNCTUATION\n for (i = $.CHAR_BRACKET_OPEN; i <= $.CHAR_BACKTICK; i++)\n t[i] = CHAR_PUNCTUATION\n for (i = $.CHAR_BRACE_OPEN; i <= $.CHAR_TILDE; i++) t[i] = CHAR_PUNCTUATION\n return t\n})()\n\n// Lookup table for inline character types (0-127): 0=normal, 1=special, 2=escape, 3=delimiter, 4=link\nexport const inlineCharTypeTable: Uint8Array = (function () {\n const t = new Uint8Array(128)\n t[$.CHAR_BACKSLASH] = INLINE_CHAR_TYPE_ESCAPE\n t[$.CHAR_BRACKET_OPEN] = INLINE_CHAR_TYPE_LINK\n t[$.CHAR_ASTERISK] =\n t[$.CHAR_UNDERSCORE] =\n t[$.CHAR_TILDE] =\n t[$.CHAR_EQ] =\n INLINE_CHAR_TYPE_DELIMITER\n t[$.CHAR_BACKTICK] =\n t[$.CHAR_LT] =\n t[$.CHAR_AT] =\n t[$.CHAR_BRACKET_CLOSE] =\n t[$.CHAR_NEWLINE] =\n t[$.CHAR_SPACE] =\n t[$.CHAR_EXCLAMATION] =\n INLINE_CHAR_TYPE_SPECIAL\n t[$.CHAR_f] = t[$.CHAR_H] = t[$.CHAR_W] = INLINE_CHAR_TYPE_SPECIAL\n return t\n})()\n\nexport function isASCIIPunctuation(code: number): boolean {\n return (\n code < $.CHAR_ASCII_BOUNDARY &&\n (charClassTable[code] & CHAR_PUNCTUATION) !== 0\n )\n}\n\nexport function isASCIIWhitespace(code: number): boolean {\n return (\n code < $.CHAR_ASCII_BOUNDARY &&\n (charClassTable[code] & CHAR_WHITESPACE) !== 0\n )\n}\n\n// Unicode property escapes for spec-compliant character classification\n// Per GFM spec Section 2.1: \"A punctuation character is a character in the general Unicode categories\n// Pc, Pd, Pe, Pf, Pi, Po, or Ps\" - this is \\p{P}\n// BUT also includes some currency symbols and other symbols per the spec's explicit list\nconst UNICODE_PUNCT_R = /[\\p{P}\\p{S}]/u\nconst UNICODE_WHITESPACE_R = /\\p{Zs}/u\n\nexport function isUnicodeWhitespace(c: string): boolean {\n if (!c) return true\n const code = c.charCodeAt(0)\n return code < $.CHAR_ASCII_BOUNDARY\n ? (charClassTable[code] & CHAR_WHITESPACE) !== 0\n : UNICODE_WHITESPACE_R.test(c)\n}\n\nexport function isUnicodePunctuation(c: string | number): boolean {\n if (typeof c === 'number')\n return (\n c < $.CHAR_ASCII_BOUNDARY && (charClassTable[c] & CHAR_PUNCTUATION) !== 0\n )\n if (!c) return false\n const code = c.charCodeAt(0)\n return code < $.CHAR_ASCII_BOUNDARY\n ? (charClassTable[code] & CHAR_PUNCTUATION) !== 0\n : UNICODE_PUNCT_R.test(c)\n}\n\n/**\n * Find the end of the current line\n * Optimized: Pure indexOf is faster than hybrid approach - JS engine optimizes it better\n */\nexport function findLineEnd(source: string, startPos: number): number {\n const newlinePos = source.indexOf('\\n', startPos)\n return newlinePos !== -1 ? newlinePos : source.length\n}\n\n/**\n * Skip whitespace characters\n */\nexport function skipWhitespace(\n source: string,\n pos: number,\n maxPos?: number\n): number {\n const end = maxPos ?? source.length\n while (pos < end && (source[pos] === ' ' || source[pos] === '\\t')) pos++\n return pos\n}\n\n/**\n * Fast check if object has any enumerable properties\n * Optimized alternative to Object.keys(obj).length > 0\n */\nexport function hasKeys(obj: Record<string, any> | null | undefined): boolean {\n if (!obj) return false\n for (var key in obj) {\n return true\n }\n return false\n}\n\n/**\n * Extract plain text from AST nodes (for image alt text, heading slugs, etc.)\n * Shared between JSX and HTML renderers\n */\n/**\n * Get nested property from object using dot notation path\n */\nexport function get(source: any, path: string, fallback: any): any {\n var result = source\n var segments = path.split('.')\n var i = 0\n while (i < segments.length) {\n result = result?.[segments[i]]\n if (result === undefined) break\n i++\n }\n return result || fallback\n}\n\n/**\n * Get tag name from override object, supporting both string and component object overrides\n */\nexport function getTag<\n T extends string | { component?: string; props?: Record<string, any> },\n>(tag: string, overrides?: Record<string, T>): string {\n if (!overrides) return tag\n const override = get(overrides, tag, undefined)\n if (typeof override === 'string') return override\n if (typeof override === 'object' && override.component)\n return override.component\n return tag\n}\n\n/**\n * Get override props from override object\n */\nexport function getOverrideProps<\n T extends string | { component?: string; props?: Record<string, any> },\n>(\n tag: string,\n overrides?: Record<string, T>\n): Record<string, string | number | boolean> {\n if (!overrides) return {}\n const override = get(overrides, tag, undefined)\n return typeof override === 'object' && override.props ? override.props : {}\n}\n\nexport function extractPlainText(nodes: Array<any>, RuleType: any): string {\n var result = ''\n for (var i = 0, len = nodes.length; i < len; i++) {\n var node = nodes[i],\n type = node.type\n if (type === RuleType.text || type === RuleType.codeInline) {\n var text = node.text\n if (text) result += text\n } else if (type === RuleType.textFormatted || type === RuleType.link) {\n if (node.children) result += extractPlainText(node.children, RuleType)\n } else if (type === RuleType.image) {\n if (node.alt) {\n result += node.alt\n }\n }\n }\n return result\n}\n\n/**\n * Check if tag should be filtered per GFM tagfilter extension\n */\nexport function shouldFilterTag(tagName: string): boolean {\n var lowerTag = tagName.toLowerCase()\n return (\n lowerTag === 'title' ||\n lowerTag === 'textarea' ||\n lowerTag === 'style' ||\n lowerTag === 'xmp' ||\n lowerTag === 'iframe' ||\n lowerTag === 'noembed' ||\n lowerTag === 'noframes' ||\n lowerTag === 'script' ||\n lowerTag === 'plaintext'\n )\n}\n\n/**\n * Apply tagfilter to text content - escape dangerous tags\n */\nexport function applyTagFilterToText(text: string): string {\n // Escape dangerous tags in raw HTML text\n // Matches opening tags like <tag> or <tag attr=\"val\">\n return text.replace(\n /<(\\/?)(title|textarea|style|xmp|iframe|noembed|noframes|script|plaintext)(\\s|>|\\/)/gi,\n function (match, slash, tagName, after) {\n // Only escape the opening <\n return '<' + slash + tagName + after\n }\n )\n}\n",
|
|
9
|
-
"import { RuleType, type MarkdownToJSX } from './types'\nimport * as $ from './constants'\nimport * as util from './utils'\n\n// NOTE: All debug and tracking functions are automatically removed by build-plugins.ts\n\n// Global parseMetrics - accessible via global.parseMetrics from all files\ndeclare global {\n var parseMetrics: {\n blockParsers: {\n [key: string]: {\n attempts: number\n hits: number\n hitTimings: number[]\n }\n }\n inlineParsers: {\n [key: string]: {\n attempts: number\n hits: number\n hitTimings: number[]\n }\n }\n totalOperations: number\n blockParseIterations: number\n inlineParseIterations: number\n } | null\n var parseMetricsStartTimes: Map<string, number> | null\n}\n\nexport {};\n\nfunction warn(message: string): void {\n console.warn(message)\n}\n\nfunction countConsecutiveChars(\n source: string,\n pos: number,\n targetChar: string,\n maxCount?: number\n): number {\n var targetCode = charCode(targetChar)\n var len = source.length\n var max = maxCount ?? len - pos\n var count = 0\n while (\n count < max &&\n pos + count < len &&\n charCode(source, pos + count) === targetCode\n )\n count++\n return count\n}\n\n// Unified flanking check: dir=0 for left, dir=1 for right\nfunction checkFlanking(\n source: string,\n delimiterStart: number,\n delimiterEnd: number,\n bound: number,\n dir: number\n): boolean {\n if (dir === 0 ? delimiterEnd >= bound : delimiterStart <= bound) return false\n\n const adjacentChar =\n dir === 0 ? source[delimiterEnd] : source[delimiterStart - 1]\n const oppositeChar =\n dir === 0\n ? delimiterStart > 0\n ? source[delimiterStart - 1]\n : null\n : delimiterEnd < source.length\n ? source[delimiterEnd]\n : null\n\n var adjacentCode = charCode(adjacentChar)\n\n if (\n adjacentCode < $.CHAR_ASCII_BOUNDARY\n ? util.isASCIIWhitespace(adjacentCode)\n : util.isUnicodeWhitespace(adjacentChar)\n ) {\n return false\n }\n\n var oppositeCode = oppositeChar ? charCode(oppositeChar) : null\n var isOppositeWS =\n oppositeChar === null ||\n oppositeChar === '\\n' ||\n oppositeChar === '\\r' ||\n (oppositeCode !== null\n ? oppositeCode < $.CHAR_ASCII_BOUNDARY\n ? util.isASCIIWhitespace(oppositeCode)\n : util.isUnicodeWhitespace(oppositeChar)\n : true)\n\n var isAdjacentPunct = isPunctuation(adjacentCode, adjacentChar)\n\n if (!isAdjacentPunct) return true\n if (isOppositeWS) return true\n\n return oppositeChar\n ? isPunctuation(charCode(oppositeChar), oppositeChar)\n : false\n}\n\n// Per CommonMark spec: backslashes escape ASCII punctuation characters in link destinations\n// For non-punctuation characters, the backslash is preserved as a literal backslash\n// Per CommonMark spec: backslash unescaping and entity reference decoding for URLs and titles\n// Any ASCII punctuation character may be backslash-escaped\n// Entity references are recognized and decoded to Unicode\nfunction unescapeUrlOrTitle(str: string): string {\n var result = '',\n i = 0\n while (i < str.length) {\n if (str[i] === '\\\\' && i + 1 < str.length) {\n var next = str[i + 1]\n result += util.isUnicodePunctuation(charCode(next)) ? next : '\\\\' + next\n i += 2\n } else {\n result += str[i++]\n }\n }\n return util.decodeEntityReferences(result)\n}\n\nfunction skipToNextLine(source: string, lineEnd: number): number {\n return lineEnd + (lineEnd < source.length ? 1 : 0)\n}\n\nfunction getCharType(code: number, skipAutoLink: boolean): number {\n if (code >= $.CHAR_ASCII_BOUNDARY) return 0\n var type = util.inlineCharTypeTable[code]\n if (\n skipAutoLink &&\n type === 1 &&\n (code === $.CHAR_f || code === $.CHAR_H || code === $.CHAR_W)\n ) {\n return 0\n }\n return type\n}\n\nfunction tryMergeBlockquoteContinuation(\n source: string,\n currentPos: number,\n lastItem: MarkdownToJSX.ASTNode[],\n continuationContent: string,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): number | null {\n if (\n !lastItem.length ||\n lastItem[lastItem.length - 1].type !== RuleType.blockQuote\n )\n return null\n const checkPos = util.skipWhitespace(\n continuationContent,\n 0,\n continuationContent.length\n )\n if (\n checkPos >= continuationContent.length ||\n continuationContent[checkPos] !== '>'\n )\n return null\n // We've already verified it starts with '>', so try blockquote directly\n // (parseBlock might match fenced code blocks first due to indentation)\n const cont = parseBlockQuote(source, currentPos, state, options)\n if (!cont) return null\n const lastBlockQuote = lastItem[\n lastItem.length - 1\n ] as MarkdownToJSX.BlockQuoteNode\n const contBlockQuote = cont as MarkdownToJSX.BlockQuoteNode & {\n endPos: number\n }\n if (contBlockQuote.children)\n lastBlockQuote.children.push(...contBlockQuote.children)\n return contBlockQuote.endPos\n}\n\nfunction createHeading(\n level: number,\n children: MarkdownToJSX.ASTNode[],\n content: string,\n slugify: (str: string) => string\n): MarkdownToJSX.HeadingNode {\n return {\n type: RuleType.heading,\n level,\n children,\n id: slugify(content),\n } as MarkdownToJSX.HeadingNode\n}\n\n// Static regex patterns for performance\nexport const UNESCAPE_R: RegExp = /\\\\(.)/g\nconst HEADING_TRAILING_HASHES_R = /\\s+#+\\s*$/\n// Unified regex for all list item patterns: ordered (digit + delimiter + content) or unordered (marker + content)\n// Groups: 1=ordered_num, 2=ordered_delim, 3=ordered_content, 4=ordered_empty_num, 5=ordered_empty_delim, 6=unordered_marker, 7=unordered_content, 8=unordered_empty_marker\nconst LIST_ITEM_R =\n /^(?:(\\d{1,9})([.)])\\s+(.*)$|(\\d{1,9})([.)])\\s*$|([-*+])\\s+(.*)$|([-*+])\\s*$)/\n// List items with content (marker + whitespace + content or end of line) - for continuation matching\nconst ORDERED_LIST_ITEM_WITH_CONTENT_R = /^(\\d{1,9})([.)])(\\s+|$)/\nconst UNORDERED_LIST_ITEM_WITH_CONTENT_R = /^([*+\\-])(\\s+|$)/\nexport const HTML_BLOCK_ELEMENT_START_R: RegExp =\n /^<([a-z][^ >/\\n\\r]*) ?([^>]*?)>/i\nexport const HTML_BLOCK_ELEMENT_START_R_ATTR: RegExp =\n /^<([a-z][^ >/]*) ?(?:[^>/]+[^/]|)>/i\n\nvar charCode = function (c: string, pos: number = 0) {\n return c.charCodeAt(pos)\n}\nvar isAlnum = function (c: string): boolean {\n return util.isAlnumCode(charCode(c))\n}\nvar isWS = function (c: string) {\n return util.isASCIIWhitespace(charCode(c))\n}\nvar isSpaceOrTab = function (c: string): boolean {\n return c === ' ' || c === '\\t'\n}\nvar isPunctuation = function (code: number, char: string): boolean {\n return util.isUnicodePunctuation(code < $.CHAR_ASCII_BOUNDARY ? code : char)\n}\nvar isNameChar = function (c: string) {\n var n = charCode(c)\n return (\n isAlnum(c) ||\n n === $.CHAR_DASH ||\n n === $.CHAR_UNDERSCORE ||\n n === $.CHAR_COLON ||\n n === $.CHAR_PERIOD\n )\n}\n\n// HTML validation functions removed - parser only recognizes boundaries, not validates syntax\n// Per GFM spec: parser's job is to identify HTML boundaries and pass content opaquely\n\nfunction parseHTMLTagName(\n source: string,\n pos: number\n): { tagName: string; tagLower: string; nextPos: number } | null {\n var sourceLen = source.length\n if (pos >= sourceLen) return null\n var firstCharCode = charCode(source[pos])\n if (!isAlphaCode(firstCharCode)) return null\n var tagNameStart = pos\n var tagNameEnd = pos\n while (tagNameEnd < sourceLen) {\n var code = charCode(source[tagNameEnd])\n if (\n (code >= $.CHAR_a && code <= $.CHAR_z) ||\n (code >= $.CHAR_A && code <= $.CHAR_Z) ||\n (code >= $.CHAR_DIGIT_0 && code <= $.CHAR_DIGIT_9) ||\n code === $.CHAR_DASH\n ) {\n tagNameEnd++\n } else {\n var tagEndCode = charCode(source[tagNameEnd])\n if (\n tagEndCode === $.CHAR_SPACE ||\n tagEndCode === $.CHAR_TAB ||\n tagEndCode === $.CHAR_NEWLINE ||\n tagEndCode === $.CHAR_CR ||\n tagEndCode === $.CHAR_GT ||\n tagEndCode === $.CHAR_SLASH\n ) {\n break\n } else {\n return null\n }\n }\n }\n if (tagNameEnd === tagNameStart) return null\n var tagName = source.slice(tagNameStart, tagNameEnd)\n\n // Validate tag name according to spec: only ASCII letters, digits, hyphens\n for (var i = 0; i < tagName.length; i++) {\n var code = charCode(tagName[i])\n if (\n !(\n (code >= $.CHAR_a && code <= $.CHAR_z) ||\n (code >= $.CHAR_A && code <= $.CHAR_Z) ||\n (code >= $.CHAR_DIGIT_0 && code <= $.CHAR_DIGIT_9) ||\n code === $.CHAR_DASH\n )\n ) {\n return null\n }\n }\n\n return { tagName, tagLower: tagName.toLowerCase(), nextPos: tagNameEnd }\n}\n\n/** Unified HTML tag parser that handles opening, closing, and self-closing tags */\nexport function parseHTMLTag(\n source: string,\n pos: number\n): {\n tagName: string\n tagLower: string\n attrs: string\n endPos: number\n isClosing: boolean\n isSelfClosing: boolean\n hasNewline: boolean\n hasSpaceBeforeSlash: boolean\n whitespaceBeforeAttrs: string\n} | null {\n var token = scanRawHTML(source, pos)\n if (!token || token.kind !== 'tag') return null\n\n // Note: hasSpaceBeforeSlash is already validated in scanner (returns null if invalid)\n return {\n tagName: token.tagName || '',\n tagLower: token.tagNameLower || '',\n attrs: token.attrs || '',\n endPos: token.endPos,\n isClosing: token.isClosing || false,\n isSelfClosing: token.isSelfClosing || false,\n hasNewline: token.hasNewline,\n hasSpaceBeforeSlash: false,\n whitespaceBeforeAttrs: token.whitespaceBeforeAttrs || '',\n }\n}\n\n/** Find matching closing tag position for inline HTML tags. Returns [contentEnd, closingTagEnd] or null */\nfunction findInlineClosingTag(\n source: string,\n startPos: number,\n tagNameLower: string\n): [number, number] | null {\n var depth = 1\n var searchPos = startPos\n while (depth > 0 && searchPos < source.length) {\n var tagIdx = source.indexOf('<', searchPos)\n if (tagIdx === -1) return null\n var tagParseResult = parseHTMLTag(source, tagIdx)\n if (!tagParseResult) {\n searchPos = tagIdx + 1\n continue\n }\n if (\n tagParseResult.isClosing &&\n tagParseResult.tagLower === tagNameLower &&\n --depth === 0\n )\n return [tagIdx, tagParseResult.endPos]\n if (\n !tagParseResult.isClosing &&\n !tagParseResult.isSelfClosing &&\n tagParseResult.tagLower === tagNameLower\n )\n depth++\n searchPos = tagParseResult.endPos\n }\n return null\n}\n\nexport const INTERPOLATION_R: RegExp = /^\\{.*\\}$/\nconst DOUBLE_NEWLINE_R = /\\n\\n/\nconst BLOCK_SYNTAX_R =\n /^(\\s{0,3}#[#\\s]|\\s{0,3}[-*+]\\s|\\s{0,3}\\d+\\.\\s|\\s{0,3}>\\s|\\s{0,3}```)/m\nconst TYPE1_TAG_R = /<\\/?(?:pre|script|style|textarea)\\b/i\nexport const UPPERCASE_TAG_R: RegExp = /^<[A-Z]/\nconst TRAILING_NEWLINE_R = /\\n$/\nconst BLOCK_START_CHARS_SET = new Set([\n '#',\n '>',\n '-',\n '*',\n '+',\n '`',\n '|',\n '0',\n '1',\n '2',\n '3',\n '4',\n '5',\n '6',\n '7',\n '8',\n '9',\n])\n\n/** Find the next occurrence of a character, ignoring escaped versions */\nfunction findUnescapedChar(\n source: string,\n startPos: number,\n endPos: number,\n targetChar: string\n): number {\n let i = startPos\n while (i < endPos) {\n if (source[i] === '\\\\' && i + 1 < endPos) {\n i += 2\n continue\n }\n if (source[i] === targetChar) return i\n i++\n }\n return -1\n}\n\ntype StyleTuple = [key: string, value: string]\n\nfunction addStyleToCollection(styles: StyleTuple[], buffer: string): void {\n var colonIndex = buffer.indexOf(':')\n if (colonIndex > 0) {\n var value = buffer.slice(colonIndex + 1).trim()\n var len = value.length\n if (len >= 2) {\n var first = value[0]\n if ((first === '\"' || first === \"'\") && value[len - 1] === first) {\n value = value.slice(1, -1)\n }\n }\n styles.push([buffer.slice(0, colonIndex).trim(), value])\n }\n}\n\nexport function parseStyleAttribute(styleString: string): StyleTuple[] {\n var styles: StyleTuple[] = []\n if (!styleString) return styles\n\n var buffer = ''\n var depth = 0\n var quoteChar = ''\n\n for (var i = 0; i < styleString.length; i++) {\n var char = styleString[i]\n\n if (char === '\"' || char === \"'\") {\n if (!quoteChar) {\n quoteChar = char\n depth++\n } else if (char === quoteChar) {\n quoteChar = ''\n depth--\n }\n } else if (char === '(' && util.endsWith(buffer, 'url')) {\n depth++\n } else if (char === ')' && depth > 0) {\n depth--\n } else if (char === ';' && depth === 0) {\n addStyleToCollection(styles, buffer)\n buffer = ''\n continue\n }\n\n buffer += char\n }\n\n addStyleToCollection(styles, buffer)\n\n return styles\n}\n\nfunction attributeValueToJSXPropValue(\n tag: MarkdownToJSX.HTMLTags,\n key: string,\n value: string,\n sanitizeUrlFn: (\n value: string,\n tag: string,\n attribute: string\n ) => string | null\n): any {\n if (key === 'style') {\n return parseStyleAttribute(value).reduce(\n function (styles, [k, v]) {\n const sanitized = sanitizeUrlFn(v, tag, k)\n if (sanitized != null) {\n styles[k.replace(/(-[a-z])/g, substr => substr[1].toUpperCase())] =\n sanitized\n }\n return styles\n },\n {} as { [key: string]: any }\n );\n }\n\n if (util.ATTRIBUTES_TO_SANITIZE.indexOf(key) !== -1) {\n return sanitizeUrlFn(\n value ? value.replace(UNESCAPE_R, '$1') : value,\n tag,\n key\n )\n }\n\n if (value.match(INTERPOLATION_R)) {\n value = value.slice(1, value.length - 1)\n value = value ? value.replace(UNESCAPE_R, '$1') : value\n }\n\n return value === 'true' ? true : value === 'false' ? false : value\n}\n\nfunction parseHTMLAttributes(\n attrs: string,\n tagName: string,\n tagNameOriginal: string,\n options: ParseOptions\n): { [key: string]: any } {\n const result: { [key: string]: any } = {}\n if (!attrs || !attrs.trim()) return result\n\n const attrMatches: string[] = []\n let i = 0\n const len = attrs.length\n while (i < len) {\n while (i < len && isSpaceOrTab(attrs[i])) i++\n if (i >= len) break\n const nameStart = i\n while (i < len && isNameChar(attrs[i])) i++\n if (i === nameStart) {\n i++\n continue\n }\n const name = attrs.slice(nameStart, i)\n while (i < len && isSpaceOrTab(attrs[i])) i++\n if (i >= len || attrs[i] !== '=') {\n attrMatches.push(name)\n continue\n }\n i++\n while (i < len && isSpaceOrTab(attrs[i])) i++\n if (i >= len) {\n attrMatches.push(name + '=')\n break\n }\n const valueStart = i\n const q = attrs[i]\n if (q === '\"' || q === \"'\") {\n i++\n while (i < len) {\n if (attrs[i] === q) {\n if (i + 1 >= len) {\n i++\n break\n }\n const nextChar = attrs[i + 1]\n if (isSpaceOrTab(nextChar) || nextChar === '/') {\n i++\n break\n }\n }\n i++\n }\n } else if (q === '{') {\n let depth = 1\n i++\n while (i < len && depth > 0) {\n if (attrs[i] === '{') depth++\n else if (attrs[i] === '}') {\n depth--\n if (depth === 0) {\n i++\n break\n }\n }\n i++\n }\n } else {\n while (i < len && !isSpaceOrTab(attrs[i])) i++\n }\n attrMatches.push(name + '=' + attrs.slice(valueStart, i))\n }\n\n if (!attrMatches?.length) return result\n const tagNameLower = tagName.toLowerCase(),\n isJSXComponent =\n tagNameOriginal.length > 0 &&\n tagNameOriginal[0] >= 'A' &&\n tagNameOriginal[0] <= 'Z'\n for (let i = 0; i < attrMatches.length; i++) {\n const rawAttr = attrMatches[i],\n delimiterIdx = rawAttr.indexOf('=')\n if (delimiterIdx !== -1) {\n const key = rawAttr.slice(0, delimiterIdx).trim(),\n keyLower = key.toLowerCase()\n if (keyLower === 'ref') continue\n const attrKey = isJSXComponent ? key : keyLower,\n rawValue = rawAttr.slice(delimiterIdx + 1).trim(),\n value = ((str: string) => {\n const first = str[0]\n if (\n (first === '\"' || first === \"'\") &&\n str.length >= 2 &&\n str[str.length - 1] === first\n )\n return str.slice(1, -1)\n return str\n })(rawValue)\n\n if (\n (keyLower === 'href' && tagNameLower === 'a') ||\n (keyLower === 'src' && tagNameLower === 'img')\n ) {\n const safe = options.sanitizer(\n value,\n tagNameLower as MarkdownToJSX.HTMLTags,\n keyLower\n )\n if (safe == null) {\n warn(`Stripped unsafe ${keyLower} on <${tagNameOriginal}>`)\n continue\n }\n result[attrKey] = safe\n } else {\n const normalizedValue = attributeValueToJSXPropValue(\n tagNameLower as MarkdownToJSX.HTMLTags,\n keyLower,\n value,\n options.sanitizer\n )\n result[attrKey] = normalizedValue\n }\n } else if (rawAttr !== 'style')\n result[isJSXComponent ? rawAttr : rawAttr.toLowerCase()] = true\n }\n if (util.SANITIZE_R.test(decodeURIComponent(attrs)))\n for (const key in result) delete result[key]\n return result\n}\n\nexport type ParseResult = (MarkdownToJSX.ASTNode & { endPos: number }) | null\n\n/** Options passed to parsers */\nexport type ParseOptions = Omit<MarkdownToJSX.Options, 'slugify'> & {\n slugify: (input: string) => string\n}\n\nvar isBlockStartChar = function (c: string): boolean {\n return BLOCK_START_CHARS_SET.has(c)\n}\n\ninterface BracketEntry {\n type: 'link' | 'image'\n pos: number\n resultIdx: number\n inAnchor: boolean\n}\n\n// Check if an invalid reference definition should be skipped per CommonMark Examples 208 and 210\nfunction shouldSkipInvalidReferenceDefinition(\n input: string,\n refCheckPos: number,\n isAtDocumentStart: boolean\n): { shouldSkip: boolean; newPos: number } {\n // Find closing ']' handling escapes\n let bracketEnd = refCheckPos + 1\n while (bracketEnd < input.length && input[bracketEnd] !== ']') {\n if (input[bracketEnd] === '\\\\' && bracketEnd + 1 < input.length) {\n bracketEnd += 2\n continue\n }\n bracketEnd++\n }\n if (bracketEnd >= input.length) return { shouldSkip: false, newPos: 0 }\n\n // Check if label starts/ends with newline (Example 208 pattern)\n const labelStart = refCheckPos + 1\n const labelEnd = bracketEnd\n const labelStartsWithNewline =\n labelStart < labelEnd &&\n (input[labelStart] === '\\n' || input[labelStart] === '\\r')\n const labelEndsWithNewline =\n labelEnd > labelStart &&\n (input[labelEnd - 1] === '\\n' || input[labelEnd - 1] === '\\r')\n\n let afterBracket = bracketEnd + 1\n // Skip whitespace after ']'\n afterBracket = util.skipWhitespace(input, afterBracket)\n\n // Check for colon\n if (afterBracket >= input.length || input[afterBracket] !== ':') {\n return { shouldSkip: false, newPos: 0 }\n }\n\n // Found colon - check for Example 208 pattern (label starts/ends with newline at document start)\n if ((labelStartsWithNewline || labelEndsWithNewline) && isAtDocumentStart) {\n // Invalid ref definition per Example 208 - skip to next line after URL\n let skipPos = afterBracket + 1\n skipPos = util.skipWhitespace(input, skipPos)\n // Skip optional newline\n if (skipPos < input.length && input[skipPos] === '\\n') {\n skipPos = util.skipWhitespace(input, skipPos + 1)\n }\n // Find end of URL line (next newline)\n while (skipPos < input.length && input[skipPos] !== '\\n') {\n skipPos++\n }\n if (skipPos < input.length) {\n skipPos++\n }\n return { shouldSkip: true, newPos: skipPos }\n }\n\n // Check for Example 210 pattern (trailing text after title)\n return checkExample210Pattern(input, afterBracket)\n}\n\n// Helper for Example 210: trailing text after title\nfunction checkExample210Pattern(\n input: string,\n colonPos: number\n): { shouldSkip: boolean; newPos: number } {\n let urlEnd = colonPos + 1\n urlEnd = util.skipWhitespace(input, urlEnd)\n // Skip optional newline\n if (urlEnd < input.length && input[urlEnd] === '\\n') {\n urlEnd = util.skipWhitespace(input, urlEnd + 1)\n }\n // Find end of URL (next newline)\n while (urlEnd < input.length && input[urlEnd] !== '\\n') {\n urlEnd++\n }\n if (urlEnd >= input.length) return { shouldSkip: false, newPos: 0 }\n\n urlEnd++\n // Check for title delimiter on next line\n let titleLineStart = util.skipWhitespace(input, urlEnd)\n if (\n titleLineStart >= input.length ||\n (input[titleLineStart] !== '\"' && input[titleLineStart] !== \"'\")\n ) {\n return { shouldSkip: false, newPos: 0 }\n }\n\n // Has title delimiter - check for trailing text (Example 210)\n const titleChar = input[titleLineStart]\n let titleEnd = titleLineStart + 1\n while (\n titleEnd < input.length &&\n input[titleEnd] !== titleChar &&\n input[titleEnd] !== '\\n'\n ) {\n if (input[titleEnd] === '\\\\' && titleEnd + 1 < input.length) {\n titleEnd += 2\n continue\n }\n titleEnd++\n }\n if (titleEnd >= input.length || input[titleEnd] !== titleChar) {\n return { shouldSkip: false, newPos: 0 }\n }\n\n // Found closing quote - check for trailing text\n let afterTitle = util.skipWhitespace(input, titleEnd + 1)\n if (\n afterTitle < input.length &&\n input[afterTitle] !== '\\n' &&\n input[afterTitle] !== '\\r'\n ) {\n // Trailing text found - invalid ref definition per Example 210\n return { shouldSkip: true, newPos: urlEnd }\n }\n\n return { shouldSkip: false, newPos: 0 }\n}\n\n// Check if nodes contain a link (prevents nested links per CommonMark)\nfunction containsLink(nodes: MarkdownToJSX.ASTNode[]): boolean {\n for (var i = 0; i < nodes.length; i++) {\n var node = nodes[i]\n if (node.type === RuleType.link) return true\n if (node.type === RuleType.textFormatted) {\n var formattedNode = node as MarkdownToJSX.FormattedTextNode\n if (formattedNode.children && containsLink(formattedNode.children))\n return true\n }\n }\n return false\n}\n\nfunction extractAllTextFromNodes(nodes: MarkdownToJSX.ASTNode[]): string {\n var text = ''\n for (var i = 0, len = nodes.length; i < len; i++) {\n var node = nodes[i]\n var type = node.type\n if (type === RuleType.text) {\n text += (node as MarkdownToJSX.TextNode).text\n } else if (type === RuleType.image) {\n var imgNode = node as MarkdownToJSX.ImageNode\n if (imgNode.alt) text += imgNode.alt\n } else if (type === RuleType.textFormatted) {\n var formattedNode = node as MarkdownToJSX.FormattedTextNode\n if (formattedNode.children) {\n text += extractAllTextFromNodes(formattedNode.children)\n }\n } else if (type === RuleType.link) {\n var linkNode = node as MarkdownToJSX.LinkNode\n if (linkNode.children) {\n text += extractAllTextFromNodes(linkNode.children)\n }\n }\n }\n return text\n}\n\nconst WHITESPACE_CHARS = new Set([' ', '\\t', '\\r', '\\n', '\\f', '\\v'])\n\n/**\n * Single pass, no recursion, eliminates parseLink/parseImage/parseRefLink/parseRefImage functions\n */\nfunction parseInlineSpan(\n source: string,\n start: number,\n end: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): MarkdownToJSX.ASTNode[] {\n var result: MarkdownToJSX.ASTNode[] = []\n var delimiterStack: DelimiterEntry[] = []\n var bracketStack: BracketEntry[] = []\n\n var pos = start\n var textStart = start\n var skipAutoLink = options.disableAutoLink || state.inAnchor\n var hasAmpersand = false\n var inAnchor = !!state.inAnchor\n var disableParsingRawHTML = !!options.disableParsingRawHTML\n\n // Helper: handle HTML tag parsing (angle brace autolinks, comments, tags, type 7 blocks)\n var handleHTMLTag = function (\n checkType7Block: boolean,\n respectDisableAutoLink: boolean\n ): boolean {\n // Skip HTML parsing if disableParsingRawHTML is enabled\n if (disableParsingRawHTML) {\n return false\n }\n\n if (!inAnchor && (!respectDisableAutoLink || !options.disableAutoLink)) {\n var angleBraceResult = parseLinkOrImage(source, pos, state, options, '<')\n if (angleBraceResult) {\n flushText(pos)\n result.push(angleBraceResult)\n pos = angleBraceResult.endPos\n textStart = pos\n return true\n }\n }\n var htmlResult = parseHTML(source, pos, state, options)\n if (htmlResult) {\n flushText(pos)\n result.push(htmlResult)\n pos = htmlResult.endPos\n textStart = pos\n return true\n }\n\n if (!checkType7Block) return false\n var tagCheckResult = parseHTMLTag(source, pos)\n if (!tagCheckResult) return false\n var tagNameStart = pos + (tagCheckResult.isClosing ? 2 : 1)\n if (tagNameStart >= source.length || isSpaceOrTab(source[tagNameStart]))\n return false\n var closeIdx = source.indexOf('>', pos + 1)\n if (closeIdx !== -1) {\n var contentStart = pos + 1\n var contentLen = closeIdx - contentStart\n if (contentLen >= 7) {\n var isHttp = util.startsWith(source, 'http://', contentStart)\n if (isHttp || util.startsWith(source, 'https://', contentStart)) {\n for (var j = contentStart; j < closeIdx; j++) {\n if (isSpaceOrTab(source[j])) return false\n }\n }\n }\n }\n var tagFirstCharCode = charCode(source, tagNameStart)\n if (\n isAlphaCode(tagFirstCharCode) &&\n tagNameStart + 1 < source.length &&\n source[tagNameStart + 1] === ':'\n )\n return false\n if (tagCheckResult.isClosing && tagCheckResult.attrs.trim().length)\n return false\n\n if (tagCheckResult.attrs.length) {\n var inQuotes = false\n var quoteChar = ''\n for (var i = 0; i < tagCheckResult.attrs.length; i++) {\n var ch = tagCheckResult.attrs[i]\n if (inQuotes && ch === quoteChar) {\n inQuotes = false\n } else if (!inQuotes && (ch === '\"' || ch === \"'\")) {\n inQuotes = true\n quoteChar = ch\n } else if (ch === '*' || ch === '#' || ch === '!') {\n var checkAhead = i + 1\n while (\n checkAhead < tagCheckResult.attrs.length &&\n tagCheckResult.attrs[checkAhead] !== '=' &&\n tagCheckResult.attrs[checkAhead] !== ' ' &&\n tagCheckResult.attrs[checkAhead] !== '\\t'\n )\n checkAhead++\n if (\n checkAhead < tagCheckResult.attrs.length &&\n tagCheckResult.attrs[checkAhead] === '='\n )\n return false\n }\n }\n }\n\n // Valid tag with newline - type 7 block, preserve as raw HTML\n var htmlBlockResult = {\n type: RuleType.htmlBlock,\n tag: tagCheckResult.tagName as MarkdownToJSX.HTMLTags,\n attrs: {},\n children: [],\n text: source.slice(pos, tagCheckResult.endPos),\n noInnerParse: true,\n endPos: tagCheckResult.endPos,\n } as MarkdownToJSX.HTMLNode & { endPos: number }\n flushText(pos)\n result.push(htmlBlockResult)\n pos = htmlBlockResult.endPos\n textStart = pos\n return true\n }\n\n var flushText = function (endPos: number) {\n if (endPos > textStart) {\n var text = source.slice(textStart, endPos)\n result.push({\n type: RuleType.text,\n text: hasAmpersand ? util.decodeEntityReferences(text) : text,\n } as MarkdownToJSX.TextNode)\n textStart = endPos\n hasAmpersand = false\n }\n }\n\n while (pos < end) {\n var code = charCode(source, pos)\n var charType = getCharType(code, skipAutoLink)\n\n if (charType === 0) {\n if (code === $.CHAR_AMPERSAND) hasAmpersand = true\n pos++\n // Fast path for ASCII text - avoid repeated charCode calls and lookups\n while (pos < end) {\n code = charCode(source, pos)\n if (code >= $.CHAR_ASCII_BOUNDARY) break\n if (code === $.CHAR_AMPERSAND) hasAmpersand = true\n var lookupCharType = util.inlineCharTypeTable[code]\n if (lookupCharType !== 0) {\n // Check for autolink exception\n if (\n skipAutoLink &&\n lookupCharType === 1 &&\n (code === $.CHAR_f || code === $.CHAR_H || code === $.CHAR_W)\n ) {\n pos++\n continue\n }\n break\n }\n pos++\n }\n continue\n }\n\n // CODE SPANS (highest priority, no nesting)\n if (code === $.CHAR_BACKTICK) {\n var backtickStart = pos\n var backtickCount = 0\n while (pos + backtickCount < end) {\n if (charCode(source, pos + backtickCount) !== $.CHAR_BACKTICK) break\n backtickCount++\n }\n\n if (backtickCount > 0) {\n var contentStart = pos + backtickCount\n var contentEnd = -1\n var i = contentStart\n // Scan character by character for closing backticks - faster than indexOf\n while (i < end) {\n // Find next backtick\n while (i < end && charCode(source, i) !== $.CHAR_BACKTICK) i++\n if (i >= end) break\n\n // Count consecutive backticks\n var closingCount = 0\n while (\n i + closingCount < end &&\n charCode(source, i + closingCount) === $.CHAR_BACKTICK\n ) {\n closingCount++\n }\n if (closingCount > backtickCount) closingCount = backtickCount\n var j = i + closingCount\n\n // Check if this is a valid closing sequence\n if (\n closingCount === backtickCount &&\n (i <= contentStart ||\n charCode(source, i - 1) !== $.CHAR_BACKTICK) &&\n (j >= end || charCode(source, j) !== $.CHAR_BACKTICK)\n ) {\n contentEnd = i\n i = j\n break\n }\n i++\n }\n\n if (contentEnd !== -1) {\n var rawContent = source.slice(contentStart, contentEnd)\n var hasNewline = false\n for (var k = 0; k < rawContent.length; k++) {\n var nlCode = charCode(rawContent, k)\n if (nlCode === $.CHAR_NEWLINE || nlCode === $.CHAR_CR) {\n hasNewline = true\n break\n }\n }\n var content = rawContent\n if (hasNewline) {\n // Optimize newline replacement by avoiding regex\n content = rawContent\n .replace(/\\r\\n/g, ' ')\n .replace(/\\r/g, ' ')\n .replace(/\\n/g, ' ')\n }\n if (content.length > 0) {\n var firstChar = charCode(content, 0)\n var lastChar = charCode(content, content.length - 1)\n if (firstChar === $.CHAR_SPACE && lastChar === $.CHAR_SPACE) {\n for (var idx = 1; idx < content.length - 1; idx++) {\n if (charCode(content, idx) !== $.CHAR_SPACE) {\n content = content.slice(1, content.length - 1)\n break\n }\n }\n }\n }\n\n flushText(backtickStart)\n result.push({\n type: RuleType.codeInline,\n text: content,\n } as MarkdownToJSX.CodeInlineNode)\n pos = i\n textStart = pos\n continue\n }\n pos = contentStart\n continue\n }\n }\n\n // AUTOLINKS: BARE URLS AND EMAIL (check BEFORE escapes to preserve backslashes in URLs)\n if (\n !inAnchor &&\n !skipAutoLink &&\n (code === $.CHAR_f || code === $.CHAR_H || code === $.CHAR_W)\n ) {\n var autolinkType: 'h' | 'w' | 'f' | null = null\n // Cache character codes to avoid repeated function calls\n var c1 = pos + 1 < end ? charCode(source, pos + 1) : 0\n var c2 = pos + 2 < end ? charCode(source, pos + 2) : 0\n var c3 = pos + 3 < end ? charCode(source, pos + 3) : 0\n var c4 = pos + 4 < end ? charCode(source, pos + 4) : 0\n var c5 = pos + 5 < end ? charCode(source, pos + 5) : 0\n\n if (\n code === $.CHAR_H &&\n c1 === $.CHAR_t &&\n c2 === $.CHAR_t &&\n c3 === $.CHAR_p\n ) {\n autolinkType = 'h'\n } else if (\n code === $.CHAR_W &&\n c1 === $.CHAR_W &&\n c2 === $.CHAR_W &&\n c3 === $.CHAR_PERIOD\n ) {\n autolinkType = 'w'\n } else if (\n code === $.CHAR_f &&\n c1 === $.CHAR_t &&\n c2 === $.CHAR_p &&\n c3 === $.CHAR_COLON &&\n c4 === $.CHAR_SLASH &&\n c5 === $.CHAR_SLASH\n ) {\n autolinkType = 'f'\n }\n if (autolinkType) {\n var bareUrlResult = parseLinkOrImage(\n source,\n pos,\n state,\n options,\n autolinkType\n )\n if (bareUrlResult) {\n flushText(pos)\n result.push(bareUrlResult)\n pos = bareUrlResult.endPos\n textStart = pos\n continue\n }\n }\n }\n\n if (!inAnchor && !skipAutoLink && code === $.CHAR_AT) {\n var emailResult = parseLinkOrImage(source, pos, state, options, '@')\n if (emailResult && 'emailStart' in emailResult) {\n var emailStart = (\n emailResult as MarkdownToJSX.LinkNode & {\n endPos: number\n emailStart: number\n }\n ).emailStart\n var emailEnd = emailResult.endPos\n var removedIndices: number[] = []\n for (var j = delimiterStack.length - 1; j >= 0; j--) {\n var delim = delimiterStack[j]\n if (delim.sourcePos >= emailStart && delim.sourcePos < emailEnd) {\n if (delim.nodeIndex >= 0 && delim.nodeIndex < result.length) {\n result.splice(delim.nodeIndex, 1)\n removedIndices.push(delim.nodeIndex)\n }\n delimiterStack.splice(j, 1)\n }\n }\n if (emailStart < textStart) {\n for (var i = result.length - 1; i >= 0; i--) {\n if (result[i].type === RuleType.text) {\n result.splice(i, 1)\n removedIndices.push(i)\n break\n }\n }\n textStart = emailStart\n }\n // Batch update delimiter indices after all removals (O(n+m) instead of O(n*m))\n if (removedIndices.length) {\n removedIndices.sort(function (a, b) {\n return a - b\n })\n var removedIdx = 0\n for (var m = 0; m < delimiterStack.length; m++) {\n var delim = delimiterStack[m]\n while (\n removedIdx < removedIndices.length &&\n removedIndices[removedIdx] < delim.nodeIndex\n )\n removedIdx++\n delim.nodeIndex -= removedIdx\n }\n }\n flushText(emailStart)\n result.push(emailResult)\n pos = emailEnd\n textStart = pos\n continue\n }\n }\n\n // HTML TAGS AND AUTOLINKS (check BEFORE escapes to preserve backslashes in autolinks)\n if (code === $.CHAR_LT) {\n if (handleHTMLTag(true, false)) continue\n }\n\n // BACKSLASH ESCAPES\n if (code === $.CHAR_BACKSLASH) {\n if (pos + 1 < end && charCode(source, pos + 1) === $.CHAR_NEWLINE) {\n var afterNewline = pos + 2\n while (\n afterNewline < end &&\n charCode(source, afterNewline) === $.CHAR_SPACE\n )\n afterNewline++\n if (afterNewline >= end) {\n pos++\n continue\n }\n flushText(pos)\n result.push({ type: RuleType.breakLine } as MarkdownToJSX.BreakLineNode)\n pos += 2\n while (pos < end && charCode(source, pos) === $.CHAR_SPACE) pos++\n textStart = pos\n continue\n }\n\n var nextChar = pos + 1 < end ? source[pos + 1] : ''\n if (\n nextChar &&\n '!\"#$%&\\'()*+,-./:;<=>?@[\\\\]^_`{|}~'.indexOf(nextChar) !== -1\n ) {\n flushText(pos)\n result.push({\n type: RuleType.text,\n text: nextChar === '&' ? '&\\u200B' : nextChar,\n } as MarkdownToJSX.TextNode)\n pos += 2\n textStart = pos\n continue\n }\n }\n\n // LINKS AND IMAGES - OPENING BRACKET\n if (code === $.CHAR_BRACKET_OPEN) {\n if (!inAnchor) {\n if (pos + 1 < end && source[pos + 1] === '^') {\n var footnoteEndPos = pos + 2\n while (footnoteEndPos < end && source[footnoteEndPos] !== ']')\n footnoteEndPos++\n if (footnoteEndPos < end) {\n var identifier = source.slice(pos + 2, footnoteEndPos)\n flushText(pos)\n result.push({\n type: RuleType.footnoteReference,\n target: `#${options.slugify(identifier)}`,\n text: identifier,\n } as MarkdownToJSX.FootnoteReferenceNode)\n pos = footnoteEndPos + 1\n textStart = pos\n continue\n }\n }\n\n if (\n state.inList &&\n pos + 2 < end &&\n charCode(source, pos + 2) === $.CHAR_BRACKET_CLOSE\n ) {\n var nextCode = charCode(source, pos + 1)\n if (\n nextCode === $.CHAR_SPACE ||\n nextCode === $.CHAR_x ||\n nextCode === $.CHAR_X\n ) {\n flushText(pos)\n result.push({\n type: RuleType.gfmTask,\n completed: nextCode === $.CHAR_x || nextCode === $.CHAR_X,\n } as MarkdownToJSX.GFMTaskNode)\n pos += 3\n textStart = pos\n continue\n }\n }\n }\n\n var isImage = false\n if (pos > start && source[pos - 1] === '!') {\n var backslashCount = 0\n for (\n var checkPos = pos - 2;\n checkPos >= start && source[checkPos] === '\\\\';\n checkPos--\n )\n backslashCount++\n if ((backslashCount & 1) === 0) {\n isImage = true\n if (textStart < pos - 1) flushText(pos - 1)\n if (\n result.length > 0 &&\n result[result.length - 1].type === RuleType.text\n ) {\n var lastText = result[result.length - 1] as MarkdownToJSX.TextNode\n if (lastText.text.endsWith('!')) {\n lastText.text = lastText.text.slice(0, -1)\n if (!lastText.text) result.pop()\n }\n }\n }\n }\n if (!isImage) flushText(pos)\n textStart = pos + 1\n if (!inAnchor || isImage) {\n bracketStack.push({\n type: isImage ? 'image' : 'link',\n pos: isImage ? pos - 1 : pos,\n resultIdx: result.length,\n inAnchor: inAnchor,\n })\n }\n\n pos++\n continue\n }\n\n // LINKS AND IMAGES - CLOSING BRACKET\n if (code === $.CHAR_BRACKET_CLOSE && bracketStack.length > 0) {\n var bracket = bracketStack[bracketStack.length - 1]\n var linkTextStart = bracket.pos + (bracket.type === 'image' ? 2 : 1)\n var linkTextEnd = pos\n flushText(pos)\n var afterBracket = pos + 1\n var linkChildren = buildLinkChildren(result, bracket)\n var hasNestedLink = bracket.type === 'link' && containsLink(linkChildren)\n var foundRefBrackets = false\n\n if (\n !hasNestedLink &&\n afterBracket < end &&\n source[afterBracket] === '('\n ) {\n var urlResult = parseUrlAndTitle(source, afterBracket + 1, true)\n if (urlResult) {\n finalizeLinkOrImageNode(\n result,\n delimiterStack,\n bracketStack,\n bracket,\n linkTextStart,\n linkTextEnd,\n options.sanitizer(\n unescapeUrlOrTitle(urlResult.target),\n 'a',\n 'href'\n ),\n urlResult.title ? unescapeUrlOrTitle(urlResult.title) : undefined\n )\n pos = urlResult.endPos\n textStart = pos\n continue\n }\n }\n\n var refs = state.refs || {}\n util.hasKeys(refs);\n var refLabel: string | null = null\n var refEnd = pos\n if (afterBracket < end && source[afterBracket] === '[') {\n var refStart = afterBracket + 1\n var i = refStart\n while (i < end && source[i] !== ']') i++\n if (i < end) {\n refLabel = source.slice(refStart, i)\n refEnd = i\n foundRefBrackets = true\n }\n }\n if (!foundRefBrackets || refLabel === '')\n refLabel = source.slice(linkTextStart, linkTextEnd)\n var normalizedRef = normalizeReferenceLabel(refLabel)\n if (!hasNestedLink && refs && refs[normalizedRef]) {\n var ref = refs[normalizedRef]\n finalizeLinkOrImageNode(\n result,\n delimiterStack,\n bracketStack,\n bracket,\n linkTextStart,\n linkTextEnd,\n ref.target,\n ref.title\n )\n pos = refEnd + 1\n textStart = pos\n continue\n }\n\n var bracketResultIdx = bracket.resultIdx\n bracketStack.pop()\n result.length = bracketResultIdx\n if (bracket.type === 'image')\n result.push({\n type: RuleType.text,\n text: '!',\n } as MarkdownToJSX.TextNode)\n result.push(\n { type: RuleType.text, text: '[' } as MarkdownToJSX.TextNode,\n ...linkChildren,\n { type: RuleType.text, text: ']' } as MarkdownToJSX.TextNode\n )\n for (var k = 0; k < delimiterStack.length; k++) {\n if (delimiterStack[k].nodeIndex >= bracketResultIdx)\n delimiterStack[k].nodeIndex++\n }\n pos++\n textStart = pos\n continue\n }\n\n // ========================================\n // EMPHASIS AND STRIKETHROUGH DELIMITERS (*, _, ~~, ==)\n // ========================================\n if (\n code === $.CHAR_ASTERISK ||\n code === $.CHAR_UNDERSCORE ||\n code === $.CHAR_TILDE ||\n code === $.CHAR_EQ\n ) {\n var delimChar = source[pos]\n var delimStart = pos\n var delimCount = countConsecutiveChars(source, pos, delimChar)\n\n // GFM strikethrough (~~) and marked text (==) require exactly 2 delimiters\n if ((delimChar === '~' || delimChar === '=') && delimCount !== 2) {\n pos++\n continue\n }\n\n var delimiterEnd = delimStart + delimCount\n var leftFlanking = checkFlanking(source, delimStart, delimiterEnd, end, 0)\n var rightFlanking = checkFlanking(\n source,\n delimStart,\n delimiterEnd,\n start,\n 1\n )\n var canOpen = leftFlanking\n var canClose = rightFlanking\n if (delimChar === '_' && leftFlanking && rightFlanking) {\n if (delimStart > 0) {\n var precedingChar = source[delimStart - 1]\n var precedingCode = charCode(precedingChar)\n canOpen = isPunctuation(precedingCode, precedingChar)\n }\n if (delimiterEnd < end) {\n var followingChar = source[delimiterEnd]\n var followingCode = charCode(followingChar)\n canClose = isPunctuation(followingCode, followingChar)\n }\n }\n flushText(delimStart)\n delimiterStack.push({\n nodeIndex: result.length,\n type: delimChar as '*' | '_' | '~' | '=',\n length: delimCount,\n canOpen: canOpen,\n canClose: canClose,\n active: true,\n sourcePos: delimStart,\n inAnchor: inAnchor,\n })\n result.push({\n type: RuleType.text,\n text: source.slice(delimStart, delimStart + delimCount),\n } as MarkdownToJSX.TextNode)\n\n pos = delimStart + delimCount\n textStart = pos\n continue\n }\n\n // ========================================\n // LINE BREAKS\n // ========================================\n if (code === $.CHAR_NEWLINE) {\n var checkPos = pos - 1\n var spaceCount = 0\n while (\n checkPos >= textStart &&\n charCode(source, checkPos) === $.CHAR_SPACE\n ) {\n spaceCount++\n checkPos--\n }\n if (spaceCount >= 2) {\n var afterNewline = pos + 1\n while (\n afterNewline < end &&\n charCode(source, afterNewline) === $.CHAR_SPACE\n )\n afterNewline++\n if (afterNewline >= end) {\n flushText(checkPos + 1)\n pos = end\n textStart = end\n continue\n }\n flushText(checkPos + 1)\n result.push({ type: RuleType.breakLine } as MarkdownToJSX.BreakLineNode)\n pos++\n while (pos < end && charCode(source, pos) === $.CHAR_SPACE) pos++\n textStart = pos\n continue\n }\n\n var prevCode = pos > textStart ? charCode(source, pos - 1) : 0\n var nextCode = pos + 1 < end ? charCode(source, pos + 1) : 0\n var flushPos =\n pos > textStart &&\n prevCode === $.CHAR_SPACE &&\n nextCode === $.CHAR_SPACE\n ? pos - 1\n : pos\n flushText(flushPos)\n result.push({ type: RuleType.text, text: '\\n' } as MarkdownToJSX.TextNode)\n textStart = pos + 1\n if (\n pos > start &&\n prevCode === $.CHAR_SPACE &&\n textStart < end &&\n charCode(source, textStart) === $.CHAR_SPACE\n )\n textStart++\n pos = textStart\n continue\n }\n\n if (code === $.CHAR_AMPERSAND) hasAmpersand = true\n pos++\n while (pos < end) {\n var code = charCode(source, pos)\n if (code >= $.CHAR_ASCII_BOUNDARY) break\n if (code === $.CHAR_AMPERSAND) hasAmpersand = true\n var lookupCharType = util.inlineCharTypeTable[code]\n if (lookupCharType === 0) {\n pos++\n continue\n }\n if (\n lookupCharType === 1 &&\n (code === $.CHAR_f || code === $.CHAR_H || code === $.CHAR_W) &&\n skipAutoLink\n ) {\n pos++\n continue\n }\n break\n }\n }\n\n flushText(pos)\n\n // Process emphasis using delimiter stack algorithm\n if (delimiterStack.length) {\n processEmphasis(result, delimiterStack, null)\n }\n\n // Insert bracket text nodes in forward order (more efficient than reverse splices)\n if (bracketStack.length) {\n bracketStack.sort(function (a, b) {\n return a.resultIdx - b.resultIdx\n })\n for (var i = 0; i < bracketStack.length; i++) {\n result.splice(bracketStack[i].resultIdx + i, 0, {\n type: RuleType.text,\n text: bracketStack[i].type === 'image' ? '![' : '[',\n } as MarkdownToJSX.TextNode)\n }\n }\n\n return result\n}\n\n// Helper: Process emphasis within link/image text and update delimiter stack\nfunction processEmphasisInLinkText(\n result: MarkdownToJSX.ASTNode[],\n delimiterStack: DelimiterEntry[],\n bracket: BracketEntry,\n linkTextStart: number,\n linkTextEnd: number\n): void {\n var hasDelims = false\n for (var di = 0; di < delimiterStack.length; di++) {\n if (\n delimiterStack[di].sourcePos >= linkTextStart &&\n delimiterStack[di].sourcePos < linkTextEnd\n ) {\n hasDelims = true\n break\n }\n }\n if (!hasDelims) return\n\n var tempNodes = buildLinkChildren(result, bracket)\n var tempDelims: DelimiterEntry[] = []\n for (var di = 0; di < delimiterStack.length; di++) {\n var delim = delimiterStack[di]\n if (delim.sourcePos >= linkTextStart && delim.sourcePos < linkTextEnd) {\n tempDelims.push({\n nodeIndex: delim.nodeIndex - bracket.resultIdx,\n type: delim.type,\n length: delim.length,\n canOpen: delim.canOpen,\n canClose: delim.canClose,\n active: delim.active,\n sourcePos: delim.sourcePos,\n inAnchor: delim.inAnchor,\n })\n }\n }\n processEmphasis(tempNodes, tempDelims, null)\n result.length = bracket.resultIdx\n for (var i = 0; i < tempNodes.length; i++) result.push(tempNodes[i])\n var newDelimStack: DelimiterEntry[] = []\n for (var di = 0; di < delimiterStack.length; di++) {\n if (\n delimiterStack[di].sourcePos < linkTextStart ||\n delimiterStack[di].sourcePos >= linkTextEnd\n ) {\n newDelimStack.push(delimiterStack[di])\n }\n }\n delimiterStack.length = 0\n for (var i = 0; i < newDelimStack.length; i++)\n delimiterStack.push(newDelimStack[i])\n}\n\n// Helper: Create link or image node from children and target/title\nfunction createLinkOrImageNode(\n bracket: BracketEntry,\n linkChildren: MarkdownToJSX.ASTNode[],\n target: string | null,\n title: string | undefined\n): MarkdownToJSX.ASTNode {\n if (bracket.type === 'link') {\n return {\n type: RuleType.link,\n target: target,\n title: title,\n children: linkChildren,\n } as MarkdownToJSX.LinkNode\n }\n return {\n type: RuleType.image,\n target: target || '',\n alt: extractAllTextFromNodes(linkChildren),\n title: title,\n } as MarkdownToJSX.ImageNode\n}\n\nfunction buildLinkChildren(\n result: MarkdownToJSX.ASTNode[],\n bracket: BracketEntry\n): MarkdownToJSX.ASTNode[] {\n return result.slice(bracket.resultIdx)\n}\n\nfunction finalizeLinkOrImageNode(\n result: MarkdownToJSX.ASTNode[],\n delimiterStack: DelimiterEntry[],\n bracketStack: BracketEntry[],\n bracket: BracketEntry,\n linkTextStart: number,\n linkTextEnd: number,\n target: string | null,\n title: string | undefined\n): void {\n processEmphasisInLinkText(\n result,\n delimiterStack,\n bracket,\n linkTextStart,\n linkTextEnd\n )\n var linkChildren = buildLinkChildren(result, bracket)\n bracketStack.pop()\n result.length = bracket.resultIdx\n result.push(createLinkOrImageNode(bracket, linkChildren, target, title))\n}\n\n/** Parse URL and optional title from parentheses: (url \"title\") */\n// Parse link destination (URL) - handles angle brackets and regular URLs\nfunction parseLinkDestination(\n source: string,\n start: number,\n allowNestedParens: boolean\n): { target: string; endPos: number; hadSpace: boolean } | null {\n let i = util.skipWhitespace(source, start)\n const hasAngleBrackets = i < source.length && source[i] === '<'\n if (hasAngleBrackets) i++\n const actualUrlStart = i\n\n // Handle empty angle brackets <>\n if (hasAngleBrackets && i < source.length && source[i] === '>') {\n return { target: '', endPos: i + 1, hadSpace: false }\n }\n\n let target: string\n let urlEnd: number\n var foundSpace = false\n\n if (hasAngleBrackets) {\n // For angle bracket URLs, parse until '>', allowing spaces and handling escapes\n urlEnd = i\n while (urlEnd < source.length && source[urlEnd] !== '>') {\n const c = source[urlEnd]\n if (c === '\\n' || c === '\\r' || c === '<') return null\n if (c === '\\\\') {\n urlEnd += 2\n continue\n }\n urlEnd++\n }\n if (urlEnd >= source.length || source[urlEnd] !== '>') return null\n urlEnd++\n // Trim leading and trailing whitespace inside < >\n let actualStart = actualUrlStart\n while (actualStart < urlEnd - 1 && isSpaceOrTab(source[actualStart]))\n actualStart++\n let actualEnd = urlEnd - 1\n while (actualEnd > actualStart && isSpaceOrTab(source[actualEnd - 1]))\n actualEnd--\n target = source.slice(actualStart, actualEnd)\n i = urlEnd\n } else {\n // Non-angle bracket URL: break on whitespace, newline\n let parenDepth = 0\n urlEnd = i\n while (urlEnd < source.length) {\n const c = source[urlEnd]\n if (c === ' ' || c === '\\t' || c === '\\n') {\n foundSpace = true\n break\n }\n if (!allowNestedParens && c === ')') break\n if (allowNestedParens && c === '(') {\n if (urlEnd > 0 && source[urlEnd - 1] === '\\\\') {\n urlEnd++\n continue\n }\n parenDepth++\n urlEnd++\n continue\n }\n if (allowNestedParens && c === ')') {\n if (urlEnd > 0 && source[urlEnd - 1] === '\\\\') {\n urlEnd++\n continue\n }\n if (parenDepth === 0) break\n parenDepth--\n urlEnd++\n continue\n }\n urlEnd++\n }\n target = source.slice(actualUrlStart, urlEnd)\n i = urlEnd\n }\n\n return { target, endPos: i, hadSpace: foundSpace }\n}\n\n// Parse link title - handles quoted and parenthesized titles\nfunction parseLinkTitle(\n source: string,\n start: number,\n hadSpaceInUrl: boolean,\n hasAngleBrackets: boolean\n): { title: string | undefined; endPos: number } {\n let i = start\n // Skip whitespace after URL\n let newlineCount = 0\n while (i < source.length) {\n const c = source[i]\n if (isSpaceOrTab(c)) {\n i++\n } else if (c === '\\n') {\n if (newlineCount >= 1) break\n newlineCount++\n i++\n } else if (util.isUnicodeWhitespace(c)) {\n break\n } else {\n break\n }\n }\n\n // If URL contained spaces and there's no title delimiter, the link is invalid\n if (hadSpaceInUrl && !hasAngleBrackets) {\n if (\n i >= source.length ||\n (source[i] !== '\"' && source[i] !== \"'\" && source[i] !== '(')\n ) {\n return { title: undefined, endPos: i }\n }\n }\n let title: string | undefined = undefined\n if (i < source.length) {\n const titleChar = source[i]\n if (titleChar === '\"' || titleChar === \"'\") {\n i++\n const titleStart = i\n while (i < source.length && source[i] !== titleChar) {\n if (source[i] === '\\\\') i++\n i++\n }\n if (i < source.length) {\n title = source.slice(titleStart, i)\n i++\n }\n } else if (titleChar === '(') {\n i++\n const titleStart = i\n let parenDepth = 1\n while (i < source.length && parenDepth > 0) {\n if (source[i] === '\\\\' && i + 1 < source.length) i++\n else if (source[i] === '(') parenDepth++\n else if (source[i] === ')') parenDepth--\n i++\n }\n if (parenDepth === 0) {\n title = source.slice(titleStart, i - 1)\n }\n }\n }\n\n i = util.skipWhitespace(source, i)\n return { title, endPos: i }\n}\n\nfunction parseUrlAndTitle(\n source: string,\n urlStart: number,\n allowNestedParens: boolean\n): { target: string; title: string | undefined; endPos: number } | null {\n const destResult = parseLinkDestination(source, urlStart, allowNestedParens)\n if (!destResult) return null\n\n let i = urlStart\n i = util.skipWhitespace(source, i)\n const hasAngleBrackets = i < source.length && source[i] === '<'\n\n // Handle empty angle brackets <>\n if (\n hasAngleBrackets &&\n destResult.target === '' &&\n destResult.endPos === i + 2\n ) {\n const titleResult = parseLinkTitle(\n source,\n destResult.endPos,\n false,\n hasAngleBrackets\n )\n if (\n titleResult.endPos >= source.length ||\n source[titleResult.endPos] !== ')'\n )\n return null\n return {\n target: '',\n title: titleResult.title,\n endPos: titleResult.endPos + 1,\n }\n }\n\n const titleResult = parseLinkTitle(\n source,\n destResult.endPos,\n destResult.hadSpace,\n hasAngleBrackets\n )\n if (titleResult.endPos >= source.length || source[titleResult.endPos] !== ')')\n return null\n\n return {\n target: destResult.target,\n title: titleResult.title,\n endPos: titleResult.endPos + 1,\n }\n}\n\nenum AutolinkMode {\n URI,\n EMAIL,\n ANGLE,\n}\n\nfunction isAlphaCode(code: number): boolean {\n return (\n (code >= $.CHAR_A && code <= $.CHAR_Z) ||\n (code >= $.CHAR_a && code <= $.CHAR_z)\n )\n}\n\nfunction isValidUriScheme(content: string): boolean {\n const colonPos = content.indexOf(':')\n if (colonPos < 2 || colonPos > 32) return false\n\n const firstCharCode = charCode(content)\n if (!isAlphaCode(firstCharCode)) {\n return false\n }\n\n // Check if all chars before colon are valid scheme chars\n for (let j = 1; j < colonPos; j++) {\n const c = content[j]\n const cCode = charCode(c)\n if (!isAlnum(c) && c !== '+' && c !== '.' && c !== '-') {\n return false\n }\n }\n return true\n}\n\nfunction isValidAutolinkContext(\n source: string,\n start: number,\n includeCR: boolean\n): boolean {\n if (start === 0) return true\n let validChars = includeCR ? ' \\t\\n\\r*_~(' : ' \\t\\n*_~('\n return validChars.indexOf(source[start - 1]) !== -1\n}\n\nfunction sanitizeAndCreate(\n target: string,\n linkText: string,\n endPos: number,\n sanitizer: (url: string, tag: string, attr: string) => string | null,\n emailStart?: number\n): ParseResult | null {\n let safe = sanitizer(target, 'a', 'href')\n if (!safe) return null\n return {\n type: RuleType.link,\n target: safe,\n children: [{ type: RuleType.text, text: linkText }],\n endPos: endPos,\n ...(emailStart !== undefined ? { emailStart } : {}),\n } as MarkdownToJSX.LinkNode & { endPos: number; emailStart?: number }\n}\n\nfunction parseAutolink(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions,\n mode: AutolinkMode\n): ParseResult | null {\n if (\n state.inAnchor ||\n (mode !== AutolinkMode.ANGLE && options.disableAutoLink)\n )\n return null\n\n if (mode === AutolinkMode.ANGLE) {\n if (source[pos] !== '<') return null\n let end = pos + 1\n while (end < source.length && source[end] !== '>') {\n if (isSpaceOrTab(source[end])) return null\n end++\n }\n if (end >= source.length || source[end] !== '>') return null\n let content = source.slice(pos + 1, end)\n if (!content.length) return null\n\n let hasBackslash = content.indexOf('\\\\') !== -1\n let hasValidUriScheme = isValidUriScheme(content)\n let isHttp =\n util.startsWith(content, 'http://') ||\n util.startsWith(content, 'https://')\n let contentLower = content.toLowerCase()\n let isMailto = util.startsWith(contentLower, 'mailto:')\n let isEmailLike =\n !hasBackslash &&\n content.indexOf('@') !== -1 &&\n content.indexOf('//') === -1 &&\n !hasValidUriScheme\n\n if (!isHttp && !isMailto && !isEmailLike && !hasValidUriScheme) return null\n\n let target = content,\n linkText = content\n if (hasValidUriScheme || isHttp) {\n // URI scheme or HTTP(S) - use content as-is (preserve case)\n } else if (isMailto) {\n let colonPos = contentLower.indexOf(':')\n linkText = content.slice(colonPos + 1)\n target = 'mailto:' + linkText\n } else if (isEmailLike) {\n target = 'mailto:' + content\n }\n\n return sanitizeAndCreate(target, linkText, end + 1, options.sanitizer)\n }\n\n if (mode === AutolinkMode.EMAIL) {\n let emailStart = pos\n while (\n emailStart > 0 &&\n (isAlnum(source[emailStart - 1]) ||\n '.+-_'.indexOf(source[emailStart - 1]) !== -1)\n )\n emailStart--\n if (emailStart >= pos || !isValidAutolinkContext(source, emailStart, true))\n return null\n\n let emailEnd = pos + 1\n let hasDot = false\n while (emailEnd < source.length) {\n let c = source[emailEnd]\n if (c === '.') {\n hasDot = true\n emailEnd++\n } else if (isAlnum(c) || c === '-' || c === '_') emailEnd++\n else break\n }\n\n if (!hasDot || emailEnd <= pos + 1) return null\n while (emailEnd > pos + 1 && source[emailEnd - 1] === '.') emailEnd--\n if (\n emailEnd > pos + 1 &&\n (source[emailEnd - 1] === '-' || source[emailEnd - 1] === '_')\n )\n return null\n // Check if email contains at least one dot\n // For large documents, prefer slice+includes to avoid scanning entire document\n const emailLength = emailEnd - (pos + 1)\n if (emailLength < 10000) {\n if (\n source.indexOf('.', pos + 1) >= emailEnd ||\n source.indexOf('.', pos + 1) === -1\n )\n return null\n } else {\n if (source.slice(pos + 1, emailEnd).indexOf('.') === -1) return null\n }\n\n let email = source.slice(emailStart, emailEnd)\n return sanitizeAndCreate(\n 'mailto:' + email,\n email,\n emailEnd,\n options.sanitizer,\n emailStart\n )\n }\n\n let isHttp =\n util.startsWith(source, 'http://', pos) ||\n util.startsWith(source, 'https://', pos)\n let isFtp = !isHttp && util.startsWith(source, 'ftp://', pos)\n let isWww = !isHttp && !isFtp && util.startsWith(source, 'www.', pos)\n if (\n !(isHttp || isFtp || isWww) ||\n !isValidAutolinkContext(source, pos, false)\n )\n return null\n\n var urlEnd =\n pos +\n (isHttp ? (charCode(source, pos + 4) === $.CHAR_s ? 8 : 7) : isFtp ? 6 : 4)\n var domainStart = urlEnd\n // Inline scanDomain\n while (urlEnd < source.length) {\n const code = charCode(source, urlEnd)\n if (\n code === $.CHAR_SPACE ||\n code === $.CHAR_TAB ||\n code === $.CHAR_NEWLINE ||\n code === $.CHAR_LT ||\n code === $.CHAR_GT\n )\n break\n urlEnd++\n }\n if (urlEnd <= domainStart) return null\n // Inline trimTrailingPunct\n let trimmed = urlEnd\n while (trimmed > domainStart) {\n let lastChar = source[trimmed - 1]\n if (trimmed > domainStart + 1 && source[trimmed - 2] === '\\\\') break\n if (\n lastChar === '?' ||\n lastChar === '!' ||\n lastChar === '.' ||\n lastChar === ',' ||\n lastChar === ':' ||\n lastChar === '*' ||\n lastChar === '_' ||\n lastChar === '~'\n ) {\n trimmed--\n } else if (lastChar === ';') {\n let ampPos = trimmed - 2\n while (\n ampPos >= domainStart &&\n source[ampPos] !== '&' &&\n source[ampPos] !== ' '\n )\n ampPos--\n if (ampPos >= domainStart && source[ampPos] === '&') {\n let entityName = source.slice(ampPos + 1, trimmed - 1)\n if (\n entityName.length >= 2 &&\n entityName.length <= 10 &&\n /^[a-zA-Z0-9]+$/.test(entityName) &&\n (entityName === 'lt' ||\n entityName === 'gt' ||\n (entityName.length >= 3 &&\n (util.startsWith(entityName, 'amp') ||\n util.startsWith(entityName, 'apos') ||\n util.startsWith(entityName, 'quot') ||\n util.startsWith(entityName, 'nbsp') ||\n /^[a-z]{3,10}$/.test(entityName))))\n )\n break\n trimmed = ampPos\n break\n }\n trimmed--\n } else if (lastChar === ')') {\n let openCount = 0,\n closeCount = 0\n for (let i = domainStart; i < trimmed; i++) {\n if (source[i] === '(') openCount++\n if (source[i] === ')') closeCount++\n }\n if (closeCount > openCount) trimmed--\n else break\n } else break\n }\n urlEnd = trimmed\n if (urlEnd <= domainStart) return null\n\n let linkText = source.slice(pos, urlEnd)\n return sanitizeAndCreate(\n isWww ? 'http://' + linkText : linkText,\n linkText,\n urlEnd,\n options.sanitizer\n )\n}\n\n// Unified link/image parser - handles all link/image types based on starting character\nfunction parseLinkOrImage(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions,\n startChar: '[' | '!' | '<' | 'h' | 'f' | 'w' | '@'\n): ParseResult | null {\n // Angle brace autolink: <url>\n if (startChar === '<') {\n return parseAutolink(\n source,\n pos,\n state,\n options,\n AutolinkMode.ANGLE\n ) as ParseResult\n }\n\n // Bare URL autolink: http://, https://, ftp://, www.\n if (startChar === 'h' || startChar === 'f' || startChar === 'w') {\n return parseAutolink(\n source,\n pos,\n state,\n options,\n AutolinkMode.URI\n ) as ParseResult\n }\n\n // Email autolink: @example.com\n if (startChar === '@') {\n return parseAutolink(\n source,\n pos,\n state,\n options,\n AutolinkMode.EMAIL\n ) as ParseResult | null\n }\n\n // Bracket-based links/images are handled inline in parseInlineSpan\n // This function only handles autolinks\n return null\n}\n\nfunction normalizeReferenceLabel(label: string): string {\n var trimmed = label.trim()\n var normalized = trimmed.replace(/[\\s\\t\\n\\r]+/g, ' ')\n if (normalized.indexOf('\\u1E9E') !== -1) {\n return normalized.replace(/\\u1E9E/g, 'ss').toLowerCase();\n }\n return normalized.toLowerCase()\n}\n\nfunction parseGFMTask(\n source: string,\n pos: number,\n state: MarkdownToJSX.State\n): ParseResult {\n if (pos + 3 >= source.length || source[pos] !== '[') return null\n const marker = source[pos + 1]\n if (marker !== ' ' && marker !== 'x' && marker !== 'X') return null\n if (source[pos + 2] !== ']') return null\n return {\n type: RuleType.gfmTask,\n completed: marker.toLowerCase() === 'x',\n endPos: pos + 3,\n } as MarkdownToJSX.GFMTaskNode & { endPos: number }\n}\n\nfunction parseBlocksWithState(\n content: string,\n state: MarkdownToJSX.State,\n options: ParseOptions,\n config: { inline?: boolean; list?: boolean; inBlockQuote?: boolean }\n): MarkdownToJSX.ASTNode[] {\n const originalInline = state.inline\n const originalList = state.inList\n const originalInBlockQuote = state.inBlockQuote\n if (config.inline !== undefined) state.inline = config.inline\n if (config.list !== undefined) state.inList = config.list\n if (config.inBlockQuote !== undefined)\n state.inBlockQuote = config.inBlockQuote\n const blocks = parseBlocksInHTML(content, state, options)\n state.inline = originalInline\n state.inList = originalList\n state.inBlockQuote = originalInBlockQuote\n return blocks\n}\n\nfunction parseInlineWithState(\n content: string,\n start: number,\n end: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): MarkdownToJSX.ASTNode[] {\n return parseWithInlineMode(state, true, () =>\n parseInlineSpan(content, start, end, state, options)\n )\n}\n\ntype BlockParserFn = (\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n) => ParseResult | null\n\nfunction parseBlock(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult | null {\n var char = source[pos]\n if (char === undefined) return null\n var effectivePos = pos\n var indentInfo: ReturnType<typeof calculateIndent> | null = null\n var firstChar = char\n var lineEnd: number | null = null\n\n var charCodeVal = charCode(char)\n var isIndentChar = charCodeVal === $.CHAR_SPACE || charCodeVal === $.CHAR_TAB\n if (isIndentChar) {\n lineEnd = util.findLineEnd(source, pos)\n indentInfo = calculateIndent(source, pos, lineEnd)\n effectivePos = pos + indentInfo.charCount\n if (effectivePos >= source.length) return parseCodeBlock(source, pos, state)\n firstChar = source[effectivePos]\n }\n var spaceEquivalent = indentInfo ? indentInfo.spaceEquivalent : 0\n if (spaceEquivalent >= 4) {\n if (isIndentChar) return parseCodeBlock(source, pos, state)\n return null\n }\n var firstCharCode = charCode(firstChar)\n if (firstCharCode === $.CHAR_GT) {\n var blockQuoteResult = parseBlockQuote(source, pos, state, options)\n if (blockQuoteResult) return blockQuoteResult\n } else if (firstCharCode === $.CHAR_UNDERSCORE) {\n return parseBreakThematic(source, pos, state, options)\n } else if (\n firstCharCode === $.CHAR_DASH ||\n firstCharCode === $.CHAR_ASTERISK ||\n firstCharCode === $.CHAR_PLUS\n ) {\n var thematicBreakResult = parseBreakThematic(source, pos, state, options)\n if (thematicBreakResult) return thematicBreakResult\n var listResult = parseList(source, pos, state, options)\n if (listResult) return listResult\n } else if (\n firstCharCode >= $.CHAR_DIGIT_0 &&\n firstCharCode <= $.CHAR_DIGIT_9\n ) {\n var listResult = parseList(source, pos, state, options)\n if (listResult) return listResult\n } else if (firstCharCode === $.CHAR_HASH) {\n return parseHeading(source, effectivePos, state, options)\n } else if (firstCharCode === $.CHAR_BRACKET_OPEN) {\n return parseDefinition(\n source,\n effectivePos,\n state,\n options,\n effectivePos + 1 < source.length &&\n charCode(source, effectivePos + 1) === $.CHAR_CARET\n )\n } else if (firstCharCode === $.CHAR_LT && !options.disableParsingRawHTML) {\n return parseHTML(source, effectivePos, state, options)\n } else if (\n firstCharCode === $.CHAR_BACKTICK ||\n firstCharCode === $.CHAR_TILDE\n ) {\n if (!lineEnd) lineEnd = util.findLineEnd(source, pos)\n if (!indentInfo) indentInfo = calculateIndent(source, pos, lineEnd)\n if (indentInfo.spaceEquivalent <= 3)\n return parseCodeFenced(source, effectivePos, state, options)\n } else if (firstCharCode === $.CHAR_PIPE) {\n return parseTable(source, pos, state, options)\n }\n if (isIndentChar) return parseCodeBlock(source, pos, state)\n return null\n}\n\n/** Parse blocks inside HTML content */\nfunction parseBlocksInHTML(\n input: string,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): MarkdownToJSX.ASTNode[] {\n const result: MarkdownToJSX.ASTNode[] = []\n let pos = 0\n\n while (pos < input.length) {\n while (pos < input.length && input[pos] === '\\n') {\n pos++\n }\n\n if (pos >= input.length) break\n\n var char = input[pos]\n\n // Fast path: check for setext heading in list context\n // Per CommonMark: setext headings take precedence over thematic breaks\n if (state.inList && result.length > 0) {\n var lastBlock = result[result.length - 1]\n if (lastBlock?.type === RuleType.paragraph) {\n var paragraph = lastBlock as MarkdownToJSX.ParagraphNode\n // Quick check for potential setext underline characters\n var code = charCode(char)\n if (\n code === $.CHAR_DASH ||\n code === $.CHAR_EQ ||\n code === $.CHAR_SPACE ||\n code === $.CHAR_TAB\n ) {\n var lineEnd = util.findLineEnd(input, pos)\n var lineContent = input.slice(pos, lineEnd)\n\n // Check indentation (up to 3 spaces allowed for setext headings)\n var indentInfo = calculateIndent(input, pos, lineEnd)\n if (indentInfo.spaceEquivalent < 4) {\n var trimmed = lineContent.slice(indentInfo.charCount).trim()\n // Use convertSetextHeadingInListItem helper to check and convert\n if (convertSetextHeadingInListItem(result, trimmed, options)) {\n pos =\n lineEnd +\n (lineEnd < input.length && input[lineEnd] === '\\n' ? 1 : 0)\n continue\n }\n }\n }\n }\n }\n\n // Try parseBlock first (handles most block types)\n var blockResult = parseBlock(input, pos, state, options)\n if (blockResult) {\n result.push(blockResult)\n pos = blockResult.endPos\n continue\n }\n\n // Try setext heading (not handled by parseBlock)\n var setextResult = parseHeadingSetext(input, pos, state, options)\n if (setextResult) {\n result.push(setextResult)\n pos = setextResult.endPos\n continue\n }\n\n var remaining = input.slice(pos).trim()\n if (remaining) {\n // Per CommonMark spec example 293: Before parsing a paragraph, check if there's\n // a blockquote ending with a paragraph in recent blocks that this should merge into\n if (state.inBlockQuote && result.length > 0) {\n // Find the deepest blockquote ending with a paragraph in recent blocks\n // (may be nested inside list items)\n function findBlockquoteWithParagraphEnd(\n node: MarkdownToJSX.ASTNode\n ): MarkdownToJSX.ParagraphNode | null {\n if (node.type === RuleType.blockQuote) {\n var blockQuote = node as MarkdownToJSX.BlockQuoteNode\n if (blockQuote.children && blockQuote.children.length > 0) {\n var lastChild =\n blockQuote.children[blockQuote.children.length - 1]\n if (lastChild.type === RuleType.paragraph) {\n return lastChild as MarkdownToJSX.ParagraphNode\n }\n }\n } else if (\n node.type === RuleType.orderedList ||\n node.type === RuleType.unorderedList\n ) {\n var list = node as\n | MarkdownToJSX.OrderedListNode\n | MarkdownToJSX.UnorderedListNode\n if (list.items && list.items.length > 0) {\n var lastItem = list.items[list.items.length - 1]\n if (lastItem && lastItem.length > 0) {\n var lastItemChild = lastItem[lastItem.length - 1]\n var found = findBlockquoteWithParagraphEnd(lastItemChild)\n if (found) return found\n }\n }\n }\n return null\n }\n\n // Check recent blocks (from end) for blockquote ending with paragraph\n for (var i = result.length - 1; i >= 0; i--) {\n var paragraph = findBlockquoteWithParagraphEnd(result[i])\n if (paragraph) {\n var parseResult = parseParagraph(input, pos, state, options)\n if (parseResult) {\n var newParagraph = parseResult as MarkdownToJSX.ParagraphNode\n // Merge the new paragraph's children into the blockquote's paragraph\n if (paragraph.children && newParagraph.children) {\n paragraph.children.push(\n { type: RuleType.text, text: '\\n' } as MarkdownToJSX.TextNode,\n ...newParagraph.children\n )\n }\n pos = parseResult.endPos\n continue\n }\n }\n }\n }\n\n var parseResult = parseParagraph(input, pos, state, options)\n if (parseResult) {\n result.push(parseResult)\n pos = parseResult.endPos\n continue\n }\n }\n\n pos++\n }\n\n return result\n}\n\nfunction parseHeading(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult {\n if (state.inline) return null\n\n // Find line end to limit expensive indentation scan\n const lineEnd = util.findLineEnd(source, pos)\n const indentResult = calculateIndent(source, pos, lineEnd, 3)\n if (indentResult.spaceEquivalent > 3 && !state.inList) return null\n var i = pos + indentResult.charCount\n\n if (i >= source.length || source[i] !== '#') return null\n\n const level = countConsecutiveChars(source, i, '#', 6)\n i += level\n\n if (i >= source.length) return null\n const afterHash = source[i]\n if (afterHash === '\\n' || afterHash === '\\r') {\n const lineEnd = util.findLineEnd(source, i)\n return {\n ...createHeading(level, [], '', options.slugify),\n endPos: lineEnd + (lineEnd < source.length ? 1 : 0),\n } as MarkdownToJSX.HeadingNode & { endPos: number }\n }\n if (afterHash !== ' ' && afterHash !== '\\t') return null\n\n const contentStart = i\n const contentEnd = util.findLineEnd(source, contentStart)\n var content = source\n .slice(contentStart, contentEnd)\n .replace(HEADING_TRAILING_HASHES_R, '')\n .trim()\n\n const children = parseInlineWithState(\n content,\n 0,\n content.length,\n state,\n options\n )\n\n return {\n ...createHeading(level, children, content, options.slugify),\n endPos: contentEnd + (contentEnd < source.length ? 1 : 0),\n } as MarkdownToJSX.HeadingNode & { endPos: number }\n}\n\nfunction parseHeadingSetext(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult {\n if (state.inline || state.inBlockQuote || state.inList) return null\n\n const firstLineEnd = util.findLineEnd(source, pos)\n if (firstLineEnd >= source.length) return null\n\n // Find underline pattern first, then validate backwards\n let underlineLineStart = firstLineEnd + 1,\n underlineLineEnd = -1,\n underlineChar: string | null = null\n\n // Scan forward for underline (= or - with up to 3 spaces indentation)\n for (\n var linesScanned = 0;\n underlineLineStart < source.length && linesScanned < 10;\n linesScanned++\n ) {\n const lineEnd = util.findLineEnd(source, underlineLineStart)\n if (lineEnd >= source.length) break\n\n // Check if blank line (stops setext headings)\n var i = underlineLineStart\n while (\n i < lineEnd &&\n (charCode(source, i) === $.CHAR_SPACE ||\n charCode(source, i) === $.CHAR_TAB ||\n charCode(source, i) === $.CHAR_CR)\n )\n i++\n if (i >= lineEnd) break\n\n // Check indentation (up to 3 spaces) and first char\n var indentCount = 0,\n checkPos = underlineLineStart\n while (\n checkPos < lineEnd &&\n indentCount < 3 &&\n charCode(source, checkPos) === $.CHAR_SPACE\n ) {\n indentCount++\n checkPos++\n }\n\n if (checkPos < lineEnd) {\n const code = charCode(source, checkPos)\n if (code === $.CHAR_EQ || code === $.CHAR_DASH) {\n // Validate underline: only = or - with optional trailing spaces, no internal spaces\n const char = source[checkPos]\n var underlineCount = 0,\n hasSeenWS = false,\n p = checkPos\n while (p < lineEnd) {\n const c = charCode(source, p)\n if (c === code) {\n if (hasSeenWS) {\n underlineCount = 0\n break\n }\n underlineCount++\n } else if (c === $.CHAR_SPACE || c === $.CHAR_TAB) {\n hasSeenWS = true\n } else {\n underlineCount = 0\n break\n }\n p++\n }\n\n if (underlineCount >= 1) {\n underlineLineEnd = lineEnd\n underlineChar = char\n break\n }\n }\n }\n\n underlineLineStart = lineEnd + 1\n }\n\n if (!underlineChar) return null\n\n // Quick validation: content cannot start with certain block characters\n const firstCharCode = charCode(source, pos)\n if (\n firstCharCode === $.CHAR_HASH ||\n firstCharCode === $.CHAR_GT ||\n source[pos] === '|'\n )\n return null\n\n // Collect content lines forward to underline\n let contentEnd = pos\n var currentPos = pos,\n hasContent = false\n\n while (currentPos < underlineLineStart) {\n const lineEnd = util.findLineEnd(source, currentPos)\n if (lineEnd >= underlineLineStart) break\n\n // Check if line has non-whitespace content\n var j = currentPos\n while (\n j < lineEnd &&\n (charCode(source, j) === $.CHAR_SPACE ||\n charCode(source, j) === $.CHAR_TAB ||\n charCode(source, j) === $.CHAR_CR)\n )\n j++\n if (j < lineEnd) {\n // Line has content\n hasContent = true\n contentEnd = lineEnd\n }\n\n currentPos = lineEnd + 1\n }\n\n if (!hasContent) return null\n\n // Extract and trim content\n const rawContent = source.slice(pos, contentEnd)\n var startTrim = 0,\n endTrim = rawContent.length\n while (\n startTrim < endTrim &&\n (rawContent.charCodeAt(startTrim) === $.CHAR_SPACE ||\n rawContent.charCodeAt(startTrim) === $.CHAR_TAB ||\n rawContent.charCodeAt(startTrim) === $.CHAR_CR ||\n rawContent.charCodeAt(startTrim) === $.CHAR_NEWLINE)\n )\n startTrim++\n while (\n endTrim > startTrim &&\n (rawContent.charCodeAt(endTrim - 1) === $.CHAR_SPACE ||\n rawContent.charCodeAt(endTrim - 1) === $.CHAR_TAB ||\n rawContent.charCodeAt(endTrim - 1) === $.CHAR_CR ||\n rawContent.charCodeAt(endTrim - 1) === $.CHAR_NEWLINE)\n )\n endTrim--\n const content = rawContent.slice(startTrim, endTrim)\n\n if (!content) return null\n\n const level = underlineChar === '=' ? 1 : 2\n const children = parseInlineWithState(\n content,\n 0,\n content.length,\n state,\n options\n )\n\n return {\n ...createHeading(level, children, content, options.slugify),\n endPos: underlineLineEnd + (underlineLineEnd < source.length ? 1 : 0),\n } as MarkdownToJSX.HeadingNode & { endPos: number }\n}\n\nfunction parseParagraph(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult {\n // Note: We don't check isBlockStartChar here because this is called as a fallback\n // after other block parsers have already tried and failed\n if (state.inline) return null\n let endPos = pos\n const sourceLen = source.length\n\n while (endPos < sourceLen) {\n let lineEnd = util.findLineEnd(source, endPos)\n let isEmptyLine = true\n\n for (let i = endPos; i < lineEnd; i++) {\n const code = charCode(source, i)\n if (code !== $.CHAR_SPACE && code !== $.CHAR_TAB && code !== $.CHAR_CR) {\n isEmptyLine = false\n break\n }\n }\n\n if (isEmptyLine) {\n endPos = lineEnd\n break\n }\n\n if (lineEnd >= sourceLen) {\n endPos = sourceLen\n break\n }\n\n const nextLineStart = lineEnd + 1\n if (nextLineStart >= sourceLen) {\n endPos = sourceLen\n break\n }\n\n let nextLineEnd = util.findLineEnd(source, nextLineStart)\n let nextLineIsEmpty = true\n let nextLineFirstChar = ''\n\n for (let i = nextLineStart; i < nextLineEnd; i++) {\n const code = charCode(source, i)\n if (code !== $.CHAR_SPACE && code !== $.CHAR_TAB && code !== $.CHAR_CR) {\n nextLineIsEmpty = false\n if (nextLineFirstChar === '') nextLineFirstChar = source[i]\n break\n }\n }\n\n if (nextLineIsEmpty) {\n endPos = lineEnd\n break\n }\n\n // Check if next line starts with a block element\n // BUT: per CommonMark, lines indented by exactly 4 spaces are paragraph continuation,\n // not code blocks or other blocks, even if they start with block-starting characters.\n let shouldBreak = false\n const nextIndentInfo = calculateIndent(source, nextLineStart, nextLineEnd)\n const isExact4SpaceIndent =\n nextIndentInfo.spaceEquivalent === 4 && nextIndentInfo.charCount === 4\n\n // Check for HTML blocks first (types 1-6 can interrupt paragraphs)\n // Per CommonMark spec: HTML blocks of types 1-6 can interrupt paragraphs\n if (\n nextLineFirstChar === '<' &&\n !isExact4SpaceIndent &&\n !options.disableParsingRawHTML\n ) {\n const htmlCheckPos = nextLineStart\n let htmlLineStart = htmlCheckPos\n let htmlIndent = 0\n while (htmlLineStart < nextLineEnd && htmlIndent < 3) {\n const code = charCode(source, htmlLineStart)\n if (code === $.CHAR_SPACE || code === $.CHAR_TAB) {\n htmlIndent++\n htmlLineStart++\n } else {\n break\n }\n }\n if (htmlLineStart < nextLineEnd && source[htmlLineStart] === '<') {\n var htmlResult = parseHTML(\n source,\n htmlLineStart,\n { ...state, inline: false },\n options\n )\n if (htmlResult) {\n shouldBreak =\n !('canInterruptParagraph' in htmlResult) ||\n (htmlResult.canInterruptParagraph as boolean)\n }\n }\n }\n\n // In list context, lines indented to the content start column are also continuation\n // For now, treat 4-space indented lines as continuation regardless of context\n if (isExact4SpaceIndent) {\n // Line is indented exactly 4 spaces - this is paragraph continuation\n // Per CommonMark spec: lines indented by exactly 4 spaces are paragraph continuation,\n // not code blocks or other blocks, even if they start with block-starting characters.\n // Don't break, continue paragraph across this line\n shouldBreak = false\n } else if (\n !shouldBreak &&\n nextLineFirstChar &&\n isBlockStartChar(nextLineFirstChar)\n ) {\n // Reference definitions don't break paragraphs - skip them\n if (nextLineFirstChar === '[') {\n // Check if it's a reference definition (not a footnote)\n const checkPos = nextLineStart\n if (checkPos + 1 >= sourceLen || source[checkPos + 1] !== '^') {\n // Could be a reference definition - don't break paragraph\n shouldBreak = false\n } else {\n // Footnote definition - break paragraph\n shouldBreak = true\n }\n } else if (nextLineFirstChar === '*' || nextLineFirstChar === '+') {\n // Asterisk/plus is only a block start for lists (*/+ followed by space/tab) or thematic breaks (3+ alone)\n // But thematic breaks can have up to 3 spaces indentation, so check for thematic break first\n const thematicBreakResult = parseBreakThematic(\n source,\n nextLineStart,\n state,\n options\n )\n if (thematicBreakResult) {\n shouldBreak = true\n } else {\n // Check if it's a list (followed by space/tab)\n const secondChar =\n nextLineStart + 1 < sourceLen ? source[nextLineStart + 1] : ''\n if (secondChar && isSpaceOrTab(secondChar)) {\n shouldBreak = true\n } else {\n // Not a list or thematic break - don't break paragraph\n shouldBreak = false\n }\n }\n } else {\n // Use parseBlock to check if next line starts a block\n // Special handling needed for setext headings and ordered lists\n const blockResult = parseBlock(source, nextLineStart, state, options)\n\n if (blockResult) {\n // Check if it's a code block from 4+ space indentation (paragraph continuation)\n if (blockResult.type === RuleType.codeBlock) {\n const blockIndentInfo = calculateIndent(\n source,\n nextLineStart,\n nextLineEnd\n )\n if (blockIndentInfo.spaceEquivalent >= 4) {\n // 4+ space indentation is paragraph continuation, not a block start\n shouldBreak = false\n } else {\n // Fenced code block - break paragraph\n shouldBreak = true\n }\n } else if (\n blockResult.type === RuleType.unorderedList ||\n blockResult.type === RuleType.orderedList\n ) {\n // Lists can interrupt paragraphs, but ordered lists starting with numbers other than 1 cannot\n if (blockResult.type === RuleType.orderedList) {\n const orderedList = blockResult as MarkdownToJSX.OrderedListNode\n // Only ordered lists starting with 1 can interrupt paragraphs\n shouldBreak = orderedList.start === 1\n } else {\n shouldBreak = true\n }\n } else if (nextLineFirstChar === '-') {\n // Dash could be setext heading underline if preceded by content\n // Per CommonMark: setext headings take precedence over thematic breaks\n if (endPos > pos) {\n // We have content - break paragraph to let setext heading parser check\n shouldBreak = true\n } else {\n // No content - use the block result (thematic break or list)\n shouldBreak = true\n }\n } else if (blockResult.type === RuleType.ref) {\n // Reference definitions don't break paragraphs\n shouldBreak = false\n } else {\n // Other block types break paragraphs\n shouldBreak = true\n }\n }\n }\n } else {\n // Next line doesn't start with a block-starting character\n // Per CommonMark: in paragraph context, lines indented by exactly 4 spaces\n // are paragraph continuation, not code blocks. Only 4+ spaces at document\n // start (not in paragraph) are code blocks.\n // So we don't break on 4-space indentation in paragraph continuation.\n }\n\n if (shouldBreak) {\n endPos = lineEnd\n break\n }\n\n // Continue paragraph across single newline\n endPos = lineEnd + 1\n }\n\n if (endPos <= pos) return null\n\n // Per CommonMark: lines indented by exactly 4 spaces in paragraph context\n // are continuation, not code blocks. We need to remove the 4-space indentation\n // from continuation lines but preserve them as part of the paragraph.\n var contentStart = pos\n var contentEnd = endPos\n\n while (contentStart < contentEnd) {\n const code = charCode(source, contentStart)\n if (code === $.CHAR_SPACE || code === $.CHAR_TAB) {\n contentStart++\n } else {\n break\n }\n }\n\n // Fast path: if no newlines, use content directly (common case)\n // Check if there's a newline between contentStart and contentEnd\n // We can optimize by checking if contentEnd is beyond the first line\n const firstLineEnd = util.findLineEnd(source, contentStart)\n var hasNewline = contentEnd > firstLineEnd\n\n var processedContent\n if (!hasNewline) {\n // Single line - no processing needed\n processedContent = source.slice(contentStart, contentEnd)\n } else {\n // Multi-line: process 4-space indentation\n var processedParts: string[] = []\n var lineStart = contentStart\n var lineIndex = 0\n\n while (lineStart < contentEnd) {\n var lineEnd = util.findLineEnd(source, lineStart)\n if (lineEnd > contentEnd) lineEnd = contentEnd\n\n if (lineIndex === 0) {\n processedParts.push(source.slice(lineStart, lineEnd))\n } else {\n // Check for exactly 4 leading spaces\n var spaceCount = 0\n while (spaceCount < 4 && lineStart + spaceCount < lineEnd) {\n if (charCode(source, lineStart + spaceCount) === $.CHAR_SPACE) {\n spaceCount++\n } else {\n break\n }\n }\n var start = spaceCount === 4 ? lineStart + 4 : lineStart\n processedParts.push(source.slice(start, lineEnd))\n }\n\n if (\n lineEnd < contentEnd &&\n charCode(source, lineEnd) === $.CHAR_NEWLINE\n ) {\n processedParts.push('\\n')\n lineStart = lineEnd + 1\n } else {\n lineStart = contentEnd\n }\n lineIndex++\n }\n processedContent = processedParts.join('')\n }\n\n var processedContentEnd = processedContent.length\n while (processedContentEnd > 0) {\n var c = processedContent.charCodeAt(processedContentEnd - 1)\n if (c === $.CHAR_SPACE || c === $.CHAR_TAB) {\n processedContentEnd--\n } else {\n break\n }\n }\n if (processedContentEnd < processedContent.length) {\n processedContent = processedContent.slice(0, processedContentEnd)\n }\n\n // Check if processed content has actual content\n let hasProcessedContent = false\n for (let i = 0; i < processedContent.length; i++) {\n const code = processedContent.charCodeAt(i)\n if (\n code !== $.CHAR_SPACE &&\n code !== $.CHAR_TAB &&\n code !== $.CHAR_NEWLINE &&\n code !== $.CHAR_CR\n ) {\n hasProcessedContent = true\n break\n }\n }\n if (!hasProcessedContent) return null\n\n // Per CommonMark spec: Extract link reference definitions from paragraph content\n // Reference definitions can appear at the end of paragraph content\n // They should be extracted and stored, not parsed as inline content\n // Scan backwards from endPos in source to find reference definitions\n var extractedContent = processedContent\n var extractedEndPos = endPos\n // Find the last newline in the source before endPos (optimized: manual scan instead of lastIndexOf)\n var lastNewlinePos = -1\n var searchPos = endPos - 1\n while (searchPos >= contentStart) {\n if (charCode(source, searchPos) === $.CHAR_NEWLINE) {\n lastNewlinePos = searchPos\n break\n }\n searchPos--\n }\n if (lastNewlinePos >= 0) {\n // Per CommonMark spec: \"A link reference definition cannot interrupt a paragraph.\"\n // Only extract reference definitions if they're at the START of the paragraph (no content before them)\n // Check if there's any non-whitespace content before the last newline\n var hasContentBeforeNewline = false\n for (var checkPos = contentStart; checkPos < lastNewlinePos; checkPos++) {\n const code = charCode(source, checkPos)\n if (\n code !== $.CHAR_SPACE &&\n code !== $.CHAR_TAB &&\n code !== $.CHAR_NEWLINE &&\n code !== $.CHAR_CR\n ) {\n hasContentBeforeNewline = true\n break\n }\n }\n\n // Only extract reference definition if there's no content before the newline\n // (i.e., it's at the start of the paragraph)\n if (!hasContentBeforeNewline) {\n // Check if the content after the last newline is a reference definition\n var refDefStartPos = lastNewlinePos + 1\n // Skip any leading whitespace\n while (refDefStartPos < source.length) {\n const code = charCode(source, refDefStartPos)\n if (code === $.CHAR_SPACE || code === $.CHAR_TAB) {\n refDefStartPos++\n } else {\n break\n }\n }\n // Check indentation - reference definitions can't be indented 4+ spaces\n var refDefIndent = refDefStartPos - (lastNewlinePos + 1)\n if (\n refDefIndent < 4 &&\n refDefStartPos < source.length &&\n source[refDefStartPos] === '['\n ) {\n var refDefState = { ...state, inline: false }\n var refDefResult = parseDefinition(\n source,\n refDefStartPos,\n refDefState,\n options,\n false\n )\n if (refDefResult) {\n // Reference definition was successfully parsed - exclude it from paragraph content\n // Find the corresponding position in processedContent\n // Count newlines from contentStart to lastNewlinePos\n var newlineCount = 0\n var searchPos = contentStart\n while (searchPos <= lastNewlinePos) {\n const nlPos = source.indexOf('\\n', searchPos)\n if (nlPos === -1 || nlPos > lastNewlinePos) break\n newlineCount++\n searchPos = nlPos + 1\n }\n // Find the corresponding position in processedContent\n var newlinePosInProcessed = 0\n var newlinesFound = 0\n searchPos = 0\n while (searchPos < processedContent.length) {\n const nlPos = processedContent.indexOf('\\n', searchPos)\n if (nlPos === -1) break\n newlinesFound++\n if (newlinesFound === newlineCount) {\n newlinePosInProcessed = nlPos + 1\n break\n }\n searchPos = nlPos + 1\n }\n if (newlinePosInProcessed > 0) {\n extractedContent = processedContent.slice(\n 0,\n newlinePosInProcessed - 1\n )\n }\n extractedEndPos = refDefResult.endPos\n // Update state.refs from the parsed reference\n state.refs = refDefState.refs\n }\n }\n }\n }\n\n // Parse as inline (newlines are preserved by default)\n const children = parseInlineWithState(\n extractedContent,\n 0,\n extractedContent.length,\n state,\n options\n )\n\n var result: MarkdownToJSX.ParagraphNode & {\n endPos: number\n removedClosingTags?: MarkdownToJSX.ASTNode[]\n } = {\n type: RuleType.paragraph,\n children,\n endPos: extractedEndPos,\n }\n\n // Per CommonMark spec Example 148: when paragraphs contain multiple closing tags at the end,\n // only the first closing tag should be kept in the paragraph, the rest should be removed\n // This handles cases where closing tags are part of HTML block structures\n // Heuristic: if there are 3+ consecutive closing tags, remove all but the first one\n // Example 148: <p><em>world</em>.</pre></p> should keep </pre> but remove </td>, </tr>, </table> (4 tags)\n // Example 623: <p></a></foo ></p> should keep both </a> and </foo > (2 tags, not removed)\n if (children.length > 0) {\n // Find closing tags at the end of paragraph children (ignoring whitespace-only text nodes)\n // Keep the first closing tag but remove the rest\n var closingTagIndices: number[] = []\n for (var i = children.length - 1; i >= 0; i--) {\n var child = children[i]\n if (\n child.type === RuleType.htmlSelfClosing &&\n child.isClosingTag === true\n ) {\n closingTagIndices.push(i)\n } else if (child.type === RuleType.text) {\n var textNode = child as MarkdownToJSX.TextNode\n // Skip whitespace-only text nodes when looking for consecutive closing tags\n if (textNode.text && textNode.text.trim().length > 0) {\n break\n }\n } else {\n // Stop at first non-closing-tag, non-whitespace node\n break\n }\n }\n // If we found 3+ consecutive closing tags at the end, remove all but the first one\n // Store the removed closing tags on the paragraph node so html() can render them separately\n // Heuristic: 3+ tags indicates HTML block structure (like </pre></td></tr></table>)\n // 2 tags might be standalone (like </a></foo >) - keep both\n if (closingTagIndices.length >= 3) {\n // Keep only the first closing tag (earliest in array), remove the rest\n var firstClosingTagIdx = closingTagIndices[closingTagIndices.length - 1]\n var removedClosingTags = children.slice(firstClosingTagIdx + 1)\n children.splice(firstClosingTagIdx + 1)\n result.removedClosingTags = removedClosingTags\n }\n }\n\n return result\n}\n\nfunction parseFrontmatter(source: string, pos: number): ParseResult {\n if (pos !== 0) return null\n const bounds = util.parseFrontmatterBounds(source)\n if (!bounds?.hasValidYaml) return null\n return {\n type: RuleType.frontmatter,\n text: source.slice(0, bounds.endPos - 1),\n endPos: bounds.endPos,\n } as MarkdownToJSX.FrontmatterNode & { endPos: number }\n}\n\nfunction parseBreakThematic(\n source: string,\n pos: number,\n state?: MarkdownToJSX.State,\n options?: ParseOptions\n): ParseResult {\n // Find the end of the line\n const lineEnd = util.findLineEnd(source, pos)\n\n // Per CommonMark: up to 3 spaces of indentation allowed\n // Count indentation, checking if it exceeds 3 spaces\n // OPTIMIZATION: Work directly on source string to avoid slice allocation\n const indentResult = calculateIndent(source, pos, lineEnd, 3)\n if (indentResult.spaceEquivalent > 3) return null\n var checkPos = pos + indentResult.charCount\n\n // Now check for thematic break character (-, *, or _)\n if (checkPos >= lineEnd) return null\n const startChar = source[checkPos]\n if (startChar !== '-' && startChar !== '*' && startChar !== '_') return null\n\n // OPTIMIZATION: Fast path - count matching characters before full validation\n // This eliminates 96% of failed attempts (102 attempts -> ~4 attempts)\n // Thematic break requires 3+ matching chars per CommonMark spec\n var charCount = 0\n var scanPos = checkPos\n while (scanPos < lineEnd) {\n var char = source[scanPos]\n if (char === startChar) {\n charCount++\n } else if (char !== ' ' && char !== '\\t') {\n // Non-matching non-whitespace character - not a thematic break\n return null\n }\n scanPos++\n }\n\n if (charCount < 3) {\n return null // Need at least 3 matching characters per CommonMark spec\n }\n\n return {\n type: RuleType.breakThematic,\n endPos: skipToNextLine(source, lineEnd),\n } as MarkdownToJSX.BreakThematicNode & { endPos: number }\n}\n\n/** Calculate the space-equivalent indentation at a position (tabs = 4 spaces) */\nexport function calculateIndent(\n source: string,\n pos: number,\n maxPos: number,\n maxSpaces?: number\n): { spaceEquivalent: number; charCount: number } {\n let spaceEquivalent = 0\n let charCount = 0\n let i = pos\n while (i < maxPos) {\n var iCode = charCode(source, i)\n if (iCode !== $.CHAR_SPACE && iCode !== $.CHAR_TAB) break\n if (maxSpaces !== undefined && spaceEquivalent >= maxSpaces) break\n if (iCode === $.CHAR_TAB) {\n spaceEquivalent += 4 - (spaceEquivalent % 4)\n } else {\n spaceEquivalent += 1\n }\n charCount++\n i++\n }\n return { spaceEquivalent, charCount }\n}\n\nfunction extractCodeBlockLineContent(\n source: string,\n lineStart: number,\n lineEnd: number,\n startColumn: number\n): string {\n let indentChars = 0\n let indentSpaceEquivalent = 0\n let currentColumn = startColumn\n for (let i = lineStart; i < lineEnd && indentSpaceEquivalent < 4; i++) {\n var iCode = charCode(source, i)\n if (iCode === $.CHAR_TAB) {\n const spaces = 4 - (currentColumn % 4)\n indentSpaceEquivalent += spaces\n indentChars++\n currentColumn += spaces\n if (indentSpaceEquivalent >= 4) break\n } else if (iCode === $.CHAR_SPACE) {\n indentSpaceEquivalent++\n indentChars++\n currentColumn++\n if (indentSpaceEquivalent >= 4) break\n } else {\n break\n }\n }\n\n let content = source.slice(lineStart + indentChars, lineEnd)\n var tabCount = 0\n for (var tc = lineStart; tc < lineEnd; tc++) {\n if (source[tc] === '\\t') tabCount++\n if (tabCount >= 2) break\n }\n if (tabCount >= 2 && util.startsWith(content, '\\t') && startColumn > 0) {\n content = ' ' + content.slice(1)\n }\n return content\n}\n\nfunction parseCodeBlock(\n source: string,\n pos: number,\n state: MarkdownToJSX.State\n): ParseResult {\n // Limit indentation scan to current line\n const lineEndForIndent = util.findLineEnd(source, pos)\n const indentInfo = calculateIndent(source, pos, lineEndForIndent)\n if (indentInfo.spaceEquivalent < 4) return null\n\n const initialIndent = indentInfo.spaceEquivalent\n const lineEnd = util.findLineEnd(source, pos + indentInfo.charCount)\n const lineStart = pos\n\n let column = 0\n var i = lineStart - 1\n while (i >= 0 && source[i] !== '\\n' && source[i] !== '\\r') {\n i--\n }\n i++\n while (i < lineStart) {\n if (source[i] === '\\t') {\n column = column + 4 - (column % 4)\n } else {\n column++\n }\n i++\n }\n\n let firstLineContent = extractCodeBlockLineContent(\n source,\n lineStart,\n lineEnd,\n column\n )\n const contentStart = skipToNextLine(source, lineEnd)\n if (contentStart >= source.length) {\n if (!firstLineContent.trim()) return null\n return {\n type: RuleType.codeBlock,\n text: firstLineContent,\n endPos: contentStart,\n } as MarkdownToJSX.CodeBlockNode & { endPos: number }\n }\n\n var parts: string[] = []\n parts.push(firstLineContent)\n let endPos = contentStart\n\n while (endPos < source.length) {\n const nextLineEnd = util.findLineEnd(source, endPos)\n if (isBlankLineCheck(source, endPos, nextLineEnd)) {\n const nextLinePos = nextLineEnd + 1\n if (nextLinePos < source.length) {\n const nextLineEnd = util.findLineEnd(source, nextLinePos)\n const nextIndentInfo = calculateIndent(source, nextLinePos, nextLineEnd)\n const nextChar = source[nextLinePos + nextIndentInfo.charCount]\n if (\n nextChar &&\n nextChar !== '\\n' &&\n (nextIndentInfo.spaceEquivalent < 4 ||\n (nextChar === '>' &&\n nextIndentInfo.spaceEquivalent < initialIndent))\n ) {\n break\n }\n }\n parts.push('\\n')\n } else {\n const currentIndentInfo = calculateIndent(source, endPos, nextLineEnd)\n if (currentIndentInfo.spaceEquivalent < 4) {\n break\n }\n\n let lineContent = extractCodeBlockLineContent(\n source,\n endPos,\n nextLineEnd,\n 0\n )\n parts.push('\\n')\n parts.push(lineContent)\n }\n\n endPos = skipToNextLine(source, nextLineEnd)\n }\n\n let content = parts.join('')\n content = content.replace(TRAILING_NEWLINE_R, '')\n if (!content.trim()) return null\n\n return {\n type: RuleType.codeBlock,\n text: content,\n endPos,\n } as MarkdownToJSX.CodeBlockNode & { endPos: number }\n}\n\nexport function parseCodeFenced(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult {\n const fenceChar = source[pos]\n if (fenceChar !== '`' && fenceChar !== '~') return null\n\n // Fast check: must have at least 3 consecutive fence chars\n const fenceLength = countConsecutiveChars(source, pos, fenceChar)\n if (fenceLength < 3) return null\n\n // Find line start for indentation calculation\n let lineStart = pos\n while (lineStart > 0 && charCode(source, lineStart - 1) !== $.CHAR_NEWLINE)\n lineStart--\n\n // Calculate indentation (caller already verified <= 3, but we need exact value)\n const indentInfo = calculateIndent(source, lineStart, pos)\n let openingIndent = indentInfo.spaceEquivalent\n let contentIndentToRemove = openingIndent\n\n // Handle 4-space indentation special case (simplified)\n if (openingIndent === 4 && indentInfo.charCount === 4) {\n // All 4 chars before pos are spaces/tabs, so this is indented code block\n openingIndent = 0\n contentIndentToRemove = 4\n }\n\n // Should not happen since caller checks indent <= 3, but keep for safety\n if (openingIndent >= 4) return null\n\n let i = util.skipWhitespace(source, pos + fenceLength)\n const lineEnd = util.findLineEnd(source, i)\n let langAndAttrs = source.slice(i, lineEnd).trim()\n\n if (fenceChar === '`' && langAndAttrs.indexOf('`') !== -1) return null\n\n langAndAttrs = langAndAttrs.replace(UNESCAPE_R, '$1')\n const langSpaceIdx = langAndAttrs.indexOf(' ')\n const lang =\n langSpaceIdx > 0 ? langAndAttrs.slice(0, langSpaceIdx) : langAndAttrs\n const attrsString =\n langSpaceIdx > 0 ? langAndAttrs.slice(langSpaceIdx + 1).trim() : ''\n const attrs =\n attrsString && /=\\s*[\"']/.test(attrsString)\n ? parseHTMLAttributes(attrsString, 'code', 'code', options)\n : undefined\n\n let contentStart = skipToNextLine(source, lineEnd)\n let endPos = contentStart\n\n while (endPos < source.length) {\n let lineEndPos = util.findLineEnd(source, endPos)\n\n let fenceStart = endPos\n let indentCount = 0\n while (fenceStart < lineEndPos) {\n const code = charCode(source, fenceStart)\n if (code === $.CHAR_SPACE) {\n indentCount++\n fenceStart++\n if (indentCount >= 4) break\n } else if (code === $.CHAR_TAB) {\n indentCount += 4 - (indentCount % 4)\n fenceStart++\n if (indentCount >= 4) break\n } else {\n break\n }\n }\n\n if (indentCount < 4) {\n let closeLen = countConsecutiveChars(\n source,\n fenceStart,\n fenceChar,\n lineEndPos - fenceStart\n )\n if (closeLen >= fenceLength) {\n let afterFence = fenceStart + closeLen\n while (afterFence < lineEndPos) {\n const code = charCode(source, afterFence)\n if (code === $.CHAR_SPACE || code === $.CHAR_TAB) {\n afterFence++\n } else {\n break\n }\n }\n if (afterFence === lineEndPos) {\n break\n }\n }\n } else if (\n contentIndentToRemove === 4 &&\n openingIndent === 0 &&\n indentCount === 4\n ) {\n let closeLen = countConsecutiveChars(\n source,\n fenceStart,\n fenceChar,\n lineEndPos - fenceStart\n )\n if (\n closeLen >= fenceLength &&\n isBlankLineCheck(source, fenceStart + closeLen, lineEndPos)\n ) {\n break\n }\n }\n\n endPos = skipToNextLine(source, lineEndPos)\n }\n\n let contentEnd =\n endPos > contentStart && source[endPos - 1] === '\\n' ? endPos - 1 : endPos\n let rawContent = source.slice(contentStart, contentEnd)\n if (contentIndentToRemove) {\n rawContent = removeExtraIndentFromCodeBlock(\n rawContent,\n contentIndentToRemove\n )\n }\n\n let finalEndPos =\n endPos < source.length\n ? skipToNextLine(source, util.findLineEnd(source, endPos))\n : endPos\n\n return {\n type: RuleType.codeBlock,\n text: rawContent,\n lang: lang,\n attrs: attrs,\n endPos: finalEndPos,\n } as MarkdownToJSX.CodeBlockNode & { endPos: number }\n}\n\nfunction parseBlockQuoteChildren(\n content: string,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): MarkdownToJSX.ASTNode[] {\n // Fast check: if content is empty or only whitespace, return early\n for (var i = 0; i < content.length; i++) {\n if (!isWS(content[i])) {\n // Parse all blocks using parseBlocksWithState (which uses parseBlock via parseBlocksInHTML)\n const blockChildren = parseBlocksWithState(content, state, options, {\n inline: false,\n inBlockQuote: true,\n })\n // Remove endPos property efficiently without creating intermediate objects\n for (var j = 0; j < blockChildren.length; j++) {\n const node = blockChildren[j] as MarkdownToJSX.ASTNode & {\n endPos?: number\n }\n if ('endPos' in node) {\n delete node.endPos\n }\n }\n return blockChildren\n }\n }\n return []\n}\n\nfunction parseBlockQuote(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult {\n if (state.inline) return null\n\n let checkPos = pos\n while (\n checkPos < source.length &&\n (source[checkPos] === ' ' || source[checkPos] === '\\t')\n ) {\n checkPos++\n }\n if (checkPos >= source.length || source[checkPos] !== '>') return null\n\n // Find the end of the blockquote and process content in single pass\n let endPos = pos\n var processedParts: string[] = []\n var alertType: string | undefined = undefined\n var hasContent = false\n var firstLineStart = -1\n\n // Track if we're currently in a code block (indented or fenced) that requires > prefix\n var inCodeBlock = false\n var codeBlockType: 'indented' | 'fenced' | null = null\n var fencedFenceChar: string | null = null\n var fencedFenceLength = 0\n var previousLineWasEmpty = false\n\n while (endPos < source.length) {\n const lineEnd = util.findLineEnd(source, endPos)\n\n // Check if this line starts a blockquote\n let lineStart = endPos\n // Skip leading whitespace\n while (\n lineStart < lineEnd &&\n (source[lineStart] === ' ' || source[lineStart] === '\\t')\n ) {\n lineStart++\n }\n\n // If line starts with '>', it's part of the blockquote\n if (lineStart < lineEnd && source[lineStart] === '>') {\n let contentStart = lineStart + 1\n if (contentStart < lineEnd && source[contentStart] === ' ') contentStart++\n\n // Inline code block detection (was detectCodeBlockInBlockQuote)\n const indentInfo = calculateIndent(source, contentStart, lineEnd)\n const isIndented = indentInfo.spaceEquivalent >= 4\n let isFenced = false\n let fenceChar: string | null = null\n let fenceLen = 0\n if (contentStart < lineEnd) {\n const firstChar = source[contentStart]\n if (firstChar === '`' || firstChar === '~') {\n let len = 0\n let i = contentStart\n while (i < lineEnd && source[i] === firstChar && len < 20) {\n len++\n i++\n }\n if (len >= 3) {\n isFenced = true\n fenceChar = firstChar\n fenceLen = len\n }\n }\n }\n\n // Update code block state\n if (\n inCodeBlock &&\n codeBlockType === 'fenced' &&\n fenceChar === fencedFenceChar &&\n fenceLen >= fencedFenceLength\n ) {\n inCodeBlock = false\n codeBlockType = null\n fencedFenceChar = null\n fencedFenceLength = 0\n } else if (isIndented || isFenced) {\n inCodeBlock = true\n codeBlockType = isIndented ? 'indented' : 'fenced'\n fencedFenceChar = fenceChar\n fencedFenceLength = fenceLen\n }\n\n // Inline blank line check (was isBlankLineCheck)\n var isBlankLine = !isIndented && !isFenced\n if (isBlankLine) {\n for (var i = contentStart; i < lineEnd; i++) {\n if (!isWS(source[i])) {\n isBlankLine = false\n break\n }\n }\n }\n previousLineWasEmpty = isBlankLine\n\n // Track first line for alert extraction\n if (firstLineStart === -1 && !isBlankLine) {\n firstLineStart = processedParts.length\n }\n if (!isBlankLine) hasContent = true\n\n // Process line content: remove > marker and optional space, handle tabs\n const afterMarkerStart = lineStart + 1\n\n // Check if first char after > is a tab (needs special handling)\n if (afterMarkerStart < lineEnd && source[afterMarkerStart] === '\\t') {\n // Expand tabs to spaces\n processedParts.push(' ') // First tab after > becomes 2 spaces\n let col = 4\n for (let k = afterMarkerStart + 1; k < lineEnd; k++) {\n const char = source[k]\n var code = charCode(char)\n if (code === $.CHAR_TAB) {\n const spaces = 4 - (col % 4)\n // Use fixed strings for common cases\n if (spaces === 1) processedParts.push(' ')\n else if (spaces === 2) processedParts.push(' ')\n else if (spaces === 3) processedParts.push(' ')\n else processedParts.push(' '.repeat(spaces))\n col += spaces\n } else {\n processedParts.push(char)\n col++\n }\n }\n if (lineEnd < source.length) processedParts.push('\\n')\n } else {\n // Fast path: no tab immediately after > (common case)\n let processedContentStart = afterMarkerStart\n if (\n processedContentStart < lineEnd &&\n source[processedContentStart] === ' '\n ) {\n processedContentStart++\n }\n processedParts.push(source.slice(processedContentStart, lineEnd))\n if (lineEnd < source.length) processedParts.push('\\n')\n }\n } else {\n // Check for lazy continuation line (line without > that continues blockquote)\n // Inline blank line check\n var isEmptyLine = true\n for (var i = endPos; i < lineEnd; i++) {\n if (!isWS(source[i])) {\n isEmptyLine = false\n break\n }\n }\n\n // Stop blockquote if: empty line, or in code block (code blocks require > prefix)\n if (isEmptyLine || inCodeBlock) {\n break\n }\n\n const lazyIndentInfo = calculateIndent(source, endPos, lineEnd)\n if (lazyIndentInfo.spaceEquivalent === 0) {\n // Check if this line starts a block (excluding reference definitions which don't break blockquotes)\n const blockResult = parseBlock(source, endPos, state, options)\n if (\n blockResult &&\n blockResult.type !== RuleType.ref &&\n blockResult.type !== RuleType.codeBlock\n ) {\n break\n }\n if (previousLineWasEmpty) {\n break\n }\n }\n processedParts.push(source.slice(endPos, lineEnd))\n if (lineEnd < source.length) processedParts.push('\\n')\n }\n\n endPos = skipToNextLine(source, lineEnd)\n }\n\n // Empty blockquotes are valid (e.g., \">\\n\" or \">\\n> \\n> \\n\")\n // Only reject if we didn't process any lines at all\n if (endPos === pos) return null\n\n // Remove trailing newline if present (avoid endsWith check by tracking)\n if (\n processedParts.length > 0 &&\n processedParts[processedParts.length - 1] === '\\n'\n ) {\n processedParts.pop()\n }\n\n let processedContent = processedParts.join('')\n\n // Extract alert type (check start of content for [!...]\\n pattern)\n if (\n processedContent.length >= 4 &&\n processedContent.charCodeAt(0) === $.CHAR_BRACKET_OPEN &&\n processedContent.charCodeAt(1) === $.CHAR_EXCLAMATION\n ) {\n const alertEnd = processedContent.indexOf(']\\n', 2)\n if (alertEnd > 2) {\n alertType = processedContent.slice(2, alertEnd)\n processedContent = processedContent.slice(alertEnd + 2)\n }\n }\n\n const children = parseBlockQuoteChildren(processedContent, state, options)\n\n const result: MarkdownToJSX.BlockQuoteNode & { endPos: number } = {\n type: RuleType.blockQuote,\n children,\n endPos,\n }\n if (alertType) {\n result.alert = alertType\n }\n return result\n}\n\n/** Remove extra indentation from code block text when used in list items */\nfunction removeExtraIndentFromCodeBlock(\n codeBlockText: string,\n extraIndent: number\n): string {\n return codeBlockText\n .split('\\n')\n .map(function (line) {\n if (line.length === 0) return line\n let toRemove = extraIndent\n let removed = 0\n let i = 0\n let currentColumn = 0\n while (i < line.length && removed < toRemove) {\n if (line[i] === ' ') {\n removed++\n currentColumn++\n i++\n } else if (line[i] === '\\t') {\n const spacesFromTab = 4 - (currentColumn % 4)\n if (removed + spacesFromTab <= toRemove) {\n removed += spacesFromTab\n currentColumn += spacesFromTab\n i++\n } else {\n const remainingToRemove = toRemove - removed\n const spacesToKeep = Math.max(0, spacesFromTab - remainingToRemove)\n return ' '.repeat(spacesToKeep) + line.slice(i + 1)\n }\n } else {\n break\n }\n }\n return line.slice(i)\n })\n .join('\\n')\n}\n\nfunction appendListContinuation(\n continuationContent: string,\n lastItem: MarkdownToJSX.ASTNode[],\n state: MarkdownToJSX.State,\n options: ParseOptions,\n addNewline: boolean = true\n): void {\n const sourceToParse = (addNewline ? '\\n' : '') + continuationContent\n const continuationInline = parseInlineWithState(\n sourceToParse,\n 0,\n sourceToParse.length,\n state,\n options\n )\n if (\n lastItem.length > 0 &&\n lastItem[lastItem.length - 1].type === RuleType.paragraph\n ) {\n ;(\n lastItem[lastItem.length - 1] as MarkdownToJSX.ParagraphNode\n ).children.push(...continuationInline)\n } else {\n lastItem.push(...continuationInline)\n }\n}\n\n// Helper: Check if list item contains block-level content\nfunction listItemHasBlockContent(item: MarkdownToJSX.ASTNode[]): boolean {\n return item.some(function (node) {\n return (\n node.type === RuleType.codeBlock ||\n node.type === RuleType.paragraph ||\n node.type === RuleType.blockQuote ||\n node.type === RuleType.orderedList ||\n node.type === RuleType.unorderedList ||\n node.type === RuleType.heading\n )\n })\n}\n\n// Helper: Check if line matches any list item pattern\nfunction isLineListItem(line: string): boolean {\n return !!line.match(LIST_ITEM_R)\n}\n\n// Helper: Find deepest nested list parent in item hierarchy\nfunction findNestedListParent(\n item: MarkdownToJSX.ASTNode[]\n): MarkdownToJSX.ASTNode[] {\n if (item.length === 0) return item\n var lastBlock = item[item.length - 1]\n if (\n (lastBlock.type === RuleType.orderedList ||\n lastBlock.type === RuleType.unorderedList) &&\n (\n lastBlock as\n | MarkdownToJSX.OrderedListNode\n | MarkdownToJSX.UnorderedListNode\n ).items?.length > 0\n ) {\n return findNestedListParent(\n (\n lastBlock as\n | MarkdownToJSX.OrderedListNode\n | MarkdownToJSX.UnorderedListNode\n ).items.slice(-1)[0]\n )\n }\n return item\n}\n\n// Helper: Skip link reference definition if present\nfunction skipLinkReferenceDefinition(\n source: string,\n linePos: number,\n lineEnd: number,\n indentInfo: ReturnType<typeof calculateIndent>,\n lineWithoutIndent: string,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): number | null {\n if (!util.startsWith(lineWithoutIndent, '[')) return null\n var refCheckState = { inline: false, list: false, refs: state.refs || {} }\n var refResult = parseDefinition(\n source,\n linePos + indentInfo.charCount,\n refCheckState,\n options,\n false\n )\n return refResult ? refResult.endPos : null\n}\n\n// Helper: Check if we should break list due to empty item after blank line\nfunction shouldBreakForEmptyItem(\n items: MarkdownToJSX.ASTNode[][],\n isEmptyItem: boolean,\n prevLineWasBlank: boolean,\n firstItemContent: string\n): boolean {\n if (items.length !== 1 || !prevLineWasBlank) return false\n const lastItem = items[0] // Since items.length === 1, this is the only item\n if (lastItem.length !== 0) return false\n if (isEmptyItem) return true\n if (!isEmptyItem && firstItemContent.trim() === '') return true\n return false\n}\n\n// Helper: Calculate content start column for a list item\n// Helper: Calculate marker end position from match\nfunction calculateMarkerEnd(match: RegExpMatchArray, ordered: boolean): number {\n var markerStart = match.index || 0\n return ordered\n ? markerStart + match[1].length + match[2].length + 1\n : markerStart + match[1].length + 1\n}\n\nfunction calculateListItemContentColumn(\n source: string,\n contentStartInSource: number,\n lineEnd: number,\n baseIndent: number,\n markerEndInLine: number\n): { contentStartColumn: number; contentStartPos: number } {\n var spacesAfterMarker = 0\n var col = baseIndent + markerEndInLine\n var contentCheckPos = contentStartInSource\n while (contentCheckPos < lineEnd && spacesAfterMarker < 4) {\n var code = charCode(source, contentCheckPos)\n if (code === $.CHAR_SPACE) {\n spacesAfterMarker++\n col++\n } else if (code === $.CHAR_TAB) {\n var spaces = 4 - (col % 4)\n if (spacesAfterMarker + spaces > 4) break\n spacesAfterMarker += spaces\n col += spaces\n } else {\n break\n }\n contentCheckPos++\n }\n return { contentStartColumn: col, contentStartPos: contentCheckPos }\n}\n\nfunction matchListItem(\n lineWithoutIndent: string\n): { match: RegExpMatchArray; ordered: boolean; listItemRegex: RegExp } | null {\n var match = lineWithoutIndent.match(LIST_ITEM_R)\n if (!match) return null\n\n // Groups: 1=ordered_num, 2=ordered_delim, 3=ordered_content, 4=ordered_empty_num, 5=ordered_empty_delim, 6=unordered_marker, 7=unordered_content, 8=unordered_empty_marker\n if (match[1]) {\n // Ordered with content: (\\d{1,9})([.)])\\s+(.*)\n return {\n match: [lineWithoutIndent, match[1], match[2], match[3]],\n ordered: true,\n listItemRegex: ORDERED_LIST_ITEM_WITH_CONTENT_R,\n }\n }\n if (match[4]) {\n // Ordered empty: (\\d{1,9})([.)])\\s*\n return {\n match: [lineWithoutIndent, match[4], match[5], ''],\n ordered: true,\n listItemRegex: ORDERED_LIST_ITEM_WITH_CONTENT_R,\n }\n }\n if (match[6]) {\n // Unordered with content: ([-*+])\\s+(.*)\n return {\n match: [lineWithoutIndent, match[6], match[7]],\n ordered: false,\n listItemRegex: UNORDERED_LIST_ITEM_WITH_CONTENT_R,\n }\n }\n if (match[8]) {\n // Unordered empty: ([-*+])\\s*\n return {\n match: [lineWithoutIndent, match[8], ''],\n ordered: false,\n listItemRegex: UNORDERED_LIST_ITEM_WITH_CONTENT_R,\n }\n }\n return null\n}\n\n// Helper: Check if a line is a matching list item for the current list\nfunction isMatchingListItem(\n lineWithoutIndent: string,\n indentInfo: ReturnType<typeof calculateIndent>,\n ordered: boolean,\n marker: string | undefined,\n delimiter: string | undefined,\n baseIndent: number,\n listItemRegex: RegExp\n): boolean {\n if (indentInfo.spaceEquivalent !== baseIndent) return false\n var match = lineWithoutIndent.match(listItemRegex)\n if (match) {\n return ordered ? match[2] === delimiter : match[1] === marker\n }\n var emptyMatch = lineWithoutIndent.match(LIST_ITEM_R)\n if (!emptyMatch) return false\n if (ordered) {\n return emptyMatch[4] && emptyMatch[5] === delimiter\n } else {\n return emptyMatch[8] === marker\n }\n}\n\n// Helper: Handle fenced code blocks that span multiple lines in list items\nfunction expandMultilineFencedCodeBlock(\n source: string,\n itemContent: string,\n startPos: number,\n markerWidth: number\n): { content: string; endPos: number } {\n var content = itemContent\n var pos = startPos\n var fenceChar = itemContent[0]\n while (pos < source.length) {\n var lineEnd = util.findLineEnd(source, pos)\n var line = source.slice(pos, lineEnd)\n var processedLine = util.startsWith(line, ' '.repeat(markerWidth))\n ? line.slice(markerWidth)\n : line\n if (\n util.startsWith(processedLine.trim(), fenceChar) &&\n countConsecutiveChars(processedLine.trim(), 0, fenceChar) >= 3\n ) {\n return { content: content, endPos: skipToNextLine(source, lineEnd) }\n }\n content += '\\n' + processedLine\n pos = skipToNextLine(source, lineEnd)\n }\n return { content: content, endPos: pos }\n}\n\n// Helper function to add a new list item with all standard processing\nfunction addListItem(\n source: string,\n items: MarkdownToJSX.ASTNode[][],\n itemContentStartColumns: number[],\n itemContent: string,\n startPos: number,\n nextLineEnd: number,\n nextIndent: number,\n nextIndentChars: number,\n nextMatch: RegExpMatchArray,\n ordered: boolean,\n hasBlankLines: boolean,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): { newCurrentPos: number; itemHasBlankLine: boolean } {\n // Derive marker/delimiter/regex (cheap to recompute vs passing 3 extra params)\n var marker = ordered ? undefined : nextMatch[1]\n var delimiter = ordered ? nextMatch[2] : undefined\n var listItemRegex = ordered\n ? ORDERED_LIST_ITEM_WITH_CONTENT_R\n : UNORDERED_LIST_ITEM_WITH_CONTENT_R\n\n // Check if item has blank lines\n var itemHasBlankLine = hasBlankLines\n if (!hasBlankLines) {\n var startCheckPos = skipToNextLine(source, nextLineEnd)\n var checkItemPos = startCheckPos\n while (checkItemPos < source.length) {\n var checkLineEnd = util.findLineEnd(source, checkItemPos)\n var checkLine = source.slice(checkItemPos, checkLineEnd)\n var checkIndentInfo = calculateIndent(source, checkItemPos, checkLineEnd)\n var checkIndent = checkIndentInfo.spaceEquivalent\n if (isBlankLineCheck(source, checkItemPos, checkLineEnd)) {\n var afterBlank = skipToNextLine(source, checkLineEnd)\n if (afterBlank < source.length) {\n var afterBlankLineEnd = util.findLineEnd(source, afterBlank)\n var afterBlankIndentInfo = calculateIndent(\n source,\n afterBlank,\n afterBlankLineEnd\n )\n var afterBlankIndent = afterBlankIndentInfo.spaceEquivalent\n var thisItemMarkerEnd = calculateMarkerEnd(nextMatch, ordered)\n var thisItemContentStartInSource =\n startPos + nextIndentChars + thisItemMarkerEnd\n var thisItemResult = calculateListItemContentColumn(\n source,\n thisItemContentStartInSource,\n nextLineEnd,\n nextIndent,\n thisItemMarkerEnd\n )\n var thisItemContentStartColumn = thisItemResult.contentStartColumn\n if (afterBlankIndent + 1 > thisItemContentStartColumn) {\n itemHasBlankLine = true\n break\n }\n }\n break\n } else if (checkIndent <= nextIndent) {\n var checkLineWithoutIndent = checkLine.slice(checkIndentInfo.charCount)\n var checkMatch = checkLineWithoutIndent.match(listItemRegex)\n if (\n checkMatch &&\n (ordered ? checkMatch[2] === delimiter : checkMatch[1] === marker)\n ) {\n break\n }\n }\n checkItemPos = skipToNextLine(source, checkLineEnd)\n }\n }\n\n // Calculate content start column\n var thisItemMarkerEnd = calculateMarkerEnd(nextMatch, ordered)\n var thisItemContentStartInSource =\n startPos + nextIndentChars + thisItemMarkerEnd\n var thisItemResult = calculateListItemContentColumn(\n source,\n thisItemContentStartInSource,\n nextLineEnd,\n nextIndent,\n thisItemMarkerEnd\n )\n var thisItemContentStartColumn = thisItemResult.contentStartColumn\n\n // Handle fenced code blocks\n var actualItemContent = itemContent\n var newCurrentPos = skipToNextLine(source, nextLineEnd)\n if (\n util.startsWith(itemContent, '```') ||\n util.startsWith(itemContent, '~~~')\n ) {\n var markerWidth = ordered\n ? nextMatch[1].length + nextMatch[2].length + 1\n : nextMatch[1].length + 1\n var expandedResult = expandMultilineFencedCodeBlock(\n source,\n itemContent,\n newCurrentPos,\n markerWidth\n )\n actualItemContent = expandedResult.content\n newCurrentPos = expandedResult.endPos\n }\n\n // Build and add item with GFM task support\n items.push(\n buildListItemContent(actualItemContent, itemHasBlankLine, state, options)\n )\n itemContentStartColumns.push(thisItemContentStartColumn)\n\n return { newCurrentPos, itemHasBlankLine }\n}\n\n// Helper function to process list item continuation lines\nfunction checkHTMLTagInterruptsList(\n source: string,\n pos: number,\n indentChars: number,\n baseIndent: number,\n indent: number,\n options: ParseOptions\n): boolean {\n if (indent > baseIndent || options.disableParsingRawHTML) return false\n const lineStartPos = pos + indentChars\n if (lineStartPos >= source.length || source[lineStartPos] !== '<')\n return false\n return isValidHTMLTagStart(source, lineStartPos)\n}\n\n// Lightweight check for HTML tag validity without full parsing\nfunction isValidHTMLTagStart(source: string, pos: number): boolean {\n if (pos >= source.length || source[pos] !== '<') return false\n const len = source.length\n let i = pos + 1\n\n // Handle closing tags\n if (i < len && source[i] === '/') {\n i++\n }\n\n // Must have at least one character for tag name\n if (i >= len) return false\n\n // First character of tag name must be letter\n const firstChar = charCode(source, i)\n if (!isAlphaCode(firstChar)) return false\n i++\n\n // Rest of tag name can be letters, digits, hyphens, underscores\n // Use early return to avoid nested conditionals\n while (i < len) {\n const ch = source[i]\n const code = charCode(source, i)\n\n // Break conditions (valid tag name terminators)\n if (\n ch === '>' ||\n ch === ' ' ||\n ch === '\\t' ||\n ch === '\\n' ||\n ch === '\\r' ||\n ch === '/'\n ) {\n break\n }\n\n // Valid tag name characters - continue\n if (\n ch === '-' ||\n ch === '_' ||\n isAlphaCode(code) ||\n (code >= 48 && code <= 57)\n ) {\n i++\n } else {\n return false // Invalid character in tag name\n }\n }\n\n // Find the end of the tag - use state machine approach to reduce branching\n let state = 0 // 0: normal, 1: in double quotes, 2: in single quotes\n while (i < len) {\n const ch = source[i]\n const code = charCode(source, i)\n\n // State machine for quote handling\n if (state === 1) {\n // in double quotes\n if (ch === '\"') state = 0\n i++\n } else if (state === 2) {\n // in single quotes\n if (ch === \"'\") state = 0\n i++\n } else if (ch === '\"') {\n state = 1\n i++\n } else if (ch === \"'\") {\n state = 2\n i++\n } else if (ch === '>') {\n return true // Found valid closing >\n } else if (ch === '/' && i + 1 < len && source[i + 1] === '>') {\n return true // Found valid self-closing />\n } else if (code === 10 || code === 13) {\n // \\n or \\r\n return false // No multiline tags in this context\n } else {\n i++\n }\n }\n\n return false // No closing > found\n}\n\nfunction processContinuation(\n source: string,\n item: MarkdownToJSX.ASTNode[],\n contentStartColumn: number,\n startPos: number,\n baseIndent: number,\n ordered: boolean,\n marker: string | undefined,\n delimiter: string | undefined,\n listItemRegex: RegExp,\n state: MarkdownToJSX.State,\n options: ParseOptions,\n allowLinkRefs?: boolean\n): number {\n let pos = startPos\n let prevLineWasBlank = false\n while (pos < source.length) {\n const lineEnd = util.findLineEnd(source, pos)\n const indentInfo = calculateIndent(source, pos, lineEnd)\n const indent = indentInfo.spaceEquivalent\n\n if (isBlankLineCheck(source, pos, lineEnd)) {\n prevLineWasBlank = true\n pos = skipToNextLine(source, lineEnd)\n continue\n }\n\n const lineWithoutIndent = source.slice(pos + indentInfo.charCount, lineEnd)\n\n if (\n indent <= baseIndent &&\n isMatchingListItem(\n lineWithoutIndent,\n indentInfo,\n ordered,\n marker,\n delimiter,\n baseIndent,\n listItemRegex\n )\n ) {\n break\n }\n\n if (indent >= contentStartColumn) {\n // Check for link reference definitions (only for first item)\n if (allowLinkRefs && prevLineWasBlank) {\n const refEndPos = skipLinkReferenceDefinition(\n source,\n pos,\n lineEnd,\n indentInfo,\n lineWithoutIndent,\n state,\n options\n )\n if (refEndPos) {\n pos = refEndPos\n prevLineWasBlank = false\n continue\n }\n }\n\n const result = processListContinuationLine(\n source,\n pos,\n lineEnd,\n indentInfo,\n contentStartColumn - 1,\n contentStartColumn,\n item,\n prevLineWasBlank,\n state,\n options,\n undefined,\n baseIndent\n )\n if (result.processed) {\n pos = result.newPos\n prevLineWasBlank = result.wasBlank\n continue\n }\n } else {\n break\n }\n }\n return pos\n}\n\n// Helper: Parse content with paragraph wrapping for tight/loose lists\nfunction parseContentWithParagraphHandling(\n content: string,\n wrapInParagraph: boolean,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): MarkdownToJSX.ASTNode[] {\n const blocks = parseBlocksWithState(content, state, options, {\n inline: false,\n list: true,\n })\n if (blocks.length > 0) {\n // Unwrap single paragraph for tight lists\n return !wrapInParagraph &&\n blocks.length === 1 &&\n blocks[0].type === RuleType.paragraph\n ? (blocks[0] as MarkdownToJSX.ParagraphNode).children\n : blocks\n }\n // Fallback to inline parsing\n const inline = parseWithInlineMode(state, true, () =>\n parseInlineSpan(content, 0, content.length, state, options)\n )\n return wrapInParagraph && inline.length > 0\n ? [\n {\n type: RuleType.paragraph,\n children: inline,\n } as MarkdownToJSX.ParagraphNode,\n ]\n : inline\n}\n\nfunction buildListItemContent(\n itemContent: string,\n itemHasBlankLine: boolean,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): MarkdownToJSX.ASTNode[] {\n const task = parseGFMTask(itemContent, 0, state)\n const hasTask =\n task &&\n (task.endPos >= itemContent.length || itemContent[task.endPos] === ' ')\n if (!hasTask) {\n return parseContentWithParagraphHandling(\n itemContent,\n itemHasBlankLine,\n state,\n options\n )\n }\n const afterTask =\n task.endPos < itemContent.length ? task.endPos + 1 : task.endPos\n const restContent = itemContent.slice(afterTask)\n const restNodes = parseContentWithParagraphHandling(\n restContent,\n itemHasBlankLine,\n state,\n options\n )\n const nodes: MarkdownToJSX.ASTNode[] = [task]\n if (task.endPos < itemContent.length) {\n nodes.push({ type: RuleType.text, text: ' ' } as MarkdownToJSX.TextNode)\n }\n nodes.push(...restNodes)\n return nodes\n}\n\nfunction checkUnicodeWhitespaceAfterMarker(\n match: RegExpMatchArray,\n marker: string\n): boolean {\n if (!match[0]) return false\n const markerInMatch = match[0].indexOf(marker)\n if (markerInMatch === -1) return false\n const afterMarkerInMatch = markerInMatch + marker.length\n if (afterMarkerInMatch >= match[0].length) return false\n const afterMarkerChar = match[0][afterMarkerInMatch]\n return afterMarkerChar ? charCode(afterMarkerChar) === $.CHAR_NBSP : false\n}\n\nfunction convertSetextHeadingInListItem(\n lastItem: MarkdownToJSX.ASTNode[],\n underlineLine: string,\n options: ParseOptions\n): boolean {\n if (lastItem.length === 0) return false\n const lastBlock = lastItem[lastItem.length - 1]\n const trimmed = underlineLine.trim()\n if (\n (!util.startsWith(trimmed, '=') && !util.startsWith(trimmed, '-')) ||\n trimmed.length < 1 ||\n !/^[=-]+[ \\t]*$/.test(trimmed)\n ) {\n return false\n }\n\n let headingChildren: MarkdownToJSX.ASTNode[] = []\n let headingContent = ''\n if (lastBlock.type === RuleType.paragraph) {\n const paragraph = lastBlock as MarkdownToJSX.ParagraphNode\n headingChildren = paragraph.children\n headingContent = paragraph.children\n .map(child =>\n child.type === RuleType.text\n ? (child as MarkdownToJSX.TextNode).text\n : ''\n )\n .join('')\n .trim()\n } else if (lastBlock.type === RuleType.text) {\n const textNodes: MarkdownToJSX.TextNode[] = []\n let i = lastItem.length - 1\n while (i >= 0 && lastItem[i].type === RuleType.text) {\n textNodes.unshift(lastItem[i] as MarkdownToJSX.TextNode)\n i--\n }\n if (textNodes.length > 0) {\n headingChildren = textNodes\n headingContent = textNodes\n .map(node => (node as MarkdownToJSX.TextNode).text)\n .join('')\n .trim()\n }\n }\n\n if (!headingContent) return false\n\n const underlineChar = trimmed[0]\n const level = underlineChar === '=' ? 1 : 2\n if (lastBlock.type === RuleType.paragraph) {\n lastItem.pop()\n } else if (lastBlock.type === RuleType.text) {\n while (\n lastItem.length > 0 &&\n lastItem[lastItem.length - 1].type === RuleType.text\n ) {\n lastItem.pop()\n }\n }\n lastItem.push(\n createHeading(level, headingChildren, headingContent, options.slugify)\n )\n return true\n}\n\nfunction processListContinuationLine(\n source: string,\n currentPos: number,\n nextLineEnd: number,\n nextIndentInfo: ReturnType<typeof calculateIndent>,\n continuationColumn: number,\n contentStartColumn: number,\n lastItem: MarkdownToJSX.ASTNode[],\n prevLineWasBlank: boolean,\n state: MarkdownToJSX.State,\n options: ParseOptions,\n unwrapParagraphs?: boolean,\n baseIndent?: number\n): { processed: boolean; newPos: number; wasBlank: boolean } {\n const nextIndent = nextIndentInfo.spaceEquivalent\n const continuationContent = source.slice(\n currentPos + nextIndentInfo.charCount,\n nextLineEnd\n )\n\n if (nextIndent >= continuationColumn + 4) {\n const blockResult = parseCodeBlock(source, currentPos, state)\n if (blockResult) {\n const codeBlockNode = blockResult as MarkdownToJSX.CodeBlockNode & {\n endPos: number\n }\n const adjustedText = removeExtraIndentFromCodeBlock(\n codeBlockNode.text || '',\n contentStartColumn\n )\n lastItem.push({\n ...codeBlockNode,\n text: adjustedText,\n } as MarkdownToJSX.CodeBlockNode)\n return {\n processed: true,\n newPos: codeBlockNode.endPos,\n wasBlank: false,\n }\n }\n }\n\n const indentRelativeToContentFenced = nextIndent - (contentStartColumn - 1)\n if (\n nextIndent + 1 >= contentStartColumn &&\n indentRelativeToContentFenced <= 3\n ) {\n const continuationStart = currentPos + nextIndentInfo.charCount\n if (continuationStart < nextLineEnd) {\n const firstCharAfterIndent = source[continuationStart]\n if (firstCharAfterIndent === '`' || firstCharAfterIndent === '~') {\n const fencedResult = parseCodeFenced(\n source,\n continuationStart,\n state,\n options\n )\n if (fencedResult) {\n const codeBlockNode = fencedResult as MarkdownToJSX.CodeBlockNode & {\n endPos: number\n }\n const adjustedText = removeExtraIndentFromCodeBlock(\n codeBlockNode.text || '',\n contentStartColumn - 1\n )\n lastItem.push({\n ...codeBlockNode,\n text: adjustedText,\n endPos: codeBlockNode.endPos,\n } as MarkdownToJSX.CodeBlockNode & { endPos: number })\n return {\n processed: true,\n newPos: codeBlockNode.endPos,\n wasBlank: false,\n }\n }\n }\n }\n }\n\n if (\n continuationContent.length > 0 &&\n (continuationContent[0] === '-' ||\n continuationContent[0] === '*' ||\n continuationContent[0] === '+' ||\n (continuationContent[0] >= '0' && continuationContent[0] <= '9'))\n ) {\n const listMarkerRegex = /^([-*+]|\\d{1,9}[.)])\\s+/\n if (listMarkerRegex.test(continuationContent)) {\n const inline = parseInlineWithState(\n continuationContent,\n 0,\n continuationContent.length,\n state,\n options\n )\n lastItem.push({ type: RuleType.text, text: '\\n' }, ...inline)\n return {\n processed: true,\n newPos: skipToNextLine(source, nextLineEnd),\n wasBlank: false,\n }\n }\n }\n\n const mergedPos = tryMergeBlockquoteContinuation(\n source,\n currentPos,\n lastItem,\n continuationContent,\n state,\n options\n )\n if (mergedPos !== null) {\n return { processed: true, newPos: mergedPos, wasBlank: false }\n }\n\n const continuationBlocks = parseBlocksWithState(\n continuationContent,\n state,\n options,\n { inline: false, list: true }\n )\n if (continuationBlocks.length > 0) {\n if (unwrapParagraphs && continuationBlocks[0].type === RuleType.paragraph) {\n const continuationParagraph =\n continuationBlocks[0] as MarkdownToJSX.ParagraphNode\n lastItem.push(\n { type: RuleType.text, text: '\\n' } as MarkdownToJSX.TextNode,\n ...continuationParagraph.children\n )\n if (continuationBlocks.length > 1) {\n lastItem.push(...continuationBlocks.slice(1))\n }\n } else if (\n !prevLineWasBlank &&\n continuationBlocks[0].type === RuleType.paragraph &&\n lastItem.length > 0\n ) {\n const lastBlock = lastItem[lastItem.length - 1]\n const continuationParagraph =\n continuationBlocks[0] as MarkdownToJSX.ParagraphNode\n if (lastBlock.type === RuleType.paragraph) {\n ;(lastBlock as MarkdownToJSX.ParagraphNode).children.push(\n { type: RuleType.text, text: '\\n' } as MarkdownToJSX.TextNode,\n ...continuationParagraph.children\n )\n } else if (lastBlock.type === RuleType.heading) {\n lastItem.push(...continuationParagraph.children)\n } else if (!listItemHasBlockContent(lastItem)) {\n lastItem.push(\n { type: RuleType.text, text: ' ' } as MarkdownToJSX.TextNode,\n ...continuationParagraph.children\n )\n } else {\n lastItem.push(...continuationBlocks)\n }\n if (continuationBlocks.length > 1) {\n lastItem.push(...continuationBlocks.slice(1))\n }\n } else {\n lastItem.push(...continuationBlocks)\n }\n return {\n processed: true,\n newPos: skipToNextLine(source, nextLineEnd),\n wasBlank: false,\n }\n }\n\n if (prevLineWasBlank) {\n const inline = parseWithInlineMode(state, true, () =>\n parseInlineSpan(\n continuationContent,\n 0,\n continuationContent.length,\n state,\n options\n )\n )\n lastItem.push({\n type: RuleType.paragraph,\n children: inline,\n } as MarkdownToJSX.ParagraphNode)\n } else {\n appendListContinuation(continuationContent, lastItem, state, options)\n }\n return {\n processed: true,\n newPos: skipToNextLine(source, nextLineEnd),\n wasBlank: false,\n }\n}\n\nfunction parseList(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult {\n if (state.inline) return null\n\n // Set inList state for proper GFM task tracking during inline parsing\n var originalInList = state.inList\n state.inList = true\n\n // Lists must start at the beginning of a line (block boundary)\n if (pos > 0) {\n var prevCharCode = charCode(source, pos - 1)\n if (prevCharCode !== $.CHAR_NEWLINE && prevCharCode !== $.CHAR_CR) {\n state.inList = originalInList\n return null\n }\n }\n\n var lineEnd = util.findLineEnd(source, pos)\n var indentInfo = calculateIndent(source, pos, lineEnd)\n // Early fail: headings/lists cannot be indented more than 3 spaces unless in list context\n if (indentInfo.spaceEquivalent > 3 && !state.inList) {\n state.inList = originalInList\n return null\n }\n var line = source.slice(pos, lineEnd)\n var indent = indentInfo.charCount\n var lineWithoutIndent = line.slice(indent)\n\n // Detect list type: ordered (digit marker) vs unordered (-/*/+ marker)\n var matchResult = matchListItem(lineWithoutIndent)\n if (!matchResult) {\n state.inList = originalInList\n return null\n }\n var match = matchResult.match\n var ordered = matchResult.ordered\n var listItemRegex = matchResult.listItemRegex\n\n var baseIndent = indentInfo.spaceEquivalent\n // Extract list-specific properties: start number and delimiter for ordered, marker for unordered\n var start = ordered ? parseInt(match[1], 10) : undefined\n var delimiter = ordered ? match[2] : undefined // '.' or ')' for ordered lists\n var marker = ordered ? undefined : match[1] // '-', '*', or '+' for unordered lists\n\n // Check if this is an empty list item (no content after marker)\n var isEmptyItem = ordered ? match[3] === '' : match[2] === ''\n\n // Helper: Check if we're at a block boundary (document start or after blank line)\n function isAtBlockBoundary(\n checkPos: number,\n requireBlankLine: boolean\n ): boolean {\n if (checkPos === 0) return true\n var prevCode = charCode(source, checkPos - 1)\n if (prevCode !== $.CHAR_NEWLINE) return false\n if (!requireBlankLine) return true\n var backPos = checkPos - 2\n while (backPos >= 0) {\n var code = charCode(source, backPos)\n if (code !== $.CHAR_SPACE && code !== $.CHAR_TAB) break\n backPos--\n }\n return backPos < 0 || charCode(source, backPos) === $.CHAR_NEWLINE\n }\n\n // Per CommonMark: empty list items cannot interrupt paragraphs (need blank line)\n if (isEmptyItem && !isAtBlockBoundary(pos, true)) {\n state.inList = originalInList\n return null\n }\n\n // Per CommonMark: only ordered lists starting with 1 can interrupt paragraphs\n if (ordered && start !== 1 && !isAtBlockBoundary(pos, false)) {\n return null\n }\n\n // For unordered lists, check that the whitespace after marker is regular space/tab, not Unicode whitespace\n if (!ordered && checkUnicodeWhitespaceAfterMarker(match, marker)) {\n return null\n }\n\n // Calculate the content start column: where the first non-whitespace character\n // after the marker delimiter actually appears in the source\n // This is needed to determine continuation indentation\n var markerStartInLine = match.index || 0\n // isEmptyItem is already set above - check if it needs updating based on spacesAfterMarkerCount\n // Empty item is different from item with whitespace but no content\n // We'll calculate spacesAfterMarkerCount later and update isEmptyItem if needed\n var markerEndInLine = ordered\n ? markerStartInLine + match[1].length + match[2].length + 1 // number + delimiter + required space\n : isEmptyItem\n ? markerStartInLine + match[1].length // marker only (no space)\n : markerStartInLine + match[1].length + 1 // marker + required space\n // Find the actual position after marker delimiter in the source\n var contentStartInSource = pos + indent + markerEndInLine\n // Count spaces/tabs before first non-whitespace in the content\n // Per CommonMark spec: marker must be followed by 1 ≤ N ≤ 4 spaces\n var contentColumnResult = calculateListItemContentColumn(\n source,\n contentStartInSource,\n lineEnd,\n baseIndent,\n markerEndInLine\n )\n var contentStartColumn = contentColumnResult.contentStartColumn\n // minimumContentStartColumn is the minimum column where content can start (for continuation checks)\n // This is the column after marker+space, regardless of how much whitespace follows\n // For empty items, it's right after the marker\n var markerBaseColumn = baseIndent + markerStartInLine + match[1].length\n var minimumContentStartColumn = ordered\n ? markerBaseColumn + match[2].length + 1 // number + delimiter + space\n : isEmptyItem\n ? markerBaseColumn // marker only (no space)\n : markerBaseColumn + 1 // marker + space\n\n var items: MarkdownToJSX.ASTNode[][] = []\n // Track contentStartColumn for each item (for nested list detection)\n var itemContentStartColumns: number[] = []\n\n // Helper: Check if a marker column is nested enough to belong to the last item\n function isMarkerNested(\n markerColumn: number,\n lastItemContentColumn: number,\n hasBlockContent: boolean\n ): boolean {\n return hasBlockContent\n ? markerColumn >= lastItemContentColumn\n : markerColumn > lastItemContentColumn\n }\n\n // Helper: Get last item\n function getLastItem(): MarkdownToJSX.ASTNode[] {\n return items[items.length - 1]\n }\n\n // Helper: Get last item's content start column\n function getLastItemContentColumn(): number {\n return (\n itemContentStartColumns[itemContentStartColumns.length - 1] ??\n contentStartColumn\n )\n }\n\n function tryParseNestedList(\n pos: number,\n lastItem: MarkdownToJSX.ASTNode[]\n ): ParseResult | null {\n const parentItem = findNestedListParent(lastItem)\n const originalList = state.inList\n state.inList = true\n const result = parseList(source, pos, state, options)\n state.inList = originalList\n if (result) {\n parentItem.push(result)\n return result\n }\n return null\n }\n\n var currentPos = skipToNextLine(source, lineEnd)\n\n // Check if this is a loose list (has blank lines)\n var checkPos = currentPos\n var hasBlankLines = false\n\n while (checkPos < source.length) {\n var nextLineEnd = util.findLineEnd(source, checkPos)\n var nextLine = source.slice(checkPos, nextLineEnd)\n if (nextLine.trim() === '') {\n // look ahead to next non-empty line\n var look = skipToNextLine(source, nextLineEnd)\n while (look < source.length) {\n var code = charCode(source, look)\n if (code === $.CHAR_NEWLINE) {\n // keep skipping\n } else if (!WHITESPACE_CHARS.has(source[look])) {\n break\n }\n look++\n }\n var lookEnd = util.findLineEnd(source, look)\n var lookLine = source.slice(look, lookEnd)\n var lookIndentInfo = calculateIndent(source, look, lookEnd)\n var lookLineWithoutIndent = lookLine.slice(lookIndentInfo.charCount)\n if (\n isMatchingListItem(\n lookLineWithoutIndent,\n lookIndentInfo,\n ordered,\n marker,\n delimiter,\n baseIndent,\n listItemRegex\n )\n ) {\n hasBlankLines = true\n } else {\n // Per CommonMark: link reference definitions can interrupt lists\n // If blank line is followed by a link reference definition, check if there's a list item after it\n var refEndPos = skipLinkReferenceDefinition(\n source,\n look,\n lookEnd,\n lookIndentInfo,\n lookLineWithoutIndent,\n state,\n options\n )\n if (refEndPos) {\n var afterRefPos = refEndPos\n while (\n afterRefPos < source.length &&\n charCode(source, afterRefPos) === $.CHAR_NEWLINE\n ) {\n afterRefPos++\n }\n if (afterRefPos < source.length) {\n var afterRefLineEnd = util.findLineEnd(source, afterRefPos)\n var afterRefLine = source.slice(afterRefPos, afterRefLineEnd)\n var afterRefIndentInfo = calculateIndent(\n source,\n afterRefPos,\n afterRefLineEnd\n )\n var afterRefLineWithoutIndent = afterRefLine.slice(\n afterRefIndentInfo.charCount\n )\n if (\n isMatchingListItem(\n afterRefLineWithoutIndent,\n afterRefIndentInfo,\n ordered,\n marker,\n delimiter,\n baseIndent,\n listItemRegex\n )\n ) {\n hasBlankLines = true\n }\n }\n }\n }\n break\n }\n var nextIndentInfo = calculateIndent(source, checkPos, nextLineEnd)\n var nextLineWithoutIndent = nextLine.slice(nextIndentInfo.charCount)\n var nextMatchResult = matchListItem(nextLineWithoutIndent)\n if (!nextMatchResult) break\n var nextMatch = nextMatchResult.match\n if (ordered) {\n if (nextMatch[2] !== delimiter) break\n } else {\n if (nextMatch[1] !== marker) break\n }\n checkPos = skipToNextLine(source, nextLineEnd)\n }\n\n // Parse the first item\n var firstItemContent = ordered ? match[3] : match[2]\n // Trim leading whitespace from content (regex now captures optional whitespace)\n firstItemContent = firstItemContent.trimStart()\n\n // Per CommonMark spec: tabs after list marker need special handling\n // For `-\\t\\tfoo`: `-` at column 0, first tab at column 1 = 3 spaces (one for marker delimiter),\n // second tab at column 4 = 4 spaces, total 6 spaces, so code block with 2 spaces remaining\n // The regex `\\s+` consumes the tabs, so match[2]/match[3] is just `foo`\n // We need to check the original source to detect tabs after the marker\n var markerStartPos = pos + indent + (match.index || 0)\n var markerEndPos = ordered\n ? markerStartPos + match[1].length + match[2].length // number + delimiter\n : markerStartPos + match[1].length // marker\n\n // Check for spaces after marker (for code blocks with 5+ spaces)\n // Per CommonMark: if there are 4+ spaces after the marker (including required space),\n // the first line is an indented code block\n var contentStartPos = markerEndPos\n // Skip the required space/tab after marker\n while (contentStartPos < source.length) {\n var code = charCode(source, contentStartPos)\n if (code !== $.CHAR_SPACE && code !== $.CHAR_TAB) break\n contentStartPos++\n }\n // Count spaces after marker (including the required one)\n var spacesAfterMarkerCount = 0\n var spacesCheckPos = markerEndPos\n while (spacesCheckPos < lineEnd) {\n var code = charCode(source, spacesCheckPos)\n if (code === $.CHAR_TAB) {\n spacesAfterMarkerCount += 4 - (spacesAfterMarkerCount % 4)\n } else if (code === $.CHAR_SPACE) {\n spacesAfterMarkerCount++\n } else {\n break\n }\n spacesCheckPos++\n }\n\n var tabsProcessed = false\n if (\n markerEndPos < source.length &&\n charCode(source, markerEndPos) === $.CHAR_TAB\n ) {\n // First tab after marker was consumed by `\\s+`\n // Tab at column 1 = 3 spaces (1 for delimiter, 2 for content)\n // Check if there's a second tab\n var tabCount = 1\n var tabCheckPos = markerEndPos + 1\n while (\n tabCheckPos < source.length &&\n charCode(source, tabCheckPos) === $.CHAR_TAB\n ) {\n tabCount++\n tabCheckPos++\n }\n\n if (tabCount >= 2) {\n // We have 2+ tabs after marker: first gives 2 spaces, second at column 4 = 4 spaces\n // Total: 6 spaces, then remove 4 for code block = 2 spaces\n firstItemContent = ' ' + firstItemContent\n tabsProcessed = true\n }\n }\n // Update isEmptyItem now that we know spacesAfterMarkerCount\n // Empty item is one with no whitespace after marker (spacesAfterMarkerCount === 0)\n // For unordered lists, also check that match[2] is empty (no content captured)\n if (!ordered) {\n isEmptyItem = isEmptyItem && spacesAfterMarkerCount === 0\n }\n // RULE_2_CODE_START: if 4+ spaces after marker, first line is indented code block\n // Skip if tabs were already processed (they already account for code block indentation)\n if (spacesAfterMarkerCount >= 4 && !tabsProcessed) {\n // Preserve the leading spaces for code blocks\n const preservedSpaces = ' '.repeat(spacesAfterMarkerCount - 1)\n firstItemContent = preservedSpaces + firstItemContent.trimStart()\n }\n\n // RULE_3_BLANK_START: check if item starts with blank line\n // If firstItemContent is empty (just whitespace), this is RULE_3_BLANK_START\n var startsWithBlankLine = firstItemContent.trim() === ''\n if (startsWithBlankLine) {\n // For RULE_3_BLANK_START, content starts after blank line(s)\n // Continuation lines need to be indented by W + 1 spaces minimum\n // W is the width of the marker (1 for '-', 2 for '10.', etc.)\n // So minimum continuation indent is markerWidth + 1\n }\n\n // Check if there will be blank lines within the first item (after currentPos)\n // by looking ahead to see if we'll encounter a blank line before the next item or end\n let firstItemHasBlankLine = hasBlankLines\n if (!hasBlankLines && currentPos < source.length) {\n var firstCheckPos = currentPos\n while (firstCheckPos < source.length) {\n var firstNextLineEnd = util.findLineEnd(source, firstCheckPos)\n var firstNextLine = source.slice(firstCheckPos, firstNextLineEnd)\n if (isBlankLineCheck(source, firstCheckPos, firstNextLineEnd)) {\n // Found blank line - check if continuation belongs to nested list or first item\n var afterBlank = skipToNextLine(source, firstNextLineEnd)\n // Skip consecutive blank lines\n while (afterBlank < source.length) {\n var blankLineEnd = util.findLineEnd(source, afterBlank)\n if (isBlankLineCheck(source, afterBlank, blankLineEnd)) {\n afterBlank = skipToNextLine(source, blankLineEnd)\n } else {\n break\n }\n }\n\n if (afterBlank < source.length) {\n var afterIndentInfo = calculateIndent(\n source,\n afterBlank,\n source.length\n )\n var afterIndent = afterIndentInfo.spaceEquivalent\n if (afterIndent >= baseIndent) {\n var afterLine = source.slice(\n afterBlank,\n util.findLineEnd(source, afterBlank)\n )\n var afterMatch = afterLine\n .slice(afterIndentInfo.charCount)\n .match(listItemRegex)\n var afterIsNewItem =\n afterMatch &&\n (ordered ? afterMatch[2] === delimiter : afterMatch[1] === marker)\n\n // Find nested item before blank line and calculate its content column\n var nestedItemContentColumn = null\n for (\n var nestedCheckPos = currentPos;\n nestedCheckPos < firstCheckPos;\n nestedCheckPos = util.findLineEnd(source, nestedCheckPos) + 1\n ) {\n var nestedCheckLineEnd = util.findLineEnd(source, nestedCheckPos)\n var nestedCheckIndentInfo = calculateIndent(\n source,\n nestedCheckPos,\n nestedCheckLineEnd\n )\n var nestedCheckMatch = source\n .slice(nestedCheckPos, nestedCheckLineEnd)\n .slice(nestedCheckIndentInfo.charCount)\n .match(listItemRegex)\n var isNestedItem =\n nestedCheckMatch &&\n nestedCheckIndentInfo.spaceEquivalent > baseIndent &&\n nestedCheckIndentInfo.spaceEquivalent >= contentStartColumn &&\n (ordered\n ? nestedCheckMatch[2] === delimiter\n : nestedCheckMatch[1] === marker)\n\n if (isNestedItem) {\n // Calculate nested item's content column (same pattern as contentStartColumn)\n var nestedMarkerStart =\n nestedCheckIndentInfo.spaceEquivalent + 1\n var nestedMarkerEnd = ordered\n ? nestedMarkerStart +\n nestedCheckMatch[1].length +\n nestedCheckMatch[2].length +\n 1\n : nestedMarkerStart + nestedCheckMatch[1].length + 1\n var nestedContentStartInSource =\n nestedCheckPos +\n nestedCheckIndentInfo.charCount +\n nestedCheckMatch[0].length\n var nestedResult = calculateListItemContentColumn(\n source,\n nestedContentStartInSource,\n nestedCheckLineEnd,\n nestedMarkerStart,\n nestedMarkerEnd - nestedMarkerStart\n )\n nestedItemContentColumn = nestedResult.contentStartColumn\n break\n }\n }\n\n var continuationCheckColumn =\n spacesAfterMarkerCount >= 5\n ? minimumContentStartColumn\n : contentStartColumn\n if (\n !afterIsNewItem &&\n afterIndent >= continuationCheckColumn &&\n (nestedItemContentColumn === null ||\n afterIndent + 1 < nestedItemContentColumn)\n ) {\n firstItemHasBlankLine = true\n }\n }\n }\n break\n }\n // Check if this line is a new list item (at same or greater indentation)\n var firstLineIndentInfo = calculateIndent(\n source,\n firstCheckPos,\n firstNextLineEnd\n )\n var firstIndent = firstLineIndentInfo.spaceEquivalent\n var firstLineWithoutIndent = firstNextLine.slice(\n firstLineIndentInfo.charCount\n )\n var firstLineMatch = firstLineWithoutIndent.match(listItemRegex)\n var firstIsNewItem =\n firstLineMatch &&\n (ordered\n ? firstLineMatch[2] === delimiter\n : firstLineMatch[1] === marker)\n // If it's a new item at baseIndent, it's the next item at same level - stop looking\n // For nested items, continue looking for blank lines after the nested list\n if (firstIsNewItem) {\n if (firstIndent <= baseIndent) {\n // Same level or higher - stop looking\n break\n }\n // Nested list - continue looking (don't break)\n }\n firstCheckPos = skipToNextLine(source, firstNextLineEnd)\n }\n }\n\n // Handle fenced code blocks that span multiple lines\n // Note: We use manual expansion here rather than parseCodeFenced because\n // we need to return a content string (with fence lines) that will be parsed later,\n // not an AST node. parseCodeFenced returns an AST node, which doesn't fit this use case.\n var actualFirstItemContent = firstItemContent\n if (\n util.startsWith(firstItemContent, '```') ||\n util.startsWith(firstItemContent, '~~~')\n ) {\n var markerWidth = ordered\n ? match[1].length + match[2].length + 1\n : match[1].length + 1\n var expandedResult = expandMultilineFencedCodeBlock(\n source,\n firstItemContent,\n currentPos,\n markerWidth\n )\n actualFirstItemContent = expandedResult.content\n currentPos = expandedResult.endPos\n }\n\n // For tight lists with whitespace-only first line, combine with continuation to avoid multiple blocks\n var hasWhitespaceButNoContent =\n !isEmptyItem &&\n firstItemContent.trim() === '' &&\n spacesAfterMarkerCount > 0 &&\n spacesAfterMarkerCount < 5\n if (hasWhitespaceButNoContent && !firstItemHasBlankLine) {\n var pos = currentPos\n while (pos < source.length) {\n var lineEnd = util.findLineEnd(source, pos)\n var line = source.slice(pos, lineEnd)\n if (line.trim() === '') break\n var indentInfo = calculateIndent(source, pos, lineEnd)\n if (indentInfo.spaceEquivalent < minimumContentStartColumn) break\n var lineWithoutIndent = line.slice(indentInfo.charCount)\n if (\n indentInfo.spaceEquivalent <= baseIndent &&\n isMatchingListItem(\n lineWithoutIndent,\n indentInfo,\n ordered,\n marker,\n delimiter,\n baseIndent,\n listItemRegex\n )\n ) {\n break\n }\n actualFirstItemContent += '\\n' + lineWithoutIndent\n currentPos = pos = skipToNextLine(source, lineEnd)\n }\n }\n\n // Build first item with GFM task support\n items.push(\n buildListItemContent(\n actualFirstItemContent,\n firstItemHasBlankLine,\n state,\n options\n )\n )\n itemContentStartColumns.push(contentStartColumn)\n\n // Process continuation lines for the first item\n // For tight lists (no blank lines), also process continuation if it's indented enough\n const shouldProcessContinuation =\n firstItemHasBlankLine &&\n (spacesAfterMarkerCount >= 5 || hasWhitespaceButNoContent)\n if (shouldProcessContinuation) {\n const lastItem = getLastItem()\n currentPos = processContinuation(\n source,\n lastItem,\n minimumContentStartColumn,\n currentPos,\n baseIndent,\n ordered,\n marker,\n delimiter,\n listItemRegex,\n state,\n options,\n true\n )\n } else if (!firstItemHasBlankLine) {\n // For tight lists (no blank lines), process continuation lines\n const continuationColumn = minimumContentStartColumn - 1\n while (currentPos < source.length) {\n const nextLineEnd = util.findLineEnd(source, currentPos)\n const nextLine = source.slice(currentPos, nextLineEnd)\n const nextIndentInfo = calculateIndent(source, currentPos, nextLineEnd)\n const nextIndent = nextIndentInfo.spaceEquivalent\n const nextLineWithoutIndent = nextLine.slice(nextIndentInfo.charCount)\n\n if (\n nextLine.trim() === '' ||\n (nextIndent <= baseIndent &&\n isMatchingListItem(\n nextLineWithoutIndent,\n nextIndentInfo,\n ordered,\n marker,\n delimiter,\n baseIndent,\n listItemRegex\n )) ||\n (isLineListItem(nextLineWithoutIndent) && nextIndent > baseIndent) ||\n nextIndent < continuationColumn\n ) {\n break\n }\n\n const lastItem = getLastItem()\n const result = processListContinuationLine(\n source,\n currentPos,\n nextLineEnd,\n nextIndentInfo,\n continuationColumn,\n contentStartColumn,\n lastItem,\n false,\n state,\n options,\n true,\n baseIndent\n )\n if (result.processed) {\n currentPos = result.newPos\n } else {\n break\n }\n }\n }\n\n // Continue parsing subsequent list items\n var prevLineWasBlank = false\n while (currentPos < source.length) {\n const nextLineEnd = util.findLineEnd(source, currentPos)\n\n const nextLine = source.slice(currentPos, nextLineEnd)\n const nextIndentInfo = calculateIndent(source, currentPos, nextLineEnd)\n const nextIndentChars = nextIndentInfo.charCount\n const nextIndent = nextIndentInfo.spaceEquivalent\n\n if (nextLine.trim() === '') {\n // Blank line - mark as loose list and continue\n hasBlankLines = true\n prevLineWasBlank = true\n currentPos = skipToNextLine(source, nextLineEnd)\n } else if (nextIndent < baseIndent) {\n const nextLineWithoutIndent = nextLine.slice(nextIndentChars)\n if (\n nextLineWithoutIndent.startsWith('<') &&\n checkHTMLTagInterruptsList(\n source,\n currentPos,\n nextIndentChars,\n baseIndent,\n nextIndent,\n options\n )\n ) {\n break\n }\n\n // Less indented - check if this is a lazy continuation line\n // Per CommonMark: lazy continuation lines can have all indentation deleted\n // They are still part of the list item if they are paragraph continuation text\n const trimmed = nextLineWithoutIndent.trim()\n if (\n trimmed.length > 0 &&\n items.length > 0 &&\n !isBlockStartChar(trimmed[0]) &&\n !isMatchingListItem(\n nextLineWithoutIndent,\n nextIndentInfo,\n ordered,\n marker,\n delimiter,\n baseIndent,\n listItemRegex\n )\n ) {\n const lastItem = getLastItem()\n if (lastItem.length > 0) {\n const lastBlock = lastItem[lastItem.length - 1]\n if (\n lastBlock.type === RuleType.paragraph ||\n lastBlock.type === RuleType.text\n ) {\n // This is a lazy continuation line - continue the paragraph\n appendListContinuation(\n nextLineWithoutIndent,\n lastItem,\n state,\n options\n )\n prevLineWasBlank = false\n currentPos = skipToNextLine(source, nextLineEnd)\n continue\n }\n }\n }\n // Not a lazy continuation - end of list\n break\n } else {\n const nextLineWithoutIndent = nextLine.slice(nextIndentChars)\n\n // Check for setext heading BEFORE thematic break\n // If last item ends with text/paragraph and this line is setext underline, convert to heading\n // Per CommonMark: setext underline must be indented enough to be continuation\n // BUT: don't check if this line is a list item marker (would be continuation of wrong item)\n if (items.length > 0) {\n const lastItemContentStartColumn =\n itemContentStartColumns[items.length - 1] || contentStartColumn\n if (\n nextIndent + 1 >= lastItemContentStartColumn &&\n !isMatchingListItem(\n nextLineWithoutIndent,\n nextIndentInfo,\n ordered,\n marker,\n delimiter,\n baseIndent,\n listItemRegex\n )\n ) {\n const lastItem = getLastItem()\n if (\n lastItem.length > 0 &&\n convertSetextHeadingInListItem(\n lastItem,\n nextLineWithoutIndent,\n options\n )\n ) {\n currentPos = skipToNextLine(source, nextLineEnd)\n continue\n }\n }\n }\n\n // Check if this line is a thematic break (per CommonMark, thematic breaks end lists)\n const thematicBreakResult = parseBreakThematic(\n source,\n currentPos,\n state,\n options\n )\n if (thematicBreakResult) {\n // Thematic break ends the list\n break\n }\n\n // Per CommonMark spec: link reference definitions interrupt list continuation\n // Check if this is a link reference definition after a blank line\n if (prevLineWasBlank) {\n const refEndPos = skipLinkReferenceDefinition(\n source,\n currentPos,\n nextLineEnd,\n nextIndentInfo,\n nextLineWithoutIndent,\n state,\n options\n )\n if (refEndPos) {\n // Skip link reference definition and continue parsing list (don't break)\n currentPos = refEndPos\n prevLineWasBlank = false\n continue\n }\n }\n\n // If line is at base indentation and not a list item, check for lazy continuation first\n if (nextIndent <= baseIndent) {\n if (\n nextLineWithoutIndent.startsWith('<') &&\n checkHTMLTagInterruptsList(\n source,\n currentPos,\n nextIndentChars,\n baseIndent,\n nextIndent,\n options\n )\n ) {\n break\n }\n\n if (\n !isMatchingListItem(\n nextLineWithoutIndent,\n nextIndentInfo,\n ordered,\n marker,\n delimiter,\n baseIndent,\n listItemRegex\n )\n ) {\n // Check for lazy continuation when nextIndent === baseIndent\n // Per CommonMark: lazy continuation lines can have all indentation deleted\n // BUT: only if there was no blank line before (lazy continuation requires no blank line)\n // AND: only if it's truly paragraph continuation text (not a block start)\n if (nextIndent === baseIndent && !prevLineWasBlank) {\n const trimmed = nextLineWithoutIndent.trim()\n if (trimmed.length > 0 && !isBlockStartChar(trimmed[0])) {\n // Check if this line would start a block (like HTML comment, thematic break, etc.)\n // If so, it should break the list, not continue it\n const blockResult = parseBlock(source, currentPos, state, options)\n if (blockResult && blockResult.type !== RuleType.paragraph) {\n break\n }\n const lastItem = getLastItem()\n if (lastItem.length > 0 && !listItemHasBlockContent(lastItem)) {\n // This is a lazy continuation line - continue the inline content\n // Lazy continuation lines don't add a newline (no space in output)\n appendListContinuation(\n nextLineWithoutIndent,\n lastItem,\n state,\n options,\n false\n )\n prevLineWasBlank = false\n currentPos = skipToNextLine(source, nextLineEnd)\n continue\n }\n }\n }\n break\n }\n }\n\n // Check for empty items with blank lines\n if (\n shouldBreakForEmptyItem(\n items,\n isEmptyItem,\n prevLineWasBlank,\n firstItemContent\n )\n )\n break\n\n const nextMatchResult = matchListItem(nextLineWithoutIndent)\n const nextMatch = nextMatchResult ? nextMatchResult.match : null\n const isSameType =\n nextMatch &&\n (ordered ? nextMatch[2] === delimiter : nextMatch[1] === marker)\n // Per CommonMark: list markers may be indented by up to 3 spaces\n // If marker is too indented (> 3 spaces), it's not a valid list item\n // If there's a blank line before such a marker, end the list (e.g., Example 313)\n if (isSameType && nextIndent > 3 && prevLineWasBlank) {\n break\n }\n // Skip list item processing and fall through to continuation check\n if (isSameType && nextIndent <= baseIndent + 3) {\n if (nextIndent >= 4 && prevLineWasBlank) break\n if (nextIndent === baseIndent) {\n // Item at same level - parse as new item\n let itemContent = ordered ? nextMatch[3] : nextMatch[2]\n itemContent = itemContent.trimStart()\n\n const result = addListItem(\n source,\n items,\n itemContentStartColumns,\n itemContent,\n currentPos,\n nextLineEnd,\n nextIndent,\n nextIndentChars,\n nextMatch,\n ordered,\n hasBlankLines,\n state,\n options\n )\n currentPos = result.newCurrentPos\n prevLineWasBlank = false\n\n // For empty items, process continuation immediately\n if (itemContent.trim() === '') {\n const newItem = items[items.length - 1]\n const thisItemContentStartColumn = getLastItemContentColumn()\n currentPos = processContinuation(\n source,\n newItem,\n thisItemContentStartColumn,\n currentPos,\n baseIndent,\n ordered,\n marker,\n delimiter,\n listItemRegex,\n state,\n options\n )\n }\n\n continue\n }\n if (nextIndent > baseIndent) {\n // Per CommonMark spec: items are only nested if indented enough to belong to previous item\n // If there was a blank line before this item, it's at the same level (not nested)\n if (prevLineWasBlank) {\n // Blank line before item means it's a new item at same level, not nested\n let itemContent = ordered ? nextMatch[3] : nextMatch[2]\n // Trim leading whitespace from content (regex now captures optional whitespace)\n itemContent = itemContent.trimStart()\n const result = addListItem(\n source,\n items,\n itemContentStartColumns,\n itemContent,\n currentPos,\n nextLineEnd,\n nextIndent,\n nextIndentChars,\n nextMatch,\n ordered,\n hasBlankLines,\n state,\n options\n )\n currentPos = result.newCurrentPos\n prevLineWasBlank = false\n continue\n }\n // Check if this item's marker position is indented enough to be continuation of previous item\n // We need to calculate the previous item's contentStartColumn, not use the first item's\n const lastItem = getLastItem()\n const markerColumn = nextIndent + 1\n const isNested = isMarkerNested(\n markerColumn,\n getLastItemContentColumn(),\n listItemHasBlockContent(lastItem)\n )\n\n if (isNested) {\n const nestedResult = tryParseNestedList(currentPos, lastItem)\n if (nestedResult) {\n currentPos = nestedResult.endPos\n prevLineWasBlank = false\n continue\n }\n }\n // Item is not indented enough to be nested - check if it's same type for same level\n if (!isNested && isSameType) {\n // This item has more indentation than baseIndent but not enough to be nested\n // It's still at the same level - parse it as a new item\n let itemContent = ordered ? nextMatch[3] : nextMatch[2]\n // Trim leading whitespace from content\n itemContent = itemContent.trimStart()\n if (!hasBlankLines) {\n // Check if this item has blank lines within it\n let checkItemPos = skipToNextLine(source, nextLineEnd)\n while (checkItemPos < source.length) {\n const checkLineEnd = util.findLineEnd(source, checkItemPos)\n const checkLine = source.slice(checkItemPos, checkLineEnd)\n const checkIndentInfo = calculateIndent(\n source,\n checkItemPos,\n checkLineEnd\n )\n const checkIndent = checkIndentInfo.spaceEquivalent\n\n if (checkLine.trim() === '') {\n const afterBlank = skipToNextLine(source, checkLineEnd)\n if (afterBlank < source.length) {\n const afterBlankIndentInfo = calculateIndent(\n source,\n afterBlank,\n source.length\n )\n const afterBlankIndent =\n afterBlankIndentInfo.spaceEquivalent\n // Calculate contentStartColumn for this item\n const thisItemMarkerStart = nextIndent\n const thisItemContentStart =\n thisItemMarkerStart +\n (ordered\n ? nextMatch[1].length + nextMatch[2].length + 1\n : nextMatch[1].length + 1)\n if (afterBlankIndent + 1 > thisItemContentStart) {\n break\n }\n }\n break\n } else if (checkIndent <= baseIndent) {\n // Check if this is the next list item at baseIndent or less\n const checkLineWithoutIndent = checkLine.slice(\n checkIndentInfo.charCount\n )\n const checkMatch = checkLineWithoutIndent.match(listItemRegex)\n const isNextItem =\n checkMatch &&\n (ordered\n ? checkMatch[2] === delimiter\n : checkMatch[1] === marker)\n if (isNextItem && checkIndent <= baseIndent) {\n break\n }\n }\n checkItemPos = skipToNextLine(source, checkLineEnd)\n }\n }\n const result = addListItem(\n source,\n items,\n itemContentStartColumns,\n itemContent,\n currentPos,\n nextLineEnd,\n nextIndent,\n nextIndentChars,\n nextMatch,\n ordered,\n hasBlankLines,\n state,\n options\n )\n currentPos = result.newCurrentPos\n prevLineWasBlank = false\n continue\n } else if (!isNested && !isSameType) {\n // Different marker type at same level - end this list\n break\n }\n // Fall through to continuation check if isNested but parseList failed\n // Check if this is continuation content\n // Per CommonMark: continuation needs to be indented to at least the content start column\n // nextIndent is space count (0-indexed), contentStartColumn is column number (1-indexed)\n // When list item has block content, exact indentation (==) continues; otherwise use >\n // For continuation checks, use minimumContentStartColumn (column after marker+space)\n // instead of contentStartColumn (which can be higher for code blocks)\n {\n const lastItem = getLastItem()\n // Check if last item is empty (no content)\n const lastItemIsEmpty = lastItem.length === 0\n // Check for empty items with blank lines\n if (\n lastItemIsEmpty &&\n shouldBreakForEmptyItem(\n items,\n isEmptyItem,\n prevLineWasBlank,\n firstItemContent\n )\n )\n break\n\n const hasBlockContent = lastItem.some(\n node =>\n node.type === RuleType.codeBlock ||\n node.type === RuleType.paragraph ||\n node.type === RuleType.blockQuote ||\n node.type === RuleType.orderedList ||\n node.type === RuleType.unorderedList ||\n node.type === RuleType.heading\n )\n // For empty items, use minimumContentStartColumn (marker + space) instead of contentStartColumn\n // which can be higher when there's extra whitespace but no content\n const continuationColumn =\n lastItemIsEmpty && items.length === 1\n ? minimumContentStartColumn\n : contentStartColumn\n const continuationCheck = hasBlockContent\n ? nextIndent >= continuationColumn\n : nextIndent > continuationColumn\n if (continuationCheck) {\n const result = processListContinuationLine(\n source,\n currentPos,\n nextLineEnd,\n nextIndentInfo,\n continuationColumn,\n contentStartColumn,\n getLastItem(),\n prevLineWasBlank,\n state,\n options,\n undefined,\n baseIndent\n )\n if (result.processed) {\n prevLineWasBlank = result.wasBlank\n currentPos = result.newPos\n continue\n }\n } else {\n break\n }\n }\n } else if (nextIndent === baseIndent) {\n // Check for Unicode whitespace after marker in unordered lists\n if (\n !ordered &&\n nextMatch &&\n checkUnicodeWhitespaceAfterMarker(nextMatch, nextMatch[1])\n ) {\n break\n }\n let itemContent = ordered ? nextMatch[3] : nextMatch[2]\n // Trim leading whitespace from content (regex now captures optional whitespace)\n itemContent = itemContent.trimStart()\n // Per CommonMark: A list is loose if items are separated by blank lines,\n // OR if an item directly contains two block-level elements with a blank line between them.\n // If list is loose (hasBlankLines = true), ALL items are wrapped.\n // Otherwise, an item is wrapped only if it has blank lines within it.\n // A blank line before this item means the PREVIOUS item was separated from this one,\n // making the list loose. For this item, we check if it has continuation after blank lines.\n // But if the list is already loose (hasBlankLines), wrap this item too.\n const result = addListItem(\n source,\n items,\n itemContentStartColumns,\n itemContent,\n currentPos,\n nextLineEnd,\n baseIndent,\n nextIndentChars,\n nextMatch,\n ordered,\n hasBlankLines,\n state,\n options\n )\n currentPos = result.newCurrentPos\n prevLineWasBlank = false\n }\n } else if (nextIndent > baseIndent) {\n // Check if this is a list item - if so, check if it should be nested or separate\n // Per CommonMark: list item markers can only be indented 0-3 spaces relative to baseIndent\n // However, nested lists can have more indentation if they're indented relative to content start\n // So we need to try parsing as nested list first, then check for paragraph continuation\n const lastItem = getLastItem()\n const isListItemResult = isLineListItem(nextLineWithoutIndent)\n if (isListItemResult) {\n // Check if marker would be properly nested (relative to content start column)\n // This handles nested lists that may have > 3 spaces indent from baseIndent\n const markerColumn = nextIndent + 1\n const isNested = isMarkerNested(\n markerColumn,\n getLastItemContentColumn(),\n listItemHasBlockContent(lastItem)\n )\n\n if (isNested) {\n // Properly nested - try parsing as nested list\n const nestedResult = tryParseNestedList(currentPos, lastItem)\n if (nestedResult) {\n currentPos = nestedResult.endPos\n prevLineWasBlank = false\n continue\n }\n }\n\n // Not properly nested - check if marker indent is valid (0-3 spaces relative to baseIndent)\n // Per CommonMark: list item markers can only be indented 0-3 spaces relative to baseIndent\n const markerIndentRelative = nextIndent - baseIndent\n if (markerIndentRelative > 3) {\n // Too much indentation (> 3 spaces from baseIndent) and not nested - not a valid list item marker\n // Check if it should be treated as paragraph continuation (if last item ends with paragraph)\n const lastBlock =\n lastItem.length > 0 ? lastItem[lastItem.length - 1] : null\n if (\n lastBlock &&\n (lastBlock.type === RuleType.paragraph ||\n lastBlock.type === RuleType.text)\n ) {\n // This is paragraph continuation text, not a code block or nested list\n appendListContinuation(\n nextLineWithoutIndent,\n lastItem,\n state,\n options\n )\n prevLineWasBlank = false\n currentPos = skipToNextLine(source, nextLineEnd)\n continue\n }\n // Not paragraph continuation - fall through to code block check\n } else {\n // Valid marker indent (0-3 spaces) but not nested - this should be a separate list\n break\n }\n } else {\n // Not a list item - try parsing as nested list (for other block types)\n const nestedResult = tryParseNestedList(currentPos, lastItem)\n if (nestedResult) {\n currentPos = nestedResult.endPos\n prevLineWasBlank = false\n continue\n }\n }\n // Check if this is continuation content\n // Per CommonMark: continuation needs to be indented to at least the content start column\n // nextIndent is space count (0-indexed), contentStartColumn is column number (1-indexed)\n // When list item has block content, exact indentation (==) continues; otherwise use >\n // For continuation checks, use minimumContentStartColumn (column after marker+space)\n // instead of contentStartColumn (which can be higher for code blocks)\n const continuationColumn = contentStartColumn\n const continuationCheck = listItemHasBlockContent(lastItem)\n ? nextIndent >= continuationColumn - 1\n : nextIndent > continuationColumn - 1\n if (continuationCheck) {\n const result = processListContinuationLine(\n source,\n currentPos,\n nextLineEnd,\n nextIndentInfo,\n continuationColumn - 1,\n contentStartColumn,\n getLastItem(),\n prevLineWasBlank,\n state,\n options,\n undefined,\n baseIndent\n )\n if (result.processed) {\n prevLineWasBlank = result.wasBlank\n currentPos = result.newPos\n continue\n }\n } else {\n break\n }\n } else {\n break\n }\n }\n }\n\n // For loose lists, ensure all items have paragraph wrappers\n // The first item may have been created before we detected that the list is loose\n if (\n hasBlankLines &&\n items.length > 1 &&\n items[0].length > 0 &&\n items[0][0].type !== RuleType.paragraph\n ) {\n // Check if list is truly loose (another item has paragraph wrapper)\n for (var j = 1; j < items.length; j++) {\n if (items[j].length > 0 && items[j][0].type === RuleType.paragraph) {\n // First item is all inline content - wrap it for loose lists\n var isBlock = false\n for (var i = 0; i < items[0].length; i++) {\n var t = items[0][i].type\n if (\n t === RuleType.codeBlock ||\n t === RuleType.heading ||\n t === RuleType.blockQuote ||\n t === RuleType.orderedList ||\n t === RuleType.unorderedList ||\n t === RuleType.htmlBlock ||\n t === RuleType.breakThematic\n ) {\n isBlock = true\n break\n }\n }\n if (!isBlock) {\n items[0] = [\n {\n type: RuleType.paragraph,\n children: items[0],\n } as MarkdownToJSX.ParagraphNode,\n ]\n }\n break\n }\n }\n }\n\n const listNode = ordered\n ? ({\n type: RuleType.orderedList,\n items,\n ordered: true,\n start,\n } as MarkdownToJSX.OrderedListNode)\n : ({\n type: RuleType.unorderedList,\n items,\n ordered: false,\n } as MarkdownToJSX.UnorderedListNode)\n\n // Restore original inList state\n state.inList = originalInList\n\n return {\n ...listNode,\n endPos: currentPos,\n } as (MarkdownToJSX.OrderedListNode | MarkdownToJSX.UnorderedListNode) & {\n endPos: number\n }\n}\n\nfunction parseTable(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult {\n if (state.inline) return null\n\n const lines: string[] = []\n let currentPos = pos\n\n while (currentPos < source.length) {\n const lineEnd = util.findLineEnd(source, currentPos)\n if (isBlankLineCheck(source, currentPos, lineEnd)) break\n\n const line = source.slice(currentPos, lineEnd).trim()\n const isTableLine =\n line.indexOf('|') !== -1 ||\n (lines.length >= 3 && line && !isBlockStartChar(line[0]))\n\n if (!isTableLine) break\n lines.push(line)\n currentPos = skipToNextLine(source, lineEnd)\n }\n\n if (lines.length < 2) return null\n\n // Unwrap pipes and split cells\n const unwrap = (line: string) =>\n line[0] === '|' && line[line.length - 1] === '|' ? line.slice(1, -1) : line\n\n const splitCells = (line: string) => {\n const cells: string[] = []\n let current = ''\n let inCode = false\n\n for (let i = 0; i < line.length; i++) {\n const ch = line[i]\n if (ch === '\\\\' && i + 1 < line.length && line[i + 1] === '|') {\n current += '|'\n i++\n } else if (ch === '`') {\n inCode = !inCode\n current += ch\n } else if (ch === '|' && !inCode) {\n cells.push(current.trim())\n current = ''\n } else {\n current += ch\n }\n }\n cells.push(current.trim())\n return cells\n }\n\n const headerCells = splitCells(unwrap(lines[0]))\n if (!headerCells.length) return null\n\n const separatorCells = splitCells(unwrap(lines[1]))\n if (\n separatorCells.length !== headerCells.length ||\n separatorCells.some(cell => !/^:?-+:?$/.test(cell))\n ) {\n return null\n }\n\n const alignments = separatorCells.map(cell => {\n const start = cell[0] === ':'\n const end = cell[cell.length - 1] === ':'\n return start && end ? 'center' : start ? 'left' : end ? 'right' : null\n })\n\n const parseRow = (cells: string[]) =>\n parseWithInlineMode(state, true, () =>\n cells.map(cell => parseInlineSpan(cell, 0, cell.length, state, options))\n )\n\n const header = parseRow(headerCells)\n\n const body = lines.slice(2).map(line => {\n const cells =\n line.indexOf('|') !== -1 ? splitCells(unwrap(line)) : [line.trim()]\n\n // Normalize cell count\n const count = headerCells.length\n while (cells.length < count) cells.push('')\n cells.length = count\n\n return parseRow(cells)\n })\n\n return {\n type: RuleType.table,\n header,\n cells: body,\n align: alignments,\n endPos: currentPos,\n } as MarkdownToJSX.TableNode & { endPos: number }\n}\n\n// Type 6 block-level tags - only the most common ones that matter in practice\n// Unknown tags default to type 7 (inline/non-interrupting) for safety\n// This is a pragmatic subset of the CommonMark spec's full list\nvar TYPE6_TAGS = [\n 'div',\n 'p',\n 'section',\n 'article',\n 'aside',\n 'nav',\n 'header',\n 'footer',\n 'main',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'blockquote',\n 'ul',\n 'ol',\n 'li',\n 'dl',\n 'dt',\n 'dd',\n 'table',\n 'thead',\n 'tbody',\n 'tfoot',\n 'tr',\n 'td',\n 'th',\n 'form',\n 'fieldset',\n 'hr',\n 'pre',\n 'details',\n 'summary',\n 'figure',\n 'figcaption',\n]\n\n// Type 1 block tags for fast lookup\nconst TYPE1_TAGS_SET = new Set(['pre', 'script', 'style', 'textarea'])\n\nfunction isType6Tag(tagName: string): boolean {\n return TYPE6_TAGS.indexOf(tagName.toLowerCase()) !== -1\n}\n\nexport function isType1Block(tagLower: string): boolean {\n return TYPE1_TAGS_SET.has(tagLower)\n}\n\nfunction isBlankLineCheck(\n source: string,\n lineStart: number,\n lineEnd: number\n): boolean {\n for (var i = lineStart; i < lineEnd; i++) {\n const code = charCode(source, i)\n if (code !== $.CHAR_SPACE && code !== $.CHAR_TAB && code !== $.CHAR_CR)\n return false\n }\n return true\n}\n\nfunction parseWithInlineMode<T>(\n state: MarkdownToJSX.State,\n inlineMode: boolean,\n parseFn: () => T\n): T {\n const originalInline = state.inline\n state.inline = inlineMode\n try {\n return parseFn()\n } finally {\n state.inline = originalInline\n }\n}\n\nfunction findNextBlankLine(\n source: string,\n startPos: number,\n sourceLen: number\n): number {\n var pos = startPos\n while (pos < sourceLen) {\n var nextLineEnd = util.findLineEnd(source, pos)\n if (isBlankLineCheck(source, pos, nextLineEnd)) return pos\n pos = nextLineEnd + (nextLineEnd < sourceLen ? 1 : 0)\n }\n return sourceLen\n}\n\nfunction createHTMLCommentResult(\n text: string,\n endPos: number,\n options?: { raw?: boolean; endsWithGreaterThan?: boolean }\n): MarkdownToJSX.HTMLCommentNode & {\n endPos: number\n raw?: boolean\n endsWithGreaterThan?: boolean\n} {\n return {\n type: RuleType.htmlComment,\n text,\n endPos,\n ...options,\n } as MarkdownToJSX.HTMLCommentNode & {\n endPos: number\n raw?: boolean\n endsWithGreaterThan?: boolean\n }\n}\n\nfunction createVerbatimHTMLBlock(\n tagName: string,\n text: string,\n endPos: number,\n attrs?: { [key: string]: any },\n rawAttrs?: string,\n isClosingTag?: boolean,\n canInterruptParagraph?: boolean,\n options?: ParseOptions\n): MarkdownToJSX.HTMLNode & {\n endPos: number\n isClosingTag?: boolean\n canInterruptParagraph?: boolean\n} {\n // Detect empty unclosed HTML tags when forceBlock is used to avoid infinite recursion\n // For empty unclosed tags like <var>, the text field contains the opening tag itself\n // When forceBlock is used, this would cause recursion if the tag is parsed again\n var finalText = text\n if (options && options.forceBlock && text && !isClosingTag) {\n var openingTagPattern = new RegExp(\n '^<' + tagName.toLowerCase() + '(\\\\s[^>]*)?>$',\n 'i'\n )\n if (openingTagPattern.test(text.trim())) {\n // Empty unclosed tag detected - render as empty element to avoid recursion\n finalText = ''\n }\n }\n return {\n type: RuleType.htmlBlock,\n tag: tagName as MarkdownToJSX.HTMLTags,\n attrs: attrs || {},\n rawAttrs: rawAttrs,\n children: [],\n text: finalText,\n noInnerParse: true,\n isClosingTag: isClosingTag,\n canInterruptParagraph: canInterruptParagraph,\n endPos: endPos,\n } as MarkdownToJSX.HTMLNode & {\n endPos: number\n isClosingTag?: boolean\n canInterruptParagraph?: boolean\n }\n}\n\n/**\n * Check if content contains block-worthy elements that should be parsed\n * (explicit block syntax or blank lines not inside type 1 HTML blocks)\n */\nfunction hasBlockContent(content: string): boolean {\n const hasExplicitBlockSyntax = BLOCK_SYNTAX_R.test(content)\n const hasBlankLines = DOUBLE_NEWLINE_R.test(content)\n const hasType1Tags = TYPE1_TAG_R.test(content)\n return hasExplicitBlockSyntax || (hasBlankLines && !hasType1Tags)\n}\n\nfunction processHTMLBlock(\n tagNameOriginal: string,\n tagName: string,\n attrs: string,\n content: string,\n fullMatch: string,\n endPos: number,\n source: string,\n state: MarkdownToJSX.State,\n parentInAnchor: boolean,\n options: ParseOptions\n): MarkdownToJSX.HTMLNode & { endPos: number } {\n // Apply block-level paragraph wrapping heuristics\n if (!state.inHTML && !state.inline && !util.endsWith(fullMatch, '\\n')) {\n let checkPos = endPos\n const sourceLen = source.length\n\n while (checkPos < sourceLen) {\n const lineEnd = util.findLineEnd(source, checkPos)\n if (isBlankLineCheck(source, checkPos, lineEnd)) break\n\n const line = source.slice(checkPos, lineEnd).trim()\n if (line.length > 0 && isBlockStartChar(line[0])) {\n const htmlResult = parseHTML(source, checkPos, state, options)\n if (htmlResult) {\n checkPos = htmlResult.endPos\n continue\n }\n const selfClosingMatch = parseHTMLTag(source, checkPos)\n if (selfClosingMatch) {\n checkPos = selfClosingMatch.endPos\n continue\n }\n return null\n }\n checkPos = skipToNextLine(source, lineEnd)\n }\n }\n\n const lowerTag = tagName\n const noInnerParse = isType1Block(lowerTag)\n\n // Per CommonMark spec: Type 6 blocks that end at blank lines should have verbatim content\n // Check if this is a type 6 block (block-level, not type 1, not void)\n var isType6Block = !noInnerParse && !util.isVoidElement(tagName)\n\n // Always extract raw attributes from fullMatch if available (for consistency)\n // Per CommonMark spec Example 153: newlines and spaces between attributes should be removed\n // (not converted to spaces) when rendering. Extract raw attributes so html() can handle this.\n var rawOpeningTag: string | undefined = undefined\n // Extract raw attributes from opening tag slice if fullMatch is available\n if (fullMatch) {\n // Find the closing > of the opening tag\n var openingTagEnd = fullMatch.indexOf('>')\n if (openingTagEnd !== -1) {\n var openingTagSlice = fullMatch.slice(0, openingTagEnd + 1)\n // Check if opening tag has newlines (for rawOpeningTag preservation)\n if (openingTagSlice.indexOf('\\n') !== -1) {\n rawOpeningTag = openingTagSlice\n }\n // Always extract raw attributes from the opening tag slice for consistency\n // Find the tag name end (after <div or <div/) - first whitespace or >\n var tagNameEnd = openingTagEnd\n for (var i = 1; i < openingTagEnd; i++) {\n var ch = openingTagSlice[i]\n if (ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '>') {\n tagNameEnd = i\n break\n }\n }\n // Extract attributes from after tag name to before >\n // Preserve leading whitespace for CommonMark compliance (Examples 615-616)\n attrs = openingTagSlice.slice(tagNameEnd, openingTagEnd)\n }\n }\n\n // Parse attributes, but always preserve raw attributes for consistency\n // Per CommonMark spec Example 153: newlines and spaces between attributes should be removed\n // (not converted to spaces) when rendering. Store raw attributes so html() can handle this.\n // Trim leading whitespace for parsing, but preserve full attrs (with whitespace) for rawAttrs\n var attrsTrimmed = attrs.replace(/^[\\s\\n\\r\\t]+/, '')\n var parsedAttributes = parseHTMLAttributes(\n attrsTrimmed,\n tagName,\n tagNameOriginal,\n options\n )\n var attributes: Record<string, any> = {\n ...parsedAttributes,\n }\n\n // For type 6 blocks, check if content ends with blank line or if there's no closing tag\n // Both cases mean content should be verbatim\n var endedAtBlankLine = false\n var hasClosingTagWithBlockSyntax = false\n if (isType6Block && content.length > 0) {\n // Check if there's a closing tag in the content - if so, extract content before it\n var closingTagPattern = '</' + lowerTag\n var closingTagIdx = content.indexOf(closingTagPattern)\n if (closingTagIdx >= 0) {\n var afterTag = closingTagIdx + closingTagPattern.length\n while (\n afterTag < content.length &&\n (content[afterTag] === ' ' || content[afterTag] === '\\t')\n )\n afterTag++\n if (afterTag < content.length && content[afterTag] === '>') {\n var contentBeforeClosingTag = content.slice(0, closingTagIdx)\n if (hasBlockContent(contentBeforeClosingTag)) {\n content = contentBeforeClosingTag\n hasClosingTagWithBlockSyntax = true\n } else {\n endedAtBlankLine = true\n }\n }\n }\n\n // If we didn't find a proper closing tag with block syntax, check if content ends with blank lines\n if (!hasClosingTagWithBlockSyntax) {\n // Check if content ends with blank line pattern (newline, optional whitespace, newline)\n var checkPos = content.length - 1\n // Skip trailing newline\n if (content[checkPos] === '\\n') {\n checkPos--\n // Skip whitespace\n while (\n checkPos >= 0 &&\n (content[checkPos] === ' ' ||\n content[checkPos] === '\\t' ||\n content[checkPos] === '\\r')\n ) {\n checkPos--\n }\n // If there's another newline before this, we have a blank line ending\n if (checkPos >= 0 && content[checkPos] === '\\n') {\n endedAtBlankLine = true\n }\n }\n }\n }\n\n // If type 6 block ended at blank line (or has no closing tag), treat content as verbatim (no parsing)\n // But if content has block-worthy content, parse it even if it ends with blank lines\n var shouldTreatAsVerbatim =\n noInnerParse ||\n (isType6Block && endedAtBlankLine && !hasBlockContent(content))\n\n if (shouldTreatAsVerbatim) {\n if (content.length > 0 && content[0] === '\\n') {\n content = content.slice(1)\n }\n if (content.length > 0 && content[content.length - 1] === '\\n') {\n content = content.slice(0, -1)\n }\n }\n\n const leftTrimMatch = content.match(/^([ \\t]*)/)\n const leftTrimAmount = leftTrimMatch ? leftTrimMatch[1] : ''\n const trimmer = new RegExp(\n `^${leftTrimAmount.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}`,\n 'gm'\n )\n const trimmed = content.replace(trimmer, '')\n\n const hasDoubleNewline = DOUBLE_NEWLINE_R.test(trimmed)\n const hasNonParagraphBlockSyntax = BLOCK_SYNTAX_R.test(trimmed)\n const isParagraphTag = lowerTag === 'p'\n // Check if content contains HTML tags - if so, parse as blocks for proper nesting\n const hasHTMLTags = HTML_BLOCK_ELEMENT_START_R.test(trimmed)\n const hasBlockSyntax = isParagraphTag\n ? hasDoubleNewline\n : hasDoubleNewline ||\n hasNonParagraphBlockSyntax ||\n (state.inHTML && hasHTMLTags)\n\n let children: MarkdownToJSX.ASTNode[] = []\n\n if (!shouldTreatAsVerbatim && trimmed) {\n // Parse as blocks when content contains HTML tags to ensure nested HTML is parsed correctly\n if (hasBlockSyntax || hasHTMLTags) {\n const blockState = {\n ...state,\n inline: false,\n inHTML: true,\n inAnchor: state.inAnchor || lowerTag === 'a',\n }\n children = parseBlocksInHTML(trimmed, blockState, options)\n } else {\n const childState = {\n ...state,\n inline: true,\n inAnchor: parentInAnchor || state.inAnchor || lowerTag === 'a',\n }\n children = parseInlineSpan(\n trimmed,\n 0,\n trimmed.length,\n childState,\n options\n )\n }\n }\n\n // For Type 1 blocks with raw opening tag HTML, store it in the text field\n // along with content, so html() can output it verbatim\n var finalText: string | undefined = undefined\n if (shouldTreatAsVerbatim) {\n if (rawOpeningTag !== undefined) {\n // Type 1 block with newlines in opening tag - preserve raw opening tag + content\n // Store the full raw HTML (opening tag + content) in text field\n // The closing tag will be added by html()\n finalText = rawOpeningTag + content\n } else {\n finalText = content\n }\n }\n\n return {\n type: RuleType.htmlBlock,\n tag: (shouldTreatAsVerbatim\n ? tagName\n : tagNameOriginal) as MarkdownToJSX.HTMLTags,\n attrs: attributes,\n rawAttrs: attrs,\n children,\n text: finalText,\n noInnerParse: shouldTreatAsVerbatim,\n canInterruptParagraph: true, // type 1-6 blocks can interrupt paragraphs\n endPos: endPos,\n } as MarkdownToJSX.HTMLNode & {\n endPos: number\n canInterruptParagraph?: boolean\n }\n}\n\nfunction parseHTML(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult {\n // Must start with '<'\n if (source[pos] !== '<') return null\n\n // Track attempt after cheap disqualifications but before expensive parsing work\n if (!state.inline) {}\n\n // Check for processing instructions, declarations, and comments first (before unified parser)\n if (pos + 1 < source.length) {\n if (source[pos + 1] === '?') {\n var piToken = scanRawHTML(source, pos)\n if (piToken && piToken.kind === 'pi') {\n return createHTMLCommentResult(piToken.text || '', piToken.endPos, {\n raw: true,\n })\n }\n } else if (source[pos + 1] === '!') {\n // Check for HTML comments (<!-- ... -->)\n if (pos + 3 < source.length && source.slice(pos, pos + 4) === '<!--') {\n if (state.inline) {} else {}\n var token = scanRawHTML(source, pos)\n if (token && token.kind === 'comment') {\n // Extract text content (strip <!-- and -->)\n var text = token.text || ''\n var endsWithGreaterThan = false\n if (text === '<!-->') {\n text = ''\n endsWithGreaterThan = true\n } else if (text === '<!--->') {\n text = '-'\n endsWithGreaterThan = true\n } else if (text.startsWith('<!--') && text.endsWith('-->')) {\n text = text.slice(4, -3)\n }\n // Track hit for inline mode (block mode hit tracking happens in parseMarkdown)\n if (state.inline) {}\n return createHTMLCommentResult(text, token.endPos, {\n endsWithGreaterThan,\n })\n }\n }\n var declToken = scanRawHTML(source, pos)\n if (\n declToken &&\n (declToken.kind === 'declaration' || declToken.kind === 'cdata')\n ) {\n return createHTMLCommentResult(declToken.text || '', declToken.endPos, {\n raw: true,\n })\n }\n }\n }\n\n // Check for space/newline after < (invalid HTML - should be escaped)\n if (pos + 1 < source.length) {\n const nextChar = source[pos + 1]\n if (\n nextChar === ' ' ||\n nextChar === '\\n' ||\n nextChar === '\\t' ||\n nextChar === '\\r'\n ) {\n return null\n }\n }\n\n // Check if this looks like an autolink before parsing as HTML\n var closeIdx = source.indexOf('>', pos + 1)\n if (closeIdx !== -1) {\n var contentBetween = source.slice(pos + 1, closeIdx)\n // Check for spaces - if found, might be failed autolink\n var hasSpace =\n contentBetween.indexOf(' ') !== -1 || contentBetween.indexOf('\\t') !== -1\n\n // Check for HTTP(S) URLs - these should be autolinks, not HTML tags\n if (\n !hasSpace &&\n (util.startsWith(contentBetween, 'http://') ||\n util.startsWith(contentBetween, 'https://'))\n ) {\n return null // This is an autolink, not an HTML tag\n }\n\n // Check for URI schemes (scheme:pattern) - no spaces\n if (!hasSpace && isValidUriScheme(contentBetween)) {\n return null // This is an autolink (URI scheme), not an HTML tag\n }\n }\n\n // Use unified parser\n var tagResult = parseHTMLTag(source, pos)\n\n // If parseHTMLTag returns null, it might be an incomplete tag\n // Handle incomplete/partial tags inline (previously handled by matchHTMLBlock)\n if (!tagResult && !state.inline) {\n // Check if we have < followed by a valid tag name (even without closing >)\n var sourceLen = source.length\n var firstLineEnd = util.findLineEnd(source, pos)\n var lineStart = pos\n // Skip up to 3 spaces of indentation (per spec)\n var indent = 0\n while (\n lineStart < firstLineEnd &&\n indent < 3 &&\n (source[lineStart] === ' ' || source[lineStart] === '\\t')\n ) {\n indent++\n lineStart++\n }\n if (lineStart >= firstLineEnd || source[lineStart] !== '<') return null\n\n // Try to parse tag name even if tag is incomplete\n // Only handle incomplete tags for block-level tags (type 6)\n // Non-block-level tags that parseHTMLTag can't parse are invalid, not incomplete\n if (lineStart + 1 < firstLineEnd) {\n var tagNameResult = parseHTMLTagName(source, lineStart + 1)\n if (tagNameResult) {\n var tagName = tagNameResult.tagName\n var isType6 = isType6Tag(tagName)\n // Only handle incomplete tags for block-level tags\n if (!isType6) {\n return null // Non-block-level tags that parseHTMLTag can't parse are invalid\n }\n // Find where the tag would end (end of line or before invalid char)\n var partialTagEnd = tagNameResult.nextPos\n var hasNewlineInTag = false\n var inQuotesPartial = false\n var quoteCharPartial = ''\n var checkEnd = firstLineEnd\n var foundClosingAngle = false\n // Check across multiple lines to find the end of the tag\n // Optimized: use indexOf to quickly find boundary characters\n while (checkEnd < sourceLen && !foundClosingAngle) {\n var advancedInInnerLoop = false\n while (partialTagEnd < checkEnd) {\n var c = source[partialTagEnd]\n if (inQuotesPartial) {\n if (c === quoteCharPartial) {\n inQuotesPartial = false\n quoteCharPartial = ''\n }\n if (c === '\\n' || c === '\\r') {\n hasNewlineInTag = true\n }\n partialTagEnd++\n advancedInInnerLoop = true\n } else if (c === '\"' || c === \"'\") {\n inQuotesPartial = true\n quoteCharPartial = c\n partialTagEnd++\n advancedInInnerLoop = true\n } else if (c === '\\n' || c === '\\r') {\n hasNewlineInTag = true\n partialTagEnd++\n advancedInInnerLoop = true\n var nextLineEnd = util.findLineEnd(source, partialTagEnd)\n if (nextLineEnd === partialTagEnd) break\n checkEnd = nextLineEnd\n } else if (c === '>') {\n partialTagEnd++\n foundClosingAngle = true\n break\n } else {\n partialTagEnd++\n advancedInInnerLoop = true\n }\n }\n if (foundClosingAngle) break\n if (!advancedInInnerLoop && partialTagEnd >= checkEnd) {\n var nextCheckEnd = util.findLineEnd(source, checkEnd + 1)\n if (nextCheckEnd <= checkEnd) break\n checkEnd = nextCheckEnd\n } else if (partialTagEnd >= checkEnd && checkEnd < sourceLen) {\n var nextCheckEnd = util.findLineEnd(source, checkEnd + 1)\n if (nextCheckEnd <= checkEnd) break\n checkEnd = nextCheckEnd\n } else {\n break\n }\n }\n // Only handle as incomplete tag if it has a newline (extends beyond first line)\n // OR if it extends to end of first line without closing >\n // If tag completes on first line with closing >, parseHTMLTag should have handled it\n if (!hasNewlineInTag && foundClosingAngle) {\n return null // Tag completes on first line but parseHTMLTag returned null - invalid, not incomplete\n }\n // Tag has newline - treat as incomplete and extend to end of first line if needed\n if (partialTagEnd >= firstLineEnd && firstLineEnd < sourceLen) {\n partialTagEnd = firstLineEnd\n }\n // Determine block type and find blank line\n var blockType: 'type6' | 'type7' = isType6 ? 'type6' : 'type7'\n var tagEnd = partialTagEnd\n var blockEnd = findNextBlankLine(source, firstLineEnd + 1, sourceLen)\n var blockContent = source.slice(tagEnd, blockEnd)\n var isClosingTag = pos + 1 < source.length && source[pos + 1] === '/'\n\n // For type 7 blocks with incomplete tags, preserve raw HTML\n if (blockType === 'type7' && blockContent.trim() === '') {\n var rawTagHTML = source.slice(pos, blockEnd)\n var tagLineEnd = util.findLineEnd(rawTagHTML, 0)\n if (tagLineEnd < rawTagHTML.length) tagLineEnd++\n var rawTag = rawTagHTML.slice(0, tagLineEnd)\n return createVerbatimHTMLBlock(\n tagName,\n rawTag,\n blockEnd,\n {},\n undefined,\n isClosingTag,\n false, // type 7 blocks cannot interrupt paragraphs\n options\n )\n }\n\n // For type 6/7 blocks with incomplete tags and content, preserve full raw HTML\n var fullRawHTML = source.slice(pos, blockEnd)\n return createVerbatimHTMLBlock(\n tagName,\n fullRawHTML,\n blockEnd,\n {},\n undefined,\n isClosingTag,\n blockType === 'type6', // type 6 can interrupt, type 7 cannot\n options\n )\n }\n }\n return null\n }\n\n if (!tagResult) return null\n\n // Per CommonMark spec: reject HTML tags that look like failed autolinks\n // Check if the content between < and > looks like a failed autolink\n // (HTTP(S) URLs with spaces are failed autolinks - checked above)\n if (closeIdx !== -1) {\n var contentBetweenCheck = source.slice(pos + 1, closeIdx)\n // If it starts with http:// or https:// but has spaces, it's a failed autolink\n if (\n (util.startsWith(contentBetweenCheck, 'http://') ||\n util.startsWith(contentBetweenCheck, 'https://')) &&\n (contentBetweenCheck.indexOf(' ') !== -1 ||\n contentBetweenCheck.indexOf('\\t') !== -1)\n ) {\n return null // Failed autolink - reject as HTML tag\n }\n }\n\n // If a tag name has a colon at position 1 (e.g., \"m:abc\"), it's trying to be an autolink\n // but the scheme is only 1 character (invalid). These should be escaped, not parsed as HTML.\n // Examples: <m:abc>, <x:foo> should be escaped as <m:abc>, <x:foo>\n var tagNameStart = pos + (tagResult.isClosing ? 2 : 1)\n if (tagNameStart < source.length) {\n var tagNameFirstChar = source[tagNameStart]\n var tagNameFirstCharCode = charCode(tagNameFirstChar)\n // Check if it starts with a letter\n if (\n (tagNameFirstCharCode >= 97 && tagNameFirstCharCode <= 122) ||\n (tagNameFirstCharCode >= 65 && tagNameFirstCharCode <= 90)\n ) {\n // Check if second character is a colon (making it a 1-char scheme, which is invalid)\n if (\n tagNameStart + 1 < source.length &&\n source[tagNameStart + 1] === ':'\n ) {\n // This looks like a failed autolink attempt - reject as HTML tag\n return null\n }\n }\n }\n\n // Handle closing tags\n if (tagResult.isClosing) {\n // Per CommonMark: closing tags cannot have attributes\n // If attrs is not empty (after trimming whitespace), it's invalid HTML - escape it\n var attrsTrimmed = tagResult.attrs.trim()\n if (attrsTrimmed.length > 0) {\n // Invalid closing tag with attributes - return null to allow escaping\n return null\n }\n\n // Per CommonMark spec: closing tags are type 7 HTML blocks\n // Parse as block if: (1) on its own line, or (2) followed by a block-level HTML tag\n // Per Example 148: </td></tr></table> should be block-level\n // Per Example 623: </a></foo > should be inline (wrapped in paragraph)\n if (!state.inline) {\n var sourceLen = source.length\n var firstLineEnd = util.findLineEnd(source, pos)\n var tagEnd = tagResult.endPos\n\n // Check if tag is on its own line or followed by a block-level HTML tag\n var afterTag = tagEnd\n while (\n afterTag < firstLineEnd &&\n (source[afterTag] === ' ' ||\n source[afterTag] === '\\t' ||\n source[afterTag] === '\\r')\n ) {\n afterTag++\n }\n\n var shouldParseAsBlock =\n afterTag >= firstLineEnd ||\n (source[afterTag] === '<' &&\n (function () {\n var nextTag = parseHTMLTag(source, afterTag)\n return nextTag && isType6Tag(nextTag.tagLower)\n })())\n\n if (shouldParseAsBlock) {\n var blockEnd = findNextBlankLine(source, firstLineEnd + 1, sourceLen)\n var blockContent = source.slice(tagEnd, blockEnd)\n if (blockContent.length > 0 && blockContent[0] === '\\n') {\n blockContent = blockContent.slice(1)\n }\n\n // Cache lowercase tag name to avoid repeated toLowerCase() calls\n const tagLower = tagResult.tagLower || tagResult.tagName.toLowerCase()\n return createVerbatimHTMLBlock(\n tagResult.tagName,\n blockContent,\n blockEnd,\n parseHTMLAttributes(\n tagResult.whitespaceBeforeAttrs + tagResult.attrs,\n tagLower,\n tagResult.tagName,\n options\n ),\n tagResult.whitespaceBeforeAttrs + tagResult.attrs,\n true,\n false\n )\n }\n }\n\n // Fallback: for inline context or if block parsing didn't match, parse as self-closing\n // Per CommonMark spec Example 623: closing tags should preserve raw HTML to maintain spacing (e.g., </foo >)\n // Always preserve rawText for closing tags (both inline and block level) so they can be rendered correctly\n var rawText = source.slice(pos, tagResult.endPos)\n const result: MarkdownToJSX.HTMLSelfClosingNode & {\n endPos: number\n isClosingTag?: boolean\n rawText?: string\n } = {\n type: RuleType.htmlSelfClosing,\n tag: tagResult.tagName,\n attrs: {},\n endPos: tagResult.endPos,\n isClosingTag: true,\n rawText: rawText,\n }\n return result\n }\n\n // Now use unified parser result\n // tagResult already contains parsed tag info\n\n // IMPORTANT: All validation must happen BEFORE block parsing check\n // This ensures invalid tags are rejected even if they would match as blocks\n\n // Validate tag name: cannot start with space or newline after <\n // Per CommonMark spec Example 621: < a> and <\\nfoo> are invalid\n var tagNameStart = pos + (tagResult.isClosing ? 2 : 1)\n if (tagNameStart < source.length) {\n var firstChar = source[tagNameStart]\n if (\n firstChar === ' ' ||\n firstChar === '\\t' ||\n firstChar === '\\n' ||\n firstChar === '\\r'\n ) {\n // Tag name starts with whitespace - invalid HTML\n return null\n }\n }\n\n // Attributes are passed through opaquely - no validation\n\n var tagNameLower = tagResult.tagLower\n var isVoid = util.isVoidElement(tagResult.tagName)\n\n // Check if this is a JSX component (starts with uppercase letter)\n // JSX components should be parsed as block-level HTML even with newlines\n const isJSXComponent =\n tagResult.tagName.length > 0 &&\n tagResult.tagName[0] >= 'A' &&\n tagResult.tagName[0] <= 'Z'\n\n // Self-closing tags: has /> or is void (except anchor tags which need special handling)\n // Per CommonMark spec: self-closing tags with newlines are type 7 blocks\n // Type 7 blocks don't interrupt paragraphs, so they should be parsed as inline HTML\n // IMPORTANT: Validation already happened above, so if we get here the tag is valid\n // EXCEPTION: JSX components (uppercase tags) should always be parsed as block-level HTML\n if (tagResult.isSelfClosing || (isVoid && tagNameLower !== 'a')) {\n // If tag has newline, it's a type 7 block - don't interrupt paragraphs\n // Return null to allow paragraph wrapping - parseInlineSpan will parse as raw HTML\n // But only if validation passed (which already happened above)\n // EXCEPTION: JSX components should be parsed as block-level HTML even with newlines\n if (tagResult.hasNewline && !isJSXComponent) {\n return null\n }\n\n // If we're not in HTML block context and not inline, parse as inline HTML\n // This allows them to be wrapped in paragraphs per type 7 block rules\n // Return null to allow paragraph wrapping - parseInlineSpan will parse them as raw HTML\n // EXCEPTION: JSX components should be parsed as block-level HTML even when not in HTML block context\n if (!state.inHTML && !state.inline && !isJSXComponent) {\n return null\n }\n\n var attrsTrimmedSelfClose = tagResult.attrs.replace(/\\/\\s*$/, '')\n var selfCloseAttrs = parseHTMLAttributes(\n attrsTrimmedSelfClose,\n tagNameLower,\n tagResult.tagName,\n options\n )\n // For inline context, preserve raw HTML to maintain spacing\n var rawText = state.inline ? source.slice(pos, tagResult.endPos) : undefined\n const result: MarkdownToJSX.HTMLSelfClosingNode & {\n endPos: number\n rawText?: string\n } = {\n type: RuleType.htmlSelfClosing,\n tag: tagResult.tagName,\n attrs: selfCloseAttrs,\n endPos: tagResult.endPos,\n }\n if (rawText !== undefined) {\n result.rawText = rawText\n }\n return result\n }\n\n // For inline context, parse as simple opening tag (no closing tag search)\n // IMPORTANT: Validation must happen before this check to reject invalid tags\n // Note: parseHTMLTag only returns a result if tag has closing >, so tag is complete\n // Multiline attributes are supported - newlines in tags are valid HTML\n if (state.inline) {\n // Validation already happened above, so if we get here the tag is valid\n var attrsTrimmedInline = tagResult.attrs.replace(/\\/\\s*$/, '')\n // Preserve whitespace before attributes for CommonMark compliance\n var rawAttrsWithWhitespace =\n tagResult.whitespaceBeforeAttrs + attrsTrimmedInline\n var parsedInlineAttrs = parseHTMLAttributes(\n attrsTrimmedInline,\n tagNameLower,\n tagResult.tagName,\n options\n )\n var inlineAttrs: Record<string, any> = {\n ...parsedInlineAttrs,\n }\n\n // For non-void inline tags, find matching closing tag and parse content\n var inlineEndPos = tagResult.endPos\n var children: MarkdownToJSX.ASTNode[] = []\n if (!util.isVoidElement(tagResult.tagName)) {\n var closingResult = findInlineClosingTag(\n source,\n tagResult.endPos,\n tagNameLower\n )\n if (closingResult !== null) {\n var content = source.slice(tagResult.endPos, closingResult[0])\n if (content) {\n if (\n (state.inHTML && HTML_BLOCK_ELEMENT_START_R.test(content)) ||\n hasBlockContent(content)\n ) {\n children = parseBlocksInHTML(\n content,\n {\n ...state,\n inline: false,\n inHTML: true,\n inAnchor: state.inAnchor || tagNameLower === 'a',\n },\n options\n )\n } else {\n children = parseInlineSpan(\n content,\n 0,\n content.length,\n {\n ...state,\n inline: true,\n inAnchor: state.inAnchor || tagNameLower === 'a',\n },\n options\n )\n }\n }\n inlineEndPos = closingResult[1]\n }\n }\n return {\n type: RuleType.htmlBlock,\n tag: tagResult.tagName as MarkdownToJSX.HTMLTags,\n attrs: inlineAttrs,\n rawAttrs: rawAttrsWithWhitespace,\n children: children,\n noInnerParse: false,\n endPos: inlineEndPos,\n } as MarkdownToJSX.HTMLNode & { endPos: number }\n }\n\n // For inline context, don't try block parsing - simple opening tags should be parsed inline\n // Block parsing is only for tags that need closing tags or are block-level\n if (!state.inline) {\n // Determine block type inline (previously handled by matchHTMLBlock)\n var sourceLen = source.length\n var firstLineEnd = util.findLineEnd(source, pos)\n var tagLower = tagResult.tagLower\n var isType1BlockVar = isType1Block(tagLower)\n var isType6Block = !isType1BlockVar && isType6Tag(tagResult.tagName)\n var tagHasClosingAngle = false\n var checkPos = pos\n while (checkPos < tagResult.endPos) {\n if (source[checkPos] === '>') {\n tagHasClosingAngle = true\n break\n }\n checkPos++\n }\n // Check if tag is followed by end of line (with optional whitespace)\n var afterTag = tagResult.endPos\n while (\n afterTag < firstLineEnd &&\n (source[afterTag] === ' ' || source[afterTag] === '\\t')\n ) {\n afterTag++\n }\n // Check if tag is complete on line\n // For type 6 blocks, they can have content on same line\n // For other tags, they must be followed by newline or end of line\n var isCompleteOnLine =\n afterTag >= firstLineEnd ||\n source[afterTag] === '\\n' ||\n source[afterTag] === '\\r' ||\n (isType6Block && afterTag < firstLineEnd) ||\n !tagHasClosingAngle\n\n // Type 1 blocks (pre, script, style, textarea) need matching closing tags\n // Handle type 1 blocks even if they have newlines in the opening tag\n if (isType1BlockVar && tagHasClosingAngle && !tagResult.isClosing) {\n // Type 1: find matching closing tag\n var type1TagName = tagResult.tagName\n var type1TagEnd = tagResult.endPos\n var type1Attrs = tagResult.attrs\n var type1ContentPos = type1TagEnd\n if (source[type1ContentPos] === '\\n') type1ContentPos++\n var type1ContentStart = type1ContentPos\n var type1ContentEnd = type1ContentPos\n var type1Depth = 1\n var type1OpenTagLen = tagLower.length + 1\n while (type1Depth > 0) {\n var type1Idx = source.indexOf('<', type1ContentPos)\n if (type1Idx === -1) {\n type1ContentEnd = sourceLen\n type1ContentPos = sourceLen\n break\n }\n var type1OpenIdx = -1\n var type1CloseIdx = -1\n if (source[type1Idx + 1] === '/') {\n type1CloseIdx = type1Idx\n } else if (\n type1Idx + type1OpenTagLen + 1 <= sourceLen &&\n (source[type1Idx + 1] === tagLower[0] ||\n source[type1Idx + 1] === type1TagName[0])\n ) {\n var type1TagCandidate = source.substring(\n type1Idx + 1,\n type1Idx + type1OpenTagLen\n )\n if (\n type1TagCandidate.toLowerCase() === tagLower &&\n (source[type1Idx + type1OpenTagLen] === ' ' ||\n source[type1Idx + type1OpenTagLen] === '>')\n ) {\n type1OpenIdx = type1Idx\n }\n }\n if (type1OpenIdx === -1 && type1CloseIdx === -1) {\n type1ContentPos = type1Idx + 1\n continue\n }\n if (\n type1OpenIdx !== -1 &&\n (type1CloseIdx === -1 || type1OpenIdx < type1CloseIdx)\n ) {\n type1ContentPos = type1OpenIdx + type1OpenTagLen + 1\n type1Depth++\n } else {\n var type1P = type1CloseIdx + 2\n while (type1P < sourceLen) {\n var type1C = source[type1P]\n if (\n type1C !== ' ' &&\n type1C !== '\\t' &&\n type1C !== '\\n' &&\n type1C !== '\\r'\n )\n break\n type1P++\n }\n if (type1P + tagLower.length > sourceLen) break\n var type1CloseTagCandidate = source.substring(\n type1P,\n type1P + tagLower.length\n )\n if (type1CloseTagCandidate.toLowerCase() !== tagLower) {\n type1ContentPos = type1P\n continue\n }\n type1P += tagLower.length\n while (type1P < sourceLen) {\n var type1C2 = source[type1P]\n if (\n type1C2 !== ' ' &&\n type1C2 !== '\\t' &&\n type1C2 !== '\\n' &&\n type1C2 !== '\\r'\n )\n break\n type1P++\n }\n if (type1P >= sourceLen || source[type1P] !== '>') {\n type1ContentPos = type1P\n continue\n }\n var type1ClosingTagEnd = type1P + 1\n var type1LineEndAfterClose = util.findLineEnd(\n source,\n type1ClosingTagEnd\n )\n type1ContentEnd = type1LineEndAfterClose\n type1ContentPos = type1LineEndAfterClose + 1\n type1Depth--\n }\n }\n var type1TrailingNl = 0\n while (\n type1ContentPos + type1TrailingNl < sourceLen &&\n source[type1ContentPos + type1TrailingNl] === '\\n'\n )\n type1TrailingNl++\n var type1FullMatch = source.slice(pos, type1ContentPos + type1TrailingNl)\n var type1Content = source.slice(type1ContentStart, type1ContentEnd)\n var type1EndPos = type1ContentPos + type1TrailingNl\n return processHTMLBlock(\n tagResult.tagName,\n tagResult.tagName,\n type1Attrs,\n type1Content,\n type1FullMatch,\n type1EndPos,\n source,\n state,\n false,\n options\n )\n }\n\n // Type 6/7 blocks end at blank lines\n if (isCompleteOnLine || !tagHasClosingAngle) {\n // Determine if type 6 or type 7\n var blockType: 'type6' | 'type7' = isType6Block ? 'type6' : 'type7'\n var tagEnd = tagResult.endPos\n var blockEnd = findNextBlankLine(source, firstLineEnd + 1, sourceLen)\n\n // For type 6 blocks, check if there's a closing tag (even beyond the blank line)\n // If there is AND there's markdown syntax, extend to include the closing tag\n // Exception: for JSX compilation, always extend if there's a closing tag (to keep HTML blocks containing <pre> intact)\n if (blockType === 'type6' && !tagResult.isClosing) {\n // Use cached tagLower from parseHTMLTag result\n const tagLowerForClosing =\n tagResult.tagLower || tagResult.tagName.toLowerCase()\n var closingTagPattern = '</' + tagLowerForClosing\n var closingIdx = source.indexOf(closingTagPattern, tagEnd)\n if (closingIdx !== -1) {\n // Found a closing tag\n // Check if it's valid\n var afterClosingTag = closingIdx + closingTagPattern.length\n while (\n afterClosingTag < sourceLen &&\n (source[afterClosingTag] === ' ' ||\n source[afterClosingTag] === '\\t')\n ) {\n afterClosingTag++\n }\n if (afterClosingTag < sourceLen && source[afterClosingTag] === '>') {\n // Valid closing tag found\n var extendedContent = source.slice(tagEnd, closingIdx)\n var shouldExtend = hasBlockContent(extendedContent)\n if (shouldExtend) {\n // Extend block to include closing tag\n var closingLineEnd = util.findLineEnd(source, afterClosingTag + 1)\n blockEnd = closingLineEnd\n }\n }\n }\n }\n\n var blockContent = source.slice(tagEnd, blockEnd)\n var blockAttrs = tagResult.whitespaceBeforeAttrs + tagResult.attrs\n var isClosingTag = tagResult.isClosing\n\n // Handle type 6/7 blocks\n // For type 7 blocks with empty content (standalone tags), determine if they should be block or inline\n // Per CommonMark: Type 7 blocks cannot interrupt paragraphs, but if they're on their own line they're blocks\n // However, if the tag contains newlines in attributes (without hasNewline flag because they're in quotes),\n // it should be treated as inline and wrapped in a paragraph\n if (blockType === 'type7' && blockContent.trim() === '') {\n // Check if the tag itself contains a newline (inside the tag, not after it)\n var rawTagText = source.slice(pos, tagResult.endPos)\n var tagContainsNewline = rawTagText.indexOf('\\n') !== -1\n\n if (tagContainsNewline) {\n // Tag has newline inside it (in attribute) - should be wrapped in paragraph\n return null\n }\n\n // Tag is on its own line, treat as block\n var tagEndInSource = tagResult.endPos\n var tagLineEnd = util.findLineEnd(source, tagEndInSource)\n if (tagLineEnd < source.length) tagLineEnd++\n var rawTag = source.slice(pos, tagLineEnd)\n return createVerbatimHTMLBlock(\n tagResult.tagName,\n rawTag,\n blockEnd,\n {},\n undefined,\n isClosingTag,\n false, // type 7 blocks cannot interrupt paragraphs\n options\n )\n }\n\n // For type 7 blocks with multi-line or incomplete opening tags, preserve raw HTML\n var openingTagHasNewline = tagResult.hasNewline\n var openingTagIsIncomplete = !tagHasClosingAngle\n if (\n (openingTagHasNewline || openingTagIsIncomplete) &&\n blockType === 'type7'\n ) {\n var openingTagEnd = tagResult.endPos\n var rawOpeningTag = source.slice(pos, openingTagEnd)\n var rawContent = blockContent\n var fullRawHTML = rawOpeningTag + rawContent\n return createVerbatimHTMLBlock(\n tagResult.tagName,\n fullRawHTML,\n blockEnd,\n {},\n undefined,\n isClosingTag,\n false, // type 7 blocks cannot interrupt paragraphs\n options\n )\n }\n\n // Parse attributes, but always preserve raw attributes for consistency\n // Cache lowercase tag name to avoid repeated toLowerCase() calls\n const tagLower = tagResult.tagLower || tagResult.tagName.toLowerCase()\n var parsedBlockAttributes = parseHTMLAttributes(\n blockAttrs,\n tagLower,\n tagResult.tagName,\n options\n )\n var blockAttributes: Record<string, any> = {\n ...parsedBlockAttributes,\n }\n\n // For type 6 blocks with block syntax, parse through processHTMLBlock\n if (blockType === 'type6') {\n var contentForBlockCheck = blockContent\n var closingTagIdx = blockContent.indexOf('</' + tagLower)\n if (closingTagIdx >= 0) {\n var afterTag = closingTagIdx + 2 + tagResult.tagName.length\n while (\n afterTag < blockContent.length &&\n (blockContent[afterTag] === ' ' || blockContent[afterTag] === '\\t')\n )\n afterTag++\n if (\n afterTag < blockContent.length &&\n blockContent[afterTag] === '>'\n ) {\n contentForBlockCheck = blockContent.slice(0, closingTagIdx)\n }\n }\n\n if (hasBlockContent(contentForBlockCheck)) {\n return processHTMLBlock(\n tagResult.tagName,\n tagResult.tagName,\n blockAttrs,\n contentForBlockCheck,\n source.slice(pos, tagResult.endPos),\n blockEnd,\n source,\n state,\n false,\n options\n )\n }\n }\n\n // For type 6 and type 7 blocks, content is verbatim (raw HTML)\n // Content includes everything from after the opening tag to the blank line\n // Remove leading newline if present\n var verbatimContent = blockContent\n if (verbatimContent.length > 0 && verbatimContent[0] === '\\n') {\n verbatimContent = verbatimContent.slice(1)\n }\n // Per CommonMark spec: remove common leading whitespace from all lines\n var lines = verbatimContent.split('\\n')\n var minIndent = Infinity\n for (var lineIdx = 0; lineIdx < lines.length; lineIdx++) {\n var line = lines[lineIdx]\n if (line.trim().length === 0) continue\n var indent = 0\n while (\n indent < line.length &&\n (line[indent] === ' ' || line[indent] === '\\t')\n ) {\n indent++\n }\n if (indent < minIndent) minIndent = indent\n }\n if (minIndent > 0 && minIndent < Infinity) {\n var dedentedLines: string[] = []\n for (var lineIdx2 = 0; lineIdx2 < lines.length; lineIdx2++) {\n var line2 = lines[lineIdx2]\n if (line2.trim().length === 0) {\n dedentedLines.push(line2)\n } else {\n dedentedLines.push(line2.slice(minIndent))\n }\n }\n verbatimContent = dedentedLines.join('\\n')\n }\n\n return createVerbatimHTMLBlock(\n tagResult.tagName,\n verbatimContent,\n blockEnd,\n blockAttributes,\n blockAttrs,\n isClosingTag,\n blockType === 'type6' ? true : false, // type 6 can interrupt, type 7 cannot\n options\n )\n }\n }\n\n // If we're in inline context and didn't match simple tag parsing, return null\n // This allows the tag to be escaped or handled by other parsers\n if (state.inline) {\n return null\n }\n\n // Fallback: Try void element without /> (manual parsing)\n // Only try this if self-closing didn't match\n var tagNameResult = parseHTMLTagName(source, pos + 1)\n if (!tagNameResult) return null\n\n var tagName = tagNameResult.tagName\n if (!util.isVoidElement(tagName)) {\n return null\n }\n\n // Use tagLower from parseHTMLTagName result to avoid repeated toLowerCase() calls\n const tagLowerVoid = tagNameResult.tagLower\n\n var i = tagNameResult.nextPos\n var len = source.length\n while (i < len && isSpaceOrTab(source[i])) i++\n var attrsStart = i\n\n while (i < len && source[i] !== '>') i++\n if (i >= len) return null\n\n const attrs = source.slice(attrsStart, i).trim()\n const afterAngle = i + 1\n\n let checkIdx = afterAngle\n while (checkIdx < len && isSpaceOrTab(source[checkIdx])) checkIdx++\n const closeTagPattern = '</' + tagLowerVoid + '>'\n const foundIdx = source.toLowerCase().indexOf(closeTagPattern, checkIdx)\n if (foundIdx !== -1) {\n const between = source.slice(checkIdx, foundIdx).trim()\n if (between) {\n return null\n }\n }\n\n i++\n const endPos = i\n while (i < len && isSpaceOrTab(source[i])) i++\n if (i < len && source[i] === '\\n') i++\n\n const fallbackAttributes = parseHTMLAttributes(\n attrs,\n tagName,\n tagName,\n options\n )\n\n return {\n type: RuleType.htmlSelfClosing,\n tag: tagName,\n attrs: fallbackAttributes,\n endPos,\n } as MarkdownToJSX.HTMLSelfClosingNode & { endPos: number }\n}\n\n// ============================================================================\n// HTML Token Interface and Unified Scanner\n// Ultra-compact unified scanner for all HTML constructs\n// ============================================================================\n\nexport interface HTMLToken {\n kind: 'tag' | 'comment' | 'pi' | 'declaration' | 'cdata'\n tagNameLower?: string\n tagName?: string\n isClosing?: boolean\n isSelfClosing?: boolean\n hasNewline: boolean\n type6Candidate?: boolean\n type7Candidate?: boolean\n endPos: number\n attrs?: string\n whitespaceBeforeAttrs?: string\n text?: string\n raw?: boolean\n}\n\n/**\n * Scan tag-like constructs: </tag, <tag\n */\nfunction scanTagLike(source: string, pos: number): HTMLToken | null {\n if (source[pos] !== '<') return null\n\n var sourceLen = source.length\n\n // Check for closing tag (</tag>)\n var isClosing = false\n var tagStart = pos + 1\n if (pos + 1 < sourceLen && source[pos + 1] === '/') {\n isClosing = true\n tagStart = pos + 2\n }\n\n // Parse tag name\n var tagNameResult = parseHTMLTagName(source, tagStart)\n if (!tagNameResult) return null\n\n var tagName = tagNameResult.tagName\n var tagLower = tagNameResult.tagLower\n var attrsStart = tagNameResult.nextPos\n\n // Fast path: tags without attributes or whitespace\n if (attrsStart < sourceLen) {\n var immediateChar = source[attrsStart]\n if (immediateChar === '>' || immediateChar === '/') {\n var endPos = immediateChar === '>' ? attrsStart + 1 : attrsStart + 2\n if (\n immediateChar === '/' &&\n (attrsStart + 1 >= sourceLen || source[attrsStart + 1] !== '>')\n ) {\n return null\n }\n var isSelfClosingFast = immediateChar === '/'\n var type6CandidateFast = isType6Tag(tagName)\n var type7CandidateFast = !isType1Block(tagLower) && !type6CandidateFast\n return {\n kind: 'tag',\n tagNameLower: tagLower,\n tagName: tagName,\n isClosing: isClosing,\n isSelfClosing: isSelfClosingFast,\n hasNewline: false,\n type6Candidate: type6CandidateFast,\n type7Candidate: type7CandidateFast,\n endPos: endPos,\n attrs: '',\n whitespaceBeforeAttrs: '',\n }\n }\n }\n\n // Capture whitespace after tag name (including newlines per CommonMark spec)\n var whitespaceStart = attrsStart\n var hasNewline = false\n while (attrsStart < sourceLen) {\n var ch = source[attrsStart]\n var code = charCode(source, attrsStart)\n if (ch === ' ' || ch === '\\t') {\n // Space or tab - continue\n } else if (code === 10 || code === 13) {\n // \\n or \\r\n hasNewline = true\n } else {\n break // Not whitespace\n }\n attrsStart++\n }\n var whitespaceBeforeAttrs = source.slice(whitespaceStart, attrsStart)\n\n // Parse attributes until we find > - minimal validation only for boundary detection\n var tagEnd = attrsStart\n var inQuotes = false\n var quoteChar = ''\n var braceDepth = 0\n var hasSlash = false\n var hasSpaceBeforeSlash = false\n\n // State machine for attribute parsing: 0=normal, 1=inDoubleQuotes, 2=inSingleQuotes\n var parseState = 0\n while (tagEnd < sourceLen) {\n var char = source[tagEnd]\n var code = charCode(source, tagEnd)\n\n // Handle quotes state machine\n if (parseState === 1) {\n // in double quotes\n if (char === '\"') {\n // Check for consecutive quotes (invalid HTML)\n if (tagEnd + 1 < sourceLen && source[tagEnd + 1] === '\"') {\n return null\n }\n parseState = 0\n }\n tagEnd++\n } else if (parseState === 2) {\n // in single quotes\n if (char === \"'\") {\n parseState = 0\n }\n tagEnd++\n } else if (char === '\"') {\n parseState = 1\n tagEnd++\n } else if (char === \"'\") {\n parseState = 2\n tagEnd++\n } else if (char === '{' || (char === '}' && braceDepth > 0)) {\n // Track JSX expression brace depth\n braceDepth += char === '{' ? 1 : -1\n tagEnd++\n } else if (char === '>' && braceDepth === 0) {\n // Found closing > - check for self-closing / and space before >\n if (tagEnd > attrsStart) {\n var checkBack = tagEnd - 1\n while (checkBack >= attrsStart) {\n var backChar = source[checkBack]\n if (backChar !== ' ' && backChar !== '\\t') break\n checkBack--\n }\n if (checkBack >= attrsStart && source[checkBack] === '/') {\n hasSlash = true\n hasSpaceBeforeSlash = checkBack < tagEnd - 1\n }\n }\n tagEnd++\n break\n } else {\n // Check for invalid attribute name characters (*, #, !)\n if (char === '*' || char === '#' || char === '!') {\n var checkAhead = tagEnd + 1\n while (checkAhead < sourceLen) {\n var aheadChar = source[checkAhead]\n if (\n aheadChar === '=' ||\n aheadChar === ' ' ||\n aheadChar === '\\t' ||\n aheadChar === '\\n' ||\n aheadChar === '\\r' ||\n aheadChar === '>'\n ) {\n break\n }\n checkAhead++\n }\n if (checkAhead < sourceLen && source[checkAhead] === '=') {\n return null // Invalid char in attribute name\n }\n }\n // Track newlines\n if (code === 10 || code === 13) {\n // \\n or \\r\n hasNewline = true\n }\n tagEnd++\n }\n }\n\n // Must have found >\n if (tagEnd > sourceLen || source[tagEnd - 1] !== '>') {\n return null\n }\n\n // Reject tags with unclosed quotes\n if (parseState === 1 || parseState === 2) {\n return null\n }\n\n // Reject tags with unclosed JSX expressions\n if (braceDepth > 0) {\n return null\n }\n\n // Reject tags with space between / and > (invalid HTML structure)\n if (hasSpaceBeforeSlash) {\n return null\n }\n\n var attrsEnd = tagEnd - 1\n if (hasSlash) {\n // For self-closing tags, exclude the / from attrs\n attrsEnd--\n }\n var attrs = source.slice(attrsStart, attrsEnd)\n var isSelfClosing = hasSlash\n\n // Minimal validation: reject missing space after quoted attribute value\n var lastQuotePos = -1\n var inQuotesCheck = false\n var quoteCharCheck = ''\n var afterEquals = false\n for (var i = 0; i < attrs.length; i++) {\n var ch = attrs[i]\n if (inQuotesCheck) {\n if (ch === quoteCharCheck) {\n inQuotesCheck = false\n lastQuotePos = i\n quoteCharCheck = ''\n afterEquals = false\n }\n } else if (ch === '\"' || ch === \"'\") {\n inQuotesCheck = true\n quoteCharCheck = ch\n afterEquals = false\n } else if (ch === '=') {\n afterEquals = true\n } else if (lastQuotePos !== -1 && i === lastQuotePos + 1) {\n // Immediately after closing quote\n var code = ch.charCodeAt(0)\n if (isAlphaCode(code)) {\n // Letter immediately after quote - missing space, reject\n return null\n }\n } else if (\n afterEquals &&\n !inQuotesCheck &&\n (ch === '*' || ch === '#' || ch === '!')\n ) {\n // Invalid char in unquoted attribute value - reject\n return null\n } else if (isSpaceOrTab(ch)) {\n afterEquals = false\n }\n }\n\n // Determine type 6/7 candidates\n var type6Candidate = isType6Tag(tagName)\n var type7Candidate = !isType1Block(tagLower) && !type6Candidate\n\n return {\n kind: 'tag',\n tagNameLower: tagLower,\n tagName: tagName,\n isClosing: isClosing,\n isSelfClosing: isSelfClosing,\n hasNewline: hasNewline,\n type6Candidate: type6Candidate,\n type7Candidate: type7Candidate,\n endPos: tagEnd,\n attrs: attrs,\n whitespaceBeforeAttrs: whitespaceBeforeAttrs,\n }\n}\n\n// ============================================================================\n// Unified HTML Scanner\n// Ultra-compact unified scanner for all HTML constructs\n// ============================================================================\n\n/**\n * Unified HTML scanner - handles tags, comments, PIs, declarations, CDATA\n * Ultra-compact implementation tuned for minification\n */\nfunction scanRawHTML(s: string, p: number): HTMLToken | null {\n if (p >= s.length || s[p] !== '<') return null\n var l = s.length\n if (p + 1 >= l) return null\n var c = s[p + 1]\n if (c === '!') {\n if (p + 4 <= l && s.slice(p, p + 4) === '<!--') {\n // Comment: scan for -->\n var endPos = p + 4\n if (endPos < l && s[endPos] === '>') {\n return {\n kind: 'comment',\n hasNewline: false,\n endPos: endPos + 1,\n text: s.slice(p, endPos + 1),\n raw: true,\n }\n }\n if (endPos + 1 < l && s[endPos] === '-' && s[endPos + 1] === '>') {\n return {\n kind: 'comment',\n hasNewline: false,\n endPos: endPos + 2,\n text: s.slice(p, endPos + 2),\n raw: true,\n }\n }\n while (endPos + 2 < l) {\n if (s.slice(endPos, endPos + 3) === '-->') {\n return {\n kind: 'comment',\n hasNewline: false,\n endPos: endPos + 3,\n text: s.slice(p, endPos + 3),\n raw: true,\n }\n }\n endPos++\n }\n return null\n }\n if (p + 9 <= l && s.slice(p, p + 9) === '<![CDATA[') {\n // CDATA: scan for ]]>\n var endPos = p + 9\n while (endPos + 2 < l) {\n if (s.slice(endPos, endPos + 3) === ']]>') {\n return {\n kind: 'cdata',\n hasNewline: false,\n endPos: endPos + 3,\n text: s.slice(p, endPos + 3),\n raw: true,\n }\n }\n endPos++\n }\n return null\n }\n if (p + 2 < l && isAlphaCode(s.charCodeAt(p + 2))) {\n // Declaration: scan for >\n var endPos = p + 2\n while (endPos < l && s[endPos] !== '>') endPos++\n if (endPos >= l) return null\n return {\n kind: 'declaration',\n hasNewline: false,\n endPos: endPos + 1,\n text: s.slice(p, endPos + 1),\n raw: true,\n }\n }\n return null\n }\n if (c === '?') {\n // Processing instruction: scan for ?>\n var endPos = p + 2\n while (endPos + 1 < l) {\n if (s.slice(endPos, endPos + 2) === '?>') {\n return {\n kind: 'pi',\n hasNewline: false,\n endPos: endPos + 2,\n text: s.slice(p, endPos + 2),\n raw: true,\n }\n }\n endPos++\n }\n return null\n }\n return scanTagLike(s, p)\n}\n\ninterface DefinitionParseResult {\n endPos: number\n target: string\n title?: string\n}\n\nfunction parseRefContent(\n source: string,\n pos: number,\n urlNewlineCount: number\n): DefinitionParseResult | null {\n const len = source.length\n let i = pos\n\n // Parse URL (can be in angle brackets or plain, can span multiple lines)\n // At this point, i should be at the start of the destination (after any whitespace/newline)\n // Per CommonMark spec: destination can be on the same line or following lines\n const hasAngleBrackets = i < len && source[i] === '<'\n if (hasAngleBrackets) i++\n\n const urlStart = i\n let urlEnd = urlStart\n\n // Per CommonMark spec Example 199: empty destination after colon (just whitespace/newline)\n // is invalid - should be parsed as paragraph, not reference definition\n // Also check if we hit a blank line (two consecutive newlines) - destination ends there\n if (urlStart >= len) {\n // No destination found - invalid (except for empty <>)\n if (!hasAngleBrackets) return null\n // For angle brackets, empty destination is valid\n urlEnd = urlStart\n } else if (\n urlNewlineCount > 0 &&\n urlStart < len &&\n source[urlStart] === '\\n'\n ) {\n // We had a newline after colon, skipped whitespace, but found another newline\n // This means blank line after colon - empty destination, invalid\n return null\n } else {\n // Find end of URL - can span multiple lines\n // Per CommonMark spec: destination ends when we encounter:\n // 1. Closing > for angle-bracketed URLs\n // 2. Whitespace followed by title delimiter (\", ', or () on same or next line\n // 3. End of input or two consecutive newlines (blank line)\n while (urlEnd < len) {\n if (hasAngleBrackets && source[urlEnd] === '>') {\n break\n }\n\n if (source[urlEnd] === '\\n') {\n // Check if next line continues the URL or starts a title\n const nextLineStart = urlEnd + 1\n if (nextLineStart >= len) break\n\n // Check for blank line (two consecutive newlines)\n if (nextLineStart < len && source[nextLineStart] === '\\n') {\n // Blank line - URL ends here\n break\n }\n\n // Skip whitespace on next line\n let checkPos = nextLineStart\n while (\n checkPos < len &&\n (source[checkPos] === ' ' || source[checkPos] === '\\t')\n ) {\n checkPos++\n }\n\n // If next line starts with title delimiter, URL ends here\n if (\n checkPos < len &&\n (source[checkPos] === '\"' ||\n source[checkPos] === \"'\" ||\n source[checkPos] === '(')\n ) {\n break\n }\n\n // Per CommonMark spec: reference definitions are block-level constructs\n // If next line starts with '[', it's a new reference definition, so current one ends here\n // Stop at the newline (don't include it in the URL)\n if (checkPos < len && source[checkPos] === '[') {\n break\n }\n\n // Check if next line looks like a block-level construct or content that would terminate the ref definition\n // Per CommonMark spec: \"No further character may occur\" after title/URL\n // URLs can span multiple lines, but continuation lines should still look like URLs\n if (checkPos < len) {\n const nextChar = source[checkPos]\n // Always stop for block-level constructs\n if (\n nextChar === '=' ||\n nextChar === '-' ||\n nextChar === '_' ||\n nextChar === '*' ||\n nextChar === '#' ||\n nextChar === '>' ||\n nextChar === '`' ||\n nextChar === '~' ||\n nextChar === '[' ||\n (nextChar >= '0' && nextChar <= '9')\n ) {\n break\n }\n // Stop if next line starts with a letter (could be content, not URL continuation)\n // URLs typically start with /, http, https, <, or are indented\n // But allow if it looks like a URL scheme (letter followed by :)\n if (nextChar >= 'a' && nextChar <= 'z') {\n // Check if it's a URL scheme (e.g., \"http:\", \"ftp:\")\n let schemeEnd = checkPos + 1\n while (\n schemeEnd < len &&\n schemeEnd < checkPos + 32 &&\n ((source[schemeEnd] >= 'a' && source[schemeEnd] <= 'z') ||\n (source[schemeEnd] >= 'A' && source[schemeEnd] <= 'Z') ||\n (source[schemeEnd] >= '0' && source[schemeEnd] <= '9') ||\n source[schemeEnd] === '+' ||\n source[schemeEnd] === '.' ||\n source[schemeEnd] === '-')\n ) {\n schemeEnd++\n }\n // If followed by ':', it's a URL scheme - allow continuation\n if (schemeEnd < len && source[schemeEnd] === ':') {\n // URL scheme - allow continuation\n } else {\n // Not a URL scheme - stop here (likely content)\n break\n }\n }\n }\n\n // Otherwise, continue URL on next line (skip the newline and leading whitespace)\n urlEnd = checkPos\n continue\n }\n\n if (\n !hasAngleBrackets &&\n (source[urlEnd] === ' ' || source[urlEnd] === '\\t')\n ) {\n // Check if this whitespace is followed by a title delimiter\n let checkPos = urlEnd + 1\n while (\n checkPos < len &&\n (source[checkPos] === ' ' || source[checkPos] === '\\t')\n ) {\n checkPos++\n }\n\n // Check if next char starts a title\n if (\n checkPos < len &&\n (source[checkPos] === '\"' ||\n source[checkPos] === \"'\" ||\n source[checkPos] === '(')\n ) {\n break\n }\n\n // Check if next line starts a title\n if (checkPos < len && source[checkPos] === '\\n') {\n const nextLineStart = checkPos + 1\n if (nextLineStart < len && source[nextLineStart] === '\\n') {\n // Blank line - URL ends here\n break\n }\n let nextLineCheck = nextLineStart\n while (\n nextLineCheck < len &&\n (source[nextLineCheck] === ' ' || source[nextLineCheck] === '\\t')\n ) {\n nextLineCheck++\n }\n if (\n nextLineCheck < len &&\n (source[nextLineCheck] === '\"' ||\n source[nextLineCheck] === \"'\" ||\n source[nextLineCheck] === '(')\n ) {\n break\n }\n }\n\n // No title delimiter found - URL continues (or ends if no title)\n // Continue parsing to find title or end\n }\n\n urlEnd++\n }\n }\n\n if (hasAngleBrackets && (urlEnd >= len || source[urlEnd] !== '>')) {\n return null // No closing >\n }\n\n // Extract target and normalize whitespace\n // Per CommonMark spec: destination can span multiple lines\n // Leading/trailing whitespace on each line should be trimmed, but internal whitespace preserved\n // Also, we need to preserve newlines between continuation lines\n let target = source.slice(urlStart, urlEnd)\n\n // Normalize whitespace: trim leading/trailing whitespace from each line\n // but preserve newlines and internal whitespace\n // Per CommonMark spec: leading/trailing whitespace is trimmed from destination\n let targetLines: string[] = []\n let targetLineStart = 0\n for (let i = 0; i <= target.length; i++) {\n if (i === target.length || target[i] === '\\n') {\n let line = target.slice(targetLineStart, i)\n // Trim leading/trailing whitespace from this line\n line = line.trim()\n if (line.length > 0 || targetLines.length === 0) {\n // Only add non-empty lines, or the first line even if empty (for angle brackets)\n targetLines.push(line)\n if (i < target.length) {\n targetLines.push('\\n')\n }\n } else if (i < target.length) {\n // Empty continuation line - preserve as newline\n targetLines.push('\\n')\n }\n targetLineStart = i + 1\n }\n }\n\n target = targetLines.join('')\n\n // Trim leading/trailing whitespace from the entire target\n target = target.trim()\n\n i = hasAngleBrackets ? urlEnd + 1 : urlEnd\n\n // Check if we stopped URL parsing because next line starts with a block construct\n // (indicating the ref definition ends here)\n // Per Example 215: ref definitions end before setext headings\n // A setext heading has content on one line, then = or - on the next line\n // We need to look ahead to detect this pattern\n var stoppedAtBlock = false\n if (i < len && source[i] === '\\n') {\n var nextLineStart = i + 1\n var checkPos = nextLineStart\n while (\n checkPos < len &&\n (source[checkPos] === ' ' || source[checkPos] === '\\t')\n ) {\n checkPos++\n }\n if (checkPos < len) {\n const nextChar = source[checkPos]\n // Check for block-level constructs that terminate ref definitions\n if (\n nextChar === '[' ||\n nextChar === '=' ||\n nextChar === '-' ||\n nextChar === '_' ||\n nextChar === '*' ||\n nextChar === '#' ||\n nextChar === '>' ||\n nextChar === '`' ||\n nextChar === '~' ||\n (nextChar >= '0' && nextChar <= '9')\n ) {\n stoppedAtBlock = true\n }\n // Per Example 215: check if this looks like a setext heading\n // Pattern: content line, then line starting with = or -\n // If next line has content (not starting with block char), check if line after that starts with = or -\n if (!stoppedAtBlock && nextChar !== '=' && nextChar !== '-') {\n // Next line might be content - check if line after that starts with = or -\n var firstLineEnd = util.findLineEnd(source, checkPos)\n if (firstLineEnd < len) {\n var secondLineStart = firstLineEnd + 1\n var secondCheckPos = secondLineStart\n while (\n secondCheckPos < len &&\n (source[secondCheckPos] === ' ' || source[secondCheckPos] === '\\t')\n ) {\n secondCheckPos++\n }\n if (secondCheckPos < len) {\n var secondChar = source[secondCheckPos]\n if (secondChar === '=' || secondChar === '-') {\n // This is a setext heading pattern - ref definition should end before content line\n stoppedAtBlock = true\n }\n }\n }\n }\n }\n }\n\n // Per CommonMark spec: title delimiter must be separated by whitespace from destination\n // Check if we see a title delimiter immediately after destination (no whitespace)\n // This makes it invalid as a reference definition\n if (\n !stoppedAtBlock &&\n i < len &&\n (source[i] === '\"' || source[i] === \"'\" || source[i] === '(')\n ) {\n // Title delimiter immediately after destination without whitespace - invalid\n return null\n }\n\n // Skip whitespace between destination and title (including optional newline)\n // Per CommonMark spec: title must be separated from destination by spaces/tabs\n // The title can be on the same line or a following line\n // Per CommonMark spec: Unicode whitespace (like non-breaking space) does NOT work for separation\n // However, if we stopped because next line starts with a block construct, don't skip past the newline\n let titleNewlineCount = 0\n while (i < len && !stoppedAtBlock) {\n const c = source[i]\n if (c === '\\n') {\n titleNewlineCount++\n if (titleNewlineCount > 1) break // Only one optional newline allowed before title\n i++\n // After newline, skip leading whitespace on next line (only ASCII space/tab)\n var whitespaceStart = i\n i = util.skipWhitespace(source, i)\n // If we hit Unicode whitespace, stop\n if (\n i < len &&\n util.isUnicodeWhitespace(source[i]) &&\n source[i] !== '\\n'\n ) {\n i = whitespaceStart - 1\n break\n }\n // Check if next line starts with a block construct (ref definition ends here)\n // Per Example 215: setext headings (= or -) also terminate ref definitions\n if (i < len) {\n const nextChar = source[i]\n if (\n nextChar === '[' ||\n nextChar === '=' ||\n nextChar === '-' ||\n nextChar === '_' ||\n nextChar === '*' ||\n nextChar === '#' ||\n nextChar === '>' ||\n nextChar === '`' ||\n nextChar === '~' ||\n (nextChar >= '0' && nextChar <= '9')\n ) {\n stoppedAtBlock = true\n i = whitespaceStart - 1 // Back up to the newline\n break\n }\n // Also check if this looks like a setext heading (need to look ahead to see if there's\n // a line that starts with = or - after some content)\n // For now, just checking = or - is sufficient as they're already in the block check above\n }\n } else if (c === ' ' || c === '\\t') {\n i++\n } else if (util.isUnicodeWhitespace(c)) {\n // Unicode whitespace does NOT work for separation - stop here\n break\n } else {\n break\n }\n }\n\n // Parse optional title (can span multiple lines, but cannot contain blank lines)\n let title: string | undefined = undefined\n let titleEndPos = i\n if (i < len) {\n const titleChar = source[i]\n if (titleChar === '\"' || titleChar === \"'\") {\n // Quoted title - can span multiple lines\n i++ // skip opening quote\n const titleStart = i\n let sawBlankLine = false\n let lastWasNewline = false\n\n while (i < len && source[i] !== titleChar) {\n if (source[i] === '\\n') {\n if (lastWasNewline) {\n // Two consecutive newlines = blank line\n sawBlankLine = true\n break\n }\n lastWasNewline = true\n i++\n } else {\n lastWasNewline = false\n if (source[i] === '\\\\' && i + 1 < len) {\n i++ // skip escaped char\n }\n i++\n }\n }\n\n if (sawBlankLine) {\n // Title contains blank line - invalid\n return null\n }\n\n if (i < len && source[i] === titleChar) {\n // Extract title preserving newlines (CommonMark spec allows multi-line titles)\n title = source.slice(titleStart, i)\n titleEndPos = i + 1\n i = titleEndPos\n // Per Example 210: after closing quote, check if there's non-whitespace before newline\n // Skip whitespace after closing quote\n var afterTitlePos = i\n while (\n afterTitlePos < len &&\n (source[afterTitlePos] === ' ' || source[afterTitlePos] === '\\t')\n ) {\n afterTitlePos++\n }\n // If there's non-whitespace before newline, invalidate the ref definition\n if (\n afterTitlePos < len &&\n source[afterTitlePos] !== '\\n' &&\n source[afterTitlePos] !== '\\r'\n ) {\n // Found non-whitespace after title closing delimiter - invalid\n return null\n }\n // Update i to point to after any whitespace (before newline)\n i = afterTitlePos\n }\n } else if (titleChar === '(') {\n // Parenthesized title - can span multiple lines\n i++ // skip opening paren\n const titleStart = i\n let parenDepth = 1\n let sawBlankLine = false\n let lastWasNewline = false\n\n while (i < len && parenDepth > 0) {\n if (source[i] === '\\n') {\n if (lastWasNewline) {\n // Two consecutive newlines = blank line\n sawBlankLine = true\n break\n }\n lastWasNewline = true\n i++\n } else {\n lastWasNewline = false\n if (source[i] === '\\\\' && i + 1 < len) {\n i++ // skip escaped char\n } else if (source[i] === '(') {\n parenDepth++\n } else if (source[i] === ')') {\n parenDepth--\n }\n i++\n }\n }\n\n if (sawBlankLine) {\n // Title contains blank line - invalid\n return null\n }\n\n if (parenDepth === 0) {\n title = source.slice(titleStart, i - 1)\n titleEndPos = i\n i = titleEndPos\n }\n }\n }\n\n // Skip trailing whitespace\n i = util.skipWhitespace(source, i)\n\n // Must end at newline or end of input\n // Per CommonMark spec: no further character may occur after title\n // Per Example 210: if there's text after the title on the same line, it's invalid\n // The title parsing already handles this - if title is found, i points to after the closing delimiter\n // We just need to ensure there's no non-whitespace before the newline\n if (i < len && source[i] !== '\\n') {\n // Check if there's non-whitespace before the newline\n var checkEndPos = i\n while (checkEndPos < len && source[checkEndPos] !== '\\n') {\n if (source[checkEndPos] !== ' ' && source[checkEndPos] !== '\\t') {\n // Found non-whitespace after title - invalid reference definition\n return null\n }\n checkEndPos++\n }\n }\n\n // Also check: if no title was found, make sure we're at end of line or there's trailing text\n // Per Example 210: `[foo]: /url\\n\"title\" ok` - the \"title\" ok is trailing text, should invalidate\n if (title === undefined && i < len && source[i] !== '\\n') {\n // No title found, but there's content after destination - check if it's just whitespace\n var checkTrailingPos = i\n while (checkTrailingPos < len && source[checkTrailingPos] !== '\\n') {\n if (\n source[checkTrailingPos] !== ' ' &&\n source[checkTrailingPos] !== '\\t'\n ) {\n // Found non-whitespace after destination - invalid reference definition\n return null\n }\n checkTrailingPos++\n }\n }\n\n return {\n endPos: i < len && source[i] === '\\n' ? i + 1 : i,\n target: target,\n title: title,\n }\n}\n\nfunction parseFootnoteContent(\n source: string,\n pos: number\n): DefinitionParseResult | null {\n // pos is already after the colon and whitespace\n let contentStart = pos\n let contentEnd = contentStart\n\n // Find the end of the footnote (next footnote definition, blank line, or end of input)\n // Continuation lines are lines that:\n // 1. Start with a newline\n // 2. Don't start with [^ (unless indented with 4+ spaces)\n // 3. Can be indented with up to 4 spaces\n // 4. Stop at a blank line (two consecutive newlines) if followed by non-indented content\n let stoppedAtBlankLine = false\n while (contentEnd < source.length) {\n // Check if we're at the start of a line (after newline or at start of input)\n const isLineStart = contentEnd === 0 || source[contentEnd - 1] === '\\n'\n\n // Check for blank line (two consecutive newlines) followed by non-indented content\n // A blank line terminates the footnote if followed by content that's not indented 4+ spaces\n // We need to check if we're at a blank line: current position is \\n and next is \\n\n if (\n contentEnd + 1 < source.length &&\n source[contentEnd] === '\\n' &&\n source[contentEnd + 1] === '\\n' &&\n contentEnd > contentStart // Make sure we're past the first line\n ) {\n // Check if there's non-indented content after the blank line\n let afterBlank = contentEnd + 2\n // Skip whitespace\n while (\n afterBlank < source.length &&\n (source[afterBlank] === ' ' || source[afterBlank] === '\\t')\n ) {\n afterBlank++\n }\n // If there's content and it's not indented with 4+ spaces, stop the footnote\n if (\n afterBlank < source.length &&\n source[afterBlank] !== '\\n' &&\n afterBlank - (contentEnd + 2) < 4\n ) {\n // Blank line followed by non-indented content - stop at the blank line\n stoppedAtBlankLine = true\n break\n }\n }\n\n if (isLineStart && util.startsWith(source, '[^', contentEnd)) {\n // Check if this is a footnote definition (has ':')\n let checkPos = contentEnd + 2\n while (checkPos < source.length && source[checkPos] !== ']') {\n checkPos++\n }\n if (\n checkPos < source.length &&\n source[checkPos] === ']' &&\n checkPos + 1 < source.length &&\n source[checkPos + 1] === ':'\n ) {\n // Found next footnote definition at start of line - stop here\n break\n }\n }\n contentEnd++\n }\n\n // Extract the footnote content (from after ']:' to before next footnote or end)\n // If we stopped at a blank line, contentEnd points to the first \\n of \\n\\n\n // We want to extract up to but not including that \\n (which slice does)\n // But we also need to make sure we don't include the trailing newline from the last line\n let extractEnd = contentEnd\n\n // pos is already after the colon and whitespace, so we can use it directly\n let contentStartPos = pos\n\n // Process lines directly without splitting to avoid intermediate array allocation\n var processedParts: string[] = []\n let lineStart = contentStartPos\n let lineIndex = 0\n let prevWasBlank = false\n\n while (lineStart < extractEnd) {\n let lineEnd = lineStart\n // Find line end\n while (lineEnd < extractEnd && source[lineEnd] !== '\\n') {\n lineEnd++\n }\n\n // Extract and process line\n if (lineIndex === 0) {\n // First line - trim trailing whitespace only\n let trimmedEnd = lineEnd\n while (\n trimmedEnd > lineStart &&\n (source[trimmedEnd - 1] === ' ' || source[trimmedEnd - 1] === '\\t')\n ) {\n trimmedEnd--\n }\n // Build first line\n let firstLineStr = source.slice(lineStart, trimmedEnd)\n processedParts.push(firstLineStr)\n // Check if first line is blank\n prevWasBlank = firstLineStr.length === 0\n } else {\n // Check indentation on current line\n let leadingSpaceCount = 0\n let checkPos = lineStart\n while (\n checkPos < lineEnd &&\n checkPos < lineStart + 4 &&\n source[checkPos] === ' '\n ) {\n leadingSpaceCount++\n checkPos++\n }\n\n // Check if current line is blank\n let lineHasContent = false\n for (let k = lineStart; k < lineEnd; k++) {\n if (source[k] !== ' ' && source[k] !== '\\t' && source[k] !== '\\r') {\n lineHasContent = true\n break\n }\n }\n let currentIsBlank = !lineHasContent\n\n // Process continuation line based on indentation rules\n if (leadingSpaceCount >= 4 && prevWasBlank) {\n // 4+ spaces after a blank line - this is a paragraph, preserve indentation\n processedParts.push(source.slice(lineStart, lineEnd))\n } else if (leadingSpaceCount === 4 && !prevWasBlank) {\n // Exactly 4 spaces without blank line - remove (markdown continuation indentation)\n processedParts.push(source.slice(lineStart + 4, lineEnd))\n } else {\n // Otherwise preserve (less than 4 spaces or more than 4 spaces without blank line)\n processedParts.push(source.slice(lineStart, lineEnd))\n }\n\n // Update prevWasBlank for next iteration\n prevWasBlank = currentIsBlank\n }\n\n // Move to next line\n if (lineEnd < extractEnd && source[lineEnd] === '\\n') {\n processedParts.push('\\n')\n lineStart = lineEnd + 1\n } else {\n lineStart = extractEnd\n }\n lineIndex++\n }\n\n let footnoteContent = processedParts.join('')\n\n // Trim trailing whitespace/newlines but preserve internal structure\n // If we stopped at a blank line, remove the trailing newline from the last line\n if (stoppedAtBlankLine) {\n // Remove trailing newline if present (but preserve newlines between lines)\n footnoteContent = footnoteContent.replace(/\\n$/, '')\n }\n var contentLen = footnoteContent.length\n while (contentLen > 0) {\n var lastChar = footnoteContent[contentLen - 1]\n if (lastChar === '\\n' || lastChar === ' ') {\n contentLen--\n } else {\n break\n }\n }\n if (contentLen < footnoteContent.length) {\n footnoteContent = footnoteContent.slice(0, contentLen)\n }\n\n return {\n endPos: contentEnd,\n target: footnoteContent,\n title: undefined,\n }\n}\n\nexport function parseDefinition(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions,\n isFootnote: boolean\n): ParseResult | null {\n if (source[pos] !== '[') return null\n var hasCaret = pos + 1 < source.length && source[pos + 1] === '^'\n if (isFootnote ? !hasCaret : hasCaret) return null\n\n var lineStart = pos\n while (lineStart > 0 && source[lineStart - 1] !== '\\n') lineStart--\n if (\n calculateIndent(source, lineStart, pos).spaceEquivalent >= 4 ||\n state.inline\n )\n return null\n\n var labelStart = pos + (isFootnote ? 2 : 1)\n var len = source.length\n var refEnd = findUnescapedChar(source, labelStart, len, ']')\n if (refEnd === -1) return null\n var ref = source.slice(labelStart, refEnd)\n if (ref.length > 999) return null\n\n var hasNonWhitespace = false,\n hasUnescapedBracket = false,\n labelHasNewlines = false\n for (var j = 0; j < ref.length; j++) {\n var c = ref[j]\n if (c === '\\\\' && j + 1 < ref.length) {\n j++\n continue\n }\n var cCode = charCode(c)\n if (cCode === $.CHAR_BRACKET_OPEN || cCode === $.CHAR_BRACKET_CLOSE) {\n hasUnescapedBracket = true\n } else if (cCode === $.CHAR_NEWLINE || cCode === $.CHAR_CR) {\n labelHasNewlines = true\n } else if (cCode !== $.CHAR_SPACE && cCode !== $.CHAR_TAB) {\n hasNonWhitespace = true\n }\n }\n if (!hasNonWhitespace || hasUnescapedBracket) return null\n\n var i = refEnd + 1\n if (labelHasNewlines) {\n var labelStartCode = charCode(source, labelStart)\n var refEndPrevCode = charCode(source, refEnd - 1)\n if (\n labelStartCode === $.CHAR_NEWLINE ||\n labelStartCode === $.CHAR_CR ||\n refEndPrevCode === $.CHAR_NEWLINE ||\n refEndPrevCode === $.CHAR_CR ||\n i >= len ||\n source[i] !== ':'\n )\n return null\n } else {\n if (i >= len || source[i] !== ':') {\n i = util.skipWhitespace(source, i)\n if (i < len && charCode(source, i) === $.CHAR_NEWLINE)\n i = util.skipWhitespace(source, i + 1)\n if (i >= len || source[i] !== ':') return null\n }\n }\n i++\n\n var urlNewlineCount = 0\n while (i < len) {\n var iCode = charCode(source, i)\n if (iCode === $.CHAR_NEWLINE) {\n if (++urlNewlineCount > 1) break\n i = util.skipWhitespace(source, i + 1)\n } else if (iCode === $.CHAR_SPACE || iCode === $.CHAR_TAB) {\n i++\n } else {\n break\n }\n }\n\n const contentResult = isFootnote\n ? parseFootnoteContent(source, i)\n : parseRefContent(source, i, urlNewlineCount)\n if (!contentResult) return null\n\n const normalizedRef = normalizeReferenceLabel(ref)\n const refs = state.refs || {}\n const storageKey = isFootnote ? `^${normalizedRef}` : normalizedRef\n if (!refs[storageKey]) {\n refs[storageKey] = {\n target: unescapeUrlOrTitle(contentResult.target.trim()),\n title: contentResult.title\n ? unescapeUrlOrTitle(contentResult.title)\n : undefined,\n }\n state.refs = refs\n }\n\n return {\n type: isFootnote ? RuleType.footnote : RuleType.ref,\n endPos: contentResult.endPos,\n } as (MarkdownToJSX.ReferenceNode | MarkdownToJSX.FootnoteNode) & {\n endPos: number\n }\n}\n\n// Delimiter stack entry for CommonMark spec delimiter stack algorithm\ninterface DelimiterEntry {\n nodeIndex: number // Index in result array where this delimiter text node is\n type: '*' | '_' | '~' | '='\n length: number // Number of delimiters in the run\n canOpen: boolean // Whether this delimiter can open emphasis\n canClose: boolean // Whether this delimiter can close emphasis\n active: boolean // Whether this delimiter is active\n sourcePos: number // Source position where this delimiter starts (for overlap detection)\n inAnchor: boolean // Whether this delimiter was collected inside a link (should not match with delimiters outside)\n}\n\n// Process emphasis using delimiter stack algorithm per CommonMark spec\nfunction processEmphasis(\n nodes: MarkdownToJSX.ASTNode[],\n delimiterStack: DelimiterEntry[],\n stackBottom: number | null\n): void {\n // openers_bottom for each delimiter type, indexed by numeric key: typeCode * 6 + (length % 3) * 2 + (canOpen ? 1 : 0)\n // Type codes: '*' = 0, '_' = 1, '~' = 2, '=' = 3\n var openersBottom: number[] = []\n\n var currentPosition = stackBottom === null ? 0 : stackBottom + 1\n\n while (currentPosition < delimiterStack.length) {\n var closer = delimiterStack[currentPosition]\n if (\n !closer ||\n (closer.type !== '*' &&\n closer.type !== '_' &&\n closer.type !== '~' &&\n closer.type !== '=')\n ) {\n currentPosition++\n continue\n }\n\n if (!closer.canClose || !closer.active) {\n currentPosition++\n continue\n }\n\n // Convert type to numeric code: '*' = 0, '_' = 1, '~' = 2, '=' = 3\n var typeCode =\n closer.type === '*'\n ? 0\n : closer.type === '_'\n ? 1\n : closer.type === '~'\n ? 2\n : 3\n var openersBottomKey =\n typeCode * 6 + (closer.length % 3) * 2 + (closer.canOpen ? 1 : 0)\n var openersBottomIndex =\n openersBottom[openersBottomKey] !== undefined\n ? openersBottom[openersBottomKey]\n : stackBottom === null\n ? -1\n : stackBottom\n\n var openerIndex = -1\n var closerType = closer.type\n var closerInAnchor = closer.inAnchor\n var closerCanOpen = closer.canOpen\n var closerLength = closer.length\n var closerLengthMod3 = closerLength % 3\n\n for (var i = currentPosition - 1; i > openersBottomIndex; i--) {\n var candidate = delimiterStack[i]\n if (\n !candidate ||\n !candidate.active ||\n candidate.type !== closerType ||\n !candidate.canOpen ||\n candidate.inAnchor !== closerInAnchor\n )\n continue\n var openerLength = candidate.length\n if (\n (!closerCanOpen && !candidate.canClose) ||\n closerLengthMod3 === 0 ||\n (openerLength + closerLength) % 3 !== 0\n ) {\n openerIndex = i\n break\n }\n }\n\n if (openerIndex >= 0) {\n var opener = delimiterStack[openerIndex]\n var openerLength = opener.length\n\n // Determine if emphasis or strong emphasis (both must have length >= 2 for strong)\n var isStrong = openerLength >= 2 && closerLength >= 2\n var delimitersToRemove = isStrong ? 2 : 1\n if (\n delimitersToRemove > openerLength ||\n delimitersToRemove > closerLength\n ) {\n currentPosition++\n continue\n }\n\n var openerNodeIndex = opener.nodeIndex\n var closerNodeIndex = closer.nodeIndex\n var contentStartIndex = openerNodeIndex + 1\n var contentEndIndex = closerNodeIndex\n var contentNodes = nodes.slice(contentStartIndex, contentEndIndex)\n\n // Remove content nodes from nodes array (they'll be in the emphasis node)\n if (contentNodes.length > 0) {\n var nodesRemoved = contentEndIndex - contentStartIndex\n nodes.splice(contentStartIndex, nodesRemoved)\n for (var k = 0; k < delimiterStack.length; k++) {\n if (delimiterStack[k].nodeIndex > contentStartIndex)\n delimiterStack[k].nodeIndex -= nodesRemoved\n }\n if (closerNodeIndex > contentStartIndex) closerNodeIndex -= nodesRemoved\n }\n\n var emphasisTag =\n opener.type === '~'\n ? 'del'\n : opener.type === '='\n ? 'mark'\n : isStrong\n ? 'strong'\n : 'em'\n var emphasisNode: MarkdownToJSX.FormattedTextNode = {\n type: RuleType.textFormatted,\n tag: emphasisTag,\n children: contentNodes,\n }\n\n var openerNode = nodes[openerNodeIndex] as MarkdownToJSX.TextNode\n if (!openerNode || !openerNode.text) {\n opener.active = closer.active = false\n continue\n }\n\n // Remove delimiters from opener text node\n var openerRemoved = openerNode.text.length <= delimitersToRemove\n if (openerRemoved) {\n nodes.splice(openerNodeIndex, 1)\n for (var k = 0; k < delimiterStack.length; k++) {\n if (delimiterStack[k].nodeIndex > openerNodeIndex)\n delimiterStack[k].nodeIndex--\n }\n if (closerNodeIndex > openerNodeIndex) closerNodeIndex--\n } else {\n openerNode.text = openerNode.text.slice(delimitersToRemove)\n }\n\n var closerNode = nodes[closerNodeIndex] as MarkdownToJSX.TextNode\n if (!closerNode || !closerNode.text) {\n opener.active = closer.active = false\n continue\n }\n var closerRemoved = closerNode.text.length <= delimitersToRemove\n if (closerRemoved) {\n nodes.splice(closerNodeIndex, 1)\n for (var k = 0; k < delimiterStack.length; k++) {\n if (delimiterStack[k].nodeIndex > closerNodeIndex)\n delimiterStack[k].nodeIndex--\n }\n } else {\n closerNode.text = closerNode.text.slice(delimitersToRemove)\n }\n\n // Insert emphasis node after opener (or at the position where opener was)\n var insertIndex = openerRemoved\n ? openerNodeIndex < closerNodeIndex\n ? closerNodeIndex - 1\n : openerNodeIndex\n : openerNodeIndex + 1\n if (insertIndex < 0 || insertIndex > nodes.length)\n insertIndex = insertIndex < 0 ? 0 : nodes.length\n nodes.splice(insertIndex, 0, emphasisNode)\n\n // Update node indices in delimiter stack after insertion\n for (var k = 0; k < delimiterStack.length; k++) {\n if (delimiterStack[k].nodeIndex >= insertIndex) {\n delimiterStack[k].nodeIndex++\n }\n }\n\n // Remove delimiters between opener and closer from stack\n for (var k = openerIndex + 1; k < currentPosition; k++) {\n delimiterStack[k].active = false\n }\n\n // Update opener and closer in stack\n if (openerRemoved) {\n opener.active = false\n } else {\n opener.length -= delimitersToRemove\n if (opener.length === 0) opener.active = false\n }\n\n if (closerRemoved) {\n closer.active = false\n currentPosition++\n } else {\n closer.length -= delimitersToRemove\n if (closer.length === 0) {\n closer.active = false\n currentPosition++\n }\n }\n } else {\n // No opener found\n openersBottom[openersBottomKey] = currentPosition - 1\n if (!closer.canOpen) {\n closer.active = false\n }\n currentPosition++\n }\n }\n\n // Remove inactive delimiters from stack (O(n) shift algorithm instead of O(n²) splice)\n var writeIndex = 0\n for (var i = 0; i < delimiterStack.length; i++) {\n if (delimiterStack[i].active) {\n delimiterStack[writeIndex++] = delimiterStack[i]\n }\n }\n delimiterStack.length = writeIndex\n}\n\nexport function parseMarkdown(\n input: string,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): MarkdownToJSX.ASTNode[] {\n var result: MarkdownToJSX.ASTNode[] = []\n var pos = 0\n var REF_CHECK_UNSET = -3\n var cachedRefCheckPos = REF_CHECK_UNSET\n\n // If inline mode, just parse the entire input as inline content\n if (state.inline)\n return parseInlineSpan(input, 0, input.length, state, options)\n\n // Block parsing mode\n\n // Check for frontmatter at the beginning (skip if doesn't start with ---)\n if (pos === 0 && input.startsWith('---')) {\n var frontmatterResult = parseFrontmatter(input, pos)\n if (frontmatterResult) {\n result.push(frontmatterResult)\n pos = frontmatterResult.endPos\n }\n }\n\n while (pos < input.length) {\n // Skip leading newlines (but preserve whitespace for indented code blocks)\n while (pos < input.length && input[pos] === '\\n') {\n pos++\n }\n\n if (pos >= input.length) break\n cachedRefCheckPos = REF_CHECK_UNSET\n\n const char = input[pos]\n\n // Try parseBlock first (handles indentation and tries all block parsers)\n // Note: Individual parsers called by parseBlock track their own attempts\n const parseResult = parseBlock(input, pos, state, options)\n if (parseResult) {\n const t = parseResult.type\n if (t === RuleType.codeBlock) {\n var isFenced = char === '`' || char === '~'\n if (!isFenced && (char === ' ' || char === '\\t')) {\n const lineEnd = util.findLineEnd(input, pos)\n const indentInfo = calculateIndent(input, pos, lineEnd)\n isFenced =\n indentInfo.spaceEquivalent <= 3 &&\n pos + indentInfo.charCount < input.length &&\n (input[pos + indentInfo.charCount] === '`' ||\n input[pos + indentInfo.charCount] === '~')\n }\n } else if (t === RuleType.breakThematic) {} else if (t === RuleType.blockQuote) {} else if (t === RuleType.heading) {} else if (t === RuleType.orderedList || t === RuleType.unorderedList) {} else if (t === RuleType.table) {} else if (t === RuleType.htmlComment) {} else if (t === RuleType.htmlBlock) {} else if (t === RuleType.ref) {}\n\n // Special handling for HTML comments with trailing content\n if (parseResult.type === RuleType.htmlComment) {\n result.push(parseResult)\n const htmlCheckPos = pos\n pos = parseResult.endPos\n\n // Per CommonMark spec Example 177: HTML comment blocks end at --> on the same line\n // If there's content after --> on the same line, it should be treated as literal text\n const commentLineEnd = util.findLineEnd(input, htmlCheckPos)\n if (pos < commentLineEnd) {\n const textContent = input.slice(pos, commentLineEnd)\n if (textContent.trim().length > 0) {\n result.push({\n type: RuleType.text,\n text: textContent,\n } as MarkdownToJSX.TextNode)\n }\n pos = commentLineEnd\n if (pos < input.length && input[pos] === '\\n') {\n pos++\n }\n }\n continue\n }\n // Special handling for HTML self-closing closing tags\n if (\n parseResult.type === RuleType.htmlBlock ||\n parseResult.type === RuleType.htmlSelfClosing\n ) {\n const isSelfClosingClosingTag =\n parseResult.type === RuleType.htmlSelfClosing &&\n parseResult.isClosingTag === true\n if (isSelfClosingClosingTag && !state.inline && !state.inHTML) {\n // Don't match, fall through to other parsers\n } else {\n result.push(parseResult)\n pos = parseResult.endPos\n continue\n }\n } else {\n result.push(parseResult)\n pos = parseResult.endPos\n continue\n }\n }\n\n // Reference definition - check BEFORE setext heading to prevent conflicts\n // Reference definitions take precedence over setext headings (e.g., [foo]: /url\\n===)\n let refCheckPos =\n cachedRefCheckPos !== REF_CHECK_UNSET ? cachedRefCheckPos : pos\n if (cachedRefCheckPos === REF_CHECK_UNSET) {\n if (isSpaceOrTab(char)) {\n const lineEnd = util.findLineEnd(input, pos)\n const indentInfo = calculateIndent(input, pos, lineEnd)\n const checkPos = pos + indentInfo.charCount\n if (\n indentInfo.spaceEquivalent <= 3 &&\n checkPos < input.length &&\n input[checkPos] === '['\n ) {\n refCheckPos = checkPos\n } else {\n refCheckPos = -1\n }\n } else if (char === '[') {\n refCheckPos = pos\n } else {\n refCheckPos = -1\n }\n cachedRefCheckPos = refCheckPos\n }\n\n if (\n refCheckPos >= 0 &&\n refCheckPos + 1 < input.length &&\n input[refCheckPos + 1] === '^'\n ) {\n refCheckPos = -1\n }\n\n if (refCheckPos >= 0) {\n const parseResult = parseDefinition(\n input,\n refCheckPos,\n state,\n options,\n false\n )\n if (parseResult) {\n result.push(parseResult)\n pos = parseResult.endPos\n continue\n }\n // parseDefinition returned null - check if this is an invalid reference definition that should be skipped\n // Per CommonMark Examples 208 and 210: certain invalid reference definitions should be skipped entirely\n const skipResult = shouldSkipInvalidReferenceDefinition(\n input,\n refCheckPos,\n pos === 0\n )\n if (skipResult.shouldSkip) {\n pos = skipResult.newPos\n continue\n }\n }\n\n // Heading (Setext style) - check after reference definitions\n const setextResult = parseHeadingSetext(input, pos, state, options)\n if (setextResult) {\n result.push(setextResult)\n pos = setextResult.endPos\n continue\n }\n\n // Footnote definition (skip leading whitespace)\n let footnoteCheckPos = pos\n if (isSpaceOrTab(input[footnoteCheckPos])) {\n const lineEnd = util.findLineEnd(input, pos)\n const indentInfo = calculateIndent(input, pos, lineEnd)\n footnoteCheckPos = pos + indentInfo.charCount\n }\n if (\n footnoteCheckPos < input.length &&\n input[footnoteCheckPos] === '[' &&\n footnoteCheckPos + 1 < input.length &&\n input[footnoteCheckPos + 1] === '^'\n ) {\n const footnoteResult = parseDefinition(\n input,\n footnoteCheckPos,\n state,\n options,\n true\n )\n if (footnoteResult) {\n pos = footnoteResult.endPos\n continue\n }\n }\n\n const paragraphResult = parseParagraph(input, pos, state, options)\n if (paragraphResult) {\n result.push(paragraphResult)\n pos = paragraphResult.endPos\n continue\n }\n\n pos++\n }\n\n // Note: Memory snapshot \"After block parsing\" is taken in compiler function\n // after parseMarkdown returns, not here\n\n // Footnotes footer is appended during rendering phase (not in AST)\n // Footnotes are stored in refs with '^' prefix and extracted during rendering\n\n // Collect all refs from state.refs (populated during parsing) and create a reference collection node\n // Reference nodes stay in their original positions, but we prepend a collection node\n // Include footnotes (keys starting with '^') so the renderer can handle them\n const allRefs = state.refs || {}\n const collectedRefs: {\n [key: string]: { target: string; title: string | undefined }\n } = {}\n for (const key in allRefs) {\n collectedRefs[key] = allRefs[key]\n }\n\n // Prepend reference collection node if we have any refs\n if (util.hasKeys(collectedRefs)) {\n const refCollectionNode: MarkdownToJSX.ReferenceCollectionNode = {\n type: RuleType.refCollection,\n refs: collectedRefs,\n }\n return [refCollectionNode, ...result]\n }\n\n return result\n}\n\nexport function collectReferenceDefinitions(\n input: string,\n refs: { [key: string]: { target: string; title: string | undefined } },\n options: ParseOptions\n): void {\n var pos = 0\n var canStartRef = true\n const len = input.length\n\n while (pos < len) {\n var newlines = 0\n // Count consecutive newlines more efficiently\n while (pos < len && charCode(input, pos) === $.CHAR_NEWLINE) {\n newlines++\n pos++\n }\n if (pos >= len) break\n if (newlines > 0) canStartRef = true\n\n // Skip fenced code\n const currentCharCode = charCode(input, pos)\n if (\n currentCharCode === $.CHAR_BACKTICK ||\n currentCharCode === $.CHAR_TILDE\n ) {\n var fence = parseCodeFenced(input, pos, { inline: false }, options)\n if (fence) {\n pos = fence.endPos\n canStartRef = true\n continue\n }\n }\n\n // Try parse ref (up to 3 space indent)\n var refPos = pos\n var indent = 0\n while (refPos < len && indent < 4) {\n const code = charCode(input, refPos)\n if (code === $.CHAR_SPACE) {\n indent++\n refPos++\n } else if (code === $.CHAR_TAB) {\n indent += 4 - (indent % 4)\n refPos++\n } else {\n break\n }\n }\n\n if (\n indent < 4 &&\n refPos < len &&\n charCode(input, refPos) === $.CHAR_BRACKET_OPEN &&\n canStartRef\n ) {\n if (refPos + 1 < len && charCode(input, refPos + 1) === $.CHAR_CARET) {\n canStartRef = false\n var lineEnd = util.findLineEnd(input, pos)\n pos = lineEnd >= len ? len : lineEnd + 1\n continue\n } else {\n var result = parseDefinition(\n input,\n refPos,\n { inline: false, refs },\n options,\n false\n )\n if (result) {\n pos = result.endPos\n canStartRef = true\n continue\n }\n // parseDefinition returned null - check if colon exists (invalid ref attempt) vs paragraph content\n var lineEnd = util.findLineEnd(input, pos)\n var colonPos = input.indexOf(':', refPos + 1)\n if (colonPos === -1 || colonPos >= lineEnd) {\n var indentInfo = calculateIndent(input, pos, lineEnd)\n if (\n !isBlankLineCheck(input, pos, lineEnd) &&\n currentCharCode !== $.CHAR_HASH &&\n currentCharCode !== $.CHAR_GT &&\n currentCharCode !== $.CHAR_DASH &&\n currentCharCode !== $.CHAR_EQ &&\n indentInfo.spaceEquivalent < 4\n ) {\n canStartRef = false\n }\n }\n pos = lineEnd >= len ? len : lineEnd + 1\n continue\n }\n }\n\n // Scan blockquotes for nested refs\n if (currentCharCode === $.CHAR_GT && canStartRef) {\n var bqEnd = pos\n var bqLines = []\n while (bqEnd < len) {\n var lineEnd = util.findLineEnd(input, bqEnd)\n var quotePos = bqEnd\n while (quotePos < lineEnd) {\n const code = charCode(input, quotePos)\n if (code === $.CHAR_SPACE || code === $.CHAR_TAB) {\n quotePos++\n } else {\n break\n }\n }\n if (quotePos >= lineEnd || charCode(input, quotePos) !== $.CHAR_GT)\n break\n\n var contentStart = quotePos + 1\n if (\n contentStart < lineEnd &&\n (charCode(input, contentStart) === $.CHAR_SPACE ||\n charCode(input, contentStart) === $.CHAR_TAB)\n )\n contentStart++\n bqLines.push(input.slice(contentStart, lineEnd))\n bqEnd = lineEnd + 1\n }\n if (bqLines.length) {\n collectReferenceDefinitions(bqLines.join('\\n'), refs, options)\n pos = bqEnd\n canStartRef = true\n continue\n }\n }\n\n var lineEnd = util.findLineEnd(input, pos)\n if (lineEnd >= len) {\n pos = len\n } else {\n var isCurrentLineBlank = isBlankLineCheck(input, pos, lineEnd)\n var indentInfo = calculateIndent(input, pos, lineEnd)\n pos = lineEnd + 1\n canStartRef =\n currentCharCode === $.CHAR_HASH ||\n currentCharCode === $.CHAR_GT ||\n currentCharCode === $.CHAR_DASH ||\n currentCharCode === $.CHAR_EQ ||\n isCurrentLineBlank ||\n indentInfo.spaceEquivalent >= 4\n }\n }\n}\n\n/**\n * Given a markdown string, return an abstract syntax tree (AST) of the markdown.\n *\n * The first node in the AST is a reference collection node. This node contains all the\n * reference definitions found in the markdown. These reference definitions are used to\n * resolve reference links and images in the markdown.\n *\n * @param source - The markdown string to parse.\n * @param options - The options for the parser.\n * @returns The AST of the markdown.\n */\nexport function parser(\n source: string,\n options?: MarkdownToJSX.Options\n): MarkdownToJSX.ASTNode[] {\n // Default state\n const defaultState: MarkdownToJSX.State = { inline: false, refs: {} }\n const finalState = { ...defaultState }\n\n // Normalize options - convert MarkdownToJSX.Options to ParseOptions\n const finalOptions: ParseOptions = {\n ...options,\n slugify: options?.slugify\n ? (input: string) => options.slugify(input, util.slugify)\n : util.slugify,\n sanitizer: options?.sanitizer || util.sanitizer,\n tagfilter: options?.tagfilter !== false,\n }\n\n // Collect reference definitions if not in inline mode\n if (!finalState.inline) {\n collectReferenceDefinitions(source, finalState.refs || {}, finalOptions)\n }\n\n // Parse markdown\n const astNodes = parseMarkdown(source, finalState, finalOptions)\n\n return astNodes\n}\n",
|
|
9
|
+
"import { RuleType, type MarkdownToJSX } from './types'\nimport * as $ from './constants'\nimport * as util from './utils'\n\n// NOTE: All debug and tracking functions are automatically removed by build-plugins.ts\n\n// Global parseMetrics - accessible via global.parseMetrics from all files\ndeclare global {\n var parseMetrics: {\n blockParsers: {\n [key: string]: {\n attempts: number\n hits: number\n hitTimings: number[]\n }\n }\n inlineParsers: {\n [key: string]: {\n attempts: number\n hits: number\n hitTimings: number[]\n }\n }\n totalOperations: number\n blockParseIterations: number\n inlineParseIterations: number\n } | null\n var parseMetricsStartTimes: Map<string, number> | null\n}\n\nexport {};\n\nfunction warn(message: string): void {\n console.warn(message)\n}\n\nfunction countConsecutiveChars(\n source: string,\n pos: number,\n targetChar: string,\n maxCount?: number\n): number {\n var targetCode = charCode(targetChar)\n var len = source.length\n var max = maxCount ?? len - pos\n var count = 0\n while (\n count < max &&\n pos + count < len &&\n charCode(source, pos + count) === targetCode\n )\n count++\n return count\n}\n\n// Unified flanking check: dir=0 for left, dir=1 for right\nfunction checkFlanking(\n source: string,\n delimiterStart: number,\n delimiterEnd: number,\n bound: number,\n dir: number\n): boolean {\n if (dir === 0 ? delimiterEnd >= bound : delimiterStart <= bound) return false\n\n const adjacentChar =\n dir === 0 ? source[delimiterEnd] : source[delimiterStart - 1]\n const oppositeChar =\n dir === 0\n ? delimiterStart > 0\n ? source[delimiterStart - 1]\n : null\n : delimiterEnd < source.length\n ? source[delimiterEnd]\n : null\n\n var adjacentCode = charCode(adjacentChar)\n\n if (\n adjacentCode < $.CHAR_ASCII_BOUNDARY\n ? util.isASCIIWhitespace(adjacentCode)\n : util.isUnicodeWhitespace(adjacentChar)\n ) {\n return false\n }\n\n var oppositeCode = oppositeChar ? charCode(oppositeChar) : null\n var isOppositeWS =\n oppositeChar === null ||\n oppositeChar === '\\n' ||\n oppositeChar === '\\r' ||\n (oppositeCode !== null\n ? oppositeCode < $.CHAR_ASCII_BOUNDARY\n ? util.isASCIIWhitespace(oppositeCode)\n : util.isUnicodeWhitespace(oppositeChar)\n : true)\n\n var isAdjacentPunct = isPunctuation(adjacentCode, adjacentChar)\n\n if (!isAdjacentPunct) return true\n if (isOppositeWS) return true\n\n return oppositeChar\n ? isPunctuation(charCode(oppositeChar), oppositeChar)\n : false\n}\n\n// Per CommonMark spec: backslashes escape ASCII punctuation characters in link destinations\n// For non-punctuation characters, the backslash is preserved as a literal backslash\n// Per CommonMark spec: backslash unescaping and entity reference decoding for URLs and titles\n// Any ASCII punctuation character may be backslash-escaped\n// Entity references are recognized and decoded to Unicode\nfunction unescapeUrlOrTitle(str: string): string {\n var result = '',\n i = 0\n while (i < str.length) {\n if (str[i] === '\\\\' && i + 1 < str.length) {\n var next = str[i + 1]\n result += util.isUnicodePunctuation(charCode(next)) ? next : '\\\\' + next\n i += 2\n } else {\n result += str[i++]\n }\n }\n return util.decodeEntityReferences(result)\n}\n\nfunction skipToNextLine(source: string, lineEnd: number): number {\n return lineEnd + (lineEnd < source.length ? 1 : 0)\n}\n\nfunction getCharType(code: number, skipAutoLink: boolean): number {\n if (code >= $.CHAR_ASCII_BOUNDARY) return 0\n var type = util.inlineCharTypeTable[code]\n if (\n skipAutoLink &&\n type === 1 &&\n (code === $.CHAR_f || code === $.CHAR_H || code === $.CHAR_W)\n ) {\n return 0\n }\n return type\n}\n\nfunction tryMergeBlockquoteContinuation(\n source: string,\n currentPos: number,\n lastItem: MarkdownToJSX.ASTNode[],\n continuationContent: string,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): number | null {\n if (\n !lastItem.length ||\n lastItem[lastItem.length - 1].type !== RuleType.blockQuote\n )\n return null\n const checkPos = util.skipWhitespace(\n continuationContent,\n 0,\n continuationContent.length\n )\n if (\n checkPos >= continuationContent.length ||\n continuationContent[checkPos] !== '>'\n )\n return null\n // We've already verified it starts with '>', so try blockquote directly\n // (parseBlock might match fenced code blocks first due to indentation)\n const cont = parseBlockQuote(source, currentPos, state, options)\n if (!cont) return null\n const lastBlockQuote = lastItem[\n lastItem.length - 1\n ] as MarkdownToJSX.BlockQuoteNode\n const contBlockQuote = cont as MarkdownToJSX.BlockQuoteNode & {\n endPos: number\n }\n if (contBlockQuote.children)\n lastBlockQuote.children.push(...contBlockQuote.children)\n return contBlockQuote.endPos\n}\n\nfunction createHeading(\n level: number,\n children: MarkdownToJSX.ASTNode[],\n content: string,\n slugify: (str: string) => string\n): MarkdownToJSX.HeadingNode {\n return {\n type: RuleType.heading,\n level,\n children,\n id: slugify(content),\n } as MarkdownToJSX.HeadingNode\n}\n\n// Static regex patterns for performance\nexport const UNESCAPE_R: RegExp = /\\\\(.)/g\nconst HEADING_TRAILING_HASHES_R = /\\s+#+\\s*$/\n// Unified regex for all list item patterns: ordered (digit + delimiter + content) or unordered (marker + content)\n// Groups: 1=ordered_num, 2=ordered_delim, 3=ordered_content, 4=ordered_empty_num, 5=ordered_empty_delim, 6=unordered_marker, 7=unordered_content, 8=unordered_empty_marker\nconst LIST_ITEM_R =\n /^(?:(\\d{1,9})([.)])\\s+(.*)$|(\\d{1,9})([.)])\\s*$|([-*+])\\s+(.*)$|([-*+])\\s*$)/\n// List items with content (marker + whitespace + content or end of line) - for continuation matching\nconst ORDERED_LIST_ITEM_WITH_CONTENT_R = /^(\\d{1,9})([.)])(\\s+|$)/\nconst UNORDERED_LIST_ITEM_WITH_CONTENT_R = /^([*+\\-])(\\s+|$)/\nexport const HTML_BLOCK_ELEMENT_START_R: RegExp =\n /^<([a-z][^ >/\\n\\r]*) ?([^>]*?)>/i\nexport const HTML_BLOCK_ELEMENT_START_R_ATTR: RegExp =\n /^<([a-z][^ >/]*) ?(?:[^>/]+[^/]|)>/i\n\nvar charCode = function (c: string, pos: number = 0) {\n return c.charCodeAt(pos)\n}\nvar isAlnum = function (c: string): boolean {\n return util.isAlnumCode(charCode(c))\n}\nvar isWS = function (c: string) {\n return util.isASCIIWhitespace(charCode(c))\n}\nvar isSpaceOrTab = function (c: string): boolean {\n return c === ' ' || c === '\\t'\n}\nvar isPunctuation = function (code: number, char: string): boolean {\n return util.isUnicodePunctuation(code < $.CHAR_ASCII_BOUNDARY ? code : char)\n}\nvar isNameChar = function (c: string) {\n var n = charCode(c)\n return (\n isAlnum(c) ||\n n === $.CHAR_DASH ||\n n === $.CHAR_UNDERSCORE ||\n n === $.CHAR_COLON ||\n n === $.CHAR_PERIOD\n )\n}\n\n// HTML validation functions removed - parser only recognizes boundaries, not validates syntax\n// Per GFM spec: parser's job is to identify HTML boundaries and pass content opaquely\n\nfunction parseHTMLTagName(\n source: string,\n pos: number\n): { tagName: string; tagLower: string; nextPos: number } | null {\n var sourceLen = source.length\n if (pos >= sourceLen) return null\n var firstCharCode = charCode(source[pos])\n if (!isAlphaCode(firstCharCode)) return null\n var tagNameStart = pos\n var tagNameEnd = pos\n while (tagNameEnd < sourceLen) {\n var code = charCode(source[tagNameEnd])\n if (\n (code >= $.CHAR_a && code <= $.CHAR_z) ||\n (code >= $.CHAR_A && code <= $.CHAR_Z) ||\n (code >= $.CHAR_DIGIT_0 && code <= $.CHAR_DIGIT_9) ||\n code === $.CHAR_DASH\n ) {\n tagNameEnd++\n } else {\n var tagEndCode = charCode(source[tagNameEnd])\n if (\n tagEndCode === $.CHAR_SPACE ||\n tagEndCode === $.CHAR_TAB ||\n tagEndCode === $.CHAR_NEWLINE ||\n tagEndCode === $.CHAR_CR ||\n tagEndCode === $.CHAR_GT ||\n tagEndCode === $.CHAR_SLASH\n ) {\n break\n } else {\n return null\n }\n }\n }\n if (tagNameEnd === tagNameStart) return null\n var tagName = source.slice(tagNameStart, tagNameEnd)\n\n // Validate tag name according to spec: only ASCII letters, digits, hyphens\n for (var i = 0; i < tagName.length; i++) {\n var code = charCode(tagName[i])\n if (\n !(\n (code >= $.CHAR_a && code <= $.CHAR_z) ||\n (code >= $.CHAR_A && code <= $.CHAR_Z) ||\n (code >= $.CHAR_DIGIT_0 && code <= $.CHAR_DIGIT_9) ||\n code === $.CHAR_DASH\n )\n ) {\n return null\n }\n }\n\n return { tagName, tagLower: tagName.toLowerCase(), nextPos: tagNameEnd }\n}\n\n/** Unified HTML tag parser that handles opening, closing, and self-closing tags */\nexport function parseHTMLTag(\n source: string,\n pos: number\n): {\n tagName: string\n tagLower: string\n attrs: string\n endPos: number\n isClosing: boolean\n isSelfClosing: boolean\n hasNewline: boolean\n hasSpaceBeforeSlash: boolean\n whitespaceBeforeAttrs: string\n} | null {\n var token = scanRawHTML(source, pos)\n if (!token || token.kind !== 'tag') return null\n\n // Note: hasSpaceBeforeSlash is already validated in scanner (returns null if invalid)\n return {\n tagName: token.tagName || '',\n tagLower: token.tagNameLower || '',\n attrs: token.attrs || '',\n endPos: token.endPos,\n isClosing: token.isClosing || false,\n isSelfClosing: token.isSelfClosing || false,\n hasNewline: token.hasNewline,\n hasSpaceBeforeSlash: false,\n whitespaceBeforeAttrs: token.whitespaceBeforeAttrs || '',\n }\n}\n\n/** Find matching closing tag position for inline HTML tags. Returns [contentEnd, closingTagEnd] or null */\nfunction findInlineClosingTag(\n source: string,\n startPos: number,\n tagNameLower: string\n): [number, number] | null {\n var depth = 1\n var searchPos = startPos\n while (depth > 0 && searchPos < source.length) {\n var tagIdx = source.indexOf('<', searchPos)\n if (tagIdx === -1) return null\n var tagParseResult = parseHTMLTag(source, tagIdx)\n if (!tagParseResult) {\n searchPos = tagIdx + 1\n continue\n }\n if (\n tagParseResult.isClosing &&\n tagParseResult.tagLower === tagNameLower &&\n --depth === 0\n )\n return [tagIdx, tagParseResult.endPos]\n if (\n !tagParseResult.isClosing &&\n !tagParseResult.isSelfClosing &&\n tagParseResult.tagLower === tagNameLower\n )\n depth++\n searchPos = tagParseResult.endPos\n }\n return null\n}\n\nexport const INTERPOLATION_R: RegExp = /^\\{.*\\}$/\nconst DOUBLE_NEWLINE_R = /\\n\\n/\nconst BLOCK_SYNTAX_R =\n /^(\\s{0,3}#[#\\s]|\\s{0,3}[-*+]\\s|\\s{0,3}\\d+\\.\\s|\\s{0,3}>\\s|\\s{0,3}```)/m\nconst TYPE1_TAG_R = /<\\/?(?:pre|script|style|textarea)\\b/i\nexport const UPPERCASE_TAG_R: RegExp = /^<[A-Z]/\nconst TRAILING_NEWLINE_R = /\\n$/\nconst BLOCK_START_CHARS_SET = new Set([\n '#',\n '>',\n '-',\n '*',\n '+',\n '`',\n '|',\n '0',\n '1',\n '2',\n '3',\n '4',\n '5',\n '6',\n '7',\n '8',\n '9',\n])\n\n/** Find the next occurrence of a character, ignoring escaped versions */\nfunction findUnescapedChar(\n source: string,\n startPos: number,\n endPos: number,\n targetChar: string\n): number {\n let i = startPos\n while (i < endPos) {\n if (source[i] === '\\\\' && i + 1 < endPos) {\n i += 2\n continue\n }\n if (source[i] === targetChar) return i\n i++\n }\n return -1\n}\n\ntype StyleTuple = [key: string, value: string]\n\nfunction addStyleToCollection(styles: StyleTuple[], buffer: string): void {\n var colonIndex = buffer.indexOf(':')\n if (colonIndex > 0) {\n var value = buffer.slice(colonIndex + 1).trim()\n var len = value.length\n if (len >= 2) {\n var first = value[0]\n if ((first === '\"' || first === \"'\") && value[len - 1] === first) {\n value = value.slice(1, -1)\n }\n }\n styles.push([buffer.slice(0, colonIndex).trim(), value])\n }\n}\n\nexport function parseStyleAttribute(styleString: string): StyleTuple[] {\n var styles: StyleTuple[] = []\n if (!styleString) return styles\n\n var buffer = ''\n var depth = 0\n var quoteChar = ''\n\n for (var i = 0; i < styleString.length; i++) {\n var char = styleString[i]\n\n if (char === '\"' || char === \"'\") {\n if (!quoteChar) {\n quoteChar = char\n depth++\n } else if (char === quoteChar) {\n quoteChar = ''\n depth--\n }\n } else if (char === '(' && util.endsWith(buffer, 'url')) {\n depth++\n } else if (char === ')' && depth > 0) {\n depth--\n } else if (char === ';' && depth === 0) {\n addStyleToCollection(styles, buffer)\n buffer = ''\n continue\n }\n\n buffer += char\n }\n\n addStyleToCollection(styles, buffer)\n\n return styles\n}\n\nfunction attributeValueToJSXPropValue(\n tag: MarkdownToJSX.HTMLTags,\n key: string,\n value: string,\n sanitizeUrlFn: (\n value: string,\n tag: string,\n attribute: string\n ) => string | null\n): any {\n if (key === 'style') {\n return parseStyleAttribute(value).reduce(\n function (styles, [k, v]) {\n const sanitized = sanitizeUrlFn(v, tag, k)\n if (sanitized != null) {\n styles[k.replace(/(-[a-z])/g, substr => substr[1].toUpperCase())] =\n sanitized\n }\n return styles\n },\n {} as { [key: string]: any }\n );\n }\n\n if (util.ATTRIBUTES_TO_SANITIZE.indexOf(key) !== -1) {\n return sanitizeUrlFn(\n value ? value.replace(UNESCAPE_R, '$1') : value,\n tag,\n key\n )\n }\n\n if (value.match(INTERPOLATION_R)) {\n value = value.slice(1, value.length - 1)\n value = value ? value.replace(UNESCAPE_R, '$1') : value\n }\n\n return value === 'true' ? true : value === 'false' ? false : value\n}\n\nfunction parseHTMLAttributes(\n attrs: string,\n tagName: string,\n tagNameOriginal: string,\n options: ParseOptions\n): { [key: string]: any } {\n const result: { [key: string]: any } = {}\n if (!attrs || !attrs.trim()) return result\n\n const attrMatches: string[] = []\n let i = 0\n const len = attrs.length\n while (i < len) {\n while (i < len && isSpaceOrTab(attrs[i])) i++\n if (i >= len) break\n const nameStart = i\n while (i < len && isNameChar(attrs[i])) i++\n if (i === nameStart) {\n i++\n continue\n }\n const name = attrs.slice(nameStart, i)\n while (i < len && isSpaceOrTab(attrs[i])) i++\n if (i >= len || attrs[i] !== '=') {\n attrMatches.push(name)\n continue\n }\n i++\n while (i < len && isSpaceOrTab(attrs[i])) i++\n if (i >= len) {\n attrMatches.push(name + '=')\n break\n }\n const valueStart = i\n const q = attrs[i]\n if (q === '\"' || q === \"'\") {\n i++\n while (i < len) {\n if (attrs[i] === q) {\n if (i + 1 >= len) {\n i++\n break\n }\n const nextChar = attrs[i + 1]\n if (isSpaceOrTab(nextChar) || nextChar === '/') {\n i++\n break\n }\n }\n i++\n }\n } else if (q === '{') {\n let depth = 1\n i++\n while (i < len && depth > 0) {\n if (attrs[i] === '{') depth++\n else if (attrs[i] === '}') {\n depth--\n if (depth === 0) {\n i++\n break\n }\n }\n i++\n }\n } else {\n while (i < len && !isSpaceOrTab(attrs[i])) i++\n }\n attrMatches.push(name + '=' + attrs.slice(valueStart, i))\n }\n\n if (!attrMatches?.length) return result\n const tagNameLower = tagName.toLowerCase(),\n isJSXComponent =\n tagNameOriginal.length > 0 &&\n tagNameOriginal[0] >= 'A' &&\n tagNameOriginal[0] <= 'Z'\n for (let i = 0; i < attrMatches.length; i++) {\n const rawAttr = attrMatches[i],\n delimiterIdx = rawAttr.indexOf('=')\n if (delimiterIdx !== -1) {\n const key = rawAttr.slice(0, delimiterIdx).trim(),\n keyLower = key.toLowerCase()\n if (keyLower === 'ref') continue\n const attrKey = isJSXComponent ? key : keyLower,\n rawValue = rawAttr.slice(delimiterIdx + 1).trim(),\n value = ((str: string) => {\n const first = str[0]\n if (\n (first === '\"' || first === \"'\") &&\n str.length >= 2 &&\n str[str.length - 1] === first\n )\n return str.slice(1, -1)\n return str\n })(rawValue)\n\n if (\n (keyLower === 'href' && tagNameLower === 'a') ||\n (keyLower === 'src' && tagNameLower === 'img')\n ) {\n const safe = options.sanitizer(\n value,\n tagNameLower as MarkdownToJSX.HTMLTags,\n keyLower\n )\n if (safe == null) {\n warn(`Stripped unsafe ${keyLower} on <${tagNameOriginal}>`)\n continue\n }\n result[attrKey] = safe\n } else {\n const normalizedValue = attributeValueToJSXPropValue(\n tagNameLower as MarkdownToJSX.HTMLTags,\n keyLower,\n value,\n options.sanitizer\n )\n result[attrKey] = normalizedValue\n }\n } else if (rawAttr !== 'style')\n result[isJSXComponent ? rawAttr : rawAttr.toLowerCase()] = true\n }\n if (util.SANITIZE_R.test(decodeURIComponent(attrs)))\n for (const key in result) delete result[key]\n return result\n}\n\nexport type ParseResult = (MarkdownToJSX.ASTNode & { endPos: number }) | null\n\n/** Options passed to parsers */\nexport type ParseOptions = Omit<MarkdownToJSX.Options, 'slugify'> & {\n slugify: (input: string) => string\n}\n\nvar isBlockStartChar = function (c: string): boolean {\n return BLOCK_START_CHARS_SET.has(c)\n}\n\ninterface BracketEntry {\n type: 'link' | 'image'\n pos: number\n resultIdx: number\n inAnchor: boolean\n}\n\n// Check if an invalid reference definition should be skipped per CommonMark Examples 208 and 210\nfunction shouldSkipInvalidReferenceDefinition(\n input: string,\n refCheckPos: number,\n isAtDocumentStart: boolean\n): { shouldSkip: boolean; newPos: number } {\n // Find closing ']' handling escapes\n let bracketEnd = refCheckPos + 1\n while (bracketEnd < input.length && input[bracketEnd] !== ']') {\n if (input[bracketEnd] === '\\\\' && bracketEnd + 1 < input.length) {\n bracketEnd += 2\n continue\n }\n bracketEnd++\n }\n if (bracketEnd >= input.length) return { shouldSkip: false, newPos: 0 }\n\n // Check if label starts/ends with newline (Example 208 pattern)\n const labelStart = refCheckPos + 1\n const labelEnd = bracketEnd\n const labelStartsWithNewline =\n labelStart < labelEnd &&\n (input[labelStart] === '\\n' || input[labelStart] === '\\r')\n const labelEndsWithNewline =\n labelEnd > labelStart &&\n (input[labelEnd - 1] === '\\n' || input[labelEnd - 1] === '\\r')\n\n let afterBracket = bracketEnd + 1\n // Skip whitespace after ']'\n afterBracket = util.skipWhitespace(input, afterBracket)\n\n // Check for colon\n if (afterBracket >= input.length || input[afterBracket] !== ':') {\n return { shouldSkip: false, newPos: 0 }\n }\n\n // Found colon - check for Example 208 pattern (label starts/ends with newline at document start)\n if ((labelStartsWithNewline || labelEndsWithNewline) && isAtDocumentStart) {\n // Invalid ref definition per Example 208 - skip to next line after URL\n let skipPos = afterBracket + 1\n skipPos = util.skipWhitespace(input, skipPos)\n // Skip optional newline\n if (skipPos < input.length && input[skipPos] === '\\n') {\n skipPos = util.skipWhitespace(input, skipPos + 1)\n }\n // Find end of URL line (next newline)\n while (skipPos < input.length && input[skipPos] !== '\\n') {\n skipPos++\n }\n if (skipPos < input.length) {\n skipPos++\n }\n return { shouldSkip: true, newPos: skipPos }\n }\n\n // Check for Example 210 pattern (trailing text after title)\n return checkExample210Pattern(input, afterBracket)\n}\n\n// Helper for Example 210: trailing text after title\nfunction checkExample210Pattern(\n input: string,\n colonPos: number\n): { shouldSkip: boolean; newPos: number } {\n let urlEnd = colonPos + 1\n urlEnd = util.skipWhitespace(input, urlEnd)\n // Skip optional newline\n if (urlEnd < input.length && input[urlEnd] === '\\n') {\n urlEnd = util.skipWhitespace(input, urlEnd + 1)\n }\n // Find end of URL (next newline)\n while (urlEnd < input.length && input[urlEnd] !== '\\n') {\n urlEnd++\n }\n if (urlEnd >= input.length) return { shouldSkip: false, newPos: 0 }\n\n urlEnd++\n // Check for title delimiter on next line\n let titleLineStart = util.skipWhitespace(input, urlEnd)\n if (\n titleLineStart >= input.length ||\n (input[titleLineStart] !== '\"' && input[titleLineStart] !== \"'\")\n ) {\n return { shouldSkip: false, newPos: 0 }\n }\n\n // Has title delimiter - check for trailing text (Example 210)\n const titleChar = input[titleLineStart]\n let titleEnd = titleLineStart + 1\n while (\n titleEnd < input.length &&\n input[titleEnd] !== titleChar &&\n input[titleEnd] !== '\\n'\n ) {\n if (input[titleEnd] === '\\\\' && titleEnd + 1 < input.length) {\n titleEnd += 2\n continue\n }\n titleEnd++\n }\n if (titleEnd >= input.length || input[titleEnd] !== titleChar) {\n return { shouldSkip: false, newPos: 0 }\n }\n\n // Found closing quote - check for trailing text\n let afterTitle = util.skipWhitespace(input, titleEnd + 1)\n if (\n afterTitle < input.length &&\n input[afterTitle] !== '\\n' &&\n input[afterTitle] !== '\\r'\n ) {\n // Trailing text found - invalid ref definition per Example 210\n return { shouldSkip: true, newPos: urlEnd }\n }\n\n return { shouldSkip: false, newPos: 0 }\n}\n\n// Check if nodes contain a link (prevents nested links per CommonMark)\nfunction containsLink(nodes: MarkdownToJSX.ASTNode[]): boolean {\n for (var i = 0; i < nodes.length; i++) {\n var node = nodes[i]\n if (node.type === RuleType.link) return true\n if (node.type === RuleType.textFormatted) {\n var formattedNode = node as MarkdownToJSX.FormattedTextNode\n if (formattedNode.children && containsLink(formattedNode.children))\n return true\n }\n }\n return false\n}\n\nfunction extractAllTextFromNodes(nodes: MarkdownToJSX.ASTNode[]): string {\n var text = ''\n for (var i = 0, len = nodes.length; i < len; i++) {\n var node = nodes[i]\n var type = node.type\n if (type === RuleType.text) {\n text += (node as MarkdownToJSX.TextNode).text\n } else if (type === RuleType.image) {\n var imgNode = node as MarkdownToJSX.ImageNode\n if (imgNode.alt) text += imgNode.alt\n } else if (type === RuleType.textFormatted) {\n var formattedNode = node as MarkdownToJSX.FormattedTextNode\n if (formattedNode.children) {\n text += extractAllTextFromNodes(formattedNode.children)\n }\n } else if (type === RuleType.link) {\n var linkNode = node as MarkdownToJSX.LinkNode\n if (linkNode.children) {\n text += extractAllTextFromNodes(linkNode.children)\n }\n }\n }\n return text\n}\n\nconst WHITESPACE_CHARS = new Set([' ', '\\t', '\\r', '\\n', '\\f', '\\v'])\n\n/**\n * Single pass, no recursion, eliminates parseLink/parseImage/parseRefLink/parseRefImage functions\n */\nfunction parseInlineSpan(\n source: string,\n start: number,\n end: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): MarkdownToJSX.ASTNode[] {\n var result: MarkdownToJSX.ASTNode[] = []\n var delimiterStack: DelimiterEntry[] = []\n var bracketStack: BracketEntry[] = []\n\n var pos = start\n var textStart = start\n var skipAutoLink = options.disableAutoLink || state.inAnchor\n var hasAmpersand = false\n var inAnchor = !!state.inAnchor\n var disableParsingRawHTML = !!options.disableParsingRawHTML\n\n // Helper: handle HTML tag parsing (angle brace autolinks, comments, tags, type 7 blocks)\n var handleHTMLTag = function (\n checkType7Block: boolean,\n respectDisableAutoLink: boolean\n ): boolean {\n if (!inAnchor && (!respectDisableAutoLink || !options.disableAutoLink)) {\n var angleBraceResult = parseLinkOrImage(source, pos, state, options, '<')\n if (angleBraceResult) {\n flushText(pos)\n result.push(angleBraceResult)\n pos = angleBraceResult.endPos\n textStart = pos\n return true\n }\n }\n\n // Skip HTML parsing if disableParsingRawHTML is enabled\n if (disableParsingRawHTML) {\n return false\n }\n\n var htmlResult = parseHTML(source, pos, state, options)\n if (htmlResult) {\n flushText(pos)\n result.push(htmlResult)\n pos = htmlResult.endPos\n textStart = pos\n return true\n }\n\n if (!checkType7Block) return false\n var tagCheckResult = parseHTMLTag(source, pos)\n if (!tagCheckResult) return false\n var tagNameStart = pos + (tagCheckResult.isClosing ? 2 : 1)\n if (tagNameStart >= source.length || isSpaceOrTab(source[tagNameStart]))\n return false\n var closeIdx = source.indexOf('>', pos + 1)\n if (closeIdx !== -1) {\n var contentStart = pos + 1\n var contentLen = closeIdx - contentStart\n if (contentLen >= 7) {\n var isHttp = util.startsWith(source, 'http://', contentStart)\n if (isHttp || util.startsWith(source, 'https://', contentStart)) {\n for (var j = contentStart; j < closeIdx; j++) {\n if (isSpaceOrTab(source[j])) return false\n }\n }\n }\n }\n var tagFirstCharCode = charCode(source, tagNameStart)\n if (\n isAlphaCode(tagFirstCharCode) &&\n tagNameStart + 1 < source.length &&\n source[tagNameStart + 1] === ':'\n )\n return false\n if (tagCheckResult.isClosing && tagCheckResult.attrs.trim().length)\n return false\n\n if (tagCheckResult.attrs.length) {\n var inQuotes = false\n var quoteChar = ''\n for (var i = 0; i < tagCheckResult.attrs.length; i++) {\n var ch = tagCheckResult.attrs[i]\n if (inQuotes && ch === quoteChar) {\n inQuotes = false\n } else if (!inQuotes && (ch === '\"' || ch === \"'\")) {\n inQuotes = true\n quoteChar = ch\n } else if (ch === '*' || ch === '#' || ch === '!') {\n var checkAhead = i + 1\n while (\n checkAhead < tagCheckResult.attrs.length &&\n tagCheckResult.attrs[checkAhead] !== '=' &&\n tagCheckResult.attrs[checkAhead] !== ' ' &&\n tagCheckResult.attrs[checkAhead] !== '\\t'\n )\n checkAhead++\n if (\n checkAhead < tagCheckResult.attrs.length &&\n tagCheckResult.attrs[checkAhead] === '='\n )\n return false\n }\n }\n }\n\n // Valid tag with newline - type 7 block, preserve as raw HTML\n var htmlBlockResult = {\n type: RuleType.htmlBlock,\n tag: tagCheckResult.tagName as MarkdownToJSX.HTMLTags,\n attrs: {},\n children: [],\n text: source.slice(pos, tagCheckResult.endPos),\n noInnerParse: true,\n endPos: tagCheckResult.endPos,\n } as MarkdownToJSX.HTMLNode & { endPos: number }\n flushText(pos)\n result.push(htmlBlockResult)\n pos = htmlBlockResult.endPos\n textStart = pos\n return true\n }\n\n var flushText = function (endPos: number) {\n if (endPos > textStart) {\n var text = source.slice(textStart, endPos)\n result.push({\n type: RuleType.text,\n text: hasAmpersand ? util.decodeEntityReferences(text) : text,\n } as MarkdownToJSX.TextNode)\n textStart = endPos\n hasAmpersand = false\n }\n }\n\n while (pos < end) {\n var code = charCode(source, pos)\n var charType = getCharType(code, skipAutoLink)\n\n if (charType === 0) {\n if (code === $.CHAR_AMPERSAND) hasAmpersand = true\n pos++\n // Fast path for ASCII text - avoid repeated charCode calls and lookups\n while (pos < end) {\n code = charCode(source, pos)\n if (code >= $.CHAR_ASCII_BOUNDARY) break\n if (code === $.CHAR_AMPERSAND) hasAmpersand = true\n var lookupCharType = util.inlineCharTypeTable[code]\n if (lookupCharType !== 0) {\n // Check for autolink exception\n if (\n skipAutoLink &&\n lookupCharType === 1 &&\n (code === $.CHAR_f || code === $.CHAR_H || code === $.CHAR_W)\n ) {\n pos++\n continue\n }\n break\n }\n pos++\n }\n continue\n }\n\n // CODE SPANS (highest priority, no nesting)\n if (code === $.CHAR_BACKTICK) {\n var backtickStart = pos\n var backtickCount = 0\n while (pos + backtickCount < end) {\n if (charCode(source, pos + backtickCount) !== $.CHAR_BACKTICK) break\n backtickCount++\n }\n\n if (backtickCount > 0) {\n var contentStart = pos + backtickCount\n var contentEnd = -1\n var i = contentStart\n // Scan character by character for closing backticks - faster than indexOf\n while (i < end) {\n // Find next backtick\n while (i < end && charCode(source, i) !== $.CHAR_BACKTICK) i++\n if (i >= end) break\n\n // Count consecutive backticks\n var closingCount = 0\n while (\n i + closingCount < end &&\n charCode(source, i + closingCount) === $.CHAR_BACKTICK\n ) {\n closingCount++\n }\n if (closingCount > backtickCount) closingCount = backtickCount\n var j = i + closingCount\n\n // Check if this is a valid closing sequence\n if (\n closingCount === backtickCount &&\n (i <= contentStart ||\n charCode(source, i - 1) !== $.CHAR_BACKTICK) &&\n (j >= end || charCode(source, j) !== $.CHAR_BACKTICK)\n ) {\n contentEnd = i\n i = j\n break\n }\n i++\n }\n\n if (contentEnd !== -1) {\n var rawContent = source.slice(contentStart, contentEnd)\n var hasNewline = false\n for (var k = 0; k < rawContent.length; k++) {\n var nlCode = charCode(rawContent, k)\n if (nlCode === $.CHAR_NEWLINE || nlCode === $.CHAR_CR) {\n hasNewline = true\n break\n }\n }\n var content = rawContent\n if (hasNewline) {\n // Optimize newline replacement by avoiding regex\n content = rawContent\n .replace(/\\r\\n/g, ' ')\n .replace(/\\r/g, ' ')\n .replace(/\\n/g, ' ')\n }\n if (content.length > 0) {\n var firstChar = charCode(content, 0)\n var lastChar = charCode(content, content.length - 1)\n if (firstChar === $.CHAR_SPACE && lastChar === $.CHAR_SPACE) {\n for (var idx = 1; idx < content.length - 1; idx++) {\n if (charCode(content, idx) !== $.CHAR_SPACE) {\n content = content.slice(1, content.length - 1)\n break\n }\n }\n }\n }\n\n flushText(backtickStart)\n result.push({\n type: RuleType.codeInline,\n text: content,\n } as MarkdownToJSX.CodeInlineNode)\n pos = i\n textStart = pos\n continue\n }\n pos = contentStart\n continue\n }\n }\n\n // AUTOLINKS: BARE URLS AND EMAIL (check BEFORE escapes to preserve backslashes in URLs)\n if (\n !inAnchor &&\n !skipAutoLink &&\n (code === $.CHAR_f || code === $.CHAR_H || code === $.CHAR_W)\n ) {\n var autolinkType: 'h' | 'w' | 'f' | null = null\n // Cache character codes to avoid repeated function calls\n var c1 = pos + 1 < end ? charCode(source, pos + 1) : 0\n var c2 = pos + 2 < end ? charCode(source, pos + 2) : 0\n var c3 = pos + 3 < end ? charCode(source, pos + 3) : 0\n var c4 = pos + 4 < end ? charCode(source, pos + 4) : 0\n var c5 = pos + 5 < end ? charCode(source, pos + 5) : 0\n\n if (\n code === $.CHAR_H &&\n c1 === $.CHAR_t &&\n c2 === $.CHAR_t &&\n c3 === $.CHAR_p\n ) {\n autolinkType = 'h'\n } else if (\n code === $.CHAR_W &&\n c1 === $.CHAR_W &&\n c2 === $.CHAR_W &&\n c3 === $.CHAR_PERIOD\n ) {\n autolinkType = 'w'\n } else if (\n code === $.CHAR_f &&\n c1 === $.CHAR_t &&\n c2 === $.CHAR_p &&\n c3 === $.CHAR_COLON &&\n c4 === $.CHAR_SLASH &&\n c5 === $.CHAR_SLASH\n ) {\n autolinkType = 'f'\n }\n if (autolinkType) {\n var bareUrlResult = parseLinkOrImage(\n source,\n pos,\n state,\n options,\n autolinkType\n )\n if (bareUrlResult) {\n flushText(pos)\n result.push(bareUrlResult)\n pos = bareUrlResult.endPos\n textStart = pos\n continue\n }\n }\n }\n\n if (!inAnchor && !skipAutoLink && code === $.CHAR_AT) {\n var emailResult = parseLinkOrImage(source, pos, state, options, '@')\n if (emailResult && 'emailStart' in emailResult) {\n var emailStart = (\n emailResult as MarkdownToJSX.LinkNode & {\n endPos: number\n emailStart: number\n }\n ).emailStart\n var emailEnd = emailResult.endPos\n var removedIndices: number[] = []\n for (var j = delimiterStack.length - 1; j >= 0; j--) {\n var delim = delimiterStack[j]\n if (delim.sourcePos >= emailStart && delim.sourcePos < emailEnd) {\n if (delim.nodeIndex >= 0 && delim.nodeIndex < result.length) {\n result.splice(delim.nodeIndex, 1)\n removedIndices.push(delim.nodeIndex)\n }\n delimiterStack.splice(j, 1)\n }\n }\n if (emailStart < textStart) {\n for (var i = result.length - 1; i >= 0; i--) {\n if (result[i].type === RuleType.text) {\n result.splice(i, 1)\n removedIndices.push(i)\n break\n }\n }\n textStart = emailStart\n }\n // Batch update delimiter indices after all removals (O(n+m) instead of O(n*m))\n if (removedIndices.length) {\n removedIndices.sort(function (a, b) {\n return a - b\n })\n var removedIdx = 0\n for (var m = 0; m < delimiterStack.length; m++) {\n var delim = delimiterStack[m]\n while (\n removedIdx < removedIndices.length &&\n removedIndices[removedIdx] < delim.nodeIndex\n )\n removedIdx++\n delim.nodeIndex -= removedIdx\n }\n }\n flushText(emailStart)\n result.push(emailResult)\n pos = emailEnd\n textStart = pos\n continue\n }\n }\n\n // HTML TAGS AND AUTOLINKS (check BEFORE escapes to preserve backslashes in autolinks)\n if (code === $.CHAR_LT) {\n if (handleHTMLTag(true, false)) continue\n }\n\n // BACKSLASH ESCAPES\n if (code === $.CHAR_BACKSLASH) {\n if (pos + 1 < end && charCode(source, pos + 1) === $.CHAR_NEWLINE) {\n var afterNewline = pos + 2\n while (\n afterNewline < end &&\n charCode(source, afterNewline) === $.CHAR_SPACE\n )\n afterNewline++\n if (afterNewline >= end) {\n pos++\n continue\n }\n flushText(pos)\n result.push({ type: RuleType.breakLine } as MarkdownToJSX.BreakLineNode)\n pos += 2\n while (pos < end && charCode(source, pos) === $.CHAR_SPACE) pos++\n textStart = pos\n continue\n }\n\n var nextChar = pos + 1 < end ? source[pos + 1] : ''\n if (\n nextChar &&\n '!\"#$%&\\'()*+,-./:;<=>?@[\\\\]^_`{|}~'.indexOf(nextChar) !== -1\n ) {\n flushText(pos)\n result.push({\n type: RuleType.text,\n text: nextChar === '&' ? '&\\u200B' : nextChar,\n } as MarkdownToJSX.TextNode)\n pos += 2\n textStart = pos\n continue\n }\n }\n\n // LINKS AND IMAGES - OPENING BRACKET\n if (code === $.CHAR_BRACKET_OPEN) {\n if (!inAnchor) {\n if (pos + 1 < end && source[pos + 1] === '^') {\n var footnoteEndPos = pos + 2\n while (footnoteEndPos < end && source[footnoteEndPos] !== ']')\n footnoteEndPos++\n if (footnoteEndPos < end) {\n var identifier = source.slice(pos + 2, footnoteEndPos)\n flushText(pos)\n result.push({\n type: RuleType.footnoteReference,\n target: `#${options.slugify(identifier)}`,\n text: identifier,\n } as MarkdownToJSX.FootnoteReferenceNode)\n pos = footnoteEndPos + 1\n textStart = pos\n continue\n }\n }\n\n if (\n state.inList &&\n pos + 2 < end &&\n charCode(source, pos + 2) === $.CHAR_BRACKET_CLOSE\n ) {\n var nextCode = charCode(source, pos + 1)\n if (\n nextCode === $.CHAR_SPACE ||\n nextCode === $.CHAR_x ||\n nextCode === $.CHAR_X\n ) {\n flushText(pos)\n result.push({\n type: RuleType.gfmTask,\n completed: nextCode === $.CHAR_x || nextCode === $.CHAR_X,\n } as MarkdownToJSX.GFMTaskNode)\n pos += 3\n textStart = pos\n continue\n }\n }\n }\n\n var isImage = false\n if (pos > start && source[pos - 1] === '!') {\n var backslashCount = 0\n for (\n var checkPos = pos - 2;\n checkPos >= start && source[checkPos] === '\\\\';\n checkPos--\n )\n backslashCount++\n if ((backslashCount & 1) === 0) {\n isImage = true\n if (textStart < pos - 1) flushText(pos - 1)\n if (\n result.length > 0 &&\n result[result.length - 1].type === RuleType.text\n ) {\n var lastText = result[result.length - 1] as MarkdownToJSX.TextNode\n if (lastText.text.endsWith('!')) {\n lastText.text = lastText.text.slice(0, -1)\n if (!lastText.text) result.pop()\n }\n }\n }\n }\n if (!isImage) flushText(pos)\n textStart = pos + 1\n if (!inAnchor || isImage) {\n bracketStack.push({\n type: isImage ? 'image' : 'link',\n pos: isImage ? pos - 1 : pos,\n resultIdx: result.length,\n inAnchor: inAnchor,\n })\n }\n\n pos++\n continue\n }\n\n // LINKS AND IMAGES - CLOSING BRACKET\n if (code === $.CHAR_BRACKET_CLOSE && bracketStack.length > 0) {\n var bracket = bracketStack[bracketStack.length - 1]\n var linkTextStart = bracket.pos + (bracket.type === 'image' ? 2 : 1)\n var linkTextEnd = pos\n flushText(pos)\n var afterBracket = pos + 1\n var linkChildren = buildLinkChildren(result, bracket)\n var hasNestedLink = bracket.type === 'link' && containsLink(linkChildren)\n var foundRefBrackets = false\n\n if (\n !hasNestedLink &&\n afterBracket < end &&\n source[afterBracket] === '('\n ) {\n var urlResult = parseUrlAndTitle(source, afterBracket + 1, true)\n if (urlResult) {\n finalizeLinkOrImageNode(\n result,\n delimiterStack,\n bracketStack,\n bracket,\n linkTextStart,\n linkTextEnd,\n options.sanitizer(\n unescapeUrlOrTitle(urlResult.target),\n 'a',\n 'href'\n ),\n urlResult.title ? unescapeUrlOrTitle(urlResult.title) : undefined\n )\n pos = urlResult.endPos\n textStart = pos\n continue\n }\n }\n\n var refs = state.refs || {}\n util.hasKeys(refs);\n var refLabel: string | null = null\n var refEnd = pos\n if (afterBracket < end && source[afterBracket] === '[') {\n var refStart = afterBracket + 1\n var i = refStart\n while (i < end && source[i] !== ']') i++\n if (i < end) {\n refLabel = source.slice(refStart, i)\n refEnd = i\n foundRefBrackets = true\n }\n }\n if (!foundRefBrackets || refLabel === '')\n refLabel = source.slice(linkTextStart, linkTextEnd)\n var normalizedRef = normalizeReferenceLabel(refLabel)\n if (!hasNestedLink && refs && refs[normalizedRef]) {\n var ref = refs[normalizedRef]\n finalizeLinkOrImageNode(\n result,\n delimiterStack,\n bracketStack,\n bracket,\n linkTextStart,\n linkTextEnd,\n ref.target,\n ref.title\n )\n pos = refEnd + 1\n textStart = pos\n continue\n }\n\n var bracketResultIdx = bracket.resultIdx\n bracketStack.pop()\n result.length = bracketResultIdx\n if (bracket.type === 'image')\n result.push({\n type: RuleType.text,\n text: '!',\n } as MarkdownToJSX.TextNode)\n result.push(\n { type: RuleType.text, text: '[' } as MarkdownToJSX.TextNode,\n ...linkChildren,\n { type: RuleType.text, text: ']' } as MarkdownToJSX.TextNode\n )\n for (var k = 0; k < delimiterStack.length; k++) {\n if (delimiterStack[k].nodeIndex >= bracketResultIdx)\n delimiterStack[k].nodeIndex++\n }\n pos++\n textStart = pos\n continue\n }\n\n // ========================================\n // EMPHASIS AND STRIKETHROUGH DELIMITERS (*, _, ~~, ==)\n // ========================================\n if (\n code === $.CHAR_ASTERISK ||\n code === $.CHAR_UNDERSCORE ||\n code === $.CHAR_TILDE ||\n code === $.CHAR_EQ\n ) {\n var delimChar = source[pos]\n var delimStart = pos\n var delimCount = countConsecutiveChars(source, pos, delimChar)\n\n // GFM strikethrough (~~) and marked text (==) require exactly 2 delimiters\n if ((delimChar === '~' || delimChar === '=') && delimCount !== 2) {\n pos++\n continue\n }\n\n var delimiterEnd = delimStart + delimCount\n var leftFlanking = checkFlanking(source, delimStart, delimiterEnd, end, 0)\n var rightFlanking = checkFlanking(\n source,\n delimStart,\n delimiterEnd,\n start,\n 1\n )\n var canOpen = leftFlanking\n var canClose = rightFlanking\n if (delimChar === '_' && leftFlanking && rightFlanking) {\n if (delimStart > 0) {\n var precedingChar = source[delimStart - 1]\n var precedingCode = charCode(precedingChar)\n canOpen = isPunctuation(precedingCode, precedingChar)\n }\n if (delimiterEnd < end) {\n var followingChar = source[delimiterEnd]\n var followingCode = charCode(followingChar)\n canClose = isPunctuation(followingCode, followingChar)\n }\n }\n flushText(delimStart)\n delimiterStack.push({\n nodeIndex: result.length,\n type: delimChar as '*' | '_' | '~' | '=',\n length: delimCount,\n canOpen: canOpen,\n canClose: canClose,\n active: true,\n sourcePos: delimStart,\n inAnchor: inAnchor,\n })\n result.push({\n type: RuleType.text,\n text: source.slice(delimStart, delimStart + delimCount),\n } as MarkdownToJSX.TextNode)\n\n pos = delimStart + delimCount\n textStart = pos\n continue\n }\n\n // ========================================\n // LINE BREAKS\n // ========================================\n if (code === $.CHAR_NEWLINE) {\n var checkPos = pos - 1\n var spaceCount = 0\n while (\n checkPos >= textStart &&\n charCode(source, checkPos) === $.CHAR_SPACE\n ) {\n spaceCount++\n checkPos--\n }\n if (spaceCount >= 2) {\n var afterNewline = pos + 1\n while (\n afterNewline < end &&\n charCode(source, afterNewline) === $.CHAR_SPACE\n )\n afterNewline++\n if (afterNewline >= end) {\n flushText(checkPos + 1)\n pos = end\n textStart = end\n continue\n }\n flushText(checkPos + 1)\n result.push({ type: RuleType.breakLine } as MarkdownToJSX.BreakLineNode)\n pos++\n while (pos < end && charCode(source, pos) === $.CHAR_SPACE) pos++\n textStart = pos\n continue\n }\n\n var prevCode = pos > textStart ? charCode(source, pos - 1) : 0\n var nextCode = pos + 1 < end ? charCode(source, pos + 1) : 0\n var flushPos =\n pos > textStart &&\n prevCode === $.CHAR_SPACE &&\n nextCode === $.CHAR_SPACE\n ? pos - 1\n : pos\n flushText(flushPos)\n result.push({ type: RuleType.text, text: '\\n' } as MarkdownToJSX.TextNode)\n textStart = pos + 1\n if (\n pos > start &&\n prevCode === $.CHAR_SPACE &&\n textStart < end &&\n charCode(source, textStart) === $.CHAR_SPACE\n )\n textStart++\n pos = textStart\n continue\n }\n\n if (code === $.CHAR_AMPERSAND) hasAmpersand = true\n pos++\n while (pos < end) {\n var code = charCode(source, pos)\n if (code >= $.CHAR_ASCII_BOUNDARY) break\n if (code === $.CHAR_AMPERSAND) hasAmpersand = true\n var lookupCharType = util.inlineCharTypeTable[code]\n if (lookupCharType === 0) {\n pos++\n continue\n }\n if (\n lookupCharType === 1 &&\n (code === $.CHAR_f || code === $.CHAR_H || code === $.CHAR_W) &&\n skipAutoLink\n ) {\n pos++\n continue\n }\n break\n }\n }\n\n flushText(pos)\n\n // Process emphasis using delimiter stack algorithm\n if (delimiterStack.length) {\n processEmphasis(result, delimiterStack, null)\n }\n\n // Insert bracket text nodes in forward order (more efficient than reverse splices)\n if (bracketStack.length) {\n bracketStack.sort(function (a, b) {\n return a.resultIdx - b.resultIdx\n })\n for (var i = 0; i < bracketStack.length; i++) {\n result.splice(bracketStack[i].resultIdx + i, 0, {\n type: RuleType.text,\n text: bracketStack[i].type === 'image' ? '![' : '[',\n } as MarkdownToJSX.TextNode)\n }\n }\n\n return result\n}\n\n// Helper: Process emphasis within link/image text and update delimiter stack\nfunction processEmphasisInLinkText(\n result: MarkdownToJSX.ASTNode[],\n delimiterStack: DelimiterEntry[],\n bracket: BracketEntry,\n linkTextStart: number,\n linkTextEnd: number\n): void {\n var hasDelims = false\n for (var di = 0; di < delimiterStack.length; di++) {\n if (\n delimiterStack[di].sourcePos >= linkTextStart &&\n delimiterStack[di].sourcePos < linkTextEnd\n ) {\n hasDelims = true\n break\n }\n }\n if (!hasDelims) return\n\n var tempNodes = buildLinkChildren(result, bracket)\n var tempDelims: DelimiterEntry[] = []\n for (var di = 0; di < delimiterStack.length; di++) {\n var delim = delimiterStack[di]\n if (delim.sourcePos >= linkTextStart && delim.sourcePos < linkTextEnd) {\n tempDelims.push({\n nodeIndex: delim.nodeIndex - bracket.resultIdx,\n type: delim.type,\n length: delim.length,\n canOpen: delim.canOpen,\n canClose: delim.canClose,\n active: delim.active,\n sourcePos: delim.sourcePos,\n inAnchor: delim.inAnchor,\n })\n }\n }\n processEmphasis(tempNodes, tempDelims, null)\n result.length = bracket.resultIdx\n for (var i = 0; i < tempNodes.length; i++) result.push(tempNodes[i])\n var newDelimStack: DelimiterEntry[] = []\n for (var di = 0; di < delimiterStack.length; di++) {\n if (\n delimiterStack[di].sourcePos < linkTextStart ||\n delimiterStack[di].sourcePos >= linkTextEnd\n ) {\n newDelimStack.push(delimiterStack[di])\n }\n }\n delimiterStack.length = 0\n for (var i = 0; i < newDelimStack.length; i++)\n delimiterStack.push(newDelimStack[i])\n}\n\n// Helper: Create link or image node from children and target/title\nfunction createLinkOrImageNode(\n bracket: BracketEntry,\n linkChildren: MarkdownToJSX.ASTNode[],\n target: string | null,\n title: string | undefined\n): MarkdownToJSX.ASTNode {\n if (bracket.type === 'link') {\n return {\n type: RuleType.link,\n target: target,\n title: title,\n children: linkChildren,\n } as MarkdownToJSX.LinkNode\n }\n return {\n type: RuleType.image,\n target: target || '',\n alt: extractAllTextFromNodes(linkChildren),\n title: title,\n } as MarkdownToJSX.ImageNode\n}\n\nfunction buildLinkChildren(\n result: MarkdownToJSX.ASTNode[],\n bracket: BracketEntry\n): MarkdownToJSX.ASTNode[] {\n return result.slice(bracket.resultIdx)\n}\n\nfunction finalizeLinkOrImageNode(\n result: MarkdownToJSX.ASTNode[],\n delimiterStack: DelimiterEntry[],\n bracketStack: BracketEntry[],\n bracket: BracketEntry,\n linkTextStart: number,\n linkTextEnd: number,\n target: string | null,\n title: string | undefined\n): void {\n processEmphasisInLinkText(\n result,\n delimiterStack,\n bracket,\n linkTextStart,\n linkTextEnd\n )\n var linkChildren = buildLinkChildren(result, bracket)\n bracketStack.pop()\n result.length = bracket.resultIdx\n result.push(createLinkOrImageNode(bracket, linkChildren, target, title))\n}\n\n/** Parse URL and optional title from parentheses: (url \"title\") */\n// Parse link destination (URL) - handles angle brackets and regular URLs\nfunction parseLinkDestination(\n source: string,\n start: number,\n allowNestedParens: boolean\n): { target: string; endPos: number; hadSpace: boolean } | null {\n let i = util.skipWhitespace(source, start)\n const hasAngleBrackets = i < source.length && source[i] === '<'\n if (hasAngleBrackets) i++\n const actualUrlStart = i\n\n // Handle empty angle brackets <>\n if (hasAngleBrackets && i < source.length && source[i] === '>') {\n return { target: '', endPos: i + 1, hadSpace: false }\n }\n\n let target: string\n let urlEnd: number\n var foundSpace = false\n\n if (hasAngleBrackets) {\n // For angle bracket URLs, parse until '>', allowing spaces and handling escapes\n urlEnd = i\n while (urlEnd < source.length && source[urlEnd] !== '>') {\n const c = source[urlEnd]\n if (c === '\\n' || c === '\\r' || c === '<') return null\n if (c === '\\\\') {\n urlEnd += 2\n continue\n }\n urlEnd++\n }\n if (urlEnd >= source.length || source[urlEnd] !== '>') return null\n urlEnd++\n // Trim leading and trailing whitespace inside < >\n let actualStart = actualUrlStart\n while (actualStart < urlEnd - 1 && isSpaceOrTab(source[actualStart]))\n actualStart++\n let actualEnd = urlEnd - 1\n while (actualEnd > actualStart && isSpaceOrTab(source[actualEnd - 1]))\n actualEnd--\n target = source.slice(actualStart, actualEnd)\n i = urlEnd\n } else {\n // Non-angle bracket URL: break on whitespace, newline\n let parenDepth = 0\n urlEnd = i\n while (urlEnd < source.length) {\n const c = source[urlEnd]\n if (c === ' ' || c === '\\t' || c === '\\n') {\n foundSpace = true\n break\n }\n if (!allowNestedParens && c === ')') break\n if (allowNestedParens && c === '(') {\n if (urlEnd > 0 && source[urlEnd - 1] === '\\\\') {\n urlEnd++\n continue\n }\n parenDepth++\n urlEnd++\n continue\n }\n if (allowNestedParens && c === ')') {\n if (urlEnd > 0 && source[urlEnd - 1] === '\\\\') {\n urlEnd++\n continue\n }\n if (parenDepth === 0) break\n parenDepth--\n urlEnd++\n continue\n }\n urlEnd++\n }\n target = source.slice(actualUrlStart, urlEnd)\n i = urlEnd\n }\n\n return { target, endPos: i, hadSpace: foundSpace }\n}\n\n// Parse link title - handles quoted and parenthesized titles\nfunction parseLinkTitle(\n source: string,\n start: number,\n hadSpaceInUrl: boolean,\n hasAngleBrackets: boolean\n): { title: string | undefined; endPos: number } {\n let i = start\n // Skip whitespace after URL\n let newlineCount = 0\n while (i < source.length) {\n const c = source[i]\n if (isSpaceOrTab(c)) {\n i++\n } else if (c === '\\n') {\n if (newlineCount >= 1) break\n newlineCount++\n i++\n } else if (util.isUnicodeWhitespace(c)) {\n break\n } else {\n break\n }\n }\n\n // If URL contained spaces and there's no title delimiter, the link is invalid\n if (hadSpaceInUrl && !hasAngleBrackets) {\n if (\n i >= source.length ||\n (source[i] !== '\"' && source[i] !== \"'\" && source[i] !== '(')\n ) {\n return { title: undefined, endPos: i }\n }\n }\n let title: string | undefined = undefined\n if (i < source.length) {\n const titleChar = source[i]\n if (titleChar === '\"' || titleChar === \"'\") {\n i++\n const titleStart = i\n while (i < source.length && source[i] !== titleChar) {\n if (source[i] === '\\\\') i++\n i++\n }\n if (i < source.length) {\n title = source.slice(titleStart, i)\n i++\n }\n } else if (titleChar === '(') {\n i++\n const titleStart = i\n let parenDepth = 1\n while (i < source.length && parenDepth > 0) {\n if (source[i] === '\\\\' && i + 1 < source.length) i++\n else if (source[i] === '(') parenDepth++\n else if (source[i] === ')') parenDepth--\n i++\n }\n if (parenDepth === 0) {\n title = source.slice(titleStart, i - 1)\n }\n }\n }\n\n i = util.skipWhitespace(source, i)\n return { title, endPos: i }\n}\n\nfunction parseUrlAndTitle(\n source: string,\n urlStart: number,\n allowNestedParens: boolean\n): { target: string; title: string | undefined; endPos: number } | null {\n const destResult = parseLinkDestination(source, urlStart, allowNestedParens)\n if (!destResult) return null\n\n let i = urlStart\n i = util.skipWhitespace(source, i)\n const hasAngleBrackets = i < source.length && source[i] === '<'\n\n // Handle empty angle brackets <>\n if (\n hasAngleBrackets &&\n destResult.target === '' &&\n destResult.endPos === i + 2\n ) {\n const titleResult = parseLinkTitle(\n source,\n destResult.endPos,\n false,\n hasAngleBrackets\n )\n if (\n titleResult.endPos >= source.length ||\n source[titleResult.endPos] !== ')'\n )\n return null\n return {\n target: '',\n title: titleResult.title,\n endPos: titleResult.endPos + 1,\n }\n }\n\n const titleResult = parseLinkTitle(\n source,\n destResult.endPos,\n destResult.hadSpace,\n hasAngleBrackets\n )\n if (titleResult.endPos >= source.length || source[titleResult.endPos] !== ')')\n return null\n\n return {\n target: destResult.target,\n title: titleResult.title,\n endPos: titleResult.endPos + 1,\n }\n}\n\nenum AutolinkMode {\n URI,\n EMAIL,\n ANGLE,\n}\n\nfunction isAlphaCode(code: number): boolean {\n return (\n (code >= $.CHAR_A && code <= $.CHAR_Z) ||\n (code >= $.CHAR_a && code <= $.CHAR_z)\n )\n}\n\nfunction isValidUriScheme(content: string): boolean {\n const colonPos = content.indexOf(':')\n if (colonPos < 2 || colonPos > 32) return false\n\n const firstCharCode = charCode(content)\n if (!isAlphaCode(firstCharCode)) {\n return false\n }\n\n // Check if all chars before colon are valid scheme chars\n for (let j = 1; j < colonPos; j++) {\n const c = content[j]\n const cCode = charCode(c)\n if (!isAlnum(c) && c !== '+' && c !== '.' && c !== '-') {\n return false\n }\n }\n return true\n}\n\nfunction isValidAutolinkContext(\n source: string,\n start: number,\n includeCR: boolean\n): boolean {\n if (start === 0) return true\n let validChars = includeCR ? ' \\t\\n\\r*_~(' : ' \\t\\n*_~('\n return validChars.indexOf(source[start - 1]) !== -1\n}\n\nfunction sanitizeAndCreate(\n target: string,\n linkText: string,\n endPos: number,\n sanitizer: (url: string, tag: string, attr: string) => string | null,\n emailStart?: number\n): ParseResult | null {\n let safe = sanitizer(target, 'a', 'href')\n if (!safe) return null\n return {\n type: RuleType.link,\n target: safe,\n children: [{ type: RuleType.text, text: linkText }],\n endPos: endPos,\n ...(emailStart !== undefined ? { emailStart } : {}),\n } as MarkdownToJSX.LinkNode & { endPos: number; emailStart?: number }\n}\n\nfunction parseAutolink(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions,\n mode: AutolinkMode\n): ParseResult | null {\n if (\n state.inAnchor ||\n (mode !== AutolinkMode.ANGLE && options.disableAutoLink)\n )\n return null\n\n if (mode === AutolinkMode.ANGLE) {\n if (source[pos] !== '<') return null\n let end = pos + 1\n while (end < source.length && source[end] !== '>') {\n const endCode = charCode(source, end)\n if (\n endCode === $.CHAR_SPACE ||\n endCode === $.CHAR_TAB ||\n endCode === $.CHAR_NEWLINE ||\n endCode === $.CHAR_CR ||\n endCode < $.CHAR_SPACE\n )\n return null\n end++\n }\n if (end >= source.length || source[end] !== '>') return null\n let content = source.slice(pos + 1, end)\n if (!content.length) return null\n\n let hasBackslash = content.indexOf('\\\\') !== -1\n let hasValidUriScheme = isValidUriScheme(content)\n let isHttp =\n util.startsWith(content, 'http://') ||\n util.startsWith(content, 'https://')\n let isMailto = false\n if (!hasValidUriScheme && !isHttp && content.length >= 7) {\n const firstChar = content[0]\n if (firstChar === 'm' || firstChar === 'M') {\n const contentLower = content.toLowerCase()\n if (util.startsWith(contentLower, 'mailto:')) {\n isMailto = true\n let colonPos = contentLower.indexOf(':')\n let mailtoText = content.slice(colonPos + 1)\n return sanitizeAndCreate(\n 'mailto:' + mailtoText,\n content,\n end + 1,\n options.sanitizer\n )\n }\n }\n }\n let isEmailLike =\n !hasBackslash &&\n content.indexOf('@') !== -1 &&\n content.indexOf('//') === -1 &&\n !hasValidUriScheme\n\n if (!isHttp && !isMailto && !isEmailLike && !hasValidUriScheme) return null\n\n let target = content,\n linkText = content\n if (!isMailto && !hasValidUriScheme && !isHttp && isEmailLike) {\n target = 'mailto:' + content\n }\n\n return sanitizeAndCreate(target, linkText, end + 1, options.sanitizer)\n }\n\n if (mode === AutolinkMode.EMAIL) {\n let emailStart = pos\n while (\n emailStart > 0 &&\n (isAlnum(source[emailStart - 1]) ||\n '.+-_'.indexOf(source[emailStart - 1]) !== -1)\n )\n emailStart--\n if (emailStart >= pos || !isValidAutolinkContext(source, emailStart, true))\n return null\n\n let emailEnd = pos + 1\n let hasDot = false\n while (emailEnd < source.length) {\n let c = source[emailEnd]\n if (c === '.') {\n hasDot = true\n emailEnd++\n } else if (isAlnum(c) || c === '-' || c === '_') emailEnd++\n else break\n }\n\n if (!hasDot || emailEnd <= pos + 1) return null\n while (emailEnd > pos + 1 && source[emailEnd - 1] === '.') emailEnd--\n if (\n emailEnd > pos + 1 &&\n (source[emailEnd - 1] === '-' || source[emailEnd - 1] === '_')\n )\n return null\n // Check if email contains at least one dot\n // For large documents, prefer slice+includes to avoid scanning entire document\n const emailLength = emailEnd - (pos + 1)\n if (emailLength < 10000) {\n if (\n source.indexOf('.', pos + 1) >= emailEnd ||\n source.indexOf('.', pos + 1) === -1\n )\n return null\n } else {\n if (source.slice(pos + 1, emailEnd).indexOf('.') === -1) return null\n }\n\n let email = source.slice(emailStart, emailEnd)\n return sanitizeAndCreate(\n 'mailto:' + email,\n email,\n emailEnd,\n options.sanitizer,\n emailStart\n )\n }\n\n let isHttp =\n util.startsWith(source, 'http://', pos) ||\n util.startsWith(source, 'https://', pos)\n let isFtp = !isHttp && util.startsWith(source, 'ftp://', pos)\n let isWww = !isHttp && !isFtp && util.startsWith(source, 'www.', pos)\n if (\n !(isHttp || isFtp || isWww) ||\n !isValidAutolinkContext(source, pos, false)\n )\n return null\n\n var urlEnd =\n pos +\n (isHttp ? (charCode(source, pos + 4) === $.CHAR_s ? 8 : 7) : isFtp ? 6 : 4)\n var domainStart = urlEnd\n // Inline scanDomain\n while (urlEnd < source.length) {\n const code = charCode(source, urlEnd)\n if (\n code === $.CHAR_SPACE ||\n code === $.CHAR_TAB ||\n code === $.CHAR_NEWLINE ||\n code === $.CHAR_LT ||\n code === $.CHAR_GT\n )\n break\n urlEnd++\n }\n if (urlEnd <= domainStart) return null\n // Inline trimTrailingPunct\n let trimmed = urlEnd\n while (trimmed > domainStart) {\n let lastChar = source[trimmed - 1]\n if (trimmed > domainStart + 1 && source[trimmed - 2] === '\\\\') break\n if (\n lastChar === '?' ||\n lastChar === '!' ||\n lastChar === '.' ||\n lastChar === ',' ||\n lastChar === ':' ||\n lastChar === '*' ||\n lastChar === '_' ||\n lastChar === '~'\n ) {\n trimmed--\n } else if (lastChar === ';') {\n let ampPos = trimmed - 2\n while (\n ampPos >= domainStart &&\n source[ampPos] !== '&' &&\n source[ampPos] !== ' '\n )\n ampPos--\n if (ampPos >= domainStart && source[ampPos] === '&') {\n let entityName = source.slice(ampPos + 1, trimmed - 1)\n if (\n entityName.length >= 2 &&\n entityName.length <= 10 &&\n /^[a-zA-Z0-9]+$/.test(entityName) &&\n (entityName === 'lt' ||\n entityName === 'gt' ||\n (entityName.length >= 3 &&\n (util.startsWith(entityName, 'amp') ||\n util.startsWith(entityName, 'apos') ||\n util.startsWith(entityName, 'quot') ||\n util.startsWith(entityName, 'nbsp') ||\n /^[a-z]{3,10}$/.test(entityName))))\n )\n break\n trimmed = ampPos\n break\n }\n trimmed--\n } else if (lastChar === ')') {\n let openCount = 0,\n closeCount = 0\n for (let i = domainStart; i < trimmed; i++) {\n if (source[i] === '(') openCount++\n if (source[i] === ')') closeCount++\n }\n if (closeCount > openCount) trimmed--\n else break\n } else break\n }\n urlEnd = trimmed\n if (urlEnd <= domainStart) return null\n\n var domainEnd = domainStart\n var lastDot = -1\n var secondLastDot = -1\n while (domainEnd < urlEnd) {\n const domainCode = charCode(source, domainEnd)\n if (\n (domainCode >= $.CHAR_A && domainCode <= $.CHAR_Z) ||\n (domainCode >= $.CHAR_a && domainCode <= $.CHAR_z) ||\n (domainCode >= $.CHAR_DIGIT_0 && domainCode <= $.CHAR_DIGIT_9) ||\n domainCode === $.CHAR_DASH ||\n domainCode === $.CHAR_UNDERSCORE ||\n domainCode === $.CHAR_PERIOD\n ) {\n if (domainCode === $.CHAR_PERIOD) {\n secondLastDot = lastDot\n lastDot = domainEnd\n }\n domainEnd++\n continue\n }\n break\n }\n if (domainEnd === domainStart || lastDot === -1) return null\n if (secondLastDot === -1) secondLastDot = domainStart - 1\n for (let i = secondLastDot + 1; i < lastDot; i++) {\n if (source[i] === '_') return null\n }\n for (let i = lastDot + 1; i < domainEnd; i++) {\n if (source[i] === '_') return null\n }\n\n let linkText = source.slice(pos, urlEnd)\n return sanitizeAndCreate(\n isWww ? 'http://' + linkText : linkText,\n linkText,\n urlEnd,\n options.sanitizer\n )\n}\n\n// Unified link/image parser - handles all link/image types based on starting character\nfunction parseLinkOrImage(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions,\n startChar: '[' | '!' | '<' | 'h' | 'f' | 'w' | '@'\n): ParseResult | null {\n // Angle brace autolink: <url>\n if (startChar === '<') {\n return parseAutolink(\n source,\n pos,\n state,\n options,\n AutolinkMode.ANGLE\n ) as ParseResult\n }\n\n // Bare URL autolink: http://, https://, ftp://, www.\n if (startChar === 'h' || startChar === 'f' || startChar === 'w') {\n return parseAutolink(\n source,\n pos,\n state,\n options,\n AutolinkMode.URI\n ) as ParseResult\n }\n\n // Email autolink: @example.com\n if (startChar === '@') {\n return parseAutolink(\n source,\n pos,\n state,\n options,\n AutolinkMode.EMAIL\n ) as ParseResult | null\n }\n\n // Bracket-based links/images are handled inline in parseInlineSpan\n // This function only handles autolinks\n return null\n}\n\nfunction normalizeReferenceLabel(label: string): string {\n var trimmed = label.trim()\n var normalized = trimmed.replace(/[\\s\\t\\n\\r]+/g, ' ')\n if (normalized.indexOf('\\u1E9E') !== -1) {\n return normalized.replace(/\\u1E9E/g, 'ss').toLowerCase();\n }\n return normalized.toLowerCase()\n}\n\nfunction parseGFMTask(\n source: string,\n pos: number,\n state: MarkdownToJSX.State\n): ParseResult {\n if (pos + 3 >= source.length || source[pos] !== '[') return null\n const marker = source[pos + 1]\n if (marker !== ' ' && marker !== 'x' && marker !== 'X') return null\n if (source[pos + 2] !== ']') return null\n return {\n type: RuleType.gfmTask,\n completed: marker.toLowerCase() === 'x',\n endPos: pos + 3,\n } as MarkdownToJSX.GFMTaskNode & { endPos: number }\n}\n\nfunction parseBlocksWithState(\n content: string,\n state: MarkdownToJSX.State,\n options: ParseOptions,\n config: { inline?: boolean; list?: boolean; inBlockQuote?: boolean }\n): MarkdownToJSX.ASTNode[] {\n const originalInline = state.inline\n const originalList = state.inList\n const originalInBlockQuote = state.inBlockQuote\n if (config.inline !== undefined) state.inline = config.inline\n if (config.list !== undefined) state.inList = config.list\n if (config.inBlockQuote !== undefined)\n state.inBlockQuote = config.inBlockQuote\n const blocks = parseBlocksInHTML(content, state, options)\n state.inline = originalInline\n state.inList = originalList\n state.inBlockQuote = originalInBlockQuote\n return blocks\n}\n\nfunction parseInlineWithState(\n content: string,\n start: number,\n end: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): MarkdownToJSX.ASTNode[] {\n return parseWithInlineMode(state, true, () =>\n parseInlineSpan(content, start, end, state, options)\n )\n}\n\ntype BlockParserFn = (\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n) => ParseResult | null\n\nfunction parseBlock(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult | null {\n var char = source[pos]\n if (char === undefined) return null\n var effectivePos = pos\n var indentInfo: ReturnType<typeof calculateIndent> | null = null\n var firstChar = char\n var lineEnd: number | null = null\n\n var charCodeVal = charCode(char)\n var isIndentChar = charCodeVal === $.CHAR_SPACE || charCodeVal === $.CHAR_TAB\n if (isIndentChar) {\n lineEnd = util.findLineEnd(source, pos)\n indentInfo = calculateIndent(source, pos, lineEnd)\n effectivePos = pos + indentInfo.charCount\n if (effectivePos >= source.length) return parseCodeBlock(source, pos, state)\n firstChar = source[effectivePos]\n }\n var spaceEquivalent = indentInfo ? indentInfo.spaceEquivalent : 0\n if (spaceEquivalent >= 4) {\n if (isIndentChar) return parseCodeBlock(source, pos, state)\n return null\n }\n var firstCharCode = charCode(firstChar)\n if (firstCharCode === $.CHAR_GT) {\n var blockQuoteResult = parseBlockQuote(source, pos, state, options)\n if (blockQuoteResult) return blockQuoteResult\n } else if (firstCharCode === $.CHAR_UNDERSCORE) {\n return parseBreakThematic(source, pos, state, options)\n } else if (\n firstCharCode === $.CHAR_DASH ||\n firstCharCode === $.CHAR_ASTERISK ||\n firstCharCode === $.CHAR_PLUS\n ) {\n var thematicBreakResult = parseBreakThematic(source, pos, state, options)\n if (thematicBreakResult) return thematicBreakResult\n var listResult = parseList(source, pos, state, options)\n if (listResult) return listResult\n } else if (\n firstCharCode >= $.CHAR_DIGIT_0 &&\n firstCharCode <= $.CHAR_DIGIT_9\n ) {\n var listResult = parseList(source, pos, state, options)\n if (listResult) return listResult\n } else if (firstCharCode === $.CHAR_HASH) {\n return parseHeading(source, effectivePos, state, options)\n } else if (firstCharCode === $.CHAR_BRACKET_OPEN) {\n return parseDefinition(\n source,\n effectivePos,\n state,\n options,\n effectivePos + 1 < source.length &&\n charCode(source, effectivePos + 1) === $.CHAR_CARET\n )\n } else if (firstCharCode === $.CHAR_LT && !options.disableParsingRawHTML) {\n return parseHTML(source, effectivePos, state, options)\n } else if (\n firstCharCode === $.CHAR_BACKTICK ||\n firstCharCode === $.CHAR_TILDE\n ) {\n if (!lineEnd) lineEnd = util.findLineEnd(source, pos)\n if (!indentInfo) indentInfo = calculateIndent(source, pos, lineEnd)\n if (indentInfo.spaceEquivalent <= 3)\n return parseCodeFenced(source, effectivePos, state, options)\n } else if (firstCharCode === $.CHAR_PIPE) {\n return parseTable(source, pos, state, options)\n }\n if (isIndentChar) return parseCodeBlock(source, pos, state)\n return null\n}\n\n/** Parse blocks inside HTML content */\nfunction parseBlocksInHTML(\n input: string,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): MarkdownToJSX.ASTNode[] {\n const result: MarkdownToJSX.ASTNode[] = []\n let pos = 0\n\n while (pos < input.length) {\n while (pos < input.length && input[pos] === '\\n') {\n pos++\n }\n\n if (pos >= input.length) break\n\n var char = input[pos]\n\n // Fast path: check for setext heading in list context\n // Per CommonMark: setext headings take precedence over thematic breaks\n if (state.inList && result.length > 0) {\n var lastBlock = result[result.length - 1]\n if (lastBlock?.type === RuleType.paragraph) {\n var paragraph = lastBlock as MarkdownToJSX.ParagraphNode\n // Quick check for potential setext underline characters\n var code = charCode(char)\n if (\n code === $.CHAR_DASH ||\n code === $.CHAR_EQ ||\n code === $.CHAR_SPACE ||\n code === $.CHAR_TAB\n ) {\n var lineEnd = util.findLineEnd(input, pos)\n var lineContent = input.slice(pos, lineEnd)\n\n // Check indentation (up to 3 spaces allowed for setext headings)\n var indentInfo = calculateIndent(input, pos, lineEnd)\n if (indentInfo.spaceEquivalent < 4) {\n var trimmed = lineContent.slice(indentInfo.charCount).trim()\n // Use convertSetextHeadingInListItem helper to check and convert\n if (convertSetextHeadingInListItem(result, trimmed, options)) {\n pos =\n lineEnd +\n (lineEnd < input.length && input[lineEnd] === '\\n' ? 1 : 0)\n continue\n }\n }\n }\n }\n }\n\n // Try parseBlock first (handles most block types)\n var blockResult = parseBlock(input, pos, state, options)\n if (blockResult) {\n result.push(blockResult)\n pos = blockResult.endPos\n continue\n }\n\n // Try setext heading (not handled by parseBlock)\n var setextResult = parseHeadingSetext(input, pos, state, options)\n if (setextResult) {\n result.push(setextResult)\n pos = setextResult.endPos\n continue\n }\n\n var remaining = input.slice(pos).trim()\n if (remaining) {\n // Per CommonMark spec example 293: Before parsing a paragraph, check if there's\n // a blockquote ending with a paragraph in recent blocks that this should merge into\n if (state.inBlockQuote && result.length > 0) {\n // Find the deepest blockquote ending with a paragraph in recent blocks\n // (may be nested inside list items)\n function findBlockquoteWithParagraphEnd(\n node: MarkdownToJSX.ASTNode\n ): MarkdownToJSX.ParagraphNode | null {\n if (node.type === RuleType.blockQuote) {\n var blockQuote = node as MarkdownToJSX.BlockQuoteNode\n if (blockQuote.children && blockQuote.children.length > 0) {\n var lastChild =\n blockQuote.children[blockQuote.children.length - 1]\n if (lastChild.type === RuleType.paragraph) {\n return lastChild as MarkdownToJSX.ParagraphNode\n }\n }\n } else if (\n node.type === RuleType.orderedList ||\n node.type === RuleType.unorderedList\n ) {\n var list = node as\n | MarkdownToJSX.OrderedListNode\n | MarkdownToJSX.UnorderedListNode\n if (list.items && list.items.length > 0) {\n var lastItem = list.items[list.items.length - 1]\n if (lastItem && lastItem.length > 0) {\n var lastItemChild = lastItem[lastItem.length - 1]\n var found = findBlockquoteWithParagraphEnd(lastItemChild)\n if (found) return found\n }\n }\n }\n return null\n }\n\n // Check recent blocks (from end) for blockquote ending with paragraph\n for (var i = result.length - 1; i >= 0; i--) {\n var paragraph = findBlockquoteWithParagraphEnd(result[i])\n if (paragraph) {\n var parseResult = parseParagraph(input, pos, state, options)\n if (parseResult) {\n var newParagraph = parseResult as MarkdownToJSX.ParagraphNode\n // Merge the new paragraph's children into the blockquote's paragraph\n if (paragraph.children && newParagraph.children) {\n paragraph.children.push(\n { type: RuleType.text, text: '\\n' } as MarkdownToJSX.TextNode,\n ...newParagraph.children\n )\n }\n pos = parseResult.endPos\n continue\n }\n }\n }\n }\n\n var parseResult = parseParagraph(input, pos, state, options)\n if (parseResult) {\n result.push(parseResult)\n pos = parseResult.endPos\n continue\n }\n }\n\n pos++\n }\n\n return result\n}\n\nfunction parseHeading(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult {\n if (state.inline) return null\n\n // Find line end to limit expensive indentation scan\n const lineEnd = util.findLineEnd(source, pos)\n const indentResult = calculateIndent(source, pos, lineEnd, 3)\n if (indentResult.spaceEquivalent > 3 && !state.inList) return null\n var i = pos + indentResult.charCount\n\n if (i >= source.length || source[i] !== '#') return null\n\n const level = countConsecutiveChars(source, i, '#', 6)\n i += level\n\n if (i >= source.length) return null\n const afterHash = source[i]\n if (afterHash === '\\n' || afterHash === '\\r') {\n const lineEnd = util.findLineEnd(source, i)\n return {\n ...createHeading(level, [], '', options.slugify),\n endPos: lineEnd + (lineEnd < source.length ? 1 : 0),\n } as MarkdownToJSX.HeadingNode & { endPos: number }\n }\n if (afterHash !== ' ' && afterHash !== '\\t') return null\n\n const contentStart = i\n const contentEnd = util.findLineEnd(source, contentStart)\n var content = source\n .slice(contentStart, contentEnd)\n .replace(HEADING_TRAILING_HASHES_R, '')\n .trim()\n\n const children = parseInlineWithState(\n content,\n 0,\n content.length,\n state,\n options\n )\n\n return {\n ...createHeading(level, children, content, options.slugify),\n endPos: contentEnd + (contentEnd < source.length ? 1 : 0),\n } as MarkdownToJSX.HeadingNode & { endPos: number }\n}\n\nfunction parseHeadingSetext(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult {\n if (state.inline || state.inBlockQuote || state.inList) return null\n\n const firstLineEnd = util.findLineEnd(source, pos)\n if (firstLineEnd >= source.length) return null\n\n // Find underline pattern first, then validate backwards\n let underlineLineStart = firstLineEnd + 1,\n underlineLineEnd = -1,\n underlineChar: string | null = null\n\n // Scan forward for underline (= or - with up to 3 spaces indentation)\n for (\n var linesScanned = 0;\n underlineLineStart < source.length && linesScanned < 10;\n linesScanned++\n ) {\n const lineEnd = util.findLineEnd(source, underlineLineStart)\n if (lineEnd >= source.length) break\n\n // Check if blank line (stops setext headings)\n var i = underlineLineStart\n while (\n i < lineEnd &&\n (charCode(source, i) === $.CHAR_SPACE ||\n charCode(source, i) === $.CHAR_TAB ||\n charCode(source, i) === $.CHAR_CR)\n )\n i++\n if (i >= lineEnd) break\n\n // Check indentation (up to 3 spaces) and first char\n var indentCount = 0,\n checkPos = underlineLineStart\n while (\n checkPos < lineEnd &&\n indentCount < 3 &&\n charCode(source, checkPos) === $.CHAR_SPACE\n ) {\n indentCount++\n checkPos++\n }\n\n if (checkPos < lineEnd) {\n const code = charCode(source, checkPos)\n if (code === $.CHAR_EQ || code === $.CHAR_DASH) {\n // Validate underline: only = or - with optional trailing spaces, no internal spaces\n const char = source[checkPos]\n var underlineCount = 0,\n hasSeenWS = false,\n p = checkPos\n while (p < lineEnd) {\n const c = charCode(source, p)\n if (c === code) {\n if (hasSeenWS) {\n underlineCount = 0\n break\n }\n underlineCount++\n } else if (c === $.CHAR_SPACE || c === $.CHAR_TAB) {\n hasSeenWS = true\n } else {\n underlineCount = 0\n break\n }\n p++\n }\n\n if (underlineCount >= 1) {\n underlineLineEnd = lineEnd\n underlineChar = char\n break\n }\n }\n }\n\n underlineLineStart = lineEnd + 1\n }\n\n if (!underlineChar) return null\n\n // Quick validation: content cannot start with certain block characters\n const firstCharCode = charCode(source, pos)\n if (\n firstCharCode === $.CHAR_HASH ||\n firstCharCode === $.CHAR_GT ||\n source[pos] === '|'\n )\n return null\n\n // Collect content lines forward to underline\n let contentEnd = pos\n var currentPos = pos,\n hasContent = false\n\n while (currentPos < underlineLineStart) {\n const lineEnd = util.findLineEnd(source, currentPos)\n if (lineEnd >= underlineLineStart) break\n\n // Check if line has non-whitespace content\n var j = currentPos\n while (\n j < lineEnd &&\n (charCode(source, j) === $.CHAR_SPACE ||\n charCode(source, j) === $.CHAR_TAB ||\n charCode(source, j) === $.CHAR_CR)\n )\n j++\n if (j < lineEnd) {\n // Line has content\n hasContent = true\n contentEnd = lineEnd\n }\n\n currentPos = lineEnd + 1\n }\n\n if (!hasContent) return null\n\n // Extract and trim content\n const rawContent = source.slice(pos, contentEnd)\n var startTrim = 0,\n endTrim = rawContent.length\n while (\n startTrim < endTrim &&\n (rawContent.charCodeAt(startTrim) === $.CHAR_SPACE ||\n rawContent.charCodeAt(startTrim) === $.CHAR_TAB ||\n rawContent.charCodeAt(startTrim) === $.CHAR_CR ||\n rawContent.charCodeAt(startTrim) === $.CHAR_NEWLINE)\n )\n startTrim++\n while (\n endTrim > startTrim &&\n (rawContent.charCodeAt(endTrim - 1) === $.CHAR_SPACE ||\n rawContent.charCodeAt(endTrim - 1) === $.CHAR_TAB ||\n rawContent.charCodeAt(endTrim - 1) === $.CHAR_CR ||\n rawContent.charCodeAt(endTrim - 1) === $.CHAR_NEWLINE)\n )\n endTrim--\n const content = rawContent.slice(startTrim, endTrim)\n\n if (!content) return null\n\n const level = underlineChar === '=' ? 1 : 2\n const children = parseInlineWithState(\n content,\n 0,\n content.length,\n state,\n options\n )\n\n return {\n ...createHeading(level, children, content, options.slugify),\n endPos: underlineLineEnd + (underlineLineEnd < source.length ? 1 : 0),\n } as MarkdownToJSX.HeadingNode & { endPos: number }\n}\n\nfunction parseParagraph(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult {\n // Note: We don't check isBlockStartChar here because this is called as a fallback\n // after other block parsers have already tried and failed\n if (state.inline) return null\n let endPos = pos\n const sourceLen = source.length\n\n while (endPos < sourceLen) {\n let lineEnd = util.findLineEnd(source, endPos)\n let isEmptyLine = true\n\n for (let i = endPos; i < lineEnd; i++) {\n const code = charCode(source, i)\n if (code !== $.CHAR_SPACE && code !== $.CHAR_TAB && code !== $.CHAR_CR) {\n isEmptyLine = false\n break\n }\n }\n\n if (isEmptyLine) {\n endPos = lineEnd\n break\n }\n\n if (lineEnd >= sourceLen) {\n endPos = sourceLen\n break\n }\n\n const nextLineStart = lineEnd + 1\n if (nextLineStart >= sourceLen) {\n endPos = sourceLen\n break\n }\n\n let nextLineEnd = util.findLineEnd(source, nextLineStart)\n let nextLineIsEmpty = true\n let nextLineFirstChar = ''\n\n for (let i = nextLineStart; i < nextLineEnd; i++) {\n const code = charCode(source, i)\n if (code !== $.CHAR_SPACE && code !== $.CHAR_TAB && code !== $.CHAR_CR) {\n nextLineIsEmpty = false\n if (nextLineFirstChar === '') nextLineFirstChar = source[i]\n break\n }\n }\n\n if (nextLineIsEmpty) {\n endPos = lineEnd\n break\n }\n\n // Check if next line starts with a block element\n // BUT: per CommonMark, lines indented by exactly 4 spaces are paragraph continuation,\n // not code blocks or other blocks, even if they start with block-starting characters.\n let shouldBreak = false\n const nextIndentInfo = calculateIndent(source, nextLineStart, nextLineEnd)\n const isExact4SpaceIndent =\n nextIndentInfo.spaceEquivalent === 4 && nextIndentInfo.charCount === 4\n\n // Check for HTML blocks first (types 1-6 can interrupt paragraphs)\n // Per CommonMark spec: HTML blocks of types 1-6 can interrupt paragraphs\n if (\n nextLineFirstChar === '<' &&\n !isExact4SpaceIndent &&\n !options.disableParsingRawHTML\n ) {\n const htmlCheckPos = nextLineStart\n let htmlLineStart = htmlCheckPos\n let htmlIndent = 0\n while (htmlLineStart < nextLineEnd && htmlIndent < 3) {\n const code = charCode(source, htmlLineStart)\n if (code === $.CHAR_SPACE || code === $.CHAR_TAB) {\n htmlIndent++\n htmlLineStart++\n } else {\n break\n }\n }\n if (htmlLineStart < nextLineEnd && source[htmlLineStart] === '<') {\n var htmlResult = parseHTML(\n source,\n htmlLineStart,\n { ...state, inline: false },\n options\n )\n if (htmlResult) {\n shouldBreak =\n !('canInterruptParagraph' in htmlResult) ||\n (htmlResult.canInterruptParagraph as boolean)\n }\n }\n }\n\n // In list context, lines indented to the content start column are also continuation\n // For now, treat 4-space indented lines as continuation regardless of context\n if (isExact4SpaceIndent) {\n // Line is indented exactly 4 spaces - this is paragraph continuation\n // Per CommonMark spec: lines indented by exactly 4 spaces are paragraph continuation,\n // not code blocks or other blocks, even if they start with block-starting characters.\n // Don't break, continue paragraph across this line\n shouldBreak = false\n } else if (\n !shouldBreak &&\n nextLineFirstChar &&\n isBlockStartChar(nextLineFirstChar)\n ) {\n // Reference definitions don't break paragraphs - skip them\n if (nextLineFirstChar === '[') {\n // Check if it's a reference definition (not a footnote)\n const checkPos = nextLineStart\n if (checkPos + 1 >= sourceLen || source[checkPos + 1] !== '^') {\n // Could be a reference definition - don't break paragraph\n shouldBreak = false\n } else {\n // Footnote definition - break paragraph\n shouldBreak = true\n }\n } else if (nextLineFirstChar === '*' || nextLineFirstChar === '+') {\n // Asterisk/plus is only a block start for lists (*/+ followed by space/tab) or thematic breaks (3+ alone)\n // But thematic breaks can have up to 3 spaces indentation, so check for thematic break first\n const thematicBreakResult = parseBreakThematic(\n source,\n nextLineStart,\n state,\n options\n )\n if (thematicBreakResult) {\n shouldBreak = true\n } else {\n // Check if it's a list (followed by space/tab)\n const secondChar =\n nextLineStart + 1 < sourceLen ? source[nextLineStart + 1] : ''\n if (secondChar && isSpaceOrTab(secondChar)) {\n shouldBreak = true\n } else {\n // Not a list or thematic break - don't break paragraph\n shouldBreak = false\n }\n }\n } else {\n // Use parseBlock to check if next line starts a block\n // Special handling needed for setext headings and ordered lists\n const blockResult = parseBlock(source, nextLineStart, state, options)\n\n if (blockResult) {\n // Check if it's a code block from 4+ space indentation (paragraph continuation)\n if (blockResult.type === RuleType.codeBlock) {\n const blockIndentInfo = calculateIndent(\n source,\n nextLineStart,\n nextLineEnd\n )\n if (blockIndentInfo.spaceEquivalent >= 4) {\n // 4+ space indentation is paragraph continuation, not a block start\n shouldBreak = false\n } else {\n // Fenced code block - break paragraph\n shouldBreak = true\n }\n } else if (\n blockResult.type === RuleType.unorderedList ||\n blockResult.type === RuleType.orderedList\n ) {\n // Lists can interrupt paragraphs, but ordered lists starting with numbers other than 1 cannot\n if (blockResult.type === RuleType.orderedList) {\n const orderedList = blockResult as MarkdownToJSX.OrderedListNode\n // Only ordered lists starting with 1 can interrupt paragraphs\n shouldBreak = orderedList.start === 1\n } else {\n shouldBreak = true\n }\n } else if (nextLineFirstChar === '-') {\n // Dash could be setext heading underline if preceded by content\n // Per CommonMark: setext headings take precedence over thematic breaks\n if (endPos > pos) {\n // We have content - break paragraph to let setext heading parser check\n shouldBreak = true\n } else {\n // No content - use the block result (thematic break or list)\n shouldBreak = true\n }\n } else if (blockResult.type === RuleType.ref) {\n // Reference definitions don't break paragraphs\n shouldBreak = false\n } else {\n // Other block types break paragraphs\n shouldBreak = true\n }\n }\n }\n } else {\n // Next line doesn't start with a block-starting character\n // Per CommonMark: in paragraph context, lines indented by exactly 4 spaces\n // are paragraph continuation, not code blocks. Only 4+ spaces at document\n // start (not in paragraph) are code blocks.\n // So we don't break on 4-space indentation in paragraph continuation.\n }\n\n if (shouldBreak) {\n endPos = lineEnd\n break\n }\n\n // Continue paragraph across single newline\n endPos = lineEnd + 1\n }\n\n if (endPos <= pos) return null\n\n // Per CommonMark: lines indented by exactly 4 spaces in paragraph context\n // are continuation, not code blocks. We need to remove the 4-space indentation\n // from continuation lines but preserve them as part of the paragraph.\n var contentStart = pos\n var contentEnd = endPos\n\n while (contentStart < contentEnd) {\n const code = charCode(source, contentStart)\n if (code === $.CHAR_SPACE || code === $.CHAR_TAB) {\n contentStart++\n } else {\n break\n }\n }\n\n // Fast path: if no newlines, use content directly (common case)\n // Check if there's a newline between contentStart and contentEnd\n // We can optimize by checking if contentEnd is beyond the first line\n const firstLineEnd = util.findLineEnd(source, contentStart)\n var hasNewline = contentEnd > firstLineEnd\n\n var processedContent\n if (!hasNewline) {\n // Single line - no processing needed\n processedContent = source.slice(contentStart, contentEnd)\n } else {\n // Multi-line: process 4-space indentation\n var processedParts: string[] = []\n var lineStart = contentStart\n var lineIndex = 0\n\n while (lineStart < contentEnd) {\n var lineEnd = util.findLineEnd(source, lineStart)\n if (lineEnd > contentEnd) lineEnd = contentEnd\n\n if (lineIndex === 0) {\n processedParts.push(source.slice(lineStart, lineEnd))\n } else {\n // Check for exactly 4 leading spaces\n var spaceCount = 0\n while (spaceCount < 4 && lineStart + spaceCount < lineEnd) {\n if (charCode(source, lineStart + spaceCount) === $.CHAR_SPACE) {\n spaceCount++\n } else {\n break\n }\n }\n var start = spaceCount === 4 ? lineStart + 4 : lineStart\n processedParts.push(source.slice(start, lineEnd))\n }\n\n if (\n lineEnd < contentEnd &&\n charCode(source, lineEnd) === $.CHAR_NEWLINE\n ) {\n processedParts.push('\\n')\n lineStart = lineEnd + 1\n } else {\n lineStart = contentEnd\n }\n lineIndex++\n }\n processedContent = processedParts.join('')\n }\n\n var processedContentEnd = processedContent.length\n while (processedContentEnd > 0) {\n var c = processedContent.charCodeAt(processedContentEnd - 1)\n if (c === $.CHAR_SPACE || c === $.CHAR_TAB) {\n processedContentEnd--\n } else {\n break\n }\n }\n if (processedContentEnd < processedContent.length) {\n processedContent = processedContent.slice(0, processedContentEnd)\n }\n\n // Check if processed content has actual content\n let hasProcessedContent = false\n for (let i = 0; i < processedContent.length; i++) {\n const code = processedContent.charCodeAt(i)\n if (\n code !== $.CHAR_SPACE &&\n code !== $.CHAR_TAB &&\n code !== $.CHAR_NEWLINE &&\n code !== $.CHAR_CR\n ) {\n hasProcessedContent = true\n break\n }\n }\n if (!hasProcessedContent) return null\n\n // Per CommonMark spec: Extract link reference definitions from paragraph content\n // Reference definitions can appear at the end of paragraph content\n // They should be extracted and stored, not parsed as inline content\n // Scan backwards from endPos in source to find reference definitions\n var extractedContent = processedContent\n var extractedEndPos = endPos\n // Find the last newline in the source before endPos (optimized: manual scan instead of lastIndexOf)\n var lastNewlinePos = -1\n var searchPos = endPos - 1\n while (searchPos >= contentStart) {\n if (charCode(source, searchPos) === $.CHAR_NEWLINE) {\n lastNewlinePos = searchPos\n break\n }\n searchPos--\n }\n if (lastNewlinePos >= 0) {\n // Per CommonMark spec: \"A link reference definition cannot interrupt a paragraph.\"\n // Only extract reference definitions if they're at the START of the paragraph (no content before them)\n // Check if there's any non-whitespace content before the last newline\n var hasContentBeforeNewline = false\n for (var checkPos = contentStart; checkPos < lastNewlinePos; checkPos++) {\n const code = charCode(source, checkPos)\n if (\n code !== $.CHAR_SPACE &&\n code !== $.CHAR_TAB &&\n code !== $.CHAR_NEWLINE &&\n code !== $.CHAR_CR\n ) {\n hasContentBeforeNewline = true\n break\n }\n }\n\n // Only extract reference definition if there's no content before the newline\n // (i.e., it's at the start of the paragraph)\n if (!hasContentBeforeNewline) {\n // Check if the content after the last newline is a reference definition\n var refDefStartPos = lastNewlinePos + 1\n // Skip any leading whitespace\n while (refDefStartPos < source.length) {\n const code = charCode(source, refDefStartPos)\n if (code === $.CHAR_SPACE || code === $.CHAR_TAB) {\n refDefStartPos++\n } else {\n break\n }\n }\n // Check indentation - reference definitions can't be indented 4+ spaces\n var refDefIndent = refDefStartPos - (lastNewlinePos + 1)\n if (\n refDefIndent < 4 &&\n refDefStartPos < source.length &&\n source[refDefStartPos] === '['\n ) {\n var refDefState = { ...state, inline: false }\n var refDefResult = parseDefinition(\n source,\n refDefStartPos,\n refDefState,\n options,\n false\n )\n if (refDefResult) {\n // Reference definition was successfully parsed - exclude it from paragraph content\n // Find the corresponding position in processedContent\n // Count newlines from contentStart to lastNewlinePos\n var newlineCount = 0\n var searchPos = contentStart\n while (searchPos <= lastNewlinePos) {\n const nlPos = source.indexOf('\\n', searchPos)\n if (nlPos === -1 || nlPos > lastNewlinePos) break\n newlineCount++\n searchPos = nlPos + 1\n }\n // Find the corresponding position in processedContent\n var newlinePosInProcessed = 0\n var newlinesFound = 0\n searchPos = 0\n while (searchPos < processedContent.length) {\n const nlPos = processedContent.indexOf('\\n', searchPos)\n if (nlPos === -1) break\n newlinesFound++\n if (newlinesFound === newlineCount) {\n newlinePosInProcessed = nlPos + 1\n break\n }\n searchPos = nlPos + 1\n }\n if (newlinePosInProcessed > 0) {\n extractedContent = processedContent.slice(\n 0,\n newlinePosInProcessed - 1\n )\n }\n extractedEndPos = refDefResult.endPos\n // Update state.refs from the parsed reference\n state.refs = refDefState.refs\n }\n }\n }\n }\n\n // Parse as inline (newlines are preserved by default)\n const children = parseInlineWithState(\n extractedContent,\n 0,\n extractedContent.length,\n state,\n options\n )\n\n var result: MarkdownToJSX.ParagraphNode & {\n endPos: number\n removedClosingTags?: MarkdownToJSX.ASTNode[]\n } = {\n type: RuleType.paragraph,\n children,\n endPos: extractedEndPos,\n }\n\n // Per CommonMark spec Example 148: when paragraphs contain multiple closing tags at the end,\n // only the first closing tag should be kept in the paragraph, the rest should be removed\n // This handles cases where closing tags are part of HTML block structures\n // Heuristic: if there are 3+ consecutive closing tags, remove all but the first one\n // Example 148: <p><em>world</em>.</pre></p> should keep </pre> but remove </td>, </tr>, </table> (4 tags)\n // Example 623: <p></a></foo ></p> should keep both </a> and </foo > (2 tags, not removed)\n if (children.length > 0) {\n // Find closing tags at the end of paragraph children (ignoring whitespace-only text nodes)\n // Keep the first closing tag but remove the rest\n var closingTagIndices: number[] = []\n for (var i = children.length - 1; i >= 0; i--) {\n var child = children[i]\n if (\n child.type === RuleType.htmlSelfClosing &&\n child.isClosingTag === true\n ) {\n closingTagIndices.push(i)\n } else if (child.type === RuleType.text) {\n var textNode = child as MarkdownToJSX.TextNode\n // Skip whitespace-only text nodes when looking for consecutive closing tags\n if (textNode.text && textNode.text.trim().length > 0) {\n break\n }\n } else {\n // Stop at first non-closing-tag, non-whitespace node\n break\n }\n }\n // If we found 3+ consecutive closing tags at the end, remove all but the first one\n // Store the removed closing tags on the paragraph node so html() can render them separately\n // Heuristic: 3+ tags indicates HTML block structure (like </pre></td></tr></table>)\n // 2 tags might be standalone (like </a></foo >) - keep both\n if (closingTagIndices.length >= 3) {\n // Keep only the first closing tag (earliest in array), remove the rest\n var firstClosingTagIdx = closingTagIndices[closingTagIndices.length - 1]\n var removedClosingTags = children.slice(firstClosingTagIdx + 1)\n children.splice(firstClosingTagIdx + 1)\n result.removedClosingTags = removedClosingTags\n }\n }\n\n return result\n}\n\nfunction parseFrontmatter(source: string, pos: number): ParseResult {\n if (pos !== 0) return null\n const bounds = util.parseFrontmatterBounds(source)\n if (!bounds?.hasValidYaml) return null\n return {\n type: RuleType.frontmatter,\n text: source.slice(0, bounds.endPos - 1),\n endPos: bounds.endPos,\n } as MarkdownToJSX.FrontmatterNode & { endPos: number }\n}\n\nfunction parseBreakThematic(\n source: string,\n pos: number,\n state?: MarkdownToJSX.State,\n options?: ParseOptions\n): ParseResult {\n // Find the end of the line\n const lineEnd = util.findLineEnd(source, pos)\n\n // Per CommonMark: up to 3 spaces of indentation allowed\n // Count indentation, checking if it exceeds 3 spaces\n // OPTIMIZATION: Work directly on source string to avoid slice allocation\n const indentResult = calculateIndent(source, pos, lineEnd, 3)\n if (indentResult.spaceEquivalent > 3) return null\n var checkPos = pos + indentResult.charCount\n\n // Now check for thematic break character (-, *, or _)\n if (checkPos >= lineEnd) return null\n const startChar = source[checkPos]\n if (startChar !== '-' && startChar !== '*' && startChar !== '_') return null\n\n // OPTIMIZATION: Fast path - count matching characters before full validation\n // This eliminates 96% of failed attempts (102 attempts -> ~4 attempts)\n // Thematic break requires 3+ matching chars per CommonMark spec\n var charCount = 0\n var scanPos = checkPos\n while (scanPos < lineEnd) {\n var char = source[scanPos]\n if (char === startChar) {\n charCount++\n } else if (char !== ' ' && char !== '\\t') {\n // Non-matching non-whitespace character - not a thematic break\n return null\n }\n scanPos++\n }\n\n if (charCount < 3) {\n return null // Need at least 3 matching characters per CommonMark spec\n }\n\n return {\n type: RuleType.breakThematic,\n endPos: skipToNextLine(source, lineEnd),\n } as MarkdownToJSX.BreakThematicNode & { endPos: number }\n}\n\n/** Calculate the space-equivalent indentation at a position (tabs = 4 spaces) */\nexport function calculateIndent(\n source: string,\n pos: number,\n maxPos: number,\n maxSpaces?: number\n): { spaceEquivalent: number; charCount: number } {\n let spaceEquivalent = 0\n let charCount = 0\n let i = pos\n while (i < maxPos) {\n var iCode = charCode(source, i)\n if (iCode !== $.CHAR_SPACE && iCode !== $.CHAR_TAB) break\n if (maxSpaces !== undefined && spaceEquivalent >= maxSpaces) break\n if (iCode === $.CHAR_TAB) {\n spaceEquivalent += 4 - (spaceEquivalent % 4)\n } else {\n spaceEquivalent += 1\n }\n charCount++\n i++\n }\n return { spaceEquivalent, charCount }\n}\n\nfunction extractCodeBlockLineContent(\n source: string,\n lineStart: number,\n lineEnd: number,\n startColumn: number\n): string {\n let indentChars = 0\n let indentSpaceEquivalent = 0\n let currentColumn = startColumn\n for (let i = lineStart; i < lineEnd && indentSpaceEquivalent < 4; i++) {\n var iCode = charCode(source, i)\n if (iCode === $.CHAR_TAB) {\n const spaces = 4 - (currentColumn % 4)\n indentSpaceEquivalent += spaces\n indentChars++\n currentColumn += spaces\n if (indentSpaceEquivalent >= 4) break\n } else if (iCode === $.CHAR_SPACE) {\n indentSpaceEquivalent++\n indentChars++\n currentColumn++\n if (indentSpaceEquivalent >= 4) break\n } else {\n break\n }\n }\n\n let content = source.slice(lineStart + indentChars, lineEnd)\n var tabCount = 0\n for (var tc = lineStart; tc < lineEnd; tc++) {\n if (source[tc] === '\\t') tabCount++\n if (tabCount >= 2) break\n }\n if (tabCount >= 2 && util.startsWith(content, '\\t') && startColumn > 0) {\n content = ' ' + content.slice(1)\n }\n return content\n}\n\nfunction parseCodeBlock(\n source: string,\n pos: number,\n state: MarkdownToJSX.State\n): ParseResult {\n // Limit indentation scan to current line\n const lineEndForIndent = util.findLineEnd(source, pos)\n const indentInfo = calculateIndent(source, pos, lineEndForIndent)\n if (indentInfo.spaceEquivalent < 4) return null\n\n const initialIndent = indentInfo.spaceEquivalent\n const lineEnd = util.findLineEnd(source, pos + indentInfo.charCount)\n const lineStart = pos\n\n let column = 0\n var i = lineStart - 1\n while (i >= 0 && source[i] !== '\\n' && source[i] !== '\\r') {\n i--\n }\n i++\n while (i < lineStart) {\n if (source[i] === '\\t') {\n column = column + 4 - (column % 4)\n } else {\n column++\n }\n i++\n }\n\n let firstLineContent = extractCodeBlockLineContent(\n source,\n lineStart,\n lineEnd,\n column\n )\n const contentStart = skipToNextLine(source, lineEnd)\n if (contentStart >= source.length) {\n if (!firstLineContent.trim()) return null\n return {\n type: RuleType.codeBlock,\n text: firstLineContent,\n endPos: contentStart,\n } as MarkdownToJSX.CodeBlockNode & { endPos: number }\n }\n\n var parts: string[] = []\n parts.push(firstLineContent)\n let endPos = contentStart\n\n while (endPos < source.length) {\n const nextLineEnd = util.findLineEnd(source, endPos)\n if (isBlankLineCheck(source, endPos, nextLineEnd)) {\n const nextLinePos = nextLineEnd + 1\n if (nextLinePos < source.length) {\n const nextLineEnd = util.findLineEnd(source, nextLinePos)\n const nextIndentInfo = calculateIndent(source, nextLinePos, nextLineEnd)\n const nextChar = source[nextLinePos + nextIndentInfo.charCount]\n if (\n nextChar &&\n nextChar !== '\\n' &&\n (nextIndentInfo.spaceEquivalent < 4 ||\n (nextChar === '>' &&\n nextIndentInfo.spaceEquivalent < initialIndent))\n ) {\n break\n }\n }\n parts.push('\\n')\n } else {\n const currentIndentInfo = calculateIndent(source, endPos, nextLineEnd)\n if (currentIndentInfo.spaceEquivalent < 4) {\n break\n }\n\n let lineContent = extractCodeBlockLineContent(\n source,\n endPos,\n nextLineEnd,\n 0\n )\n parts.push('\\n')\n parts.push(lineContent)\n }\n\n endPos = skipToNextLine(source, nextLineEnd)\n }\n\n let content = parts.join('')\n content = content.replace(TRAILING_NEWLINE_R, '')\n if (!content.trim()) return null\n\n return {\n type: RuleType.codeBlock,\n text: content,\n endPos,\n } as MarkdownToJSX.CodeBlockNode & { endPos: number }\n}\n\nexport function parseCodeFenced(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult {\n const fenceChar = source[pos]\n if (fenceChar !== '`' && fenceChar !== '~') return null\n\n // Fast check: must have at least 3 consecutive fence chars\n const fenceLength = countConsecutiveChars(source, pos, fenceChar)\n if (fenceLength < 3) return null\n\n // Find line start for indentation calculation\n let lineStart = pos\n while (lineStart > 0 && charCode(source, lineStart - 1) !== $.CHAR_NEWLINE)\n lineStart--\n\n // Calculate indentation (caller already verified <= 3, but we need exact value)\n const indentInfo = calculateIndent(source, lineStart, pos)\n let openingIndent = indentInfo.spaceEquivalent\n let contentIndentToRemove = openingIndent\n\n // Handle 4-space indentation special case (simplified)\n if (openingIndent === 4 && indentInfo.charCount === 4) {\n // All 4 chars before pos are spaces/tabs, so this is indented code block\n openingIndent = 0\n contentIndentToRemove = 4\n }\n\n // Should not happen since caller checks indent <= 3, but keep for safety\n if (openingIndent >= 4) return null\n\n let i = util.skipWhitespace(source, pos + fenceLength)\n const lineEnd = util.findLineEnd(source, i)\n let langAndAttrs = source.slice(i, lineEnd).trim()\n\n if (fenceChar === '`' && langAndAttrs.indexOf('`') !== -1) return null\n\n langAndAttrs = langAndAttrs.replace(UNESCAPE_R, '$1')\n const langSpaceIdx = langAndAttrs.indexOf(' ')\n const lang =\n langSpaceIdx > 0 ? langAndAttrs.slice(0, langSpaceIdx) : langAndAttrs\n const attrsString =\n langSpaceIdx > 0 ? langAndAttrs.slice(langSpaceIdx + 1).trim() : ''\n const attrs =\n attrsString && /=\\s*[\"']/.test(attrsString)\n ? parseHTMLAttributes(attrsString, 'code', 'code', options)\n : undefined\n\n let contentStart = skipToNextLine(source, lineEnd)\n let endPos = contentStart\n\n while (endPos < source.length) {\n let lineEndPos = util.findLineEnd(source, endPos)\n\n let fenceStart = endPos\n let indentCount = 0\n while (fenceStart < lineEndPos) {\n const code = charCode(source, fenceStart)\n if (code === $.CHAR_SPACE) {\n indentCount++\n fenceStart++\n if (indentCount >= 4) break\n } else if (code === $.CHAR_TAB) {\n indentCount += 4 - (indentCount % 4)\n fenceStart++\n if (indentCount >= 4) break\n } else {\n break\n }\n }\n\n if (indentCount < 4) {\n let closeLen = countConsecutiveChars(\n source,\n fenceStart,\n fenceChar,\n lineEndPos - fenceStart\n )\n if (closeLen >= fenceLength) {\n let afterFence = fenceStart + closeLen\n while (afterFence < lineEndPos) {\n const code = charCode(source, afterFence)\n if (code === $.CHAR_SPACE || code === $.CHAR_TAB) {\n afterFence++\n } else {\n break\n }\n }\n if (afterFence === lineEndPos) {\n break\n }\n }\n } else if (\n contentIndentToRemove === 4 &&\n openingIndent === 0 &&\n indentCount === 4\n ) {\n let closeLen = countConsecutiveChars(\n source,\n fenceStart,\n fenceChar,\n lineEndPos - fenceStart\n )\n if (\n closeLen >= fenceLength &&\n isBlankLineCheck(source, fenceStart + closeLen, lineEndPos)\n ) {\n break\n }\n }\n\n endPos = skipToNextLine(source, lineEndPos)\n }\n\n let contentEnd =\n endPos > contentStart && source[endPos - 1] === '\\n' ? endPos - 1 : endPos\n let rawContent = source.slice(contentStart, contentEnd)\n if (contentIndentToRemove) {\n rawContent = removeExtraIndentFromCodeBlock(\n rawContent,\n contentIndentToRemove\n )\n }\n\n let finalEndPos =\n endPos < source.length\n ? skipToNextLine(source, util.findLineEnd(source, endPos))\n : endPos\n\n return {\n type: RuleType.codeBlock,\n text: rawContent,\n lang: lang,\n attrs: attrs,\n endPos: finalEndPos,\n } as MarkdownToJSX.CodeBlockNode & { endPos: number }\n}\n\nfunction parseBlockQuoteChildren(\n content: string,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): MarkdownToJSX.ASTNode[] {\n // Fast check: if content is empty or only whitespace, return early\n for (var i = 0; i < content.length; i++) {\n if (!isWS(content[i])) {\n // Parse all blocks using parseBlocksWithState (which uses parseBlock via parseBlocksInHTML)\n const blockChildren = parseBlocksWithState(content, state, options, {\n inline: false,\n inBlockQuote: true,\n })\n // Remove endPos property efficiently without creating intermediate objects\n for (var j = 0; j < blockChildren.length; j++) {\n const node = blockChildren[j] as MarkdownToJSX.ASTNode & {\n endPos?: number\n }\n if ('endPos' in node) {\n delete node.endPos\n }\n }\n return blockChildren\n }\n }\n return []\n}\n\nfunction parseBlockQuote(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult {\n if (state.inline) return null\n\n let checkPos = pos\n while (\n checkPos < source.length &&\n (source[checkPos] === ' ' || source[checkPos] === '\\t')\n ) {\n checkPos++\n }\n if (checkPos >= source.length || source[checkPos] !== '>') return null\n\n // Find the end of the blockquote and process content in single pass\n let endPos = pos\n var processedParts: string[] = []\n var alertType: string | undefined = undefined\n var hasContent = false\n var firstLineStart = -1\n\n // Track if we're currently in a code block (indented or fenced) that requires > prefix\n var inCodeBlock = false\n var codeBlockType: 'indented' | 'fenced' | null = null\n var fencedFenceChar: string | null = null\n var fencedFenceLength = 0\n var previousLineWasEmpty = false\n\n while (endPos < source.length) {\n const lineEnd = util.findLineEnd(source, endPos)\n\n // Check if this line starts a blockquote\n let lineStart = endPos\n // Skip leading whitespace\n while (\n lineStart < lineEnd &&\n (source[lineStart] === ' ' || source[lineStart] === '\\t')\n ) {\n lineStart++\n }\n\n // If line starts with '>', it's part of the blockquote\n if (lineStart < lineEnd && source[lineStart] === '>') {\n let contentStart = lineStart + 1\n if (contentStart < lineEnd && source[contentStart] === ' ') contentStart++\n\n // Inline code block detection (was detectCodeBlockInBlockQuote)\n const indentInfo = calculateIndent(source, contentStart, lineEnd)\n const isIndented = indentInfo.spaceEquivalent >= 4\n let isFenced = false\n let fenceChar: string | null = null\n let fenceLen = 0\n if (contentStart < lineEnd) {\n const firstChar = source[contentStart]\n if (firstChar === '`' || firstChar === '~') {\n let len = 0\n let i = contentStart\n while (i < lineEnd && source[i] === firstChar && len < 20) {\n len++\n i++\n }\n if (len >= 3) {\n isFenced = true\n fenceChar = firstChar\n fenceLen = len\n }\n }\n }\n\n // Update code block state\n if (\n inCodeBlock &&\n codeBlockType === 'fenced' &&\n fenceChar === fencedFenceChar &&\n fenceLen >= fencedFenceLength\n ) {\n inCodeBlock = false\n codeBlockType = null\n fencedFenceChar = null\n fencedFenceLength = 0\n } else if (isIndented || isFenced) {\n inCodeBlock = true\n codeBlockType = isIndented ? 'indented' : 'fenced'\n fencedFenceChar = fenceChar\n fencedFenceLength = fenceLen\n }\n\n // Inline blank line check (was isBlankLineCheck)\n var isBlankLine = !isIndented && !isFenced\n if (isBlankLine) {\n for (var i = contentStart; i < lineEnd; i++) {\n if (!isWS(source[i])) {\n isBlankLine = false\n break\n }\n }\n }\n previousLineWasEmpty = isBlankLine\n\n // Track first line for alert extraction\n if (firstLineStart === -1 && !isBlankLine) {\n firstLineStart = processedParts.length\n }\n if (!isBlankLine) hasContent = true\n\n // Process line content: remove > marker and optional space, handle tabs\n const afterMarkerStart = lineStart + 1\n\n // Check if first char after > is a tab (needs special handling)\n if (afterMarkerStart < lineEnd && source[afterMarkerStart] === '\\t') {\n // Expand tabs to spaces\n processedParts.push(' ') // First tab after > becomes 2 spaces\n let col = 4\n for (let k = afterMarkerStart + 1; k < lineEnd; k++) {\n const char = source[k]\n var code = charCode(char)\n if (code === $.CHAR_TAB) {\n const spaces = 4 - (col % 4)\n // Use fixed strings for common cases\n if (spaces === 1) processedParts.push(' ')\n else if (spaces === 2) processedParts.push(' ')\n else if (spaces === 3) processedParts.push(' ')\n else processedParts.push(' '.repeat(spaces))\n col += spaces\n } else {\n processedParts.push(char)\n col++\n }\n }\n if (lineEnd < source.length) processedParts.push('\\n')\n } else {\n // Fast path: no tab immediately after > (common case)\n let processedContentStart = afterMarkerStart\n if (\n processedContentStart < lineEnd &&\n source[processedContentStart] === ' '\n ) {\n processedContentStart++\n }\n processedParts.push(source.slice(processedContentStart, lineEnd))\n if (lineEnd < source.length) processedParts.push('\\n')\n }\n } else {\n // Check for lazy continuation line (line without > that continues blockquote)\n // Inline blank line check\n var isEmptyLine = true\n for (var i = endPos; i < lineEnd; i++) {\n if (!isWS(source[i])) {\n isEmptyLine = false\n break\n }\n }\n\n // Stop blockquote if: empty line, or in code block (code blocks require > prefix)\n if (isEmptyLine || inCodeBlock) {\n break\n }\n\n const lazyIndentInfo = calculateIndent(source, endPos, lineEnd)\n if (lazyIndentInfo.spaceEquivalent === 0) {\n // Check if this line starts a block (excluding reference definitions which don't break blockquotes)\n const blockResult = parseBlock(source, endPos, state, options)\n if (\n blockResult &&\n blockResult.type !== RuleType.ref &&\n blockResult.type !== RuleType.codeBlock\n ) {\n break\n }\n if (previousLineWasEmpty) {\n break\n }\n }\n processedParts.push(source.slice(endPos, lineEnd))\n if (lineEnd < source.length) processedParts.push('\\n')\n }\n\n endPos = skipToNextLine(source, lineEnd)\n }\n\n // Empty blockquotes are valid (e.g., \">\\n\" or \">\\n> \\n> \\n\")\n // Only reject if we didn't process any lines at all\n if (endPos === pos) return null\n\n // Remove trailing newline if present (avoid endsWith check by tracking)\n if (\n processedParts.length > 0 &&\n processedParts[processedParts.length - 1] === '\\n'\n ) {\n processedParts.pop()\n }\n\n let processedContent = processedParts.join('')\n\n // Extract alert type (check start of content for [!...]\\n pattern)\n if (\n processedContent.length >= 4 &&\n processedContent.charCodeAt(0) === $.CHAR_BRACKET_OPEN &&\n processedContent.charCodeAt(1) === $.CHAR_EXCLAMATION\n ) {\n const alertEnd = processedContent.indexOf(']\\n', 2)\n if (alertEnd > 2) {\n alertType = processedContent.slice(2, alertEnd)\n processedContent = processedContent.slice(alertEnd + 2)\n }\n }\n\n const children = parseBlockQuoteChildren(processedContent, state, options)\n\n const result: MarkdownToJSX.BlockQuoteNode & { endPos: number } = {\n type: RuleType.blockQuote,\n children,\n endPos,\n }\n if (alertType) {\n result.alert = alertType\n }\n return result\n}\n\n/** Remove extra indentation from code block text when used in list items */\nfunction removeExtraIndentFromCodeBlock(\n codeBlockText: string,\n extraIndent: number\n): string {\n return codeBlockText\n .split('\\n')\n .map(function (line) {\n if (line.length === 0) return line\n let toRemove = extraIndent\n let removed = 0\n let i = 0\n let currentColumn = 0\n while (i < line.length && removed < toRemove) {\n if (line[i] === ' ') {\n removed++\n currentColumn++\n i++\n } else if (line[i] === '\\t') {\n const spacesFromTab = 4 - (currentColumn % 4)\n if (removed + spacesFromTab <= toRemove) {\n removed += spacesFromTab\n currentColumn += spacesFromTab\n i++\n } else {\n const remainingToRemove = toRemove - removed\n const spacesToKeep = Math.max(0, spacesFromTab - remainingToRemove)\n return ' '.repeat(spacesToKeep) + line.slice(i + 1)\n }\n } else {\n break\n }\n }\n return line.slice(i)\n })\n .join('\\n')\n}\n\nfunction appendListContinuation(\n continuationContent: string,\n lastItem: MarkdownToJSX.ASTNode[],\n state: MarkdownToJSX.State,\n options: ParseOptions,\n addNewline: boolean = true\n): void {\n const sourceToParse = (addNewline ? '\\n' : '') + continuationContent\n const continuationInline = parseInlineWithState(\n sourceToParse,\n 0,\n sourceToParse.length,\n state,\n options\n )\n if (\n lastItem.length > 0 &&\n lastItem[lastItem.length - 1].type === RuleType.paragraph\n ) {\n ;(\n lastItem[lastItem.length - 1] as MarkdownToJSX.ParagraphNode\n ).children.push(...continuationInline)\n } else {\n lastItem.push(...continuationInline)\n }\n}\n\n// Helper: Check if list item contains block-level content\nfunction listItemHasBlockContent(item: MarkdownToJSX.ASTNode[]): boolean {\n return item.some(function (node) {\n return (\n node.type === RuleType.codeBlock ||\n node.type === RuleType.paragraph ||\n node.type === RuleType.blockQuote ||\n node.type === RuleType.orderedList ||\n node.type === RuleType.unorderedList ||\n node.type === RuleType.heading\n )\n })\n}\n\n// Helper: Check if line matches any list item pattern\nfunction isLineListItem(line: string): boolean {\n return !!line.match(LIST_ITEM_R)\n}\n\n// Helper: Find deepest nested list parent in item hierarchy\nfunction findNestedListParent(\n item: MarkdownToJSX.ASTNode[]\n): MarkdownToJSX.ASTNode[] {\n if (item.length === 0) return item\n var lastBlock = item[item.length - 1]\n if (\n (lastBlock.type === RuleType.orderedList ||\n lastBlock.type === RuleType.unorderedList) &&\n (\n lastBlock as\n | MarkdownToJSX.OrderedListNode\n | MarkdownToJSX.UnorderedListNode\n ).items?.length > 0\n ) {\n return findNestedListParent(\n (\n lastBlock as\n | MarkdownToJSX.OrderedListNode\n | MarkdownToJSX.UnorderedListNode\n ).items.slice(-1)[0]\n )\n }\n return item\n}\n\n// Helper: Skip link reference definition if present\nfunction skipLinkReferenceDefinition(\n source: string,\n linePos: number,\n lineEnd: number,\n indentInfo: ReturnType<typeof calculateIndent>,\n lineWithoutIndent: string,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): number | null {\n if (!util.startsWith(lineWithoutIndent, '[')) return null\n var refCheckState = { inline: false, list: false, refs: state.refs || {} }\n var refResult = parseDefinition(\n source,\n linePos + indentInfo.charCount,\n refCheckState,\n options,\n false\n )\n return refResult ? refResult.endPos : null\n}\n\n// Helper: Check if we should break list due to empty item after blank line\nfunction shouldBreakForEmptyItem(\n items: MarkdownToJSX.ASTNode[][],\n isEmptyItem: boolean,\n prevLineWasBlank: boolean,\n firstItemContent: string\n): boolean {\n if (items.length !== 1 || !prevLineWasBlank) return false\n const lastItem = items[0] // Since items.length === 1, this is the only item\n if (lastItem.length !== 0) return false\n if (isEmptyItem) return true\n if (!isEmptyItem && firstItemContent.trim() === '') return true\n return false\n}\n\n// Helper: Calculate content start column for a list item\n// Helper: Calculate marker end position from match\nfunction calculateMarkerEnd(match: RegExpMatchArray, ordered: boolean): number {\n var markerStart = match.index || 0\n return ordered\n ? markerStart + match[1].length + match[2].length + 1\n : markerStart + match[1].length + 1\n}\n\nfunction calculateListItemContentColumn(\n source: string,\n contentStartInSource: number,\n lineEnd: number,\n baseIndent: number,\n markerEndInLine: number\n): { contentStartColumn: number; contentStartPos: number } {\n var spacesAfterMarker = 0\n var col = baseIndent + markerEndInLine\n var contentCheckPos = contentStartInSource\n while (contentCheckPos < lineEnd && spacesAfterMarker < 4) {\n var code = charCode(source, contentCheckPos)\n if (code === $.CHAR_SPACE) {\n spacesAfterMarker++\n col++\n } else if (code === $.CHAR_TAB) {\n var spaces = 4 - (col % 4)\n if (spacesAfterMarker + spaces > 4) break\n spacesAfterMarker += spaces\n col += spaces\n } else {\n break\n }\n contentCheckPos++\n }\n return { contentStartColumn: col, contentStartPos: contentCheckPos }\n}\n\nfunction matchListItem(\n lineWithoutIndent: string\n): { match: RegExpMatchArray; ordered: boolean; listItemRegex: RegExp } | null {\n var match = lineWithoutIndent.match(LIST_ITEM_R)\n if (!match) return null\n\n // Groups: 1=ordered_num, 2=ordered_delim, 3=ordered_content, 4=ordered_empty_num, 5=ordered_empty_delim, 6=unordered_marker, 7=unordered_content, 8=unordered_empty_marker\n if (match[1]) {\n // Ordered with content: (\\d{1,9})([.)])\\s+(.*)\n return {\n match: [lineWithoutIndent, match[1], match[2], match[3]],\n ordered: true,\n listItemRegex: ORDERED_LIST_ITEM_WITH_CONTENT_R,\n }\n }\n if (match[4]) {\n // Ordered empty: (\\d{1,9})([.)])\\s*\n return {\n match: [lineWithoutIndent, match[4], match[5], ''],\n ordered: true,\n listItemRegex: ORDERED_LIST_ITEM_WITH_CONTENT_R,\n }\n }\n if (match[6]) {\n // Unordered with content: ([-*+])\\s+(.*)\n return {\n match: [lineWithoutIndent, match[6], match[7]],\n ordered: false,\n listItemRegex: UNORDERED_LIST_ITEM_WITH_CONTENT_R,\n }\n }\n if (match[8]) {\n // Unordered empty: ([-*+])\\s*\n return {\n match: [lineWithoutIndent, match[8], ''],\n ordered: false,\n listItemRegex: UNORDERED_LIST_ITEM_WITH_CONTENT_R,\n }\n }\n return null\n}\n\n// Helper: Check if a line is a matching list item for the current list\nfunction isMatchingListItem(\n lineWithoutIndent: string,\n indentInfo: ReturnType<typeof calculateIndent>,\n ordered: boolean,\n marker: string | undefined,\n delimiter: string | undefined,\n baseIndent: number,\n listItemRegex: RegExp\n): boolean {\n if (indentInfo.spaceEquivalent !== baseIndent) return false\n var match = lineWithoutIndent.match(listItemRegex)\n if (match) {\n return ordered ? match[2] === delimiter : match[1] === marker\n }\n var emptyMatch = lineWithoutIndent.match(LIST_ITEM_R)\n if (!emptyMatch) return false\n if (ordered) {\n return emptyMatch[4] && emptyMatch[5] === delimiter\n } else {\n return emptyMatch[8] === marker\n }\n}\n\n// Helper: Handle fenced code blocks that span multiple lines in list items\nfunction expandMultilineFencedCodeBlock(\n source: string,\n itemContent: string,\n startPos: number,\n markerWidth: number\n): { content: string; endPos: number } {\n var content = itemContent\n var pos = startPos\n var fenceChar = itemContent[0]\n while (pos < source.length) {\n var lineEnd = util.findLineEnd(source, pos)\n var line = source.slice(pos, lineEnd)\n var processedLine = util.startsWith(line, ' '.repeat(markerWidth))\n ? line.slice(markerWidth)\n : line\n if (\n util.startsWith(processedLine.trim(), fenceChar) &&\n countConsecutiveChars(processedLine.trim(), 0, fenceChar) >= 3\n ) {\n return { content: content, endPos: skipToNextLine(source, lineEnd) }\n }\n content += '\\n' + processedLine\n pos = skipToNextLine(source, lineEnd)\n }\n return { content: content, endPos: pos }\n}\n\n// Helper function to add a new list item with all standard processing\nfunction addListItem(\n source: string,\n items: MarkdownToJSX.ASTNode[][],\n itemContentStartColumns: number[],\n itemContent: string,\n startPos: number,\n nextLineEnd: number,\n nextIndent: number,\n nextIndentChars: number,\n nextMatch: RegExpMatchArray,\n ordered: boolean,\n hasBlankLines: boolean,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): { newCurrentPos: number; itemHasBlankLine: boolean } {\n // Derive marker/delimiter/regex (cheap to recompute vs passing 3 extra params)\n var marker = ordered ? undefined : nextMatch[1]\n var delimiter = ordered ? nextMatch[2] : undefined\n var listItemRegex = ordered\n ? ORDERED_LIST_ITEM_WITH_CONTENT_R\n : UNORDERED_LIST_ITEM_WITH_CONTENT_R\n\n // Check if item has blank lines\n var itemHasBlankLine = hasBlankLines\n if (!hasBlankLines) {\n var startCheckPos = skipToNextLine(source, nextLineEnd)\n var checkItemPos = startCheckPos\n while (checkItemPos < source.length) {\n var checkLineEnd = util.findLineEnd(source, checkItemPos)\n var checkLine = source.slice(checkItemPos, checkLineEnd)\n var checkIndentInfo = calculateIndent(source, checkItemPos, checkLineEnd)\n var checkIndent = checkIndentInfo.spaceEquivalent\n if (isBlankLineCheck(source, checkItemPos, checkLineEnd)) {\n var afterBlank = skipToNextLine(source, checkLineEnd)\n if (afterBlank < source.length) {\n var afterBlankLineEnd = util.findLineEnd(source, afterBlank)\n var afterBlankIndentInfo = calculateIndent(\n source,\n afterBlank,\n afterBlankLineEnd\n )\n var afterBlankIndent = afterBlankIndentInfo.spaceEquivalent\n var thisItemMarkerEnd = calculateMarkerEnd(nextMatch, ordered)\n var thisItemContentStartInSource =\n startPos + nextIndentChars + thisItemMarkerEnd\n var thisItemResult = calculateListItemContentColumn(\n source,\n thisItemContentStartInSource,\n nextLineEnd,\n nextIndent,\n thisItemMarkerEnd\n )\n var thisItemContentStartColumn = thisItemResult.contentStartColumn\n if (afterBlankIndent + 1 > thisItemContentStartColumn) {\n itemHasBlankLine = true\n break\n }\n }\n break\n } else if (checkIndent <= nextIndent) {\n var checkLineWithoutIndent = checkLine.slice(checkIndentInfo.charCount)\n var checkMatch = checkLineWithoutIndent.match(listItemRegex)\n if (\n checkMatch &&\n (ordered ? checkMatch[2] === delimiter : checkMatch[1] === marker)\n ) {\n break\n }\n }\n checkItemPos = skipToNextLine(source, checkLineEnd)\n }\n }\n\n // Calculate content start column\n var thisItemMarkerEnd = calculateMarkerEnd(nextMatch, ordered)\n var thisItemContentStartInSource =\n startPos + nextIndentChars + thisItemMarkerEnd\n var thisItemResult = calculateListItemContentColumn(\n source,\n thisItemContentStartInSource,\n nextLineEnd,\n nextIndent,\n thisItemMarkerEnd\n )\n var thisItemContentStartColumn = thisItemResult.contentStartColumn\n\n // Handle fenced code blocks\n var actualItemContent = itemContent\n var newCurrentPos = skipToNextLine(source, nextLineEnd)\n if (\n util.startsWith(itemContent, '```') ||\n util.startsWith(itemContent, '~~~')\n ) {\n var markerWidth = ordered\n ? nextMatch[1].length + nextMatch[2].length + 1\n : nextMatch[1].length + 1\n var expandedResult = expandMultilineFencedCodeBlock(\n source,\n itemContent,\n newCurrentPos,\n markerWidth\n )\n actualItemContent = expandedResult.content\n newCurrentPos = expandedResult.endPos\n }\n\n // Build and add item with GFM task support\n items.push(\n buildListItemContent(actualItemContent, itemHasBlankLine, state, options)\n )\n itemContentStartColumns.push(thisItemContentStartColumn)\n\n return { newCurrentPos, itemHasBlankLine }\n}\n\n// Helper function to process list item continuation lines\nfunction checkHTMLTagInterruptsList(\n source: string,\n pos: number,\n indentChars: number,\n baseIndent: number,\n indent: number,\n options: ParseOptions\n): boolean {\n if (indent > baseIndent || options.disableParsingRawHTML) return false\n const lineStartPos = pos + indentChars\n if (lineStartPos >= source.length || source[lineStartPos] !== '<')\n return false\n return isValidHTMLTagStart(source, lineStartPos)\n}\n\n// Lightweight check for HTML tag validity without full parsing\nfunction isValidHTMLTagStart(source: string, pos: number): boolean {\n if (pos >= source.length || source[pos] !== '<') return false\n const len = source.length\n let i = pos + 1\n\n // Handle closing tags\n if (i < len && source[i] === '/') {\n i++\n }\n\n // Must have at least one character for tag name\n if (i >= len) return false\n\n // First character of tag name must be letter\n const firstChar = charCode(source, i)\n if (!isAlphaCode(firstChar)) return false\n i++\n\n // Rest of tag name can be letters, digits, hyphens, underscores\n // Use early return to avoid nested conditionals\n while (i < len) {\n const ch = source[i]\n const code = charCode(source, i)\n\n // Break conditions (valid tag name terminators)\n if (\n ch === '>' ||\n ch === ' ' ||\n ch === '\\t' ||\n ch === '\\n' ||\n ch === '\\r' ||\n ch === '/'\n ) {\n break\n }\n\n // Valid tag name characters - continue\n if (\n ch === '-' ||\n ch === '_' ||\n isAlphaCode(code) ||\n (code >= 48 && code <= 57)\n ) {\n i++\n } else {\n return false // Invalid character in tag name\n }\n }\n\n // Find the end of the tag - use state machine approach to reduce branching\n let state = 0 // 0: normal, 1: in double quotes, 2: in single quotes\n while (i < len) {\n const ch = source[i]\n const code = charCode(source, i)\n\n // State machine for quote handling\n if (state === 1) {\n // in double quotes\n if (ch === '\"') state = 0\n i++\n } else if (state === 2) {\n // in single quotes\n if (ch === \"'\") state = 0\n i++\n } else if (ch === '\"') {\n state = 1\n i++\n } else if (ch === \"'\") {\n state = 2\n i++\n } else if (ch === '>') {\n return true // Found valid closing >\n } else if (ch === '/' && i + 1 < len && source[i + 1] === '>') {\n return true // Found valid self-closing />\n } else if (code === 10 || code === 13) {\n // \\n or \\r\n return false // No multiline tags in this context\n } else {\n i++\n }\n }\n\n return false // No closing > found\n}\n\nfunction processContinuation(\n source: string,\n item: MarkdownToJSX.ASTNode[],\n contentStartColumn: number,\n startPos: number,\n baseIndent: number,\n ordered: boolean,\n marker: string | undefined,\n delimiter: string | undefined,\n listItemRegex: RegExp,\n state: MarkdownToJSX.State,\n options: ParseOptions,\n allowLinkRefs?: boolean\n): number {\n let pos = startPos\n let prevLineWasBlank = false\n while (pos < source.length) {\n const lineEnd = util.findLineEnd(source, pos)\n const indentInfo = calculateIndent(source, pos, lineEnd)\n const indent = indentInfo.spaceEquivalent\n\n if (isBlankLineCheck(source, pos, lineEnd)) {\n prevLineWasBlank = true\n pos = skipToNextLine(source, lineEnd)\n continue\n }\n\n const lineWithoutIndent = source.slice(pos + indentInfo.charCount, lineEnd)\n\n if (\n indent <= baseIndent &&\n isMatchingListItem(\n lineWithoutIndent,\n indentInfo,\n ordered,\n marker,\n delimiter,\n baseIndent,\n listItemRegex\n )\n ) {\n break\n }\n\n if (indent >= contentStartColumn) {\n // Check for link reference definitions (only for first item)\n if (allowLinkRefs && prevLineWasBlank) {\n const refEndPos = skipLinkReferenceDefinition(\n source,\n pos,\n lineEnd,\n indentInfo,\n lineWithoutIndent,\n state,\n options\n )\n if (refEndPos) {\n pos = refEndPos\n prevLineWasBlank = false\n continue\n }\n }\n\n const result = processListContinuationLine(\n source,\n pos,\n lineEnd,\n indentInfo,\n contentStartColumn - 1,\n contentStartColumn,\n item,\n prevLineWasBlank,\n state,\n options,\n undefined,\n baseIndent\n )\n if (result.processed) {\n pos = result.newPos\n prevLineWasBlank = result.wasBlank\n continue\n }\n } else {\n break\n }\n }\n return pos\n}\n\n// Helper: Parse content with paragraph wrapping for tight/loose lists\nfunction parseContentWithParagraphHandling(\n content: string,\n wrapInParagraph: boolean,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): MarkdownToJSX.ASTNode[] {\n const blocks = parseBlocksWithState(content, state, options, {\n inline: false,\n list: true,\n })\n if (blocks.length > 0) {\n // Unwrap single paragraph for tight lists\n return !wrapInParagraph &&\n blocks.length === 1 &&\n blocks[0].type === RuleType.paragraph\n ? (blocks[0] as MarkdownToJSX.ParagraphNode).children\n : blocks\n }\n // Fallback to inline parsing\n const inline = parseWithInlineMode(state, true, () =>\n parseInlineSpan(content, 0, content.length, state, options)\n )\n return wrapInParagraph && inline.length > 0\n ? [\n {\n type: RuleType.paragraph,\n children: inline,\n } as MarkdownToJSX.ParagraphNode,\n ]\n : inline\n}\n\nfunction buildListItemContent(\n itemContent: string,\n itemHasBlankLine: boolean,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): MarkdownToJSX.ASTNode[] {\n const task = parseGFMTask(itemContent, 0, state)\n const hasTask =\n task &&\n (task.endPos >= itemContent.length || itemContent[task.endPos] === ' ')\n if (!hasTask) {\n return parseContentWithParagraphHandling(\n itemContent,\n itemHasBlankLine,\n state,\n options\n )\n }\n const afterTask =\n task.endPos < itemContent.length ? task.endPos + 1 : task.endPos\n const restContent = itemContent.slice(afterTask)\n const restNodes = parseContentWithParagraphHandling(\n restContent,\n itemHasBlankLine,\n state,\n options\n )\n const nodes: MarkdownToJSX.ASTNode[] = [task]\n if (task.endPos < itemContent.length) {\n nodes.push({ type: RuleType.text, text: ' ' } as MarkdownToJSX.TextNode)\n }\n nodes.push(...restNodes)\n return nodes\n}\n\nfunction checkUnicodeWhitespaceAfterMarker(\n match: RegExpMatchArray,\n marker: string\n): boolean {\n if (!match[0]) return false\n const markerInMatch = match[0].indexOf(marker)\n if (markerInMatch === -1) return false\n const afterMarkerInMatch = markerInMatch + marker.length\n if (afterMarkerInMatch >= match[0].length) return false\n const afterMarkerChar = match[0][afterMarkerInMatch]\n return afterMarkerChar ? charCode(afterMarkerChar) === $.CHAR_NBSP : false\n}\n\nfunction convertSetextHeadingInListItem(\n lastItem: MarkdownToJSX.ASTNode[],\n underlineLine: string,\n options: ParseOptions\n): boolean {\n if (lastItem.length === 0) return false\n const lastBlock = lastItem[lastItem.length - 1]\n const trimmed = underlineLine.trim()\n if (\n (!util.startsWith(trimmed, '=') && !util.startsWith(trimmed, '-')) ||\n trimmed.length < 1 ||\n !/^[=-]+[ \\t]*$/.test(trimmed)\n ) {\n return false\n }\n\n let headingChildren: MarkdownToJSX.ASTNode[] = []\n let headingContent = ''\n if (lastBlock.type === RuleType.paragraph) {\n const paragraph = lastBlock as MarkdownToJSX.ParagraphNode\n headingChildren = paragraph.children\n headingContent = paragraph.children\n .map(child =>\n child.type === RuleType.text\n ? (child as MarkdownToJSX.TextNode).text\n : ''\n )\n .join('')\n .trim()\n } else if (lastBlock.type === RuleType.text) {\n const textNodes: MarkdownToJSX.TextNode[] = []\n let i = lastItem.length - 1\n while (i >= 0 && lastItem[i].type === RuleType.text) {\n textNodes.unshift(lastItem[i] as MarkdownToJSX.TextNode)\n i--\n }\n if (textNodes.length > 0) {\n headingChildren = textNodes\n headingContent = textNodes\n .map(node => (node as MarkdownToJSX.TextNode).text)\n .join('')\n .trim()\n }\n }\n\n if (!headingContent) return false\n\n const underlineChar = trimmed[0]\n const level = underlineChar === '=' ? 1 : 2\n if (lastBlock.type === RuleType.paragraph) {\n lastItem.pop()\n } else if (lastBlock.type === RuleType.text) {\n while (\n lastItem.length > 0 &&\n lastItem[lastItem.length - 1].type === RuleType.text\n ) {\n lastItem.pop()\n }\n }\n lastItem.push(\n createHeading(level, headingChildren, headingContent, options.slugify)\n )\n return true\n}\n\nfunction processListContinuationLine(\n source: string,\n currentPos: number,\n nextLineEnd: number,\n nextIndentInfo: ReturnType<typeof calculateIndent>,\n continuationColumn: number,\n contentStartColumn: number,\n lastItem: MarkdownToJSX.ASTNode[],\n prevLineWasBlank: boolean,\n state: MarkdownToJSX.State,\n options: ParseOptions,\n unwrapParagraphs?: boolean,\n baseIndent?: number\n): { processed: boolean; newPos: number; wasBlank: boolean } {\n const nextIndent = nextIndentInfo.spaceEquivalent\n const continuationContent = source.slice(\n currentPos + nextIndentInfo.charCount,\n nextLineEnd\n )\n\n if (nextIndent >= continuationColumn + 4) {\n const blockResult = parseCodeBlock(source, currentPos, state)\n if (blockResult) {\n const codeBlockNode = blockResult as MarkdownToJSX.CodeBlockNode & {\n endPos: number\n }\n const adjustedText = removeExtraIndentFromCodeBlock(\n codeBlockNode.text || '',\n contentStartColumn\n )\n lastItem.push({\n ...codeBlockNode,\n text: adjustedText,\n } as MarkdownToJSX.CodeBlockNode)\n return {\n processed: true,\n newPos: codeBlockNode.endPos,\n wasBlank: false,\n }\n }\n }\n\n const indentRelativeToContentFenced = nextIndent - (contentStartColumn - 1)\n if (\n nextIndent + 1 >= contentStartColumn &&\n indentRelativeToContentFenced <= 3\n ) {\n const continuationStart = currentPos + nextIndentInfo.charCount\n if (continuationStart < nextLineEnd) {\n const firstCharAfterIndent = source[continuationStart]\n if (firstCharAfterIndent === '`' || firstCharAfterIndent === '~') {\n const fencedResult = parseCodeFenced(\n source,\n continuationStart,\n state,\n options\n )\n if (fencedResult) {\n const codeBlockNode = fencedResult as MarkdownToJSX.CodeBlockNode & {\n endPos: number\n }\n const adjustedText = removeExtraIndentFromCodeBlock(\n codeBlockNode.text || '',\n contentStartColumn - 1\n )\n lastItem.push({\n ...codeBlockNode,\n text: adjustedText,\n endPos: codeBlockNode.endPos,\n } as MarkdownToJSX.CodeBlockNode & { endPos: number })\n return {\n processed: true,\n newPos: codeBlockNode.endPos,\n wasBlank: false,\n }\n }\n }\n }\n }\n\n if (\n continuationContent.length > 0 &&\n (continuationContent[0] === '-' ||\n continuationContent[0] === '*' ||\n continuationContent[0] === '+' ||\n (continuationContent[0] >= '0' && continuationContent[0] <= '9'))\n ) {\n const listMarkerRegex = /^([-*+]|\\d{1,9}[.)])\\s+/\n if (listMarkerRegex.test(continuationContent)) {\n const inline = parseInlineWithState(\n continuationContent,\n 0,\n continuationContent.length,\n state,\n options\n )\n lastItem.push({ type: RuleType.text, text: '\\n' }, ...inline)\n return {\n processed: true,\n newPos: skipToNextLine(source, nextLineEnd),\n wasBlank: false,\n }\n }\n }\n\n const mergedPos = tryMergeBlockquoteContinuation(\n source,\n currentPos,\n lastItem,\n continuationContent,\n state,\n options\n )\n if (mergedPos !== null) {\n return { processed: true, newPos: mergedPos, wasBlank: false }\n }\n\n const continuationBlocks = parseBlocksWithState(\n continuationContent,\n state,\n options,\n { inline: false, list: true }\n )\n if (continuationBlocks.length > 0) {\n if (unwrapParagraphs && continuationBlocks[0].type === RuleType.paragraph) {\n const continuationParagraph =\n continuationBlocks[0] as MarkdownToJSX.ParagraphNode\n lastItem.push(\n { type: RuleType.text, text: '\\n' } as MarkdownToJSX.TextNode,\n ...continuationParagraph.children\n )\n if (continuationBlocks.length > 1) {\n lastItem.push(...continuationBlocks.slice(1))\n }\n } else if (\n !prevLineWasBlank &&\n continuationBlocks[0].type === RuleType.paragraph &&\n lastItem.length > 0\n ) {\n const lastBlock = lastItem[lastItem.length - 1]\n const continuationParagraph =\n continuationBlocks[0] as MarkdownToJSX.ParagraphNode\n if (lastBlock.type === RuleType.paragraph) {\n ;(lastBlock as MarkdownToJSX.ParagraphNode).children.push(\n { type: RuleType.text, text: '\\n' } as MarkdownToJSX.TextNode,\n ...continuationParagraph.children\n )\n } else if (lastBlock.type === RuleType.heading) {\n lastItem.push(...continuationParagraph.children)\n } else if (!listItemHasBlockContent(lastItem)) {\n lastItem.push(\n { type: RuleType.text, text: ' ' } as MarkdownToJSX.TextNode,\n ...continuationParagraph.children\n )\n } else {\n lastItem.push(...continuationBlocks)\n }\n if (continuationBlocks.length > 1) {\n lastItem.push(...continuationBlocks.slice(1))\n }\n } else {\n lastItem.push(...continuationBlocks)\n }\n return {\n processed: true,\n newPos: skipToNextLine(source, nextLineEnd),\n wasBlank: false,\n }\n }\n\n if (prevLineWasBlank) {\n const inline = parseWithInlineMode(state, true, () =>\n parseInlineSpan(\n continuationContent,\n 0,\n continuationContent.length,\n state,\n options\n )\n )\n lastItem.push({\n type: RuleType.paragraph,\n children: inline,\n } as MarkdownToJSX.ParagraphNode)\n } else {\n appendListContinuation(continuationContent, lastItem, state, options)\n }\n return {\n processed: true,\n newPos: skipToNextLine(source, nextLineEnd),\n wasBlank: false,\n }\n}\n\nfunction parseList(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult {\n if (state.inline) return null\n\n // Set inList state for proper GFM task tracking during inline parsing\n var originalInList = state.inList\n state.inList = true\n\n // Lists must start at the beginning of a line (block boundary)\n if (pos > 0) {\n var prevCharCode = charCode(source, pos - 1)\n if (prevCharCode !== $.CHAR_NEWLINE && prevCharCode !== $.CHAR_CR) {\n state.inList = originalInList\n return null\n }\n }\n\n var lineEnd = util.findLineEnd(source, pos)\n var indentInfo = calculateIndent(source, pos, lineEnd)\n // Early fail: headings/lists cannot be indented more than 3 spaces unless in list context\n if (indentInfo.spaceEquivalent > 3 && !state.inList) {\n state.inList = originalInList\n return null\n }\n var line = source.slice(pos, lineEnd)\n var indent = indentInfo.charCount\n var lineWithoutIndent = line.slice(indent)\n\n // Detect list type: ordered (digit marker) vs unordered (-/*/+ marker)\n var matchResult = matchListItem(lineWithoutIndent)\n if (!matchResult) {\n state.inList = originalInList\n return null\n }\n var match = matchResult.match\n var ordered = matchResult.ordered\n var listItemRegex = matchResult.listItemRegex\n\n var baseIndent = indentInfo.spaceEquivalent\n // Extract list-specific properties: start number and delimiter for ordered, marker for unordered\n var start = ordered ? parseInt(match[1], 10) : undefined\n var delimiter = ordered ? match[2] : undefined // '.' or ')' for ordered lists\n var marker = ordered ? undefined : match[1] // '-', '*', or '+' for unordered lists\n\n // Check if this is an empty list item (no content after marker)\n var isEmptyItem = ordered ? match[3] === '' : match[2] === ''\n\n // Helper: Check if we're at a block boundary (document start or after blank line)\n function isAtBlockBoundary(\n checkPos: number,\n requireBlankLine: boolean\n ): boolean {\n if (checkPos === 0) return true\n var prevCode = charCode(source, checkPos - 1)\n if (prevCode !== $.CHAR_NEWLINE) return false\n if (!requireBlankLine) return true\n var backPos = checkPos - 2\n while (backPos >= 0) {\n var code = charCode(source, backPos)\n if (code !== $.CHAR_SPACE && code !== $.CHAR_TAB) break\n backPos--\n }\n return backPos < 0 || charCode(source, backPos) === $.CHAR_NEWLINE\n }\n\n // Per CommonMark: empty list items cannot interrupt paragraphs (need blank line)\n if (isEmptyItem && !isAtBlockBoundary(pos, true)) {\n state.inList = originalInList\n return null\n }\n\n // Per CommonMark: only ordered lists starting with 1 can interrupt paragraphs\n if (ordered && start !== 1 && !isAtBlockBoundary(pos, false)) {\n return null\n }\n\n // For unordered lists, check that the whitespace after marker is regular space/tab, not Unicode whitespace\n if (!ordered && checkUnicodeWhitespaceAfterMarker(match, marker)) {\n return null\n }\n\n // Calculate the content start column: where the first non-whitespace character\n // after the marker delimiter actually appears in the source\n // This is needed to determine continuation indentation\n var markerStartInLine = match.index || 0\n // isEmptyItem is already set above - check if it needs updating based on spacesAfterMarkerCount\n // Empty item is different from item with whitespace but no content\n // We'll calculate spacesAfterMarkerCount later and update isEmptyItem if needed\n var markerEndInLine = ordered\n ? markerStartInLine + match[1].length + match[2].length + 1 // number + delimiter + required space\n : isEmptyItem\n ? markerStartInLine + match[1].length // marker only (no space)\n : markerStartInLine + match[1].length + 1 // marker + required space\n // Find the actual position after marker delimiter in the source\n var contentStartInSource = pos + indent + markerEndInLine\n // Count spaces/tabs before first non-whitespace in the content\n // Per CommonMark spec: marker must be followed by 1 ≤ N ≤ 4 spaces\n var contentColumnResult = calculateListItemContentColumn(\n source,\n contentStartInSource,\n lineEnd,\n baseIndent,\n markerEndInLine\n )\n var contentStartColumn = contentColumnResult.contentStartColumn\n // minimumContentStartColumn is the minimum column where content can start (for continuation checks)\n // This is the column after marker+space, regardless of how much whitespace follows\n // For empty items, it's right after the marker\n var markerBaseColumn = baseIndent + markerStartInLine + match[1].length\n var minimumContentStartColumn = ordered\n ? markerBaseColumn + match[2].length + 1 // number + delimiter + space\n : isEmptyItem\n ? markerBaseColumn // marker only (no space)\n : markerBaseColumn + 1 // marker + space\n\n var items: MarkdownToJSX.ASTNode[][] = []\n // Track contentStartColumn for each item (for nested list detection)\n var itemContentStartColumns: number[] = []\n\n // Helper: Check if a marker column is nested enough to belong to the last item\n function isMarkerNested(\n markerColumn: number,\n lastItemContentColumn: number,\n hasBlockContent: boolean\n ): boolean {\n return hasBlockContent\n ? markerColumn >= lastItemContentColumn\n : markerColumn > lastItemContentColumn\n }\n\n // Helper: Get last item\n function getLastItem(): MarkdownToJSX.ASTNode[] {\n return items[items.length - 1]\n }\n\n // Helper: Get last item's content start column\n function getLastItemContentColumn(): number {\n return (\n itemContentStartColumns[itemContentStartColumns.length - 1] ??\n contentStartColumn\n )\n }\n\n function tryParseNestedList(\n pos: number,\n lastItem: MarkdownToJSX.ASTNode[]\n ): ParseResult | null {\n const parentItem = findNestedListParent(lastItem)\n const originalList = state.inList\n state.inList = true\n const result = parseList(source, pos, state, options)\n state.inList = originalList\n if (result) {\n parentItem.push(result)\n return result\n }\n return null\n }\n\n var currentPos = skipToNextLine(source, lineEnd)\n\n // Check if this is a loose list (has blank lines)\n var checkPos = currentPos\n var hasBlankLines = false\n\n while (checkPos < source.length) {\n var nextLineEnd = util.findLineEnd(source, checkPos)\n var nextLine = source.slice(checkPos, nextLineEnd)\n if (nextLine.trim() === '') {\n // look ahead to next non-empty line\n var look = skipToNextLine(source, nextLineEnd)\n while (look < source.length) {\n var code = charCode(source, look)\n if (code === $.CHAR_NEWLINE) {\n // keep skipping\n } else if (!WHITESPACE_CHARS.has(source[look])) {\n break\n }\n look++\n }\n var lookEnd = util.findLineEnd(source, look)\n var lookLine = source.slice(look, lookEnd)\n var lookIndentInfo = calculateIndent(source, look, lookEnd)\n var lookLineWithoutIndent = lookLine.slice(lookIndentInfo.charCount)\n if (\n isMatchingListItem(\n lookLineWithoutIndent,\n lookIndentInfo,\n ordered,\n marker,\n delimiter,\n baseIndent,\n listItemRegex\n )\n ) {\n hasBlankLines = true\n } else {\n // Per CommonMark: link reference definitions can interrupt lists\n // If blank line is followed by a link reference definition, check if there's a list item after it\n var refEndPos = skipLinkReferenceDefinition(\n source,\n look,\n lookEnd,\n lookIndentInfo,\n lookLineWithoutIndent,\n state,\n options\n )\n if (refEndPos) {\n var afterRefPos = refEndPos\n while (\n afterRefPos < source.length &&\n charCode(source, afterRefPos) === $.CHAR_NEWLINE\n ) {\n afterRefPos++\n }\n if (afterRefPos < source.length) {\n var afterRefLineEnd = util.findLineEnd(source, afterRefPos)\n var afterRefLine = source.slice(afterRefPos, afterRefLineEnd)\n var afterRefIndentInfo = calculateIndent(\n source,\n afterRefPos,\n afterRefLineEnd\n )\n var afterRefLineWithoutIndent = afterRefLine.slice(\n afterRefIndentInfo.charCount\n )\n if (\n isMatchingListItem(\n afterRefLineWithoutIndent,\n afterRefIndentInfo,\n ordered,\n marker,\n delimiter,\n baseIndent,\n listItemRegex\n )\n ) {\n hasBlankLines = true\n }\n }\n }\n }\n break\n }\n var nextIndentInfo = calculateIndent(source, checkPos, nextLineEnd)\n var nextLineWithoutIndent = nextLine.slice(nextIndentInfo.charCount)\n var nextMatchResult = matchListItem(nextLineWithoutIndent)\n if (!nextMatchResult) break\n var nextMatch = nextMatchResult.match\n if (ordered) {\n if (nextMatch[2] !== delimiter) break\n } else {\n if (nextMatch[1] !== marker) break\n }\n checkPos = skipToNextLine(source, nextLineEnd)\n }\n\n // Parse the first item\n var firstItemContent = ordered ? match[3] : match[2]\n // Trim leading whitespace from content (regex now captures optional whitespace)\n firstItemContent = firstItemContent.trimStart()\n\n // Per CommonMark spec: tabs after list marker need special handling\n // For `-\\t\\tfoo`: `-` at column 0, first tab at column 1 = 3 spaces (one for marker delimiter),\n // second tab at column 4 = 4 spaces, total 6 spaces, so code block with 2 spaces remaining\n // The regex `\\s+` consumes the tabs, so match[2]/match[3] is just `foo`\n // We need to check the original source to detect tabs after the marker\n var markerStartPos = pos + indent + (match.index || 0)\n var markerEndPos = ordered\n ? markerStartPos + match[1].length + match[2].length // number + delimiter\n : markerStartPos + match[1].length // marker\n\n // Check for spaces after marker (for code blocks with 5+ spaces)\n // Per CommonMark: if there are 4+ spaces after the marker (including required space),\n // the first line is an indented code block\n var contentStartPos = markerEndPos\n // Skip the required space/tab after marker\n while (contentStartPos < source.length) {\n var code = charCode(source, contentStartPos)\n if (code !== $.CHAR_SPACE && code !== $.CHAR_TAB) break\n contentStartPos++\n }\n // Count spaces after marker (including the required one)\n var spacesAfterMarkerCount = 0\n var spacesCheckPos = markerEndPos\n while (spacesCheckPos < lineEnd) {\n var code = charCode(source, spacesCheckPos)\n if (code === $.CHAR_TAB) {\n spacesAfterMarkerCount += 4 - (spacesAfterMarkerCount % 4)\n } else if (code === $.CHAR_SPACE) {\n spacesAfterMarkerCount++\n } else {\n break\n }\n spacesCheckPos++\n }\n\n var tabsProcessed = false\n if (\n markerEndPos < source.length &&\n charCode(source, markerEndPos) === $.CHAR_TAB\n ) {\n // First tab after marker was consumed by `\\s+`\n // Tab at column 1 = 3 spaces (1 for delimiter, 2 for content)\n // Check if there's a second tab\n var tabCount = 1\n var tabCheckPos = markerEndPos + 1\n while (\n tabCheckPos < source.length &&\n charCode(source, tabCheckPos) === $.CHAR_TAB\n ) {\n tabCount++\n tabCheckPos++\n }\n\n if (tabCount >= 2) {\n // We have 2+ tabs after marker: first gives 2 spaces, second at column 4 = 4 spaces\n // Total: 6 spaces, then remove 4 for code block = 2 spaces\n firstItemContent = ' ' + firstItemContent\n tabsProcessed = true\n }\n }\n // Update isEmptyItem now that we know spacesAfterMarkerCount\n // Empty item is one with no whitespace after marker (spacesAfterMarkerCount === 0)\n // For unordered lists, also check that match[2] is empty (no content captured)\n if (!ordered) {\n isEmptyItem = isEmptyItem && spacesAfterMarkerCount === 0\n }\n // RULE_2_CODE_START: if 4+ spaces after marker, first line is indented code block\n // Skip if tabs were already processed (they already account for code block indentation)\n if (spacesAfterMarkerCount >= 4 && !tabsProcessed) {\n // Preserve the leading spaces for code blocks\n const preservedSpaces = ' '.repeat(spacesAfterMarkerCount - 1)\n firstItemContent = preservedSpaces + firstItemContent.trimStart()\n }\n\n // RULE_3_BLANK_START: check if item starts with blank line\n // If firstItemContent is empty (just whitespace), this is RULE_3_BLANK_START\n var startsWithBlankLine = firstItemContent.trim() === ''\n if (startsWithBlankLine) {\n // For RULE_3_BLANK_START, content starts after blank line(s)\n // Continuation lines need to be indented by W + 1 spaces minimum\n // W is the width of the marker (1 for '-', 2 for '10.', etc.)\n // So minimum continuation indent is markerWidth + 1\n }\n\n // Check if there will be blank lines within the first item (after currentPos)\n // by looking ahead to see if we'll encounter a blank line before the next item or end\n let firstItemHasBlankLine = hasBlankLines\n if (!hasBlankLines && currentPos < source.length) {\n var firstCheckPos = currentPos\n while (firstCheckPos < source.length) {\n var firstNextLineEnd = util.findLineEnd(source, firstCheckPos)\n var firstNextLine = source.slice(firstCheckPos, firstNextLineEnd)\n if (isBlankLineCheck(source, firstCheckPos, firstNextLineEnd)) {\n // Found blank line - check if continuation belongs to nested list or first item\n var afterBlank = skipToNextLine(source, firstNextLineEnd)\n // Skip consecutive blank lines\n while (afterBlank < source.length) {\n var blankLineEnd = util.findLineEnd(source, afterBlank)\n if (isBlankLineCheck(source, afterBlank, blankLineEnd)) {\n afterBlank = skipToNextLine(source, blankLineEnd)\n } else {\n break\n }\n }\n\n if (afterBlank < source.length) {\n var afterIndentInfo = calculateIndent(\n source,\n afterBlank,\n source.length\n )\n var afterIndent = afterIndentInfo.spaceEquivalent\n if (afterIndent >= baseIndent) {\n var afterLine = source.slice(\n afterBlank,\n util.findLineEnd(source, afterBlank)\n )\n var afterMatch = afterLine\n .slice(afterIndentInfo.charCount)\n .match(listItemRegex)\n var afterIsNewItem =\n afterMatch &&\n (ordered ? afterMatch[2] === delimiter : afterMatch[1] === marker)\n\n // Find nested item before blank line and calculate its content column\n var nestedItemContentColumn = null\n for (\n var nestedCheckPos = currentPos;\n nestedCheckPos < firstCheckPos;\n nestedCheckPos = util.findLineEnd(source, nestedCheckPos) + 1\n ) {\n var nestedCheckLineEnd = util.findLineEnd(source, nestedCheckPos)\n var nestedCheckIndentInfo = calculateIndent(\n source,\n nestedCheckPos,\n nestedCheckLineEnd\n )\n var nestedCheckMatch = source\n .slice(nestedCheckPos, nestedCheckLineEnd)\n .slice(nestedCheckIndentInfo.charCount)\n .match(listItemRegex)\n var isNestedItem =\n nestedCheckMatch &&\n nestedCheckIndentInfo.spaceEquivalent > baseIndent &&\n nestedCheckIndentInfo.spaceEquivalent >= contentStartColumn &&\n (ordered\n ? nestedCheckMatch[2] === delimiter\n : nestedCheckMatch[1] === marker)\n\n if (isNestedItem) {\n // Calculate nested item's content column (same pattern as contentStartColumn)\n var nestedMarkerStart =\n nestedCheckIndentInfo.spaceEquivalent + 1\n var nestedMarkerEnd = ordered\n ? nestedMarkerStart +\n nestedCheckMatch[1].length +\n nestedCheckMatch[2].length +\n 1\n : nestedMarkerStart + nestedCheckMatch[1].length + 1\n var nestedContentStartInSource =\n nestedCheckPos +\n nestedCheckIndentInfo.charCount +\n nestedCheckMatch[0].length\n var nestedResult = calculateListItemContentColumn(\n source,\n nestedContentStartInSource,\n nestedCheckLineEnd,\n nestedMarkerStart,\n nestedMarkerEnd - nestedMarkerStart\n )\n nestedItemContentColumn = nestedResult.contentStartColumn\n break\n }\n }\n\n var continuationCheckColumn =\n spacesAfterMarkerCount >= 5\n ? minimumContentStartColumn\n : contentStartColumn\n if (\n !afterIsNewItem &&\n afterIndent >= continuationCheckColumn &&\n (nestedItemContentColumn === null ||\n afterIndent + 1 < nestedItemContentColumn)\n ) {\n firstItemHasBlankLine = true\n }\n }\n }\n break\n }\n // Check if this line is a new list item (at same or greater indentation)\n var firstLineIndentInfo = calculateIndent(\n source,\n firstCheckPos,\n firstNextLineEnd\n )\n var firstIndent = firstLineIndentInfo.spaceEquivalent\n var firstLineWithoutIndent = firstNextLine.slice(\n firstLineIndentInfo.charCount\n )\n var firstLineMatch = firstLineWithoutIndent.match(listItemRegex)\n var firstIsNewItem =\n firstLineMatch &&\n (ordered\n ? firstLineMatch[2] === delimiter\n : firstLineMatch[1] === marker)\n // If it's a new item at baseIndent, it's the next item at same level - stop looking\n // For nested items, continue looking for blank lines after the nested list\n if (firstIsNewItem) {\n if (firstIndent <= baseIndent) {\n // Same level or higher - stop looking\n break\n }\n // Nested list - continue looking (don't break)\n }\n firstCheckPos = skipToNextLine(source, firstNextLineEnd)\n }\n }\n\n // Handle fenced code blocks that span multiple lines\n // Note: We use manual expansion here rather than parseCodeFenced because\n // we need to return a content string (with fence lines) that will be parsed later,\n // not an AST node. parseCodeFenced returns an AST node, which doesn't fit this use case.\n var actualFirstItemContent = firstItemContent\n if (\n util.startsWith(firstItemContent, '```') ||\n util.startsWith(firstItemContent, '~~~')\n ) {\n var markerWidth = ordered\n ? match[1].length + match[2].length + 1\n : match[1].length + 1\n var expandedResult = expandMultilineFencedCodeBlock(\n source,\n firstItemContent,\n currentPos,\n markerWidth\n )\n actualFirstItemContent = expandedResult.content\n currentPos = expandedResult.endPos\n }\n\n // For tight lists with whitespace-only first line, combine with continuation to avoid multiple blocks\n var hasWhitespaceButNoContent =\n !isEmptyItem &&\n firstItemContent.trim() === '' &&\n spacesAfterMarkerCount > 0 &&\n spacesAfterMarkerCount < 5\n if (hasWhitespaceButNoContent && !firstItemHasBlankLine) {\n var pos = currentPos\n while (pos < source.length) {\n var lineEnd = util.findLineEnd(source, pos)\n var line = source.slice(pos, lineEnd)\n if (line.trim() === '') break\n var indentInfo = calculateIndent(source, pos, lineEnd)\n if (indentInfo.spaceEquivalent < minimumContentStartColumn) break\n var lineWithoutIndent = line.slice(indentInfo.charCount)\n if (\n indentInfo.spaceEquivalent <= baseIndent &&\n isMatchingListItem(\n lineWithoutIndent,\n indentInfo,\n ordered,\n marker,\n delimiter,\n baseIndent,\n listItemRegex\n )\n ) {\n break\n }\n actualFirstItemContent += '\\n' + lineWithoutIndent\n currentPos = pos = skipToNextLine(source, lineEnd)\n }\n }\n\n // Build first item with GFM task support\n items.push(\n buildListItemContent(\n actualFirstItemContent,\n firstItemHasBlankLine,\n state,\n options\n )\n )\n itemContentStartColumns.push(contentStartColumn)\n\n // Process continuation lines for the first item\n // For tight lists (no blank lines), also process continuation if it's indented enough\n const shouldProcessContinuation =\n firstItemHasBlankLine &&\n (spacesAfterMarkerCount >= 5 || hasWhitespaceButNoContent)\n if (shouldProcessContinuation) {\n const lastItem = getLastItem()\n currentPos = processContinuation(\n source,\n lastItem,\n minimumContentStartColumn,\n currentPos,\n baseIndent,\n ordered,\n marker,\n delimiter,\n listItemRegex,\n state,\n options,\n true\n )\n } else if (!firstItemHasBlankLine) {\n // For tight lists (no blank lines), process continuation lines\n const continuationColumn = minimumContentStartColumn - 1\n while (currentPos < source.length) {\n const nextLineEnd = util.findLineEnd(source, currentPos)\n const nextLine = source.slice(currentPos, nextLineEnd)\n const nextIndentInfo = calculateIndent(source, currentPos, nextLineEnd)\n const nextIndent = nextIndentInfo.spaceEquivalent\n const nextLineWithoutIndent = nextLine.slice(nextIndentInfo.charCount)\n\n if (\n nextLine.trim() === '' ||\n (nextIndent <= baseIndent &&\n isMatchingListItem(\n nextLineWithoutIndent,\n nextIndentInfo,\n ordered,\n marker,\n delimiter,\n baseIndent,\n listItemRegex\n )) ||\n (isLineListItem(nextLineWithoutIndent) && nextIndent > baseIndent) ||\n nextIndent < continuationColumn\n ) {\n break\n }\n\n const lastItem = getLastItem()\n const result = processListContinuationLine(\n source,\n currentPos,\n nextLineEnd,\n nextIndentInfo,\n continuationColumn,\n contentStartColumn,\n lastItem,\n false,\n state,\n options,\n true,\n baseIndent\n )\n if (result.processed) {\n currentPos = result.newPos\n } else {\n break\n }\n }\n }\n\n // Continue parsing subsequent list items\n var prevLineWasBlank = false\n while (currentPos < source.length) {\n const nextLineEnd = util.findLineEnd(source, currentPos)\n\n const nextLine = source.slice(currentPos, nextLineEnd)\n const nextIndentInfo = calculateIndent(source, currentPos, nextLineEnd)\n const nextIndentChars = nextIndentInfo.charCount\n const nextIndent = nextIndentInfo.spaceEquivalent\n\n if (nextLine.trim() === '') {\n // Blank line - mark as loose list and continue\n hasBlankLines = true\n prevLineWasBlank = true\n currentPos = skipToNextLine(source, nextLineEnd)\n } else if (nextIndent < baseIndent) {\n const nextLineWithoutIndent = nextLine.slice(nextIndentChars)\n if (\n nextLineWithoutIndent.startsWith('<') &&\n checkHTMLTagInterruptsList(\n source,\n currentPos,\n nextIndentChars,\n baseIndent,\n nextIndent,\n options\n )\n ) {\n break\n }\n\n // Less indented - check if this is a lazy continuation line\n // Per CommonMark: lazy continuation lines can have all indentation deleted\n // They are still part of the list item if they are paragraph continuation text\n const trimmed = nextLineWithoutIndent.trim()\n if (\n trimmed.length > 0 &&\n items.length > 0 &&\n !isBlockStartChar(trimmed[0]) &&\n !isMatchingListItem(\n nextLineWithoutIndent,\n nextIndentInfo,\n ordered,\n marker,\n delimiter,\n baseIndent,\n listItemRegex\n )\n ) {\n const lastItem = getLastItem()\n if (lastItem.length > 0) {\n const lastBlock = lastItem[lastItem.length - 1]\n if (\n lastBlock.type === RuleType.paragraph ||\n lastBlock.type === RuleType.text\n ) {\n // This is a lazy continuation line - continue the paragraph\n appendListContinuation(\n nextLineWithoutIndent,\n lastItem,\n state,\n options\n )\n prevLineWasBlank = false\n currentPos = skipToNextLine(source, nextLineEnd)\n continue\n }\n }\n }\n // Not a lazy continuation - end of list\n break\n } else {\n const nextLineWithoutIndent = nextLine.slice(nextIndentChars)\n\n // Check for setext heading BEFORE thematic break\n // If last item ends with text/paragraph and this line is setext underline, convert to heading\n // Per CommonMark: setext underline must be indented enough to be continuation\n // BUT: don't check if this line is a list item marker (would be continuation of wrong item)\n if (items.length > 0) {\n const lastItemContentStartColumn =\n itemContentStartColumns[items.length - 1] || contentStartColumn\n if (\n nextIndent + 1 >= lastItemContentStartColumn &&\n !isMatchingListItem(\n nextLineWithoutIndent,\n nextIndentInfo,\n ordered,\n marker,\n delimiter,\n baseIndent,\n listItemRegex\n )\n ) {\n const lastItem = getLastItem()\n if (\n lastItem.length > 0 &&\n convertSetextHeadingInListItem(\n lastItem,\n nextLineWithoutIndent,\n options\n )\n ) {\n currentPos = skipToNextLine(source, nextLineEnd)\n continue\n }\n }\n }\n\n // Check if this line is a thematic break (per CommonMark, thematic breaks end lists)\n const thematicBreakResult = parseBreakThematic(\n source,\n currentPos,\n state,\n options\n )\n if (thematicBreakResult) {\n // Thematic break ends the list\n break\n }\n\n // Per CommonMark spec: link reference definitions interrupt list continuation\n // Check if this is a link reference definition after a blank line\n if (prevLineWasBlank) {\n const refEndPos = skipLinkReferenceDefinition(\n source,\n currentPos,\n nextLineEnd,\n nextIndentInfo,\n nextLineWithoutIndent,\n state,\n options\n )\n if (refEndPos) {\n // Skip link reference definition and continue parsing list (don't break)\n currentPos = refEndPos\n prevLineWasBlank = false\n continue\n }\n }\n\n // If line is at base indentation and not a list item, check for lazy continuation first\n if (nextIndent <= baseIndent) {\n if (\n nextLineWithoutIndent.startsWith('<') &&\n checkHTMLTagInterruptsList(\n source,\n currentPos,\n nextIndentChars,\n baseIndent,\n nextIndent,\n options\n )\n ) {\n break\n }\n\n if (\n !isMatchingListItem(\n nextLineWithoutIndent,\n nextIndentInfo,\n ordered,\n marker,\n delimiter,\n baseIndent,\n listItemRegex\n )\n ) {\n // Check for lazy continuation when nextIndent === baseIndent\n // Per CommonMark: lazy continuation lines can have all indentation deleted\n // BUT: only if there was no blank line before (lazy continuation requires no blank line)\n // AND: only if it's truly paragraph continuation text (not a block start)\n if (nextIndent === baseIndent && !prevLineWasBlank) {\n const trimmed = nextLineWithoutIndent.trim()\n if (trimmed.length > 0 && !isBlockStartChar(trimmed[0])) {\n // Check if this line would start a block (like HTML comment, thematic break, etc.)\n // If so, it should break the list, not continue it\n const blockResult = parseBlock(source, currentPos, state, options)\n if (blockResult && blockResult.type !== RuleType.paragraph) {\n break\n }\n const lastItem = getLastItem()\n if (lastItem.length > 0 && !listItemHasBlockContent(lastItem)) {\n // This is a lazy continuation line - continue the inline content\n // Lazy continuation lines don't add a newline (no space in output)\n appendListContinuation(\n nextLineWithoutIndent,\n lastItem,\n state,\n options,\n false\n )\n prevLineWasBlank = false\n currentPos = skipToNextLine(source, nextLineEnd)\n continue\n }\n }\n }\n break\n }\n }\n\n // Check for empty items with blank lines\n if (\n shouldBreakForEmptyItem(\n items,\n isEmptyItem,\n prevLineWasBlank,\n firstItemContent\n )\n )\n break\n\n const nextMatchResult = matchListItem(nextLineWithoutIndent)\n const nextMatch = nextMatchResult ? nextMatchResult.match : null\n const isSameType =\n nextMatch &&\n (ordered ? nextMatch[2] === delimiter : nextMatch[1] === marker)\n // Per CommonMark: list markers may be indented by up to 3 spaces\n // If marker is too indented (> 3 spaces), it's not a valid list item\n // If there's a blank line before such a marker, end the list (e.g., Example 313)\n if (isSameType && nextIndent > 3 && prevLineWasBlank) {\n break\n }\n // Skip list item processing and fall through to continuation check\n if (isSameType && nextIndent <= baseIndent + 3) {\n if (nextIndent >= 4 && prevLineWasBlank) break\n if (nextIndent === baseIndent) {\n // Item at same level - parse as new item\n let itemContent = ordered ? nextMatch[3] : nextMatch[2]\n itemContent = itemContent.trimStart()\n\n const result = addListItem(\n source,\n items,\n itemContentStartColumns,\n itemContent,\n currentPos,\n nextLineEnd,\n nextIndent,\n nextIndentChars,\n nextMatch,\n ordered,\n hasBlankLines,\n state,\n options\n )\n currentPos = result.newCurrentPos\n prevLineWasBlank = false\n\n // For empty items, process continuation immediately\n if (itemContent.trim() === '') {\n const newItem = items[items.length - 1]\n const thisItemContentStartColumn = getLastItemContentColumn()\n currentPos = processContinuation(\n source,\n newItem,\n thisItemContentStartColumn,\n currentPos,\n baseIndent,\n ordered,\n marker,\n delimiter,\n listItemRegex,\n state,\n options\n )\n }\n\n continue\n }\n if (nextIndent > baseIndent) {\n // Per CommonMark spec: items are only nested if indented enough to belong to previous item\n // If there was a blank line before this item, it's at the same level (not nested)\n if (prevLineWasBlank) {\n // Blank line before item means it's a new item at same level, not nested\n let itemContent = ordered ? nextMatch[3] : nextMatch[2]\n // Trim leading whitespace from content (regex now captures optional whitespace)\n itemContent = itemContent.trimStart()\n const result = addListItem(\n source,\n items,\n itemContentStartColumns,\n itemContent,\n currentPos,\n nextLineEnd,\n nextIndent,\n nextIndentChars,\n nextMatch,\n ordered,\n hasBlankLines,\n state,\n options\n )\n currentPos = result.newCurrentPos\n prevLineWasBlank = false\n continue\n }\n // Check if this item's marker position is indented enough to be continuation of previous item\n // We need to calculate the previous item's contentStartColumn, not use the first item's\n const lastItem = getLastItem()\n const markerColumn = nextIndent + 1\n const isNested = isMarkerNested(\n markerColumn,\n getLastItemContentColumn(),\n listItemHasBlockContent(lastItem)\n )\n\n if (isNested) {\n const nestedResult = tryParseNestedList(currentPos, lastItem)\n if (nestedResult) {\n currentPos = nestedResult.endPos\n prevLineWasBlank = false\n continue\n }\n }\n // Item is not indented enough to be nested - check if it's same type for same level\n if (!isNested && isSameType) {\n // This item has more indentation than baseIndent but not enough to be nested\n // It's still at the same level - parse it as a new item\n let itemContent = ordered ? nextMatch[3] : nextMatch[2]\n // Trim leading whitespace from content\n itemContent = itemContent.trimStart()\n if (!hasBlankLines) {\n // Check if this item has blank lines within it\n let checkItemPos = skipToNextLine(source, nextLineEnd)\n while (checkItemPos < source.length) {\n const checkLineEnd = util.findLineEnd(source, checkItemPos)\n const checkLine = source.slice(checkItemPos, checkLineEnd)\n const checkIndentInfo = calculateIndent(\n source,\n checkItemPos,\n checkLineEnd\n )\n const checkIndent = checkIndentInfo.spaceEquivalent\n\n if (checkLine.trim() === '') {\n const afterBlank = skipToNextLine(source, checkLineEnd)\n if (afterBlank < source.length) {\n const afterBlankIndentInfo = calculateIndent(\n source,\n afterBlank,\n source.length\n )\n const afterBlankIndent =\n afterBlankIndentInfo.spaceEquivalent\n // Calculate contentStartColumn for this item\n const thisItemMarkerStart = nextIndent\n const thisItemContentStart =\n thisItemMarkerStart +\n (ordered\n ? nextMatch[1].length + nextMatch[2].length + 1\n : nextMatch[1].length + 1)\n if (afterBlankIndent + 1 > thisItemContentStart) {\n break\n }\n }\n break\n } else if (checkIndent <= baseIndent) {\n // Check if this is the next list item at baseIndent or less\n const checkLineWithoutIndent = checkLine.slice(\n checkIndentInfo.charCount\n )\n const checkMatch = checkLineWithoutIndent.match(listItemRegex)\n const isNextItem =\n checkMatch &&\n (ordered\n ? checkMatch[2] === delimiter\n : checkMatch[1] === marker)\n if (isNextItem && checkIndent <= baseIndent) {\n break\n }\n }\n checkItemPos = skipToNextLine(source, checkLineEnd)\n }\n }\n const result = addListItem(\n source,\n items,\n itemContentStartColumns,\n itemContent,\n currentPos,\n nextLineEnd,\n nextIndent,\n nextIndentChars,\n nextMatch,\n ordered,\n hasBlankLines,\n state,\n options\n )\n currentPos = result.newCurrentPos\n prevLineWasBlank = false\n continue\n } else if (!isNested && !isSameType) {\n // Different marker type at same level - end this list\n break\n }\n // Fall through to continuation check if isNested but parseList failed\n // Check if this is continuation content\n // Per CommonMark: continuation needs to be indented to at least the content start column\n // nextIndent is space count (0-indexed), contentStartColumn is column number (1-indexed)\n // When list item has block content, exact indentation (==) continues; otherwise use >\n // For continuation checks, use minimumContentStartColumn (column after marker+space)\n // instead of contentStartColumn (which can be higher for code blocks)\n {\n const lastItem = getLastItem()\n // Check if last item is empty (no content)\n const lastItemIsEmpty = lastItem.length === 0\n // Check for empty items with blank lines\n if (\n lastItemIsEmpty &&\n shouldBreakForEmptyItem(\n items,\n isEmptyItem,\n prevLineWasBlank,\n firstItemContent\n )\n )\n break\n\n const hasBlockContent = lastItem.some(\n node =>\n node.type === RuleType.codeBlock ||\n node.type === RuleType.paragraph ||\n node.type === RuleType.blockQuote ||\n node.type === RuleType.orderedList ||\n node.type === RuleType.unorderedList ||\n node.type === RuleType.heading\n )\n // For empty items, use minimumContentStartColumn (marker + space) instead of contentStartColumn\n // which can be higher when there's extra whitespace but no content\n const continuationColumn =\n lastItemIsEmpty && items.length === 1\n ? minimumContentStartColumn\n : contentStartColumn\n const continuationCheck = hasBlockContent\n ? nextIndent >= continuationColumn\n : nextIndent > continuationColumn\n if (continuationCheck) {\n const result = processListContinuationLine(\n source,\n currentPos,\n nextLineEnd,\n nextIndentInfo,\n continuationColumn,\n contentStartColumn,\n getLastItem(),\n prevLineWasBlank,\n state,\n options,\n undefined,\n baseIndent\n )\n if (result.processed) {\n prevLineWasBlank = result.wasBlank\n currentPos = result.newPos\n continue\n }\n } else {\n break\n }\n }\n } else if (nextIndent === baseIndent) {\n // Check for Unicode whitespace after marker in unordered lists\n if (\n !ordered &&\n nextMatch &&\n checkUnicodeWhitespaceAfterMarker(nextMatch, nextMatch[1])\n ) {\n break\n }\n let itemContent = ordered ? nextMatch[3] : nextMatch[2]\n // Trim leading whitespace from content (regex now captures optional whitespace)\n itemContent = itemContent.trimStart()\n // Per CommonMark: A list is loose if items are separated by blank lines,\n // OR if an item directly contains two block-level elements with a blank line between them.\n // If list is loose (hasBlankLines = true), ALL items are wrapped.\n // Otherwise, an item is wrapped only if it has blank lines within it.\n // A blank line before this item means the PREVIOUS item was separated from this one,\n // making the list loose. For this item, we check if it has continuation after blank lines.\n // But if the list is already loose (hasBlankLines), wrap this item too.\n const result = addListItem(\n source,\n items,\n itemContentStartColumns,\n itemContent,\n currentPos,\n nextLineEnd,\n baseIndent,\n nextIndentChars,\n nextMatch,\n ordered,\n hasBlankLines,\n state,\n options\n )\n currentPos = result.newCurrentPos\n prevLineWasBlank = false\n }\n } else if (nextIndent > baseIndent) {\n // Check if this is a list item - if so, check if it should be nested or separate\n // Per CommonMark: list item markers can only be indented 0-3 spaces relative to baseIndent\n // However, nested lists can have more indentation if they're indented relative to content start\n // So we need to try parsing as nested list first, then check for paragraph continuation\n const lastItem = getLastItem()\n const isListItemResult = isLineListItem(nextLineWithoutIndent)\n if (isListItemResult) {\n // Check if marker would be properly nested (relative to content start column)\n // This handles nested lists that may have > 3 spaces indent from baseIndent\n const markerColumn = nextIndent + 1\n const isNested = isMarkerNested(\n markerColumn,\n getLastItemContentColumn(),\n listItemHasBlockContent(lastItem)\n )\n\n if (isNested) {\n // Properly nested - try parsing as nested list\n const nestedResult = tryParseNestedList(currentPos, lastItem)\n if (nestedResult) {\n currentPos = nestedResult.endPos\n prevLineWasBlank = false\n continue\n }\n }\n\n // Not properly nested - check if marker indent is valid (0-3 spaces relative to baseIndent)\n // Per CommonMark: list item markers can only be indented 0-3 spaces relative to baseIndent\n const markerIndentRelative = nextIndent - baseIndent\n if (markerIndentRelative > 3) {\n // Too much indentation (> 3 spaces from baseIndent) and not nested - not a valid list item marker\n // Check if it should be treated as paragraph continuation (if last item ends with paragraph)\n const lastBlock =\n lastItem.length > 0 ? lastItem[lastItem.length - 1] : null\n if (\n lastBlock &&\n (lastBlock.type === RuleType.paragraph ||\n lastBlock.type === RuleType.text)\n ) {\n // This is paragraph continuation text, not a code block or nested list\n appendListContinuation(\n nextLineWithoutIndent,\n lastItem,\n state,\n options\n )\n prevLineWasBlank = false\n currentPos = skipToNextLine(source, nextLineEnd)\n continue\n }\n // Not paragraph continuation - fall through to code block check\n } else {\n // Valid marker indent (0-3 spaces) but not nested - this should be a separate list\n break\n }\n } else {\n // Not a list item - try parsing as nested list (for other block types)\n const nestedResult = tryParseNestedList(currentPos, lastItem)\n if (nestedResult) {\n currentPos = nestedResult.endPos\n prevLineWasBlank = false\n continue\n }\n }\n // Check if this is continuation content\n // Per CommonMark: continuation needs to be indented to at least the content start column\n // nextIndent is space count (0-indexed), contentStartColumn is column number (1-indexed)\n // When list item has block content, exact indentation (==) continues; otherwise use >\n // For continuation checks, use minimumContentStartColumn (column after marker+space)\n // instead of contentStartColumn (which can be higher for code blocks)\n const continuationColumn = contentStartColumn\n const continuationCheck = listItemHasBlockContent(lastItem)\n ? nextIndent >= continuationColumn - 1\n : nextIndent > continuationColumn - 1\n if (continuationCheck) {\n const result = processListContinuationLine(\n source,\n currentPos,\n nextLineEnd,\n nextIndentInfo,\n continuationColumn - 1,\n contentStartColumn,\n getLastItem(),\n prevLineWasBlank,\n state,\n options,\n undefined,\n baseIndent\n )\n if (result.processed) {\n prevLineWasBlank = result.wasBlank\n currentPos = result.newPos\n continue\n }\n } else {\n break\n }\n } else {\n break\n }\n }\n }\n\n // For loose lists, ensure all items have paragraph wrappers\n // The first item may have been created before we detected that the list is loose\n if (\n hasBlankLines &&\n items.length > 1 &&\n items[0].length > 0 &&\n items[0][0].type !== RuleType.paragraph\n ) {\n // Check if list is truly loose (another item has paragraph wrapper)\n for (var j = 1; j < items.length; j++) {\n if (items[j].length > 0 && items[j][0].type === RuleType.paragraph) {\n // First item is all inline content - wrap it for loose lists\n var isBlock = false\n for (var i = 0; i < items[0].length; i++) {\n var t = items[0][i].type\n if (\n t === RuleType.codeBlock ||\n t === RuleType.heading ||\n t === RuleType.blockQuote ||\n t === RuleType.orderedList ||\n t === RuleType.unorderedList ||\n t === RuleType.htmlBlock ||\n t === RuleType.breakThematic\n ) {\n isBlock = true\n break\n }\n }\n if (!isBlock) {\n items[0] = [\n {\n type: RuleType.paragraph,\n children: items[0],\n } as MarkdownToJSX.ParagraphNode,\n ]\n }\n break\n }\n }\n }\n\n const listNode = ordered\n ? ({\n type: RuleType.orderedList,\n items,\n ordered: true,\n start,\n } as MarkdownToJSX.OrderedListNode)\n : ({\n type: RuleType.unorderedList,\n items,\n ordered: false,\n } as MarkdownToJSX.UnorderedListNode)\n\n // Restore original inList state\n state.inList = originalInList\n\n return {\n ...listNode,\n endPos: currentPos,\n } as (MarkdownToJSX.OrderedListNode | MarkdownToJSX.UnorderedListNode) & {\n endPos: number\n }\n}\n\nfunction parseTable(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult {\n if (state.inline) return null\n\n const lines: string[] = []\n let currentPos = pos\n\n while (currentPos < source.length) {\n const lineEnd = util.findLineEnd(source, currentPos)\n if (isBlankLineCheck(source, currentPos, lineEnd)) break\n\n const line = source.slice(currentPos, lineEnd).trim()\n const isTableLine =\n line.indexOf('|') !== -1 ||\n (lines.length >= 3 && line && !isBlockStartChar(line[0]))\n\n if (!isTableLine) break\n lines.push(line)\n currentPos = skipToNextLine(source, lineEnd)\n }\n\n if (lines.length < 2) return null\n\n // Unwrap pipes and split cells\n const unwrap = (line: string) =>\n line[0] === '|' && line[line.length - 1] === '|' ? line.slice(1, -1) : line\n\n const splitCells = (line: string) => {\n const cells: string[] = []\n let current = ''\n let inCode = false\n\n for (let i = 0; i < line.length; i++) {\n const ch = line[i]\n if (ch === '\\\\' && i + 1 < line.length && line[i + 1] === '|') {\n current += '|'\n i++\n } else if (ch === '`') {\n inCode = !inCode\n current += ch\n } else if (ch === '|' && !inCode) {\n cells.push(current.trim())\n current = ''\n } else {\n current += ch\n }\n }\n cells.push(current.trim())\n return cells\n }\n\n const headerCells = splitCells(unwrap(lines[0]))\n if (!headerCells.length) return null\n\n const separatorCells = splitCells(unwrap(lines[1]))\n if (\n separatorCells.length !== headerCells.length ||\n separatorCells.some(cell => !/^:?-+:?$/.test(cell))\n ) {\n return null\n }\n\n const alignments = separatorCells.map(cell => {\n const start = cell[0] === ':'\n const end = cell[cell.length - 1] === ':'\n return start && end ? 'center' : start ? 'left' : end ? 'right' : null\n })\n\n const parseRow = (cells: string[]) =>\n parseWithInlineMode(state, true, () =>\n cells.map(cell => parseInlineSpan(cell, 0, cell.length, state, options))\n )\n\n const header = parseRow(headerCells)\n\n const body = lines.slice(2).map(line => {\n const cells =\n line.indexOf('|') !== -1 ? splitCells(unwrap(line)) : [line.trim()]\n\n // Normalize cell count\n const count = headerCells.length\n while (cells.length < count) cells.push('')\n cells.length = count\n\n return parseRow(cells)\n })\n\n return {\n type: RuleType.table,\n header,\n cells: body,\n align: alignments,\n endPos: currentPos,\n } as MarkdownToJSX.TableNode & { endPos: number }\n}\n\n// Type 6 block-level tags - only the most common ones that matter in practice\n// Unknown tags default to type 7 (inline/non-interrupting) for safety\n// This is a pragmatic subset of the CommonMark spec's full list\nvar TYPE6_TAGS = [\n 'div',\n 'p',\n 'section',\n 'article',\n 'aside',\n 'nav',\n 'header',\n 'footer',\n 'main',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'blockquote',\n 'ul',\n 'ol',\n 'li',\n 'dl',\n 'dt',\n 'dd',\n 'table',\n 'thead',\n 'tbody',\n 'tfoot',\n 'tr',\n 'td',\n 'th',\n 'form',\n 'fieldset',\n 'hr',\n 'pre',\n 'details',\n 'summary',\n 'figure',\n 'figcaption',\n]\n\n// Type 1 block tags for fast lookup\nconst TYPE1_TAGS_SET = new Set(['pre', 'script', 'style', 'textarea'])\n\nfunction isType6Tag(tagName: string): boolean {\n return TYPE6_TAGS.indexOf(tagName.toLowerCase()) !== -1\n}\n\nexport function isType1Block(tagLower: string): boolean {\n return TYPE1_TAGS_SET.has(tagLower)\n}\n\nfunction isBlankLineCheck(\n source: string,\n lineStart: number,\n lineEnd: number\n): boolean {\n for (var i = lineStart; i < lineEnd; i++) {\n const code = charCode(source, i)\n if (code !== $.CHAR_SPACE && code !== $.CHAR_TAB && code !== $.CHAR_CR)\n return false\n }\n return true\n}\n\nfunction parseWithInlineMode<T>(\n state: MarkdownToJSX.State,\n inlineMode: boolean,\n parseFn: () => T\n): T {\n const originalInline = state.inline\n state.inline = inlineMode\n try {\n return parseFn()\n } finally {\n state.inline = originalInline\n }\n}\n\nfunction findNextBlankLine(\n source: string,\n startPos: number,\n sourceLen: number\n): number {\n var pos = startPos\n while (pos < sourceLen) {\n var nextLineEnd = util.findLineEnd(source, pos)\n if (isBlankLineCheck(source, pos, nextLineEnd)) return pos\n pos = nextLineEnd + (nextLineEnd < sourceLen ? 1 : 0)\n }\n return sourceLen\n}\n\nfunction createHTMLCommentResult(\n text: string,\n endPos: number,\n options?: { raw?: boolean; endsWithGreaterThan?: boolean }\n): MarkdownToJSX.HTMLCommentNode & {\n endPos: number\n raw?: boolean\n endsWithGreaterThan?: boolean\n} {\n return {\n type: RuleType.htmlComment,\n text,\n endPos,\n ...options,\n } as MarkdownToJSX.HTMLCommentNode & {\n endPos: number\n raw?: boolean\n endsWithGreaterThan?: boolean\n }\n}\n\nfunction createVerbatimHTMLBlock(\n tagName: string,\n text: string,\n endPos: number,\n attrs?: { [key: string]: any },\n rawAttrs?: string,\n isClosingTag?: boolean,\n canInterruptParagraph?: boolean,\n options?: ParseOptions\n): MarkdownToJSX.HTMLNode & {\n endPos: number\n isClosingTag?: boolean\n canInterruptParagraph?: boolean\n} {\n // Detect empty unclosed HTML tags when forceBlock is used to avoid infinite recursion\n // For empty unclosed tags like <var>, the text field contains the opening tag itself\n // When forceBlock is used, this would cause recursion if the tag is parsed again\n var finalText = text\n if (options && options.forceBlock && text && !isClosingTag) {\n var openingTagPattern = new RegExp(\n '^<' + tagName.toLowerCase() + '(\\\\s[^>]*)?>$',\n 'i'\n )\n if (openingTagPattern.test(text.trim())) {\n // Empty unclosed tag detected - render as empty element to avoid recursion\n finalText = ''\n }\n }\n return {\n type: RuleType.htmlBlock,\n tag: tagName as MarkdownToJSX.HTMLTags,\n attrs: attrs || {},\n rawAttrs: rawAttrs,\n children: [],\n text: finalText,\n noInnerParse: true,\n isClosingTag: isClosingTag,\n canInterruptParagraph: canInterruptParagraph,\n endPos: endPos,\n } as MarkdownToJSX.HTMLNode & {\n endPos: number\n isClosingTag?: boolean\n canInterruptParagraph?: boolean\n }\n}\n\n/**\n * Check if content contains block-worthy elements that should be parsed\n * (explicit block syntax or blank lines not inside type 1 HTML blocks)\n */\nfunction hasBlockContent(content: string): boolean {\n const hasExplicitBlockSyntax = BLOCK_SYNTAX_R.test(content)\n const hasBlankLines = DOUBLE_NEWLINE_R.test(content)\n const hasType1Tags = TYPE1_TAG_R.test(content)\n return hasExplicitBlockSyntax || (hasBlankLines && !hasType1Tags)\n}\n\nfunction processHTMLBlock(\n tagNameOriginal: string,\n tagName: string,\n attrs: string,\n content: string,\n fullMatch: string,\n endPos: number,\n source: string,\n state: MarkdownToJSX.State,\n parentInAnchor: boolean,\n options: ParseOptions\n): MarkdownToJSX.HTMLNode & { endPos: number } {\n // Apply block-level paragraph wrapping heuristics\n if (!state.inHTML && !state.inline && !util.endsWith(fullMatch, '\\n')) {\n let checkPos = endPos\n const sourceLen = source.length\n\n while (checkPos < sourceLen) {\n const lineEnd = util.findLineEnd(source, checkPos)\n if (isBlankLineCheck(source, checkPos, lineEnd)) break\n\n const line = source.slice(checkPos, lineEnd).trim()\n if (line.length > 0 && isBlockStartChar(line[0])) {\n const htmlResult = parseHTML(source, checkPos, state, options)\n if (htmlResult) {\n checkPos = htmlResult.endPos\n continue\n }\n const selfClosingMatch = parseHTMLTag(source, checkPos)\n if (selfClosingMatch) {\n checkPos = selfClosingMatch.endPos\n continue\n }\n return null\n }\n checkPos = skipToNextLine(source, lineEnd)\n }\n }\n\n const lowerTag = tagName\n const noInnerParse = isType1Block(lowerTag)\n\n // Per CommonMark spec: Type 6 blocks that end at blank lines should have verbatim content\n // Check if this is a type 6 block (block-level, not type 1, not void)\n var isType6Block = !noInnerParse && !util.isVoidElement(tagName)\n\n // Always extract raw attributes from fullMatch if available (for consistency)\n // Per CommonMark spec Example 153: newlines and spaces between attributes should be removed\n // (not converted to spaces) when rendering. Extract raw attributes so html() can handle this.\n var rawOpeningTag: string | undefined = undefined\n // Extract raw attributes from opening tag slice if fullMatch is available\n if (fullMatch) {\n // Find the closing > of the opening tag\n var openingTagEnd = fullMatch.indexOf('>')\n if (openingTagEnd !== -1) {\n var openingTagSlice = fullMatch.slice(0, openingTagEnd + 1)\n // Check if opening tag has newlines (for rawOpeningTag preservation)\n if (openingTagSlice.indexOf('\\n') !== -1) {\n rawOpeningTag = openingTagSlice\n }\n // Always extract raw attributes from the opening tag slice for consistency\n // Find the tag name end (after <div or <div/) - first whitespace or >\n var tagNameEnd = openingTagEnd\n for (var i = 1; i < openingTagEnd; i++) {\n var ch = openingTagSlice[i]\n if (ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '>') {\n tagNameEnd = i\n break\n }\n }\n // Extract attributes from after tag name to before >\n // Preserve leading whitespace for CommonMark compliance (Examples 615-616)\n attrs = openingTagSlice.slice(tagNameEnd, openingTagEnd)\n }\n }\n\n // Parse attributes, but always preserve raw attributes for consistency\n // Per CommonMark spec Example 153: newlines and spaces between attributes should be removed\n // (not converted to spaces) when rendering. Store raw attributes so html() can handle this.\n // Trim leading whitespace for parsing, but preserve full attrs (with whitespace) for rawAttrs\n var attrsTrimmed = attrs.replace(/^[\\s\\n\\r\\t]+/, '')\n var parsedAttributes = parseHTMLAttributes(\n attrsTrimmed,\n tagName,\n tagNameOriginal,\n options\n )\n var attributes: Record<string, any> = {\n ...parsedAttributes,\n }\n\n // For type 6 blocks, check if content ends with blank line or if there's no closing tag\n // Both cases mean content should be verbatim\n var endedAtBlankLine = false\n var hasClosingTagWithBlockSyntax = false\n if (isType6Block && content.length > 0) {\n // Check if there's a closing tag in the content - if so, extract content before it\n var closingTagPattern = '</' + lowerTag\n var closingTagIdx = content.indexOf(closingTagPattern)\n if (closingTagIdx >= 0) {\n var afterTag = closingTagIdx + closingTagPattern.length\n while (\n afterTag < content.length &&\n (content[afterTag] === ' ' || content[afterTag] === '\\t')\n )\n afterTag++\n if (afterTag < content.length && content[afterTag] === '>') {\n var contentBeforeClosingTag = content.slice(0, closingTagIdx)\n if (hasBlockContent(contentBeforeClosingTag)) {\n content = contentBeforeClosingTag\n hasClosingTagWithBlockSyntax = true\n } else {\n endedAtBlankLine = true\n }\n }\n }\n\n // If we didn't find a proper closing tag with block syntax, check if content ends with blank lines\n if (!hasClosingTagWithBlockSyntax) {\n // Check if content ends with blank line pattern (newline, optional whitespace, newline)\n var checkPos = content.length - 1\n // Skip trailing newline\n if (content[checkPos] === '\\n') {\n checkPos--\n // Skip whitespace\n while (\n checkPos >= 0 &&\n (content[checkPos] === ' ' ||\n content[checkPos] === '\\t' ||\n content[checkPos] === '\\r')\n ) {\n checkPos--\n }\n // If there's another newline before this, we have a blank line ending\n if (checkPos >= 0 && content[checkPos] === '\\n') {\n endedAtBlankLine = true\n }\n }\n }\n }\n\n // If type 6 block ended at blank line (or has no closing tag), treat content as verbatim (no parsing)\n // But if content has block-worthy content, parse it even if it ends with blank lines\n var shouldTreatAsVerbatim =\n noInnerParse ||\n (isType6Block && endedAtBlankLine && !hasBlockContent(content))\n\n if (shouldTreatAsVerbatim) {\n if (content.length > 0 && content[0] === '\\n') {\n content = content.slice(1)\n }\n if (content.length > 0 && content[content.length - 1] === '\\n') {\n content = content.slice(0, -1)\n }\n }\n\n const leftTrimMatch = content.match(/^([ \\t]*)/)\n const leftTrimAmount = leftTrimMatch ? leftTrimMatch[1] : ''\n const trimmer = new RegExp(\n `^${leftTrimAmount.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}`,\n 'gm'\n )\n const trimmed = content.replace(trimmer, '')\n\n const hasDoubleNewline = DOUBLE_NEWLINE_R.test(trimmed)\n const hasNonParagraphBlockSyntax = BLOCK_SYNTAX_R.test(trimmed)\n const isParagraphTag = lowerTag === 'p'\n // Check if content contains HTML tags - if so, parse as blocks for proper nesting\n const hasHTMLTags = HTML_BLOCK_ELEMENT_START_R.test(trimmed)\n const hasBlockSyntax = isParagraphTag\n ? hasDoubleNewline\n : hasDoubleNewline ||\n hasNonParagraphBlockSyntax ||\n (state.inHTML && hasHTMLTags)\n\n let children: MarkdownToJSX.ASTNode[] = []\n\n if (!shouldTreatAsVerbatim && trimmed) {\n // Parse as blocks when content contains HTML tags to ensure nested HTML is parsed correctly\n if (hasBlockSyntax || hasHTMLTags) {\n const blockState = {\n ...state,\n inline: false,\n inHTML: true,\n inAnchor: state.inAnchor || lowerTag === 'a',\n }\n children = parseBlocksInHTML(trimmed, blockState, options)\n } else {\n const childState = {\n ...state,\n inline: true,\n inAnchor: parentInAnchor || state.inAnchor || lowerTag === 'a',\n }\n children = parseInlineSpan(\n trimmed,\n 0,\n trimmed.length,\n childState,\n options\n )\n }\n }\n\n // For Type 1 blocks with raw opening tag HTML, store it in the text field\n // along with content, so html() can output it verbatim\n var finalText: string | undefined = undefined\n if (shouldTreatAsVerbatim) {\n if (rawOpeningTag !== undefined) {\n // Type 1 block with newlines in opening tag - preserve raw opening tag + content\n // Store the full raw HTML (opening tag + content) in text field\n // The closing tag will be added by html()\n finalText = rawOpeningTag + content\n } else {\n finalText = content\n }\n }\n\n return {\n type: RuleType.htmlBlock,\n tag: (shouldTreatAsVerbatim\n ? tagName\n : tagNameOriginal) as MarkdownToJSX.HTMLTags,\n attrs: attributes,\n rawAttrs: attrs,\n children,\n text: finalText,\n noInnerParse: shouldTreatAsVerbatim,\n canInterruptParagraph: true, // type 1-6 blocks can interrupt paragraphs\n endPos: endPos,\n } as MarkdownToJSX.HTMLNode & {\n endPos: number\n canInterruptParagraph?: boolean\n }\n}\n\nfunction parseHTML(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): ParseResult {\n // Must start with '<'\n if (source[pos] !== '<') return null\n\n // Track attempt after cheap disqualifications but before expensive parsing work\n if (!state.inline) {}\n\n // Check for processing instructions, declarations, and comments first (before unified parser)\n if (pos + 1 < source.length) {\n if (source[pos + 1] === '?') {\n var piToken = scanRawHTML(source, pos)\n if (piToken && piToken.kind === 'pi') {\n return createHTMLCommentResult(piToken.text || '', piToken.endPos, {\n raw: true,\n })\n }\n } else if (source[pos + 1] === '!') {\n // Check for HTML comments (<!-- ... -->)\n if (pos + 3 < source.length && source.slice(pos, pos + 4) === '<!--') {\n if (state.inline) {} else {}\n var token = scanRawHTML(source, pos)\n if (token && token.kind === 'comment') {\n // Extract text content (strip <!-- and -->)\n var text = token.text || ''\n var endsWithGreaterThan = false\n if (text === '<!-->') {\n text = ''\n endsWithGreaterThan = true\n } else if (text === '<!--->') {\n text = '-'\n endsWithGreaterThan = true\n } else if (text.startsWith('<!--') && text.endsWith('-->')) {\n text = text.slice(4, -3)\n }\n // Track hit for inline mode (block mode hit tracking happens in parseMarkdown)\n if (state.inline) {}\n return createHTMLCommentResult(text, token.endPos, {\n endsWithGreaterThan,\n })\n }\n }\n var declToken = scanRawHTML(source, pos)\n if (\n declToken &&\n (declToken.kind === 'declaration' || declToken.kind === 'cdata')\n ) {\n return createHTMLCommentResult(declToken.text || '', declToken.endPos, {\n raw: true,\n })\n }\n }\n }\n\n // Check for space/newline after < (invalid HTML - should be escaped)\n if (pos + 1 < source.length) {\n const nextChar = source[pos + 1]\n if (\n nextChar === ' ' ||\n nextChar === '\\n' ||\n nextChar === '\\t' ||\n nextChar === '\\r'\n ) {\n return null\n }\n }\n\n // Check if this looks like an autolink before parsing as HTML\n var closeIdx = source.indexOf('>', pos + 1)\n if (closeIdx !== -1) {\n var contentBetween = source.slice(pos + 1, closeIdx)\n // Check for spaces - if found, might be failed autolink\n var hasSpace =\n contentBetween.indexOf(' ') !== -1 || contentBetween.indexOf('\\t') !== -1\n\n // Check for HTTP(S) URLs - these should be autolinks, not HTML tags\n if (\n !hasSpace &&\n (util.startsWith(contentBetween, 'http://') ||\n util.startsWith(contentBetween, 'https://'))\n ) {\n return null // This is an autolink, not an HTML tag\n }\n\n // Check for URI schemes (scheme:pattern) - no spaces\n if (!hasSpace && isValidUriScheme(contentBetween)) {\n return null // This is an autolink (URI scheme), not an HTML tag\n }\n }\n\n // Use unified parser\n var tagResult = parseHTMLTag(source, pos)\n\n // If parseHTMLTag returns null, it might be an incomplete tag\n // Handle incomplete/partial tags inline (previously handled by matchHTMLBlock)\n if (!tagResult && !state.inline) {\n // Check if we have < followed by a valid tag name (even without closing >)\n var sourceLen = source.length\n var firstLineEnd = util.findLineEnd(source, pos)\n var lineStart = pos\n // Skip up to 3 spaces of indentation (per spec)\n var indent = 0\n while (\n lineStart < firstLineEnd &&\n indent < 3 &&\n (source[lineStart] === ' ' || source[lineStart] === '\\t')\n ) {\n indent++\n lineStart++\n }\n if (lineStart >= firstLineEnd || source[lineStart] !== '<') return null\n\n // Try to parse tag name even if tag is incomplete\n // Only handle incomplete tags for block-level tags (type 6)\n // Non-block-level tags that parseHTMLTag can't parse are invalid, not incomplete\n if (lineStart + 1 < firstLineEnd) {\n var tagNameResult = parseHTMLTagName(source, lineStart + 1)\n if (tagNameResult) {\n var tagName = tagNameResult.tagName\n var isType6 = isType6Tag(tagName)\n // Only handle incomplete tags for block-level tags\n if (!isType6) {\n return null // Non-block-level tags that parseHTMLTag can't parse are invalid\n }\n // Find where the tag would end (end of line or before invalid char)\n var partialTagEnd = tagNameResult.nextPos\n var hasNewlineInTag = false\n var inQuotesPartial = false\n var quoteCharPartial = ''\n var checkEnd = firstLineEnd\n var foundClosingAngle = false\n // Check across multiple lines to find the end of the tag\n // Optimized: use indexOf to quickly find boundary characters\n while (checkEnd < sourceLen && !foundClosingAngle) {\n var advancedInInnerLoop = false\n while (partialTagEnd < checkEnd) {\n var c = source[partialTagEnd]\n if (inQuotesPartial) {\n if (c === quoteCharPartial) {\n inQuotesPartial = false\n quoteCharPartial = ''\n }\n if (c === '\\n' || c === '\\r') {\n hasNewlineInTag = true\n }\n partialTagEnd++\n advancedInInnerLoop = true\n } else if (c === '\"' || c === \"'\") {\n inQuotesPartial = true\n quoteCharPartial = c\n partialTagEnd++\n advancedInInnerLoop = true\n } else if (c === '\\n' || c === '\\r') {\n hasNewlineInTag = true\n partialTagEnd++\n advancedInInnerLoop = true\n var nextLineEnd = util.findLineEnd(source, partialTagEnd)\n if (nextLineEnd === partialTagEnd) break\n checkEnd = nextLineEnd\n } else if (c === '>') {\n partialTagEnd++\n foundClosingAngle = true\n break\n } else {\n partialTagEnd++\n advancedInInnerLoop = true\n }\n }\n if (foundClosingAngle) break\n if (!advancedInInnerLoop && partialTagEnd >= checkEnd) {\n var nextCheckEnd = util.findLineEnd(source, checkEnd + 1)\n if (nextCheckEnd <= checkEnd) break\n checkEnd = nextCheckEnd\n } else if (partialTagEnd >= checkEnd && checkEnd < sourceLen) {\n var nextCheckEnd = util.findLineEnd(source, checkEnd + 1)\n if (nextCheckEnd <= checkEnd) break\n checkEnd = nextCheckEnd\n } else {\n break\n }\n }\n // Only handle as incomplete tag if it has a newline (extends beyond first line)\n // OR if it extends to end of first line without closing >\n // If tag completes on first line with closing >, parseHTMLTag should have handled it\n if (!hasNewlineInTag && foundClosingAngle) {\n return null // Tag completes on first line but parseHTMLTag returned null - invalid, not incomplete\n }\n // Tag has newline - treat as incomplete and extend to end of first line if needed\n if (partialTagEnd >= firstLineEnd && firstLineEnd < sourceLen) {\n partialTagEnd = firstLineEnd\n }\n // Determine block type and find blank line\n var blockType: 'type6' | 'type7' = isType6 ? 'type6' : 'type7'\n var tagEnd = partialTagEnd\n var blockEnd = findNextBlankLine(source, firstLineEnd + 1, sourceLen)\n var blockContent = source.slice(tagEnd, blockEnd)\n var isClosingTag = pos + 1 < source.length && source[pos + 1] === '/'\n\n // For type 7 blocks with incomplete tags, preserve raw HTML\n if (blockType === 'type7' && blockContent.trim() === '') {\n var rawTagHTML = source.slice(pos, blockEnd)\n var tagLineEnd = util.findLineEnd(rawTagHTML, 0)\n if (tagLineEnd < rawTagHTML.length) tagLineEnd++\n var rawTag = rawTagHTML.slice(0, tagLineEnd)\n return createVerbatimHTMLBlock(\n tagName,\n rawTag,\n blockEnd,\n {},\n undefined,\n isClosingTag,\n false, // type 7 blocks cannot interrupt paragraphs\n options\n )\n }\n\n // For type 6/7 blocks with incomplete tags and content, preserve full raw HTML\n var fullRawHTML = source.slice(pos, blockEnd)\n return createVerbatimHTMLBlock(\n tagName,\n fullRawHTML,\n blockEnd,\n {},\n undefined,\n isClosingTag,\n blockType === 'type6', // type 6 can interrupt, type 7 cannot\n options\n )\n }\n }\n return null\n }\n\n if (!tagResult) return null\n\n // Per CommonMark spec: reject HTML tags that look like failed autolinks\n // Check if the content between < and > looks like a failed autolink\n // (HTTP(S) URLs with spaces are failed autolinks - checked above)\n if (closeIdx !== -1) {\n var contentBetweenCheck = source.slice(pos + 1, closeIdx)\n // If it starts with http:// or https:// but has spaces, it's a failed autolink\n if (\n (util.startsWith(contentBetweenCheck, 'http://') ||\n util.startsWith(contentBetweenCheck, 'https://')) &&\n (contentBetweenCheck.indexOf(' ') !== -1 ||\n contentBetweenCheck.indexOf('\\t') !== -1)\n ) {\n return null // Failed autolink - reject as HTML tag\n }\n }\n\n // If a tag name has a colon at position 1 (e.g., \"m:abc\"), it's trying to be an autolink\n // but the scheme is only 1 character (invalid). These should be escaped, not parsed as HTML.\n // Examples: <m:abc>, <x:foo> should be escaped as <m:abc>, <x:foo>\n var tagNameStart = pos + (tagResult.isClosing ? 2 : 1)\n if (tagNameStart < source.length) {\n var tagNameFirstChar = source[tagNameStart]\n var tagNameFirstCharCode = charCode(tagNameFirstChar)\n // Check if it starts with a letter\n if (\n (tagNameFirstCharCode >= 97 && tagNameFirstCharCode <= 122) ||\n (tagNameFirstCharCode >= 65 && tagNameFirstCharCode <= 90)\n ) {\n // Check if second character is a colon (making it a 1-char scheme, which is invalid)\n if (\n tagNameStart + 1 < source.length &&\n source[tagNameStart + 1] === ':'\n ) {\n // This looks like a failed autolink attempt - reject as HTML tag\n return null\n }\n }\n }\n\n // Handle closing tags\n if (tagResult.isClosing) {\n // Per CommonMark: closing tags cannot have attributes\n // If attrs is not empty (after trimming whitespace), it's invalid HTML - escape it\n var attrsTrimmed = tagResult.attrs.trim()\n if (attrsTrimmed.length > 0) {\n // Invalid closing tag with attributes - return null to allow escaping\n return null\n }\n\n // Per CommonMark spec: closing tags are type 7 HTML blocks\n // Parse as block if: (1) on its own line, or (2) followed by a block-level HTML tag\n // Per Example 148: </td></tr></table> should be block-level\n // Per Example 623: </a></foo > should be inline (wrapped in paragraph)\n if (!state.inline) {\n var sourceLen = source.length\n var firstLineEnd = util.findLineEnd(source, pos)\n var tagEnd = tagResult.endPos\n\n // Check if tag is on its own line or followed by a block-level HTML tag\n var afterTag = tagEnd\n while (\n afterTag < firstLineEnd &&\n (source[afterTag] === ' ' ||\n source[afterTag] === '\\t' ||\n source[afterTag] === '\\r')\n ) {\n afterTag++\n }\n\n var shouldParseAsBlock =\n afterTag >= firstLineEnd ||\n (source[afterTag] === '<' &&\n (function () {\n var nextTag = parseHTMLTag(source, afterTag)\n return nextTag && isType6Tag(nextTag.tagLower)\n })())\n\n if (shouldParseAsBlock) {\n var blockEnd = findNextBlankLine(source, firstLineEnd + 1, sourceLen)\n var blockContent = source.slice(tagEnd, blockEnd)\n if (blockContent.length > 0 && blockContent[0] === '\\n') {\n blockContent = blockContent.slice(1)\n }\n\n // Cache lowercase tag name to avoid repeated toLowerCase() calls\n const tagLower = tagResult.tagLower || tagResult.tagName.toLowerCase()\n return createVerbatimHTMLBlock(\n tagResult.tagName,\n blockContent,\n blockEnd,\n parseHTMLAttributes(\n tagResult.whitespaceBeforeAttrs + tagResult.attrs,\n tagLower,\n tagResult.tagName,\n options\n ),\n tagResult.whitespaceBeforeAttrs + tagResult.attrs,\n true,\n false\n )\n }\n }\n\n // Fallback: for inline context or if block parsing didn't match, parse as self-closing\n // Per CommonMark spec Example 623: closing tags should preserve raw HTML to maintain spacing (e.g., </foo >)\n // Always preserve rawText for closing tags (both inline and block level) so they can be rendered correctly\n var rawText = source.slice(pos, tagResult.endPos)\n const result: MarkdownToJSX.HTMLSelfClosingNode & {\n endPos: number\n isClosingTag?: boolean\n rawText?: string\n } = {\n type: RuleType.htmlSelfClosing,\n tag: tagResult.tagName,\n attrs: {},\n endPos: tagResult.endPos,\n isClosingTag: true,\n rawText: rawText,\n }\n return result\n }\n\n // Now use unified parser result\n // tagResult already contains parsed tag info\n\n // IMPORTANT: All validation must happen BEFORE block parsing check\n // This ensures invalid tags are rejected even if they would match as blocks\n\n // Validate tag name: cannot start with space or newline after <\n // Per CommonMark spec Example 621: < a> and <\\nfoo> are invalid\n var tagNameStart = pos + (tagResult.isClosing ? 2 : 1)\n if (tagNameStart < source.length) {\n var firstChar = source[tagNameStart]\n if (\n firstChar === ' ' ||\n firstChar === '\\t' ||\n firstChar === '\\n' ||\n firstChar === '\\r'\n ) {\n // Tag name starts with whitespace - invalid HTML\n return null\n }\n }\n\n // Attributes are passed through opaquely - no validation\n\n var tagNameLower = tagResult.tagLower\n var isVoid = util.isVoidElement(tagResult.tagName)\n\n // Check if this is a JSX component (starts with uppercase letter)\n // JSX components should be parsed as block-level HTML even with newlines\n const isJSXComponent =\n tagResult.tagName.length > 0 &&\n tagResult.tagName[0] >= 'A' &&\n tagResult.tagName[0] <= 'Z'\n\n // Self-closing tags: has /> or is void (except anchor tags which need special handling)\n // Per CommonMark spec: self-closing tags with newlines are type 7 blocks\n // Type 7 blocks don't interrupt paragraphs, so they should be parsed as inline HTML\n // IMPORTANT: Validation already happened above, so if we get here the tag is valid\n // EXCEPTION: JSX components (uppercase tags) should always be parsed as block-level HTML\n if (tagResult.isSelfClosing || (isVoid && tagNameLower !== 'a')) {\n // If tag has newline, it's a type 7 block - don't interrupt paragraphs\n // Return null to allow paragraph wrapping - parseInlineSpan will parse as raw HTML\n // But only if validation passed (which already happened above)\n // EXCEPTION: JSX components should be parsed as block-level HTML even with newlines\n if (tagResult.hasNewline && !isJSXComponent) {\n return null\n }\n\n // If we're not in HTML block context and not inline, parse as inline HTML\n // This allows them to be wrapped in paragraphs per type 7 block rules\n // Return null to allow paragraph wrapping - parseInlineSpan will parse them as raw HTML\n // EXCEPTION: JSX components should be parsed as block-level HTML even when not in HTML block context\n if (!state.inHTML && !state.inline && !isJSXComponent) {\n return null\n }\n\n var attrsTrimmedSelfClose = tagResult.attrs.replace(/\\/\\s*$/, '')\n var selfCloseAttrs = parseHTMLAttributes(\n attrsTrimmedSelfClose,\n tagNameLower,\n tagResult.tagName,\n options\n )\n // For inline context, preserve raw HTML to maintain spacing\n var rawText = state.inline ? source.slice(pos, tagResult.endPos) : undefined\n const result: MarkdownToJSX.HTMLSelfClosingNode & {\n endPos: number\n rawText?: string\n } = {\n type: RuleType.htmlSelfClosing,\n tag: tagResult.tagName,\n attrs: selfCloseAttrs,\n endPos: tagResult.endPos,\n }\n if (rawText !== undefined) {\n result.rawText = rawText\n }\n return result\n }\n\n // For inline context, parse as simple opening tag (no closing tag search)\n // IMPORTANT: Validation must happen before this check to reject invalid tags\n // Note: parseHTMLTag only returns a result if tag has closing >, so tag is complete\n // Multiline attributes are supported - newlines in tags are valid HTML\n if (state.inline) {\n // Validation already happened above, so if we get here the tag is valid\n var attrsTrimmedInline = tagResult.attrs.replace(/\\/\\s*$/, '')\n // Preserve whitespace before attributes for CommonMark compliance\n var rawAttrsWithWhitespace =\n tagResult.whitespaceBeforeAttrs + attrsTrimmedInline\n var parsedInlineAttrs = parseHTMLAttributes(\n attrsTrimmedInline,\n tagNameLower,\n tagResult.tagName,\n options\n )\n var inlineAttrs: Record<string, any> = {\n ...parsedInlineAttrs,\n }\n\n // For non-void inline tags, find matching closing tag and parse content\n var inlineEndPos = tagResult.endPos\n var children: MarkdownToJSX.ASTNode[] = []\n if (!util.isVoidElement(tagResult.tagName)) {\n var closingResult = findInlineClosingTag(\n source,\n tagResult.endPos,\n tagNameLower\n )\n if (closingResult !== null) {\n var content = source.slice(tagResult.endPos, closingResult[0])\n if (content) {\n if (\n (state.inHTML && HTML_BLOCK_ELEMENT_START_R.test(content)) ||\n hasBlockContent(content)\n ) {\n children = parseBlocksInHTML(\n content,\n {\n ...state,\n inline: false,\n inHTML: true,\n inAnchor: state.inAnchor || tagNameLower === 'a',\n },\n options\n )\n } else {\n children = parseInlineSpan(\n content,\n 0,\n content.length,\n {\n ...state,\n inline: true,\n inAnchor: state.inAnchor || tagNameLower === 'a',\n },\n options\n )\n }\n }\n inlineEndPos = closingResult[1]\n }\n }\n return {\n type: RuleType.htmlBlock,\n tag: tagResult.tagName as MarkdownToJSX.HTMLTags,\n attrs: inlineAttrs,\n rawAttrs: rawAttrsWithWhitespace,\n children: children,\n noInnerParse: false,\n endPos: inlineEndPos,\n } as MarkdownToJSX.HTMLNode & { endPos: number }\n }\n\n // For inline context, don't try block parsing - simple opening tags should be parsed inline\n // Block parsing is only for tags that need closing tags or are block-level\n if (!state.inline) {\n // Determine block type inline (previously handled by matchHTMLBlock)\n var sourceLen = source.length\n var firstLineEnd = util.findLineEnd(source, pos)\n var tagLower = tagResult.tagLower\n var isType1BlockVar = isType1Block(tagLower)\n var isType6Block = !isType1BlockVar && isType6Tag(tagResult.tagName)\n var tagHasClosingAngle = false\n var checkPos = pos\n while (checkPos < tagResult.endPos) {\n if (source[checkPos] === '>') {\n tagHasClosingAngle = true\n break\n }\n checkPos++\n }\n // Check if tag is followed by end of line (with optional whitespace)\n var afterTag = tagResult.endPos\n while (\n afterTag < firstLineEnd &&\n (source[afterTag] === ' ' || source[afterTag] === '\\t')\n ) {\n afterTag++\n }\n // Check if tag is complete on line\n // For type 6 blocks, they can have content on same line\n // For other tags, they must be followed by newline or end of line\n var isCompleteOnLine =\n afterTag >= firstLineEnd ||\n source[afterTag] === '\\n' ||\n source[afterTag] === '\\r' ||\n (isType6Block && afterTag < firstLineEnd) ||\n !tagHasClosingAngle\n\n // Type 1 blocks (pre, script, style, textarea) need matching closing tags\n // Handle type 1 blocks even if they have newlines in the opening tag\n if (isType1BlockVar && tagHasClosingAngle && !tagResult.isClosing) {\n // Type 1: find matching closing tag\n var type1TagName = tagResult.tagName\n var type1TagEnd = tagResult.endPos\n var type1Attrs = tagResult.attrs\n var type1ContentPos = type1TagEnd\n if (source[type1ContentPos] === '\\n') type1ContentPos++\n var type1ContentStart = type1ContentPos\n var type1ContentEnd = type1ContentPos\n var type1Depth = 1\n var type1OpenTagLen = tagLower.length + 1\n while (type1Depth > 0) {\n var type1Idx = source.indexOf('<', type1ContentPos)\n if (type1Idx === -1) {\n type1ContentEnd = sourceLen\n type1ContentPos = sourceLen\n break\n }\n var type1OpenIdx = -1\n var type1CloseIdx = -1\n if (source[type1Idx + 1] === '/') {\n type1CloseIdx = type1Idx\n } else if (\n type1Idx + type1OpenTagLen + 1 <= sourceLen &&\n (source[type1Idx + 1] === tagLower[0] ||\n source[type1Idx + 1] === type1TagName[0])\n ) {\n var type1TagCandidate = source.substring(\n type1Idx + 1,\n type1Idx + type1OpenTagLen\n )\n if (\n type1TagCandidate.toLowerCase() === tagLower &&\n (source[type1Idx + type1OpenTagLen] === ' ' ||\n source[type1Idx + type1OpenTagLen] === '>')\n ) {\n type1OpenIdx = type1Idx\n }\n }\n if (type1OpenIdx === -1 && type1CloseIdx === -1) {\n type1ContentPos = type1Idx + 1\n continue\n }\n if (\n type1OpenIdx !== -1 &&\n (type1CloseIdx === -1 || type1OpenIdx < type1CloseIdx)\n ) {\n type1ContentPos = type1OpenIdx + type1OpenTagLen + 1\n type1Depth++\n } else {\n var type1P = type1CloseIdx + 2\n while (type1P < sourceLen) {\n var type1C = source[type1P]\n if (\n type1C !== ' ' &&\n type1C !== '\\t' &&\n type1C !== '\\n' &&\n type1C !== '\\r'\n )\n break\n type1P++\n }\n if (type1P + tagLower.length > sourceLen) break\n var type1CloseTagCandidate = source.substring(\n type1P,\n type1P + tagLower.length\n )\n if (type1CloseTagCandidate.toLowerCase() !== tagLower) {\n type1ContentPos = type1P\n continue\n }\n type1P += tagLower.length\n while (type1P < sourceLen) {\n var type1C2 = source[type1P]\n if (\n type1C2 !== ' ' &&\n type1C2 !== '\\t' &&\n type1C2 !== '\\n' &&\n type1C2 !== '\\r'\n )\n break\n type1P++\n }\n if (type1P >= sourceLen || source[type1P] !== '>') {\n type1ContentPos = type1P\n continue\n }\n var type1ClosingTagEnd = type1P + 1\n var type1LineEndAfterClose = util.findLineEnd(\n source,\n type1ClosingTagEnd\n )\n type1ContentEnd = type1LineEndAfterClose\n type1ContentPos = type1LineEndAfterClose + 1\n type1Depth--\n }\n }\n var type1TrailingNl = 0\n while (\n type1ContentPos + type1TrailingNl < sourceLen &&\n source[type1ContentPos + type1TrailingNl] === '\\n'\n )\n type1TrailingNl++\n var type1FullMatch = source.slice(pos, type1ContentPos + type1TrailingNl)\n var type1Content = source.slice(type1ContentStart, type1ContentEnd)\n var type1EndPos = type1ContentPos + type1TrailingNl\n return processHTMLBlock(\n tagResult.tagName,\n tagResult.tagName,\n type1Attrs,\n type1Content,\n type1FullMatch,\n type1EndPos,\n source,\n state,\n false,\n options\n )\n }\n\n // Type 6/7 blocks end at blank lines\n if (isCompleteOnLine || !tagHasClosingAngle) {\n // Determine if type 6 or type 7\n var blockType: 'type6' | 'type7' = isType6Block ? 'type6' : 'type7'\n var tagEnd = tagResult.endPos\n var blockEnd = findNextBlankLine(source, firstLineEnd + 1, sourceLen)\n\n // For type 6 blocks, check if there's a closing tag (even beyond the blank line)\n // If there is AND there's markdown syntax, extend to include the closing tag\n // Exception: for JSX compilation, always extend if there's a closing tag (to keep HTML blocks containing <pre> intact)\n if (blockType === 'type6' && !tagResult.isClosing) {\n // Use cached tagLower from parseHTMLTag result\n const tagLowerForClosing =\n tagResult.tagLower || tagResult.tagName.toLowerCase()\n var closingTagPattern = '</' + tagLowerForClosing\n var closingIdx = source.indexOf(closingTagPattern, tagEnd)\n if (closingIdx !== -1) {\n // Found a closing tag\n // Check if it's valid\n var afterClosingTag = closingIdx + closingTagPattern.length\n while (\n afterClosingTag < sourceLen &&\n (source[afterClosingTag] === ' ' ||\n source[afterClosingTag] === '\\t')\n ) {\n afterClosingTag++\n }\n if (afterClosingTag < sourceLen && source[afterClosingTag] === '>') {\n // Valid closing tag found\n var extendedContent = source.slice(tagEnd, closingIdx)\n var shouldExtend = hasBlockContent(extendedContent)\n if (shouldExtend) {\n // Extend block to include closing tag\n var closingLineEnd = util.findLineEnd(source, afterClosingTag + 1)\n blockEnd = closingLineEnd\n }\n }\n }\n }\n\n var blockContent = source.slice(tagEnd, blockEnd)\n var blockAttrs = tagResult.whitespaceBeforeAttrs + tagResult.attrs\n var isClosingTag = tagResult.isClosing\n\n // Handle type 6/7 blocks\n // For type 7 blocks with empty content (standalone tags), determine if they should be block or inline\n // Per CommonMark: Type 7 blocks cannot interrupt paragraphs, but if they're on their own line they're blocks\n // However, if the tag contains newlines in attributes (without hasNewline flag because they're in quotes),\n // it should be treated as inline and wrapped in a paragraph\n if (blockType === 'type7' && blockContent.trim() === '') {\n // Check if the tag itself contains a newline (inside the tag, not after it)\n var rawTagText = source.slice(pos, tagResult.endPos)\n var tagContainsNewline = rawTagText.indexOf('\\n') !== -1\n\n if (tagContainsNewline) {\n // Tag has newline inside it (in attribute) - should be wrapped in paragraph\n return null\n }\n\n // Tag is on its own line, treat as block\n var tagEndInSource = tagResult.endPos\n var tagLineEnd = util.findLineEnd(source, tagEndInSource)\n if (tagLineEnd < source.length) tagLineEnd++\n var rawTag = source.slice(pos, tagLineEnd)\n return createVerbatimHTMLBlock(\n tagResult.tagName,\n rawTag,\n blockEnd,\n {},\n undefined,\n isClosingTag,\n false, // type 7 blocks cannot interrupt paragraphs\n options\n )\n }\n\n // For type 7 blocks with multi-line or incomplete opening tags, preserve raw HTML\n var openingTagHasNewline = tagResult.hasNewline\n var openingTagIsIncomplete = !tagHasClosingAngle\n if (\n (openingTagHasNewline || openingTagIsIncomplete) &&\n blockType === 'type7'\n ) {\n var openingTagEnd = tagResult.endPos\n var rawOpeningTag = source.slice(pos, openingTagEnd)\n var rawContent = blockContent\n var fullRawHTML = rawOpeningTag + rawContent\n return createVerbatimHTMLBlock(\n tagResult.tagName,\n fullRawHTML,\n blockEnd,\n {},\n undefined,\n isClosingTag,\n false, // type 7 blocks cannot interrupt paragraphs\n options\n )\n }\n\n // Parse attributes, but always preserve raw attributes for consistency\n // Cache lowercase tag name to avoid repeated toLowerCase() calls\n const tagLower = tagResult.tagLower || tagResult.tagName.toLowerCase()\n var parsedBlockAttributes = parseHTMLAttributes(\n blockAttrs,\n tagLower,\n tagResult.tagName,\n options\n )\n var blockAttributes: Record<string, any> = {\n ...parsedBlockAttributes,\n }\n\n // For type 6 blocks with block syntax, parse through processHTMLBlock\n if (blockType === 'type6') {\n var contentForBlockCheck = blockContent\n var closingTagIdx = blockContent.indexOf('</' + tagLower)\n if (closingTagIdx >= 0) {\n var afterTag = closingTagIdx + 2 + tagResult.tagName.length\n while (\n afterTag < blockContent.length &&\n (blockContent[afterTag] === ' ' || blockContent[afterTag] === '\\t')\n )\n afterTag++\n if (\n afterTag < blockContent.length &&\n blockContent[afterTag] === '>'\n ) {\n contentForBlockCheck = blockContent.slice(0, closingTagIdx)\n }\n }\n\n if (hasBlockContent(contentForBlockCheck)) {\n return processHTMLBlock(\n tagResult.tagName,\n tagResult.tagName,\n blockAttrs,\n contentForBlockCheck,\n source.slice(pos, tagResult.endPos),\n blockEnd,\n source,\n state,\n false,\n options\n )\n }\n }\n\n // For type 6 and type 7 blocks, content is verbatim (raw HTML)\n // Content includes everything from after the opening tag to the blank line\n // Remove leading newline if present\n var verbatimContent = blockContent\n if (verbatimContent.length > 0 && verbatimContent[0] === '\\n') {\n verbatimContent = verbatimContent.slice(1)\n }\n // Per CommonMark spec: remove common leading whitespace from all lines\n var lines = verbatimContent.split('\\n')\n var minIndent = Infinity\n for (var lineIdx = 0; lineIdx < lines.length; lineIdx++) {\n var line = lines[lineIdx]\n if (line.trim().length === 0) continue\n var indent = 0\n while (\n indent < line.length &&\n (line[indent] === ' ' || line[indent] === '\\t')\n ) {\n indent++\n }\n if (indent < minIndent) minIndent = indent\n }\n if (minIndent > 0 && minIndent < Infinity) {\n var dedentedLines: string[] = []\n for (var lineIdx2 = 0; lineIdx2 < lines.length; lineIdx2++) {\n var line2 = lines[lineIdx2]\n if (line2.trim().length === 0) {\n dedentedLines.push(line2)\n } else {\n dedentedLines.push(line2.slice(minIndent))\n }\n }\n verbatimContent = dedentedLines.join('\\n')\n }\n\n return createVerbatimHTMLBlock(\n tagResult.tagName,\n verbatimContent,\n blockEnd,\n blockAttributes,\n blockAttrs,\n isClosingTag,\n blockType === 'type6' ? true : false, // type 6 can interrupt, type 7 cannot\n options\n )\n }\n }\n\n // If we're in inline context and didn't match simple tag parsing, return null\n // This allows the tag to be escaped or handled by other parsers\n if (state.inline) {\n return null\n }\n\n // Fallback: Try void element without /> (manual parsing)\n // Only try this if self-closing didn't match\n var tagNameResult = parseHTMLTagName(source, pos + 1)\n if (!tagNameResult) return null\n\n var tagName = tagNameResult.tagName\n if (!util.isVoidElement(tagName)) {\n return null\n }\n\n // Use tagLower from parseHTMLTagName result to avoid repeated toLowerCase() calls\n const tagLowerVoid = tagNameResult.tagLower\n\n var i = tagNameResult.nextPos\n var len = source.length\n while (i < len && isSpaceOrTab(source[i])) i++\n var attrsStart = i\n\n while (i < len && source[i] !== '>') i++\n if (i >= len) return null\n\n const attrs = source.slice(attrsStart, i).trim()\n const afterAngle = i + 1\n\n let checkIdx = afterAngle\n while (checkIdx < len && isSpaceOrTab(source[checkIdx])) checkIdx++\n const closeTagPattern = '</' + tagLowerVoid + '>'\n const foundIdx = source.toLowerCase().indexOf(closeTagPattern, checkIdx)\n if (foundIdx !== -1) {\n const between = source.slice(checkIdx, foundIdx).trim()\n if (between) {\n return null\n }\n }\n\n i++\n const endPos = i\n while (i < len && isSpaceOrTab(source[i])) i++\n if (i < len && source[i] === '\\n') i++\n\n const fallbackAttributes = parseHTMLAttributes(\n attrs,\n tagName,\n tagName,\n options\n )\n\n return {\n type: RuleType.htmlSelfClosing,\n tag: tagName,\n attrs: fallbackAttributes,\n endPos,\n } as MarkdownToJSX.HTMLSelfClosingNode & { endPos: number }\n}\n\n// ============================================================================\n// HTML Token Interface and Unified Scanner\n// Ultra-compact unified scanner for all HTML constructs\n// ============================================================================\n\nexport interface HTMLToken {\n kind: 'tag' | 'comment' | 'pi' | 'declaration' | 'cdata'\n tagNameLower?: string\n tagName?: string\n isClosing?: boolean\n isSelfClosing?: boolean\n hasNewline: boolean\n type6Candidate?: boolean\n type7Candidate?: boolean\n endPos: number\n attrs?: string\n whitespaceBeforeAttrs?: string\n text?: string\n raw?: boolean\n}\n\n/**\n * Scan tag-like constructs: </tag, <tag\n */\nfunction scanTagLike(source: string, pos: number): HTMLToken | null {\n if (source[pos] !== '<') return null\n\n var sourceLen = source.length\n\n // Check for closing tag (</tag>)\n var isClosing = false\n var tagStart = pos + 1\n if (pos + 1 < sourceLen && source[pos + 1] === '/') {\n isClosing = true\n tagStart = pos + 2\n }\n\n // Parse tag name\n var tagNameResult = parseHTMLTagName(source, tagStart)\n if (!tagNameResult) return null\n\n var tagName = tagNameResult.tagName\n var tagLower = tagNameResult.tagLower\n var attrsStart = tagNameResult.nextPos\n\n // Fast path: tags without attributes or whitespace\n if (attrsStart < sourceLen) {\n var immediateChar = source[attrsStart]\n if (immediateChar === '>' || immediateChar === '/') {\n var endPos = immediateChar === '>' ? attrsStart + 1 : attrsStart + 2\n if (\n immediateChar === '/' &&\n (attrsStart + 1 >= sourceLen || source[attrsStart + 1] !== '>')\n ) {\n return null\n }\n var isSelfClosingFast = immediateChar === '/'\n var type6CandidateFast = isType6Tag(tagName)\n var type7CandidateFast = !isType1Block(tagLower) && !type6CandidateFast\n return {\n kind: 'tag',\n tagNameLower: tagLower,\n tagName: tagName,\n isClosing: isClosing,\n isSelfClosing: isSelfClosingFast,\n hasNewline: false,\n type6Candidate: type6CandidateFast,\n type7Candidate: type7CandidateFast,\n endPos: endPos,\n attrs: '',\n whitespaceBeforeAttrs: '',\n }\n }\n }\n\n // Capture whitespace after tag name (including newlines per CommonMark spec)\n var whitespaceStart = attrsStart\n var hasNewline = false\n while (attrsStart < sourceLen) {\n var ch = source[attrsStart]\n var code = charCode(source, attrsStart)\n if (ch === ' ' || ch === '\\t') {\n // Space or tab - continue\n } else if (code === 10 || code === 13) {\n // \\n or \\r\n hasNewline = true\n } else {\n break // Not whitespace\n }\n attrsStart++\n }\n var whitespaceBeforeAttrs = source.slice(whitespaceStart, attrsStart)\n\n // Parse attributes until we find > - minimal validation only for boundary detection\n var tagEnd = attrsStart\n var inQuotes = false\n var quoteChar = ''\n var braceDepth = 0\n var hasSlash = false\n var hasSpaceBeforeSlash = false\n\n // State machine for attribute parsing: 0=normal, 1=inDoubleQuotes, 2=inSingleQuotes\n var parseState = 0\n while (tagEnd < sourceLen) {\n var char = source[tagEnd]\n var code = charCode(source, tagEnd)\n\n // Handle quotes state machine\n if (parseState === 1) {\n // in double quotes\n if (char === '\"') {\n // Check for consecutive quotes (invalid HTML)\n if (tagEnd + 1 < sourceLen && source[tagEnd + 1] === '\"') {\n return null\n }\n parseState = 0\n }\n tagEnd++\n } else if (parseState === 2) {\n // in single quotes\n if (char === \"'\") {\n parseState = 0\n }\n tagEnd++\n } else if (char === '\"') {\n parseState = 1\n tagEnd++\n } else if (char === \"'\") {\n parseState = 2\n tagEnd++\n } else if (char === '{' || (char === '}' && braceDepth > 0)) {\n // Track JSX expression brace depth\n braceDepth += char === '{' ? 1 : -1\n tagEnd++\n } else if (char === '>' && braceDepth === 0) {\n // Found closing > - check for self-closing / and space before >\n if (tagEnd > attrsStart) {\n var checkBack = tagEnd - 1\n while (checkBack >= attrsStart) {\n var backChar = source[checkBack]\n if (backChar !== ' ' && backChar !== '\\t') break\n checkBack--\n }\n if (checkBack >= attrsStart && source[checkBack] === '/') {\n hasSlash = true\n hasSpaceBeforeSlash = checkBack < tagEnd - 1\n }\n }\n tagEnd++\n break\n } else {\n // Check for invalid attribute name characters (*, #, !)\n if (char === '*' || char === '#' || char === '!') {\n var checkAhead = tagEnd + 1\n while (checkAhead < sourceLen) {\n var aheadChar = source[checkAhead]\n if (\n aheadChar === '=' ||\n aheadChar === ' ' ||\n aheadChar === '\\t' ||\n aheadChar === '\\n' ||\n aheadChar === '\\r' ||\n aheadChar === '>'\n ) {\n break\n }\n checkAhead++\n }\n if (checkAhead < sourceLen && source[checkAhead] === '=') {\n return null // Invalid char in attribute name\n }\n }\n // Track newlines\n if (code === 10 || code === 13) {\n // \\n or \\r\n hasNewline = true\n }\n tagEnd++\n }\n }\n\n // Must have found >\n if (tagEnd > sourceLen || source[tagEnd - 1] !== '>') {\n return null\n }\n\n // Reject tags with unclosed quotes\n if (parseState === 1 || parseState === 2) {\n return null\n }\n\n // Reject tags with unclosed JSX expressions\n if (braceDepth > 0) {\n return null\n }\n\n // Reject tags with space between / and > (invalid HTML structure)\n if (hasSpaceBeforeSlash) {\n return null\n }\n\n var attrsEnd = tagEnd - 1\n if (hasSlash) {\n // For self-closing tags, exclude the / from attrs\n attrsEnd--\n }\n var attrs = source.slice(attrsStart, attrsEnd)\n var isSelfClosing = hasSlash\n\n // Minimal validation: reject missing space after quoted attribute value\n var lastQuotePos = -1\n var inQuotesCheck = false\n var quoteCharCheck = ''\n var afterEquals = false\n for (var i = 0; i < attrs.length; i++) {\n var ch = attrs[i]\n if (inQuotesCheck) {\n if (ch === quoteCharCheck) {\n inQuotesCheck = false\n lastQuotePos = i\n quoteCharCheck = ''\n afterEquals = false\n }\n } else if (ch === '\"' || ch === \"'\") {\n inQuotesCheck = true\n quoteCharCheck = ch\n afterEquals = false\n } else if (ch === '=') {\n afterEquals = true\n } else if (lastQuotePos !== -1 && i === lastQuotePos + 1) {\n // Immediately after closing quote\n var code = ch.charCodeAt(0)\n if (isAlphaCode(code)) {\n // Letter immediately after quote - missing space, reject\n return null\n }\n } else if (\n afterEquals &&\n !inQuotesCheck &&\n (ch === '*' || ch === '#' || ch === '!')\n ) {\n // Invalid char in unquoted attribute value - reject\n return null\n } else if (isSpaceOrTab(ch)) {\n afterEquals = false\n }\n }\n\n // Determine type 6/7 candidates\n var type6Candidate = isType6Tag(tagName)\n var type7Candidate = !isType1Block(tagLower) && !type6Candidate\n\n return {\n kind: 'tag',\n tagNameLower: tagLower,\n tagName: tagName,\n isClosing: isClosing,\n isSelfClosing: isSelfClosing,\n hasNewline: hasNewline,\n type6Candidate: type6Candidate,\n type7Candidate: type7Candidate,\n endPos: tagEnd,\n attrs: attrs,\n whitespaceBeforeAttrs: whitespaceBeforeAttrs,\n }\n}\n\n// ============================================================================\n// Unified HTML Scanner\n// Ultra-compact unified scanner for all HTML constructs\n// ============================================================================\n\n/**\n * Unified HTML scanner - handles tags, comments, PIs, declarations, CDATA\n * Ultra-compact implementation tuned for minification\n */\nfunction scanRawHTML(s: string, p: number): HTMLToken | null {\n if (p >= s.length || s[p] !== '<') return null\n var l = s.length\n if (p + 1 >= l) return null\n var c = s[p + 1]\n if (c === '!') {\n if (p + 4 <= l && s.slice(p, p + 4) === '<!--') {\n // Comment: scan for -->\n var endPos = p + 4\n if (endPos < l && s[endPos] === '>') {\n return {\n kind: 'comment',\n hasNewline: false,\n endPos: endPos + 1,\n text: s.slice(p, endPos + 1),\n raw: true,\n }\n }\n if (endPos + 1 < l && s[endPos] === '-' && s[endPos + 1] === '>') {\n return {\n kind: 'comment',\n hasNewline: false,\n endPos: endPos + 2,\n text: s.slice(p, endPos + 2),\n raw: true,\n }\n }\n while (endPos + 2 < l) {\n if (s.slice(endPos, endPos + 3) === '-->') {\n return {\n kind: 'comment',\n hasNewline: false,\n endPos: endPos + 3,\n text: s.slice(p, endPos + 3),\n raw: true,\n }\n }\n endPos++\n }\n return null\n }\n if (p + 9 <= l && s.slice(p, p + 9) === '<![CDATA[') {\n // CDATA: scan for ]]>\n var endPos = p + 9\n while (endPos + 2 < l) {\n if (s.slice(endPos, endPos + 3) === ']]>') {\n return {\n kind: 'cdata',\n hasNewline: false,\n endPos: endPos + 3,\n text: s.slice(p, endPos + 3),\n raw: true,\n }\n }\n endPos++\n }\n return null\n }\n if (p + 2 < l && isAlphaCode(s.charCodeAt(p + 2))) {\n // Declaration: scan for >\n var endPos = p + 2\n while (endPos < l && s[endPos] !== '>') endPos++\n if (endPos >= l) return null\n return {\n kind: 'declaration',\n hasNewline: false,\n endPos: endPos + 1,\n text: s.slice(p, endPos + 1),\n raw: true,\n }\n }\n return null\n }\n if (c === '?') {\n // Processing instruction: scan for ?>\n var endPos = p + 2\n while (endPos + 1 < l) {\n if (s.slice(endPos, endPos + 2) === '?>') {\n return {\n kind: 'pi',\n hasNewline: false,\n endPos: endPos + 2,\n text: s.slice(p, endPos + 2),\n raw: true,\n }\n }\n endPos++\n }\n return null\n }\n return scanTagLike(s, p)\n}\n\ninterface DefinitionParseResult {\n endPos: number\n target: string\n title?: string\n}\n\nfunction parseRefContent(\n source: string,\n pos: number,\n urlNewlineCount: number\n): DefinitionParseResult | null {\n const len = source.length\n let i = pos\n\n // Parse URL (can be in angle brackets or plain, can span multiple lines)\n // At this point, i should be at the start of the destination (after any whitespace/newline)\n // Per CommonMark spec: destination can be on the same line or following lines\n const hasAngleBrackets = i < len && source[i] === '<'\n if (hasAngleBrackets) i++\n\n const urlStart = i\n let urlEnd = urlStart\n\n // Per CommonMark spec Example 199: empty destination after colon (just whitespace/newline)\n // is invalid - should be parsed as paragraph, not reference definition\n // Also check if we hit a blank line (two consecutive newlines) - destination ends there\n if (urlStart >= len) {\n // No destination found - invalid (except for empty <>)\n if (!hasAngleBrackets) return null\n // For angle brackets, empty destination is valid\n urlEnd = urlStart\n } else if (\n urlNewlineCount > 0 &&\n urlStart < len &&\n source[urlStart] === '\\n'\n ) {\n // We had a newline after colon, skipped whitespace, but found another newline\n // This means blank line after colon - empty destination, invalid\n return null\n } else {\n // Find end of URL - can span multiple lines\n // Per CommonMark spec: destination ends when we encounter:\n // 1. Closing > for angle-bracketed URLs\n // 2. Whitespace followed by title delimiter (\", ', or () on same or next line\n // 3. End of input or two consecutive newlines (blank line)\n while (urlEnd < len) {\n if (hasAngleBrackets && source[urlEnd] === '>') {\n break\n }\n\n if (source[urlEnd] === '\\n') {\n // Check if next line continues the URL or starts a title\n const nextLineStart = urlEnd + 1\n if (nextLineStart >= len) break\n\n // Check for blank line (two consecutive newlines)\n if (nextLineStart < len && source[nextLineStart] === '\\n') {\n // Blank line - URL ends here\n break\n }\n\n // Skip whitespace on next line\n let checkPos = nextLineStart\n while (\n checkPos < len &&\n (source[checkPos] === ' ' || source[checkPos] === '\\t')\n ) {\n checkPos++\n }\n\n // If next line starts with title delimiter, URL ends here\n if (\n checkPos < len &&\n (source[checkPos] === '\"' ||\n source[checkPos] === \"'\" ||\n source[checkPos] === '(')\n ) {\n break\n }\n\n // Per CommonMark spec: reference definitions are block-level constructs\n // If next line starts with '[', it's a new reference definition, so current one ends here\n // Stop at the newline (don't include it in the URL)\n if (checkPos < len && source[checkPos] === '[') {\n break\n }\n\n // Check if next line looks like a block-level construct or content that would terminate the ref definition\n // Per CommonMark spec: \"No further character may occur\" after title/URL\n // URLs can span multiple lines, but continuation lines should still look like URLs\n if (checkPos < len) {\n const nextChar = source[checkPos]\n // Always stop for block-level constructs\n if (\n nextChar === '=' ||\n nextChar === '-' ||\n nextChar === '_' ||\n nextChar === '*' ||\n nextChar === '#' ||\n nextChar === '>' ||\n nextChar === '`' ||\n nextChar === '~' ||\n nextChar === '[' ||\n (nextChar >= '0' && nextChar <= '9')\n ) {\n break\n }\n // Stop if next line starts with a letter (could be content, not URL continuation)\n // URLs typically start with /, http, https, <, or are indented\n // But allow if it looks like a URL scheme (letter followed by :)\n if (nextChar >= 'a' && nextChar <= 'z') {\n // Check if it's a URL scheme (e.g., \"http:\", \"ftp:\")\n let schemeEnd = checkPos + 1\n while (\n schemeEnd < len &&\n schemeEnd < checkPos + 32 &&\n ((source[schemeEnd] >= 'a' && source[schemeEnd] <= 'z') ||\n (source[schemeEnd] >= 'A' && source[schemeEnd] <= 'Z') ||\n (source[schemeEnd] >= '0' && source[schemeEnd] <= '9') ||\n source[schemeEnd] === '+' ||\n source[schemeEnd] === '.' ||\n source[schemeEnd] === '-')\n ) {\n schemeEnd++\n }\n // If followed by ':', it's a URL scheme - allow continuation\n if (schemeEnd < len && source[schemeEnd] === ':') {\n // URL scheme - allow continuation\n } else {\n // Not a URL scheme - stop here (likely content)\n break\n }\n }\n }\n\n // Otherwise, continue URL on next line (skip the newline and leading whitespace)\n urlEnd = checkPos\n continue\n }\n\n if (\n !hasAngleBrackets &&\n (source[urlEnd] === ' ' || source[urlEnd] === '\\t')\n ) {\n // Check if this whitespace is followed by a title delimiter\n let checkPos = urlEnd + 1\n while (\n checkPos < len &&\n (source[checkPos] === ' ' || source[checkPos] === '\\t')\n ) {\n checkPos++\n }\n\n // Check if next char starts a title\n if (\n checkPos < len &&\n (source[checkPos] === '\"' ||\n source[checkPos] === \"'\" ||\n source[checkPos] === '(')\n ) {\n break\n }\n\n // Check if next line starts a title\n if (checkPos < len && source[checkPos] === '\\n') {\n const nextLineStart = checkPos + 1\n if (nextLineStart < len && source[nextLineStart] === '\\n') {\n // Blank line - URL ends here\n break\n }\n let nextLineCheck = nextLineStart\n while (\n nextLineCheck < len &&\n (source[nextLineCheck] === ' ' || source[nextLineCheck] === '\\t')\n ) {\n nextLineCheck++\n }\n if (\n nextLineCheck < len &&\n (source[nextLineCheck] === '\"' ||\n source[nextLineCheck] === \"'\" ||\n source[nextLineCheck] === '(')\n ) {\n break\n }\n }\n\n // No title delimiter found - URL continues (or ends if no title)\n // Continue parsing to find title or end\n }\n\n urlEnd++\n }\n }\n\n if (hasAngleBrackets && (urlEnd >= len || source[urlEnd] !== '>')) {\n return null // No closing >\n }\n\n // Extract target and normalize whitespace\n // Per CommonMark spec: destination can span multiple lines\n // Leading/trailing whitespace on each line should be trimmed, but internal whitespace preserved\n // Also, we need to preserve newlines between continuation lines\n let target = source.slice(urlStart, urlEnd)\n\n // Normalize whitespace: trim leading/trailing whitespace from each line\n // but preserve newlines and internal whitespace\n // Per CommonMark spec: leading/trailing whitespace is trimmed from destination\n let targetLines: string[] = []\n let targetLineStart = 0\n for (let i = 0; i <= target.length; i++) {\n if (i === target.length || target[i] === '\\n') {\n let line = target.slice(targetLineStart, i)\n // Trim leading/trailing whitespace from this line\n line = line.trim()\n if (line.length > 0 || targetLines.length === 0) {\n // Only add non-empty lines, or the first line even if empty (for angle brackets)\n targetLines.push(line)\n if (i < target.length) {\n targetLines.push('\\n')\n }\n } else if (i < target.length) {\n // Empty continuation line - preserve as newline\n targetLines.push('\\n')\n }\n targetLineStart = i + 1\n }\n }\n\n target = targetLines.join('')\n\n // Trim leading/trailing whitespace from the entire target\n target = target.trim()\n\n i = hasAngleBrackets ? urlEnd + 1 : urlEnd\n\n // Check if we stopped URL parsing because next line starts with a block construct\n // (indicating the ref definition ends here)\n // Per Example 215: ref definitions end before setext headings\n // A setext heading has content on one line, then = or - on the next line\n // We need to look ahead to detect this pattern\n var stoppedAtBlock = false\n if (i < len && source[i] === '\\n') {\n var nextLineStart = i + 1\n var checkPos = nextLineStart\n while (\n checkPos < len &&\n (source[checkPos] === ' ' || source[checkPos] === '\\t')\n ) {\n checkPos++\n }\n if (checkPos < len) {\n const nextChar = source[checkPos]\n // Check for block-level constructs that terminate ref definitions\n if (\n nextChar === '[' ||\n nextChar === '=' ||\n nextChar === '-' ||\n nextChar === '_' ||\n nextChar === '*' ||\n nextChar === '#' ||\n nextChar === '>' ||\n nextChar === '`' ||\n nextChar === '~' ||\n (nextChar >= '0' && nextChar <= '9')\n ) {\n stoppedAtBlock = true\n }\n // Per Example 215: check if this looks like a setext heading\n // Pattern: content line, then line starting with = or -\n // If next line has content (not starting with block char), check if line after that starts with = or -\n if (!stoppedAtBlock && nextChar !== '=' && nextChar !== '-') {\n // Next line might be content - check if line after that starts with = or -\n var firstLineEnd = util.findLineEnd(source, checkPos)\n if (firstLineEnd < len) {\n var secondLineStart = firstLineEnd + 1\n var secondCheckPos = secondLineStart\n while (\n secondCheckPos < len &&\n (source[secondCheckPos] === ' ' || source[secondCheckPos] === '\\t')\n ) {\n secondCheckPos++\n }\n if (secondCheckPos < len) {\n var secondChar = source[secondCheckPos]\n if (secondChar === '=' || secondChar === '-') {\n // This is a setext heading pattern - ref definition should end before content line\n stoppedAtBlock = true\n }\n }\n }\n }\n }\n }\n\n // Per CommonMark spec: title delimiter must be separated by whitespace from destination\n // Check if we see a title delimiter immediately after destination (no whitespace)\n // This makes it invalid as a reference definition\n if (\n !stoppedAtBlock &&\n i < len &&\n (source[i] === '\"' || source[i] === \"'\" || source[i] === '(')\n ) {\n // Title delimiter immediately after destination without whitespace - invalid\n return null\n }\n\n // Skip whitespace between destination and title (including optional newline)\n // Per CommonMark spec: title must be separated from destination by spaces/tabs\n // The title can be on the same line or a following line\n // Per CommonMark spec: Unicode whitespace (like non-breaking space) does NOT work for separation\n // However, if we stopped because next line starts with a block construct, don't skip past the newline\n let titleNewlineCount = 0\n while (i < len && !stoppedAtBlock) {\n const c = source[i]\n if (c === '\\n') {\n titleNewlineCount++\n if (titleNewlineCount > 1) break // Only one optional newline allowed before title\n i++\n // After newline, skip leading whitespace on next line (only ASCII space/tab)\n var whitespaceStart = i\n i = util.skipWhitespace(source, i)\n // If we hit Unicode whitespace, stop\n if (\n i < len &&\n util.isUnicodeWhitespace(source[i]) &&\n source[i] !== '\\n'\n ) {\n i = whitespaceStart - 1\n break\n }\n // Check if next line starts with a block construct (ref definition ends here)\n // Per Example 215: setext headings (= or -) also terminate ref definitions\n if (i < len) {\n const nextChar = source[i]\n if (\n nextChar === '[' ||\n nextChar === '=' ||\n nextChar === '-' ||\n nextChar === '_' ||\n nextChar === '*' ||\n nextChar === '#' ||\n nextChar === '>' ||\n nextChar === '`' ||\n nextChar === '~' ||\n (nextChar >= '0' && nextChar <= '9')\n ) {\n stoppedAtBlock = true\n i = whitespaceStart - 1 // Back up to the newline\n break\n }\n // Also check if this looks like a setext heading (need to look ahead to see if there's\n // a line that starts with = or - after some content)\n // For now, just checking = or - is sufficient as they're already in the block check above\n }\n } else if (c === ' ' || c === '\\t') {\n i++\n } else if (util.isUnicodeWhitespace(c)) {\n // Unicode whitespace does NOT work for separation - stop here\n break\n } else {\n break\n }\n }\n\n // Parse optional title (can span multiple lines, but cannot contain blank lines)\n let title: string | undefined = undefined\n let titleEndPos = i\n if (i < len) {\n const titleChar = source[i]\n if (titleChar === '\"' || titleChar === \"'\") {\n // Quoted title - can span multiple lines\n i++ // skip opening quote\n const titleStart = i\n let sawBlankLine = false\n let lastWasNewline = false\n\n while (i < len && source[i] !== titleChar) {\n if (source[i] === '\\n') {\n if (lastWasNewline) {\n // Two consecutive newlines = blank line\n sawBlankLine = true\n break\n }\n lastWasNewline = true\n i++\n } else {\n lastWasNewline = false\n if (source[i] === '\\\\' && i + 1 < len) {\n i++ // skip escaped char\n }\n i++\n }\n }\n\n if (sawBlankLine) {\n // Title contains blank line - invalid\n return null\n }\n\n if (i < len && source[i] === titleChar) {\n // Extract title preserving newlines (CommonMark spec allows multi-line titles)\n title = source.slice(titleStart, i)\n titleEndPos = i + 1\n i = titleEndPos\n // Per Example 210: after closing quote, check if there's non-whitespace before newline\n // Skip whitespace after closing quote\n var afterTitlePos = i\n while (\n afterTitlePos < len &&\n (source[afterTitlePos] === ' ' || source[afterTitlePos] === '\\t')\n ) {\n afterTitlePos++\n }\n // If there's non-whitespace before newline, invalidate the ref definition\n if (\n afterTitlePos < len &&\n source[afterTitlePos] !== '\\n' &&\n source[afterTitlePos] !== '\\r'\n ) {\n // Found non-whitespace after title closing delimiter - invalid\n return null\n }\n // Update i to point to after any whitespace (before newline)\n i = afterTitlePos\n }\n } else if (titleChar === '(') {\n // Parenthesized title - can span multiple lines\n i++ // skip opening paren\n const titleStart = i\n let parenDepth = 1\n let sawBlankLine = false\n let lastWasNewline = false\n\n while (i < len && parenDepth > 0) {\n if (source[i] === '\\n') {\n if (lastWasNewline) {\n // Two consecutive newlines = blank line\n sawBlankLine = true\n break\n }\n lastWasNewline = true\n i++\n } else {\n lastWasNewline = false\n if (source[i] === '\\\\' && i + 1 < len) {\n i++ // skip escaped char\n } else if (source[i] === '(') {\n parenDepth++\n } else if (source[i] === ')') {\n parenDepth--\n }\n i++\n }\n }\n\n if (sawBlankLine) {\n // Title contains blank line - invalid\n return null\n }\n\n if (parenDepth === 0) {\n title = source.slice(titleStart, i - 1)\n titleEndPos = i\n i = titleEndPos\n }\n }\n }\n\n // Skip trailing whitespace\n i = util.skipWhitespace(source, i)\n\n // Must end at newline or end of input\n // Per CommonMark spec: no further character may occur after title\n // Per Example 210: if there's text after the title on the same line, it's invalid\n // The title parsing already handles this - if title is found, i points to after the closing delimiter\n // We just need to ensure there's no non-whitespace before the newline\n if (i < len && source[i] !== '\\n') {\n // Check if there's non-whitespace before the newline\n var checkEndPos = i\n while (checkEndPos < len && source[checkEndPos] !== '\\n') {\n if (source[checkEndPos] !== ' ' && source[checkEndPos] !== '\\t') {\n // Found non-whitespace after title - invalid reference definition\n return null\n }\n checkEndPos++\n }\n }\n\n // Also check: if no title was found, make sure we're at end of line or there's trailing text\n // Per Example 210: `[foo]: /url\\n\"title\" ok` - the \"title\" ok is trailing text, should invalidate\n if (title === undefined && i < len && source[i] !== '\\n') {\n // No title found, but there's content after destination - check if it's just whitespace\n var checkTrailingPos = i\n while (checkTrailingPos < len && source[checkTrailingPos] !== '\\n') {\n if (\n source[checkTrailingPos] !== ' ' &&\n source[checkTrailingPos] !== '\\t'\n ) {\n // Found non-whitespace after destination - invalid reference definition\n return null\n }\n checkTrailingPos++\n }\n }\n\n return {\n endPos: i < len && source[i] === '\\n' ? i + 1 : i,\n target: target,\n title: title,\n }\n}\n\nfunction parseFootnoteContent(\n source: string,\n pos: number\n): DefinitionParseResult | null {\n // pos is already after the colon and whitespace\n let contentStart = pos\n let contentEnd = contentStart\n\n // Find the end of the footnote (next footnote definition, blank line, or end of input)\n // Continuation lines are lines that:\n // 1. Start with a newline\n // 2. Don't start with [^ (unless indented with 4+ spaces)\n // 3. Can be indented with up to 4 spaces\n // 4. Stop at a blank line (two consecutive newlines) if followed by non-indented content\n let stoppedAtBlankLine = false\n while (contentEnd < source.length) {\n // Check if we're at the start of a line (after newline or at start of input)\n const isLineStart = contentEnd === 0 || source[contentEnd - 1] === '\\n'\n\n // Check for blank line (two consecutive newlines) followed by non-indented content\n // A blank line terminates the footnote if followed by content that's not indented 4+ spaces\n // We need to check if we're at a blank line: current position is \\n and next is \\n\n if (\n contentEnd + 1 < source.length &&\n source[contentEnd] === '\\n' &&\n source[contentEnd + 1] === '\\n' &&\n contentEnd > contentStart // Make sure we're past the first line\n ) {\n // Check if there's non-indented content after the blank line\n let afterBlank = contentEnd + 2\n // Skip whitespace\n while (\n afterBlank < source.length &&\n (source[afterBlank] === ' ' || source[afterBlank] === '\\t')\n ) {\n afterBlank++\n }\n // If there's content and it's not indented with 4+ spaces, stop the footnote\n if (\n afterBlank < source.length &&\n source[afterBlank] !== '\\n' &&\n afterBlank - (contentEnd + 2) < 4\n ) {\n // Blank line followed by non-indented content - stop at the blank line\n stoppedAtBlankLine = true\n break\n }\n }\n\n if (isLineStart && util.startsWith(source, '[^', contentEnd)) {\n // Check if this is a footnote definition (has ':')\n let checkPos = contentEnd + 2\n while (checkPos < source.length && source[checkPos] !== ']') {\n checkPos++\n }\n if (\n checkPos < source.length &&\n source[checkPos] === ']' &&\n checkPos + 1 < source.length &&\n source[checkPos + 1] === ':'\n ) {\n // Found next footnote definition at start of line - stop here\n break\n }\n }\n contentEnd++\n }\n\n // Extract the footnote content (from after ']:' to before next footnote or end)\n // If we stopped at a blank line, contentEnd points to the first \\n of \\n\\n\n // We want to extract up to but not including that \\n (which slice does)\n // But we also need to make sure we don't include the trailing newline from the last line\n let extractEnd = contentEnd\n\n // pos is already after the colon and whitespace, so we can use it directly\n let contentStartPos = pos\n\n // Process lines directly without splitting to avoid intermediate array allocation\n var processedParts: string[] = []\n let lineStart = contentStartPos\n let lineIndex = 0\n let prevWasBlank = false\n\n while (lineStart < extractEnd) {\n let lineEnd = lineStart\n // Find line end\n while (lineEnd < extractEnd && source[lineEnd] !== '\\n') {\n lineEnd++\n }\n\n // Extract and process line\n if (lineIndex === 0) {\n // First line - trim trailing whitespace only\n let trimmedEnd = lineEnd\n while (\n trimmedEnd > lineStart &&\n (source[trimmedEnd - 1] === ' ' || source[trimmedEnd - 1] === '\\t')\n ) {\n trimmedEnd--\n }\n // Build first line\n let firstLineStr = source.slice(lineStart, trimmedEnd)\n processedParts.push(firstLineStr)\n // Check if first line is blank\n prevWasBlank = firstLineStr.length === 0\n } else {\n // Check indentation on current line\n let leadingSpaceCount = 0\n let checkPos = lineStart\n while (\n checkPos < lineEnd &&\n checkPos < lineStart + 4 &&\n source[checkPos] === ' '\n ) {\n leadingSpaceCount++\n checkPos++\n }\n\n // Check if current line is blank\n let lineHasContent = false\n for (let k = lineStart; k < lineEnd; k++) {\n if (source[k] !== ' ' && source[k] !== '\\t' && source[k] !== '\\r') {\n lineHasContent = true\n break\n }\n }\n let currentIsBlank = !lineHasContent\n\n // Process continuation line based on indentation rules\n if (leadingSpaceCount >= 4 && prevWasBlank) {\n // 4+ spaces after a blank line - this is a paragraph, preserve indentation\n processedParts.push(source.slice(lineStart, lineEnd))\n } else if (leadingSpaceCount === 4 && !prevWasBlank) {\n // Exactly 4 spaces without blank line - remove (markdown continuation indentation)\n processedParts.push(source.slice(lineStart + 4, lineEnd))\n } else {\n // Otherwise preserve (less than 4 spaces or more than 4 spaces without blank line)\n processedParts.push(source.slice(lineStart, lineEnd))\n }\n\n // Update prevWasBlank for next iteration\n prevWasBlank = currentIsBlank\n }\n\n // Move to next line\n if (lineEnd < extractEnd && source[lineEnd] === '\\n') {\n processedParts.push('\\n')\n lineStart = lineEnd + 1\n } else {\n lineStart = extractEnd\n }\n lineIndex++\n }\n\n let footnoteContent = processedParts.join('')\n\n // Trim trailing whitespace/newlines but preserve internal structure\n // If we stopped at a blank line, remove the trailing newline from the last line\n if (stoppedAtBlankLine) {\n // Remove trailing newline if present (but preserve newlines between lines)\n footnoteContent = footnoteContent.replace(/\\n$/, '')\n }\n var contentLen = footnoteContent.length\n while (contentLen > 0) {\n var lastChar = footnoteContent[contentLen - 1]\n if (lastChar === '\\n' || lastChar === ' ') {\n contentLen--\n } else {\n break\n }\n }\n if (contentLen < footnoteContent.length) {\n footnoteContent = footnoteContent.slice(0, contentLen)\n }\n\n return {\n endPos: contentEnd,\n target: footnoteContent,\n title: undefined,\n }\n}\n\nexport function parseDefinition(\n source: string,\n pos: number,\n state: MarkdownToJSX.State,\n options: ParseOptions,\n isFootnote: boolean\n): ParseResult | null {\n if (source[pos] !== '[') return null\n var hasCaret = pos + 1 < source.length && source[pos + 1] === '^'\n if (isFootnote ? !hasCaret : hasCaret) return null\n\n var lineStart = pos\n while (lineStart > 0 && source[lineStart - 1] !== '\\n') lineStart--\n if (\n calculateIndent(source, lineStart, pos).spaceEquivalent >= 4 ||\n state.inline\n )\n return null\n\n var labelStart = pos + (isFootnote ? 2 : 1)\n var len = source.length\n var refEnd = findUnescapedChar(source, labelStart, len, ']')\n if (refEnd === -1) return null\n var ref = source.slice(labelStart, refEnd)\n if (ref.length > 999) return null\n\n var hasNonWhitespace = false,\n hasUnescapedBracket = false,\n labelHasNewlines = false\n for (var j = 0; j < ref.length; j++) {\n var c = ref[j]\n if (c === '\\\\' && j + 1 < ref.length) {\n j++\n continue\n }\n var cCode = charCode(c)\n if (cCode === $.CHAR_BRACKET_OPEN || cCode === $.CHAR_BRACKET_CLOSE) {\n hasUnescapedBracket = true\n } else if (cCode === $.CHAR_NEWLINE || cCode === $.CHAR_CR) {\n labelHasNewlines = true\n } else if (cCode !== $.CHAR_SPACE && cCode !== $.CHAR_TAB) {\n hasNonWhitespace = true\n }\n }\n if (!hasNonWhitespace || hasUnescapedBracket) return null\n\n var i = refEnd + 1\n if (labelHasNewlines) {\n var labelStartCode = charCode(source, labelStart)\n var refEndPrevCode = charCode(source, refEnd - 1)\n if (\n labelStartCode === $.CHAR_NEWLINE ||\n labelStartCode === $.CHAR_CR ||\n refEndPrevCode === $.CHAR_NEWLINE ||\n refEndPrevCode === $.CHAR_CR ||\n i >= len ||\n source[i] !== ':'\n )\n return null\n } else {\n if (i >= len || source[i] !== ':') {\n i = util.skipWhitespace(source, i)\n if (i < len && charCode(source, i) === $.CHAR_NEWLINE)\n i = util.skipWhitespace(source, i + 1)\n if (i >= len || source[i] !== ':') return null\n }\n }\n i++\n\n var urlNewlineCount = 0\n while (i < len) {\n var iCode = charCode(source, i)\n if (iCode === $.CHAR_NEWLINE) {\n if (++urlNewlineCount > 1) break\n i = util.skipWhitespace(source, i + 1)\n } else if (iCode === $.CHAR_SPACE || iCode === $.CHAR_TAB) {\n i++\n } else {\n break\n }\n }\n\n const contentResult = isFootnote\n ? parseFootnoteContent(source, i)\n : parseRefContent(source, i, urlNewlineCount)\n if (!contentResult) return null\n\n const normalizedRef = normalizeReferenceLabel(ref)\n const refs = state.refs || {}\n const storageKey = isFootnote ? `^${normalizedRef}` : normalizedRef\n if (!refs[storageKey]) {\n refs[storageKey] = {\n target: unescapeUrlOrTitle(contentResult.target.trim()),\n title: contentResult.title\n ? unescapeUrlOrTitle(contentResult.title)\n : undefined,\n }\n state.refs = refs\n }\n\n return {\n type: isFootnote ? RuleType.footnote : RuleType.ref,\n endPos: contentResult.endPos,\n } as (MarkdownToJSX.ReferenceNode | MarkdownToJSX.FootnoteNode) & {\n endPos: number\n }\n}\n\n// Delimiter stack entry for CommonMark spec delimiter stack algorithm\ninterface DelimiterEntry {\n nodeIndex: number // Index in result array where this delimiter text node is\n type: '*' | '_' | '~' | '='\n length: number // Number of delimiters in the run\n canOpen: boolean // Whether this delimiter can open emphasis\n canClose: boolean // Whether this delimiter can close emphasis\n active: boolean // Whether this delimiter is active\n sourcePos: number // Source position where this delimiter starts (for overlap detection)\n inAnchor: boolean // Whether this delimiter was collected inside a link (should not match with delimiters outside)\n}\n\n// Process emphasis using delimiter stack algorithm per CommonMark spec\nfunction processEmphasis(\n nodes: MarkdownToJSX.ASTNode[],\n delimiterStack: DelimiterEntry[],\n stackBottom: number | null\n): void {\n // openers_bottom for each delimiter type, indexed by numeric key: typeCode * 6 + (length % 3) * 2 + (canOpen ? 1 : 0)\n // Type codes: '*' = 0, '_' = 1, '~' = 2, '=' = 3\n var openersBottom: number[] = []\n\n var currentPosition = stackBottom === null ? 0 : stackBottom + 1\n\n while (currentPosition < delimiterStack.length) {\n var closer = delimiterStack[currentPosition]\n if (\n !closer ||\n (closer.type !== '*' &&\n closer.type !== '_' &&\n closer.type !== '~' &&\n closer.type !== '=')\n ) {\n currentPosition++\n continue\n }\n\n if (!closer.canClose || !closer.active) {\n currentPosition++\n continue\n }\n\n // Convert type to numeric code: '*' = 0, '_' = 1, '~' = 2, '=' = 3\n var typeCode =\n closer.type === '*'\n ? 0\n : closer.type === '_'\n ? 1\n : closer.type === '~'\n ? 2\n : 3\n var openersBottomKey =\n typeCode * 6 + (closer.length % 3) * 2 + (closer.canOpen ? 1 : 0)\n var openersBottomIndex =\n openersBottom[openersBottomKey] !== undefined\n ? openersBottom[openersBottomKey]\n : stackBottom === null\n ? -1\n : stackBottom\n\n var openerIndex = -1\n var closerType = closer.type\n var closerInAnchor = closer.inAnchor\n var closerCanOpen = closer.canOpen\n var closerLength = closer.length\n var closerLengthMod3 = closerLength % 3\n\n for (var i = currentPosition - 1; i > openersBottomIndex; i--) {\n var candidate = delimiterStack[i]\n if (\n !candidate ||\n !candidate.active ||\n candidate.type !== closerType ||\n !candidate.canOpen ||\n candidate.inAnchor !== closerInAnchor\n )\n continue\n var openerLength = candidate.length\n if (\n (!closerCanOpen && !candidate.canClose) ||\n closerLengthMod3 === 0 ||\n (openerLength + closerLength) % 3 !== 0\n ) {\n openerIndex = i\n break\n }\n }\n\n if (openerIndex >= 0) {\n var opener = delimiterStack[openerIndex]\n var openerLength = opener.length\n\n // Determine if emphasis or strong emphasis (both must have length >= 2 for strong)\n var isStrong = openerLength >= 2 && closerLength >= 2\n var delimitersToRemove = isStrong ? 2 : 1\n if (\n delimitersToRemove > openerLength ||\n delimitersToRemove > closerLength\n ) {\n currentPosition++\n continue\n }\n\n var openerNodeIndex = opener.nodeIndex\n var closerNodeIndex = closer.nodeIndex\n var contentStartIndex = openerNodeIndex + 1\n var contentEndIndex = closerNodeIndex\n var contentNodes = nodes.slice(contentStartIndex, contentEndIndex)\n\n // Remove content nodes from nodes array (they'll be in the emphasis node)\n if (contentNodes.length > 0) {\n var nodesRemoved = contentEndIndex - contentStartIndex\n nodes.splice(contentStartIndex, nodesRemoved)\n for (var k = 0; k < delimiterStack.length; k++) {\n if (delimiterStack[k].nodeIndex > contentStartIndex)\n delimiterStack[k].nodeIndex -= nodesRemoved\n }\n if (closerNodeIndex > contentStartIndex) closerNodeIndex -= nodesRemoved\n }\n\n var emphasisTag =\n opener.type === '~'\n ? 'del'\n : opener.type === '='\n ? 'mark'\n : isStrong\n ? 'strong'\n : 'em'\n var emphasisNode: MarkdownToJSX.FormattedTextNode = {\n type: RuleType.textFormatted,\n tag: emphasisTag,\n children: contentNodes,\n }\n\n var openerNode = nodes[openerNodeIndex] as MarkdownToJSX.TextNode\n if (!openerNode || !openerNode.text) {\n opener.active = closer.active = false\n continue\n }\n\n // Remove delimiters from opener text node\n var openerRemoved = openerNode.text.length <= delimitersToRemove\n if (openerRemoved) {\n nodes.splice(openerNodeIndex, 1)\n for (var k = 0; k < delimiterStack.length; k++) {\n if (delimiterStack[k].nodeIndex > openerNodeIndex)\n delimiterStack[k].nodeIndex--\n }\n if (closerNodeIndex > openerNodeIndex) closerNodeIndex--\n } else {\n openerNode.text = openerNode.text.slice(delimitersToRemove)\n }\n\n var closerNode = nodes[closerNodeIndex] as MarkdownToJSX.TextNode\n if (!closerNode || !closerNode.text) {\n opener.active = closer.active = false\n continue\n }\n var closerRemoved = closerNode.text.length <= delimitersToRemove\n if (closerRemoved) {\n nodes.splice(closerNodeIndex, 1)\n for (var k = 0; k < delimiterStack.length; k++) {\n if (delimiterStack[k].nodeIndex > closerNodeIndex)\n delimiterStack[k].nodeIndex--\n }\n } else {\n closerNode.text = closerNode.text.slice(delimitersToRemove)\n }\n\n // Insert emphasis node after opener (or at the position where opener was)\n var insertIndex = openerRemoved\n ? openerNodeIndex < closerNodeIndex\n ? closerNodeIndex - 1\n : openerNodeIndex\n : openerNodeIndex + 1\n if (insertIndex < 0 || insertIndex > nodes.length)\n insertIndex = insertIndex < 0 ? 0 : nodes.length\n nodes.splice(insertIndex, 0, emphasisNode)\n\n // Update node indices in delimiter stack after insertion\n for (var k = 0; k < delimiterStack.length; k++) {\n if (delimiterStack[k].nodeIndex >= insertIndex) {\n delimiterStack[k].nodeIndex++\n }\n }\n\n // Remove delimiters between opener and closer from stack\n for (var k = openerIndex + 1; k < currentPosition; k++) {\n delimiterStack[k].active = false\n }\n\n // Update opener and closer in stack\n if (openerRemoved) {\n opener.active = false\n } else {\n opener.length -= delimitersToRemove\n if (opener.length === 0) opener.active = false\n }\n\n if (closerRemoved) {\n closer.active = false\n currentPosition++\n } else {\n closer.length -= delimitersToRemove\n if (closer.length === 0) {\n closer.active = false\n currentPosition++\n }\n }\n } else {\n // No opener found\n openersBottom[openersBottomKey] = currentPosition - 1\n if (!closer.canOpen) {\n closer.active = false\n }\n currentPosition++\n }\n }\n\n // Remove inactive delimiters from stack (O(n) shift algorithm instead of O(n²) splice)\n var writeIndex = 0\n for (var i = 0; i < delimiterStack.length; i++) {\n if (delimiterStack[i].active) {\n delimiterStack[writeIndex++] = delimiterStack[i]\n }\n }\n delimiterStack.length = writeIndex\n}\n\nexport function parseMarkdown(\n input: string,\n state: MarkdownToJSX.State,\n options: ParseOptions\n): MarkdownToJSX.ASTNode[] {\n var result: MarkdownToJSX.ASTNode[] = []\n var pos = 0\n var REF_CHECK_UNSET = -3\n var cachedRefCheckPos = REF_CHECK_UNSET\n\n // If inline mode, just parse the entire input as inline content\n if (state.inline)\n return parseInlineSpan(input, 0, input.length, state, options)\n\n // Block parsing mode\n\n // Check for frontmatter at the beginning (skip if doesn't start with ---)\n if (pos === 0 && input.startsWith('---')) {\n var frontmatterResult = parseFrontmatter(input, pos)\n if (frontmatterResult) {\n result.push(frontmatterResult)\n pos = frontmatterResult.endPos\n }\n }\n\n while (pos < input.length) {\n // Skip leading newlines (but preserve whitespace for indented code blocks)\n while (pos < input.length && input[pos] === '\\n') {\n pos++\n }\n\n if (pos >= input.length) break\n cachedRefCheckPos = REF_CHECK_UNSET\n\n const char = input[pos]\n\n // Try parseBlock first (handles indentation and tries all block parsers)\n // Note: Individual parsers called by parseBlock track their own attempts\n const parseResult = parseBlock(input, pos, state, options)\n if (parseResult) {\n const t = parseResult.type\n if (t === RuleType.codeBlock) {\n var isFenced = char === '`' || char === '~'\n if (!isFenced && (char === ' ' || char === '\\t')) {\n const lineEnd = util.findLineEnd(input, pos)\n const indentInfo = calculateIndent(input, pos, lineEnd)\n isFenced =\n indentInfo.spaceEquivalent <= 3 &&\n pos + indentInfo.charCount < input.length &&\n (input[pos + indentInfo.charCount] === '`' ||\n input[pos + indentInfo.charCount] === '~')\n }\n } else if (t === RuleType.breakThematic) {} else if (t === RuleType.blockQuote) {} else if (t === RuleType.heading) {} else if (t === RuleType.orderedList || t === RuleType.unorderedList) {} else if (t === RuleType.table) {} else if (t === RuleType.htmlComment) {} else if (t === RuleType.htmlBlock) {} else if (t === RuleType.ref) {}\n\n // Special handling for HTML comments with trailing content\n if (parseResult.type === RuleType.htmlComment) {\n result.push(parseResult)\n const htmlCheckPos = pos\n pos = parseResult.endPos\n\n // Per CommonMark spec Example 177: HTML comment blocks end at --> on the same line\n // If there's content after --> on the same line, it should be treated as literal text\n const commentLineEnd = util.findLineEnd(input, htmlCheckPos)\n if (pos < commentLineEnd) {\n const textContent = input.slice(pos, commentLineEnd)\n if (textContent.trim().length > 0) {\n result.push({\n type: RuleType.text,\n text: textContent,\n } as MarkdownToJSX.TextNode)\n }\n pos = commentLineEnd\n if (pos < input.length && input[pos] === '\\n') {\n pos++\n }\n }\n continue\n }\n // Special handling for HTML self-closing closing tags\n if (\n parseResult.type === RuleType.htmlBlock ||\n parseResult.type === RuleType.htmlSelfClosing\n ) {\n const isSelfClosingClosingTag =\n parseResult.type === RuleType.htmlSelfClosing &&\n parseResult.isClosingTag === true\n if (isSelfClosingClosingTag && !state.inline && !state.inHTML) {\n // Don't match, fall through to other parsers\n } else {\n result.push(parseResult)\n pos = parseResult.endPos\n continue\n }\n } else {\n result.push(parseResult)\n pos = parseResult.endPos\n continue\n }\n }\n\n // Reference definition - check BEFORE setext heading to prevent conflicts\n // Reference definitions take precedence over setext headings (e.g., [foo]: /url\\n===)\n let refCheckPos =\n cachedRefCheckPos !== REF_CHECK_UNSET ? cachedRefCheckPos : pos\n if (cachedRefCheckPos === REF_CHECK_UNSET) {\n if (isSpaceOrTab(char)) {\n const lineEnd = util.findLineEnd(input, pos)\n const indentInfo = calculateIndent(input, pos, lineEnd)\n const checkPos = pos + indentInfo.charCount\n if (\n indentInfo.spaceEquivalent <= 3 &&\n checkPos < input.length &&\n input[checkPos] === '['\n ) {\n refCheckPos = checkPos\n } else {\n refCheckPos = -1\n }\n } else if (char === '[') {\n refCheckPos = pos\n } else {\n refCheckPos = -1\n }\n cachedRefCheckPos = refCheckPos\n }\n\n if (\n refCheckPos >= 0 &&\n refCheckPos + 1 < input.length &&\n input[refCheckPos + 1] === '^'\n ) {\n refCheckPos = -1\n }\n\n if (refCheckPos >= 0) {\n const parseResult = parseDefinition(\n input,\n refCheckPos,\n state,\n options,\n false\n )\n if (parseResult) {\n result.push(parseResult)\n pos = parseResult.endPos\n continue\n }\n // parseDefinition returned null - check if this is an invalid reference definition that should be skipped\n // Per CommonMark Examples 208 and 210: certain invalid reference definitions should be skipped entirely\n const skipResult = shouldSkipInvalidReferenceDefinition(\n input,\n refCheckPos,\n pos === 0\n )\n if (skipResult.shouldSkip) {\n pos = skipResult.newPos\n continue\n }\n }\n\n // Heading (Setext style) - check after reference definitions\n const setextResult = parseHeadingSetext(input, pos, state, options)\n if (setextResult) {\n result.push(setextResult)\n pos = setextResult.endPos\n continue\n }\n\n // Footnote definition (skip leading whitespace)\n let footnoteCheckPos = pos\n if (isSpaceOrTab(input[footnoteCheckPos])) {\n const lineEnd = util.findLineEnd(input, pos)\n const indentInfo = calculateIndent(input, pos, lineEnd)\n footnoteCheckPos = pos + indentInfo.charCount\n }\n if (\n footnoteCheckPos < input.length &&\n input[footnoteCheckPos] === '[' &&\n footnoteCheckPos + 1 < input.length &&\n input[footnoteCheckPos + 1] === '^'\n ) {\n const footnoteResult = parseDefinition(\n input,\n footnoteCheckPos,\n state,\n options,\n true\n )\n if (footnoteResult) {\n pos = footnoteResult.endPos\n continue\n }\n }\n\n const paragraphResult = parseParagraph(input, pos, state, options)\n if (paragraphResult) {\n result.push(paragraphResult)\n pos = paragraphResult.endPos\n continue\n }\n\n pos++\n }\n\n // Note: Memory snapshot \"After block parsing\" is taken in compiler function\n // after parseMarkdown returns, not here\n\n // Footnotes footer is appended during rendering phase (not in AST)\n // Footnotes are stored in refs with '^' prefix and extracted during rendering\n\n // Collect all refs from state.refs (populated during parsing) and create a reference collection node\n // Reference nodes stay in their original positions, but we prepend a collection node\n // Include footnotes (keys starting with '^') so the renderer can handle them\n const allRefs = state.refs || {}\n const collectedRefs: {\n [key: string]: { target: string; title: string | undefined }\n } = {}\n for (const key in allRefs) {\n collectedRefs[key] = allRefs[key]\n }\n\n // Prepend reference collection node if we have any refs\n if (util.hasKeys(collectedRefs)) {\n const refCollectionNode: MarkdownToJSX.ReferenceCollectionNode = {\n type: RuleType.refCollection,\n refs: collectedRefs,\n }\n return [refCollectionNode, ...result]\n }\n\n return result\n}\n\nexport function collectReferenceDefinitions(\n input: string,\n refs: { [key: string]: { target: string; title: string | undefined } },\n options: ParseOptions\n): void {\n var pos = 0\n var canStartRef = true\n const len = input.length\n\n while (pos < len) {\n var newlines = 0\n // Count consecutive newlines more efficiently\n while (pos < len && charCode(input, pos) === $.CHAR_NEWLINE) {\n newlines++\n pos++\n }\n if (pos >= len) break\n if (newlines > 0) canStartRef = true\n\n // Skip fenced code\n const currentCharCode = charCode(input, pos)\n if (\n currentCharCode === $.CHAR_BACKTICK ||\n currentCharCode === $.CHAR_TILDE\n ) {\n var fence = parseCodeFenced(input, pos, { inline: false }, options)\n if (fence) {\n pos = fence.endPos\n canStartRef = true\n continue\n }\n }\n\n // Try parse ref (up to 3 space indent)\n var refPos = pos\n var indent = 0\n while (refPos < len && indent < 4) {\n const code = charCode(input, refPos)\n if (code === $.CHAR_SPACE) {\n indent++\n refPos++\n } else if (code === $.CHAR_TAB) {\n indent += 4 - (indent % 4)\n refPos++\n } else {\n break\n }\n }\n\n if (\n indent < 4 &&\n refPos < len &&\n charCode(input, refPos) === $.CHAR_BRACKET_OPEN &&\n canStartRef\n ) {\n if (refPos + 1 < len && charCode(input, refPos + 1) === $.CHAR_CARET) {\n canStartRef = false\n var lineEnd = util.findLineEnd(input, pos)\n pos = lineEnd >= len ? len : lineEnd + 1\n continue\n } else {\n var result = parseDefinition(\n input,\n refPos,\n { inline: false, refs },\n options,\n false\n )\n if (result) {\n pos = result.endPos\n canStartRef = true\n continue\n }\n // parseDefinition returned null - check if colon exists (invalid ref attempt) vs paragraph content\n var lineEnd = util.findLineEnd(input, pos)\n var colonPos = input.indexOf(':', refPos + 1)\n if (colonPos === -1 || colonPos >= lineEnd) {\n var indentInfo = calculateIndent(input, pos, lineEnd)\n if (\n !isBlankLineCheck(input, pos, lineEnd) &&\n currentCharCode !== $.CHAR_HASH &&\n currentCharCode !== $.CHAR_GT &&\n currentCharCode !== $.CHAR_DASH &&\n currentCharCode !== $.CHAR_EQ &&\n indentInfo.spaceEquivalent < 4\n ) {\n canStartRef = false\n }\n }\n pos = lineEnd >= len ? len : lineEnd + 1\n continue\n }\n }\n\n // Scan blockquotes for nested refs\n if (currentCharCode === $.CHAR_GT && canStartRef) {\n var bqEnd = pos\n var bqLines = []\n while (bqEnd < len) {\n var lineEnd = util.findLineEnd(input, bqEnd)\n var quotePos = bqEnd\n while (quotePos < lineEnd) {\n const code = charCode(input, quotePos)\n if (code === $.CHAR_SPACE || code === $.CHAR_TAB) {\n quotePos++\n } else {\n break\n }\n }\n if (quotePos >= lineEnd || charCode(input, quotePos) !== $.CHAR_GT)\n break\n\n var contentStart = quotePos + 1\n if (\n contentStart < lineEnd &&\n (charCode(input, contentStart) === $.CHAR_SPACE ||\n charCode(input, contentStart) === $.CHAR_TAB)\n )\n contentStart++\n bqLines.push(input.slice(contentStart, lineEnd))\n bqEnd = lineEnd + 1\n }\n if (bqLines.length) {\n collectReferenceDefinitions(bqLines.join('\\n'), refs, options)\n pos = bqEnd\n canStartRef = true\n continue\n }\n }\n\n var lineEnd = util.findLineEnd(input, pos)\n if (lineEnd >= len) {\n pos = len\n } else {\n var isCurrentLineBlank = isBlankLineCheck(input, pos, lineEnd)\n var indentInfo = calculateIndent(input, pos, lineEnd)\n pos = lineEnd + 1\n canStartRef =\n currentCharCode === $.CHAR_HASH ||\n currentCharCode === $.CHAR_GT ||\n currentCharCode === $.CHAR_DASH ||\n currentCharCode === $.CHAR_EQ ||\n isCurrentLineBlank ||\n indentInfo.spaceEquivalent >= 4\n }\n }\n}\n\n/**\n * Given a markdown string, return an abstract syntax tree (AST) of the markdown.\n *\n * The first node in the AST is a reference collection node. This node contains all the\n * reference definitions found in the markdown. These reference definitions are used to\n * resolve reference links and images in the markdown.\n *\n * @param source - The markdown string to parse.\n * @param options - The options for the parser.\n * @returns The AST of the markdown.\n */\nexport function parser(\n source: string,\n options?: MarkdownToJSX.Options\n): MarkdownToJSX.ASTNode[] {\n // Default state\n const defaultState: MarkdownToJSX.State = { inline: false, refs: {} }\n const finalState = { ...defaultState }\n\n // Normalize options - convert MarkdownToJSX.Options to ParseOptions\n const finalOptions: ParseOptions = {\n ...options,\n slugify: options?.slugify\n ? (input: string) => options.slugify(input, util.slugify)\n : util.slugify,\n sanitizer: options?.sanitizer || util.sanitizer,\n tagfilter: options?.tagfilter !== false,\n }\n\n // Collect reference definitions if not in inline mode\n if (!finalState.inline) {\n collectReferenceDefinitions(source, finalState.refs || {}, finalOptions)\n }\n\n // Parse markdown\n const astNodes = parseMarkdown(source, finalState, finalOptions)\n\n return astNodes\n}\n",
|
|
10
10
|
"import { RuleType, type MarkdownToJSX } from './types'\nimport { isVoidElement, getTag, getOverrideProps } from './utils'\nimport { parser } from './parse'\n\nexport type MarkdownOverride =\n | {\n component?: string\n props?: Record<string, string | number | boolean>\n }\n | string\n\nexport type MarkdownOverrides = {\n [tag in MarkdownToJSX.HTMLTags]?: MarkdownOverride\n} & {\n [customComponent: string]: MarkdownOverride\n}\n\n/**\n * Markdown-specific compiler options that extend the main MarkdownToJSX options\n * Excludes React/HTML-specific options (createElement, wrapper, wrapperProps, forceWrapper)\n */\nexport type MarkdownCompilerOptions = Omit<\n MarkdownToJSX.Options,\n 'createElement' | 'wrapper' | 'wrapperProps' | 'forceWrapper'\n> & {\n /**\n * Whether to use reference-style links instead of inline links\n * @default false\n */\n useReferenceLinks?: boolean\n\n /**\n * Whether to use setext-style headers for level 1 and 2 headers\n * @default false\n */\n useSetextHeaders?: boolean\n\n /**\n * Allows for full control over rendering of particular rules.\n * Returns a markdown string instead of JSX.\n */\n renderRule?: (\n next: () => string,\n node: MarkdownToJSX.ASTNode,\n renderChildren: (children: MarkdownToJSX.ASTNode[]) => string,\n state: MarkdownToJSX.State\n ) => string\n\n /**\n * Override HTML tag names and add attributes for HTML blocks and self-closing tags.\n * Output is markdown string (HTML tags in markdown).\n */\n overrides?: MarkdownOverrides\n}\n\n/**\n * Compiler function that parses markdown and renders to markdown string\n * Convenience function that combines parser() and astToMarkdown()\n */\nexport function compiler(\n input: string,\n options?: MarkdownCompilerOptions\n): string {\n const ast = parser(input, options)\n return astToMarkdown(ast, options)\n}\n\nexport function astToMarkdown(\n ast: MarkdownToJSX.ASTNode | MarkdownToJSX.ASTNode[],\n options?: MarkdownCompilerOptions\n): string {\n const nodes = Array.isArray(ast) ? ast : [ast]\n var overrides = options?.overrides || {}\n\n // Extract refs from reference collection node\n var refs: { [key: string]: { target: string; title: string | undefined } } =\n {}\n var nonRefCollectionNodes: MarkdownToJSX.ASTNode[] = []\n var foundRefCollection = false\n\n for (var i = 0; i < nodes.length; i++) {\n var node = nodes[i]\n if (node.type === RuleType.refCollection && !foundRefCollection) {\n refs = (node as MarkdownToJSX.ReferenceCollectionNode).refs || {}\n foundRefCollection = true\n nonRefCollectionNodes.push(node)\n } else if (\n node.type !== RuleType.footnote &&\n node.type !== RuleType.ref &&\n (node.type !== RuleType.frontmatter || options?.preserveFrontmatter !== false)\n ) {\n nonRefCollectionNodes.push(node)\n }\n }\n\n const state: CompilerState = {\n options: options || {},\n references: new Map(),\n referenceIndex: 1,\n overrides,\n }\n\n function renderChildren(children: MarkdownToJSX.ASTNode[]): string {\n // For inline content (like paragraph children), render without block separators\n return children.map(child => compileNode(child, state)).join('')\n }\n\n function renderNodeWithRule(\n node: MarkdownToJSX.ASTNode,\n stateWithKey: MarkdownToJSX.State = {}\n ): string {\n if (!node || typeof node !== 'object') return ''\n if (\n node.type === RuleType.ref ||\n node.type === RuleType.footnote ||\n (node.type === RuleType.frontmatter && options?.preserveFrontmatter === false)\n ) return ''\n\n if (options?.renderRule) {\n return options.renderRule(\n () => compileNode(node, state),\n node,\n renderChildren,\n stateWithKey\n )\n }\n\n return compileNode(node, state)\n }\n\n // Filter out refCollection from nodes that get keys (it's rendered separately)\n const renderableNodes = nonRefCollectionNodes.filter(\n node => node.type !== RuleType.refCollection\n )\n const content = nonRefCollectionNodes\n .map((node, i) => {\n // Only assign keys to renderable nodes (exclude refCollection from key counting)\n const keyIndex =\n node.type === RuleType.refCollection\n ? undefined\n : renderableNodes.indexOf(node)\n return renderNodeWithRule(node, { key: keyIndex, refs })\n })\n .join('\\n\\n')\n\n if (state.options.useReferenceLinks && state.references.size > 0) {\n const references = Array.from(state.references.entries())\n .map(([key, { url, title }]) =>\n title ? `[${key}]: ${url} \"${title}\"` : `[${key}]: ${url}`\n )\n .join('\\n')\n return content + '\\n\\n' + references\n }\n\n return content\n}\n\n// Alias for backwards compatibility\nexport const markdown: typeof astToMarkdown = astToMarkdown\n\n/**\n * Internal compiler state\n */\ninterface CompilerState {\n options: MarkdownCompilerOptions\n references: Map<string, { url: string; title?: string }>\n referenceIndex: number\n overrides?: MarkdownOverrides\n}\n\n/**\n * Compile a single AST node to markdown\n */\nfunction compileNode(\n node: MarkdownToJSX.ASTNode,\n state: CompilerState\n): string {\n switch (node.type) {\n case RuleType.text:\n return compileText(node)\n\n case RuleType.paragraph:\n return compileParagraph(node, state)\n\n case RuleType.heading:\n return compileHeading(node, state)\n\n case RuleType.breakThematic:\n return compileBreakThematic(node)\n\n case RuleType.breakLine:\n return compileBreakLine(node)\n\n case RuleType.codeBlock:\n return compileCodeBlock(node)\n\n case RuleType.codeInline:\n return compileCodeInline(node)\n\n case RuleType.textFormatted:\n return compileTextFormatted(node, state)\n\n case RuleType.link:\n return compileLink(node, state)\n\n case RuleType.image:\n return compileImage(node, state)\n\n case RuleType.orderedList:\n return compileOrderedList(node, state)\n\n case RuleType.unorderedList:\n return compileUnorderedList(node, state)\n\n case RuleType.blockQuote:\n return compileBlockQuote(node, state)\n\n case RuleType.table:\n return compileTable(node, state)\n\n case RuleType.htmlBlock:\n return compileHTMLBlock(node, state)\n\n case RuleType.htmlSelfClosing:\n return compileHTMLSelfClosing(node, state)\n\n case RuleType.htmlComment:\n return compileHTMLComment(node)\n\n case RuleType.footnote:\n return compileFootnote(node)\n\n case RuleType.footnoteReference:\n return compileFootnoteReference(node)\n\n case RuleType.frontmatter:\n return compileFrontmatter(node)\n\n case RuleType.gfmTask:\n return compileGFMTask(node)\n\n case RuleType.ref:\n return compileReference(node)\n\n case RuleType.refCollection:\n return compileReferenceCollection(node)\n\n default:\n // Unknown node type, return empty string\n return ''\n }\n}\n\nfunction compileText(node: MarkdownToJSX.TextNode): string {\n return node.text\n}\n\nfunction compileParagraph(\n node: MarkdownToJSX.ParagraphNode,\n state: CompilerState\n): string {\n return node.children.map(child => compileNode(child, state)).join('')\n}\n\nfunction compileHeading(\n node: MarkdownToJSX.HeadingNode,\n state: CompilerState\n): string {\n const content = node.children.map(child => compileNode(child, state)).join('')\n\n if (\n state.options.useSetextHeaders &&\n (node.level === 1 || node.level === 2)\n ) {\n return `${content}\\n${(node.level === 1 ? '=' : '-').repeat(content.length)}`\n }\n\n return `${'#'.repeat(node.level)}${state.options.enforceAtxHeadings !== false ? ' ' : ''}${content}`\n}\n\nfunction compileBreakThematic(_node: MarkdownToJSX.BreakThematicNode): string {\n return '---'\n}\n\nfunction compileBreakLine(_node: MarkdownToJSX.BreakLineNode): string {\n return ' \\n'\n}\n\nfunction compileCodeBlock(node: MarkdownToJSX.CodeBlockNode): string {\n return `${node.lang ? `\\`\\`\\`${node.lang}\\n` : '```\\n'}${node.text}\\n\\`\\`\\``\n}\n\nfunction compileCodeInline(node: MarkdownToJSX.CodeInlineNode): string {\n return node.text.indexOf('`') !== -1\n ? `\\`\\`${node.text}\\`\\``\n : `\\`${node.text}\\``\n}\n\nfunction compileTextFormatted(\n node: MarkdownToJSX.FormattedTextNode,\n state: CompilerState\n): string {\n const content = node.children.map(child => compileNode(child, state)).join('')\n switch (node.tag) {\n case 'em':\n case 'i':\n return `*${content}*`\n case 'strong':\n case 'b':\n return `**${content}**`\n case 'del':\n case 's':\n return `~~${content}~~`\n case 'code':\n return compileCodeInline({ type: RuleType.codeInline, text: content })\n default:\n return content\n }\n}\n\nfunction compileLink(\n node: MarkdownToJSX.LinkNode,\n state: CompilerState\n): string {\n const text = node.children.map(child => compileNode(child, state)).join('')\n const url = node.target || ''\n const title = node.title\n\n if (state.options.useReferenceLinks) {\n const refKey = generateReferenceKey(url, state)\n if (!state.references.has(refKey)) {\n state.references.set(refKey, { url, title })\n }\n return `[${text}][${refKey}]`\n }\n\n return title ? `[${text}](${url} \"${title}\")` : `[${text}](${url})`\n}\n\nfunction compileImage(\n node: MarkdownToJSX.ImageNode,\n state: CompilerState\n): string {\n const alt = node.alt || ''\n const url = node.target\n const title = node.title\n\n if (state.options.useReferenceLinks) {\n const refKey = generateReferenceKey(url, state)\n if (!state.references.has(refKey)) {\n state.references.set(refKey, { url, title })\n }\n return `![${alt}][${refKey}]`\n }\n\n return title ? `` : ``\n}\n\nfunction compileOrderedList(\n node: MarkdownToJSX.OrderedListNode,\n state: CompilerState\n): string {\n const start = node.start || 1\n return node.items\n .map((item, index) => {\n const content = item.map(child => compileNode(child, state)).join('')\n return `${start + index}. ${content.replace(/\\n/g, '\\n ')}`\n })\n .join('\\n')\n}\n\nfunction compileUnorderedList(\n node: MarkdownToJSX.UnorderedListNode,\n state: CompilerState\n): string {\n return node.items\n .map(item => {\n const content = item.map(child => compileNode(child, state)).join('')\n return `- ${content.replace(/\\n/g, '\\n ')}`\n })\n .join('\\n')\n}\n\nfunction compileBlockQuote(\n node: MarkdownToJSX.BlockQuoteNode,\n state: CompilerState\n): string {\n return node.children\n .map(child => compileNode(child, state))\n .join('\\n\\n')\n .split('\\n')\n .map(line => (line.trim() ? `> ${line}` : '>'))\n .join('\\n')\n}\n\nfunction compileTable(\n node: MarkdownToJSX.TableNode,\n state: CompilerState\n): string {\n const headerRow = node.header\n .map(cell => cell.map(child => compileNode(child, state)).join(''))\n .join(' | ')\n\n const finalSeparator =\n node.align.length > 0\n ? node.align\n .map(align => {\n if (align === 'left') return ':---'\n if (align === 'right') return '---:'\n if (align === 'center') return ':---:'\n return '---'\n })\n .join('|')\n : Array(node.header.length).fill('---').join('|')\n\n const dataRows = node.cells\n .map(row =>\n row\n .map(cell => cell.map(child => compileNode(child, state)).join(''))\n .join(' | ')\n )\n .join('\\n')\n\n return `${headerRow}\\n${finalSeparator}\\n${dataRows}`\n}\n\nfunction compileHTMLBlock(\n node: MarkdownToJSX.HTMLNode,\n state: CompilerState\n): string {\n const defaultTag = node.tag || 'div'\n const tag = getTag(defaultTag, state.overrides)\n const overrideProps = getOverrideProps(defaultTag, state.overrides)\n const mergedAttrs = { ...(node.attrs || {}), ...overrideProps }\n const attrs = compileAttributes(mergedAttrs)\n\n // Check if this is a void element (self-closing)\n const isVoid = isVoidElement(tag)\n\n if (node.text) {\n // For HTML blocks with raw text content\n // node.text already includes the closing tag\n return `<${tag}${attrs}>${node.text}`\n }\n\n // For HTML blocks with children, reconstruct the HTML\n const content = node.children\n ? `\\n${node.children.map(child => compileNode(child, state)).join('\\n')}\\n`\n : ''\n const closingTag = isVoid ? '' : `</${tag}>`\n return `<${tag}${attrs}>${content}${closingTag}`\n}\n\n/**\n * Compile self-closing HTML tag\n */\nfunction compileHTMLSelfClosing(\n node: MarkdownToJSX.HTMLSelfClosingNode,\n state: CompilerState\n): string {\n const defaultTag = node.tag || 'div'\n const tag = getTag(defaultTag, state.overrides)\n const overrideProps = getOverrideProps(defaultTag, state.overrides)\n const mergedAttrs = { ...(node.attrs || {}), ...overrideProps }\n const attrs = compileAttributes(mergedAttrs)\n return `<${tag}${attrs} />`\n}\n\nfunction compileHTMLComment(node: MarkdownToJSX.HTMLCommentNode): string {\n return `<!--${node.text}-->`\n}\n\nfunction compileFootnote(_node: MarkdownToJSX.FootnoteNode): string {\n return ''\n}\n\nfunction compileFootnoteReference(\n node: MarkdownToJSX.FootnoteReferenceNode\n): string {\n return `[^${node.text}]`\n}\n\nfunction compileFrontmatter(node: MarkdownToJSX.FrontmatterNode): string {\n return `---\\n${node.text}\\n---`\n}\n\nfunction compileGFMTask(node: MarkdownToJSX.GFMTaskNode): string {\n return node.completed ? '[x]' : '[ ]'\n}\n\nfunction compileReference(_node: MarkdownToJSX.ReferenceNode): string {\n return ''\n}\n\nfunction compileReferenceCollection(\n node: MarkdownToJSX.ReferenceCollectionNode\n): string {\n return Object.entries(node.refs)\n .map(([key, { target, title }]) =>\n title ? `[${key}]: ${target} \"${title}\"` : `[${key}]: ${target}`\n )\n .join('\\n')\n}\n\nfunction generateReferenceKey(url: string, state: CompilerState): string {\n return `ref${state.referenceIndex++}`\n}\n\nfunction compileAttributes(attrs: Record<string, any>): string {\n return Object.entries(attrs || {})\n .map(([key, value]) =>\n typeof value === 'boolean'\n ? value\n ? ` ${key}`\n : ''\n : ` ${key}=\"${String(value).replace(/\"/g, '"')}\"`\n )\n .join('')\n}\n"
|
|
11
11
|
],
|
|
12
|
-
"mappings": "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",
|
|
13
|
-
"debugId": "
|
|
12
|
+
"mappings": "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",
|
|
13
|
+
"debugId": "E4FA2BFD3E543C0C64756E2164756E21",
|
|
14
14
|
"names": []
|
|
15
15
|
}
|