diff --git a/dist/index.js b/dist/index.js index dca01d5..5a5ec5c 100644 --- a/dist/index.js +++ b/dist/index.js @@ -140,6 +140,7 @@ const file_command_1 = __nccwpck_require__(717); const utils_1 = __nccwpck_require__(5278); const os = __importStar(__nccwpck_require__(2037)); const path = __importStar(__nccwpck_require__(1017)); +const uuid_1 = __nccwpck_require__(5840); const oidc_utils_1 = __nccwpck_require__(8041); /** * The code to exit an action @@ -169,7 +170,14 @@ function exportVariable(name, val) { process.env[name] = convertedVal; const filePath = process.env['GITHUB_ENV'] || ''; if (filePath) { - const delimiter = '_GitHubActionsFileCommandDelimeter_'; + const delimiter = `ghadelimiter_${uuid_1.v4()}`; + // These should realistically never happen, but just in case someone finds a way to exploit uuid generation let's not allow keys or values that contain the delimiter. + if (name.includes(delimiter)) { + throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); + } + if (convertedVal.includes(delimiter)) { + throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); + } const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`; file_command_1.issueCommand('ENV', commandValue); } @@ -6582,8 +6590,9 @@ function compile(self) { .map(escapeRE) .join('|'); // (?!_) cause 1.5x slowdown - self.re.schema_test = RegExp('(^|(?!_)(?:[><\uff5c]|' + re.src_ZPCc + '))(' + slist + ')', 'i'); - self.re.schema_search = RegExp('(^|(?!_)(?:[><\uff5c]|' + re.src_ZPCc + '))(' + slist + ')', 'ig'); + self.re.schema_test = RegExp('(^|(?!_)(?:[><\uff5c]|' + re.src_ZPCc + '))(' + slist + ')', 'i'); + self.re.schema_search = RegExp('(^|(?!_)(?:[><\uff5c]|' + re.src_ZPCc + '))(' + slist + ')', 'ig'); + self.re.schema_at_start = RegExp('^' + self.re.schema_search.source, 'i'); self.re.pretest = RegExp( '(' + self.re.schema_test.source + ')|(' + self.re.host_fuzzy_test.source + ')|@', @@ -6898,6 +6907,33 @@ LinkifyIt.prototype.match = function match(text) { }; +/** + * LinkifyIt#matchAtStart(text) -> Match|null + * + * Returns fully-formed (not fuzzy) link if it starts at the beginning + * of the string, and null otherwise. + **/ +LinkifyIt.prototype.matchAtStart = function matchAtStart(text) { + // Reset scan cache + this.__text_cache__ = text; + this.__index__ = -1; + + if (!text.length) return null; + + var m = this.re.schema_at_start.exec(text); + if (!m) return null; + + var len = this.testSchemaAt(text, m[2], m[0].length); + if (!len) return null; + + this.__schema__ = m[2]; + this.__index__ = m.index + m[1].length; + this.__last_index__ = m.index + m[0].length + len; + + return createMatch(this, 0); +}; + + /** chainable * LinkifyIt#tlds(list [, keepOld]) -> this * - list (Array): list of tlds @@ -6975,6 +7011,7 @@ module.exports = LinkifyIt; module.exports = function (opts) { var re = {}; + opts = opts || {}; // Use direct extract instead of `regenerate` to reduse browserified size re.src_Any = (__nccwpck_require__(703).source); @@ -7014,7 +7051,8 @@ module.exports = function (opts) { re.src_host_terminator = - '(?=$|' + text_separators + '|' + re.src_ZPCc + ')(?!-|_|:\\d|\\.-|\\.(?!$|' + re.src_ZPCc + '))'; + '(?=$|' + text_separators + '|' + re.src_ZPCc + ')' + + '(?!' + (opts['---'] ? '-(?!--)|' : '-|') + '_|:\\d|\\.-|\\.(?!$|' + re.src_ZPCc + '))'; re.src_path = @@ -7027,7 +7065,7 @@ module.exports = function (opts) { '\\{(?:(?!' + re.src_ZCc + '|[}]).)*\\}|' + '\\"(?:(?!' + re.src_ZCc + '|["]).)+\\"|' + "\\'(?:(?!" + re.src_ZCc + "|[']).)+\\'|" + - "\\'(?=" + re.src_pseudo_letter + '|[-]).|' + // allow `I'm_king` if no pair found + "\\'(?=" + re.src_pseudo_letter + '|[-])|' + // allow `I'm_king` if no pair found '\\.{2,}[a-zA-Z0-9%/&]|' + // google has many dots in "google search" links (#66, #81). // github has ... in commit range links, // Restrict to @@ -7036,16 +7074,16 @@ module.exports = function (opts) { // - parts of file path // - params separator // until more examples found. - '\\.(?!' + re.src_ZCc + '|[.]).|' + - (opts && opts['---'] ? + '\\.(?!' + re.src_ZCc + '|[.]|$)|' + + (opts['---'] ? '\\-(?!--(?:[^-]|$))(?:-*)|' // `---` => long dash, terminate : '\\-+|' ) + - ',(?!' + re.src_ZCc + ').|' + // allow `,,,` in paths - ';(?!' + re.src_ZCc + ').|' + // allow `;` if not followed by space-like char - '\\!+(?!' + re.src_ZCc + '|[!]).|' + // allow `!!!` in paths, but not at the end - '\\?(?!' + re.src_ZCc + '|[?]).' + + ',(?!' + re.src_ZCc + '|$)|' + // allow `,,,` in paths + ';(?!' + re.src_ZCc + '|$)|' + // allow `;` if not followed by space-like char + '\\!+(?!' + re.src_ZCc + '|[!]|$)|' + // allow `!!!` in paths, but not at the end + '\\?(?!' + re.src_ZCc + '|[?]|$)' + ')+' + '|\\/' + ')?'; @@ -8586,7 +8624,10 @@ var _rules = [ [ 'inline', __nccwpck_require__(1951) ], [ 'linkify', __nccwpck_require__(5462) ], [ 'replacements', __nccwpck_require__(8373) ], - [ 'smartquotes', __nccwpck_require__(2178) ] + [ 'smartquotes', __nccwpck_require__(2178) ], + // `text_join` finds `text_special` tokens (for escape sequences) + // and joins them with the rest of the text + [ 'text_join', __nccwpck_require__(7502) ] ]; @@ -8650,6 +8691,7 @@ var Ruler = __nccwpck_require__(2093); var _rules = [ [ 'text', __nccwpck_require__(1117) ], + [ 'linkify', __nccwpck_require__(1783) ], [ 'newline', __nccwpck_require__(8774) ], [ 'escape', __nccwpck_require__(1836) ], [ 'backticks', __nccwpck_require__(8520) ], @@ -8662,11 +8704,18 @@ var _rules = [ [ 'entity', __nccwpck_require__(973) ] ]; +// `rule2` ruleset was created specifically for emphasis/strikethrough +// post-processing and may be changed in the future. +// +// Don't use this for anything except pairs (plugins working with `balance_pairs`). +// var _rules2 = [ [ 'balance_pairs', __nccwpck_require__(9418) ], [ 'strikethrough', (__nccwpck_require__(3015)/* .postProcess */ .g) ], [ 'emphasis', (__nccwpck_require__(1677)/* .postProcess */ .g) ], - [ 'text_collapse', __nccwpck_require__(2333) ] + // rules for pairs separate '**' into its own text tokens, which may be left unused, + // rule below merges unused segments back with the rest of the text + [ 'fragments_join', __nccwpck_require__(3807) ] ]; @@ -8859,7 +8908,8 @@ module.exports = { rules: [ 'normalize', 'block', - 'inline' + 'inline', + 'text_join' ] }, @@ -8894,7 +8944,7 @@ module.exports = { rules2: [ 'balance_pairs', 'emphasis', - 'text_collapse' + 'fragments_join' ] } } @@ -8997,7 +9047,8 @@ module.exports = { rules: [ 'normalize', 'block', - 'inline' + 'inline', + 'text_join' ] }, @@ -9013,7 +9064,7 @@ module.exports = { ], rules2: [ 'balance_pairs', - 'text_collapse' + 'fragments_join' ] } } @@ -11352,7 +11403,7 @@ function getLine(state, line) { var pos = state.bMarks[line] + state.tShift[line], max = state.eMarks[line]; - return state.src.substr(pos, max - pos); + return state.src.slice(pos, max); } function escapedSplit(str) { @@ -11686,8 +11737,17 @@ module.exports = function linkify(state) { level = currentToken.level; lastPos = 0; - for (ln = 0; ln < links.length; ln++) { + // forbid escape sequence at the start of the string, + // this avoids http\://example.com/ from being linkified as + // http://example.com/ + if (links.length > 0 && + links[0].index === 0 && + i > 0 && + tokens[i - 1].type === 'text_special') { + links = links.slice(1); + } + for (ln = 0; ln < links.length; ln++) { url = links[ln].url; fullUrl = state.md.normalizeLink(url); if (!state.md.validateLink(fullUrl)) { continue; } @@ -11800,19 +11860,18 @@ module.exports = function normalize(state) { // TODO: // - fractionals 1/2, 1/4, 3/4 -> ½, ¼, ¾ -// - miltiplication 2 x 4 -> 2 × 4 +// - multiplications 2 x 4 -> 2 × 4 var RARE_RE = /\+-|\.\.|\?\?\?\?|!!!!|,,|--/; // Workaround for phantomjs - need regex without /g flag, // or root check will fail every second time -var SCOPED_ABBR_TEST_RE = /\((c|tm|r|p)\)/i; +var SCOPED_ABBR_TEST_RE = /\((c|tm|r)\)/i; -var SCOPED_ABBR_RE = /\((c|tm|r|p)\)/ig; +var SCOPED_ABBR_RE = /\((c|tm|r)\)/ig; var SCOPED_ABBR = { c: '©', r: '®', - p: '§', tm: '™' }; @@ -11915,7 +11974,7 @@ var APOSTROPHE = '\u2019'; /* ’ */ function replaceAt(str, index, ch) { - return str.substr(0, index) + ch + str.substr(index + 1); + return str.slice(0, index) + ch + str.slice(index + 1); } function process_inlines(tokens, state) { @@ -12131,6 +12190,59 @@ StateCore.prototype.Token = Token; module.exports = StateCore; +/***/ }), + +/***/ 7502: +/***/ ((module) => { + +"use strict"; +// Join raw text tokens with the rest of the text +// +// This is set as a separate rule to provide an opportunity for plugins +// to run text replacements after text join, but before escape join. +// +// For example, `\:)` shouldn't be replaced with an emoji. +// + + + +module.exports = function text_join(state) { + var j, l, tokens, curr, max, last, + blockTokens = state.tokens; + + for (j = 0, l = blockTokens.length; j < l; j++) { + if (blockTokens[j].type !== 'inline') continue; + + tokens = blockTokens[j].children; + max = tokens.length; + + for (curr = 0; curr < max; curr++) { + if (tokens[curr].type === 'text_special') { + tokens[curr].type = 'text'; + } + } + + for (curr = last = 0; curr < max; curr++) { + if (tokens[curr].type === 'text' && + curr + 1 < max && + tokens[curr + 1].type === 'text') { + + // collapse two adjacent text nodes + tokens[curr + 1].content = tokens[curr].content + tokens[curr + 1].content; + } else { + if (curr !== last) { tokens[last] = tokens[curr]; } + + last++; + } + } + + if (curr !== last) { + tokens.length = last; + } + } +}; + + /***/ }), /***/ 3939: @@ -12583,38 +12695,45 @@ var NAMED_RE = /^&([a-z][a-z0-9]{1,31});/i; module.exports = function entity(state, silent) { - var ch, code, match, pos = state.pos, max = state.posMax; + var ch, code, match, token, pos = state.pos, max = state.posMax; - if (state.src.charCodeAt(pos) !== 0x26/* & */) { return false; } + if (state.src.charCodeAt(pos) !== 0x26/* & */) return false; - if (pos + 1 < max) { - ch = state.src.charCodeAt(pos + 1); + if (pos + 1 >= max) return false; - if (ch === 0x23 /* # */) { - match = state.src.slice(pos).match(DIGITAL_RE); - if (match) { + ch = state.src.charCodeAt(pos + 1); + + if (ch === 0x23 /* # */) { + match = state.src.slice(pos).match(DIGITAL_RE); + if (match) { + if (!silent) { + code = match[1][0].toLowerCase() === 'x' ? parseInt(match[1].slice(1), 16) : parseInt(match[1], 10); + + token = state.push('text_special', '', 0); + token.content = isValidEntityCode(code) ? fromCodePoint(code) : fromCodePoint(0xFFFD); + token.markup = match[0]; + token.info = 'entity'; + } + state.pos += match[0].length; + return true; + } + } else { + match = state.src.slice(pos).match(NAMED_RE); + if (match) { + if (has(entities, match[1])) { if (!silent) { - code = match[1][0].toLowerCase() === 'x' ? parseInt(match[1].slice(1), 16) : parseInt(match[1], 10); - state.pending += isValidEntityCode(code) ? fromCodePoint(code) : fromCodePoint(0xFFFD); + token = state.push('text_special', '', 0); + token.content = entities[match[1]]; + token.markup = match[0]; + token.info = 'entity'; } state.pos += match[0].length; return true; } - } else { - match = state.src.slice(pos).match(NAMED_RE); - if (match) { - if (has(entities, match[1])) { - if (!silent) { state.pending += entities[match[1]]; } - state.pos += match[0].length; - return true; - } - } } } - if (!silent) { state.pending += '&'; } - state.pos++; - return true; + return false; }; @@ -12639,45 +12758,113 @@ for (var i = 0; i < 256; i++) { ESCAPED.push(0); } module.exports = function escape(state, silent) { - var ch, pos = state.pos, max = state.posMax; - - if (state.src.charCodeAt(pos) !== 0x5C/* \ */) { return false; } + var ch1, ch2, origStr, escapedStr, token, pos = state.pos, max = state.posMax; + if (state.src.charCodeAt(pos) !== 0x5C/* \ */) return false; pos++; - if (pos < max) { - ch = state.src.charCodeAt(pos); + // '\' at the end of the inline block + if (pos >= max) return false; - if (ch < 256 && ESCAPED[ch] !== 0) { - if (!silent) { state.pending += state.src[pos]; } - state.pos += 2; - return true; + ch1 = state.src.charCodeAt(pos); + + if (ch1 === 0x0A) { + if (!silent) { + state.push('hardbreak', 'br', 0); } - if (ch === 0x0A) { - if (!silent) { - state.push('hardbreak', 'br', 0); - } + pos++; + // skip leading whitespaces from next line + while (pos < max) { + ch1 = state.src.charCodeAt(pos); + if (!isSpace(ch1)) break; + pos++; + } + + state.pos = pos; + return true; + } + escapedStr = state.src[pos]; + + if (ch1 >= 0xD800 && ch1 <= 0xDBFF && pos + 1 < max) { + ch2 = state.src.charCodeAt(pos + 1); + + if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) { + escapedStr += state.src[pos + 1]; pos++; - // skip leading whitespaces from next line - while (pos < max) { - ch = state.src.charCodeAt(pos); - if (!isSpace(ch)) { break; } - pos++; - } + } + } - state.pos = pos; - return true; + origStr = '\\' + escapedStr; + + if (!silent) { + token = state.push('text_special', '', 0); + + if (ch1 < 256 && ESCAPED[ch1] !== 0) { + token.content = escapedStr; + } else { + token.content = origStr; } + + token.markup = origStr; + token.info = 'escape'; } - if (!silent) { state.pending += '\\'; } - state.pos++; + state.pos = pos + 1; return true; }; +/***/ }), + +/***/ 3807: +/***/ ((module) => { + +"use strict"; +// Clean up tokens after emphasis and strikethrough postprocessing: +// merge adjacent text nodes into one and re-calculate all token levels +// +// This is necessary because initially emphasis delimiter markers (*, _, ~) +// are treated as their own separate text tokens. Then emphasis rule either +// leaves them as text (needed to merge with adjacent text) or turns them +// into opening/closing tags (which messes up levels inside). +// + + + +module.exports = function fragments_join(state) { + var curr, last, + level = 0, + tokens = state.tokens, + max = state.tokens.length; + + for (curr = last = 0; curr < max; curr++) { + // re-calculate levels after emphasis/strikethrough turns some text nodes + // into opening/closing tags + if (tokens[curr].nesting < 0) level--; // closing tag + tokens[curr].level = level; + if (tokens[curr].nesting > 0) level++; // opening tag + + if (tokens[curr].type === 'text' && + curr + 1 < max && + tokens[curr + 1].type === 'text') { + + // collapse two adjacent text nodes + tokens[curr + 1].content = tokens[curr].content + tokens[curr + 1].content; + } else { + if (curr !== last) { tokens[last] = tokens[curr]; } + + last++; + } + } + + if (curr !== last) { + tokens.length = last; + } +}; + + /***/ }), /***/ 7753: @@ -12692,6 +12879,14 @@ module.exports = function escape(state, silent) { var HTML_TAG_RE = (__nccwpck_require__(6537)/* .HTML_TAG_RE */ .n); +function isLinkOpen(str) { + return /^\s]/i.test(str); +} +function isLinkClose(str) { + return /^<\/a\s*>/i.test(str); +} + + function isLetter(ch) { /*eslint no-bitwise:0*/ var lc = ch | 0x20; // to lower case @@ -12727,6 +12922,9 @@ module.exports = function html_inline(state, silent) { if (!silent) { token = state.push('html_inline', '', 0); token.content = state.src.slice(pos, pos + match[0].length); + + if (isLinkOpen(token.content)) state.linkLevel++; + if (isLinkClose(token.content)) state.linkLevel--; } state.pos += match[0].length; return true; @@ -13038,7 +13236,9 @@ module.exports = function link(state, silent) { attrs.push([ 'title', title ]); } + state.linkLevel++; state.md.inline.tokenize(state); + state.linkLevel--; token = state.push('link_close', 'a', -1); } @@ -13049,6 +13249,72 @@ module.exports = function link(state, silent) { }; +/***/ }), + +/***/ 1783: +/***/ ((module) => { + +"use strict"; +// Process links like https://example.org/ + + + + +// RFC3986: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) +var SCHEME_RE = /(?:^|[^a-z0-9.+-])([a-z][a-z0-9.+-]*)$/i; + + +module.exports = function linkify(state, silent) { + var pos, max, match, proto, link, url, fullUrl, token; + + if (!state.md.options.linkify) return false; + if (state.linkLevel > 0) return false; + + pos = state.pos; + max = state.posMax; + + if (pos + 3 > max) return false; + if (state.src.charCodeAt(pos) !== 0x3A/* : */) return false; + if (state.src.charCodeAt(pos + 1) !== 0x2F/* / */) return false; + if (state.src.charCodeAt(pos + 2) !== 0x2F/* / */) return false; + + match = state.pending.match(SCHEME_RE); + if (!match) return false; + + proto = match[1]; + + link = state.md.linkify.matchAtStart(state.src.slice(pos - proto.length)); + if (!link) return false; + + url = link.url; + + // disallow '*' at the end of the link (conflicts with emphasis) + url = url.replace(/\*+$/, ''); + + fullUrl = state.md.normalizeLink(url); + if (!state.md.validateLink(fullUrl)) return false; + + if (!silent) { + state.pending = state.pending.slice(0, -proto.length); + + token = state.push('link_open', 'a', 1); + token.attrs = [ [ 'href', fullUrl ] ]; + token.markup = 'linkify'; + token.info = 'auto'; + + token = state.push('text', '', 0); + token.content = state.md.normalizeLinkText(url); + + token = state.push('link_close', 'a', -1); + token.markup = 'linkify'; + token.info = 'auto'; + } + + state.pos += url.length - proto.length; + return true; +}; + + /***/ }), /***/ 8774: @@ -13146,6 +13412,10 @@ function StateInline(src, md, env, outTokens) { // backtick length => last seen position this.backticks = {}; this.backticksScanned = false; + + // Counter used to disable inline linkify-it execution + // inside and markdown links + this.linkLevel = 0; } @@ -13500,55 +13770,6 @@ module.exports = function text(state, silent) { };*/ -/***/ }), - -/***/ 2333: -/***/ ((module) => { - -"use strict"; -// Clean up tokens after emphasis and strikethrough postprocessing: -// merge adjacent text nodes into one and re-calculate all token levels -// -// This is necessary because initially emphasis delimiter markers (*, _, ~) -// are treated as their own separate text tokens. Then emphasis rule either -// leaves them as text (needed to merge with adjacent text) or turns them -// into opening/closing tags (which messes up levels inside). -// - - - -module.exports = function text_collapse(state) { - var curr, last, - level = 0, - tokens = state.tokens, - max = state.tokens.length; - - for (curr = last = 0; curr < max; curr++) { - // re-calculate levels after emphasis/strikethrough turns some text nodes - // into opening/closing tags - if (tokens[curr].nesting < 0) level--; // closing tag - tokens[curr].level = level; - if (tokens[curr].nesting > 0) level++; // opening tag - - if (tokens[curr].type === 'text' && - curr + 1 < max && - tokens[curr + 1].type === 'text') { - - // collapse two adjacent text nodes - tokens[curr + 1].content = tokens[curr].content + tokens[curr + 1].content; - } else { - if (curr !== last) { tokens[last] = tokens[curr]; } - - last++; - } - } - - if (curr !== last) { - tokens.length = last; - } -}; - - /***/ }), /***/ 8622: @@ -13792,8 +14013,8 @@ module.exports = outputFormatter; /***/ }), -/***/ 2870: -/***/ ((module) => { +/***/ 2935: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; // @ts-check @@ -13810,11 +14031,15 @@ module.exports.frontMatterRe = // eslint-disable-next-line max-len /((^---\s*$[^]*?^---\s*$)|(^\+\+\+\s*$[^]*?^(\+\+\+|\.\.\.)\s*$)|(^\{\s*$[^]*?^\}\s*$))(\r\n|\r|\n|$)/m; -// Regular expression for matching inline disable/enable comments -const inlineCommentRe = +// Regular expression for matching the start of inline disable/enable comments +const inlineCommentStartRe = // eslint-disable-next-line max-len - //ig; -module.exports.inlineCommentRe = inlineCommentRe; + /()/ig; +module.exports.inlineCommentStartRe = inlineCommentStartRe; + +// Regular expression for matching HTML elements +const htmlElementRe = /<(([A-Za-z][A-Za-z0-9-]*)(?:\s[^`>]*)?)\/?>/g; +module.exports.htmlElementRe = htmlElementRe; // Regular expressions for range matching module.exports.bareUrlRe = /(?:http|ftp)s?:\/\/[^\s\]"']*(?:\/|[^\s\]"'\W])/ig; @@ -13824,12 +14049,17 @@ module.exports.orderedListItemMarkerRe = /^[\s>]*0*(\d+)[.)]/; // Regular expression for all instances of emphasis markers const emphasisMarkersRe = /[_*]/g; -// Regular expression for inline links and shortcut reference links -const linkRe = /(\[(?:[^[\]]|\[[^\]]*\])*\])(\(\S*\)|\[\S*\])?/g; -module.exports.linkRe = linkRe; +// Regular expression for blockquote prefixes +const blockquotePrefixRe = /^[>\s]*/; +module.exports.blockquotePrefixRe = blockquotePrefixRe; -// Regular expression for link reference definition lines -module.exports.linkReferenceRe = /^ {0,3}\[[^\]]+]:\s.*$/; +// Regular expression for reference links (full, collapsed, and shortcut) +const referenceLinkRe = + /!?\\?\[((?:\[[^\]\0]*]|[^\]\0])*)](?:(?:\[([^\]\0]*)\])|([^(])|$)/g; + +// Regular expression for link reference definitions +const linkReferenceDefinitionRe = /^ {0,3}\[([^\]]*[^\\])]:/; +module.exports.linkReferenceDefinitionRe = linkReferenceDefinitionRe; // All punctuation characters (normal and full-width) const allPunctuation = ".,;:!?。,;:!?"; @@ -13858,22 +14088,43 @@ module.exports.isObject = function isObject(obj) { return (obj !== null) && (typeof obj === "object") && !Array.isArray(obj); }; -// Returns true iff the input line is blank (no content) -// Example: Contains nothing, whitespace, or comment (unclosed start/end okay) -module.exports.isBlankLine = function isBlankLine(line) { - // Call to String.replace follows best practices and is not a security check - // False-positive for js/incomplete-multi-character-sanitization +/** + * Returns true iff the input line is blank (contains nothing, whitespace, or + * comments (unclosed start/end comments allowed)). + * + * @param {string} line Input line. + * @returns {boolean} True iff line is blank. + */ +function isBlankLine(line) { + const startComment = ""; + const removeComments = (s) => { + // eslint-disable-next-line no-constant-condition + while (true) { + const start = s.indexOf(startComment); + const end = s.indexOf(endComment); + if ((end !== -1) && ((start === -1) || (end < start))) { + // Unmatched end comment is first + s = s.slice(end + endComment.length); + } else if ((start !== -1) && (end !== -1)) { + // Start comment is before end comment + s = s.slice(0, start) + s.slice(end + endComment.length); + } else if ((start !== -1) && (end === -1)) { + // Unmatched start comment is last + s = s.slice(0, start); + } else { + // No more comments to remove + return s; + } + } + }; return ( !line || !line.trim() || - !line - .replace(//g, "") - .replace(//g, "") - .replace(/>/g, "") - .trim() + !removeComments(line).replace(/>/g, "").trim() ); -}; +} +module.exports.isBlankLine = isBlankLine; /** * Compare function for Array.prototype.sort for ascending order of numbers. @@ -13933,16 +14184,10 @@ module.exports.clearHtmlCommentText = function clearHtmlCommentText(text) { !content.endsWith("-") && !content.includes("--")); // If a valid block/inline comment... if (isValid) { - const inlineCommentIndex = text - .slice(i, j + htmlCommentEnd.length) - .search(inlineCommentRe); - // If not a markdownlint inline directive... - if (inlineCommentIndex === -1) { - text = - text.slice(0, i + htmlCommentBegin.length) + - content.replace(/[^\r\n]/g, ".") + - text.slice(j); - } + text = + text.slice(0, i + htmlCommentBegin.length) + + content.replace(/[^\r\n]/g, ".") + + text.slice(j); } } } @@ -14051,11 +14296,11 @@ module.exports.unorderedListStyleFor = function unorderedListStyleFor(token) { * @returns {void} */ function filterTokens(params, type, handler) { - params.tokens.forEach(function forToken(token) { + for (const token of params.tokens) { if (token.type === type) { handler(token); } - }); + } } module.exports.filterTokens = filterTokens; @@ -14106,11 +14351,11 @@ module.exports.getLineMetadata = function getLineMetadata(params) { filterTokens(params, "hr", (token) => { lineMetadata[token.map[0]][6] = true; }); - params.tokens.filter(isMathBlock).forEach((token) => { + for (const token of params.tokens.filter(isMathBlock)) { for (let i = token.map[0]; i < token.map[1]; i++) { lineMetadata[i][7] = true; } - }); + } return lineMetadata; }; @@ -14123,9 +14368,9 @@ module.exports.getLineMetadata = function getLineMetadata(params) { * @returns {void} */ function forEachLine(lineMetadata, handler) { - lineMetadata.forEach(function forMetadata(metadata) { + for (const metadata of lineMetadata) { handler(...metadata); - }); + } } module.exports.forEachLine = forEachLine; @@ -14137,7 +14382,7 @@ module.exports.flattenLists = function flattenLists(tokens) { let nesting = 0; const nestingStack = []; let lastWithMap = { "map": [ 0, 1 ] }; - tokens.forEach((token) => { + for (const token of tokens) { if ((token.type === "bullet_list_open") || (token.type === "ordered_list_open")) { // Save current context and start a new one @@ -14170,12 +14415,13 @@ module.exports.flattenLists = function flattenLists(tokens) { nestingStack.push(nesting); nesting = 0; } else if (token.type === "blockquote_close") { - nesting = nestingStack.pop(); - } else if (token.map) { + nesting = nestingStack.pop() || 0; + } + if (token.map) { // Track last token with map lastWithMap = token; } - }); + } return flattenedLists; }; @@ -14183,26 +14429,26 @@ module.exports.flattenLists = function flattenLists(tokens) { module.exports.forEachInlineChild = function forEachInlineChild(params, type, handler) { filterTokens(params, "inline", function forToken(token) { - token.children.forEach(function forChild(child) { + for (const child of token.children) { if (child.type === type) { handler(child, token); } - }); + } }); }; // Calls the provided function for each heading's content module.exports.forEachHeading = function forEachHeading(params, handler) { let heading = null; - params.tokens.forEach(function forToken(token) { + for (const token of params.tokens) { if (token.type === "heading_open") { heading = token; } else if (token.type === "heading_close") { heading = null; } else if ((token.type === "inline") && heading) { - handler(heading, token.content); + handler(heading, token.content, token); } - }); + } }; /** @@ -14214,84 +14460,71 @@ module.exports.forEachHeading = function forEachHeading(params, handler) { * @returns {void} */ function forEachInlineCodeSpan(input, handler) { - let currentLine = 0; - let currentColumn = 0; - let index = 0; - while (index < input.length) { - let startIndex = -1; - let startLine = -1; - let startColumn = -1; - let tickCount = 0; - let currentTicks = 0; - let state = "normal"; - // Deliberate <= so trailing 0 completes the last span (ex: "text `code`") - // False-positive for js/index-out-of-bounds - for (; index <= input.length; index++) { - const char = input[index]; - // Ignore backticks in link destination - if ((char === "[") && (state === "normal")) { - state = "linkTextOpen"; - } else if ((char === "]") && (state === "linkTextOpen")) { - state = "linkTextClosed"; - } else if ((char === "(") && (state === "linkTextClosed")) { - state = "linkDestinationOpen"; - } else if ( - ((char === "(") && (state === "linkDestinationOpen")) || - ((char === ")") && (state === "linkDestinationOpen")) || - (state === "linkTextClosed")) { - state = "normal"; - } - // Parse backtick open/close - if ((char === "`") && (state !== "linkDestinationOpen")) { - // Count backticks at start or end of code span - currentTicks++; - if ((startIndex === -1) || (startColumn === -1)) { - startIndex = index + 1; - } - } else { - if ((startIndex >= 0) && - (startColumn >= 0) && - (tickCount === currentTicks)) { - // Found end backticks; invoke callback for code span + const backtickRe = /`+/g; + let match = null; + const backticksLengthAndIndex = []; + while ((match = backtickRe.exec(input)) !== null) { + backticksLengthAndIndex.push([ match[0].length, match.index ]); + } + const newLinesIndex = []; + while ((match = newLineRe.exec(input)) !== null) { + newLinesIndex.push(match.index); + } + let lineIndex = 0; + let lineStartIndex = 0; + let k = 0; + for (let i = 0; i < backticksLengthAndIndex.length - 1; i++) { + const [ startLength, startIndex ] = backticksLengthAndIndex[i]; + if ((startIndex === 0) || (input[startIndex - 1] !== "\\")) { + for (let j = i + 1; j < backticksLengthAndIndex.length; j++) { + const [ endLength, endIndex ] = backticksLengthAndIndex[j]; + if (startLength === endLength) { + for (; k < newLinesIndex.length; k++) { + const newLineIndex = newLinesIndex[k]; + if (startIndex < newLineIndex) { + break; + } + lineIndex++; + lineStartIndex = newLineIndex + 1; + } + const columnIndex = startIndex - lineStartIndex + startLength; handler( - input.substring(startIndex, index - currentTicks), - startLine, startColumn, tickCount); - startIndex = -1; - startColumn = -1; - } else if ((startIndex >= 0) && (startColumn === -1)) { - // Found start backticks - tickCount = currentTicks; - startLine = currentLine; - startColumn = currentColumn; - } - // Not in backticks - currentTicks = 0; - } - if (char === "\n") { - // On next line - currentLine++; - currentColumn = 0; - } else if ((char === "\\") && - ((startIndex === -1) || (startColumn === -1)) && - (input[index + 1] !== "\n")) { - // Escape character outside code, skip next - index++; - currentColumn += 2; - } else { - // On next column - currentColumn++; + input.slice(startIndex + startLength, endIndex), + lineIndex, + columnIndex, + startLength + ); + i = j; + break; + } } } - if (startIndex >= 0) { - // Restart loop after unmatched start backticks (ex: "`text``code``") - index = startIndex; - currentLine = startLine; - currentColumn = startColumn; - } } } module.exports.forEachInlineCodeSpan = forEachInlineCodeSpan; +/** + * Adds ellipsis to the left/right/middle of the specified text. + * + * @param {string} text Text to ellipsify. + * @param {boolean} [start] True iff the start of the text is important. + * @param {boolean} [end] True iff the end of the text is important. + * @returns {string} Ellipsified text. + */ +function ellipsify(text, start, end) { + if (text.length <= 30) { + // Nothing to do + } else if (start && end) { + text = text.slice(0, 15) + "..." + text.slice(-15); + } else if (end) { + text = "..." + text.slice(-30); + } else { + text = text.slice(0, 30) + "..."; + } + return text; +} +module.exports.ellipsify = ellipsify; + /** * Adds a generic error object via the onError callback. * @@ -14332,16 +14565,8 @@ module.exports.addErrorDetailIf = function addErrorDetailIf( // Adds an error object with context via the onError callback module.exports.addErrorContext = function addErrorContext( onError, lineNumber, context, left, right, range, fixInfo) { - if (context.length <= 30) { - // Nothing to do - } else if (left && right) { - context = context.substr(0, 15) + "..." + context.substr(-15); - } else if (right) { - context = "..." + context.substr(-30); - } else { - context = context.substr(0, 30) + "..."; - } - addError(onError, lineNumber, null, context, range, fixInfo); + context = ellipsify(context, left, right); + addError(onError, lineNumber, undefined, context, range, fixInfo); }; /** @@ -14382,21 +14607,41 @@ module.exports.codeBlockAndSpanRanges = (params, lineMetadata) => { }; /** - * Determines whether the specified range overlaps another range. + * Returns an array of HTML element ranges. + * + * @param {Object} params RuleParams instance. + * @param {Object} lineMetadata Line metadata object. + * @returns {number[][]} Array of ranges (lineIndex, columnIndex, length). + */ +module.exports.htmlElementRanges = (params, lineMetadata) => { + const exclusions = []; + forEachLine(lineMetadata, (line, lineIndex, inCode) => { + let match = null; + // eslint-disable-next-line no-unmodified-loop-condition + while (!inCode && ((match = htmlElementRe.exec(line)) !== null)) { + exclusions.push([ lineIndex, match.index, match[0].length ]); + } + }); + return exclusions; +}; + +/** + * Determines whether the specified range is within another range. * * @param {number[][]} ranges Array of ranges (line, index, length). * @param {number} lineIndex Line index to check. * @param {number} index Index to check. * @param {number} length Length to check. - * @returns {boolean} True iff the specified range overlaps. + * @returns {boolean} True iff the specified range is within. */ -module.exports.overlapsAnyRange = (ranges, lineIndex, index, length) => ( +const withinAnyRange = (ranges, lineIndex, index, length) => ( !ranges.every((span) => ( (lineIndex !== span[0]) || - (index + length < span[1]) || - (index > span[1] + span[2]) + (index < span[1]) || + (index + length > span[1] + span[2]) )) ); +module.exports.withinAnyRange = withinAnyRange; // Returns a range object for a line by applying a RegExp module.exports.rangeFromRegExp = function rangeFromRegExp(line, regexp) { @@ -14424,6 +14669,82 @@ module.exports.frontMatterHasTitle = frontMatterLines.some((line) => frontMatterTitleRe.test(line)); }; +/** + * Calls the provided function for each link. + * + * @param {string} line Line of Markdown input. + * @param {Function} handler Function taking (index, link, text, destination). + * @returns {void} + */ +function forEachLink(line, handler) { + // Helper to find matching close symbol for link text/destination + const findClosingSymbol = (index) => { + const begin = line[index]; + const end = (begin === "[") ? "]" : ")"; + let nesting = 0; + let escaping = false; + let pointy = false; + for (let i = index + 1; i < line.length; i++) { + const current = line[i]; + if (current === "\\") { + escaping = !escaping; + } else if (!escaping && (current === begin)) { + nesting++; + } else if (!escaping && (current === end)) { + if (nesting > 0) { + nesting--; + } else if (!pointy) { + // Return index after matching close symbol + return i + 1; + } + } else if ((i === index + 1) && (begin === "(") && (current === "<")) { + pointy = true; + } else if (!escaping && pointy && current === ">") { + pointy = false; + nesting = 0; + } else { + escaping = false; + } + } + // No match found + return -1; + }; + // Scan line for unescaped "[" character + let escaping = false; + for (let i = 0; i < line.length; i++) { + const current = line[i]; + if (current === "\\") { + escaping = !escaping; + } else if (!escaping && (current === "[")) { + // Scan for matching close "]" of link text + const textEnd = findClosingSymbol(i); + if (textEnd !== -1) { + if ((line[textEnd] === "(") || (line[textEnd] === "[")) { + // Scan for matching close ")" or "]" of link destination + const destEnd = findClosingSymbol(textEnd); + if (destEnd !== -1) { + // Call handler with link text and destination + const link = line.slice(i, destEnd); + const text = line.slice(i, textEnd); + const dest = line.slice(textEnd, destEnd); + handler(i, link, text, dest); + i = destEnd; + } + } + if (i < textEnd) { + // Call handler with link text only + const text = line.slice(i, textEnd); + handler(i, text, text); + i = textEnd; + } + } + } else { + escaping = false; + } + } +} +module.exports.forEachLink = forEachLink; + /** * Returns a list of emphasis markers in code spans and links. * @@ -14434,17 +14755,16 @@ function emphasisMarkersInContent(params) { const { lines } = params; const byLine = new Array(lines.length); // Search links - lines.forEach((tokenLine, tokenLineIndex) => { + for (const [ tokenLineIndex, tokenLine ] of lines.entries()) { const inLine = []; - let linkMatch = null; - while ((linkMatch = linkRe.exec(tokenLine))) { + forEachLink(tokenLine, (index, match) => { let markerMatch = null; - while ((markerMatch = emphasisMarkersRe.exec(linkMatch[0]))) { - inLine.push(linkMatch.index + markerMatch.index); + while ((markerMatch = emphasisMarkersRe.exec(match))) { + inLine.push(index + markerMatch.index); } - } + }); byLine[tokenLineIndex] = inLine; - }); + } // Search code spans filterTokens(params, "inline", (token) => { const { children, lineNumber, map } = token; @@ -14454,7 +14774,7 @@ function emphasisMarkersInContent(params) { tokenLines.join("\n"), (code, lineIndex, column, tickCount) => { const codeLines = code.split(newLineRe); - codeLines.forEach((codeLine, codeLineIndex) => { + for (const [ codeLineIndex, codeLine ] of codeLines.entries()) { const byLineIndex = lineNumber - 1 + lineIndex + codeLineIndex; const inLine = byLine[byLineIndex]; const codeLineOffset = codeLineIndex ? 0 : column - 1 + tickCount; @@ -14463,7 +14783,7 @@ function emphasisMarkersInContent(params) { inLine.push(codeLineOffset + match.index); } byLine[byLineIndex] = inLine; - }); + } } ); } @@ -14472,19 +14792,152 @@ function emphasisMarkersInContent(params) { } module.exports.emphasisMarkersInContent = emphasisMarkersInContent; +/** + * Returns an object with information about reference links and images. + * + * @param {Object} lineMetadata Line metadata object. + * @returns {Object} Reference link/image data. + */ +function getReferenceLinkImageData(lineMetadata) { + // Initialize return values + const references = new Map(); + const shortcuts = new Set(); + const definitions = new Map(); + const duplicateDefinitions = []; + // Define helper functions + const normalizeLabel = (s) => s.toLowerCase().trim().replace(/\s+/g, " "); + const exclusions = []; + const excluded = (match) => withinAnyRange( + exclusions, 0, match.index, match[0].length - (match[3] || "").length + ); + // Convert input to single-line so multi-line links/images are easier + const lineOffsets = []; + let currentOffset = 0; + const contentLines = []; + forEachLine(lineMetadata, (line, lineIndex, inCode) => { + lineOffsets[lineIndex] = currentOffset; + if (!inCode) { + line = line.replace(blockquotePrefixRe, ""); + if (line.trim().length === 0) { + // Allow RegExp to detect the end of a block + line = "\0"; + } + contentLines.push(line); + currentOffset += line.length + 1; + } + }); + lineOffsets.push(currentOffset); + const contentLine = contentLines.join(" "); + // Determine single-line exclusions for inline code spans + forEachInlineCodeSpan(contentLine, (code, lineIndex, columnIndex) => { + exclusions.push([ 0, columnIndex, code.length ]); + }); + // Identify all link/image reference definitions + forEachLine(lineMetadata, (line, lineIndex, inCode) => { + if (!inCode) { + const linkReferenceDefinitionMatch = linkReferenceDefinitionRe.exec(line); + if (linkReferenceDefinitionMatch) { + const label = normalizeLabel(linkReferenceDefinitionMatch[1]); + if (definitions.has(label)) { + duplicateDefinitions.push([ label, lineIndex ]); + } else { + definitions.set(label, lineIndex); + } + exclusions.push([ 0, lineOffsets[lineIndex], line.length ]); + } + } + }); + // Identify all link and image references + let lineIndex = 0; + const pendingContents = [ + { + "content": contentLine, + "contentLineIndex": 0, + "contentIndex": 0, + "topLevel": true + } + ]; + let pendingContent = null; + while ((pendingContent = pendingContents.shift())) { + const { content, contentLineIndex, contentIndex, topLevel } = + pendingContent; + let referenceLinkMatch = null; + while ((referenceLinkMatch = referenceLinkRe.exec(content)) !== null) { + const [ matchString, matchText, matchLabel ] = referenceLinkMatch; + if ( + !matchString.startsWith("\\") && + !matchString.startsWith("!\\") && + !matchText.endsWith("\\") && + !(matchLabel || "").endsWith("\\") && + !(topLevel && excluded(referenceLinkMatch)) + ) { + const shortcutLink = (matchLabel === undefined); + const collapsedLink = + (!shortcutLink && (matchLabel.length === 0)); + const label = normalizeLabel( + (shortcutLink || collapsedLink) ? matchText : matchLabel + ); + if (label.length > 0) { + const referenceindex = referenceLinkMatch.index; + if (topLevel) { + // Calculate line index + while (lineOffsets[lineIndex + 1] <= referenceindex) { + lineIndex++; + } + } else { + // Use provided line index + lineIndex = contentLineIndex; + } + const referenceIndex = referenceindex + + (topLevel ? -lineOffsets[lineIndex] : contentIndex); + if (shortcutLink) { + // Track separately due to ambiguity in "text [text] text" + shortcuts.add(label); + } else { + // Track reference and location + const referenceData = references.get(label) || []; + referenceData.push([ + lineIndex, + referenceIndex, + matchString.length + ]); + references.set(label, referenceData); + } + // Check for links embedded in brackets + if (!matchString.startsWith("!")) { + pendingContents.push({ + "content": matchText, + "contentLineIndex": lineIndex, + "contentIndex": referenceIndex + 1, + "topLevel": false + }); + } + } + } + } + } + return { + references, + shortcuts, + definitions, + duplicateDefinitions + }; +} +module.exports.getReferenceLinkImageData = getReferenceLinkImageData; + /** * Gets the most common line ending, falling back to the platform default. * * @param {string} input Markdown content to analyze. - * @param {string} [platform] Platform identifier (process.platform). + * @param {Object} [os] Node.js "os" module. * @returns {string} Preferred line ending. */ -function getPreferredLineEnding(input, platform) { +function getPreferredLineEnding(input, os) { let cr = 0; let lf = 0; let crlf = 0; const endings = input.match(newLineRe) || []; - endings.forEach((ending) => { + for (const ending of endings) { // eslint-disable-next-line default-case switch (ending) { case "\r": @@ -14497,11 +14950,10 @@ function getPreferredLineEnding(input, platform) { crlf++; break; } - }); + } let preferredLineEnding = null; if (!cr && !lf && !crlf) { - preferredLineEnding = - ((platform || process.platform) === "win32") ? "\r\n" : "\n"; + preferredLineEnding = (os && os.EOL) || "\n"; } else if ((lf >= crlf) && (lf >= cr)) { preferredLineEnding = "\n"; } else if (crlf >= cr) { @@ -14534,8 +14986,8 @@ function normalizeFixInfo(fixInfo, lineNumber) { * * @param {string} line Line of Markdown content. * @param {Object} fixInfo RuleOnErrorFixInfo instance. - * @param {string} lineEnding Line ending to use. - * @returns {string} Fixed content. + * @param {string} [lineEnding] Line ending to use. + * @returns {string | null} Fixed content. */ function applyFix(line, fixInfo, lineEnding) { const { editColumn, deleteCount, insertText } = normalizeFixInfo(fixInfo); @@ -14548,9 +15000,15 @@ function applyFix(line, fixInfo, lineEnding) { } module.exports.applyFix = applyFix; -// Applies as many fixes as possible to the input lines -module.exports.applyFixes = function applyFixes(input, errors) { - const lineEnding = getPreferredLineEnding(input); +/** + * Applies as many fixes as possible to Markdown content. + * + * @param {string} input Lines of Markdown content. + * @param {Object[]} errors RuleOnErrorInfo instances. + * @returns {string} Corrected content. + */ +function applyFixes(input, errors) { + const lineEnding = getPreferredLineEnding(input, __nccwpck_require__(2037)); const lines = input.split(newLineRe); // Normalize fixInfo objects let fixInfos = errors @@ -14580,8 +15038,10 @@ module.exports.applyFixes = function applyFixes(input, errors) { return unique; }); // Collapse insert/no-delete and no-insert/delete for same line/column - lastFixInfo = {}; - fixInfos.forEach((fixInfo) => { + lastFixInfo = { + "lineNumber": -1 + }; + for (const fixInfo of fixInfos) { if ( (fixInfo.lineNumber === lastFixInfo.lineNumber) && (fixInfo.editColumn === lastFixInfo.editColumn) && @@ -14593,12 +15053,12 @@ module.exports.applyFixes = function applyFixes(input, errors) { lastFixInfo.lineNumber = 0; } lastFixInfo = fixInfo; - }); + } fixInfos = fixInfos.filter((fixInfo) => fixInfo.lineNumber); // Apply all (remaining/updated) fixes let lastLineIndex = -1; let lastEditIndex = -1; - fixInfos.forEach((fixInfo) => { + for (const fixInfo of fixInfos) { const { lineNumber, editColumn, deleteCount } = fixInfo; const lineIndex = lineNumber - 1; const editIndex = editColumn - 1; @@ -14608,14 +15068,16 @@ module.exports.applyFixes = function applyFixes(input, errors) { ((editIndex + deleteCount) <= (lastEditIndex - ((deleteCount > 0) ? 0 : 1))) ) { + // @ts-ignore lines[lineIndex] = applyFix(lines[lineIndex], fixInfo, lineEnding); } lastLineIndex = lineIndex; lastEditIndex = editIndex; - }); + } // Return corrected input return lines.filter((line) => line !== null).join(lineEnding); -}; +} +module.exports.applyFixes = applyFixes; /** * Gets the range and fixInfo values for reporting an error if the expected @@ -14625,28 +15087,33 @@ module.exports.applyFixes = function applyFixes(input, errors) { * @param {number} lineIndex Line index to check. * @param {string} search Text to search for. * @param {string} replace Text to replace with. + * @param {number} [instance] Instance on the line (1-based). * @returns {Object} Range and fixInfo wrapper. */ -function getRangeAndFixInfoIfFound(lines, lineIndex, search, replace) { - let range = null; - let fixInfo = null; - const searchIndex = lines[lineIndex].indexOf(search); - if (searchIndex !== -1) { - const column = searchIndex + 1; - const length = search.length; - range = [ column, length ]; - fixInfo = { - "editColumn": column, - "deleteCount": length, - "insertText": replace +module.exports.getRangeAndFixInfoIfFound = + (lines, lineIndex, search, replace, instance = 1) => { + let range = null; + let fixInfo = null; + let searchIndex = -1; + while (instance > 0) { + searchIndex = lines[lineIndex].indexOf(search, searchIndex + 1); + instance--; + } + if (searchIndex !== -1) { + const column = searchIndex + 1; + const length = search.length; + range = [ column, length ]; + fixInfo = { + "editColumn": column, + "deleteCount": length, + "insertText": replace + }; + } + return { + range, + fixInfo }; - } - return { - range, - fixInfo }; -} -module.exports.getRangeAndFixInfoIfFound = getRangeAndFixInfoIfFound; /** * Gets the next (subsequent) child token if it is of the expected type. @@ -14673,16865 +15140,18690 @@ function getNextChildToken(parentToken, childToken, nextType, nextNextType) { module.exports.getNextChildToken = getNextChildToken; /** - * Calls Object.freeze() on an object and its children. + * Expands a path with a tilde to an absolute path. * - * @param {Object} obj Object to deep freeze. - * @returns {Object} Object passed to the function. + * @param {string} file Path that may begin with a tilde. + * @param {Object} os Node.js "os" module. + * @returns {string} Absolute path (or original path). */ -function deepFreeze(obj) { - const pending = [ obj ]; - let current = null; - while ((current = pending.shift())) { - Object.freeze(current); - for (const name of Object.getOwnPropertyNames(current)) { - const value = current[name]; - if (value && (typeof value === "object")) { - pending.push(value); - } - } - } - return obj; +function expandTildePath(file, os) { + const homedir = os && os.homedir && os.homedir(); + return homedir ? file.replace(/^~($|\/|\\)/, `${homedir}$1`) : file; } -module.exports.deepFreeze = deepFreeze; +module.exports.expandTildePath = expandTildePath; /***/ }), -/***/ 2935: +/***/ 6023: /***/ ((module) => { "use strict"; -// @ts-check -// Regular expression for matching common newline characters -// See NEWLINES_RE in markdown-it/lib/rules_core/normalize.js -const newLineRe = /\r\n?|\n/g; -module.exports.newLineRe = newLineRe; -// Regular expression for matching common front matter (YAML and TOML) -module.exports.frontMatterRe = - // eslint-disable-next-line max-len - /((^---\s*$[^]*?^---\s*$)|(^\+\+\+\s*$[^]*?^(\+\+\+|\.\.\.)\s*$)|(^\{\s*$[^]*?^\}\s*$))(\r\n|\r|\n|$)/m; +/* eslint-disable no-bitwise */ -// Regular expression for matching inline disable/enable comments -const inlineCommentRe = - // eslint-disable-next-line max-len - //ig; -module.exports.inlineCommentRe = inlineCommentRe; +var decodeCache = {}; -// Regular expressions for range matching -module.exports.bareUrlRe = /(?:http|ftp)s?:\/\/[^\s\]"']*(?:\/|[^\s\]"'\W])/ig; -module.exports.listItemMarkerRe = /^([\s>]*)(?:[*+-]|\d+[.)])\s+/; -module.exports.orderedListItemMarkerRe = /^[\s>]*0*(\d+)[.)]/; +function getDecodeCache(exclude) { + var i, ch, cache = decodeCache[exclude]; + if (cache) { return cache; } -// Regular expression for all instances of emphasis markers -const emphasisMarkersRe = /[_*]/g; + cache = decodeCache[exclude] = []; -// Regular expression for inline links and shortcut reference links -const linkRe = /(\[(?:[^[\]]|\[[^\]]*\])*\])(\(\S*\)|\[\S*\])?/g; -module.exports.linkRe = linkRe; + for (i = 0; i < 128; i++) { + ch = String.fromCharCode(i); + cache.push(ch); + } -// Regular expression for link reference definition lines -module.exports.linkReferenceRe = /^ {0,3}\[[^\]]+]:\s.*$/; + for (i = 0; i < exclude.length; i++) { + ch = exclude.charCodeAt(i); + cache[ch] = '%' + ('0' + ch.toString(16).toUpperCase()).slice(-2); + } -// All punctuation characters (normal and full-width) -const allPunctuation = ".,;:!?。,;:!?"; -module.exports.allPunctuation = allPunctuation; + return cache; +} -// All punctuation characters without question mark (normal and full-width) -module.exports.allPunctuationNoQuestion = allPunctuation.replace(/[??]/gu, ""); -// Returns true iff the input is a number -module.exports.isNumber = function isNumber(obj) { - return typeof obj === "number"; -}; +// Decode percent-encoded string. +// +function decode(string, exclude) { + var cache; -// Returns true iff the input is a string -module.exports.isString = function isString(obj) { - return typeof obj === "string"; -}; + if (typeof exclude !== 'string') { + exclude = decode.defaultChars; + } -// Returns true iff the input string is empty -module.exports.isEmptyString = function isEmptyString(str) { - return str.length === 0; -}; + cache = getDecodeCache(exclude); -// Returns true iff the input is an object -module.exports.isObject = function isObject(obj) { - return (obj !== null) && (typeof obj === "object") && !Array.isArray(obj); -}; + return string.replace(/(%[a-f0-9]{2})+/gi, function(seq) { + var i, l, b1, b2, b3, b4, chr, + result = ''; -// Returns true iff the input line is blank (no content) -// Example: Contains nothing, whitespace, or comment (unclosed start/end okay) -module.exports.isBlankLine = function isBlankLine(line) { - // Call to String.replace follows best practices and is not a security check - // False-positive for js/incomplete-multi-character-sanitization - return ( - !line || - !line.trim() || - !line - .replace(//g, "") - .replace(//g, "") - .replace(/>/g, "") - .trim() - ); -}; + for (i = 0, l = seq.length; i < l; i += 3) { + b1 = parseInt(seq.slice(i + 1, i + 3), 16); -/** - * Compare function for Array.prototype.sort for ascending order of numbers. - * - * @param {number} a First number. - * @param {number} b Second number. - * @returns {number} Positive value if a>b, negative value if b> 1; - if (array[mid] < element) { - left = mid + 1; - } else if (array[mid] > element) { - right = mid - 1; - } else { - return true; - } - } - return false; -}; + if ((b1 & 0xE0) === 0xC0 && (i + 3 < l)) { + // 110xxxxx 10xxxxxx + b2 = parseInt(seq.slice(i + 4, i + 6), 16); -// Replaces the content of properly-formatted CommonMark comments with "." -// This preserves the line/column information for the rest of the document -// https://spec.commonmark.org/0.29/#html-blocks -// https://spec.commonmark.org/0.29/#html-comment -const htmlCommentBegin = ""; -module.exports.clearHtmlCommentText = function clearHtmlCommentText(text) { - let i = 0; - while ((i = text.indexOf(htmlCommentBegin, i)) !== -1) { - const j = text.indexOf(htmlCommentEnd, i + 2); - if (j === -1) { - // Un-terminated comments are treated as text - break; - } - // If the comment has content... - if (j > i + htmlCommentBegin.length) { - let k = i - 1; - while (text[k] === " ") { - k--; - } - // If comment is not within an indented code block... - if (k >= i - 4) { - const content = text.slice(i + htmlCommentBegin.length, j); - const isBlock = (k < 0) || (text[k] === "\n"); - const isValid = isBlock || - (!content.startsWith(">") && !content.startsWith("->") && - !content.endsWith("-") && !content.includes("--")); - // If a valid block/inline comment... - if (isValid) { - const inlineCommentIndex = text - .slice(i, j + htmlCommentEnd.length) - .search(inlineCommentRe); - // If not a markdownlint inline directive... - if (inlineCommentIndex === -1) { - text = - text.slice(0, i + htmlCommentBegin.length) + - content.replace(/[^\r\n]/g, ".") + - text.slice(j); + if ((b2 & 0xC0) === 0x80) { + chr = ((b1 << 6) & 0x7C0) | (b2 & 0x3F); + + if (chr < 0x80) { + result += '\ufffd\ufffd'; + } else { + result += String.fromCharCode(chr); } + + i += 3; + continue; } } - } - i = j + htmlCommentEnd.length; - } - return text; -}; -// Escapes a string for use in a RegExp -module.exports.escapeForRegExp = function escapeForRegExp(str) { - return str.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"); -}; + if ((b1 & 0xF0) === 0xE0 && (i + 6 < l)) { + // 1110xxxx 10xxxxxx 10xxxxxx + b2 = parseInt(seq.slice(i + 4, i + 6), 16); + b3 = parseInt(seq.slice(i + 7, i + 9), 16); -// Un-escapes Markdown content (simple algorithm; not a parser) -const escapedMarkdownRe = /\\./g; -module.exports.unescapeMarkdown = - function unescapeMarkdown(markdown, replacement) { - return markdown.replace(escapedMarkdownRe, (match) => { - const char = match[1]; - if ("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~".includes(char)) { - return replacement || char; + if ((b2 & 0xC0) === 0x80 && (b3 & 0xC0) === 0x80) { + chr = ((b1 << 12) & 0xF000) | ((b2 << 6) & 0xFC0) | (b3 & 0x3F); + + if (chr < 0x800 || (chr >= 0xD800 && chr <= 0xDFFF)) { + result += '\ufffd\ufffd\ufffd'; + } else { + result += String.fromCharCode(chr); + } + + i += 6; + continue; + } } - return match; - }); - }; -/** - * Return the string representation of a fence markup character. - * - * @param {string} markup Fence string. - * @returns {string} String representation. - */ -module.exports.fencedCodeBlockStyleFor = - function fencedCodeBlockStyleFor(markup) { - switch (markup[0]) { - case "~": - return "tilde"; - default: - return "backtick"; - } - }; + if ((b1 & 0xF8) === 0xF0 && (i + 9 < l)) { + // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx + b2 = parseInt(seq.slice(i + 4, i + 6), 16); + b3 = parseInt(seq.slice(i + 7, i + 9), 16); + b4 = parseInt(seq.slice(i + 10, i + 12), 16); -/** - * Return the string representation of a emphasis or strong markup character. - * - * @param {string} markup Emphasis or strong string. - * @returns {string} String representation. - */ -module.exports.emphasisOrStrongStyleFor = - function emphasisOrStrongStyleFor(markup) { - switch (markup[0]) { - case "*": - return "asterisk"; - default: - return "underscore"; + if ((b2 & 0xC0) === 0x80 && (b3 & 0xC0) === 0x80 && (b4 & 0xC0) === 0x80) { + chr = ((b1 << 18) & 0x1C0000) | ((b2 << 12) & 0x3F000) | ((b3 << 6) & 0xFC0) | (b4 & 0x3F); + + if (chr < 0x10000 || chr > 0x10FFFF) { + result += '\ufffd\ufffd\ufffd\ufffd'; + } else { + chr -= 0x10000; + result += String.fromCharCode(0xD800 + (chr >> 10), 0xDC00 + (chr & 0x3FF)); + } + + i += 9; + continue; + } + } + + result += '\ufffd'; } - }; -/** - * Return the number of characters of indent for a token. - * - * @param {Object} token MarkdownItToken instance. - * @returns {number} Characters of indent. - */ -function indentFor(token) { - const line = token.line.replace(/^[\s>]*(> |>)/, ""); - return line.length - line.trimStart().length; + return result; + }); } -module.exports.indentFor = indentFor; -// Returns the heading style for a heading token -module.exports.headingStyleFor = function headingStyleFor(token) { - if ((token.map[1] - token.map[0]) === 1) { - if (/[^\\]#\s*$/.test(token.line)) { - return "atx_closed"; + +decode.defaultChars = ';/?:@&=+$,#'; +decode.componentChars = ''; + + +module.exports = decode; + + +/***/ }), + +/***/ 6756: +/***/ ((module) => { + +"use strict"; + + + + +var encodeCache = {}; + + +// Create a lookup array where anything but characters in `chars` string +// and alphanumeric chars is percent-encoded. +// +function getEncodeCache(exclude) { + var i, ch, cache = encodeCache[exclude]; + if (cache) { return cache; } + + cache = encodeCache[exclude] = []; + + for (i = 0; i < 128; i++) { + ch = String.fromCharCode(i); + + if (/^[0-9a-z]$/i.test(ch)) { + // always allow unencoded alphanumeric characters + cache.push(ch); + } else { + cache.push('%' + ('0' + i.toString(16).toUpperCase()).slice(-2)); } - return "atx"; } - return "setext"; -}; -/** - * Return the string representation of an unordered list marker. - * - * @param {Object} token MarkdownItToken instance. - * @returns {string} String representation. - */ -module.exports.unorderedListStyleFor = function unorderedListStyleFor(token) { - switch (token.markup) { - case "-": - return "dash"; - case "+": - return "plus"; - // case "*": - default: - return "asterisk"; + for (i = 0; i < exclude.length; i++) { + cache[exclude.charCodeAt(i)] = exclude[i]; } -}; -/** - * Calls the provided function for each matching token. - * - * @param {Object} params RuleParams instance. - * @param {string} type Token type identifier. - * @param {Function} handler Callback function. - * @returns {void} - */ -function filterTokens(params, type, handler) { - params.tokens.forEach(function forToken(token) { - if (token.type === type) { - handler(token); - } - }); + return cache; } -module.exports.filterTokens = filterTokens; -/** - * Returns whether a token is a math block (created by markdown-it-texmath). - * - * @param {Object} token MarkdownItToken instance. - * @returns {boolean} True iff token is a math block. - */ -function isMathBlock(token) { - return ( - ((token.tag === "$$") || (token.tag === "math")) && - token.type.startsWith("math_block") && - !token.type.endsWith("_end") - ); -} -module.exports.isMathBlock = isMathBlock; -// Get line metadata array -module.exports.getLineMetadata = function getLineMetadata(params) { - const lineMetadata = params.lines.map( - (line, index) => [ line, index, false, 0, false, false, false, false ] - ); - filterTokens(params, "fence", (token) => { - lineMetadata[token.map[0]][3] = 1; - lineMetadata[token.map[1] - 1][3] = -1; - for (let i = token.map[0] + 1; i < token.map[1] - 1; i++) { - lineMetadata[i][2] = true; +// Encode unsafe characters with percent-encoding, skipping already +// encoded sequences. +// +// - string - string to encode +// - exclude - list of characters to ignore (in addition to a-zA-Z0-9) +// - keepEscaped - don't encode '%' in a correct escape sequence (default: true) +// +function encode(string, exclude, keepEscaped) { + var i, l, code, nextCode, cache, + result = ''; + + if (typeof exclude !== 'string') { + // encode(string, keepEscaped) + keepEscaped = exclude; + exclude = encode.defaultChars; + } + + if (typeof keepEscaped === 'undefined') { + keepEscaped = true; + } + + cache = getEncodeCache(exclude); + + for (i = 0, l = string.length; i < l; i++) { + code = string.charCodeAt(i); + + if (keepEscaped && code === 0x25 /* % */ && i + 2 < l) { + if (/^[0-9a-f]{2}$/i.test(string.slice(i + 1, i + 3))) { + result += string.slice(i, i + 3); + i += 2; + continue; + } } - }); - filterTokens(params, "code_block", (token) => { - for (let i = token.map[0]; i < token.map[1]; i++) { - lineMetadata[i][2] = true; - } - }); - filterTokens(params, "table_open", (token) => { - for (let i = token.map[0]; i < token.map[1]; i++) { - lineMetadata[i][4] = true; - } - }); - filterTokens(params, "list_item_open", (token) => { - let count = 1; - for (let i = token.map[0]; i < token.map[1]; i++) { - lineMetadata[i][5] = count; - count++; - } - }); - filterTokens(params, "hr", (token) => { - lineMetadata[token.map[0]][6] = true; - }); - params.tokens.filter(isMathBlock).forEach((token) => { - for (let i = token.map[0]; i < token.map[1]; i++) { - lineMetadata[i][7] = true; - } - }); - return lineMetadata; -}; - -/** - * Calls the provided function for each line. - * - * @param {Object} lineMetadata Line metadata object. - * @param {Function} handler Function taking (line, lineIndex, inCode, onFence, - * inTable, inItem, inBreak, inMath). - * @returns {void} - */ -function forEachLine(lineMetadata, handler) { - lineMetadata.forEach(function forMetadata(metadata) { - handler(...metadata); - }); -} -module.exports.forEachLine = forEachLine; - -// Returns (nested) lists as a flat array (in order) -module.exports.flattenLists = function flattenLists(tokens) { - const flattenedLists = []; - const stack = []; - let current = null; - let nesting = 0; - const nestingStack = []; - let lastWithMap = { "map": [ 0, 1 ] }; - tokens.forEach((token) => { - if ((token.type === "bullet_list_open") || - (token.type === "ordered_list_open")) { - // Save current context and start a new one - stack.push(current); - current = { - "unordered": (token.type === "bullet_list_open"), - "parentsUnordered": !current || - (current.unordered && current.parentsUnordered), - "open": token, - "indent": indentFor(token), - "parentIndent": (current && current.indent) || 0, - "items": [], - "nesting": nesting, - "lastLineIndex": -1, - "insert": flattenedLists.length - }; - nesting++; - } else if ((token.type === "bullet_list_close") || - (token.type === "ordered_list_close")) { - // Finalize current context and restore previous - current.lastLineIndex = lastWithMap.map[1]; - flattenedLists.splice(current.insert, 0, current); - delete current.insert; - current = stack.pop(); - nesting--; - } else if (token.type === "list_item_open") { - // Add list item - current.items.push(token); - } else if (token.type === "blockquote_open") { - nestingStack.push(nesting); - nesting = 0; - } else if (token.type === "blockquote_close") { - nesting = nestingStack.pop(); - } else if (token.map) { - // Track last token with map - lastWithMap = token; - } - }); - return flattenedLists; -}; - -// Calls the provided function for each specified inline child token -module.exports.forEachInlineChild = -function forEachInlineChild(params, type, handler) { - filterTokens(params, "inline", function forToken(token) { - token.children.forEach(function forChild(child) { - if (child.type === type) { - handler(child, token); - } - }); - }); -}; -// Calls the provided function for each heading's content -module.exports.forEachHeading = function forEachHeading(params, handler) { - let heading = null; - params.tokens.forEach(function forToken(token) { - if (token.type === "heading_open") { - heading = token; - } else if (token.type === "heading_close") { - heading = null; - } else if ((token.type === "inline") && heading) { - handler(heading, token.content); + if (code < 128) { + result += cache[code]; + continue; } - }); -}; -/** - * Calls the provided function for each inline code span's content. - * - * @param {string} input Markdown content. - * @param {Function} handler Callback function taking (code, lineIndex, - * columnIndex, ticks). - * @returns {void} - */ -function forEachInlineCodeSpan(input, handler) { - let currentLine = 0; - let currentColumn = 0; - let index = 0; - while (index < input.length) { - let startIndex = -1; - let startLine = -1; - let startColumn = -1; - let tickCount = 0; - let currentTicks = 0; - let state = "normal"; - // Deliberate <= so trailing 0 completes the last span (ex: "text `code`") - // False-positive for js/index-out-of-bounds - for (; index <= input.length; index++) { - const char = input[index]; - // Ignore backticks in link destination - if ((char === "[") && (state === "normal")) { - state = "linkTextOpen"; - } else if ((char === "]") && (state === "linkTextOpen")) { - state = "linkTextClosed"; - } else if ((char === "(") && (state === "linkTextClosed")) { - state = "linkDestinationOpen"; - } else if ( - ((char === "(") && (state === "linkDestinationOpen")) || - ((char === ")") && (state === "linkDestinationOpen")) || - (state === "linkTextClosed")) { - state = "normal"; - } - // Parse backtick open/close - if ((char === "`") && (state !== "linkDestinationOpen")) { - // Count backticks at start or end of code span - currentTicks++; - if ((startIndex === -1) || (startColumn === -1)) { - startIndex = index + 1; + if (code >= 0xD800 && code <= 0xDFFF) { + if (code >= 0xD800 && code <= 0xDBFF && i + 1 < l) { + nextCode = string.charCodeAt(i + 1); + if (nextCode >= 0xDC00 && nextCode <= 0xDFFF) { + result += encodeURIComponent(string[i] + string[i + 1]); + i++; + continue; } - } else { - if ((startIndex >= 0) && - (startColumn >= 0) && - (tickCount === currentTicks)) { - // Found end backticks; invoke callback for code span - handler( - input.substring(startIndex, index - currentTicks), - startLine, startColumn, tickCount); - startIndex = -1; - startColumn = -1; - } else if ((startIndex >= 0) && (startColumn === -1)) { - // Found start backticks - tickCount = currentTicks; - startLine = currentLine; - startColumn = currentColumn; - } - // Not in backticks - currentTicks = 0; - } - if (char === "\n") { - // On next line - currentLine++; - currentColumn = 0; - } else if ((char === "\\") && - ((startIndex === -1) || (startColumn === -1)) && - (input[index + 1] !== "\n")) { - // Escape character outside code, skip next - index++; - currentColumn += 2; - } else { - // On next column - currentColumn++; } + result += '%EF%BF%BD'; + continue; } - if (startIndex >= 0) { - // Restart loop after unmatched start backticks (ex: "`text``code``") - index = startIndex; - currentLine = startLine; - currentColumn = startColumn; - } + + result += encodeURIComponent(string[i]); } -} -module.exports.forEachInlineCodeSpan = forEachInlineCodeSpan; -/** - * Adds a generic error object via the onError callback. - * - * @param {Object} onError RuleOnError instance. - * @param {number} lineNumber Line number. - * @param {string} [detail] Error details. - * @param {string} [context] Error context. - * @param {number[]} [range] Column and length of error. - * @param {Object} [fixInfo] RuleOnErrorFixInfo instance. - * @returns {void} - */ -function addError(onError, lineNumber, detail, context, range, fixInfo) { - onError({ - lineNumber, - detail, - context, - range, - fixInfo - }); + return result; } -module.exports.addError = addError; -// Adds an error object with details conditionally via the onError callback -module.exports.addErrorDetailIf = function addErrorDetailIf( - onError, lineNumber, expected, actual, detail, context, range, fixInfo) { - if (expected !== actual) { - addError( - onError, - lineNumber, - "Expected: " + expected + "; Actual: " + actual + - (detail ? "; " + detail : ""), - context, - range, - fixInfo); - } -}; +encode.defaultChars = ";/?:@&=+$,-_.!~*'()#"; +encode.componentChars = "-_.!~*'()"; -// Adds an error object with context via the onError callback -module.exports.addErrorContext = function addErrorContext( - onError, lineNumber, context, left, right, range, fixInfo) { - if (context.length <= 30) { - // Nothing to do - } else if (left && right) { - context = context.substr(0, 15) + "..." + context.substr(-15); - } else if (right) { - context = "..." + context.substr(-30); + +module.exports = encode; + + +/***/ }), + +/***/ 8612: +/***/ ((module) => { + +"use strict"; + + + + +module.exports = function format(url) { + var result = ''; + + result += url.protocol || ''; + result += url.slashes ? '//' : ''; + result += url.auth ? url.auth + '@' : ''; + + if (url.hostname && url.hostname.indexOf(':') !== -1) { + // ipv6 address + result += '[' + url.hostname + ']'; } else { - context = context.substr(0, 30) + "..."; + result += url.hostname || ''; } - addError(onError, lineNumber, null, context, range, fixInfo); -}; -/** - * Returns an array of code block and span content ranges. - * - * @param {Object} params RuleParams instance. - * @param {Object} lineMetadata Line metadata object. - * @returns {number[][]} Array of ranges (lineIndex, columnIndex, length). - */ -module.exports.codeBlockAndSpanRanges = (params, lineMetadata) => { - const exclusions = []; - // Add code block ranges (excludes fences) - forEachLine(lineMetadata, (line, lineIndex, inCode, onFence) => { - if (inCode && !onFence) { - exclusions.push([ lineIndex, 0, line.length ]); - } - }); - // Add code span ranges (excludes ticks) - filterTokens(params, "inline", (token) => { - if (token.children.some((child) => child.type === "code_inline")) { - const tokenLines = params.lines.slice(token.map[0], token.map[1]); - forEachInlineCodeSpan( - tokenLines.join("\n"), - (code, lineIndex, columnIndex) => { - const codeLines = code.split(newLineRe); - for (const [ i, line ] of codeLines.entries()) { - exclusions.push([ - token.lineNumber - 1 + lineIndex + i, - i ? 0 : columnIndex, - line.length - ]); - } - } - ); - } - }); - return exclusions; + result += url.port ? ':' + url.port : ''; + result += url.pathname || ''; + result += url.search || ''; + result += url.hash || ''; + + return result; }; -/** - * Determines whether the specified range overlaps another range. - * - * @param {number[][]} ranges Array of ranges (line, index, length). - * @param {number} lineIndex Line index to check. - * @param {number} index Index to check. - * @param {number} length Length to check. - * @returns {boolean} True iff the specified range overlaps. - */ -module.exports.overlapsAnyRange = (ranges, lineIndex, index, length) => ( - !ranges.every((span) => ( - (lineIndex !== span[0]) || - (index + length < span[1]) || - (index > span[1] + span[2]) - )) -); -// Returns a range object for a line by applying a RegExp -module.exports.rangeFromRegExp = function rangeFromRegExp(line, regexp) { - let range = null; - const match = line.match(regexp); - if (match) { - const column = match.index + 1; - const length = match[0].length; - range = [ column, length ]; - } - return range; -}; +/***/ }), -// Determines if the front matter includes a title -module.exports.frontMatterHasTitle = - function frontMatterHasTitle(frontMatterLines, frontMatterTitlePattern) { - const ignoreFrontMatter = - (frontMatterTitlePattern !== undefined) && !frontMatterTitlePattern; - const frontMatterTitleRe = - new RegExp( - String(frontMatterTitlePattern || "^\\s*\"?title\"?\\s*[:=]"), - "i" - ); - return !ignoreFrontMatter && - frontMatterLines.some((line) => frontMatterTitleRe.test(line)); - }; +/***/ 114: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -/** - * Returns a list of emphasis markers in code spans and links. - * - * @param {Object} params RuleParams instance. - * @returns {number[][]} List of markers. - */ -function emphasisMarkersInContent(params) { - const { lines } = params; - const byLine = new Array(lines.length); - // Search links - lines.forEach((tokenLine, tokenLineIndex) => { - const inLine = []; - let linkMatch = null; - while ((linkMatch = linkRe.exec(tokenLine))) { - let markerMatch = null; - while ((markerMatch = emphasisMarkersRe.exec(linkMatch[0]))) { - inLine.push(linkMatch.index + markerMatch.index); - } - } - byLine[tokenLineIndex] = inLine; - }); - // Search code spans - filterTokens(params, "inline", (token) => { - const { children, lineNumber, map } = token; - if (children.some((child) => child.type === "code_inline")) { - const tokenLines = lines.slice(map[0], map[1]); - forEachInlineCodeSpan( - tokenLines.join("\n"), - (code, lineIndex, column, tickCount) => { - const codeLines = code.split(newLineRe); - codeLines.forEach((codeLine, codeLineIndex) => { - const byLineIndex = lineNumber - 1 + lineIndex + codeLineIndex; - const inLine = byLine[byLineIndex]; - const codeLineOffset = codeLineIndex ? 0 : column - 1 + tickCount; - let match = null; - while ((match = emphasisMarkersRe.exec(codeLine))) { - inLine.push(codeLineOffset + match.index); - } - byLine[byLineIndex] = inLine; - }); - } - ); - } - }); - return byLine; -} -module.exports.emphasisMarkersInContent = emphasisMarkersInContent; +"use strict"; -/** - * Gets the most common line ending, falling back to the platform default. - * - * @param {string} input Markdown content to analyze. - * @param {string} [platform] Platform identifier (process.platform). - * @returns {string} Preferred line ending. - */ -function getPreferredLineEnding(input, platform) { - let cr = 0; - let lf = 0; - let crlf = 0; - const endings = input.match(newLineRe) || []; - endings.forEach((ending) => { - // eslint-disable-next-line default-case - switch (ending) { - case "\r": - cr++; - break; - case "\n": - lf++; - break; - case "\r\n": - crlf++; - break; - } - }); - let preferredLineEnding = null; - if (!cr && !lf && !crlf) { - preferredLineEnding = - ((platform || process.platform) === "win32") ? "\r\n" : "\n"; - } else if ((lf >= crlf) && (lf >= cr)) { - preferredLineEnding = "\n"; - } else if (crlf >= cr) { - preferredLineEnding = "\r\n"; - } else { - preferredLineEnding = "\r"; - } - return preferredLineEnding; -} -module.exports.getPreferredLineEnding = getPreferredLineEnding; -/** - * Normalizes the fields of a RuleOnErrorFixInfo instance. - * - * @param {Object} fixInfo RuleOnErrorFixInfo instance. - * @param {number} [lineNumber] Line number. - * @returns {Object} Normalized RuleOnErrorFixInfo instance. - */ -function normalizeFixInfo(fixInfo, lineNumber) { - return { - "lineNumber": fixInfo.lineNumber || lineNumber, - "editColumn": fixInfo.editColumn || 1, - "deleteCount": fixInfo.deleteCount || 0, - "insertText": fixInfo.insertText || "" - }; -} -/** - * Fixes the specified error on a line of Markdown content. - * - * @param {string} line Line of Markdown content. - * @param {Object} fixInfo RuleOnErrorFixInfo instance. - * @param {string} lineEnding Line ending to use. - * @returns {string} Fixed content. - */ -function applyFix(line, fixInfo, lineEnding) { - const { editColumn, deleteCount, insertText } = normalizeFixInfo(fixInfo); - const editIndex = editColumn - 1; - return (deleteCount === -1) ? - null : - line.slice(0, editIndex) + - insertText.replace(/\n/g, lineEnding || "\n") + - line.slice(editIndex + deleteCount); -} -module.exports.applyFix = applyFix; +module.exports.encode = __nccwpck_require__(6756); +module.exports.decode = __nccwpck_require__(6023); +module.exports.format = __nccwpck_require__(8612); +module.exports.parse = __nccwpck_require__(8062); -// Applies as many fixes as possible to the input lines -module.exports.applyFixes = function applyFixes(input, errors) { - const lineEnding = getPreferredLineEnding(input); - const lines = input.split(newLineRe); - // Normalize fixInfo objects - let fixInfos = errors - .filter((error) => error.fixInfo) - .map((error) => normalizeFixInfo(error.fixInfo, error.lineNumber)); - // Sort bottom-to-top, line-deletes last, right-to-left, long-to-short - fixInfos.sort((a, b) => { - const aDeletingLine = (a.deleteCount === -1); - const bDeletingLine = (b.deleteCount === -1); - return ( - (b.lineNumber - a.lineNumber) || - (aDeletingLine ? 1 : (bDeletingLine ? -1 : 0)) || - (b.editColumn - a.editColumn) || - (b.insertText.length - a.insertText.length) - ); - }); - // Remove duplicate entries (needed for following collapse step) - let lastFixInfo = {}; - fixInfos = fixInfos.filter((fixInfo) => { - const unique = ( - (fixInfo.lineNumber !== lastFixInfo.lineNumber) || - (fixInfo.editColumn !== lastFixInfo.editColumn) || - (fixInfo.deleteCount !== lastFixInfo.deleteCount) || - (fixInfo.insertText !== lastFixInfo.insertText) - ); - lastFixInfo = fixInfo; - return unique; - }); - // Collapse insert/no-delete and no-insert/delete for same line/column - lastFixInfo = {}; - fixInfos.forEach((fixInfo) => { - if ( - (fixInfo.lineNumber === lastFixInfo.lineNumber) && - (fixInfo.editColumn === lastFixInfo.editColumn) && - !fixInfo.insertText && - (fixInfo.deleteCount > 0) && - lastFixInfo.insertText && - !lastFixInfo.deleteCount) { - fixInfo.insertText = lastFixInfo.insertText; - lastFixInfo.lineNumber = 0; - } - lastFixInfo = fixInfo; - }); - fixInfos = fixInfos.filter((fixInfo) => fixInfo.lineNumber); - // Apply all (remaining/updated) fixes - let lastLineIndex = -1; - let lastEditIndex = -1; - fixInfos.forEach((fixInfo) => { - const { lineNumber, editColumn, deleteCount } = fixInfo; - const lineIndex = lineNumber - 1; - const editIndex = editColumn - 1; - if ( - (lineIndex !== lastLineIndex) || - (deleteCount === -1) || - ((editIndex + deleteCount) <= - (lastEditIndex - ((deleteCount > 0) ? 0 : 1))) - ) { - lines[lineIndex] = applyFix(lines[lineIndex], fixInfo, lineEnding); - } - lastLineIndex = lineIndex; - lastEditIndex = editIndex; - }); - // Return corrected input - return lines.filter((line) => line !== null).join(lineEnding); -}; -/** - * Gets the range and fixInfo values for reporting an error if the expected - * text is found on the specified line. - * - * @param {string[]} lines Lines of Markdown content. - * @param {number} lineIndex Line index to check. - * @param {string} search Text to search for. - * @param {string} replace Text to replace with. - * @returns {Object} Range and fixInfo wrapper. - */ -function getRangeAndFixInfoIfFound(lines, lineIndex, search, replace) { - let range = null; - let fixInfo = null; - const searchIndex = lines[lineIndex].indexOf(search); - if (searchIndex !== -1) { - const column = searchIndex + 1; - const length = search.length; - range = [ column, length ]; - fixInfo = { - "editColumn": column, - "deleteCount": length, - "insertText": replace - }; - } - return { - range, - fixInfo - }; -} -module.exports.getRangeAndFixInfoIfFound = getRangeAndFixInfoIfFound; +/***/ }), -/** - * Gets the next (subsequent) child token if it is of the expected type. - * - * @param {Object} parentToken Parent token. - * @param {Object} childToken Child token basis. - * @param {string} nextType Token type of next token. - * @param {string} nextNextType Token type of next-next token. - * @returns {Object} Next token. - */ -function getNextChildToken(parentToken, childToken, nextType, nextNextType) { - const { children } = parentToken; - const index = children.indexOf(childToken); - if ( - (index !== -1) && - (children.length > index + 2) && - (children[index + 1].type === nextType) && - (children[index + 2].type === nextNextType) - ) { - return children[index + 1]; - } - return null; -} -module.exports.getNextChildToken = getNextChildToken; +/***/ 8062: +/***/ ((module) => { -/** - * Calls Object.freeze() on an object and its children. - * - * @param {Object} obj Object to deep freeze. - * @returns {Object} Object passed to the function. - */ -function deepFreeze(obj) { - const pending = [ obj ]; - let current = null; - while ((current = pending.shift())) { - Object.freeze(current); - for (const name of Object.getOwnPropertyNames(current)) { - const value = current[name]; - if (value && (typeof value === "object")) { - pending.push(value); - } - } - } - return obj; -} -module.exports.deepFreeze = deepFreeze; - - -/***/ }), +"use strict"; +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. -/***/ 3266: -/***/ ((module) => { -"use strict"; -// @ts-check +// +// Changes from joyent/node: +// +// 1. No leading slash in paths, +// e.g. in `url.parse('http://foo?bar')` pathname is ``, not `/` +// +// 2. Backslashes are not replaced with slashes, +// so `http:\\example.org\` is treated like a relative path +// +// 3. Trailing colon is treated like a part of the path, +// i.e. in `http://example.org:foo` pathname is `:foo` +// +// 4. Nothing is URL-encoded in the resulting object, +// (in joyent/node some chars in auth and paths are encoded) +// +// 5. `url.parse()` does not have `parseQueryString` argument +// +// 6. Removed extraneous result properties: `host`, `path`, `query`, etc., +// which can be constructed using other parts of the url. +// -let codeBlockAndSpanRanges = null; -module.exports.codeBlockAndSpanRanges = (value) => { - if (value) { - codeBlockAndSpanRanges = value; - } - return codeBlockAndSpanRanges; -}; +function Url() { + this.protocol = null; + this.slashes = null; + this.auth = null; + this.port = null; + this.hostname = null; + this.hash = null; + this.search = null; + this.pathname = null; +} -let flattenedLists = null; -module.exports.flattenedLists = (value) => { - if (value) { - flattenedLists = value; - } - return flattenedLists; -}; +// Reference: RFC 3986, RFC 1808, RFC 2396 -let lineMetadata = null; -module.exports.lineMetadata = (value) => { - if (value) { - lineMetadata = value; - } - return lineMetadata; -}; +// define these here so at least they only have to be +// compiled once on the first module load. +var protocolPattern = /^([a-z0-9.+-]+:)/i, + portPattern = /:[0-9]*$/, -module.exports.clear = () => { - codeBlockAndSpanRanges = null; - flattenedLists = null; - lineMetadata = null; -}; + // Special case for a simple path URL + simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/, + // RFC 2396: characters reserved for delimiting URLs. + // We actually just auto-escape these. + delims = [ '<', '>', '"', '`', ' ', '\r', '\n', '\t' ], -/***/ }), + // RFC 2396: characters not allowed for various reasons. + unwise = [ '{', '}', '|', '\\', '^', '`' ].concat(delims), -/***/ 5039: -/***/ ((module) => { + // Allowed by RFCs, but cause of XSS attacks. Always escape these. + autoEscape = [ '\'' ].concat(unwise), + // Characters that are never ever allowed in a hostname. + // Note that any invalid chars are also handled, but these + // are the ones that are *expected* to be seen, so we fast-path + // them. + nonHostChars = [ '%', '/', '?', ';', '#' ].concat(autoEscape), + hostEndingChars = [ '/', '?', '#' ], + hostnameMaxLen = 255, + hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/, + hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/, + // protocols that can allow "unsafe" and "unwise" chars. + /* eslint-disable no-script-url */ + // protocols that never have a hostname. + hostlessProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that always contain a // bit. + slashedProtocol = { + 'http': true, + 'https': true, + 'ftp': true, + 'gopher': true, + 'file': true, + 'http:': true, + 'https:': true, + 'ftp:': true, + 'gopher:': true, + 'file:': true + }; + /* eslint-enable no-script-url */ -"use strict"; -// @ts-check +function urlParse(url, slashesDenoteHost) { + if (url && url instanceof Url) { return url; } + var u = new Url(); + u.parse(url, slashesDenoteHost); + return u; +} +Url.prototype.parse = function(url, slashesDenoteHost) { + var i, l, lowerProto, hec, slashes, + rest = url; -module.exports.deprecatedRuleNames = [ "MD002", "MD006" ]; -module.exports.homepage = "https://github.com/DavidAnson/markdownlint"; -module.exports.version = "0.25.1"; + // trim before proceeding. + // This is to support parse stuff like " http://foo.com \n" + rest = rest.trim(); + if (!slashesDenoteHost && url.split('#').length === 1) { + // Try fast path regexp + var simplePath = simplePathPattern.exec(rest); + if (simplePath) { + this.pathname = simplePath[1]; + if (simplePath[2]) { + this.search = simplePath[2]; + } + return this; + } + } -/***/ }), + var proto = protocolPattern.exec(rest); + if (proto) { + proto = proto[0]; + lowerProto = proto.toLowerCase(); + this.protocol = proto; + rest = rest.substr(proto.length); + } -/***/ 3611: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // figure out if it's got a host + // user@server is *always* interpreted as a hostname, and url + // resolution will treat //foo/bar as host=foo,path=bar because that's + // how the browser resolves relative URLs. + if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { + slashes = rest.substr(0, 2) === '//'; + if (slashes && !(proto && hostlessProtocol[proto])) { + rest = rest.substr(2); + this.slashes = true; + } + } -"use strict"; -// @ts-check + if (!hostlessProtocol[proto] && + (slashes || (proto && !slashedProtocol[proto]))) { + // there's a hostname. + // the first instance of /, ?, ;, or # ends the host. + // + // If there is an @ in the hostname, then non-host chars *are* allowed + // to the left of the last @ sign, unless some host-ending character + // comes *before* the @-sign. + // URLs are obnoxious. + // + // ex: + // http://a@b@c/ => user:a@b host:c + // http://a@b?@c => user:a host:c path:/?@c + // v0.12 TODO(isaacs): This is not quite how Chrome does things. + // Review our test case against browsers more comprehensively. -const path = __nccwpck_require__(1017); -const { promisify } = __nccwpck_require__(3837); -const markdownIt = __nccwpck_require__(8561); -const { deprecatedRuleNames } = __nccwpck_require__(5039); -const rules = __nccwpck_require__(7494); -const helpers = __nccwpck_require__(2935); -const cache = __nccwpck_require__(3266); + // find the first instance of any hostEndingChars + var hostEnd = -1; + for (i = 0; i < hostEndingChars.length; i++) { + hec = rest.indexOf(hostEndingChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) { + hostEnd = hec; + } + } -// @ts-ignore -// eslint-disable-next-line camelcase, max-len, no-inline-comments, no-undef -const dynamicRequire = (typeof require === "undefined") ? require : /* c8 ignore next */ eval("require"); -// Capture native require implementation for dynamic loading of modules + // at this point, either we have an explicit point where the + // auth portion cannot go past, or the last @ char is the decider. + var auth, atSign; + if (hostEnd === -1) { + // atSign can be anywhere. + atSign = rest.lastIndexOf('@'); + } else { + // atSign must be in auth portion. + // http://a@b/c@d => host:b auth:a path:/c@d + atSign = rest.lastIndexOf('@', hostEnd); + } -/** - * Validate the list of rules for structure and reuse. - * - * @param {Rule[]} ruleList List of rules. - * @param {boolean} synchronous Whether to execute synchronously. - * @returns {string} Error message if validation fails. - */ -function validateRuleList(ruleList, synchronous) { - let result = null; - if (ruleList.length === rules.length) { - // No need to validate if only using built-in rules - return result; - } - const allIds = {}; - ruleList.forEach(function forRule(rule, index) { - const customIndex = index - rules.length; - // eslint-disable-next-line jsdoc/require-jsdoc - function newError(property) { - return new Error( - "Property '" + property + "' of custom rule at index " + - customIndex + " is incorrect."); + // Now we have a portion which is definitely the auth. + // Pull that off. + if (atSign !== -1) { + auth = rest.slice(0, atSign); + rest = rest.slice(atSign + 1); + this.auth = auth; } - [ "names", "tags" ].forEach(function forProperty(property) { - const value = rule[property]; - if (!result && - (!value || !Array.isArray(value) || (value.length === 0) || - !value.every(helpers.isString) || value.some(helpers.isEmptyString))) { - result = newError(property); - } - }); - [ - [ "description", "string" ], - [ "function", "function" ] - ].forEach(function forProperty(propertyInfo) { - const property = propertyInfo[0]; - const value = rule[property]; - if (!result && (!value || (typeof value !== propertyInfo[1]))) { - result = newError(property); + + // the host is the remaining to the left of the first non-host char + hostEnd = -1; + for (i = 0; i < nonHostChars.length; i++) { + hec = rest.indexOf(nonHostChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) { + hostEnd = hec; } - }); - if ( - !result && - rule.information && - (Object.getPrototypeOf(rule.information) !== URL.prototype) - ) { - result = newError("information"); } - if ( - !result && - (rule.asynchronous !== undefined) && - (typeof rule.asynchronous !== "boolean") - ) { - result = newError("asynchronous"); - } - if (!result && rule.asynchronous && synchronous) { - result = new Error( - "Custom rule " + rule.names.join("/") + " at index " + customIndex + - " is asynchronous and can not be used in a synchronous context." - ); - } - if (!result) { - rule.names.forEach(function forName(name) { - const nameUpper = name.toUpperCase(); - if (!result && (allIds[nameUpper] !== undefined)) { - result = new Error("Name '" + name + "' of custom rule at index " + - customIndex + " is already used as a name or tag."); - } - allIds[nameUpper] = true; - }); - rule.tags.forEach(function forTag(tag) { - const tagUpper = tag.toUpperCase(); - if (!result && allIds[tagUpper]) { - result = new Error("Tag '" + tag + "' of custom rule at index " + - customIndex + " is already used as a name."); - } - allIds[tagUpper] = false; - }); + // if we still have not hit it, then the entire thing is a host. + if (hostEnd === -1) { + hostEnd = rest.length; } - }); - return result; -} -/** - * Creates a LintResults instance with toString for pretty display. - * - * @param {Rule[]} ruleList List of rules. - * @returns {LintResults} New LintResults instance. - */ -function newResults(ruleList) { - const lintResults = {}; - // eslint-disable-next-line jsdoc/require-jsdoc - function toString(useAlias) { - let ruleNameToRule = null; - const results = []; - const keys = Object.keys(lintResults); - keys.sort(); - keys.forEach(function forFile(file) { - const fileResults = lintResults[file]; - if (Array.isArray(fileResults)) { - fileResults.forEach(function forResult(result) { - const ruleMoniker = result.ruleNames ? - result.ruleNames.join("/") : - (result.ruleName + "/" + result.ruleAlias); - results.push( - file + ": " + - result.lineNumber + ": " + - ruleMoniker + " " + - result.ruleDescription + - (result.errorDetail ? - " [" + result.errorDetail + "]" : - "") + - (result.errorContext ? - " [Context: \"" + result.errorContext + "\"]" : - "")); - }); - } else { - if (!ruleNameToRule) { - ruleNameToRule = {}; - ruleList.forEach(function forRule(rule) { - const ruleName = rule.names[0].toUpperCase(); - ruleNameToRule[ruleName] = rule; - }); - } - Object.keys(fileResults).forEach(function forRule(ruleName) { - const rule = ruleNameToRule[ruleName.toUpperCase()]; - const ruleResults = fileResults[ruleName]; - ruleResults.forEach(function forLine(lineNumber) { - const nameIndex = Math.min(useAlias ? 1 : 0, rule.names.length - 1); - const result = - file + ": " + - lineNumber + ": " + - rule.names[nameIndex] + " " + - rule.description; - results.push(result); - }); - }); - } - }); - return results.join("\n"); - } - Object.defineProperty(lintResults, "toString", { "value": toString }); - // @ts-ignore - return lintResults; -} + if (rest[hostEnd - 1] === ':') { hostEnd--; } + var host = rest.slice(0, hostEnd); + rest = rest.slice(hostEnd); -/** - * Remove front matter (if present at beginning of content). - * - * @param {string} content Markdown content. - * @param {RegExp} frontMatter Regular expression to match front matter. - * @returns {Object} Trimmed content and front matter lines. - */ -function removeFrontMatter(content, frontMatter) { - let frontMatterLines = []; - if (frontMatter) { - const frontMatterMatch = content.match(frontMatter); - if (frontMatterMatch && !frontMatterMatch.index) { - const contentMatched = frontMatterMatch[0]; - content = content.slice(contentMatched.length); - frontMatterLines = contentMatched.split(helpers.newLineRe); - if ((frontMatterLines.length > 0) && - (frontMatterLines[frontMatterLines.length - 1] === "")) { - frontMatterLines.length--; + // pull out port. + this.parseHost(host); + + // we've indicated that there is a hostname, + // so even if it's empty, it has to be present. + this.hostname = this.hostname || ''; + + // if hostname begins with [ and ends with ] + // assume that it's an IPv6 address. + var ipv6Hostname = this.hostname[0] === '[' && + this.hostname[this.hostname.length - 1] === ']'; + + // validate a little. + if (!ipv6Hostname) { + var hostparts = this.hostname.split(/\./); + for (i = 0, l = hostparts.length; i < l; i++) { + var part = hostparts[i]; + if (!part) { continue; } + if (!part.match(hostnamePartPattern)) { + var newpart = ''; + for (var j = 0, k = part.length; j < k; j++) { + if (part.charCodeAt(j) > 127) { + // we replace non-ASCII char with a temporary placeholder + // we need this to make sure size of hostname is not + // broken by replacing non-ASCII by nothing + newpart += 'x'; + } else { + newpart += part[j]; + } + } + // we test again with ASCII char only + if (!newpart.match(hostnamePartPattern)) { + var validParts = hostparts.slice(0, i); + var notHost = hostparts.slice(i + 1); + var bit = part.match(hostnamePartStart); + if (bit) { + validParts.push(bit[1]); + notHost.unshift(bit[2]); + } + if (notHost.length) { + rest = notHost.join('.') + rest; + } + this.hostname = validParts.join('.'); + break; + } + } } } - } - return { - "content": content, - "frontMatterLines": frontMatterLines - }; -} -/** - * Annotate tokens with line/lineNumber. - * - * @param {MarkdownItToken[]} tokens Array of markdown-it tokens. - * @param {string[]} lines Lines of Markdown content. - * @returns {void} - */ -function annotateTokens(tokens, lines) { - let trMap = null; - tokens.forEach(function forToken(token) { - // Provide missing maps for table content - if (token.type === "tr_open") { - trMap = token.map; - } else if (token.type === "tr_close") { - trMap = null; - } - if (!token.map && trMap) { - token.map = [ ...trMap ]; + if (this.hostname.length > hostnameMaxLen) { + this.hostname = ''; } - // Adjust maps for math blocks - if (helpers.isMathBlock(token) && token.map[1]) { - // markdown-it-texmath plugin does not account for math_block_end - token.map[1]++; + + // strip [ and ] from the hostname + // the host field still retains them, though + if (ipv6Hostname) { + this.hostname = this.hostname.substr(1, this.hostname.length - 2); } - // Update token metadata - if (token.map) { - token.line = lines[token.map[0]]; - token.lineNumber = token.map[0] + 1; - // Trim bottom of token to exclude whitespace lines - while (token.map[1] && !((lines[token.map[1] - 1] || "").trim())) { - token.map[1]--; - } - // Annotate children with lineNumber - let lineNumber = token.lineNumber; - const codeSpanExtraLines = []; - helpers.forEachInlineCodeSpan( - token.content, - function handleInlineCodeSpan(code) { - codeSpanExtraLines.push(code.split(helpers.newLineRe).length - 1); - } - ); - (token.children || []).forEach(function forChild(child) { - child.lineNumber = lineNumber; - child.line = lines[lineNumber - 1]; - if ((child.type === "softbreak") || (child.type === "hardbreak")) { - lineNumber++; - } else if (child.type === "code_inline") { - lineNumber += codeSpanExtraLines.shift(); - } - }); + } + + // chop off from the tail first. + var hash = rest.indexOf('#'); + if (hash !== -1) { + // got a fragment string. + this.hash = rest.substr(hash); + rest = rest.slice(0, hash); + } + var qm = rest.indexOf('?'); + if (qm !== -1) { + this.search = rest.substr(qm); + rest = rest.slice(0, qm); + } + if (rest) { this.pathname = rest; } + if (slashedProtocol[lowerProto] && + this.hostname && !this.pathname) { + this.pathname = ''; + } + + return this; +}; + +Url.prototype.parseHost = function(host) { + var port = portPattern.exec(host); + if (port) { + port = port[0]; + if (port !== ':') { + this.port = port.substr(1); } - }); -} + host = host.substr(0, host.length - port.length); + } + if (host) { this.hostname = host; } +}; -/** - * Map rule names/tags to canonical rule name. +module.exports = urlParse; + + +/***/ }), + +/***/ 2578: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + +/* + * merge2 + * https://github.com/teambition/merge2 * - * @param {Rule[]} ruleList List of rules. - * @returns {Object.} Map of alias to rule name. + * Copyright (c) 2014-2020 Teambition + * Licensed under the MIT license. */ -function mapAliasToRuleNames(ruleList) { - const aliasToRuleNames = {}; - // const tagToRuleNames = {}; - ruleList.forEach(function forRule(rule) { - const ruleName = rule.names[0].toUpperCase(); - // The following is useful for updating README.md: - // console.log( - // "* **[" + ruleName + "](doc/Rules.md#" + ruleName.toLowerCase() + - // ")** *" + rule.names.slice(1).join("/") + "* - " + rule.description); - rule.names.forEach(function forName(name) { - const nameUpper = name.toUpperCase(); - aliasToRuleNames[nameUpper] = [ ruleName ]; - }); - rule.tags.forEach(function forTag(tag) { - const tagUpper = tag.toUpperCase(); - const ruleNames = aliasToRuleNames[tagUpper] || []; - ruleNames.push(ruleName); - aliasToRuleNames[tagUpper] = ruleNames; - // tagToRuleNames[tag] = ruleName; - }); - }); - // The following is useful for updating README.md: - // Object.keys(tagToRuleNames).sort().forEach(function forTag(tag) { - // console.log("* **" + tag + "** - " + - // aliasToRuleNames[tag.toUpperCase()].join(", ")); - // }); - // @ts-ignore - return aliasToRuleNames; -} +const Stream = __nccwpck_require__(2781) +const PassThrough = Stream.PassThrough +const slice = Array.prototype.slice -/** - * Apply (and normalize) configuration object. - * - * @param {Rule[]} ruleList List of rules. - * @param {Configuration} config Configuration object. - * @param {Object.} aliasToRuleNames Map of alias to rule - * names. - * @returns {Configuration} Effective configuration. - */ -function getEffectiveConfig(ruleList, config, aliasToRuleNames) { - const defaultKey = Object.keys(config).filter( - (key) => key.toUpperCase() === "DEFAULT" - ); - const ruleDefault = (defaultKey.length === 0) || !!config[defaultKey[0]]; - const effectiveConfig = {}; - ruleList.forEach((rule) => { - const ruleName = rule.names[0].toUpperCase(); - effectiveConfig[ruleName] = ruleDefault; - }); - deprecatedRuleNames.forEach((ruleName) => { - effectiveConfig[ruleName] = false; - }); - Object.keys(config).forEach((key) => { - let value = config[key]; - if (value) { - if (!(value instanceof Object)) { - value = {}; +module.exports = merge2 + +function merge2 () { + const streamsQueue = [] + const args = slice.call(arguments) + let merging = false + let options = args[args.length - 1] + + if (options && !Array.isArray(options) && options.pipe == null) { + args.pop() + } else { + options = {} + } + + const doEnd = options.end !== false + const doPipeError = options.pipeError === true + if (options.objectMode == null) { + options.objectMode = true + } + if (options.highWaterMark == null) { + options.highWaterMark = 64 * 1024 + } + const mergedStream = PassThrough(options) + + function addStream () { + for (let i = 0, len = arguments.length; i < len; i++) { + streamsQueue.push(pauseStreams(arguments[i], options)) + } + mergeStream() + return this + } + + function mergeStream () { + if (merging) { + return + } + merging = true + + let streams = streamsQueue.shift() + if (!streams) { + process.nextTick(endStream) + return + } + if (!Array.isArray(streams)) { + streams = [streams] + } + + let pipesCount = streams.length + 1 + + function next () { + if (--pipesCount > 0) { + return } - } else { - value = false; + merging = false + mergeStream() } - const keyUpper = key.toUpperCase(); - (aliasToRuleNames[keyUpper] || []).forEach((ruleName) => { - effectiveConfig[ruleName] = value; - }); - }); - return effectiveConfig; -} -/** - * Create a mapping of enabled rules per line. - * - * @param {Rule[]} ruleList List of rules. - * @param {string[]} lines List of content lines. - * @param {string[]} frontMatterLines List of front matter lines. - * @param {boolean} noInlineConfig Whether to allow inline configuration. - * @param {Configuration} config Configuration object. - * @param {Object.} aliasToRuleNames Map of alias to rule - * names. - * @returns {Object} Effective configuration and enabled rules per line number. - */ -function getEnabledRulesPerLineNumber( - ruleList, - lines, - frontMatterLines, - noInlineConfig, - config, - aliasToRuleNames) { - // Shared variables - let enabledRules = {}; - let capturedRules = {}; - const allRuleNames = []; - const enabledRulesPerLineNumber = new Array(1 + frontMatterLines.length); - // Helper functions - // eslint-disable-next-line jsdoc/require-jsdoc - function handleInlineConfig(input, forEachMatch, forEachLine) { - input.forEach((line, lineIndex) => { - if (!noInlineConfig) { - let match = null; - while ((match = helpers.inlineCommentRe.exec(line))) { - const action = (match[1] || match[3]).toUpperCase(); - const parameter = match[2] || match[4]; - forEachMatch(action, parameter, lineIndex + 1); + function pipe (stream) { + function onend () { + stream.removeListener('merge2UnpipeEnd', onend) + stream.removeListener('end', onend) + if (doPipeError) { + stream.removeListener('error', onerror) } + next() } - if (forEachLine) { - forEachLine(); + function onerror (err) { + mergedStream.emit('error', err) } - }); - } - // eslint-disable-next-line jsdoc/require-jsdoc - function configureFile(action, parameter) { - if (action === "CONFIGURE-FILE") { - try { - const json = JSON.parse(parameter); - config = { - ...config, - ...json - }; - } catch { - // Ignore parse errors for inline configuration + // skip ended stream + if (stream._readableState.endEmitted) { + return next() + } + + stream.on('merge2UnpipeEnd', onend) + stream.on('end', onend) + + if (doPipeError) { + stream.on('error', onerror) } + + stream.pipe(mergedStream, { end: false }) + // compatible for old stream + stream.resume() } - } - // eslint-disable-next-line jsdoc/require-jsdoc - function applyEnableDisable(action, parameter, state) { - state = { ...state }; - const enabled = (action.startsWith("ENABLE")); - const items = parameter ? - parameter.trim().toUpperCase().split(/\s+/) : - allRuleNames; - items.forEach((nameUpper) => { - (aliasToRuleNames[nameUpper] || []).forEach((ruleName) => { - state[ruleName] = enabled; - }); - }); - return state; - } - // eslint-disable-next-line jsdoc/require-jsdoc - function enableDisableFile(action, parameter) { - if ((action === "ENABLE-FILE") || (action === "DISABLE-FILE")) { - enabledRules = applyEnableDisable(action, parameter, enabledRules); + + for (let i = 0; i < streams.length; i++) { + pipe(streams[i]) } + + next() } - // eslint-disable-next-line jsdoc/require-jsdoc - function captureRestoreEnableDisable(action, parameter) { - if (action === "CAPTURE") { - capturedRules = enabledRules; - } else if (action === "RESTORE") { - enabledRules = capturedRules; - } else if ((action === "ENABLE") || (action === "DISABLE")) { - enabledRules = applyEnableDisable(action, parameter, enabledRules); + + function endStream () { + merging = false + // emit 'queueDrain' when all streams merged. + mergedStream.emit('queueDrain') + if (doEnd) { + mergedStream.end() } } - // eslint-disable-next-line jsdoc/require-jsdoc - function updateLineState() { - enabledRulesPerLineNumber.push(enabledRules); - } - // eslint-disable-next-line jsdoc/require-jsdoc - function disableNextLine(action, parameter, lineNumber) { - if (action === "DISABLE-NEXT-LINE") { - const nextLineNumber = frontMatterLines.length + lineNumber + 1; - enabledRulesPerLineNumber[nextLineNumber] = - applyEnableDisable( - action, - parameter, - enabledRulesPerLineNumber[nextLineNumber] || {} - ); - } + + mergedStream.setMaxListeners(0) + mergedStream.add = addStream + mergedStream.on('unpipe', function (stream) { + stream.emit('merge2UnpipeEnd') + }) + + if (args.length) { + addStream.apply(null, args) } - // Handle inline comments - handleInlineConfig([ lines.join("\n") ], configureFile); - const effectiveConfig = getEffectiveConfig( - ruleList, config, aliasToRuleNames); - ruleList.forEach((rule) => { - const ruleName = rule.names[0].toUpperCase(); - allRuleNames.push(ruleName); - enabledRules[ruleName] = !!effectiveConfig[ruleName]; - }); - capturedRules = enabledRules; - handleInlineConfig(lines, enableDisableFile); - handleInlineConfig(lines, captureRestoreEnableDisable, updateLineState); - handleInlineConfig(lines, disableNextLine); - // Return results - return { - effectiveConfig, - enabledRulesPerLineNumber - }; + return mergedStream } +// check and pause streams for pipe. +function pauseStreams (streams, options) { + if (!Array.isArray(streams)) { + // Backwards-compat with old-style streams + if (!streams._readableState && streams.pipe) { + streams = streams.pipe(PassThrough(options)) + } + if (!streams._readableState || !streams.pause || !streams.pipe) { + throw new Error('Only readable stream can be merged.') + } + streams.pause() + } else { + for (let i = 0, len = streams.length; i < len; i++) { + streams[i] = pauseStreams(streams[i], options) + } + } + return streams +} + + +/***/ }), + +/***/ 6228: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const util = __nccwpck_require__(3837); +const braces = __nccwpck_require__(610); +const picomatch = __nccwpck_require__(8569); +const utils = __nccwpck_require__(479); +const isEmptyString = val => val === '' || val === './'; + /** - * Lints a string containing Markdown content. + * Returns an array of strings that match one or more glob patterns. * - * @param {Rule[]} ruleList List of rules. - * @param {string} name Identifier for the content. - * @param {string} content Markdown content. - * @param {Object} md Instance of markdown-it. - * @param {Configuration} config Configuration object. - * @param {RegExp} frontMatter Regular expression for front matter. - * @param {boolean} handleRuleFailures Whether to handle exceptions in rules. - * @param {boolean} noInlineConfig Whether to allow inline configuration. - * @param {number} resultVersion Version of the LintResults object to return. - * @param {Function} callback Callback (err, result) function. - * @returns {void} + * ```js + * const mm = require('micromatch'); + * // mm(list, patterns[, options]); + * + * console.log(mm(['a.js', 'a.txt'], ['*.js'])); + * //=> [ 'a.js' ] + * ``` + * @param {String|Array} `list` List of strings to match. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) + * @return {Array} Returns an array of matches + * @summary false + * @api public */ -function lintContent( - ruleList, - name, - content, - md, - config, - frontMatter, - handleRuleFailures, - noInlineConfig, - resultVersion, - callback) { - // Remove UTF-8 byte order marker (if present) - content = content.replace(/^\uFEFF/, ""); - // Remove front matter - const removeFrontMatterResult = removeFrontMatter(content, frontMatter); - const frontMatterLines = removeFrontMatterResult.frontMatterLines; - // Ignore the content of HTML comments - content = helpers.clearHtmlCommentText(removeFrontMatterResult.content); - // Parse content into tokens and lines - const tokens = md.parse(content, {}); - const lines = content.split(helpers.newLineRe); - annotateTokens(tokens, lines); - const aliasToRuleNames = mapAliasToRuleNames(ruleList); - const { effectiveConfig, enabledRulesPerLineNumber } = - getEnabledRulesPerLineNumber( - ruleList, - lines, - frontMatterLines, - noInlineConfig, - config, - aliasToRuleNames - ); - // Create parameters for rules - const params = { - "name": helpers.deepFreeze(name), - "tokens": helpers.deepFreeze(tokens), - "lines": helpers.deepFreeze(lines), - "frontMatterLines": helpers.deepFreeze(frontMatterLines) - }; - cache.lineMetadata(helpers.getLineMetadata(params)); - cache.flattenedLists(helpers.flattenLists(params.tokens)); - cache.codeBlockAndSpanRanges( - helpers.codeBlockAndSpanRanges(params, cache.lineMetadata()) - ); - // Function to run for each rule - let results = []; - // eslint-disable-next-line jsdoc/require-jsdoc - function forRule(rule) { - // Configure rule - const ruleName = rule.names[0].toUpperCase(); - params.config = effectiveConfig[ruleName]; - // eslint-disable-next-line jsdoc/require-jsdoc - function throwError(property) { - throw new Error( - "Property '" + property + "' of onError parameter is incorrect."); + +const micromatch = (list, patterns, options) => { + patterns = [].concat(patterns); + list = [].concat(list); + + let omit = new Set(); + let keep = new Set(); + let items = new Set(); + let negatives = 0; + + let onResult = state => { + items.add(state.output); + if (options && options.onResult) { + options.onResult(state); } - // eslint-disable-next-line jsdoc/require-jsdoc - function onError(errorInfo) { - if (!errorInfo || - !helpers.isNumber(errorInfo.lineNumber) || - (errorInfo.lineNumber < 1) || - (errorInfo.lineNumber > lines.length)) { - throwError("lineNumber"); - } - const lineNumber = errorInfo.lineNumber + frontMatterLines.length; - if (!enabledRulesPerLineNumber[lineNumber][ruleName]) { - return; - } - if (errorInfo.detail && - !helpers.isString(errorInfo.detail)) { - throwError("detail"); - } - if (errorInfo.context && - !helpers.isString(errorInfo.context)) { - throwError("context"); - } - if (errorInfo.range && - (!Array.isArray(errorInfo.range) || - (errorInfo.range.length !== 2) || - !helpers.isNumber(errorInfo.range[0]) || - (errorInfo.range[0] < 1) || - !helpers.isNumber(errorInfo.range[1]) || - (errorInfo.range[1] < 1) || - ((errorInfo.range[0] + errorInfo.range[1] - 1) > - lines[errorInfo.lineNumber - 1].length))) { - throwError("range"); - } - const fixInfo = errorInfo.fixInfo; - const cleanFixInfo = {}; - if (fixInfo) { - if (!helpers.isObject(fixInfo)) { - throwError("fixInfo"); - } - if (fixInfo.lineNumber !== undefined) { - if ((!helpers.isNumber(fixInfo.lineNumber) || - (fixInfo.lineNumber < 1) || - (fixInfo.lineNumber > lines.length))) { - throwError("fixInfo.lineNumber"); - } - cleanFixInfo.lineNumber = - fixInfo.lineNumber + frontMatterLines.length; - } - const effectiveLineNumber = fixInfo.lineNumber || errorInfo.lineNumber; - if (fixInfo.editColumn !== undefined) { - if ((!helpers.isNumber(fixInfo.editColumn) || - (fixInfo.editColumn < 1) || - (fixInfo.editColumn > - lines[effectiveLineNumber - 1].length + 1))) { - throwError("fixInfo.editColumn"); - } - cleanFixInfo.editColumn = fixInfo.editColumn; - } - if (fixInfo.deleteCount !== undefined) { - if ((!helpers.isNumber(fixInfo.deleteCount) || - (fixInfo.deleteCount < -1) || - (fixInfo.deleteCount > - lines[effectiveLineNumber - 1].length))) { - throwError("fixInfo.deleteCount"); - } - cleanFixInfo.deleteCount = fixInfo.deleteCount; - } - if (fixInfo.insertText !== undefined) { - if (!helpers.isString(fixInfo.insertText)) { - throwError("fixInfo.insertText"); - } - cleanFixInfo.insertText = fixInfo.insertText; - } + }; + + for (let i = 0; i < patterns.length; i++) { + let isMatch = picomatch(String(patterns[i]), { ...options, onResult }, true); + let negated = isMatch.state.negated || isMatch.state.negatedExtglob; + if (negated) negatives++; + + for (let item of list) { + let matched = isMatch(item, true); + + let match = negated ? !matched.isMatch : matched.isMatch; + if (!match) continue; + + if (negated) { + omit.add(matched.output); + } else { + omit.delete(matched.output); + keep.add(matched.output); } - results.push({ - lineNumber, - "ruleName": rule.names[0], - "ruleNames": rule.names, - "ruleDescription": rule.description, - "ruleInformation": rule.information ? rule.information.href : null, - "errorDetail": errorInfo.detail || null, - "errorContext": errorInfo.context || null, - "errorRange": errorInfo.range ? [ ...errorInfo.range ] : null, - "fixInfo": fixInfo ? cleanFixInfo : null - }); } - // Call (possibly external) rule function to report errors - const catchCallsOnError = (error) => onError({ - "lineNumber": 1, - "detail": `This rule threw an exception: ${error.message || error}` - }); - const invokeRuleFunction = () => rule.function(params, onError); - if (rule.asynchronous) { - // Asynchronous rule, ensure it returns a Promise - const ruleFunctionPromise = - Promise.resolve().then(invokeRuleFunction); - return handleRuleFailures ? - ruleFunctionPromise.catch(catchCallsOnError) : - ruleFunctionPromise; + } + + let result = negatives === patterns.length ? [...items] : [...keep]; + let matches = result.filter(item => !omit.has(item)); + + if (options && matches.length === 0) { + if (options.failglob === true) { + throw new Error(`No matches found for "${patterns.join(', ')}"`); } - // Synchronous rule - try { - invokeRuleFunction(); - } catch (error) { - if (handleRuleFailures) { - catchCallsOnError(error); - } else { - throw error; - } + + if (options.nonull === true || options.nullglob === true) { + return options.unescape ? patterns.map(p => p.replace(/\\/g, '')) : patterns; } - return null; } - // eslint-disable-next-line jsdoc/require-jsdoc - function formatResults() { - // Sort results by rule name by line number - results.sort((a, b) => ( - a.ruleName.localeCompare(b.ruleName) || - a.lineNumber - b.lineNumber - )); - if (resultVersion < 3) { - // Remove fixInfo and multiple errors for the same rule and line number - const noPrevious = { - "ruleName": null, - "lineNumber": -1 - }; - results = results.filter((error, index, array) => { - delete error.fixInfo; - const previous = array[index - 1] || noPrevious; - return ( - (error.ruleName !== previous.ruleName) || - (error.lineNumber !== previous.lineNumber) - ); - }); - } - if (resultVersion === 0) { - // Return a dictionary of rule->[line numbers] - const dictionary = {}; - for (const error of results) { - const ruleLines = dictionary[error.ruleName] || []; - ruleLines.push(error.lineNumber); - dictionary[error.ruleName] = ruleLines; - } - // @ts-ignore - results = dictionary; - } else if (resultVersion === 1) { - // Use ruleAlias instead of ruleNames - for (const error of results) { - error.ruleAlias = error.ruleNames[1] || error.ruleName; - delete error.ruleNames; - } - } else { - // resultVersion 2 or 3: Remove unwanted ruleName - for (const error of results) { - delete error.ruleName; - } - } - return results; - } - // Run all rules - const ruleListAsync = ruleList.filter((rule) => rule.asynchronous); - const ruleListSync = ruleList.filter((rule) => !rule.asynchronous); - const ruleListAsyncFirst = [ - ...ruleListAsync, - ...ruleListSync - ]; - const callbackSuccess = () => callback(null, formatResults()); - const callbackError = - (error) => callback(error instanceof Error ? error : new Error(error)); - try { - const ruleResults = ruleListAsyncFirst.map(forRule); - if (ruleListAsync.length > 0) { - Promise.all(ruleResults.slice(0, ruleListAsync.length)) - .then(callbackSuccess) - .catch(callbackError); - } else { - callbackSuccess(); + + return matches; +}; + +/** + * Backwards compatibility + */ + +micromatch.match = micromatch; + +/** + * Returns a matcher function from the given glob `pattern` and `options`. + * The returned function takes a string to match as its only argument and returns + * true if the string is a match. + * + * ```js + * const mm = require('micromatch'); + * // mm.matcher(pattern[, options]); + * + * const isMatch = mm.matcher('*.!(*a)'); + * console.log(isMatch('a.a')); //=> false + * console.log(isMatch('a.b')); //=> true + * ``` + * @param {String} `pattern` Glob pattern + * @param {Object} `options` + * @return {Function} Returns a matcher function. + * @api public + */ + +micromatch.matcher = (pattern, options) => picomatch(pattern, options); + +/** + * Returns true if **any** of the given glob `patterns` match the specified `string`. + * + * ```js + * const mm = require('micromatch'); + * // mm.isMatch(string, patterns[, options]); + * + * console.log(mm.isMatch('a.a', ['b.*', '*.a'])); //=> true + * console.log(mm.isMatch('a.a', 'b.*')); //=> false + * ``` + * @param {String} `str` The string to test. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `[options]` See available [options](#options). + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ + +micromatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); + +/** + * Backwards compatibility + */ + +micromatch.any = micromatch.isMatch; + +/** + * Returns a list of strings that _**do not match any**_ of the given `patterns`. + * + * ```js + * const mm = require('micromatch'); + * // mm.not(list, patterns[, options]); + * + * console.log(mm.not(['a.a', 'b.b', 'c.c'], '*.a')); + * //=> ['b.b', 'c.c'] + * ``` + * @param {Array} `list` Array of strings to match. + * @param {String|Array} `patterns` One or more glob pattern to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Array} Returns an array of strings that **do not match** the given patterns. + * @api public + */ + +micromatch.not = (list, patterns, options = {}) => { + patterns = [].concat(patterns).map(String); + let result = new Set(); + let items = []; + + let onResult = state => { + if (options.onResult) options.onResult(state); + items.push(state.output); + }; + + let matches = new Set(micromatch(list, patterns, { ...options, onResult })); + + for (let item of items) { + if (!matches.has(item)) { + result.add(item); } - } catch (error) { - callbackError(error); - } finally { - cache.clear(); } -} + return [...result]; +}; /** - * Lints a file containing Markdown content. + * Returns true if the given `string` contains the given pattern. Similar + * to [.isMatch](#isMatch) but the pattern can match any part of the string. * - * @param {Rule[]} ruleList List of rules. - * @param {string} file Path of file to lint. - * @param {Object} md Instance of markdown-it. - * @param {Configuration} config Configuration object. - * @param {RegExp} frontMatter Regular expression for front matter. - * @param {boolean} handleRuleFailures Whether to handle exceptions in rules. - * @param {boolean} noInlineConfig Whether to allow inline configuration. - * @param {number} resultVersion Version of the LintResults object to return. - * @param {Object} fs File system implementation. - * @param {boolean} synchronous Whether to execute synchronously. - * @param {Function} callback Callback (err, result) function. - * @returns {void} + * ```js + * var mm = require('micromatch'); + * // mm.contains(string, pattern[, options]); + * + * console.log(mm.contains('aa/bb/cc', '*b')); + * //=> true + * console.log(mm.contains('aa/bb/cc', '*d')); + * //=> false + * ``` + * @param {String} `str` The string to match. + * @param {String|Array} `patterns` Glob pattern to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if any of the patterns matches any part of `str`. + * @api public */ -function lintFile( - ruleList, - file, - md, - config, - frontMatter, - handleRuleFailures, - noInlineConfig, - resultVersion, - fs, - synchronous, - callback) { - // eslint-disable-next-line jsdoc/require-jsdoc - function lintContentWrapper(err, content) { - if (err) { - return callback(err); - } - return lintContent(ruleList, file, content, md, config, frontMatter, - handleRuleFailures, noInlineConfig, resultVersion, callback); + +micromatch.contains = (str, pattern, options) => { + if (typeof str !== 'string') { + throw new TypeError(`Expected a string: "${util.inspect(str)}"`); } - // Make a/synchronous call to read file - if (synchronous) { - lintContentWrapper(null, fs.readFileSync(file, "utf8")); - } else { - fs.readFile(file, "utf8", lintContentWrapper); + + if (Array.isArray(pattern)) { + return pattern.some(p => micromatch.contains(str, p, options)); + } + + if (typeof pattern === 'string') { + if (isEmptyString(str) || isEmptyString(pattern)) { + return false; + } + + if (str.includes(pattern) || (str.startsWith('./') && str.slice(2).includes(pattern))) { + return true; + } } -} + + return micromatch.isMatch(str, pattern, { ...options, contains: true }); +}; /** - * Lint files and strings specified in the Options object. + * Filter the keys of the given object with the given `glob` pattern + * and `options`. Does not attempt to match nested keys. If you need this feature, + * use [glob-object][] instead. * - * @param {Options} options Options object. - * @param {boolean} synchronous Whether to execute synchronously. - * @param {Function} callback Callback (err, result) function. - * @returns {void} + * ```js + * const mm = require('micromatch'); + * // mm.matchKeys(object, patterns[, options]); + * + * const obj = { aa: 'a', ab: 'b', ac: 'c' }; + * console.log(mm.matchKeys(obj, '*b')); + * //=> { ab: 'b' } + * ``` + * @param {Object} `object` The object with keys to filter. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Object} Returns an object with only keys that match the given patterns. + * @api public */ -function lintInput(options, synchronous, callback) { - // Normalize inputs - options = options || {}; - callback = callback || function noop() {}; - // eslint-disable-next-line unicorn/prefer-spread - const ruleList = rules.concat(options.customRules || []); - const ruleErr = validateRuleList(ruleList, synchronous); - if (ruleErr) { - return callback(ruleErr); + +micromatch.matchKeys = (obj, patterns, options) => { + if (!utils.isObject(obj)) { + throw new TypeError('Expected the first argument to be an object'); } - let files = []; - if (Array.isArray(options.files)) { - files = [ ...options.files ]; - } else if (options.files) { - files = [ String(options.files) ]; - } - const strings = options.strings || {}; - const stringsKeys = Object.keys(strings); - const config = options.config || { "default": true }; - const frontMatter = (options.frontMatter === undefined) ? - helpers.frontMatterRe : options.frontMatter; - const handleRuleFailures = !!options.handleRuleFailures; - const noInlineConfig = !!options.noInlineConfig; - const resultVersion = (options.resultVersion === undefined) ? - 2 : options.resultVersion; - const md = markdownIt({ "html": true }); - const markdownItPlugins = options.markdownItPlugins || []; - markdownItPlugins.forEach(function forPlugin(plugin) { - // @ts-ignore - md.use(...plugin); - }); - const fs = options.fs || __nccwpck_require__(7147); - const results = newResults(ruleList); - let done = false; - let concurrency = 0; - // eslint-disable-next-line jsdoc/require-jsdoc - function lintWorker() { - let currentItem = null; - // eslint-disable-next-line jsdoc/require-jsdoc - function lintWorkerCallback(err, result) { - concurrency--; - if (err) { - done = true; - return callback(err); - } - results[currentItem] = result; - if (!synchronous) { - lintWorker(); - } - return null; - } - if (done) { - // Abort for error or nothing left to do - } else if (files.length > 0) { - // Lint next file - concurrency++; - currentItem = files.shift(); - lintFile( - ruleList, - currentItem, - md, - config, - frontMatter, - handleRuleFailures, - noInlineConfig, - resultVersion, - fs, - synchronous, - lintWorkerCallback - ); - } else if (stringsKeys.length > 0) { - // Lint next string - concurrency++; - currentItem = stringsKeys.shift(); - lintContent( - ruleList, - currentItem, - strings[currentItem] || "", - md, - config, - frontMatter, - handleRuleFailures, - noInlineConfig, - resultVersion, - lintWorkerCallback - ); - } else if (concurrency === 0) { - // Finish - done = true; - return callback(null, results); + let keys = micromatch(Object.keys(obj), patterns, options); + let res = {}; + for (let key of keys) res[key] = obj[key]; + return res; +}; + +/** + * Returns true if some of the strings in the given `list` match any of the given glob `patterns`. + * + * ```js + * const mm = require('micromatch'); + * // mm.some(list, patterns[, options]); + * + * console.log(mm.some(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); + * // true + * console.log(mm.some(['foo.js'], ['*.js', '!foo.js'])); + * // false + * ``` + * @param {String|Array} `list` The string or array of strings to test. Returns as soon as the first match is found. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if any `patterns` matches any of the strings in `list` + * @api public + */ + +micromatch.some = (list, patterns, options) => { + let items = [].concat(list); + + for (let pattern of [].concat(patterns)) { + let isMatch = picomatch(String(pattern), options); + if (items.some(item => isMatch(item))) { + return true; } - return null; } - if (synchronous) { - while (!done) { - lintWorker(); + return false; +}; + +/** + * Returns true if every string in the given `list` matches + * any of the given glob `patterns`. + * + * ```js + * const mm = require('micromatch'); + * // mm.every(list, patterns[, options]); + * + * console.log(mm.every('foo.js', ['foo.js'])); + * // true + * console.log(mm.every(['foo.js', 'bar.js'], ['*.js'])); + * // true + * console.log(mm.every(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); + * // false + * console.log(mm.every(['foo.js'], ['*.js', '!foo.js'])); + * // false + * ``` + * @param {String|Array} `list` The string or array of strings to test. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if all `patterns` matches all of the strings in `list` + * @api public + */ + +micromatch.every = (list, patterns, options) => { + let items = [].concat(list); + + for (let pattern of [].concat(patterns)) { + let isMatch = picomatch(String(pattern), options); + if (!items.every(item => isMatch(item))) { + return false; } - } else { - // Testing on a Raspberry Pi 4 Model B with an artificial 5ms file access - // delay suggests that a concurrency factor of 8 can eliminate the impact - // of that delay (i.e., total time is the same as with no delay). - lintWorker(); - lintWorker(); - lintWorker(); - lintWorker(); - lintWorker(); - lintWorker(); - lintWorker(); - lintWorker(); } - return null; -} + return true; +}; /** - * Lint specified Markdown files. + * Returns true if **all** of the given `patterns` match + * the specified string. * - * @param {Options} options Configuration options. - * @param {LintCallback} callback Callback (err, result) function. - * @returns {void} + * ```js + * const mm = require('micromatch'); + * // mm.all(string, patterns[, options]); + * + * console.log(mm.all('foo.js', ['foo.js'])); + * // true + * + * console.log(mm.all('foo.js', ['*.js', '!foo.js'])); + * // false + * + * console.log(mm.all('foo.js', ['*.js', 'foo.js'])); + * // true + * + * console.log(mm.all('foo.js', ['*.js', 'f*', '*o*', '*o.js'])); + * // true + * ``` + * @param {String|Array} `str` The string to test. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if any patterns match `str` + * @api public */ -function markdownlint(options, callback) { - return lintInput(options, false, callback); -} -const markdownlintPromisify = promisify && promisify(markdownlint); +micromatch.all = (str, patterns, options) => { + if (typeof str !== 'string') { + throw new TypeError(`Expected a string: "${util.inspect(str)}"`); + } + + return [].concat(patterns).every(p => picomatch(p, options)(str)); +}; /** - * Lint specified Markdown files. + * Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match. * - * @param {Options} options Configuration options. - * @returns {Promise} Results object. + * ```js + * const mm = require('micromatch'); + * // mm.capture(pattern, string[, options]); + * + * console.log(mm.capture('test/*.js', 'test/foo.js')); + * //=> ['foo'] + * console.log(mm.capture('test/*.js', 'foo/bar.css')); + * //=> null + * ``` + * @param {String} `glob` Glob pattern to use for matching. + * @param {String} `input` String to match + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Array|null} Returns an array of captures if the input matches the glob pattern, otherwise `null`. + * @api public */ -function markdownlintPromise(options) { - return markdownlintPromisify(options); -} + +micromatch.capture = (glob, input, options) => { + let posix = utils.isWindows(options); + let regex = picomatch.makeRe(String(glob), { ...options, capture: true }); + let match = regex.exec(posix ? utils.toPosixSlashes(input) : input); + + if (match) { + return match.slice(1).map(v => v === void 0 ? '' : v); + } +}; /** - * Lint specified Markdown files synchronously. + * Create a regular expression from the given glob `pattern`. * - * @param {Options} options Configuration options. - * @returns {LintResults} Results object. + * ```js + * const mm = require('micromatch'); + * // mm.makeRe(pattern[, options]); + * + * console.log(mm.makeRe('*.js')); + * //=> /^(?:(\.[\\\/])?(?!\.)(?=.)[^\/]*?\.js)$/ + * ``` + * @param {String} `pattern` A glob pattern to convert to regex. + * @param {Object} `options` + * @return {RegExp} Returns a regex created from the given pattern. + * @api public */ -function markdownlintSync(options) { - let results = null; - lintInput(options, true, function callback(error, res) { - if (error) { - throw error; - } - results = res; - }); - return results; -} + +micromatch.makeRe = (...args) => picomatch.makeRe(...args); /** - * Parse the content of a configuration file. + * Scan a glob pattern to separate the pattern into segments. Used + * by the [split](#split) method. * - * @param {string} name Name of the configuration file. - * @param {string} content Configuration content. - * @param {ConfigurationParser[]} parsers Parsing function(s). - * @returns {Object} Configuration object and error message. + * ```js + * const mm = require('micromatch'); + * const state = mm.scan(pattern[, options]); + * ``` + * @param {String} `pattern` + * @param {Object} `options` + * @return {Object} Returns an object with + * @api public */ -function parseConfiguration(name, content, parsers) { - let config = null; - let message = ""; - const errors = []; - let index = 0; - // Try each parser - (parsers || [ JSON.parse ]).every((parser) => { - try { - config = parser(content); - } catch (error) { - errors.push(`Parser ${index++}: ${error.message}`); - } - return !config; - }); - // Message if unable to parse - if (!config) { - errors.unshift(`Unable to parse '${name}'`); - message = errors.join("; "); - } - return { - config, - message - }; -} -/** - * Resolve referenced "extends" path in a configuration file - * using path.resolve() with require.resolve() as a fallback. - * - * @param {string} configFile Configuration file name. - * @param {string} referenceId Referenced identifier to resolve. - * @param {Object} fs File system implementation. - * @param {ResolveConfigExtendsCallback} [callback] Callback (err, result) - * function. - * @returns {void} - */ -function resolveConfigExtends(configFile, referenceId, fs, callback) { - const configFileDirname = path.dirname(configFile); - const resolvedExtendsFile = path.resolve(configFileDirname, referenceId); - fs.access(resolvedExtendsFile, (err) => { - if (err) { - // Not a file, try require.resolve - try { - return callback(null, dynamicRequire.resolve( - referenceId, - { "paths": [ configFileDirname ] } - )); - } catch { - // Unable to resolve, use resolvedExtendsFile - } - } - return callback(null, resolvedExtendsFile); - }); -} +micromatch.scan = (...args) => picomatch.scan(...args); /** - * Resolve referenced "extends" path in a configuration file - * using path.resolve() with require.resolve() as a fallback. + * Parse a glob pattern to create the source string for a regular + * expression. * - * @param {string} configFile Configuration file name. - * @param {string} referenceId Referenced identifier to resolve. - * @param {Object} fs File system implementation. - * @returns {string} Resolved path to file. + * ```js + * const mm = require('micromatch'); + * const state = mm.parse(pattern[, options]); + * ``` + * @param {String} `glob` + * @param {Object} `options` + * @return {Object} Returns an object with useful properties and output to be used as regex source string. + * @api public */ -function resolveConfigExtendsSync(configFile, referenceId, fs) { - const configFileDirname = path.dirname(configFile); - const resolvedExtendsFile = path.resolve(configFileDirname, referenceId); - try { - fs.accessSync(resolvedExtendsFile); - return resolvedExtendsFile; - } catch { - // Not a file, try require.resolve - } - try { - return dynamicRequire.resolve( - referenceId, - { "paths": [ configFileDirname ] } - ); - } catch { - // Unable to resolve, return resolvedExtendsFile - } - return resolvedExtendsFile; -} -/** - * Read specified configuration file. - * - * @param {string} file Configuration file name. - * @param {ConfigurationParser[] | ReadConfigCallback} parsers Parsing - * function(s). - * @param {Object} [fs] File system implementation. - * @param {ReadConfigCallback} [callback] Callback (err, result) function. - * @returns {void} - */ -function readConfig(file, parsers, fs, callback) { - if (!callback) { - if (fs) { - callback = fs; - fs = null; - } else { - // @ts-ignore - callback = parsers; - parsers = null; +micromatch.parse = (patterns, options) => { + let res = []; + for (let pattern of [].concat(patterns || [])) { + for (let str of braces(String(pattern), options)) { + res.push(picomatch.parse(str, options)); } } - if (!fs) { - fs = __nccwpck_require__(7147); - } - // Read file - fs.readFile(file, "utf8", (err, content) => { - if (err) { - return callback(err); - } - // Try to parse file - // @ts-ignore - const { config, message } = parseConfiguration(file, content, parsers); - if (!config) { - return callback(new Error(message)); - } - // Extend configuration - const configExtends = config.extends; - if (configExtends) { - delete config.extends; - return resolveConfigExtends( - file, - configExtends, - fs, - (_, resolvedExtends) => readConfig( - resolvedExtends, - parsers, - fs, - (errr, extendsConfig) => { - if (errr) { - return callback(errr); - } - return callback(null, { - ...extendsConfig, - ...config - }); - } - ) - ); - } - return callback(null, config); - }); -} - -const readConfigPromisify = promisify && promisify(readConfig); + return res; +}; /** - * Read specified configuration file. + * Process the given brace `pattern`. * - * @param {string} file Configuration file name. - * @param {ConfigurationParser[]} [parsers] Parsing function(s). - * @param {Object} [fs] File system implementation. - * @returns {Promise} Configuration object. - */ -function readConfigPromise(file, parsers, fs) { - // @ts-ignore - return readConfigPromisify(file, parsers, fs); -} - -/** - * Read specified configuration file synchronously. + * ```js + * const { braces } = require('micromatch'); + * console.log(braces('foo/{a,b,c}/bar')); + * //=> [ 'foo/(a|b|c)/bar' ] * - * @param {string} file Configuration file name. - * @param {ConfigurationParser[]} [parsers] Parsing function(s). - * @param {Object} [fs] File system implementation. - * @returns {Configuration} Configuration object. - * @throws An Error if processing fails. + * console.log(braces('foo/{a,b,c}/bar', { expand: true })); + * //=> [ 'foo/a/bar', 'foo/b/bar', 'foo/c/bar' ] + * ``` + * @param {String} `pattern` String with brace pattern to process. + * @param {Object} `options` Any [options](#options) to change how expansion is performed. See the [braces][] library for all available options. + * @return {Array} + * @api public */ -function readConfigSync(file, parsers, fs) { - if (!fs) { - fs = __nccwpck_require__(7147); - } - // Read file - const content = fs.readFileSync(file, "utf8"); - // Try to parse file - const { config, message } = parseConfiguration(file, content, parsers); - if (!config) { - throw new Error(message); - } - // Extend configuration - const configExtends = config.extends; - if (configExtends) { - delete config.extends; - const resolvedExtends = resolveConfigExtendsSync(file, configExtends, fs); - return { - ...readConfigSync(resolvedExtends, parsers, fs), - ...config - }; + +micromatch.braces = (pattern, options) => { + if (typeof pattern !== 'string') throw new TypeError('Expected a string'); + if ((options && options.nobrace === true) || !/\{.*\}/.test(pattern)) { + return [pattern]; } - return config; -} + return braces(pattern, options); +}; /** - * Gets the (semantic) version of the library. - * - * @returns {string} SemVer string. + * Expand braces */ -function getVersion() { - return (__nccwpck_require__(5039).version); -} -// Export a/synchronous/Promise APIs -markdownlint.sync = markdownlintSync; -markdownlint.readConfig = readConfig; -markdownlint.readConfigSync = readConfigSync; -markdownlint.getVersion = getVersion; -markdownlint.promises = { - "markdownlint": markdownlintPromise, - "readConfig": readConfigPromise +micromatch.braceExpand = (pattern, options) => { + if (typeof pattern !== 'string') throw new TypeError('Expected a string'); + return micromatch.braces(pattern, { ...options, expand: true }); }; -module.exports = markdownlint; - -// Type declarations /** - * Function to implement rule logic. - * - * @callback RuleFunction - * @param {RuleParams} params Rule parameters. - * @param {RuleOnError} onError Error-reporting callback. - * @returns {void} + * Expose micromatch */ -/** - * Rule parameters. - * - * @typedef {Object} RuleParams - * @property {string} name File/string name. - * @property {MarkdownItToken[]} tokens Token objects from markdown-it. - * @property {string[]} lines File/string lines. - * @property {string[]} frontMatterLines Front matter lines. - * @property {RuleConfiguration} config Rule configuration. - */ - -/** - * Markdown-It token. - * - * @typedef {Object} MarkdownItToken - * @property {string[][]} attrs HTML attributes. - * @property {boolean} block Block-level token. - * @property {MarkdownItToken[]} children Child nodes. - * @property {string} content Tag contents. - * @property {boolean} hidden Ignore element. - * @property {string} info Fence info. - * @property {number} level Nesting level. - * @property {number[]} map Beginning/ending line numbers. - * @property {string} markup Markup text. - * @property {Object} meta Arbitrary data. - * @property {number} nesting Level change. - * @property {string} tag HTML tag name. - * @property {string} type Token type. - * @property {number} lineNumber Line number (1-based). - * @property {string} line Line content. - */ - -/** - * Error-reporting callback. - * - * @callback RuleOnError - * @param {RuleOnErrorInfo} onErrorInfo Error information. - * @returns {void} - */ - -/** - * Fix information for RuleOnError callback. - * - * @typedef {Object} RuleOnErrorInfo - * @property {number} lineNumber Line number (1-based). - * @property {string} [detail] Detail about the error. - * @property {string} [context] Context for the error. - * @property {number[]} [range] Column number (1-based) and length. - * @property {RuleOnErrorFixInfo} [fixInfo] Fix information. - */ - -/** - * Fix information for RuleOnErrorInfo. - * - * @typedef {Object} RuleOnErrorFixInfo - * @property {number} [lineNumber] Line number (1-based). - * @property {number} [editColumn] Column of the fix (1-based). - * @property {number} [deleteCount] Count of characters to delete. - * @property {string} [insertText] Text to insert (after deleting). - */ - -/** - * Rule definition. - * - * @typedef {Object} Rule - * @property {string[]} names Rule name(s). - * @property {string} description Rule description. - * @property {URL} [information] Link to more information. - * @property {string[]} tags Rule tag(s). - * @property {boolean} [asynchronous] True if asynchronous. - * @property {RuleFunction} function Rule implementation. - */ +module.exports = micromatch; -/** - * Configuration options. - * - * @typedef {Object} Options - * @property {string[] | string} [files] Files to lint. - * @property {Object.} [strings] Strings to lint. - * @property {Configuration} [config] Configuration object. - * @property {Rule[] | Rule} [customRules] Custom rules. - * @property {RegExp} [frontMatter] Front matter pattern. - * @property {boolean} [handleRuleFailures] True to catch exceptions. - * @property {boolean} [noInlineConfig] True to ignore HTML directives. - * @property {number} [resultVersion] Results object version. - * @property {Plugin[]} [markdownItPlugins] Additional plugins. - * @property {Object} [fs] File system implementation. - */ -/** - * A markdown-it plugin. - * - * @typedef {Array} Plugin - */ +/***/ }), -/** - * Function to pretty-print lint results. - * - * @callback ToStringCallback - * @param {boolean} [ruleAliases] True to use rule aliases. - * @returns {string} - */ +/***/ 3433: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -/** - * Lint results (for resultVersion 3). - * - * @typedef {Object.} LintResults - * @property {ToStringCallback} toString String representation. - */ +"use strict"; -/** - * Lint error. - * - * @typedef {Object} LintError - * @property {number} lineNumber Line number (1-based). - * @property {string[]} ruleNames Rule name(s). - * @property {string} ruleDescription Rule description. - * @property {string} ruleInformation Link to more information. - * @property {string} errorDetail Detail about the error. - * @property {string} errorContext Context for the error. - * @property {number[]} errorRange Column number (1-based) and length. - * @property {FixInfo} [fixInfo] Fix information. - */ +const {promisify} = __nccwpck_require__(3837); +const fs = __nccwpck_require__(7147); -/** - * Fix information. - * - * @typedef {Object} FixInfo - * @property {number} [lineNumber] Line number (1-based). - * @property {number} [editColumn] Column of the fix (1-based). - * @property {number} [deleteCount] Count of characters to delete. - * @property {string} [insertText] Text to insert (after deleting). - */ +async function isType(fsStatType, statsMethodName, filePath) { + if (typeof filePath !== 'string') { + throw new TypeError(`Expected a string, got ${typeof filePath}`); + } -/** - * Called with the result of the lint function. - * - * @callback LintCallback - * @param {Error | null} err Error object or null. - * @param {LintResults} [results] Lint results. - * @returns {void} - */ + try { + const stats = await promisify(fs[fsStatType])(filePath); + return stats[statsMethodName](); + } catch (error) { + if (error.code === 'ENOENT') { + return false; + } -/** - * Configuration object for linting rules. For a detailed schema, see - * {@link ../schema/markdownlint-config-schema.json}. - * - * @typedef {Object.} Configuration - */ + throw error; + } +} -/** - * Rule configuration object. - * - * @typedef {boolean | Object} RuleConfiguration Rule configuration. - */ +function isTypeSync(fsStatType, statsMethodName, filePath) { + if (typeof filePath !== 'string') { + throw new TypeError(`Expected a string, got ${typeof filePath}`); + } -/** - * Parses a configuration string and returns a configuration object. - * - * @callback ConfigurationParser - * @param {string} text Configuration string. - * @returns {Configuration} - */ + try { + return fs[fsStatType](filePath)[statsMethodName](); + } catch (error) { + if (error.code === 'ENOENT') { + return false; + } -/** - * Called with the result of the readConfig function. - * - * @callback ReadConfigCallback - * @param {Error | null} err Error object or null. - * @param {Configuration} [config] Configuration object. - * @returns {void} - */ + throw error; + } +} -/** - * Called with the result of the resolveConfigExtends function. - * - * @callback ResolveConfigExtendsCallback - * @param {Error | null} err Error object or null. - * @param {string} [path] Resolved path to file. - * @returns {void} - */ +exports.isFile = isType.bind(null, 'stat', 'isFile'); +exports.isDirectory = isType.bind(null, 'stat', 'isDirectory'); +exports.isSymlink = isType.bind(null, 'lstat', 'isSymbolicLink'); +exports.isFileSync = isTypeSync.bind(null, 'statSync', 'isFile'); +exports.isDirectorySync = isTypeSync.bind(null, 'statSync', 'isDirectory'); +exports.isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink'); /***/ }), -/***/ 3516: +/***/ 8569: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -// @ts-check - - -const { addErrorDetailIf, filterTokens } = __nccwpck_require__(2935); -module.exports = { - "names": [ "MD001", "heading-increment", "header-increment" ], - "description": "Heading levels should only increment by one level at a time", - "tags": [ "headings", "headers" ], - "function": function MD001(params, onError) { - let prevLevel = 0; - filterTokens(params, "heading_open", function forToken(token) { - const level = Number.parseInt(token.tag.slice(1), 10); - if (prevLevel && (level > prevLevel)) { - addErrorDetailIf(onError, token.lineNumber, - "h" + (prevLevel + 1), "h" + level); - } - prevLevel = level; - }); - } -}; +module.exports = __nccwpck_require__(3322); /***/ }), -/***/ 7706: +/***/ 6099: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -// @ts-check - - - -const { addErrorDetailIf } = __nccwpck_require__(2935); -module.exports = { - "names": [ "MD002", "first-heading-h1", "first-header-h1" ], - "description": "First heading should be a top-level heading", - "tags": [ "headings", "headers" ], - "function": function MD002(params, onError) { - const level = Number(params.config.level || 1); - const tag = "h" + level; - params.tokens.every(function forToken(token) { - if (token.type === "heading_open") { - addErrorDetailIf(onError, token.lineNumber, tag, token.tag); - return false; - } - return true; - }); - } -}; +const path = __nccwpck_require__(1017); +const WIN_SLASH = '\\\\/'; +const WIN_NO_SLASH = `[^${WIN_SLASH}]`; -/***/ }), +/** + * Posix glob regex + */ -/***/ 2898: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const DOT_LITERAL = '\\.'; +const PLUS_LITERAL = '\\+'; +const QMARK_LITERAL = '\\?'; +const SLASH_LITERAL = '\\/'; +const ONE_CHAR = '(?=.)'; +const QMARK = '[^/]'; +const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; +const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; +const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; +const NO_DOT = `(?!${DOT_LITERAL})`; +const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; +const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; +const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; +const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; +const STAR = `${QMARK}*?`; -"use strict"; -// @ts-check +const POSIX_CHARS = { + DOT_LITERAL, + PLUS_LITERAL, + QMARK_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + QMARK, + END_ANCHOR, + DOTS_SLASH, + NO_DOT, + NO_DOTS, + NO_DOT_SLASH, + NO_DOTS_SLASH, + QMARK_NO_DOT, + STAR, + START_ANCHOR +}; +/** + * Windows glob regex + */ +const WINDOWS_CHARS = { + ...POSIX_CHARS, -const { addErrorDetailIf, filterTokens, headingStyleFor } = - __nccwpck_require__(2935); + SLASH_LITERAL: `[${WIN_SLASH}]`, + QMARK: WIN_NO_SLASH, + STAR: `${WIN_NO_SLASH}*?`, + DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, + NO_DOT: `(?!${DOT_LITERAL})`, + NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, + NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, + NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, + QMARK_NO_DOT: `[^.${WIN_SLASH}]`, + START_ANCHOR: `(?:^|[${WIN_SLASH}])`, + END_ANCHOR: `(?:[${WIN_SLASH}]|$)` +}; + +/** + * POSIX Bracket Regex + */ + +const POSIX_REGEX_SOURCE = { + alnum: 'a-zA-Z0-9', + alpha: 'a-zA-Z', + ascii: '\\x00-\\x7F', + blank: ' \\t', + cntrl: '\\x00-\\x1F\\x7F', + digit: '0-9', + graph: '\\x21-\\x7E', + lower: 'a-z', + print: '\\x20-\\x7E ', + punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', + space: ' \\t\\r\\n\\v\\f', + upper: 'A-Z', + word: 'A-Za-z0-9_', + xdigit: 'A-Fa-f0-9' +}; module.exports = { - "names": [ "MD003", "heading-style", "header-style" ], - "description": "Heading style", - "tags": [ "headings", "headers" ], - "function": function MD003(params, onError) { - let style = String(params.config.style || "consistent"); - filterTokens(params, "heading_open", function forToken(token) { - const styleForToken = headingStyleFor(token); - if (style === "consistent") { - style = styleForToken; - } - if (styleForToken !== style) { - const h12 = /h[12]/.test(token.tag); - const setextWithAtx = - (style === "setext_with_atx") && - ((h12 && (styleForToken === "setext")) || - (!h12 && (styleForToken === "atx"))); - const setextWithAtxClosed = - (style === "setext_with_atx_closed") && - ((h12 && (styleForToken === "setext")) || - (!h12 && (styleForToken === "atx_closed"))); - if (!setextWithAtx && !setextWithAtxClosed) { - let expected = style; - if (style === "setext_with_atx") { - expected = h12 ? "setext" : "atx"; - } else if (style === "setext_with_atx_closed") { - expected = h12 ? "setext" : "atx_closed"; - } - addErrorDetailIf(onError, token.lineNumber, - expected, styleForToken); - } - } - }); + MAX_LENGTH: 1024 * 64, + POSIX_REGEX_SOURCE, + + // regular expressions + REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, + REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, + REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, + REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, + REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, + REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, + + // Replace globs with equivalent patterns to reduce parsing time. + REPLACEMENTS: { + '***': '*', + '**/**': '**', + '**/**/**': '**' + }, + + // Digits + CHAR_0: 48, /* 0 */ + CHAR_9: 57, /* 9 */ + + // Alphabet chars. + CHAR_UPPERCASE_A: 65, /* A */ + CHAR_LOWERCASE_A: 97, /* a */ + CHAR_UPPERCASE_Z: 90, /* Z */ + CHAR_LOWERCASE_Z: 122, /* z */ + + CHAR_LEFT_PARENTHESES: 40, /* ( */ + CHAR_RIGHT_PARENTHESES: 41, /* ) */ + + CHAR_ASTERISK: 42, /* * */ + + // Non-alphabetic chars. + CHAR_AMPERSAND: 38, /* & */ + CHAR_AT: 64, /* @ */ + CHAR_BACKWARD_SLASH: 92, /* \ */ + CHAR_CARRIAGE_RETURN: 13, /* \r */ + CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ + CHAR_COLON: 58, /* : */ + CHAR_COMMA: 44, /* , */ + CHAR_DOT: 46, /* . */ + CHAR_DOUBLE_QUOTE: 34, /* " */ + CHAR_EQUAL: 61, /* = */ + CHAR_EXCLAMATION_MARK: 33, /* ! */ + CHAR_FORM_FEED: 12, /* \f */ + CHAR_FORWARD_SLASH: 47, /* / */ + CHAR_GRAVE_ACCENT: 96, /* ` */ + CHAR_HASH: 35, /* # */ + CHAR_HYPHEN_MINUS: 45, /* - */ + CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ + CHAR_LEFT_CURLY_BRACE: 123, /* { */ + CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ + CHAR_LINE_FEED: 10, /* \n */ + CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ + CHAR_PERCENT: 37, /* % */ + CHAR_PLUS: 43, /* + */ + CHAR_QUESTION_MARK: 63, /* ? */ + CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ + CHAR_RIGHT_CURLY_BRACE: 125, /* } */ + CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ + CHAR_SEMICOLON: 59, /* ; */ + CHAR_SINGLE_QUOTE: 39, /* ' */ + CHAR_SPACE: 32, /* */ + CHAR_TAB: 9, /* \t */ + CHAR_UNDERSCORE: 95, /* _ */ + CHAR_VERTICAL_LINE: 124, /* | */ + CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ + + SEP: path.sep, + + /** + * Create EXTGLOB_CHARS + */ + + extglobChars(chars) { + return { + '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, + '?': { type: 'qmark', open: '(?:', close: ')?' }, + '+': { type: 'plus', open: '(?:', close: ')+' }, + '*': { type: 'star', open: '(?:', close: ')*' }, + '@': { type: 'at', open: '(?:', close: ')' } + }; + }, + + /** + * Create GLOB_CHARS + */ + + globChars(win32) { + return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; } }; /***/ }), -/***/ 3469: +/***/ 2139: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -// @ts-check +const constants = __nccwpck_require__(6099); +const utils = __nccwpck_require__(479); -const { addErrorDetailIf, listItemMarkerRe, unorderedListStyleFor } = - __nccwpck_require__(2935); -const { flattenedLists } = __nccwpck_require__(3266); +/** + * Constants + */ -const expectedStyleToMarker = { - "dash": "-", - "plus": "+", - "asterisk": "*" +const { + MAX_LENGTH, + POSIX_REGEX_SOURCE, + REGEX_NON_SPECIAL_CHARS, + REGEX_SPECIAL_CHARS_BACKREF, + REPLACEMENTS +} = constants; + +/** + * Helpers + */ + +const expandRange = (args, options) => { + if (typeof options.expandRange === 'function') { + return options.expandRange(...args, options); + } + + args.sort(); + const value = `[${args.join('-')}]`; + + try { + /* eslint-disable-next-line no-new */ + new RegExp(value); + } catch (ex) { + return args.map(v => utils.escapeRegex(v)).join('..'); + } + + return value; }; -const differentItemStyle = { - "dash": "plus", - "plus": "asterisk", - "asterisk": "dash" + +/** + * Create the message for a syntax error + */ + +const syntaxError = (type, char) => { + return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; }; -const validStyles = Object.keys(expectedStyleToMarker); -module.exports = { - "names": [ "MD004", "ul-style" ], - "description": "Unordered list style", - "tags": [ "bullet", "ul" ], - "function": function MD004(params, onError) { - const style = String(params.config.style || "consistent"); - let expectedStyle = style; - const nestingStyles = []; - flattenedLists().forEach((list) => { - if (list.unordered) { - if (expectedStyle === "consistent") { - expectedStyle = unorderedListStyleFor(list.items[0]); - } - list.items.forEach((item) => { - const itemStyle = unorderedListStyleFor(item); - if (style === "sublist") { - const nesting = list.nesting; - if (!nestingStyles[nesting]) { - nestingStyles[nesting] = - (itemStyle === nestingStyles[nesting - 1]) ? - differentItemStyle[itemStyle] : - itemStyle; - } - expectedStyle = nestingStyles[nesting]; - } - if (!validStyles.includes(expectedStyle)) { - expectedStyle = validStyles[0]; - } - let range = null; - let fixInfo = null; - const match = item.line.match(listItemMarkerRe); - if (match) { - const column = match.index + 1; - const length = match[0].length; - range = [ column, length ]; - fixInfo = { - "editColumn": match[1].length + 1, - "deleteCount": 1, - "insertText": expectedStyleToMarker[expectedStyle] - }; - } - addErrorDetailIf( - onError, - item.lineNumber, - expectedStyle, - itemStyle, - null, - null, - range, - fixInfo - ); - }); - } - }); +/** + * Parse the given input string. + * @param {String} input + * @param {Object} options + * @return {Object} + */ + +const parse = (input, options) => { + if (typeof input !== 'string') { + throw new TypeError('Expected a string'); } -}; + input = REPLACEMENTS[input] || input; -/***/ }), + const opts = { ...options }; + const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; -/***/ 1842: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + let len = input.length; + if (len > max) { + throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); + } -"use strict"; -// @ts-check + const bos = { type: 'bos', value: '', output: opts.prepend || '' }; + const tokens = [bos]; + const capture = opts.capture ? '' : '?:'; + const win32 = utils.isWindows(options); + // create constants based on platform, for windows or posix + const PLATFORM_CHARS = constants.globChars(win32); + const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS); -const { addError, addErrorDetailIf, indentFor, listItemMarkerRe, - orderedListItemMarkerRe, rangeFromRegExp } = __nccwpck_require__(2935); -const { flattenedLists } = __nccwpck_require__(3266); + const { + DOT_LITERAL, + PLUS_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + DOTS_SLASH, + NO_DOT, + NO_DOT_SLASH, + NO_DOTS_SLASH, + QMARK, + QMARK_NO_DOT, + STAR, + START_ANCHOR + } = PLATFORM_CHARS; -module.exports = { - "names": [ "MD005", "list-indent" ], - "description": "Inconsistent indentation for list items at the same level", - "tags": [ "bullet", "ul", "indentation" ], - "function": function MD005(params, onError) { - flattenedLists().forEach((list) => { - const expectedIndent = list.indent; - let expectedEnd = 0; - let actualEnd = -1; - let endMatching = false; - list.items.forEach((item) => { - const { line, lineNumber } = item; - const actualIndent = indentFor(item); - let match = null; - if (list.unordered) { - addErrorDetailIf( - onError, - lineNumber, - expectedIndent, - actualIndent, - null, - null, - rangeFromRegExp(line, listItemMarkerRe) - // No fixInfo; MD007 handles this scenario better - ); - } else if ((match = orderedListItemMarkerRe.exec(line))) { - actualEnd = match[0].length; - expectedEnd = expectedEnd || actualEnd; - const markerLength = match[1].length + 1; - if ((expectedIndent !== actualIndent) || endMatching) { - if (expectedEnd === actualEnd) { - endMatching = true; - } else { - const detail = endMatching ? - `Expected: (${expectedEnd}); Actual: (${actualEnd})` : - `Expected: ${expectedIndent}; Actual: ${actualIndent}`; - const expected = endMatching ? - expectedEnd - markerLength : - expectedIndent; - const actual = endMatching ? - actualEnd - markerLength : - actualIndent; - addError( - onError, - lineNumber, - detail, - null, - rangeFromRegExp(line, listItemMarkerRe), - { - "editColumn": Math.min(actual, expected) + 1, - "deleteCount": Math.max(actual - expected, 0), - "insertText": "".padEnd(Math.max(expected - actual, 0)) - } - ); - } - } - } - }); - }); - } -}; + const globstar = opts => { + return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; + }; + const nodot = opts.dot ? '' : NO_DOT; + const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; + let star = opts.bash === true ? globstar(opts) : STAR; -/***/ }), + if (opts.capture) { + star = `(${star})`; + } -/***/ 2246: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // minimatch options support + if (typeof opts.noext === 'boolean') { + opts.noextglob = opts.noext; + } -"use strict"; -// @ts-check + const state = { + input, + index: -1, + start: 0, + dot: opts.dot === true, + consumed: '', + output: '', + prefix: '', + backtrack: false, + negated: false, + brackets: 0, + braces: 0, + parens: 0, + quotes: 0, + globstar: false, + tokens + }; + input = utils.removePrefix(input, state); + len = input.length; + const extglobs = []; + const braces = []; + const stack = []; + let prev = bos; + let value; -const { addErrorDetailIf, listItemMarkerRe, rangeFromRegExp } = - __nccwpck_require__(2935); -const { flattenedLists } = __nccwpck_require__(3266); + /** + * Tokenizing helpers + */ -module.exports = { - "names": [ "MD006", "ul-start-left" ], - "description": - "Consider starting bulleted lists at the beginning of the line", - "tags": [ "bullet", "ul", "indentation" ], - "function": function MD006(params, onError) { - flattenedLists().forEach((list) => { - if (list.unordered && !list.nesting && (list.indent !== 0)) { - list.items.forEach((item) => { - const { lineNumber, line } = item; - addErrorDetailIf( - onError, - lineNumber, - 0, - list.indent, - null, - null, - rangeFromRegExp(line, listItemMarkerRe), - { - "deleteCount": line.length - line.trimStart().length - }); - }); - } - }); - } -}; + const eos = () => state.index === len - 1; + const peek = state.peek = (n = 1) => input[state.index + n]; + const advance = state.advance = () => input[++state.index] || ''; + const remaining = () => input.slice(state.index + 1); + const consume = (value = '', num = 0) => { + state.consumed += value; + state.index += num; + }; + const append = token => { + state.output += token.output != null ? token.output : token.value; + consume(token.value); + }; -/***/ }), + const negate = () => { + let count = 1; -/***/ 1316: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { + advance(); + state.start++; + count++; + } -"use strict"; -// @ts-check + if (count % 2 === 0) { + return false; + } + state.negated = true; + state.start++; + return true; + }; + const increment = type => { + state[type]++; + stack.push(type); + }; -const { addErrorDetailIf, indentFor, listItemMarkerRe } = - __nccwpck_require__(2935); -const { flattenedLists } = __nccwpck_require__(3266); - -module.exports = { - "names": [ "MD007", "ul-indent" ], - "description": "Unordered list indentation", - "tags": [ "bullet", "ul", "indentation" ], - "function": function MD007(params, onError) { - const indent = Number(params.config.indent || 2); - const startIndented = !!params.config.start_indented; - const startIndent = Number(params.config.start_indent || indent); - flattenedLists().forEach((list) => { - if (list.unordered && list.parentsUnordered) { - list.items.forEach((item) => { - const { lineNumber, line } = item; - const expectedIndent = - (startIndented ? startIndent : 0) + - (list.nesting * indent); - const actualIndent = indentFor(item); - let range = null; - let editColumn = 1; - const match = line.match(listItemMarkerRe); - if (match) { - range = [ 1, match[0].length ]; - editColumn += match[1].length - actualIndent; - } - addErrorDetailIf( - onError, - lineNumber, - expectedIndent, - actualIndent, - null, - null, - range, - { - editColumn, - "deleteCount": actualIndent, - "insertText": "".padEnd(expectedIndent) - }); - }); - } - }); - } -}; - + const decrement = type => { + state[type]--; + stack.pop(); + }; -/***/ }), + /** + * Push tokens onto the tokens array. This helper speeds up + * tokenizing by 1) helping us avoid backtracking as much as possible, + * and 2) helping us avoid creating extra tokens when consecutive + * characters are plain text. This improves performance and simplifies + * lookbehinds. + */ -/***/ 9798: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const push = tok => { + if (prev.type === 'globstar') { + const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); + const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); -"use strict"; -// @ts-check + if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { + state.output = state.output.slice(0, -prev.output.length); + prev.type = 'star'; + prev.value = '*'; + prev.output = star; + state.output += prev.output; + } + } + if (extglobs.length && tok.type !== 'paren') { + extglobs[extglobs.length - 1].inner += tok.value; + } + if (tok.value || tok.output) append(tok); + if (prev && prev.type === 'text' && tok.type === 'text') { + prev.value += tok.value; + prev.output = (prev.output || '') + tok.value; + return; + } -const { addError, filterTokens, forEachInlineCodeSpan, forEachLine, - includesSorted, newLineRe, numericSortAscending } = __nccwpck_require__(2935); -const { lineMetadata } = __nccwpck_require__(3266); + tok.prev = prev; + tokens.push(tok); + prev = tok; + }; -module.exports = { - "names": [ "MD009", "no-trailing-spaces" ], - "description": "Trailing spaces", - "tags": [ "whitespace" ], - "function": function MD009(params, onError) { - let brSpaces = params.config.br_spaces; - brSpaces = Number((brSpaces === undefined) ? 2 : brSpaces); - const listItemEmptyLines = !!params.config.list_item_empty_lines; - const strict = !!params.config.strict; - const listItemLineNumbers = []; - if (listItemEmptyLines) { - filterTokens(params, "list_item_open", (token) => { - for (let i = token.map[0]; i < token.map[1]; i++) { - listItemLineNumbers.push(i + 1); - } - }); - listItemLineNumbers.sort(numericSortAscending); - } - const paragraphLineNumbers = []; - const codeInlineLineNumbers = []; - if (strict) { - filterTokens(params, "paragraph_open", (token) => { - for (let i = token.map[0]; i < token.map[1] - 1; i++) { - paragraphLineNumbers.push(i + 1); - } - }); - paragraphLineNumbers.sort(numericSortAscending); - filterTokens(params, "inline", (token) => { - if (token.children.some((child) => child.type === "code_inline")) { - const tokenLines = params.lines.slice(token.map[0], token.map[1]); - forEachInlineCodeSpan(tokenLines.join("\n"), (code, lineIndex) => { - const codeLineCount = code.split(newLineRe).length; - for (let i = 0; i < codeLineCount; i++) { - codeInlineLineNumbers.push(token.lineNumber + lineIndex + i); - } - }); - } - }); - codeInlineLineNumbers.sort(numericSortAscending); - } - const expected = (brSpaces < 2) ? 0 : brSpaces; - forEachLine(lineMetadata(), (line, lineIndex, inCode) => { - const lineNumber = lineIndex + 1; - const trailingSpaces = line.length - line.trimEnd().length; - if ( - trailingSpaces && - !inCode && - !includesSorted(listItemLineNumbers, lineNumber) && - ( - (expected !== trailingSpaces) || - (strict && - (!includesSorted(paragraphLineNumbers, lineNumber) || - includesSorted(codeInlineLineNumbers, lineNumber))) - ) - ) { - const column = line.length - trailingSpaces + 1; - addError( - onError, - lineNumber, - "Expected: " + (expected === 0 ? "" : "0 or ") + - expected + "; Actual: " + trailingSpaces, - null, - [ column, trailingSpaces ], - { - "editColumn": column, - "deleteCount": trailingSpaces - }); - } - }); - } -}; + const extglobOpen = (type, value) => { + const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; + token.prev = prev; + token.parens = state.parens; + token.output = state.output; + const output = (opts.capture ? '(' : '') + token.open; -/***/ }), + increment('parens'); + push({ type, value, output: state.output ? '' : ONE_CHAR }); + push({ type: 'paren', extglob: true, value: advance(), output }); + extglobs.push(token); + }; -/***/ 9059: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const extglobClose = token => { + let output = token.close + (opts.capture ? ')' : ''); + let rest; -"use strict"; -// @ts-check + if (token.type === 'negate') { + let extglobStar = star; + if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { + extglobStar = globstar(opts); + } + if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { + output = token.close = `)$))${extglobStar}`; + } -const { addError, forEachLine, overlapsAnyRange } = __nccwpck_require__(2935); -const { codeBlockAndSpanRanges, lineMetadata } = __nccwpck_require__(3266); + if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) { + // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis. + // In this case, we need to parse the string and use it in the output of the original pattern. + // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`. + // + // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`. + const expression = parse(rest, { ...options, fastpaths: false }).output; -const tabRe = /\t+/g; + output = token.close = `)${expression})${extglobStar})`; + } -module.exports = { - "names": [ "MD010", "no-hard-tabs" ], - "description": "Hard tabs", - "tags": [ "whitespace", "hard_tab" ], - "function": function MD010(params, onError) { - const codeBlocks = params.config.code_blocks; - const includeCode = (codeBlocks === undefined) ? true : !!codeBlocks; - const spacesPerTab = params.config.spaces_per_tab; - const spaceMultiplier = (spacesPerTab === undefined) ? - 1 : - Math.max(0, Number(spacesPerTab)); - const exclusions = includeCode ? [] : codeBlockAndSpanRanges(); - forEachLine(lineMetadata(), (line, lineIndex, inCode) => { - if (includeCode || !inCode) { - let match = null; - while ((match = tabRe.exec(line)) !== null) { - const { index } = match; - const column = index + 1; - const length = match[0].length; - if (!overlapsAnyRange(exclusions, lineIndex, index, length)) { - addError( - onError, - lineIndex + 1, - "Column: " + column, - null, - [ column, length ], - { - "editColumn": column, - "deleteCount": length, - "insertText": "".padEnd(length * spaceMultiplier) - } - ); - } - } + if (token.prev.type === 'bos') { + state.negatedExtglob = true; } - }); - } -}; + } + push({ type: 'paren', extglob: true, value, output }); + decrement('parens'); + }; -/***/ }), + /** + * Fast paths + */ -/***/ 1813: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { + let backslashes = false; -"use strict"; -// @ts-check + let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { + if (first === '\\') { + backslashes = true; + return m; + } + if (first === '?') { + if (esc) { + return esc + first + (rest ? QMARK.repeat(rest.length) : ''); + } + if (index === 0) { + return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); + } + return QMARK.repeat(chars.length); + } + if (first === '.') { + return DOT_LITERAL.repeat(chars.length); + } -const { addError, forEachLine, overlapsAnyRange } = __nccwpck_require__(2935); -const { codeBlockAndSpanRanges, lineMetadata } = __nccwpck_require__(3266); + if (first === '*') { + if (esc) { + return esc + first + (rest ? star : ''); + } + return star; + } + return esc ? m : `\\${m}`; + }); -const reversedLinkRe = - /(^|[^\\])\(([^)]+)\)\[([^\]^][^\]]*)](?!\()/g; - -module.exports = { - "names": [ "MD011", "no-reversed-links" ], - "description": "Reversed link syntax", - "tags": [ "links" ], - "function": function MD011(params, onError) { - const exclusions = codeBlockAndSpanRanges(); - forEachLine(lineMetadata(), (line, lineIndex, inCode, onFence) => { - if (!inCode && !onFence) { - let match = null; - while ((match = reversedLinkRe.exec(line)) !== null) { - const [ reversedLink, preChar, linkText, linkDestination ] = match; - const index = match.index + preChar.length; - const length = match[0].length - preChar.length; - if ( - !linkText.endsWith("\\") && - !linkDestination.endsWith("\\") && - !overlapsAnyRange(exclusions, lineIndex, index, length) - ) { - addError( - onError, - lineIndex + 1, - reversedLink.slice(preChar.length), - null, - [ index + 1, length ], - { - "editColumn": index + 1, - "deleteCount": length, - "insertText": `[${linkText}](${linkDestination})` - } - ); - } - } + if (backslashes === true) { + if (opts.unescape === true) { + output = output.replace(/\\/g, ''); + } else { + output = output.replace(/\\+/g, m => { + return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); + }); } - }); - } -}; + } + + if (output === input && opts.contains === true) { + state.output = input; + return state; + } + state.output = utils.wrapOutput(output, state, options); + return state; + } -/***/ }), + /** + * Tokenize input until we reach end-of-string + */ -/***/ 3347: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + while (!eos()) { + value = advance(); -"use strict"; -// @ts-check + if (value === '\u0000') { + continue; + } + /** + * Escaped characters + */ + if (value === '\\') { + const next = peek(); -const { addErrorDetailIf, forEachLine } = __nccwpck_require__(2935); -const { lineMetadata } = __nccwpck_require__(3266); + if (next === '/' && opts.bash !== true) { + continue; + } -module.exports = { - "names": [ "MD012", "no-multiple-blanks" ], - "description": "Multiple consecutive blank lines", - "tags": [ "whitespace", "blank_lines" ], - "function": function MD012(params, onError) { - const maximum = Number(params.config.maximum || 1); - let count = 0; - forEachLine(lineMetadata(), (line, lineIndex, inCode) => { - count = (inCode || (line.trim().length > 0)) ? 0 : count + 1; - if (maximum < count) { - addErrorDetailIf( - onError, - lineIndex + 1, - maximum, - count, - null, - null, - null, - { - "deleteCount": -1 - }); + if (next === '.' || next === ';') { + continue; } - }); - } -}; + if (!next) { + value += '\\'; + push({ type: 'text', value }); + continue; + } -/***/ }), + // collapse slashes to reduce potential for exploits + const match = /^\\+/.exec(remaining()); + let slashes = 0; -/***/ 9811: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (match && match[0].length > 2) { + slashes = match[0].length; + state.index += slashes; + if (slashes % 2 !== 0) { + value += '\\'; + } + } -"use strict"; -// @ts-check + if (opts.unescape === true) { + value = advance(); + } else { + value += advance(); + } + if (state.brackets === 0) { + push({ type: 'text', value }); + continue; + } + } + /** + * If we're inside a regex character class, continue + * until we reach the closing bracket. + */ -const { addErrorDetailIf, filterTokens, forEachHeading, forEachLine, - includesSorted } = __nccwpck_require__(2935); -const { lineMetadata } = __nccwpck_require__(3266); + if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { + if (opts.posix !== false && value === ':') { + const inner = prev.value.slice(1); + if (inner.includes('[')) { + prev.posix = true; -const longLineRePrefix = "^.{"; -const longLineRePostfixRelaxed = "}.*\\s.*$"; -const longLineRePostfixStrict = "}.+$"; -const labelRe = /^\s*\[.*[^\\]]:/; -const linkOrImageOnlyLineRe = /^[es]*(lT?L|I)[ES]*$/; -const sternModeRe = /^([#>\s]*\s)?\S*$/; -const tokenTypeMap = { - "em_open": "e", - "em_close": "E", - "image": "I", - "link_open": "l", - "link_close": "L", - "strong_open": "s", - "strong_close": "S", - "text": "T" -}; + if (inner.includes(':')) { + const idx = prev.value.lastIndexOf('['); + const pre = prev.value.slice(0, idx); + const rest = prev.value.slice(idx + 2); + const posix = POSIX_REGEX_SOURCE[rest]; + if (posix) { + prev.value = pre + posix; + state.backtrack = true; + advance(); -module.exports = { - "names": [ "MD013", "line-length" ], - "description": "Line length", - "tags": [ "line_length" ], - "function": function MD013(params, onError) { - const lineLength = Number(params.config.line_length || 80); - const headingLineLength = - Number(params.config.heading_line_length || lineLength); - const codeLineLength = - Number(params.config.code_block_line_length || lineLength); - const strict = !!params.config.strict; - const stern = !!params.config.stern; - const longLineRePostfix = - (strict || stern) ? longLineRePostfixStrict : longLineRePostfixRelaxed; - const longLineRe = - new RegExp(longLineRePrefix + lineLength + longLineRePostfix); - const longHeadingLineRe = - new RegExp(longLineRePrefix + headingLineLength + longLineRePostfix); - const longCodeLineRe = - new RegExp(longLineRePrefix + codeLineLength + longLineRePostfix); - const codeBlocks = params.config.code_blocks; - const includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks; - const tables = params.config.tables; - const includeTables = (tables === undefined) ? true : !!tables; - let headings = params.config.headings; - if (headings === undefined) { - headings = params.config.headers; - } - const includeHeadings = (headings === undefined) ? true : !!headings; - const headingLineNumbers = []; - forEachHeading(params, (heading) => { - headingLineNumbers.push(heading.lineNumber); - }); - const linkOnlyLineNumbers = []; - filterTokens(params, "inline", (token) => { - let childTokenTypes = ""; - token.children.forEach((child) => { - if (child.type !== "text" || child.content !== "") { - childTokenTypes += tokenTypeMap[child.type] || "x"; + if (!bos.output && tokens.indexOf(prev) === 1) { + bos.output = ONE_CHAR; + } + continue; + } + } } - }); - if (linkOrImageOnlyLineRe.test(childTokenTypes)) { - linkOnlyLineNumbers.push(token.lineNumber); - } - }); - forEachLine(lineMetadata(), (line, lineIndex, inCode, onFence, inTable) => { - const lineNumber = lineIndex + 1; - const isHeading = includesSorted(headingLineNumbers, lineNumber); - const length = inCode ? - codeLineLength : - (isHeading ? headingLineLength : lineLength); - const lengthRe = inCode ? - longCodeLineRe : - (isHeading ? longHeadingLineRe : longLineRe); - if ((includeCodeBlocks || !inCode) && - (includeTables || !inTable) && - (includeHeadings || !isHeading) && - (strict || - (!(stern && sternModeRe.test(line)) && - !includesSorted(linkOnlyLineNumbers, lineNumber) && - !labelRe.test(line))) && - lengthRe.test(line)) { - addErrorDetailIf( - onError, - lineNumber, - length, - line.length, - null, - null, - [ length + 1, line.length - length ]); } - }); - } -}; + if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { + value = `\\${value}`; + } -/***/ }), + if (value === ']' && (prev.value === '[' || prev.value === '[^')) { + value = `\\${value}`; + } -/***/ 1004: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (opts.posix === true && value === '!' && prev.value === '[') { + value = '^'; + } -"use strict"; -// @ts-check + prev.value += value; + append({ value }); + continue; + } + /** + * If we're inside a quoted string, continue + * until we reach the closing double quote. + */ + if (state.quotes === 1 && value !== '"') { + value = utils.escapeRegex(value); + prev.value += value; + append({ value }); + continue; + } -const { addErrorContext, filterTokens } = __nccwpck_require__(2935); + /** + * Double quotes + */ -const dollarCommandRe = /^(\s*)(\$\s+)/; + if (value === '"') { + state.quotes = state.quotes === 1 ? 0 : 1; + if (opts.keepQuotes === true) { + push({ type: 'text', value }); + } + continue; + } -module.exports = { - "names": [ "MD014", "commands-show-output" ], - "description": "Dollar signs used before commands without showing output", - "tags": [ "code" ], - "function": function MD014(params, onError) { - [ "code_block", "fence" ].forEach((type) => { - filterTokens(params, type, (token) => { - const margin = (token.type === "fence") ? 1 : 0; - const dollarInstances = []; - let allDollars = true; - for (let i = token.map[0] + margin; i < token.map[1] - margin; i++) { - const line = params.lines[i]; - const lineTrim = line.trim(); - if (lineTrim) { - const match = dollarCommandRe.exec(line); - if (match) { - const column = match[1].length + 1; - const length = match[2].length; - dollarInstances.push([ i, lineTrim, column, length ]); - } else { - allDollars = false; - } - } - } - if (allDollars) { - dollarInstances.forEach((instance) => { - const [ i, lineTrim, column, length ] = instance; - addErrorContext( - onError, - i + 1, - lineTrim, - null, - null, - [ column, length ], - { - "editColumn": column, - "deleteCount": length - } - ); - }); - } - }); - }); - } -}; + /** + * Parentheses + */ + if (value === '(') { + increment('parens'); + push({ type: 'paren', value }); + continue; + } -/***/ }), + if (value === ')') { + if (state.parens === 0 && opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('opening', '(')); + } -/***/ 2450: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const extglob = extglobs[extglobs.length - 1]; + if (extglob && state.parens === extglob.parens + 1) { + extglobClose(extglobs.pop()); + continue; + } -"use strict"; -// @ts-check + push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); + decrement('parens'); + continue; + } + /** + * Square brackets + */ + if (value === '[') { + if (opts.nobracket === true || !remaining().includes(']')) { + if (opts.nobracket !== true && opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('closing', ']')); + } -const { addErrorContext, forEachLine } = __nccwpck_require__(2935); -const { lineMetadata } = __nccwpck_require__(3266); + value = `\\${value}`; + } else { + increment('brackets'); + } -module.exports = { - "names": [ "MD018", "no-missing-space-atx" ], - "description": "No space after hash on atx style heading", - "tags": [ "headings", "headers", "atx", "spaces" ], - "function": function MD018(params, onError) { - forEachLine(lineMetadata(), (line, lineIndex, inCode) => { - if (!inCode && - /^#+[^# \t]/.test(line) && - !/#\s*$/.test(line) && - !line.startsWith("#️⃣")) { - const hashCount = /^#+/.exec(line)[0].length; - addErrorContext( - onError, - lineIndex + 1, - line.trim(), - null, - null, - [ 1, hashCount + 1 ], - { - "editColumn": hashCount + 1, - "insertText": " " - } - ); + push({ type: 'bracket', value }); + continue; + } + + if (value === ']') { + if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { + push({ type: 'text', value, output: `\\${value}` }); + continue; } - }); - } -}; + if (state.brackets === 0) { + if (opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('opening', '[')); + } -/***/ }), + push({ type: 'text', value, output: `\\${value}` }); + continue; + } -/***/ 1803: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + decrement('brackets'); -"use strict"; -// @ts-check + const prevValue = prev.value.slice(1); + if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { + value = `/${value}`; + } + prev.value += value; + append({ value }); + // when literal brackets are explicitly disabled + // assume we should match with a regex character class + if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { + continue; + } -const { addErrorContext, filterTokens, headingStyleFor } = - __nccwpck_require__(2935); + const escaped = utils.escapeRegex(prev.value); + state.output = state.output.slice(0, -prev.value.length); -module.exports = { - "names": [ "MD019", "no-multiple-space-atx" ], - "description": "Multiple spaces after hash on atx style heading", - "tags": [ "headings", "headers", "atx", "spaces" ], - "function": function MD019(params, onError) { - filterTokens(params, "heading_open", (token) => { - if (headingStyleFor(token) === "atx") { - const { line, lineNumber } = token; - const match = /^(#+)([ \t]{2,})(?:\S)/.exec(line); - if (match) { - const [ - , - { "length": hashLength }, - { "length": spacesLength } - ] = match; - addErrorContext( - onError, - lineNumber, - line.trim(), - null, - null, - [ 1, hashLength + spacesLength + 1 ], - { - "editColumn": hashLength + 1, - "deleteCount": spacesLength - 1 - } - ); - } + // when literal brackets are explicitly enabled + // assume we should escape the brackets to match literal characters + if (opts.literalBrackets === true) { + state.output += escaped; + prev.value = escaped; + continue; } - }); - } -}; + // when the user specifies nothing, try to match both + prev.value = `(${capture}${escaped}|${prev.value})`; + state.output += prev.value; + continue; + } -/***/ }), + /** + * Braces + */ -/***/ 9799: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (value === '{' && opts.nobrace !== true) { + increment('braces'); -"use strict"; -// @ts-check + const open = { + type: 'brace', + value, + output: '(', + outputIndex: state.output.length, + tokensIndex: state.tokens.length + }; + braces.push(open); + push(open); + continue; + } + if (value === '}') { + const brace = braces[braces.length - 1]; -const { addErrorContext, forEachLine } = __nccwpck_require__(2935); -const { lineMetadata } = __nccwpck_require__(3266); + if (opts.nobrace === true || !brace) { + push({ type: 'text', value, output: value }); + continue; + } -module.exports = { - "names": [ "MD020", "no-missing-space-closed-atx" ], - "description": "No space inside hashes on closed atx style heading", - "tags": [ "headings", "headers", "atx_closed", "spaces" ], - "function": function MD020(params, onError) { - forEachLine(lineMetadata(), (line, lineIndex, inCode) => { - if (!inCode) { - const match = - /^(#+)([ \t]*)([^#]*?[^#\\])([ \t]*)((?:\\#)?)(#+)(\s*)$/.exec(line); - if (match) { - const [ - , - leftHash, - { "length": leftSpaceLength }, - content, - { "length": rightSpaceLength }, - rightEscape, - rightHash, - { "length": trailSpaceLength } - ] = match; - const leftHashLength = leftHash.length; - const rightHashLength = rightHash.length; - const left = !leftSpaceLength; - const right = !rightSpaceLength || rightEscape; - const rightEscapeReplacement = rightEscape ? `${rightEscape} ` : ""; - if (left || right) { - const range = left ? - [ - 1, - leftHashLength + 1 - ] : - [ - line.length - trailSpaceLength - rightHashLength, - rightHashLength + 1 - ]; - addErrorContext( - onError, - lineIndex + 1, - line.trim(), - left, - right, - range, - { - "editColumn": 1, - "deleteCount": line.length, - "insertText": - `${leftHash} ${content} ${rightEscapeReplacement}${rightHash}` - } - ); + let output = ')'; + + if (brace.dots === true) { + const arr = tokens.slice(); + const range = []; + + for (let i = arr.length - 1; i >= 0; i--) { + tokens.pop(); + if (arr[i].type === 'brace') { + break; + } + if (arr[i].type !== 'dots') { + range.unshift(arr[i].value); } } - } - }); - } -}; + output = expandRange(range, opts); + state.backtrack = true; + } -/***/ }), + if (brace.comma !== true && brace.dots !== true) { + const out = state.output.slice(0, brace.outputIndex); + const toks = state.tokens.slice(brace.tokensIndex); + brace.value = brace.output = '\\{'; + value = output = '\\}'; + state.output = out; + for (const t of toks) { + state.output += (t.output || t.value); + } + } -/***/ 385: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + push({ type: 'brace', value, output }); + decrement('braces'); + braces.pop(); + continue; + } -"use strict"; -// @ts-check + /** + * Pipes + */ + if (value === '|') { + if (extglobs.length > 0) { + extglobs[extglobs.length - 1].conditions++; + } + push({ type: 'text', value }); + continue; + } + /** + * Commas + */ -const { addErrorContext, filterTokens, headingStyleFor } = - __nccwpck_require__(2935); + if (value === ',') { + let output = value; -module.exports = { - "names": [ "MD021", "no-multiple-space-closed-atx" ], - "description": "Multiple spaces inside hashes on closed atx style heading", - "tags": [ "headings", "headers", "atx_closed", "spaces" ], - "function": function MD021(params, onError) { - filterTokens(params, "heading_open", (token) => { - if (headingStyleFor(token) === "atx_closed") { - const { line, lineNumber } = token; - const match = /^(#+)([ \t]+)([^#]+?)([ \t]+)(#+)(\s*)$/.exec(line); - if (match) { - const [ - , - leftHash, - { "length": leftSpaceLength }, - content, - { "length": rightSpaceLength }, - rightHash, - { "length": trailSpaceLength } - ] = match; - const left = leftSpaceLength > 1; - const right = rightSpaceLength > 1; - if (left || right) { - const length = line.length; - const leftHashLength = leftHash.length; - const rightHashLength = rightHash.length; - const range = left ? - [ - 1, - leftHashLength + leftSpaceLength + 1 - ] : - [ - length - trailSpaceLength - rightHashLength - rightSpaceLength, - rightSpaceLength + rightHashLength + 1 - ]; - addErrorContext( - onError, - lineNumber, - line.trim(), - left, - right, - range, - { - "editColumn": 1, - "deleteCount": length, - "insertText": `${leftHash} ${content} ${rightHash}` - } - ); - } - } + const brace = braces[braces.length - 1]; + if (brace && stack[stack.length - 1] === 'braces') { + brace.comma = true; + output = '|'; } - }); - } -}; - - -/***/ }), -/***/ 6836: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + push({ type: 'comma', value, output }); + continue; + } -"use strict"; -// @ts-check + /** + * Slashes + */ + if (value === '/') { + // if the beginning of the glob is "./", advance the start + // to the current index, and don't add the "./" characters + // to the state. This greatly simplifies lookbehinds when + // checking for BOS characters like "!" and "." (not "./") + if (prev.type === 'dot' && state.index === state.start + 1) { + state.start = state.index + 1; + state.consumed = ''; + state.output = ''; + tokens.pop(); + prev = bos; // reset "prev" to the first token + continue; + } + push({ type: 'slash', value, output: SLASH_LITERAL }); + continue; + } -const { addErrorDetailIf, filterTokens, isBlankLine } = __nccwpck_require__(2935); + /** + * Dots + */ -module.exports = { - "names": [ "MD022", "blanks-around-headings", "blanks-around-headers" ], - "description": "Headings should be surrounded by blank lines", - "tags": [ "headings", "headers", "blank_lines" ], - "function": function MD022(params, onError) { - let linesAbove = params.config.lines_above; - linesAbove = Number((linesAbove === undefined) ? 1 : linesAbove); - let linesBelow = params.config.lines_below; - linesBelow = Number((linesBelow === undefined) ? 1 : linesBelow); - const { lines } = params; - filterTokens(params, "heading_open", (token) => { - const [ topIndex, nextIndex ] = token.map; - let actualAbove = 0; - for (let i = 0; i < linesAbove; i++) { - if (isBlankLine(lines[topIndex - i - 1])) { - actualAbove++; - } + if (value === '.') { + if (state.braces > 0 && prev.type === 'dot') { + if (prev.value === '.') prev.output = DOT_LITERAL; + const brace = braces[braces.length - 1]; + prev.type = 'dots'; + prev.output += value; + prev.value += value; + brace.dots = true; + continue; } - addErrorDetailIf( - onError, - topIndex + 1, - linesAbove, - actualAbove, - "Above", - lines[topIndex].trim(), - null, - { - "insertText": "".padEnd(linesAbove - actualAbove, "\n") - }); - let actualBelow = 0; - for (let i = 0; i < linesBelow; i++) { - if (isBlankLine(lines[nextIndex + i])) { - actualBelow++; - } + + if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { + push({ type: 'text', value, output: DOT_LITERAL }); + continue; } - addErrorDetailIf( - onError, - topIndex + 1, - linesBelow, - actualBelow, - "Below", - lines[topIndex].trim(), - null, - { - "lineNumber": nextIndex + 1, - "insertText": "".padEnd(linesBelow - actualBelow, "\n") - }); - }); - } -}; + push({ type: 'dot', value, output: DOT_LITERAL }); + continue; + } -/***/ }), + /** + * Question marks + */ -/***/ 6313: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (value === '?') { + const isGroup = prev && prev.value === '('; + if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('qmark', value); + continue; + } -"use strict"; -// @ts-check + if (prev && prev.type === 'paren') { + const next = peek(); + let output = value; + if (next === '<' && !utils.supportsLookbehinds()) { + throw new Error('Node.js v10 or higher is required for regex lookbehinds'); + } + if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { + output = `\\${value}`; + } -const { addErrorContext, filterTokens } = __nccwpck_require__(2935); + push({ type: 'text', value, output }); + continue; + } -const spaceBeforeHeadingRe = /^((?:\s+)|(?:[>\s]+\s\s))[^>\s]/; + if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { + push({ type: 'qmark', value, output: QMARK_NO_DOT }); + continue; + } -module.exports = { - "names": [ "MD023", "heading-start-left", "header-start-left" ], - "description": "Headings must start at the beginning of the line", - "tags": [ "headings", "headers", "spaces" ], - "function": function MD023(params, onError) { - filterTokens(params, "heading_open", function forToken(token) { - const { lineNumber, line } = token; - const match = line.match(spaceBeforeHeadingRe); - if (match) { - const [ prefixAndFirstChar, prefix ] = match; - let deleteCount = prefix.length; - const prefixLengthNoSpace = prefix.trimEnd().length; - if (prefixLengthNoSpace) { - deleteCount -= prefixLengthNoSpace - 1; + push({ type: 'qmark', value, output: QMARK }); + continue; + } + + /** + * Exclamation + */ + + if (value === '!') { + if (opts.noextglob !== true && peek() === '(') { + if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { + extglobOpen('negate', value); + continue; } - addErrorContext( - onError, - lineNumber, - line, - null, - null, - [ 1, prefixAndFirstChar.length ], - { - "editColumn": prefixLengthNoSpace + 1, - "deleteCount": deleteCount - }); } - }); - } -}; + if (opts.nonegate !== true && state.index === 0) { + negate(); + continue; + } + } -/***/ }), + /** + * Plus + */ -/***/ 2822: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (value === '+') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('plus', value); + continue; + } -"use strict"; -// @ts-check + if ((prev && prev.value === '(') || opts.regex === false) { + push({ type: 'plus', value, output: PLUS_LITERAL }); + continue; + } + if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { + push({ type: 'plus', value }); + continue; + } + push({ type: 'plus', value: PLUS_LITERAL }); + continue; + } -const { addErrorContext, forEachHeading } = __nccwpck_require__(2935); + /** + * Plain text + */ -module.exports = { - "names": [ "MD024", "no-duplicate-heading", "no-duplicate-header" ], - "description": "Multiple headings with the same content", - "tags": [ "headings", "headers" ], - "function": function MD024(params, onError) { - const siblingsOnly = !!params.config.siblings_only || - !!params.config.allow_different_nesting || false; - const knownContents = [ null, [] ]; - let lastLevel = 1; - let knownContent = knownContents[lastLevel]; - forEachHeading(params, (heading, content) => { - if (siblingsOnly) { - const newLevel = heading.tag.slice(1); - while (lastLevel < newLevel) { - lastLevel++; - knownContents[lastLevel] = []; - } - while (lastLevel > newLevel) { - knownContents[lastLevel] = []; - lastLevel--; - } - knownContent = knownContents[newLevel]; + if (value === '@') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + push({ type: 'at', extglob: true, value, output: '' }); + continue; } - if (knownContent.includes(content)) { - addErrorContext(onError, heading.lineNumber, - heading.line.trim()); - } else { - knownContent.push(content); + + push({ type: 'text', value }); + continue; + } + + /** + * Plain text + */ + + if (value !== '*') { + if (value === '$' || value === '^') { + value = `\\${value}`; + } + + const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); + if (match) { + value += match[0]; + state.index += match[0].length; } - }); - } -}; + push({ type: 'text', value }); + continue; + } -/***/ }), + /** + * Stars + */ -/***/ 2785: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (prev && (prev.type === 'globstar' || prev.star === true)) { + prev.type = 'star'; + prev.star = true; + prev.value += value; + prev.output = star; + state.backtrack = true; + state.globstar = true; + consume(value); + continue; + } -"use strict"; -// @ts-check + let rest = remaining(); + if (opts.noextglob !== true && /^\([^?]/.test(rest)) { + extglobOpen('star', value); + continue; + } + if (prev.type === 'star') { + if (opts.noglobstar === true) { + consume(value); + continue; + } + const prior = prev.prev; + const before = prior.prev; + const isStart = prior.type === 'slash' || prior.type === 'bos'; + const afterStar = before && (before.type === 'star' || before.type === 'globstar'); -const { addErrorContext, filterTokens, frontMatterHasTitle } = - __nccwpck_require__(2935); + if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { + push({ type: 'star', value, output: '' }); + continue; + } -module.exports = { - "names": [ "MD025", "single-title", "single-h1" ], - "description": "Multiple top-level headings in the same document", - "tags": [ "headings", "headers" ], - "function": function MD025(params, onError) { - const level = Number(params.config.level || 1); - const tag = "h" + level; - const foundFrontMatterTitle = - frontMatterHasTitle( - params.frontMatterLines, - params.config.front_matter_title - ); - let hasTopLevelHeading = false; - filterTokens(params, "heading_open", function forToken(token) { - if (token.tag === tag) { - if (hasTopLevelHeading || foundFrontMatterTitle) { - addErrorContext(onError, token.lineNumber, - token.line.trim()); - } else if (token.lineNumber === 1) { - hasTopLevelHeading = true; + const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); + const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); + if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { + push({ type: 'star', value, output: '' }); + continue; + } + + // strip consecutive `/**/` + while (rest.slice(0, 3) === '/**') { + const after = input[state.index + 4]; + if (after && after !== '/') { + break; } + rest = rest.slice(3); + consume('/**', 3); } - }); - } -}; + if (prior.type === 'bos' && eos()) { + prev.type = 'globstar'; + prev.value += value; + prev.output = globstar(opts); + state.output = prev.output; + state.globstar = true; + consume(value); + continue; + } -/***/ }), + if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { + state.output = state.output.slice(0, -(prior.output + prev.output).length); + prior.output = `(?:${prior.output}`; -/***/ 3782: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + prev.type = 'globstar'; + prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); + prev.value += value; + state.globstar = true; + state.output += prior.output + prev.output; + consume(value); + continue; + } -"use strict"; -// @ts-check + if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { + const end = rest[1] !== void 0 ? '|$' : ''; + state.output = state.output.slice(0, -(prior.output + prev.output).length); + prior.output = `(?:${prior.output}`; + prev.type = 'globstar'; + prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; + prev.value += value; -const { addError, allPunctuationNoQuestion, escapeForRegExp, forEachHeading } = - __nccwpck_require__(2935); + state.output += prior.output + prev.output; + state.globstar = true; -const endOfLineHtmlEntityRe = /&#?[0-9a-zA-Z]+;$/; + consume(value + advance()); -module.exports = { - "names": [ "MD026", "no-trailing-punctuation" ], - "description": "Trailing punctuation in heading", - "tags": [ "headings", "headers" ], - "function": function MD026(params, onError) { - let punctuation = params.config.punctuation; - punctuation = String( - (punctuation === undefined) ? allPunctuationNoQuestion : punctuation - ); - const trailingPunctuationRe = - new RegExp("\\s*[" + escapeForRegExp(punctuation) + "]+$"); - forEachHeading(params, (heading) => { - const { line, lineNumber } = heading; - const trimmedLine = line.replace(/[\s#]*$/, ""); - const match = trailingPunctuationRe.exec(trimmedLine); - if (match && !endOfLineHtmlEntityRe.test(trimmedLine)) { - const fullMatch = match[0]; - const column = match.index + 1; - const length = fullMatch.length; - addError( - onError, - lineNumber, - `Punctuation: '${fullMatch}'`, - null, - [ column, length ], - { - "editColumn": column, - "deleteCount": length - } - ); + push({ type: 'slash', value: '/', output: '' }); + continue; } - }); - } -}; + if (prior.type === 'bos' && rest[0] === '/') { + prev.type = 'globstar'; + prev.value += value; + prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; + state.output = prev.output; + state.globstar = true; + consume(value + advance()); + push({ type: 'slash', value: '/', output: '' }); + continue; + } -/***/ }), + // remove single star from output + state.output = state.output.slice(0, -prev.output.length); -/***/ 2923: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // reset previous token to globstar + prev.type = 'globstar'; + prev.output = globstar(opts); + prev.value += value; -"use strict"; -// @ts-check + // reset output with globstar + state.output += prev.output; + state.globstar = true; + consume(value); + continue; + } + const token = { type: 'star', value, output: star }; + if (opts.bash === true) { + token.output = '.*?'; + if (prev.type === 'bos' || prev.type === 'slash') { + token.output = nodot + token.output; + } + push(token); + continue; + } -const { addErrorContext, newLineRe } = __nccwpck_require__(2935); + if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { + token.output = value; + push(token); + continue; + } -const spaceAfterBlockQuoteRe = /^((?:\s*>)+)(\s{2,})\S/; + if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { + if (prev.type === 'dot') { + state.output += NO_DOT_SLASH; + prev.output += NO_DOT_SLASH; -module.exports = { - "names": [ "MD027", "no-multiple-space-blockquote" ], - "description": "Multiple spaces after blockquote symbol", - "tags": [ "blockquote", "whitespace", "indentation" ], - "function": function MD027(params, onError) { - let blockquoteNesting = 0; - let listItemNesting = 0; - params.tokens.forEach((token) => { - const { content, lineNumber, type } = token; - if (type === "blockquote_open") { - blockquoteNesting++; - } else if (type === "blockquote_close") { - blockquoteNesting--; - } else if (type === "list_item_open") { - listItemNesting++; - } else if (type === "list_item_close") { - listItemNesting--; - } else if ((type === "inline") && blockquoteNesting) { - const lineCount = content.split(newLineRe).length; - for (let i = 0; i < lineCount; i++) { - const line = params.lines[lineNumber + i - 1]; - const match = line.match(spaceAfterBlockQuoteRe); - if (match) { - const [ - fullMatch, - { "length": blockquoteLength }, - { "length": spaceLength } - ] = match; - if (!listItemNesting || (fullMatch[fullMatch.length - 1] === ">")) { - addErrorContext( - onError, - lineNumber + i, - line, - null, - null, - [ 1, fullMatch.length ], - { - "editColumn": blockquoteLength + 1, - "deleteCount": spaceLength - 1 - } - ); - } - } - } + } else if (opts.dot === true) { + state.output += NO_DOTS_SLASH; + prev.output += NO_DOTS_SLASH; + + } else { + state.output += nodot; + prev.output += nodot; } - }); - } -}; + if (peek() !== '*') { + state.output += ONE_CHAR; + prev.output += ONE_CHAR; + } + } + + push(token); + } -/***/ }), + while (state.brackets > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); + state.output = utils.escapeLast(state.output, '['); + decrement('brackets'); + } -/***/ 333: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + while (state.parens > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); + state.output = utils.escapeLast(state.output, '('); + decrement('parens'); + } -"use strict"; -// @ts-check + while (state.braces > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); + state.output = utils.escapeLast(state.output, '{'); + decrement('braces'); + } + if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { + push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); + } + // rebuild the output if we had to backtrack at any point + if (state.backtrack === true) { + state.output = ''; -const { addError } = __nccwpck_require__(2935); + for (const token of state.tokens) { + state.output += token.output != null ? token.output : token.value; -module.exports = { - "names": [ "MD028", "no-blanks-blockquote" ], - "description": "Blank line inside blockquote", - "tags": [ "blockquote", "whitespace" ], - "function": function MD028(params, onError) { - let prevToken = {}; - let prevLineNumber = null; - params.tokens.forEach(function forToken(token) { - if ((token.type === "blockquote_open") && - (prevToken.type === "blockquote_close")) { - for ( - let lineNumber = prevLineNumber; - lineNumber < token.lineNumber; - lineNumber++) { - addError(onError, lineNumber); - } - } - prevToken = token; - if (token.type === "blockquote_open") { - prevLineNumber = token.map[1] + 1; + if (token.suffix) { + state.output += token.suffix; } - }); + } } + + return state; }; +/** + * Fast paths for creating regular expressions for common glob patterns. + * This can significantly speed up processing and has very little downside + * impact when none of the fast paths match. + */ -/***/ }), +parse.fastpaths = (input, options) => { + const opts = { ...options }; + const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + const len = input.length; + if (len > max) { + throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); + } -/***/ 8278: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + input = REPLACEMENTS[input] || input; + const win32 = utils.isWindows(options); -"use strict"; -// @ts-check + // create constants based on platform, for windows or posix + const { + DOT_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + DOTS_SLASH, + NO_DOT, + NO_DOTS, + NO_DOTS_SLASH, + STAR, + START_ANCHOR + } = constants.globChars(win32); + const nodot = opts.dot ? NO_DOTS : NO_DOT; + const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; + const capture = opts.capture ? '' : '?:'; + const state = { negated: false, prefix: '' }; + let star = opts.bash === true ? '.*?' : STAR; + if (opts.capture) { + star = `(${star})`; + } -const { addErrorDetailIf, listItemMarkerRe, orderedListItemMarkerRe, - rangeFromRegExp } = __nccwpck_require__(2935); -const { flattenedLists } = __nccwpck_require__(3266); - -const listStyleExamples = { - "one": "1/1/1", - "ordered": "1/2/3", - "zero": "0/0/0" -}; - -module.exports = { - "names": [ "MD029", "ol-prefix" ], - "description": "Ordered list item prefix", - "tags": [ "ol" ], - "function": function MD029(params, onError) { - const style = String(params.config.style || "one_or_ordered"); - flattenedLists().filter((list) => !list.unordered).forEach((list) => { - const { items } = list; - let current = 1; - let incrementing = false; - // Check for incrementing number pattern 1/2/3 or 0/1/2 - if (items.length >= 2) { - const first = orderedListItemMarkerRe.exec(items[0].line); - const second = orderedListItemMarkerRe.exec(items[1].line); - if (first && second) { - const [ , firstNumber ] = first; - const [ , secondNumber ] = second; - if ((secondNumber !== "1") || (firstNumber === "0")) { - incrementing = true; - if (firstNumber === "0") { - current = 0; - } - } - } - } - // Determine effective style - let listStyle = style; - if (listStyle === "one_or_ordered") { - listStyle = incrementing ? "ordered" : "one"; - } - // Force expected value for 0/0/0 and 1/1/1 patterns - if (listStyle === "zero") { - current = 0; - } else if (listStyle === "one") { - current = 1; - } - // Validate each list item marker - items.forEach((item) => { - const match = orderedListItemMarkerRe.exec(item.line); - if (match) { - addErrorDetailIf(onError, item.lineNumber, - String(current), match[1], - "Style: " + listStyleExamples[listStyle], null, - rangeFromRegExp(item.line, listItemMarkerRe)); - if (listStyle === "ordered") { - current++; - } - } - }); - }); - } -}; - - -/***/ }), - -/***/ 4156: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; -// @ts-check + const globstar = opts => { + if (opts.noglobstar === true) return star; + return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; + }; + const create = str => { + switch (str) { + case '*': + return `${nodot}${ONE_CHAR}${star}`; + case '.*': + return `${DOT_LITERAL}${ONE_CHAR}${star}`; -const { addErrorDetailIf } = __nccwpck_require__(2935); -const { flattenedLists } = __nccwpck_require__(3266); + case '*.*': + return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; -module.exports = { - "names": [ "MD030", "list-marker-space" ], - "description": "Spaces after list markers", - "tags": [ "ol", "ul", "whitespace" ], - "function": function MD030(params, onError) { - const ulSingle = Number(params.config.ul_single || 1); - const olSingle = Number(params.config.ol_single || 1); - const ulMulti = Number(params.config.ul_multi || 1); - const olMulti = Number(params.config.ol_multi || 1); - flattenedLists().forEach((list) => { - const lineCount = list.lastLineIndex - list.open.map[0]; - const allSingle = lineCount === list.items.length; - const expectedSpaces = list.unordered ? - (allSingle ? ulSingle : ulMulti) : - (allSingle ? olSingle : olMulti); - list.items.forEach((item) => { - const { line, lineNumber } = item; - const match = /^[\s>]*\S+(\s*)/.exec(line); - const [ { "length": matchLength }, { "length": actualSpaces } ] = match; - if (matchLength < line.length) { - let fixInfo = null; - if (expectedSpaces !== actualSpaces) { - fixInfo = { - "editColumn": matchLength - actualSpaces + 1, - "deleteCount": actualSpaces, - "insertText": "".padEnd(expectedSpaces) - }; - } - addErrorDetailIf( - onError, - lineNumber, - expectedSpaces, - actualSpaces, - null, - null, - [ 1, matchLength ], - fixInfo - ); - } - }); - }); - } -}; + case '*/*': + return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; + case '**': + return nodot + globstar(opts); -/***/ }), + case '**/*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; -/***/ 8578: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + case '**/*.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; -"use strict"; -// @ts-check + case '**/.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; + default: { + const match = /^(.*?)\.(\w+)$/.exec(str); + if (!match) return; + const source = create(match[1]); + if (!source) return; -const { addErrorContext, forEachLine, isBlankLine } = __nccwpck_require__(2935); -const { lineMetadata } = __nccwpck_require__(3266); + return source + DOT_LITERAL + match[2]; + } + } + }; -const codeFencePrefixRe = /^(.*?)\s*[`~]/; + const output = utils.removePrefix(input, state); + let source = create(output); -module.exports = { - "names": [ "MD031", "blanks-around-fences" ], - "description": "Fenced code blocks should be surrounded by blank lines", - "tags": [ "code", "blank_lines" ], - "function": function MD031(params, onError) { - const listItems = params.config.list_items; - const includeListItems = (listItems === undefined) ? true : !!listItems; - const { lines } = params; - forEachLine(lineMetadata(), (line, i, inCode, onFence, inTable, inItem) => { - const onTopFence = (onFence > 0); - const onBottomFence = (onFence < 0); - if ((includeListItems || !inItem) && - ((onTopFence && !isBlankLine(lines[i - 1])) || - (onBottomFence && !isBlankLine(lines[i + 1])))) { - const [ , prefix ] = line.match(codeFencePrefixRe) || []; - const fixInfo = (prefix === undefined) ? null : { - "lineNumber": i + (onTopFence ? 1 : 2), - "insertText": `${prefix}\n` - }; - addErrorContext( - onError, - i + 1, - lines[i].trim(), - null, - null, - null, - fixInfo); - } - }); + if (source && opts.strictSlashes !== true) { + source += `${SLASH_LITERAL}?`; } + + return source; }; +module.exports = parse; + /***/ }), -/***/ 995: +/***/ 3322: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -// @ts-check +const path = __nccwpck_require__(1017); +const scan = __nccwpck_require__(2429); +const parse = __nccwpck_require__(2139); +const utils = __nccwpck_require__(479); +const constants = __nccwpck_require__(6099); +const isObject = val => val && typeof val === 'object' && !Array.isArray(val); -const { addErrorContext, isBlankLine } = __nccwpck_require__(2935); -const { flattenedLists } = __nccwpck_require__(3266); - -const quotePrefixRe = /^[>\s]*/; +/** + * Creates a matcher function from one or more glob patterns. The + * returned function takes a string to match as its first argument, + * and returns true if the string is a match. The returned matcher + * function also takes a boolean as the second argument that, when true, + * returns an object with additional information. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch(glob[, options]); + * + * const isMatch = picomatch('*.!(*a)'); + * console.log(isMatch('a.a')); //=> false + * console.log(isMatch('a.b')); //=> true + * ``` + * @name picomatch + * @param {String|Array} `globs` One or more glob patterns. + * @param {Object=} `options` + * @return {Function=} Returns a matcher function. + * @api public + */ -module.exports = { - "names": [ "MD032", "blanks-around-lists" ], - "description": "Lists should be surrounded by blank lines", - "tags": [ "bullet", "ul", "ol", "blank_lines" ], - "function": function MD032(params, onError) { - const { lines } = params; - flattenedLists().filter((list) => !list.nesting).forEach((list) => { - const firstIndex = list.open.map[0]; - if (!isBlankLine(lines[firstIndex - 1])) { - const line = lines[firstIndex]; - const quotePrefix = line.match(quotePrefixRe)[0].trimEnd(); - addErrorContext( - onError, - firstIndex + 1, - line.trim(), - null, - null, - null, - { - "insertText": `${quotePrefix}\n` - }); - } - const lastIndex = list.lastLineIndex - 1; - if (!isBlankLine(lines[lastIndex + 1])) { - const line = lines[lastIndex]; - const quotePrefix = line.match(quotePrefixRe)[0].trimEnd(); - addErrorContext( - onError, - lastIndex + 1, - line.trim(), - null, - null, - null, - { - "lineNumber": lastIndex + 2, - "insertText": `${quotePrefix}\n` - }); +const picomatch = (glob, options, returnState = false) => { + if (Array.isArray(glob)) { + const fns = glob.map(input => picomatch(input, options, returnState)); + const arrayMatcher = str => { + for (const isMatch of fns) { + const state = isMatch(str); + if (state) return state; } - }); + return false; + }; + return arrayMatcher; } -}; + const isState = isObject(glob) && glob.tokens && glob.input; -/***/ }), + if (glob === '' || (typeof glob !== 'string' && !isState)) { + throw new TypeError('Expected pattern to be a non-empty string'); + } -/***/ 4167: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const opts = options || {}; + const posix = utils.isWindows(options); + const regex = isState + ? picomatch.compileRe(glob, options) + : picomatch.makeRe(glob, options, false, true); -"use strict"; -// @ts-check + const state = regex.state; + delete regex.state; + let isIgnored = () => false; + if (opts.ignore) { + const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; + isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); + } + const matcher = (input, returnObject = false) => { + const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); + const result = { glob, state, regex, posix, input, output, match, isMatch }; -const { - addError, forEachLine, overlapsAnyRange, unescapeMarkdown -} = __nccwpck_require__(2935); -const { codeBlockAndSpanRanges, lineMetadata } = __nccwpck_require__(3266); + if (typeof opts.onResult === 'function') { + opts.onResult(result); + } -const htmlElementRe = /<(([A-Za-z][A-Za-z0-9-]*)(?:\s[^>]*)?)\/?>/g; -const linkDestinationRe = /]\(\s*$/; -// See https://spec.commonmark.org/0.29/#autolinks -const emailAddressRe = - // eslint-disable-next-line max-len - /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; + if (isMatch === false) { + result.isMatch = false; + return returnObject ? result : false; + } -module.exports = { - "names": [ "MD033", "no-inline-html" ], - "description": "Inline HTML", - "tags": [ "html" ], - "function": function MD033(params, onError) { - let allowedElements = params.config.allowed_elements; - allowedElements = Array.isArray(allowedElements) ? allowedElements : []; - allowedElements = allowedElements.map((element) => element.toLowerCase()); - const exclusions = codeBlockAndSpanRanges(); - forEachLine(lineMetadata(), (line, lineIndex, inCode) => { - let match = null; - // eslint-disable-next-line no-unmodified-loop-condition - while (!inCode && ((match = htmlElementRe.exec(line)) !== null)) { - const [ tag, content, element ] = match; - if ( - !allowedElements.includes(element.toLowerCase()) && - !tag.endsWith("\\>") && - !emailAddressRe.test(content) && - !overlapsAnyRange(exclusions, lineIndex, match.index, match[0].length) - ) { - const prefix = line.substring(0, match.index); - if (!linkDestinationRe.test(prefix)) { - const unescaped = unescapeMarkdown(prefix + "<", "_"); - if (!unescaped.endsWith("_")) { - addError(onError, lineIndex + 1, "Element: " + element, - null, [ match.index + 1, tag.length ]); - } - } - } + if (isIgnored(input)) { + if (typeof opts.onIgnore === 'function') { + opts.onIgnore(result); } - }); - } -}; + result.isMatch = false; + return returnObject ? result : false; + } + if (typeof opts.onMatch === 'function') { + opts.onMatch(result); + } + return returnObject ? result : true; + }; -/***/ }), + if (returnState) { + matcher.state = state; + } -/***/ 4222: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return matcher; +}; -"use strict"; -// @ts-check +/** + * Test `input` with the given `regex`. This is used by the main + * `picomatch()` function to test the input string. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.test(input, regex[, options]); + * + * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); + * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } + * ``` + * @param {String} `input` String to test. + * @param {RegExp} `regex` + * @return {Object} Returns an object with matching info. + * @api public + */ +picomatch.test = (input, regex, options, { glob, posix } = {}) => { + if (typeof input !== 'string') { + throw new TypeError('Expected input to be a string'); + } + if (input === '') { + return { isMatch: false, output: '' }; + } -const { addErrorContext, bareUrlRe, filterTokens } = __nccwpck_require__(2935); + const opts = options || {}; + const format = opts.format || (posix ? utils.toPosixSlashes : null); + let match = input === glob; + let output = (match && format) ? format(input) : input; -module.exports = { - "names": [ "MD034", "no-bare-urls" ], - "description": "Bare URL used", - "tags": [ "links", "url" ], - "function": function MD034(params, onError) { - filterTokens(params, "inline", (token) => { - let inLink = false; - token.children.forEach((child) => { - const { content, line, lineNumber, type } = child; - let match = null; - if (type === "link_open") { - inLink = true; - } else if (type === "link_close") { - inLink = false; - } else if ((type === "text") && !inLink) { - while ((match = bareUrlRe.exec(content)) !== null) { - const [ bareUrl ] = match; - const matchIndex = match.index; - const bareUrlLength = bareUrl.length; - // Allow "[https://example.com]" to avoid conflicts with - // MD011/no-reversed-links; allow quoting as another way - // of deliberately including a bare URL - const leftChar = content[matchIndex - 1]; - const rightChar = content[matchIndex + bareUrlLength]; - if ( - !((leftChar === "[") && (rightChar === "]")) && - !((leftChar === "\"") && (rightChar === "\"")) && - !((leftChar === "'") && (rightChar === "'")) - ) { - const index = line.indexOf(content); - const range = (index === -1) ? null : [ - index + matchIndex + 1, - bareUrlLength - ]; - const fixInfo = range ? { - "editColumn": range[0], - "deleteCount": range[1], - "insertText": `<${bareUrl}>` - } : null; - addErrorContext( - onError, - lineNumber, - bareUrl, - null, - null, - range, - fixInfo - ); - } - } - } - }); - }); + if (match === false) { + output = format ? format(input) : input; + match = output === glob; } -}; + if (match === false || opts.capture === true) { + if (opts.matchBase === true || opts.basename === true) { + match = picomatch.matchBase(input, regex, options, posix); + } else { + match = regex.exec(output); + } + } -/***/ }), + return { isMatch: Boolean(match), match, output }; +}; -/***/ 2936: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/** + * Match the basename of a filepath. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.matchBase(input, glob[, options]); + * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true + * ``` + * @param {String} `input` String to test. + * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). + * @return {Boolean} + * @api public + */ -"use strict"; -// @ts-check +picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => { + const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); + return regex.test(path.basename(input)); +}; +/** + * Returns true if **any** of the given glob `patterns` match the specified `string`. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.isMatch(string, patterns[, options]); + * + * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true + * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false + * ``` + * @param {String|Array} str The string to test. + * @param {String|Array} patterns One or more glob patterns to use for matching. + * @param {Object} [options] See available [options](#options). + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ +picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); -const { addErrorDetailIf, filterTokens } = __nccwpck_require__(2935); +/** + * Parse a glob pattern to create the source string for a regular + * expression. + * + * ```js + * const picomatch = require('picomatch'); + * const result = picomatch.parse(pattern[, options]); + * ``` + * @param {String} `pattern` + * @param {Object} `options` + * @return {Object} Returns an object with useful properties and output to be used as a regex source string. + * @api public + */ -module.exports = { - "names": [ "MD035", "hr-style" ], - "description": "Horizontal rule style", - "tags": [ "hr" ], - "function": function MD035(params, onError) { - let style = String(params.config.style || "consistent"); - filterTokens(params, "hr", (token) => { - const { lineNumber, markup } = token; - if (style === "consistent") { - style = markup; - } - addErrorDetailIf(onError, lineNumber, style, markup); - }); - } +picomatch.parse = (pattern, options) => { + if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); + return parse(pattern, { ...options, fastpaths: false }); }; +/** + * Scan a glob pattern to separate the pattern into segments. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.scan(input[, options]); + * + * const result = picomatch.scan('!./foo/*.js'); + * console.log(result); + * { prefix: '!./', + * input: '!./foo/*.js', + * start: 3, + * base: 'foo', + * glob: '*.js', + * isBrace: false, + * isBracket: false, + * isGlob: true, + * isExtglob: false, + * isGlobstar: false, + * negated: true } + * ``` + * @param {String} `input` Glob pattern to scan. + * @param {Object} `options` + * @return {Object} Returns an object with + * @api public + */ -/***/ }), +picomatch.scan = (input, options) => scan(input, options); -/***/ 6626: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/** + * Compile a regular expression from the `state` object returned by the + * [parse()](#parse) method. + * + * @param {Object} `state` + * @param {Object} `options` + * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser. + * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. + * @return {RegExp} + * @api public + */ -"use strict"; -// @ts-check +picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => { + if (returnOutput === true) { + return state.output; + } + const opts = options || {}; + const prepend = opts.contains ? '' : '^'; + const append = opts.contains ? '' : '$'; + let source = `${prepend}(?:${state.output})${append}`; + if (state && state.negated === true) { + source = `^(?!${source}).*$`; + } -const { addErrorContext, allPunctuation } = __nccwpck_require__(2935); + const regex = picomatch.toRegex(source, options); + if (returnState === true) { + regex.state = state; + } -module.exports = { - "names": [ "MD036", "no-emphasis-as-heading", "no-emphasis-as-header" ], - "description": "Emphasis used instead of a heading", - "tags": [ "headings", "headers", "emphasis" ], - "function": function MD036(params, onError) { - let punctuation = params.config.punctuation; - punctuation = - String((punctuation === undefined) ? allPunctuation : punctuation); - const re = new RegExp("[" + punctuation + "]$"); - // eslint-disable-next-line jsdoc/require-jsdoc - function base(token) { - if (token.type === "paragraph_open") { - return function inParagraph(t) { - // Always paragraph_open/inline/paragraph_close, - const children = t.children.filter(function notEmptyText(child) { - return (child.type !== "text") || (child.content !== ""); - }); - if ((children.length === 3) && - ((children[0].type === "strong_open") || - (children[0].type === "em_open")) && - (children[1].type === "text") && - !re.test(children[1].content)) { - addErrorContext(onError, t.lineNumber, - children[1].content); - } - return base; - }; - } else if (token.type === "blockquote_open") { - return function inBlockquote(t) { - if (t.type !== "blockquote_close") { - return inBlockquote; - } - return base; - }; - } else if (token.type === "list_item_open") { - return function inListItem(t) { - if (t.type !== "list_item_close") { - return inListItem; - } - return base; - }; - } - return base; - } - let state = base; - params.tokens.forEach(function forToken(token) { - state = state(token); - }); + return regex; +}; + +/** + * Create a regular expression from a parsed glob pattern. + * + * ```js + * const picomatch = require('picomatch'); + * const state = picomatch.parse('*.js'); + * // picomatch.compileRe(state[, options]); + * + * console.log(picomatch.compileRe(state)); + * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ + * ``` + * @param {String} `state` The object returned from the `.parse` method. + * @param {Object} `options` + * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result. + * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression. + * @return {RegExp} Returns a regex created from the given pattern. + * @api public + */ + +picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => { + if (!input || typeof input !== 'string') { + throw new TypeError('Expected a non-empty string'); + } + + let parsed = { negated: false, fastpaths: true }; + + if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { + parsed.output = parse.fastpaths(input, options); + } + + if (!parsed.output) { + parsed = parse(input, options); + } + + return picomatch.compileRe(parsed, options, returnOutput, returnState); +}; + +/** + * Create a regular expression from the given regex source string. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.toRegex(source[, options]); + * + * const { output } = picomatch.parse('*.js'); + * console.log(picomatch.toRegex(output)); + * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ + * ``` + * @param {String} `source` Regular expression source string. + * @param {Object} `options` + * @return {RegExp} + * @api public + */ + +picomatch.toRegex = (source, options) => { + try { + const opts = options || {}; + return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); + } catch (err) { + if (options && options.debug === true) throw err; + return /$^/; } }; +/** + * Picomatch constants. + * @return {Object} + */ + +picomatch.constants = constants; + +/** + * Expose "picomatch" + */ + +module.exports = picomatch; + /***/ }), -/***/ 1706: +/***/ 2429: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -// @ts-check +const utils = __nccwpck_require__(479); +const { + CHAR_ASTERISK, /* * */ + CHAR_AT, /* @ */ + CHAR_BACKWARD_SLASH, /* \ */ + CHAR_COMMA, /* , */ + CHAR_DOT, /* . */ + CHAR_EXCLAMATION_MARK, /* ! */ + CHAR_FORWARD_SLASH, /* / */ + CHAR_LEFT_CURLY_BRACE, /* { */ + CHAR_LEFT_PARENTHESES, /* ( */ + CHAR_LEFT_SQUARE_BRACKET, /* [ */ + CHAR_PLUS, /* + */ + CHAR_QUESTION_MARK, /* ? */ + CHAR_RIGHT_CURLY_BRACE, /* } */ + CHAR_RIGHT_PARENTHESES, /* ) */ + CHAR_RIGHT_SQUARE_BRACKET /* ] */ +} = __nccwpck_require__(6099); -const { addErrorContext, emphasisMarkersInContent, forEachLine, isBlankLine } = - __nccwpck_require__(2935); -const { lineMetadata } = __nccwpck_require__(3266); +const isPathSeparator = code => { + return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; +}; -const emphasisRe = /(^|[^\\]|\\\\)(?:(\*\*?\*?)|(__?_?))/g; -const embeddedUnderscoreRe = /([A-Za-z0-9])_([A-Za-z0-9])/g; -const asteriskListItemMarkerRe = /^([\s>]*)\*(\s+)/; -const leftSpaceRe = /^\s+/; -const rightSpaceRe = /\s+$/; -const tablePipeRe = /\|/; +const depth = token => { + if (token.isPrefix !== true) { + token.depth = token.isGlobstar ? Infinity : 1; + } +}; -module.exports = { - "names": [ "MD037", "no-space-in-emphasis" ], - "description": "Spaces inside emphasis markers", - "tags": [ "whitespace", "emphasis" ], - "function": function MD037(params, onError) { - // eslint-disable-next-line init-declarations - let effectiveEmphasisLength, emphasisIndex, emphasisKind, emphasisLength, - pendingError = null; - // eslint-disable-next-line jsdoc/require-jsdoc - function resetRunTracking() { - emphasisIndex = -1; - emphasisLength = 0; - emphasisKind = ""; - effectiveEmphasisLength = 0; - pendingError = null; +/** + * Quickly scans a glob pattern and returns an object with a handful of + * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), + * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not + * with `!(`) and `negatedExtglob` (true if the path starts with `!(`). + * + * ```js + * const pm = require('picomatch'); + * console.log(pm.scan('foo/bar/*.js')); + * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } + * ``` + * @param {String} `str` + * @param {Object} `options` + * @return {Object} Returns an object with tokens and regex source string. + * @api public + */ + +const scan = (input, options) => { + const opts = options || {}; + + const length = input.length - 1; + const scanToEnd = opts.parts === true || opts.scanToEnd === true; + const slashes = []; + const tokens = []; + const parts = []; + + let str = input; + let index = -1; + let start = 0; + let lastIndex = 0; + let isBrace = false; + let isBracket = false; + let isGlob = false; + let isExtglob = false; + let isGlobstar = false; + let braceEscaped = false; + let backslashes = false; + let negated = false; + let negatedExtglob = false; + let finished = false; + let braces = 0; + let prev; + let code; + let token = { value: '', depth: 0, isGlob: false }; + + const eos = () => index >= length; + const peek = () => str.charCodeAt(index + 1); + const advance = () => { + prev = code; + return str.charCodeAt(++index); + }; + + while (index < length) { + code = advance(); + let next; + + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + code = advance(); + + if (code === CHAR_LEFT_CURLY_BRACE) { + braceEscaped = true; + } + continue; } - // eslint-disable-next-line jsdoc/require-jsdoc - function handleRunEnd( - line, lineIndex, contextLength, match, matchIndex, inTable - ) { - // Close current run - let content = line.substring(emphasisIndex, matchIndex); - if (!emphasisLength) { - content = content.trimStart(); - } - if (!match) { - content = content.trimEnd(); - } - const leftSpace = leftSpaceRe.test(content); - const rightSpace = rightSpaceRe.test(content); - if ( - (leftSpace || rightSpace) && - (!inTable || !tablePipeRe.test(content)) - ) { - // Report the violation - const contextStart = emphasisIndex - emphasisLength; - const contextEnd = matchIndex + contextLength; - const context = line.substring(contextStart, contextEnd); - const column = contextStart + 1; - const length = contextEnd - contextStart; - const leftMarker = line.substring(contextStart, emphasisIndex); - const rightMarker = match ? (match[2] || match[3]) : ""; - const fixedText = `${leftMarker}${content.trim()}${rightMarker}`; - return [ - onError, - lineIndex + 1, - context, - leftSpace, - rightSpace, - [ column, length ], - { - "editColumn": column, - "deleteCount": length, - "insertText": fixedText - } - ]; - } - return null; - } - // Initialize - const ignoreMarkersByLine = emphasisMarkersInContent(params); - resetRunTracking(); - forEachLine( - lineMetadata(), - (line, lineIndex, inCode, onFence, inTable, inItem, onBreak, inMath) => { - const onItemStart = (inItem === 1); - if ( - inCode || - onFence || - inTable || - onBreak || - onItemStart || - isBlankLine(line) - ) { - // Emphasis resets when leaving a block - resetRunTracking(); - } - if ( - inCode || - onFence || - onBreak || - inMath - ) { - // Emphasis has no meaning here - return; + + if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) { + braces++; + + while (eos() !== true && (code = advance())) { + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + advance(); + continue; } - let patchedLine = line.replace(embeddedUnderscoreRe, "$1 $2"); - if (onItemStart) { - // Trim overlapping '*' list item marker - patchedLine = patchedLine.replace(asteriskListItemMarkerRe, "$1 $2"); + + if (code === CHAR_LEFT_CURLY_BRACE) { + braces++; + continue; } - let match = null; - // Match all emphasis-looking runs in the line... - while ((match = emphasisRe.exec(patchedLine))) { - const ignoreMarkersForLine = ignoreMarkersByLine[lineIndex]; - const matchIndex = match.index + match[1].length; - if (ignoreMarkersForLine.includes(matchIndex)) { - // Ignore emphasis markers inside code spans and links + + if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) { + isBrace = token.isBrace = true; + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { continue; } - const matchLength = match[0].length - match[1].length; - const matchKind = (match[2] || match[3])[0]; - if (emphasisIndex === -1) { - // New run - emphasisIndex = matchIndex + matchLength; - emphasisLength = matchLength; - emphasisKind = matchKind; - effectiveEmphasisLength = matchLength; - } else if (matchKind === emphasisKind) { - // Matching emphasis markers - if (matchLength === effectiveEmphasisLength) { - // Ending an existing run, report any pending error - if (pendingError) { - // @ts-ignore - addErrorContext(...pendingError); - pendingError = null; - } - const error = handleRunEnd( - line, - lineIndex, - effectiveEmphasisLength, - match, - matchIndex, - inTable - ); - if (error) { - // @ts-ignore - addErrorContext(...error); - } - // Reset - resetRunTracking(); - } else if (matchLength === 3) { - // Swap internal run length (1->2 or 2->1) - effectiveEmphasisLength = matchLength - effectiveEmphasisLength; - } else if (effectiveEmphasisLength === 3) { - // Downgrade internal run (3->1 or 3->2) - effectiveEmphasisLength -= matchLength; - } else { - // Upgrade to internal run (1->3 or 2->3) - effectiveEmphasisLength += matchLength; - } - // Back up one character so RegExp has a chance to match the - // next marker (ex: "**star**_underscore_") - if (emphasisRe.lastIndex > 1) { - emphasisRe.lastIndex--; - } - } else if (emphasisRe.lastIndex > 1) { - // Back up one character so RegExp has a chance to match the - // mis-matched marker (ex: "*text_*") - emphasisRe.lastIndex--; + + break; + } + + if (braceEscaped !== true && code === CHAR_COMMA) { + isBrace = token.isBrace = true; + isGlob = token.isGlob = true; + finished = true; + + if (scanToEnd === true) { + continue; } + + break; } - if (emphasisIndex !== -1) { - pendingError = pendingError || - handleRunEnd(line, lineIndex, 0, null, line.length, inTable); - // Adjust for pending run on new line - emphasisIndex = 0; - emphasisLength = 0; + + if (code === CHAR_RIGHT_CURLY_BRACE) { + braces--; + + if (braces === 0) { + braceEscaped = false; + isBrace = token.isBrace = true; + finished = true; + break; + } } } - ); - } -}; + if (scanToEnd === true) { + continue; + } -/***/ }), + break; + } -/***/ 94: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (code === CHAR_FORWARD_SLASH) { + slashes.push(index); + tokens.push(token); + token = { value: '', depth: 0, isGlob: false }; -"use strict"; -// @ts-check + if (finished === true) continue; + if (prev === CHAR_DOT && index === (start + 1)) { + start += 2; + continue; + } + lastIndex = index + 1; + continue; + } + if (opts.noext !== true) { + const isExtglobChar = code === CHAR_PLUS + || code === CHAR_AT + || code === CHAR_ASTERISK + || code === CHAR_QUESTION_MARK + || code === CHAR_EXCLAMATION_MARK; -const { addErrorContext, filterTokens, forEachInlineCodeSpan, newLineRe } = - __nccwpck_require__(2935); + if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { + isGlob = token.isGlob = true; + isExtglob = token.isExtglob = true; + finished = true; + if (code === CHAR_EXCLAMATION_MARK && index === start) { + negatedExtglob = true; + } -const leftSpaceRe = /^\s([^`]|$)/; -const rightSpaceRe = /[^`]\s$/; -const singleLeftRightSpaceRe = /^\s(?:\S.*\S|\S)\s$/; + if (scanToEnd === true) { + while (eos() !== true && (code = advance())) { + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + code = advance(); + continue; + } -module.exports = { - "names": [ "MD038", "no-space-in-code" ], - "description": "Spaces inside code span elements", - "tags": [ "whitespace", "code" ], - "function": function MD038(params, onError) { - filterTokens(params, "inline", (token) => { - if (token.children.some((child) => child.type === "code_inline")) { - const tokenLines = params.lines.slice(token.map[0], token.map[1]); - forEachInlineCodeSpan( - tokenLines.join("\n"), - (code, lineIndex, columnIndex, tickCount) => { - let rangeIndex = columnIndex - tickCount; - let rangeLength = code.length + (2 * tickCount); - let rangeLineOffset = 0; - let fixIndex = columnIndex; - let fixLength = code.length; - const codeLines = code.split(newLineRe); - const left = leftSpaceRe.test(code); - const right = !left && rightSpaceRe.test(code); - if (right && (codeLines.length > 1)) { - rangeIndex = 0; - rangeLineOffset = codeLines.length - 1; - fixIndex = 0; + if (code === CHAR_RIGHT_PARENTHESES) { + isGlob = token.isGlob = true; + finished = true; + break; } - const allowed = singleLeftRightSpaceRe.test(code); - if ((left || right) && !allowed) { - const codeLinesRange = codeLines[rangeLineOffset]; - if (codeLines.length > 1) { - rangeLength = codeLinesRange.length + tickCount; - fixLength = codeLinesRange.length; - } - const context = tokenLines[lineIndex + rangeLineOffset] - .substring(rangeIndex, rangeIndex + rangeLength); - const codeLinesRangeTrim = codeLinesRange.trim(); - const fixText = - (codeLinesRangeTrim.startsWith("`") ? " " : "") + - codeLinesRangeTrim + - (codeLinesRangeTrim.endsWith("`") ? " " : ""); - addErrorContext( - onError, - token.lineNumber + lineIndex + rangeLineOffset, - context, - left, - right, - [ rangeIndex + 1, rangeLength ], - { - "editColumn": fixIndex + 1, - "deleteCount": fixLength, - "insertText": fixText - } - ); - } - }); + } + continue; + } + break; } - }); - } -}; - - -/***/ }), - -/***/ 443: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; -// @ts-check + } + if (code === CHAR_ASTERISK) { + if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; + isGlob = token.isGlob = true; + finished = true; + if (scanToEnd === true) { + continue; + } + break; + } -const { addErrorContext, filterTokens } = __nccwpck_require__(2935); + if (code === CHAR_QUESTION_MARK) { + isGlob = token.isGlob = true; + finished = true; -const spaceInLinkRe = - /\[(?:\s+(?:[^\]]*?)\s*|(?:[^\]]*?)\s+)](?=((?:\([^)]*\))|(?:\[[^\]]*\])))/; + if (scanToEnd === true) { + continue; + } + break; + } -module.exports = { - "names": [ "MD039", "no-space-in-links" ], - "description": "Spaces inside link text", - "tags": [ "whitespace", "links" ], - "function": function MD039(params, onError) { - filterTokens(params, "inline", (token) => { - const { children } = token; - let { lineNumber } = token; - let inLink = false; - let linkText = ""; - let lineIndex = 0; - children.forEach((child) => { - const { content, type } = child; - if (type === "link_open") { - inLink = true; - linkText = ""; - } else if (type === "link_close") { - inLink = false; - const left = linkText.trimStart().length !== linkText.length; - const right = linkText.trimEnd().length !== linkText.length; - if (left || right) { - const line = params.lines[lineNumber - 1]; - let range = null; - let fixInfo = null; - const match = line.slice(lineIndex).match(spaceInLinkRe); - if (match) { - const column = match.index + lineIndex + 1; - const length = match[0].length; - range = [ column, length ]; - fixInfo = { - "editColumn": column + 1, - "deleteCount": length - 2, - "insertText": linkText.trim() - }; - lineIndex = column + length - 1; - } - addErrorContext( - onError, - lineNumber, - `[${linkText}]`, - left, - right, - range, - fixInfo - ); - } - } else if ((type === "softbreak") || (type === "hardbreak")) { - lineNumber++; - lineIndex = 0; - } else if (inLink) { - linkText += content; + if (code === CHAR_LEFT_SQUARE_BRACKET) { + while (eos() !== true && (next = advance())) { + if (next === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + advance(); + continue; } - }); - }); - } -}; - -/***/ }), + if (next === CHAR_RIGHT_SQUARE_BRACKET) { + isBracket = token.isBracket = true; + isGlob = token.isGlob = true; + finished = true; + break; + } + } -/***/ 1025: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (scanToEnd === true) { + continue; + } -"use strict"; -// @ts-check + break; + } + if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { + negated = token.negated = true; + start++; + continue; + } + if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { + isGlob = token.isGlob = true; -const { addErrorContext, filterTokens } = __nccwpck_require__(2935); + if (scanToEnd === true) { + while (eos() !== true && (code = advance())) { + if (code === CHAR_LEFT_PARENTHESES) { + backslashes = token.backslashes = true; + code = advance(); + continue; + } -module.exports = { - "names": [ "MD040", "fenced-code-language" ], - "description": "Fenced code blocks should have a language specified", - "tags": [ "code", "language" ], - "function": function MD040(params, onError) { - filterTokens(params, "fence", function forToken(token) { - if (!token.info.trim()) { - addErrorContext(onError, token.lineNumber, token.line); + if (code === CHAR_RIGHT_PARENTHESES) { + finished = true; + break; + } + } + continue; } - }); - } -}; + break; + } + if (isGlob === true) { + finished = true; -/***/ }), + if (scanToEnd === true) { + continue; + } -/***/ 5864: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + break; + } + } -"use strict"; -// @ts-check + if (opts.noext === true) { + isExtglob = false; + isGlob = false; + } + let base = str; + let prefix = ''; + let glob = ''; + if (start > 0) { + prefix = str.slice(0, start); + str = str.slice(start); + lastIndex -= start; + } -const { addErrorContext, frontMatterHasTitle } = __nccwpck_require__(2935); + if (base && isGlob === true && lastIndex > 0) { + base = str.slice(0, lastIndex); + glob = str.slice(lastIndex); + } else if (isGlob === true) { + base = ''; + glob = str; + } else { + base = str; + } -module.exports = { - "names": [ "MD041", "first-line-heading", "first-line-h1" ], - "description": "First line in a file should be a top-level heading", - "tags": [ "headings", "headers" ], - "function": function MD041(params, onError) { - const level = Number(params.config.level || 1); - const tag = "h" + level; - const foundFrontMatterTitle = - frontMatterHasTitle( - params.frontMatterLines, - params.config.front_matter_title - ); - if (!foundFrontMatterTitle) { - const htmlHeadingRe = new RegExp(`^]`, "i"); - params.tokens.every((token) => { - let isError = false; - if (token.type === "html_block") { - if (token.content.startsWith("", startIndex); + if (endIndex === -1) { break; } + const parameter = line.slice(startIndex, endIndex); + forEachMatch(action, parameter, lineIndex + 1); } } - - if (scanToEnd === true) { - continue; + if (forEachLine) { + forEachLine(); } - - break; } - - if (code === CHAR_FORWARD_SLASH) { - slashes.push(index); - tokens.push(token); - token = { value: '', depth: 0, isGlob: false }; - - if (finished === true) continue; - if (prev === CHAR_DOT && index === (start + 1)) { - start += 2; - continue; + } + // eslint-disable-next-line jsdoc/require-jsdoc + function configureFile(action, parameter) { + if (action === "CONFIGURE-FILE") { + const { "config": parsed } = parseConfiguration( + "CONFIGURE-FILE", parameter, configParsers + ); + if (parsed) { + config = { + ...config, + ...parsed + }; } - - lastIndex = index + 1; - continue; - } - - if (opts.noext !== true) { - const isExtglobChar = code === CHAR_PLUS - || code === CHAR_AT - || code === CHAR_ASTERISK - || code === CHAR_QUESTION_MARK - || code === CHAR_EXCLAMATION_MARK; - - if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { - isGlob = token.isGlob = true; - isExtglob = token.isExtglob = true; - finished = true; - if (code === CHAR_EXCLAMATION_MARK && index === start) { - negatedExtglob = true; - } - - if (scanToEnd === true) { - while (eos() !== true && (code = advance())) { - if (code === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - code = advance(); - continue; - } - - if (code === CHAR_RIGHT_PARENTHESES) { - isGlob = token.isGlob = true; - finished = true; - break; - } - } - continue; - } - break; - } - } - - if (code === CHAR_ASTERISK) { - if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; - isGlob = token.isGlob = true; - finished = true; - - if (scanToEnd === true) { - continue; - } - break; - } - - if (code === CHAR_QUESTION_MARK) { - isGlob = token.isGlob = true; - finished = true; - - if (scanToEnd === true) { - continue; - } - break; - } - - if (code === CHAR_LEFT_SQUARE_BRACKET) { - while (eos() !== true && (next = advance())) { - if (next === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - advance(); - continue; - } - - if (next === CHAR_RIGHT_SQUARE_BRACKET) { - isBracket = token.isBracket = true; - isGlob = token.isGlob = true; - finished = true; - break; - } - } - - if (scanToEnd === true) { - continue; - } - - break; - } - - if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { - negated = token.negated = true; - start++; - continue; - } - - if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { - isGlob = token.isGlob = true; - - if (scanToEnd === true) { - while (eos() !== true && (code = advance())) { - if (code === CHAR_LEFT_PARENTHESES) { - backslashes = token.backslashes = true; - code = advance(); - continue; - } - - if (code === CHAR_RIGHT_PARENTHESES) { - finished = true; - break; - } - } - continue; - } - break; } - - if (isGlob === true) { - finished = true; - - if (scanToEnd === true) { - continue; + } + // eslint-disable-next-line jsdoc/require-jsdoc + function applyEnableDisable(action, parameter, state) { + state = { ...state }; + const enabled = (action.startsWith("ENABLE")); + const trimmed = parameter && parameter.trim(); + const items = trimmed ? trimmed.toUpperCase().split(/\s+/) : allRuleNames; + for (const nameUpper of items) { + for (const ruleName of (aliasToRuleNames[nameUpper] || [])) { + state[ruleName] = enabled; } - - break; } + return state; } - - if (opts.noext === true) { - isExtglob = false; - isGlob = false; - } - - let base = str; - let prefix = ''; - let glob = ''; - - if (start > 0) { - prefix = str.slice(0, start); - str = str.slice(start); - lastIndex -= start; - } - - if (base && isGlob === true && lastIndex > 0) { - base = str.slice(0, lastIndex); - glob = str.slice(lastIndex); - } else if (isGlob === true) { - base = ''; - glob = str; - } else { - base = str; - } - - if (base && base !== '' && base !== '/' && base !== str) { - if (isPathSeparator(base.charCodeAt(base.length - 1))) { - base = base.slice(0, -1); + // eslint-disable-next-line jsdoc/require-jsdoc + function enableDisableFile(action, parameter) { + if ((action === "ENABLE-FILE") || (action === "DISABLE-FILE")) { + enabledRules = applyEnableDisable(action, parameter, enabledRules); } } - - if (opts.unescape === true) { - if (glob) glob = utils.removeBackslashes(glob); - - if (base && backslashes === true) { - base = utils.removeBackslashes(base); + // eslint-disable-next-line jsdoc/require-jsdoc + function captureRestoreEnableDisable(action, parameter) { + if (action === "CAPTURE") { + capturedRules = enabledRules; + } else if (action === "RESTORE") { + enabledRules = capturedRules; + } else if ((action === "ENABLE") || (action === "DISABLE")) { + enabledRules = applyEnableDisable(action, parameter, enabledRules); } } - - const state = { - prefix, - input, - start, - base, - glob, - isBrace, - isBracket, - isGlob, - isExtglob, - isGlobstar, - negated, - negatedExtglob - }; - - if (opts.tokens === true) { - state.maxDepth = 0; - if (!isPathSeparator(code)) { - tokens.push(token); - } - state.tokens = tokens; + // eslint-disable-next-line jsdoc/require-jsdoc + function updateLineState() { + enabledRulesPerLineNumber.push(enabledRules); } - - if (opts.parts === true || opts.tokens === true) { - let prevIndex; - - for (let idx = 0; idx < slashes.length; idx++) { - const n = prevIndex ? prevIndex + 1 : start; - const i = slashes[idx]; - const value = input.slice(n, i); - if (opts.tokens) { - if (idx === 0 && start !== 0) { - tokens[idx].isPrefix = true; - tokens[idx].value = prefix; - } else { - tokens[idx].value = value; - } - depth(tokens[idx]); - state.maxDepth += tokens[idx].depth; - } - if (idx !== 0 || value !== '') { - parts.push(value); - } - prevIndex = i; - } - - if (prevIndex && prevIndex + 1 < input.length) { - const value = input.slice(prevIndex + 1); - parts.push(value); - - if (opts.tokens) { - tokens[tokens.length - 1].value = value; - depth(tokens[tokens.length - 1]); - state.maxDepth += tokens[tokens.length - 1].depth; - } + // eslint-disable-next-line jsdoc/require-jsdoc + function disableLineNextLine(action, parameter, lineNumber) { + const disableLine = (action === "DISABLE-LINE"); + const disableNextLine = (action === "DISABLE-NEXT-LINE"); + if (disableLine || disableNextLine) { + const nextLineNumber = + frontMatterLines.length + lineNumber + (disableNextLine ? 1 : 0); + enabledRulesPerLineNumber[nextLineNumber] = + applyEnableDisable( + action, + parameter, + enabledRulesPerLineNumber[nextLineNumber] || {} + ); } - - state.slashes = slashes; - state.parts = parts; } + // Handle inline comments + handleInlineConfig([ lines.join("\n") ], configureFile); + const effectiveConfig = getEffectiveConfig( + ruleList, config, aliasToRuleNames); + for (const rule of ruleList) { + const ruleName = rule.names[0].toUpperCase(); + allRuleNames.push(ruleName); + enabledRules[ruleName] = !!effectiveConfig[ruleName]; + } + capturedRules = enabledRules; + handleInlineConfig(lines, enableDisableFile); + handleInlineConfig(lines, captureRestoreEnableDisable, updateLineState); + handleInlineConfig(lines, disableLineNextLine); + // Return results + return { + effectiveConfig, + enabledRulesPerLineNumber + }; +} - return state; -}; - -module.exports = scan; - - -/***/ }), - -/***/ 479: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -const path = __nccwpck_require__(1017); -const win32 = process.platform === 'win32'; -const { - REGEX_BACKSLASH, - REGEX_REMOVE_BACKSLASH, - REGEX_SPECIAL_CHARS, - REGEX_SPECIAL_CHARS_GLOBAL -} = __nccwpck_require__(6099); - -exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); -exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); -exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); -exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); -exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); - -exports.removeBackslashes = str => { - return str.replace(REGEX_REMOVE_BACKSLASH, match => { - return match === '\\' ? '' : match; +/** + * Lints a string containing Markdown content. + * + * @param {Rule[]} ruleList List of rules. + * @param {string} name Identifier for the content. + * @param {string} content Markdown content. + * @param {Object} md Instance of markdown-it. + * @param {Configuration} config Configuration object. + * @param {ConfigurationParser[] | null} configParsers Configuration parsers. + * @param {RegExp} frontMatter Regular expression for front matter. + * @param {boolean} handleRuleFailures Whether to handle exceptions in rules. + * @param {boolean} noInlineConfig Whether to allow inline configuration. + * @param {number} resultVersion Version of the LintResults object to return. + * @param {Function} callback Callback (err, result) function. + * @returns {void} + */ +function lintContent( + ruleList, + name, + content, + md, + config, + configParsers, + frontMatter, + handleRuleFailures, + noInlineConfig, + resultVersion, + callback) { + // Remove UTF-8 byte order marker (if present) + content = content.replace(/^\uFEFF/, ""); + // Remove front matter + const removeFrontMatterResult = removeFrontMatter(content, frontMatter); + const { frontMatterLines } = removeFrontMatterResult; + content = removeFrontMatterResult.content; + // Get enabled rules per line (with HTML comments present) + const { effectiveConfig, enabledRulesPerLineNumber } = + getEnabledRulesPerLineNumber( + ruleList, + content.split(helpers.newLineRe), + frontMatterLines, + noInlineConfig, + config, + configParsers, + mapAliasToRuleNames(ruleList) + ); + // Hide the content of HTML comments from rules, etc. + content = helpers.clearHtmlCommentText(content); + // Parse content into tokens and lines + const tokens = md.parse(content, {}); + const lines = content.split(helpers.newLineRe); + annotateAndFreezeTokens(tokens, lines); + // Create (frozen) parameters for rules + const paramsBase = { + name, + tokens, + "lines": Object.freeze(lines), + "frontMatterLines": Object.freeze(frontMatterLines) + }; + const lineMetadata = + helpers.getLineMetadata(paramsBase); + const codeBlockAndSpanRanges = + helpers.codeBlockAndSpanRanges(paramsBase, lineMetadata); + const flattenedLists = + helpers.flattenLists(paramsBase.tokens); + const htmlElementRanges = + helpers.htmlElementRanges(paramsBase, lineMetadata); + const referenceLinkImageData = + helpers.getReferenceLinkImageData(lineMetadata); + cache.set({ + codeBlockAndSpanRanges, + flattenedLists, + htmlElementRanges, + lineMetadata, + referenceLinkImageData }); -}; - -exports.supportsLookbehinds = () => { - const segs = process.version.slice(1).split('.').map(Number); - if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) { - return true; - } - return false; -}; - -exports.isWindows = options => { - if (options && typeof options.windows === 'boolean') { - return options.windows; - } - return win32 === true || path.sep === '\\'; -}; - -exports.escapeLast = (input, char, lastIdx) => { - const idx = input.lastIndexOf(char, lastIdx); - if (idx === -1) return input; - if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); - return `${input.slice(0, idx)}\\${input.slice(idx)}`; -}; - -exports.removePrefix = (input, state = {}) => { - let output = input; - if (output.startsWith('./')) { - output = output.slice(2); - state.prefix = './'; - } - return output; -}; - -exports.wrapOutput = (input, state = {}, options = {}) => { - const prepend = options.contains ? '' : '^'; - const append = options.contains ? '' : '$'; - - let output = `${prepend}(?:${input})${append}`; - if (state.negated === true) { - output = `(?:^(?!${output}).*$)`; - } - return output; -}; - - -/***/ }), - -/***/ 9795: -/***/ ((module) => { - -/*! queue-microtask. MIT License. Feross Aboukhadijeh */ -let promise - -module.exports = typeof queueMicrotask === 'function' - ? queueMicrotask.bind(typeof window !== 'undefined' ? window : global) - // reuse resolved promise, and allocate it lazily - : cb => (promise || (promise = Promise.resolve())) - .then(cb) - .catch(err => setTimeout(() => { throw err }, 0)) - - -/***/ }), - -/***/ 2113: -/***/ ((module) => { - -"use strict"; - - -function reusify (Constructor) { - var head = new Constructor() - var tail = head - - function get () { - var current = head - - if (current.next) { - head = current.next - } else { - head = new Constructor() - tail = head + // Function to run for each rule + let results = []; + // eslint-disable-next-line jsdoc/require-jsdoc + function forRule(rule) { + // Configure rule + const ruleName = rule.names[0].toUpperCase(); + const params = { + ...paramsBase, + "config": effectiveConfig[ruleName] + }; + // eslint-disable-next-line jsdoc/require-jsdoc + function throwError(property) { + throw new Error( + "Property '" + property + "' of onError parameter is incorrect."); } - - current.next = null - - return current - } - - function release (obj) { - tail.next = obj - tail = obj - } - - return { - get: get, - release: release - } -} - -module.exports = reusify - - -/***/ }), - -/***/ 5288: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -/*! run-parallel. MIT License. Feross Aboukhadijeh */ -module.exports = runParallel - -const queueMicrotask = __nccwpck_require__(9795) - -function runParallel (tasks, cb) { - let results, pending, keys - let isSync = true - - if (Array.isArray(tasks)) { - results = [] - pending = tasks.length - } else { - keys = Object.keys(tasks) - results = {} - pending = keys.length - } - - function done (err) { - function end () { - if (cb) cb(err, results) - cb = null + // eslint-disable-next-line jsdoc/require-jsdoc + function onError(errorInfo) { + if (!errorInfo || + !helpers.isNumber(errorInfo.lineNumber) || + (errorInfo.lineNumber < 1) || + (errorInfo.lineNumber > lines.length)) { + throwError("lineNumber"); + } + const lineNumber = errorInfo.lineNumber + frontMatterLines.length; + if (!enabledRulesPerLineNumber[lineNumber][ruleName]) { + return; + } + if (errorInfo.detail && + !helpers.isString(errorInfo.detail)) { + throwError("detail"); + } + if (errorInfo.context && + !helpers.isString(errorInfo.context)) { + throwError("context"); + } + if (errorInfo.range && + (!Array.isArray(errorInfo.range) || + (errorInfo.range.length !== 2) || + !helpers.isNumber(errorInfo.range[0]) || + (errorInfo.range[0] < 1) || + !helpers.isNumber(errorInfo.range[1]) || + (errorInfo.range[1] < 1) || + ((errorInfo.range[0] + errorInfo.range[1] - 1) > + lines[errorInfo.lineNumber - 1].length))) { + throwError("range"); + } + const fixInfo = errorInfo.fixInfo; + const cleanFixInfo = {}; + if (fixInfo) { + if (!helpers.isObject(fixInfo)) { + throwError("fixInfo"); + } + if (fixInfo.lineNumber !== undefined) { + if ((!helpers.isNumber(fixInfo.lineNumber) || + (fixInfo.lineNumber < 1) || + (fixInfo.lineNumber > lines.length))) { + throwError("fixInfo.lineNumber"); + } + cleanFixInfo.lineNumber = + fixInfo.lineNumber + frontMatterLines.length; + } + const effectiveLineNumber = fixInfo.lineNumber || errorInfo.lineNumber; + if (fixInfo.editColumn !== undefined) { + if ((!helpers.isNumber(fixInfo.editColumn) || + (fixInfo.editColumn < 1) || + (fixInfo.editColumn > + lines[effectiveLineNumber - 1].length + 1))) { + throwError("fixInfo.editColumn"); + } + cleanFixInfo.editColumn = fixInfo.editColumn; + } + if (fixInfo.deleteCount !== undefined) { + if ((!helpers.isNumber(fixInfo.deleteCount) || + (fixInfo.deleteCount < -1) || + (fixInfo.deleteCount > + lines[effectiveLineNumber - 1].length))) { + throwError("fixInfo.deleteCount"); + } + cleanFixInfo.deleteCount = fixInfo.deleteCount; + } + if (fixInfo.insertText !== undefined) { + if (!helpers.isString(fixInfo.insertText)) { + throwError("fixInfo.insertText"); + } + cleanFixInfo.insertText = fixInfo.insertText; + } + } + results.push({ + lineNumber, + "ruleName": rule.names[0], + "ruleNames": rule.names, + "ruleDescription": rule.description, + "ruleInformation": rule.information ? rule.information.href : null, + "errorDetail": errorInfo.detail || null, + "errorContext": errorInfo.context || null, + "errorRange": errorInfo.range ? [ ...errorInfo.range ] : null, + "fixInfo": fixInfo ? cleanFixInfo : null + }); } - if (isSync) queueMicrotask(end) - else end() - } - - function each (i, err, result) { - results[i] = result - if (--pending === 0 || err) { - done(err) + // Call (possibly external) rule function to report errors + const catchCallsOnError = (error) => onError({ + "lineNumber": 1, + "detail": `This rule threw an exception: ${error.message || error}` + }); + const invokeRuleFunction = () => rule.function(params, onError); + if (rule.asynchronous) { + // Asynchronous rule, ensure it returns a Promise + const ruleFunctionPromise = + Promise.resolve().then(invokeRuleFunction); + return handleRuleFailures ? + ruleFunctionPromise.catch(catchCallsOnError) : + ruleFunctionPromise; } + // Synchronous rule + try { + invokeRuleFunction(); + } catch (error) { + if (handleRuleFailures) { + catchCallsOnError(error); + } else { + throw error; + } + } + return null; } - - if (!pending) { - // empty - done(null) - } else if (keys) { - // object - keys.forEach(function (key) { - tasks[key](function (err, result) { each(key, err, result) }) - }) - } else { - // array - tasks.forEach(function (task, i) { - task(function (err, result) { each(i, err, result) }) - }) - } - - isSync = false -} - - -/***/ }), - -/***/ 1861: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; -/*! - * to-regex-range - * - * Copyright (c) 2015-present, Jon Schlinkert. - * Released under the MIT License. - */ - - - -const isNumber = __nccwpck_require__(5680); - -const toRegexRange = (min, max, options) => { - if (isNumber(min) === false) { - throw new TypeError('toRegexRange: expected the first argument to be a number'); - } - - if (max === void 0 || min === max) { - return String(min); - } - - if (isNumber(max) === false) { - throw new TypeError('toRegexRange: expected the second argument to be a number.'); - } - - let opts = { relaxZeros: true, ...options }; - if (typeof opts.strictZeros === 'boolean') { - opts.relaxZeros = opts.strictZeros === false; - } - - let relax = String(opts.relaxZeros); - let shorthand = String(opts.shorthand); - let capture = String(opts.capture); - let wrap = String(opts.wrap); - let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap; - - if (toRegexRange.cache.hasOwnProperty(cacheKey)) { - return toRegexRange.cache[cacheKey].result; - } - - let a = Math.min(min, max); - let b = Math.max(min, max); - - if (Math.abs(a - b) === 1) { - let result = min + '|' + max; - if (opts.capture) { - return `(${result})`; + // eslint-disable-next-line jsdoc/require-jsdoc + function formatResults() { + // Sort results by rule name by line number + results.sort((a, b) => ( + a.ruleName.localeCompare(b.ruleName) || + a.lineNumber - b.lineNumber + )); + if (resultVersion < 3) { + // Remove fixInfo and multiple errors for the same rule and line number + const noPrevious = { + "ruleName": null, + "lineNumber": -1 + }; + results = results.filter((error, index, array) => { + delete error.fixInfo; + const previous = array[index - 1] || noPrevious; + return ( + (error.ruleName !== previous.ruleName) || + (error.lineNumber !== previous.lineNumber) + ); + }); } - if (opts.wrap === false) { - return result; + if (resultVersion === 0) { + // Return a dictionary of rule->[line numbers] + const dictionary = {}; + for (const error of results) { + const ruleLines = dictionary[error.ruleName] || []; + ruleLines.push(error.lineNumber); + dictionary[error.ruleName] = ruleLines; + } + // @ts-ignore + results = dictionary; + } else if (resultVersion === 1) { + // Use ruleAlias instead of ruleNames + for (const error of results) { + error.ruleAlias = error.ruleNames[1] || error.ruleName; + delete error.ruleNames; + } + } else { + // resultVersion 2 or 3: Remove unwanted ruleName + for (const error of results) { + delete error.ruleName; + } } - return `(?:${result})`; - } - - let isPadded = hasPadding(min) || hasPadding(max); - let state = { min, max, a, b }; - let positives = []; - let negatives = []; - - if (isPadded) { - state.isPadded = isPadded; - state.maxLen = String(state.max).length; - } - - if (a < 0) { - let newMin = b < 0 ? Math.abs(b) : 1; - negatives = splitToPatterns(newMin, Math.abs(a), state, opts); - a = state.a = 0; - } - - if (b >= 0) { - positives = splitToPatterns(a, b, state, opts); + return results; } - - state.negatives = negatives; - state.positives = positives; - state.result = collatePatterns(negatives, positives, opts); - - if (opts.capture === true) { - state.result = `(${state.result})`; - } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) { - state.result = `(?:${state.result})`; + // Run all rules + const ruleListAsync = ruleList.filter((rule) => rule.asynchronous); + const ruleListSync = ruleList.filter((rule) => !rule.asynchronous); + const ruleListAsyncFirst = [ + ...ruleListAsync, + ...ruleListSync + ]; + const callbackSuccess = () => callback(null, formatResults()); + const callbackError = + (error) => callback(error instanceof Error ? error : new Error(error)); + try { + const ruleResults = ruleListAsyncFirst.map(forRule); + if (ruleListAsync.length > 0) { + Promise.all(ruleResults.slice(0, ruleListAsync.length)) + .then(callbackSuccess) + .catch(callbackError); + } else { + callbackSuccess(); + } + } catch (error) { + callbackError(error); + } finally { + cache.clear(); } - - toRegexRange.cache[cacheKey] = state; - return state.result; -}; - -function collatePatterns(neg, pos, options) { - let onlyNegative = filterPatterns(neg, pos, '-', false, options) || []; - let onlyPositive = filterPatterns(pos, neg, '', false, options) || []; - let intersected = filterPatterns(neg, pos, '-?', true, options) || []; - let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); - return subpatterns.join('|'); } -function splitToRanges(min, max) { - let nines = 1; - let zeros = 1; - - let stop = countNines(min, nines); - let stops = new Set([max]); - - while (min <= stop && stop <= max) { - stops.add(stop); - nines += 1; - stop = countNines(min, nines); +/** + * Lints a file containing Markdown content. + * + * @param {Rule[]} ruleList List of rules. + * @param {string} file Path of file to lint. + * @param {Object} md Instance of markdown-it. + * @param {Configuration} config Configuration object. + * @param {ConfigurationParser[] | null} configParsers Configuration parsers. + * @param {RegExp} frontMatter Regular expression for front matter. + * @param {boolean} handleRuleFailures Whether to handle exceptions in rules. + * @param {boolean} noInlineConfig Whether to allow inline configuration. + * @param {number} resultVersion Version of the LintResults object to return. + * @param {Object} fs File system implementation. + * @param {boolean} synchronous Whether to execute synchronously. + * @param {Function} callback Callback (err, result) function. + * @returns {void} + */ +function lintFile( + ruleList, + file, + md, + config, + configParsers, + frontMatter, + handleRuleFailures, + noInlineConfig, + resultVersion, + fs, + synchronous, + callback) { + // eslint-disable-next-line jsdoc/require-jsdoc + function lintContentWrapper(err, content) { + if (err) { + return callback(err); + } + return lintContent( + ruleList, + file, + content, + md, + config, + configParsers, + frontMatter, + handleRuleFailures, + noInlineConfig, + resultVersion, + callback + ); } - - stop = countZeros(max + 1, zeros) - 1; - - while (min < stop && stop <= max) { - stops.add(stop); - zeros += 1; - stop = countZeros(max + 1, zeros) - 1; + // Make a/synchronous call to read file + if (synchronous) { + lintContentWrapper(null, fs.readFileSync(file, "utf8")); + } else { + fs.readFile(file, "utf8", lintContentWrapper); } - - stops = [...stops]; - stops.sort(compare); - return stops; } /** - * Convert a range to a regex pattern - * @param {Number} `start` - * @param {Number} `stop` - * @return {String} + * Lint files and strings specified in the Options object. + * + * @param {Options} options Options object. + * @param {boolean} synchronous Whether to execute synchronously. + * @param {Function} callback Callback (err, result) function. + * @returns {void} */ - -function rangeToPattern(start, stop, options) { - if (start === stop) { - return { pattern: start, count: [], digits: 0 }; +function lintInput(options, synchronous, callback) { + // Normalize inputs + options = options || {}; + callback = callback || function noop() {}; + // eslint-disable-next-line unicorn/prefer-spread + const ruleList = rules.concat(options.customRules || []); + const ruleErr = validateRuleList(ruleList, synchronous); + if (ruleErr) { + callback(ruleErr); + return; } - - let zipped = zip(start, stop); - let digits = zipped.length; - let pattern = ''; - let count = 0; - - for (let i = 0; i < digits; i++) { - let [startDigit, stopDigit] = zipped[i]; - - if (startDigit === stopDigit) { - pattern += startDigit; - - } else if (startDigit !== '0' || stopDigit !== '9') { - pattern += toCharacterClass(startDigit, stopDigit, options); - - } else { - count++; - } + let files = []; + if (Array.isArray(options.files)) { + files = [ ...options.files ]; + } else if (options.files) { + files = [ String(options.files) ]; } - - if (count) { - pattern += options.shorthand === true ? '\\d' : '[0-9]'; + const strings = options.strings || {}; + const stringsKeys = Object.keys(strings); + const config = options.config || { "default": true }; + const configParsers = options.configParsers || null; + const frontMatter = (options.frontMatter === undefined) ? + helpers.frontMatterRe : options.frontMatter; + const handleRuleFailures = !!options.handleRuleFailures; + const noInlineConfig = !!options.noInlineConfig; + const resultVersion = (options.resultVersion === undefined) ? + 3 : options.resultVersion; + const md = markdownIt({ "html": true }); + const markdownItPlugins = options.markdownItPlugins || []; + for (const plugin of markdownItPlugins) { + // @ts-ignore + md.use(...plugin); } - - return { pattern, count: [count], digits }; -} - -function splitToPatterns(min, max, tok, options) { - let ranges = splitToRanges(min, max); - let tokens = []; - let start = min; - let prev; - - for (let i = 0; i < ranges.length; i++) { - let max = ranges[i]; - let obj = rangeToPattern(String(start), String(max), options); - let zeros = ''; - - if (!tok.isPadded && prev && prev.pattern === obj.pattern) { - if (prev.count.length > 1) { - prev.count.pop(); + const fs = options.fs || __nccwpck_require__(7147); + const results = newResults(ruleList); + let done = false; + let concurrency = 0; + // eslint-disable-next-line jsdoc/require-jsdoc + function lintWorker() { + let currentItem = null; + // eslint-disable-next-line jsdoc/require-jsdoc + function lintWorkerCallback(err, result) { + concurrency--; + if (err) { + done = true; + return callback(err); } - - prev.count.push(obj.count[0]); - prev.string = prev.pattern + toQuantifier(prev.count); - start = max + 1; - continue; - } - - if (tok.isPadded) { - zeros = padZeros(max, tok, options); + results[currentItem] = result; + if (!synchronous) { + lintWorker(); + } + return null; } - - obj.string = zeros + obj.pattern + toQuantifier(obj.count); - tokens.push(obj); - start = max + 1; - prev = obj; - } - - return tokens; -} - -function filterPatterns(arr, comparison, prefix, intersection, options) { - let result = []; - - for (let ele of arr) { - let { string } = ele; - - // only push if _both_ are negative... - if (!intersection && !contains(comparison, 'string', string)) { - result.push(prefix + string); + if (done) { + // Abort for error or nothing left to do + } else if (files.length > 0) { + // Lint next file + concurrency++; + currentItem = files.shift(); + lintFile( + ruleList, + currentItem, + md, + config, + configParsers, + frontMatter, + handleRuleFailures, + noInlineConfig, + resultVersion, + fs, + synchronous, + lintWorkerCallback + ); + } else if ((currentItem = stringsKeys.shift())) { + // Lint next string + concurrency++; + lintContent( + ruleList, + currentItem, + strings[currentItem] || "", + md, + config, + configParsers, + frontMatter, + handleRuleFailures, + noInlineConfig, + resultVersion, + lintWorkerCallback + ); + } else if (concurrency === 0) { + // Finish + done = true; + return callback(null, results); } - - // or _both_ are positive - if (intersection && contains(comparison, 'string', string)) { - result.push(prefix + string); + return null; + } + if (synchronous) { + while (!done) { + lintWorker(); } + } else { + // Testing on a Raspberry Pi 4 Model B with an artificial 5ms file access + // delay suggests that a concurrency factor of 8 can eliminate the impact + // of that delay (i.e., total time is the same as with no delay). + lintWorker(); + lintWorker(); + lintWorker(); + lintWorker(); + lintWorker(); + lintWorker(); + lintWorker(); + lintWorker(); } - return result; } /** - * Zip strings + * Lint specified Markdown files. + * + * @param {Options} options Configuration options. + * @param {LintCallback} callback Callback (err, result) function. + * @returns {void} */ - -function zip(a, b) { - let arr = []; - for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]); - return arr; -} - -function compare(a, b) { - return a > b ? 1 : b > a ? -1 : 0; -} - -function contains(arr, key, val) { - return arr.some(ele => ele[key] === val); -} - -function countNines(min, len) { - return Number(String(min).slice(0, -len) + '9'.repeat(len)); -} - -function countZeros(integer, zeros) { - return integer - (integer % Math.pow(10, zeros)); -} - -function toQuantifier(digits) { - let [start = 0, stop = ''] = digits; - if (stop || start > 1) { - return `{${start + (stop ? ',' + stop : '')}}`; - } - return ''; -} - -function toCharacterClass(a, b, options) { - return `[${a}${(b - a === 1) ? '' : '-'}${b}]`; -} - -function hasPadding(str) { - return /^-?(0+)\d/.test(str); +function markdownlint(options, callback) { + return lintInput(options, false, callback); } -function padZeros(value, tok, options) { - if (!tok.isPadded) { - return value; - } - - let diff = Math.abs(tok.maxLen - String(value).length); - let relax = options.relaxZeros !== false; - - switch (diff) { - case 0: - return ''; - case 1: - return relax ? '0?' : '0'; - case 2: - return relax ? '0{0,2}' : '00'; - default: { - return relax ? `0{0,${diff}}` : `0{${diff}}`; - } - } -} +const markdownlintPromisify = promisify && promisify(markdownlint); /** - * Cache + * Lint specified Markdown files. + * + * @param {Options} options Configuration options. + * @returns {Promise} Results object. */ - -toRegexRange.cache = {}; -toRegexRange.clearCache = () => (toRegexRange.cache = {}); +function markdownlintPromise(options) { + // @ts-ignore + return markdownlintPromisify(options); +} /** - * Expose `toRegexRange` + * Lint specified Markdown files synchronously. + * + * @param {Options} options Configuration options. + * @returns {LintResults} Results object. */ - -module.exports = toRegexRange; - - -/***/ }), - -/***/ 4294: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -module.exports = __nccwpck_require__(4219); - - -/***/ }), - -/***/ 4219: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -var net = __nccwpck_require__(1808); -var tls = __nccwpck_require__(4404); -var http = __nccwpck_require__(3685); -var https = __nccwpck_require__(5687); -var events = __nccwpck_require__(2361); -var assert = __nccwpck_require__(9491); -var util = __nccwpck_require__(3837); - - -exports.httpOverHttp = httpOverHttp; -exports.httpsOverHttp = httpsOverHttp; -exports.httpOverHttps = httpOverHttps; -exports.httpsOverHttps = httpsOverHttps; - - -function httpOverHttp(options) { - var agent = new TunnelingAgent(options); - agent.request = http.request; - return agent; -} - -function httpsOverHttp(options) { - var agent = new TunnelingAgent(options); - agent.request = http.request; - agent.createSocket = createSecureSocket; - agent.defaultPort = 443; - return agent; -} - -function httpOverHttps(options) { - var agent = new TunnelingAgent(options); - agent.request = https.request; - return agent; -} - -function httpsOverHttps(options) { - var agent = new TunnelingAgent(options); - agent.request = https.request; - agent.createSocket = createSecureSocket; - agent.defaultPort = 443; - return agent; -} - - -function TunnelingAgent(options) { - var self = this; - self.options = options || {}; - self.proxyOptions = self.options.proxy || {}; - self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; - self.requests = []; - self.sockets = []; - - self.on('free', function onFree(socket, host, port, localAddress) { - var options = toOptions(host, port, localAddress); - for (var i = 0, len = self.requests.length; i < len; ++i) { - var pending = self.requests[i]; - if (pending.host === options.host && pending.port === options.port) { - // Detect the request to connect same origin server, - // reuse the connection. - self.requests.splice(i, 1); - pending.request.onSocket(socket); - return; - } +function markdownlintSync(options) { + let results = {}; + lintInput(options, true, function callback(error, res) { + if (error) { + throw error; } - socket.destroy(); - self.removeSocket(socket); + results = res; }); + // @ts-ignore + return results; } -util.inherits(TunnelingAgent, events.EventEmitter); - -TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { - var self = this; - var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); - - if (self.sockets.length >= this.maxSockets) { - // We are over limit so we'll add it to the queue. - self.requests.push(options); - return; - } - - // If we are under maxSockets create a new one. - self.createSocket(options, function(socket) { - socket.on('free', onFree); - socket.on('close', onCloseOrRemove); - socket.on('agentRemove', onCloseOrRemove); - req.onSocket(socket); - - function onFree() { - self.emit('free', socket, options); - } - function onCloseOrRemove(err) { - self.removeSocket(socket); - socket.removeListener('free', onFree); - socket.removeListener('close', onCloseOrRemove); - socket.removeListener('agentRemove', onCloseOrRemove); - } - }); -}; - -TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { - var self = this; - var placeholder = {}; - self.sockets.push(placeholder); - - var connectOptions = mergeOptions({}, self.proxyOptions, { - method: 'CONNECT', - path: options.host + ':' + options.port, - agent: false, - headers: { - host: options.host + ':' + options.port +/** + * Resolve referenced "extends" path in a configuration file + * using path.resolve() with require.resolve() as a fallback. + * + * @param {string} configFile Configuration file name. + * @param {string} referenceId Referenced identifier to resolve. + * @param {Object} fs File system implementation. + * @param {ResolveConfigExtendsCallback} callback Callback (err, result) + * function. + * @returns {void} + */ +function resolveConfigExtends(configFile, referenceId, fs, callback) { + const configFileDirname = path.dirname(configFile); + const resolvedExtendsFile = path.resolve(configFileDirname, referenceId); + fs.access(resolvedExtendsFile, (err) => { + if (err) { + // Not a file, try require.resolve + try { + return callback(null, dynamicRequire.resolve( + referenceId, + { "paths": [ configFileDirname ] } + )); + } catch { + // Unable to resolve, use resolvedExtendsFile + } } + return callback(null, resolvedExtendsFile); }); - if (options.localAddress) { - connectOptions.localAddress = options.localAddress; - } - if (connectOptions.proxyAuth) { - connectOptions.headers = connectOptions.headers || {}; - connectOptions.headers['Proxy-Authorization'] = 'Basic ' + - new Buffer(connectOptions.proxyAuth).toString('base64'); - } - - debug('making CONNECT request'); - var connectReq = self.request(connectOptions); - connectReq.useChunkedEncodingByDefault = false; // for v0.6 - connectReq.once('response', onResponse); // for v0.6 - connectReq.once('upgrade', onUpgrade); // for v0.6 - connectReq.once('connect', onConnect); // for v0.7 or later - connectReq.once('error', onError); - connectReq.end(); +} - function onResponse(res) { - // Very hacky. This is necessary to avoid http-parser leaks. - res.upgrade = true; +/** + * Resolve referenced "extends" path in a configuration file + * using path.resolve() with require.resolve() as a fallback. + * + * @param {string} configFile Configuration file name. + * @param {string} referenceId Referenced identifier to resolve. + * @param {Object} fs File system implementation. + * @returns {string} Resolved path to file. + */ +function resolveConfigExtendsSync(configFile, referenceId, fs) { + const configFileDirname = path.dirname(configFile); + const resolvedExtendsFile = path.resolve(configFileDirname, referenceId); + try { + fs.accessSync(resolvedExtendsFile); + return resolvedExtendsFile; + } catch { + // Not a file, try require.resolve } - - function onUpgrade(res, socket, head) { - // Hacky. - process.nextTick(function() { - onConnect(res, socket, head); - }); + try { + return dynamicRequire.resolve( + referenceId, + { "paths": [ configFileDirname ] } + ); + } catch { + // Unable to resolve, return resolvedExtendsFile } + return resolvedExtendsFile; +} - function onConnect(res, socket, head) { - connectReq.removeAllListeners(); - socket.removeAllListeners(); - - if (res.statusCode !== 200) { - debug('tunneling socket could not be established, statusCode=%d', - res.statusCode); - socket.destroy(); - var error = new Error('tunneling socket could not be established, ' + - 'statusCode=' + res.statusCode); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - return; - } - if (head.length > 0) { - debug('got illegal response body from proxy'); - socket.destroy(); - var error = new Error('got illegal response body from proxy'); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - return; +/** + * Read specified configuration file. + * + * @param {string} file Configuration file name. + * @param {ConfigurationParser[] | ReadConfigCallback} parsers Parsing + * function(s). + * @param {Object} [fs] File system implementation. + * @param {ReadConfigCallback} [callback] Callback (err, result) function. + * @returns {void} + */ +function readConfig(file, parsers, fs, callback) { + if (!callback) { + if (fs) { + callback = fs; + fs = null; + } else { + // @ts-ignore + callback = parsers; + // @ts-ignore + parsers = null; } - debug('tunneling connection has established'); - self.sockets[self.sockets.indexOf(placeholder)] = socket; - return cb(socket); - } - - function onError(cause) { - connectReq.removeAllListeners(); - - debug('tunneling socket could not be established, cause=%s\n', - cause.message, cause.stack); - var error = new Error('tunneling socket could not be established, ' + - 'cause=' + cause.message); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - } -}; - -TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { - var pos = this.sockets.indexOf(socket) - if (pos === -1) { - return; } - this.sockets.splice(pos, 1); - - var pending = this.requests.shift(); - if (pending) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createSocket(pending, function(socket) { - pending.request.onSocket(socket); - }); + if (!fs) { + fs = __nccwpck_require__(7147); } -}; - -function createSecureSocket(options, cb) { - var self = this; - TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { - var hostHeader = options.request.getHeader('host'); - var tlsOptions = mergeOptions({}, self.options, { - socket: socket, - servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host - }); - - // 0 is dummy port for v0.6 - var secureSocket = tls.connect(0, tlsOptions); - self.sockets[self.sockets.indexOf(socket)] = secureSocket; - cb(secureSocket); + // Read file + const os = __nccwpck_require__(2037); + file = helpers.expandTildePath(file, os); + fs.readFile(file, "utf8", (err, content) => { + if (err) { + // @ts-ignore + return callback(err); + } + // Try to parse file + // @ts-ignore + const { config, message } = parseConfiguration(file, content, parsers); + if (!config) { + // @ts-ignore + return callback(new Error(message)); + } + // Extend configuration + const configExtends = config.extends; + if (configExtends) { + delete config.extends; + return resolveConfigExtends( + file, + helpers.expandTildePath(configExtends, os), + fs, + (_, resolvedExtends) => readConfig( + // @ts-ignore + resolvedExtends, + parsers, + fs, + (errr, extendsConfig) => { + if (errr) { + // @ts-ignore + return callback(errr); + } + // @ts-ignore + return callback(null, { + ...extendsConfig, + ...config + }); + } + ) + ); + } + // @ts-ignore + return callback(null, config); }); } +const readConfigPromisify = promisify && promisify(readConfig); -function toOptions(host, port, localAddress) { - if (typeof host === 'string') { // since v0.10 - return { - host: host, - port: port, - localAddress: localAddress - }; - } - return host; // for v0.11 or later +/** + * Read specified configuration file. + * + * @param {string} file Configuration file name. + * @param {ConfigurationParser[]} [parsers] Parsing function(s). + * @param {Object} [fs] File system implementation. + * @returns {Promise} Configuration object. + */ +function readConfigPromise(file, parsers, fs) { + // @ts-ignore + return readConfigPromisify(file, parsers, fs); } -function mergeOptions(target) { - for (var i = 1, len = arguments.length; i < len; ++i) { - var overrides = arguments[i]; - if (typeof overrides === 'object') { - var keys = Object.keys(overrides); - for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { - var k = keys[j]; - if (overrides[k] !== undefined) { - target[k] = overrides[k]; - } - } - } +/** + * Read specified configuration file synchronously. + * + * @param {string} file Configuration file name. + * @param {ConfigurationParser[]} [parsers] Parsing function(s). + * @param {Object} [fs] File system implementation. + * @returns {Configuration} Configuration object. + * @throws An Error if processing fails. + */ +function readConfigSync(file, parsers, fs) { + if (!fs) { + fs = __nccwpck_require__(7147); + } + // Read file + const os = __nccwpck_require__(2037); + file = helpers.expandTildePath(file, os); + const content = fs.readFileSync(file, "utf8"); + // Try to parse file + const { config, message } = parseConfiguration(file, content, parsers); + if (!config) { + throw new Error(message); + } + // Extend configuration + const configExtends = config.extends; + if (configExtends) { + delete config.extends; + const resolvedExtends = resolveConfigExtendsSync( + file, + helpers.expandTildePath(configExtends, os), + fs + ); + return { + ...readConfigSync(resolvedExtends, parsers, fs), + ...config + }; } - return target; + return config; } - -var debug; -if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { - debug = function() { - var args = Array.prototype.slice.call(arguments); - if (typeof args[0] === 'string') { - args[0] = 'TUNNEL: ' + args[0]; - } else { - args.unshift('TUNNEL:'); - } - console.error.apply(console, args); - } -} else { - debug = function() {}; +/** + * Gets the (semantic) version of the library. + * + * @returns {string} SemVer string. + */ +function getVersion() { + return (__nccwpck_require__(983).version); } -exports.debug = debug; // for test - - -/***/ }), - -/***/ 4338: -/***/ ((module) => { -module.exports=/[\0-\x1F\x7F-\x9F]/ +// Export a/synchronous/Promise APIs +markdownlint.sync = markdownlintSync; +markdownlint.readConfig = readConfig; +markdownlint.readConfigSync = readConfigSync; +markdownlint.getVersion = getVersion; +markdownlint.promises = { + "markdownlint": markdownlintPromise, + "readConfig": readConfigPromise +}; +module.exports = markdownlint; -/***/ }), +// Type declarations -/***/ 6149: -/***/ ((module) => { +/** + * Function to implement rule logic. + * + * @callback RuleFunction + * @param {RuleParams} params Rule parameters. + * @param {RuleOnError} onError Error-reporting callback. + * @returns {void} + */ -module.exports=/[\xAD\u0600-\u0605\u061C\u06DD\u070F\u08E2\u180E\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u206F\uFEFF\uFFF9-\uFFFB]|\uD804[\uDCBD\uDCCD]|\uD82F[\uDCA0-\uDCA3]|\uD834[\uDD73-\uDD7A]|\uDB40[\uDC01\uDC20-\uDC7F]/ +/** + * Rule parameters. + * + * @typedef {Object} RuleParams + * @property {string} name File/string name. + * @property {MarkdownItToken[]} tokens Token objects from markdown-it. + * @property {string[]} lines File/string lines. + * @property {string[]} frontMatterLines Front matter lines. + * @property {RuleConfiguration} config Rule configuration. + */ -/***/ }), +/** + * Markdown-It token. + * + * @typedef {Object} MarkdownItToken + * @property {string[][]} attrs HTML attributes. + * @property {boolean} block Block-level token. + * @property {MarkdownItToken[]} children Child nodes. + * @property {string} content Tag contents. + * @property {boolean} hidden Ignore element. + * @property {string} info Fence info. + * @property {number} level Nesting level. + * @property {number[]} map Beginning/ending line numbers. + * @property {string} markup Markup text. + * @property {Object} meta Arbitrary data. + * @property {number} nesting Level change. + * @property {string} tag HTML tag name. + * @property {string} type Token type. + * @property {number} lineNumber Line number (1-based). + * @property {string} line Line content. + */ -/***/ 8019: -/***/ ((module) => { +/** + * Error-reporting callback. + * + * @callback RuleOnError + * @param {RuleOnErrorInfo} onErrorInfo Error information. + * @returns {void} + */ -module.exports=/[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4E\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDF55-\uDF59]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDC4B-\uDC4F\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDF3C-\uDF3E]|\uD806[\uDC3B\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDE97-\uDE9A]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD83A[\uDD5E\uDD5F]/ +/** + * Fix information for RuleOnError callback. + * + * @typedef {Object} RuleOnErrorInfo + * @property {number} lineNumber Line number (1-based). + * @property {string} [detail] Detail about the error. + * @property {string} [context] Context for the error. + * @property {number[]} [range] Column number (1-based) and length. + * @property {RuleOnErrorFixInfo} [fixInfo] Fix information. + */ -/***/ }), +/** + * Fix information for RuleOnErrorInfo. + * + * @typedef {Object} RuleOnErrorFixInfo + * @property {number} [lineNumber] Line number (1-based). + * @property {number} [editColumn] Column of the fix (1-based). + * @property {number} [deleteCount] Count of characters to delete. + * @property {string} [insertText] Text to insert (after deleting). + */ -/***/ 8810: -/***/ ((module) => { +/** + * Rule definition. + * + * @typedef {Object} Rule + * @property {string[]} names Rule name(s). + * @property {string} description Rule description. + * @property {URL} [information] Link to more information. + * @property {string[]} tags Rule tag(s). + * @property {boolean} [asynchronous] True if asynchronous. + * @property {RuleFunction} function Rule implementation. + */ -module.exports=/[ \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]/ +/** + * Configuration options. + * + * @typedef {Object} Options + * @property {Configuration} [config] Configuration object. + * @property {ConfigurationParser[]} [configParsers] Configuration parsers. + * @property {Rule[] | Rule} [customRules] Custom rules. + * @property {string[] | string} [files] Files to lint. + * @property {RegExp} [frontMatter] Front matter pattern. + * @property {Object} [fs] File system implementation. + * @property {boolean} [handleRuleFailures] True to catch exceptions. + * @property {Plugin[]} [markdownItPlugins] Additional plugins. + * @property {boolean} [noInlineConfig] True to ignore HTML directives. + * @property {number} [resultVersion] Results object version. + * @property {Object.} [strings] Strings to lint. + */ -/***/ }), +/** + * A markdown-it plugin. + * + * @typedef {Array} Plugin + */ -/***/ 5649: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/** + * Function to pretty-print lint results. + * + * @callback ToStringCallback + * @param {boolean} [ruleAliases] True to use rule aliases. + * @returns {string} + */ -"use strict"; +/** + * Lint results (for resultVersion 3). + * + * @typedef {Object.} LintResults + * @property {ToStringCallback} toString String representation. + */ +/** + * Lint error. + * + * @typedef {Object} LintError + * @property {number} lineNumber Line number (1-based). + * @property {string[]} ruleNames Rule name(s). + * @property {string} ruleDescription Rule description. + * @property {string} ruleInformation Link to more information. + * @property {string} errorDetail Detail about the error. + * @property {string} errorContext Context for the error. + * @property {number[]} errorRange Column number (1-based) and length. + * @property {FixInfo} [fixInfo] Fix information. + */ -exports.Any = __nccwpck_require__(703); -exports.Cc = __nccwpck_require__(4338); -exports.Cf = __nccwpck_require__(6149); -exports.P = __nccwpck_require__(8019); -exports.Z = __nccwpck_require__(8810); +/** + * Fix information. + * + * @typedef {Object} FixInfo + * @property {number} [lineNumber] Line number (1-based). + * @property {number} [editColumn] Column of the fix (1-based). + * @property {number} [deleteCount] Count of characters to delete. + * @property {string} [insertText] Text to insert (after deleting). + */ +/** + * Called with the result of the lint function. + * + * @callback LintCallback + * @param {Error | null} err Error object or null. + * @param {LintResults} [results] Lint results. + * @returns {void} + */ -/***/ }), +/** + * Configuration object for linting rules. For a detailed schema, see + * {@link ../schema/markdownlint-config-schema.json}. + * + * @typedef {Object.} Configuration + */ -/***/ 703: -/***/ ((module) => { +/** + * Rule configuration object. + * + * @typedef {boolean | Object} RuleConfiguration Rule configuration. + */ -module.exports=/[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/ +/** + * Parses a configuration string and returns a configuration object. + * + * @callback ConfigurationParser + * @param {string} text Configuration string. + * @returns {Configuration} + */ -/***/ }), +/** + * Called with the result of the readConfig function. + * + * @callback ReadConfigCallback + * @param {Error | null} err Error object or null. + * @param {Configuration} [config] Configuration object. + * @returns {void} + */ -/***/ 9491: -/***/ ((module) => { +/** + * Called with the result of the resolveConfigExtends function. + * + * @callback ResolveConfigExtendsCallback + * @param {Error | null} err Error object or null. + * @param {string} [path] Resolved path to file. + * @returns {void} + */ -"use strict"; -module.exports = require("assert"); /***/ }), -/***/ 2361: -/***/ ((module) => { +/***/ 9651: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -module.exports = require("events"); - -/***/ }), +// @ts-check -/***/ 7147: -/***/ ((module) => { -"use strict"; -module.exports = require("fs"); -/***/ }), +const { addErrorDetailIf, filterTokens } = __nccwpck_require__(2935); -/***/ 3685: -/***/ ((module) => { +module.exports = { + "names": [ "MD001", "heading-increment", "header-increment" ], + "description": "Heading levels should only increment by one level at a time", + "tags": [ "headings", "headers" ], + "function": function MD001(params, onError) { + let prevLevel = 0; + filterTokens(params, "heading_open", function forToken(token) { + const level = Number.parseInt(token.tag.slice(1), 10); + if (prevLevel && (level > prevLevel)) { + addErrorDetailIf(onError, token.lineNumber, + "h" + (prevLevel + 1), "h" + level); + } + prevLevel = level; + }); + } +}; -"use strict"; -module.exports = require("http"); /***/ }), -/***/ 5687: -/***/ ((module) => { +/***/ 4545: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -module.exports = require("https"); - -/***/ }), +// @ts-check -/***/ 1808: -/***/ ((module) => { -"use strict"; -module.exports = require("net"); -/***/ }), +const { addErrorDetailIf } = __nccwpck_require__(2935); -/***/ 2037: -/***/ ((module) => { +module.exports = { + "names": [ "MD002", "first-heading-h1", "first-header-h1" ], + "description": "First heading should be a top-level heading", + "tags": [ "headings", "headers" ], + "function": function MD002(params, onError) { + const level = Number(params.config.level || 1); + const tag = "h" + level; + params.tokens.every(function forToken(token) { + if (token.type === "heading_open") { + addErrorDetailIf(onError, token.lineNumber, tag, token.tag); + return false; + } + return true; + }); + } +}; -"use strict"; -module.exports = require("os"); /***/ }), -/***/ 1017: -/***/ ((module) => { +/***/ 9277: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -module.exports = require("path"); +// @ts-check -/***/ }), -/***/ 5477: -/***/ ((module) => { -"use strict"; -module.exports = require("punycode"); +const { addErrorDetailIf, filterTokens, headingStyleFor } = + __nccwpck_require__(2935); + +module.exports = { + "names": [ "MD003", "heading-style", "header-style" ], + "description": "Heading style", + "tags": [ "headings", "headers" ], + "function": function MD003(params, onError) { + let style = String(params.config.style || "consistent"); + filterTokens(params, "heading_open", function forToken(token) { + const styleForToken = headingStyleFor(token); + if (style === "consistent") { + style = styleForToken; + } + if (styleForToken !== style) { + const h12 = /h[12]/.test(token.tag); + const setextWithAtx = + (style === "setext_with_atx") && + ((h12 && (styleForToken === "setext")) || + (!h12 && (styleForToken === "atx"))); + const setextWithAtxClosed = + (style === "setext_with_atx_closed") && + ((h12 && (styleForToken === "setext")) || + (!h12 && (styleForToken === "atx_closed"))); + if (!setextWithAtx && !setextWithAtxClosed) { + let expected = style; + if (style === "setext_with_atx") { + expected = h12 ? "setext" : "atx"; + } else if (style === "setext_with_atx_closed") { + expected = h12 ? "setext" : "atx_closed"; + } + addErrorDetailIf(onError, token.lineNumber, + expected, styleForToken); + } + } + }); + } +}; + /***/ }), -/***/ 2781: -/***/ ((module) => { +/***/ 3755: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -module.exports = require("stream"); +// @ts-check -/***/ }), -/***/ 4404: -/***/ ((module) => { -"use strict"; -module.exports = require("tls"); +const { addErrorDetailIf, listItemMarkerRe, unorderedListStyleFor } = + __nccwpck_require__(2935); +const { flattenedLists } = __nccwpck_require__(2260); -/***/ }), +const expectedStyleToMarker = { + "dash": "-", + "plus": "+", + "asterisk": "*" +}; +const differentItemStyle = { + "dash": "plus", + "plus": "asterisk", + "asterisk": "dash" +}; +const validStyles = Object.keys(expectedStyleToMarker); -/***/ 3837: -/***/ ((module) => { +module.exports = { + "names": [ "MD004", "ul-style" ], + "description": "Unordered list style", + "tags": [ "bullet", "ul" ], + "function": function MD004(params, onError) { + const style = String(params.config.style || "consistent"); + let expectedStyle = style; + const nestingStyles = []; + for (const list of flattenedLists()) { + if (list.unordered) { + if (expectedStyle === "consistent") { + expectedStyle = unorderedListStyleFor(list.items[0]); + } + for (const item of list.items) { + const itemStyle = unorderedListStyleFor(item); + if (style === "sublist") { + const nesting = list.nesting; + if (!nestingStyles[nesting]) { + nestingStyles[nesting] = + (itemStyle === nestingStyles[nesting - 1]) ? + differentItemStyle[itemStyle] : + itemStyle; + } + expectedStyle = nestingStyles[nesting]; + } + if (!validStyles.includes(expectedStyle)) { + expectedStyle = validStyles[0]; + } + let range = null; + let fixInfo = null; + const match = item.line.match(listItemMarkerRe); + if (match) { + const column = match.index + 1; + const length = match[0].length; + range = [ column, length ]; + fixInfo = { + "editColumn": match[1].length + 1, + "deleteCount": 1, + "insertText": expectedStyleToMarker[expectedStyle] + }; + } + addErrorDetailIf( + onError, + item.lineNumber, + expectedStyle, + itemStyle, + null, + null, + range, + fixInfo + ); + } + } + } + } +}; -"use strict"; -module.exports = require("util"); /***/ }), -/***/ 7314: -/***/ ((module) => { +/***/ 3354: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; // @ts-check -const sliceSize = 1000; +const { addError, addErrorDetailIf, indentFor, listItemMarkerRe, + orderedListItemMarkerRe, rangeFromRegExp } = __nccwpck_require__(2935); +const { flattenedLists } = __nccwpck_require__(2260); -/** - * Efficiently appends the source array to the destination array. - * @param {Object[]} destination Destination Array. - * @param {Object[]} source Source Array. - * @returns void - */ -const appendToArray = (destination, source) => { - // NOTE: destination.push(...source) throws "RangeError: Maximum call stack - // size exceeded" for sufficiently lengthy source arrays - let index = 0; - let slice = null; - while ((slice = source.slice(index, index + sliceSize)).length > 0) { - destination.push(...slice); - index += sliceSize; +module.exports = { + "names": [ "MD005", "list-indent" ], + "description": "Inconsistent indentation for list items at the same level", + "tags": [ "bullet", "ul", "indentation" ], + "function": function MD005(params, onError) { + for (const list of flattenedLists()) { + const expectedIndent = list.indent; + let expectedEnd = 0; + let actualEnd = -1; + let endMatching = false; + for (const item of list.items) { + const { line, lineNumber } = item; + const actualIndent = indentFor(item); + let match = null; + if (list.unordered) { + addErrorDetailIf( + onError, + lineNumber, + expectedIndent, + actualIndent, + null, + null, + rangeFromRegExp(line, listItemMarkerRe) + // No fixInfo; MD007 handles this scenario better + ); + } else if ((match = orderedListItemMarkerRe.exec(line))) { + actualEnd = match[0].length; + expectedEnd = expectedEnd || actualEnd; + const markerLength = match[1].length + 1; + if ((expectedIndent !== actualIndent) || endMatching) { + if (expectedEnd === actualEnd) { + endMatching = true; + } else { + const detail = endMatching ? + `Expected: (${expectedEnd}); Actual: (${actualEnd})` : + `Expected: ${expectedIndent}; Actual: ${actualIndent}`; + const expected = endMatching ? + expectedEnd - markerLength : + expectedIndent; + const actual = endMatching ? + actualEnd - markerLength : + actualIndent; + addError( + onError, + lineNumber, + detail, + null, + rangeFromRegExp(line, listItemMarkerRe), + { + "editColumn": Math.min(actual, expected) + 1, + "deleteCount": Math.max(actual - expected, 0), + "insertText": "".padEnd(Math.max(expected - actual, 0)) + } + ); + } + } + } + } + } } }; -appendToArray.sliceSize = sliceSize; -module.exports = appendToArray; - /***/ }), -/***/ 9247: +/***/ 725: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; - // @ts-check -// @ts-ignore -// eslint-disable-next-line camelcase, max-len, no-inline-comments, no-undef -const dynamicRequire = (typeof require === "undefined") ? require : /* c8 ignore next */ eval("require"); -// Capture native require implementation for dynamic loading of modules +const { addErrorDetailIf, listItemMarkerRe, rangeFromRegExp } = + __nccwpck_require__(2935); +const { flattenedLists } = __nccwpck_require__(2260); -// Requires -const path = __nccwpck_require__(1017); -const markdownlintLibrary = __nccwpck_require__(3611); -const { markdownlint, "readConfig": markdownlintReadConfig } = - markdownlintLibrary.promises; -const markdownlintRuleHelpers = __nccwpck_require__(2870); -const appendToArray = __nccwpck_require__(7314); -const mergeOptions = __nccwpck_require__(8446); -const resolveAndRequire = __nccwpck_require__(5317); +module.exports = { + "names": [ "MD006", "ul-start-left" ], + "description": + "Consider starting bulleted lists at the beginning of the line", + "tags": [ "bullet", "ul", "indentation" ], + "function": function MD006(params, onError) { + for (const list of flattenedLists()) { + if (list.unordered && !list.nesting && (list.indent !== 0)) { + for (const item of list.items) { + const { lineNumber, line } = item; + addErrorDetailIf( + onError, + lineNumber, + 0, + list.indent, + null, + null, + rangeFromRegExp(line, listItemMarkerRe), + { + "deleteCount": line.length - line.trimStart().length + }); + } + } + } + } +}; -// Variables -const packageName = "markdownlint-cli2"; -const packageVersion = "0.4.0"; -const libraryName = "markdownlint"; -const libraryVersion = markdownlintLibrary.getVersion(); -const dotOnlySubstitute = "*.{md,markdown}"; -const utf8 = "utf8"; -// No-op function -const noop = () => null; +/***/ }), -// Gets a synchronous function to parse JSONC text -const getJsoncParse = async () => { - const { "default": stripJsonComments } = - // eslint-disable-next-line max-len - // eslint-disable-next-line no-inline-comments, node/no-unsupported-features/es-syntax - await Promise.resolve(/* import() eager */).then(__nccwpck_require__.bind(__nccwpck_require__, 6177)); - return (text) => JSON.parse(stripJsonComments(text)); -}; +/***/ 8121: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -// Synchronous function to parse YAML text -const yamlParse = (text) => (__nccwpck_require__(4603).parse)(text); +"use strict"; +// @ts-check -// Negate a glob -const negateGlob = (glob) => `!${glob}`; -// Return a posix path (even on Windows) -const posixPath = (p) => p.split(path.sep).join(path.posix.sep); -// Read a JSON(C) or YAML file and return the object -const readConfig = (fs, dir, name, otherwise) => { - const file = path.posix.join(dir, name); - return () => fs.promises.access(file). - then( - () => getJsoncParse().then( - (jsoncParse) => markdownlintReadConfig( - file, - [ jsoncParse, yamlParse ], - fs - ) - ), - otherwise - ); -}; +const { addErrorDetailIf, indentFor, listItemMarkerRe } = + __nccwpck_require__(2935); +const { flattenedLists } = __nccwpck_require__(2260); -// Require a module ID with the specified directory in the path -const requireResolve = (dir, id) => { - if (typeof id === "string") { - return resolveAndRequire(dynamicRequire, id, dir); +module.exports = { + "names": [ "MD007", "ul-indent" ], + "description": "Unordered list indentation", + "tags": [ "bullet", "ul", "indentation" ], + "function": function MD007(params, onError) { + const indent = Number(params.config.indent || 2); + const startIndented = !!params.config.start_indented; + const startIndent = Number(params.config.start_indent || indent); + for (const list of flattenedLists()) { + if (list.unordered && list.parentsUnordered) { + for (const item of list.items) { + const { lineNumber, line } = item; + const expectedIndent = + (startIndented ? startIndent : 0) + + (list.nesting * indent); + const actualIndent = indentFor(item); + let range = null; + let editColumn = 1; + const match = line.match(listItemMarkerRe); + if (match) { + range = [ 1, match[0].length ]; + editColumn += match[1].length - actualIndent; + } + addErrorDetailIf( + onError, + lineNumber, + expectedIndent, + actualIndent, + null, + null, + range, + { + editColumn, + "deleteCount": actualIndent, + "insertText": "".padEnd(expectedIndent) + }); + } + } + } } - return id; }; -// Require an array of modules by ID -const requireIds = (dir, ids, noRequire) => ( - noRequire ? [] : ids.map((id) => requireResolve(dir, id)) -); -// Require an array of modules by ID (preserving parameters) -const requireIdsAndParams = (dir, idsAndParams, noRequire) => { - if (noRequire) { - return []; - } - const ids = idsAndParams.map((entry) => entry[0]); - const modules = requireIds(dir, ids); - const modulesAndParams = idsAndParams. - map((entry, i) => [ modules[i], ...entry.slice(1) ]); - return modulesAndParams; -}; +/***/ }), -// Require a JS file and return the exported object -const requireConfig = (fs, dir, name, noRequire) => ( - () => (noRequire - // eslint-disable-next-line prefer-promise-reject-errors - ? Promise.reject() - : fs.promises.access(path.posix.join(dir, name)) - ). - then( - () => requireResolve(dir, `./${name}`), - noop - ) -); +/***/ 7315: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -// Read an options or config file in any format and return the object -const readOptionsOrConfig = async (configPath, fs, noRequire) => { - const basename = path.basename(configPath); - const dirname = path.dirname(configPath); - let options = null; - let config = null; - if (basename.endsWith(".markdownlint-cli2.jsonc")) { - const jsoncParse = await getJsoncParse(); - options = jsoncParse(await fs.promises.readFile(configPath, utf8)); - } else if (basename.endsWith(".markdownlint-cli2.yaml")) { - options = yamlParse(await fs.promises.readFile(configPath, utf8)); - } else if (basename.endsWith(".markdownlint-cli2.cjs")) { - options = await (requireConfig(fs, dirname, basename, noRequire)()); - } else if ( - basename.endsWith(".markdownlint.jsonc") || - basename.endsWith(".markdownlint.json") || - basename.endsWith(".markdownlint.yaml") || - basename.endsWith(".markdownlint.yml") - ) { - const jsoncParse = await getJsoncParse(); - config = - await markdownlintReadConfig(configPath, [ jsoncParse, yamlParse ], fs); - } else if (basename.endsWith(".markdownlint.cjs")) { - config = await (requireConfig(fs, dirname, basename, noRequire)()); - } - return options || { config }; -}; +"use strict"; +// @ts-check -// Filter a list of files to ignore by glob -const removeIgnoredFiles = (dir, files, ignores) => { - const micromatch = __nccwpck_require__(6228); - return micromatch( - files.map((file) => path.posix.relative(dir, file)), - ignores - ).map((file) => path.posix.join(dir, file)); -}; -// Process/normalize command-line arguments and return glob patterns -const processArgv = (argv) => { - const globPatterns = (argv || []).map( - (glob) => { - if (glob.startsWith(":")) { - return glob; - } - // Escape RegExp special characters recognized by fast-glob - // https://github.com/mrmlnc/fast-glob#advanced-syntax - const specialCharacters = /\\(?![$()*+?[\]^])/gu; - if (glob.startsWith("\\:")) { - return `\\:${glob.slice(2).replace(specialCharacters, "/")}`; + +const { addError, filterTokens, forEachLine, includesSorted, + numericSortAscending } = __nccwpck_require__(2935); +const { lineMetadata } = __nccwpck_require__(2260); + +module.exports = { + "names": [ "MD009", "no-trailing-spaces" ], + "description": "Trailing spaces", + "tags": [ "whitespace" ], + "function": function MD009(params, onError) { + let brSpaces = params.config.br_spaces; + brSpaces = Number((brSpaces === undefined) ? 2 : brSpaces); + const listItemEmptyLines = !!params.config.list_item_empty_lines; + const strict = !!params.config.strict; + const listItemLineNumbers = []; + if (listItemEmptyLines) { + filterTokens(params, "list_item_open", (token) => { + for (let i = token.map[0]; i < token.map[1]; i++) { + listItemLineNumbers.push(i + 1); + } + }); + listItemLineNumbers.sort(numericSortAscending); + } + const paragraphLineNumbers = []; + const codeInlineLineNumbers = []; + if (strict) { + filterTokens(params, "paragraph_open", (token) => { + for (let i = token.map[0]; i < token.map[1] - 1; i++) { + paragraphLineNumbers.push(i + 1); + } + }); + const addLineNumberRange = (start, end) => { + for (let i = start; i < end; i++) { + codeInlineLineNumbers.push(i); + } + }; + filterTokens(params, "inline", (token) => { + let start = 0; + for (const child of token.children) { + if (start > 0) { + addLineNumberRange(start, child.lineNumber); + start = 0; + } + if (child.type === "code_inline") { + start = child.lineNumber; + } + } + if (start > 0) { + addLineNumberRange(start, token.map[1]); + } + }); + } + const expected = (brSpaces < 2) ? 0 : brSpaces; + forEachLine(lineMetadata(), (line, lineIndex, inCode) => { + const lineNumber = lineIndex + 1; + const trailingSpaces = line.length - line.trimEnd().length; + if ( + trailingSpaces && + !inCode && + !includesSorted(listItemLineNumbers, lineNumber) && + ( + (expected !== trailingSpaces) || + (strict && + (!includesSorted(paragraphLineNumbers, lineNumber) || + includesSorted(codeInlineLineNumbers, lineNumber))) + ) + ) { + const column = line.length - trailingSpaces + 1; + addError( + onError, + lineNumber, + "Expected: " + (expected === 0 ? "" : "0 or ") + + expected + "; Actual: " + trailingSpaces, + undefined, + [ column, trailingSpaces ], + { + "editColumn": column, + "deleteCount": trailingSpaces + }); } - return (glob.startsWith("#") ? `!${glob.slice(1)}` : glob). - replace(specialCharacters, "/"); - } - ); - if ((globPatterns.length === 1) && (globPatterns[0] === ".")) { - // Substitute a more reasonable pattern - globPatterns[0] = dotOnlySubstitute; + }); } - return globPatterns; }; -// Show help if missing arguments -const showHelp = (logMessage) => { - /* eslint-disable max-len */ - logMessage(`https://github.com/DavidAnson/markdownlint-cli2 - -Syntax: markdownlint-cli2 glob0 [glob1] [...] [globN] - markdownlint-cli2-fix glob0 [glob1] [...] [globN] - markdownlint-cli2-config config-file glob0 [glob1] [...] [globN] - -Glob expressions (from the globby library): -- * matches any number of characters, but not / -- ? matches a single character, but not / -- ** matches any number of characters, including / -- {} allows for a comma-separated list of "or" expressions -- ! or # at the beginning of a pattern negate the match -- : at the beginning identifies a literal file path -Dot-only glob: -- The command "markdownlint-cli2 ." would lint every file in the current directory tree which is probably not intended -- Instead, it is mapped to "markdownlint-cli2 ${dotOnlySubstitute}" which lints all Markdown files in the current directory -- To lint every file in the current directory tree, the command "markdownlint-cli2 **" can be used instead +/***/ }), -Configuration via: -- .markdownlint-cli2.jsonc -- .markdownlint-cli2.yaml -- .markdownlint-cli2.cjs -- .markdownlint.jsonc or .markdownlint.json -- .markdownlint.yaml or .markdownlint.yml -- .markdownlint.cjs +/***/ 1016: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -Cross-platform compatibility: -- UNIX and Windows shells expand globs according to different rules; quoting arguments is recommended -- Some Windows shells don't handle single-quoted (') arguments well; double-quote (") is recommended -- Shells that expand globs do not support negated patterns (!node_modules); quoting is required here -- Some UNIX shells parse exclamation (!) in double-quotes; hashtag (#) is recommended in these cases -- The path separator is forward slash (/) on all platforms; backslash (\\) is automatically converted +"use strict"; +// @ts-check -The most compatible syntax for cross-platform support: -$ markdownlint-cli2 "**/*.md" "#node_modules"` - ); - /* eslint-enable max-len */ -}; -// Get (creating if necessary) and process a directory's info object -const getAndProcessDirInfo = -(fs, tasks, dirToDirInfo, dir, noRequire, func) => { - let dirInfo = dirToDirInfo[dir]; - if (!dirInfo) { - dirInfo = { - dir, - "parent": null, - "files": [], - "markdownlintConfig": null, - "markdownlintOptions": null - }; - dirToDirInfo[dir] = dirInfo; - // Load markdownlint-cli2 object(s) - const markdownlintCli2Jsonc = - path.posix.join(dir, ".markdownlint-cli2.jsonc"); - const markdownlintCli2Yaml = - path.posix.join(dir, ".markdownlint-cli2.yaml"); - tasks.push( - fs.promises.access(markdownlintCli2Jsonc). - then( - () => fs.promises. - readFile(markdownlintCli2Jsonc, utf8). - then( - (content) => getJsoncParse(). - then((jsoncParse) => jsoncParse(content)) - ), - () => fs.promises.access(markdownlintCli2Yaml). - then( - () => fs.promises. - readFile(markdownlintCli2Yaml, utf8). - then(yamlParse), - requireConfig( - fs, - dir, - ".markdownlint-cli2.cjs", - noRequire - ) - ) - ). - then((options) => { - dirInfo.markdownlintOptions = options; - }) - ); +const { addError, filterTokens, forEachLine, withinAnyRange } = + __nccwpck_require__(2935); +const { codeBlockAndSpanRanges, lineMetadata } = __nccwpck_require__(2260); - // Load markdownlint object(s) - const readConfigs = - readConfig( - fs, - dir, - ".markdownlint.jsonc", - readConfig( - fs, - dir, - ".markdownlint.json", - readConfig( - fs, - dir, - ".markdownlint.yaml", - readConfig( - fs, - dir, - ".markdownlint.yml", - requireConfig( - fs, - dir, - ".markdownlint.cjs", - noRequire - ) - ) - ) - ) - ); - tasks.push( - readConfigs(). - then((config) => { - dirInfo.markdownlintConfig = config; - }) - ); - } - if (func) { - func(dirInfo); - } - return dirInfo; -}; +const tabRe = /\t+/g; -// Get base markdownlint-cli2 options object -const getBaseOptions = async ( - fs, - baseDir, - globPatterns, - optionsDefault, - fixDefault, - noGlobs, - noRequire -) => { - const tasks = []; - const dirToDirInfo = {}; - getAndProcessDirInfo(fs, tasks, dirToDirInfo, baseDir, noRequire); - await Promise.all(tasks); - // eslint-disable-next-line no-multi-assign - const baseMarkdownlintOptions = dirToDirInfo[baseDir].markdownlintOptions = - mergeOptions( - mergeOptions(optionsDefault, { "fix": fixDefault }), - dirToDirInfo[baseDir].markdownlintOptions +module.exports = { + "names": [ "MD010", "no-hard-tabs" ], + "description": "Hard tabs", + "tags": [ "whitespace", "hard_tab" ], + "function": function MD010(params, onError) { + const codeBlocks = params.config.code_blocks; + const includeCode = (codeBlocks === undefined) ? true : !!codeBlocks; + const ignoreCodeLanguages = new Set( + (params.config.ignore_code_languages || []) + .map((language) => language.toLowerCase()) ); - - if (!noGlobs) { - // Append any globs specified in markdownlint-cli2 configuration - const globs = baseMarkdownlintOptions.globs || []; - appendToArray(globPatterns, globs); - } - - // Pass base ignore globs as globby patterns (best performance) - const ignorePatterns = - // eslint-disable-next-line unicorn/no-array-callback-reference - (baseMarkdownlintOptions.ignores || []).map(negateGlob); - appendToArray(globPatterns, ignorePatterns); - - return { - baseMarkdownlintOptions, - dirToDirInfo - }; -}; - -// Enumerate files from globs and build directory infos -const enumerateFiles = -// eslint-disable-next-line max-len -async (fs, baseDirSystem, baseDir, globPatterns, dirToDirInfo, noErrors, noRequire) => { - const tasks = []; - const globbyOptions = { - "absolute": true, - "cwd": baseDir, - "expandDirectories": false, - fs - }; - if (noErrors) { - globbyOptions.suppressErrors = true; - } - // Special-case literal files - const literalFiles = []; - const filteredGlobPatterns = globPatterns.filter( - (globPattern) => { - if (globPattern.startsWith(":")) { - literalFiles.push( - posixPath(path.resolve(baseDirSystem, globPattern.slice(1))) - ); - return false; + const spacesPerTab = params.config.spaces_per_tab; + const spaceMultiplier = (spacesPerTab === undefined) ? + 1 : + Math.max(0, Number(spacesPerTab)); + const exclusions = includeCode ? [] : codeBlockAndSpanRanges(); + filterTokens(params, "fence", (token) => { + const language = token.info.trim().toLowerCase(); + if (ignoreCodeLanguages.has(language)) { + for (let i = token.map[0] + 1; i < token.map[1] - 1; i++) { + exclusions.push([ i, 0, params.lines[i].length ]); + } } - return true; - } - ).map((globPattern) => globPattern.replace(/^\\:/u, ":")); - const baseMarkdownlintOptions = dirToDirInfo[baseDir].markdownlintOptions; - const globsForIgnore = - (baseMarkdownlintOptions.globs || []). - filter((glob) => glob.startsWith("!")); - const filteredLiteralFiles = - ((literalFiles.length > 0) && (globsForIgnore.length > 0)) - ? removeIgnoredFiles(baseDir, literalFiles, globsForIgnore) - : literalFiles; - // Manually expand directories to avoid globby call to dir-glob.sync - const expandedDirectories = await Promise.all( - filteredGlobPatterns.map((globPattern) => { - const barePattern = - globPattern.startsWith("!") - ? globPattern.slice(1) - : globPattern; - const globPath = - (path.posix.isAbsolute(barePattern) || path.isAbsolute(barePattern)) - ? barePattern - : path.posix.join(baseDir, barePattern); - return fs.promises.stat(globPath). - then((stats) => (stats.isDirectory() - ? path.posix.join(globPattern, "**") - : globPattern)). - catch(() => globPattern); - }) - ); - // Process glob patterns - // eslint-disable-next-line max-len - // eslint-disable-next-line no-inline-comments, node/no-unsupported-features/es-syntax - const { globby } = await Promise.resolve(/* import() eager */).then(__nccwpck_require__.bind(__nccwpck_require__, 236)); - const files = [ - ...await globby(expandedDirectories, globbyOptions), - ...filteredLiteralFiles - ]; - for (const file of files) { - const dir = path.posix.dirname(file); - getAndProcessDirInfo( - fs, - tasks, - dirToDirInfo, - dir, - noRequire, - (dirInfo) => { - dirInfo.files.push(file); + }); + forEachLine(lineMetadata(), (line, lineIndex, inCode) => { + if (includeCode || !inCode) { + let match = null; + while ((match = tabRe.exec(line)) !== null) { + const { index } = match; + const column = index + 1; + const length = match[0].length; + if (!withinAnyRange(exclusions, lineIndex, index, length)) { + addError( + onError, + lineIndex + 1, + "Column: " + column, + null, + [ column, length ], + { + "editColumn": column, + "deleteCount": length, + "insertText": "".padEnd(length * spaceMultiplier) + } + ); + } + } } - ); + }); } - await Promise.all(tasks); }; -// Enumerate (possibly missing) parent directories and update directory infos -const enumerateParents = async (fs, baseDir, dirToDirInfo, noRequire) => { - const tasks = []; - // Create a lookup of baseDir and parents - const baseDirParents = {}; - let baseDirParent = baseDir; - do { - baseDirParents[baseDirParent] = true; - baseDirParent = path.posix.dirname(baseDirParent); - } while (!baseDirParents[baseDirParent]); +/***/ }), - // Visit parents of each dirInfo - for (let lastDirInfo of Object.values(dirToDirInfo)) { - let { dir } = lastDirInfo; - let lastDir = dir; - while ( - !baseDirParents[dir] && - (dir = path.posix.dirname(dir)) && - (dir !== lastDir) - ) { - lastDir = dir; - lastDirInfo = - getAndProcessDirInfo( - fs, - tasks, - dirToDirInfo, - dir, - noRequire, - // eslint-disable-next-line no-loop-func - (dirInfo) => { - lastDirInfo.parent = dirInfo; - } - ); - } +/***/ 3753: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // If dir not under baseDir, inject it as parent for configuration - if (dir !== baseDir) { - dirToDirInfo[dir].parent = dirToDirInfo[baseDir]; - } - } - await Promise.all(tasks); -}; +"use strict"; +// @ts-check -// Create directory info objects by enumerating file globs -const createDirInfos = -// eslint-disable-next-line max-len -async (fs, baseDirSystem, baseDir, globPatterns, dirToDirInfo, optionsOverride, noErrors, noRequire) => { - await enumerateFiles( - fs, - baseDirSystem, - baseDir, - globPatterns, - dirToDirInfo, - noErrors, - noRequire - ); - await enumerateParents( - fs, - baseDir, - dirToDirInfo, - noRequire - ); - // Merge file lists with identical configuration - const dirs = Object.keys(dirToDirInfo); - dirs.sort((a, b) => b.length - a.length); - const dirInfos = []; - const noConfigDirInfo = - (dirInfo) => ( - dirInfo.parent && - !dirInfo.markdownlintConfig && - !dirInfo.markdownlintOptions - ); - for (const dir of dirs) { - const dirInfo = dirToDirInfo[dir]; - if (noConfigDirInfo(dirInfo)) { - if (dirInfo.parent) { - appendToArray(dirInfo.parent.files, dirInfo.files); - } - dirToDirInfo[dir] = null; - } else { - const { markdownlintOptions } = dirInfo; - if (markdownlintOptions && markdownlintOptions.customRules) { - const customRules = - requireIds( - dir, - markdownlintOptions.customRules, - noRequire - ); - // Expand nested arrays (for packages that export multiple rules) - markdownlintOptions.customRules = customRules.flat(); - } - if (markdownlintOptions && markdownlintOptions.markdownItPlugins) { - markdownlintOptions.markdownItPlugins = - requireIdsAndParams( - dir, - markdownlintOptions.markdownItPlugins, - noRequire - ); - } - dirInfos.push(dirInfo); - } - } - for (const dirInfo of dirInfos) { - while (dirInfo.parent && !dirToDirInfo[dirInfo.parent.dir]) { - dirInfo.parent = dirInfo.parent.parent; - } - } - // Verify dirInfos is simplified - // if ( - // dirInfos.filter( - // (di) => di.parent && !dirInfos.includes(di.parent) - // ).length > 0 - // ) { - // throw new Error("Extra parent"); - // } - // if ( - // dirInfos.filter( - // (di) => !di.parent && (di.dir !== baseDir) - // ).length > 0 - // ) { - // throw new Error("Missing parent"); - // } - // if ( - // dirInfos.filter( - // (di) => di.parent && - // !((di.markdownlintConfig ? 1 : 0) ^ (di.markdownlintOptions ? 1 : 0)) - // ).length > 0 - // ) { - // throw new Error("Missing object"); - // } - // if (dirInfos.filter((di) => di.dir === "/").length > 0) { - // throw new Error("Includes root"); - // } +const { addError, forEachLine, withinAnyRange } = __nccwpck_require__(2935); +const { codeBlockAndSpanRanges, lineMetadata } = __nccwpck_require__(2260); - // Merge configuration by inheritance - for (const dirInfo of dirInfos) { - let markdownlintOptions = dirInfo.markdownlintOptions || {}; - let { markdownlintConfig } = dirInfo; - let parent = dirInfo; - // eslint-disable-next-line prefer-destructuring - while ((parent = parent.parent)) { - if (parent.markdownlintOptions) { - markdownlintOptions = mergeOptions( - parent.markdownlintOptions, - markdownlintOptions - ); - } - if ( - !markdownlintConfig && - parent.markdownlintConfig && - !markdownlintOptions.config - ) { - // eslint-disable-next-line prefer-destructuring - markdownlintConfig = parent.markdownlintConfig; - } - } - dirInfo.markdownlintOptions = mergeOptions( - markdownlintOptions, - optionsOverride - ); - dirInfo.markdownlintConfig = markdownlintConfig; - } - return dirInfos; -}; +const reversedLinkRe = + /(^|[^\\])\(([^)]+)\)\[([^\]^][^\]]*)](?!\()/g; -// Lint files in groups by shared configuration -const lintFiles = (fs, dirInfos, fileContents) => { - const tasks = []; - // For each dirInfo - for (const dirInfo of dirInfos) { - const { dir, files, markdownlintConfig, markdownlintOptions } = dirInfo; - // Filter file/string inputs to only those in the dirInfo - let filesAfterIgnores = files; - if ( - markdownlintOptions.ignores && - (markdownlintOptions.ignores.length > 0) - ) { - // eslint-disable-next-line unicorn/no-array-callback-reference - const ignores = markdownlintOptions.ignores.map(negateGlob); - filesAfterIgnores = removeIgnoredFiles(dir, files, ignores); - } - const filteredFiles = filesAfterIgnores.filter( - (file) => fileContents[file] === undefined - ); - const filteredStrings = {}; - for (const file of filesAfterIgnores) { - if (fileContents[file] !== undefined) { - filteredStrings[file] = fileContents[file]; - } - } - // Create markdownlint options object - const options = { - "files": filteredFiles, - "strings": filteredStrings, - "config": markdownlintConfig || markdownlintOptions.config, - "customRules": markdownlintOptions.customRules, - "frontMatter": markdownlintOptions.frontMatter - ? new RegExp(markdownlintOptions.frontMatter, "u") - : undefined, - "handleRuleFailures": true, - "markdownItPlugins": markdownlintOptions.markdownItPlugins, - "noInlineConfig": Boolean(markdownlintOptions.noInlineConfig), - "resultVersion": 3, - fs - }; - // Invoke markdownlint - // @ts-ignore - let task = markdownlint(options); - // For any fixable errors, read file, apply fixes, and write it back - if (markdownlintOptions.fix) { - task = task.then((results) => { - options.files = []; - const subTasks = []; - const errorFiles = Object.keys(results); - for (const fileName of errorFiles) { - const errorInfos = results[fileName]. - filter((errorInfo) => errorInfo.fixInfo); - if (errorInfos.length > 0) { - delete results[fileName]; - options.files.push(fileName); - subTasks.push(fs.promises.readFile(fileName, utf8). - then((original) => { - const fixed = markdownlintRuleHelpers. - applyFixes(original, errorInfos); - return fs.promises.writeFile(fileName, fixed, utf8); - }) +module.exports = { + "names": [ "MD011", "no-reversed-links" ], + "description": "Reversed link syntax", + "tags": [ "links" ], + "function": function MD011(params, onError) { + const exclusions = codeBlockAndSpanRanges(); + forEachLine(lineMetadata(), (line, lineIndex, inCode, onFence) => { + if (!inCode && !onFence) { + let match = null; + while ((match = reversedLinkRe.exec(line)) !== null) { + const [ reversedLink, preChar, linkText, linkDestination ] = match; + const index = match.index + preChar.length; + const length = match[0].length - preChar.length; + if ( + !linkText.endsWith("\\") && + !linkDestination.endsWith("\\") && + !withinAnyRange(exclusions, lineIndex, index, length) + ) { + addError( + onError, + lineIndex + 1, + reversedLink.slice(preChar.length), + null, + [ index + 1, length ], + { + "editColumn": index + 1, + "deleteCount": length, + "insertText": `[${linkText}](${linkDestination})` + } ); } } - return Promise.all(subTasks). - // @ts-ignore - then(() => markdownlint(options)). - then((fixResults) => ({ - ...results, - ...fixResults - })); - }); - } - // Queue tasks for this dirInfo - tasks.push(task); + } + }); } - // Return result of all tasks - return Promise.all(tasks); }; -// Create summary of results -const createSummary = (baseDir, taskResults) => { - const summary = []; - let counter = 0; - for (const results of taskResults) { - for (const fileName in results) { - const errorInfos = results[fileName]; - for (const errorInfo of errorInfos) { - const fileNameRelative = path.posix.relative(baseDir, fileName); - summary.push({ - "fileName": fileNameRelative, - ...errorInfo, - counter - }); - counter++; + +/***/ }), + +/***/ 6454: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; +// @ts-check + + + +const { addErrorDetailIf, forEachLine } = __nccwpck_require__(2935); +const { lineMetadata } = __nccwpck_require__(2260); + +module.exports = { + "names": [ "MD012", "no-multiple-blanks" ], + "description": "Multiple consecutive blank lines", + "tags": [ "whitespace", "blank_lines" ], + "function": function MD012(params, onError) { + const maximum = Number(params.config.maximum || 1); + let count = 0; + forEachLine(lineMetadata(), (line, lineIndex, inCode) => { + count = (inCode || (line.trim().length > 0)) ? 0 : count + 1; + if (maximum < count) { + addErrorDetailIf( + onError, + lineIndex + 1, + maximum, + count, + null, + null, + null, + { + "deleteCount": -1 + }); } - } - } - summary.sort((a, b) => ( - a.fileName.localeCompare(b.fileName) || - (a.lineNumber - b.lineNumber) || - a.ruleNames[0].localeCompare(b.ruleNames[0]) || - (a.counter - b.counter) - )); - for (const result of summary) { - delete result.counter; + }); } - return summary; }; -// Output summary via formatters -const outputSummary = - async (baseDir, summary, outputFormatters, logMessage, logError) => { - const errorsPresent = (summary.length > 0); - if (errorsPresent || outputFormatters) { - const formatterOptions = { - "directory": baseDir, - "results": summary, - logMessage, - logError - }; - const formattersAndParams = outputFormatters - ? requireIdsAndParams(baseDir, outputFormatters) - : [ [ __nccwpck_require__(8552) ] ]; - await Promise.all(formattersAndParams.map((formatterAndParams) => { - const [ formatter, ...formatterParams ] = formatterAndParams; - return formatter(formatterOptions, ...formatterParams); - })); - } - return errorsPresent; - }; -// Main function -const main = async (params) => { - // Capture parameters - const { - directory, - argv, - optionsDefault, - optionsOverride, - fixDefault, - fileContents, - nonFileContents, - noErrors, - noGlobs, - noRequire, - name - } = params; - const logMessage = params.logMessage || noop; - const logError = params.logError || noop; - const fs = params.fs || __nccwpck_require__(7147); - const baseDirSystem = - (directory && path.resolve(directory)) || - process.cwd(); - const baseDir = posixPath(baseDirSystem); - // Output banner - logMessage( - // eslint-disable-next-line max-len - `${name || packageName} v${packageVersion} (${libraryName} v${libraryVersion})` - ); - // Read argv configuration file (if relevant and present) - let optionsArgv = null; - const [ configPath ] = (argv || []); - if ((name === "markdownlint-cli2-config") && configPath) { - optionsArgv = - await readOptionsOrConfig(configPath, fs, noRequire); - } - // Process arguments and get base options - const globPatterns = processArgv(optionsArgv ? argv.slice(1) : argv); - const { baseMarkdownlintOptions, dirToDirInfo } = - await getBaseOptions( - fs, - baseDir, - globPatterns, - optionsArgv || optionsDefault, - fixDefault, - noGlobs, - noRequire - ); - if ((globPatterns.length === 0) && !nonFileContents) { - showHelp(logMessage); - return 1; - } - // Include any file overrides or non-file content - const resolvedFileContents = {}; - for (const file in fileContents) { - const resolvedFile = posixPath(path.resolve(baseDirSystem, file)); - resolvedFileContents[resolvedFile] = - fileContents[file]; - } - for (const nonFile in nonFileContents) { - resolvedFileContents[nonFile] = nonFileContents[nonFile]; - } - appendToArray( - dirToDirInfo[baseDir].files, - Object.keys(nonFileContents || {}) - ); - // Output finding status - const showProgress = !baseMarkdownlintOptions.noProgress; - if (showProgress) { - logMessage(`Finding: ${globPatterns.join(" ")}`); - } - // Create linting tasks - const dirInfos = - await createDirInfos( - fs, - baseDirSystem, - baseDir, - globPatterns, - dirToDirInfo, - optionsOverride, - noErrors, - noRequire - ); - // Output linting status - if (showProgress) { - let fileCount = 0; - for (const dirInfo of dirInfos) { - fileCount += dirInfo.files.length; +/***/ }), + +/***/ 1518: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; +// @ts-check + + + +const { addErrorDetailIf, filterTokens, forEachHeading, forEachLine, + includesSorted, linkReferenceDefinitionRe } = __nccwpck_require__(2935); +const { lineMetadata } = __nccwpck_require__(2260); + +const longLineRePrefix = "^.{"; +const longLineRePostfixRelaxed = "}.*\\s.*$"; +const longLineRePostfixStrict = "}.+$"; +const linkOrImageOnlyLineRe = /^[es]*(lT?L|I)[ES]*$/; +const sternModeRe = /^([#>\s]*\s)?\S*$/; +const tokenTypeMap = { + "em_open": "e", + "em_close": "E", + "image": "I", + "link_open": "l", + "link_close": "L", + "strong_open": "s", + "strong_close": "S", + "text": "T" +}; + +module.exports = { + "names": [ "MD013", "line-length" ], + "description": "Line length", + "tags": [ "line_length" ], + "function": function MD013(params, onError) { + const lineLength = Number(params.config.line_length || 80); + const headingLineLength = + Number(params.config.heading_line_length || lineLength); + const codeLineLength = + Number(params.config.code_block_line_length || lineLength); + const strict = !!params.config.strict; + const stern = !!params.config.stern; + const longLineRePostfix = + (strict || stern) ? longLineRePostfixStrict : longLineRePostfixRelaxed; + const longLineRe = + new RegExp(longLineRePrefix + lineLength + longLineRePostfix); + const longHeadingLineRe = + new RegExp(longLineRePrefix + headingLineLength + longLineRePostfix); + const longCodeLineRe = + new RegExp(longLineRePrefix + codeLineLength + longLineRePostfix); + const codeBlocks = params.config.code_blocks; + const includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks; + const tables = params.config.tables; + const includeTables = (tables === undefined) ? true : !!tables; + let headings = params.config.headings; + if (headings === undefined) { + headings = params.config.headers; } - logMessage(`Linting: ${fileCount} file(s)`); - } - // Lint files - const lintResults = await lintFiles(fs, dirInfos, resolvedFileContents); - // Output summary - const summary = createSummary(baseDir, lintResults); - if (showProgress) { - logMessage(`Summary: ${summary.length} error(s)`); + const includeHeadings = (headings === undefined) ? true : !!headings; + const headingLineNumbers = []; + forEachHeading(params, (heading) => { + headingLineNumbers.push(heading.lineNumber); + }); + const linkOnlyLineNumbers = []; + filterTokens(params, "inline", (token) => { + let childTokenTypes = ""; + for (const child of token.children) { + if (child.type !== "text" || child.content !== "") { + childTokenTypes += tokenTypeMap[child.type] || "x"; + } + } + if (linkOrImageOnlyLineRe.test(childTokenTypes)) { + linkOnlyLineNumbers.push(token.lineNumber); + } + }); + forEachLine(lineMetadata(), (line, lineIndex, inCode, onFence, inTable) => { + const lineNumber = lineIndex + 1; + const isHeading = includesSorted(headingLineNumbers, lineNumber); + const length = inCode ? + codeLineLength : + (isHeading ? headingLineLength : lineLength); + const lengthRe = inCode ? + longCodeLineRe : + (isHeading ? longHeadingLineRe : longLineRe); + if ((includeCodeBlocks || !inCode) && + (includeTables || !inTable) && + (includeHeadings || !isHeading) && + (strict || + (!(stern && sternModeRe.test(line)) && + !includesSorted(linkOnlyLineNumbers, lineNumber) && + !linkReferenceDefinitionRe.test(line))) && + lengthRe.test(line)) { + addErrorDetailIf( + onError, + lineNumber, + length, + line.length, + null, + null, + [ length + 1, line.length - length ]); + } + }); } - const outputFormatters = - (optionsOverride && optionsOverride.outputFormatters) || - baseMarkdownlintOptions.outputFormatters; - const errorsPresent = await outputSummary( - baseDir, summary, outputFormatters, logMessage, logError - ); - // Return result - return errorsPresent ? 1 : 0; }; -// Run function -const run = (overrides) => { - (async () => { - try { - const defaultParams = { - "argv": process.argv.slice(2), - "logMessage": console.log, - "logError": console.error - }; - const params = { - ...defaultParams, - ...overrides - }; - process.exitCode = await main(params); - } catch (error) { - console.error(error); - process.exitCode = 2; + +/***/ }), + +/***/ 3463: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; +// @ts-check + + + +const { addErrorContext, filterTokens } = __nccwpck_require__(2935); + +const dollarCommandRe = /^(\s*)(\$\s+)/; + +module.exports = { + "names": [ "MD014", "commands-show-output" ], + "description": "Dollar signs used before commands without showing output", + "tags": [ "code" ], + "function": function MD014(params, onError) { + for (const type of [ "code_block", "fence" ]) { + filterTokens(params, type, (token) => { + const margin = (token.type === "fence") ? 1 : 0; + const dollarInstances = []; + let allDollars = true; + for (let i = token.map[0] + margin; i < token.map[1] - margin; i++) { + const line = params.lines[i]; + const lineTrim = line.trim(); + if (lineTrim) { + const match = dollarCommandRe.exec(line); + if (match) { + const column = match[1].length + 1; + const length = match[2].length; + dollarInstances.push([ i, lineTrim, column, length ]); + } else { + allDollars = false; + } + } + } + if (allDollars) { + for (const instance of dollarInstances) { + const [ i, lineTrim, column, length ] = instance; + addErrorContext( + onError, + i + 1, + lineTrim, + null, + null, + [ column, length ], + { + "editColumn": column, + "deleteCount": length + } + ); + } + } + }); } - })(); + } }; -// Export functions + +/***/ }), + +/***/ 5496: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; +// @ts-check + + + +const { addErrorContext, forEachLine } = __nccwpck_require__(2935); +const { lineMetadata } = __nccwpck_require__(2260); + module.exports = { - main, - run + "names": [ "MD018", "no-missing-space-atx" ], + "description": "No space after hash on atx style heading", + "tags": [ "headings", "headers", "atx", "spaces" ], + "function": function MD018(params, onError) { + forEachLine(lineMetadata(), (line, lineIndex, inCode) => { + if (!inCode && + /^#+[^# \t]/.test(line) && + !/#\s*$/.test(line) && + !line.startsWith("#️⃣")) { + const hashCount = /^#+/.exec(line)[0].length; + addErrorContext( + onError, + lineIndex + 1, + line.trim(), + null, + null, + [ 1, hashCount + 1 ], + { + "editColumn": hashCount + 1, + "insertText": " " + } + ); + } + }); + } }; -// Run if invoked as a CLI -// @ts-ignore -if (false) {} + +/***/ }), + +/***/ 6478: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; +// @ts-check + + + +const { addErrorContext, filterTokens, headingStyleFor } = + __nccwpck_require__(2935); + +module.exports = { + "names": [ "MD019", "no-multiple-space-atx" ], + "description": "Multiple spaces after hash on atx style heading", + "tags": [ "headings", "headers", "atx", "spaces" ], + "function": function MD019(params, onError) { + filterTokens(params, "heading_open", (token) => { + if (headingStyleFor(token) === "atx") { + const { line, lineNumber } = token; + const match = /^(#+)([ \t]{2,})(?:\S)/.exec(line); + if (match) { + const [ + , + { "length": hashLength }, + { "length": spacesLength } + ] = match; + addErrorContext( + onError, + lineNumber, + line.trim(), + null, + null, + [ 1, hashLength + spacesLength + 1 ], + { + "editColumn": hashLength + 1, + "deleteCount": spacesLength - 1 + } + ); + } + } + }); + } +}; /***/ }), -/***/ 8446: -/***/ ((module) => { +/***/ 9915: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; // @ts-check -/** - * Merges two options objects by combining config and replacing properties. - * @param {Object} first First options object. - * @param {Object} second Second options object. - * @returns {Object} Merged options object. - */ -const mergeOptions = (first, second) => { - const merged = { - ...first, - ...second - }; - const firstConfig = first && first.config; - const secondConfig = second && second.config; - if (firstConfig || secondConfig) { - merged.config = { - ...firstConfig, - ...secondConfig - }; +const { addErrorContext, forEachLine } = __nccwpck_require__(2935); +const { lineMetadata } = __nccwpck_require__(2260); + +module.exports = { + "names": [ "MD020", "no-missing-space-closed-atx" ], + "description": "No space inside hashes on closed atx style heading", + "tags": [ "headings", "headers", "atx_closed", "spaces" ], + "function": function MD020(params, onError) { + forEachLine(lineMetadata(), (line, lineIndex, inCode) => { + if (!inCode) { + const match = + /^(#+)([ \t]*)([^#]*?[^#\\])([ \t]*)((?:\\#)?)(#+)(\s*)$/.exec(line); + if (match) { + const [ + , + leftHash, + { "length": leftSpaceLength }, + content, + { "length": rightSpaceLength }, + rightEscape, + rightHash, + { "length": trailSpaceLength } + ] = match; + const leftHashLength = leftHash.length; + const rightHashLength = rightHash.length; + const left = !leftSpaceLength; + const right = !rightSpaceLength || rightEscape; + const rightEscapeReplacement = rightEscape ? `${rightEscape} ` : ""; + if (left || right) { + const range = left ? + [ + 1, + leftHashLength + 1 + ] : + [ + line.length - trailSpaceLength - rightHashLength, + rightHashLength + 1 + ]; + addErrorContext( + onError, + lineIndex + 1, + line.trim(), + left, + right, + range, + { + "editColumn": 1, + "deleteCount": line.length, + "insertText": + `${leftHash} ${content} ${rightEscapeReplacement}${rightHash}` + } + ); + } + } + } + }); } - return merged; }; -module.exports = mergeOptions; - /***/ }), -/***/ 5317: -/***/ ((module) => { +/***/ 4898: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; // @ts-check -/** - * Wrapper for calling Node's require.resolve/require with an additional path. - * @param {Object} req Node's require implementation (or equivalent). - * @param {String} id Package identifier to require. - * @param {String} dir Directory to include when resolving paths. - * @returns {Object} Exported module content. - */ -const resolveAndRequire = (req, id, dir) => { - const resolvePaths = req.resolve.paths ? req.resolve.paths("") : []; - const paths = [ dir, ...resolvePaths ]; - const resolved = req.resolve(id, { paths }); - return req(resolved); -}; - -module.exports = resolveAndRequire; - - -/***/ }), - -/***/ 525: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - +const { addErrorContext, filterTokens, headingStyleFor } = + __nccwpck_require__(2935); -var PlainValue = __nccwpck_require__(4941); -var resolveSeq = __nccwpck_require__(2387); -var Schema = __nccwpck_require__(1387); +const closedAtxRe = /^(#+)([ \t]+)([^ \t]|[^ \t].*[^ \t])([ \t]+)(#+)(\s*)$/; -const defaultOptions = { - anchorPrefix: 'a', - customTags: null, - indent: 2, - indentSeq: true, - keepCstNodes: false, - keepNodeTypes: true, - keepBlobsInJSON: true, - mapAsMap: false, - maxAliasCount: 100, - prettyErrors: false, - // TODO Set true in v2 - simpleKeys: false, - version: '1.2' +module.exports = { + "names": [ "MD021", "no-multiple-space-closed-atx" ], + "description": "Multiple spaces inside hashes on closed atx style heading", + "tags": [ "headings", "headers", "atx_closed", "spaces" ], + "function": function MD021(params, onError) { + filterTokens(params, "heading_open", (token) => { + if (headingStyleFor(token) === "atx_closed") { + const { line, lineNumber } = token; + const match = closedAtxRe.exec(line); + if (match) { + const [ + , + leftHash, + { "length": leftSpaceLength }, + content, + { "length": rightSpaceLength }, + rightHash, + { "length": trailSpaceLength } + ] = match; + const left = leftSpaceLength > 1; + const right = rightSpaceLength > 1; + if (left || right) { + const length = line.length; + const leftHashLength = leftHash.length; + const rightHashLength = rightHash.length; + const range = left ? + [ + 1, + leftHashLength + leftSpaceLength + 1 + ] : + [ + length - trailSpaceLength - rightHashLength - rightSpaceLength, + rightSpaceLength + rightHashLength + 1 + ]; + addErrorContext( + onError, + lineNumber, + line.trim(), + left, + right, + range, + { + "editColumn": 1, + "deleteCount": length, + "insertText": `${leftHash} ${content} ${rightHash}` + } + ); + } + } + } + }); + } }; -const scalarOptions = { - get binary() { - return resolveSeq.binaryOptions; - }, - - set binary(opt) { - Object.assign(resolveSeq.binaryOptions, opt); - }, - - get bool() { - return resolveSeq.boolOptions; - }, - set bool(opt) { - Object.assign(resolveSeq.boolOptions, opt); - }, - get int() { - return resolveSeq.intOptions; - }, +/***/ }), - set int(opt) { - Object.assign(resolveSeq.intOptions, opt); - }, +/***/ 5164: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - get null() { - return resolveSeq.nullOptions; - }, +"use strict"; +// @ts-check - set null(opt) { - Object.assign(resolveSeq.nullOptions, opt); - }, - get str() { - return resolveSeq.strOptions; - }, - set str(opt) { - Object.assign(resolveSeq.strOptions, opt); - } +const { addErrorDetailIf, filterTokens, isBlankLine } = __nccwpck_require__(2935); -}; -const documentOptions = { - '1.0': { - schema: 'yaml-1.1', - merge: true, - tagPrefixes: [{ - handle: '!', - prefix: PlainValue.defaultTagPrefix - }, { - handle: '!!', - prefix: 'tag:private.yaml.org,2002:' - }] - }, - 1.1: { - schema: 'yaml-1.1', - merge: true, - tagPrefixes: [{ - handle: '!', - prefix: '!' - }, { - handle: '!!', - prefix: PlainValue.defaultTagPrefix - }] - }, - 1.2: { - schema: 'core', - merge: false, - tagPrefixes: [{ - handle: '!', - prefix: '!' - }, { - handle: '!!', - prefix: PlainValue.defaultTagPrefix - }] +module.exports = { + "names": [ "MD022", "blanks-around-headings", "blanks-around-headers" ], + "description": "Headings should be surrounded by blank lines", + "tags": [ "headings", "headers", "blank_lines" ], + "function": function MD022(params, onError) { + let linesAbove = params.config.lines_above; + linesAbove = Number((linesAbove === undefined) ? 1 : linesAbove); + let linesBelow = params.config.lines_below; + linesBelow = Number((linesBelow === undefined) ? 1 : linesBelow); + const { lines } = params; + filterTokens(params, "heading_open", (token) => { + const [ topIndex, nextIndex ] = token.map; + let actualAbove = 0; + for (let i = 0; i < linesAbove; i++) { + if (isBlankLine(lines[topIndex - i - 1])) { + actualAbove++; + } + } + addErrorDetailIf( + onError, + topIndex + 1, + linesAbove, + actualAbove, + "Above", + lines[topIndex].trim(), + null, + { + "insertText": "".padEnd(linesAbove - actualAbove, "\n") + }); + let actualBelow = 0; + for (let i = 0; i < linesBelow; i++) { + if (isBlankLine(lines[nextIndex + i])) { + actualBelow++; + } + } + addErrorDetailIf( + onError, + topIndex + 1, + linesBelow, + actualBelow, + "Below", + lines[topIndex].trim(), + null, + { + "lineNumber": nextIndex + 1, + "insertText": "".padEnd(linesBelow - actualBelow, "\n") + }); + }); } }; -function stringifyTag(doc, tag) { - if ((doc.version || doc.options.version) === '1.0') { - const priv = tag.match(/^tag:private\.yaml\.org,2002:([^:/]+)$/); - if (priv) return '!' + priv[1]; - const vocab = tag.match(/^tag:([a-zA-Z0-9-]+)\.yaml\.org,2002:(.*)/); - return vocab ? `!${vocab[1]}/${vocab[2]}` : `!${tag.replace(/^tag:/, '')}`; - } - - let p = doc.tagPrefixes.find(p => tag.indexOf(p.prefix) === 0); - if (!p) { - const dtp = doc.getDefaults().tagPrefixes; - p = dtp && dtp.find(p => tag.indexOf(p.prefix) === 0); - } +/***/ }), - if (!p) return tag[0] === '!' ? tag : `!<${tag}>`; - const suffix = tag.substr(p.prefix.length).replace(/[!,[\]{}]/g, ch => ({ - '!': '%21', - ',': '%2C', - '[': '%5B', - ']': '%5D', - '{': '%7B', - '}': '%7D' - })[ch]); - return p.handle + suffix; -} +/***/ 1829: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -function getTagObject(tags, item) { - if (item instanceof resolveSeq.Alias) return resolveSeq.Alias; +"use strict"; +// @ts-check - if (item.tag) { - const match = tags.filter(t => t.tag === item.tag); - if (match.length > 0) return match.find(t => t.format === item.format) || match[0]; - } - let tagObj, obj; - if (item instanceof resolveSeq.Scalar) { - obj = item.value; // TODO: deprecate/remove class check +const { addErrorContext, filterTokens } = __nccwpck_require__(2935); - const match = tags.filter(t => t.identify && t.identify(obj) || t.class && obj instanceof t.class); - tagObj = match.find(t => t.format === item.format) || match.find(t => !t.format); - } else { - obj = item; - tagObj = tags.find(t => t.nodeClass && obj instanceof t.nodeClass); - } +const spaceBeforeHeadingRe = /^((?:\s+)|(?:[>\s]+\s\s))[^>\s]/; - if (!tagObj) { - const name = obj && obj.constructor ? obj.constructor.name : typeof obj; - throw new Error(`Tag not resolved for ${name} value`); +module.exports = { + "names": [ "MD023", "heading-start-left", "header-start-left" ], + "description": "Headings must start at the beginning of the line", + "tags": [ "headings", "headers", "spaces" ], + "function": function MD023(params, onError) { + filterTokens(params, "heading_open", function forToken(token) { + const { lineNumber, line } = token; + const match = line.match(spaceBeforeHeadingRe); + if (match) { + const [ prefixAndFirstChar, prefix ] = match; + let deleteCount = prefix.length; + const prefixLengthNoSpace = prefix.trimEnd().length; + if (prefixLengthNoSpace) { + deleteCount -= prefixLengthNoSpace - 1; + } + addErrorContext( + onError, + lineNumber, + line, + null, + null, + [ 1, prefixAndFirstChar.length ], + { + "editColumn": prefixLengthNoSpace + 1, + "deleteCount": deleteCount + }); + } + }); } - - return tagObj; -} // needs to be called before value stringifier to allow for circular anchor refs +}; -function stringifyProps(node, tagObj, { - anchors, - doc -}) { - const props = []; - const anchor = doc.anchors.getName(node); +/***/ }), - if (anchor) { - anchors[anchor] = node; - props.push(`&${anchor}`); - } +/***/ 7177: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (node.tag) { - props.push(stringifyTag(doc, node.tag)); - } else if (!tagObj.default) { - props.push(stringifyTag(doc, tagObj.tag)); - } +"use strict"; +// @ts-check - return props.join(' '); -} -function stringify(item, ctx, onComment, onChompKeep) { - const { - anchors, - schema - } = ctx.doc; - let tagObj; - - if (!(item instanceof resolveSeq.Node)) { - const createCtx = { - aliasNodes: [], - onTagObj: o => tagObj = o, - prevObjects: new Map() - }; - item = schema.createNode(item, true, null, createCtx); - for (const alias of createCtx.aliasNodes) { - alias.source = alias.source.node; - let name = anchors.getName(alias.source); +const { addErrorContext, forEachHeading } = __nccwpck_require__(2935); - if (!name) { - name = anchors.newName(); - anchors.map[name] = alias.source; +module.exports = { + "names": [ "MD024", "no-duplicate-heading", "no-duplicate-header" ], + "description": "Multiple headings with the same content", + "tags": [ "headings", "headers" ], + "function": function MD024(params, onError) { + const siblingsOnly = !!params.config.siblings_only || + !!params.config.allow_different_nesting || false; + const knownContents = [ null, [] ]; + let lastLevel = 1; + let knownContent = knownContents[lastLevel]; + forEachHeading(params, (heading, content) => { + if (siblingsOnly) { + const newLevel = heading.tag.slice(1); + while (lastLevel < newLevel) { + lastLevel++; + knownContents[lastLevel] = []; + } + while (lastLevel > newLevel) { + knownContents[lastLevel] = []; + lastLevel--; + } + knownContent = knownContents[newLevel]; } - } - } - - if (item instanceof resolveSeq.Pair) return item.toString(ctx, onComment, onChompKeep); - if (!tagObj) tagObj = getTagObject(schema.tags, item); - const props = stringifyProps(item, tagObj, ctx); - if (props.length > 0) ctx.indentAtStart = (ctx.indentAtStart || 0) + props.length + 1; - const str = typeof tagObj.stringify === 'function' ? tagObj.stringify(item, ctx, onComment, onChompKeep) : item instanceof resolveSeq.Scalar ? resolveSeq.stringifyString(item, ctx, onComment, onChompKeep) : item.toString(ctx, onComment, onChompKeep); - if (!props) return str; - return item instanceof resolveSeq.Scalar || str[0] === '{' || str[0] === '[' ? `${props} ${str}` : `${props}\n${ctx.indent}${str}`; -} - -class Anchors { - static validAnchorNode(node) { - return node instanceof resolveSeq.Scalar || node instanceof resolveSeq.YAMLSeq || node instanceof resolveSeq.YAMLMap; - } - - constructor(prefix) { - PlainValue._defineProperty(this, "map", Object.create(null)); - - this.prefix = prefix; - } - - createAlias(node, name) { - this.setAnchor(node, name); - return new resolveSeq.Alias(node); - } - - createMergePair(...sources) { - const merge = new resolveSeq.Merge(); - merge.value.items = sources.map(s => { - if (s instanceof resolveSeq.Alias) { - if (s.source instanceof resolveSeq.YAMLMap) return s; - } else if (s instanceof resolveSeq.YAMLMap) { - return this.createAlias(s); + if (knownContent.includes(content)) { + addErrorContext(onError, heading.lineNumber, + heading.line.trim()); + } else { + knownContent.push(content); } - - throw new Error('Merge sources must be Map nodes or their Aliases'); }); - return merge; } +}; - getName(node) { - const { - map - } = this; - return Object.keys(map).find(a => map[a] === node); - } - getNames() { - return Object.keys(this.map); - } +/***/ }), - getNode(name) { - return this.map[name]; - } +/***/ 692: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - newName(prefix) { - if (!prefix) prefix = this.prefix; - const names = Object.keys(this.map); +"use strict"; +// @ts-check - for (let i = 1; true; ++i) { - const name = `${prefix}${i}`; - if (!names.includes(name)) return name; - } - } // During parsing, map & aliases contain CST nodes - resolveNodes() { - const { - map, - _cstAliases - } = this; - Object.keys(map).forEach(a => { - map[a] = map[a].resolved; - }); +const { addErrorContext, filterTokens, frontMatterHasTitle } = + __nccwpck_require__(2935); - _cstAliases.forEach(a => { - a.source = a.source.resolved; +module.exports = { + "names": [ "MD025", "single-title", "single-h1" ], + "description": "Multiple top-level headings in the same document", + "tags": [ "headings", "headers" ], + "function": function MD025(params, onError) { + const level = Number(params.config.level || 1); + const tag = "h" + level; + const foundFrontMatterTitle = + frontMatterHasTitle( + params.frontMatterLines, + params.config.front_matter_title + ); + let hasTopLevelHeading = false; + filterTokens(params, "heading_open", function forToken(token) { + if (token.tag === tag) { + if (hasTopLevelHeading || foundFrontMatterTitle) { + addErrorContext(onError, token.lineNumber, + token.line.trim()); + } else if (token.lineNumber === 1) { + hasTopLevelHeading = true; + } + } }); - - delete this._cstAliases; } +}; - setAnchor(node, name) { - if (node != null && !Anchors.validAnchorNode(node)) { - throw new Error('Anchors may only be set for Scalar, Seq and Map nodes'); - } - if (name && /[\x00-\x19\s,[\]{}]/.test(name)) { - throw new Error('Anchor names must not contain whitespace or control characters'); - } +/***/ }), - const { - map - } = this; - const prev = node && Object.keys(map).find(a => map[a] === node); +/***/ 1629: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (prev) { - if (!name) { - return prev; - } else if (prev !== name) { - delete map[prev]; - map[name] = node; - } - } else { - if (!name) { - if (!node) return null; - name = this.newName(); - } +"use strict"; +// @ts-check - map[name] = node; - } - return name; - } -} +const { addError, allPunctuationNoQuestion, escapeForRegExp, forEachHeading } = + __nccwpck_require__(2935); -const visit = (node, tags) => { - if (node && typeof node === 'object') { - const { - tag - } = node; +const endOfLineHtmlEntityRe = /&#?[0-9a-zA-Z]+;$/; - if (node instanceof resolveSeq.Collection) { - if (tag) tags[tag] = true; - node.items.forEach(n => visit(n, tags)); - } else if (node instanceof resolveSeq.Pair) { - visit(node.key, tags); - visit(node.value, tags); - } else if (node instanceof resolveSeq.Scalar) { - if (tag) tags[tag] = true; - } +module.exports = { + "names": [ "MD026", "no-trailing-punctuation" ], + "description": "Trailing punctuation in heading", + "tags": [ "headings", "headers" ], + "function": function MD026(params, onError) { + let punctuation = params.config.punctuation; + punctuation = String( + (punctuation === undefined) ? allPunctuationNoQuestion : punctuation + ); + const trailingPunctuationRe = + new RegExp("\\s*[" + escapeForRegExp(punctuation) + "]+$"); + forEachHeading(params, (heading) => { + const { line, lineNumber } = heading; + const trimmedLine = line.replace(/([^\s#])[\s#]+$/, "$1"); + const match = trailingPunctuationRe.exec(trimmedLine); + if (match && !endOfLineHtmlEntityRe.test(trimmedLine)) { + const fullMatch = match[0]; + const column = match.index + 1; + const length = fullMatch.length; + addError( + onError, + lineNumber, + `Punctuation: '${fullMatch}'`, + null, + [ column, length ], + { + "editColumn": column, + "deleteCount": length + } + ); + } + }); } - - return tags; }; -const listTagNames = node => Object.keys(visit(node, {})); -function parseContents(doc, contents) { - const comments = { - before: [], - after: [] - }; - let body = undefined; - let spaceBefore = false; - - for (const node of contents) { - if (node.valueRange) { - if (body !== undefined) { - const msg = 'Document contains trailing content not separated by a ... or --- line'; - doc.errors.push(new PlainValue.YAMLSyntaxError(node, msg)); - break; - } +/***/ }), - const res = resolveSeq.resolveNode(doc, node); +/***/ 6325: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (spaceBefore) { - res.spaceBefore = true; - spaceBefore = false; - } +"use strict"; +// @ts-check - body = res; - } else if (node.comment !== null) { - const cc = body === undefined ? comments.before : comments.after; - cc.push(node.comment); - } else if (node.type === PlainValue.Type.BLANK_LINE) { - spaceBefore = true; - if (body === undefined && comments.before.length > 0 && !doc.commentBefore) { - // space-separated comments at start are parsed as document comments - doc.commentBefore = comments.before.join('\n'); - comments.before = []; - } - } - } - doc.contents = body || null; +const { addErrorContext, newLineRe } = __nccwpck_require__(2935); - if (!body) { - doc.comment = comments.before.concat(comments.after).join('\n') || null; - } else { - const cb = comments.before.join('\n'); +const spaceAfterBlockQuoteRe = /^((?:\s*>)+)(\s{2,})\S/; - if (cb) { - const cbNode = body instanceof resolveSeq.Collection && body.items[0] ? body.items[0] : body; - cbNode.commentBefore = cbNode.commentBefore ? `${cb}\n${cbNode.commentBefore}` : cb; +module.exports = { + "names": [ "MD027", "no-multiple-space-blockquote" ], + "description": "Multiple spaces after blockquote symbol", + "tags": [ "blockquote", "whitespace", "indentation" ], + "function": function MD027(params, onError) { + let blockquoteNesting = 0; + let listItemNesting = 0; + for (const token of params.tokens) { + const { content, lineNumber, type } = token; + if (type === "blockquote_open") { + blockquoteNesting++; + } else if (type === "blockquote_close") { + blockquoteNesting--; + } else if (type === "list_item_open") { + listItemNesting++; + } else if (type === "list_item_close") { + listItemNesting--; + } else if ((type === "inline") && blockquoteNesting) { + const lineCount = content.split(newLineRe).length; + for (let i = 0; i < lineCount; i++) { + const line = params.lines[lineNumber + i - 1]; + const match = line.match(spaceAfterBlockQuoteRe); + if (match) { + const [ + fullMatch, + { "length": blockquoteLength }, + { "length": spaceLength } + ] = match; + if (!listItemNesting || (fullMatch[fullMatch.length - 1] === ">")) { + addErrorContext( + onError, + lineNumber + i, + line, + null, + null, + [ 1, fullMatch.length ], + { + "editColumn": blockquoteLength + 1, + "deleteCount": spaceLength - 1 + } + ); + } + } + } + } } - - doc.comment = comments.after.join('\n') || null; } -} +}; -function resolveTagDirective({ - tagPrefixes -}, directive) { - const [handle, prefix] = directive.parameters; - if (!handle || !prefix) { - const msg = 'Insufficient parameters given for %TAG directive'; - throw new PlainValue.YAMLSemanticError(directive, msg); - } +/***/ }), - if (tagPrefixes.some(p => p.handle === handle)) { - const msg = 'The %TAG directive must only be given at most once per handle in the same document.'; - throw new PlainValue.YAMLSemanticError(directive, msg); - } +/***/ 7542: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - return { - handle, - prefix - }; -} +"use strict"; +// @ts-check -function resolveYamlDirective(doc, directive) { - let [version] = directive.parameters; - if (directive.name === 'YAML:1.0') version = '1.0'; - if (!version) { - const msg = 'Insufficient parameters given for %YAML directive'; - throw new PlainValue.YAMLSemanticError(directive, msg); - } - if (!documentOptions[version]) { - const v0 = doc.version || doc.options.version; - const msg = `Document will be parsed as YAML ${v0} rather than YAML ${version}`; - doc.warnings.push(new PlainValue.YAMLWarning(directive, msg)); +const { addError } = __nccwpck_require__(2935); + +module.exports = { + "names": [ "MD028", "no-blanks-blockquote" ], + "description": "Blank line inside blockquote", + "tags": [ "blockquote", "whitespace" ], + "function": function MD028(params, onError) { + let prevToken = {}; + let prevLineNumber = null; + for (const token of params.tokens) { + if ((token.type === "blockquote_open") && + (prevToken.type === "blockquote_close")) { + for ( + let lineNumber = prevLineNumber; + lineNumber < token.lineNumber; + lineNumber++) { + addError(onError, lineNumber); + } + } + prevToken = token; + if (token.type === "blockquote_open") { + prevLineNumber = token.map[1] + 1; + } + } } +}; - return version; -} -function parseDirectives(doc, directives, prevDoc) { - const directiveComments = []; - let hasDirectives = false; +/***/ }), - for (const directive of directives) { - const { - comment, - name - } = directive; +/***/ 3404: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - switch (name) { - case 'TAG': - try { - doc.tagPrefixes.push(resolveTagDirective(doc, directive)); - } catch (error) { - doc.errors.push(error); - } +"use strict"; +// @ts-check - hasDirectives = true; - break; - case 'YAML': - case 'YAML:1.0': - if (doc.version) { - const msg = 'The %YAML directive must only be given at most once per document.'; - doc.errors.push(new PlainValue.YAMLSemanticError(directive, msg)); - } - try { - doc.version = resolveYamlDirective(doc, directive); - } catch (error) { - doc.errors.push(error); - } +const { addErrorDetailIf, listItemMarkerRe, orderedListItemMarkerRe, + rangeFromRegExp } = __nccwpck_require__(2935); +const { flattenedLists } = __nccwpck_require__(2260); - hasDirectives = true; - break; +const listStyleExamples = { + "one": "1/1/1", + "ordered": "1/2/3", + "zero": "0/0/0" +}; - default: - if (name) { - const msg = `YAML only supports %TAG and %YAML directives, and not %${name}`; - doc.warnings.push(new PlainValue.YAMLWarning(directive, msg)); +module.exports = { + "names": [ "MD029", "ol-prefix" ], + "description": "Ordered list item prefix", + "tags": [ "ol" ], + "function": function MD029(params, onError) { + const style = String(params.config.style || "one_or_ordered"); + const filteredLists = flattenedLists().filter((list) => !list.unordered); + for (const list of filteredLists) { + const { items } = list; + let current = 1; + let incrementing = false; + // Check for incrementing number pattern 1/2/3 or 0/1/2 + if (items.length >= 2) { + const first = orderedListItemMarkerRe.exec(items[0].line); + const second = orderedListItemMarkerRe.exec(items[1].line); + if (first && second) { + const [ , firstNumber ] = first; + const [ , secondNumber ] = second; + if ((secondNumber !== "1") || (firstNumber === "0")) { + incrementing = true; + if (firstNumber === "0") { + current = 0; + } + } } - + } + // Determine effective style + let listStyle = style; + if (listStyle === "one_or_ordered") { + listStyle = incrementing ? "ordered" : "one"; + } + // Force expected value for 0/0/0 and 1/1/1 patterns + if (listStyle === "zero") { + current = 0; + } else if (listStyle === "one") { + current = 1; + } + // Validate each list item marker + for (const item of items) { + const match = orderedListItemMarkerRe.exec(item.line); + if (match) { + addErrorDetailIf(onError, item.lineNumber, + String(current), match[1], + "Style: " + listStyleExamples[listStyle], null, + rangeFromRegExp(item.line, listItemMarkerRe)); + if (listStyle === "ordered") { + current++; + } + } + } } - - if (comment) directiveComments.push(comment); } +}; - if (prevDoc && !hasDirectives && '1.1' === (doc.version || prevDoc.version || doc.options.version)) { - const copyTagPrefix = ({ - handle, - prefix - }) => ({ - handle, - prefix - }); - - doc.tagPrefixes = prevDoc.tagPrefixes.map(copyTagPrefix); - doc.version = prevDoc.version; - } - doc.commentBefore = directiveComments.join('\n') || null; -} +/***/ }), -function assertCollection(contents) { - if (contents instanceof resolveSeq.Collection) return true; - throw new Error('Expected a YAML collection as document contents'); -} +/***/ 2549: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -class Document { - constructor(options) { - this.anchors = new Anchors(options.anchorPrefix); - this.commentBefore = null; - this.comment = null; - this.contents = null; - this.directivesEndMarker = null; - this.errors = []; - this.options = options; - this.schema = null; - this.tagPrefixes = []; - this.version = null; - this.warnings = []; - } +"use strict"; +// @ts-check - add(value) { - assertCollection(this.contents); - return this.contents.add(value); - } - addIn(path, value) { - assertCollection(this.contents); - this.contents.addIn(path, value); - } - delete(key) { - assertCollection(this.contents); - return this.contents.delete(key); - } +const { addErrorDetailIf } = __nccwpck_require__(2935); +const { flattenedLists } = __nccwpck_require__(2260); - deleteIn(path) { - if (resolveSeq.isEmptyPath(path)) { - if (this.contents == null) return false; - this.contents = null; - return true; +module.exports = { + "names": [ "MD030", "list-marker-space" ], + "description": "Spaces after list markers", + "tags": [ "ol", "ul", "whitespace" ], + "function": function MD030(params, onError) { + const ulSingle = Number(params.config.ul_single || 1); + const olSingle = Number(params.config.ol_single || 1); + const ulMulti = Number(params.config.ul_multi || 1); + const olMulti = Number(params.config.ol_multi || 1); + for (const list of flattenedLists()) { + const lineCount = list.lastLineIndex - list.open.map[0]; + const allSingle = lineCount === list.items.length; + const expectedSpaces = list.unordered ? + (allSingle ? ulSingle : ulMulti) : + (allSingle ? olSingle : olMulti); + for (const item of list.items) { + const { line, lineNumber } = item; + const match = /^[\s>]*\S+(\s*)/.exec(line); + const [ { "length": matchLength }, { "length": actualSpaces } ] = match; + if (matchLength < line.length) { + let fixInfo = null; + if (expectedSpaces !== actualSpaces) { + fixInfo = { + "editColumn": matchLength - actualSpaces + 1, + "deleteCount": actualSpaces, + "insertText": "".padEnd(expectedSpaces) + }; + } + addErrorDetailIf( + onError, + lineNumber, + expectedSpaces, + actualSpaces, + null, + null, + [ 1, matchLength ], + fixInfo + ); + } + } } - - assertCollection(this.contents); - return this.contents.deleteIn(path); - } - - getDefaults() { - return Document.defaults[this.version] || Document.defaults[this.options.version] || {}; } +}; - get(key, keepScalar) { - return this.contents instanceof resolveSeq.Collection ? this.contents.get(key, keepScalar) : undefined; - } - getIn(path, keepScalar) { - if (resolveSeq.isEmptyPath(path)) return !keepScalar && this.contents instanceof resolveSeq.Scalar ? this.contents.value : this.contents; - return this.contents instanceof resolveSeq.Collection ? this.contents.getIn(path, keepScalar) : undefined; - } +/***/ }), - has(key) { - return this.contents instanceof resolveSeq.Collection ? this.contents.has(key) : false; - } +/***/ 2202: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - hasIn(path) { - if (resolveSeq.isEmptyPath(path)) return this.contents !== undefined; - return this.contents instanceof resolveSeq.Collection ? this.contents.hasIn(path) : false; - } +"use strict"; +// @ts-check - set(key, value) { - assertCollection(this.contents); - this.contents.set(key, value); - } - setIn(path, value) { - if (resolveSeq.isEmptyPath(path)) this.contents = value;else { - assertCollection(this.contents); - this.contents.setIn(path, value); - } - } - setSchema(id, customTags) { - if (!id && !customTags && this.schema) return; - if (typeof id === 'number') id = id.toFixed(1); +const { addErrorContext, forEachLine, isBlankLine } = __nccwpck_require__(2935); +const { lineMetadata } = __nccwpck_require__(2260); - if (id === '1.0' || id === '1.1' || id === '1.2') { - if (this.version) this.version = id;else this.options.version = id; - delete this.options.schema; - } else if (id && typeof id === 'string') { - this.options.schema = id; - } +const codeFencePrefixRe = /^(.*?)[`~]/; - if (Array.isArray(customTags)) this.options.customTags = customTags; - const opt = Object.assign({}, this.getDefaults(), this.options); - this.schema = new Schema.Schema(opt); +module.exports = { + "names": [ "MD031", "blanks-around-fences" ], + "description": "Fenced code blocks should be surrounded by blank lines", + "tags": [ "code", "blank_lines" ], + "function": function MD031(params, onError) { + const listItems = params.config.list_items; + const includeListItems = (listItems === undefined) ? true : !!listItems; + const { lines } = params; + forEachLine(lineMetadata(), (line, i, inCode, onFence, inTable, inItem) => { + const onTopFence = (onFence > 0); + const onBottomFence = (onFence < 0); + if ((includeListItems || !inItem) && + ((onTopFence && !isBlankLine(lines[i - 1])) || + (onBottomFence && !isBlankLine(lines[i + 1])))) { + const [ , prefix ] = line.match(codeFencePrefixRe) || []; + const fixInfo = (prefix === undefined) ? null : { + "lineNumber": i + (onTopFence ? 1 : 2), + "insertText": `${prefix.replace(/[^>]/g, " ").trim()}\n` + }; + addErrorContext( + onError, + i + 1, + lines[i].trim(), + null, + null, + null, + fixInfo); + } + }); } +}; - parse(node, prevDoc) { - if (this.options.keepCstNodes) this.cstNode = node; - if (this.options.keepNodeTypes) this.type = 'DOCUMENT'; - const { - directives = [], - contents = [], - directivesEndMarker, - error, - valueRange - } = node; - - if (error) { - if (!error.source) error.source = this; - this.errors.push(error); - } - parseDirectives(this, directives, prevDoc); - if (directivesEndMarker) this.directivesEndMarker = true; - this.range = valueRange ? [valueRange.start, valueRange.end] : null; - this.setSchema(); - this.anchors._cstAliases = []; - parseContents(this, contents); - this.anchors.resolveNodes(); +/***/ }), - if (this.options.prettyErrors) { - for (const error of this.errors) if (error instanceof PlainValue.YAMLError) error.makePretty(); +/***/ 3474: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - for (const warn of this.warnings) if (warn instanceof PlainValue.YAMLError) warn.makePretty(); - } +"use strict"; +// @ts-check - return this; - } - listNonDefaultTags() { - return listTagNames(this.contents).filter(t => t.indexOf(Schema.Schema.defaultPrefix) !== 0); - } - setTagPrefix(handle, prefix) { - if (handle[0] !== '!' || handle[handle.length - 1] !== '!') throw new Error('Handle must start and end with !'); +const { addErrorContext, blockquotePrefixRe, isBlankLine } = + __nccwpck_require__(2935); +const { flattenedLists } = __nccwpck_require__(2260); - if (prefix) { - const prev = this.tagPrefixes.find(p => p.handle === handle); - if (prev) prev.prefix = prefix;else this.tagPrefixes.push({ - handle, - prefix - }); - } else { - this.tagPrefixes = this.tagPrefixes.filter(p => p.handle !== handle); +module.exports = { + "names": [ "MD032", "blanks-around-lists" ], + "description": "Lists should be surrounded by blank lines", + "tags": [ "bullet", "ul", "ol", "blank_lines" ], + "function": function MD032(params, onError) { + const { lines } = params; + const filteredLists = flattenedLists().filter((list) => !list.nesting); + for (const list of filteredLists) { + const firstIndex = list.open.map[0]; + if (!isBlankLine(lines[firstIndex - 1])) { + const line = lines[firstIndex]; + const quotePrefix = line.match(blockquotePrefixRe)[0].trimEnd(); + addErrorContext( + onError, + firstIndex + 1, + line.trim(), + null, + null, + null, + { + "insertText": `${quotePrefix}\n` + }); + } + const lastIndex = list.lastLineIndex - 1; + if (!isBlankLine(lines[lastIndex + 1])) { + const line = lines[lastIndex]; + const quotePrefix = line.match(blockquotePrefixRe)[0].trimEnd(); + addErrorContext( + onError, + lastIndex + 1, + line.trim(), + null, + null, + null, + { + "lineNumber": lastIndex + 2, + "insertText": `${quotePrefix}\n` + }); + } } } +}; - toJSON(arg, onAnchor) { - const { - keepBlobsInJSON, - mapAsMap, - maxAliasCount - } = this.options; - const keep = keepBlobsInJSON && (typeof arg !== 'string' || !(this.contents instanceof resolveSeq.Scalar)); - const ctx = { - doc: this, - indentStep: ' ', - keep, - mapAsMap: keep && !!mapAsMap, - maxAliasCount, - stringify // Requiring directly in Pair would create circular dependencies - }; - const anchorNames = Object.keys(this.anchors.map); - if (anchorNames.length > 0) ctx.anchors = new Map(anchorNames.map(name => [this.anchors.map[name], { - alias: [], - aliasCount: 0, - count: 1 - }])); - const res = resolveSeq.toJSON(this.contents, arg, ctx); - if (typeof onAnchor === 'function' && ctx.anchors) for (const { - count, - res - } of ctx.anchors.values()) onAnchor(res, count); - return res; - } +/***/ }), - toString() { - if (this.errors.length > 0) throw new Error('Document with errors cannot be stringified'); - const indentSize = this.options.indent; +/***/ 77: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (!Number.isInteger(indentSize) || indentSize <= 0) { - const s = JSON.stringify(indentSize); - throw new Error(`"indent" option must be a positive integer, not ${s}`); - } +"use strict"; +// @ts-check - this.setSchema(); - const lines = []; - let hasDirectives = false; - if (this.version) { - let vd = '%YAML 1.2'; - if (this.schema.name === 'yaml-1.1') { - if (this.version === '1.0') vd = '%YAML:1.0';else if (this.version === '1.1') vd = '%YAML 1.1'; - } +const { + addError, forEachLine, htmlElementRe, withinAnyRange, unescapeMarkdown +} = __nccwpck_require__(2935); +const { codeBlockAndSpanRanges, lineMetadata } = __nccwpck_require__(2260); - lines.push(vd); - hasDirectives = true; - } +const linkDestinationRe = /]\(\s*$/; +// See https://spec.commonmark.org/0.29/#autolinks +const emailAddressRe = + // eslint-disable-next-line max-len + /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; - const tagNames = this.listNonDefaultTags(); - this.tagPrefixes.forEach(({ - handle, - prefix - }) => { - if (tagNames.some(t => t.indexOf(prefix) === 0)) { - lines.push(`%TAG ${handle} ${prefix}`); - hasDirectives = true; +module.exports = { + "names": [ "MD033", "no-inline-html" ], + "description": "Inline HTML", + "tags": [ "html" ], + "function": function MD033(params, onError) { + let allowedElements = params.config.allowed_elements; + allowedElements = Array.isArray(allowedElements) ? allowedElements : []; + allowedElements = allowedElements.map((element) => element.toLowerCase()); + const exclusions = codeBlockAndSpanRanges(); + forEachLine(lineMetadata(), (line, lineIndex, inCode) => { + let match = null; + // eslint-disable-next-line no-unmodified-loop-condition + while (!inCode && ((match = htmlElementRe.exec(line)) !== null)) { + const [ tag, content, element ] = match; + if ( + !allowedElements.includes(element.toLowerCase()) && + !tag.endsWith("\\>") && + !emailAddressRe.test(content) && + !withinAnyRange(exclusions, lineIndex, match.index, match[0].length) + ) { + const prefix = line.substring(0, match.index); + if (!linkDestinationRe.test(prefix)) { + const unescaped = unescapeMarkdown(prefix + "<", "_"); + if (!unescaped.endsWith("_")) { + addError(onError, lineIndex + 1, "Element: " + element, + undefined, [ match.index + 1, tag.length ]); + } + } + } } }); - if (hasDirectives || this.directivesEndMarker) lines.push('---'); + } +}; - if (this.commentBefore) { - if (hasDirectives || !this.directivesEndMarker) lines.unshift(''); - lines.unshift(this.commentBefore.replace(/^/gm, '#')); - } - const ctx = { - anchors: Object.create(null), - doc: this, - indent: '', - indentStep: ' '.repeat(indentSize), - stringify // Requiring directly in nodes would create circular dependencies +/***/ }), + +/***/ 4721: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; +// @ts-check - }; - let chompKeep = false; - let contentComment = null; - if (this.contents) { - if (this.contents instanceof resolveSeq.Node) { - if (this.contents.spaceBefore && (hasDirectives || this.directivesEndMarker)) lines.push(''); - if (this.contents.commentBefore) lines.push(this.contents.commentBefore.replace(/^/gm, '#')); // top-level block scalars need to be indented if followed by a comment - ctx.forceBlockIndent = !!this.comment; - contentComment = this.contents.comment; +const { addErrorContext, bareUrlRe, filterTokens } = __nccwpck_require__(2935); + +module.exports = { + "names": [ "MD034", "no-bare-urls" ], + "description": "Bare URL used", + "tags": [ "links", "url" ], + "function": function MD034(params, onError) { + filterTokens(params, "inline", (token) => { + let inLink = false; + for (const child of token.children) { + const { content, line, lineNumber, type } = child; + let match = null; + if (type === "link_open") { + inLink = true; + } else if (type === "link_close") { + inLink = false; + } else if ((type === "text") && !inLink) { + while ((match = bareUrlRe.exec(content)) !== null) { + const [ bareUrl ] = match; + const matchIndex = match.index; + const bareUrlLength = bareUrl.length; + // Allow "[https://example.com]" to avoid conflicts with + // MD011/no-reversed-links; allow quoting as another way + // of deliberately including a bare URL + const leftChar = content[matchIndex - 1]; + const rightChar = content[matchIndex + bareUrlLength]; + if ( + !((leftChar === "[") && (rightChar === "]")) && + !((leftChar === "\"") && (rightChar === "\"")) && + !((leftChar === "'") && (rightChar === "'")) + ) { + const index = line.indexOf(content); + const range = (index === -1) ? null : [ + index + matchIndex + 1, + bareUrlLength + ]; + const fixInfo = range ? { + "editColumn": range[0], + "deleteCount": range[1], + "insertText": `<${bareUrl}>` + } : null; + addErrorContext( + onError, + lineNumber, + bareUrl, + null, + null, + range, + fixInfo + ); + } + } + } } - - const onChompKeep = contentComment ? null : () => chompKeep = true; - const body = stringify(this.contents, ctx, () => contentComment = null, onChompKeep); - lines.push(resolveSeq.addComment(body, '', contentComment)); - } else if (this.contents !== undefined) { - lines.push(stringify(this.contents, ctx)); - } - - if (this.comment) { - if ((!chompKeep || contentComment) && lines[lines.length - 1] !== '') lines.push(''); - lines.push(this.comment.replace(/^/gm, '#')); - } - - return lines.join('\n') + '\n'; + }); } - -} - -PlainValue._defineProperty(Document, "defaults", documentOptions); - -exports.Document = Document; -exports.defaultOptions = defaultOptions; -exports.scalarOptions = scalarOptions; +}; /***/ }), -/***/ 4941: -/***/ ((__unused_webpack_module, exports) => { +/***/ 2997: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; +// @ts-check -const Char = { - ANCHOR: '&', - COMMENT: '#', - TAG: '!', - DIRECTIVES_END: '-', - DOCUMENT_END: '.' -}; -const Type = { - ALIAS: 'ALIAS', - BLANK_LINE: 'BLANK_LINE', - BLOCK_FOLDED: 'BLOCK_FOLDED', - BLOCK_LITERAL: 'BLOCK_LITERAL', - COMMENT: 'COMMENT', - DIRECTIVE: 'DIRECTIVE', - DOCUMENT: 'DOCUMENT', - FLOW_MAP: 'FLOW_MAP', - FLOW_SEQ: 'FLOW_SEQ', - MAP: 'MAP', - MAP_KEY: 'MAP_KEY', - MAP_VALUE: 'MAP_VALUE', - PLAIN: 'PLAIN', - QUOTE_DOUBLE: 'QUOTE_DOUBLE', - QUOTE_SINGLE: 'QUOTE_SINGLE', - SEQ: 'SEQ', - SEQ_ITEM: 'SEQ_ITEM' -}; -const defaultTagPrefix = 'tag:yaml.org,2002:'; -const defaultTags = { - MAP: 'tag:yaml.org,2002:map', - SEQ: 'tag:yaml.org,2002:seq', - STR: 'tag:yaml.org,2002:str' -}; - -function findLineStarts(src) { - const ls = [0]; - let offset = src.indexOf('\n'); - - while (offset !== -1) { - offset += 1; - ls.push(offset); - offset = src.indexOf('\n', offset); - } - - return ls; -} - -function getSrcInfo(cst) { - let lineStarts, src; - if (typeof cst === 'string') { - lineStarts = findLineStarts(cst); - src = cst; - } else { - if (Array.isArray(cst)) cst = cst[0]; +const { addErrorDetailIf, filterTokens } = __nccwpck_require__(2935); - if (cst && cst.context) { - if (!cst.lineStarts) cst.lineStarts = findLineStarts(cst.context.src); - lineStarts = cst.lineStarts; - src = cst.context.src; - } +module.exports = { + "names": [ "MD035", "hr-style" ], + "description": "Horizontal rule style", + "tags": [ "hr" ], + "function": function MD035(params, onError) { + let style = String(params.config.style || "consistent").trim(); + filterTokens(params, "hr", (token) => { + const { line, lineNumber } = token; + let { markup } = token; + const match = line.match(/[_*\-\s\t]+$/); + if (match) { + markup = match[0].trim(); + } + if (style === "consistent") { + style = markup; + } + addErrorDetailIf(onError, lineNumber, style, markup); + }); } - - return { - lineStarts, - src - }; -} -/** - * @typedef {Object} LinePos - One-indexed position in the source - * @property {number} line - * @property {number} col - */ - -/** - * Determine the line/col position matching a character offset. - * - * Accepts a source string or a CST document as the second parameter. With - * the latter, starting indices for lines are cached in the document as - * `lineStarts: number[]`. - * - * Returns a one-indexed `{ line, col }` location if found, or - * `undefined` otherwise. - * - * @param {number} offset - * @param {string|Document|Document[]} cst - * @returns {?LinePos} - */ +}; -function getLinePos(offset, cst) { - if (typeof offset !== 'number' || offset < 0) return null; - const { - lineStarts, - src - } = getSrcInfo(cst); - if (!lineStarts || !src || offset > src.length) return null; - - for (let i = 0; i < lineStarts.length; ++i) { - const start = lineStarts[i]; - - if (offset < start) { - return { - line: i, - col: offset - lineStarts[i - 1] + 1 - }; - } +/***/ }), - if (offset === start) return { - line: i + 1, - col: 1 - }; - } +/***/ 338: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - const line = lineStarts.length; - return { - line, - col: offset - lineStarts[line - 1] + 1 - }; -} -/** - * Get a specified line from the source. - * - * Accepts a source string or a CST document as the second parameter. With - * the latter, starting indices for lines are cached in the document as - * `lineStarts: number[]`. - * - * Returns the line as a string if found, or `null` otherwise. - * - * @param {number} line One-indexed line number - * @param {string|Document|Document[]} cst - * @returns {?string} - */ +"use strict"; +// @ts-check -function getLine(line, cst) { - const { - lineStarts, - src - } = getSrcInfo(cst); - if (!lineStarts || !(line >= 1) || line > lineStarts.length) return null; - const start = lineStarts[line - 1]; - let end = lineStarts[line]; // undefined for last line; that's ok for slice() - while (end && end > start && src[end - 1] === '\n') --end; - return src.slice(start, end); -} -/** - * Pretty-print the starting line from the source indicated by the range `pos` - * - * Trims output to `maxWidth` chars while keeping the starting column visible, - * using `…` at either end to indicate dropped characters. - * - * Returns a two-line string (or `null`) with `\n` as separator; the second line - * will hold appropriately indented `^` marks indicating the column range. - * - * @param {Object} pos - * @param {LinePos} pos.start - * @param {LinePos} [pos.end] - * @param {string|Document|Document[]*} cst - * @param {number} [maxWidth=80] - * @returns {?string} - */ +const { addErrorContext, allPunctuation } = __nccwpck_require__(2935); -function getPrettyContext({ - start, - end -}, cst, maxWidth = 80) { - let src = getLine(start.line, cst); - if (!src) return null; - let { - col - } = start; - - if (src.length > maxWidth) { - if (col <= maxWidth - 10) { - src = src.substr(0, maxWidth - 1) + '…'; - } else { - const halfWidth = Math.round(maxWidth / 2); - if (src.length > col + halfWidth) src = src.substr(0, col + halfWidth - 1) + '…'; - col -= src.length - maxWidth; - src = '…' + src.substr(1 - maxWidth); +module.exports = { + "names": [ "MD036", "no-emphasis-as-heading", "no-emphasis-as-header" ], + "description": "Emphasis used instead of a heading", + "tags": [ "headings", "headers", "emphasis" ], + "function": function MD036(params, onError) { + let punctuation = params.config.punctuation; + punctuation = + String((punctuation === undefined) ? allPunctuation : punctuation); + const re = new RegExp("[" + punctuation + "]$"); + // eslint-disable-next-line jsdoc/require-jsdoc + function base(token) { + if (token.type === "paragraph_open") { + return function inParagraph(t) { + // Always paragraph_open/inline/paragraph_close, + const children = t.children.filter(function notEmptyText(child) { + return (child.type !== "text") || (child.content !== ""); + }); + if ((children.length === 3) && + ((children[0].type === "strong_open") || + (children[0].type === "em_open")) && + (children[1].type === "text") && + !re.test(children[1].content)) { + addErrorContext(onError, t.lineNumber, + children[1].content); + } + return base; + }; + } else if (token.type === "blockquote_open") { + return function inBlockquote(t) { + if (t.type !== "blockquote_close") { + return inBlockquote; + } + return base; + }; + } else if (token.type === "list_item_open") { + return function inListItem(t) { + if (t.type !== "list_item_close") { + return inListItem; + } + return base; + }; + } + return base; } - } - - let errLen = 1; - let errEnd = ''; - - if (end) { - if (end.line === start.line && col + (end.col - start.col) <= maxWidth + 1) { - errLen = end.col - start.col; - } else { - errLen = Math.min(src.length + 1, maxWidth) - col; - errEnd = '…'; + let state = base; + for (const token of params.tokens) { + state = state(token); } } +}; - const offset = col > 1 ? ' '.repeat(col - 1) : ''; - const err = '^'.repeat(errLen); - return `${src}\n${offset}${err}${errEnd}`; -} -class Range { - static copy(orig) { - return new Range(orig.start, orig.end); - } +/***/ }), - constructor(start, end) { - this.start = start; - this.end = end || start; - } +/***/ 2905: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - isEmpty() { - return typeof this.start !== 'number' || !this.end || this.end <= this.start; - } - /** - * Set `origStart` and `origEnd` to point to the original source range for - * this node, which may differ due to dropped CR characters. - * - * @param {number[]} cr - Positions of dropped CR characters - * @param {number} offset - Starting index of `cr` from the last call - * @returns {number} - The next offset, matching the one found for `origStart` - */ +"use strict"; +// @ts-check - setOrigRange(cr, offset) { - const { - start, - end - } = this; - if (cr.length === 0 || end <= cr[0]) { - this.origStart = start; - this.origEnd = end; - return offset; - } +const { addErrorContext, emphasisMarkersInContent, forEachLine, isBlankLine, + withinAnyRange } = __nccwpck_require__(2935); +const { htmlElementRanges, lineMetadata } = __nccwpck_require__(2260); - let i = offset; +const emphasisRe = /(^|[^\\]|\\\\)(?:(\*\*?\*?)|(__?_?))/g; +const embeddedUnderscoreRe = /([A-Za-z0-9])_([A-Za-z0-9])/g; +const asteriskListItemMarkerRe = /^([\s>]*)\*(\s+)/; +const leftSpaceRe = /^\s+/; +const rightSpaceRe = /\s+$/; +const tablePipeRe = /\|/; - while (i < cr.length) { - if (cr[i] > start) break;else ++i; +module.exports = { + "names": [ "MD037", "no-space-in-emphasis" ], + "description": "Spaces inside emphasis markers", + "tags": [ "whitespace", "emphasis" ], + "function": function MD037(params, onError) { + const exclusions = htmlElementRanges(); + // eslint-disable-next-line init-declarations + let effectiveEmphasisLength, emphasisIndex, emphasisKind, emphasisLength, + pendingError = null; + // eslint-disable-next-line jsdoc/require-jsdoc + function resetRunTracking() { + emphasisIndex = -1; + emphasisLength = 0; + emphasisKind = ""; + effectiveEmphasisLength = 0; + pendingError = null; } - - this.origStart = start + i; - const nextOffset = i; - - while (i < cr.length) { - // if end was at \n, it should now be at \r - if (cr[i] >= end) break;else ++i; + // eslint-disable-next-line jsdoc/require-jsdoc + function handleRunEnd( + line, lineIndex, contextLength, match, matchIndex, inTable + ) { + // Close current run + let content = line.substring(emphasisIndex, matchIndex); + if (!emphasisLength) { + content = content.trimStart(); + } + if (!match) { + content = content.trimEnd(); + } + const leftSpace = leftSpaceRe.test(content); + const rightSpace = rightSpaceRe.test(content); + if ( + (leftSpace || rightSpace) && + (!inTable || !tablePipeRe.test(content)) + ) { + // Report the violation + const contextStart = emphasisIndex - emphasisLength; + const contextEnd = matchIndex + contextLength; + const column = contextStart + 1; + const length = contextEnd - contextStart; + if (!withinAnyRange(exclusions, lineIndex, column, length)) { + const context = line.substring(contextStart, contextEnd); + const leftMarker = line.substring(contextStart, emphasisIndex); + const rightMarker = match ? (match[2] || match[3]) : ""; + const fixedText = `${leftMarker}${content.trim()}${rightMarker}`; + return [ + onError, + lineIndex + 1, + context, + leftSpace, + rightSpace, + [ column, length ], + { + "editColumn": column, + "deleteCount": length, + "insertText": fixedText + } + ]; + } + } + return null; } - - this.origEnd = end + i; - return nextOffset; + // Initialize + const ignoreMarkersByLine = emphasisMarkersInContent(params); + resetRunTracking(); + forEachLine( + lineMetadata(), + (line, lineIndex, inCode, onFence, inTable, inItem, onBreak, inMath) => { + const onItemStart = (inItem === 1); + if ( + inCode || + onFence || + inTable || + onBreak || + onItemStart || + isBlankLine(line) + ) { + // Emphasis resets when leaving a block + resetRunTracking(); + } + if ( + inCode || + onFence || + onBreak || + inMath + ) { + // Emphasis has no meaning here + return; + } + let patchedLine = line.replace(embeddedUnderscoreRe, "$1 $2"); + if (onItemStart) { + // Trim overlapping '*' list item marker + patchedLine = patchedLine.replace(asteriskListItemMarkerRe, "$1 $2"); + } + let match = null; + // Match all emphasis-looking runs in the line... + while ((match = emphasisRe.exec(patchedLine))) { + const ignoreMarkersForLine = ignoreMarkersByLine[lineIndex]; + const matchIndex = match.index + match[1].length; + if (ignoreMarkersForLine.includes(matchIndex)) { + // Ignore emphasis markers inside code spans and links + continue; + } + const matchLength = match[0].length - match[1].length; + const matchKind = (match[2] || match[3])[0]; + if (emphasisIndex === -1) { + // New run + emphasisIndex = matchIndex + matchLength; + emphasisLength = matchLength; + emphasisKind = matchKind; + effectiveEmphasisLength = matchLength; + } else if (matchKind === emphasisKind) { + // Matching emphasis markers + if (matchLength === effectiveEmphasisLength) { + // Ending an existing run, report any pending error + if (pendingError) { + // @ts-ignore + addErrorContext(...pendingError); + pendingError = null; + } + const error = handleRunEnd( + line, + lineIndex, + effectiveEmphasisLength, + match, + matchIndex, + inTable + ); + if (error) { + // @ts-ignore + addErrorContext(...error); + } + // Reset + resetRunTracking(); + } else if (matchLength === 3) { + // Swap internal run length (1->2 or 2->1) + effectiveEmphasisLength = matchLength - effectiveEmphasisLength; + } else if (effectiveEmphasisLength === 3) { + // Downgrade internal run (3->1 or 3->2) + effectiveEmphasisLength -= matchLength; + } else { + // Upgrade to internal run (1->3 or 2->3) + effectiveEmphasisLength += matchLength; + } + // Back up one character so RegExp has a chance to match the + // next marker (ex: "**star**_underscore_") + if (emphasisRe.lastIndex > 1) { + emphasisRe.lastIndex--; + } + } else if (emphasisRe.lastIndex > 1) { + // Back up one character so RegExp has a chance to match the + // mis-matched marker (ex: "*text_*") + emphasisRe.lastIndex--; + } + } + if (emphasisIndex !== -1) { + pendingError = pendingError || + handleRunEnd(line, lineIndex, 0, null, line.length, inTable); + // Adjust for pending run on new line + emphasisIndex = 0; + emphasisLength = 0; + } + } + ); } +}; -} -/** Root class of all nodes */ +/***/ }), -class Node { - static addStringTerminator(src, offset, str) { - if (str[str.length - 1] === '\n') return str; - const next = Node.endOfWhiteSpace(src, offset); - return next >= src.length || src[next] === '\n' ? str + '\n' : str; - } // ^(---|...) +/***/ 6054: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +"use strict"; +// @ts-check - static atDocumentBoundary(src, offset, sep) { - const ch0 = src[offset]; - if (!ch0) return true; - const prev = src[offset - 1]; - if (prev && prev !== '\n') return false; - if (sep) { - if (ch0 !== sep) return false; - } else { - if (ch0 !== Char.DIRECTIVES_END && ch0 !== Char.DOCUMENT_END) return false; - } - const ch1 = src[offset + 1]; - const ch2 = src[offset + 2]; - if (ch1 !== ch0 || ch2 !== ch0) return false; - const ch3 = src[offset + 3]; - return !ch3 || ch3 === '\n' || ch3 === '\t' || ch3 === ' '; - } +const { addErrorContext, filterTokens, forEachInlineCodeSpan, newLineRe } = + __nccwpck_require__(2935); - static endOfIdentifier(src, offset) { - let ch = src[offset]; - const isVerbatim = ch === '<'; - const notOk = isVerbatim ? ['\n', '\t', ' ', '>'] : ['\n', '\t', ' ', '[', ']', '{', '}', ',']; +const leftSpaceRe = /^\s([^`]|$)/; +const rightSpaceRe = /[^`]\s$/; - while (ch && notOk.indexOf(ch) === -1) ch = src[offset += 1]; +const spaceInsideCodeInline = (token) => ( + (token.type === "code_inline") && + (leftSpaceRe.test(token.content) || rightSpaceRe.test(token.content)) +); - if (isVerbatim && ch === '>') offset += 1; - return offset; +module.exports = { + "names": [ "MD038", "no-space-in-code" ], + "description": "Spaces inside code span elements", + "tags": [ "whitespace", "code" ], + "function": function MD038(params, onError) { + filterTokens(params, "inline", (token) => { + if (token.children.some(spaceInsideCodeInline)) { + const tokenLines = params.lines.slice(token.map[0], token.map[1]); + forEachInlineCodeSpan( + tokenLines.join("\n"), + (code, lineIndex, columnIndex, tickCount) => { + let rangeIndex = columnIndex - tickCount; + let rangeLength = code.length + (2 * tickCount); + let rangeLineOffset = 0; + let fixIndex = columnIndex; + let fixLength = code.length; + const codeLines = code.split(newLineRe); + const left = leftSpaceRe.test(code); + const right = !left && rightSpaceRe.test(code); + if (right && (codeLines.length > 1)) { + rangeIndex = 0; + rangeLineOffset = codeLines.length - 1; + fixIndex = 0; + } + if (left || right) { + const codeLinesRange = codeLines[rangeLineOffset]; + if (codeLines.length > 1) { + rangeLength = codeLinesRange.length + tickCount; + fixLength = codeLinesRange.length; + } + const context = tokenLines[lineIndex + rangeLineOffset] + .substring(rangeIndex, rangeIndex + rangeLength); + const codeLinesRangeTrim = codeLinesRange.trim(); + const fixText = + (codeLinesRangeTrim.startsWith("`") ? " " : "") + + codeLinesRangeTrim + + (codeLinesRangeTrim.endsWith("`") ? " " : ""); + addErrorContext( + onError, + token.lineNumber + lineIndex + rangeLineOffset, + context, + left, + right, + [ rangeIndex + 1, rangeLength ], + { + "editColumn": fixIndex + 1, + "deleteCount": fixLength, + "insertText": fixText + } + ); + } + }); + } + }); } +}; - static endOfIndent(src, offset) { - let ch = src[offset]; - while (ch === ' ') ch = src[offset += 1]; +/***/ }), - return offset; - } +/***/ 8596: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - static endOfLine(src, offset) { - let ch = src[offset]; +"use strict"; +// @ts-check - while (ch && ch !== '\n') ch = src[offset += 1]; - return offset; - } - static endOfWhiteSpace(src, offset) { - let ch = src[offset]; +const { addErrorContext, filterTokens } = __nccwpck_require__(2935); - while (ch === '\t' || ch === ' ') ch = src[offset += 1]; +const spaceInLinkRe = + /\[(?:\s+(?:[^\]]*?)\s*|(?:[^\]]*?)\s+)](?=((?:\([^)]*\))|(?:\[[^\]]*\])))/; - return offset; +module.exports = { + "names": [ "MD039", "no-space-in-links" ], + "description": "Spaces inside link text", + "tags": [ "whitespace", "links" ], + "function": function MD039(params, onError) { + filterTokens(params, "inline", (token) => { + const { children } = token; + let { lineNumber } = token; + let inLink = false; + let linkText = ""; + let lineIndex = 0; + for (const child of children) { + const { content, markup, type } = child; + if (type === "link_open") { + inLink = true; + linkText = ""; + } else if (type === "link_close") { + inLink = false; + const left = linkText.trimStart().length !== linkText.length; + const right = linkText.trimEnd().length !== linkText.length; + if (left || right) { + const line = params.lines[lineNumber - 1]; + let range = null; + let fixInfo = null; + const match = line.slice(lineIndex).match(spaceInLinkRe); + if (match) { + const column = match.index + lineIndex + 1; + const length = match[0].length; + range = [ column, length ]; + fixInfo = { + "editColumn": column + 1, + "deleteCount": length - 2, + "insertText": linkText.trim() + }; + lineIndex = column + length - 1; + } + addErrorContext( + onError, + lineNumber, + `[${linkText}]`, + left, + right, + range, + fixInfo + ); + } + } else if ((type === "softbreak") || (type === "hardbreak")) { + lineNumber++; + lineIndex = 0; + } else if (inLink) { + linkText += type.endsWith("_inline") ? + `${markup}${content}${markup}` : + (content || markup); + } + } + }); } +}; - static startOfLine(src, offset) { - let ch = src[offset - 1]; - if (ch === '\n') return offset; - while (ch && ch !== '\n') ch = src[offset -= 1]; +/***/ }), - return offset + 1; - } - /** - * End of indentation, or null if the line's indent level is not more - * than `indent` - * - * @param {string} src - * @param {number} indent - * @param {number} lineStart - * @returns {?number} - */ +/***/ 320: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +"use strict"; +// @ts-check - static endOfBlockIndent(src, indent, lineStart) { - const inEnd = Node.endOfIndent(src, lineStart); - if (inEnd > lineStart + indent) { - return inEnd; - } else { - const wsEnd = Node.endOfWhiteSpace(src, inEnd); - const ch = src[wsEnd]; - if (!ch || ch === '\n') return wsEnd; - } - return null; - } +const { addErrorContext, filterTokens } = __nccwpck_require__(2935); - static atBlank(src, offset, endAsBlank) { - const ch = src[offset]; - return ch === '\n' || ch === '\t' || ch === ' ' || endAsBlank && !ch; +module.exports = { + "names": [ "MD040", "fenced-code-language" ], + "description": "Fenced code blocks should have a language specified", + "tags": [ "code", "language" ], + "function": function MD040(params, onError) { + filterTokens(params, "fence", function forToken(token) { + if (!token.info.trim()) { + addErrorContext(onError, token.lineNumber, token.line); + } + }); } +}; - static nextNodeIsIndented(ch, indentDiff, indicatorAsIndent) { - if (!ch || indentDiff < 0) return false; - if (indentDiff > 0) return true; - return indicatorAsIndent && ch === '-'; - } // should be at line or string end, or at next non-whitespace char - - - static normalizeOffset(src, offset) { - const ch = src[offset]; - return !ch ? offset : ch !== '\n' && src[offset - 1] === '\n' ? offset - 1 : Node.endOfWhiteSpace(src, offset); - } // fold single newline into space, multiple newlines to N - 1 newlines - // presumes src[offset] === '\n' - - - static foldNewline(src, offset, indent) { - let inCount = 0; - let error = false; - let fold = ''; - let ch = src[offset + 1]; - while (ch === ' ' || ch === '\t' || ch === '\n') { - switch (ch) { - case '\n': - inCount = 0; - offset += 1; - fold += '\n'; - break; +/***/ }), - case '\t': - if (inCount <= indent) error = true; - offset = Node.endOfWhiteSpace(src, offset + 2) - 1; - break; +/***/ 8679: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - case ' ': - inCount += 1; - offset += 1; - break; - } +"use strict"; +// @ts-check - ch = src[offset + 1]; - } - if (!fold) fold = ' '; - if (ch && inCount <= indent) error = true; - return { - fold, - offset, - error - }; - } - constructor(type, props, context) { - Object.defineProperty(this, 'context', { - value: context || null, - writable: true - }); - this.error = null; - this.range = null; - this.valueRange = null; - this.props = props || []; - this.type = type; - this.value = null; - } +const { addErrorContext, frontMatterHasTitle } = __nccwpck_require__(2935); - getPropValue(idx, key, skipKey) { - if (!this.context) return null; - const { - src - } = this.context; - const prop = this.props[idx]; - return prop && src[prop.start] === key ? src.slice(prop.start + (skipKey ? 1 : 0), prop.end) : null; +module.exports = { + "names": [ "MD041", "first-line-heading", "first-line-h1" ], + "description": "First line in a file should be a top-level heading", + "tags": [ "headings", "headers" ], + "function": function MD041(params, onError) { + const level = Number(params.config.level || 1); + const tag = "h" + level; + const foundFrontMatterTitle = + frontMatterHasTitle( + params.frontMatterLines, + params.config.front_matter_title + ); + if (!foundFrontMatterTitle) { + const htmlHeadingRe = new RegExp(`^]`, "i"); + params.tokens.every((token) => { + let isError = false; + if (token.type === "html_block") { + if (token.content.startsWith("