/* markdownlint - https://github.com/DavidAnson/markdownlint - @license MIT */ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.markdownlint = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i/ig; module.exports.inlineCommentRe = inlineCommentRe; // Regular expressions for range matching module.exports.bareUrlRe = /(?:http|ftp)s?:\/\/[^\s]*/ig; module.exports.listItemMarkerRe = /^[\s>]*(?:[*+-]|\d+[.)])\s+/; module.exports.orderedListItemMarkerRe = /^[\s>]*0*(\d+)[.)]/; // readFile options for reading with the UTF-8 encoding module.exports.utf8Encoding = { "encoding": "utf8" }; // All punctuation characters (normal and full-width) module.exports.allPunctuation = ".,;:!?。,;:!?"; // Returns true iff the input is a number module.exports.isNumber = function isNumber(obj) { return typeof obj === "number"; }; // Returns true iff the input is a string module.exports.isString = function isString(obj) { return typeof obj === "string"; }; // Returns true iff the input string is empty module.exports.isEmptyString = function isEmptyString(str) { return str.length === 0; }; // Returns true iff the input is an object 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 comments var blankLineRe = />|(?:)/g; module.exports.isBlankLine = function isBlankLine(line) { return !line || !line.trim() || !line.replace(blankLineRe, "").trim(); }; // Returns true iff the sorted array contains the specified element module.exports.includesSorted = function includesSorted(array, element) { var left = 0; var right = array.length - 1; while (left <= right) { /* eslint-disable no-bitwise */ var mid = (left + right) >> 1; if (array[mid] < element) { left = mid + 1; } else if (array[mid] > element) { right = mid - 1; } else { return true; } } return false; }; // Replaces the text of all properly-formatted HTML comments with whitespace // This preserves the line/column information for the rest of the document // Trailing whitespace is avoided with a '\' character in the last column // See https://www.w3.org/TR/html5/syntax.html#comments for details var htmlCommentBegin = ""; module.exports.clearHtmlCommentText = function clearHtmlCommentText(text) { var i = 0; while ((i = text.indexOf(htmlCommentBegin, i)) !== -1) { var j = text.indexOf(htmlCommentEnd, i); if (j === -1) { j = text.length; text += "\\\n"; } var comment = text.slice(i + htmlCommentBegin.length, j); if ((comment.length > 0) && (comment[0] !== ">") && (comment[comment.length - 1] !== "-") && !comment.includes("--") && (text.slice(i, j + htmlCommentEnd.length) .search(inlineCommentRe) === -1)) { var blanks = comment .replace(/[^\r\n]/g, " ") .replace(/ ([\r\n])/g, "\\$1"); text = text.slice(0, i + htmlCommentBegin.length) + blanks + text.slice(j); } i = j + htmlCommentEnd.length; } return text; }; // Escapes a string for use in a RegExp module.exports.escapeForRegExp = function escapeForRegExp(str) { return str.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"); }; // Un-escapes Markdown content (simple algorithm; not a parser) var escapedMarkdownRe = /\\./g; module.exports.unescapeMarkdown = function unescapeMarkdown(markdown, replacement) { return markdown.replace(escapedMarkdownRe, function (match) { var char = match[1]; if ("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~".includes(char)) { return replacement || char; } return match; }); }; // Returns the indent for a token function indentFor(token) { var line = token.line.replace(/^[\s>]*(> |>)/, ""); return line.length - line.trimLeft().length; } 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"; } return "atx"; } return "setext"; }; // Calls the provided function for each matching token function filterTokens(params, type, handler) { params.tokens.forEach(function forToken(token) { if (token.type === type) { handler(token); } }); } module.exports.filterTokens = filterTokens; // Get line metadata array module.exports.getLineMetadata = function getLineMetadata(params) { var lineMetadata = params.lines.map(function mapLine(line, index) { return [line, index, false, 0, false, false]; }); filterTokens(params, "fence", function forToken(token) { lineMetadata[token.map[0]][3] = 1; lineMetadata[token.map[1] - 1][3] = -1; for (var i = token.map[0] + 1; i < token.map[1] - 1; i++) { lineMetadata[i][2] = true; } }); filterTokens(params, "code_block", function forToken(token) { for (var i = token.map[0]; i < token.map[1]; i++) { lineMetadata[i][2] = true; } }); filterTokens(params, "table_open", function forToken(token) { for (var i = token.map[0]; i < token.map[1]; i++) { lineMetadata[i][4] = true; } }); filterTokens(params, "list_item_open", function forToken(token) { for (var i = token.map[0]; i < token.map[1]; i++) { lineMetadata[i][5] = true; } }); return lineMetadata; }; // Calls the provided function for each line (with context) module.exports.forEachLine = function forEachLine(lineMetadata, handler) { lineMetadata.forEach(function forMetadata(metadata) { // Parameters: line, lineIndex, inCode, onFence, inTable handler.apply(void 0, metadata); }); }; // Returns (nested) lists as a flat array (in order) module.exports.flattenLists = function flattenLists(params) { var flattenedLists = []; var stack = []; var current = null; var lastWithMap = { "map": [0, 1] }; params.tokens.forEach(function forToken(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": stack.length - 1, "lastLineIndex": -1, "insert": flattenedLists.length }; } 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(); } else if (token.type === "list_item_open") { // Add list item current.items.push(token); } 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) { var 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); } }); }; // Calls the provided function for each inline code span's content module.exports.forEachInlineCodeSpan = function forEachInlineCodeSpan(input, handler) { var currentLine = 0; var currentColumn = 0; var index = 0; while (index < input.length) { var startIndex = -1; var startLine = -1; var startColumn = -1; var tickCount = 0; var currentTicks = 0; var state = "normal"; // Deliberate <= so trailing 0 completes the last span (ex: "text `code`") for (; index <= input.length; index++) { var 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 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++; } } if (startIndex >= 0) { // Restart loop after unmatched start backticks (ex: "`text``code``") index = startIndex; currentLine = startLine; currentColumn = startColumn; } } }; // Adds a generic error object via the onError callback function addError(onError, lineNumber, detail, context, range, fixInfo) { onError({ lineNumber: lineNumber, detail: detail, context: context, range: range, fixInfo: fixInfo }); } 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); } }; // 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); }; // Returns a range object for a line by applying a RegExp module.exports.rangeFromRegExp = function rangeFromRegExp(line, regexp) { var range = null; var match = line.match(regexp); if (match) { var column = match.index + 1; var length_1 = match[0].length; if (match[2]) { column += match[1].length; length_1 -= match[1].length; } range = [column, length_1]; } return range; }; // Determines if the front matter includes a title module.exports.frontMatterHasTitle = function frontMatterHasTitle(frontMatterLines, frontMatterTitlePattern) { var ignoreFrontMatter = (frontMatterTitlePattern !== undefined) && !frontMatterTitlePattern; var frontMatterTitleRe = new RegExp(frontMatterTitlePattern || "^\\s*title\\s*[:=]", "i"); return !ignoreFrontMatter && frontMatterLines.some(function (line) { return frontMatterTitleRe.test(line); }); }; // Gets the most common line ending, falling back to platform default function getPreferredLineEnding(input) { var cr = 0; var lf = 0; var crlf = 0; var endings = input.match(newLineRe) || []; endings.forEach(function (ending) { // eslint-disable-next-line default-case switch (ending) { case "\r": cr++; break; case "\n": lf++; break; case "\r\n": crlf++; break; } }); var preferredLineEnding = null; if (!cr && !lf && !crlf) { preferredLineEnding = os.EOL; } 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 fixInfo object function normalizeFixInfo(fixInfo, lineNumber) { return { "lineNumber": fixInfo.lineNumber || lineNumber, "editColumn": fixInfo.editColumn || 1, "deleteCount": fixInfo.deleteCount || 0, "insertText": fixInfo.insertText || "" }; } // Fixes the specifide error on a line function applyFix(line, fixInfo, lineEnding) { var _a = normalizeFixInfo(fixInfo), editColumn = _a.editColumn, deleteCount = _a.deleteCount, insertText = _a.insertText; var 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; // Applies as many fixes as possible to the input lines module.exports.applyFixes = function applyFixes(input, errors) { var lineEnding = getPreferredLineEnding(input); var lines = input.split(newLineRe); // Normalize fixInfo objects var fixInfos = errors .filter(function (error) { return error.fixInfo; }) .map(function (error) { return normalizeFixInfo(error.fixInfo, error.lineNumber); }); // Sort bottom-to-top, line-deletes last, right-to-left, long-to-short fixInfos.sort(function (a, b) { var aDeletingLine = (a.deleteCount === -1); var 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) var lastFixInfo = {}; fixInfos = fixInfos.filter(function (fixInfo) { var 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(function (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(function (fixInfo) { return fixInfo.lineNumber; }); // Apply all (remaining/updated) fixes var lastLineIndex = -1; var lastEditIndex = -1; fixInfos.forEach(function (fixInfo) { var lineNumber = fixInfo.lineNumber, editColumn = fixInfo.editColumn, deleteCount = fixInfo.deleteCount; var lineIndex = lineNumber - 1; var editIndex = editColumn - 1; if ((lineIndex !== lastLineIndex) || ((editIndex + deleteCount) < lastEditIndex) || (deleteCount === -1)) { lines[lineIndex] = applyFix(lines[lineIndex], fixInfo, lineEnding); } lastLineIndex = lineIndex; lastEditIndex = editIndex; }); // Return corrected input return lines.filter(function (line) { return line !== null; }).join(lineEnding); }; },{"os":51}],3:[function(require,module,exports){ // @ts-check "use strict"; var lineMetadata = null; module.exports.lineMetadata = function (value) { if (value) { lineMetadata = value; } return lineMetadata; }; var flattenedLists = null; module.exports.flattenedLists = function (value) { if (value) { flattenedLists = value; } return flattenedLists; }; module.exports.clear = function () { lineMetadata = null; flattenedLists = null; }; },{}],4:[function(require,module,exports){ // @ts-check "use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var fs = require("fs"); var path = require("path"); var URL = require("url").URL; var markdownIt = require("markdown-it"); var rules = require("./rules"); var helpers = require("../helpers"); var cache = require("./cache"); var deprecatedRuleNames = ["MD002"]; // Validates the list of rules for structure and reuse function validateRuleList(ruleList) { var result = null; if (ruleList.length === rules.length) { // No need to validate if only using built-in rules return result; } var allIds = {}; ruleList.forEach(function forRule(rule, index) { var customIndex = index - rules.length; function newError(property) { return new Error("Property '" + property + "' of custom rule at index " + customIndex + " is incorrect."); } ["names", "tags"].forEach(function forProperty(property) { var 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) { var property = propertyInfo[0]; var value = rule[property]; if (!result && (!value || (typeof value !== propertyInfo[1]))) { result = newError(property); } }); if (!result && rule.information) { if (Object.getPrototypeOf(rule.information) !== URL.prototype) { result = newError("information"); } } if (!result) { rule.names.forEach(function forName(name) { var 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) { var 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; }); } }); return result; } // Class for results with toString for pretty display function newResults(ruleList) { function Results() { } Results.prototype.toString = function toString(useAlias) { var that = this; var ruleNameToRule = null; var results = []; Object.keys(that).forEach(function forFile(file) { var fileResults = that[file]; if (Array.isArray(fileResults)) { fileResults.forEach(function forResult(result) { var 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) { var ruleName = rule.names[0].toUpperCase(); ruleNameToRule[ruleName] = rule; }); } Object.keys(fileResults).forEach(function forRule(ruleName) { var rule = ruleNameToRule[ruleName.toUpperCase()]; var ruleResults = fileResults[ruleName]; ruleResults.forEach(function forLine(lineNumber) { var nameIndex = Math.min(useAlias ? 1 : 0, rule.names.length - 1); var result = file + ": " + lineNumber + ": " + rule.names[nameIndex] + " " + rule.description; results.push(result); }); }); } }); return results.join("\n"); }; return new Results(); } // Remove front matter (if present at beginning of content) function removeFrontMatter(content, frontMatter) { var frontMatterLines = []; if (frontMatter) { var frontMatterMatch = content.match(frontMatter); if (frontMatterMatch && !frontMatterMatch.index) { var contentMatched = frontMatterMatch[0]; content = content.slice(contentMatched.length); frontMatterLines = contentMatched.split(helpers.newLineRe); if (frontMatterLines.length && (frontMatterLines[frontMatterLines.length - 1] === "")) { frontMatterLines.length--; } } } return { "content": content, "frontMatterLines": frontMatterLines }; } // Annotate tokens with line/lineNumber function annotateTokens(tokens, lines) { var tbodyMap = null; tokens.forEach(function forToken(token) { // Handle missing maps for table body if (token.type === "tbody_open") { tbodyMap = token.map.slice(); } else if ((token.type === "tr_close") && tbodyMap) { tbodyMap[0]++; } else if (token.type === "tbody_close") { tbodyMap = null; } if (tbodyMap && !token.map) { token.map = tbodyMap.slice(); } // 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 var lineNumber_1 = token.lineNumber; var codeSpanExtraLines_1 = []; helpers.forEachInlineCodeSpan(token.content, function handleInlineCodeSpan(code) { codeSpanExtraLines_1.push(code.split(helpers.newLineRe).length - 1); }); (token.children || []).forEach(function forChild(child) { child.lineNumber = lineNumber_1; child.line = lines[lineNumber_1 - 1]; if ((child.type === "softbreak") || (child.type === "hardbreak")) { lineNumber_1++; } else if (child.type === "code_inline") { lineNumber_1 += codeSpanExtraLines_1.shift(); } }); } }); } // Map rule names/tags to canonical rule name function mapAliasToRuleNames(ruleList) { var aliasToRuleNames = {}; // const tagToRuleNames = {}; ruleList.forEach(function forRule(rule) { var 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) { var nameUpper = name.toUpperCase(); aliasToRuleNames[nameUpper] = [ruleName]; }); rule.tags.forEach(function forTag(tag) { var tagUpper = tag.toUpperCase(); var 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(", ")); // }); return aliasToRuleNames; } // Apply (and normalize) config function getEffectiveConfig(ruleList, config, aliasToRuleNames) { var defaultKey = Object.keys(config).filter(function (key) { return key.toUpperCase() === "DEFAULT"; }); var ruleDefault = (defaultKey.length === 0) || !!config[defaultKey[0]]; var effectiveConfig = {}; ruleList.forEach(function (rule) { var ruleName = rule.names[0].toUpperCase(); effectiveConfig[ruleName] = ruleDefault; }); deprecatedRuleNames.forEach(function (ruleName) { effectiveConfig[ruleName] = false; }); Object.keys(config).forEach(function (key) { var value = config[key]; if (value) { if (!(value instanceof Object)) { value = {}; } } else { value = false; } var keyUpper = key.toUpperCase(); (aliasToRuleNames[keyUpper] || []).forEach(function (ruleName) { effectiveConfig[ruleName] = value; }); }); return effectiveConfig; } // Create mapping of enabled rules per line function getEnabledRulesPerLineNumber(ruleList, lines, frontMatterLines, noInlineConfig, effectiveConfig, aliasToRuleNames) { var enabledRules = {}; var allRuleNames = []; ruleList.forEach(function forRule(rule) { var ruleName = rule.names[0].toUpperCase(); allRuleNames.push(ruleName); enabledRules[ruleName] = !!effectiveConfig[ruleName]; }); var capturedRules = enabledRules; function forMatch(match) { var action = match[1].toUpperCase(); if (action === "CAPTURE") { capturedRules = __assign({}, enabledRules); } else if (action === "RESTORE") { enabledRules = __assign({}, capturedRules); } else { var enabled_1 = (action === "ENABLE"); var items = match[2] ? match[2].trim().toUpperCase().split(/\s+/) : allRuleNames; items.forEach(function forItem(nameUpper) { (aliasToRuleNames[nameUpper] || []).forEach(function forRule(ruleName) { enabledRules[ruleName] = enabled_1; }); }); } } var enabledRulesPerLineNumber = new Array(1 + frontMatterLines.length); lines.forEach(function forLine(line) { if (!noInlineConfig) { var match = helpers.inlineCommentRe.exec(line); if (match) { enabledRules = __assign({}, enabledRules); while (match) { forMatch(match); match = helpers.inlineCommentRe.exec(line); } } } enabledRulesPerLineNumber.push(enabledRules); }); return enabledRulesPerLineNumber; } // Array.sort comparison for objects in errors array function lineNumberComparison(a, b) { return a.lineNumber - b.lineNumber; } // Function to return true for all inputs function filterAllValues() { return true; } // Function to return unique values from a sorted errors array function uniqueFilterForSortedErrors(value, index, array) { return (index === 0) || (value.lineNumber > array[index - 1].lineNumber); } // Lints a single string 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 var removeFrontMatterResult = removeFrontMatter(content, frontMatter); var frontMatterLines = removeFrontMatterResult.frontMatterLines; // Ignore the content of HTML comments content = helpers.clearHtmlCommentText(removeFrontMatterResult.content); // Parse content into tokens and lines var tokens = md.parse(content, {}); var lines = content.split(helpers.newLineRe); annotateTokens(tokens, lines); var aliasToRuleNames = mapAliasToRuleNames(ruleList); var effectiveConfig = getEffectiveConfig(ruleList, config, aliasToRuleNames); var enabledRulesPerLineNumber = getEnabledRulesPerLineNumber(ruleList, lines, frontMatterLines, noInlineConfig, effectiveConfig, aliasToRuleNames); // Create parameters for rules var params = { name: name, tokens: tokens, lines: lines, frontMatterLines: frontMatterLines }; cache.lineMetadata(helpers.getLineMetadata(params)); cache.flattenedLists(helpers.flattenLists(params)); // Function to run for each rule var result = (resultVersion === 0) ? {} : []; function forRule(rule) { // Configure rule var ruleNameFriendly = rule.names[0]; var ruleName = ruleNameFriendly.toUpperCase(); params.config = effectiveConfig[ruleName]; function throwError(property) { throw new Error("Property '" + property + "' of onError parameter is incorrect."); } var errors = []; function onError(errorInfo) { if (!errorInfo || !helpers.isNumber(errorInfo.lineNumber) || (errorInfo.lineNumber < 1) || (errorInfo.lineNumber > lines.length)) { throwError("lineNumber"); } 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"); } var fixInfo = errorInfo.fixInfo; var 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; } var 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; } } errors.push({ "lineNumber": errorInfo.lineNumber + frontMatterLines.length, "detail": errorInfo.detail || null, "context": errorInfo.context || null, "range": errorInfo.range || null, "fixInfo": fixInfo ? cleanFixInfo : null }); } // Call (possibly external) rule function if (handleRuleFailures) { try { rule["function"](params, onError); } catch (ex) { onError({ "lineNumber": 1, "detail": "This rule threw an exception: " + ex.message }); } } else { rule["function"](params, onError); } // Record any errors (significant performance benefit from length check) if (errors.length) { errors.sort(lineNumberComparison); var filteredErrors = errors .filter((resultVersion === 3) ? filterAllValues : uniqueFilterForSortedErrors) .filter(function removeDisabledRules(error) { return enabledRulesPerLineNumber[error.lineNumber][ruleName]; }) .map(function formatResults(error) { if (resultVersion === 0) { return error.lineNumber; } var errorObject = {}; errorObject.lineNumber = error.lineNumber; if (resultVersion === 1) { errorObject.ruleName = ruleNameFriendly; errorObject.ruleAlias = rule.names[1] || rule.names[0]; } else { errorObject.ruleNames = rule.names; } errorObject.ruleDescription = rule.description; errorObject.ruleInformation = rule.information ? rule.information.href : null; errorObject.errorDetail = error.detail; errorObject.errorContext = error.context; errorObject.errorRange = error.range; if (resultVersion === 3) { errorObject.fixInfo = error.fixInfo; } return errorObject; }); if (filteredErrors.length) { if (resultVersion === 0) { result[ruleNameFriendly] = filteredErrors; } else { Array.prototype.push.apply(result, filteredErrors); } } } } // Run all rules try { ruleList.forEach(forRule); } catch (ex) { cache.clear(); return callback(ex); } cache.clear(); return callback(null, result); } // Lints a single file function lintFile(ruleList, file, md, config, frontMatter, handleRuleFailures, noInlineConfig, resultVersion, synchronous, callback) { function lintContentWrapper(err, content) { if (err) { return callback(err); } return lintContent(ruleList, file, content, md, config, frontMatter, handleRuleFailures, noInlineConfig, resultVersion, callback); } // Make a/synchronous call to read file if (synchronous) { lintContentWrapper(null, fs.readFileSync(file, helpers.utf8Encoding)); } else { fs.readFile(file, helpers.utf8Encoding, lintContentWrapper); } } // Lints files and strings function lintInput(options, synchronous, callback) { // Normalize inputs options = options || {}; callback = callback || function noop() { }; var ruleList = rules.concat(options.customRules || []); var ruleErr = validateRuleList(ruleList); if (ruleErr) { return callback(ruleErr); } var files = []; if (Array.isArray(options.files)) { files = options.files.slice(); } else if (options.files) { files = [String(options.files)]; } var strings = options.strings || {}; var stringsKeys = Object.keys(strings); var config = options.config || { "default": true }; var frontMatter = (options.frontMatter === undefined) ? helpers.frontMatterRe : options.frontMatter; var handleRuleFailures = !!options.handleRuleFailures; var noInlineConfig = !!options.noInlineConfig; var resultVersion = (options.resultVersion === undefined) ? 2 : options.resultVersion; var md = markdownIt({ "html": true }); var markdownItPlugins = options.markdownItPlugins || []; markdownItPlugins.forEach(function forPlugin(plugin) { // @ts-ignore md.use.apply(md, plugin); }); var results = newResults(ruleList); // Helper to lint the next string or file /* eslint-disable consistent-return */ function lintNextItem() { var iterating = true; var item = null; function lintNextItemCallback(err, result) { if (err) { iterating = false; return callback(err); } results[item] = result; return iterating || lintNextItem(); } while (iterating) { if ((item = stringsKeys.shift())) { lintContent(ruleList, item, strings[item] || "", md, config, frontMatter, handleRuleFailures, noInlineConfig, resultVersion, lintNextItemCallback); } else if ((item = files.shift())) { iterating = synchronous; lintFile(ruleList, item, md, config, frontMatter, handleRuleFailures, noInlineConfig, resultVersion, synchronous, lintNextItemCallback); } else { return callback(null, results); } } } return lintNextItem(); } /** * Lint specified Markdown files. * * @param {Object} options Configuration options. * @param {Function} callback Callback (err, result) function. * @returns {void} */ function markdownlint(options, callback) { return lintInput(options, false, callback); } /** * Lint specified Markdown files synchronously. * * @param {Object} options Configuration options. * @returns {Object} Result object. */ function markdownlintSync(options) { var results = null; lintInput(options, true, function callback(error, res) { if (error) { throw error; } results = res; }); return results; } // Parses the content of a configuration file function parseConfiguration(name, content, parsers) { var config = null; var message = ""; var errors = []; // Try each parser (parsers || [JSON.parse]).every(function (parser) { try { config = parser(content); } catch (ex) { errors.push(ex.message); } return !config; }); // Message if unable to parse if (!config) { errors.unshift("Unable to parse '" + name + "'"); message = errors.join("; "); } return { config: config, message: message }; } /** * Read specified configuration file. * * @param {String} file Configuration file name/path. * @param {Array} [parsers] Optional parsing function(s). * @param {Function} callback Callback (err, result) function. * @returns {void} */ function readConfig(file, parsers, callback) { if (!callback) { // @ts-ignore callback = parsers; parsers = null; } // Read file fs.readFile(file, helpers.utf8Encoding, function (err, content) { if (err) { return callback(err); } // Try to parse file var _a = parseConfiguration(file, content, parsers), config = _a.config, message = _a.message; if (!config) { return callback(new Error(message)); } // Extend configuration var configExtends = config["extends"]; if (configExtends) { delete config["extends"]; var extendsFile = path.resolve(path.dirname(file), configExtends); return readConfig(extendsFile, parsers, function (errr, extendsConfig) { if (errr) { return callback(errr); } return callback(null, __assign(__assign({}, extendsConfig), config)); }); } return callback(null, config); }); } /** * Read specified configuration file synchronously. * * @param {String} file Configuration file name/path. * @param {Array} [parsers] Optional parsing function(s). * @returns {Object} Configuration object. */ function readConfigSync(file, parsers) { // Read file var content = fs.readFileSync(file, helpers.utf8Encoding); // Try to parse file var _a = parseConfiguration(file, content, parsers), config = _a.config, message = _a.message; if (!config) { throw new Error(message); } // Extend configuration var configExtends = config["extends"]; if (configExtends) { delete config["extends"]; return __assign(__assign({}, readConfigSync(path.resolve(path.dirname(file), configExtends), parsers)), config); } return config; } // Export a/synchronous APIs markdownlint.sync = markdownlintSync; markdownlint.readConfig = readConfig; markdownlint.readConfigSync = readConfigSync; module.exports = markdownlint; },{"../helpers":2,"./cache":3,"./rules":48,"fs":50,"markdown-it":1,"path":52,"url":58}],5:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorDetailIf = _a.addErrorDetailIf, filterTokens = _a.filterTokens; 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) { var prevLevel = 0; filterTokens(params, "heading_open", function forToken(token) { var level = parseInt(token.tag.slice(1), 10); if (prevLevel && (level > prevLevel)) { addErrorDetailIf(onError, token.lineNumber, "h" + (prevLevel + 1), "h" + level); } prevLevel = level; }); } }; },{"../helpers":2}],6:[function(require,module,exports){ // @ts-check "use strict"; var addErrorDetailIf = require("../helpers").addErrorDetailIf; 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) { var level = params.config.level || 1; var 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; }); } }; },{"../helpers":2}],7:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorDetailIf = _a.addErrorDetailIf, filterTokens = _a.filterTokens, headingStyleFor = _a.headingStyleFor; module.exports = { "names": ["MD003", "heading-style", "header-style"], "description": "Heading style", "tags": ["headings", "headers"], "function": function MD003(params, onError) { var style = params.config.style || "consistent"; filterTokens(params, "heading_open", function forToken(token) { var styleForToken = headingStyleFor(token); if (style === "consistent") { style = styleForToken; } if (styleForToken !== style) { var h12 = /h[12]/.test(token.tag); var setextWithAtx = (style === "setext_with_atx") && ((h12 && (styleForToken === "setext")) || (!h12 && (styleForToken === "atx"))); var setextWithAtxClosed = (style === "setext_with_atx_closed") && ((h12 && (styleForToken === "setext")) || (!h12 && (styleForToken === "atx_closed"))); if (!setextWithAtx && !setextWithAtxClosed) { var 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); } } }); } }; },{"../helpers":2}],8:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorDetailIf = _a.addErrorDetailIf, listItemMarkerRe = _a.listItemMarkerRe, rangeFromRegExp = _a.rangeFromRegExp; var flattenedLists = require("./cache").flattenedLists; // Returns the unordered list style for a list item token function unorderedListStyleFor(token) { switch (token.markup) { case "-": return "dash"; case "+": return "plus"; // case "*": default: return "asterisk"; } } module.exports = { "names": ["MD004", "ul-style"], "description": "Unordered list style", "tags": ["bullet", "ul"], "function": function MD004(params, onError) { var style = params.config.style || "consistent"; var expectedStyle = style; var nestingStyles = []; flattenedLists().forEach(function (list) { if (list.unordered) { if (expectedStyle === "consistent") { expectedStyle = unorderedListStyleFor(list.items[0]); } list.items.forEach(function (item) { var itemStyle = unorderedListStyleFor(item); if (style === "sublist") { var nesting = list.nesting; if (!nestingStyles[nesting] && (itemStyle !== nestingStyles[nesting - 1])) { nestingStyles[nesting] = itemStyle; } else { addErrorDetailIf(onError, item.lineNumber, nestingStyles[nesting], itemStyle, null, null, rangeFromRegExp(item.line, listItemMarkerRe)); } } else { addErrorDetailIf(onError, item.lineNumber, expectedStyle, itemStyle, null, null, rangeFromRegExp(item.line, listItemMarkerRe)); } }); } }); } }; },{"../helpers":2,"./cache":3}],9:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addError = _a.addError, addErrorDetailIf = _a.addErrorDetailIf, indentFor = _a.indentFor, listItemMarkerRe = _a.listItemMarkerRe, orderedListItemMarkerRe = _a.orderedListItemMarkerRe, rangeFromRegExp = _a.rangeFromRegExp; var flattenedLists = require("./cache").flattenedLists; 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(function (list) { var expectedIndent = list.indent; var expectedEnd = 0; var actualEnd = -1; var endMatching = false; list.items.forEach(function (item) { var actualIndent = indentFor(item); if (list.unordered) { addErrorDetailIf(onError, item.lineNumber, expectedIndent, actualIndent, null, null, rangeFromRegExp(item.line, listItemMarkerRe)); } else { var match = orderedListItemMarkerRe.exec(item.line); actualEnd = match && match[0].length; expectedEnd = expectedEnd || actualEnd; if ((expectedIndent !== actualIndent) || endMatching) { if (expectedEnd === actualEnd) { endMatching = true; } else { var detail = endMatching ? "Expected: (" + expectedEnd + "); Actual: (" + actualEnd + ")" : "Expected: " + expectedIndent + "; Actual: " + actualIndent; addError(onError, item.lineNumber, detail, null, rangeFromRegExp(item.line, listItemMarkerRe)); } } } }); }); } }; },{"../helpers":2,"./cache":3}],10:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorDetailIf = _a.addErrorDetailIf, listItemMarkerRe = _a.listItemMarkerRe, rangeFromRegExp = _a.rangeFromRegExp; var flattenedLists = require("./cache").flattenedLists; 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(function (list) { if (list.unordered && !list.nesting && (list.indent !== 0)) { var _a = list.open, lineNumber = _a.lineNumber, line = _a.line; addErrorDetailIf(onError, lineNumber, 0, list.indent, null, null, rangeFromRegExp(line, listItemMarkerRe), { "deleteCount": line.length - line.trimLeft().length }); } }); } }; },{"../helpers":2,"./cache":3}],11:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorDetailIf = _a.addErrorDetailIf, listItemMarkerRe = _a.listItemMarkerRe, rangeFromRegExp = _a.rangeFromRegExp; var flattenedLists = require("./cache").flattenedLists; module.exports = { "names": ["MD007", "ul-indent"], "description": "Unordered list indentation", "tags": ["bullet", "ul", "indentation"], "function": function MD007(params, onError) { var optionsIndent = params.config.indent || 2; flattenedLists().forEach(function (list) { if (list.unordered && list.parentsUnordered && list.indent) { addErrorDetailIf(onError, list.open.lineNumber, list.parentIndent + optionsIndent, list.indent, null, null, rangeFromRegExp(list.open.line, listItemMarkerRe)); } }); } }; },{"../helpers":2,"./cache":3}],12:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addError = _a.addError, filterTokens = _a.filterTokens, forEachLine = _a.forEachLine, includesSorted = _a.includesSorted; var lineMetadata = require("./cache").lineMetadata; module.exports = { "names": ["MD009", "no-trailing-spaces"], "description": "Trailing spaces", "tags": ["whitespace"], "function": function MD009(params, onError) { var brSpaces = params.config.br_spaces; if (brSpaces === undefined) { brSpaces = 2; } var listItemEmptyLines = params.config.list_item_empty_lines; var allowListItemEmptyLines = (listItemEmptyLines === undefined) ? false : !!listItemEmptyLines; var listItemLineNumbers = []; if (allowListItemEmptyLines) { filterTokens(params, "list_item_open", function (token) { for (var i = token.map[0]; i < token.map[1]; i++) { listItemLineNumbers.push(i + 1); } }); listItemLineNumbers.sort(function (a, b) { return a - b; }); } var expected = (brSpaces < 2) ? 0 : brSpaces; var inFencedCode = 0; forEachLine(lineMetadata(), function (line, lineIndex, inCode, onFence) { inFencedCode += onFence; var lineNumber = lineIndex + 1; var trailingSpaces = line.length - line.trimRight().length; if ((!inCode || inFencedCode) && trailingSpaces && !includesSorted(listItemLineNumbers, lineNumber)) { if (expected !== trailingSpaces) { var column = line.length - trailingSpaces + 1; addError(onError, lineNumber, "Expected: " + (expected === 0 ? "" : "0 or ") + expected + "; Actual: " + trailingSpaces, null, [column, trailingSpaces], { "editColumn": column, "deleteCount": trailingSpaces }); } } }); } }; },{"../helpers":2,"./cache":3}],13:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addError = _a.addError, forEachLine = _a.forEachLine; var lineMetadata = require("./cache").lineMetadata; var tabRe = /\t+/g; module.exports = { "names": ["MD010", "no-hard-tabs"], "description": "Hard tabs", "tags": ["whitespace", "hard_tab"], "function": function MD010(params, onError) { var codeBlocks = params.config.code_blocks; var includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks; forEachLine(lineMetadata(), function (line, lineIndex, inCode) { if (!inCode || includeCodeBlocks) { var match = null; while ((match = tabRe.exec(line)) !== null) { var column = match.index + 1; var length_1 = match[0].length; addError(onError, lineIndex + 1, "Column: " + column, null, [column, length_1], { "editColumn": column, "deleteCount": length_1, "insertText": "".padEnd(length_1) }); } } }); } }; },{"../helpers":2,"./cache":3}],14:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addError = _a.addError, forEachInlineChild = _a.forEachInlineChild, unescapeMarkdown = _a.unescapeMarkdown; var reversedLinkRe = /\(([^)]+)\)\[([^\]^][^\]]*)]/g; module.exports = { "names": ["MD011", "no-reversed-links"], "description": "Reversed link syntax", "tags": ["links"], "function": function MD011(params, onError) { forEachInlineChild(params, "text", function (token) { var lineNumber = token.lineNumber, content = token.content; var match = null; while ((match = reversedLinkRe.exec(content)) !== null) { var reversedLink = match[0], linkText = match[1], linkDestination = match[2]; var line = params.lines[lineNumber - 1]; var column = unescapeMarkdown(line).indexOf(reversedLink) + 1; var length_1 = reversedLink.length; addError(onError, lineNumber, reversedLink, null, [column, length_1], { "editColumn": column, "deleteCount": length_1, "insertText": "[" + linkText + "](" + linkDestination + ")" }); } }); } }; },{"../helpers":2}],15:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorDetailIf = _a.addErrorDetailIf, forEachLine = _a.forEachLine; var lineMetadata = require("./cache").lineMetadata; module.exports = { "names": ["MD012", "no-multiple-blanks"], "description": "Multiple consecutive blank lines", "tags": ["whitespace", "blank_lines"], "function": function MD012(params, onError) { var maximum = params.config.maximum || 1; var count = 0; forEachLine(lineMetadata(), function (line, lineIndex, inCode) { count = (inCode || line.trim().length) ? 0 : count + 1; if (maximum < count) { addErrorDetailIf(onError, lineIndex + 1, maximum, count, null, null, null, { "deleteCount": -1 }); } }); } }; },{"../helpers":2,"./cache":3}],16:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorDetailIf = _a.addErrorDetailIf, filterTokens = _a.filterTokens, forEachHeading = _a.forEachHeading, forEachLine = _a.forEachLine, includesSorted = _a.includesSorted, rangeFromRegExp = _a.rangeFromRegExp; var lineMetadata = require("./cache").lineMetadata; var longLineRePrefix = "^(.{"; var longLineRePostfix = "})(.*\\s.*)$"; var labelRe = /^\s*\[.*[^\\]]:/; var linkOnlyLineRe = /^[es]*lT?L[ES]*$/; var tokenTypeMap = { "em_open": "e", "em_close": "E", "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) { var lineLength = params.config.line_length || 80; var headingLineLength = params.config.heading_line_length || lineLength; var codeLineLength = params.config.code_block_line_length || lineLength; var longLineRe = new RegExp(longLineRePrefix + lineLength + longLineRePostfix); var longHeadingLineRe = new RegExp(longLineRePrefix + headingLineLength + longLineRePostfix); var longCodeLineRe = new RegExp(longLineRePrefix + codeLineLength + longLineRePostfix); var codeBlocks = params.config.code_blocks; var includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks; var tables = params.config.tables; var includeTables = (tables === undefined) ? true : !!tables; var headings = params.config.headings; if (headings === undefined) { headings = params.config.headers; } var includeHeadings = (headings === undefined) ? true : !!headings; var headingLineNumbers = []; forEachHeading(params, function (heading) { headingLineNumbers.push(heading.lineNumber); }); var linkOnlyLineNumbers = []; filterTokens(params, "inline", function (token) { var childTokenTypes = ""; token.children.forEach(function (child) { if (child.type !== "text" || child.content !== "") { childTokenTypes += tokenTypeMap[child.type] || "x"; } }); if (linkOnlyLineRe.test(childTokenTypes)) { linkOnlyLineNumbers.push(token.lineNumber); } }); forEachLine(lineMetadata(), function (line, lineIndex, inCode, onFence, inTable) { var lineNumber = lineIndex + 1; var isHeading = includesSorted(headingLineNumbers, lineNumber); var length = inCode ? codeLineLength : (isHeading ? headingLineLength : lineLength); var lengthRe = inCode ? longCodeLineRe : (isHeading ? longHeadingLineRe : longLineRe); if ((includeCodeBlocks || !inCode) && (includeTables || !inTable) && (includeHeadings || !isHeading) && !includesSorted(linkOnlyLineNumbers, lineNumber) && lengthRe.test(line) && !labelRe.test(line)) { addErrorDetailIf(onError, lineNumber, length, line.length, null, null, rangeFromRegExp(line, lengthRe)); } }); } }; },{"../helpers":2,"./cache":3}],17:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, filterTokens = _a.filterTokens; var dollarCommandRe = /^(\s*)(\$\s+)/; function addErrorIfPreviousWasCommand(onError, previous) { if (previous) { var lineNumber = previous.lineNumber, lineTrim = previous.lineTrim, column = previous.column, length_1 = previous.length; addErrorContext(onError, lineNumber, lineTrim, null, null, [column, length_1], { "editColumn": column, "deleteCount": length_1 }); } } 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(function (type) { filterTokens(params, type, function (token) { var previous = null; var margin = (token.type === "fence") ? 1 : 0; for (var i = token.map[0] + margin; i < token.map[1] - margin; i++) { var line = params.lines[i]; var lineTrim = line.trim(); var match = dollarCommandRe.exec(line); if (!lineTrim || match) { addErrorIfPreviousWasCommand(onError, previous); } previous = match ? { "lineNumber": i + 1, "lineTrim": lineTrim, "column": match[1].length + 1, "length": match[2].length } : null; } addErrorIfPreviousWasCommand(onError, previous); }); }); } }; },{"../helpers":2}],18:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, forEachLine = _a.forEachLine; var lineMetadata = require("./cache").lineMetadata; 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(), function (line, lineIndex, inCode) { if (!inCode && /^#+[^#\s]/.test(line) && !/#\s*$/.test(line)) { var hashCount = /^#+/.exec(line)[0].length; addErrorContext(onError, lineIndex + 1, line.trim(), null, null, [1, hashCount + 1], { "editColumn": hashCount + 1, "insertText": " " }); } }); } }; },{"../helpers":2,"./cache":3}],19:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, filterTokens = _a.filterTokens, headingStyleFor = _a.headingStyleFor; 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", function (token) { if (headingStyleFor(token) === "atx") { var line = token.line, lineNumber = token.lineNumber; var match = /^(#+)(\s{2,})(?:\S)/.exec(line); if (match) { var hashLength = match[1]["length"], spacesLength = match[2]["length"]; addErrorContext(onError, lineNumber, line.trim(), null, null, [1, hashLength + spacesLength + 1], { "editColumn": hashLength + 1, "deleteCount": spacesLength - 1 }); } } }); } }; },{"../helpers":2}],20:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, forEachLine = _a.forEachLine; var lineMetadata = require("./cache").lineMetadata; 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(), function (line, lineIndex, inCode) { if (!inCode) { var match = /^(#+)(\s*)([^#]*?[^#\\])(\s*)((?:\\#)?)(#+)(\s*)$/.exec(line); if (match) { var leftHash = match[1], leftSpaceLength = match[2]["length"], content = match[3], rightSpaceLength = match[4]["length"], rightEscape = match[5], rightHash = match[6], trailSpaceLength = match[7]["length"]; var leftHashLength = leftHash.length; var rightHashLength = rightHash.length; var left = !leftSpaceLength; var right = !rightSpaceLength || rightEscape; var rightEscapeReplacement = rightEscape ? rightEscape + " " : ""; if (left || right) { var 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 }); } } } }); } }; },{"../helpers":2,"./cache":3}],21:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, filterTokens = _a.filterTokens, headingStyleFor = _a.headingStyleFor; 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", function (token) { if (headingStyleFor(token) === "atx_closed") { var line = token.line, lineNumber = token.lineNumber; var match = /^(#+)(\s+)([^#]+?)(\s+)(#+)(\s*)$/.exec(line); if (match) { var leftHash = match[1], leftSpaceLength = match[2]["length"], content = match[3], rightSpaceLength = match[4]["length"], rightHash = match[5], trailSpaceLength = match[6]["length"]; var left = leftSpaceLength > 1; var right = rightSpaceLength > 1; if (left || right) { var length_1 = line.length; var leftHashLength = leftHash.length; var rightHashLength = rightHash.length; var range = left ? [ 1, leftHashLength + leftSpaceLength + 1 ] : [ length_1 - trailSpaceLength - rightHashLength - rightSpaceLength, rightSpaceLength + rightHashLength + 1 ]; addErrorContext(onError, lineNumber, line.trim(), left, right, range, { "editColumn": 1, "deleteCount": length_1, "insertText": leftHash + " " + content + " " + rightHash }); } } } }); } }; },{"../helpers":2}],22:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorDetailIf = _a.addErrorDetailIf, filterTokens = _a.filterTokens, isBlankLine = _a.isBlankLine; 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) { var linesAbove = params.config.lines_above; if (linesAbove === undefined) { linesAbove = 1; } var linesBelow = params.config.lines_below; if (linesBelow === undefined) { linesBelow = 1; } var lines = params.lines; filterTokens(params, "heading_open", function (token) { var _a = token.map, topIndex = _a[0], nextIndex = _a[1]; var actualAbove = 0; for (var 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") }); var actualBelow = 0; for (var 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") }); }); } }; },{"../helpers":2}],23:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, filterTokens = _a.filterTokens; var spaceBeforeHeadingRe = /^((?:\s+)|(?:[>\s]+\s\s))[^>\s]/; 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) { var lineNumber = token.lineNumber, line = token.line; var match = line.match(spaceBeforeHeadingRe); if (match) { var prefixAndFirstChar = match[0], prefix = match[1]; var deleteCount = prefix.length; var prefixLengthNoSpace = prefix.trimRight().length; if (prefixLengthNoSpace) { deleteCount -= prefixLengthNoSpace - 1; } addErrorContext(onError, lineNumber, line, null, null, [1, prefixAndFirstChar.length], { "editColumn": prefixLengthNoSpace + 1, "deleteCount": deleteCount }); } }); } }; },{"../helpers":2}],24:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, forEachHeading = _a.forEachHeading; 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) { var siblingsOnly = params.config.siblings_only || params.config.allow_different_nesting || false; var knownContents = [null, []]; var lastLevel = 1; var knownContent = knownContents[lastLevel]; forEachHeading(params, function (heading, content) { if (siblingsOnly) { var newLevel = heading.tag.slice(1); while (lastLevel < newLevel) { lastLevel++; knownContents[lastLevel] = []; } while (lastLevel > newLevel) { knownContents[lastLevel] = []; lastLevel--; } knownContent = knownContents[newLevel]; } if (knownContent.includes(content)) { addErrorContext(onError, heading.lineNumber, heading.line.trim()); } else { knownContent.push(content); } }); } }; },{"../helpers":2}],25:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, filterTokens = _a.filterTokens, frontMatterHasTitle = _a.frontMatterHasTitle; 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) { var level = params.config.level || 1; var tag = "h" + level; var foundFrontMatterTitle = frontMatterHasTitle(params.frontMatterLines, params.config.front_matter_title); var 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; } } }); } }; },{"../helpers":2}],26:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addError = _a.addError, allPunctuation = _a.allPunctuation, escapeForRegExp = _a.escapeForRegExp, forEachHeading = _a.forEachHeading; module.exports = { "names": ["MD026", "no-trailing-punctuation"], "description": "Trailing punctuation in heading", "tags": ["headings", "headers"], "function": function MD026(params, onError) { var punctuation = params.config.punctuation; if (punctuation === undefined) { punctuation = allPunctuation; } var trailingPunctuationRe = new RegExp("\\s*[" + escapeForRegExp(punctuation) + "]+$"); forEachHeading(params, function (heading) { var line = heading.line, lineNumber = heading.lineNumber; var trimmedLine = line.replace(/[\s#]*$/, ""); var match = trailingPunctuationRe.exec(trimmedLine); if (match) { var fullMatch = match[0]; var column = match.index + 1; var length_1 = fullMatch.length; addError(onError, lineNumber, "Punctuation: '" + fullMatch + "'", null, [column, length_1], { "editColumn": column, "deleteCount": length_1 }); } }); } }; },{"../helpers":2}],27:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, newLineRe = _a.newLineRe; var spaceAfterBlockQuoteRe = /^((?:\s*>)+)(\s{2,})\S/; module.exports = { "names": ["MD027", "no-multiple-space-blockquote"], "description": "Multiple spaces after blockquote symbol", "tags": ["blockquote", "whitespace", "indentation"], "function": function MD027(params, onError) { var blockquoteNesting = 0; var listItemNesting = 0; params.tokens.forEach(function (token) { var content = token.content, lineNumber = token.lineNumber, type = token.type; 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) { var lineCount = content.split(newLineRe).length; for (var i = 0; i < lineCount; i++) { var line = params.lines[lineNumber + i - 1]; var match = line.match(spaceAfterBlockQuoteRe); if (match) { var fullMatch = match[0], blockquoteLength = match[1]["length"], spaceLength = match[2]["length"]; if (!listItemNesting || (fullMatch[fullMatch.length - 1] === ">")) { addErrorContext(onError, lineNumber + i, line, null, null, [1, fullMatch.length], { "editColumn": blockquoteLength + 1, "deleteCount": spaceLength - 1 }); } } } } }); } }; },{"../helpers":2}],28:[function(require,module,exports){ // @ts-check "use strict"; var addError = require("../helpers").addError; module.exports = { "names": ["MD028", "no-blanks-blockquote"], "description": "Blank line inside blockquote", "tags": ["blockquote", "whitespace"], "function": function MD028(params, onError) { var prevToken = {}; var prevLineNumber = null; params.tokens.forEach(function forToken(token) { if ((token.type === "blockquote_open") && (prevToken.type === "blockquote_close")) { for (var lineNumber = prevLineNumber; lineNumber < token.lineNumber; lineNumber++) { addError(onError, lineNumber, null, null, null, { "deleteCount": -1 }); } } prevToken = token; if (token.type === "blockquote_open") { prevLineNumber = token.map[1] + 1; } }); } }; },{"../helpers":2}],29:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorDetailIf = _a.addErrorDetailIf, listItemMarkerRe = _a.listItemMarkerRe, orderedListItemMarkerRe = _a.orderedListItemMarkerRe, rangeFromRegExp = _a.rangeFromRegExp; var flattenedLists = require("./cache").flattenedLists; var 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) { var style = params.config.style || "one_or_ordered"; flattenedLists().forEach(function (list) { if (!list.unordered) { var listStyle_1 = style; if (listStyle_1 === "one_or_ordered") { var second = (list.items.length > 1) && orderedListItemMarkerRe.exec(list.items[1].line); listStyle_1 = (second && (second[1] !== "1")) ? "ordered" : "one"; } var number_1 = (listStyle_1 === "zero") ? 0 : 1; list.items.forEach(function (item) { var match = orderedListItemMarkerRe.exec(item.line); addErrorDetailIf(onError, item.lineNumber, String(number_1), !match || match[1], "Style: " + listStyleExamples[listStyle_1], null, rangeFromRegExp(item.line, listItemMarkerRe)); if (listStyle_1 === "ordered") { number_1++; } }); } }); } }; },{"../helpers":2,"./cache":3}],30:[function(require,module,exports){ // @ts-check "use strict"; var addErrorDetailIf = require("../helpers").addErrorDetailIf; var flattenedLists = require("./cache").flattenedLists; module.exports = { "names": ["MD030", "list-marker-space"], "description": "Spaces after list markers", "tags": ["ol", "ul", "whitespace"], "function": function MD030(params, onError) { var ulSingle = params.config.ul_single || 1; var olSingle = params.config.ol_single || 1; var ulMulti = params.config.ul_multi || 1; var olMulti = params.config.ol_multi || 1; flattenedLists().forEach(function (list) { var lineCount = list.lastLineIndex - list.open.map[0]; var allSingle = lineCount === list.items.length; var expectedSpaces = list.unordered ? (allSingle ? ulSingle : ulMulti) : (allSingle ? olSingle : olMulti); list.items.forEach(function (item) { var line = item.line, lineNumber = item.lineNumber; var match = /^[\s>]*\S+(\s*)/.exec(line); var matchLength = match[0]["length"], actualSpaces = match[1]["length"]; var fixInfo = null; if ((expectedSpaces !== actualSpaces) && (line.length > matchLength)) { fixInfo = { "editColumn": matchLength - actualSpaces + 1, "deleteCount": actualSpaces, "insertText": "".padEnd(expectedSpaces) }; } addErrorDetailIf(onError, lineNumber, expectedSpaces, actualSpaces, null, null, [1, matchLength], fixInfo); }); }); } }; },{"../helpers":2,"./cache":3}],31:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, forEachLine = _a.forEachLine, isBlankLine = _a.isBlankLine; var lineMetadata = require("./cache").lineMetadata; 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) { var listItems = params.config.list_items; var includeListItems = (listItems === undefined) ? true : !!listItems; var lines = params.lines; forEachLine(lineMetadata(), function (line, i, inCode, onFence, inTable, inItem) { var onTopFence = (onFence > 0); var onBottomFence = (onFence < 0); if ((includeListItems || !inItem) && ((onTopFence && !isBlankLine(lines[i - 1])) || (onBottomFence && !isBlankLine(lines[i + 1])))) { addErrorContext(onError, i + 1, lines[i].trim(), null, null, null, { "lineNumber": i + (onTopFence ? 1 : 2), "insertText": "\n" }); } }); } }; },{"../helpers":2,"./cache":3}],32:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, isBlankLine = _a.isBlankLine; var flattenedLists = require("./cache").flattenedLists; var quotePrefixRe = /^[>\s]*/; 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) { var lines = params.lines; flattenedLists().filter(function (list) { return !list.nesting; }).forEach(function (list) { var firstIndex = list.open.map[0]; if (!isBlankLine(lines[firstIndex - 1])) { var line = lines[firstIndex]; var quotePrefix = line.match(quotePrefixRe)[0].trimRight(); addErrorContext(onError, firstIndex + 1, line.trim(), null, null, null, { "insertText": quotePrefix + "\n" }); } var lastIndex = list.lastLineIndex - 1; if (!isBlankLine(lines[lastIndex + 1])) { var line = lines[lastIndex]; var quotePrefix = line.match(quotePrefixRe)[0].trimRight(); addErrorContext(onError, lastIndex + 1, line.trim(), null, null, null, { "lineNumber": lastIndex + 2, "insertText": quotePrefix + "\n" }); } }); } }; },{"../helpers":2,"./cache":3}],33:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addError = _a.addError, forEachLine = _a.forEachLine, unescapeMarkdown = _a.unescapeMarkdown; var lineMetadata = require("./cache").lineMetadata; var htmlElementRe = /<(([A-Za-z][A-Za-z0-9-]*)(?:\s[^>]*)?)\/?>/g; var linkDestinationRe = /]\(\s*$/; var inlineCodeRe = /^[^`]*(`+[^`]+`+[^`]+)*`+[^`]*$/; // See https://spec.commonmark.org/0.29/#autolinks var 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])?)*$/; module.exports = { "names": ["MD033", "no-inline-html"], "description": "Inline HTML", "tags": ["html"], "function": function MD033(params, onError) { var allowedElements = (params.config.allowed_elements || []) .map(function (element) { return element.toLowerCase(); }); forEachLine(lineMetadata(), function (line, lineIndex, inCode) { var match = null; // eslint-disable-next-line no-unmodified-loop-condition while (!inCode && ((match = htmlElementRe.exec(line)) !== null)) { var tag = match[0], content = match[1], element = match[2]; if (!allowedElements.includes(element.toLowerCase()) && !tag.endsWith("\\>") && !emailAddressRe.test(content)) { var prefix = line.substring(0, match.index); if (!linkDestinationRe.test(prefix) && !inlineCodeRe.test(prefix)) { var unescaped = unescapeMarkdown(prefix + "<", "_"); if (!unescaped.endsWith("_") && ((unescaped + "`").match(/`/g).length % 2)) { addError(onError, lineIndex + 1, "Element: " + element, null, [match.index + 1, tag.length]); } } } } }); } }; },{"../helpers":2,"./cache":3}],34:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, bareUrlRe = _a.bareUrlRe, filterTokens = _a.filterTokens; module.exports = { "names": ["MD034", "no-bare-urls"], "description": "Bare URL used", "tags": ["links", "url"], "function": function MD034(params, onError) { filterTokens(params, "inline", function (token) { var inLink = false; token.children.forEach(function (child) { var content = child.content, line = child.line, lineNumber = child.lineNumber, type = child.type; var 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) { var bareUrl = match[0]; var index = line.indexOf(content); var range = (index === -1) ? null : [ line.indexOf(content) + match.index + 1, bareUrl.length ]; var fixInfo = range ? { "editColumn": range[0], "deleteCount": range[1], "insertText": "<" + bareUrl + ">" } : null; addErrorContext(onError, lineNumber, bareUrl, null, null, range, fixInfo); } } }); }); } }; },{"../helpers":2}],35:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorDetailIf = _a.addErrorDetailIf, filterTokens = _a.filterTokens; module.exports = { "names": ["MD035", "hr-style"], "description": "Horizontal rule style", "tags": ["hr"], "function": function MD035(params, onError) { var style = params.config.style || "consistent"; filterTokens(params, "hr", function forToken(token) { var lineTrim = token.line.trim(); if (style === "consistent") { style = lineTrim; } addErrorDetailIf(onError, token.lineNumber, style, lineTrim); }); } }; },{"../helpers":2}],36:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, allPunctuation = _a.allPunctuation; 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) { var punctuation = params.config.punctuation || allPunctuation; var re = new RegExp("[" + punctuation + "]$"); function base(token) { if (token.type === "paragraph_open") { return function inParagraph(t) { // Always paragraph_open/inline/paragraph_close, // omit (t.type === "inline") var 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; } var state = base; params.tokens.forEach(function forToken(token) { state = state(token); }); } }; },{"../helpers":2}],37:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, forEachInlineChild = _a.forEachInlineChild; var leftSpaceRe = /(?:^|\s)(\*\*?\*?|__?_?)\s.*[^\\]\1/g; var rightSpaceRe = /(?:^|[^\\])(\*\*?\*?|__?_?).+\s\1(?:\s|$)/g; module.exports = { "names": ["MD037", "no-space-in-emphasis"], "description": "Spaces inside emphasis markers", "tags": ["whitespace", "emphasis"], "function": function MD037(params, onError) { forEachInlineChild(params, "text", function (token) { var content = token.content, lineNumber = token.lineNumber; var columnsReported = []; [leftSpaceRe, rightSpaceRe].forEach(function (spaceRe, index) { var match = null; while ((match = spaceRe.exec(content)) !== null) { var fullText = match[0], marker = match[1]; var line = params.lines[lineNumber - 1]; if (line.includes(fullText)) { var text = fullText.trim(); var column = line.indexOf(text) + 1; if (!columnsReported.includes(column)) { var length_1 = text.length; var markerLength = marker.length; var emphasized = text.slice(markerLength, length_1 - markerLength); var fixedText = "" + marker + emphasized.trim() + marker; addErrorContext(onError, lineNumber, text, index === 0, index !== 0, [column, length_1], { "editColumn": column, "deleteCount": length_1, "insertText": fixedText }); columnsReported.push(column); } } } }); }); } }; },{"../helpers":2}],38:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, filterTokens = _a.filterTokens, forEachInlineCodeSpan = _a.forEachInlineCodeSpan, newLineRe = _a.newLineRe; var leftSpaceRe = /^\s([^`]|$)/; var rightSpaceRe = /[^`]\s$/; 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", function (token) { if (token.children.some(function (child) { return child.type === "code_inline"; })) { var tokenLines_1 = params.lines.slice(token.map[0], token.map[1]); forEachInlineCodeSpan(tokenLines_1.join("\n"), function (code, lineIndex, columnIndex, tickCount) { var rangeIndex = columnIndex - tickCount; var rangeLength = code.length + (2 * tickCount); var rangeLineOffset = 0; var fixIndex = columnIndex; var fixLength = code.length; var codeLines = code.split(newLineRe); var left = leftSpaceRe.test(code); var right = !left && rightSpaceRe.test(code); if (right && (codeLines.length > 1)) { rangeIndex = 0; rangeLineOffset = codeLines.length - 1; fixIndex = 0; } if (left || right) { var codeLinesRange = codeLines[rangeLineOffset]; if (codeLines.length > 1) { rangeLength = codeLinesRange.length + tickCount; fixLength = codeLinesRange.length; } var context = tokenLines_1[lineIndex + rangeLineOffset] .substring(rangeIndex, rangeIndex + rangeLength); var codeLinesRangeTrim = codeLinesRange.trim(); var 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 }); } }); } }); } }; },{"../helpers":2}],39:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, filterTokens = _a.filterTokens; var spaceInLinkRe = /\[(?:\s+(?:[^\]]*?)\s*|(?:[^\]]*?)\s+)](?=\(\S*\))/; module.exports = { "names": ["MD039", "no-space-in-links"], "description": "Spaces inside link text", "tags": ["whitespace", "links"], "function": function MD039(params, onError) { filterTokens(params, "inline", function (token) { var children = token.children; var lineNumber = token.lineNumber; var inLink = false; var linkText = ""; var lineIndex = 0; children.forEach(function (child) { var content = child.content, type = child.type; if (type === "link_open") { inLink = true; linkText = ""; } else if (type === "link_close") { inLink = false; var left = linkText.trimLeft().length !== linkText.length; var right = linkText.trimRight().length !== linkText.length; if (left || right) { var line = params.lines[lineNumber - 1]; var match = line.slice(lineIndex).match(spaceInLinkRe); var column = match.index + lineIndex + 1; var length_1 = match[0].length; lineIndex = column + length_1 - 1; addErrorContext(onError, lineNumber, "[" + linkText + "]", left, right, [column, length_1], { "editColumn": column + 1, "deleteCount": length_1 - 2, "insertText": linkText.trim() }); } } else if ((type === "softbreak") || (type === "hardbreak")) { lineNumber++; lineIndex = 0; } else if (inLink) { linkText += content; } }); }); } }; },{"../helpers":2}],40:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, filterTokens = _a.filterTokens; 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); } }); } }; },{"../helpers":2}],41:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, frontMatterHasTitle = _a.frontMatterHasTitle; module.exports = { "names": ["MD041", "first-line-heading", "first-line-h1"], "description": "First line in file should be a top level heading", "tags": ["headings", "headers"], "function": function MD041(params, onError) { var level = params.config.level || 1; var tag = "h" + level; var foundFrontMatterTitle = frontMatterHasTitle(params.frontMatterLines, params.config.front_matter_title); if (!foundFrontMatterTitle) { params.tokens.every(function (token) { if (token.type === "html_block") { return true; } if ((token.type !== "heading_open") || (token.tag !== tag)) { addErrorContext(onError, token.lineNumber, token.line); } return false; }); } } }; },{"../helpers":2}],42:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, filterTokens = _a.filterTokens, rangeFromRegExp = _a.rangeFromRegExp; var emptyLinkRe = /\[[^\]]*](?:\((?:#?|(?:<>))\))/; module.exports = { "names": ["MD042", "no-empty-links"], "description": "No empty links", "tags": ["links"], "function": function MD042(params, onError) { filterTokens(params, "inline", function forToken(token) { var inLink = false; var linkText = ""; var emptyLink = false; token.children.forEach(function forChild(child) { if (child.type === "link_open") { inLink = true; linkText = ""; child.attrs.forEach(function forAttr(attr) { if (attr[0] === "href" && (!attr[1] || (attr[1] === "#"))) { emptyLink = true; } }); } else if (child.type === "link_close") { inLink = false; if (emptyLink) { addErrorContext(onError, child.lineNumber, "[" + linkText + "]()", null, null, rangeFromRegExp(child.line, emptyLinkRe)); } } else if (inLink) { linkText += child.content; } }); }); } }; },{"../helpers":2}],43:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorContext = _a.addErrorContext, addErrorDetailIf = _a.addErrorDetailIf, forEachHeading = _a.forEachHeading; module.exports = { "names": ["MD043", "required-headings", "required-headers"], "description": "Required heading structure", "tags": ["headings", "headers"], "function": function MD043(params, onError) { var requiredHeadings = params.config.headings || params.config.headers; if (requiredHeadings) { var levels_1 = {}; [1, 2, 3, 4, 5, 6].forEach(function forLevel(level) { levels_1["h" + level] = "######".substr(-level); }); var i_1 = 0; var optional_1 = false; var errorCount_1 = 0; forEachHeading(params, function forHeading(heading, content) { if (!errorCount_1) { var actual = levels_1[heading.tag] + " " + content; var expected = requiredHeadings[i_1++] || "[None]"; if (expected === "*") { optional_1 = true; } else if (expected.toLowerCase() === actual.toLowerCase()) { optional_1 = false; } else if (optional_1) { i_1--; } else { addErrorDetailIf(onError, heading.lineNumber, expected, actual); errorCount_1++; } } }); if ((i_1 < requiredHeadings.length) && !errorCount_1) { addErrorContext(onError, params.lines.length, requiredHeadings[i_1]); } } } }; },{"../helpers":2}],44:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addErrorDetailIf = _a.addErrorDetailIf, bareUrlRe = _a.bareUrlRe, escapeForRegExp = _a.escapeForRegExp, filterTokens = _a.filterTokens, forEachInlineChild = _a.forEachInlineChild, newLineRe = _a.newLineRe; module.exports = { "names": ["MD044", "proper-names"], "description": "Proper names should have the correct capitalization", "tags": ["spelling"], "function": function MD044(params, onError) { var names = params.config.names || []; var codeBlocks = params.config.code_blocks; var includeCodeBlocks = (codeBlocks === undefined) ? true : !!codeBlocks; names.forEach(function (name) { var escapedName = escapeForRegExp(name); var namePattern = "\\S*\\b(" + escapedName + ")\\b\\S*"; var anyNameRe = new RegExp(namePattern, "gi"); function forToken(token) { var fenceOffset = (token.type === "fence") ? 1 : 0; token.content.split(newLineRe) .forEach(function (line, index) { var match = null; while ((match = anyNameRe.exec(line)) !== null) { var fullMatch = match[0]; if (fullMatch.search(bareUrlRe) === -1) { var wordMatch = fullMatch .replace(/^\W*/, "").replace(/\W*$/, ""); if (!names.includes(wordMatch)) { var lineNumber = token.lineNumber + index + fenceOffset; var fullLine = params.lines[lineNumber - 1]; var matchIndex = match.index; var matchLength = wordMatch.length; var fullLineWord = fullLine.slice(matchIndex, matchIndex + matchLength); if (fullLineWord !== wordMatch) { // Attempt to fix bad offset due to inline content matchIndex = fullLine.indexOf(wordMatch); } var range = [matchIndex + 1, matchLength]; addErrorDetailIf(onError, lineNumber, name, match[1], null, null, range, { "editColumn": matchIndex + 1, "deleteCount": matchLength, "insertText": name }); } } } }); } forEachInlineChild(params, "text", forToken); if (includeCodeBlocks) { forEachInlineChild(params, "code_inline", forToken); filterTokens(params, "code_block", forToken); filterTokens(params, "fence", forToken); } }); } }; },{"../helpers":2}],45:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addError = _a.addError, forEachInlineChild = _a.forEachInlineChild; module.exports = { "names": ["MD045", "no-alt-text"], "description": "Images should have alternate text (alt text)", "tags": ["accessibility", "images"], "function": function MD045(params, onError) { forEachInlineChild(params, "image", function forToken(token) { if (token.content === "") { addError(onError, token.lineNumber); } }); } }; },{"../helpers":2}],46:[function(require,module,exports){ // @ts-check "use strict"; var addErrorDetailIf = require("../helpers").addErrorDetailIf; var tokenTypeToStyle = { "fence": "fenced", "code_block": "indented" }; module.exports = { "names": ["MD046", "code-block-style"], "description": "Code block style", "tags": ["code"], "function": function MD046(params, onError) { var expectedStyle = params.config.style || "consistent"; params.tokens .filter(function (token) { return token.type === "code_block" || token.type === "fence"; }) .forEach(function (token) { var lineNumber = token.lineNumber, type = token.type; if (expectedStyle === "consistent") { expectedStyle = tokenTypeToStyle[type]; } addErrorDetailIf(onError, lineNumber, expectedStyle, tokenTypeToStyle[type]); }); } }; },{"../helpers":2}],47:[function(require,module,exports){ // @ts-check "use strict"; var _a = require("../helpers"), addError = _a.addError, isBlankLine = _a.isBlankLine; module.exports = { "names": ["MD047", "single-trailing-newline"], "description": "Files should end with a single newline character", "tags": ["blank_lines"], "function": function MD047(params, onError) { var lastLineNumber = params.lines.length; var lastLine = params.lines[lastLineNumber - 1]; if (!isBlankLine(lastLine)) { addError(onError, lastLineNumber, null, null, [lastLine.length, 1], { "insertText": "\n", "editColumn": lastLine.length + 1 }); } } }; },{"../helpers":2}],48:[function(require,module,exports){ // @ts-check "use strict"; var URL = require("url").URL; var packageJson = require("../package.json"); var homepage = packageJson.homepage; var version = packageJson.version; var rules = [ require("./md001"), require("./md002"), require("./md003"), require("./md004"), require("./md005"), require("./md006"), require("./md007"), require("./md009"), require("./md010"), require("./md011"), require("./md012"), require("./md013"), require("./md014"), require("./md018"), require("./md019"), require("./md020"), require("./md021"), require("./md022"), require("./md023"), require("./md024"), require("./md025"), require("./md026"), require("./md027"), require("./md028"), require("./md029"), require("./md030"), require("./md031"), require("./md032"), require("./md033"), require("./md034"), require("./md035"), require("./md036"), require("./md037"), require("./md038"), require("./md039"), require("./md040"), require("./md041"), require("./md042"), require("./md043"), require("./md044"), require("./md045"), require("./md046"), require("./md047") ]; rules.forEach(function (rule) { var name = rule.names[0].toLowerCase(); rule.information = new URL(homepage + "/blob/v" + version + "/doc/Rules.md#" + name); }); module.exports = rules; },{"../package.json":49,"./md001":5,"./md002":6,"./md003":7,"./md004":8,"./md005":9,"./md006":10,"./md007":11,"./md009":12,"./md010":13,"./md011":14,"./md012":15,"./md013":16,"./md014":17,"./md018":18,"./md019":19,"./md020":20,"./md021":21,"./md022":22,"./md023":23,"./md024":24,"./md025":25,"./md026":26,"./md027":27,"./md028":28,"./md029":29,"./md030":30,"./md031":31,"./md032":32,"./md033":33,"./md034":34,"./md035":35,"./md036":36,"./md037":37,"./md038":38,"./md039":39,"./md040":40,"./md041":41,"./md042":42,"./md043":43,"./md044":44,"./md045":45,"./md046":46,"./md047":47,"url":58}],49:[function(require,module,exports){ module.exports={ "name": "markdownlint", "version": "0.17.2", "description": "A Node.js style checker and lint tool for Markdown/CommonMark files.", "main": "lib/markdownlint.js", "author": "David Anson (https://dlaa.me/)", "license": "MIT", "homepage": "https://github.com/DavidAnson/markdownlint", "repository": { "type": "git", "url": "https://github.com/DavidAnson/markdownlint.git" }, "bugs": "https://github.com/DavidAnson/markdownlint/issues", "scripts": { "test": "nodeunit test/markdownlint-test.js", "test-cover": "nyc --check-coverage --skip-full node_modules/nodeunit/bin/nodeunit test/markdownlint-test.js", "test-extra": "nodeunit test/markdownlint-test-extra.js", "debug": "node debug node_modules/nodeunit/bin/nodeunit", "lint": "eslint lib helpers test schema && eslint --env browser --global markdownit --global markdownlint --rule \"no-unused-vars: 0, no-extend-native: 0, max-statements: 0, no-console: 0, no-var: 0\" demo && eslint --rule \"no-console: 0, no-invalid-this: 0, no-shadow: 0, object-property-newline: 0\" example", "ci": "npm run test && npm run lint && npm run test-cover", "build-config-schema": "node schema/build-config-schema.js", "build-demo": "cpy node_modules/markdown-it/dist/markdown-it.min.js demo && cd demo && rimraf markdownlint-browser.* && cpy file-header.js . --rename=markdownlint-browser.js && tsc --allowJs --resolveJsonModule --outDir ../lib-es3 ../lib/markdownlint.js && cpy ../helpers/package.json ../lib-es3/helpers && browserify ../lib-es3/lib/markdownlint.js --standalone markdownlint >> markdownlint-browser.js && uglifyjs markdownlint-browser.js --compress --mangle --comments --output markdownlint-browser.min.js", "build-example": "npm install --no-save --ignore-scripts grunt grunt-cli gulp through2", "example": "cd example && node standalone.js && grunt markdownlint --force && gulp markdownlint" }, "engines": { "node": ">=8" }, "dependencies": { "markdown-it": "10.0.0" }, "devDependencies": { "@types/node": "~12.7.11", "browserify": "~16.5.0", "cpy-cli": "~2.0.0", "eslint": "~6.5.1", "glob": "~7.1.4", "js-yaml": "~3.13.1", "markdown-it-for-inline": "~0.1.1", "markdown-it-katex": "~2.0.3", "markdown-it-sub": "~1.0.0", "markdown-it-sup": "~1.0.0", "markdownlint-rule-helpers": "~0.4.0", "nodeunit": "~0.11.3", "nyc": "~14.1.1", "rimraf": "~3.0.0", "toml": "~3.0.0", "tv4": "~1.3.0", "typescript": "~3.6.3", "uglify-js": "~3.6.0" }, "keywords": [ "markdown", "lint", "md", "CommonMark", "markdownlint" ], "browser": { "markdown-it": "../demo/markdown-it-stub.js" } } },{}],50:[function(require,module,exports){ },{}],51:[function(require,module,exports){ exports.endianness = function () { return 'LE' }; exports.hostname = function () { if (typeof location !== 'undefined') { return location.hostname } else return ''; }; exports.loadavg = function () { return [] }; exports.uptime = function () { return 0 }; exports.freemem = function () { return Number.MAX_VALUE; }; exports.totalmem = function () { return Number.MAX_VALUE; }; exports.cpus = function () { return [] }; exports.type = function () { return 'Browser' }; exports.release = function () { if (typeof navigator !== 'undefined') { return navigator.appVersion; } return ''; }; exports.networkInterfaces = exports.getNetworkInterfaces = function () { return {} }; exports.arch = function () { return 'javascript' }; exports.platform = function () { return 'browser' }; exports.tmpdir = exports.tmpDir = function () { return '/tmp'; }; exports.EOL = '\n'; exports.homedir = function () { return '/' }; },{}],52:[function(require,module,exports){ (function (process){ // .dirname, .basename, and .extname methods are extracted from Node.js v8.11.1, // backported and transplited with Babel, with backwards-compat fixes // 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. // resolves . and .. elements in a path array with directory names there // must be no slashes, empty elements, or device names (c:\) in the array // (so also no leading and trailing slashes - it does not distinguish // relative and absolute paths) function normalizeArray(parts, allowAboveRoot) { // if the path tries to go above the root, `up` ends up > 0 var up = 0; for (var i = parts.length - 1; i >= 0; i--) { var last = parts[i]; if (last === '.') { parts.splice(i, 1); } else if (last === '..') { parts.splice(i, 1); up++; } else if (up) { parts.splice(i, 1); up--; } } // if the path is allowed to go above the root, restore leading ..s if (allowAboveRoot) { for (; up--; up) { parts.unshift('..'); } } return parts; } // path.resolve([from ...], to) // posix version exports.resolve = function() { var resolvedPath = '', resolvedAbsolute = false; for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { var path = (i >= 0) ? arguments[i] : process.cwd(); // Skip empty and invalid entries if (typeof path !== 'string') { throw new TypeError('Arguments to path.resolve must be strings'); } else if (!path) { continue; } resolvedPath = path + '/' + resolvedPath; resolvedAbsolute = path.charAt(0) === '/'; } // At this point the path should be resolved to a full absolute path, but // handle relative paths to be safe (might happen when process.cwd() fails) // Normalize the path resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { return !!p; }), !resolvedAbsolute).join('/'); return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; }; // path.normalize(path) // posix version exports.normalize = function(path) { var isAbsolute = exports.isAbsolute(path), trailingSlash = substr(path, -1) === '/'; // Normalize the path path = normalizeArray(filter(path.split('/'), function(p) { return !!p; }), !isAbsolute).join('/'); if (!path && !isAbsolute) { path = '.'; } if (path && trailingSlash) { path += '/'; } return (isAbsolute ? '/' : '') + path; }; // posix version exports.isAbsolute = function(path) { return path.charAt(0) === '/'; }; // posix version exports.join = function() { var paths = Array.prototype.slice.call(arguments, 0); return exports.normalize(filter(paths, function(p, index) { if (typeof p !== 'string') { throw new TypeError('Arguments to path.join must be strings'); } return p; }).join('/')); }; // path.relative(from, to) // posix version exports.relative = function(from, to) { from = exports.resolve(from).substr(1); to = exports.resolve(to).substr(1); function trim(arr) { var start = 0; for (; start < arr.length; start++) { if (arr[start] !== '') break; } var end = arr.length - 1; for (; end >= 0; end--) { if (arr[end] !== '') break; } if (start > end) return []; return arr.slice(start, end - start + 1); } var fromParts = trim(from.split('/')); var toParts = trim(to.split('/')); var length = Math.min(fromParts.length, toParts.length); var samePartsLength = length; for (var i = 0; i < length; i++) { if (fromParts[i] !== toParts[i]) { samePartsLength = i; break; } } var outputParts = []; for (var i = samePartsLength; i < fromParts.length; i++) { outputParts.push('..'); } outputParts = outputParts.concat(toParts.slice(samePartsLength)); return outputParts.join('/'); }; exports.sep = '/'; exports.delimiter = ':'; exports.dirname = function (path) { if (typeof path !== 'string') path = path + ''; if (path.length === 0) return '.'; var code = path.charCodeAt(0); var hasRoot = code === 47 /*/*/; var end = -1; var matchedSlash = true; for (var i = path.length - 1; i >= 1; --i) { code = path.charCodeAt(i); if (code === 47 /*/*/) { if (!matchedSlash) { end = i; break; } } else { // We saw the first non-path separator matchedSlash = false; } } if (end === -1) return hasRoot ? '/' : '.'; if (hasRoot && end === 1) { // return '//'; // Backwards-compat fix: return '/'; } return path.slice(0, end); }; function basename(path) { if (typeof path !== 'string') path = path + ''; var start = 0; var end = -1; var matchedSlash = true; var i; for (i = path.length - 1; i >= 0; --i) { if (path.charCodeAt(i) === 47 /*/*/) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { start = i + 1; break; } } else if (end === -1) { // We saw the first non-path separator, mark this as the end of our // path component matchedSlash = false; end = i + 1; } } if (end === -1) return ''; return path.slice(start, end); } // Uses a mixed approach for backwards-compatibility, as ext behavior changed // in new Node.js versions, so only basename() above is backported here exports.basename = function (path, ext) { var f = basename(path); if (ext && f.substr(-1 * ext.length) === ext) { f = f.substr(0, f.length - ext.length); } return f; }; exports.extname = function (path) { if (typeof path !== 'string') path = path + ''; var startDot = -1; var startPart = 0; var end = -1; var matchedSlash = true; // Track the state of characters (if any) we see before our first dot and // after any path separator we find var preDotState = 0; for (var i = path.length - 1; i >= 0; --i) { var code = path.charCodeAt(i); if (code === 47 /*/*/) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { startPart = i + 1; break; } continue; } if (end === -1) { // We saw the first non-path separator, mark this as the end of our // extension matchedSlash = false; end = i + 1; } if (code === 46 /*.*/) { // If this is our first dot, mark it as the start of our extension if (startDot === -1) startDot = i; else if (preDotState !== 1) preDotState = 1; } else if (startDot !== -1) { // We saw a non-dot and non-path separator before our dot, so we should // have a good chance at having a non-empty extension preDotState = -1; } } if (startDot === -1 || end === -1 || // We saw a non-dot character immediately before the dot preDotState === 0 || // The (right-most) trimmed path component is exactly '..' preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { return ''; } return path.slice(startDot, end); }; function filter (xs, f) { if (xs.filter) return xs.filter(f); var res = []; for (var i = 0; i < xs.length; i++) { if (f(xs[i], i, xs)) res.push(xs[i]); } return res; } // String.prototype.substr - negative index don't work in IE8 var substr = 'ab'.substr(-1) === 'b' ? function (str, start, len) { return str.substr(start, len) } : function (str, start, len) { if (start < 0) start = str.length + start; return str.substr(start, len); } ; }).call(this,require('_process')) },{"_process":53}],53:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; // cached from whatever global is present so that test runners that stub it // don't break things. But we need to wrap it in a try catch in case it is // wrapped in strict mode code which doesn't define any globals. It's inside a // function because try/catches deoptimize in certain engines. var cachedSetTimeout; var cachedClearTimeout; function defaultSetTimout() { throw new Error('setTimeout has not been defined'); } function defaultClearTimeout () { throw new Error('clearTimeout has not been defined'); } (function () { try { if (typeof setTimeout === 'function') { cachedSetTimeout = setTimeout; } else { cachedSetTimeout = defaultSetTimout; } } catch (e) { cachedSetTimeout = defaultSetTimout; } try { if (typeof clearTimeout === 'function') { cachedClearTimeout = clearTimeout; } else { cachedClearTimeout = defaultClearTimeout; } } catch (e) { cachedClearTimeout = defaultClearTimeout; } } ()) function runTimeout(fun) { if (cachedSetTimeout === setTimeout) { //normal enviroments in sane situations return setTimeout(fun, 0); } // if setTimeout wasn't available but was latter defined if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { cachedSetTimeout = setTimeout; return setTimeout(fun, 0); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedSetTimeout(fun, 0); } catch(e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedSetTimeout.call(null, fun, 0); } catch(e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error return cachedSetTimeout.call(this, fun, 0); } } } function runClearTimeout(marker) { if (cachedClearTimeout === clearTimeout) { //normal enviroments in sane situations return clearTimeout(marker); } // if clearTimeout wasn't available but was latter defined if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { cachedClearTimeout = clearTimeout; return clearTimeout(marker); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedClearTimeout(marker); } catch (e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedClearTimeout.call(null, marker); } catch (e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. // Some versions of I.E. have different rules for clearTimeout vs setTimeout return cachedClearTimeout.call(this, marker); } } } var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { if (!draining || !currentQueue) { return; } draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = runTimeout(cleanUpNextTick); draining = true; var len = queue.length; while(len) { currentQueue = queue; queue = []; while (++queueIndex < len) { if (currentQueue) { currentQueue[queueIndex].run(); } } queueIndex = -1; len = queue.length; } currentQueue = null; draining = false; runClearTimeout(timeout); } process.nextTick = function (fun) { var args = new Array(arguments.length - 1); if (arguments.length > 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { runTimeout(drainQueue); } }; // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.prependListener = noop; process.prependOnceListener = noop; process.listeners = function (name) { return [] } process.binding = function (name) { throw new Error('process.binding is not supported'); }; process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function() { return 0; }; },{}],54:[function(require,module,exports){ (function (global){ /*! https://mths.be/punycode v1.4.1 by @mathias */ ;(function(root) { /** Detect free variables */ var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; var freeModule = typeof module == 'object' && module && !module.nodeType && module; var freeGlobal = typeof global == 'object' && global; if ( freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal ) { root = freeGlobal; } /** * The `punycode` object. * @name punycode * @type Object */ var punycode, /** Highest positive signed 32-bit float value */ maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 /** Bootstring parameters */ base = 36, tMin = 1, tMax = 26, skew = 38, damp = 700, initialBias = 72, initialN = 128, // 0x80 delimiter = '-', // '\x2D' /** Regular expressions */ regexPunycode = /^xn--/, regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators /** Error messages */ errors = { 'overflow': 'Overflow: input needs wider integers to process', 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', 'invalid-input': 'Invalid input' }, /** Convenience shortcuts */ baseMinusTMin = base - tMin, floor = Math.floor, stringFromCharCode = String.fromCharCode, /** Temporary variable */ key; /*--------------------------------------------------------------------------*/ /** * A generic error utility function. * @private * @param {String} type The error type. * @returns {Error} Throws a `RangeError` with the applicable error message. */ function error(type) { throw new RangeError(errors[type]); } /** * A generic `Array#map` utility function. * @private * @param {Array} array The array to iterate over. * @param {Function} callback The function that gets called for every array * item. * @returns {Array} A new array of values returned by the callback function. */ function map(array, fn) { var length = array.length; var result = []; while (length--) { result[length] = fn(array[length]); } return result; } /** * A simple `Array#map`-like wrapper to work with domain name strings or email * addresses. * @private * @param {String} domain The domain name or email address. * @param {Function} callback The function that gets called for every * character. * @returns {Array} A new string of characters returned by the callback * function. */ function mapDomain(string, fn) { var parts = string.split('@'); var result = ''; if (parts.length > 1) { // In email addresses, only the domain name should be punycoded. Leave // the local part (i.e. everything up to `@`) intact. result = parts[0] + '@'; string = parts[1]; } // Avoid `split(regex)` for IE8 compatibility. See #17. string = string.replace(regexSeparators, '\x2E'); var labels = string.split('.'); var encoded = map(labels, fn).join('.'); return result + encoded; } /** * Creates an array containing the numeric code points of each Unicode * character in the string. While JavaScript uses UCS-2 internally, * this function will convert a pair of surrogate halves (each of which * UCS-2 exposes as separate characters) into a single code point, * matching UTF-16. * @see `punycode.ucs2.encode` * @see * @memberOf punycode.ucs2 * @name decode * @param {String} string The Unicode input string (UCS-2). * @returns {Array} The new array of code points. */ function ucs2decode(string) { var output = [], counter = 0, length = string.length, value, extra; while (counter < length) { value = string.charCodeAt(counter++); if (value >= 0xD800 && value <= 0xDBFF && counter < length) { // high surrogate, and there is a next character extra = string.charCodeAt(counter++); if ((extra & 0xFC00) == 0xDC00) { // low surrogate output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); } else { // unmatched surrogate; only append this code unit, in case the next // code unit is the high surrogate of a surrogate pair output.push(value); counter--; } } else { output.push(value); } } return output; } /** * Creates a string based on an array of numeric code points. * @see `punycode.ucs2.decode` * @memberOf punycode.ucs2 * @name encode * @param {Array} codePoints The array of numeric code points. * @returns {String} The new Unicode string (UCS-2). */ function ucs2encode(array) { return map(array, function(value) { var output = ''; if (value > 0xFFFF) { value -= 0x10000; output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); value = 0xDC00 | value & 0x3FF; } output += stringFromCharCode(value); return output; }).join(''); } /** * Converts a basic code point into a digit/integer. * @see `digitToBasic()` * @private * @param {Number} codePoint The basic numeric code point value. * @returns {Number} The numeric value of a basic code point (for use in * representing integers) in the range `0` to `base - 1`, or `base` if * the code point does not represent a value. */ function basicToDigit(codePoint) { if (codePoint - 48 < 10) { return codePoint - 22; } if (codePoint - 65 < 26) { return codePoint - 65; } if (codePoint - 97 < 26) { return codePoint - 97; } return base; } /** * Converts a digit/integer into a basic code point. * @see `basicToDigit()` * @private * @param {Number} digit The numeric value of a basic code point. * @returns {Number} The basic code point whose value (when used for * representing integers) is `digit`, which needs to be in the range * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is * used; else, the lowercase form is used. The behavior is undefined * if `flag` is non-zero and `digit` has no uppercase form. */ function digitToBasic(digit, flag) { // 0..25 map to ASCII a..z or A..Z // 26..35 map to ASCII 0..9 return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); } /** * Bias adaptation function as per section 3.4 of RFC 3492. * https://tools.ietf.org/html/rfc3492#section-3.4 * @private */ function adapt(delta, numPoints, firstTime) { var k = 0; delta = firstTime ? floor(delta / damp) : delta >> 1; delta += floor(delta / numPoints); for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { delta = floor(delta / baseMinusTMin); } return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); } /** * Converts a Punycode string of ASCII-only symbols to a string of Unicode * symbols. * @memberOf punycode * @param {String} input The Punycode string of ASCII-only symbols. * @returns {String} The resulting string of Unicode symbols. */ function decode(input) { // Don't use UCS-2 var output = [], inputLength = input.length, out, i = 0, n = initialN, bias = initialBias, basic, j, index, oldi, w, k, digit, t, /** Cached calculation results */ baseMinusT; // Handle the basic code points: let `basic` be the number of input code // points before the last delimiter, or `0` if there is none, then copy // the first basic code points to the output. basic = input.lastIndexOf(delimiter); if (basic < 0) { basic = 0; } for (j = 0; j < basic; ++j) { // if it's not a basic code point if (input.charCodeAt(j) >= 0x80) { error('not-basic'); } output.push(input.charCodeAt(j)); } // Main decoding loop: start just after the last delimiter if any basic code // points were copied; start at the beginning otherwise. for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { // `index` is the index of the next character to be consumed. // Decode a generalized variable-length integer into `delta`, // which gets added to `i`. The overflow checking is easier // if we increase `i` as we go, then subtract off its starting // value at the end to obtain `delta`. for (oldi = i, w = 1, k = base; /* no condition */; k += base) { if (index >= inputLength) { error('invalid-input'); } digit = basicToDigit(input.charCodeAt(index++)); if (digit >= base || digit > floor((maxInt - i) / w)) { error('overflow'); } i += digit * w; t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); if (digit < t) { break; } baseMinusT = base - t; if (w > floor(maxInt / baseMinusT)) { error('overflow'); } w *= baseMinusT; } out = output.length + 1; bias = adapt(i - oldi, out, oldi == 0); // `i` was supposed to wrap around from `out` to `0`, // incrementing `n` each time, so we'll fix that now: if (floor(i / out) > maxInt - n) { error('overflow'); } n += floor(i / out); i %= out; // Insert `n` at position `i` of the output output.splice(i++, 0, n); } return ucs2encode(output); } /** * Converts a string of Unicode symbols (e.g. a domain name label) to a * Punycode string of ASCII-only symbols. * @memberOf punycode * @param {String} input The string of Unicode symbols. * @returns {String} The resulting Punycode string of ASCII-only symbols. */ function encode(input) { var n, delta, handledCPCount, basicLength, bias, j, m, q, k, t, currentValue, output = [], /** `inputLength` will hold the number of code points in `input`. */ inputLength, /** Cached calculation results */ handledCPCountPlusOne, baseMinusT, qMinusT; // Convert the input in UCS-2 to Unicode input = ucs2decode(input); // Cache the length inputLength = input.length; // Initialize the state n = initialN; delta = 0; bias = initialBias; // Handle the basic code points for (j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue < 0x80) { output.push(stringFromCharCode(currentValue)); } } handledCPCount = basicLength = output.length; // `handledCPCount` is the number of code points that have been handled; // `basicLength` is the number of basic code points. // Finish the basic string - if it is not empty - with a delimiter if (basicLength) { output.push(delimiter); } // Main encoding loop: while (handledCPCount < inputLength) { // All non-basic code points < n have been handled already. Find the next // larger one: for (m = maxInt, j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue >= n && currentValue < m) { m = currentValue; } } // Increase `delta` enough to advance the decoder's state to , // but guard against overflow handledCPCountPlusOne = handledCPCount + 1; if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { error('overflow'); } delta += (m - n) * handledCPCountPlusOne; n = m; for (j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue < n && ++delta > maxInt) { error('overflow'); } if (currentValue == n) { // Represent delta as a generalized variable-length integer for (q = delta, k = base; /* no condition */; k += base) { t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); if (q < t) { break; } qMinusT = q - t; baseMinusT = base - t; output.push( stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) ); q = floor(qMinusT / baseMinusT); } output.push(stringFromCharCode(digitToBasic(q, 0))); bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); delta = 0; ++handledCPCount; } } ++delta; ++n; } return output.join(''); } /** * Converts a Punycode string representing a domain name or an email address * to Unicode. Only the Punycoded parts of the input will be converted, i.e. * it doesn't matter if you call it on a string that has already been * converted to Unicode. * @memberOf punycode * @param {String} input The Punycoded domain name or email address to * convert to Unicode. * @returns {String} The Unicode representation of the given Punycode * string. */ function toUnicode(input) { return mapDomain(input, function(string) { return regexPunycode.test(string) ? decode(string.slice(4).toLowerCase()) : string; }); } /** * Converts a Unicode string representing a domain name or an email address to * Punycode. Only the non-ASCII parts of the domain name will be converted, * i.e. it doesn't matter if you call it with a domain that's already in * ASCII. * @memberOf punycode * @param {String} input The domain name or email address to convert, as a * Unicode string. * @returns {String} The Punycode representation of the given domain name or * email address. */ function toASCII(input) { return mapDomain(input, function(string) { return regexNonASCII.test(string) ? 'xn--' + encode(string) : string; }); } /*--------------------------------------------------------------------------*/ /** Define the public API */ punycode = { /** * A string representing the current Punycode.js version number. * @memberOf punycode * @type String */ 'version': '1.4.1', /** * An object of methods to convert from JavaScript's internal character * representation (UCS-2) to Unicode code points, and back. * @see * @memberOf punycode * @type Object */ 'ucs2': { 'decode': ucs2decode, 'encode': ucs2encode }, 'decode': decode, 'encode': encode, 'toASCII': toASCII, 'toUnicode': toUnicode }; /** Expose `punycode` */ // Some AMD build optimizers, like r.js, check for specific condition patterns // like the following: if ( typeof define == 'function' && typeof define.amd == 'object' && define.amd ) { define('punycode', function() { return punycode; }); } else if (freeExports && freeModule) { if (module.exports == freeExports) { // in Node.js, io.js, or RingoJS v0.8.0+ freeModule.exports = punycode; } else { // in Narwhal or RingoJS v0.7.0- for (key in punycode) { punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); } } } else { // in Rhino or a web browser root.punycode = punycode; } }(this)); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],55:[function(require,module,exports){ // 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. 'use strict'; // If obj.hasOwnProperty has been overridden, then calling // obj.hasOwnProperty(prop) will break. // See: https://github.com/joyent/node/issues/1707 function hasOwnProperty(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } module.exports = function(qs, sep, eq, options) { sep = sep || '&'; eq = eq || '='; var obj = {}; if (typeof qs !== 'string' || qs.length === 0) { return obj; } var regexp = /\+/g; qs = qs.split(sep); var maxKeys = 1000; if (options && typeof options.maxKeys === 'number') { maxKeys = options.maxKeys; } var len = qs.length; // maxKeys <= 0 means that we should not limit keys count if (maxKeys > 0 && len > maxKeys) { len = maxKeys; } for (var i = 0; i < len; ++i) { var x = qs[i].replace(regexp, '%20'), idx = x.indexOf(eq), kstr, vstr, k, v; if (idx >= 0) { kstr = x.substr(0, idx); vstr = x.substr(idx + 1); } else { kstr = x; vstr = ''; } k = decodeURIComponent(kstr); v = decodeURIComponent(vstr); if (!hasOwnProperty(obj, k)) { obj[k] = v; } else if (isArray(obj[k])) { obj[k].push(v); } else { obj[k] = [obj[k], v]; } } return obj; }; var isArray = Array.isArray || function (xs) { return Object.prototype.toString.call(xs) === '[object Array]'; }; },{}],56:[function(require,module,exports){ // 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. 'use strict'; var stringifyPrimitive = function(v) { switch (typeof v) { case 'string': return v; case 'boolean': return v ? 'true' : 'false'; case 'number': return isFinite(v) ? v : ''; default: return ''; } }; module.exports = function(obj, sep, eq, name) { sep = sep || '&'; eq = eq || '='; if (obj === null) { obj = undefined; } if (typeof obj === 'object') { return map(objectKeys(obj), function(k) { var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; if (isArray(obj[k])) { return map(obj[k], function(v) { return ks + encodeURIComponent(stringifyPrimitive(v)); }).join(sep); } else { return ks + encodeURIComponent(stringifyPrimitive(obj[k])); } }).join(sep); } if (!name) return ''; return encodeURIComponent(stringifyPrimitive(name)) + eq + encodeURIComponent(stringifyPrimitive(obj)); }; var isArray = Array.isArray || function (xs) { return Object.prototype.toString.call(xs) === '[object Array]'; }; function map (xs, f) { if (xs.map) return xs.map(f); var res = []; for (var i = 0; i < xs.length; i++) { res.push(f(xs[i], i)); } return res; } var objectKeys = Object.keys || function (obj) { var res = []; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); } return res; }; },{}],57:[function(require,module,exports){ 'use strict'; exports.decode = exports.parse = require('./decode'); exports.encode = exports.stringify = require('./encode'); },{"./decode":55,"./encode":56}],58:[function(require,module,exports){ // 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. 'use strict'; var punycode = require('punycode'); var util = require('./util'); exports.parse = urlParse; exports.resolve = urlResolve; exports.resolveObject = urlResolveObject; exports.format = urlFormat; exports.Url = Url; function Url() { this.protocol = null; this.slashes = null; this.auth = null; this.host = null; this.port = null; this.hostname = null; this.hash = null; this.search = null; this.query = null; this.pathname = null; this.path = null; this.href = null; } // Reference: RFC 3986, RFC 1808, RFC 2396 // 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]*$/, // 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), // 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. unsafeProtocol = { 'javascript': true, 'javascript:': true }, // 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 }, querystring = require('querystring'); function urlParse(url, parseQueryString, slashesDenoteHost) { if (url && util.isObject(url) && url instanceof Url) return url; var u = new Url; u.parse(url, parseQueryString, slashesDenoteHost); return u; } Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { if (!util.isString(url)) { throw new TypeError("Parameter 'url' must be a string, not " + typeof url); } // Copy chrome, IE, opera backslash-handling behavior. // Back slashes before the query string get converted to forward slashes // See: https://code.google.com/p/chromium/issues/detail?id=25916 var queryIndex = url.indexOf('?'), splitter = (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#', uSplit = url.split(splitter), slashRegex = /\\/g; uSplit[0] = uSplit[0].replace(slashRegex, '/'); url = uSplit.join(splitter); var rest = url; // 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.path = rest; this.href = rest; this.pathname = simplePath[1]; if (simplePath[2]) { this.search = simplePath[2]; if (parseQueryString) { this.query = querystring.parse(this.search.substr(1)); } else { this.query = this.search.substr(1); } } else if (parseQueryString) { this.search = ''; this.query = {}; } return this; } } var proto = protocolPattern.exec(rest); if (proto) { proto = proto[0]; var lowerProto = proto.toLowerCase(); this.protocol = lowerProto; rest = rest.substr(proto.length); } // 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(/^\/\/[^@\/]+@[^@\/]+/)) { var slashes = rest.substr(0, 2) === '//'; if (slashes && !(proto && hostlessProtocol[proto])) { rest = rest.substr(2); this.slashes = true; } } 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. // find the first instance of any hostEndingChars var hostEnd = -1; for (var i = 0; i < hostEndingChars.length; i++) { var hec = rest.indexOf(hostEndingChars[i]); if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) hostEnd = hec; } // 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); } // 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 = decodeURIComponent(auth); } // the host is the remaining to the left of the first non-host char hostEnd = -1; for (var i = 0; i < nonHostChars.length; i++) { var hec = rest.indexOf(nonHostChars[i]); if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) hostEnd = hec; } // if we still have not hit it, then the entire thing is a host. if (hostEnd === -1) hostEnd = rest.length; this.host = rest.slice(0, hostEnd); rest = rest.slice(hostEnd); // pull out port. this.parseHost(); // 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 (var 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; } } } } if (this.hostname.length > hostnameMaxLen) { this.hostname = ''; } else { // hostnames are always lower case. this.hostname = this.hostname.toLowerCase(); } if (!ipv6Hostname) { // IDNA Support: Returns a punycoded representation of "domain". // It only converts parts of the domain name that // have non-ASCII characters, i.e. it doesn't matter if // you call it with a domain that already is ASCII-only. this.hostname = punycode.toASCII(this.hostname); } var p = this.port ? ':' + this.port : ''; var h = this.hostname || ''; this.host = h + p; this.href += this.host; // strip [ and ] from the hostname // the host field still retains them, though if (ipv6Hostname) { this.hostname = this.hostname.substr(1, this.hostname.length - 2); if (rest[0] !== '/') { rest = '/' + rest; } } } // now rest is set to the post-host stuff. // chop off any delim chars. if (!unsafeProtocol[lowerProto]) { // First, make 100% sure that any "autoEscape" chars get // escaped, even if encodeURIComponent doesn't think they // need to be. for (var i = 0, l = autoEscape.length; i < l; i++) { var ae = autoEscape[i]; if (rest.indexOf(ae) === -1) continue; var esc = encodeURIComponent(ae); if (esc === ae) { esc = escape(ae); } rest = rest.split(ae).join(esc); } } // 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); this.query = rest.substr(qm + 1); if (parseQueryString) { this.query = querystring.parse(this.query); } rest = rest.slice(0, qm); } else if (parseQueryString) { // no query string, but parseQueryString still requested this.search = ''; this.query = {}; } if (rest) this.pathname = rest; if (slashedProtocol[lowerProto] && this.hostname && !this.pathname) { this.pathname = '/'; } //to support http.request if (this.pathname || this.search) { var p = this.pathname || ''; var s = this.search || ''; this.path = p + s; } // finally, reconstruct the href based on what has been validated. this.href = this.format(); return this; }; // format a parsed object into a url string function urlFormat(obj) { // ensure it's an object, and not a string url. // If it's an obj, this is a no-op. // this way, you can call url_format() on strings // to clean up potentially wonky urls. if (util.isString(obj)) obj = urlParse(obj); if (!(obj instanceof Url)) return Url.prototype.format.call(obj); return obj.format(); } Url.prototype.format = function() { var auth = this.auth || ''; if (auth) { auth = encodeURIComponent(auth); auth = auth.replace(/%3A/i, ':'); auth += '@'; } var protocol = this.protocol || '', pathname = this.pathname || '', hash = this.hash || '', host = false, query = ''; if (this.host) { host = auth + this.host; } else if (this.hostname) { host = auth + (this.hostname.indexOf(':') === -1 ? this.hostname : '[' + this.hostname + ']'); if (this.port) { host += ':' + this.port; } } if (this.query && util.isObject(this.query) && Object.keys(this.query).length) { query = querystring.stringify(this.query); } var search = this.search || (query && ('?' + query)) || ''; if (protocol && protocol.substr(-1) !== ':') protocol += ':'; // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. // unless they had them to begin with. if (this.slashes || (!protocol || slashedProtocol[protocol]) && host !== false) { host = '//' + (host || ''); if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; } else if (!host) { host = ''; } if (hash && hash.charAt(0) !== '#') hash = '#' + hash; if (search && search.charAt(0) !== '?') search = '?' + search; pathname = pathname.replace(/[?#]/g, function(match) { return encodeURIComponent(match); }); search = search.replace('#', '%23'); return protocol + host + pathname + search + hash; }; function urlResolve(source, relative) { return urlParse(source, false, true).resolve(relative); } Url.prototype.resolve = function(relative) { return this.resolveObject(urlParse(relative, false, true)).format(); }; function urlResolveObject(source, relative) { if (!source) return relative; return urlParse(source, false, true).resolveObject(relative); } Url.prototype.resolveObject = function(relative) { if (util.isString(relative)) { var rel = new Url(); rel.parse(relative, false, true); relative = rel; } var result = new Url(); var tkeys = Object.keys(this); for (var tk = 0; tk < tkeys.length; tk++) { var tkey = tkeys[tk]; result[tkey] = this[tkey]; } // hash is always overridden, no matter what. // even href="" will remove it. result.hash = relative.hash; // if the relative url is empty, then there's nothing left to do here. if (relative.href === '') { result.href = result.format(); return result; } // hrefs like //foo/bar always cut to the protocol. if (relative.slashes && !relative.protocol) { // take everything except the protocol from relative var rkeys = Object.keys(relative); for (var rk = 0; rk < rkeys.length; rk++) { var rkey = rkeys[rk]; if (rkey !== 'protocol') result[rkey] = relative[rkey]; } //urlParse appends trailing / to urls like http://www.example.com if (slashedProtocol[result.protocol] && result.hostname && !result.pathname) { result.path = result.pathname = '/'; } result.href = result.format(); return result; } if (relative.protocol && relative.protocol !== result.protocol) { // if it's a known url protocol, then changing // the protocol does weird things // first, if it's not file:, then we MUST have a host, // and if there was a path // to begin with, then we MUST have a path. // if it is file:, then the host is dropped, // because that's known to be hostless. // anything else is assumed to be absolute. if (!slashedProtocol[relative.protocol]) { var keys = Object.keys(relative); for (var v = 0; v < keys.length; v++) { var k = keys[v]; result[k] = relative[k]; } result.href = result.format(); return result; } result.protocol = relative.protocol; if (!relative.host && !hostlessProtocol[relative.protocol]) { var relPath = (relative.pathname || '').split('/'); while (relPath.length && !(relative.host = relPath.shift())); if (!relative.host) relative.host = ''; if (!relative.hostname) relative.hostname = ''; if (relPath[0] !== '') relPath.unshift(''); if (relPath.length < 2) relPath.unshift(''); result.pathname = relPath.join('/'); } else { result.pathname = relative.pathname; } result.search = relative.search; result.query = relative.query; result.host = relative.host || ''; result.auth = relative.auth; result.hostname = relative.hostname || relative.host; result.port = relative.port; // to support http.request if (result.pathname || result.search) { var p = result.pathname || ''; var s = result.search || ''; result.path = p + s; } result.slashes = result.slashes || relative.slashes; result.href = result.format(); return result; } var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), isRelAbs = ( relative.host || relative.pathname && relative.pathname.charAt(0) === '/' ), mustEndAbs = (isRelAbs || isSourceAbs || (result.host && relative.pathname)), removeAllDots = mustEndAbs, srcPath = result.pathname && result.pathname.split('/') || [], relPath = relative.pathname && relative.pathname.split('/') || [], psychotic = result.protocol && !slashedProtocol[result.protocol]; // if the url is a non-slashed url, then relative // links like ../.. should be able // to crawl up to the hostname, as well. This is strange. // result.protocol has already been set by now. // Later on, put the first path part into the host field. if (psychotic) { result.hostname = ''; result.port = null; if (result.host) { if (srcPath[0] === '') srcPath[0] = result.host; else srcPath.unshift(result.host); } result.host = ''; if (relative.protocol) { relative.hostname = null; relative.port = null; if (relative.host) { if (relPath[0] === '') relPath[0] = relative.host; else relPath.unshift(relative.host); } relative.host = null; } mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); } if (isRelAbs) { // it's absolute. result.host = (relative.host || relative.host === '') ? relative.host : result.host; result.hostname = (relative.hostname || relative.hostname === '') ? relative.hostname : result.hostname; result.search = relative.search; result.query = relative.query; srcPath = relPath; // fall through to the dot-handling below. } else if (relPath.length) { // it's relative // throw away the existing file, and take the new path instead. if (!srcPath) srcPath = []; srcPath.pop(); srcPath = srcPath.concat(relPath); result.search = relative.search; result.query = relative.query; } else if (!util.isNullOrUndefined(relative.search)) { // just pull out the search. // like href='?foo'. // Put this after the other two cases because it simplifies the booleans if (psychotic) { result.hostname = result.host = srcPath.shift(); //occationaly the auth can get stuck only in host //this especially happens in cases like //url.resolveObject('mailto:local1@domain1', 'local2@domain2') var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; if (authInHost) { result.auth = authInHost.shift(); result.host = result.hostname = authInHost.shift(); } } result.search = relative.search; result.query = relative.query; //to support http.request if (!util.isNull(result.pathname) || !util.isNull(result.search)) { result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); } result.href = result.format(); return result; } if (!srcPath.length) { // no path at all. easy. // we've already handled the other stuff above. result.pathname = null; //to support http.request if (result.search) { result.path = '/' + result.search; } else { result.path = null; } result.href = result.format(); return result; } // if a url ENDs in . or .., then it must get a trailing slash. // however, if it ends in anything else non-slashy, // then it must NOT get a trailing slash. var last = srcPath.slice(-1)[0]; var hasTrailingSlash = ( (result.host || relative.host || srcPath.length > 1) && (last === '.' || last === '..') || last === ''); // strip single dots, resolve double dots to parent dir // if the path tries to go above the root, `up` ends up > 0 var up = 0; for (var i = srcPath.length; i >= 0; i--) { last = srcPath[i]; if (last === '.') { srcPath.splice(i, 1); } else if (last === '..') { srcPath.splice(i, 1); up++; } else if (up) { srcPath.splice(i, 1); up--; } } // if the path is allowed to go above the root, restore leading ..s if (!mustEndAbs && !removeAllDots) { for (; up--; up) { srcPath.unshift('..'); } } if (mustEndAbs && srcPath[0] !== '' && (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { srcPath.unshift(''); } if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { srcPath.push(''); } var isAbsolute = srcPath[0] === '' || (srcPath[0] && srcPath[0].charAt(0) === '/'); // put the host back if (psychotic) { result.hostname = result.host = isAbsolute ? '' : srcPath.length ? srcPath.shift() : ''; //occationaly the auth can get stuck only in host //this especially happens in cases like //url.resolveObject('mailto:local1@domain1', 'local2@domain2') var authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; if (authInHost) { result.auth = authInHost.shift(); result.host = result.hostname = authInHost.shift(); } } mustEndAbs = mustEndAbs || (result.host && srcPath.length); if (mustEndAbs && !isAbsolute) { srcPath.unshift(''); } if (!srcPath.length) { result.pathname = null; result.path = null; } else { result.pathname = srcPath.join('/'); } //to support request.http if (!util.isNull(result.pathname) || !util.isNull(result.search)) { result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); } result.auth = relative.auth || result.auth; result.slashes = result.slashes || relative.slashes; result.href = result.format(); return result; }; Url.prototype.parseHost = function() { var host = this.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; }; },{"./util":59,"punycode":54,"querystring":57}],59:[function(require,module,exports){ 'use strict'; module.exports = { isString: function(arg) { return typeof(arg) === 'string'; }, isObject: function(arg) { return typeof(arg) === 'object' && arg !== null; }, isNull: function(arg) { return arg === null; }, isNullOrUndefined: function(arg) { return arg == null; } }; },{}]},{},[4])(4) });