{"version":3,"sources":["webpack:///./node_modules/html-to-text/lib/stack-item.js","webpack:///./node_modules/html-to-text/lib/helper.js","webpack:///./node_modules/html-to-text/lib/table-printer.js","webpack:///./node_modules/html-to-text/lib/whitespace-processor.js","webpack:///./node_modules/html-to-text/lib/block-text-builder.js","webpack:///./node_modules/html-to-text/lib/inline-text-builder.js","webpack:///./node_modules/html-to-text/index.js","webpack:///./node_modules/html-to-text/lib/html-to-text.js","webpack:///./node_modules/html-to-text/lib/formatter.js"],"names":["InlineTextBuilder","StackItem","next","this","BlockStackItem","options","leadingLineBreaks","maxLineLength","super","inlineTextBuilder","rawText","stashedLineBreaks","isPre","TableStackItem","rows","TableRowStackItem","cells","TableCellStackItem","maxColumnWidth","TransformerStackItem","transform","module","exports","merge","splitClassesAndIds","selectors","classes","ids","selector","startsWith","push","substring","limitedDepthRecursive","n","f","g","undefined","f1","args","numberToLetterSequence","num","baseChar","base","digits","baseCode","charCodeAt","reverse","map","String","fromCharCode","join","I","V","numberToRoman","v","i","repeat","trimCharacter","str","char","start","end","length","get","obj","path","key","set","value","valueKey","pop","nested","mergeDuplicatesPreferLast","items","getKey","Map","item","has","arrayMerge","overwriteMerge","values","acc","src","getRow","matrix","j","findFirstVacantIndex","row","x","transposeInPlace","maxSize","rowI","rowJ","temp","putCellIntoLayout","cell","layout","baseRow","baseCol","r","rowspan","layoutRow","c","colspan","updateOffset","offsets","span","Math","max","tableToString","tableRows","rowSpacing","colSpacing","colNumber","rowNumber","rowOffsets","lines","text","split","cellHeight","outputLines","colOffsets","y","rendered","cellWidth","line","lineOffset","padEnd","charactersToCodes","toString","padStart","WhitespaceProcessor","whitespaceChars","whitespaceCharacters","replace","whitespaceCodes","leadingWhitespaceRe","RegExp","trailingWhitespaceRe","allWhitespaceOrEmptyRe","preserveNewlines","wordOrNewlineRe","shrinkWrapAdd","previouslyStashedSpace","stashedSpace","anyMatch","m","exec","startNewLine","testLeadingWhitespace","pushWord","concatWord","testTrailingWhitespace","wordRe","test","Picker","BlockTextBuilder","picker","whitepaceProcessor","_stackItem","_wordTransformer","wordTransform","applyTransformer","transformer","wordBreakOpportunity","optionsObjectOrNoWordTransform","_addInline","noWordTransform","testContainsWords","_getCombinedWordTransformer","optionsObjectOrLeadingLineBreaks","reservedLineLength","_openBlock","optionsObjectOrTrailingLineBreaks","blockTransform","_closeBlock","trailingLineBreaks","block","_popStackItem","blockText","getText","addText","Error","optionsObjectOrMaxColumnWidth","_openTableCell","optionsObjectOrColspan","_closeTableCell","optionsObjectOrColSpacing","_closeTable","table","output","getRoot","stackItem","isEmpty","parentText","lineBreaks","clear","nextLineWords","wordwrap","Number","MAX_VALUE","nextLineAvailableChars","wrapCharacters","longWordSplit","forceWrapOnLimit","word","isLineStart","cost","first","rest","splitLongWord","part","lastWord","popWord","concat","Array","from","words","parts","idx","firstLine","remainingChars","splitIndex","lastIndexOf","hp2Builder","he","htmlparser","selderee","defaultFormatters","DEFAULT_OPTIONS","baseElements","orderBy","returnDomByDefault","decodeOptions","isAttributeValue","strict","formatters","limits","ellipsis","maxBaseElements","maxChildNodes","maxDepth","maxInputLength","format","baseUrl","hideLinkHrefIfSameAsText","ignoreHref","noAnchorUrl","noLinkBrackets","trimEmptyLines","uppercase","uppercaseHeaderCells","itemPrefix","tables","concatMerge","selectorsMerge","some","s","compile","customMerge","Object","assign","handleDeprecatedOptions","uniqueSelectors","selectorsWithoutFormat","filter","DecisionTree","build","baseSelectorsPicker","findBaseElements","dom","findBases","limitedWalk","recursiveWalk","builder","addInline","html","process","walk","console","warn","handler","DomHandler","Parser","decodeEntities","parseComplete","bases","convert","selectorDefinitions","tags","tagDefinitions","entries","definition","copyFormatterOption","source","target","baseElement","isArray","results","slice","elem","type","pickedSelectorIndex","pick1","selectorIndex","element","children","sort","a","b","tooManyChildNodes","data","decode","tagDefinition","fromString","htmlToText","formatSkip","formatOptions","formatInline","formatBlock","openBlock","closeBlock","formatLineBreak","addLineBreak","formatWbr","addWordBreakOpportunity","formatHorizontalLine","formatParagraph","formatPre","formatHeading","pushWordTransform","toUpperCase","popWordTransform","formatBlockquote","formatImage","attribs","alt","indexOf","formatAnchor","getHref","href","hideSameLink","formatList","nextPrefixCallback","isNestedList","maxPrefixLength","listItems","child","name","node","prefix","trimStart","spacing","formatUnorderedList","formatOrderedList","nextIndex","indexFunction","getOrderedListIndexFunction","olType","toLowerCase","isDataTable","attr","attrClasses","attrIds","includes","formatTable","formatDataTable","formatCell","cellNode","openTableCell","closeTableCell","walkTable","formatHeaderCell","forEach","openTableRow","childOfTr","closeTableRow","openTable","closeTable","anchor","blockquote","dataTable","heading","horizontalLine","image","inline","lineBreak","orderedList","paragraph","pre","skip","unorderedList","wbr"],"mappings":"uGAEA,MAAM,kBAAEA,GAAsB,EAAQ,QAGtC,MAAMC,EACJ,YAAaC,EAAO,MAAQC,KAAKD,KAAOA,EAExC,UAAa,OAAQC,KAAS,KAAIA,KAAKD,KAAOC,MAGhD,MAAMC,UAAuBH,EAC3B,YAAaI,EAASH,EAAO,KAAMI,EAAoB,EAAGC,GACxDC,MAAMN,GACNC,KAAKG,kBAAoBA,EACzBH,KAAKM,kBAAoB,IAAIT,EAAkBK,EAASE,GACxDJ,KAAKO,QAAU,GACfP,KAAKQ,kBAAoB,EACzBR,KAAKS,MAAQV,GAAQA,EAAKU,OAI9B,MAAMC,UAAuBZ,EAC3B,YAAaC,EAAO,MAClBM,MAAMN,GACNC,KAAKW,KAAO,GACZX,KAAKS,MAAQV,GAAQA,EAAKU,OAI9B,MAAMG,UAA0Bd,EAC9B,YAAaC,EAAO,MAClBM,MAAMN,GACNC,KAAKa,MAAQ,GACbb,KAAKS,MAAQV,GAAQA,EAAKU,OAI9B,MAAMK,UAA2BhB,EAC/B,YAAaI,EAASH,EAAO,KAAMgB,GACjCV,MAAMN,GACNC,KAAKM,kBAAoB,IAAIT,EAAkBK,EAASa,GACxDf,KAAKO,QAAU,GACfP,KAAKQ,kBAAoB,EACzBR,KAAKS,MAAQV,GAAQA,EAAKU,OAI9B,MAAMO,UAA6BlB,EACjC,YAAaC,EAAO,KAAMkB,GACxBZ,MAAMN,GACNC,KAAKiB,UAAYA,GAIrBC,EAAOC,QAAU,CACflB,eAAgBA,EAChBH,UAAWA,EACXgB,mBAAoBA,EACpBF,kBAAmBA,EACnBF,eAAgBA,EAChBM,qBAAsBA,I,qBC5DxB,MAAMI,EAAQ,EAAQ,QAStB,SAASC,EAAoBC,GAC3B,MAAMC,EAAU,GACVC,EAAM,GACZ,IAAK,MAAMC,KAAYH,EACjBG,EAASC,WAAW,KACtBH,EAAQI,KAAKF,EAASG,UAAU,IACvBH,EAASC,WAAW,MAC7BF,EAAIG,KAAKF,EAASG,UAAU,IAGhC,MAAO,CAAEL,QAASA,EAASC,IAAKA,GAalC,SAASK,EAAuBC,EAAGC,EAAGC,EAAI,UACxC,QAAUC,IAANH,EAAiB,CACnB,MAAMI,EAAK,YAAaC,GAAQ,OAAOJ,EAAEG,KAAOC,IAChD,OAAOD,EAET,OAAIJ,GAAK,EACA,YAAaK,GAAQ,OAAOJ,EAAEF,EAAsBC,EAAI,EAAGC,EAAGC,MAAOG,IAEvEH,EAaT,SAASI,EAAwBC,EAAKC,EAAW,IAAKC,EAAO,IAC3D,MAAMC,EAAS,GACf,GACEH,GAAO,EACPG,EAAOb,KAAKU,EAAME,GAClBF,EAAOA,EAAME,GAAS,QACfF,EAAM,GACf,MAAMI,EAAWH,EAASI,WAAW,GACrC,OAAOF,EACJG,UACAC,IAAId,GAAKe,OAAOC,aAAaL,EAAWX,IACxCiB,KAAK,IAGV,MAAMC,EAAI,CAAC,IAAK,IAAK,IAAK,KACpBC,EAAI,CAAC,IAAK,IAAK,KAQrB,SAASC,EAAeb,GACtB,MAAO,IAAI,EAAQ,IAChBO,IAAId,IAAMA,GACVa,UACAC,IAAI,CAACO,EAAGC,IAAQD,EAAI,EAAI,GACpBA,EAAI,EAAI,GAAKF,EAAEG,IAAMJ,EAAEI,GAAGC,OAAOF,EAAI,GACtCH,EAAEI,IAAMD,EAAI,EAAIF,EAAEG,GAAKJ,EAAEI,EAAI,KAChCT,UACAI,KAAK,IAUV,SAASO,EAAeC,EAAKC,GAC3B,IAAIC,EAAQ,EACRC,EAAMH,EAAII,OACd,MAAOF,EAAQC,GAAOH,EAAIE,KAAWD,IAAUC,EAC/C,MAAOC,EAAMD,GAASF,EAAIG,EAAM,KAAOF,IAAUE,EACjD,OAAQD,EAAQ,GAAKC,EAAMH,EAAII,OAC3BJ,EAAI3B,UAAU6B,EAAOC,GACrBH,EAUN,SAASK,EAAKC,EAAKC,GACjB,IAAK,MAAMC,KAAOD,EAAM,CACtB,IAAKD,EAAO,OACZA,EAAMA,EAAIE,GAEZ,OAAOF,EAUT,SAASG,EAAKH,EAAKC,EAAMG,GACvB,MAAMC,EAAWJ,EAAKK,MACtB,IAAK,MAAMJ,KAAOD,EAAM,CACtB,IAAIM,EAASP,EAAIE,GACZK,IACHA,EAAS,GACTP,EAAIE,GAAOK,GAEbP,EAAMO,EAERP,EAAIK,GAAYD,EAalB,SAASI,EAA2BC,EAAOC,GACzC,MAAM3B,EAAM,IAAI4B,IAChB,IAAK,IAAIpB,EAAIkB,EAAMX,OAAQP,KAAM,GAAI,CACnC,MAAMqB,EAAOH,EAAMlB,GACbW,EAAMQ,EAAOE,GACnB7B,EAAIoB,IACFD,EACCnB,EAAI8B,IAAIX,GACL3C,EAAMqD,EAAM7B,EAAIgB,IAAIG,GAAM,CAAEY,WAAYC,IACxCH,GAGR,MAAO,IAAI7B,EAAIiC,UAAUlC,UAG3B,MAAMiC,EAAiB,CAACE,EAAKC,EAAK7E,IAAY,IAAI6E,GAElD7D,EAAOC,QAAU,CACfyC,IAAKA,EACL/B,sBAAuBA,EACvBwC,0BAA2BA,EAC3BjC,uBAAwBA,EACxBc,cAAeA,EACfc,IAAKA,EACL3C,mBAAoBA,EACpBiC,cAAeA,I,4CC9KjB,SAAS0B,EAAQC,EAAQC,GAEvB,OADKD,EAAOC,KAAMD,EAAOC,GAAK,IACvBD,EAAOC,GAGhB,SAASC,EAAsBC,EAAKC,EAAI,GACtC,MAAOD,EAAIC,GAAMA,IACjB,OAAOA,EAGT,SAASC,EAAkBL,EAAQM,GACjC,IAAK,IAAInC,EAAI,EAAGA,EAAImC,EAASnC,IAAK,CAChC,MAAMoC,EAAOR,EAAOC,EAAQ7B,GAC5B,IAAK,IAAI8B,EAAI,EAAGA,EAAI9B,EAAG8B,IAAK,CAC1B,MAAMO,EAAOT,EAAOC,EAAQC,GACtBQ,EAAOF,EAAKN,GAClBM,EAAKN,GAAKO,EAAKrC,GACfqC,EAAKrC,GAAKsC,IAKhB,SAASC,EAAmBC,EAAMC,EAAQC,EAASC,GACjD,IAAK,IAAIC,EAAI,EAAGA,EAAIJ,EAAKK,QAASD,IAAK,CACrC,MAAME,EAAYlB,EAAOa,EAAQC,EAAUE,GAC3C,IAAK,IAAIG,EAAI,EAAGA,EAAIP,EAAKQ,QAASD,IAChCD,EAAUH,EAAUI,GAAKP,GAK/B,SAASS,EAAcC,EAAS/D,EAAMgE,EAAMtC,GAC1CqC,EAAQ/D,EAAOgE,GAAQC,KAAKC,IAC1BH,EAAQ/D,EAAOgE,IAAS,EACxBD,EAAQ/D,GAAQ0B,GAwBpB,SAASyC,EAAeC,EAAWC,EAAYC,GAC7C,MAAMhB,EAAS,GACf,IAAIiB,EAAY,EAChB,MAAMC,EAAYJ,EAAUhD,OACtBqD,EAAa,CAAC,GAEpB,IAAK,IAAI9B,EAAI,EAAGA,EAAI6B,EAAW7B,IAAK,CAClC,MAAMgB,EAAYlB,EAAOa,EAAQX,GAC3BrE,EAAQ8F,EAAUzB,GACxB,IAAIG,EAAI,EACR,IAAK,IAAIjC,EAAI,EAAGA,EAAIvC,EAAM8C,OAAQP,IAAK,CACrC,MAAMwC,EAAO/E,EAAMuC,GACnBiC,EAAIF,EAAqBe,EAAWb,GACpCM,EAAkBC,EAAMC,EAAQX,EAAGG,GACnCA,GAAKO,EAAKQ,QACVR,EAAKqB,MAAQrB,EAAKsB,KAAKC,MAAM,MAC7B,MAAMC,EAAaxB,EAAKqB,MAAMtD,OAC9B0C,EAAaW,EAAY9B,EAAGU,EAAKK,QAASmB,EAAaR,GAEzDE,EAAaZ,EAAUvC,OAASmD,EAAaZ,EAAUvC,OAASmD,EAGlExB,EAAiBO,EAASkB,EAAYD,EAAaC,EAAYD,GAE/D,MAAMO,EAAc,GACdC,EAAa,CAAC,GAEpB,IAAK,IAAIjC,EAAI,EAAGA,EAAIyB,EAAWzB,IAAK,CAClC,IACIO,EADA2B,EAAI,EAER,MAAOA,EAAIR,IAAcnB,EAAOC,EAAOR,GAAGkC,IAAK,CAC7C,IAAK3B,EAAK4B,SAAU,CAClB,IAAIC,EAAY,EAChB,IAAK,IAAIvC,EAAI,EAAGA,EAAIU,EAAKqB,MAAMtD,OAAQuB,IAAK,CAC1C,MAAMwC,EAAO9B,EAAKqB,MAAM/B,GAClByC,EAAaX,EAAWO,GAAKrC,EACnCmC,EAAYM,IAAeN,EAAYM,IAAe,IAAIC,OAAON,EAAWjC,IAAMqC,EAClFD,EAAaC,EAAK/D,OAAS8D,EAAaC,EAAK/D,OAAS8D,EAExDpB,EAAaiB,EAAYjC,EAAGO,EAAKQ,QAASqB,EAAYZ,GACtDjB,EAAK4B,UAAW,EAElBD,GAAK3B,EAAKK,SAId,OAAOoB,EAAYtE,KAAK,MAG1B7B,EAAOC,QAAU,CAAEuF,cAAeA,I,sBC1GlC,MAAM,kBAAE7G,GAAsB,EAAQ,QAMtC,SAASgI,EAAmBtE,GAC1B,MAAO,IAAIA,GACRX,IAAIuD,GAAK,MAAQA,EAAEzD,WAAW,GAAGoF,SAAS,IAAIC,SAAS,EAAG,MAC1DhF,KAAK,IANV,EAAQ,QAcR,MAAMiF,EAQJ,YAAa9H,GACXF,KAAKiI,gBAAmB/H,EAAwB,iBAC5CA,EAAQgI,qBAAqBC,QAAQ,MAAO,IAC5CjI,EAAQgI,qBACZ,MAAME,EAAkBP,EAAkB7H,KAAKiI,iBAK/C,GAJAjI,KAAKqI,oBAAsB,IAAIC,OAAO,KAAKF,MAC3CpI,KAAKuI,qBAAuB,IAAID,OAAO,IAAIF,OAC3CpI,KAAKwI,uBAAyB,IAAIF,OAAO,KAAKF,QAE1ClI,EAAQuI,iBAAkB,CAE5B,MAAMC,EAAkB,IAAIJ,OAAO,UAAUF,MAAqB,MASlEpI,KAAK2I,cAAgB,SAAUzB,EAAM5G,EAAmBW,EAAY,CAACsC,GAAOA,IAC1E,IAAK2D,EAAQ,OACb,MAAM0B,EAAyBtI,EAAkBuI,aACjD,IAAIC,GAAW,EACXC,EAAIL,EAAgBM,KAAK9B,GAC7B,GAAI6B,EAAG,CACLD,GAAW,EACE,OAATC,EAAE,GACJzI,EAAkB2I,eACTL,GAA0B5I,KAAKkJ,sBAAsBhC,GAC9D5G,EAAkB6I,SAASlI,EAAU8H,EAAE,KAEvCzI,EAAkB8I,WAAWnI,EAAU8H,EAAE,KAE3C,MAA4C,QAApCA,EAAIL,EAAgBM,KAAK9B,IAClB,OAAT6B,EAAE,GACJzI,EAAkB2I,eAElB3I,EAAkB6I,SAASlI,EAAU8H,EAAE,KAI7CzI,EAAkBuI,aAAgBD,IAA2BE,GAAc9I,KAAKqJ,uBAAuBnC,QAKpG,CAEL,MAAMoC,EAAS,IAAIhB,OAAO,KAAKF,MAAqB,KAEpDpI,KAAK2I,cAAgB,SAAUzB,EAAM5G,EAAmBW,EAAY,CAACsC,GAAOA,IAC1E,IAAK2D,EAAQ,OACb,MAAM0B,EAAyBtI,EAAkBuI,aACjD,IAAIC,GAAW,EACXC,EAAIO,EAAON,KAAK9B,GACpB,GAAI6B,EAAG,CACLD,GAAW,EACPF,GAA0B5I,KAAKkJ,sBAAsBhC,GACvD5G,EAAkB6I,SAASlI,EAAU8H,EAAE,KAEvCzI,EAAkB8I,WAAWnI,EAAU8H,EAAE,KAE3C,MAAmC,QAA3BA,EAAIO,EAAON,KAAK9B,IACtB5G,EAAkB6I,SAASlI,EAAU8H,EAAE,KAG3CzI,EAAkBuI,aAAgBD,IAA2BE,GAAa9I,KAAKqJ,uBAAuBnC,KAY5G,sBAAuBA,GACrB,OAAOlH,KAAKqI,oBAAoBkB,KAAKrC,GASvC,uBAAwBA,GACtB,OAAOlH,KAAKuI,qBAAqBgB,KAAKrC,GASxC,kBAAmBA,GACjB,OAAQlH,KAAKwI,uBAAuBe,KAAKrC,IAK7ChG,EAAOC,QAAU,CAAE6G,oBAAqBA,I,uBClIxC,MAAM,OAAEwB,GAAW,EAAQ,SAErB,cAAElG,GAAkB,EAAQ,SAE5B,UAAExD,EAAS,eAAEG,EAAc,mBAAEa,EAAkB,kBAAEF,EAAiB,eAAEF,EAAc,qBAAEM,GACtF,EAAQ,SACN,cAAE0F,GAAkB,EAAQ,SAC5B,oBAAEsB,GAAwB,EAAQ,SAGxC,EAAQ,QAQR,MAAMyB,EAQJ,YAAavJ,EAASwJ,GACpB1J,KAAKE,QAAUA,EACfF,KAAK0J,OAASA,EACd1J,KAAK2J,mBAAqB,IAAI3B,EAAoB9H,GAElDF,KAAK4J,WAAa,IAAI3J,EAAeC,GAErCF,KAAK6J,sBAAmB5H,EAY1B,kBAAmB6H,GACjB9J,KAAK6J,iBAAmB,IAAI7I,EAAqBhB,KAAK6J,iBAAkBC,GAQ1E,mBACE,IAAK9J,KAAK6J,iBAAoB,OAC9B,MAAM5I,EAAYjB,KAAK6J,iBAAiB5I,UAExC,OADAjB,KAAK6J,iBAAmB7J,KAAK6J,iBAAiB9J,KACvCkB,EAIT,8BACE,MAAM8I,EAAmB,CAACxG,EAAKyG,IAC5B,EAAgBD,EAAiBC,EAAY/I,UAAUsC,GAAMyG,EAAYjK,MAAQwD,EACpF,OAAQA,GAAQwG,EAAiBxG,EAAKvD,KAAK6J,kBAG7C,gBACE,MAAMpF,EAAOzE,KAAK4J,WAElB,OADA5J,KAAK4J,WAAanF,EAAK1E,KAChB0E,EAMT,gBAEIzE,KAAK4J,sBAAsB3J,GACxBD,KAAK4J,sBAAsB9I,KAE5Bd,KAAK4J,WAAWnJ,MAClBT,KAAK4J,WAAWrJ,SAAW,KAE3BP,KAAK4J,WAAWtJ,kBAAkB2I,gBAOtC,2BAEIjJ,KAAK4J,sBAAsB3J,GACxBD,KAAK4J,sBAAsB9I,KAE9Bd,KAAK4J,WAAWtJ,kBAAkB2J,sBAAuB,GAkB7D,UAAW1G,EAAK2G,EAAiC,IACD,kBAAnCA,EACTlK,KAAKmK,WAAW5G,EAAK2G,GAErBlK,KAAKmK,WAAW5G,EAAK,CAAE6G,gBAAiBF,IAI5C,WAAY3G,GAAK,gBAAE6G,GAAkB,GAAU,KAE3CpK,KAAK4J,sBAAsB3J,GACxBD,KAAK4J,sBAAsB9I,KAG5Bd,KAAK4J,WAAWnJ,MAClBT,KAAK4J,WAAWrJ,SAAWgD,GAK3BvD,KAAK2J,mBAAmBU,kBAAkB9G,IACzCA,EAAII,SAAW3D,KAAK4J,WAAWpJ,qBAE5BR,KAAK4J,WAAWpJ,mBAClBR,KAAK4J,WAAWtJ,kBAAkB2I,aAAajJ,KAAK4J,WAAWpJ,mBAEjER,KAAK2J,mBAAmBhB,cACtBpF,EACAvD,KAAK4J,WAAWtJ,kBACfN,KAAK6J,mBAAqBO,EAAmBpK,KAAKsK,mCAAgCrI,GAErFjC,KAAK4J,WAAWpJ,kBAAoB,IA2BxC,UAAW+J,EAAmC,GAAIC,EAAgC/J,GAChC,kBAArC8J,EACTvK,KAAKyK,WAAWF,GAEhBvK,KAAKyK,WAAW,CACdhK,MAAOA,EACPN,kBAAmBoK,EACnBC,mBAAoBA,IAK1B,YAAY,kBAAErK,EAAoB,EAAC,mBAAEqK,EAAqB,EAAC,MAAE/J,GAAQ,GAAU,IAC7E,MAAML,EAAgBoG,KAAKC,IAAI,GAAIzG,KAAK4J,WAAWtJ,kBAAkBF,cAAgBoK,GACrFxK,KAAK4J,WAAa,IAAI3J,EACpBD,KAAKE,QACLF,KAAK4J,WACLzJ,EACAC,GAEEK,IAAST,KAAK4J,WAAWnJ,OAAQ,GAuBvC,WAAYiK,EAAoC,GAAIC,GACD,kBAAtCD,EACT1K,KAAK4K,YAAYF,GAEjB1K,KAAK4K,YAAY,CACfC,mBAAoBH,EACpBC,eAAgBA,IAKtB,aAAa,mBAAEE,EAAqB,EAAC,eAAEF,GAA+B,IACpE,MAAMG,EAAQ9K,KAAK+K,gBACbC,EAAY,EAAmBL,EAAeM,EAAQH,IAAUG,EAAQH,GAC9EI,EAAQlL,KAAK4J,WAAYoB,EAAWF,EAAM3K,kBAAmBqG,KAAKC,IAAIqE,EAAMtK,kBAAmBqK,IAMjG,YACE7K,KAAK4J,WAAa,IAAIlJ,EAAeV,KAAK4J,YAM5C,eACE,KAAM5J,KAAK4J,sBAAsBlJ,GAC/B,MAAM,IAAIyK,MAAM,8EAElBnL,KAAK4J,WAAa,IAAIhJ,EAAkBZ,KAAK4J,YAc/C,cAAewB,EAAgC,IACA,kBAAlCA,EACTpL,KAAKqL,eAAeD,GAEpBpL,KAAKqL,eAAe,CAAEtK,eAAgBqK,IAI1C,gBAAgB,eAAErK,GAA+B,IAC/C,KAAMf,KAAK4J,sBAAsBhJ,GAC/B,MAAM,IAAIuK,MAAM,mFAElBnL,KAAK4J,WAAa,IAAI9I,EAAmBd,KAAKE,QAASF,KAAK4J,WAAY7I,GAgB1E,eAAgBuK,EAAyB,GAAIrF,GACL,kBAA3BqF,EACTtL,KAAKuL,gBAAgBD,GAErBtL,KAAKuL,gBAAgB,CACnBnF,QAASkF,EACTrF,QAASA,IAKf,iBAAiB,QAAEG,EAAU,EAAC,QAAEH,EAAU,GAAM,IAC9C,MAAML,EAAO5F,KAAK+K,gBACZ7D,EAAO5D,EAAc2H,EAAQrF,GAAO,MAC1CA,EAAK7F,KAAKc,MAAMc,KAAK,CAAEyE,QAASA,EAASH,QAASA,EAASiB,KAAMA,IAMnE,gBACE,MAAM9B,EAAMpF,KAAK+K,gBACjB3F,EAAIrF,KAAKY,KAAKgB,KAAKyD,EAAIvE,OAgCzB,WACE2K,EAA4B,GAC5B5E,EACAzG,EACA0K,GAEyC,kBAA9BW,EACTxL,KAAKyL,YAAYD,GAEjBxL,KAAKyL,YAAY,CACf5E,WAAY2E,EACZrL,kBAAmBA,EACnByG,WAAYA,EACZiE,mBAAoBA,IAK1B,aAAa,WAAEhE,EAAa,EAAC,WAAED,EAAa,EAAC,kBAAEzG,EAAoB,EAAC,mBAAE0K,EAAqB,GAAM,IAC/F,MAAMa,EAAQ1L,KAAK+K,gBACbY,EAASjF,EAAcgF,EAAM/K,KAAMiG,EAAYC,GACjD8E,GACFT,EAAQlL,KAAK4J,WAAY+B,EAAQxL,EAAmB0K,GASxD,WACE,OAAOI,EAAQjL,KAAK4J,WAAWgC,YAMnC,SAASX,EAASY,GAChB,KACEA,aAAqB5L,GAClB4L,aAAqB/K,GAExB,MAAM,IAAIqK,MAAM,mEAElB,OAAQU,EAAUvL,kBAAkBwL,UAChCD,EAAUtL,QACVsL,EAAUtL,QAAUsL,EAAUvL,kBAAkBwH,WAGtD,SAASoD,EAASW,EAAW3E,EAAM/G,EAAmB0K,GACpD,KACEgB,aAAqB5L,GAClB4L,aAAqB/K,GAExB,MAAM,IAAIqK,MAAM,iDAElB,MAAMY,EAAad,EAAQY,GACrBG,EAAaxF,KAAKC,IAAIoF,EAAUrL,kBAAmBL,GACzD0L,EAAUvL,kBAAkB2L,QACxBF,EACFF,EAAUtL,QAAUwL,EAAa,KAAK1I,OAAO2I,GAAc9E,GAE3D2E,EAAUtL,QAAU2G,EACpB2E,EAAU1L,kBAAoB6L,GAEhCH,EAAUrL,kBAAoBqK,EAGhC3J,EAAOC,QAAU,CAAEsI,iBAAkBA,I,uBC7ZrC,EAAQ,QAKR,MAAM5J,EASJ,YAAaK,EAASE,GAEpBJ,KAAKiH,MAAQ,GAEbjH,KAAKkM,cAAgB,GACrBlM,KAAKI,cAAgBA,GAAiBF,EAAQiM,UAAYC,OAAOC,UACjErM,KAAKsM,uBAAyBtM,KAAKI,cACnCJ,KAAKuM,eAAiBrM,EAAQsM,cAAcD,gBAAkB,GAC9DvM,KAAKyM,iBAAmBvM,EAAQsM,cAAcC,mBAAoB,EAElEzM,KAAK6I,cAAe,EACpB7I,KAAKiK,sBAAuB,EAQ9B,SAAUyC,GACJ1M,KAAKsM,wBAA0B,GACjCtM,KAAKiJ,eAEP,MAAM0D,EAA4C,IAA9B3M,KAAKkM,cAAcvI,OACjCiJ,EAAOF,EAAK/I,QAAUgJ,EAAc,EAAI,GAC9C,GAAIC,GAAQ5M,KAAKsM,uBAEftM,KAAKkM,cAAcvK,KAAK+K,GACxB1M,KAAKsM,wBAA0BM,MAE1B,CAGL,MAAOC,KAAUC,GAAQ9M,KAAK+M,cAAcL,GACvCC,GAAe3M,KAAKiJ,eACzBjJ,KAAKkM,cAAcvK,KAAKkL,GACxB7M,KAAKsM,wBAA0BO,EAAMlJ,OACrC,IAAK,MAAMqJ,KAAQF,EACjB9M,KAAKiJ,eACLjJ,KAAKkM,cAAcvK,KAAKqL,GACxBhN,KAAKsM,wBAA0BU,EAAKrJ,QAY1C,UACE,MAAMsJ,EAAWjN,KAAKkM,cAAc/H,MACpC,QAAiBlC,IAAbgL,EAAwB,CAC1B,MAAMN,EAA4C,IAA9B3M,KAAKkM,cAAcvI,OACjCiJ,EAAOK,EAAStJ,QAAUgJ,EAAc,EAAI,GAClD3M,KAAKsM,wBAA0BM,EAEjC,OAAOK,EAST,WAAYP,GACV,GAAI1M,KAAKiK,sBAAwByC,EAAK/I,OAAS3D,KAAKsM,uBAClDtM,KAAKmJ,SAASuD,GACd1M,KAAKiK,sBAAuB,MACvB,CACL,MAAMgD,EAAWjN,KAAKkN,UACtBlN,KAAKmJ,SAAS,EAAa8D,EAASE,OAAOT,GAAQA,IASvD,aAAc5K,EAAI,GAChB9B,KAAKiH,MAAMtF,KAAK3B,KAAKkM,eACjBpK,EAAI,GACN9B,KAAKiH,MAAMtF,QAAQyL,MAAMC,KAAK,CAAE1J,OAAQ7B,EAAI,GAAK,IAAM,KAEzD9B,KAAKkM,cAAgB,GACrBlM,KAAKsM,uBAAyBtM,KAAKI,cAQrC,UACE,OAA6B,IAAtBJ,KAAKiH,MAAMtD,QACmB,IAA9B3D,KAAKkM,cAAcvI,OAG5B,QACE3D,KAAKiH,MAAMtD,OAAS,EACpB3D,KAAKkM,cAAcvI,OAAS,EAC5B3D,KAAKsM,uBAAyBtM,KAAKI,cAQrC,WACE,MAAO,IAAIJ,KAAKiH,MAAOjH,KAAKkM,eACzBtJ,IAAI0K,GAASA,EAAMvK,KAAK,MACxBA,KAAK,MAWV,cAAe2J,GACb,MAAMa,EAAQ,GACd,IAAIC,EAAM,EACV,MAAOd,EAAK/I,OAAS3D,KAAKI,cAAe,CAEvC,MAAMqN,EAAYf,EAAK9K,UAAU,EAAG5B,KAAKI,eACnCsN,EAAiBhB,EAAK9K,UAAU5B,KAAKI,eAErCuN,EAAaF,EAAUG,YAAY5N,KAAKuM,eAAeiB,IAE7D,GAAIG,GAAc,EAEhBjB,EAAOe,EAAU7L,UAAU+L,EAAa,GAAKD,EAC7CH,EAAM5L,KAAK8L,EAAU7L,UAAU,EAAG+L,EAAa,QAE1C,CAGL,GADAH,MACIA,EAAMxN,KAAKuM,eAAe5I,QAIvB,CAEL,GAAI3D,KAAKyM,kBAGP,GAFAc,EAAM5L,KAAK8L,GACXf,EAAOgB,EACHhB,EAAK/I,OAAS3D,KAAKI,cACrB,cAGFsM,EAAOe,EAAYC,EAErB,MAbAhB,EAAOe,EAAYC,GAqBzB,OADAH,EAAM5L,KAAK+K,GACJa,GAIXrM,EAAOC,QAAU,CAAEtB,kBAAmBA,I,qBC3LtCqB,EAAOC,QAAU,EAAQ,S,qBCAzB,MAAM,WAAE0M,GAAe,EAAQ,QACzBzM,EAAQ,EAAQ,QAChB0M,EAAK,EAAQ,QACbC,EAAa,EAAQ,QACrBC,EAAW,EAAQ,SAEnB,iBAAEvE,GAAqB,EAAQ,QAC/BwE,EAAoB,EAAQ,SAC5B,sBAAEpM,EAAqB,0BAAEwC,EAAyB,IAAEL,GAAQ,EAAQ,QAG1E,EAAQ,QAWR,MAAMkK,EAAkB,CACtBC,aAAc,CACZ7M,UAAW,CAAE,QACb8M,QAAS,YACTC,oBAAoB,GAEtBC,cAAe,CACbC,kBAAkB,EAClBC,QAAQ,GAEVC,WAAY,GACZC,OAAQ,CACNC,SAAU,MACVC,qBAAiB3M,EACjB4M,mBAAe5M,EACf6M,cAAU7M,EACV8M,eAAiB,GAAK,IAExBvC,cAAe,CACbC,kBAAkB,EAClBF,eAAgB,IAElB9D,kBAAkB,EAClBnH,UAAW,CACT,CAAEG,SAAU,IAAKuN,OAAQ,UACzB,CACEvN,SAAU,IACVuN,OAAQ,SACR9O,QAAS,CACP+O,QAAS,KACTC,0BAA0B,EAC1BC,YAAY,EACZC,aAAa,EACbC,gBAAgB,IAGpB,CAAE5N,SAAU,UAAWuN,OAAQ,SAC/B,CAAEvN,SAAU,QAASuN,OAAQ,SAC7B,CACEvN,SAAU,aACVuN,OAAQ,aACR9O,QAAS,CAAEC,kBAAmB,EAAG0K,mBAAoB,EAAGyE,gBAAgB,IAE1E,CAAE7N,SAAU,KAAMuN,OAAQ,aAC1B,CAAEvN,SAAU,MAAOuN,OAAQ,SAC3B,CAAEvN,SAAU,SAAUuN,OAAQ,SAC9B,CAAEvN,SAAU,OAAQuN,OAAQ,SAC5B,CAAEvN,SAAU,KAAMuN,OAAQ,UAAW9O,QAAS,CAAEC,kBAAmB,EAAG0K,mBAAoB,EAAG0E,WAAW,IACxG,CAAE9N,SAAU,KAAMuN,OAAQ,UAAW9O,QAAS,CAAEC,kBAAmB,EAAG0K,mBAAoB,EAAG0E,WAAW,IACxG,CAAE9N,SAAU,KAAMuN,OAAQ,UAAW9O,QAAS,CAAEC,kBAAmB,EAAG0K,mBAAoB,EAAG0E,WAAW,IACxG,CAAE9N,SAAU,KAAMuN,OAAQ,UAAW9O,QAAS,CAAEC,kBAAmB,EAAG0K,mBAAoB,EAAG0E,WAAW,IACxG,CAAE9N,SAAU,KAAMuN,OAAQ,UAAW9O,QAAS,CAAEC,kBAAmB,EAAG0K,mBAAoB,EAAG0E,WAAW,IACxG,CAAE9N,SAAU,KAAMuN,OAAQ,UAAW9O,QAAS,CAAEC,kBAAmB,EAAG0K,mBAAoB,EAAG0E,WAAW,IACxG,CAAE9N,SAAU,SAAUuN,OAAQ,SAC9B,CACEvN,SAAU,KACVuN,OAAQ,iBACR9O,QAAS,CAAEC,kBAAmB,EAAGwD,YAAQ1B,EAAW4I,mBAAoB,IAE1E,CAAEpJ,SAAU,MAAOuN,OAAQ,QAAS9O,QAAS,CAAE+O,QAAS,OACxD,CAAExN,SAAU,OAAQuN,OAAQ,SAC5B,CAAEvN,SAAU,MAAOuN,OAAQ,SAC3B,CACEvN,SAAU,KACVuN,OAAQ,cACR9O,QAAS,CAAEC,kBAAmB,EAAG0K,mBAAoB,IAEvD,CAAEpJ,SAAU,IAAKuN,OAAQ,YAAa9O,QAAS,CAAEC,kBAAmB,EAAG0K,mBAAoB,IAC3F,CAAEpJ,SAAU,MAAOuN,OAAQ,MAAO9O,QAAS,CAAEC,kBAAmB,EAAG0K,mBAAoB,IACvF,CAAEpJ,SAAU,UAAWuN,OAAQ,SAC/B,CACEvN,SAAU,QACVuN,OAAQ,QACR9O,QAAS,CACP2G,WAAY,EACZ1G,kBAAmB,EACnBY,eAAgB,GAChB6F,WAAY,EACZiE,mBAAoB,EACpB2E,sBAAsB,IAG1B,CACE/N,SAAU,KACVuN,OAAQ,gBACR9O,QAAS,CAAEuP,WAAY,MAAOtP,kBAAmB,EAAG0K,mBAAoB,IAE1E,CAAEpJ,SAAU,MAAOuN,OAAQ,QAE7BU,OAAQ,GACRxH,qBAAsB,aACtBiE,SAAU,IAGNwD,EAAc,CAAC7K,EAAKC,EAAK7E,IAAY,IAAI4E,KAAQC,GACjDH,EAAiB,CAACE,EAAKC,EAAK7E,IAAY,IAAI6E,GAC5C6K,EAAiB,CAAC9K,EAAKC,EAAK7E,IAC/B4E,EAAI+K,KAAKC,GAAkB,kBAANA,GAClBH,EAAY7K,EAAKC,EAAK7E,GACtB0E,EAAeE,EAAKC,EAAK7E,GAW/B,SAAS6P,EAAS7P,EAAU,IAC1BA,EAAUkB,EACR8M,EACAhO,EACA,CACEyE,WAAYC,EACZoL,YAAcjM,GAAkB,cAARA,EAAuB6L,OAAiB3N,IAGpE/B,EAAQuO,WAAawB,OAAOC,OAAO,GAAIjC,EAAmB/N,EAAQuO,YAElE0B,EAAwBjQ,GAExB,MAAMkQ,EAAkB/L,EAA0BnE,EAAQoB,UAAYwO,GAAKA,EAAErO,UACvE4O,EAAyBD,EAAgBE,OAAOR,IAAMA,EAAEd,QAC9D,GAAIqB,EAAuB1M,OACzB,MAAM,IAAIwH,MACR,iDACAkF,EAAuBzN,IAAIkN,GAAK,KAAKA,EAAErO,cAAcsB,KAAK,OAG9D,MAAM2G,EAAS,IAAIsE,EAASuC,aAC1BH,EAAgBxN,IAAIkN,GAAK,CAACA,EAAErO,SAAUqO,KACtCU,MAAM3C,GAEF4C,EAAsB,IAAIzC,EAASuC,aACvCrQ,EAAQiO,aAAa7M,UAAUsB,IAAI,CAACkN,EAAG1M,IAAM,CAAC0M,EAAG1M,EAAI,KACrDoN,MAAM3C,GACR,SAAS6C,EAAkBC,GACzB,OAAOC,EAAUD,EAAKzQ,EAASuQ,GAGjC,MAAMI,EAAchP,EAClB3B,EAAQwO,OAAOI,SACfgC,GACA,SAAUH,EAAKI,GACbA,EAAQC,UAAU9Q,EAAQwO,OAAOC,UAAY,OAIjD,OAAO,SAAUsC,GACf,OAAOC,EAAQD,EAAM/Q,EAASwJ,EAAQgH,EAAkBG,IAiB5D,SAASK,EAASD,EAAM/Q,EAASwJ,EAAQgH,EAAkBS,GACzD,MAAMpC,EAAiB7O,EAAQwO,OAAOK,eAClCA,GAAkBkC,GAAQA,EAAKtN,OAASoL,IAC1CqC,QAAQC,KACN,gBAAgBJ,EAAKtN,oCAAoCoL,mCAE3DkC,EAAOA,EAAKrP,UAAU,EAAGmN,IAG3B,MAAMuC,EAAU,IAAIvD,EAAWwD,WAC/B,IAAIxD,EAAWyD,OAAOF,EAAS,CAAEG,gBAAgB,IAASC,cAAcT,GAExE,MAAMU,EAAQjB,EAAiBY,EAAQX,KACjCI,EAAU,IAAItH,EAAiBvJ,EAASwJ,GAE9C,OADAyH,EAAKQ,EAAOZ,GACLA,EAAQjJ,WAkBjB,SAAS8J,EAASX,EAAM/Q,EAAU,IAChC,OAAO6P,EAAQ7P,EAAR6P,CAAiBkB,GAS1B,SAASd,EAAyBjQ,GAChC,MAAM2R,EAAsB3R,EAAQoB,UAEpC,GAAIpB,EAAQ4R,KAAM,CAChB,MAAMC,EAAiB9B,OAAO+B,QAAQ9R,EAAQ4R,MAAMlP,IAClD,EAAEnB,EAAUwQ,MAAgB,IAAMA,EAAYxQ,SAAUA,GAAY,OAEtEoQ,EAAoBlQ,QAAQoQ,GAG9B,SAASG,EAAqBC,EAAQnD,EAAQoD,GAC5C,QAAwBnQ,IAApB/B,EAAQiS,GACZ,IAAK,MAAMF,KAAcJ,EACnBI,EAAWjD,SAAWA,GACxBhL,EAAIiO,EAAY,CAAC,UAAWG,GAASlS,EAAQiS,IAmBnD,GAdAD,EAAoB,2BAA4B,SAAU,4BAC1DA,EAAoB,aAAc,SAAU,cAC5CA,EAAoB,kBAAmB,SAAU,WACjDA,EAAoB,cAAe,SAAU,eAC7CA,EAAoB,iBAAkB,SAAU,kBAEhDA,EAAoB,kBAAmB,QAAS,WAEhDA,EAAoB,0BAA2B,gBAAiB,cAEhEA,EAAoB,oBAAqB,UAAW,aACpDA,EAAoB,oBAAqB,QAAS,qBAClDA,EAAoB,oBAAqB,YAAa,qBAElDhS,EAAQ,eACV,IAAK,MAAM+R,KAAcJ,EACG,UAAtBI,EAAWjD,SACbiD,EAAWjD,OAAS,QAK1B,GAAI9O,EAAQ,2BACV,IAAK,MAAM+R,KAAcJ,EACG,cAAtBI,EAAWjD,QAAgD,QAAtBiD,EAAWjD,SAClDhL,EAAIiO,EAAY,CAAC,UAAW,qBAAsB,GAClDjO,EAAIiO,EAAY,CAAC,UAAW,sBAAuB,IAKzD,GAAI/R,EAAQ,eAAgB,CAC1B,MAAMmS,EAAcnS,EAAQ,eAC5B8D,EACE9D,EACA,CAAC,eAAgB,aAChBkN,MAAMkF,QAAQD,GAAeA,EAAc,CAACA,SAGXpQ,IAAlC/B,EAAQ,uBACV8D,EAAI9D,EAAS,CAAC,eAAgB,sBAAuBA,EAAQ,uBAIjE,SAAS0Q,EAAWD,EAAKzQ,EAASuQ,GAChC,MAAM8B,EAAU,GAEhB,SAASzB,EAAeK,EAAiCR,GACvDA,EAAMA,EAAI6B,MAAM,EAAGtS,EAAQwO,OAAOG,eAClC,IAAK,MAAM4D,KAAQ9B,EAAK,CACtB,GAAkB,QAAd8B,EAAKC,KACP,SAEF,MAAMC,EAAsBlC,EAAoBmC,MAAMH,GAMtD,GALIE,EAAsB,EACxBJ,EAAQ5Q,KAAK,CAAEkR,cAAeF,EAAqBG,QAASL,IACnDA,EAAKM,UACd5B,EAAKsB,EAAKM,UAERR,EAAQ5O,QAAUzD,EAAQwO,OAAOE,gBACnC,QAKN,MAAMiC,EAAchP,EAClB3B,EAAQwO,OAAOI,SACfgC,GAOF,OALAD,EAAYF,GAEyB,eAAjCzQ,EAAQiO,aAAaC,SACvBmE,EAAQS,KAAK,CAACC,EAAGC,IAAMD,EAAEJ,cAAgBK,EAAEL,eAErC3S,EAAQiO,aAAaE,oBAAyC,IAAnBkE,EAAQ5O,OACvDgN,EACA4B,EAAQ3P,IAAIyC,GAAKA,EAAEyN,SAWzB,SAAShC,EAAeK,EAAMR,EAAKI,GACjC,IAAKJ,EAAO,OAEZ,MAAMzQ,EAAU6Q,EAAQ7Q,QAElBiT,EAAoBxC,EAAIhN,OAASzD,EAAQwO,OAAOG,cAClDsE,IACFxC,EAAMA,EAAI6B,MAAM,EAAGtS,EAAQwO,OAAOG,eAClC8B,EAAIhP,KAAK,CACPyR,KAAMlT,EAAQwO,OAAOC,SACrB+D,KAAM,UAIV,IAAK,MAAMD,KAAQ9B,EACjB,OAAQ8B,EAAKC,MACX,IAAK,OACH3B,EAAQC,UAAUlD,EAAGuF,OAAOZ,EAAKW,KAAMlT,EAAQoO,gBAC/C,MAEF,IAAK,MAAO,CACV,MAAMgF,EAAgBvC,EAAQrH,OAAOkJ,MAAMH,GACrCzD,EAAS9O,EAAQuO,WAAW6E,EAActE,QAChDA,EAAOyD,EAAMtB,EAAMJ,EAASuC,EAAcpT,SAAW,IACrD,MAEF,QAEE,OAgBR,MAAMqT,EAAa,CAACtC,EAAM/Q,EAAU,KAAO0R,EAAQX,EAAM/Q,GAEzDgB,EAAOC,QAAU,CACf4O,QAASA,EACT6B,QAASA,EACT2B,WAAYA,EACZC,WAAY5B,I,qBCrYd,MAAM9D,EAAK,EAAQ,SAEb,IAAElK,EAAG,uBAAExB,EAAsB,cAAEc,EAAa,mBAAE7B,EAAkB,cAAEiC,GAAkB,EAAQ,QAWlG,SAASmQ,EAAYhB,EAAMtB,EAAMJ,EAAS2C,IAS1C,SAASC,EAAclB,EAAMtB,EAAMJ,EAAS2C,GAC1CvC,EAAKsB,EAAKM,SAAUhC,GAQtB,SAAS6C,EAAanB,EAAMtB,EAAMJ,EAAS2C,GACzC3C,EAAQ8C,UAAU,CAAE1T,kBAAmBuT,EAAcvT,oBACrDgR,EAAKsB,EAAKM,SAAUhC,GACpBA,EAAQ+C,WAAW,CAAEjJ,mBAAoB6I,EAAc7I,qBAQzD,SAASkJ,EAAiBtB,EAAMtB,EAAMJ,EAAS2C,GAC7C3C,EAAQiD,eAQV,SAASC,EAAWxB,EAAMtB,EAAMJ,EAAS2C,GACvC3C,EAAQmD,0BAQV,SAASC,EAAsB1B,EAAMtB,EAAMJ,EAAS2C,GAClD3C,EAAQ8C,UAAU,CAAE1T,kBAAmBuT,EAAcvT,mBAAqB,IAC1E4Q,EAAQC,UAAU,IAAI3N,OAAOqQ,EAAc/P,QAAUoN,EAAQ7Q,QAAQiM,UAAY,KACjF4E,EAAQ+C,WAAW,CAAEjJ,mBAAoB6I,EAAc7I,oBAAsB,IAQ/E,SAASuJ,EAAiB3B,EAAMtB,EAAMJ,EAAS2C,GAC7C3C,EAAQ8C,UAAU,CAAE1T,kBAAmBuT,EAAcvT,mBAAqB,IAC1EgR,EAAKsB,EAAKM,SAAUhC,GACpBA,EAAQ+C,WAAW,CAAEjJ,mBAAoB6I,EAAc7I,oBAAsB,IAQ/E,SAASwJ,EAAW5B,EAAMtB,EAAMJ,EAAS2C,GACvC3C,EAAQ8C,UAAU,CAChBpT,OAAO,EACPN,kBAAmBuT,EAAcvT,mBAAqB,IAExDgR,EAAKsB,EAAKM,SAAUhC,GACpBA,EAAQ+C,WAAW,CAAEjJ,mBAAoB6I,EAAc7I,oBAAsB,IAQ/E,SAASyJ,EAAe7B,EAAMtB,EAAMJ,EAAS2C,GAC3C3C,EAAQ8C,UAAU,CAAE1T,kBAAmBuT,EAAcvT,mBAAqB,KAC1C,IAA5BuT,EAAcnE,WAChBwB,EAAQwD,kBAAkBhR,GAAOA,EAAIiR,eACrCrD,EAAKsB,EAAKM,SAAUhC,GACpBA,EAAQ0D,oBAERtD,EAAKsB,EAAKM,SAAUhC,GAEtBA,EAAQ+C,WAAW,CAAEjJ,mBAAoB6I,EAAc7I,oBAAsB,IAQ/E,SAAS6J,EAAkBjC,EAAMtB,EAAMJ,EAAS2C,GAC9C3C,EAAQ8C,UAAU,CAChB1T,kBAAmBuT,EAAcvT,mBAAqB,EACtDqK,mBAAoB,IAEtB2G,EAAKsB,EAAKM,SAAUhC,GACpBA,EAAQ+C,WAAW,CACjBjJ,mBAAoB6I,EAAc7I,oBAAsB,EACxDF,eAAgBpH,KAA0C,IAAjCmQ,EAAcpE,eAA4BhM,EAAcC,EAAK,MAAQA,GAC3F4D,MAAM,MACNvE,IAAI8E,GAAQ,KAAOA,GACnB3E,KAAK,QASZ,SAAS4R,EAAalC,EAAMtB,EAAMJ,EAAS2C,GACzC,MAAMkB,EAAUnC,EAAKmC,SAAW,GAC1BC,EAAOD,EAAW,IACpB9G,EAAGuF,OAAOuB,EAAQC,IAAK9D,EAAQ7Q,QAAQoO,eACvC,GACEvJ,EAAQ6P,EAAQ7P,IAEjB2O,EAAczE,SAAwC,IAA7B2F,EAAQ7P,IAAI+P,QAAQ,KAC5CpB,EAAczE,QAAU2F,EAAQ7P,IAChC6P,EAAQ7P,IAHV,GAIEmC,EAASnC,EAET8P,EAEAA,EAAM,KAAO9P,EAAM,IADnB,IAAMA,EAAM,IAFd8P,EAKJ9D,EAAQC,UAAU9J,GAQpB,SAAS6N,EAActC,EAAMtB,EAAMJ,EAAS2C,GAC1C,SAASsB,IACP,GAAItB,EAAcvE,WAAc,MAAO,GACvC,IAAKsD,EAAKmC,UAAYnC,EAAKmC,QAAQK,KAAQ,MAAO,GAClD,IAAIA,EAAOxC,EAAKmC,QAAQK,KAAK9M,QAAQ,WAAY,IACjD,OAAIuL,EAActE,aAA2B,MAAZ6F,EAAK,GAAqB,IAC3DA,EAAQvB,EAAczE,SAAuB,MAAZgG,EAAK,GAClCvB,EAAczE,QAAUgG,EACxBA,EACGnH,EAAGuF,OAAO4B,EAAMlE,EAAQ7Q,QAAQoO,gBAEzC,MAAM2G,EAAOD,IACb,GAAKC,EAEE,CACL,IAAI/N,EAAO,GACX6J,EAAQwD,kBACNhR,IACMA,IAAO2D,GAAQ3D,GACZA,IAGX4N,EAAKsB,EAAKM,SAAUhC,GACpBA,EAAQ0D,mBAER,MAAMS,EAAexB,EAAcxE,0BAA4B+F,IAAS/N,EACnEgO,GACHnE,EAAQC,UACJ9J,EAEGwM,EAA4B,eAC3B,IAAMuB,EACN,KAAOA,EAAO,IAHhBA,EAIJ,CAAE7K,iBAAiB,SApBvB+G,EAAKsB,EAAKM,SAAUhC,GAiCxB,SAASoE,EAAY1C,EAAMtB,EAAMJ,EAAS2C,EAAe0B,GACvD,MAAMC,EAAiD,OAAlCzR,EAAI6O,EAAM,CAAC,SAAU,SAI1C,IAAI6C,EAAkB,EACtB,MAAMC,GAAa9C,EAAKM,UAAY,IAEjCzC,OAAOkF,GAAwB,SAAfA,EAAM9C,OAAoB,QAAQnJ,KAAKiM,EAAMpC,OAC7DxQ,KAAI,SAAU4S,GACb,GAAmB,OAAfA,EAAMC,KACR,MAAO,CAAEC,KAAMF,EAAOG,OAAQ,IAEhC,MAAMA,EAAS,EACXP,IAAqBQ,YACrBR,IAEJ,OADIO,EAAOhS,OAAS2R,IAAmBA,EAAkBK,EAAOhS,QACzD,CAAE+R,KAAMF,EAAOG,OAAQA,MAElC,IAAKJ,EAAU5R,OAAU,OAEzB,MAAM6G,EAAqB8K,EACrBO,EAAU,KAAO,IAAIxS,OAAOmH,GAClCuG,EAAQ8C,UAAU,CAAE1T,kBAAmBkV,EAAe,EAAK3B,EAAcvT,mBAAqB,IAC9F,IAAK,MAAM,KAAEuV,EAAI,OAAEC,KAAYJ,EAC7BxE,EAAQ8C,UAAU,CAChB1T,kBAAmB,EACnBqK,mBAAoBA,IAEtB2G,EAAK,CAACuE,GAAO3E,GACbA,EAAQ+C,WAAW,CACjBjJ,mBAAoB,EACpBF,eAAgBpH,GAAOoS,EAAS,IAAItS,OAAOmH,EAAqBmL,EAAOhS,QAAUJ,EAAI4E,QAAQ,MAAO0N,KAGxG9E,EAAQ+C,WAAW,CAAEjJ,mBAAoBwK,EAAe,EAAK3B,EAAc7I,oBAAsB,IAQnG,SAASiL,EAAqBrD,EAAMtB,EAAMJ,EAAS2C,GACjD,MAAMiC,EAASjC,EAAcjE,YAAc,MAC3C,OAAO0F,EAAW1C,EAAMtB,EAAMJ,EAAS2C,EAAe,IAAMiC,GAQ9D,SAASI,EAAmBtD,EAAMtB,EAAMJ,EAAS2C,GAC/C,IAAIsC,EAAY5J,OAAOqG,EAAKmC,QAAQnR,OAAS,KAC7C,MAAMwS,EAAgBC,EAA4BzD,EAAKmC,QAAQlC,MACzD0C,EAAqB,IAAM,IAAMa,EAAcD,KAAe,KACpE,OAAOb,EAAW1C,EAAMtB,EAAMJ,EAAS2C,EAAe0B,GASxD,SAASc,EAA6BC,EAAS,KAC7C,OAAQA,GACN,IAAK,IAAK,OAAQ/S,GAAMhB,EAAuBgB,EAAG,KAClD,IAAK,IAAK,OAAQA,GAAMhB,EAAuBgB,EAAG,KAClD,IAAK,IAAK,OAAQA,GAAMF,EAAcE,GAAGgT,cACzC,IAAK,IAAK,OAAQhT,GAAMF,EAAcE,GACtC,IAAK,IACL,QAAS,OAAQA,GAAM,EAAI0E,YAI/B,SAASuO,EAAaC,EAAM5G,GAC1B,IAAe,IAAXA,EAAmB,OAAO,EAC9B,IAAK4G,EAAQ,OAAO,EAEpB,MAAM,QAAE/U,EAAO,IAAEC,GAAQH,EAAmBqO,GACtC6G,GAAeD,EAAK,UAAY,IAAInP,MAAM,KAC1CqP,GAAWF,EAAK,OAAS,IAAInP,MAAM,KAEzC,OAAOoP,EAAY1G,KAAKxK,GAAK9D,EAAQkV,SAASpR,KAAOmR,EAAQ3G,KAAKxK,GAAK7D,EAAIiV,SAASpR,IAQtF,SAASqR,EAAajE,EAAMtB,EAAMJ,EAAS2C,GACzC,OAAO2C,EAAY5D,EAAKmC,QAAS7D,EAAQ7Q,QAAQwP,QAC7CiH,EAAgBlE,EAAMtB,EAAMJ,EAAS2C,GACrCE,EAAYnB,EAAMtB,EAAMJ,EAAS2C,GAQvC,SAASiD,EAAiBlE,EAAMtB,EAAMJ,EAAS2C,GAU7C,SAASkD,EAAYC,GACnB,MAAMzQ,GAAWxC,EAAIiT,EAAU,CAAC,UAAW,aAAe,EACpD5Q,GAAWrC,EAAIiT,EAAU,CAAC,UAAW,aAAe,EAC1D9F,EAAQ+F,cAAc,CAAE/V,eAAgB2S,EAAc3S,iBACtDoQ,EAAK0F,EAAS9D,SAAUhC,GACxBA,EAAQgG,eAAe,CAAE3Q,QAASA,EAASH,QAASA,IAGtD,SAAS+Q,EAAWvE,GAClB,GAAkB,QAAdA,EAAKC,KAAkB,OAE3B,MAAMuE,GAA2D,IAAvCvD,EAAclE,qBACnCqH,IACD9F,EAAQwD,kBAAkBhR,GAAOA,EAAIiR,eACrCoC,EAAWC,GACX9F,EAAQ0D,oBAERmC,EAEJ,OAAQnE,EAAKgD,MACX,IAAK,QACL,IAAK,QACL,IAAK,QACL,IAAK,SAEH,YADAhD,EAAKM,SAASmE,QAAQF,GAGxB,IAAK,KACHjG,EAAQoG,eACR,IAAK,MAAMC,KAAa3E,EAAKM,SAC3B,GAAuB,QAAnBqE,EAAU1E,KACd,OAAQ0E,EAAU3B,MAChB,IAAK,KACHwB,EAAiBG,GACjB,MAEF,IAAK,KACHR,EAAWQ,GACX,MAEF,SAIJrG,EAAQsG,gBACR,MAGF,UAzDJtG,EAAQuG,YACR7E,EAAKM,SAASmE,QAAQF,GACtBjG,EAAQwG,WAAW,CACjB1Q,WAAY6M,EAAc7M,WAC1B1G,kBAAmBuT,EAAcvT,kBACjCyG,WAAY8M,EAAc9M,WAC1BiE,mBAAoB6I,EAAc7I,qBArTtC,EAAQ,QA8WR3J,EAAOC,QAAU,CACfqW,OAAQzC,EACRjK,MAAO8I,EACP6D,WAAY/C,EACZgD,UAAWf,EACXgB,QAASrD,EACTsD,eAAgBzD,EAChB0D,MAAOlD,EACPmD,OAAQnE,EACRoE,UAAWhE,EACXiE,YAAajC,EACbkC,UAAW7D,EACX8D,IAAK7D,EACL8D,KAAM1E,EACN/H,MAAOgL,EACP0B,cAAetC,EACfuC,IAAKpE","file":"js/npm.html-to-text.c325188d.js","sourcesContent":["/* eslint-disable max-classes-per-file */\n\nconst { InlineTextBuilder } = require('./inline-text-builder');\n\n\nclass StackItem {\n constructor (next = null) { this.next = next; }\n\n getRoot () { return (this.next) ? this.next : this; }\n}\n\nclass BlockStackItem extends StackItem {\n constructor (options, next = null, leadingLineBreaks = 1, maxLineLength = undefined) {\n super(next);\n this.leadingLineBreaks = leadingLineBreaks;\n this.inlineTextBuilder = new InlineTextBuilder(options, maxLineLength);\n this.rawText = '';\n this.stashedLineBreaks = 0;\n this.isPre = next && next.isPre;\n }\n}\n\nclass TableStackItem extends StackItem {\n constructor (next = null) {\n super(next);\n this.rows = [];\n this.isPre = next && next.isPre;\n }\n}\n\nclass TableRowStackItem extends StackItem {\n constructor (next = null) {\n super(next);\n this.cells = [];\n this.isPre = next && next.isPre;\n }\n}\n\nclass TableCellStackItem extends StackItem {\n constructor (options, next = null, maxColumnWidth = undefined) {\n super(next);\n this.inlineTextBuilder = new InlineTextBuilder(options, maxColumnWidth);\n this.rawText = '';\n this.stashedLineBreaks = 0;\n this.isPre = next && next.isPre;\n }\n}\n\nclass TransformerStackItem extends StackItem {\n constructor (next = null, transform) {\n super(next);\n this.transform = transform;\n }\n}\n\nmodule.exports = {\n BlockStackItem: BlockStackItem,\n StackItem: StackItem,\n TableCellStackItem: TableCellStackItem,\n TableRowStackItem: TableRowStackItem,\n TableStackItem: TableStackItem,\n TransformerStackItem: TransformerStackItem,\n};\n","\nconst merge = require('deepmerge');\n\n/**\n * Given a list of class and ID selectors (prefixed with '.' and '#'),\n * return them as separate lists of names without prefixes.\n *\n * @param { string[] } selectors Class and ID selectors (`[\".class\", \"#id\"]` etc).\n * @returns { { classes: string[], ids: string[] } }\n */\nfunction splitClassesAndIds (selectors) {\n const classes = [];\n const ids = [];\n for (const selector of selectors) {\n if (selector.startsWith('.')) {\n classes.push(selector.substring(1));\n } else if (selector.startsWith('#')) {\n ids.push(selector.substring(1));\n }\n }\n return { classes: classes, ids: ids };\n}\n\n/**\n * Make a recursive function that will only run to a given depth\n * and switches to an alternative function at that depth. \\\n * No limitation if `n` is `undefined` (Just wraps `f` in that case).\n *\n * @param { number | undefined } n Allowed depth of recursion. `undefined` for no limitation.\n * @param { Function } f Function that accepts recursive callback as the first argument.\n * @param { Function } [g] Function to run instead, when maximum depth was reached. Do nothing by default.\n * @returns { Function }\n */\nfunction limitedDepthRecursive (n, f, g = () => undefined) {\n if (n === undefined) {\n const f1 = function (...args) { return f(f1, ...args); };\n return f1;\n }\n if (n >= 0) {\n return function (...args) { return f(limitedDepthRecursive(n - 1, f, g), ...args); };\n }\n return g;\n}\n\n/**\n * Convert a number into alphabetic sequence representation (Sequence without zeroes).\n *\n * For example: `a, ..., z, aa, ..., zz, aaa, ...`.\n *\n * @param { number } num Number to convert. Must be >= 1.\n * @param { string } [baseChar = 'a'] Character for 1 in the sequence.\n * @param { number } [base = 26] Number of characters in the sequence.\n * @returns { string }\n */\nfunction numberToLetterSequence (num, baseChar = 'a', base = 26) {\n const digits = [];\n do {\n num -= 1;\n digits.push(num % base);\n num = (num / base) >> 0; // quick `floor`\n } while (num > 0);\n const baseCode = baseChar.charCodeAt(0);\n return digits\n .reverse()\n .map(n => String.fromCharCode(baseCode + n))\n .join('');\n}\n\nconst I = ['I', 'X', 'C', 'M'];\nconst V = ['V', 'L', 'D'];\n\n/**\n * Convert a number to it's Roman representation. No large numbers extension.\n *\n * @param { number } num Number to convert. `0 < num <= 3999`.\n * @returns { string }\n */\nfunction numberToRoman (num) {\n return [...(num) + '']\n .map(n => +n)\n .reverse()\n .map((v, i) => ((v % 5 < 4)\n ? (v < 5 ? '' : V[i]) + I[i].repeat(v % 5)\n : I[i] + (v < 5 ? V[i] : I[i + 1])))\n .reverse()\n .join('');\n}\n\n/**\n * Return the same string or a substring with the given character occurences removed from each end if any.\n *\n * @param { string } str A string to trim.\n * @param { string } char A character to be trimmed.\n * @returns { string }\n */\nfunction trimCharacter (str, char) {\n let start = 0;\n let end = str.length;\n while (start < end && str[start] === char) { ++start; }\n while (end > start && str[end - 1] === char) { --end; }\n return (start > 0 || end < str.length)\n ? str.substring(start, end)\n : str;\n}\n\n/**\n * Get a nested property from an object.\n *\n * @param { object } obj The object to query for the value.\n * @param { string[] } path The path to the property.\n * @returns { any }\n */\nfunction get (obj, path) {\n for (const key of path) {\n if (!obj) { return undefined; }\n obj = obj[key];\n }\n return obj;\n}\n\n/**\n * Set a nested property of an object.\n *\n * @param { object } obj The object to modify.\n * @param { string[] } path The path to the property.\n * @param { any } value The value to set.\n */\nfunction set (obj, path, value) {\n const valueKey = path.pop();\n for (const key of path) {\n let nested = obj[key];\n if (!nested) {\n nested = {};\n obj[key] = nested;\n }\n obj = nested;\n }\n obj[valueKey] = value;\n}\n\n/**\n * Deduplicate an array by a given key callback.\n * Item properties are merged recursively and with the preference for last defined values.\n * Of items with the same key, merged item takes the place of the last item,\n * others are omitted.\n *\n * @param { any[] } items An array to deduplicate.\n * @param { (x: any) => string } getKey Callback to get a value that distinguishes unique items.\n * @returns { any[] }\n */\nfunction mergeDuplicatesPreferLast (items, getKey) {\n const map = new Map();\n for (let i = items.length; i-- > 0;) {\n const item = items[i];\n const key = getKey(item);\n map.set(\n key,\n (map.has(key))\n ? merge(item, map.get(key), { arrayMerge: overwriteMerge })\n : item\n );\n }\n return [...map.values()].reverse();\n}\n\nconst overwriteMerge = (acc, src, options) => [...src];\n\nmodule.exports = {\n get: get,\n limitedDepthRecursive: limitedDepthRecursive,\n mergeDuplicatesPreferLast: mergeDuplicatesPreferLast,\n numberToLetterSequence: numberToLetterSequence,\n numberToRoman: numberToRoman,\n set: set,\n splitClassesAndIds: splitClassesAndIds,\n trimCharacter: trimCharacter\n};\n","\nfunction getRow (matrix, j) {\n if (!matrix[j]) { matrix[j] = []; }\n return matrix[j];\n}\n\nfunction findFirstVacantIndex (row, x = 0) {\n while (row[x]) { x++; }\n return x;\n}\n\nfunction transposeInPlace (matrix, maxSize) {\n for (let i = 0; i < maxSize; i++) {\n const rowI = getRow(matrix, i);\n for (let j = 0; j < i; j++) {\n const rowJ = getRow(matrix, j);\n const temp = rowI[j];\n rowI[j] = rowJ[i];\n rowJ[i] = temp;\n }\n }\n}\n\nfunction putCellIntoLayout (cell, layout, baseRow, baseCol) {\n for (let r = 0; r < cell.rowspan; r++) {\n const layoutRow = getRow(layout, baseRow + r);\n for (let c = 0; c < cell.colspan; c++) {\n layoutRow[baseCol + c] = cell;\n }\n }\n}\n\nfunction updateOffset (offsets, base, span, value) {\n offsets[base + span] = Math.max(\n offsets[base + span] || 0,\n offsets[base] + value\n );\n}\n\n/**\n * @typedef { object } TablePrinterCell\n * Cell definition for the table printer.\n *\n * @property { number } colspan Number of columns this cell occupies.\n * @property { number } rowspan Number of rows this cell occupies.\n * @property { string } text Cell contents (pre-wrapped).\n */\n\n/**\n * Render a table into string.\n * Cells can contain multiline text and span across multiple rows and columns.\n *\n * Modifies cells to add lines array.\n *\n * @param { TablePrinterCell[][] } tableRows Table to render.\n * @param { number } rowSpacing Number of spaces between columns.\n * @param { number } colSpacing Number of empty lines between rows.\n * @returns { string }\n */\nfunction tableToString (tableRows, rowSpacing, colSpacing) {\n const layout = [];\n let colNumber = 0;\n const rowNumber = tableRows.length;\n const rowOffsets = [0];\n // Fill the layout table and row offsets row-by-row.\n for (let j = 0; j < rowNumber; j++) {\n const layoutRow = getRow(layout, j);\n const cells = tableRows[j];\n let x = 0;\n for (let i = 0; i < cells.length; i++) {\n const cell = cells[i];\n x = findFirstVacantIndex(layoutRow, x);\n putCellIntoLayout(cell, layout, j, x);\n x += cell.colspan;\n cell.lines = cell.text.split('\\n');\n const cellHeight = cell.lines.length;\n updateOffset(rowOffsets, j, cell.rowspan, cellHeight + rowSpacing);\n }\n colNumber = (layoutRow.length > colNumber) ? layoutRow.length : colNumber;\n }\n\n transposeInPlace(layout, (rowNumber > colNumber) ? rowNumber : colNumber);\n\n const outputLines = [];\n const colOffsets = [0];\n // Fill column offsets and output lines column-by-column.\n for (let x = 0; x < colNumber; x++) {\n let y = 0;\n let cell;\n while (y < rowNumber && (cell = layout[x][y])) {\n if (!cell.rendered) {\n let cellWidth = 0;\n for (let j = 0; j < cell.lines.length; j++) {\n const line = cell.lines[j];\n const lineOffset = rowOffsets[y] + j;\n outputLines[lineOffset] = (outputLines[lineOffset] || '').padEnd(colOffsets[x]) + line;\n cellWidth = (line.length > cellWidth) ? line.length : cellWidth;\n }\n updateOffset(colOffsets, x, cell.colspan, cellWidth + colSpacing);\n cell.rendered = true;\n }\n y += cell.rowspan;\n }\n }\n\n return outputLines.join('\\n');\n}\n\nmodule.exports = { tableToString: tableToString };\n","\n// eslint-disable-next-line no-unused-vars\nconst { InlineTextBuilder } = require('./inline-text-builder');\n\n// eslint-disable-next-line import/no-unassigned-import\nrequire('./typedefs');\n\n\nfunction charactersToCodes (str) {\n return [...str]\n .map(c => '\\\\u' + c.charCodeAt(0).toString(16).padStart(4, '0'))\n .join('');\n}\n\n/**\n * Helps to handle HTML whitespaces.\n *\n * @class WhitespaceProcessor\n */\nclass WhitespaceProcessor {\n\n /**\n * Creates an instance of WhitespaceProcessor.\n *\n * @param { Options } options HtmlToText options.\n * @memberof WhitespaceProcessor\n */\n constructor (options) {\n this.whitespaceChars = (options.preserveNewlines)\n ? options.whitespaceCharacters.replace(/\\n/g, '')\n : options.whitespaceCharacters;\n const whitespaceCodes = charactersToCodes(this.whitespaceChars);\n this.leadingWhitespaceRe = new RegExp(`^[${whitespaceCodes}]`);\n this.trailingWhitespaceRe = new RegExp(`[${whitespaceCodes}]$`);\n this.allWhitespaceOrEmptyRe = new RegExp(`^[${whitespaceCodes}]*$`);\n\n if (options.preserveNewlines) {\n\n const wordOrNewlineRe = new RegExp(`\\n|[^\\n${whitespaceCodes}]+`, 'gm');\n\n /**\n * Shrink whitespaces and wrap text, add to the builder.\n *\n * @param { string } text Input text.\n * @param { InlineTextBuilder } inlineTextBuilder A builder to receive processed text.\n * @param { (str: string) => string } [ transform ] A transform to be applied to words.\n */\n this.shrinkWrapAdd = function (text, inlineTextBuilder, transform = (str => str)) {\n if (!text) { return; }\n const previouslyStashedSpace = inlineTextBuilder.stashedSpace;\n let anyMatch = false;\n let m = wordOrNewlineRe.exec(text);\n if (m) {\n anyMatch = true;\n if (m[0] === '\\n') {\n inlineTextBuilder.startNewLine();\n } else if (previouslyStashedSpace || this.testLeadingWhitespace(text)) {\n inlineTextBuilder.pushWord(transform(m[0]));\n } else {\n inlineTextBuilder.concatWord(transform(m[0]));\n }\n while ((m = wordOrNewlineRe.exec(text)) !== null) {\n if (m[0] === '\\n') {\n inlineTextBuilder.startNewLine();\n } else {\n inlineTextBuilder.pushWord(transform(m[0]));\n }\n }\n }\n inlineTextBuilder.stashedSpace = (previouslyStashedSpace && !anyMatch) || (this.testTrailingWhitespace(text));\n // No need to stash a space in case last added item was a new line,\n // but that won't affect anything later anyway.\n };\n\n } else {\n\n const wordRe = new RegExp(`[^${whitespaceCodes}]+`, 'g');\n\n this.shrinkWrapAdd = function (text, inlineTextBuilder, transform = (str => str)) {\n if (!text) { return; }\n const previouslyStashedSpace = inlineTextBuilder.stashedSpace;\n let anyMatch = false;\n let m = wordRe.exec(text);\n if (m) {\n anyMatch = true;\n if (previouslyStashedSpace || this.testLeadingWhitespace(text)) {\n inlineTextBuilder.pushWord(transform(m[0]));\n } else {\n inlineTextBuilder.concatWord(transform(m[0]));\n }\n while ((m = wordRe.exec(text)) !== null) {\n inlineTextBuilder.pushWord(transform(m[0]));\n }\n }\n inlineTextBuilder.stashedSpace = (previouslyStashedSpace && !anyMatch) || this.testTrailingWhitespace(text);\n };\n\n }\n }\n\n /**\n * Test whether the given text starts with HTML whitespace character.\n *\n * @param { string } text The string to test.\n * @returns { boolean }\n */\n testLeadingWhitespace (text) {\n return this.leadingWhitespaceRe.test(text);\n }\n\n /**\n * Test whether the given text ends with HTML whitespace character.\n *\n * @param { string } text The string to test.\n * @returns { boolean }\n */\n testTrailingWhitespace (text) {\n return this.trailingWhitespaceRe.test(text);\n }\n\n /**\n * Test whether the given text contains any non-whitespace characters.\n *\n * @param { string } text The string to test.\n * @returns { boolean }\n */\n testContainsWords (text) {\n return !this.allWhitespaceOrEmptyRe.test(text);\n }\n\n}\n\nmodule.exports = { WhitespaceProcessor: WhitespaceProcessor };\n","\n// eslint-disable-next-line no-unused-vars\nconst { Picker } = require('selderee');\n\nconst { trimCharacter } = require('./helper');\n// eslint-disable-next-line no-unused-vars\nconst { StackItem, BlockStackItem, TableCellStackItem, TableRowStackItem, TableStackItem, TransformerStackItem }\n = require('./stack-item');\nconst { tableToString } = require('./table-printer');\nconst { WhitespaceProcessor } = require('./whitespace-processor');\n\n// eslint-disable-next-line import/no-unassigned-import\nrequire('./typedefs');\n\n\n/**\n * Helps to build text from inline and block elements.\n *\n * @class BlockTextBuilder\n */\nclass BlockTextBuilder {\n\n /**\n * Creates an instance of BlockTextBuilder.\n *\n * @param { Options } options HtmlToText options.\n * @param { Picker } picker Selectors decision tree picker.\n */\n constructor (options, picker) {\n this.options = options;\n this.picker = picker;\n this.whitepaceProcessor = new WhitespaceProcessor(options);\n /** @type { StackItem } */\n this._stackItem = new BlockStackItem(options);\n /** @type { TransformerStackItem } */\n this._wordTransformer = undefined;\n }\n\n /**\n * Put a word-by-word transform function onto the transformations stack.\n *\n * Mainly used for uppercasing. Can be bypassed to add unformatted text such as URLs.\n *\n * Word transformations applied before wrapping.\n *\n * @param { (str: string) => string } wordTransform Word transformation function.\n */\n pushWordTransform (wordTransform) {\n this._wordTransformer = new TransformerStackItem(this._wordTransformer, wordTransform);\n }\n\n /**\n * Remove a function from the word transformations stack.\n *\n * @returns { (str: string) => string } A function that was removed.\n */\n popWordTransform () {\n if (!this._wordTransformer) { return undefined; }\n const transform = this._wordTransformer.transform;\n this._wordTransformer = this._wordTransformer.next;\n return transform;\n }\n\n /** @returns { (str: string) => string } */\n _getCombinedWordTransformer () {\n const applyTransformer = (str, transformer) =>\n ((transformer) ? applyTransformer(transformer.transform(str), transformer.next) : str);\n return (str) => applyTransformer(str, this._wordTransformer);\n }\n\n _popStackItem () {\n const item = this._stackItem;\n this._stackItem = item.next;\n return item;\n }\n\n /**\n * Add a line break into currently built block.\n */\n addLineBreak () {\n if (!(\n this._stackItem instanceof BlockStackItem\n || this._stackItem instanceof TableCellStackItem\n )) { return; }\n if (this._stackItem.isPre) {\n this._stackItem.rawText += '\\n';\n } else {\n this._stackItem.inlineTextBuilder.startNewLine();\n }\n }\n\n /**\n * Allow to break line in case directly following text will not fit.\n */\n addWordBreakOpportunity () {\n if (\n this._stackItem instanceof BlockStackItem\n || this._stackItem instanceof TableCellStackItem\n ) {\n this._stackItem.inlineTextBuilder.wordBreakOpportunity = true;\n }\n }\n\n /**\n * Add a node inline into the currently built block.\n *\n * @param { string } str\n * Text content of a node to add.\n *\n * @param { object | boolean } [ optionsObjectOrNoWordTransform ]\n * Object holding the parameters of the operation.\n *\n * Boolean value is deprecated.\n *\n * @param { boolean } [ optionsObjectOrNoWordTransform.noWordTransform = false ]\n * Ignore word transformers if there are any.\n */\n addInline (str, optionsObjectOrNoWordTransform = {}) {\n if (typeof optionsObjectOrNoWordTransform === 'object') {\n this._addInline(str, optionsObjectOrNoWordTransform);\n } else {\n this._addInline(str, { noWordTransform: optionsObjectOrNoWordTransform });\n }\n }\n\n _addInline (str, { noWordTransform = false } = {}) {\n if (!(\n this._stackItem instanceof BlockStackItem\n || this._stackItem instanceof TableCellStackItem\n )) { return; }\n\n if (this._stackItem.isPre) {\n this._stackItem.rawText += str;\n return;\n }\n\n if (\n this.whitepaceProcessor.testContainsWords(str) || // There are words to add;\n (str.length && !this._stackItem.stashedLineBreaks) // or at least spaces to take into account.\n ) {\n if (this._stackItem.stashedLineBreaks) {\n this._stackItem.inlineTextBuilder.startNewLine(this._stackItem.stashedLineBreaks);\n }\n this.whitepaceProcessor.shrinkWrapAdd(\n str,\n this._stackItem.inlineTextBuilder,\n (this._wordTransformer && !noWordTransform) ? this._getCombinedWordTransformer() : undefined\n );\n this._stackItem.stashedLineBreaks = 0; // inline text doesn't introduce line breaks\n }\n }\n\n /**\n * Start building a new block.\n *\n * @param { object | number } [optionsObjectOrLeadingLineBreaks]\n * Object holding the parameters of the block.\n *\n * Number value is deprecated.\n *\n * @param { number } [optionsObjectOrLeadingLineBreaks.leadingLineBreaks = 1]\n * This block should have at least this number of line breaks to separate if from any preceding block.\n *\n * @param { number } [optionsObjectOrLeadingLineBreaks.reservedLineLength = 0]\n * Reserve this number of characters on each line for block markup.\n *\n * @param { boolean } [optionsObjectOrLeadingLineBreaks.isPre = false]\n * Should HTML whitespace be preserved inside this block.\n *\n * @param { number } [reservedLineLength]\n * Deprecated.\n *\n * @param { boolean } [isPre]\n * Deprecated.\n */\n openBlock (optionsObjectOrLeadingLineBreaks = {}, reservedLineLength = undefined, isPre = undefined) {\n if (typeof optionsObjectOrLeadingLineBreaks === 'object') {\n this._openBlock(optionsObjectOrLeadingLineBreaks);\n } else {\n this._openBlock({\n isPre: isPre,\n leadingLineBreaks: optionsObjectOrLeadingLineBreaks,\n reservedLineLength: reservedLineLength,\n });\n }\n }\n\n _openBlock ({ leadingLineBreaks = 1, reservedLineLength = 0, isPre = false } = {}) {\n const maxLineLength = Math.max(20, this._stackItem.inlineTextBuilder.maxLineLength - reservedLineLength);\n this._stackItem = new BlockStackItem(\n this.options,\n this._stackItem,\n leadingLineBreaks,\n maxLineLength\n );\n if (isPre) { this._stackItem.isPre = true; }\n }\n\n /**\n * Finalize currently built block, add it's content to the parent block.\n *\n * @param { object | number } [optionsObjectOrTrailingLineBreaks]\n * Object holding the parameters of the block.\n *\n * Number value is deprecated.\n *\n * @param { number } [optionsObjectOrTrailingLineBreaks.trailingLineBreaks = 1]\n * This block should have at least this number of line breaks to separate it from any following block.\n *\n * @param { (str: string) => string } [optionsObjectOrTrailingLineBreaks.blockTransform = undefined]\n * A function to transform the block text before adding to the parent block.\n * This happens after word wrap and should be used in combination with reserved line length\n * in order to keep line lengths correct.\n * Used for whole block markup.\n *\n * @param { (str: string) => string } [blockTransform]\n * Deprecated.\n */\n closeBlock (optionsObjectOrTrailingLineBreaks = {}, blockTransform = undefined) {\n if (typeof optionsObjectOrTrailingLineBreaks === 'object') {\n this._closeBlock(optionsObjectOrTrailingLineBreaks);\n } else {\n this._closeBlock({\n trailingLineBreaks: optionsObjectOrTrailingLineBreaks,\n blockTransform: blockTransform,\n });\n }\n }\n\n _closeBlock ({ trailingLineBreaks = 1, blockTransform = undefined } = {}) {\n const block = this._popStackItem();\n const blockText = (blockTransform) ? blockTransform(getText(block)) : getText(block);\n addText(this._stackItem, blockText, block.leadingLineBreaks, Math.max(block.stashedLineBreaks, trailingLineBreaks));\n }\n\n /**\n * Start building a table.\n */\n openTable () {\n this._stackItem = new TableStackItem(this._stackItem);\n }\n\n /**\n * Start building a table row.\n */\n openTableRow () {\n if (!(this._stackItem instanceof TableStackItem)) {\n throw new Error('Can\\'t add table row to something that is not a table! Check the formatter.');\n }\n this._stackItem = new TableRowStackItem(this._stackItem);\n }\n\n /**\n * Start building a table cell.\n *\n * @param { object | number } [optionsObjectOrMaxColumnWidth = undefined]\n * Object holding the parameters of the cell.\n *\n * Number value is deprecated.\n *\n * @param { number } [optionsObjectOrMaxColumnWidth.maxColumnWidth = undefined]\n * Wrap cell content to this width. Fall back to global wordwrap value if undefined.\n */\n openTableCell (optionsObjectOrMaxColumnWidth = {}) {\n if (typeof optionsObjectOrMaxColumnWidth === 'object') {\n this._openTableCell(optionsObjectOrMaxColumnWidth);\n } else {\n this._openTableCell({ maxColumnWidth: optionsObjectOrMaxColumnWidth });\n }\n }\n\n _openTableCell ({ maxColumnWidth = undefined } = {}) {\n if (!(this._stackItem instanceof TableRowStackItem)) {\n throw new Error('Can\\'t add table cell to something that is not a table row! Check the formatter.');\n }\n this._stackItem = new TableCellStackItem(this.options, this._stackItem, maxColumnWidth);\n }\n\n /**\n * Finalize currently built table cell and add it to parent table row's cells.\n *\n * @param { object | number } [optionsObjectOrColspan]\n * Object holding the parameters of the cell.\n *\n * Number value is deprecated.\n *\n * @param { number } [optionsObjectOrColspan.colspan = 1] How many columns this cell should occupy.\n * @param { number } [optionsObjectOrColspan.rowspan = 1] How many rows this cell should occupy.\n *\n * @param { number } [rowspan] Deprecated.\n */\n closeTableCell (optionsObjectOrColspan = {}, rowspan = undefined) {\n if (typeof optionsObjectOrColspan === 'object') {\n this._closeTableCell(optionsObjectOrColspan);\n } else {\n this._closeTableCell({\n colspan: optionsObjectOrColspan,\n rowspan: rowspan,\n });\n }\n }\n\n _closeTableCell ({ colspan = 1, rowspan = 1 } = {}) {\n const cell = this._popStackItem();\n const text = trimCharacter(getText(cell), '\\n');\n cell.next.cells.push({ colspan: colspan, rowspan: rowspan, text: text });\n }\n\n /**\n * Finalize currently built table row and add it to parent table's rows.\n */\n closeTableRow () {\n const row = this._popStackItem();\n row.next.rows.push(row.cells);\n }\n\n /**\n * Finalize currently built table and add the rendered text to the parent block.\n *\n * @param { object | number } [optionsObjectOrColSpacing]\n * Object holding the parameters of the table.\n *\n * Number value is depreceted.\n *\n * @param { number } [optionsObjectOrColSpacing.colSpacing = 3]\n * Number of spaces between table columns.\n *\n * @param { number } [optionsObjectOrColSpacing.rowSpacing = 0]\n * Number of empty lines between table rows.\n *\n * @param { number } [optionsObjectOrColSpacing.leadingLineBreaks = 2]\n * This table should have at least this number of line breaks to separate if from any preceding block.\n *\n * @param { number } [optionsObjectOrColSpacing.trailingLineBreaks = 2]\n * This table should have at least this number of line breaks to separate it from any following block.\n *\n * @param { number } [rowSpacing]\n * Deprecated.\n *\n * @param { number } [leadingLineBreaks]\n * Deprecated.\n *\n * @param { number } [trailingLineBreaks]\n * Deprecated.\n */\n closeTable (\n optionsObjectOrColSpacing = {},\n rowSpacing = undefined,\n leadingLineBreaks = undefined,\n trailingLineBreaks = undefined\n ) {\n if (typeof optionsObjectOrColSpacing === 'object') {\n this._closeTable(optionsObjectOrColSpacing);\n } else {\n this._closeTable({\n colSpacing: optionsObjectOrColSpacing,\n leadingLineBreaks: leadingLineBreaks,\n rowSpacing: rowSpacing,\n trailingLineBreaks: trailingLineBreaks\n });\n }\n }\n\n _closeTable ({ colSpacing = 3, rowSpacing = 0, leadingLineBreaks = 2, trailingLineBreaks = 2 } = {}) {\n const table = this._popStackItem();\n const output = tableToString(table.rows, rowSpacing, colSpacing);\n if (output) {\n addText(this._stackItem, output, leadingLineBreaks, trailingLineBreaks);\n }\n }\n\n /**\n * Return the rendered text content of this builder.\n *\n * @returns { string }\n */\n toString () {\n return getText(this._stackItem.getRoot());\n // There should only be the root item if everything is closed properly.\n }\n\n}\n\nfunction getText (stackItem) {\n if (!(\n stackItem instanceof BlockStackItem\n || stackItem instanceof TableCellStackItem\n )) {\n throw new Error('Only blocks and table cells can be requested for text contents.');\n }\n return (stackItem.inlineTextBuilder.isEmpty())\n ? stackItem.rawText\n : stackItem.rawText + stackItem.inlineTextBuilder.toString();\n}\n\nfunction addText (stackItem, text, leadingLineBreaks, trailingLineBreaks) {\n if (!(\n stackItem instanceof BlockStackItem\n || stackItem instanceof TableCellStackItem\n )) {\n throw new Error('Only blocks and table cells can contain text.');\n }\n const parentText = getText(stackItem);\n const lineBreaks = Math.max(stackItem.stashedLineBreaks, leadingLineBreaks);\n stackItem.inlineTextBuilder.clear();\n if (parentText) {\n stackItem.rawText = parentText + '\\n'.repeat(lineBreaks) + text;\n } else {\n stackItem.rawText = text;\n stackItem.leadingLineBreaks = lineBreaks;\n }\n stackItem.stashedLineBreaks = trailingLineBreaks;\n}\n\nmodule.exports = { BlockTextBuilder: BlockTextBuilder };\n","// eslint-disable-next-line import/no-unassigned-import\nrequire('./typedefs');\n\n/**\n * Helps to build text from words.\n */\nclass InlineTextBuilder {\n /**\n * Creates an instance of InlineTextBuilder.\n *\n * If `maxLineLength` is not provided then it is either `options.wordwrap` or unlimited.\n *\n * @param { Options } options HtmlToText options.\n * @param { number } [ maxLineLength ] This builder will try to wrap text to fit this line length.\n */\n constructor (options, maxLineLength = undefined) {\n /** @type { string[][] } */\n this.lines = [];\n /** @type { string[] } */\n this.nextLineWords = [];\n this.maxLineLength = maxLineLength || options.wordwrap || Number.MAX_VALUE;\n this.nextLineAvailableChars = this.maxLineLength;\n this.wrapCharacters = options.longWordSplit.wrapCharacters || [];\n this.forceWrapOnLimit = options.longWordSplit.forceWrapOnLimit || false;\n\n this.stashedSpace = false;\n this.wordBreakOpportunity = false;\n }\n\n /**\n * Add a new word.\n *\n * @param { string } word A word to add.\n */\n pushWord (word) {\n if (this.nextLineAvailableChars <= 0) {\n this.startNewLine();\n }\n const isLineStart = this.nextLineWords.length === 0;\n const cost = word.length + (isLineStart ? 0 : 1);\n if (cost <= this.nextLineAvailableChars) { // Fits into available budget\n\n this.nextLineWords.push(word);\n this.nextLineAvailableChars -= cost;\n\n } else { // Does not fit - try to split the word\n\n // The word is moved to a new line - prefer to wrap between words.\n const [first, ...rest] = this.splitLongWord(word);\n if (!isLineStart) { this.startNewLine(); }\n this.nextLineWords.push(first);\n this.nextLineAvailableChars -= first.length;\n for (const part of rest) {\n this.startNewLine();\n this.nextLineWords.push(part);\n this.nextLineAvailableChars -= part.length;\n }\n\n }\n }\n\n /**\n * Pop a word from the currently built line.\n * This doesn't affect completed lines.\n *\n * @returns { string }\n */\n popWord () {\n const lastWord = this.nextLineWords.pop();\n if (lastWord !== undefined) {\n const isLineStart = this.nextLineWords.length === 0;\n const cost = lastWord.length + (isLineStart ? 0 : 1);\n this.nextLineAvailableChars += cost;\n }\n return lastWord;\n }\n\n /**\n * Concat a word to the last word already in the builder.\n * Adds a new word in case there are no words yet in the last line.\n *\n * @param { string } word A word to be concatenated.\n */\n concatWord (word) {\n if (this.wordBreakOpportunity && word.length > this.nextLineAvailableChars) {\n this.pushWord(word);\n this.wordBreakOpportunity = false;\n } else {\n const lastWord = this.popWord();\n this.pushWord((lastWord) ? lastWord.concat(word) : word);\n }\n }\n\n /**\n * Add current line (and more empty lines if provided argument > 1) to the list of complete lines and start a new one.\n *\n * @param { number } n Number of line breaks that will be added to the resulting string.\n */\n startNewLine (n = 1) {\n this.lines.push(this.nextLineWords);\n if (n > 1) {\n this.lines.push(...Array.from({ length: n - 1 }, () => []));\n }\n this.nextLineWords = [];\n this.nextLineAvailableChars = this.maxLineLength;\n }\n\n /**\n * No words in this builder.\n *\n * @returns { boolean }\n */\n isEmpty () {\n return this.lines.length === 0\n && this.nextLineWords.length === 0;\n }\n\n clear () {\n this.lines.length = 0;\n this.nextLineWords.length = 0;\n this.nextLineAvailableChars = this.maxLineLength;\n }\n\n /**\n * Join all lines of words inside the InlineTextBuilder into a complete string.\n *\n * @returns { string }\n */\n toString () {\n return [...this.lines, this.nextLineWords]\n .map(words => words.join(' '))\n .join('\\n');\n }\n\n /**\n * Split a long word up to fit within the word wrap limit.\n * Use either a character to split looking back from the word wrap limit,\n * or truncate to the word wrap limit.\n *\n * @param { string } word Input word.\n * @returns { string[] } Parts of the word.\n */\n splitLongWord (word) {\n const parts = [];\n let idx = 0;\n while (word.length > this.maxLineLength) {\n\n const firstLine = word.substring(0, this.maxLineLength);\n const remainingChars = word.substring(this.maxLineLength);\n\n const splitIndex = firstLine.lastIndexOf(this.wrapCharacters[idx]);\n\n if (splitIndex > -1) { // Found a character to split on\n\n word = firstLine.substring(splitIndex + 1) + remainingChars;\n parts.push(firstLine.substring(0, splitIndex + 1));\n\n } else { // Not found a character to split on\n\n idx++;\n if (idx < this.wrapCharacters.length) { // There is next character to try\n\n word = firstLine + remainingChars;\n\n } else { // No more characters to try\n\n if (this.forceWrapOnLimit) {\n parts.push(firstLine);\n word = remainingChars;\n if (word.length > this.maxLineLength) {\n continue;\n }\n } else {\n word = firstLine + remainingChars;\n }\n break;\n\n }\n\n }\n\n }\n parts.push(word); // Add remaining part to array\n return parts;\n }\n}\n\nmodule.exports = { InlineTextBuilder: InlineTextBuilder };\n","module.exports = require('./lib/html-to-text');\n","const { hp2Builder } = require('@selderee/plugin-htmlparser2');\nconst merge = require('deepmerge');\nconst he = require('he');\nconst htmlparser = require('htmlparser2');\nconst selderee = require('selderee');\n\nconst { BlockTextBuilder } = require('./block-text-builder');\nconst defaultFormatters = require('./formatter');\nconst { limitedDepthRecursive, mergeDuplicatesPreferLast, set } = require('./helper');\n\n// eslint-disable-next-line import/no-unassigned-import\nrequire('./typedefs');\n\n\n/**\n * Default options.\n *\n * @constant\n * @type { Options }\n * @default\n * @private\n */\nconst DEFAULT_OPTIONS = {\n baseElements: {\n selectors: [ 'body' ],\n orderBy: 'selectors', // 'selectors' | 'occurrence'\n returnDomByDefault: true\n },\n decodeOptions: {\n isAttributeValue: false,\n strict: false\n },\n formatters: {},\n limits: {\n ellipsis: '...',\n maxBaseElements: undefined,\n maxChildNodes: undefined,\n maxDepth: undefined,\n maxInputLength: (1 << 24) // 16_777_216\n },\n longWordSplit: {\n forceWrapOnLimit: false,\n wrapCharacters: []\n },\n preserveNewlines: false,\n selectors: [\n { selector: '*', format: 'inline' },\n {\n selector: 'a',\n format: 'anchor',\n options: {\n baseUrl: null,\n hideLinkHrefIfSameAsText: false,\n ignoreHref: false,\n noAnchorUrl: true,\n noLinkBrackets: false\n }\n },\n { selector: 'article', format: 'block' },\n { selector: 'aside', format: 'block' },\n {\n selector: 'blockquote',\n format: 'blockquote',\n options: { leadingLineBreaks: 2, trailingLineBreaks: 2, trimEmptyLines: true }\n },\n { selector: 'br', format: 'lineBreak' },\n { selector: 'div', format: 'block' },\n { selector: 'footer', format: 'block' },\n { selector: 'form', format: 'block' },\n { selector: 'h1', format: 'heading', options: { leadingLineBreaks: 3, trailingLineBreaks: 2, uppercase: true } },\n { selector: 'h2', format: 'heading', options: { leadingLineBreaks: 3, trailingLineBreaks: 2, uppercase: true } },\n { selector: 'h3', format: 'heading', options: { leadingLineBreaks: 3, trailingLineBreaks: 2, uppercase: true } },\n { selector: 'h4', format: 'heading', options: { leadingLineBreaks: 2, trailingLineBreaks: 2, uppercase: true } },\n { selector: 'h5', format: 'heading', options: { leadingLineBreaks: 2, trailingLineBreaks: 2, uppercase: true } },\n { selector: 'h6', format: 'heading', options: { leadingLineBreaks: 2, trailingLineBreaks: 2, uppercase: true } },\n { selector: 'header', format: 'block' },\n {\n selector: 'hr',\n format: 'horizontalLine',\n options: { leadingLineBreaks: 2, length: undefined, trailingLineBreaks: 2 }\n },\n { selector: 'img', format: 'image', options: { baseUrl: null } },\n { selector: 'main', format: 'block' },\n { selector: 'nav', format: 'block' },\n {\n selector: 'ol',\n format: 'orderedList',\n options: { leadingLineBreaks: 2, trailingLineBreaks: 2 }\n },\n { selector: 'p', format: 'paragraph', options: { leadingLineBreaks: 2, trailingLineBreaks: 2 } },\n { selector: 'pre', format: 'pre', options: { leadingLineBreaks: 2, trailingLineBreaks: 2 } },\n { selector: 'section', format: 'block' },\n {\n selector: 'table',\n format: 'table',\n options: {\n colSpacing: 3,\n leadingLineBreaks: 2,\n maxColumnWidth: 60,\n rowSpacing: 0,\n trailingLineBreaks: 2,\n uppercaseHeaderCells: true\n }\n },\n {\n selector: 'ul',\n format: 'unorderedList',\n options: { itemPrefix: ' * ', leadingLineBreaks: 2, trailingLineBreaks: 2 }\n },\n { selector: 'wbr', format: 'wbr' },\n ],\n tables: [], // deprecated\n whitespaceCharacters: ' \\t\\r\\n\\f\\u200b',\n wordwrap: 80\n};\n\nconst concatMerge = (acc, src, options) => [...acc, ...src];\nconst overwriteMerge = (acc, src, options) => [...src];\nconst selectorsMerge = (acc, src, options) => (\n (acc.some(s => typeof s === 'object'))\n ? concatMerge(acc, src, options) // selectors\n : overwriteMerge(acc, src, options) // baseElements.selectors\n);\n\n/**\n * Preprocess options, compile selectors into a decision tree,\n * return a function intended for batch processing.\n *\n * @param { Options } [options = {}] HtmlToText options.\n * @returns { (html: string) => string } Pre-configured converter function.\n * @static\n */\nfunction compile (options = {}) {\n options = merge(\n DEFAULT_OPTIONS,\n options,\n {\n arrayMerge: overwriteMerge,\n customMerge: (key) => ((key === 'selectors') ? selectorsMerge : undefined)\n }\n );\n options.formatters = Object.assign({}, defaultFormatters, options.formatters);\n\n handleDeprecatedOptions(options);\n\n const uniqueSelectors = mergeDuplicatesPreferLast(options.selectors, (s => s.selector));\n const selectorsWithoutFormat = uniqueSelectors.filter(s => !s.format);\n if (selectorsWithoutFormat.length) {\n throw new Error(\n 'Following selectors have no specified format: ' +\n selectorsWithoutFormat.map(s => `\\`${s.selector}\\``).join(', ')\n );\n }\n const picker = new selderee.DecisionTree(\n uniqueSelectors.map(s => [s.selector, s])\n ).build(hp2Builder);\n\n const baseSelectorsPicker = new selderee.DecisionTree(\n options.baseElements.selectors.map((s, i) => [s, i + 1])\n ).build(hp2Builder);\n function findBaseElements (dom) {\n return findBases(dom, options, baseSelectorsPicker);\n }\n\n const limitedWalk = limitedDepthRecursive(\n options.limits.maxDepth,\n recursiveWalk,\n function (dom, builder) {\n builder.addInline(options.limits.ellipsis || '');\n }\n );\n\n return function (html) {\n return process(html, options, picker, findBaseElements, limitedWalk);\n };\n}\n\n/**\n * Convert given HTML according to preprocessed options.\n *\n * @param { string } html HTML content to convert.\n * @param { Options } options HtmlToText options (preprocessed).\n * @param { Picker } picker\n * Tag definition picker for DOM nodes processing.\n * @param { (dom: DomNode[]) => DomNode[] } findBaseElements\n * Function to extract elements from HTML DOM\n * that will only be present in the output text.\n * @param { RecursiveCallback } walk Recursive callback.\n * @returns { string }\n */\nfunction process (html, options, picker, findBaseElements, walk) {\n const maxInputLength = options.limits.maxInputLength;\n if (maxInputLength && html && html.length > maxInputLength) {\n console.warn(\n `Input length ${html.length} is above allowed limit of ${maxInputLength}. Truncating without ellipsis.`\n );\n html = html.substring(0, maxInputLength);\n }\n\n const handler = new htmlparser.DomHandler();\n new htmlparser.Parser(handler, { decodeEntities: false }).parseComplete(html);\n\n const bases = findBaseElements(handler.dom);\n const builder = new BlockTextBuilder(options, picker);\n walk(bases, builder);\n return builder.toString();\n}\n\n/**\n * Convert given HTML content to plain text string.\n *\n * @param { string } html HTML content to convert.\n * @param { Options } [options = {}] HtmlToText options.\n * @returns { string } Plain text string.\n * @static\n *\n * @example\n * const { convert } = require('html-to-text');\n * const text = convert('

Hello World

', {\n * wordwrap: 130\n * });\n * console.log(text); // HELLO WORLD\n */\nfunction convert (html, options = {}) {\n return compile(options)(html);\n}\n\n/**\n * Map previously existing and now deprecated options to the new options layout.\n * This is a subject for cleanup in major releases.\n *\n * @param { Options } options HtmlToText options.\n */\nfunction handleDeprecatedOptions (options) {\n const selectorDefinitions = options.selectors;\n\n if (options.tags) {\n const tagDefinitions = Object.entries(options.tags).map(\n ([selector, definition]) => ({ ...definition, selector: selector || '*' })\n );\n selectorDefinitions.push(...tagDefinitions);\n }\n\n function copyFormatterOption (source, format, target) {\n if (options[source] === undefined) { return; }\n for (const definition of selectorDefinitions) {\n if (definition.format === format) {\n set(definition, ['options', target], options[source]);\n }\n }\n }\n\n copyFormatterOption('hideLinkHrefIfSameAsText', 'anchor', 'hideLinkHrefIfSameAsText');\n copyFormatterOption('ignoreHref', 'anchor', 'ignoreHref');\n copyFormatterOption('linkHrefBaseUrl', 'anchor', 'baseUrl');\n copyFormatterOption('noAnchorUrl', 'anchor', 'noAnchorUrl');\n copyFormatterOption('noLinkBrackets', 'anchor', 'noLinkBrackets');\n\n copyFormatterOption('linkHrefBaseUrl', 'image', 'baseUrl');\n\n copyFormatterOption('unorderedListItemPrefix', 'unorderedList', 'itemPrefix');\n\n copyFormatterOption('uppercaseHeadings', 'heading', 'uppercase');\n copyFormatterOption('uppercaseHeadings', 'table', 'uppercaseHeadings');\n copyFormatterOption('uppercaseHeadings', 'dataTable', 'uppercaseHeadings');\n\n if (options['ignoreImage']) {\n for (const definition of selectorDefinitions) {\n if (definition.format === 'image') {\n definition.format = 'skip';\n }\n }\n }\n\n if (options['singleNewLineParagraphs']) {\n for (const definition of selectorDefinitions) {\n if (definition.format === 'paragraph' || definition.format === 'pre') {\n set(definition, ['options', 'leadingLineBreaks'], 1);\n set(definition, ['options', 'trailingLineBreaks'], 1);\n }\n }\n }\n\n if (options['baseElement']) {\n const baseElement = options['baseElement'];\n set(\n options,\n ['baseElements', 'selectors'],\n (Array.isArray(baseElement) ? baseElement : [baseElement])\n );\n }\n if (options['returnDomByDefault'] !== undefined) {\n set(options, ['baseElements', 'returnDomByDefault'], options['returnDomByDefault']);\n }\n}\n\nfunction findBases (dom, options, baseSelectorsPicker) {\n const results = [];\n\n function recursiveWalk (walk, /** @type { DomNode[] } */ dom) {\n dom = dom.slice(0, options.limits.maxChildNodes);\n for (const elem of dom) {\n if (elem.type !== 'tag') {\n continue;\n }\n const pickedSelectorIndex = baseSelectorsPicker.pick1(elem);\n if (pickedSelectorIndex > 0) {\n results.push({ selectorIndex: pickedSelectorIndex, element: elem });\n } else if (elem.children) {\n walk(elem.children);\n }\n if (results.length >= options.limits.maxBaseElements) {\n return;\n }\n }\n }\n\n const limitedWalk = limitedDepthRecursive(\n options.limits.maxDepth,\n recursiveWalk\n );\n limitedWalk(dom);\n\n if (options.baseElements.orderBy !== 'occurrence') { // 'selectors'\n results.sort((a, b) => a.selectorIndex - b.selectorIndex);\n }\n return (options.baseElements.returnDomByDefault && results.length === 0)\n ? dom\n : results.map(x => x.element);\n}\n\n/**\n * Function to walk through DOM nodes and accumulate their string representations.\n *\n * @param { RecursiveCallback } walk Recursive callback.\n * @param { DomNode[] } [dom] Nodes array to process.\n * @param { BlockTextBuilder } builder Passed around to accumulate output text.\n * @private\n */\nfunction recursiveWalk (walk, dom, builder) {\n if (!dom) { return; }\n\n const options = builder.options;\n\n const tooManyChildNodes = dom.length > options.limits.maxChildNodes;\n if (tooManyChildNodes) {\n dom = dom.slice(0, options.limits.maxChildNodes);\n dom.push({\n data: options.limits.ellipsis,\n type: 'text'\n });\n }\n\n for (const elem of dom) {\n switch (elem.type) {\n case 'text': {\n builder.addInline(he.decode(elem.data, options.decodeOptions));\n break;\n }\n case 'tag': {\n const tagDefinition = builder.picker.pick1(elem);\n const format = options.formatters[tagDefinition.format];\n format(elem, walk, builder, tagDefinition.options || {});\n break;\n }\n default:\n /* do nothing */\n break;\n }\n }\n\n return;\n}\n\n/**\n * @deprecated Use `{ convert }` function instead!\n * @see convert\n *\n * @param { string } html HTML content to convert.\n * @param { Options } [options = {}] HtmlToText options.\n * @returns { string } Plain text string.\n * @static\n */\nconst fromString = (html, options = {}) => convert(html, options);\n\nmodule.exports = {\n compile: compile,\n convert: convert,\n fromString: fromString,\n htmlToText: convert\n};\n","const he = require('he');\n\nconst { get, numberToLetterSequence, numberToRoman, splitClassesAndIds, trimCharacter } = require('./helper');\n\n// eslint-disable-next-line import/no-unassigned-import\nrequire('./typedefs');\n\n\n/**\n * Dummy formatter that discards the input and does nothing.\n *\n * @type { FormatCallback }\n */\nfunction formatSkip (elem, walk, builder, formatOptions) {\n /* do nothing */\n}\n\n/**\n * Process an inline-level element.\n *\n * @type { FormatCallback }\n */\nfunction formatInline (elem, walk, builder, formatOptions) {\n walk(elem.children, builder);\n}\n\n/**\n * Process a block-level container.\n *\n * @type { FormatCallback }\n */\nfunction formatBlock (elem, walk, builder, formatOptions) {\n builder.openBlock({ leadingLineBreaks: formatOptions.leadingLineBreaks });\n walk(elem.children, builder);\n builder.closeBlock({ trailingLineBreaks: formatOptions.trailingLineBreaks });\n}\n\n/**\n * Process a line-break.\n *\n * @type { FormatCallback }\n */\nfunction formatLineBreak (elem, walk, builder, formatOptions) {\n builder.addLineBreak();\n}\n\n/**\n * Process a `wbk` tag (word break opportunity).\n *\n * @type { FormatCallback }\n */\nfunction formatWbr (elem, walk, builder, formatOptions) {\n builder.addWordBreakOpportunity();\n}\n\n/**\n * Process a horizontal line.\n *\n * @type { FormatCallback }\n */\nfunction formatHorizontalLine (elem, walk, builder, formatOptions) {\n builder.openBlock({ leadingLineBreaks: formatOptions.leadingLineBreaks || 2 });\n builder.addInline('-'.repeat(formatOptions.length || builder.options.wordwrap || 40));\n builder.closeBlock({ trailingLineBreaks: formatOptions.trailingLineBreaks || 2 });\n}\n\n/**\n * Process a paragraph.\n *\n * @type { FormatCallback }\n */\nfunction formatParagraph (elem, walk, builder, formatOptions) {\n builder.openBlock({ leadingLineBreaks: formatOptions.leadingLineBreaks || 2 });\n walk(elem.children, builder);\n builder.closeBlock({ trailingLineBreaks: formatOptions.trailingLineBreaks || 2 });\n}\n\n/**\n * Process a preformatted content.\n *\n * @type { FormatCallback }\n */\nfunction formatPre (elem, walk, builder, formatOptions) {\n builder.openBlock({\n isPre: true,\n leadingLineBreaks: formatOptions.leadingLineBreaks || 2\n });\n walk(elem.children, builder);\n builder.closeBlock({ trailingLineBreaks: formatOptions.trailingLineBreaks || 2 });\n}\n\n/**\n * Process a heading.\n *\n * @type { FormatCallback }\n */\nfunction formatHeading (elem, walk, builder, formatOptions) {\n builder.openBlock({ leadingLineBreaks: formatOptions.leadingLineBreaks || 2 });\n if (formatOptions.uppercase !== false) {\n builder.pushWordTransform(str => str.toUpperCase());\n walk(elem.children, builder);\n builder.popWordTransform();\n } else {\n walk(elem.children, builder);\n }\n builder.closeBlock({ trailingLineBreaks: formatOptions.trailingLineBreaks || 2 });\n}\n\n/**\n * Process a blockquote.\n *\n * @type { FormatCallback }\n */\nfunction formatBlockquote (elem, walk, builder, formatOptions) {\n builder.openBlock({\n leadingLineBreaks: formatOptions.leadingLineBreaks || 2,\n reservedLineLength: 2\n });\n walk(elem.children, builder);\n builder.closeBlock({\n trailingLineBreaks: formatOptions.trailingLineBreaks || 2,\n blockTransform: str => ((formatOptions.trimEmptyLines !== false) ? trimCharacter(str, '\\n') : str)\n .split('\\n')\n .map(line => '> ' + line)\n .join('\\n')\n });\n}\n\n/**\n * Process an image.\n *\n * @type { FormatCallback }\n */\nfunction formatImage (elem, walk, builder, formatOptions) {\n const attribs = elem.attribs || {};\n const alt = (attribs.alt)\n ? he.decode(attribs.alt, builder.options.decodeOptions)\n : '';\n const src = (!attribs.src)\n ? ''\n : (formatOptions.baseUrl && attribs.src.indexOf('/') === 0)\n ? formatOptions.baseUrl + attribs.src\n : attribs.src;\n const text = (!src)\n ? alt\n : (!alt)\n ? '[' + src + ']'\n : alt + ' [' + src + ']';\n\n builder.addInline(text);\n}\n\n/**\n * Process an anchor.\n *\n * @type { FormatCallback }\n */\nfunction formatAnchor (elem, walk, builder, formatOptions) {\n function getHref () {\n if (formatOptions.ignoreHref) { return ''; }\n if (!elem.attribs || !elem.attribs.href) { return ''; }\n let href = elem.attribs.href.replace(/^mailto:/, '');\n if (formatOptions.noAnchorUrl && href[0] === '#') { return ''; }\n href = (formatOptions.baseUrl && href[0] === '/')\n ? formatOptions.baseUrl + href\n : href;\n return he.decode(href, builder.options.decodeOptions);\n }\n const href = getHref();\n if (!href) {\n walk(elem.children, builder);\n } else {\n let text = '';\n builder.pushWordTransform(\n str => {\n if (str) { text += str; }\n return str;\n }\n );\n walk(elem.children, builder);\n builder.popWordTransform();\n\n const hideSameLink = formatOptions.hideLinkHrefIfSameAsText && href === text;\n if (!hideSameLink) {\n builder.addInline(\n (!text)\n ? href\n : (formatOptions.noLinkBrackets)\n ? ' ' + href\n : ' [' + href + ']',\n { noWordTransform: true }\n );\n }\n }\n}\n\n/**\n * @param { DomNode } elem List items with their prefixes.\n * @param { RecursiveCallback } walk Recursive callback to process child nodes.\n * @param { BlockTextBuilder } builder Passed around to accumulate output text.\n * @param { FormatOptions } formatOptions Options specific to a formatter.\n * @param { () => string } nextPrefixCallback Function that returns inreasing index each time it is called.\n */\nfunction formatList (elem, walk, builder, formatOptions, nextPrefixCallback) {\n const isNestedList = get(elem, ['parent', 'name']) === 'li';\n\n // With Roman numbers, index length is not as straightforward as with Arabic numbers or letters,\n // so the dumb length comparison is the most robust way to get the correct value.\n let maxPrefixLength = 0;\n const listItems = (elem.children || [])\n // it might be more accuurate to check only for html spaces here, but no significant benefit\n .filter(child => child.type !== 'text' || !/^\\s*$/.test(child.data))\n .map(function (child) {\n if (child.name !== 'li') {\n return { node: child, prefix: '' };\n }\n const prefix = (isNestedList)\n ? nextPrefixCallback().trimStart()\n : nextPrefixCallback();\n if (prefix.length > maxPrefixLength) { maxPrefixLength = prefix.length; }\n return { node: child, prefix: prefix };\n });\n if (!listItems.length) { return; }\n\n const reservedLineLength = maxPrefixLength;\n const spacing = '\\n' + ' '.repeat(reservedLineLength);\n builder.openBlock({ leadingLineBreaks: isNestedList ? 1 : (formatOptions.leadingLineBreaks || 2) });\n for (const { node, prefix } of listItems) {\n builder.openBlock({\n leadingLineBreaks: 1,\n reservedLineLength: reservedLineLength\n });\n walk([node], builder);\n builder.closeBlock({\n trailingLineBreaks: 1,\n blockTransform: str => prefix + ' '.repeat(reservedLineLength - prefix.length) + str.replace(/\\n/g, spacing)\n });\n }\n builder.closeBlock({ trailingLineBreaks: isNestedList ? 1 : (formatOptions.trailingLineBreaks || 2) });\n}\n\n/**\n * Process an unordered list.\n *\n * @type { FormatCallback }\n */\nfunction formatUnorderedList (elem, walk, builder, formatOptions) {\n const prefix = formatOptions.itemPrefix || ' * ';\n return formatList(elem, walk, builder, formatOptions, () => prefix);\n}\n\n/**\n * Process an ordered list.\n *\n * @type { FormatCallback }\n */\nfunction formatOrderedList (elem, walk, builder, formatOptions) {\n let nextIndex = Number(elem.attribs.start || '1');\n const indexFunction = getOrderedListIndexFunction(elem.attribs.type);\n const nextPrefixCallback = () => ' ' + indexFunction(nextIndex++) + '. ';\n return formatList(elem, walk, builder, formatOptions, nextPrefixCallback);\n}\n\n/**\n * Return a function that can be used to generate index markers of a specified format.\n *\n * @param { string } [olType='1'] Marker type.\n * @returns { (i: number) => string }\n */\nfunction getOrderedListIndexFunction (olType = '1') {\n switch (olType) {\n case 'a': return (i) => numberToLetterSequence(i, 'a');\n case 'A': return (i) => numberToLetterSequence(i, 'A');\n case 'i': return (i) => numberToRoman(i).toLowerCase();\n case 'I': return (i) => numberToRoman(i);\n case '1':\n default: return (i) => (i).toString();\n }\n}\n\nfunction isDataTable (attr, tables) {\n if (tables === true) { return true; }\n if (!attr) { return false; }\n\n const { classes, ids } = splitClassesAndIds(tables);\n const attrClasses = (attr['class'] || '').split(' ');\n const attrIds = (attr['id'] || '').split(' ');\n\n return attrClasses.some(x => classes.includes(x)) || attrIds.some(x => ids.includes(x));\n}\n\n/**\n * Process a table (either as a container or as a data table, depending on options).\n *\n * @type { FormatCallback }\n */\nfunction formatTable (elem, walk, builder, formatOptions) {\n return isDataTable(elem.attribs, builder.options.tables)\n ? formatDataTable(elem, walk, builder, formatOptions)\n : formatBlock(elem, walk, builder, formatOptions);\n}\n\n/**\n * Process a data table.\n *\n * @type { FormatCallback }\n */\nfunction formatDataTable (elem, walk, builder, formatOptions) {\n builder.openTable();\n elem.children.forEach(walkTable);\n builder.closeTable({\n colSpacing: formatOptions.colSpacing,\n leadingLineBreaks: formatOptions.leadingLineBreaks,\n rowSpacing: formatOptions.rowSpacing,\n trailingLineBreaks: formatOptions.trailingLineBreaks\n });\n\n function formatCell (cellNode) {\n const colspan = +get(cellNode, ['attribs', 'colspan']) || 1;\n const rowspan = +get(cellNode, ['attribs', 'rowspan']) || 1;\n builder.openTableCell({ maxColumnWidth: formatOptions.maxColumnWidth });\n walk(cellNode.children, builder);\n builder.closeTableCell({ colspan: colspan, rowspan: rowspan });\n }\n\n function walkTable (elem) {\n if (elem.type !== 'tag') { return; }\n\n const formatHeaderCell = (formatOptions.uppercaseHeaderCells !== false)\n ? (cellNode) => {\n builder.pushWordTransform(str => str.toUpperCase());\n formatCell(cellNode);\n builder.popWordTransform();\n }\n : formatCell;\n\n switch (elem.name) {\n case 'thead':\n case 'tbody':\n case 'tfoot':\n case 'center':\n elem.children.forEach(walkTable);\n return;\n\n case 'tr': {\n builder.openTableRow();\n for (const childOfTr of elem.children) {\n if (childOfTr.type !== 'tag') { continue; }\n switch (childOfTr.name) {\n case 'th': {\n formatHeaderCell(childOfTr);\n break;\n }\n case 'td': {\n formatCell(childOfTr);\n break;\n }\n default:\n // do nothing\n }\n }\n builder.closeTableRow();\n break;\n }\n\n default:\n // do nothing\n }\n }\n}\n\nmodule.exports = {\n anchor: formatAnchor,\n block: formatBlock,\n blockquote: formatBlockquote,\n dataTable: formatDataTable,\n heading: formatHeading,\n horizontalLine: formatHorizontalLine,\n image: formatImage,\n inline: formatInline,\n lineBreak: formatLineBreak,\n orderedList: formatOrderedList,\n paragraph: formatParagraph,\n pre: formatPre,\n skip: formatSkip,\n table: formatTable,\n unorderedList: formatUnorderedList,\n wbr: formatWbr\n};\n"],"sourceRoot":""}