diff --git a/.eslintignore b/.eslintignore index e8b8c3f297709a..8ab4750abd1685 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,8 +4,7 @@ test/addons/??_* test/fixtures test/message/esm_display_syntax_error.mjs tools/icu -tools/lint-md.mjs -tools/node-lint-md-cli-rollup/dist +tools/lint-md/lint-md.mjs benchmark/tmp doc/**/*.js !.eslintrc.js diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index 04cecbbc516052..2694e07ab3c6fd 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -55,7 +55,7 @@ jobs: - name: Get release version numbers if: ${{ github.event.pull_request && github.event.pull_request.base.ref == github.event.pull_request.base.repo.default_branch }} id: get-released-versions - run: ./tools/node-lint-md-cli-rollup/src/list-released-versions-from-changelogs.mjs + run: ./tools/lint-md/list-released-versions-from-changelogs.mjs - name: Lint docs run: | echo "::add-matcher::.github/workflows/remark-lint-problem-matcher.json" diff --git a/Makefile b/Makefile index baae6a3b46bd26..1ac93d4d5849fc 100644 --- a/Makefile +++ b/Makefile @@ -1221,12 +1221,11 @@ bench-addons-clean: .PHONY: lint-md-rollup lint-md-rollup: $(RM) tools/.*mdlintstamp - cd tools/node-lint-md-cli-rollup && npm install - cd tools/node-lint-md-cli-rollup && npm run build-node + cd tools/lint-md && npm ci && npm run build .PHONY: lint-md-clean lint-md-clean: - $(RM) -r tools/node-lint-md-cli-rollup/node_modules + $(RM) -r tools/lint-md/node_modules $(RM) tools/.*mdlintstamp .PHONY: lint-md-build @@ -1243,7 +1242,7 @@ LINT_MD_TARGETS = doc src lib benchmark test tools/doc tools/icu $(wildcard *.md LINT_MD_FILES = $(shell $(FIND) $(LINT_MD_TARGETS) -type f \ ! -path '*node_modules*' ! -path 'test/fixtures/*' -name '*.md' \ $(LINT_MD_NEWER)) -run-lint-md = tools/lint-md.mjs -q -f --no-stdout $(LINT_MD_FILES) +run-lint-md = tools/lint-md/lint-md.mjs $(LINT_MD_FILES) # Lint all changed markdown files maintained by us tools/.mdlintstamp: $(LINT_MD_FILES) $(info Running Markdown linter...) diff --git a/tools/lint-md.mjs b/tools/lint-md.mjs deleted file mode 100644 index f5e5a47a30e98b..00000000000000 --- a/tools/lint-md.mjs +++ /dev/null @@ -1,56085 +0,0 @@ -import path$b from 'path'; -import process$1 from 'process'; -import { URL as URL$1, fileURLToPath, pathToFileURL } from 'url'; -import require$$0$3, { realpathSync as realpathSync$1, statSync, Stats } from 'fs'; -import process$2 from 'node:process'; -import stream, { PassThrough } from 'node:stream'; -import require$$0$2 from 'os'; -import tty$1 from 'tty'; -import require$$0$5 from 'events'; -import require$$0$4, { format as format$2, inspect as inspect$1 } from 'util'; -import require$$1 from 'stream'; -import path$c from 'node:path'; -import { pathToFileURL as pathToFileURL$1 } from 'node:url'; -import assert$2 from 'assert'; -import fs$a from 'node:fs'; -import { EventEmitter as EventEmitter$1 } from 'node:events'; - -var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - -function getAugmentedNamespace(n) { - if (n.__esModule) return n; - var a = Object.defineProperty({}, '__esModule', {value: true}); - Object.keys(n).forEach(function (k) { - var d = Object.getOwnPropertyDescriptor(n, k); - Object.defineProperty(a, k, d.get ? d : { - enumerable: true, - get: function () { - return n[k]; - } - }); - }); - return a; -} - -function commonjsRequire (path) { - throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.'); -} - -var ansiStyles$2 = {exports: {}}; - -var colorName$1 = { - "aliceblue": [240, 248, 255], - "antiquewhite": [250, 235, 215], - "aqua": [0, 255, 255], - "aquamarine": [127, 255, 212], - "azure": [240, 255, 255], - "beige": [245, 245, 220], - "bisque": [255, 228, 196], - "black": [0, 0, 0], - "blanchedalmond": [255, 235, 205], - "blue": [0, 0, 255], - "blueviolet": [138, 43, 226], - "brown": [165, 42, 42], - "burlywood": [222, 184, 135], - "cadetblue": [95, 158, 160], - "chartreuse": [127, 255, 0], - "chocolate": [210, 105, 30], - "coral": [255, 127, 80], - "cornflowerblue": [100, 149, 237], - "cornsilk": [255, 248, 220], - "crimson": [220, 20, 60], - "cyan": [0, 255, 255], - "darkblue": [0, 0, 139], - "darkcyan": [0, 139, 139], - "darkgoldenrod": [184, 134, 11], - "darkgray": [169, 169, 169], - "darkgreen": [0, 100, 0], - "darkgrey": [169, 169, 169], - "darkkhaki": [189, 183, 107], - "darkmagenta": [139, 0, 139], - "darkolivegreen": [85, 107, 47], - "darkorange": [255, 140, 0], - "darkorchid": [153, 50, 204], - "darkred": [139, 0, 0], - "darksalmon": [233, 150, 122], - "darkseagreen": [143, 188, 143], - "darkslateblue": [72, 61, 139], - "darkslategray": [47, 79, 79], - "darkslategrey": [47, 79, 79], - "darkturquoise": [0, 206, 209], - "darkviolet": [148, 0, 211], - "deeppink": [255, 20, 147], - "deepskyblue": [0, 191, 255], - "dimgray": [105, 105, 105], - "dimgrey": [105, 105, 105], - "dodgerblue": [30, 144, 255], - "firebrick": [178, 34, 34], - "floralwhite": [255, 250, 240], - "forestgreen": [34, 139, 34], - "fuchsia": [255, 0, 255], - "gainsboro": [220, 220, 220], - "ghostwhite": [248, 248, 255], - "gold": [255, 215, 0], - "goldenrod": [218, 165, 32], - "gray": [128, 128, 128], - "green": [0, 128, 0], - "greenyellow": [173, 255, 47], - "grey": [128, 128, 128], - "honeydew": [240, 255, 240], - "hotpink": [255, 105, 180], - "indianred": [205, 92, 92], - "indigo": [75, 0, 130], - "ivory": [255, 255, 240], - "khaki": [240, 230, 140], - "lavender": [230, 230, 250], - "lavenderblush": [255, 240, 245], - "lawngreen": [124, 252, 0], - "lemonchiffon": [255, 250, 205], - "lightblue": [173, 216, 230], - "lightcoral": [240, 128, 128], - "lightcyan": [224, 255, 255], - "lightgoldenrodyellow": [250, 250, 210], - "lightgray": [211, 211, 211], - "lightgreen": [144, 238, 144], - "lightgrey": [211, 211, 211], - "lightpink": [255, 182, 193], - "lightsalmon": [255, 160, 122], - "lightseagreen": [32, 178, 170], - "lightskyblue": [135, 206, 250], - "lightslategray": [119, 136, 153], - "lightslategrey": [119, 136, 153], - "lightsteelblue": [176, 196, 222], - "lightyellow": [255, 255, 224], - "lime": [0, 255, 0], - "limegreen": [50, 205, 50], - "linen": [250, 240, 230], - "magenta": [255, 0, 255], - "maroon": [128, 0, 0], - "mediumaquamarine": [102, 205, 170], - "mediumblue": [0, 0, 205], - "mediumorchid": [186, 85, 211], - "mediumpurple": [147, 112, 219], - "mediumseagreen": [60, 179, 113], - "mediumslateblue": [123, 104, 238], - "mediumspringgreen": [0, 250, 154], - "mediumturquoise": [72, 209, 204], - "mediumvioletred": [199, 21, 133], - "midnightblue": [25, 25, 112], - "mintcream": [245, 255, 250], - "mistyrose": [255, 228, 225], - "moccasin": [255, 228, 181], - "navajowhite": [255, 222, 173], - "navy": [0, 0, 128], - "oldlace": [253, 245, 230], - "olive": [128, 128, 0], - "olivedrab": [107, 142, 35], - "orange": [255, 165, 0], - "orangered": [255, 69, 0], - "orchid": [218, 112, 214], - "palegoldenrod": [238, 232, 170], - "palegreen": [152, 251, 152], - "paleturquoise": [175, 238, 238], - "palevioletred": [219, 112, 147], - "papayawhip": [255, 239, 213], - "peachpuff": [255, 218, 185], - "peru": [205, 133, 63], - "pink": [255, 192, 203], - "plum": [221, 160, 221], - "powderblue": [176, 224, 230], - "purple": [128, 0, 128], - "rebeccapurple": [102, 51, 153], - "red": [255, 0, 0], - "rosybrown": [188, 143, 143], - "royalblue": [65, 105, 225], - "saddlebrown": [139, 69, 19], - "salmon": [250, 128, 114], - "sandybrown": [244, 164, 96], - "seagreen": [46, 139, 87], - "seashell": [255, 245, 238], - "sienna": [160, 82, 45], - "silver": [192, 192, 192], - "skyblue": [135, 206, 235], - "slateblue": [106, 90, 205], - "slategray": [112, 128, 144], - "slategrey": [112, 128, 144], - "snow": [255, 250, 250], - "springgreen": [0, 255, 127], - "steelblue": [70, 130, 180], - "tan": [210, 180, 140], - "teal": [0, 128, 128], - "thistle": [216, 191, 216], - "tomato": [255, 99, 71], - "turquoise": [64, 224, 208], - "violet": [238, 130, 238], - "wheat": [245, 222, 179], - "white": [255, 255, 255], - "whitesmoke": [245, 245, 245], - "yellow": [255, 255, 0], - "yellowgreen": [154, 205, 50] -}; - -/* MIT license */ - -/* eslint-disable no-mixed-operators */ -const cssKeywords$1 = colorName$1; - -// NOTE: conversions should only return primitive values (i.e. arrays, or -// values that give correct `typeof` results). -// do not use box values types (i.e. Number(), String(), etc.) - -const reverseKeywords$1 = {}; -for (const key of Object.keys(cssKeywords$1)) { - reverseKeywords$1[cssKeywords$1[key]] = key; -} - -const convert$4 = { - rgb: {channels: 3, labels: 'rgb'}, - hsl: {channels: 3, labels: 'hsl'}, - hsv: {channels: 3, labels: 'hsv'}, - hwb: {channels: 3, labels: 'hwb'}, - cmyk: {channels: 4, labels: 'cmyk'}, - xyz: {channels: 3, labels: 'xyz'}, - lab: {channels: 3, labels: 'lab'}, - lch: {channels: 3, labels: 'lch'}, - hex: {channels: 1, labels: ['hex']}, - keyword: {channels: 1, labels: ['keyword']}, - ansi16: {channels: 1, labels: ['ansi16']}, - ansi256: {channels: 1, labels: ['ansi256']}, - hcg: {channels: 3, labels: ['h', 'c', 'g']}, - apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, - gray: {channels: 1, labels: ['gray']} -}; - -var conversions$5 = convert$4; - -// Hide .channels and .labels properties -for (const model of Object.keys(convert$4)) { - if (!('channels' in convert$4[model])) { - throw new Error('missing channels property: ' + model); - } - - if (!('labels' in convert$4[model])) { - throw new Error('missing channel labels property: ' + model); - } - - if (convert$4[model].labels.length !== convert$4[model].channels) { - throw new Error('channel and label counts mismatch: ' + model); - } - - const {channels, labels} = convert$4[model]; - delete convert$4[model].channels; - delete convert$4[model].labels; - Object.defineProperty(convert$4[model], 'channels', {value: channels}); - Object.defineProperty(convert$4[model], 'labels', {value: labels}); -} - -convert$4.rgb.hsl = function (rgb) { - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - const min = Math.min(r, g, b); - const max = Math.max(r, g, b); - const delta = max - min; - let h; - let s; - - if (max === min) { - h = 0; - } else if (r === max) { - h = (g - b) / delta; - } else if (g === max) { - h = 2 + (b - r) / delta; - } else if (b === max) { - h = 4 + (r - g) / delta; - } - - h = Math.min(h * 60, 360); - - if (h < 0) { - h += 360; - } - - const l = (min + max) / 2; - - if (max === min) { - s = 0; - } else if (l <= 0.5) { - s = delta / (max + min); - } else { - s = delta / (2 - max - min); - } - - return [h, s * 100, l * 100]; -}; - -convert$4.rgb.hsv = function (rgb) { - let rdif; - let gdif; - let bdif; - let h; - let s; - - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - const v = Math.max(r, g, b); - const diff = v - Math.min(r, g, b); - const diffc = function (c) { - return (v - c) / 6 / diff + 1 / 2; - }; - - if (diff === 0) { - h = 0; - s = 0; - } else { - s = diff / v; - rdif = diffc(r); - gdif = diffc(g); - bdif = diffc(b); - - if (r === v) { - h = bdif - gdif; - } else if (g === v) { - h = (1 / 3) + rdif - bdif; - } else if (b === v) { - h = (2 / 3) + gdif - rdif; - } - - if (h < 0) { - h += 1; - } else if (h > 1) { - h -= 1; - } - } - - return [ - h * 360, - s * 100, - v * 100 - ]; -}; - -convert$4.rgb.hwb = function (rgb) { - const r = rgb[0]; - const g = rgb[1]; - let b = rgb[2]; - const h = convert$4.rgb.hsl(rgb)[0]; - const w = 1 / 255 * Math.min(r, Math.min(g, b)); - - b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); - - return [h, w * 100, b * 100]; -}; - -convert$4.rgb.cmyk = function (rgb) { - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - - const k = Math.min(1 - r, 1 - g, 1 - b); - const c = (1 - r - k) / (1 - k) || 0; - const m = (1 - g - k) / (1 - k) || 0; - const y = (1 - b - k) / (1 - k) || 0; - - return [c * 100, m * 100, y * 100, k * 100]; -}; - -function comparativeDistance$1(x, y) { - /* - See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance - */ - return ( - ((x[0] - y[0]) ** 2) + - ((x[1] - y[1]) ** 2) + - ((x[2] - y[2]) ** 2) - ); -} - -convert$4.rgb.keyword = function (rgb) { - const reversed = reverseKeywords$1[rgb]; - if (reversed) { - return reversed; - } - - let currentClosestDistance = Infinity; - let currentClosestKeyword; - - for (const keyword of Object.keys(cssKeywords$1)) { - const value = cssKeywords$1[keyword]; - - // Compute comparative distance - const distance = comparativeDistance$1(rgb, value); - - // Check if its less, if so set as closest - if (distance < currentClosestDistance) { - currentClosestDistance = distance; - currentClosestKeyword = keyword; - } - } - - return currentClosestKeyword; -}; - -convert$4.keyword.rgb = function (keyword) { - return cssKeywords$1[keyword]; -}; - -convert$4.rgb.xyz = function (rgb) { - let r = rgb[0] / 255; - let g = rgb[1] / 255; - let b = rgb[2] / 255; - - // Assume sRGB - r = r > 0.04045 ? (((r + 0.055) / 1.055) ** 2.4) : (r / 12.92); - g = g > 0.04045 ? (((g + 0.055) / 1.055) ** 2.4) : (g / 12.92); - b = b > 0.04045 ? (((b + 0.055) / 1.055) ** 2.4) : (b / 12.92); - - const x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); - const y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); - const z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); - - return [x * 100, y * 100, z * 100]; -}; - -convert$4.rgb.lab = function (rgb) { - const xyz = convert$4.rgb.xyz(rgb); - let x = xyz[0]; - let y = xyz[1]; - let z = xyz[2]; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); - - const l = (116 * y) - 16; - const a = 500 * (x - y); - const b = 200 * (y - z); - - return [l, a, b]; -}; - -convert$4.hsl.rgb = function (hsl) { - const h = hsl[0] / 360; - const s = hsl[1] / 100; - const l = hsl[2] / 100; - let t2; - let t3; - let val; - - if (s === 0) { - val = l * 255; - return [val, val, val]; - } - - if (l < 0.5) { - t2 = l * (1 + s); - } else { - t2 = l + s - l * s; - } - - const t1 = 2 * l - t2; - - const rgb = [0, 0, 0]; - for (let i = 0; i < 3; i++) { - t3 = h + 1 / 3 * -(i - 1); - if (t3 < 0) { - t3++; - } - - if (t3 > 1) { - t3--; - } - - if (6 * t3 < 1) { - val = t1 + (t2 - t1) * 6 * t3; - } else if (2 * t3 < 1) { - val = t2; - } else if (3 * t3 < 2) { - val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; - } else { - val = t1; - } - - rgb[i] = val * 255; - } - - return rgb; -}; - -convert$4.hsl.hsv = function (hsl) { - const h = hsl[0]; - let s = hsl[1] / 100; - let l = hsl[2] / 100; - let smin = s; - const lmin = Math.max(l, 0.01); - - l *= 2; - s *= (l <= 1) ? l : 2 - l; - smin *= lmin <= 1 ? lmin : 2 - lmin; - const v = (l + s) / 2; - const sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); - - return [h, sv * 100, v * 100]; -}; - -convert$4.hsv.rgb = function (hsv) { - const h = hsv[0] / 60; - const s = hsv[1] / 100; - let v = hsv[2] / 100; - const hi = Math.floor(h) % 6; - - const f = h - Math.floor(h); - const p = 255 * v * (1 - s); - const q = 255 * v * (1 - (s * f)); - const t = 255 * v * (1 - (s * (1 - f))); - v *= 255; - - switch (hi) { - case 0: - return [v, t, p]; - case 1: - return [q, v, p]; - case 2: - return [p, v, t]; - case 3: - return [p, q, v]; - case 4: - return [t, p, v]; - case 5: - return [v, p, q]; - } -}; - -convert$4.hsv.hsl = function (hsv) { - const h = hsv[0]; - const s = hsv[1] / 100; - const v = hsv[2] / 100; - const vmin = Math.max(v, 0.01); - let sl; - let l; - - l = (2 - s) * v; - const lmin = (2 - s) * vmin; - sl = s * vmin; - sl /= (lmin <= 1) ? lmin : 2 - lmin; - sl = sl || 0; - l /= 2; - - return [h, sl * 100, l * 100]; -}; - -// http://dev.w3.org/csswg/css-color/#hwb-to-rgb -convert$4.hwb.rgb = function (hwb) { - const h = hwb[0] / 360; - let wh = hwb[1] / 100; - let bl = hwb[2] / 100; - const ratio = wh + bl; - let f; - - // Wh + bl cant be > 1 - if (ratio > 1) { - wh /= ratio; - bl /= ratio; - } - - const i = Math.floor(6 * h); - const v = 1 - bl; - f = 6 * h - i; - - if ((i & 0x01) !== 0) { - f = 1 - f; - } - - const n = wh + f * (v - wh); // Linear interpolation - - let r; - let g; - let b; - /* eslint-disable max-statements-per-line,no-multi-spaces */ - switch (i) { - default: - case 6: - case 0: r = v; g = n; b = wh; break; - case 1: r = n; g = v; b = wh; break; - case 2: r = wh; g = v; b = n; break; - case 3: r = wh; g = n; b = v; break; - case 4: r = n; g = wh; b = v; break; - case 5: r = v; g = wh; b = n; break; - } - /* eslint-enable max-statements-per-line,no-multi-spaces */ - - return [r * 255, g * 255, b * 255]; -}; - -convert$4.cmyk.rgb = function (cmyk) { - const c = cmyk[0] / 100; - const m = cmyk[1] / 100; - const y = cmyk[2] / 100; - const k = cmyk[3] / 100; - - const r = 1 - Math.min(1, c * (1 - k) + k); - const g = 1 - Math.min(1, m * (1 - k) + k); - const b = 1 - Math.min(1, y * (1 - k) + k); - - return [r * 255, g * 255, b * 255]; -}; - -convert$4.xyz.rgb = function (xyz) { - const x = xyz[0] / 100; - const y = xyz[1] / 100; - const z = xyz[2] / 100; - let r; - let g; - let b; - - r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); - g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); - b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); - - // Assume sRGB - r = r > 0.0031308 - ? ((1.055 * (r ** (1.0 / 2.4))) - 0.055) - : r * 12.92; - - g = g > 0.0031308 - ? ((1.055 * (g ** (1.0 / 2.4))) - 0.055) - : g * 12.92; - - b = b > 0.0031308 - ? ((1.055 * (b ** (1.0 / 2.4))) - 0.055) - : b * 12.92; - - r = Math.min(Math.max(0, r), 1); - g = Math.min(Math.max(0, g), 1); - b = Math.min(Math.max(0, b), 1); - - return [r * 255, g * 255, b * 255]; -}; - -convert$4.xyz.lab = function (xyz) { - let x = xyz[0]; - let y = xyz[1]; - let z = xyz[2]; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); - - const l = (116 * y) - 16; - const a = 500 * (x - y); - const b = 200 * (y - z); - - return [l, a, b]; -}; - -convert$4.lab.xyz = function (lab) { - const l = lab[0]; - const a = lab[1]; - const b = lab[2]; - let x; - let y; - let z; - - y = (l + 16) / 116; - x = a / 500 + y; - z = y - b / 200; - - const y2 = y ** 3; - const x2 = x ** 3; - const z2 = z ** 3; - y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; - x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; - z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; - - x *= 95.047; - y *= 100; - z *= 108.883; - - return [x, y, z]; -}; - -convert$4.lab.lch = function (lab) { - const l = lab[0]; - const a = lab[1]; - const b = lab[2]; - let h; - - const hr = Math.atan2(b, a); - h = hr * 360 / 2 / Math.PI; - - if (h < 0) { - h += 360; - } - - const c = Math.sqrt(a * a + b * b); - - return [l, c, h]; -}; - -convert$4.lch.lab = function (lch) { - const l = lch[0]; - const c = lch[1]; - const h = lch[2]; - - const hr = h / 360 * 2 * Math.PI; - const a = c * Math.cos(hr); - const b = c * Math.sin(hr); - - return [l, a, b]; -}; - -convert$4.rgb.ansi16 = function (args, saturation = null) { - const [r, g, b] = args; - let value = saturation === null ? convert$4.rgb.hsv(args)[2] : saturation; // Hsv -> ansi16 optimization - - value = Math.round(value / 50); - - if (value === 0) { - return 30; - } - - let ansi = 30 - + ((Math.round(b / 255) << 2) - | (Math.round(g / 255) << 1) - | Math.round(r / 255)); - - if (value === 2) { - ansi += 60; - } - - return ansi; -}; - -convert$4.hsv.ansi16 = function (args) { - // Optimization here; we already know the value and don't need to get - // it converted for us. - return convert$4.rgb.ansi16(convert$4.hsv.rgb(args), args[2]); -}; - -convert$4.rgb.ansi256 = function (args) { - const r = args[0]; - const g = args[1]; - const b = args[2]; - - // We use the extended greyscale palette here, with the exception of - // black and white. normal palette only has 4 greyscale shades. - if (r === g && g === b) { - if (r < 8) { - return 16; - } - - if (r > 248) { - return 231; - } - - return Math.round(((r - 8) / 247) * 24) + 232; - } - - const ansi = 16 - + (36 * Math.round(r / 255 * 5)) - + (6 * Math.round(g / 255 * 5)) - + Math.round(b / 255 * 5); - - return ansi; -}; - -convert$4.ansi16.rgb = function (args) { - let color = args % 10; - - // Handle greyscale - if (color === 0 || color === 7) { - if (args > 50) { - color += 3.5; - } - - color = color / 10.5 * 255; - - return [color, color, color]; - } - - const mult = (~~(args > 50) + 1) * 0.5; - const r = ((color & 1) * mult) * 255; - const g = (((color >> 1) & 1) * mult) * 255; - const b = (((color >> 2) & 1) * mult) * 255; - - return [r, g, b]; -}; - -convert$4.ansi256.rgb = function (args) { - // Handle greyscale - if (args >= 232) { - const c = (args - 232) * 10 + 8; - return [c, c, c]; - } - - args -= 16; - - let rem; - const r = Math.floor(args / 36) / 5 * 255; - const g = Math.floor((rem = args % 36) / 6) / 5 * 255; - const b = (rem % 6) / 5 * 255; - - return [r, g, b]; -}; - -convert$4.rgb.hex = function (args) { - const integer = ((Math.round(args[0]) & 0xFF) << 16) - + ((Math.round(args[1]) & 0xFF) << 8) - + (Math.round(args[2]) & 0xFF); - - const string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; - -convert$4.hex.rgb = function (args) { - const match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); - if (!match) { - return [0, 0, 0]; - } - - let colorString = match[0]; - - if (match[0].length === 3) { - colorString = colorString.split('').map(char => { - return char + char; - }).join(''); - } - - const integer = parseInt(colorString, 16); - const r = (integer >> 16) & 0xFF; - const g = (integer >> 8) & 0xFF; - const b = integer & 0xFF; - - return [r, g, b]; -}; - -convert$4.rgb.hcg = function (rgb) { - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - const max = Math.max(Math.max(r, g), b); - const min = Math.min(Math.min(r, g), b); - const chroma = (max - min); - let grayscale; - let hue; - - if (chroma < 1) { - grayscale = min / (1 - chroma); - } else { - grayscale = 0; - } - - if (chroma <= 0) { - hue = 0; - } else - if (max === r) { - hue = ((g - b) / chroma) % 6; - } else - if (max === g) { - hue = 2 + (b - r) / chroma; - } else { - hue = 4 + (r - g) / chroma; - } - - hue /= 6; - hue %= 1; - - return [hue * 360, chroma * 100, grayscale * 100]; -}; - -convert$4.hsl.hcg = function (hsl) { - const s = hsl[1] / 100; - const l = hsl[2] / 100; - - const c = l < 0.5 ? (2.0 * s * l) : (2.0 * s * (1.0 - l)); - - let f = 0; - if (c < 1.0) { - f = (l - 0.5 * c) / (1.0 - c); - } - - return [hsl[0], c * 100, f * 100]; -}; - -convert$4.hsv.hcg = function (hsv) { - const s = hsv[1] / 100; - const v = hsv[2] / 100; - - const c = s * v; - let f = 0; - - if (c < 1.0) { - f = (v - c) / (1 - c); - } - - return [hsv[0], c * 100, f * 100]; -}; - -convert$4.hcg.rgb = function (hcg) { - const h = hcg[0] / 360; - const c = hcg[1] / 100; - const g = hcg[2] / 100; - - if (c === 0.0) { - return [g * 255, g * 255, g * 255]; - } - - const pure = [0, 0, 0]; - const hi = (h % 1) * 6; - const v = hi % 1; - const w = 1 - v; - let mg = 0; - - /* eslint-disable max-statements-per-line */ - switch (Math.floor(hi)) { - case 0: - pure[0] = 1; pure[1] = v; pure[2] = 0; break; - case 1: - pure[0] = w; pure[1] = 1; pure[2] = 0; break; - case 2: - pure[0] = 0; pure[1] = 1; pure[2] = v; break; - case 3: - pure[0] = 0; pure[1] = w; pure[2] = 1; break; - case 4: - pure[0] = v; pure[1] = 0; pure[2] = 1; break; - default: - pure[0] = 1; pure[1] = 0; pure[2] = w; - } - /* eslint-enable max-statements-per-line */ - - mg = (1.0 - c) * g; - - return [ - (c * pure[0] + mg) * 255, - (c * pure[1] + mg) * 255, - (c * pure[2] + mg) * 255 - ]; -}; - -convert$4.hcg.hsv = function (hcg) { - const c = hcg[1] / 100; - const g = hcg[2] / 100; - - const v = c + g * (1.0 - c); - let f = 0; - - if (v > 0.0) { - f = c / v; - } - - return [hcg[0], f * 100, v * 100]; -}; - -convert$4.hcg.hsl = function (hcg) { - const c = hcg[1] / 100; - const g = hcg[2] / 100; - - const l = g * (1.0 - c) + 0.5 * c; - let s = 0; - - if (l > 0.0 && l < 0.5) { - s = c / (2 * l); - } else - if (l >= 0.5 && l < 1.0) { - s = c / (2 * (1 - l)); - } - - return [hcg[0], s * 100, l * 100]; -}; - -convert$4.hcg.hwb = function (hcg) { - const c = hcg[1] / 100; - const g = hcg[2] / 100; - const v = c + g * (1.0 - c); - return [hcg[0], (v - c) * 100, (1 - v) * 100]; -}; - -convert$4.hwb.hcg = function (hwb) { - const w = hwb[1] / 100; - const b = hwb[2] / 100; - const v = 1 - b; - const c = v - w; - let g = 0; - - if (c < 1) { - g = (v - c) / (1 - c); - } - - return [hwb[0], c * 100, g * 100]; -}; - -convert$4.apple.rgb = function (apple) { - return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; -}; - -convert$4.rgb.apple = function (rgb) { - return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; -}; - -convert$4.gray.rgb = function (args) { - return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; -}; - -convert$4.gray.hsl = function (args) { - return [0, 0, args[0]]; -}; - -convert$4.gray.hsv = convert$4.gray.hsl; - -convert$4.gray.hwb = function (gray) { - return [0, 100, gray[0]]; -}; - -convert$4.gray.cmyk = function (gray) { - return [0, 0, 0, gray[0]]; -}; - -convert$4.gray.lab = function (gray) { - return [gray[0], 0, 0]; -}; - -convert$4.gray.hex = function (gray) { - const val = Math.round(gray[0] / 100 * 255) & 0xFF; - const integer = (val << 16) + (val << 8) + val; - - const string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; - -convert$4.rgb.gray = function (rgb) { - const val = (rgb[0] + rgb[1] + rgb[2]) / 3; - return [val / 255 * 100]; -}; - -const conversions$4 = conversions$5; - -/* - This function routes a model to all other models. - - all functions that are routed have a property `.conversion` attached - to the returned synthetic function. This property is an array - of strings, each with the steps in between the 'from' and 'to' - color models (inclusive). - - conversions that are not possible simply are not included. -*/ - -function buildGraph$1() { - const graph = {}; - // https://jsperf.com/object-keys-vs-for-in-with-closure/3 - const models = Object.keys(conversions$4); - - for (let len = models.length, i = 0; i < len; i++) { - graph[models[i]] = { - // http://jsperf.com/1-vs-infinity - // micro-opt, but this is simple. - distance: -1, - parent: null - }; - } - - return graph; -} - -// https://en.wikipedia.org/wiki/Breadth-first_search -function deriveBFS$1(fromModel) { - const graph = buildGraph$1(); - const queue = [fromModel]; // Unshift -> queue -> pop - - graph[fromModel].distance = 0; - - while (queue.length) { - const current = queue.pop(); - const adjacents = Object.keys(conversions$4[current]); - - for (let len = adjacents.length, i = 0; i < len; i++) { - const adjacent = adjacents[i]; - const node = graph[adjacent]; - - if (node.distance === -1) { - node.distance = graph[current].distance + 1; - node.parent = current; - queue.unshift(adjacent); - } - } - } - - return graph; -} - -function link$2(from, to) { - return function (args) { - return to(from(args)); - }; -} - -function wrapConversion$1(toModel, graph) { - const path = [graph[toModel].parent, toModel]; - let fn = conversions$4[graph[toModel].parent][toModel]; - - let cur = graph[toModel].parent; - while (graph[cur].parent) { - path.unshift(graph[cur].parent); - fn = link$2(conversions$4[graph[cur].parent][cur], fn); - cur = graph[cur].parent; - } - - fn.conversion = path; - return fn; -} - -var route$3 = function (fromModel) { - const graph = deriveBFS$1(fromModel); - const conversion = {}; - - const models = Object.keys(graph); - for (let len = models.length, i = 0; i < len; i++) { - const toModel = models[i]; - const node = graph[toModel]; - - if (node.parent === null) { - // No possible conversion, or this node is the source model. - continue; - } - - conversion[toModel] = wrapConversion$1(toModel, graph); - } - - return conversion; -}; - -const conversions$3 = conversions$5; -const route$2 = route$3; - -const convert$3 = {}; - -const models$1 = Object.keys(conversions$3); - -function wrapRaw$1(fn) { - const wrappedFn = function (...args) { - const arg0 = args[0]; - if (arg0 === undefined || arg0 === null) { - return arg0; - } - - if (arg0.length > 1) { - args = arg0; - } - - return fn(args); - }; - - // Preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } - - return wrappedFn; -} - -function wrapRounded$1(fn) { - const wrappedFn = function (...args) { - const arg0 = args[0]; - - if (arg0 === undefined || arg0 === null) { - return arg0; - } - - if (arg0.length > 1) { - args = arg0; - } - - const result = fn(args); - - // We're assuming the result is an array here. - // see notice in conversions.js; don't use box types - // in conversion functions. - if (typeof result === 'object') { - for (let len = result.length, i = 0; i < len; i++) { - result[i] = Math.round(result[i]); - } - } - - return result; - }; - - // Preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } - - return wrappedFn; -} - -models$1.forEach(fromModel => { - convert$3[fromModel] = {}; - - Object.defineProperty(convert$3[fromModel], 'channels', {value: conversions$3[fromModel].channels}); - Object.defineProperty(convert$3[fromModel], 'labels', {value: conversions$3[fromModel].labels}); - - const routes = route$2(fromModel); - const routeModels = Object.keys(routes); - - routeModels.forEach(toModel => { - const fn = routes[toModel]; - - convert$3[fromModel][toModel] = wrapRounded$1(fn); - convert$3[fromModel][toModel].raw = wrapRaw$1(fn); - }); -}); - -var colorConvert$1 = convert$3; - -(function (module) { - -const wrapAnsi16 = (fn, offset) => (...args) => { - const code = fn(...args); - return `\u001B[${code + offset}m`; -}; - -const wrapAnsi256 = (fn, offset) => (...args) => { - const code = fn(...args); - return `\u001B[${38 + offset};5;${code}m`; -}; - -const wrapAnsi16m = (fn, offset) => (...args) => { - const rgb = fn(...args); - return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; -}; - -const ansi2ansi = n => n; -const rgb2rgb = (r, g, b) => [r, g, b]; - -const setLazyProperty = (object, property, get) => { - Object.defineProperty(object, property, { - get: () => { - const value = get(); - - Object.defineProperty(object, property, { - value, - enumerable: true, - configurable: true - }); - - return value; - }, - enumerable: true, - configurable: true - }); -}; - -/** @type {typeof import('color-convert')} */ -let colorConvert; -const makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => { - if (colorConvert === undefined) { - colorConvert = colorConvert$1; - } - - const offset = isBackground ? 10 : 0; - const styles = {}; - - for (const [sourceSpace, suite] of Object.entries(colorConvert)) { - const name = sourceSpace === 'ansi16' ? 'ansi' : sourceSpace; - if (sourceSpace === targetSpace) { - styles[name] = wrap(identity, offset); - } else if (typeof suite === 'object') { - styles[name] = wrap(suite[targetSpace], offset); - } - } - - return styles; -}; - -function assembleStyles() { - const codes = new Map(); - const styles = { - modifier: { - reset: [0, 0], - // 21 isn't widely supported and 22 does the same thing - bold: [1, 22], - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29] - }, - color: { - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], - - // Bright color - blackBright: [90, 39], - redBright: [91, 39], - greenBright: [92, 39], - yellowBright: [93, 39], - blueBright: [94, 39], - magentaBright: [95, 39], - cyanBright: [96, 39], - whiteBright: [97, 39] - }, - bgColor: { - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49], - - // Bright color - bgBlackBright: [100, 49], - bgRedBright: [101, 49], - bgGreenBright: [102, 49], - bgYellowBright: [103, 49], - bgBlueBright: [104, 49], - bgMagentaBright: [105, 49], - bgCyanBright: [106, 49], - bgWhiteBright: [107, 49] - } - }; - - // Alias bright black as gray (and grey) - styles.color.gray = styles.color.blackBright; - styles.bgColor.bgGray = styles.bgColor.bgBlackBright; - styles.color.grey = styles.color.blackBright; - styles.bgColor.bgGrey = styles.bgColor.bgBlackBright; - - for (const [groupName, group] of Object.entries(styles)) { - for (const [styleName, style] of Object.entries(group)) { - styles[styleName] = { - open: `\u001B[${style[0]}m`, - close: `\u001B[${style[1]}m` - }; - - group[styleName] = styles[styleName]; - - codes.set(style[0], style[1]); - } - - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false - }); - } - - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false - }); - - styles.color.close = '\u001B[39m'; - styles.bgColor.close = '\u001B[49m'; - - setLazyProperty(styles.color, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, false)); - setLazyProperty(styles.color, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, false)); - setLazyProperty(styles.color, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, false)); - setLazyProperty(styles.bgColor, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, true)); - setLazyProperty(styles.bgColor, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, true)); - setLazyProperty(styles.bgColor, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, true)); - - return styles; -} - -// Make the export immutable -Object.defineProperty(module, 'exports', { - enumerable: true, - get: assembleStyles -}); -}(ansiStyles$2)); - -var hasFlag$4 = (flag, argv = process.argv) => { - const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const position = argv.indexOf(prefix + flag); - const terminatorPosition = argv.indexOf('--'); - return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); -}; - -const os$2 = require$$0$2; -const tty = tty$1; -const hasFlag$3 = hasFlag$4; - -const {env: env$2} = process; - -let forceColor$1; -if (hasFlag$3('no-color') || - hasFlag$3('no-colors') || - hasFlag$3('color=false') || - hasFlag$3('color=never')) { - forceColor$1 = 0; -} else if (hasFlag$3('color') || - hasFlag$3('colors') || - hasFlag$3('color=true') || - hasFlag$3('color=always')) { - forceColor$1 = 1; -} - -if ('FORCE_COLOR' in env$2) { - if (env$2.FORCE_COLOR === 'true') { - forceColor$1 = 1; - } else if (env$2.FORCE_COLOR === 'false') { - forceColor$1 = 0; - } else { - forceColor$1 = env$2.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env$2.FORCE_COLOR, 10), 3); - } -} - -function translateLevel$2(level) { - if (level === 0) { - return false; - } - - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; -} - -function supportsColor$2(haveStream, streamIsTTY) { - if (forceColor$1 === 0) { - return 0; - } - - if (hasFlag$3('color=16m') || - hasFlag$3('color=full') || - hasFlag$3('color=truecolor')) { - return 3; - } - - if (hasFlag$3('color=256')) { - return 2; - } - - if (haveStream && !streamIsTTY && forceColor$1 === undefined) { - return 0; - } - - const min = forceColor$1 || 0; - - if (env$2.TERM === 'dumb') { - return min; - } - - if (process.platform === 'win32') { - // Windows 10 build 10586 is the first Windows release that supports 256 colors. - // Windows 10 build 14931 is the first release that supports 16m/TrueColor. - const osRelease = os$2.release().split('.'); - if ( - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; - } - - return 1; - } - - if ('CI' in env$2) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE'].some(sign => sign in env$2) || env$2.CI_NAME === 'codeship') { - return 1; - } - - return min; - } - - if ('TEAMCITY_VERSION' in env$2) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env$2.TEAMCITY_VERSION) ? 1 : 0; - } - - if (env$2.COLORTERM === 'truecolor') { - return 3; - } - - if ('TERM_PROGRAM' in env$2) { - const version = parseInt((env$2.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - - switch (env$2.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default - } - } - - if (/-256(color)?$/i.test(env$2.TERM)) { - return 2; - } - - if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env$2.TERM)) { - return 1; - } - - if ('COLORTERM' in env$2) { - return 1; - } - - return min; -} - -function getSupportLevel$1(stream) { - const level = supportsColor$2(stream, stream && stream.isTTY); - return translateLevel$2(level); -} - -var supportsColor_1$1 = { - supportsColor: getSupportLevel$1, - stdout: translateLevel$2(supportsColor$2(true, tty.isatty(1))), - stderr: translateLevel$2(supportsColor$2(true, tty.isatty(2))) -}; - -const stringReplaceAll$1 = (string, substring, replacer) => { - let index = string.indexOf(substring); - if (index === -1) { - return string; - } - - const substringLength = substring.length; - let endIndex = 0; - let returnValue = ''; - do { - returnValue += string.substr(endIndex, index - endIndex) + substring + replacer; - endIndex = index + substringLength; - index = string.indexOf(substring, endIndex); - } while (index !== -1); - - returnValue += string.substr(endIndex); - return returnValue; -}; - -const stringEncaseCRLFWithFirstIndex$1 = (string, prefix, postfix, index) => { - let endIndex = 0; - let returnValue = ''; - do { - const gotCR = string[index - 1] === '\r'; - returnValue += string.substr(endIndex, (gotCR ? index - 1 : index) - endIndex) + prefix + (gotCR ? '\r\n' : '\n') + postfix; - endIndex = index + 1; - index = string.indexOf('\n', endIndex); - } while (index !== -1); - - returnValue += string.substr(endIndex); - return returnValue; -}; - -var util$4 = { - stringReplaceAll: stringReplaceAll$1, - stringEncaseCRLFWithFirstIndex: stringEncaseCRLFWithFirstIndex$1 -}; - -const TEMPLATE_REGEX$1 = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; -const STYLE_REGEX$1 = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; -const STRING_REGEX$1 = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; -const ESCAPE_REGEX$1 = /\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi; - -const ESCAPES$1 = new Map([ - ['n', '\n'], - ['r', '\r'], - ['t', '\t'], - ['b', '\b'], - ['f', '\f'], - ['v', '\v'], - ['0', '\0'], - ['\\', '\\'], - ['e', '\u001B'], - ['a', '\u0007'] -]); - -function unescape$1(c) { - const u = c[0] === 'u'; - const bracket = c[1] === '{'; - - if ((u && !bracket && c.length === 5) || (c[0] === 'x' && c.length === 3)) { - return String.fromCharCode(parseInt(c.slice(1), 16)); - } - - if (u && bracket) { - return String.fromCodePoint(parseInt(c.slice(2, -1), 16)); - } - - return ESCAPES$1.get(c) || c; -} - -function parseArguments$1(name, arguments_) { - const results = []; - const chunks = arguments_.trim().split(/\s*,\s*/g); - let matches; - - for (const chunk of chunks) { - const number = Number(chunk); - if (!Number.isNaN(number)) { - results.push(number); - } else if ((matches = chunk.match(STRING_REGEX$1))) { - results.push(matches[2].replace(ESCAPE_REGEX$1, (m, escape, character) => escape ? unescape$1(escape) : character)); - } else { - throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); - } - } - - return results; -} - -function parseStyle$1(style) { - STYLE_REGEX$1.lastIndex = 0; - - const results = []; - let matches; - - while ((matches = STYLE_REGEX$1.exec(style)) !== null) { - const name = matches[1]; - - if (matches[2]) { - const args = parseArguments$1(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); - } - } - - return results; -} - -function buildStyle$1(chalk, styles) { - const enabled = {}; - - for (const layer of styles) { - for (const style of layer.styles) { - enabled[style[0]] = layer.inverse ? null : style.slice(1); - } - } - - let current = chalk; - for (const [styleName, styles] of Object.entries(enabled)) { - if (!Array.isArray(styles)) { - continue; - } - - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } - - current = styles.length > 0 ? current[styleName](...styles) : current[styleName]; - } - - return current; -} - -var templates$1 = (chalk, temporary) => { - const styles = []; - const chunks = []; - let chunk = []; - - // eslint-disable-next-line max-params - temporary.replace(TEMPLATE_REGEX$1, (m, escapeCharacter, inverse, style, close, character) => { - if (escapeCharacter) { - chunk.push(unescape$1(escapeCharacter)); - } else if (style) { - const string = chunk.join(''); - chunk = []; - chunks.push(styles.length === 0 ? string : buildStyle$1(chalk, styles)(string)); - styles.push({inverse, styles: parseStyle$1(style)}); - } else if (close) { - if (styles.length === 0) { - throw new Error('Found extraneous } in Chalk template literal'); - } - - chunks.push(buildStyle$1(chalk, styles)(chunk.join(''))); - chunk = []; - styles.pop(); - } else { - chunk.push(character); - } - }); - - chunks.push(chunk.join('')); - - if (styles.length > 0) { - const errMessage = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMessage); - } - - return chunks.join(''); -}; - -const ansiStyles$1 = ansiStyles$2.exports; -const {stdout: stdoutColor, stderr: stderrColor} = supportsColor_1$1; -const { - stringReplaceAll, - stringEncaseCRLFWithFirstIndex -} = util$4; - -const {isArray: isArray$2} = Array; - -// `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = [ - 'ansi', - 'ansi', - 'ansi256', - 'ansi16m' -]; - -const styles = Object.create(null); - -const applyOptions = (object, options = {}) => { - if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) { - throw new Error('The `level` option should be an integer from 0 to 3'); - } - - // Detect level if not set manually - const colorLevel = stdoutColor ? stdoutColor.level : 0; - object.level = options.level === undefined ? colorLevel : options.level; -}; - -class ChalkClass { - constructor(options) { - // eslint-disable-next-line no-constructor-return - return chalkFactory(options); - } -} - -const chalkFactory = options => { - const chalk = {}; - applyOptions(chalk, options); - - chalk.template = (...arguments_) => chalkTag(chalk.template, ...arguments_); - - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); - - chalk.template.constructor = () => { - throw new Error('`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.'); - }; - - chalk.template.Instance = ChalkClass; - - return chalk.template; -}; - -function Chalk(options) { - return chalkFactory(options); -} - -for (const [styleName, style] of Object.entries(ansiStyles$1)) { - styles[styleName] = { - get() { - const builder = createBuilder(this, createStyler(style.open, style.close, this._styler), this._isEmpty); - Object.defineProperty(this, styleName, {value: builder}); - return builder; - } - }; -} - -styles.visible = { - get() { - const builder = createBuilder(this, this._styler, true); - Object.defineProperty(this, 'visible', {value: builder}); - return builder; - } -}; - -const usedModels = ['rgb', 'hex', 'keyword', 'hsl', 'hsv', 'hwb', 'ansi', 'ansi256']; - -for (const model of usedModels) { - styles[model] = { - get() { - const {level} = this; - return function (...arguments_) { - const styler = createStyler(ansiStyles$1.color[levelMapping[level]][model](...arguments_), ansiStyles$1.color.close, this._styler); - return createBuilder(this, styler, this._isEmpty); - }; - } - }; -} - -for (const model of usedModels) { - const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); - styles[bgModel] = { - get() { - const {level} = this; - return function (...arguments_) { - const styler = createStyler(ansiStyles$1.bgColor[levelMapping[level]][model](...arguments_), ansiStyles$1.bgColor.close, this._styler); - return createBuilder(this, styler, this._isEmpty); - }; - } - }; -} - -const proto = Object.defineProperties(() => {}, { - ...styles, - level: { - enumerable: true, - get() { - return this._generator.level; - }, - set(level) { - this._generator.level = level; - } - } -}); - -const createStyler = (open, close, parent) => { - let openAll; - let closeAll; - if (parent === undefined) { - openAll = open; - closeAll = close; - } else { - openAll = parent.openAll + open; - closeAll = close + parent.closeAll; - } - - return { - open, - close, - openAll, - closeAll, - parent - }; -}; - -const createBuilder = (self, _styler, _isEmpty) => { - const builder = (...arguments_) => { - if (isArray$2(arguments_[0]) && isArray$2(arguments_[0].raw)) { - // Called as a template literal, for example: chalk.red`2 + 3 = {bold ${2+3}}` - return applyStyle(builder, chalkTag(builder, ...arguments_)); - } - - // Single argument is hot path, implicit coercion is faster than anything - // eslint-disable-next-line no-implicit-coercion - return applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' ')); - }; - - // We alter the prototype because we must return a function, but there is - // no way to create a function with a different prototype - Object.setPrototypeOf(builder, proto); - - builder._generator = self; - builder._styler = _styler; - builder._isEmpty = _isEmpty; - - return builder; -}; - -const applyStyle = (self, string) => { - if (self.level <= 0 || !string) { - return self._isEmpty ? '' : string; - } - - let styler = self._styler; - - if (styler === undefined) { - return string; - } - - const {openAll, closeAll} = styler; - if (string.indexOf('\u001B') !== -1) { - while (styler !== undefined) { - // Replace any instances already present with a re-opening code - // otherwise only the part of the string until said closing code - // will be colored, and the rest will simply be 'plain'. - string = stringReplaceAll(string, styler.close, styler.open); - - styler = styler.parent; - } - } - - // We can move both next actions out of loop, because remaining actions in loop won't have - // any/visible effect on parts we add here. Close the styling before a linebreak and reopen - // after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92 - const lfIndex = string.indexOf('\n'); - if (lfIndex !== -1) { - string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex); - } - - return openAll + string + closeAll; -}; - -let template; -const chalkTag = (chalk, ...strings) => { - const [firstString] = strings; - - if (!isArray$2(firstString) || !isArray$2(firstString.raw)) { - // If chalk() was called by itself or with a string, - // return the string itself as a string. - return strings.join(' '); - } - - const arguments_ = strings.slice(1); - const parts = [firstString.raw[0]]; - - for (let i = 1; i < firstString.length; i++) { - parts.push( - String(arguments_[i - 1]).replace(/[{}\\]/g, '\\$&'), - String(firstString.raw[i]) - ); - } - - if (template === undefined) { - template = templates$1; - } - - return template(chalk, parts.join('')); -}; - -Object.defineProperties(Chalk.prototype, styles); - -const chalk$1 = Chalk(); // eslint-disable-line new-cap -chalk$1.supportsColor = stdoutColor; -chalk$1.stderr = Chalk({level: stderrColor ? stderrColor.level : 0}); // eslint-disable-line new-cap -chalk$1.stderr.supportsColor = stderrColor; - -var source$1 = chalk$1; - -var chokidar = {}; - -var utils$7 = {}; - -const path$a = path$b; -const WIN_SLASH = '\\\\/'; -const WIN_NO_SLASH = `[^${WIN_SLASH}]`; - -/** - * Posix glob regex - */ - -const DOT_LITERAL = '\\.'; -const PLUS_LITERAL = '\\+'; -const QMARK_LITERAL = '\\?'; -const SLASH_LITERAL = '\\/'; -const ONE_CHAR = '(?=.)'; -const QMARK = '[^/]'; -const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; -const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; -const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; -const NO_DOT = `(?!${DOT_LITERAL})`; -const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; -const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; -const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; -const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; -const STAR$1 = `${QMARK}*?`; - -const POSIX_CHARS = { - DOT_LITERAL, - PLUS_LITERAL, - QMARK_LITERAL, - SLASH_LITERAL, - ONE_CHAR, - QMARK, - END_ANCHOR, - DOTS_SLASH, - NO_DOT, - NO_DOTS, - NO_DOT_SLASH, - NO_DOTS_SLASH, - QMARK_NO_DOT, - STAR: STAR$1, - START_ANCHOR -}; - -/** - * Windows glob regex - */ - -const WINDOWS_CHARS = { - ...POSIX_CHARS, - - SLASH_LITERAL: `[${WIN_SLASH}]`, - QMARK: WIN_NO_SLASH, - STAR: `${WIN_NO_SLASH}*?`, - DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, - NO_DOT: `(?!${DOT_LITERAL})`, - NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, - NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, - NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, - QMARK_NO_DOT: `[^.${WIN_SLASH}]`, - START_ANCHOR: `(?:^|[${WIN_SLASH}])`, - END_ANCHOR: `(?:[${WIN_SLASH}]|$)` -}; - -/** - * POSIX Bracket Regex - */ - -const POSIX_REGEX_SOURCE$1 = { - alnum: 'a-zA-Z0-9', - alpha: 'a-zA-Z', - ascii: '\\x00-\\x7F', - blank: ' \\t', - cntrl: '\\x00-\\x1F\\x7F', - digit: '0-9', - graph: '\\x21-\\x7E', - lower: 'a-z', - print: '\\x20-\\x7E ', - punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', - space: ' \\t\\r\\n\\v\\f', - upper: 'A-Z', - word: 'A-Za-z0-9_', - xdigit: 'A-Fa-f0-9' -}; - -var constants$5 = { - MAX_LENGTH: 1024 * 64, - POSIX_REGEX_SOURCE: POSIX_REGEX_SOURCE$1, - - // regular expressions - REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, - REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, - REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, - REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, - REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, - REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, - - // Replace globs with equivalent patterns to reduce parsing time. - REPLACEMENTS: { - '***': '*', - '**/**': '**', - '**/**/**': '**' - }, - - // Digits - CHAR_0: 48, /* 0 */ - CHAR_9: 57, /* 9 */ - - // Alphabet chars. - CHAR_UPPERCASE_A: 65, /* A */ - CHAR_LOWERCASE_A: 97, /* a */ - CHAR_UPPERCASE_Z: 90, /* Z */ - CHAR_LOWERCASE_Z: 122, /* z */ - - CHAR_LEFT_PARENTHESES: 40, /* ( */ - CHAR_RIGHT_PARENTHESES: 41, /* ) */ - - CHAR_ASTERISK: 42, /* * */ - - // Non-alphabetic chars. - CHAR_AMPERSAND: 38, /* & */ - CHAR_AT: 64, /* @ */ - CHAR_BACKWARD_SLASH: 92, /* \ */ - CHAR_CARRIAGE_RETURN: 13, /* \r */ - CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ - CHAR_COLON: 58, /* : */ - CHAR_COMMA: 44, /* , */ - CHAR_DOT: 46, /* . */ - CHAR_DOUBLE_QUOTE: 34, /* " */ - CHAR_EQUAL: 61, /* = */ - CHAR_EXCLAMATION_MARK: 33, /* ! */ - CHAR_FORM_FEED: 12, /* \f */ - CHAR_FORWARD_SLASH: 47, /* / */ - CHAR_GRAVE_ACCENT: 96, /* ` */ - CHAR_HASH: 35, /* # */ - CHAR_HYPHEN_MINUS: 45, /* - */ - CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ - CHAR_LEFT_CURLY_BRACE: 123, /* { */ - CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ - CHAR_LINE_FEED: 10, /* \n */ - CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ - CHAR_PERCENT: 37, /* % */ - CHAR_PLUS: 43, /* + */ - CHAR_QUESTION_MARK: 63, /* ? */ - CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ - CHAR_RIGHT_CURLY_BRACE: 125, /* } */ - CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ - CHAR_SEMICOLON: 59, /* ; */ - CHAR_SINGLE_QUOTE: 39, /* ' */ - CHAR_SPACE: 32, /* */ - CHAR_TAB: 9, /* \t */ - CHAR_UNDERSCORE: 95, /* _ */ - CHAR_VERTICAL_LINE: 124, /* | */ - CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ - - SEP: path$a.sep, - - /** - * Create EXTGLOB_CHARS - */ - - extglobChars(chars) { - return { - '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, - '?': { type: 'qmark', open: '(?:', close: ')?' }, - '+': { type: 'plus', open: '(?:', close: ')+' }, - '*': { type: 'star', open: '(?:', close: ')*' }, - '@': { type: 'at', open: '(?:', close: ')' } - }; - }, - - /** - * Create GLOB_CHARS - */ - - globChars(win32) { - return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; - } -}; - -(function (exports) { - -const path = path$b; -const win32 = process.platform === 'win32'; -const { - REGEX_BACKSLASH, - REGEX_REMOVE_BACKSLASH, - REGEX_SPECIAL_CHARS, - REGEX_SPECIAL_CHARS_GLOBAL -} = constants$5; - -exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); -exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); -exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); -exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); -exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); - -exports.removeBackslashes = str => { - return str.replace(REGEX_REMOVE_BACKSLASH, match => { - return match === '\\' ? '' : match; - }); -}; - -exports.supportsLookbehinds = () => { - const segs = process.version.slice(1).split('.').map(Number); - if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) { - return true; - } - return false; -}; - -exports.isWindows = options => { - if (options && typeof options.windows === 'boolean') { - return options.windows; - } - return win32 === true || path.sep === '\\'; -}; - -exports.escapeLast = (input, char, lastIdx) => { - const idx = input.lastIndexOf(char, lastIdx); - if (idx === -1) return input; - if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); - return `${input.slice(0, idx)}\\${input.slice(idx)}`; -}; - -exports.removePrefix = (input, state = {}) => { - let output = input; - if (output.startsWith('./')) { - output = output.slice(2); - state.prefix = './'; - } - return output; -}; - -exports.wrapOutput = (input, state = {}, options = {}) => { - const prepend = options.contains ? '' : '^'; - const append = options.contains ? '' : '$'; - - let output = `${prepend}(?:${input})${append}`; - if (state.negated === true) { - output = `(?:^(?!${output}).*$)`; - } - return output; -}; -}(utils$7)); - -const utils$6 = utils$7; -const { - CHAR_ASTERISK: CHAR_ASTERISK$1, /* * */ - CHAR_AT, /* @ */ - CHAR_BACKWARD_SLASH, /* \ */ - CHAR_COMMA: CHAR_COMMA$2, /* , */ - CHAR_DOT: CHAR_DOT$1, /* . */ - CHAR_EXCLAMATION_MARK, /* ! */ - CHAR_FORWARD_SLASH, /* / */ - CHAR_LEFT_CURLY_BRACE: CHAR_LEFT_CURLY_BRACE$1, /* { */ - CHAR_LEFT_PARENTHESES: CHAR_LEFT_PARENTHESES$1, /* ( */ - CHAR_LEFT_SQUARE_BRACKET: CHAR_LEFT_SQUARE_BRACKET$2, /* [ */ - CHAR_PLUS, /* + */ - CHAR_QUESTION_MARK, /* ? */ - CHAR_RIGHT_CURLY_BRACE: CHAR_RIGHT_CURLY_BRACE$1, /* } */ - CHAR_RIGHT_PARENTHESES: CHAR_RIGHT_PARENTHESES$1, /* ) */ - CHAR_RIGHT_SQUARE_BRACKET: CHAR_RIGHT_SQUARE_BRACKET$2 /* ] */ -} = constants$5; - -const isPathSeparator = code => { - return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; -}; - -const depth = token => { - if (token.isPrefix !== true) { - token.depth = token.isGlobstar ? Infinity : 1; - } -}; - -/** - * Quickly scans a glob pattern and returns an object with a handful of - * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), - * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not - * with `!(`) and `negatedExtglob` (true if the path starts with `!(`). - * - * ```js - * const pm = require('picomatch'); - * console.log(pm.scan('foo/bar/*.js')); - * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } - * ``` - * @param {String} `str` - * @param {Object} `options` - * @return {Object} Returns an object with tokens and regex source string. - * @api public - */ - -const scan$1 = (input, options) => { - const opts = options || {}; - - const length = input.length - 1; - const scanToEnd = opts.parts === true || opts.scanToEnd === true; - const slashes = []; - const tokens = []; - const parts = []; - - let str = input; - let index = -1; - let start = 0; - let lastIndex = 0; - let isBrace = false; - let isBracket = false; - let isGlob = false; - let isExtglob = false; - let isGlobstar = false; - let braceEscaped = false; - let backslashes = false; - let negated = false; - let negatedExtglob = false; - let finished = false; - let braces = 0; - let prev; - let code; - let token = { value: '', depth: 0, isGlob: false }; - - const eos = () => index >= length; - const peek = () => str.charCodeAt(index + 1); - const advance = () => { - prev = code; - return str.charCodeAt(++index); - }; - - while (index < length) { - code = advance(); - let next; - - if (code === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - code = advance(); - - if (code === CHAR_LEFT_CURLY_BRACE$1) { - braceEscaped = true; - } - continue; - } - - if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE$1) { - braces++; - - while (eos() !== true && (code = advance())) { - if (code === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - advance(); - continue; - } - - if (code === CHAR_LEFT_CURLY_BRACE$1) { - braces++; - continue; - } - - if (braceEscaped !== true && code === CHAR_DOT$1 && (code = advance()) === CHAR_DOT$1) { - isBrace = token.isBrace = true; - isGlob = token.isGlob = true; - finished = true; - - if (scanToEnd === true) { - continue; - } - - break; - } - - if (braceEscaped !== true && code === CHAR_COMMA$2) { - isBrace = token.isBrace = true; - isGlob = token.isGlob = true; - finished = true; - - if (scanToEnd === true) { - continue; - } - - break; - } - - if (code === CHAR_RIGHT_CURLY_BRACE$1) { - braces--; - - if (braces === 0) { - braceEscaped = false; - isBrace = token.isBrace = true; - finished = true; - break; - } - } - } - - if (scanToEnd === true) { - continue; - } - - break; - } - - if (code === CHAR_FORWARD_SLASH) { - slashes.push(index); - tokens.push(token); - token = { value: '', depth: 0, isGlob: false }; - - if (finished === true) continue; - if (prev === CHAR_DOT$1 && index === (start + 1)) { - start += 2; - continue; - } - - lastIndex = index + 1; - continue; - } - - if (opts.noext !== true) { - const isExtglobChar = code === CHAR_PLUS - || code === CHAR_AT - || code === CHAR_ASTERISK$1 - || code === CHAR_QUESTION_MARK - || code === CHAR_EXCLAMATION_MARK; - - if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES$1) { - isGlob = token.isGlob = true; - isExtglob = token.isExtglob = true; - finished = true; - if (code === CHAR_EXCLAMATION_MARK && index === start) { - negatedExtglob = true; - } - - if (scanToEnd === true) { - while (eos() !== true && (code = advance())) { - if (code === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - code = advance(); - continue; - } - - if (code === CHAR_RIGHT_PARENTHESES$1) { - isGlob = token.isGlob = true; - finished = true; - break; - } - } - continue; - } - break; - } - } - - if (code === CHAR_ASTERISK$1) { - if (prev === CHAR_ASTERISK$1) isGlobstar = token.isGlobstar = true; - isGlob = token.isGlob = true; - finished = true; - - if (scanToEnd === true) { - continue; - } - break; - } - - if (code === CHAR_QUESTION_MARK) { - isGlob = token.isGlob = true; - finished = true; - - if (scanToEnd === true) { - continue; - } - break; - } - - if (code === CHAR_LEFT_SQUARE_BRACKET$2) { - while (eos() !== true && (next = advance())) { - if (next === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - advance(); - continue; - } - - if (next === CHAR_RIGHT_SQUARE_BRACKET$2) { - isBracket = token.isBracket = true; - isGlob = token.isGlob = true; - finished = true; - break; - } - } - - if (scanToEnd === true) { - continue; - } - - break; - } - - if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { - negated = token.negated = true; - start++; - continue; - } - - if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES$1) { - isGlob = token.isGlob = true; - - if (scanToEnd === true) { - while (eos() !== true && (code = advance())) { - if (code === CHAR_LEFT_PARENTHESES$1) { - backslashes = token.backslashes = true; - code = advance(); - continue; - } - - if (code === CHAR_RIGHT_PARENTHESES$1) { - finished = true; - break; - } - } - continue; - } - break; - } - - if (isGlob === true) { - finished = true; - - if (scanToEnd === true) { - continue; - } - - break; - } - } - - if (opts.noext === true) { - isExtglob = false; - isGlob = false; - } - - let base = str; - let prefix = ''; - let glob = ''; - - if (start > 0) { - prefix = str.slice(0, start); - str = str.slice(start); - lastIndex -= start; - } - - if (base && isGlob === true && lastIndex > 0) { - base = str.slice(0, lastIndex); - glob = str.slice(lastIndex); - } else if (isGlob === true) { - base = ''; - glob = str; - } else { - base = str; - } - - if (base && base !== '' && base !== '/' && base !== str) { - if (isPathSeparator(base.charCodeAt(base.length - 1))) { - base = base.slice(0, -1); - } - } - - if (opts.unescape === true) { - if (glob) glob = utils$6.removeBackslashes(glob); - - if (base && backslashes === true) { - base = utils$6.removeBackslashes(base); - } - } - - const state = { - prefix, - input, - start, - base, - glob, - isBrace, - isBracket, - isGlob, - isExtglob, - isGlobstar, - negated, - negatedExtglob - }; - - if (opts.tokens === true) { - state.maxDepth = 0; - if (!isPathSeparator(code)) { - tokens.push(token); - } - state.tokens = tokens; - } - - if (opts.parts === true || opts.tokens === true) { - let prevIndex; - - for (let idx = 0; idx < slashes.length; idx++) { - const n = prevIndex ? prevIndex + 1 : start; - const i = slashes[idx]; - const value = input.slice(n, i); - if (opts.tokens) { - if (idx === 0 && start !== 0) { - tokens[idx].isPrefix = true; - tokens[idx].value = prefix; - } else { - tokens[idx].value = value; - } - depth(tokens[idx]); - state.maxDepth += tokens[idx].depth; - } - if (idx !== 0 || value !== '') { - parts.push(value); - } - prevIndex = i; - } - - if (prevIndex && prevIndex + 1 < input.length) { - const value = input.slice(prevIndex + 1); - parts.push(value); - - if (opts.tokens) { - tokens[tokens.length - 1].value = value; - depth(tokens[tokens.length - 1]); - state.maxDepth += tokens[tokens.length - 1].depth; - } - } - - state.slashes = slashes; - state.parts = parts; - } - - return state; -}; - -var scan_1 = scan$1; - -const constants$4 = constants$5; -const utils$5 = utils$7; - -/** - * Constants - */ - -const { - MAX_LENGTH: MAX_LENGTH$4, - POSIX_REGEX_SOURCE, - REGEX_NON_SPECIAL_CHARS, - REGEX_SPECIAL_CHARS_BACKREF, - REPLACEMENTS -} = constants$4; - -/** - * Helpers - */ - -const expandRange = (args, options) => { - if (typeof options.expandRange === 'function') { - return options.expandRange(...args, options); - } - - args.sort(); - const value = `[${args.join('-')}]`; - - try { - /* eslint-disable-next-line no-new */ - new RegExp(value); - } catch (ex) { - return args.map(v => utils$5.escapeRegex(v)).join('..'); - } - - return value; -}; - -/** - * Create the message for a syntax error - */ - -const syntaxError$1 = (type, char) => { - return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; -}; - -/** - * Parse the given input string. - * @param {String} input - * @param {Object} options - * @return {Object} - */ - -const parse$e = (input, options) => { - if (typeof input !== 'string') { - throw new TypeError('Expected a string'); - } - - input = REPLACEMENTS[input] || input; - - const opts = { ...options }; - const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH$4, opts.maxLength) : MAX_LENGTH$4; - - let len = input.length; - if (len > max) { - throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); - } - - const bos = { type: 'bos', value: '', output: opts.prepend || '' }; - const tokens = [bos]; - - const capture = opts.capture ? '' : '?:'; - const win32 = utils$5.isWindows(options); - - // create constants based on platform, for windows or posix - const PLATFORM_CHARS = constants$4.globChars(win32); - const EXTGLOB_CHARS = constants$4.extglobChars(PLATFORM_CHARS); - - const { - DOT_LITERAL, - PLUS_LITERAL, - SLASH_LITERAL, - ONE_CHAR, - DOTS_SLASH, - NO_DOT, - NO_DOT_SLASH, - NO_DOTS_SLASH, - QMARK, - QMARK_NO_DOT, - STAR, - START_ANCHOR - } = PLATFORM_CHARS; - - const globstar = opts => { - return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; - }; - - const nodot = opts.dot ? '' : NO_DOT; - const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; - let star = opts.bash === true ? globstar(opts) : STAR; - - if (opts.capture) { - star = `(${star})`; - } - - // minimatch options support - if (typeof opts.noext === 'boolean') { - opts.noextglob = opts.noext; - } - - const state = { - input, - index: -1, - start: 0, - dot: opts.dot === true, - consumed: '', - output: '', - prefix: '', - backtrack: false, - negated: false, - brackets: 0, - braces: 0, - parens: 0, - quotes: 0, - globstar: false, - tokens - }; - - input = utils$5.removePrefix(input, state); - len = input.length; - - const extglobs = []; - const braces = []; - const stack = []; - let prev = bos; - let value; - - /** - * Tokenizing helpers - */ - - const eos = () => state.index === len - 1; - const peek = state.peek = (n = 1) => input[state.index + n]; - const advance = state.advance = () => input[++state.index] || ''; - const remaining = () => input.slice(state.index + 1); - const consume = (value = '', num = 0) => { - state.consumed += value; - state.index += num; - }; - - const append = token => { - state.output += token.output != null ? token.output : token.value; - consume(token.value); - }; - - const negate = () => { - let count = 1; - - while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { - advance(); - state.start++; - count++; - } - - if (count % 2 === 0) { - return false; - } - - state.negated = true; - state.start++; - return true; - }; - - const increment = type => { - state[type]++; - stack.push(type); - }; - - const decrement = type => { - state[type]--; - stack.pop(); - }; - - /** - * Push tokens onto the tokens array. This helper speeds up - * tokenizing by 1) helping us avoid backtracking as much as possible, - * and 2) helping us avoid creating extra tokens when consecutive - * characters are plain text. This improves performance and simplifies - * lookbehinds. - */ - - const push = tok => { - if (prev.type === 'globstar') { - const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); - const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); - - if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { - state.output = state.output.slice(0, -prev.output.length); - prev.type = 'star'; - prev.value = '*'; - prev.output = star; - state.output += prev.output; - } - } - - if (extglobs.length && tok.type !== 'paren') { - extglobs[extglobs.length - 1].inner += tok.value; - } - - if (tok.value || tok.output) append(tok); - if (prev && prev.type === 'text' && tok.type === 'text') { - prev.value += tok.value; - prev.output = (prev.output || '') + tok.value; - return; - } - - tok.prev = prev; - tokens.push(tok); - prev = tok; - }; - - const extglobOpen = (type, value) => { - const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; - - token.prev = prev; - token.parens = state.parens; - token.output = state.output; - const output = (opts.capture ? '(' : '') + token.open; - - increment('parens'); - push({ type, value, output: state.output ? '' : ONE_CHAR }); - push({ type: 'paren', extglob: true, value: advance(), output }); - extglobs.push(token); - }; - - const extglobClose = token => { - let output = token.close + (opts.capture ? ')' : ''); - let rest; - - if (token.type === 'negate') { - let extglobStar = star; - - if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { - extglobStar = globstar(opts); - } - - if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { - output = token.close = `)$))${extglobStar}`; - } - - if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) { - output = token.close = `)${rest})${extglobStar})`; - } - - if (token.prev.type === 'bos') { - state.negatedExtglob = true; - } - } - - push({ type: 'paren', extglob: true, value, output }); - decrement('parens'); - }; - - /** - * Fast paths - */ - - if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { - let backslashes = false; - - let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { - if (first === '\\') { - backslashes = true; - return m; - } - - if (first === '?') { - if (esc) { - return esc + first + (rest ? QMARK.repeat(rest.length) : ''); - } - if (index === 0) { - return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); - } - return QMARK.repeat(chars.length); - } - - if (first === '.') { - return DOT_LITERAL.repeat(chars.length); - } - - if (first === '*') { - if (esc) { - return esc + first + (rest ? star : ''); - } - return star; - } - return esc ? m : `\\${m}`; - }); - - if (backslashes === true) { - if (opts.unescape === true) { - output = output.replace(/\\/g, ''); - } else { - output = output.replace(/\\+/g, m => { - return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); - }); - } - } - - if (output === input && opts.contains === true) { - state.output = input; - return state; - } - - state.output = utils$5.wrapOutput(output, state, options); - return state; - } - - /** - * Tokenize input until we reach end-of-string - */ - - while (!eos()) { - value = advance(); - - if (value === '\u0000') { - continue; - } - - /** - * Escaped characters - */ - - if (value === '\\') { - const next = peek(); - - if (next === '/' && opts.bash !== true) { - continue; - } - - if (next === '.' || next === ';') { - continue; - } - - if (!next) { - value += '\\'; - push({ type: 'text', value }); - continue; - } - - // collapse slashes to reduce potential for exploits - const match = /^\\+/.exec(remaining()); - let slashes = 0; - - if (match && match[0].length > 2) { - slashes = match[0].length; - state.index += slashes; - if (slashes % 2 !== 0) { - value += '\\'; - } - } - - if (opts.unescape === true) { - value = advance(); - } else { - value += advance(); - } - - if (state.brackets === 0) { - push({ type: 'text', value }); - continue; - } - } - - /** - * If we're inside a regex character class, continue - * until we reach the closing bracket. - */ - - if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { - if (opts.posix !== false && value === ':') { - const inner = prev.value.slice(1); - if (inner.includes('[')) { - prev.posix = true; - - if (inner.includes(':')) { - const idx = prev.value.lastIndexOf('['); - const pre = prev.value.slice(0, idx); - const rest = prev.value.slice(idx + 2); - const posix = POSIX_REGEX_SOURCE[rest]; - if (posix) { - prev.value = pre + posix; - state.backtrack = true; - advance(); - - if (!bos.output && tokens.indexOf(prev) === 1) { - bos.output = ONE_CHAR; - } - continue; - } - } - } - } - - if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { - value = `\\${value}`; - } - - if (value === ']' && (prev.value === '[' || prev.value === '[^')) { - value = `\\${value}`; - } - - if (opts.posix === true && value === '!' && prev.value === '[') { - value = '^'; - } - - prev.value += value; - append({ value }); - continue; - } - - /** - * If we're inside a quoted string, continue - * until we reach the closing double quote. - */ - - if (state.quotes === 1 && value !== '"') { - value = utils$5.escapeRegex(value); - prev.value += value; - append({ value }); - continue; - } - - /** - * Double quotes - */ - - if (value === '"') { - state.quotes = state.quotes === 1 ? 0 : 1; - if (opts.keepQuotes === true) { - push({ type: 'text', value }); - } - continue; - } - - /** - * Parentheses - */ - - if (value === '(') { - increment('parens'); - push({ type: 'paren', value }); - continue; - } - - if (value === ')') { - if (state.parens === 0 && opts.strictBrackets === true) { - throw new SyntaxError(syntaxError$1('opening', '(')); - } - - const extglob = extglobs[extglobs.length - 1]; - if (extglob && state.parens === extglob.parens + 1) { - extglobClose(extglobs.pop()); - continue; - } - - push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); - decrement('parens'); - continue; - } - - /** - * Square brackets - */ - - if (value === '[') { - if (opts.nobracket === true || !remaining().includes(']')) { - if (opts.nobracket !== true && opts.strictBrackets === true) { - throw new SyntaxError(syntaxError$1('closing', ']')); - } - - value = `\\${value}`; - } else { - increment('brackets'); - } - - push({ type: 'bracket', value }); - continue; - } - - if (value === ']') { - if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { - push({ type: 'text', value, output: `\\${value}` }); - continue; - } - - if (state.brackets === 0) { - if (opts.strictBrackets === true) { - throw new SyntaxError(syntaxError$1('opening', '[')); - } - - push({ type: 'text', value, output: `\\${value}` }); - continue; - } - - decrement('brackets'); - - const prevValue = prev.value.slice(1); - if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { - value = `/${value}`; - } - - prev.value += value; - append({ value }); - - // when literal brackets are explicitly disabled - // assume we should match with a regex character class - if (opts.literalBrackets === false || utils$5.hasRegexChars(prevValue)) { - continue; - } - - const escaped = utils$5.escapeRegex(prev.value); - state.output = state.output.slice(0, -prev.value.length); - - // when literal brackets are explicitly enabled - // assume we should escape the brackets to match literal characters - if (opts.literalBrackets === true) { - state.output += escaped; - prev.value = escaped; - continue; - } - - // when the user specifies nothing, try to match both - prev.value = `(${capture}${escaped}|${prev.value})`; - state.output += prev.value; - continue; - } - - /** - * Braces - */ - - if (value === '{' && opts.nobrace !== true) { - increment('braces'); - - const open = { - type: 'brace', - value, - output: '(', - outputIndex: state.output.length, - tokensIndex: state.tokens.length - }; - - braces.push(open); - push(open); - continue; - } - - if (value === '}') { - const brace = braces[braces.length - 1]; - - if (opts.nobrace === true || !brace) { - push({ type: 'text', value, output: value }); - continue; - } - - let output = ')'; - - if (brace.dots === true) { - const arr = tokens.slice(); - const range = []; - - for (let i = arr.length - 1; i >= 0; i--) { - tokens.pop(); - if (arr[i].type === 'brace') { - break; - } - if (arr[i].type !== 'dots') { - range.unshift(arr[i].value); - } - } - - output = expandRange(range, opts); - state.backtrack = true; - } - - if (brace.comma !== true && brace.dots !== true) { - const out = state.output.slice(0, brace.outputIndex); - const toks = state.tokens.slice(brace.tokensIndex); - brace.value = brace.output = '\\{'; - value = output = '\\}'; - state.output = out; - for (const t of toks) { - state.output += (t.output || t.value); - } - } - - push({ type: 'brace', value, output }); - decrement('braces'); - braces.pop(); - continue; - } - - /** - * Pipes - */ - - if (value === '|') { - if (extglobs.length > 0) { - extglobs[extglobs.length - 1].conditions++; - } - push({ type: 'text', value }); - continue; - } - - /** - * Commas - */ - - if (value === ',') { - let output = value; - - const brace = braces[braces.length - 1]; - if (brace && stack[stack.length - 1] === 'braces') { - brace.comma = true; - output = '|'; - } - - push({ type: 'comma', value, output }); - continue; - } - - /** - * Slashes - */ - - if (value === '/') { - // if the beginning of the glob is "./", advance the start - // to the current index, and don't add the "./" characters - // to the state. This greatly simplifies lookbehinds when - // checking for BOS characters like "!" and "." (not "./") - if (prev.type === 'dot' && state.index === state.start + 1) { - state.start = state.index + 1; - state.consumed = ''; - state.output = ''; - tokens.pop(); - prev = bos; // reset "prev" to the first token - continue; - } - - push({ type: 'slash', value, output: SLASH_LITERAL }); - continue; - } - - /** - * Dots - */ - - if (value === '.') { - if (state.braces > 0 && prev.type === 'dot') { - if (prev.value === '.') prev.output = DOT_LITERAL; - const brace = braces[braces.length - 1]; - prev.type = 'dots'; - prev.output += value; - prev.value += value; - brace.dots = true; - continue; - } - - if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { - push({ type: 'text', value, output: DOT_LITERAL }); - continue; - } - - push({ type: 'dot', value, output: DOT_LITERAL }); - continue; - } - - /** - * Question marks - */ - - if (value === '?') { - const isGroup = prev && prev.value === '('; - if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - extglobOpen('qmark', value); - continue; - } - - if (prev && prev.type === 'paren') { - const next = peek(); - let output = value; - - if (next === '<' && !utils$5.supportsLookbehinds()) { - throw new Error('Node.js v10 or higher is required for regex lookbehinds'); - } - - if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { - output = `\\${value}`; - } - - push({ type: 'text', value, output }); - continue; - } - - if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { - push({ type: 'qmark', value, output: QMARK_NO_DOT }); - continue; - } - - push({ type: 'qmark', value, output: QMARK }); - continue; - } - - /** - * Exclamation - */ - - if (value === '!') { - if (opts.noextglob !== true && peek() === '(') { - if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { - extglobOpen('negate', value); - continue; - } - } - - if (opts.nonegate !== true && state.index === 0) { - negate(); - continue; - } - } - - /** - * Plus - */ - - if (value === '+') { - if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - extglobOpen('plus', value); - continue; - } - - if ((prev && prev.value === '(') || opts.regex === false) { - push({ type: 'plus', value, output: PLUS_LITERAL }); - continue; - } - - if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { - push({ type: 'plus', value }); - continue; - } - - push({ type: 'plus', value: PLUS_LITERAL }); - continue; - } - - /** - * Plain text - */ - - if (value === '@') { - if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - push({ type: 'at', extglob: true, value, output: '' }); - continue; - } - - push({ type: 'text', value }); - continue; - } - - /** - * Plain text - */ - - if (value !== '*') { - if (value === '$' || value === '^') { - value = `\\${value}`; - } - - const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); - if (match) { - value += match[0]; - state.index += match[0].length; - } - - push({ type: 'text', value }); - continue; - } - - /** - * Stars - */ - - if (prev && (prev.type === 'globstar' || prev.star === true)) { - prev.type = 'star'; - prev.star = true; - prev.value += value; - prev.output = star; - state.backtrack = true; - state.globstar = true; - consume(value); - continue; - } - - let rest = remaining(); - if (opts.noextglob !== true && /^\([^?]/.test(rest)) { - extglobOpen('star', value); - continue; - } - - if (prev.type === 'star') { - if (opts.noglobstar === true) { - consume(value); - continue; - } - - const prior = prev.prev; - const before = prior.prev; - const isStart = prior.type === 'slash' || prior.type === 'bos'; - const afterStar = before && (before.type === 'star' || before.type === 'globstar'); - - if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { - push({ type: 'star', value, output: '' }); - continue; - } - - const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); - const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); - if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { - push({ type: 'star', value, output: '' }); - continue; - } - - // strip consecutive `/**/` - while (rest.slice(0, 3) === '/**') { - const after = input[state.index + 4]; - if (after && after !== '/') { - break; - } - rest = rest.slice(3); - consume('/**', 3); - } - - if (prior.type === 'bos' && eos()) { - prev.type = 'globstar'; - prev.value += value; - prev.output = globstar(opts); - state.output = prev.output; - state.globstar = true; - consume(value); - continue; - } - - if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { - state.output = state.output.slice(0, -(prior.output + prev.output).length); - prior.output = `(?:${prior.output}`; - - prev.type = 'globstar'; - prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); - prev.value += value; - state.globstar = true; - state.output += prior.output + prev.output; - consume(value); - continue; - } - - if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { - const end = rest[1] !== void 0 ? '|$' : ''; - - state.output = state.output.slice(0, -(prior.output + prev.output).length); - prior.output = `(?:${prior.output}`; - - prev.type = 'globstar'; - prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; - prev.value += value; - - state.output += prior.output + prev.output; - state.globstar = true; - - consume(value + advance()); - - push({ type: 'slash', value: '/', output: '' }); - continue; - } - - if (prior.type === 'bos' && rest[0] === '/') { - prev.type = 'globstar'; - prev.value += value; - prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; - state.output = prev.output; - state.globstar = true; - consume(value + advance()); - push({ type: 'slash', value: '/', output: '' }); - continue; - } - - // remove single star from output - state.output = state.output.slice(0, -prev.output.length); - - // reset previous token to globstar - prev.type = 'globstar'; - prev.output = globstar(opts); - prev.value += value; - - // reset output with globstar - state.output += prev.output; - state.globstar = true; - consume(value); - continue; - } - - const token = { type: 'star', value, output: star }; - - if (opts.bash === true) { - token.output = '.*?'; - if (prev.type === 'bos' || prev.type === 'slash') { - token.output = nodot + token.output; - } - push(token); - continue; - } - - if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { - token.output = value; - push(token); - continue; - } - - if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { - if (prev.type === 'dot') { - state.output += NO_DOT_SLASH; - prev.output += NO_DOT_SLASH; - - } else if (opts.dot === true) { - state.output += NO_DOTS_SLASH; - prev.output += NO_DOTS_SLASH; - - } else { - state.output += nodot; - prev.output += nodot; - } - - if (peek() !== '*') { - state.output += ONE_CHAR; - prev.output += ONE_CHAR; - } - } - - push(token); - } - - while (state.brackets > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError$1('closing', ']')); - state.output = utils$5.escapeLast(state.output, '['); - decrement('brackets'); - } - - while (state.parens > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError$1('closing', ')')); - state.output = utils$5.escapeLast(state.output, '('); - decrement('parens'); - } - - while (state.braces > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError$1('closing', '}')); - state.output = utils$5.escapeLast(state.output, '{'); - decrement('braces'); - } - - if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { - push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); - } - - // rebuild the output if we had to backtrack at any point - if (state.backtrack === true) { - state.output = ''; - - for (const token of state.tokens) { - state.output += token.output != null ? token.output : token.value; - - if (token.suffix) { - state.output += token.suffix; - } - } - } - - return state; -}; - -/** - * Fast paths for creating regular expressions for common glob patterns. - * This can significantly speed up processing and has very little downside - * impact when none of the fast paths match. - */ - -parse$e.fastpaths = (input, options) => { - const opts = { ...options }; - const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH$4, opts.maxLength) : MAX_LENGTH$4; - const len = input.length; - if (len > max) { - throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); - } - - input = REPLACEMENTS[input] || input; - const win32 = utils$5.isWindows(options); - - // create constants based on platform, for windows or posix - const { - DOT_LITERAL, - SLASH_LITERAL, - ONE_CHAR, - DOTS_SLASH, - NO_DOT, - NO_DOTS, - NO_DOTS_SLASH, - STAR, - START_ANCHOR - } = constants$4.globChars(win32); - - const nodot = opts.dot ? NO_DOTS : NO_DOT; - const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; - const capture = opts.capture ? '' : '?:'; - const state = { negated: false, prefix: '' }; - let star = opts.bash === true ? '.*?' : STAR; - - if (opts.capture) { - star = `(${star})`; - } - - const globstar = opts => { - if (opts.noglobstar === true) return star; - return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; - }; - - const create = str => { - switch (str) { - case '*': - return `${nodot}${ONE_CHAR}${star}`; - - case '.*': - return `${DOT_LITERAL}${ONE_CHAR}${star}`; - - case '*.*': - return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; - - case '*/*': - return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; - - case '**': - return nodot + globstar(opts); - - case '**/*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; - - case '**/*.*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; - - case '**/.*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; - - default: { - const match = /^(.*?)\.(\w+)$/.exec(str); - if (!match) return; - - const source = create(match[1]); - if (!source) return; - - return source + DOT_LITERAL + match[2]; - } - } - }; - - const output = utils$5.removePrefix(input, state); - let source = create(output); - - if (source && opts.strictSlashes !== true) { - source += `${SLASH_LITERAL}?`; - } - - return source; -}; - -var parse_1$2 = parse$e; - -const path$9 = path$b; -const scan = scan_1; -const parse$d = parse_1$2; -const utils$4 = utils$7; -const constants$3 = constants$5; -const isObject$3 = val => val && typeof val === 'object' && !Array.isArray(val); - -/** - * Creates a matcher function from one or more glob patterns. The - * returned function takes a string to match as its first argument, - * and returns true if the string is a match. The returned matcher - * function also takes a boolean as the second argument that, when true, - * returns an object with additional information. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch(glob[, options]); - * - * const isMatch = picomatch('*.!(*a)'); - * console.log(isMatch('a.a')); //=> false - * console.log(isMatch('a.b')); //=> true - * ``` - * @name picomatch - * @param {String|Array} `globs` One or more glob patterns. - * @param {Object=} `options` - * @return {Function=} Returns a matcher function. - * @api public - */ - -const picomatch$3 = (glob, options, returnState = false) => { - if (Array.isArray(glob)) { - const fns = glob.map(input => picomatch$3(input, options, returnState)); - const arrayMatcher = str => { - for (const isMatch of fns) { - const state = isMatch(str); - if (state) return state; - } - return false; - }; - return arrayMatcher; - } - - const isState = isObject$3(glob) && glob.tokens && glob.input; - - if (glob === '' || (typeof glob !== 'string' && !isState)) { - throw new TypeError('Expected pattern to be a non-empty string'); - } - - const opts = options || {}; - const posix = utils$4.isWindows(options); - const regex = isState - ? picomatch$3.compileRe(glob, options) - : picomatch$3.makeRe(glob, options, false, true); - - const state = regex.state; - delete regex.state; - - let isIgnored = () => false; - if (opts.ignore) { - const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; - isIgnored = picomatch$3(opts.ignore, ignoreOpts, returnState); - } - - const matcher = (input, returnObject = false) => { - const { isMatch, match, output } = picomatch$3.test(input, regex, options, { glob, posix }); - const result = { glob, state, regex, posix, input, output, match, isMatch }; - - if (typeof opts.onResult === 'function') { - opts.onResult(result); - } - - if (isMatch === false) { - result.isMatch = false; - return returnObject ? result : false; - } - - if (isIgnored(input)) { - if (typeof opts.onIgnore === 'function') { - opts.onIgnore(result); - } - result.isMatch = false; - return returnObject ? result : false; - } - - if (typeof opts.onMatch === 'function') { - opts.onMatch(result); - } - return returnObject ? result : true; - }; - - if (returnState) { - matcher.state = state; - } - - return matcher; -}; - -/** - * Test `input` with the given `regex`. This is used by the main - * `picomatch()` function to test the input string. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.test(input, regex[, options]); - * - * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); - * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } - * ``` - * @param {String} `input` String to test. - * @param {RegExp} `regex` - * @return {Object} Returns an object with matching info. - * @api public - */ - -picomatch$3.test = (input, regex, options, { glob, posix } = {}) => { - if (typeof input !== 'string') { - throw new TypeError('Expected input to be a string'); - } - - if (input === '') { - return { isMatch: false, output: '' }; - } - - const opts = options || {}; - const format = opts.format || (posix ? utils$4.toPosixSlashes : null); - let match = input === glob; - let output = (match && format) ? format(input) : input; - - if (match === false) { - output = format ? format(input) : input; - match = output === glob; - } - - if (match === false || opts.capture === true) { - if (opts.matchBase === true || opts.basename === true) { - match = picomatch$3.matchBase(input, regex, options, posix); - } else { - match = regex.exec(output); - } - } - - return { isMatch: Boolean(match), match, output }; -}; - -/** - * Match the basename of a filepath. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.matchBase(input, glob[, options]); - * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true - * ``` - * @param {String} `input` String to test. - * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). - * @return {Boolean} - * @api public - */ - -picomatch$3.matchBase = (input, glob, options, posix = utils$4.isWindows(options)) => { - const regex = glob instanceof RegExp ? glob : picomatch$3.makeRe(glob, options); - return regex.test(path$9.basename(input)); -}; - -/** - * Returns true if **any** of the given glob `patterns` match the specified `string`. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.isMatch(string, patterns[, options]); - * - * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true - * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false - * ``` - * @param {String|Array} str The string to test. - * @param {String|Array} patterns One or more glob patterns to use for matching. - * @param {Object} [options] See available [options](#options). - * @return {Boolean} Returns true if any patterns match `str` - * @api public - */ - -picomatch$3.isMatch = (str, patterns, options) => picomatch$3(patterns, options)(str); - -/** - * Parse a glob pattern to create the source string for a regular - * expression. - * - * ```js - * const picomatch = require('picomatch'); - * const result = picomatch.parse(pattern[, options]); - * ``` - * @param {String} `pattern` - * @param {Object} `options` - * @return {Object} Returns an object with useful properties and output to be used as a regex source string. - * @api public - */ - -picomatch$3.parse = (pattern, options) => { - if (Array.isArray(pattern)) return pattern.map(p => picomatch$3.parse(p, options)); - return parse$d(pattern, { ...options, fastpaths: false }); -}; - -/** - * Scan a glob pattern to separate the pattern into segments. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.scan(input[, options]); - * - * const result = picomatch.scan('!./foo/*.js'); - * console.log(result); - * { prefix: '!./', - * input: '!./foo/*.js', - * start: 3, - * base: 'foo', - * glob: '*.js', - * isBrace: false, - * isBracket: false, - * isGlob: true, - * isExtglob: false, - * isGlobstar: false, - * negated: true } - * ``` - * @param {String} `input` Glob pattern to scan. - * @param {Object} `options` - * @return {Object} Returns an object with - * @api public - */ - -picomatch$3.scan = (input, options) => scan(input, options); - -/** - * Compile a regular expression from the `state` object returned by the - * [parse()](#parse) method. - * - * @param {Object} `state` - * @param {Object} `options` - * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser. - * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. - * @return {RegExp} - * @api public - */ - -picomatch$3.compileRe = (state, options, returnOutput = false, returnState = false) => { - if (returnOutput === true) { - return state.output; - } - - const opts = options || {}; - const prepend = opts.contains ? '' : '^'; - const append = opts.contains ? '' : '$'; - - let source = `${prepend}(?:${state.output})${append}`; - if (state && state.negated === true) { - source = `^(?!${source}).*$`; - } - - const regex = picomatch$3.toRegex(source, options); - if (returnState === true) { - regex.state = state; - } - - return regex; -}; - -/** - * Create a regular expression from a parsed glob pattern. - * - * ```js - * const picomatch = require('picomatch'); - * const state = picomatch.parse('*.js'); - * // picomatch.compileRe(state[, options]); - * - * console.log(picomatch.compileRe(state)); - * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ - * ``` - * @param {String} `state` The object returned from the `.parse` method. - * @param {Object} `options` - * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result. - * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression. - * @return {RegExp} Returns a regex created from the given pattern. - * @api public - */ - -picomatch$3.makeRe = (input, options = {}, returnOutput = false, returnState = false) => { - if (!input || typeof input !== 'string') { - throw new TypeError('Expected a non-empty string'); - } - - let parsed = { negated: false, fastpaths: true }; - - if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { - parsed.output = parse$d.fastpaths(input, options); - } - - if (!parsed.output) { - parsed = parse$d(input, options); - } - - return picomatch$3.compileRe(parsed, options, returnOutput, returnState); -}; - -/** - * Create a regular expression from the given regex source string. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.toRegex(source[, options]); - * - * const { output } = picomatch.parse('*.js'); - * console.log(picomatch.toRegex(output)); - * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ - * ``` - * @param {String} `source` Regular expression source string. - * @param {Object} `options` - * @return {RegExp} - * @api public - */ - -picomatch$3.toRegex = (source, options) => { - try { - const opts = options || {}; - return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); - } catch (err) { - if (options && options.debug === true) throw err; - return /$^/; - } -}; - -/** - * Picomatch constants. - * @return {Object} - */ - -picomatch$3.constants = constants$3; - -/** - * Expose "picomatch" - */ - -var picomatch_1 = picomatch$3; - -var picomatch$2 = picomatch_1; - -const fs$9 = require$$0$3; -const { Readable } = require$$1; -const sysPath$3 = path$b; -const { promisify: promisify$3 } = require$$0$4; -const picomatch$1 = picomatch$2; - -const readdir$1 = promisify$3(fs$9.readdir); -const stat$3 = promisify$3(fs$9.stat); -const lstat$2 = promisify$3(fs$9.lstat); -const realpath$2 = promisify$3(fs$9.realpath); - -/** - * @typedef {Object} EntryInfo - * @property {String} path - * @property {String} fullPath - * @property {fs.Stats=} stats - * @property {fs.Dirent=} dirent - * @property {String} basename - */ - -const BANG$2 = '!'; -const RECURSIVE_ERROR_CODE = 'READDIRP_RECURSIVE_ERROR'; -const NORMAL_FLOW_ERRORS = new Set(['ENOENT', 'EPERM', 'EACCES', 'ELOOP', RECURSIVE_ERROR_CODE]); -const FILE_TYPE = 'files'; -const DIR_TYPE = 'directories'; -const FILE_DIR_TYPE = 'files_directories'; -const EVERYTHING_TYPE = 'all'; -const ALL_TYPES = [FILE_TYPE, DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE]; - -const isNormalFlowError = error => NORMAL_FLOW_ERRORS.has(error.code); -const [maj, min] = process.versions.node.split('.').slice(0, 2).map(n => Number.parseInt(n, 10)); -const wantBigintFsStats = process.platform === 'win32' && (maj > 10 || (maj === 10 && min >= 5)); - -const normalizeFilter = filter => { - if (filter === undefined) return; - if (typeof filter === 'function') return filter; - - if (typeof filter === 'string') { - const glob = picomatch$1(filter.trim()); - return entry => glob(entry.basename); - } - - if (Array.isArray(filter)) { - const positive = []; - const negative = []; - for (const item of filter) { - const trimmed = item.trim(); - if (trimmed.charAt(0) === BANG$2) { - negative.push(picomatch$1(trimmed.slice(1))); - } else { - positive.push(picomatch$1(trimmed)); - } - } - - if (negative.length > 0) { - if (positive.length > 0) { - return entry => - positive.some(f => f(entry.basename)) && !negative.some(f => f(entry.basename)); - } - return entry => !negative.some(f => f(entry.basename)); - } - return entry => positive.some(f => f(entry.basename)); - } -}; - -class ReaddirpStream extends Readable { - static get defaultOptions() { - return { - root: '.', - /* eslint-disable no-unused-vars */ - fileFilter: (path) => true, - directoryFilter: (path) => true, - /* eslint-enable no-unused-vars */ - type: FILE_TYPE, - lstat: false, - depth: 2147483648, - alwaysStat: false - }; - } - - constructor(options = {}) { - super({ - objectMode: true, - autoDestroy: true, - highWaterMark: options.highWaterMark || 4096 - }); - const opts = { ...ReaddirpStream.defaultOptions, ...options }; - const { root, type } = opts; - - this._fileFilter = normalizeFilter(opts.fileFilter); - this._directoryFilter = normalizeFilter(opts.directoryFilter); - - const statMethod = opts.lstat ? lstat$2 : stat$3; - // Use bigint stats if it's windows and stat() supports options (node 10+). - if (wantBigintFsStats) { - this._stat = path => statMethod(path, { bigint: true }); - } else { - this._stat = statMethod; - } - - this._maxDepth = opts.depth; - this._wantsDir = [DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type); - this._wantsFile = [FILE_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type); - this._wantsEverything = type === EVERYTHING_TYPE; - this._root = sysPath$3.resolve(root); - this._isDirent = ('Dirent' in fs$9) && !opts.alwaysStat; - this._statsProp = this._isDirent ? 'dirent' : 'stats'; - this._rdOptions = { encoding: 'utf8', withFileTypes: this._isDirent }; - - // Launch stream with one parent, the root dir. - this.parents = [this._exploreDir(root, 1)]; - this.reading = false; - this.parent = undefined; - } - - async _read(batch) { - if (this.reading) return; - this.reading = true; - - try { - while (!this.destroyed && batch > 0) { - const { path, depth, files = [] } = this.parent || {}; - - if (files.length > 0) { - const slice = files.splice(0, batch).map(dirent => this._formatEntry(dirent, path)); - for (const entry of await Promise.all(slice)) { - if (this.destroyed) return; - - const entryType = await this._getEntryType(entry); - if (entryType === 'directory' && this._directoryFilter(entry)) { - if (depth <= this._maxDepth) { - this.parents.push(this._exploreDir(entry.fullPath, depth + 1)); - } - - if (this._wantsDir) { - this.push(entry); - batch--; - } - } else if ((entryType === 'file' || this._includeAsFile(entry)) && this._fileFilter(entry)) { - if (this._wantsFile) { - this.push(entry); - batch--; - } - } - } - } else { - const parent = this.parents.pop(); - if (!parent) { - this.push(null); - break; - } - this.parent = await parent; - if (this.destroyed) return; - } - } - } catch (error) { - this.destroy(error); - } finally { - this.reading = false; - } - } - - async _exploreDir(path, depth) { - let files; - try { - files = await readdir$1(path, this._rdOptions); - } catch (error) { - this._onError(error); - } - return { files, depth, path }; - } - - async _formatEntry(dirent, path) { - let entry; - try { - const basename = this._isDirent ? dirent.name : dirent; - const fullPath = sysPath$3.resolve(sysPath$3.join(path, basename)); - entry = { path: sysPath$3.relative(this._root, fullPath), fullPath, basename }; - entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath); - } catch (err) { - this._onError(err); - } - return entry; - } - - _onError(err) { - if (isNormalFlowError(err) && !this.destroyed) { - this.emit('warn', err); - } else { - this.destroy(err); - } - } - - async _getEntryType(entry) { - // entry may be undefined, because a warning or an error were emitted - // and the statsProp is undefined - const stats = entry && entry[this._statsProp]; - if (!stats) { - return; - } - if (stats.isFile()) { - return 'file'; - } - if (stats.isDirectory()) { - return 'directory'; - } - if (stats && stats.isSymbolicLink()) { - const full = entry.fullPath; - try { - const entryRealPath = await realpath$2(full); - const entryRealPathStats = await lstat$2(entryRealPath); - if (entryRealPathStats.isFile()) { - return 'file'; - } - if (entryRealPathStats.isDirectory()) { - const len = entryRealPath.length; - if (full.startsWith(entryRealPath) && full.substr(len, 1) === sysPath$3.sep) { - const recursiveError = new Error( - `Circular symlink detected: "${full}" points to "${entryRealPath}"` - ); - recursiveError.code = RECURSIVE_ERROR_CODE; - return this._onError(recursiveError); - } - return 'directory'; - } - } catch (error) { - this._onError(error); - } - } - } - - _includeAsFile(entry) { - const stats = entry && entry[this._statsProp]; - - return stats && this._wantsEverything && !stats.isDirectory(); - } -} - -/** - * @typedef {Object} ReaddirpArguments - * @property {Function=} fileFilter - * @property {Function=} directoryFilter - * @property {String=} type - * @property {Number=} depth - * @property {String=} root - * @property {Boolean=} lstat - * @property {Boolean=} bigint - */ - -/** - * Main function which ends up calling readdirRec and reads all files and directories in given root recursively. - * @param {String} root Root directory - * @param {ReaddirpArguments=} options Options to specify root (start directory), filters and recursion depth - */ -const readdirp$1 = (root, options = {}) => { - let type = options.entryType || options.type; - if (type === 'both') type = FILE_DIR_TYPE; // backwards-compatibility - if (type) options.type = type; - if (!root) { - throw new Error('readdirp: root argument is required. Usage: readdirp(root, options)'); - } else if (typeof root !== 'string') { - throw new TypeError('readdirp: root argument must be a string. Usage: readdirp(root, options)'); - } else if (type && !ALL_TYPES.includes(type)) { - throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(', ')}`); - } - - options.root = root; - return new ReaddirpStream(options); -}; - -const readdirpPromise = (root, options = {}) => { - return new Promise((resolve, reject) => { - const files = []; - readdirp$1(root, options) - .on('data', entry => files.push(entry)) - .on('end', () => resolve(files)) - .on('error', error => reject(error)); - }); -}; - -readdirp$1.promise = readdirpPromise; -readdirp$1.ReaddirpStream = ReaddirpStream; -readdirp$1.default = readdirp$1; - -var readdirp_1 = readdirp$1; - -var anymatch$2 = {exports: {}}; - -/*! - * normalize-path - * - * Copyright (c) 2014-2018, Jon Schlinkert. - * Released under the MIT License. - */ - -var normalizePath$2 = function(path, stripTrailing) { - if (typeof path !== 'string') { - throw new TypeError('expected path to be a string'); - } - - if (path === '\\' || path === '/') return '/'; - - var len = path.length; - if (len <= 1) return path; - - // ensure that win32 namespaces has two leading slashes, so that the path is - // handled properly by the win32 version of path.parse() after being normalized - // https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces - var prefix = ''; - if (len > 4 && path[3] === '\\') { - var ch = path[2]; - if ((ch === '?' || ch === '.') && path.slice(0, 2) === '\\\\') { - path = path.slice(2); - prefix = '//'; - } - } - - var segs = path.split(/[/\\]+/); - if (stripTrailing !== false && segs[segs.length - 1] === '') { - segs.pop(); - } - return prefix + segs.join('/'); -}; - -Object.defineProperty(anymatch$2.exports, "__esModule", { value: true }); - -const picomatch = picomatch$2; -const normalizePath$1 = normalizePath$2; - -/** - * @typedef {(testString: string) => boolean} AnymatchFn - * @typedef {string|RegExp|AnymatchFn} AnymatchPattern - * @typedef {AnymatchPattern|AnymatchPattern[]} AnymatchMatcher - */ -const BANG$1 = '!'; -const DEFAULT_OPTIONS = {returnIndex: false}; -const arrify$1 = (item) => Array.isArray(item) ? item : [item]; - -/** - * @param {AnymatchPattern} matcher - * @param {object} options - * @returns {AnymatchFn} - */ -const createPattern = (matcher, options) => { - if (typeof matcher === 'function') { - return matcher; - } - if (typeof matcher === 'string') { - const glob = picomatch(matcher, options); - return (string) => matcher === string || glob(string); - } - if (matcher instanceof RegExp) { - return (string) => matcher.test(string); - } - return (string) => false; -}; - -/** - * @param {Array} patterns - * @param {Array} negPatterns - * @param {String|Array} args - * @param {Boolean} returnIndex - * @returns {boolean|number} - */ -const matchPatterns = (patterns, negPatterns, args, returnIndex) => { - const isList = Array.isArray(args); - const _path = isList ? args[0] : args; - if (!isList && typeof _path !== 'string') { - throw new TypeError('anymatch: second argument must be a string: got ' + - Object.prototype.toString.call(_path)) - } - const path = normalizePath$1(_path); - - for (let index = 0; index < negPatterns.length; index++) { - const nglob = negPatterns[index]; - if (nglob(path)) { - return returnIndex ? -1 : false; - } - } - - const applied = isList && [path].concat(args.slice(1)); - for (let index = 0; index < patterns.length; index++) { - const pattern = patterns[index]; - if (isList ? pattern(...applied) : pattern(path)) { - return returnIndex ? index : true; - } - } - - return returnIndex ? -1 : false; -}; - -/** - * @param {AnymatchMatcher} matchers - * @param {Array|string} testString - * @param {object} options - * @returns {boolean|number|Function} - */ -const anymatch$1 = (matchers, testString, options = DEFAULT_OPTIONS) => { - if (matchers == null) { - throw new TypeError('anymatch: specify first argument'); - } - const opts = typeof options === 'boolean' ? {returnIndex: options} : options; - const returnIndex = opts.returnIndex || false; - - // Early cache for matchers. - const mtchers = arrify$1(matchers); - const negatedGlobs = mtchers - .filter(item => typeof item === 'string' && item.charAt(0) === BANG$1) - .map(item => item.slice(1)) - .map(item => picomatch(item, opts)); - const patterns = mtchers - .filter(item => typeof item !== 'string' || (typeof item === 'string' && item.charAt(0) !== BANG$1)) - .map(matcher => createPattern(matcher, opts)); - - if (testString == null) { - return (testString, ri = false) => { - const returnIndex = typeof ri === 'boolean' ? ri : false; - return matchPatterns(patterns, negatedGlobs, testString, returnIndex); - } - } - - return matchPatterns(patterns, negatedGlobs, testString, returnIndex); -}; - -anymatch$1.default = anymatch$1; -anymatch$2.exports = anymatch$1; - -/*! - * is-extglob - * - * Copyright (c) 2014-2016, Jon Schlinkert. - * Licensed under the MIT License. - */ - -var isExtglob$1 = function isExtglob(str) { - if (typeof str !== 'string' || str === '') { - return false; - } - - var match; - while ((match = /(\\).|([@?!+*]\(.*\))/g.exec(str))) { - if (match[2]) return true; - str = str.slice(match.index + match[0].length); - } - - return false; -}; - -/*! - * is-glob - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - -var isExtglob = isExtglob$1; -var chars$1 = { '{': '}', '(': ')', '[': ']'}; -var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; -var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; - -var isGlob$2 = function isGlob(str, options) { - if (typeof str !== 'string' || str === '') { - return false; - } - - if (isExtglob(str)) { - return true; - } - - var regex = strictRegex; - var match; - - // optionally relax regex - if (options && options.strict === false) { - regex = relaxedRegex; - } - - while ((match = regex.exec(str))) { - if (match[2]) return true; - var idx = match.index + match[0].length; - - // if an open bracket/brace/paren is escaped, - // set the index to the next closing character - var open = match[1]; - var close = open ? chars$1[open] : null; - if (open && close) { - var n = str.indexOf(close, idx); - if (n !== -1) { - idx = n + 1; - } - } - - str = str.slice(idx); - } - return false; -}; - -var isGlob$1 = isGlob$2; -var pathPosixDirname = path$b.posix.dirname; -var isWin32 = require$$0$2.platform() === 'win32'; - -var slash = '/'; -var backslash = /\\/g; -var enclosure = /[\{\[].*[\}\]]$/; -var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/; -var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g; - -/** - * @param {string} str - * @param {Object} opts - * @param {boolean} [opts.flipBackslashes=true] - * @returns {string} - */ -var globParent$1 = function globParent(str, opts) { - var options = Object.assign({ flipBackslashes: true }, opts); - - // flip windows path separators - if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) { - str = str.replace(backslash, slash); - } - - // special case for strings ending in enclosure containing path separator - if (enclosure.test(str)) { - str += slash; - } - - // preserves full path in case of trailing path separator - str += 'a'; - - // remove path parts that are globby - do { - str = pathPosixDirname(str); - } while (isGlob$1(str) || globby.test(str)); - - // remove escape chars and return result - return str.replace(escaped, '$1'); -}; - -var utils$3 = {}; - -(function (exports) { - -exports.isInteger = num => { - if (typeof num === 'number') { - return Number.isInteger(num); - } - if (typeof num === 'string' && num.trim() !== '') { - return Number.isInteger(Number(num)); - } - return false; -}; - -/** - * Find a node of the given type - */ - -exports.find = (node, type) => node.nodes.find(node => node.type === type); - -/** - * Find a node of the given type - */ - -exports.exceedsLimit = (min, max, step = 1, limit) => { - if (limit === false) return false; - if (!exports.isInteger(min) || !exports.isInteger(max)) return false; - return ((Number(max) - Number(min)) / Number(step)) >= limit; -}; - -/** - * Escape the given node with '\\' before node.value - */ - -exports.escapeNode = (block, n = 0, type) => { - let node = block.nodes[n]; - if (!node) return; - - if ((type && node.type === type) || node.type === 'open' || node.type === 'close') { - if (node.escaped !== true) { - node.value = '\\' + node.value; - node.escaped = true; - } - } -}; - -/** - * Returns true if the given brace node should be enclosed in literal braces - */ - -exports.encloseBrace = node => { - if (node.type !== 'brace') return false; - if ((node.commas >> 0 + node.ranges >> 0) === 0) { - node.invalid = true; - return true; - } - return false; -}; - -/** - * Returns true if a brace node is invalid. - */ - -exports.isInvalidBrace = block => { - if (block.type !== 'brace') return false; - if (block.invalid === true || block.dollar) return true; - if ((block.commas >> 0 + block.ranges >> 0) === 0) { - block.invalid = true; - return true; - } - if (block.open !== true || block.close !== true) { - block.invalid = true; - return true; - } - return false; -}; - -/** - * Returns true if a node is an open or close node - */ - -exports.isOpenOrClose = node => { - if (node.type === 'open' || node.type === 'close') { - return true; - } - return node.open === true || node.close === true; -}; - -/** - * Reduce an array of text nodes. - */ - -exports.reduce = nodes => nodes.reduce((acc, node) => { - if (node.type === 'text') acc.push(node.value); - if (node.type === 'range') node.type = 'text'; - return acc; -}, []); - -/** - * Flatten an array - */ - -exports.flatten = (...args) => { - const result = []; - const flat = arr => { - for (let i = 0; i < arr.length; i++) { - let ele = arr[i]; - Array.isArray(ele) ? flat(ele) : ele !== void 0 && result.push(ele); - } - return result; - }; - flat(args); - return result; -}; -}(utils$3)); - -const utils$2 = utils$3; - -var stringify$6 = (ast, options = {}) => { - let stringify = (node, parent = {}) => { - let invalidBlock = options.escapeInvalid && utils$2.isInvalidBrace(parent); - let invalidNode = node.invalid === true && options.escapeInvalid === true; - let output = ''; - - if (node.value) { - if ((invalidBlock || invalidNode) && utils$2.isOpenOrClose(node)) { - return '\\' + node.value; - } - return node.value; - } - - if (node.value) { - return node.value; - } - - if (node.nodes) { - for (let child of node.nodes) { - output += stringify(child); - } - } - return output; - }; - - return stringify(ast); -}; - -/*! - * is-number - * - * Copyright (c) 2014-present, Jon Schlinkert. - * Released under the MIT License. - */ - -var isNumber$3 = function(num) { - if (typeof num === 'number') { - return num - num === 0; - } - if (typeof num === 'string' && num.trim() !== '') { - return Number.isFinite ? Number.isFinite(+num) : isFinite(+num); - } - return false; -}; - -/*! - * to-regex-range - * - * Copyright (c) 2015-present, Jon Schlinkert. - * Released under the MIT License. - */ - -const isNumber$2 = isNumber$3; - -const toRegexRange$1 = (min, max, options) => { - if (isNumber$2(min) === false) { - throw new TypeError('toRegexRange: expected the first argument to be a number'); - } - - if (max === void 0 || min === max) { - return String(min); - } - - if (isNumber$2(max) === false) { - throw new TypeError('toRegexRange: expected the second argument to be a number.'); - } - - let opts = { relaxZeros: true, ...options }; - if (typeof opts.strictZeros === 'boolean') { - opts.relaxZeros = opts.strictZeros === false; - } - - let relax = String(opts.relaxZeros); - let shorthand = String(opts.shorthand); - let capture = String(opts.capture); - let wrap = String(opts.wrap); - let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap; - - if (toRegexRange$1.cache.hasOwnProperty(cacheKey)) { - return toRegexRange$1.cache[cacheKey].result; - } - - let a = Math.min(min, max); - let b = Math.max(min, max); - - if (Math.abs(a - b) === 1) { - let result = min + '|' + max; - if (opts.capture) { - return `(${result})`; - } - if (opts.wrap === false) { - return result; - } - return `(?:${result})`; - } - - let isPadded = hasPadding(min) || hasPadding(max); - let state = { min, max, a, b }; - let positives = []; - let negatives = []; - - if (isPadded) { - state.isPadded = isPadded; - state.maxLen = String(state.max).length; - } - - if (a < 0) { - let newMin = b < 0 ? Math.abs(b) : 1; - negatives = splitToPatterns(newMin, Math.abs(a), state, opts); - a = state.a = 0; - } - - if (b >= 0) { - positives = splitToPatterns(a, b, state, opts); - } - - state.negatives = negatives; - state.positives = positives; - state.result = collatePatterns(negatives, positives); - - if (opts.capture === true) { - state.result = `(${state.result})`; - } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) { - state.result = `(?:${state.result})`; - } - - toRegexRange$1.cache[cacheKey] = state; - return state.result; -}; - -function collatePatterns(neg, pos, options) { - let onlyNegative = filterPatterns(neg, pos, '-', false) || []; - let onlyPositive = filterPatterns(pos, neg, '', false) || []; - let intersected = filterPatterns(neg, pos, '-?', true) || []; - let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); - return subpatterns.join('|'); -} - -function splitToRanges(min, max) { - let nines = 1; - let zeros = 1; - - let stop = countNines(min, nines); - let stops = new Set([max]); - - while (min <= stop && stop <= max) { - stops.add(stop); - nines += 1; - stop = countNines(min, nines); - } - - stop = countZeros(max + 1, zeros) - 1; - - while (min < stop && stop <= max) { - stops.add(stop); - zeros += 1; - stop = countZeros(max + 1, zeros) - 1; - } - - stops = [...stops]; - stops.sort(compare$c); - return stops; -} - -/** - * Convert a range to a regex pattern - * @param {Number} `start` - * @param {Number} `stop` - * @return {String} - */ - -function rangeToPattern(start, stop, options) { - if (start === stop) { - return { pattern: start, count: [], digits: 0 }; - } - - let zipped = zip(start, stop); - let digits = zipped.length; - let pattern = ''; - let count = 0; - - for (let i = 0; i < digits; i++) { - let [startDigit, stopDigit] = zipped[i]; - - if (startDigit === stopDigit) { - pattern += startDigit; - - } else if (startDigit !== '0' || stopDigit !== '9') { - pattern += toCharacterClass(startDigit, stopDigit); - - } else { - count++; - } - } - - if (count) { - pattern += options.shorthand === true ? '\\d' : '[0-9]'; - } - - return { pattern, count: [count], digits }; -} - -function splitToPatterns(min, max, tok, options) { - let ranges = splitToRanges(min, max); - let tokens = []; - let start = min; - let prev; - - for (let i = 0; i < ranges.length; i++) { - let max = ranges[i]; - let obj = rangeToPattern(String(start), String(max), options); - let zeros = ''; - - if (!tok.isPadded && prev && prev.pattern === obj.pattern) { - if (prev.count.length > 1) { - prev.count.pop(); - } - - prev.count.push(obj.count[0]); - prev.string = prev.pattern + toQuantifier(prev.count); - start = max + 1; - continue; - } - - if (tok.isPadded) { - zeros = padZeros(max, tok, options); - } - - obj.string = zeros + obj.pattern + toQuantifier(obj.count); - tokens.push(obj); - start = max + 1; - prev = obj; - } - - return tokens; -} - -function filterPatterns(arr, comparison, prefix, intersection, options) { - let result = []; - - for (let ele of arr) { - let { string } = ele; - - // only push if _both_ are negative... - if (!intersection && !contains(comparison, 'string', string)) { - result.push(prefix + string); - } - - // or _both_ are positive - if (intersection && contains(comparison, 'string', string)) { - result.push(prefix + string); - } - } - return result; -} - -/** - * Zip strings - */ - -function zip(a, b) { - let arr = []; - for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]); - return arr; -} - -function compare$c(a, b) { - return a > b ? 1 : b > a ? -1 : 0; -} - -function contains(arr, key, val) { - return arr.some(ele => ele[key] === val); -} - -function countNines(min, len) { - return Number(String(min).slice(0, -len) + '9'.repeat(len)); -} - -function countZeros(integer, zeros) { - return integer - (integer % Math.pow(10, zeros)); -} - -function toQuantifier(digits) { - let [start = 0, stop = ''] = digits; - if (stop || start > 1) { - return `{${start + (stop ? ',' + stop : '')}}`; - } - return ''; -} - -function toCharacterClass(a, b, options) { - return `[${a}${(b - a === 1) ? '' : '-'}${b}]`; -} - -function hasPadding(str) { - return /^-?(0+)\d/.test(str); -} - -function padZeros(value, tok, options) { - if (!tok.isPadded) { - return value; - } - - let diff = Math.abs(tok.maxLen - String(value).length); - let relax = options.relaxZeros !== false; - - switch (diff) { - case 0: - return ''; - case 1: - return relax ? '0?' : '0'; - case 2: - return relax ? '0{0,2}' : '00'; - default: { - return relax ? `0{0,${diff}}` : `0{${diff}}`; - } - } -} - -/** - * Cache - */ - -toRegexRange$1.cache = {}; -toRegexRange$1.clearCache = () => (toRegexRange$1.cache = {}); - -/** - * Expose `toRegexRange` - */ - -var toRegexRange_1 = toRegexRange$1; - -/*! - * fill-range - * - * Copyright (c) 2014-present, Jon Schlinkert. - * Licensed under the MIT License. - */ - -const util$3 = require$$0$4; -const toRegexRange = toRegexRange_1; - -const isObject$2 = val => val !== null && typeof val === 'object' && !Array.isArray(val); - -const transform$3 = toNumber => { - return value => toNumber === true ? Number(value) : String(value); -}; - -const isValidValue = value => { - return typeof value === 'number' || (typeof value === 'string' && value !== ''); -}; - -const isNumber$1 = num => Number.isInteger(+num); - -const zeros = input => { - let value = `${input}`; - let index = -1; - if (value[0] === '-') value = value.slice(1); - if (value === '0') return false; - while (value[++index] === '0'); - return index > 0; -}; - -const stringify$5 = (start, end, options) => { - if (typeof start === 'string' || typeof end === 'string') { - return true; - } - return options.stringify === true; -}; - -const pad = (input, maxLength, toNumber) => { - if (maxLength > 0) { - let dash = input[0] === '-' ? '-' : ''; - if (dash) input = input.slice(1); - input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0')); - } - if (toNumber === false) { - return String(input); - } - return input; -}; - -const toMaxLen = (input, maxLength) => { - let negative = input[0] === '-' ? '-' : ''; - if (negative) { - input = input.slice(1); - maxLength--; - } - while (input.length < maxLength) input = '0' + input; - return negative ? ('-' + input) : input; -}; - -const toSequence = (parts, options) => { - parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); - parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); - - let prefix = options.capture ? '' : '?:'; - let positives = ''; - let negatives = ''; - let result; - - if (parts.positives.length) { - positives = parts.positives.join('|'); - } - - if (parts.negatives.length) { - negatives = `-(${prefix}${parts.negatives.join('|')})`; - } - - if (positives && negatives) { - result = `${positives}|${negatives}`; - } else { - result = positives || negatives; - } - - if (options.wrap) { - return `(${prefix}${result})`; - } - - return result; -}; - -const toRange = (a, b, isNumbers, options) => { - if (isNumbers) { - return toRegexRange(a, b, { wrap: false, ...options }); - } - - let start = String.fromCharCode(a); - if (a === b) return start; - - let stop = String.fromCharCode(b); - return `[${start}-${stop}]`; -}; - -const toRegex = (start, end, options) => { - if (Array.isArray(start)) { - let wrap = options.wrap === true; - let prefix = options.capture ? '' : '?:'; - return wrap ? `(${prefix}${start.join('|')})` : start.join('|'); - } - return toRegexRange(start, end, options); -}; - -const rangeError = (...args) => { - return new RangeError('Invalid range arguments: ' + util$3.inspect(...args)); -}; - -const invalidRange = (start, end, options) => { - if (options.strictRanges === true) throw rangeError([start, end]); - return []; -}; - -const invalidStep = (step, options) => { - if (options.strictRanges === true) { - throw new TypeError(`Expected step "${step}" to be a number`); - } - return []; -}; - -const fillNumbers = (start, end, step = 1, options = {}) => { - let a = Number(start); - let b = Number(end); - - if (!Number.isInteger(a) || !Number.isInteger(b)) { - if (options.strictRanges === true) throw rangeError([start, end]); - return []; - } - - // fix negative zero - if (a === 0) a = 0; - if (b === 0) b = 0; - - let descending = a > b; - let startString = String(start); - let endString = String(end); - let stepString = String(step); - step = Math.max(Math.abs(step), 1); - - let padded = zeros(startString) || zeros(endString) || zeros(stepString); - let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0; - let toNumber = padded === false && stringify$5(start, end, options) === false; - let format = options.transform || transform$3(toNumber); - - if (options.toRegex && step === 1) { - return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options); - } - - let parts = { negatives: [], positives: [] }; - let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num)); - let range = []; - let index = 0; - - while (descending ? a >= b : a <= b) { - if (options.toRegex === true && step > 1) { - push(a); - } else { - range.push(pad(format(a, index), maxLen, toNumber)); - } - a = descending ? a - step : a + step; - index++; - } - - if (options.toRegex === true) { - return step > 1 - ? toSequence(parts, options) - : toRegex(range, null, { wrap: false, ...options }); - } - - return range; -}; - -const fillLetters = (start, end, step = 1, options = {}) => { - if ((!isNumber$1(start) && start.length > 1) || (!isNumber$1(end) && end.length > 1)) { - return invalidRange(start, end, options); - } - - - let format = options.transform || (val => String.fromCharCode(val)); - let a = `${start}`.charCodeAt(0); - let b = `${end}`.charCodeAt(0); - - let descending = a > b; - let min = Math.min(a, b); - let max = Math.max(a, b); - - if (options.toRegex && step === 1) { - return toRange(min, max, false, options); - } - - let range = []; - let index = 0; - - while (descending ? a >= b : a <= b) { - range.push(format(a, index)); - a = descending ? a - step : a + step; - index++; - } - - if (options.toRegex === true) { - return toRegex(range, null, { wrap: false, options }); - } - - return range; -}; - -const fill$2 = (start, end, step, options = {}) => { - if (end == null && isValidValue(start)) { - return [start]; - } - - if (!isValidValue(start) || !isValidValue(end)) { - return invalidRange(start, end, options); - } - - if (typeof step === 'function') { - return fill$2(start, end, 1, { transform: step }); - } - - if (isObject$2(step)) { - return fill$2(start, end, 0, step); - } - - let opts = { ...options }; - if (opts.capture === true) opts.wrap = true; - step = step || opts.step || 1; - - if (!isNumber$1(step)) { - if (step != null && !isObject$2(step)) return invalidStep(step, opts); - return fill$2(start, end, 1, step); - } - - if (isNumber$1(start) && isNumber$1(end)) { - return fillNumbers(start, end, step, opts); - } - - return fillLetters(start, end, Math.max(Math.abs(step), 1), opts); -}; - -var fillRange = fill$2; - -const fill$1 = fillRange; -const utils$1 = utils$3; - -const compile$1 = (ast, options = {}) => { - let walk = (node, parent = {}) => { - let invalidBlock = utils$1.isInvalidBrace(parent); - let invalidNode = node.invalid === true && options.escapeInvalid === true; - let invalid = invalidBlock === true || invalidNode === true; - let prefix = options.escapeInvalid === true ? '\\' : ''; - let output = ''; - - if (node.isOpen === true) { - return prefix + node.value; - } - if (node.isClose === true) { - return prefix + node.value; - } - - if (node.type === 'open') { - return invalid ? (prefix + node.value) : '('; - } - - if (node.type === 'close') { - return invalid ? (prefix + node.value) : ')'; - } - - if (node.type === 'comma') { - return node.prev.type === 'comma' ? '' : (invalid ? node.value : '|'); - } - - if (node.value) { - return node.value; - } - - if (node.nodes && node.ranges > 0) { - let args = utils$1.reduce(node.nodes); - let range = fill$1(...args, { ...options, wrap: false, toRegex: true }); - - if (range.length !== 0) { - return args.length > 1 && range.length > 1 ? `(${range})` : range; - } - } - - if (node.nodes) { - for (let child of node.nodes) { - output += walk(child, node); - } - } - return output; - }; - - return walk(ast); -}; - -var compile_1 = compile$1; - -const fill = fillRange; -const stringify$4 = stringify$6; -const utils = utils$3; - -const append = (queue = '', stash = '', enclose = false) => { - let result = []; - - queue = [].concat(queue); - stash = [].concat(stash); - - if (!stash.length) return queue; - if (!queue.length) { - return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash; - } - - for (let item of queue) { - if (Array.isArray(item)) { - for (let value of item) { - result.push(append(value, stash, enclose)); - } - } else { - for (let ele of stash) { - if (enclose === true && typeof ele === 'string') ele = `{${ele}}`; - result.push(Array.isArray(ele) ? append(item, ele, enclose) : (item + ele)); - } - } - } - return utils.flatten(result); -}; - -const expand$4 = (ast, options = {}) => { - let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit; - - let walk = (node, parent = {}) => { - node.queue = []; - - let p = parent; - let q = parent.queue; - - while (p.type !== 'brace' && p.type !== 'root' && p.parent) { - p = p.parent; - q = p.queue; - } - - if (node.invalid || node.dollar) { - q.push(append(q.pop(), stringify$4(node, options))); - return; - } - - if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) { - q.push(append(q.pop(), ['{}'])); - return; - } - - if (node.nodes && node.ranges > 0) { - let args = utils.reduce(node.nodes); - - if (utils.exceedsLimit(...args, options.step, rangeLimit)) { - throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); - } - - let range = fill(...args, options); - if (range.length === 0) { - range = stringify$4(node, options); - } - - q.push(append(q.pop(), range)); - node.nodes = []; - return; - } - - let enclose = utils.encloseBrace(node); - let queue = node.queue; - let block = node; - - while (block.type !== 'brace' && block.type !== 'root' && block.parent) { - block = block.parent; - queue = block.queue; - } - - for (let i = 0; i < node.nodes.length; i++) { - let child = node.nodes[i]; - - if (child.type === 'comma' && node.type === 'brace') { - if (i === 1) queue.push(''); - queue.push(''); - continue; - } - - if (child.type === 'close') { - q.push(append(q.pop(), queue, enclose)); - continue; - } - - if (child.value && child.type !== 'open') { - queue.push(append(queue.pop(), child.value)); - continue; - } - - if (child.nodes) { - walk(child, node); - } - } - - return queue; - }; - - return utils.flatten(walk(ast)); -}; - -var expand_1 = expand$4; - -var constants$2 = { - MAX_LENGTH: 1024 * 64, - - // Digits - CHAR_0: '0', /* 0 */ - CHAR_9: '9', /* 9 */ - - // Alphabet chars. - CHAR_UPPERCASE_A: 'A', /* A */ - CHAR_LOWERCASE_A: 'a', /* a */ - CHAR_UPPERCASE_Z: 'Z', /* Z */ - CHAR_LOWERCASE_Z: 'z', /* z */ - - CHAR_LEFT_PARENTHESES: '(', /* ( */ - CHAR_RIGHT_PARENTHESES: ')', /* ) */ - - CHAR_ASTERISK: '*', /* * */ - - // Non-alphabetic chars. - CHAR_AMPERSAND: '&', /* & */ - CHAR_AT: '@', /* @ */ - CHAR_BACKSLASH: '\\', /* \ */ - CHAR_BACKTICK: '`', /* ` */ - CHAR_CARRIAGE_RETURN: '\r', /* \r */ - CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */ - CHAR_COLON: ':', /* : */ - CHAR_COMMA: ',', /* , */ - CHAR_DOLLAR: '$', /* . */ - CHAR_DOT: '.', /* . */ - CHAR_DOUBLE_QUOTE: '"', /* " */ - CHAR_EQUAL: '=', /* = */ - CHAR_EXCLAMATION_MARK: '!', /* ! */ - CHAR_FORM_FEED: '\f', /* \f */ - CHAR_FORWARD_SLASH: '/', /* / */ - CHAR_HASH: '#', /* # */ - CHAR_HYPHEN_MINUS: '-', /* - */ - CHAR_LEFT_ANGLE_BRACKET: '<', /* < */ - CHAR_LEFT_CURLY_BRACE: '{', /* { */ - CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */ - CHAR_LINE_FEED: '\n', /* \n */ - CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */ - CHAR_PERCENT: '%', /* % */ - CHAR_PLUS: '+', /* + */ - CHAR_QUESTION_MARK: '?', /* ? */ - CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */ - CHAR_RIGHT_CURLY_BRACE: '}', /* } */ - CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */ - CHAR_SEMICOLON: ';', /* ; */ - CHAR_SINGLE_QUOTE: '\'', /* ' */ - CHAR_SPACE: ' ', /* */ - CHAR_TAB: '\t', /* \t */ - CHAR_UNDERSCORE: '_', /* _ */ - CHAR_VERTICAL_LINE: '|', /* | */ - CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */ -}; - -const stringify$3 = stringify$6; - -/** - * Constants - */ - -const { - MAX_LENGTH: MAX_LENGTH$3, - CHAR_BACKSLASH, /* \ */ - CHAR_BACKTICK, /* ` */ - CHAR_COMMA: CHAR_COMMA$1, /* , */ - CHAR_DOT, /* . */ - CHAR_LEFT_PARENTHESES, /* ( */ - CHAR_RIGHT_PARENTHESES, /* ) */ - CHAR_LEFT_CURLY_BRACE, /* { */ - CHAR_RIGHT_CURLY_BRACE, /* } */ - CHAR_LEFT_SQUARE_BRACKET: CHAR_LEFT_SQUARE_BRACKET$1, /* [ */ - CHAR_RIGHT_SQUARE_BRACKET: CHAR_RIGHT_SQUARE_BRACKET$1, /* ] */ - CHAR_DOUBLE_QUOTE: CHAR_DOUBLE_QUOTE$1, /* " */ - CHAR_SINGLE_QUOTE: CHAR_SINGLE_QUOTE$1, /* ' */ - CHAR_NO_BREAK_SPACE, - CHAR_ZERO_WIDTH_NOBREAK_SPACE -} = constants$2; - -/** - * parse - */ - -const parse$c = (input, options = {}) => { - if (typeof input !== 'string') { - throw new TypeError('Expected a string'); - } - - let opts = options || {}; - let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH$3, opts.maxLength) : MAX_LENGTH$3; - if (input.length > max) { - throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`); - } - - let ast = { type: 'root', input, nodes: [] }; - let stack = [ast]; - let block = ast; - let prev = ast; - let brackets = 0; - let length = input.length; - let index = 0; - let depth = 0; - let value; - - /** - * Helpers - */ - - const advance = () => input[index++]; - const push = node => { - if (node.type === 'text' && prev.type === 'dot') { - prev.type = 'text'; - } - - if (prev && prev.type === 'text' && node.type === 'text') { - prev.value += node.value; - return; - } - - block.nodes.push(node); - node.parent = block; - node.prev = prev; - prev = node; - return node; - }; - - push({ type: 'bos' }); - - while (index < length) { - block = stack[stack.length - 1]; - value = advance(); - - /** - * Invalid chars - */ - - if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) { - continue; - } - - /** - * Escaped chars - */ - - if (value === CHAR_BACKSLASH) { - push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() }); - continue; - } - - /** - * Right square bracket (literal): ']' - */ - - if (value === CHAR_RIGHT_SQUARE_BRACKET$1) { - push({ type: 'text', value: '\\' + value }); - continue; - } - - /** - * Left square bracket: '[' - */ - - if (value === CHAR_LEFT_SQUARE_BRACKET$1) { - brackets++; - let next; - - while (index < length && (next = advance())) { - value += next; - - if (next === CHAR_LEFT_SQUARE_BRACKET$1) { - brackets++; - continue; - } - - if (next === CHAR_BACKSLASH) { - value += advance(); - continue; - } - - if (next === CHAR_RIGHT_SQUARE_BRACKET$1) { - brackets--; - - if (brackets === 0) { - break; - } - } - } - - push({ type: 'text', value }); - continue; - } - - /** - * Parentheses - */ - - if (value === CHAR_LEFT_PARENTHESES) { - block = push({ type: 'paren', nodes: [] }); - stack.push(block); - push({ type: 'text', value }); - continue; - } - - if (value === CHAR_RIGHT_PARENTHESES) { - if (block.type !== 'paren') { - push({ type: 'text', value }); - continue; - } - block = stack.pop(); - push({ type: 'text', value }); - block = stack[stack.length - 1]; - continue; - } - - /** - * Quotes: '|"|` - */ - - if (value === CHAR_DOUBLE_QUOTE$1 || value === CHAR_SINGLE_QUOTE$1 || value === CHAR_BACKTICK) { - let open = value; - let next; - - if (options.keepQuotes !== true) { - value = ''; - } - - while (index < length && (next = advance())) { - if (next === CHAR_BACKSLASH) { - value += next + advance(); - continue; - } - - if (next === open) { - if (options.keepQuotes === true) value += next; - break; - } - - value += next; - } - - push({ type: 'text', value }); - continue; - } - - /** - * Left curly brace: '{' - */ - - if (value === CHAR_LEFT_CURLY_BRACE) { - depth++; - - let dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true; - let brace = { - type: 'brace', - open: true, - close: false, - dollar, - depth, - commas: 0, - ranges: 0, - nodes: [] - }; - - block = push(brace); - stack.push(block); - push({ type: 'open', value }); - continue; - } - - /** - * Right curly brace: '}' - */ - - if (value === CHAR_RIGHT_CURLY_BRACE) { - if (block.type !== 'brace') { - push({ type: 'text', value }); - continue; - } - - let type = 'close'; - block = stack.pop(); - block.close = true; - - push({ type, value }); - depth--; - - block = stack[stack.length - 1]; - continue; - } - - /** - * Comma: ',' - */ - - if (value === CHAR_COMMA$1 && depth > 0) { - if (block.ranges > 0) { - block.ranges = 0; - let open = block.nodes.shift(); - block.nodes = [open, { type: 'text', value: stringify$3(block) }]; - } - - push({ type: 'comma', value }); - block.commas++; - continue; - } - - /** - * Dot: '.' - */ - - if (value === CHAR_DOT && depth > 0 && block.commas === 0) { - let siblings = block.nodes; - - if (depth === 0 || siblings.length === 0) { - push({ type: 'text', value }); - continue; - } - - if (prev.type === 'dot') { - block.range = []; - prev.value += value; - prev.type = 'range'; - - if (block.nodes.length !== 3 && block.nodes.length !== 5) { - block.invalid = true; - block.ranges = 0; - prev.type = 'text'; - continue; - } - - block.ranges++; - block.args = []; - continue; - } - - if (prev.type === 'range') { - siblings.pop(); - - let before = siblings[siblings.length - 1]; - before.value += prev.value + value; - prev = before; - block.ranges--; - continue; - } - - push({ type: 'dot', value }); - continue; - } - - /** - * Text - */ - - push({ type: 'text', value }); - } - - // Mark imbalanced braces and brackets as invalid - do { - block = stack.pop(); - - if (block.type !== 'root') { - block.nodes.forEach(node => { - if (!node.nodes) { - if (node.type === 'open') node.isOpen = true; - if (node.type === 'close') node.isClose = true; - if (!node.nodes) node.type = 'text'; - node.invalid = true; - } - }); - - // get the location of the block on parent.nodes (block's siblings) - let parent = stack[stack.length - 1]; - let index = parent.nodes.indexOf(block); - // replace the (invalid) block with it's nodes - parent.nodes.splice(index, 1, ...block.nodes); - } - } while (stack.length > 0); - - push({ type: 'eos' }); - return ast; -}; - -var parse_1$1 = parse$c; - -const stringify$2 = stringify$6; -const compile = compile_1; -const expand$3 = expand_1; -const parse$b = parse_1$1; - -/** - * Expand the given pattern or create a regex-compatible string. - * - * ```js - * const braces = require('braces'); - * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)'] - * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c'] - * ``` - * @param {String} `str` - * @param {Object} `options` - * @return {String} - * @api public - */ - -const braces$1 = (input, options = {}) => { - let output = []; - - if (Array.isArray(input)) { - for (let pattern of input) { - let result = braces$1.create(pattern, options); - if (Array.isArray(result)) { - output.push(...result); - } else { - output.push(result); - } - } - } else { - output = [].concat(braces$1.create(input, options)); - } - - if (options && options.expand === true && options.nodupes === true) { - output = [...new Set(output)]; - } - return output; -}; - -/** - * Parse the given `str` with the given `options`. - * - * ```js - * // braces.parse(pattern, [, options]); - * const ast = braces.parse('a/{b,c}/d'); - * console.log(ast); - * ``` - * @param {String} pattern Brace pattern to parse - * @param {Object} options - * @return {Object} Returns an AST - * @api public - */ - -braces$1.parse = (input, options = {}) => parse$b(input, options); - -/** - * Creates a braces string from an AST, or an AST node. - * - * ```js - * const braces = require('braces'); - * let ast = braces.parse('foo/{a,b}/bar'); - * console.log(stringify(ast.nodes[2])); //=> '{a,b}' - * ``` - * @param {String} `input` Brace pattern or AST. - * @param {Object} `options` - * @return {Array} Returns an array of expanded values. - * @api public - */ - -braces$1.stringify = (input, options = {}) => { - if (typeof input === 'string') { - return stringify$2(braces$1.parse(input, options), options); - } - return stringify$2(input, options); -}; - -/** - * Compiles a brace pattern into a regex-compatible, optimized string. - * This method is called by the main [braces](#braces) function by default. - * - * ```js - * const braces = require('braces'); - * console.log(braces.compile('a/{b,c}/d')); - * //=> ['a/(b|c)/d'] - * ``` - * @param {String} `input` Brace pattern or AST. - * @param {Object} `options` - * @return {Array} Returns an array of expanded values. - * @api public - */ - -braces$1.compile = (input, options = {}) => { - if (typeof input === 'string') { - input = braces$1.parse(input, options); - } - return compile(input, options); -}; - -/** - * Expands a brace pattern into an array. This method is called by the - * main [braces](#braces) function when `options.expand` is true. Before - * using this method it's recommended that you read the [performance notes](#performance)) - * and advantages of using [.compile](#compile) instead. - * - * ```js - * const braces = require('braces'); - * console.log(braces.expand('a/{b,c}/d')); - * //=> ['a/b/d', 'a/c/d']; - * ``` - * @param {String} `pattern` Brace pattern - * @param {Object} `options` - * @return {Array} Returns an array of expanded values. - * @api public - */ - -braces$1.expand = (input, options = {}) => { - if (typeof input === 'string') { - input = braces$1.parse(input, options); - } - - let result = expand$3(input, options); - - // filter out empty strings if specified - if (options.noempty === true) { - result = result.filter(Boolean); - } - - // filter out duplicates if specified - if (options.nodupes === true) { - result = [...new Set(result)]; - } - - return result; -}; - -/** - * Processes a brace pattern and returns either an expanded array - * (if `options.expand` is true), a highly optimized regex-compatible string. - * This method is called by the main [braces](#braces) function. - * - * ```js - * const braces = require('braces'); - * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}')) - * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)' - * ``` - * @param {String} `pattern` Brace pattern - * @param {Object} `options` - * @return {Array} Returns an array of expanded values. - * @api public - */ - -braces$1.create = (input, options = {}) => { - if (input === '' || input.length < 3) { - return [input]; - } - - return options.expand !== true - ? braces$1.compile(input, options) - : braces$1.expand(input, options); -}; - -/** - * Expose "braces" - */ - -var braces_1 = braces$1; - -var require$$0$1 = [ - "3dm", - "3ds", - "3g2", - "3gp", - "7z", - "a", - "aac", - "adp", - "ai", - "aif", - "aiff", - "alz", - "ape", - "apk", - "appimage", - "ar", - "arj", - "asf", - "au", - "avi", - "bak", - "baml", - "bh", - "bin", - "bk", - "bmp", - "btif", - "bz2", - "bzip2", - "cab", - "caf", - "cgm", - "class", - "cmx", - "cpio", - "cr2", - "cur", - "dat", - "dcm", - "deb", - "dex", - "djvu", - "dll", - "dmg", - "dng", - "doc", - "docm", - "docx", - "dot", - "dotm", - "dra", - "DS_Store", - "dsk", - "dts", - "dtshd", - "dvb", - "dwg", - "dxf", - "ecelp4800", - "ecelp7470", - "ecelp9600", - "egg", - "eol", - "eot", - "epub", - "exe", - "f4v", - "fbs", - "fh", - "fla", - "flac", - "flatpak", - "fli", - "flv", - "fpx", - "fst", - "fvt", - "g3", - "gh", - "gif", - "graffle", - "gz", - "gzip", - "h261", - "h263", - "h264", - "icns", - "ico", - "ief", - "img", - "ipa", - "iso", - "jar", - "jpeg", - "jpg", - "jpgv", - "jpm", - "jxr", - "key", - "ktx", - "lha", - "lib", - "lvp", - "lz", - "lzh", - "lzma", - "lzo", - "m3u", - "m4a", - "m4v", - "mar", - "mdi", - "mht", - "mid", - "midi", - "mj2", - "mka", - "mkv", - "mmr", - "mng", - "mobi", - "mov", - "movie", - "mp3", - "mp4", - "mp4a", - "mpeg", - "mpg", - "mpga", - "mxu", - "nef", - "npx", - "numbers", - "nupkg", - "o", - "odp", - "ods", - "odt", - "oga", - "ogg", - "ogv", - "otf", - "ott", - "pages", - "pbm", - "pcx", - "pdb", - "pdf", - "pea", - "pgm", - "pic", - "png", - "pnm", - "pot", - "potm", - "potx", - "ppa", - "ppam", - "ppm", - "pps", - "ppsm", - "ppsx", - "ppt", - "pptm", - "pptx", - "psd", - "pya", - "pyc", - "pyo", - "pyv", - "qt", - "rar", - "ras", - "raw", - "resources", - "rgb", - "rip", - "rlc", - "rmf", - "rmvb", - "rpm", - "rtf", - "rz", - "s3m", - "s7z", - "scpt", - "sgi", - "shar", - "snap", - "sil", - "sketch", - "slk", - "smv", - "snk", - "so", - "stl", - "suo", - "sub", - "swf", - "tar", - "tbz", - "tbz2", - "tga", - "tgz", - "thmx", - "tif", - "tiff", - "tlz", - "ttc", - "ttf", - "txz", - "udf", - "uvh", - "uvi", - "uvm", - "uvp", - "uvs", - "uvu", - "viv", - "vob", - "war", - "wav", - "wax", - "wbmp", - "wdp", - "weba", - "webm", - "webp", - "whl", - "wim", - "wm", - "wma", - "wmv", - "wmx", - "woff", - "woff2", - "wrm", - "wvx", - "xbm", - "xif", - "xla", - "xlam", - "xls", - "xlsb", - "xlsm", - "xlsx", - "xlt", - "xltm", - "xltx", - "xm", - "xmind", - "xpi", - "xpm", - "xwd", - "xz", - "z", - "zip", - "zipx" -]; - -var binaryExtensions$1 = require$$0$1; - -const path$8 = path$b; -const binaryExtensions = binaryExtensions$1; - -const extensions = new Set(binaryExtensions); - -var isBinaryPath$1 = filePath => extensions.has(path$8.extname(filePath).slice(1).toLowerCase()); - -var constants$1 = {}; - -(function (exports) { - -const {sep} = path$b; -const {platform} = process; -const os = require$$0$2; - -exports.EV_ALL = 'all'; -exports.EV_READY = 'ready'; -exports.EV_ADD = 'add'; -exports.EV_CHANGE = 'change'; -exports.EV_ADD_DIR = 'addDir'; -exports.EV_UNLINK = 'unlink'; -exports.EV_UNLINK_DIR = 'unlinkDir'; -exports.EV_RAW = 'raw'; -exports.EV_ERROR = 'error'; - -exports.STR_DATA = 'data'; -exports.STR_END = 'end'; -exports.STR_CLOSE = 'close'; - -exports.FSEVENT_CREATED = 'created'; -exports.FSEVENT_MODIFIED = 'modified'; -exports.FSEVENT_DELETED = 'deleted'; -exports.FSEVENT_MOVED = 'moved'; -exports.FSEVENT_CLONED = 'cloned'; -exports.FSEVENT_UNKNOWN = 'unknown'; -exports.FSEVENT_TYPE_FILE = 'file'; -exports.FSEVENT_TYPE_DIRECTORY = 'directory'; -exports.FSEVENT_TYPE_SYMLINK = 'symlink'; - -exports.KEY_LISTENERS = 'listeners'; -exports.KEY_ERR = 'errHandlers'; -exports.KEY_RAW = 'rawEmitters'; -exports.HANDLER_KEYS = [exports.KEY_LISTENERS, exports.KEY_ERR, exports.KEY_RAW]; - -exports.DOT_SLASH = `.${sep}`; - -exports.BACK_SLASH_RE = /\\/g; -exports.DOUBLE_SLASH_RE = /\/\//; -exports.SLASH_OR_BACK_SLASH_RE = /[/\\]/; -exports.DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/; -exports.REPLACER_RE = /^\.[/\\]/; - -exports.SLASH = '/'; -exports.SLASH_SLASH = '//'; -exports.BRACE_START = '{'; -exports.BANG = '!'; -exports.ONE_DOT = '.'; -exports.TWO_DOTS = '..'; -exports.STAR = '*'; -exports.GLOBSTAR = '**'; -exports.ROOT_GLOBSTAR = '/**/*'; -exports.SLASH_GLOBSTAR = '/**'; -exports.DIR_SUFFIX = 'Dir'; -exports.ANYMATCH_OPTS = {dot: true}; -exports.STRING_TYPE = 'string'; -exports.FUNCTION_TYPE = 'function'; -exports.EMPTY_STR = ''; -exports.EMPTY_FN = () => {}; -exports.IDENTITY_FN = val => val; - -exports.isWindows = platform === 'win32'; -exports.isMacos = platform === 'darwin'; -exports.isLinux = platform === 'linux'; -exports.isIBMi = os.type() === 'OS400'; -}(constants$1)); - -const fs$8 = require$$0$3; -const sysPath$2 = path$b; -const { promisify: promisify$2 } = require$$0$4; -const isBinaryPath = isBinaryPath$1; -const { - isWindows: isWindows$3, - isLinux, - EMPTY_FN: EMPTY_FN$2, - EMPTY_STR: EMPTY_STR$1, - KEY_LISTENERS, - KEY_ERR, - KEY_RAW, - HANDLER_KEYS, - EV_CHANGE: EV_CHANGE$2, - EV_ADD: EV_ADD$2, - EV_ADD_DIR: EV_ADD_DIR$2, - EV_ERROR: EV_ERROR$2, - STR_DATA: STR_DATA$1, - STR_END: STR_END$2, - BRACE_START: BRACE_START$1, - STAR -} = constants$1; - -const THROTTLE_MODE_WATCH = 'watch'; - -const open = promisify$2(fs$8.open); -const stat$2 = promisify$2(fs$8.stat); -const lstat$1 = promisify$2(fs$8.lstat); -const close = promisify$2(fs$8.close); -const fsrealpath = promisify$2(fs$8.realpath); - -const statMethods$1 = { lstat: lstat$1, stat: stat$2 }; - -// TODO: emit errors properly. Example: EMFILE on Macos. -const foreach = (val, fn) => { - if (val instanceof Set) { - val.forEach(fn); - } else { - fn(val); - } -}; - -const addAndConvert = (main, prop, item) => { - let container = main[prop]; - if (!(container instanceof Set)) { - main[prop] = container = new Set([container]); - } - container.add(item); -}; - -const clearItem = cont => key => { - const set = cont[key]; - if (set instanceof Set) { - set.clear(); - } else { - delete cont[key]; - } -}; - -const delFromSet = (main, prop, item) => { - const container = main[prop]; - if (container instanceof Set) { - container.delete(item); - } else if (container === item) { - delete main[prop]; - } -}; - -const isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val; - -/** - * @typedef {String} Path - */ - -// fs_watch helpers - -// object to hold per-process fs_watch instances -// (may be shared across chokidar FSWatcher instances) - -/** - * @typedef {Object} FsWatchContainer - * @property {Set} listeners - * @property {Set} errHandlers - * @property {Set} rawEmitters - * @property {fs.FSWatcher=} watcher - * @property {Boolean=} watcherUnusable - */ - -/** - * @type {Map} - */ -const FsWatchInstances = new Map(); - -/** - * Instantiates the fs_watch interface - * @param {String} path to be watched - * @param {Object} options to be passed to fs_watch - * @param {Function} listener main event handler - * @param {Function} errHandler emits info about errors - * @param {Function} emitRaw emits raw event data - * @returns {fs.FSWatcher} new fsevents instance - */ -function createFsWatchInstance(path, options, listener, errHandler, emitRaw) { - const handleEvent = (rawEvent, evPath) => { - listener(path); - emitRaw(rawEvent, evPath, {watchedPath: path}); - - // emit based on events occurring for files from a directory's watcher in - // case the file's watcher misses it (and rely on throttling to de-dupe) - if (evPath && path !== evPath) { - fsWatchBroadcast( - sysPath$2.resolve(path, evPath), KEY_LISTENERS, sysPath$2.join(path, evPath) - ); - } - }; - try { - return fs$8.watch(path, options, handleEvent); - } catch (error) { - errHandler(error); - } -} - -/** - * Helper for passing fs_watch event data to a collection of listeners - * @param {Path} fullPath absolute path bound to fs_watch instance - * @param {String} type listener type - * @param {*=} val1 arguments to be passed to listeners - * @param {*=} val2 - * @param {*=} val3 - */ -const fsWatchBroadcast = (fullPath, type, val1, val2, val3) => { - const cont = FsWatchInstances.get(fullPath); - if (!cont) return; - foreach(cont[type], (listener) => { - listener(val1, val2, val3); - }); -}; - -/** - * Instantiates the fs_watch interface or binds listeners - * to an existing one covering the same file system entry - * @param {String} path - * @param {String} fullPath absolute path - * @param {Object} options to be passed to fs_watch - * @param {Object} handlers container for event listener functions - */ -const setFsWatchListener = (path, fullPath, options, handlers) => { - const {listener, errHandler, rawEmitter} = handlers; - let cont = FsWatchInstances.get(fullPath); - - /** @type {fs.FSWatcher=} */ - let watcher; - if (!options.persistent) { - watcher = createFsWatchInstance( - path, options, listener, errHandler, rawEmitter - ); - return watcher.close.bind(watcher); - } - if (cont) { - addAndConvert(cont, KEY_LISTENERS, listener); - addAndConvert(cont, KEY_ERR, errHandler); - addAndConvert(cont, KEY_RAW, rawEmitter); - } else { - watcher = createFsWatchInstance( - path, - options, - fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), - errHandler, // no need to use broadcast here - fsWatchBroadcast.bind(null, fullPath, KEY_RAW) - ); - if (!watcher) return; - watcher.on(EV_ERROR$2, async (error) => { - const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR); - cont.watcherUnusable = true; // documented since Node 10.4.1 - // Workaround for https://github.com/joyent/node/issues/4337 - if (isWindows$3 && error.code === 'EPERM') { - try { - const fd = await open(path, 'r'); - await close(fd); - broadcastErr(error); - } catch (err) {} - } else { - broadcastErr(error); - } - }); - cont = { - listeners: listener, - errHandlers: errHandler, - rawEmitters: rawEmitter, - watcher - }; - FsWatchInstances.set(fullPath, cont); - } - // const index = cont.listeners.indexOf(listener); - - // removes this instance's listeners and closes the underlying fs_watch - // instance if there are no more listeners left - return () => { - delFromSet(cont, KEY_LISTENERS, listener); - delFromSet(cont, KEY_ERR, errHandler); - delFromSet(cont, KEY_RAW, rawEmitter); - if (isEmptySet(cont.listeners)) { - // Check to protect against issue gh-730. - // if (cont.watcherUnusable) { - cont.watcher.close(); - // } - FsWatchInstances.delete(fullPath); - HANDLER_KEYS.forEach(clearItem(cont)); - cont.watcher = undefined; - Object.freeze(cont); - } - }; -}; - -// fs_watchFile helpers - -// object to hold per-process fs_watchFile instances -// (may be shared across chokidar FSWatcher instances) -const FsWatchFileInstances = new Map(); - -/** - * Instantiates the fs_watchFile interface or binds listeners - * to an existing one covering the same file system entry - * @param {String} path to be watched - * @param {String} fullPath absolute path - * @param {Object} options options to be passed to fs_watchFile - * @param {Object} handlers container for event listener functions - * @returns {Function} closer - */ -const setFsWatchFileListener = (path, fullPath, options, handlers) => { - const {listener, rawEmitter} = handlers; - let cont = FsWatchFileInstances.get(fullPath); - - const copts = cont && cont.options; - if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) { - fs$8.unwatchFile(fullPath); - cont = undefined; - } - - /* eslint-enable no-unused-vars, prefer-destructuring */ - - if (cont) { - addAndConvert(cont, KEY_LISTENERS, listener); - addAndConvert(cont, KEY_RAW, rawEmitter); - } else { - // TODO - // listeners.add(listener); - // rawEmitters.add(rawEmitter); - cont = { - listeners: listener, - rawEmitters: rawEmitter, - options, - watcher: fs$8.watchFile(fullPath, options, (curr, prev) => { - foreach(cont.rawEmitters, (rawEmitter) => { - rawEmitter(EV_CHANGE$2, fullPath, {curr, prev}); - }); - const currmtime = curr.mtimeMs; - if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) { - foreach(cont.listeners, (listener) => listener(path, curr)); - } - }) - }; - FsWatchFileInstances.set(fullPath, cont); - } - // const index = cont.listeners.indexOf(listener); - - // Removes this instance's listeners and closes the underlying fs_watchFile - // instance if there are no more listeners left. - return () => { - delFromSet(cont, KEY_LISTENERS, listener); - delFromSet(cont, KEY_RAW, rawEmitter); - if (isEmptySet(cont.listeners)) { - FsWatchFileInstances.delete(fullPath); - fs$8.unwatchFile(fullPath); - cont.options = cont.watcher = undefined; - Object.freeze(cont); - } - }; -}; - -/** - * @mixin - */ -class NodeFsHandler$1 { - -/** - * @param {import("../index").FSWatcher} fsW - */ -constructor(fsW) { - this.fsw = fsW; - this._boundHandleError = (error) => fsW._handleError(error); -} - -/** - * Watch file for changes with fs_watchFile or fs_watch. - * @param {String} path to file or dir - * @param {Function} listener on fs change - * @returns {Function} closer for the watcher instance - */ -_watchWithNodeFs(path, listener) { - const opts = this.fsw.options; - const directory = sysPath$2.dirname(path); - const basename = sysPath$2.basename(path); - const parent = this.fsw._getWatchedDir(directory); - parent.add(basename); - const absolutePath = sysPath$2.resolve(path); - const options = {persistent: opts.persistent}; - if (!listener) listener = EMPTY_FN$2; - - let closer; - if (opts.usePolling) { - options.interval = opts.enableBinaryInterval && isBinaryPath(basename) ? - opts.binaryInterval : opts.interval; - closer = setFsWatchFileListener(path, absolutePath, options, { - listener, - rawEmitter: this.fsw._emitRaw - }); - } else { - closer = setFsWatchListener(path, absolutePath, options, { - listener, - errHandler: this._boundHandleError, - rawEmitter: this.fsw._emitRaw - }); - } - return closer; -} - -/** - * Watch a file and emit add event if warranted. - * @param {Path} file Path - * @param {fs.Stats} stats result of fs_stat - * @param {Boolean} initialAdd was the file added at watch instantiation? - * @returns {Function} closer for the watcher instance - */ -_handleFile(file, stats, initialAdd) { - if (this.fsw.closed) { - return; - } - const dirname = sysPath$2.dirname(file); - const basename = sysPath$2.basename(file); - const parent = this.fsw._getWatchedDir(dirname); - // stats is always present - let prevStats = stats; - - // if the file is already being watched, do nothing - if (parent.has(basename)) return; - - const listener = async (path, newStats) => { - if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5)) return; - if (!newStats || newStats.mtimeMs === 0) { - try { - const newStats = await stat$2(file); - if (this.fsw.closed) return; - // Check that change event was not fired because of changed only accessTime. - const at = newStats.atimeMs; - const mt = newStats.mtimeMs; - if (!at || at <= mt || mt !== prevStats.mtimeMs) { - this.fsw._emit(EV_CHANGE$2, file, newStats); - } - if (isLinux && prevStats.ino !== newStats.ino) { - this.fsw._closeFile(path); - prevStats = newStats; - this.fsw._addPathCloser(path, this._watchWithNodeFs(file, listener)); - } else { - prevStats = newStats; - } - } catch (error) { - // Fix issues where mtime is null but file is still present - this.fsw._remove(dirname, basename); - } - // add is about to be emitted if file not already tracked in parent - } else if (parent.has(basename)) { - // Check that change event was not fired because of changed only accessTime. - const at = newStats.atimeMs; - const mt = newStats.mtimeMs; - if (!at || at <= mt || mt !== prevStats.mtimeMs) { - this.fsw._emit(EV_CHANGE$2, file, newStats); - } - prevStats = newStats; - } - }; - // kick off the watcher - const closer = this._watchWithNodeFs(file, listener); - - // emit an add event if we're supposed to - if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) { - if (!this.fsw._throttle(EV_ADD$2, file, 0)) return; - this.fsw._emit(EV_ADD$2, file, stats); - } - - return closer; -} - -/** - * Handle symlinks encountered while reading a dir. - * @param {Object} entry returned by readdirp - * @param {String} directory path of dir being read - * @param {String} path of this item - * @param {String} item basename of this item - * @returns {Promise} true if no more processing is needed for this entry. - */ -async _handleSymlink(entry, directory, path, item) { - if (this.fsw.closed) { - return; - } - const full = entry.fullPath; - const dir = this.fsw._getWatchedDir(directory); - - if (!this.fsw.options.followSymlinks) { - // watch symlink directly (don't follow) and detect changes - this.fsw._incrReadyCount(); - const linkPath = await fsrealpath(path); - if (this.fsw.closed) return; - if (dir.has(item)) { - if (this.fsw._symlinkPaths.get(full) !== linkPath) { - this.fsw._symlinkPaths.set(full, linkPath); - this.fsw._emit(EV_CHANGE$2, path, entry.stats); - } - } else { - dir.add(item); - this.fsw._symlinkPaths.set(full, linkPath); - this.fsw._emit(EV_ADD$2, path, entry.stats); - } - this.fsw._emitReady(); - return true; - } - - // don't follow the same symlink more than once - if (this.fsw._symlinkPaths.has(full)) { - return true; - } - - this.fsw._symlinkPaths.set(full, true); -} - -_handleRead(directory, initialAdd, wh, target, dir, depth, throttler) { - // Normalize the directory name on Windows - directory = sysPath$2.join(directory, EMPTY_STR$1); - - if (!wh.hasGlob) { - throttler = this.fsw._throttle('readdir', directory, 1000); - if (!throttler) return; - } - - const previous = this.fsw._getWatchedDir(wh.path); - const current = new Set(); - - let stream = this.fsw._readdirp(directory, { - fileFilter: entry => wh.filterPath(entry), - directoryFilter: entry => wh.filterDir(entry), - depth: 0 - }).on(STR_DATA$1, async (entry) => { - if (this.fsw.closed) { - stream = undefined; - return; - } - const item = entry.path; - let path = sysPath$2.join(directory, item); - current.add(item); - - if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path, item)) { - return; - } - - if (this.fsw.closed) { - stream = undefined; - return; - } - // Files that present in current directory snapshot - // but absent in previous are added to watch list and - // emit `add` event. - if (item === target || !target && !previous.has(item)) { - this.fsw._incrReadyCount(); - - // ensure relativeness of path is preserved in case of watcher reuse - path = sysPath$2.join(dir, sysPath$2.relative(dir, path)); - - this._addToNodeFs(path, initialAdd, wh, depth + 1); - } - }).on(EV_ERROR$2, this._boundHandleError); - - return new Promise(resolve => - stream.once(STR_END$2, () => { - if (this.fsw.closed) { - stream = undefined; - return; - } - const wasThrottled = throttler ? throttler.clear() : false; - - resolve(); - - // Files that absent in current directory snapshot - // but present in previous emit `remove` event - // and are removed from @watched[directory]. - previous.getChildren().filter((item) => { - return item !== directory && - !current.has(item) && - // in case of intersecting globs; - // a path may have been filtered out of this readdir, but - // shouldn't be removed because it matches a different glob - (!wh.hasGlob || wh.filterPath({ - fullPath: sysPath$2.resolve(directory, item) - })); - }).forEach((item) => { - this.fsw._remove(directory, item); - }); - - stream = undefined; - - // one more time for any missed in case changes came in extremely quickly - if (wasThrottled) this._handleRead(directory, false, wh, target, dir, depth, throttler); - }) - ); -} - -/** - * Read directory to add / remove files from `@watched` list and re-read it on change. - * @param {String} dir fs path - * @param {fs.Stats} stats - * @param {Boolean} initialAdd - * @param {Number} depth relative to user-supplied path - * @param {String} target child path targeted for watch - * @param {Object} wh Common watch helpers for this path - * @param {String} realpath - * @returns {Promise} closer for the watcher instance. - */ -async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath) { - const parentDir = this.fsw._getWatchedDir(sysPath$2.dirname(dir)); - const tracked = parentDir.has(sysPath$2.basename(dir)); - if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) { - if (!wh.hasGlob || wh.globFilter(dir)) this.fsw._emit(EV_ADD_DIR$2, dir, stats); - } - - // ensure dir is tracked (harmless if redundant) - parentDir.add(sysPath$2.basename(dir)); - this.fsw._getWatchedDir(dir); - let throttler; - let closer; - - const oDepth = this.fsw.options.depth; - if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath)) { - if (!target) { - await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler); - if (this.fsw.closed) return; - } - - closer = this._watchWithNodeFs(dir, (dirPath, stats) => { - // if current directory is removed, do nothing - if (stats && stats.mtimeMs === 0) return; - - this._handleRead(dirPath, false, wh, target, dir, depth, throttler); - }); - } - return closer; -} - -/** - * Handle added file, directory, or glob pattern. - * Delegates call to _handleFile / _handleDir after checks. - * @param {String} path to file or ir - * @param {Boolean} initialAdd was the file added at watch instantiation? - * @param {Object} priorWh depth relative to user-supplied path - * @param {Number} depth Child path actually targeted for watch - * @param {String=} target Child path actually targeted for watch - * @returns {Promise} - */ -async _addToNodeFs(path, initialAdd, priorWh, depth, target) { - const ready = this.fsw._emitReady; - if (this.fsw._isIgnored(path) || this.fsw.closed) { - ready(); - return false; - } - - const wh = this.fsw._getWatchHelpers(path, depth); - if (!wh.hasGlob && priorWh) { - wh.hasGlob = priorWh.hasGlob; - wh.globFilter = priorWh.globFilter; - wh.filterPath = entry => priorWh.filterPath(entry); - wh.filterDir = entry => priorWh.filterDir(entry); - } - - // evaluate what is at the path we're being asked to watch - try { - const stats = await statMethods$1[wh.statMethod](wh.watchPath); - if (this.fsw.closed) return; - if (this.fsw._isIgnored(wh.watchPath, stats)) { - ready(); - return false; - } - - const follow = this.fsw.options.followSymlinks && !path.includes(STAR) && !path.includes(BRACE_START$1); - let closer; - if (stats.isDirectory()) { - const absPath = sysPath$2.resolve(path); - const targetPath = follow ? await fsrealpath(path) : path; - if (this.fsw.closed) return; - closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath); - if (this.fsw.closed) return; - // preserve this symlink's target path - if (absPath !== targetPath && targetPath !== undefined) { - this.fsw._symlinkPaths.set(absPath, targetPath); - } - } else if (stats.isSymbolicLink()) { - const targetPath = follow ? await fsrealpath(path) : path; - if (this.fsw.closed) return; - const parent = sysPath$2.dirname(wh.watchPath); - this.fsw._getWatchedDir(parent).add(wh.watchPath); - this.fsw._emit(EV_ADD$2, wh.watchPath, stats); - closer = await this._handleDir(parent, stats, initialAdd, depth, path, wh, targetPath); - if (this.fsw.closed) return; - - // preserve this symlink's target path - if (targetPath !== undefined) { - this.fsw._symlinkPaths.set(sysPath$2.resolve(path), targetPath); - } - } else { - closer = this._handleFile(wh.watchPath, stats, initialAdd); - } - ready(); - - this.fsw._addPathCloser(path, closer); - return false; - - } catch (error) { - if (this.fsw._handleError(error)) { - ready(); - return path; - } - } -} - -} - -var nodefsHandler = NodeFsHandler$1; - -var fseventsHandler = {exports: {}}; - -const fs$7 = require$$0$3; -const sysPath$1 = path$b; -const { promisify: promisify$1 } = require$$0$4; - -let fsevents; -try { - fsevents = undefined; -} catch (error) { - if (process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR) console.error(error); -} - -if (fsevents) { - // TODO: real check - const mtch = process.version.match(/v(\d+)\.(\d+)/); - if (mtch && mtch[1] && mtch[2]) { - const maj = Number.parseInt(mtch[1], 10); - const min = Number.parseInt(mtch[2], 10); - if (maj === 8 && min < 16) { - fsevents = undefined; - } - } -} - -const { - EV_ADD: EV_ADD$1, - EV_CHANGE: EV_CHANGE$1, - EV_ADD_DIR: EV_ADD_DIR$1, - EV_UNLINK: EV_UNLINK$1, - EV_ERROR: EV_ERROR$1, - STR_DATA, - STR_END: STR_END$1, - FSEVENT_CREATED, - FSEVENT_MODIFIED, - FSEVENT_DELETED, - FSEVENT_MOVED, - // FSEVENT_CLONED, - FSEVENT_UNKNOWN, - FSEVENT_TYPE_FILE, - FSEVENT_TYPE_DIRECTORY, - FSEVENT_TYPE_SYMLINK, - - ROOT_GLOBSTAR, - DIR_SUFFIX, - DOT_SLASH, - FUNCTION_TYPE: FUNCTION_TYPE$1, - EMPTY_FN: EMPTY_FN$1, - IDENTITY_FN -} = constants$1; - -const Depth = (value) => isNaN(value) ? {} : {depth: value}; - -const stat$1 = promisify$1(fs$7.stat); -const lstat = promisify$1(fs$7.lstat); -const realpath$1 = promisify$1(fs$7.realpath); - -const statMethods = { stat: stat$1, lstat }; - -/** - * @typedef {String} Path - */ - -/** - * @typedef {Object} FsEventsWatchContainer - * @property {Set} listeners - * @property {Function} rawEmitter - * @property {{stop: Function}} watcher - */ - -// fsevents instance helper functions -/** - * Object to hold per-process fsevents instances (may be shared across chokidar FSWatcher instances) - * @type {Map} - */ -const FSEventsWatchers = new Map(); - -// Threshold of duplicate path prefixes at which to start -// consolidating going forward -const consolidateThreshhold = 10; - -const wrongEventFlags = new Set([ - 69888, 70400, 71424, 72704, 73472, 131328, 131840, 262912 -]); - -/** - * Instantiates the fsevents interface - * @param {Path} path path to be watched - * @param {Function} callback called when fsevents is bound and ready - * @returns {{stop: Function}} new fsevents instance - */ -const createFSEventsInstance = (path, callback) => { - const stop = fsevents.watch(path, callback); - return {stop}; -}; - -/** - * Instantiates the fsevents interface or binds listeners to an existing one covering - * the same file tree. - * @param {Path} path - to be watched - * @param {Path} realPath - real path for symlinks - * @param {Function} listener - called when fsevents emits events - * @param {Function} rawEmitter - passes data to listeners of the 'raw' event - * @returns {Function} closer - */ -function setFSEventsListener(path, realPath, listener, rawEmitter) { - let watchPath = sysPath$1.extname(realPath) ? sysPath$1.dirname(realPath) : realPath; - - const parentPath = sysPath$1.dirname(watchPath); - let cont = FSEventsWatchers.get(watchPath); - - // If we've accumulated a substantial number of paths that - // could have been consolidated by watching one directory - // above the current one, create a watcher on the parent - // path instead, so that we do consolidate going forward. - if (couldConsolidate(parentPath)) { - watchPath = parentPath; - } - - const resolvedPath = sysPath$1.resolve(path); - const hasSymlink = resolvedPath !== realPath; - - const filteredListener = (fullPath, flags, info) => { - if (hasSymlink) fullPath = fullPath.replace(realPath, resolvedPath); - if ( - fullPath === resolvedPath || - !fullPath.indexOf(resolvedPath + sysPath$1.sep) - ) listener(fullPath, flags, info); - }; - - // check if there is already a watcher on a parent path - // modifies `watchPath` to the parent path when it finds a match - let watchedParent = false; - for (const watchedPath of FSEventsWatchers.keys()) { - if (realPath.indexOf(sysPath$1.resolve(watchedPath) + sysPath$1.sep) === 0) { - watchPath = watchedPath; - cont = FSEventsWatchers.get(watchPath); - watchedParent = true; - break; - } - } - - if (cont || watchedParent) { - cont.listeners.add(filteredListener); - } else { - cont = { - listeners: new Set([filteredListener]), - rawEmitter, - watcher: createFSEventsInstance(watchPath, (fullPath, flags) => { - if (!cont.listeners.size) return; - const info = fsevents.getInfo(fullPath, flags); - cont.listeners.forEach(list => { - list(fullPath, flags, info); - }); - - cont.rawEmitter(info.event, fullPath, info); - }) - }; - FSEventsWatchers.set(watchPath, cont); - } - - // removes this instance's listeners and closes the underlying fsevents - // instance if there are no more listeners left - return () => { - const lst = cont.listeners; - - lst.delete(filteredListener); - if (!lst.size) { - FSEventsWatchers.delete(watchPath); - if (cont.watcher) return cont.watcher.stop().then(() => { - cont.rawEmitter = cont.watcher = undefined; - Object.freeze(cont); - }); - } - }; -} - -// Decide whether or not we should start a new higher-level -// parent watcher -const couldConsolidate = (path) => { - let count = 0; - for (const watchPath of FSEventsWatchers.keys()) { - if (watchPath.indexOf(path) === 0) { - count++; - if (count >= consolidateThreshhold) { - return true; - } - } - } - - return false; -}; - -// returns boolean indicating whether fsevents can be used -const canUse = () => fsevents && FSEventsWatchers.size < 128; - -// determines subdirectory traversal levels from root to path -const calcDepth = (path, root) => { - let i = 0; - while (!path.indexOf(root) && (path = sysPath$1.dirname(path)) !== root) i++; - return i; -}; - -// returns boolean indicating whether the fsevents' event info has the same type -// as the one returned by fs.stat -const sameTypes = (info, stats) => ( - info.type === FSEVENT_TYPE_DIRECTORY && stats.isDirectory() || - info.type === FSEVENT_TYPE_SYMLINK && stats.isSymbolicLink() || - info.type === FSEVENT_TYPE_FILE && stats.isFile() -); - -/** - * @mixin - */ -class FsEventsHandler$1 { - -/** - * @param {import('../index').FSWatcher} fsw - */ -constructor(fsw) { - this.fsw = fsw; -} -checkIgnored(path, stats) { - const ipaths = this.fsw._ignoredPaths; - if (this.fsw._isIgnored(path, stats)) { - ipaths.add(path); - if (stats && stats.isDirectory()) { - ipaths.add(path + ROOT_GLOBSTAR); - } - return true; - } - - ipaths.delete(path); - ipaths.delete(path + ROOT_GLOBSTAR); -} - -addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts) { - const event = watchedDir.has(item) ? EV_CHANGE$1 : EV_ADD$1; - this.handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts); -} - -async checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts) { - try { - const stats = await stat$1(path); - if (this.fsw.closed) return; - if (sameTypes(info, stats)) { - this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); - } else { - this.handleEvent(EV_UNLINK$1, path, fullPath, realPath, parent, watchedDir, item, info, opts); - } - } catch (error) { - if (error.code === 'EACCES') { - this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); - } else { - this.handleEvent(EV_UNLINK$1, path, fullPath, realPath, parent, watchedDir, item, info, opts); - } - } -} - -handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts) { - if (this.fsw.closed || this.checkIgnored(path)) return; - - if (event === EV_UNLINK$1) { - const isDirectory = info.type === FSEVENT_TYPE_DIRECTORY; - // suppress unlink events on never before seen files - if (isDirectory || watchedDir.has(item)) { - this.fsw._remove(parent, item, isDirectory); - } - } else { - if (event === EV_ADD$1) { - // track new directories - if (info.type === FSEVENT_TYPE_DIRECTORY) this.fsw._getWatchedDir(path); - - if (info.type === FSEVENT_TYPE_SYMLINK && opts.followSymlinks) { - // push symlinks back to the top of the stack to get handled - const curDepth = opts.depth === undefined ? - undefined : calcDepth(fullPath, realPath) + 1; - return this._addToFsEvents(path, false, true, curDepth); - } - - // track new paths - // (other than symlinks being followed, which will be tracked soon) - this.fsw._getWatchedDir(parent).add(item); - } - /** - * @type {'add'|'addDir'|'unlink'|'unlinkDir'} - */ - const eventName = info.type === FSEVENT_TYPE_DIRECTORY ? event + DIR_SUFFIX : event; - this.fsw._emit(eventName, path); - if (eventName === EV_ADD_DIR$1) this._addToFsEvents(path, false, true); - } -} - -/** - * Handle symlinks encountered during directory scan - * @param {String} watchPath - file/dir path to be watched with fsevents - * @param {String} realPath - real path (in case of symlinks) - * @param {Function} transform - path transformer - * @param {Function} globFilter - path filter in case a glob pattern was provided - * @returns {Function} closer for the watcher instance -*/ -_watchWithFsEvents(watchPath, realPath, transform, globFilter) { - if (this.fsw.closed || this.fsw._isIgnored(watchPath)) return; - const opts = this.fsw.options; - const watchCallback = async (fullPath, flags, info) => { - if (this.fsw.closed) return; - if ( - opts.depth !== undefined && - calcDepth(fullPath, realPath) > opts.depth - ) return; - const path = transform(sysPath$1.join( - watchPath, sysPath$1.relative(watchPath, fullPath) - )); - if (globFilter && !globFilter(path)) return; - // ensure directories are tracked - const parent = sysPath$1.dirname(path); - const item = sysPath$1.basename(path); - const watchedDir = this.fsw._getWatchedDir( - info.type === FSEVENT_TYPE_DIRECTORY ? path : parent - ); - - // correct for wrong events emitted - if (wrongEventFlags.has(flags) || info.event === FSEVENT_UNKNOWN) { - if (typeof opts.ignored === FUNCTION_TYPE$1) { - let stats; - try { - stats = await stat$1(path); - } catch (error) {} - if (this.fsw.closed) return; - if (this.checkIgnored(path, stats)) return; - if (sameTypes(info, stats)) { - this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); - } else { - this.handleEvent(EV_UNLINK$1, path, fullPath, realPath, parent, watchedDir, item, info, opts); - } - } else { - this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts); - } - } else { - switch (info.event) { - case FSEVENT_CREATED: - case FSEVENT_MODIFIED: - return this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); - case FSEVENT_DELETED: - case FSEVENT_MOVED: - return this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts); - } - } - }; - - const closer = setFSEventsListener( - watchPath, - realPath, - watchCallback, - this.fsw._emitRaw - ); - - this.fsw._emitReady(); - return closer; -} - -/** - * Handle symlinks encountered during directory scan - * @param {String} linkPath path to symlink - * @param {String} fullPath absolute path to the symlink - * @param {Function} transform pre-existing path transformer - * @param {Number} curDepth level of subdirectories traversed to where symlink is - * @returns {Promise} - */ -async _handleFsEventsSymlink(linkPath, fullPath, transform, curDepth) { - // don't follow the same symlink more than once - if (this.fsw.closed || this.fsw._symlinkPaths.has(fullPath)) return; - - this.fsw._symlinkPaths.set(fullPath, true); - this.fsw._incrReadyCount(); - - try { - const linkTarget = await realpath$1(linkPath); - if (this.fsw.closed) return; - if (this.fsw._isIgnored(linkTarget)) { - return this.fsw._emitReady(); - } - - this.fsw._incrReadyCount(); - - // add the linkTarget for watching with a wrapper for transform - // that causes emitted paths to incorporate the link's path - this._addToFsEvents(linkTarget || linkPath, (path) => { - let aliasedPath = linkPath; - if (linkTarget && linkTarget !== DOT_SLASH) { - aliasedPath = path.replace(linkTarget, linkPath); - } else if (path !== DOT_SLASH) { - aliasedPath = sysPath$1.join(linkPath, path); - } - return transform(aliasedPath); - }, false, curDepth); - } catch(error) { - if (this.fsw._handleError(error)) { - return this.fsw._emitReady(); - } - } -} - -/** - * - * @param {Path} newPath - * @param {fs.Stats} stats - */ -emitAdd(newPath, stats, processPath, opts, forceAdd) { - const pp = processPath(newPath); - const isDir = stats.isDirectory(); - const dirObj = this.fsw._getWatchedDir(sysPath$1.dirname(pp)); - const base = sysPath$1.basename(pp); - - // ensure empty dirs get tracked - if (isDir) this.fsw._getWatchedDir(pp); - if (dirObj.has(base)) return; - dirObj.add(base); - - if (!opts.ignoreInitial || forceAdd === true) { - this.fsw._emit(isDir ? EV_ADD_DIR$1 : EV_ADD$1, pp, stats); - } -} - -initWatch(realPath, path, wh, processPath) { - if (this.fsw.closed) return; - const closer = this._watchWithFsEvents( - wh.watchPath, - sysPath$1.resolve(realPath || wh.watchPath), - processPath, - wh.globFilter - ); - this.fsw._addPathCloser(path, closer); -} - -/** - * Handle added path with fsevents - * @param {String} path file/dir path or glob pattern - * @param {Function|Boolean=} transform converts working path to what the user expects - * @param {Boolean=} forceAdd ensure add is emitted - * @param {Number=} priorDepth Level of subdirectories already traversed. - * @returns {Promise} - */ -async _addToFsEvents(path, transform, forceAdd, priorDepth) { - if (this.fsw.closed) { - return; - } - const opts = this.fsw.options; - const processPath = typeof transform === FUNCTION_TYPE$1 ? transform : IDENTITY_FN; - - const wh = this.fsw._getWatchHelpers(path); - - // evaluate what is at the path we're being asked to watch - try { - const stats = await statMethods[wh.statMethod](wh.watchPath); - if (this.fsw.closed) return; - if (this.fsw._isIgnored(wh.watchPath, stats)) { - throw null; - } - if (stats.isDirectory()) { - // emit addDir unless this is a glob parent - if (!wh.globFilter) this.emitAdd(processPath(path), stats, processPath, opts, forceAdd); - - // don't recurse further if it would exceed depth setting - if (priorDepth && priorDepth > opts.depth) return; - - // scan the contents of the dir - this.fsw._readdirp(wh.watchPath, { - fileFilter: entry => wh.filterPath(entry), - directoryFilter: entry => wh.filterDir(entry), - ...Depth(opts.depth - (priorDepth || 0)) - }).on(STR_DATA, (entry) => { - // need to check filterPath on dirs b/c filterDir is less restrictive - if (this.fsw.closed) { - return; - } - if (entry.stats.isDirectory() && !wh.filterPath(entry)) return; - - const joinedPath = sysPath$1.join(wh.watchPath, entry.path); - const {fullPath} = entry; - - if (wh.followSymlinks && entry.stats.isSymbolicLink()) { - // preserve the current depth here since it can't be derived from - // real paths past the symlink - const curDepth = opts.depth === undefined ? - undefined : calcDepth(joinedPath, sysPath$1.resolve(wh.watchPath)) + 1; - - this._handleFsEventsSymlink(joinedPath, fullPath, processPath, curDepth); - } else { - this.emitAdd(joinedPath, entry.stats, processPath, opts, forceAdd); - } - }).on(EV_ERROR$1, EMPTY_FN$1).on(STR_END$1, () => { - this.fsw._emitReady(); - }); - } else { - this.emitAdd(wh.watchPath, stats, processPath, opts, forceAdd); - this.fsw._emitReady(); - } - } catch (error) { - if (!error || this.fsw._handleError(error)) { - // TODO: Strange thing: "should not choke on an ignored watch path" will be failed without 2 ready calls -__- - this.fsw._emitReady(); - this.fsw._emitReady(); - } - } - - if (opts.persistent && forceAdd !== true) { - if (typeof transform === FUNCTION_TYPE$1) { - // realpath has already been resolved - this.initWatch(undefined, path, wh, processPath); - } else { - let realPath; - try { - realPath = await realpath$1(wh.watchPath); - } catch (e) {} - this.initWatch(realPath, path, wh, processPath); - } - } -} - -} - -fseventsHandler.exports = FsEventsHandler$1; -fseventsHandler.exports.canUse = canUse; - -const { EventEmitter } = require$$0$5; -const fs$6 = require$$0$3; -const sysPath = path$b; -const { promisify } = require$$0$4; -const readdirp = readdirp_1; -const anymatch = anymatch$2.exports.default; -const globParent = globParent$1; -const isGlob = isGlob$2; -const braces = braces_1; -const normalizePath = normalizePath$2; - -const NodeFsHandler = nodefsHandler; -const FsEventsHandler = fseventsHandler.exports; -const { - EV_ALL, - EV_READY, - EV_ADD, - EV_CHANGE, - EV_UNLINK, - EV_ADD_DIR, - EV_UNLINK_DIR, - EV_RAW, - EV_ERROR, - - STR_CLOSE, - STR_END, - - BACK_SLASH_RE, - DOUBLE_SLASH_RE, - SLASH_OR_BACK_SLASH_RE, - DOT_RE, - REPLACER_RE, - - SLASH: SLASH$1, - SLASH_SLASH, - BRACE_START, - BANG, - ONE_DOT, - TWO_DOTS, - GLOBSTAR: GLOBSTAR$1, - SLASH_GLOBSTAR, - ANYMATCH_OPTS, - STRING_TYPE, - FUNCTION_TYPE, - EMPTY_STR, - EMPTY_FN, - - isWindows: isWindows$2, - isMacos, - isIBMi -} = constants$1; - -const stat = promisify(fs$6.stat); -const readdir = promisify(fs$6.readdir); - -/** - * @typedef {String} Path - * @typedef {'all'|'add'|'addDir'|'change'|'unlink'|'unlinkDir'|'raw'|'error'|'ready'} EventName - * @typedef {'readdir'|'watch'|'add'|'remove'|'change'} ThrottleType - */ - -/** - * - * @typedef {Object} WatchHelpers - * @property {Boolean} followSymlinks - * @property {'stat'|'lstat'} statMethod - * @property {Path} path - * @property {Path} watchPath - * @property {Function} entryPath - * @property {Boolean} hasGlob - * @property {Object} globFilter - * @property {Function} filterPath - * @property {Function} filterDir - */ - -const arrify = (value = []) => Array.isArray(value) ? value : [value]; -const flatten$1 = (list, result = []) => { - list.forEach(item => { - if (Array.isArray(item)) { - flatten$1(item, result); - } else { - result.push(item); - } - }); - return result; -}; - -const unifyPaths = (paths_) => { - /** - * @type {Array} - */ - const paths = flatten$1(arrify(paths_)); - if (!paths.every(p => typeof p === STRING_TYPE)) { - throw new TypeError(`Non-string provided as watch path: ${paths}`); - } - return paths.map(normalizePathToUnix); -}; - -// If SLASH_SLASH occurs at the beginning of path, it is not replaced -// because "//StoragePC/DrivePool/Movies" is a valid network path -const toUnix = (string) => { - let str = string.replace(BACK_SLASH_RE, SLASH$1); - let prepend = false; - if (str.startsWith(SLASH_SLASH)) { - prepend = true; - } - while (str.match(DOUBLE_SLASH_RE)) { - str = str.replace(DOUBLE_SLASH_RE, SLASH$1); - } - if (prepend) { - str = SLASH$1 + str; - } - return str; -}; - -// Our version of upath.normalize -// TODO: this is not equal to path-normalize module - investigate why -const normalizePathToUnix = (path) => toUnix(sysPath.normalize(toUnix(path))); - -const normalizeIgnored = (cwd = EMPTY_STR) => (path) => { - if (typeof path !== STRING_TYPE) return path; - return normalizePathToUnix(sysPath.isAbsolute(path) ? path : sysPath.join(cwd, path)); -}; - -const getAbsolutePath = (path, cwd) => { - if (sysPath.isAbsolute(path)) { - return path; - } - if (path.startsWith(BANG)) { - return BANG + sysPath.join(cwd, path.slice(1)); - } - return sysPath.join(cwd, path); -}; - -const undef = (opts, key) => opts[key] === undefined; - -/** - * Directory entry. - * @property {Path} path - * @property {Set} items - */ -class DirEntry { - /** - * @param {Path} dir - * @param {Function} removeWatcher - */ - constructor(dir, removeWatcher) { - this.path = dir; - this._removeWatcher = removeWatcher; - /** @type {Set} */ - this.items = new Set(); - } - - add(item) { - const {items} = this; - if (!items) return; - if (item !== ONE_DOT && item !== TWO_DOTS) items.add(item); - } - - async remove(item) { - const {items} = this; - if (!items) return; - items.delete(item); - if (items.size > 0) return; - - const dir = this.path; - try { - await readdir(dir); - } catch (err) { - if (this._removeWatcher) { - this._removeWatcher(sysPath.dirname(dir), sysPath.basename(dir)); - } - } - } - - has(item) { - const {items} = this; - if (!items) return; - return items.has(item); - } - - /** - * @returns {Array} - */ - getChildren() { - const {items} = this; - if (!items) return; - return [...items.values()]; - } - - dispose() { - this.items.clear(); - delete this.path; - delete this._removeWatcher; - delete this.items; - Object.freeze(this); - } -} - -const STAT_METHOD_F = 'stat'; -const STAT_METHOD_L = 'lstat'; -class WatchHelper { - constructor(path, watchPath, follow, fsw) { - this.fsw = fsw; - this.path = path = path.replace(REPLACER_RE, EMPTY_STR); - this.watchPath = watchPath; - this.fullWatchPath = sysPath.resolve(watchPath); - this.hasGlob = watchPath !== path; - /** @type {object|boolean} */ - if (path === EMPTY_STR) this.hasGlob = false; - this.globSymlink = this.hasGlob && follow ? undefined : false; - this.globFilter = this.hasGlob ? anymatch(path, undefined, ANYMATCH_OPTS) : false; - this.dirParts = this.getDirParts(path); - this.dirParts.forEach((parts) => { - if (parts.length > 1) parts.pop(); - }); - this.followSymlinks = follow; - this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L; - } - - checkGlobSymlink(entry) { - // only need to resolve once - // first entry should always have entry.parentDir === EMPTY_STR - if (this.globSymlink === undefined) { - this.globSymlink = entry.fullParentDir === this.fullWatchPath ? - false : {realPath: entry.fullParentDir, linkPath: this.fullWatchPath}; - } - - if (this.globSymlink) { - return entry.fullPath.replace(this.globSymlink.realPath, this.globSymlink.linkPath); - } - - return entry.fullPath; - } - - entryPath(entry) { - return sysPath.join(this.watchPath, - sysPath.relative(this.watchPath, this.checkGlobSymlink(entry)) - ); - } - - filterPath(entry) { - const {stats} = entry; - if (stats && stats.isSymbolicLink()) return this.filterDir(entry); - const resolvedPath = this.entryPath(entry); - const matchesGlob = this.hasGlob && typeof this.globFilter === FUNCTION_TYPE ? - this.globFilter(resolvedPath) : true; - return matchesGlob && - this.fsw._isntIgnored(resolvedPath, stats) && - this.fsw._hasReadPermissions(stats); - } - - getDirParts(path) { - if (!this.hasGlob) return []; - const parts = []; - const expandedPath = path.includes(BRACE_START) ? braces.expand(path) : [path]; - expandedPath.forEach((path) => { - parts.push(sysPath.relative(this.watchPath, path).split(SLASH_OR_BACK_SLASH_RE)); - }); - return parts; - } - - filterDir(entry) { - if (this.hasGlob) { - const entryParts = this.getDirParts(this.checkGlobSymlink(entry)); - let globstar = false; - this.unmatchedGlob = !this.dirParts.some((parts) => { - return parts.every((part, i) => { - if (part === GLOBSTAR$1) globstar = true; - return globstar || !entryParts[0][i] || anymatch(part, entryParts[0][i], ANYMATCH_OPTS); - }); - }); - } - return !this.unmatchedGlob && this.fsw._isntIgnored(this.entryPath(entry), entry.stats); - } -} - -/** - * Watches files & directories for changes. Emitted events: - * `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error` - * - * new FSWatcher() - * .add(directories) - * .on('add', path => log('File', path, 'was added')) - */ -class FSWatcher extends EventEmitter { -// Not indenting methods for history sake; for now. -constructor(_opts) { - super(); - - const opts = {}; - if (_opts) Object.assign(opts, _opts); // for frozen objects - - /** @type {Map} */ - this._watched = new Map(); - /** @type {Map} */ - this._closers = new Map(); - /** @type {Set} */ - this._ignoredPaths = new Set(); - - /** @type {Map} */ - this._throttled = new Map(); - - /** @type {Map} */ - this._symlinkPaths = new Map(); - - this._streams = new Set(); - this.closed = false; - - // Set up default options. - if (undef(opts, 'persistent')) opts.persistent = true; - if (undef(opts, 'ignoreInitial')) opts.ignoreInitial = false; - if (undef(opts, 'ignorePermissionErrors')) opts.ignorePermissionErrors = false; - if (undef(opts, 'interval')) opts.interval = 100; - if (undef(opts, 'binaryInterval')) opts.binaryInterval = 300; - if (undef(opts, 'disableGlobbing')) opts.disableGlobbing = false; - opts.enableBinaryInterval = opts.binaryInterval !== opts.interval; - - // Enable fsevents on OS X when polling isn't explicitly enabled. - if (undef(opts, 'useFsEvents')) opts.useFsEvents = !opts.usePolling; - - // If we can't use fsevents, ensure the options reflect it's disabled. - const canUseFsEvents = FsEventsHandler.canUse(); - if (!canUseFsEvents) opts.useFsEvents = false; - - // Use polling on Mac if not using fsevents. - // Other platforms use non-polling fs_watch. - if (undef(opts, 'usePolling') && !opts.useFsEvents) { - opts.usePolling = isMacos; - } - - // Always default to polling on IBM i because fs.watch() is not available on IBM i. - if(isIBMi) { - opts.usePolling = true; - } - - // Global override (useful for end-developers that need to force polling for all - // instances of chokidar, regardless of usage/dependency depth) - const envPoll = process.env.CHOKIDAR_USEPOLLING; - if (envPoll !== undefined) { - const envLower = envPoll.toLowerCase(); - - if (envLower === 'false' || envLower === '0') { - opts.usePolling = false; - } else if (envLower === 'true' || envLower === '1') { - opts.usePolling = true; - } else { - opts.usePolling = !!envLower; - } - } - const envInterval = process.env.CHOKIDAR_INTERVAL; - if (envInterval) { - opts.interval = Number.parseInt(envInterval, 10); - } - - // Editor atomic write normalization enabled by default with fs.watch - if (undef(opts, 'atomic')) opts.atomic = !opts.usePolling && !opts.useFsEvents; - if (opts.atomic) this._pendingUnlinks = new Map(); - - if (undef(opts, 'followSymlinks')) opts.followSymlinks = true; - - if (undef(opts, 'awaitWriteFinish')) opts.awaitWriteFinish = false; - if (opts.awaitWriteFinish === true) opts.awaitWriteFinish = {}; - const awf = opts.awaitWriteFinish; - if (awf) { - if (!awf.stabilityThreshold) awf.stabilityThreshold = 2000; - if (!awf.pollInterval) awf.pollInterval = 100; - this._pendingWrites = new Map(); - } - if (opts.ignored) opts.ignored = arrify(opts.ignored); - - let readyCalls = 0; - this._emitReady = () => { - readyCalls++; - if (readyCalls >= this._readyCount) { - this._emitReady = EMPTY_FN; - this._readyEmitted = true; - // use process.nextTick to allow time for listener to be bound - process.nextTick(() => this.emit(EV_READY)); - } - }; - this._emitRaw = (...args) => this.emit(EV_RAW, ...args); - this._readyEmitted = false; - this.options = opts; - - // Initialize with proper watcher. - if (opts.useFsEvents) { - this._fsEventsHandler = new FsEventsHandler(this); - } else { - this._nodeFsHandler = new NodeFsHandler(this); - } - - // You’re frozen when your heart’s not open. - Object.freeze(opts); -} - -// Public methods - -/** - * Adds paths to be watched on an existing FSWatcher instance - * @param {Path|Array} paths_ - * @param {String=} _origAdd private; for handling non-existent paths to be watched - * @param {Boolean=} _internal private; indicates a non-user add - * @returns {FSWatcher} for chaining - */ -add(paths_, _origAdd, _internal) { - const {cwd, disableGlobbing} = this.options; - this.closed = false; - let paths = unifyPaths(paths_); - if (cwd) { - paths = paths.map((path) => { - const absPath = getAbsolutePath(path, cwd); - - // Check `path` instead of `absPath` because the cwd portion can't be a glob - if (disableGlobbing || !isGlob(path)) { - return absPath; - } - return normalizePath(absPath); - }); - } - - // set aside negated glob strings - paths = paths.filter((path) => { - if (path.startsWith(BANG)) { - this._ignoredPaths.add(path.slice(1)); - return false; - } - - // if a path is being added that was previously ignored, stop ignoring it - this._ignoredPaths.delete(path); - this._ignoredPaths.delete(path + SLASH_GLOBSTAR); - - // reset the cached userIgnored anymatch fn - // to make ignoredPaths changes effective - this._userIgnored = undefined; - - return true; - }); - - if (this.options.useFsEvents && this._fsEventsHandler) { - if (!this._readyCount) this._readyCount = paths.length; - if (this.options.persistent) this._readyCount *= 2; - paths.forEach((path) => this._fsEventsHandler._addToFsEvents(path)); - } else { - if (!this._readyCount) this._readyCount = 0; - this._readyCount += paths.length; - Promise.all( - paths.map(async path => { - const res = await this._nodeFsHandler._addToNodeFs(path, !_internal, 0, 0, _origAdd); - if (res) this._emitReady(); - return res; - }) - ).then(results => { - if (this.closed) return; - results.filter(item => item).forEach(item => { - this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item)); - }); - }); - } - - return this; -} - -/** - * Close watchers or start ignoring events from specified paths. - * @param {Path|Array} paths_ - string or array of strings, file/directory paths and/or globs - * @returns {FSWatcher} for chaining -*/ -unwatch(paths_) { - if (this.closed) return this; - const paths = unifyPaths(paths_); - const {cwd} = this.options; - - paths.forEach((path) => { - // convert to absolute path unless relative path already matches - if (!sysPath.isAbsolute(path) && !this._closers.has(path)) { - if (cwd) path = sysPath.join(cwd, path); - path = sysPath.resolve(path); - } - - this._closePath(path); - - this._ignoredPaths.add(path); - if (this._watched.has(path)) { - this._ignoredPaths.add(path + SLASH_GLOBSTAR); - } - - // reset the cached userIgnored anymatch fn - // to make ignoredPaths changes effective - this._userIgnored = undefined; - }); - - return this; -} - -/** - * Close watchers and remove all listeners from watched paths. - * @returns {Promise}. -*/ -close() { - if (this.closed) return this._closePromise; - this.closed = true; - - // Memory management. - this.removeAllListeners(); - const closers = []; - this._closers.forEach(closerList => closerList.forEach(closer => { - const promise = closer(); - if (promise instanceof Promise) closers.push(promise); - })); - this._streams.forEach(stream => stream.destroy()); - this._userIgnored = undefined; - this._readyCount = 0; - this._readyEmitted = false; - this._watched.forEach(dirent => dirent.dispose()); - ['closers', 'watched', 'streams', 'symlinkPaths', 'throttled'].forEach(key => { - this[`_${key}`].clear(); - }); - - this._closePromise = closers.length ? Promise.all(closers).then(() => undefined) : Promise.resolve(); - return this._closePromise; -} - -/** - * Expose list of watched paths - * @returns {Object} for chaining -*/ -getWatched() { - const watchList = {}; - this._watched.forEach((entry, dir) => { - const key = this.options.cwd ? sysPath.relative(this.options.cwd, dir) : dir; - watchList[key || ONE_DOT] = entry.getChildren().sort(); - }); - return watchList; -} - -emitWithAll(event, args) { - this.emit(...args); - if (event !== EV_ERROR) this.emit(EV_ALL, ...args); -} - -// Common helpers -// -------------- - -/** - * Normalize and emit events. - * Calling _emit DOES NOT MEAN emit() would be called! - * @param {EventName} event Type of event - * @param {Path} path File or directory path - * @param {*=} val1 arguments to be passed with event - * @param {*=} val2 - * @param {*=} val3 - * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag - */ -async _emit(event, path, val1, val2, val3) { - if (this.closed) return; - - const opts = this.options; - if (isWindows$2) path = sysPath.normalize(path); - if (opts.cwd) path = sysPath.relative(opts.cwd, path); - /** @type Array */ - const args = [event, path]; - if (val3 !== undefined) args.push(val1, val2, val3); - else if (val2 !== undefined) args.push(val1, val2); - else if (val1 !== undefined) args.push(val1); - - const awf = opts.awaitWriteFinish; - let pw; - if (awf && (pw = this._pendingWrites.get(path))) { - pw.lastChange = new Date(); - return this; - } - - if (opts.atomic) { - if (event === EV_UNLINK) { - this._pendingUnlinks.set(path, args); - setTimeout(() => { - this._pendingUnlinks.forEach((entry, path) => { - this.emit(...entry); - this.emit(EV_ALL, ...entry); - this._pendingUnlinks.delete(path); - }); - }, typeof opts.atomic === 'number' ? opts.atomic : 100); - return this; - } - if (event === EV_ADD && this._pendingUnlinks.has(path)) { - event = args[0] = EV_CHANGE; - this._pendingUnlinks.delete(path); - } - } - - if (awf && (event === EV_ADD || event === EV_CHANGE) && this._readyEmitted) { - const awfEmit = (err, stats) => { - if (err) { - event = args[0] = EV_ERROR; - args[1] = err; - this.emitWithAll(event, args); - } else if (stats) { - // if stats doesn't exist the file must have been deleted - if (args.length > 2) { - args[2] = stats; - } else { - args.push(stats); - } - this.emitWithAll(event, args); - } - }; - - this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit); - return this; - } - - if (event === EV_CHANGE) { - const isThrottled = !this._throttle(EV_CHANGE, path, 50); - if (isThrottled) return this; - } - - if (opts.alwaysStat && val1 === undefined && - (event === EV_ADD || event === EV_ADD_DIR || event === EV_CHANGE) - ) { - const fullPath = opts.cwd ? sysPath.join(opts.cwd, path) : path; - let stats; - try { - stats = await stat(fullPath); - } catch (err) {} - // Suppress event when fs_stat fails, to avoid sending undefined 'stat' - if (!stats || this.closed) return; - args.push(stats); - } - this.emitWithAll(event, args); - - return this; -} - -/** - * Common handler for errors - * @param {Error} error - * @returns {Error|Boolean} The error if defined, otherwise the value of the FSWatcher instance's `closed` flag - */ -_handleError(error) { - const code = error && error.code; - if (error && code !== 'ENOENT' && code !== 'ENOTDIR' && - (!this.options.ignorePermissionErrors || (code !== 'EPERM' && code !== 'EACCES')) - ) { - this.emit(EV_ERROR, error); - } - return error || this.closed; -} - -/** - * Helper utility for throttling - * @param {ThrottleType} actionType type being throttled - * @param {Path} path being acted upon - * @param {Number} timeout duration of time to suppress duplicate actions - * @returns {Object|false} tracking object or false if action should be suppressed - */ -_throttle(actionType, path, timeout) { - if (!this._throttled.has(actionType)) { - this._throttled.set(actionType, new Map()); - } - - /** @type {Map} */ - const action = this._throttled.get(actionType); - /** @type {Object} */ - const actionPath = action.get(path); - - if (actionPath) { - actionPath.count++; - return false; - } - - let timeoutObject; - const clear = () => { - const item = action.get(path); - const count = item ? item.count : 0; - action.delete(path); - clearTimeout(timeoutObject); - if (item) clearTimeout(item.timeoutObject); - return count; - }; - timeoutObject = setTimeout(clear, timeout); - const thr = {timeoutObject, clear, count: 0}; - action.set(path, thr); - return thr; -} - -_incrReadyCount() { - return this._readyCount++; -} - -/** - * Awaits write operation to finish. - * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback. - * @param {Path} path being acted upon - * @param {Number} threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished - * @param {EventName} event - * @param {Function} awfEmit Callback to be called when ready for event to be emitted. - */ -_awaitWriteFinish(path, threshold, event, awfEmit) { - let timeoutHandler; - - let fullPath = path; - if (this.options.cwd && !sysPath.isAbsolute(path)) { - fullPath = sysPath.join(this.options.cwd, path); - } - - const now = new Date(); - - const awaitWriteFinish = (prevStat) => { - fs$6.stat(fullPath, (err, curStat) => { - if (err || !this._pendingWrites.has(path)) { - if (err && err.code !== 'ENOENT') awfEmit(err); - return; - } - - const now = Number(new Date()); - - if (prevStat && curStat.size !== prevStat.size) { - this._pendingWrites.get(path).lastChange = now; - } - const pw = this._pendingWrites.get(path); - const df = now - pw.lastChange; - - if (df >= threshold) { - this._pendingWrites.delete(path); - awfEmit(undefined, curStat); - } else { - timeoutHandler = setTimeout( - awaitWriteFinish, - this.options.awaitWriteFinish.pollInterval, - curStat - ); - } - }); - }; - - if (!this._pendingWrites.has(path)) { - this._pendingWrites.set(path, { - lastChange: now, - cancelWait: () => { - this._pendingWrites.delete(path); - clearTimeout(timeoutHandler); - return event; - } - }); - timeoutHandler = setTimeout( - awaitWriteFinish, - this.options.awaitWriteFinish.pollInterval - ); - } -} - -_getGlobIgnored() { - return [...this._ignoredPaths.values()]; -} - -/** - * Determines whether user has asked to ignore this path. - * @param {Path} path filepath or dir - * @param {fs.Stats=} stats result of fs.stat - * @returns {Boolean} - */ -_isIgnored(path, stats) { - if (this.options.atomic && DOT_RE.test(path)) return true; - if (!this._userIgnored) { - const {cwd} = this.options; - const ign = this.options.ignored; - - const ignored = ign && ign.map(normalizeIgnored(cwd)); - const paths = arrify(ignored) - .filter((path) => typeof path === STRING_TYPE && !isGlob(path)) - .map((path) => path + SLASH_GLOBSTAR); - const list = this._getGlobIgnored().map(normalizeIgnored(cwd)).concat(ignored, paths); - this._userIgnored = anymatch(list, undefined, ANYMATCH_OPTS); - } - - return this._userIgnored([path, stats]); -} - -_isntIgnored(path, stat) { - return !this._isIgnored(path, stat); -} - -/** - * Provides a set of common helpers and properties relating to symlink and glob handling. - * @param {Path} path file, directory, or glob pattern being watched - * @param {Number=} depth at any depth > 0, this isn't a glob - * @returns {WatchHelper} object containing helpers for this path - */ -_getWatchHelpers(path, depth) { - const watchPath = depth || this.options.disableGlobbing || !isGlob(path) ? path : globParent(path); - const follow = this.options.followSymlinks; - - return new WatchHelper(path, watchPath, follow, this); -} - -// Directory helpers -// ----------------- - -/** - * Provides directory tracking objects - * @param {String} directory path of the directory - * @returns {DirEntry} the directory's tracking object - */ -_getWatchedDir(directory) { - if (!this._boundRemove) this._boundRemove = this._remove.bind(this); - const dir = sysPath.resolve(directory); - if (!this._watched.has(dir)) this._watched.set(dir, new DirEntry(dir, this._boundRemove)); - return this._watched.get(dir); -} - -// File helpers -// ------------ - -/** - * Check for read permissions. - * Based on this answer on SO: https://stackoverflow.com/a/11781404/1358405 - * @param {fs.Stats} stats - object, result of fs_stat - * @returns {Boolean} indicates whether the file can be read -*/ -_hasReadPermissions(stats) { - if (this.options.ignorePermissionErrors) return true; - - // stats.mode may be bigint - const md = stats && Number.parseInt(stats.mode, 10); - const st = md & 0o777; - const it = Number.parseInt(st.toString(8)[0], 10); - return Boolean(4 & it); -} - -/** - * Handles emitting unlink events for - * files and directories, and via recursion, for - * files and directories within directories that are unlinked - * @param {String} directory within which the following item is located - * @param {String} item base path of item/directory - * @returns {void} -*/ -_remove(directory, item, isDirectory) { - // if what is being deleted is a directory, get that directory's paths - // for recursive deleting and cleaning of watched object - // if it is not a directory, nestedDirectoryChildren will be empty array - const path = sysPath.join(directory, item); - const fullPath = sysPath.resolve(path); - isDirectory = isDirectory != null - ? isDirectory - : this._watched.has(path) || this._watched.has(fullPath); - - // prevent duplicate handling in case of arriving here nearly simultaneously - // via multiple paths (such as _handleFile and _handleDir) - if (!this._throttle('remove', path, 100)) return; - - // if the only watched file is removed, watch for its return - if (!isDirectory && !this.options.useFsEvents && this._watched.size === 1) { - this.add(directory, item, true); - } - - // This will create a new entry in the watched object in either case - // so we got to do the directory check beforehand - const wp = this._getWatchedDir(path); - const nestedDirectoryChildren = wp.getChildren(); - - // Recursively remove children directories / files. - nestedDirectoryChildren.forEach(nested => this._remove(path, nested)); - - // Check if item was on the watched list and remove it - const parent = this._getWatchedDir(directory); - const wasTracked = parent.has(item); - parent.remove(item); - - // Fixes issue #1042 -> Relative paths were detected and added as symlinks - // (https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L612), - // but never removed from the map in case the path was deleted. - // This leads to an incorrect state if the path was recreated: - // https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L553 - if (this._symlinkPaths.has(fullPath)) { - this._symlinkPaths.delete(fullPath); - } - - // If we wait for this file to be fully written, cancel the wait. - let relPath = path; - if (this.options.cwd) relPath = sysPath.relative(this.options.cwd, path); - if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) { - const event = this._pendingWrites.get(relPath).cancelWait(); - if (event === EV_ADD) return; - } - - // The Entry will either be a directory that just got removed - // or a bogus entry to a file, in either case we have to remove it - this._watched.delete(path); - this._watched.delete(fullPath); - const eventName = isDirectory ? EV_UNLINK_DIR : EV_UNLINK; - if (wasTracked && !this._isIgnored(path)) this._emit(eventName, path); - - // Avoid conflicts if we later create another file with the same name - if (!this.options.useFsEvents) { - this._closePath(path); - } -} - -/** - * Closes all watchers for a path - * @param {Path} path - */ -_closePath(path) { - this._closeFile(path); - const dir = sysPath.dirname(path); - this._getWatchedDir(dir).remove(sysPath.basename(path)); -} - -/** - * Closes only file-specific watchers - * @param {Path} path - */ -_closeFile(path) { - const closers = this._closers.get(path); - if (!closers) return; - closers.forEach(closer => closer()); - this._closers.delete(path); -} - -/** - * - * @param {Path} path - * @param {Function} closer - */ -_addPathCloser(path, closer) { - if (!closer) return; - let list = this._closers.get(path); - if (!list) { - list = []; - this._closers.set(path, list); - } - list.push(closer); -} - -_readdirp(root, opts) { - if (this.closed) return; - const options = {type: EV_ALL, alwaysStat: true, lstat: true, ...opts}; - let stream = readdirp(root, options); - this._streams.add(stream); - stream.once(STR_CLOSE, () => { - stream = undefined; - }); - stream.once(STR_END, () => { - if (stream) { - this._streams.delete(stream); - stream = undefined; - } - }); - return stream; -} - -} - -// Export FSWatcher class -chokidar.FSWatcher = FSWatcher; - -/** - * Instantiates watcher with paths to be tracked. - * @param {String|Array} paths file/directory paths and/or globs - * @param {Object=} options chokidar opts - * @returns an instance of FSWatcher for chaining. - */ -const watch = (paths, options) => { - const watcher = new FSWatcher(options); - watcher.add(paths); - return watcher; -}; - -chokidar.watch = watch; - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('vfile-message').VFileMessage} VFileMessage - * - * @typedef Statistics - * @property {number} fatal Fatal errors (`fatal: true`) - * @property {number} warn warning errors (`fatal: false`) - * @property {number} info informational messages (`fatal: null|undefined`) - * @property {number} nonfatal warning + info - * @property {number} total nonfatal + fatal - */ - -/** - * Get stats for a file, list of files, or list of messages. - * - * @param {Array.|VFile|VFileMessage} [value] - * @returns {Statistics} - */ -function statistics(value) { - var result = {true: 0, false: 0, null: 0}; - - if (value) { - if (Array.isArray(value)) { - list(value); - } else { - one(value); - } - } - - return { - fatal: result.true, - nonfatal: result.false + result.null, - warn: result.false, - info: result.null, - total: result.true + result.false + result.null - } - - /** - * @param {Array.} value - * @returns {void} - */ - function list(value) { - var index = -1; - - while (++index < value.length) { - one(value[index]); - } - } - - /** - * @param {VFile|VFileMessage} value - * @returns {void} - */ - function one(value) { - if ('messages' in value) return list(value.messages) - - result[ - value.fatal === undefined || value.fatal === null - ? null - : Boolean(value.fatal) - ]++; - } -} - -/** - * @typedef {(error?: Error|null|undefined, ...output: any[]) => void} Callback - * @typedef {(...input: any[]) => any} Middleware - * - * @typedef {(...input: any[]) => void} Run Call all middleware. - * @typedef {(fn: Middleware) => Pipeline} Use Add `fn` (middleware) to the list. - * @typedef {{run: Run, use: Use}} Pipeline - */ - -/** - * Create new middleware. - * - * @returns {Pipeline} - */ -function trough() { - /** @type {Middleware[]} */ - const fns = []; - /** @type {Pipeline} */ - const pipeline = {run, use}; - - return pipeline - - /** @type {Run} */ - function run(...values) { - let middlewareIndex = -1; - /** @type {Callback} */ - const callback = values.pop(); - - if (typeof callback !== 'function') { - throw new TypeError('Expected function as last argument, not ' + callback) - } - - next(null, ...values); - - /** - * Run the next `fn`, or we’re done. - * - * @param {Error|null|undefined} error - * @param {any[]} output - */ - function next(error, ...output) { - const fn = fns[++middlewareIndex]; - let index = -1; - - if (error) { - callback(error); - return - } - - // Copy non-nullish input into values. - while (++index < values.length) { - if (output[index] === null || output[index] === undefined) { - output[index] = values[index]; - } - } - - // Save the newly created `output` for the next call. - values = output; - - // Next or done. - if (fn) { - wrap(fn, next)(...output); - } else { - callback(null, ...output); - } - } - } - - /** @type {Use} */ - function use(middelware) { - if (typeof middelware !== 'function') { - throw new TypeError( - 'Expected `middelware` to be a function, not ' + middelware - ) - } - - fns.push(middelware); - return pipeline - } -} - -/** - * Wrap `middleware`. - * Can be sync or async; return a promise, receive a callback, or return new - * values and errors. - * - * @param {Middleware} middleware - * @param {Callback} callback - */ -function wrap(middleware, callback) { - /** @type {boolean} */ - let called; - - return wrapped - - /** - * Call `middleware`. - * @param {any[]} parameters - * @returns {void} - */ - function wrapped(...parameters) { - const fnExpectsCallback = middleware.length > parameters.length; - /** @type {any} */ - let result; - - if (fnExpectsCallback) { - parameters.push(done); - } - - try { - result = middleware(...parameters); - } catch (error) { - /** @type {Error} */ - const exception = error; - - // Well, this is quite the pickle. - // `middleware` received a callback and called it synchronously, but that - // threw an error. - // The only thing left to do is to throw the thing instead. - if (fnExpectsCallback && called) { - throw exception - } - - return done(exception) - } - - if (!fnExpectsCallback) { - if (result instanceof Promise) { - result.then(then, done); - } else if (result instanceof Error) { - done(result); - } else { - then(result); - } - } - } - - /** - * Call `callback`, only once. - * @type {Callback} - */ - function done(error, ...output) { - if (!called) { - called = true; - callback(error, ...output); - } - } - - /** - * Call `done` with one value. - * - * @param {any} [value] - */ - function then(value) { - done(null, value); - } -} - -/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */ -function isNothing(subject) { - return (typeof subject === 'undefined') || (subject === null); -} - - -function isObject$1(subject) { - return (typeof subject === 'object') && (subject !== null); -} - - -function toArray(sequence) { - if (Array.isArray(sequence)) return sequence; - else if (isNothing(sequence)) return []; - - return [ sequence ]; -} - - -function extend$2(target, source) { - var index, length, key, sourceKeys; - - if (source) { - sourceKeys = Object.keys(source); - - for (index = 0, length = sourceKeys.length; index < length; index += 1) { - key = sourceKeys[index]; - target[key] = source[key]; - } - } - - return target; -} - - -function repeat(string, count) { - var result = '', cycle; - - for (cycle = 0; cycle < count; cycle += 1) { - result += string; - } - - return result; -} - - -function isNegativeZero(number) { - return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number); -} - - -var isNothing_1 = isNothing; -var isObject_1 = isObject$1; -var toArray_1 = toArray; -var repeat_1 = repeat; -var isNegativeZero_1 = isNegativeZero; -var extend_1 = extend$2; - -var common$4 = { - isNothing: isNothing_1, - isObject: isObject_1, - toArray: toArray_1, - repeat: repeat_1, - isNegativeZero: isNegativeZero_1, - extend: extend_1 -}; - -// YAML error class. http://stackoverflow.com/questions/8458984 - - -function formatError(exception, compact) { - var where = '', message = exception.reason || '(unknown reason)'; - - if (!exception.mark) return message; - - if (exception.mark.name) { - where += 'in "' + exception.mark.name + '" '; - } - - where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')'; - - if (!compact && exception.mark.snippet) { - where += '\n\n' + exception.mark.snippet; - } - - return message + ' ' + where; -} - - -function YAMLException$1(reason, mark) { - // Super constructor - Error.call(this); - - this.name = 'YAMLException'; - this.reason = reason; - this.mark = mark; - this.message = formatError(this, false); - - // Include stack trace in error object - if (Error.captureStackTrace) { - // Chrome and NodeJS - Error.captureStackTrace(this, this.constructor); - } else { - // FF, IE 10+ and Safari 6+. Fallback for others - this.stack = (new Error()).stack || ''; - } -} - - -// Inherit from Error -YAMLException$1.prototype = Object.create(Error.prototype); -YAMLException$1.prototype.constructor = YAMLException$1; - - -YAMLException$1.prototype.toString = function toString(compact) { - return this.name + ': ' + formatError(this, compact); -}; - - -var exception = YAMLException$1; - -// get snippet for a single line, respecting maxLength -function getLine(buffer, lineStart, lineEnd, position, maxLineLength) { - var head = ''; - var tail = ''; - var maxHalfLength = Math.floor(maxLineLength / 2) - 1; - - if (position - lineStart > maxHalfLength) { - head = ' ... '; - lineStart = position - maxHalfLength + head.length; - } - - if (lineEnd - position > maxHalfLength) { - tail = ' ...'; - lineEnd = position + maxHalfLength - tail.length; - } - - return { - str: head + buffer.slice(lineStart, lineEnd).replace(/\t/g, '→') + tail, - pos: position - lineStart + head.length // relative position - }; -} - - -function padStart(string, max) { - return common$4.repeat(' ', max - string.length) + string; -} - - -function makeSnippet(mark, options) { - options = Object.create(options || null); - - if (!mark.buffer) return null; - - if (!options.maxLength) options.maxLength = 79; - if (typeof options.indent !== 'number') options.indent = 1; - if (typeof options.linesBefore !== 'number') options.linesBefore = 3; - if (typeof options.linesAfter !== 'number') options.linesAfter = 2; - - var re = /\r?\n|\r|\0/g; - var lineStarts = [ 0 ]; - var lineEnds = []; - var match; - var foundLineNo = -1; - - while ((match = re.exec(mark.buffer))) { - lineEnds.push(match.index); - lineStarts.push(match.index + match[0].length); - - if (mark.position <= match.index && foundLineNo < 0) { - foundLineNo = lineStarts.length - 2; - } - } - - if (foundLineNo < 0) foundLineNo = lineStarts.length - 1; - - var result = '', i, line; - var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length; - var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3); - - for (i = 1; i <= options.linesBefore; i++) { - if (foundLineNo - i < 0) break; - line = getLine( - mark.buffer, - lineStarts[foundLineNo - i], - lineEnds[foundLineNo - i], - mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]), - maxLineLength - ); - result = common$4.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) + - ' | ' + line.str + '\n' + result; - } - - line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength); - result += common$4.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) + - ' | ' + line.str + '\n'; - result += common$4.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\n'; - - for (i = 1; i <= options.linesAfter; i++) { - if (foundLineNo + i >= lineEnds.length) break; - line = getLine( - mark.buffer, - lineStarts[foundLineNo + i], - lineEnds[foundLineNo + i], - mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]), - maxLineLength - ); - result += common$4.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) + - ' | ' + line.str + '\n'; - } - - return result.replace(/\n$/, ''); -} - - -var snippet = makeSnippet; - -var TYPE_CONSTRUCTOR_OPTIONS = [ - 'kind', - 'multi', - 'resolve', - 'construct', - 'instanceOf', - 'predicate', - 'represent', - 'representName', - 'defaultStyle', - 'styleAliases' -]; - -var YAML_NODE_KINDS = [ - 'scalar', - 'sequence', - 'mapping' -]; - -function compileStyleAliases(map) { - var result = {}; - - if (map !== null) { - Object.keys(map).forEach(function (style) { - map[style].forEach(function (alias) { - result[String(alias)] = style; - }); - }); - } - - return result; -} - -function Type$1(tag, options) { - options = options || {}; - - Object.keys(options).forEach(function (name) { - if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) { - throw new exception('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.'); - } - }); - - // TODO: Add tag format check. - this.options = options; // keep original options in case user wants to extend this type later - this.tag = tag; - this.kind = options['kind'] || null; - this.resolve = options['resolve'] || function () { return true; }; - this.construct = options['construct'] || function (data) { return data; }; - this.instanceOf = options['instanceOf'] || null; - this.predicate = options['predicate'] || null; - this.represent = options['represent'] || null; - this.representName = options['representName'] || null; - this.defaultStyle = options['defaultStyle'] || null; - this.multi = options['multi'] || false; - this.styleAliases = compileStyleAliases(options['styleAliases'] || null); - - if (YAML_NODE_KINDS.indexOf(this.kind) === -1) { - throw new exception('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.'); - } -} - -var type$1 = Type$1; - -/*eslint-disable max-len*/ - - - - - -function compileList(schema, name) { - var result = []; - - schema[name].forEach(function (currentType) { - var newIndex = result.length; - - result.forEach(function (previousType, previousIndex) { - if (previousType.tag === currentType.tag && - previousType.kind === currentType.kind && - previousType.multi === currentType.multi) { - - newIndex = previousIndex; - } - }); - - result[newIndex] = currentType; - }); - - return result; -} - - -function compileMap(/* lists... */) { - var result = { - scalar: {}, - sequence: {}, - mapping: {}, - fallback: {}, - multi: { - scalar: [], - sequence: [], - mapping: [], - fallback: [] - } - }, index, length; - - function collectType(type) { - if (type.multi) { - result.multi[type.kind].push(type); - result.multi['fallback'].push(type); - } else { - result[type.kind][type.tag] = result['fallback'][type.tag] = type; - } - } - - for (index = 0, length = arguments.length; index < length; index += 1) { - arguments[index].forEach(collectType); - } - return result; -} - - -function Schema$1(definition) { - return this.extend(definition); -} - - -Schema$1.prototype.extend = function extend(definition) { - var implicit = []; - var explicit = []; - - if (definition instanceof type$1) { - // Schema.extend(type) - explicit.push(definition); - - } else if (Array.isArray(definition)) { - // Schema.extend([ type1, type2, ... ]) - explicit = explicit.concat(definition); - - } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) { - // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] }) - if (definition.implicit) implicit = implicit.concat(definition.implicit); - if (definition.explicit) explicit = explicit.concat(definition.explicit); - - } else { - throw new exception('Schema.extend argument should be a Type, [ Type ], ' + - 'or a schema definition ({ implicit: [...], explicit: [...] })'); - } - - implicit.forEach(function (type$1$1) { - if (!(type$1$1 instanceof type$1)) { - throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.'); - } - - if (type$1$1.loadKind && type$1$1.loadKind !== 'scalar') { - throw new exception('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.'); - } - - if (type$1$1.multi) { - throw new exception('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.'); - } - }); - - explicit.forEach(function (type$1$1) { - if (!(type$1$1 instanceof type$1)) { - throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.'); - } - }); - - var result = Object.create(Schema$1.prototype); - - result.implicit = (this.implicit || []).concat(implicit); - result.explicit = (this.explicit || []).concat(explicit); - - result.compiledImplicit = compileList(result, 'implicit'); - result.compiledExplicit = compileList(result, 'explicit'); - result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit); - - return result; -}; - - -var schema$1 = Schema$1; - -var str = new type$1('tag:yaml.org,2002:str', { - kind: 'scalar', - construct: function (data) { return data !== null ? data : ''; } -}); - -var seq = new type$1('tag:yaml.org,2002:seq', { - kind: 'sequence', - construct: function (data) { return data !== null ? data : []; } -}); - -var map$3 = new type$1('tag:yaml.org,2002:map', { - kind: 'mapping', - construct: function (data) { return data !== null ? data : {}; } -}); - -var failsafe = new schema$1({ - explicit: [ - str, - seq, - map$3 - ] -}); - -function resolveYamlNull(data) { - if (data === null) return true; - - var max = data.length; - - return (max === 1 && data === '~') || - (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL')); -} - -function constructYamlNull() { - return null; -} - -function isNull(object) { - return object === null; -} - -var _null = new type$1('tag:yaml.org,2002:null', { - kind: 'scalar', - resolve: resolveYamlNull, - construct: constructYamlNull, - predicate: isNull, - represent: { - canonical: function () { return '~'; }, - lowercase: function () { return 'null'; }, - uppercase: function () { return 'NULL'; }, - camelcase: function () { return 'Null'; }, - empty: function () { return ''; } - }, - defaultStyle: 'lowercase' -}); - -function resolveYamlBoolean(data) { - if (data === null) return false; - - var max = data.length; - - return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) || - (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE')); -} - -function constructYamlBoolean(data) { - return data === 'true' || - data === 'True' || - data === 'TRUE'; -} - -function isBoolean(object) { - return Object.prototype.toString.call(object) === '[object Boolean]'; -} - -var bool = new type$1('tag:yaml.org,2002:bool', { - kind: 'scalar', - resolve: resolveYamlBoolean, - construct: constructYamlBoolean, - predicate: isBoolean, - represent: { - lowercase: function (object) { return object ? 'true' : 'false'; }, - uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; }, - camelcase: function (object) { return object ? 'True' : 'False'; } - }, - defaultStyle: 'lowercase' -}); - -function isHexCode(c) { - return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) || - ((0x41/* A */ <= c) && (c <= 0x46/* F */)) || - ((0x61/* a */ <= c) && (c <= 0x66/* f */)); -} - -function isOctCode(c) { - return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */)); -} - -function isDecCode(c) { - return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)); -} - -function resolveYamlInteger(data) { - if (data === null) return false; - - var max = data.length, - index = 0, - hasDigits = false, - ch; - - if (!max) return false; - - ch = data[index]; - - // sign - if (ch === '-' || ch === '+') { - ch = data[++index]; - } - - if (ch === '0') { - // 0 - if (index + 1 === max) return true; - ch = data[++index]; - - // base 2, base 8, base 16 - - if (ch === 'b') { - // base 2 - index++; - - for (; index < max; index++) { - ch = data[index]; - if (ch === '_') continue; - if (ch !== '0' && ch !== '1') return false; - hasDigits = true; - } - return hasDigits && ch !== '_'; - } - - - if (ch === 'x') { - // base 16 - index++; - - for (; index < max; index++) { - ch = data[index]; - if (ch === '_') continue; - if (!isHexCode(data.charCodeAt(index))) return false; - hasDigits = true; - } - return hasDigits && ch !== '_'; - } - - - if (ch === 'o') { - // base 8 - index++; - - for (; index < max; index++) { - ch = data[index]; - if (ch === '_') continue; - if (!isOctCode(data.charCodeAt(index))) return false; - hasDigits = true; - } - return hasDigits && ch !== '_'; - } - } - - // base 10 (except 0) - - // value should not start with `_`; - if (ch === '_') return false; - - for (; index < max; index++) { - ch = data[index]; - if (ch === '_') continue; - if (!isDecCode(data.charCodeAt(index))) { - return false; - } - hasDigits = true; - } - - // Should have digits and should not end with `_` - if (!hasDigits || ch === '_') return false; - - return true; -} - -function constructYamlInteger(data) { - var value = data, sign = 1, ch; - - if (value.indexOf('_') !== -1) { - value = value.replace(/_/g, ''); - } - - ch = value[0]; - - if (ch === '-' || ch === '+') { - if (ch === '-') sign = -1; - value = value.slice(1); - ch = value[0]; - } - - if (value === '0') return 0; - - if (ch === '0') { - if (value[1] === 'b') return sign * parseInt(value.slice(2), 2); - if (value[1] === 'x') return sign * parseInt(value.slice(2), 16); - if (value[1] === 'o') return sign * parseInt(value.slice(2), 8); - } - - return sign * parseInt(value, 10); -} - -function isInteger(object) { - return (Object.prototype.toString.call(object)) === '[object Number]' && - (object % 1 === 0 && !common$4.isNegativeZero(object)); -} - -var int = new type$1('tag:yaml.org,2002:int', { - kind: 'scalar', - resolve: resolveYamlInteger, - construct: constructYamlInteger, - predicate: isInteger, - represent: { - binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); }, - octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1); }, - decimal: function (obj) { return obj.toString(10); }, - /* eslint-disable max-len */ - hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); } - }, - defaultStyle: 'decimal', - styleAliases: { - binary: [ 2, 'bin' ], - octal: [ 8, 'oct' ], - decimal: [ 10, 'dec' ], - hexadecimal: [ 16, 'hex' ] - } -}); - -var YAML_FLOAT_PATTERN = new RegExp( - // 2.5e4, 2.5 and integers - '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' + - // .2e4, .2 - // special case, seems not from spec - '|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' + - // .inf - '|[-+]?\\.(?:inf|Inf|INF)' + - // .nan - '|\\.(?:nan|NaN|NAN))$'); - -function resolveYamlFloat(data) { - if (data === null) return false; - - if (!YAML_FLOAT_PATTERN.test(data) || - // Quick hack to not allow integers end with `_` - // Probably should update regexp & check speed - data[data.length - 1] === '_') { - return false; - } - - return true; -} - -function constructYamlFloat(data) { - var value, sign; - - value = data.replace(/_/g, '').toLowerCase(); - sign = value[0] === '-' ? -1 : 1; - - if ('+-'.indexOf(value[0]) >= 0) { - value = value.slice(1); - } - - if (value === '.inf') { - return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; - - } else if (value === '.nan') { - return NaN; - } - return sign * parseFloat(value, 10); -} - - -var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/; - -function representYamlFloat(object, style) { - var res; - - if (isNaN(object)) { - switch (style) { - case 'lowercase': return '.nan'; - case 'uppercase': return '.NAN'; - case 'camelcase': return '.NaN'; - } - } else if (Number.POSITIVE_INFINITY === object) { - switch (style) { - case 'lowercase': return '.inf'; - case 'uppercase': return '.INF'; - case 'camelcase': return '.Inf'; - } - } else if (Number.NEGATIVE_INFINITY === object) { - switch (style) { - case 'lowercase': return '-.inf'; - case 'uppercase': return '-.INF'; - case 'camelcase': return '-.Inf'; - } - } else if (common$4.isNegativeZero(object)) { - return '-0.0'; - } - - res = object.toString(10); - - // JS stringifier can build scientific format without dots: 5e-100, - // while YAML requres dot: 5.e-100. Fix it with simple hack - - return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res; -} - -function isFloat(object) { - return (Object.prototype.toString.call(object) === '[object Number]') && - (object % 1 !== 0 || common$4.isNegativeZero(object)); -} - -var float = new type$1('tag:yaml.org,2002:float', { - kind: 'scalar', - resolve: resolveYamlFloat, - construct: constructYamlFloat, - predicate: isFloat, - represent: representYamlFloat, - defaultStyle: 'lowercase' -}); - -var json = failsafe.extend({ - implicit: [ - _null, - bool, - int, - float - ] -}); - -var core = json; - -var YAML_DATE_REGEXP = new RegExp( - '^([0-9][0-9][0-9][0-9])' + // [1] year - '-([0-9][0-9])' + // [2] month - '-([0-9][0-9])$'); // [3] day - -var YAML_TIMESTAMP_REGEXP = new RegExp( - '^([0-9][0-9][0-9][0-9])' + // [1] year - '-([0-9][0-9]?)' + // [2] month - '-([0-9][0-9]?)' + // [3] day - '(?:[Tt]|[ \\t]+)' + // ... - '([0-9][0-9]?)' + // [4] hour - ':([0-9][0-9])' + // [5] minute - ':([0-9][0-9])' + // [6] second - '(?:\\.([0-9]*))?' + // [7] fraction - '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour - '(?::([0-9][0-9]))?))?$'); // [11] tz_minute - -function resolveYamlTimestamp(data) { - if (data === null) return false; - if (YAML_DATE_REGEXP.exec(data) !== null) return true; - if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true; - return false; -} - -function constructYamlTimestamp(data) { - var match, year, month, day, hour, minute, second, fraction = 0, - delta = null, tz_hour, tz_minute, date; - - match = YAML_DATE_REGEXP.exec(data); - if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data); - - if (match === null) throw new Error('Date resolve error'); - - // match: [1] year [2] month [3] day - - year = +(match[1]); - month = +(match[2]) - 1; // JS month starts with 0 - day = +(match[3]); - - if (!match[4]) { // no hour - return new Date(Date.UTC(year, month, day)); - } - - // match: [4] hour [5] minute [6] second [7] fraction - - hour = +(match[4]); - minute = +(match[5]); - second = +(match[6]); - - if (match[7]) { - fraction = match[7].slice(0, 3); - while (fraction.length < 3) { // milli-seconds - fraction += '0'; - } - fraction = +fraction; - } - - // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute - - if (match[9]) { - tz_hour = +(match[10]); - tz_minute = +(match[11] || 0); - delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds - if (match[9] === '-') delta = -delta; - } - - date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction)); - - if (delta) date.setTime(date.getTime() - delta); - - return date; -} - -function representYamlTimestamp(object /*, style*/) { - return object.toISOString(); -} - -var timestamp = new type$1('tag:yaml.org,2002:timestamp', { - kind: 'scalar', - resolve: resolveYamlTimestamp, - construct: constructYamlTimestamp, - instanceOf: Date, - represent: representYamlTimestamp -}); - -function resolveYamlMerge(data) { - return data === '<<' || data === null; -} - -var merge$1 = new type$1('tag:yaml.org,2002:merge', { - kind: 'scalar', - resolve: resolveYamlMerge -}); - -/*eslint-disable no-bitwise*/ - - - - - -// [ 64, 65, 66 ] -> [ padding, CR, LF ] -var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r'; - - -function resolveYamlBinary(data) { - if (data === null) return false; - - var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP; - - // Convert one by one. - for (idx = 0; idx < max; idx++) { - code = map.indexOf(data.charAt(idx)); - - // Skip CR/LF - if (code > 64) continue; - - // Fail on illegal characters - if (code < 0) return false; - - bitlen += 6; - } - - // If there are any bits left, source was corrupted - return (bitlen % 8) === 0; -} - -function constructYamlBinary(data) { - var idx, tailbits, - input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan - max = input.length, - map = BASE64_MAP, - bits = 0, - result = []; - - // Collect by 6*4 bits (3 bytes) - - for (idx = 0; idx < max; idx++) { - if ((idx % 4 === 0) && idx) { - result.push((bits >> 16) & 0xFF); - result.push((bits >> 8) & 0xFF); - result.push(bits & 0xFF); - } - - bits = (bits << 6) | map.indexOf(input.charAt(idx)); - } - - // Dump tail - - tailbits = (max % 4) * 6; - - if (tailbits === 0) { - result.push((bits >> 16) & 0xFF); - result.push((bits >> 8) & 0xFF); - result.push(bits & 0xFF); - } else if (tailbits === 18) { - result.push((bits >> 10) & 0xFF); - result.push((bits >> 2) & 0xFF); - } else if (tailbits === 12) { - result.push((bits >> 4) & 0xFF); - } - - return new Uint8Array(result); -} - -function representYamlBinary(object /*, style*/) { - var result = '', bits = 0, idx, tail, - max = object.length, - map = BASE64_MAP; - - // Convert every three bytes to 4 ASCII characters. - - for (idx = 0; idx < max; idx++) { - if ((idx % 3 === 0) && idx) { - result += map[(bits >> 18) & 0x3F]; - result += map[(bits >> 12) & 0x3F]; - result += map[(bits >> 6) & 0x3F]; - result += map[bits & 0x3F]; - } - - bits = (bits << 8) + object[idx]; - } - - // Dump tail - - tail = max % 3; - - if (tail === 0) { - result += map[(bits >> 18) & 0x3F]; - result += map[(bits >> 12) & 0x3F]; - result += map[(bits >> 6) & 0x3F]; - result += map[bits & 0x3F]; - } else if (tail === 2) { - result += map[(bits >> 10) & 0x3F]; - result += map[(bits >> 4) & 0x3F]; - result += map[(bits << 2) & 0x3F]; - result += map[64]; - } else if (tail === 1) { - result += map[(bits >> 2) & 0x3F]; - result += map[(bits << 4) & 0x3F]; - result += map[64]; - result += map[64]; - } - - return result; -} - -function isBinary(obj) { - return Object.prototype.toString.call(obj) === '[object Uint8Array]'; -} - -var binary = new type$1('tag:yaml.org,2002:binary', { - kind: 'scalar', - resolve: resolveYamlBinary, - construct: constructYamlBinary, - predicate: isBinary, - represent: representYamlBinary -}); - -var _hasOwnProperty$3 = Object.prototype.hasOwnProperty; -var _toString$2 = Object.prototype.toString; - -function resolveYamlOmap(data) { - if (data === null) return true; - - var objectKeys = [], index, length, pair, pairKey, pairHasKey, - object = data; - - for (index = 0, length = object.length; index < length; index += 1) { - pair = object[index]; - pairHasKey = false; - - if (_toString$2.call(pair) !== '[object Object]') return false; - - for (pairKey in pair) { - if (_hasOwnProperty$3.call(pair, pairKey)) { - if (!pairHasKey) pairHasKey = true; - else return false; - } - } - - if (!pairHasKey) return false; - - if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey); - else return false; - } - - return true; -} - -function constructYamlOmap(data) { - return data !== null ? data : []; -} - -var omap = new type$1('tag:yaml.org,2002:omap', { - kind: 'sequence', - resolve: resolveYamlOmap, - construct: constructYamlOmap -}); - -var _toString$1 = Object.prototype.toString; - -function resolveYamlPairs(data) { - if (data === null) return true; - - var index, length, pair, keys, result, - object = data; - - result = new Array(object.length); - - for (index = 0, length = object.length; index < length; index += 1) { - pair = object[index]; - - if (_toString$1.call(pair) !== '[object Object]') return false; - - keys = Object.keys(pair); - - if (keys.length !== 1) return false; - - result[index] = [ keys[0], pair[keys[0]] ]; - } - - return true; -} - -function constructYamlPairs(data) { - if (data === null) return []; - - var index, length, pair, keys, result, - object = data; - - result = new Array(object.length); - - for (index = 0, length = object.length; index < length; index += 1) { - pair = object[index]; - - keys = Object.keys(pair); - - result[index] = [ keys[0], pair[keys[0]] ]; - } - - return result; -} - -var pairs = new type$1('tag:yaml.org,2002:pairs', { - kind: 'sequence', - resolve: resolveYamlPairs, - construct: constructYamlPairs -}); - -var _hasOwnProperty$2 = Object.prototype.hasOwnProperty; - -function resolveYamlSet(data) { - if (data === null) return true; - - var key, object = data; - - for (key in object) { - if (_hasOwnProperty$2.call(object, key)) { - if (object[key] !== null) return false; - } - } - - return true; -} - -function constructYamlSet(data) { - return data !== null ? data : {}; -} - -var set = new type$1('tag:yaml.org,2002:set', { - kind: 'mapping', - resolve: resolveYamlSet, - construct: constructYamlSet -}); - -var _default$1 = core.extend({ - implicit: [ - timestamp, - merge$1 - ], - explicit: [ - binary, - omap, - pairs, - set - ] -}); - -/*eslint-disable max-len,no-use-before-define*/ - - - - - - - -var _hasOwnProperty$1 = Object.prototype.hasOwnProperty; - - -var CONTEXT_FLOW_IN = 1; -var CONTEXT_FLOW_OUT = 2; -var CONTEXT_BLOCK_IN = 3; -var CONTEXT_BLOCK_OUT = 4; - - -var CHOMPING_CLIP = 1; -var CHOMPING_STRIP = 2; -var CHOMPING_KEEP = 3; - - -var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; -var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/; -var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/; -var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i; -var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; - - -function _class(obj) { return Object.prototype.toString.call(obj); } - -function is_EOL(c) { - return (c === 0x0A/* LF */) || (c === 0x0D/* CR */); -} - -function is_WHITE_SPACE(c) { - return (c === 0x09/* Tab */) || (c === 0x20/* Space */); -} - -function is_WS_OR_EOL(c) { - return (c === 0x09/* Tab */) || - (c === 0x20/* Space */) || - (c === 0x0A/* LF */) || - (c === 0x0D/* CR */); -} - -function is_FLOW_INDICATOR(c) { - return c === 0x2C/* , */ || - c === 0x5B/* [ */ || - c === 0x5D/* ] */ || - c === 0x7B/* { */ || - c === 0x7D/* } */; -} - -function fromHexCode(c) { - var lc; - - if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { - return c - 0x30; - } - - /*eslint-disable no-bitwise*/ - lc = c | 0x20; - - if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) { - return lc - 0x61 + 10; - } - - return -1; -} - -function escapedHexLen(c) { - if (c === 0x78/* x */) { return 2; } - if (c === 0x75/* u */) { return 4; } - if (c === 0x55/* U */) { return 8; } - return 0; -} - -function fromDecimalCode(c) { - if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { - return c - 0x30; - } - - return -1; -} - -function simpleEscapeSequence(c) { - /* eslint-disable indent */ - return (c === 0x30/* 0 */) ? '\x00' : - (c === 0x61/* a */) ? '\x07' : - (c === 0x62/* b */) ? '\x08' : - (c === 0x74/* t */) ? '\x09' : - (c === 0x09/* Tab */) ? '\x09' : - (c === 0x6E/* n */) ? '\x0A' : - (c === 0x76/* v */) ? '\x0B' : - (c === 0x66/* f */) ? '\x0C' : - (c === 0x72/* r */) ? '\x0D' : - (c === 0x65/* e */) ? '\x1B' : - (c === 0x20/* Space */) ? ' ' : - (c === 0x22/* " */) ? '\x22' : - (c === 0x2F/* / */) ? '/' : - (c === 0x5C/* \ */) ? '\x5C' : - (c === 0x4E/* N */) ? '\x85' : - (c === 0x5F/* _ */) ? '\xA0' : - (c === 0x4C/* L */) ? '\u2028' : - (c === 0x50/* P */) ? '\u2029' : ''; -} - -function charFromCodepoint(c) { - if (c <= 0xFFFF) { - return String.fromCharCode(c); - } - // Encode UTF-16 surrogate pair - // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF - return String.fromCharCode( - ((c - 0x010000) >> 10) + 0xD800, - ((c - 0x010000) & 0x03FF) + 0xDC00 - ); -} - -var simpleEscapeCheck = new Array(256); // integer, for fast access -var simpleEscapeMap = new Array(256); -for (var i = 0; i < 256; i++) { - simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0; - simpleEscapeMap[i] = simpleEscapeSequence(i); -} - - -function State$1(input, options) { - this.input = input; - - this.filename = options['filename'] || null; - this.schema = options['schema'] || _default$1; - this.onWarning = options['onWarning'] || null; - // (Hidden) Remove? makes the loader to expect YAML 1.1 documents - // if such documents have no explicit %YAML directive - this.legacy = options['legacy'] || false; - - this.json = options['json'] || false; - this.listener = options['listener'] || null; - - this.implicitTypes = this.schema.compiledImplicit; - this.typeMap = this.schema.compiledTypeMap; - - this.length = input.length; - this.position = 0; - this.line = 0; - this.lineStart = 0; - this.lineIndent = 0; - - // position of first leading tab in the current line, - // used to make sure there are no tabs in the indentation - this.firstTabInLine = -1; - - this.documents = []; - - /* - this.version; - this.checkLineBreaks; - this.tagMap; - this.anchorMap; - this.tag; - this.anchor; - this.kind; - this.result;*/ - -} - - -function generateError(state, message) { - var mark = { - name: state.filename, - buffer: state.input.slice(0, -1), // omit trailing \0 - position: state.position, - line: state.line, - column: state.position - state.lineStart - }; - - mark.snippet = snippet(mark); - - return new exception(message, mark); -} - -function throwError$1(state, message) { - throw generateError(state, message); -} - -function throwWarning(state, message) { - if (state.onWarning) { - state.onWarning.call(null, generateError(state, message)); - } -} - - -var directiveHandlers = { - - YAML: function handleYamlDirective(state, name, args) { - - var match, major, minor; - - if (state.version !== null) { - throwError$1(state, 'duplication of %YAML directive'); - } - - if (args.length !== 1) { - throwError$1(state, 'YAML directive accepts exactly one argument'); - } - - match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]); - - if (match === null) { - throwError$1(state, 'ill-formed argument of the YAML directive'); - } - - major = parseInt(match[1], 10); - minor = parseInt(match[2], 10); - - if (major !== 1) { - throwError$1(state, 'unacceptable YAML version of the document'); - } - - state.version = args[0]; - state.checkLineBreaks = (minor < 2); - - if (minor !== 1 && minor !== 2) { - throwWarning(state, 'unsupported YAML version of the document'); - } - }, - - TAG: function handleTagDirective(state, name, args) { - - var handle, prefix; - - if (args.length !== 2) { - throwError$1(state, 'TAG directive accepts exactly two arguments'); - } - - handle = args[0]; - prefix = args[1]; - - if (!PATTERN_TAG_HANDLE.test(handle)) { - throwError$1(state, 'ill-formed tag handle (first argument) of the TAG directive'); - } - - if (_hasOwnProperty$1.call(state.tagMap, handle)) { - throwError$1(state, 'there is a previously declared suffix for "' + handle + '" tag handle'); - } - - if (!PATTERN_TAG_URI.test(prefix)) { - throwError$1(state, 'ill-formed tag prefix (second argument) of the TAG directive'); - } - - try { - prefix = decodeURIComponent(prefix); - } catch (err) { - throwError$1(state, 'tag prefix is malformed: ' + prefix); - } - - state.tagMap[handle] = prefix; - } -}; - - -function captureSegment(state, start, end, checkJson) { - var _position, _length, _character, _result; - - if (start < end) { - _result = state.input.slice(start, end); - - if (checkJson) { - for (_position = 0, _length = _result.length; _position < _length; _position += 1) { - _character = _result.charCodeAt(_position); - if (!(_character === 0x09 || - (0x20 <= _character && _character <= 0x10FFFF))) { - throwError$1(state, 'expected valid JSON character'); - } - } - } else if (PATTERN_NON_PRINTABLE.test(_result)) { - throwError$1(state, 'the stream contains non-printable characters'); - } - - state.result += _result; - } -} - -function mergeMappings(state, destination, source, overridableKeys) { - var sourceKeys, key, index, quantity; - - if (!common$4.isObject(source)) { - throwError$1(state, 'cannot merge mappings; the provided source object is unacceptable'); - } - - sourceKeys = Object.keys(source); - - for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) { - key = sourceKeys[index]; - - if (!_hasOwnProperty$1.call(destination, key)) { - destination[key] = source[key]; - overridableKeys[key] = true; - } - } -} - -function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, - startLine, startLineStart, startPos) { - - var index, quantity; - - // The output is a plain object here, so keys can only be strings. - // We need to convert keyNode to a string, but doing so can hang the process - // (deeply nested arrays that explode exponentially using aliases). - if (Array.isArray(keyNode)) { - keyNode = Array.prototype.slice.call(keyNode); - - for (index = 0, quantity = keyNode.length; index < quantity; index += 1) { - if (Array.isArray(keyNode[index])) { - throwError$1(state, 'nested arrays are not supported inside keys'); - } - - if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') { - keyNode[index] = '[object Object]'; - } - } - } - - // Avoid code execution in load() via toString property - // (still use its own toString for arrays, timestamps, - // and whatever user schema extensions happen to have @@toStringTag) - if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') { - keyNode = '[object Object]'; - } - - - keyNode = String(keyNode); - - if (_result === null) { - _result = {}; - } - - if (keyTag === 'tag:yaml.org,2002:merge') { - if (Array.isArray(valueNode)) { - for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { - mergeMappings(state, _result, valueNode[index], overridableKeys); - } - } else { - mergeMappings(state, _result, valueNode, overridableKeys); - } - } else { - if (!state.json && - !_hasOwnProperty$1.call(overridableKeys, keyNode) && - _hasOwnProperty$1.call(_result, keyNode)) { - state.line = startLine || state.line; - state.lineStart = startLineStart || state.lineStart; - state.position = startPos || state.position; - throwError$1(state, 'duplicated mapping key'); - } - - // used for this specific key only because Object.defineProperty is slow - if (keyNode === '__proto__') { - Object.defineProperty(_result, keyNode, { - configurable: true, - enumerable: true, - writable: true, - value: valueNode - }); - } else { - _result[keyNode] = valueNode; - } - delete overridableKeys[keyNode]; - } - - return _result; -} - -function readLineBreak(state) { - var ch; - - ch = state.input.charCodeAt(state.position); - - if (ch === 0x0A/* LF */) { - state.position++; - } else if (ch === 0x0D/* CR */) { - state.position++; - if (state.input.charCodeAt(state.position) === 0x0A/* LF */) { - state.position++; - } - } else { - throwError$1(state, 'a line break is expected'); - } - - state.line += 1; - state.lineStart = state.position; - state.firstTabInLine = -1; -} - -function skipSeparationSpace(state, allowComments, checkIndent) { - var lineBreaks = 0, - ch = state.input.charCodeAt(state.position); - - while (ch !== 0) { - while (is_WHITE_SPACE(ch)) { - if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) { - state.firstTabInLine = state.position; - } - ch = state.input.charCodeAt(++state.position); - } - - if (allowComments && ch === 0x23/* # */) { - do { - ch = state.input.charCodeAt(++state.position); - } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0); - } - - if (is_EOL(ch)) { - readLineBreak(state); - - ch = state.input.charCodeAt(state.position); - lineBreaks++; - state.lineIndent = 0; - - while (ch === 0x20/* Space */) { - state.lineIndent++; - ch = state.input.charCodeAt(++state.position); - } - } else { - break; - } - } - - if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) { - throwWarning(state, 'deficient indentation'); - } - - return lineBreaks; -} - -function testDocumentSeparator(state) { - var _position = state.position, - ch; - - ch = state.input.charCodeAt(_position); - - // Condition state.position === state.lineStart is tested - // in parent on each call, for efficiency. No needs to test here again. - if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) && - ch === state.input.charCodeAt(_position + 1) && - ch === state.input.charCodeAt(_position + 2)) { - - _position += 3; - - ch = state.input.charCodeAt(_position); - - if (ch === 0 || is_WS_OR_EOL(ch)) { - return true; - } - } - - return false; -} - -function writeFoldedLines(state, count) { - if (count === 1) { - state.result += ' '; - } else if (count > 1) { - state.result += common$4.repeat('\n', count - 1); - } -} - - -function readPlainScalar(state, nodeIndent, withinFlowCollection) { - var preceding, - following, - captureStart, - captureEnd, - hasPendingContent, - _line, - _lineStart, - _lineIndent, - _kind = state.kind, - _result = state.result, - ch; - - ch = state.input.charCodeAt(state.position); - - if (is_WS_OR_EOL(ch) || - is_FLOW_INDICATOR(ch) || - ch === 0x23/* # */ || - ch === 0x26/* & */ || - ch === 0x2A/* * */ || - ch === 0x21/* ! */ || - ch === 0x7C/* | */ || - ch === 0x3E/* > */ || - ch === 0x27/* ' */ || - ch === 0x22/* " */ || - ch === 0x25/* % */ || - ch === 0x40/* @ */ || - ch === 0x60/* ` */) { - return false; - } - - if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) { - following = state.input.charCodeAt(state.position + 1); - - if (is_WS_OR_EOL(following) || - withinFlowCollection && is_FLOW_INDICATOR(following)) { - return false; - } - } - - state.kind = 'scalar'; - state.result = ''; - captureStart = captureEnd = state.position; - hasPendingContent = false; - - while (ch !== 0) { - if (ch === 0x3A/* : */) { - following = state.input.charCodeAt(state.position + 1); - - if (is_WS_OR_EOL(following) || - withinFlowCollection && is_FLOW_INDICATOR(following)) { - break; - } - - } else if (ch === 0x23/* # */) { - preceding = state.input.charCodeAt(state.position - 1); - - if (is_WS_OR_EOL(preceding)) { - break; - } - - } else if ((state.position === state.lineStart && testDocumentSeparator(state)) || - withinFlowCollection && is_FLOW_INDICATOR(ch)) { - break; - - } else if (is_EOL(ch)) { - _line = state.line; - _lineStart = state.lineStart; - _lineIndent = state.lineIndent; - skipSeparationSpace(state, false, -1); - - if (state.lineIndent >= nodeIndent) { - hasPendingContent = true; - ch = state.input.charCodeAt(state.position); - continue; - } else { - state.position = captureEnd; - state.line = _line; - state.lineStart = _lineStart; - state.lineIndent = _lineIndent; - break; - } - } - - if (hasPendingContent) { - captureSegment(state, captureStart, captureEnd, false); - writeFoldedLines(state, state.line - _line); - captureStart = captureEnd = state.position; - hasPendingContent = false; - } - - if (!is_WHITE_SPACE(ch)) { - captureEnd = state.position + 1; - } - - ch = state.input.charCodeAt(++state.position); - } - - captureSegment(state, captureStart, captureEnd, false); - - if (state.result) { - return true; - } - - state.kind = _kind; - state.result = _result; - return false; -} - -function readSingleQuotedScalar(state, nodeIndent) { - var ch, - captureStart, captureEnd; - - ch = state.input.charCodeAt(state.position); - - if (ch !== 0x27/* ' */) { - return false; - } - - state.kind = 'scalar'; - state.result = ''; - state.position++; - captureStart = captureEnd = state.position; - - while ((ch = state.input.charCodeAt(state.position)) !== 0) { - if (ch === 0x27/* ' */) { - captureSegment(state, captureStart, state.position, true); - ch = state.input.charCodeAt(++state.position); - - if (ch === 0x27/* ' */) { - captureStart = state.position; - state.position++; - captureEnd = state.position; - } else { - return true; - } - - } else if (is_EOL(ch)) { - captureSegment(state, captureStart, captureEnd, true); - writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); - captureStart = captureEnd = state.position; - - } else if (state.position === state.lineStart && testDocumentSeparator(state)) { - throwError$1(state, 'unexpected end of the document within a single quoted scalar'); - - } else { - state.position++; - captureEnd = state.position; - } - } - - throwError$1(state, 'unexpected end of the stream within a single quoted scalar'); -} - -function readDoubleQuotedScalar(state, nodeIndent) { - var captureStart, - captureEnd, - hexLength, - hexResult, - tmp, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch !== 0x22/* " */) { - return false; - } - - state.kind = 'scalar'; - state.result = ''; - state.position++; - captureStart = captureEnd = state.position; - - while ((ch = state.input.charCodeAt(state.position)) !== 0) { - if (ch === 0x22/* " */) { - captureSegment(state, captureStart, state.position, true); - state.position++; - return true; - - } else if (ch === 0x5C/* \ */) { - captureSegment(state, captureStart, state.position, true); - ch = state.input.charCodeAt(++state.position); - - if (is_EOL(ch)) { - skipSeparationSpace(state, false, nodeIndent); - - // TODO: rework to inline fn with no type cast? - } else if (ch < 256 && simpleEscapeCheck[ch]) { - state.result += simpleEscapeMap[ch]; - state.position++; - - } else if ((tmp = escapedHexLen(ch)) > 0) { - hexLength = tmp; - hexResult = 0; - - for (; hexLength > 0; hexLength--) { - ch = state.input.charCodeAt(++state.position); - - if ((tmp = fromHexCode(ch)) >= 0) { - hexResult = (hexResult << 4) + tmp; - - } else { - throwError$1(state, 'expected hexadecimal character'); - } - } - - state.result += charFromCodepoint(hexResult); - - state.position++; - - } else { - throwError$1(state, 'unknown escape sequence'); - } - - captureStart = captureEnd = state.position; - - } else if (is_EOL(ch)) { - captureSegment(state, captureStart, captureEnd, true); - writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); - captureStart = captureEnd = state.position; - - } else if (state.position === state.lineStart && testDocumentSeparator(state)) { - throwError$1(state, 'unexpected end of the document within a double quoted scalar'); - - } else { - state.position++; - captureEnd = state.position; - } - } - - throwError$1(state, 'unexpected end of the stream within a double quoted scalar'); -} - -function readFlowCollection(state, nodeIndent) { - var readNext = true, - _line, - _lineStart, - _pos, - _tag = state.tag, - _result, - _anchor = state.anchor, - following, - terminator, - isPair, - isExplicitPair, - isMapping, - overridableKeys = Object.create(null), - keyNode, - keyTag, - valueNode, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch === 0x5B/* [ */) { - terminator = 0x5D;/* ] */ - isMapping = false; - _result = []; - } else if (ch === 0x7B/* { */) { - terminator = 0x7D;/* } */ - isMapping = true; - _result = {}; - } else { - return false; - } - - if (state.anchor !== null) { - state.anchorMap[state.anchor] = _result; - } - - ch = state.input.charCodeAt(++state.position); - - while (ch !== 0) { - skipSeparationSpace(state, true, nodeIndent); - - ch = state.input.charCodeAt(state.position); - - if (ch === terminator) { - state.position++; - state.tag = _tag; - state.anchor = _anchor; - state.kind = isMapping ? 'mapping' : 'sequence'; - state.result = _result; - return true; - } else if (!readNext) { - throwError$1(state, 'missed comma between flow collection entries'); - } else if (ch === 0x2C/* , */) { - // "flow collection entries can never be completely empty", as per YAML 1.2, section 7.4 - throwError$1(state, "expected the node content, but found ','"); - } - - keyTag = keyNode = valueNode = null; - isPair = isExplicitPair = false; - - if (ch === 0x3F/* ? */) { - following = state.input.charCodeAt(state.position + 1); - - if (is_WS_OR_EOL(following)) { - isPair = isExplicitPair = true; - state.position++; - skipSeparationSpace(state, true, nodeIndent); - } - } - - _line = state.line; // Save the current line. - _lineStart = state.lineStart; - _pos = state.position; - composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); - keyTag = state.tag; - keyNode = state.result; - skipSeparationSpace(state, true, nodeIndent); - - ch = state.input.charCodeAt(state.position); - - if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) { - isPair = true; - ch = state.input.charCodeAt(++state.position); - skipSeparationSpace(state, true, nodeIndent); - composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); - valueNode = state.result; - } - - if (isMapping) { - storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos); - } else if (isPair) { - _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos)); - } else { - _result.push(keyNode); - } - - skipSeparationSpace(state, true, nodeIndent); - - ch = state.input.charCodeAt(state.position); - - if (ch === 0x2C/* , */) { - readNext = true; - ch = state.input.charCodeAt(++state.position); - } else { - readNext = false; - } - } - - throwError$1(state, 'unexpected end of the stream within a flow collection'); -} - -function readBlockScalar(state, nodeIndent) { - var captureStart, - folding, - chomping = CHOMPING_CLIP, - didReadContent = false, - detectedIndent = false, - textIndent = nodeIndent, - emptyLines = 0, - atMoreIndented = false, - tmp, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch === 0x7C/* | */) { - folding = false; - } else if (ch === 0x3E/* > */) { - folding = true; - } else { - return false; - } - - state.kind = 'scalar'; - state.result = ''; - - while (ch !== 0) { - ch = state.input.charCodeAt(++state.position); - - if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { - if (CHOMPING_CLIP === chomping) { - chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP; - } else { - throwError$1(state, 'repeat of a chomping mode identifier'); - } - - } else if ((tmp = fromDecimalCode(ch)) >= 0) { - if (tmp === 0) { - throwError$1(state, 'bad explicit indentation width of a block scalar; it cannot be less than one'); - } else if (!detectedIndent) { - textIndent = nodeIndent + tmp - 1; - detectedIndent = true; - } else { - throwError$1(state, 'repeat of an indentation width identifier'); - } - - } else { - break; - } - } - - if (is_WHITE_SPACE(ch)) { - do { ch = state.input.charCodeAt(++state.position); } - while (is_WHITE_SPACE(ch)); - - if (ch === 0x23/* # */) { - do { ch = state.input.charCodeAt(++state.position); } - while (!is_EOL(ch) && (ch !== 0)); - } - } - - while (ch !== 0) { - readLineBreak(state); - state.lineIndent = 0; - - ch = state.input.charCodeAt(state.position); - - while ((!detectedIndent || state.lineIndent < textIndent) && - (ch === 0x20/* Space */)) { - state.lineIndent++; - ch = state.input.charCodeAt(++state.position); - } - - if (!detectedIndent && state.lineIndent > textIndent) { - textIndent = state.lineIndent; - } - - if (is_EOL(ch)) { - emptyLines++; - continue; - } - - // End of the scalar. - if (state.lineIndent < textIndent) { - - // Perform the chomping. - if (chomping === CHOMPING_KEEP) { - state.result += common$4.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); - } else if (chomping === CHOMPING_CLIP) { - if (didReadContent) { // i.e. only if the scalar is not empty. - state.result += '\n'; - } - } - - // Break this `while` cycle and go to the funciton's epilogue. - break; - } - - // Folded style: use fancy rules to handle line breaks. - if (folding) { - - // Lines starting with white space characters (more-indented lines) are not folded. - if (is_WHITE_SPACE(ch)) { - atMoreIndented = true; - // except for the first content line (cf. Example 8.1) - state.result += common$4.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); - - // End of more-indented block. - } else if (atMoreIndented) { - atMoreIndented = false; - state.result += common$4.repeat('\n', emptyLines + 1); - - // Just one line break - perceive as the same line. - } else if (emptyLines === 0) { - if (didReadContent) { // i.e. only if we have already read some scalar content. - state.result += ' '; - } - - // Several line breaks - perceive as different lines. - } else { - state.result += common$4.repeat('\n', emptyLines); - } - - // Literal style: just add exact number of line breaks between content lines. - } else { - // Keep all line breaks except the header line break. - state.result += common$4.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); - } - - didReadContent = true; - detectedIndent = true; - emptyLines = 0; - captureStart = state.position; - - while (!is_EOL(ch) && (ch !== 0)) { - ch = state.input.charCodeAt(++state.position); - } - - captureSegment(state, captureStart, state.position, false); - } - - return true; -} - -function readBlockSequence(state, nodeIndent) { - var _line, - _tag = state.tag, - _anchor = state.anchor, - _result = [], - following, - detected = false, - ch; - - // there is a leading tab before this token, so it can't be a block sequence/mapping; - // it can still be flow sequence/mapping or a scalar - if (state.firstTabInLine !== -1) return false; - - if (state.anchor !== null) { - state.anchorMap[state.anchor] = _result; - } - - ch = state.input.charCodeAt(state.position); - - while (ch !== 0) { - if (state.firstTabInLine !== -1) { - state.position = state.firstTabInLine; - throwError$1(state, 'tab characters must not be used in indentation'); - } - - if (ch !== 0x2D/* - */) { - break; - } - - following = state.input.charCodeAt(state.position + 1); - - if (!is_WS_OR_EOL(following)) { - break; - } - - detected = true; - state.position++; - - if (skipSeparationSpace(state, true, -1)) { - if (state.lineIndent <= nodeIndent) { - _result.push(null); - ch = state.input.charCodeAt(state.position); - continue; - } - } - - _line = state.line; - composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true); - _result.push(state.result); - skipSeparationSpace(state, true, -1); - - ch = state.input.charCodeAt(state.position); - - if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { - throwError$1(state, 'bad indentation of a sequence entry'); - } else if (state.lineIndent < nodeIndent) { - break; - } - } - - if (detected) { - state.tag = _tag; - state.anchor = _anchor; - state.kind = 'sequence'; - state.result = _result; - return true; - } - return false; -} - -function readBlockMapping(state, nodeIndent, flowIndent) { - var following, - allowCompact, - _line, - _keyLine, - _keyLineStart, - _keyPos, - _tag = state.tag, - _anchor = state.anchor, - _result = {}, - overridableKeys = Object.create(null), - keyTag = null, - keyNode = null, - valueNode = null, - atExplicitKey = false, - detected = false, - ch; - - // there is a leading tab before this token, so it can't be a block sequence/mapping; - // it can still be flow sequence/mapping or a scalar - if (state.firstTabInLine !== -1) return false; - - if (state.anchor !== null) { - state.anchorMap[state.anchor] = _result; - } - - ch = state.input.charCodeAt(state.position); - - while (ch !== 0) { - if (!atExplicitKey && state.firstTabInLine !== -1) { - state.position = state.firstTabInLine; - throwError$1(state, 'tab characters must not be used in indentation'); - } - - following = state.input.charCodeAt(state.position + 1); - _line = state.line; // Save the current line. - - // - // Explicit notation case. There are two separate blocks: - // first for the key (denoted by "?") and second for the value (denoted by ":") - // - if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) { - - if (ch === 0x3F/* ? */) { - if (atExplicitKey) { - storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); - keyTag = keyNode = valueNode = null; - } - - detected = true; - atExplicitKey = true; - allowCompact = true; - - } else if (atExplicitKey) { - // i.e. 0x3A/* : */ === character after the explicit key. - atExplicitKey = false; - allowCompact = true; - - } else { - throwError$1(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line'); - } - - state.position += 1; - ch = following; - - // - // Implicit notation case. Flow-style node as the key first, then ":", and the value. - // - } else { - _keyLine = state.line; - _keyLineStart = state.lineStart; - _keyPos = state.position; - - if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) { - // Neither implicit nor explicit notation. - // Reading is done. Go to the epilogue. - break; - } - - if (state.line === _line) { - ch = state.input.charCodeAt(state.position); - - while (is_WHITE_SPACE(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - if (ch === 0x3A/* : */) { - ch = state.input.charCodeAt(++state.position); - - if (!is_WS_OR_EOL(ch)) { - throwError$1(state, 'a whitespace character is expected after the key-value separator within a block mapping'); - } - - if (atExplicitKey) { - storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); - keyTag = keyNode = valueNode = null; - } - - detected = true; - atExplicitKey = false; - allowCompact = false; - keyTag = state.tag; - keyNode = state.result; - - } else if (detected) { - throwError$1(state, 'can not read an implicit mapping pair; a colon is missed'); - - } else { - state.tag = _tag; - state.anchor = _anchor; - return true; // Keep the result of `composeNode`. - } - - } else if (detected) { - throwError$1(state, 'can not read a block mapping entry; a multiline key may not be an implicit key'); - - } else { - state.tag = _tag; - state.anchor = _anchor; - return true; // Keep the result of `composeNode`. - } - } - - // - // Common reading code for both explicit and implicit notations. - // - if (state.line === _line || state.lineIndent > nodeIndent) { - if (atExplicitKey) { - _keyLine = state.line; - _keyLineStart = state.lineStart; - _keyPos = state.position; - } - - if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) { - if (atExplicitKey) { - keyNode = state.result; - } else { - valueNode = state.result; - } - } - - if (!atExplicitKey) { - storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos); - keyTag = keyNode = valueNode = null; - } - - skipSeparationSpace(state, true, -1); - ch = state.input.charCodeAt(state.position); - } - - if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { - throwError$1(state, 'bad indentation of a mapping entry'); - } else if (state.lineIndent < nodeIndent) { - break; - } - } - - // - // Epilogue. - // - - // Special case: last mapping's node contains only the key in explicit notation. - if (atExplicitKey) { - storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); - } - - // Expose the resulting mapping. - if (detected) { - state.tag = _tag; - state.anchor = _anchor; - state.kind = 'mapping'; - state.result = _result; - } - - return detected; -} - -function readTagProperty(state) { - var _position, - isVerbatim = false, - isNamed = false, - tagHandle, - tagName, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch !== 0x21/* ! */) return false; - - if (state.tag !== null) { - throwError$1(state, 'duplication of a tag property'); - } - - ch = state.input.charCodeAt(++state.position); - - if (ch === 0x3C/* < */) { - isVerbatim = true; - ch = state.input.charCodeAt(++state.position); - - } else if (ch === 0x21/* ! */) { - isNamed = true; - tagHandle = '!!'; - ch = state.input.charCodeAt(++state.position); - - } else { - tagHandle = '!'; - } - - _position = state.position; - - if (isVerbatim) { - do { ch = state.input.charCodeAt(++state.position); } - while (ch !== 0 && ch !== 0x3E/* > */); - - if (state.position < state.length) { - tagName = state.input.slice(_position, state.position); - ch = state.input.charCodeAt(++state.position); - } else { - throwError$1(state, 'unexpected end of the stream within a verbatim tag'); - } - } else { - while (ch !== 0 && !is_WS_OR_EOL(ch)) { - - if (ch === 0x21/* ! */) { - if (!isNamed) { - tagHandle = state.input.slice(_position - 1, state.position + 1); - - if (!PATTERN_TAG_HANDLE.test(tagHandle)) { - throwError$1(state, 'named tag handle cannot contain such characters'); - } - - isNamed = true; - _position = state.position + 1; - } else { - throwError$1(state, 'tag suffix cannot contain exclamation marks'); - } - } - - ch = state.input.charCodeAt(++state.position); - } - - tagName = state.input.slice(_position, state.position); - - if (PATTERN_FLOW_INDICATORS.test(tagName)) { - throwError$1(state, 'tag suffix cannot contain flow indicator characters'); - } - } - - if (tagName && !PATTERN_TAG_URI.test(tagName)) { - throwError$1(state, 'tag name cannot contain such characters: ' + tagName); - } - - try { - tagName = decodeURIComponent(tagName); - } catch (err) { - throwError$1(state, 'tag name is malformed: ' + tagName); - } - - if (isVerbatim) { - state.tag = tagName; - - } else if (_hasOwnProperty$1.call(state.tagMap, tagHandle)) { - state.tag = state.tagMap[tagHandle] + tagName; - - } else if (tagHandle === '!') { - state.tag = '!' + tagName; - - } else if (tagHandle === '!!') { - state.tag = 'tag:yaml.org,2002:' + tagName; - - } else { - throwError$1(state, 'undeclared tag handle "' + tagHandle + '"'); - } - - return true; -} - -function readAnchorProperty(state) { - var _position, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch !== 0x26/* & */) return false; - - if (state.anchor !== null) { - throwError$1(state, 'duplication of an anchor property'); - } - - ch = state.input.charCodeAt(++state.position); - _position = state.position; - - while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - if (state.position === _position) { - throwError$1(state, 'name of an anchor node must contain at least one character'); - } - - state.anchor = state.input.slice(_position, state.position); - return true; -} - -function readAlias(state) { - var _position, alias, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch !== 0x2A/* * */) return false; - - ch = state.input.charCodeAt(++state.position); - _position = state.position; - - while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - if (state.position === _position) { - throwError$1(state, 'name of an alias node must contain at least one character'); - } - - alias = state.input.slice(_position, state.position); - - if (!_hasOwnProperty$1.call(state.anchorMap, alias)) { - throwError$1(state, 'unidentified alias "' + alias + '"'); - } - - state.result = state.anchorMap[alias]; - skipSeparationSpace(state, true, -1); - return true; -} - -function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) { - var allowBlockStyles, - allowBlockScalars, - allowBlockCollections, - indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) { - indentStatus = 1; - } else if (state.lineIndent === parentIndent) { - indentStatus = 0; - } else if (state.lineIndent < parentIndent) { - indentStatus = -1; - } - } - } - - if (indentStatus === 1) { - while (readTagProperty(state) || readAnchorProperty(state)) { - if (skipSeparationSpace(state, true, -1)) { - atNewLine = true; - allowBlockCollections = allowBlockStyles; - - if (state.lineIndent > parentIndent) { - indentStatus = 1; - } else if (state.lineIndent === parentIndent) { - indentStatus = 0; - } else if (state.lineIndent < parentIndent) { - indentStatus = -1; - } - } else { - allowBlockCollections = false; - } - } - } - - if (allowBlockCollections) { - allowBlockCollections = atNewLine || allowCompact; - } - - if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) { - if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) { - flowIndent = parentIndent; - } else { - flowIndent = parentIndent + 1; - } - - blockIndent = state.position - state.lineStart; - - if (indentStatus === 1) { - if (allowBlockCollections && - (readBlockSequence(state, blockIndent) || - readBlockMapping(state, blockIndent, flowIndent)) || - readFlowCollection(state, flowIndent)) { - hasContent = true; - } else { - if ((allowBlockScalars && readBlockScalar(state, flowIndent)) || - readSingleQuotedScalar(state, flowIndent) || - readDoubleQuotedScalar(state, flowIndent)) { - hasContent = true; - - } else if (readAlias(state)) { - hasContent = true; - - if (state.tag !== null || state.anchor !== null) { - throwError$1(state, 'alias node should not have any properties'); - } - - } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) { - hasContent = true; - - if (state.tag === null) { - state.tag = '?'; - } - } - - if (state.anchor !== null) { - state.anchorMap[state.anchor] = state.result; - } - } - } else if (indentStatus === 0) { - // Special case: block sequences are allowed to have same indentation level as the parent. - // http://www.yaml.org/spec/1.2/spec.html#id2799784 - hasContent = allowBlockCollections && readBlockSequence(state, blockIndent); - } - } - - if (state.tag === null) { - if (state.anchor !== null) { - state.anchorMap[state.anchor] = state.result; - } - - } else if (state.tag === '?') { - // Implicit resolving is not allowed for non-scalar types, and '?' - // non-specific tag is only automatically assigned to plain scalars. - // - // We only need to check kind conformity in case user explicitly assigns '?' - // tag, for example like this: "! [0]" - // - if (state.result !== null && state.kind !== 'scalar') { - throwError$1(state, 'unacceptable node kind for ! tag; it should be "scalar", not "' + state.kind + '"'); - } - - for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) { - type = state.implicitTypes[typeIndex]; - - if (type.resolve(state.result)) { // `state.result` updated in resolver if matched - state.result = type.construct(state.result); - state.tag = type.tag; - if (state.anchor !== null) { - state.anchorMap[state.anchor] = state.result; - } - break; - } - } - } else if (state.tag !== '!') { - if (_hasOwnProperty$1.call(state.typeMap[state.kind || 'fallback'], state.tag)) { - type = state.typeMap[state.kind || 'fallback'][state.tag]; - } else { - // looking for multi type - type = null; - typeList = state.typeMap.multi[state.kind || 'fallback']; - - for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) { - if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) { - type = typeList[typeIndex]; - break; - } - } - } - - if (!type) { - throwError$1(state, 'unknown tag !<' + state.tag + '>'); - } - - if (state.result !== null && type.kind !== state.kind) { - throwError$1(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"'); - } - - if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched - throwError$1(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag'); - } else { - state.result = type.construct(state.result, state.tag); - if (state.anchor !== null) { - state.anchorMap[state.anchor] = state.result; - } - } - } - - if (state.listener !== null) { - state.listener('close', state); - } - return state.tag !== null || state.anchor !== null || hasContent; -} - -function readDocument(state) { - var documentStart = state.position, - _position, - directiveName, - directiveArgs, - hasDirectives = false, - ch; - - state.version = null; - state.checkLineBreaks = state.legacy; - state.tagMap = Object.create(null); - state.anchorMap = Object.create(null); - - while ((ch = state.input.charCodeAt(state.position)) !== 0) { - skipSeparationSpace(state, true, -1); - - ch = state.input.charCodeAt(state.position); - - if (state.lineIndent > 0 || ch !== 0x25/* % */) { - break; - } - - hasDirectives = true; - ch = state.input.charCodeAt(++state.position); - _position = state.position; - - while (ch !== 0 && !is_WS_OR_EOL(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - directiveName = state.input.slice(_position, state.position); - directiveArgs = []; - - if (directiveName.length < 1) { - throwError$1(state, 'directive name must not be less than one character in length'); - } - - while (ch !== 0) { - while (is_WHITE_SPACE(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - if (ch === 0x23/* # */) { - do { ch = state.input.charCodeAt(++state.position); } - while (ch !== 0 && !is_EOL(ch)); - break; - } - - if (is_EOL(ch)) break; - - _position = state.position; - - while (ch !== 0 && !is_WS_OR_EOL(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - directiveArgs.push(state.input.slice(_position, state.position)); - } - - if (ch !== 0) readLineBreak(state); - - if (_hasOwnProperty$1.call(directiveHandlers, directiveName)) { - directiveHandlers[directiveName](state, directiveName, directiveArgs); - } else { - throwWarning(state, 'unknown document directive "' + directiveName + '"'); - } - } - - skipSeparationSpace(state, true, -1); - - if (state.lineIndent === 0 && - state.input.charCodeAt(state.position) === 0x2D/* - */ && - state.input.charCodeAt(state.position + 1) === 0x2D/* - */ && - state.input.charCodeAt(state.position + 2) === 0x2D/* - */) { - state.position += 3; - skipSeparationSpace(state, true, -1); - - } else if (hasDirectives) { - throwError$1(state, 'directives end mark is expected'); - } - - composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true); - skipSeparationSpace(state, true, -1); - - if (state.checkLineBreaks && - PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) { - throwWarning(state, 'non-ASCII line breaks are interpreted as content'); - } - - state.documents.push(state.result); - - if (state.position === state.lineStart && testDocumentSeparator(state)) { - - if (state.input.charCodeAt(state.position) === 0x2E/* . */) { - state.position += 3; - skipSeparationSpace(state, true, -1); - } - return; - } - - if (state.position < (state.length - 1)) { - throwError$1(state, 'end of the stream or a document separator is expected'); - } else { - return; - } -} - - -function loadDocuments(input, options) { - input = String(input); - options = options || {}; - - if (input.length !== 0) { - - // Add tailing `\n` if not exists - if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ && - input.charCodeAt(input.length - 1) !== 0x0D/* CR */) { - input += '\n'; - } - - // Strip BOM - if (input.charCodeAt(0) === 0xFEFF) { - input = input.slice(1); - } - } - - var state = new State$1(input, options); - - var nullpos = input.indexOf('\0'); - - if (nullpos !== -1) { - state.position = nullpos; - throwError$1(state, 'null byte is not allowed in input'); - } - - // Use 0 as string terminator. That significantly simplifies bounds check. - state.input += '\0'; - - while (state.input.charCodeAt(state.position) === 0x20/* Space */) { - state.lineIndent += 1; - state.position += 1; - } - - while (state.position < (state.length - 1)) { - readDocument(state); - } - - return state.documents; -} - - -function loadAll$1(input, iterator, options) { - if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') { - options = iterator; - iterator = null; - } - - var documents = loadDocuments(input, options); - - if (typeof iterator !== 'function') { - return documents; - } - - for (var index = 0, length = documents.length; index < length; index += 1) { - iterator(documents[index]); - } -} - - -function load$1(input, options) { - var documents = loadDocuments(input, options); - - if (documents.length === 0) { - /*eslint-disable no-undefined*/ - return undefined; - } else if (documents.length === 1) { - return documents[0]; - } - throw new exception('expected a single document in the stream, but found more'); -} - - -var loadAll_1 = loadAll$1; -var load_1 = load$1; - -var loader = { - loadAll: loadAll_1, - load: load_1 -}; - -/*eslint-disable no-use-before-define*/ - - - - - -var _toString = Object.prototype.toString; -var _hasOwnProperty = Object.prototype.hasOwnProperty; - -var CHAR_BOM = 0xFEFF; -var CHAR_TAB = 0x09; /* Tab */ -var CHAR_LINE_FEED = 0x0A; /* LF */ -var CHAR_CARRIAGE_RETURN = 0x0D; /* CR */ -var CHAR_SPACE = 0x20; /* Space */ -var CHAR_EXCLAMATION = 0x21; /* ! */ -var CHAR_DOUBLE_QUOTE = 0x22; /* " */ -var CHAR_SHARP = 0x23; /* # */ -var CHAR_PERCENT = 0x25; /* % */ -var CHAR_AMPERSAND = 0x26; /* & */ -var CHAR_SINGLE_QUOTE = 0x27; /* ' */ -var CHAR_ASTERISK = 0x2A; /* * */ -var CHAR_COMMA = 0x2C; /* , */ -var CHAR_MINUS = 0x2D; /* - */ -var CHAR_COLON = 0x3A; /* : */ -var CHAR_EQUALS = 0x3D; /* = */ -var CHAR_GREATER_THAN = 0x3E; /* > */ -var CHAR_QUESTION = 0x3F; /* ? */ -var CHAR_COMMERCIAL_AT = 0x40; /* @ */ -var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ -var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ -var CHAR_GRAVE_ACCENT = 0x60; /* ` */ -var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ -var CHAR_VERTICAL_LINE = 0x7C; /* | */ -var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ - -var ESCAPE_SEQUENCES = {}; - -ESCAPE_SEQUENCES[0x00] = '\\0'; -ESCAPE_SEQUENCES[0x07] = '\\a'; -ESCAPE_SEQUENCES[0x08] = '\\b'; -ESCAPE_SEQUENCES[0x09] = '\\t'; -ESCAPE_SEQUENCES[0x0A] = '\\n'; -ESCAPE_SEQUENCES[0x0B] = '\\v'; -ESCAPE_SEQUENCES[0x0C] = '\\f'; -ESCAPE_SEQUENCES[0x0D] = '\\r'; -ESCAPE_SEQUENCES[0x1B] = '\\e'; -ESCAPE_SEQUENCES[0x22] = '\\"'; -ESCAPE_SEQUENCES[0x5C] = '\\\\'; -ESCAPE_SEQUENCES[0x85] = '\\N'; -ESCAPE_SEQUENCES[0xA0] = '\\_'; -ESCAPE_SEQUENCES[0x2028] = '\\L'; -ESCAPE_SEQUENCES[0x2029] = '\\P'; - -var DEPRECATED_BOOLEANS_SYNTAX = [ - 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON', - 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF' -]; - -var DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/; - -function compileStyleMap(schema, map) { - var result, keys, index, length, tag, style, type; - - if (map === null) return {}; - - result = {}; - keys = Object.keys(map); - - for (index = 0, length = keys.length; index < length; index += 1) { - tag = keys[index]; - style = String(map[tag]); - - if (tag.slice(0, 2) === '!!') { - tag = 'tag:yaml.org,2002:' + tag.slice(2); - } - type = schema.compiledTypeMap['fallback'][tag]; - - if (type && _hasOwnProperty.call(type.styleAliases, style)) { - style = type.styleAliases[style]; - } - - result[tag] = style; - } - - return result; -} - -function encodeHex(character) { - var string, handle, length; - - string = character.toString(16).toUpperCase(); - - if (character <= 0xFF) { - handle = 'x'; - length = 2; - } else if (character <= 0xFFFF) { - handle = 'u'; - length = 4; - } else if (character <= 0xFFFFFFFF) { - handle = 'U'; - length = 8; - } else { - throw new exception('code point within a string may not be greater than 0xFFFFFFFF'); - } - - return '\\' + handle + common$4.repeat('0', length - string.length) + string; -} - - -var QUOTING_TYPE_SINGLE = 1, - QUOTING_TYPE_DOUBLE = 2; - -function State(options) { - this.schema = options['schema'] || _default$1; - this.indent = Math.max(1, (options['indent'] || 2)); - this.noArrayIndent = options['noArrayIndent'] || false; - this.skipInvalid = options['skipInvalid'] || false; - this.flowLevel = (common$4.isNothing(options['flowLevel']) ? -1 : options['flowLevel']); - this.styleMap = compileStyleMap(this.schema, options['styles'] || null); - this.sortKeys = options['sortKeys'] || false; - this.lineWidth = options['lineWidth'] || 80; - this.noRefs = options['noRefs'] || false; - this.noCompatMode = options['noCompatMode'] || false; - this.condenseFlow = options['condenseFlow'] || false; - this.quotingType = options['quotingType'] === '"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE; - this.forceQuotes = options['forceQuotes'] || false; - this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null; - - this.implicitTypes = this.schema.compiledImplicit; - this.explicitTypes = this.schema.compiledExplicit; - - this.tag = null; - this.result = ''; - - this.duplicates = []; - this.usedDuplicates = null; -} - -// Indents every line in a string. Empty lines (\n only) are not indented. -function indentString(string, spaces) { - var ind = common$4.repeat(' ', spaces), - position = 0, - next = -1, - result = '', - line, - length = string.length; - - while (position < length) { - next = string.indexOf('\n', position); - if (next === -1) { - line = string.slice(position); - position = length; - } else { - line = string.slice(position, next + 1); - position = next + 1; - } - - if (line.length && line !== '\n') result += ind; - - result += line; - } - - return result; -} - -function generateNextLine(state, level) { - return '\n' + common$4.repeat(' ', state.indent * level); -} - -function testImplicitResolving(state, str) { - var index, length, type; - - for (index = 0, length = state.implicitTypes.length; index < length; index += 1) { - type = state.implicitTypes[index]; - - if (type.resolve(str)) { - return true; - } - } - - return false; -} - -// [33] s-white ::= s-space | s-tab -function isWhitespace(c) { - return c === CHAR_SPACE || c === CHAR_TAB; -} - -// Returns true if the character can be printed without escaping. -// From YAML 1.2: "any allowed characters known to be non-printable -// should also be escaped. [However,] This isn’t mandatory" -// Derived from nb-char - \t - #x85 - #xA0 - #x2028 - #x2029. -function isPrintable(c) { - return (0x00020 <= c && c <= 0x00007E) - || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029) - || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM) - || (0x10000 <= c && c <= 0x10FFFF); -} - -// [34] ns-char ::= nb-char - s-white -// [27] nb-char ::= c-printable - b-char - c-byte-order-mark -// [26] b-char ::= b-line-feed | b-carriage-return -// Including s-white (for some reason, examples doesn't match specs in this aspect) -// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark -function isNsCharOrWhitespace(c) { - return isPrintable(c) - && c !== CHAR_BOM - // - b-char - && c !== CHAR_CARRIAGE_RETURN - && c !== CHAR_LINE_FEED; -} - -// [127] ns-plain-safe(c) ::= c = flow-out ⇒ ns-plain-safe-out -// c = flow-in ⇒ ns-plain-safe-in -// c = block-key ⇒ ns-plain-safe-out -// c = flow-key ⇒ ns-plain-safe-in -// [128] ns-plain-safe-out ::= ns-char -// [129] ns-plain-safe-in ::= ns-char - c-flow-indicator -// [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - “:” - “#” ) -// | ( /* An ns-char preceding */ “#” ) -// | ( “:” /* Followed by an ns-plain-safe(c) */ ) -function isPlainSafe(c, prev, inblock) { - var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c); - var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c); - return ( - // ns-plain-safe - inblock ? // c = flow-in - cIsNsCharOrWhitespace - : cIsNsCharOrWhitespace - // - c-flow-indicator - && c !== CHAR_COMMA - && c !== CHAR_LEFT_SQUARE_BRACKET - && c !== CHAR_RIGHT_SQUARE_BRACKET - && c !== CHAR_LEFT_CURLY_BRACKET - && c !== CHAR_RIGHT_CURLY_BRACKET - ) - // ns-plain-char - && c !== CHAR_SHARP // false on '#' - && !(prev === CHAR_COLON && !cIsNsChar) // false on ': ' - || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#' - || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]' -} - -// Simplified test for values allowed as the first character in plain style. -function isPlainSafeFirst(c) { - // Uses a subset of ns-char - c-indicator - // where ns-char = nb-char - s-white. - // No support of ( ( “?” | “:” | “-” ) /* Followed by an ns-plain-safe(c)) */ ) part - return isPrintable(c) && c !== CHAR_BOM - && !isWhitespace(c) // - s-white - // - (c-indicator ::= - // “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}” - && c !== CHAR_MINUS - && c !== CHAR_QUESTION - && c !== CHAR_COLON - && c !== CHAR_COMMA - && c !== CHAR_LEFT_SQUARE_BRACKET - && c !== CHAR_RIGHT_SQUARE_BRACKET - && c !== CHAR_LEFT_CURLY_BRACKET - && c !== CHAR_RIGHT_CURLY_BRACKET - // | “#” | “&” | “*” | “!” | “|” | “=” | “>” | “'” | “"” - && c !== CHAR_SHARP - && c !== CHAR_AMPERSAND - && c !== CHAR_ASTERISK - && c !== CHAR_EXCLAMATION - && c !== CHAR_VERTICAL_LINE - && c !== CHAR_EQUALS - && c !== CHAR_GREATER_THAN - && c !== CHAR_SINGLE_QUOTE - && c !== CHAR_DOUBLE_QUOTE - // | “%” | “@” | “`”) - && c !== CHAR_PERCENT - && c !== CHAR_COMMERCIAL_AT - && c !== CHAR_GRAVE_ACCENT; -} - -// Simplified test for values allowed as the last character in plain style. -function isPlainSafeLast(c) { - // just not whitespace or colon, it will be checked to be plain character later - return !isWhitespace(c) && c !== CHAR_COLON; -} - -// Same as 'string'.codePointAt(pos), but works in older browsers. -function codePointAt(string, pos) { - var first = string.charCodeAt(pos), second; - if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) { - second = string.charCodeAt(pos + 1); - if (second >= 0xDC00 && second <= 0xDFFF) { - // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae - return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000; - } - } - return first; -} - -// Determines whether block indentation indicator is required. -function needIndentIndicator(string) { - var leadingSpaceRe = /^\n* /; - return leadingSpaceRe.test(string); -} - -var STYLE_PLAIN = 1, - STYLE_SINGLE = 2, - STYLE_LITERAL = 3, - STYLE_FOLDED = 4, - STYLE_DOUBLE = 5; - -// Determines which scalar styles are possible and returns the preferred style. -// lineWidth = -1 => no limit. -// Pre-conditions: str.length > 0. -// Post-conditions: -// STYLE_PLAIN or STYLE_SINGLE => no \n are in the string. -// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1). -// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1). -function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, - testAmbiguousType, quotingType, forceQuotes, inblock) { - - var i; - var char = 0; - var prevChar = null; - var hasLineBreak = false; - var hasFoldableLine = false; // only checked if shouldTrackWidth - var shouldTrackWidth = lineWidth !== -1; - var previousLineBreak = -1; // count the first line correctly - var plain = isPlainSafeFirst(codePointAt(string, 0)) - && isPlainSafeLast(codePointAt(string, string.length - 1)); - - if (singleLineOnly || forceQuotes) { - // Case: no block styles. - // Check for disallowed characters to rule out plain and single. - for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { - char = codePointAt(string, i); - if (!isPrintable(char)) { - return STYLE_DOUBLE; - } - plain = plain && isPlainSafe(char, prevChar, inblock); - prevChar = char; - } - } else { - // Case: block styles permitted. - for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { - char = codePointAt(string, i); - if (char === CHAR_LINE_FEED) { - hasLineBreak = true; - // Check if any line can be folded. - if (shouldTrackWidth) { - hasFoldableLine = hasFoldableLine || - // Foldable line = too long, and not more-indented. - (i - previousLineBreak - 1 > lineWidth && - string[previousLineBreak + 1] !== ' '); - previousLineBreak = i; - } - } else if (!isPrintable(char)) { - return STYLE_DOUBLE; - } - plain = plain && isPlainSafe(char, prevChar, inblock); - prevChar = char; - } - // in case the end is missing a \n - hasFoldableLine = hasFoldableLine || (shouldTrackWidth && - (i - previousLineBreak - 1 > lineWidth && - string[previousLineBreak + 1] !== ' ')); - } - // Although every style can represent \n without escaping, prefer block styles - // for multiline, since they're more readable and they don't add empty lines. - // Also prefer folding a super-long line. - if (!hasLineBreak && !hasFoldableLine) { - // Strings interpretable as another type have to be quoted; - // e.g. the string 'true' vs. the boolean true. - if (plain && !forceQuotes && !testAmbiguousType(string)) { - return STYLE_PLAIN; - } - return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE; - } - // Edge case: block indentation indicator can only have one digit. - if (indentPerLevel > 9 && needIndentIndicator(string)) { - return STYLE_DOUBLE; - } - // At this point we know block styles are valid. - // Prefer literal style unless we want to fold. - if (!forceQuotes) { - return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL; - } - return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE; -} - -// Note: line breaking/folding is implemented for only the folded style. -// NB. We drop the last trailing newline (if any) of a returned block scalar -// since the dumper adds its own newline. This always works: -// • No ending newline => unaffected; already using strip "-" chomping. -// • Ending newline => removed then restored. -// Importantly, this keeps the "+" chomp indicator from gaining an extra line. -function writeScalar(state, string, level, iskey, inblock) { - state.dump = (function () { - if (string.length === 0) { - return state.quotingType === QUOTING_TYPE_DOUBLE ? '""' : "''"; - } - if (!state.noCompatMode) { - if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) { - return state.quotingType === QUOTING_TYPE_DOUBLE ? ('"' + string + '"') : ("'" + string + "'"); - } - } - - var indent = state.indent * Math.max(1, level); // no 0-indent scalars - // As indentation gets deeper, let the width decrease monotonically - // to the lower bound min(state.lineWidth, 40). - // Note that this implies - // state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound. - // state.lineWidth > 40 + state.indent: width decreases until the lower bound. - // This behaves better than a constant minimum width which disallows narrower options, - // or an indent threshold which causes the width to suddenly increase. - var lineWidth = state.lineWidth === -1 - ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent); - - // Without knowing if keys are implicit/explicit, assume implicit for safety. - var singleLineOnly = iskey - // No block styles in flow mode. - || (state.flowLevel > -1 && level >= state.flowLevel); - function testAmbiguity(string) { - return testImplicitResolving(state, string); - } - - switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth, - testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) { - - case STYLE_PLAIN: - return string; - case STYLE_SINGLE: - return "'" + string.replace(/'/g, "''") + "'"; - case STYLE_LITERAL: - return '|' + blockHeader(string, state.indent) - + dropEndingNewline(indentString(string, indent)); - case STYLE_FOLDED: - return '>' + blockHeader(string, state.indent) - + dropEndingNewline(indentString(foldString(string, lineWidth), indent)); - case STYLE_DOUBLE: - return '"' + escapeString(string) + '"'; - default: - throw new exception('impossible error: invalid scalar style'); - } - }()); -} - -// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9. -function blockHeader(string, indentPerLevel) { - var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : ''; - - // note the special case: the string '\n' counts as a "trailing" empty line. - var clip = string[string.length - 1] === '\n'; - var keep = clip && (string[string.length - 2] === '\n' || string === '\n'); - var chomp = keep ? '+' : (clip ? '' : '-'); - - return indentIndicator + chomp + '\n'; -} - -// (See the note for writeScalar.) -function dropEndingNewline(string) { - return string[string.length - 1] === '\n' ? string.slice(0, -1) : string; -} - -// Note: a long line without a suitable break point will exceed the width limit. -// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0. -function foldString(string, width) { - // In folded style, $k$ consecutive newlines output as $k+1$ newlines— - // unless they're before or after a more-indented line, or at the very - // beginning or end, in which case $k$ maps to $k$. - // Therefore, parse each chunk as newline(s) followed by a content line. - var lineRe = /(\n+)([^\n]*)/g; - - // first line (possibly an empty line) - var result = (function () { - var nextLF = string.indexOf('\n'); - nextLF = nextLF !== -1 ? nextLF : string.length; - lineRe.lastIndex = nextLF; - return foldLine(string.slice(0, nextLF), width); - }()); - // If we haven't reached the first content line yet, don't add an extra \n. - var prevMoreIndented = string[0] === '\n' || string[0] === ' '; - var moreIndented; - - // rest of the lines - var match; - while ((match = lineRe.exec(string))) { - var prefix = match[1], line = match[2]; - moreIndented = (line[0] === ' '); - result += prefix - + (!prevMoreIndented && !moreIndented && line !== '' - ? '\n' : '') - + foldLine(line, width); - prevMoreIndented = moreIndented; - } - - return result; -} - -// Greedy line breaking. -// Picks the longest line under the limit each time, -// otherwise settles for the shortest line over the limit. -// NB. More-indented lines *cannot* be folded, as that would add an extra \n. -function foldLine(line, width) { - if (line === '' || line[0] === ' ') return line; - - // Since a more-indented line adds a \n, breaks can't be followed by a space. - var breakRe = / [^ ]/g; // note: the match index will always be <= length-2. - var match; - // start is an inclusive index. end, curr, and next are exclusive. - var start = 0, end, curr = 0, next = 0; - var result = ''; - - // Invariants: 0 <= start <= length-1. - // 0 <= curr <= next <= max(0, length-2). curr - start <= width. - // Inside the loop: - // A match implies length >= 2, so curr and next are <= length-2. - while ((match = breakRe.exec(line))) { - next = match.index; - // maintain invariant: curr - start <= width - if (next - start > width) { - end = (curr > start) ? curr : next; // derive end <= length-2 - result += '\n' + line.slice(start, end); - // skip the space that was output as \n - start = end + 1; // derive start <= length-1 - } - curr = next; - } - - // By the invariants, start <= length-1, so there is something left over. - // It is either the whole string or a part starting from non-whitespace. - result += '\n'; - // Insert a break if the remainder is too long and there is a break available. - if (line.length - start > width && curr > start) { - result += line.slice(start, curr) + '\n' + line.slice(curr + 1); - } else { - result += line.slice(start); - } - - return result.slice(1); // drop extra \n joiner -} - -// Escapes a double-quoted string. -function escapeString(string) { - var result = ''; - var char = 0; - var escapeSeq; - - for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { - char = codePointAt(string, i); - escapeSeq = ESCAPE_SEQUENCES[char]; - - if (!escapeSeq && isPrintable(char)) { - result += string[i]; - if (char >= 0x10000) result += string[i + 1]; - } else { - result += escapeSeq || encodeHex(char); - } - } - - return result; -} - -function writeFlowSequence(state, level, object) { - var _result = '', - _tag = state.tag, - index, - length, - value; - - for (index = 0, length = object.length; index < length; index += 1) { - value = object[index]; - - if (state.replacer) { - value = state.replacer.call(object, String(index), value); - } - - // Write only valid elements, put null instead of invalid elements. - if (writeNode(state, level, value, false, false) || - (typeof value === 'undefined' && - writeNode(state, level, null, false, false))) { - - if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : ''); - _result += state.dump; - } - } - - state.tag = _tag; - state.dump = '[' + _result + ']'; -} - -function writeBlockSequence(state, level, object, compact) { - var _result = '', - _tag = state.tag, - index, - length, - value; - - for (index = 0, length = object.length; index < length; index += 1) { - value = object[index]; - - if (state.replacer) { - value = state.replacer.call(object, String(index), value); - } - - // Write only valid elements, put null instead of invalid elements. - if (writeNode(state, level + 1, value, true, true, false, true) || - (typeof value === 'undefined' && - writeNode(state, level + 1, null, true, true, false, true))) { - - if (!compact || _result !== '') { - _result += generateNextLine(state, level); - } - - if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { - _result += '-'; - } else { - _result += '- '; - } - - _result += state.dump; - } - } - - state.tag = _tag; - state.dump = _result || '[]'; // Empty sequence if no valid values. -} - -function writeFlowMapping(state, level, object) { - var _result = '', - _tag = state.tag, - objectKeyList = Object.keys(object), - index, - length, - objectKey, - objectValue, - pairBuffer; - - for (index = 0, length = objectKeyList.length; index < length; index += 1) { - - pairBuffer = ''; - if (_result !== '') pairBuffer += ', '; - - if (state.condenseFlow) pairBuffer += '"'; - - objectKey = objectKeyList[index]; - objectValue = object[objectKey]; - - if (state.replacer) { - objectValue = state.replacer.call(object, objectKey, objectValue); - } - - if (!writeNode(state, level, objectKey, false, false)) { - continue; // Skip this pair because of invalid key; - } - - if (state.dump.length > 1024) pairBuffer += '? '; - - pairBuffer += state.dump + (state.condenseFlow ? '"' : '') + ':' + (state.condenseFlow ? '' : ' '); - - if (!writeNode(state, level, objectValue, false, false)) { - continue; // Skip this pair because of invalid value. - } - - pairBuffer += state.dump; - - // Both key and value are valid. - _result += pairBuffer; - } - - state.tag = _tag; - state.dump = '{' + _result + '}'; -} - -function writeBlockMapping(state, level, object, compact) { - var _result = '', - _tag = state.tag, - objectKeyList = Object.keys(object), - index, - length, - objectKey, - objectValue, - explicitPair, - pairBuffer; - - // Allow sorting keys so that the output file is deterministic - if (state.sortKeys === true) { - // Default sorting - objectKeyList.sort(); - } else if (typeof state.sortKeys === 'function') { - // Custom sort function - objectKeyList.sort(state.sortKeys); - } else if (state.sortKeys) { - // Something is wrong - throw new exception('sortKeys must be a boolean or a function'); - } - - for (index = 0, length = objectKeyList.length; index < length; index += 1) { - pairBuffer = ''; - - if (!compact || _result !== '') { - pairBuffer += generateNextLine(state, level); - } - - objectKey = objectKeyList[index]; - objectValue = object[objectKey]; - - if (state.replacer) { - objectValue = state.replacer.call(object, objectKey, objectValue); - } - - if (!writeNode(state, level + 1, objectKey, true, true, true)) { - continue; // Skip this pair because of invalid key. - } - - explicitPair = (state.tag !== null && state.tag !== '?') || - (state.dump && state.dump.length > 1024); - - if (explicitPair) { - if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { - pairBuffer += '?'; - } else { - pairBuffer += '? '; - } - } - - pairBuffer += state.dump; - - if (explicitPair) { - pairBuffer += generateNextLine(state, level); - } - - if (!writeNode(state, level + 1, objectValue, true, explicitPair)) { - continue; // Skip this pair because of invalid value. - } - - if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { - pairBuffer += ':'; - } else { - pairBuffer += ': '; - } - - pairBuffer += state.dump; - - // Both key and value are valid. - _result += pairBuffer; - } - - state.tag = _tag; - state.dump = _result || '{}'; // Empty mapping if no valid pairs. -} - -function detectType(state, object, explicit) { - var _result, typeList, index, length, type, style; - - typeList = explicit ? state.explicitTypes : state.implicitTypes; - - for (index = 0, length = typeList.length; index < length; index += 1) { - type = typeList[index]; - - if ((type.instanceOf || type.predicate) && - (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) && - (!type.predicate || type.predicate(object))) { - - if (explicit) { - if (type.multi && type.representName) { - state.tag = type.representName(object); - } else { - state.tag = type.tag; - } - } else { - state.tag = '?'; - } - - if (type.represent) { - style = state.styleMap[type.tag] || type.defaultStyle; - - if (_toString.call(type.represent) === '[object Function]') { - _result = type.represent(object, style); - } else if (_hasOwnProperty.call(type.represent, style)) { - _result = type.represent[style](object, style); - } else { - throw new exception('!<' + type.tag + '> tag resolver accepts not "' + style + '" style'); - } - - state.dump = _result; - } - - return true; - } - } - - return false; -} - -// Serializes `object` and writes it to global `result`. -// Returns true on success, or false on invalid object. -// -function writeNode(state, level, object, block, compact, iskey, isblockseq) { - state.tag = null; - state.dump = object; - - if (!detectType(state, object, false)) { - detectType(state, object, true); - } - - var type = _toString.call(state.dump); - var inblock = block; - var tagStr; - - if (block) { - block = (state.flowLevel < 0 || state.flowLevel > level); - } - - var objectOrArray = type === '[object Object]' || type === '[object Array]', - duplicateIndex, - duplicate; - - if (objectOrArray) { - duplicateIndex = state.duplicates.indexOf(object); - duplicate = duplicateIndex !== -1; - } - - if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) { - compact = false; - } - - if (duplicate && state.usedDuplicates[duplicateIndex]) { - state.dump = '*ref_' + duplicateIndex; - } else { - if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) { - state.usedDuplicates[duplicateIndex] = true; - } - if (type === '[object Object]') { - if (block && (Object.keys(state.dump).length !== 0)) { - writeBlockMapping(state, level, state.dump, compact); - if (duplicate) { - state.dump = '&ref_' + duplicateIndex + state.dump; - } - } else { - writeFlowMapping(state, level, state.dump); - if (duplicate) { - state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; - } - } - } else if (type === '[object Array]') { - if (block && (state.dump.length !== 0)) { - if (state.noArrayIndent && !isblockseq && level > 0) { - writeBlockSequence(state, level - 1, state.dump, compact); - } else { - writeBlockSequence(state, level, state.dump, compact); - } - if (duplicate) { - state.dump = '&ref_' + duplicateIndex + state.dump; - } - } else { - writeFlowSequence(state, level, state.dump); - if (duplicate) { - state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; - } - } - } else if (type === '[object String]') { - if (state.tag !== '?') { - writeScalar(state, state.dump, level, iskey, inblock); - } - } else if (type === '[object Undefined]') { - return false; - } else { - if (state.skipInvalid) return false; - throw new exception('unacceptable kind of an object to dump ' + type); - } - - if (state.tag !== null && state.tag !== '?') { - // Need to encode all characters except those allowed by the spec: - // - // [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */ - // [36] ns-hex-digit ::= ns-dec-digit - // | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */ - // [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */ - // [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | “-” - // [39] ns-uri-char ::= “%” ns-hex-digit ns-hex-digit | ns-word-char | “#” - // | “;” | “/” | “?” | “:” | “@” | “&” | “=” | “+” | “$” | “,” - // | “_” | “.” | “!” | “~” | “*” | “'” | “(” | “)” | “[” | “]” - // - // Also need to encode '!' because it has special meaning (end of tag prefix). - // - tagStr = encodeURI( - state.tag[0] === '!' ? state.tag.slice(1) : state.tag - ).replace(/!/g, '%21'); - - if (state.tag[0] === '!') { - tagStr = '!' + tagStr; - } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') { - tagStr = '!!' + tagStr.slice(18); - } else { - tagStr = '!<' + tagStr + '>'; - } - - state.dump = tagStr + ' ' + state.dump; - } - } - - return true; -} - -function getDuplicateReferences(object, state) { - var objects = [], - duplicatesIndexes = [], - index, - length; - - inspectNode(object, objects, duplicatesIndexes); - - for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) { - state.duplicates.push(objects[duplicatesIndexes[index]]); - } - state.usedDuplicates = new Array(length); -} - -function inspectNode(object, objects, duplicatesIndexes) { - var objectKeyList, - index, - length; - - if (object !== null && typeof object === 'object') { - index = objects.indexOf(object); - if (index !== -1) { - if (duplicatesIndexes.indexOf(index) === -1) { - duplicatesIndexes.push(index); - } - } else { - objects.push(object); - - if (Array.isArray(object)) { - for (index = 0, length = object.length; index < length; index += 1) { - inspectNode(object[index], objects, duplicatesIndexes); - } - } else { - objectKeyList = Object.keys(object); - - for (index = 0, length = objectKeyList.length; index < length; index += 1) { - inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes); - } - } - } - } -} - -function dump$1(input, options) { - options = options || {}; - - var state = new State(options); - - if (!state.noRefs) getDuplicateReferences(input, state); - - var value = input; - - if (state.replacer) { - value = state.replacer.call({ '': value }, '', value); - } - - if (writeNode(state, 0, value, true, true)) return state.dump + '\n'; - - return ''; -} - -var dump_1 = dump$1; - -var dumper = { - dump: dump_1 -}; - -function renamed(from, to) { - return function () { - throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' + - 'Use yaml.' + to + ' instead, which is now safe by default.'); - }; -} - - -var Type = type$1; -var Schema = schema$1; -var FAILSAFE_SCHEMA = failsafe; -var JSON_SCHEMA = json; -var CORE_SCHEMA = core; -var DEFAULT_SCHEMA = _default$1; -var load = loader.load; -var loadAll = loader.loadAll; -var dump = dumper.dump; -var YAMLException = exception; - -// Re-export all types in case user wants to create custom schema -var types$1 = { - binary: binary, - float: float, - map: map$3, - null: _null, - pairs: pairs, - set: set, - timestamp: timestamp, - bool: bool, - int: int, - merge: merge$1, - omap: omap, - seq: seq, - str: str -}; - -// Removed functions from JS-YAML 3.0.x -var safeLoad = renamed('safeLoad', 'load'); -var safeLoadAll = renamed('safeLoadAll', 'loadAll'); -var safeDump = renamed('safeDump', 'dump'); - -var jsYaml = { - Type: Type, - Schema: Schema, - FAILSAFE_SCHEMA: FAILSAFE_SCHEMA, - JSON_SCHEMA: JSON_SCHEMA, - CORE_SCHEMA: CORE_SCHEMA, - DEFAULT_SCHEMA: DEFAULT_SCHEMA, - load: load, - loadAll: loadAll, - dump: dump, - YAMLException: YAMLException, - types: types$1, - safeLoad: safeLoad, - safeLoadAll: safeLoadAll, - safeDump: safeDump -}; - -var isArrayish$2 = function isArrayish(obj) { - if (!obj) { - return false; - } - - return obj instanceof Array || Array.isArray(obj) || - (obj.length >= 0 && obj.splice instanceof Function); -}; - -var util$2 = require$$0$4; -var isArrayish$1 = isArrayish$2; - -var errorEx$1 = function errorEx(name, properties) { - if (!name || name.constructor !== String) { - properties = name || {}; - name = Error.name; - } - - var errorExError = function ErrorEXError(message) { - if (!this) { - return new ErrorEXError(message); - } - - message = message instanceof Error - ? message.message - : (message || this.message); - - Error.call(this, message); - Error.captureStackTrace(this, errorExError); - - this.name = name; - - Object.defineProperty(this, 'message', { - configurable: true, - enumerable: false, - get: function () { - var newMessage = message.split(/\r?\n/g); - - for (var key in properties) { - if (!properties.hasOwnProperty(key)) { - continue; - } - - var modifier = properties[key]; - - if ('message' in modifier) { - newMessage = modifier.message(this[key], newMessage) || newMessage; - if (!isArrayish$1(newMessage)) { - newMessage = [newMessage]; - } - } - } - - return newMessage.join('\n'); - }, - set: function (v) { - message = v; - } - }); - - var overwrittenStack = null; - - var stackDescriptor = Object.getOwnPropertyDescriptor(this, 'stack'); - var stackGetter = stackDescriptor.get; - var stackValue = stackDescriptor.value; - delete stackDescriptor.value; - delete stackDescriptor.writable; - - stackDescriptor.set = function (newstack) { - overwrittenStack = newstack; - }; - - stackDescriptor.get = function () { - var stack = (overwrittenStack || ((stackGetter) - ? stackGetter.call(this) - : stackValue)).split(/\r?\n+/g); - - // starting in Node 7, the stack builder caches the message. - // just replace it. - if (!overwrittenStack) { - stack[0] = this.name + ': ' + this.message; - } - - var lineCount = 1; - for (var key in properties) { - if (!properties.hasOwnProperty(key)) { - continue; - } - - var modifier = properties[key]; - - if ('line' in modifier) { - var line = modifier.line(this[key]); - if (line) { - stack.splice(lineCount++, 0, ' ' + line); - } - } - - if ('stack' in modifier) { - modifier.stack(this[key], stack); - } - } - - return stack.join('\n'); - }; - - Object.defineProperty(this, 'stack', stackDescriptor); - }; - - if (Object.setPrototypeOf) { - Object.setPrototypeOf(errorExError.prototype, Error.prototype); - Object.setPrototypeOf(errorExError, Error); - } else { - util$2.inherits(errorExError, Error); - } - - return errorExError; -}; - -errorEx$1.append = function (str, def) { - return { - message: function (v, message) { - v = v || def; - - if (v) { - message[0] += ' ' + str.replace('%s', v.toString()); - } - - return message; - } - }; -}; - -errorEx$1.line = function (str, def) { - return { - line: function (v) { - v = v || def; - - if (v) { - return str.replace('%s', v.toString()); - } - - return null; - } - }; -}; - -var errorEx_1 = errorEx$1; - -const hexify = char => { - const h = char.charCodeAt(0).toString(16).toUpperCase(); - return '0x' + (h.length % 2 ? '0' : '') + h -}; - -const parseError = (e, txt, context) => { - if (!txt) { - return { - message: e.message + ' while parsing empty string', - position: 0, - } - } - const badToken = e.message.match(/^Unexpected token (.) .*position\s+(\d+)/i); - const errIdx = badToken ? +badToken[2] - : e.message.match(/^Unexpected end of JSON.*/i) ? txt.length - 1 - : null; - - const msg = badToken ? e.message.replace(/^Unexpected token ./, `Unexpected token ${ - JSON.stringify(badToken[1]) - } (${hexify(badToken[1])})`) - : e.message; - - if (errIdx !== null && errIdx !== undefined) { - const start = errIdx <= context ? 0 - : errIdx - context; - - const end = errIdx + context >= txt.length ? txt.length - : errIdx + context; - - const slice = (start === 0 ? '' : '...') + - txt.slice(start, end) + - (end === txt.length ? '' : '...'); - - const near = txt === slice ? '' : 'near '; - - return { - message: msg + ` while parsing ${near}${JSON.stringify(slice)}`, - position: errIdx, - } - } else { - return { - message: msg + ` while parsing '${txt.slice(0, context * 2)}'`, - position: 0, - } - } -}; - -class JSONParseError extends SyntaxError { - constructor (er, txt, context, caller) { - context = context || 20; - const metadata = parseError(er, txt, context); - super(metadata.message); - Object.assign(this, metadata); - this.code = 'EJSONPARSE'; - this.systemError = er; - Error.captureStackTrace(this, caller || this.constructor); - } - get name () { return this.constructor.name } - set name (n) {} - get [Symbol.toStringTag] () { return this.constructor.name } -} - -const kIndent = Symbol.for('indent'); -const kNewline = Symbol.for('newline'); -// only respect indentation if we got a line break, otherwise squash it -// things other than objects and arrays aren't indented, so ignore those -// Important: in both of these regexps, the $1 capture group is the newline -// or undefined, and the $2 capture group is the indent, or undefined. -const formatRE = /^\s*[{\[]((?:\r?\n)+)([\s\t]*)/; -const emptyRE = /^(?:\{\}|\[\])((?:\r?\n)+)?$/; - -const parseJson$1 = (txt, reviver, context) => { - const parseText = stripBOM(txt); - context = context || 20; - try { - // get the indentation so that we can save it back nicely - // if the file starts with {" then we have an indent of '', ie, none - // otherwise, pick the indentation of the next line after the first \n - // If the pattern doesn't match, then it means no indentation. - // JSON.stringify ignores symbols, so this is reasonably safe. - // if the string is '{}' or '[]', then use the default 2-space indent. - const [, newline = '\n', indent = ' '] = parseText.match(emptyRE) || - parseText.match(formatRE) || - [, '', '']; - - const result = JSON.parse(parseText, reviver); - if (result && typeof result === 'object') { - result[kNewline] = newline; - result[kIndent] = indent; - } - return result - } catch (e) { - if (typeof txt !== 'string' && !Buffer.isBuffer(txt)) { - const isEmptyArray = Array.isArray(txt) && txt.length === 0; - throw Object.assign(new TypeError( - `Cannot parse ${isEmptyArray ? 'an empty array' : String(txt)}` - ), { - code: 'EJSONPARSE', - systemError: e, - }) - } - - throw new JSONParseError(e, parseText, context, parseJson$1) - } -}; - -// Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) -// because the buffer-to-string conversion in `fs.readFileSync()` -// translates it to FEFF, the UTF-16 BOM. -const stripBOM = txt => String(txt).replace(/^\uFEFF/, ''); - -var jsonParseEvenBetterErrors = parseJson$1; -parseJson$1.JSONParseError = JSONParseError; - -parseJson$1.noExceptions = (txt, reviver) => { - try { - return JSON.parse(stripBOM(txt), reviver) - } catch (e) {} -}; - -var LF = '\n'; -var CR = '\r'; -var LinesAndColumns$1 = (function () { - function LinesAndColumns(string) { - this.string = string; - var offsets = [0]; - for (var offset = 0; offset < string.length;) { - switch (string[offset]) { - case LF: - offset += LF.length; - offsets.push(offset); - break; - case CR: - offset += CR.length; - if (string[offset] === LF) { - offset += LF.length; - } - offsets.push(offset); - break; - default: - offset++; - break; - } - } - this.offsets = offsets; - } - LinesAndColumns.prototype.locationForIndex = function (index) { - if (index < 0 || index > this.string.length) { - return null; - } - var line = 0; - var offsets = this.offsets; - while (offsets[line + 1] <= index) { - line++; - } - var column = index - offsets[line]; - return { line: line, column: column }; - }; - LinesAndColumns.prototype.indexForLocation = function (location) { - var line = location.line, column = location.column; - if (line < 0 || line >= this.offsets.length) { - return null; - } - if (column < 0 || column > this.lengthOfLine(line)) { - return null; - } - return this.offsets[line] + column; - }; - LinesAndColumns.prototype.lengthOfLine = function (line) { - var offset = this.offsets[line]; - var nextOffset = line === this.offsets.length - 1 ? this.string.length : this.offsets[line + 1]; - return nextOffset - offset; - }; - return LinesAndColumns; -}()); - -var dist = /*#__PURE__*/Object.freeze({ - __proto__: null, - 'default': LinesAndColumns$1 -}); - -var require$$2 = /*@__PURE__*/getAugmentedNamespace(dist); - -var lib$4 = {}; - -var lib$3 = {}; - -var jsTokens = {}; - -// Copyright 2014, 2015, 2016, 2017, 2018 Simon Lydell -// License: MIT. (See LICENSE.) - -Object.defineProperty(jsTokens, "__esModule", { - value: true -}); - -// This regex comes from regex.coffee, and is inserted here by generate-index.js -// (run `npm run build`). -jsTokens.default = /((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyus]{1,6}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g; - -jsTokens.matchToToken = function(match) { - var token = {type: "invalid", value: match[0], closed: undefined}; - if (match[ 1]) token.type = "string" , token.closed = !!(match[3] || match[4]); - else if (match[ 5]) token.type = "comment"; - else if (match[ 6]) token.type = "comment", token.closed = !!match[7]; - else if (match[ 8]) token.type = "regex"; - else if (match[ 9]) token.type = "number"; - else if (match[10]) token.type = "name"; - else if (match[11]) token.type = "punctuator"; - else if (match[12]) token.type = "whitespace"; - return token -}; - -var lib$2 = {}; - -var identifier = {}; - -Object.defineProperty(identifier, "__esModule", { - value: true -}); -identifier.isIdentifierStart = isIdentifierStart; -identifier.isIdentifierChar = isIdentifierChar; -identifier.isIdentifierName = isIdentifierName; -let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08c7\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\u9ffc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7ca\ua7f5-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; -let nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf\u1ac0\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; -const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); -const nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); -nonASCIIidentifierStartChars = nonASCIIidentifierChars = null; -const astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 349, 41, 7, 1, 79, 28, 11, 0, 9, 21, 107, 20, 28, 22, 13, 52, 76, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 85, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 230, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 35, 56, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 190, 0, 80, 921, 103, 110, 18, 195, 2749, 1070, 4050, 582, 8634, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 43, 8, 8952, 286, 50, 2, 18, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 2357, 44, 11, 6, 17, 0, 370, 43, 1301, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42717, 35, 4148, 12, 221, 3, 5761, 15, 7472, 3104, 541, 1507, 4938]; -const astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 154, 10, 176, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 161, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 19306, 9, 135, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 262, 6, 10, 9, 419, 13, 1495, 6, 110, 6, 6, 9, 4759, 9, 787719, 239]; - -function isInAstralSet(code, set) { - let pos = 0x10000; - - for (let i = 0, length = set.length; i < length; i += 2) { - pos += set[i]; - if (pos > code) return false; - pos += set[i + 1]; - if (pos >= code) return true; - } - - return false; -} - -function isIdentifierStart(code) { - if (code < 65) return code === 36; - if (code <= 90) return true; - if (code < 97) return code === 95; - if (code <= 122) return true; - - if (code <= 0xffff) { - return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)); - } - - return isInAstralSet(code, astralIdentifierStartCodes); -} - -function isIdentifierChar(code) { - if (code < 48) return code === 36; - if (code < 58) return true; - if (code < 65) return false; - if (code <= 90) return true; - if (code < 97) return code === 95; - if (code <= 122) return true; - - if (code <= 0xffff) { - return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)); - } - - return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes); -} - -function isIdentifierName(name) { - let isFirst = true; - - for (let i = 0; i < name.length; i++) { - let cp = name.charCodeAt(i); - - if ((cp & 0xfc00) === 0xd800 && i + 1 < name.length) { - const trail = name.charCodeAt(++i); - - if ((trail & 0xfc00) === 0xdc00) { - cp = 0x10000 + ((cp & 0x3ff) << 10) + (trail & 0x3ff); - } - } - - if (isFirst) { - isFirst = false; - - if (!isIdentifierStart(cp)) { - return false; - } - } else if (!isIdentifierChar(cp)) { - return false; - } - } - - return !isFirst; -} - -var keyword = {}; - -Object.defineProperty(keyword, "__esModule", { - value: true -}); -keyword.isReservedWord = isReservedWord; -keyword.isStrictReservedWord = isStrictReservedWord; -keyword.isStrictBindOnlyReservedWord = isStrictBindOnlyReservedWord; -keyword.isStrictBindReservedWord = isStrictBindReservedWord; -keyword.isKeyword = isKeyword; -const reservedWords = { - keyword: ["break", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "false", "in", "instanceof", "typeof", "void", "delete"], - strict: ["implements", "interface", "let", "package", "private", "protected", "public", "static", "yield"], - strictBind: ["eval", "arguments"] -}; -const keywords$1 = new Set(reservedWords.keyword); -const reservedWordsStrictSet = new Set(reservedWords.strict); -const reservedWordsStrictBindSet = new Set(reservedWords.strictBind); - -function isReservedWord(word, inModule) { - return inModule && word === "await" || word === "enum"; -} - -function isStrictReservedWord(word, inModule) { - return isReservedWord(word, inModule) || reservedWordsStrictSet.has(word); -} - -function isStrictBindOnlyReservedWord(word) { - return reservedWordsStrictBindSet.has(word); -} - -function isStrictBindReservedWord(word, inModule) { - return isStrictReservedWord(word, inModule) || isStrictBindOnlyReservedWord(word); -} - -function isKeyword(word) { - return keywords$1.has(word); -} - -(function (exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "isIdentifierName", { - enumerable: true, - get: function () { - return _identifier.isIdentifierName; - } -}); -Object.defineProperty(exports, "isIdentifierChar", { - enumerable: true, - get: function () { - return _identifier.isIdentifierChar; - } -}); -Object.defineProperty(exports, "isIdentifierStart", { - enumerable: true, - get: function () { - return _identifier.isIdentifierStart; - } -}); -Object.defineProperty(exports, "isReservedWord", { - enumerable: true, - get: function () { - return _keyword.isReservedWord; - } -}); -Object.defineProperty(exports, "isStrictBindOnlyReservedWord", { - enumerable: true, - get: function () { - return _keyword.isStrictBindOnlyReservedWord; - } -}); -Object.defineProperty(exports, "isStrictBindReservedWord", { - enumerable: true, - get: function () { - return _keyword.isStrictBindReservedWord; - } -}); -Object.defineProperty(exports, "isStrictReservedWord", { - enumerable: true, - get: function () { - return _keyword.isStrictReservedWord; - } -}); -Object.defineProperty(exports, "isKeyword", { - enumerable: true, - get: function () { - return _keyword.isKeyword; - } -}); - -var _identifier = identifier; - -var _keyword = keyword; -}(lib$2)); - -var chalk = {exports: {}}; - -var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; - -var escapeStringRegexp$1 = function (str) { - if (typeof str !== 'string') { - throw new TypeError('Expected a string'); - } - - return str.replace(matchOperatorsRe, '\\$&'); -}; - -var ansiStyles = {exports: {}}; - -var conversions$2 = {exports: {}}; - -var colorName = { - "aliceblue": [240, 248, 255], - "antiquewhite": [250, 235, 215], - "aqua": [0, 255, 255], - "aquamarine": [127, 255, 212], - "azure": [240, 255, 255], - "beige": [245, 245, 220], - "bisque": [255, 228, 196], - "black": [0, 0, 0], - "blanchedalmond": [255, 235, 205], - "blue": [0, 0, 255], - "blueviolet": [138, 43, 226], - "brown": [165, 42, 42], - "burlywood": [222, 184, 135], - "cadetblue": [95, 158, 160], - "chartreuse": [127, 255, 0], - "chocolate": [210, 105, 30], - "coral": [255, 127, 80], - "cornflowerblue": [100, 149, 237], - "cornsilk": [255, 248, 220], - "crimson": [220, 20, 60], - "cyan": [0, 255, 255], - "darkblue": [0, 0, 139], - "darkcyan": [0, 139, 139], - "darkgoldenrod": [184, 134, 11], - "darkgray": [169, 169, 169], - "darkgreen": [0, 100, 0], - "darkgrey": [169, 169, 169], - "darkkhaki": [189, 183, 107], - "darkmagenta": [139, 0, 139], - "darkolivegreen": [85, 107, 47], - "darkorange": [255, 140, 0], - "darkorchid": [153, 50, 204], - "darkred": [139, 0, 0], - "darksalmon": [233, 150, 122], - "darkseagreen": [143, 188, 143], - "darkslateblue": [72, 61, 139], - "darkslategray": [47, 79, 79], - "darkslategrey": [47, 79, 79], - "darkturquoise": [0, 206, 209], - "darkviolet": [148, 0, 211], - "deeppink": [255, 20, 147], - "deepskyblue": [0, 191, 255], - "dimgray": [105, 105, 105], - "dimgrey": [105, 105, 105], - "dodgerblue": [30, 144, 255], - "firebrick": [178, 34, 34], - "floralwhite": [255, 250, 240], - "forestgreen": [34, 139, 34], - "fuchsia": [255, 0, 255], - "gainsboro": [220, 220, 220], - "ghostwhite": [248, 248, 255], - "gold": [255, 215, 0], - "goldenrod": [218, 165, 32], - "gray": [128, 128, 128], - "green": [0, 128, 0], - "greenyellow": [173, 255, 47], - "grey": [128, 128, 128], - "honeydew": [240, 255, 240], - "hotpink": [255, 105, 180], - "indianred": [205, 92, 92], - "indigo": [75, 0, 130], - "ivory": [255, 255, 240], - "khaki": [240, 230, 140], - "lavender": [230, 230, 250], - "lavenderblush": [255, 240, 245], - "lawngreen": [124, 252, 0], - "lemonchiffon": [255, 250, 205], - "lightblue": [173, 216, 230], - "lightcoral": [240, 128, 128], - "lightcyan": [224, 255, 255], - "lightgoldenrodyellow": [250, 250, 210], - "lightgray": [211, 211, 211], - "lightgreen": [144, 238, 144], - "lightgrey": [211, 211, 211], - "lightpink": [255, 182, 193], - "lightsalmon": [255, 160, 122], - "lightseagreen": [32, 178, 170], - "lightskyblue": [135, 206, 250], - "lightslategray": [119, 136, 153], - "lightslategrey": [119, 136, 153], - "lightsteelblue": [176, 196, 222], - "lightyellow": [255, 255, 224], - "lime": [0, 255, 0], - "limegreen": [50, 205, 50], - "linen": [250, 240, 230], - "magenta": [255, 0, 255], - "maroon": [128, 0, 0], - "mediumaquamarine": [102, 205, 170], - "mediumblue": [0, 0, 205], - "mediumorchid": [186, 85, 211], - "mediumpurple": [147, 112, 219], - "mediumseagreen": [60, 179, 113], - "mediumslateblue": [123, 104, 238], - "mediumspringgreen": [0, 250, 154], - "mediumturquoise": [72, 209, 204], - "mediumvioletred": [199, 21, 133], - "midnightblue": [25, 25, 112], - "mintcream": [245, 255, 250], - "mistyrose": [255, 228, 225], - "moccasin": [255, 228, 181], - "navajowhite": [255, 222, 173], - "navy": [0, 0, 128], - "oldlace": [253, 245, 230], - "olive": [128, 128, 0], - "olivedrab": [107, 142, 35], - "orange": [255, 165, 0], - "orangered": [255, 69, 0], - "orchid": [218, 112, 214], - "palegoldenrod": [238, 232, 170], - "palegreen": [152, 251, 152], - "paleturquoise": [175, 238, 238], - "palevioletred": [219, 112, 147], - "papayawhip": [255, 239, 213], - "peachpuff": [255, 218, 185], - "peru": [205, 133, 63], - "pink": [255, 192, 203], - "plum": [221, 160, 221], - "powderblue": [176, 224, 230], - "purple": [128, 0, 128], - "rebeccapurple": [102, 51, 153], - "red": [255, 0, 0], - "rosybrown": [188, 143, 143], - "royalblue": [65, 105, 225], - "saddlebrown": [139, 69, 19], - "salmon": [250, 128, 114], - "sandybrown": [244, 164, 96], - "seagreen": [46, 139, 87], - "seashell": [255, 245, 238], - "sienna": [160, 82, 45], - "silver": [192, 192, 192], - "skyblue": [135, 206, 235], - "slateblue": [106, 90, 205], - "slategray": [112, 128, 144], - "slategrey": [112, 128, 144], - "snow": [255, 250, 250], - "springgreen": [0, 255, 127], - "steelblue": [70, 130, 180], - "tan": [210, 180, 140], - "teal": [0, 128, 128], - "thistle": [216, 191, 216], - "tomato": [255, 99, 71], - "turquoise": [64, 224, 208], - "violet": [238, 130, 238], - "wheat": [245, 222, 179], - "white": [255, 255, 255], - "whitesmoke": [245, 245, 245], - "yellow": [255, 255, 0], - "yellowgreen": [154, 205, 50] -}; - -/* MIT license */ - -var cssKeywords = colorName; - -// NOTE: conversions should only return primitive values (i.e. arrays, or -// values that give correct `typeof` results). -// do not use box values types (i.e. Number(), String(), etc.) - -var reverseKeywords = {}; -for (var key$1 in cssKeywords) { - if (cssKeywords.hasOwnProperty(key$1)) { - reverseKeywords[cssKeywords[key$1]] = key$1; - } -} - -var convert$2 = conversions$2.exports = { - rgb: {channels: 3, labels: 'rgb'}, - hsl: {channels: 3, labels: 'hsl'}, - hsv: {channels: 3, labels: 'hsv'}, - hwb: {channels: 3, labels: 'hwb'}, - cmyk: {channels: 4, labels: 'cmyk'}, - xyz: {channels: 3, labels: 'xyz'}, - lab: {channels: 3, labels: 'lab'}, - lch: {channels: 3, labels: 'lch'}, - hex: {channels: 1, labels: ['hex']}, - keyword: {channels: 1, labels: ['keyword']}, - ansi16: {channels: 1, labels: ['ansi16']}, - ansi256: {channels: 1, labels: ['ansi256']}, - hcg: {channels: 3, labels: ['h', 'c', 'g']}, - apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, - gray: {channels: 1, labels: ['gray']} -}; - -// hide .channels and .labels properties -for (var model in convert$2) { - if (convert$2.hasOwnProperty(model)) { - if (!('channels' in convert$2[model])) { - throw new Error('missing channels property: ' + model); - } - - if (!('labels' in convert$2[model])) { - throw new Error('missing channel labels property: ' + model); - } - - if (convert$2[model].labels.length !== convert$2[model].channels) { - throw new Error('channel and label counts mismatch: ' + model); - } - - var channels = convert$2[model].channels; - var labels$1 = convert$2[model].labels; - delete convert$2[model].channels; - delete convert$2[model].labels; - Object.defineProperty(convert$2[model], 'channels', {value: channels}); - Object.defineProperty(convert$2[model], 'labels', {value: labels$1}); - } -} - -convert$2.rgb.hsl = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var min = Math.min(r, g, b); - var max = Math.max(r, g, b); - var delta = max - min; - var h; - var s; - var l; - - if (max === min) { - h = 0; - } else if (r === max) { - h = (g - b) / delta; - } else if (g === max) { - h = 2 + (b - r) / delta; - } else if (b === max) { - h = 4 + (r - g) / delta; - } - - h = Math.min(h * 60, 360); - - if (h < 0) { - h += 360; - } - - l = (min + max) / 2; - - if (max === min) { - s = 0; - } else if (l <= 0.5) { - s = delta / (max + min); - } else { - s = delta / (2 - max - min); - } - - return [h, s * 100, l * 100]; -}; - -convert$2.rgb.hsv = function (rgb) { - var rdif; - var gdif; - var bdif; - var h; - var s; - - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var v = Math.max(r, g, b); - var diff = v - Math.min(r, g, b); - var diffc = function (c) { - return (v - c) / 6 / diff + 1 / 2; - }; - - if (diff === 0) { - h = s = 0; - } else { - s = diff / v; - rdif = diffc(r); - gdif = diffc(g); - bdif = diffc(b); - - if (r === v) { - h = bdif - gdif; - } else if (g === v) { - h = (1 / 3) + rdif - bdif; - } else if (b === v) { - h = (2 / 3) + gdif - rdif; - } - if (h < 0) { - h += 1; - } else if (h > 1) { - h -= 1; - } - } - - return [ - h * 360, - s * 100, - v * 100 - ]; -}; - -convert$2.rgb.hwb = function (rgb) { - var r = rgb[0]; - var g = rgb[1]; - var b = rgb[2]; - var h = convert$2.rgb.hsl(rgb)[0]; - var w = 1 / 255 * Math.min(r, Math.min(g, b)); - - b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); - - return [h, w * 100, b * 100]; -}; - -convert$2.rgb.cmyk = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var c; - var m; - var y; - var k; - - k = Math.min(1 - r, 1 - g, 1 - b); - c = (1 - r - k) / (1 - k) || 0; - m = (1 - g - k) / (1 - k) || 0; - y = (1 - b - k) / (1 - k) || 0; - - return [c * 100, m * 100, y * 100, k * 100]; -}; - -/** - * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance - * */ -function comparativeDistance(x, y) { - return ( - Math.pow(x[0] - y[0], 2) + - Math.pow(x[1] - y[1], 2) + - Math.pow(x[2] - y[2], 2) - ); -} - -convert$2.rgb.keyword = function (rgb) { - var reversed = reverseKeywords[rgb]; - if (reversed) { - return reversed; - } - - var currentClosestDistance = Infinity; - var currentClosestKeyword; - - for (var keyword in cssKeywords) { - if (cssKeywords.hasOwnProperty(keyword)) { - var value = cssKeywords[keyword]; - - // Compute comparative distance - var distance = comparativeDistance(rgb, value); - - // Check if its less, if so set as closest - if (distance < currentClosestDistance) { - currentClosestDistance = distance; - currentClosestKeyword = keyword; - } - } - } - - return currentClosestKeyword; -}; - -convert$2.keyword.rgb = function (keyword) { - return cssKeywords[keyword]; -}; - -convert$2.rgb.xyz = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - - // assume sRGB - r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); - g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); - b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); - - var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); - var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); - var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); - - return [x * 100, y * 100, z * 100]; -}; - -convert$2.rgb.lab = function (rgb) { - var xyz = convert$2.rgb.xyz(rgb); - var x = xyz[0]; - var y = xyz[1]; - var z = xyz[2]; - var l; - var a; - var b; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); - - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); - - return [l, a, b]; -}; - -convert$2.hsl.rgb = function (hsl) { - var h = hsl[0] / 360; - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var t1; - var t2; - var t3; - var rgb; - var val; - - if (s === 0) { - val = l * 255; - return [val, val, val]; - } - - if (l < 0.5) { - t2 = l * (1 + s); - } else { - t2 = l + s - l * s; - } - - t1 = 2 * l - t2; - - rgb = [0, 0, 0]; - for (var i = 0; i < 3; i++) { - t3 = h + 1 / 3 * -(i - 1); - if (t3 < 0) { - t3++; - } - if (t3 > 1) { - t3--; - } - - if (6 * t3 < 1) { - val = t1 + (t2 - t1) * 6 * t3; - } else if (2 * t3 < 1) { - val = t2; - } else if (3 * t3 < 2) { - val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; - } else { - val = t1; - } - - rgb[i] = val * 255; - } - - return rgb; -}; - -convert$2.hsl.hsv = function (hsl) { - var h = hsl[0]; - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var smin = s; - var lmin = Math.max(l, 0.01); - var sv; - var v; - - l *= 2; - s *= (l <= 1) ? l : 2 - l; - smin *= lmin <= 1 ? lmin : 2 - lmin; - v = (l + s) / 2; - sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); - - return [h, sv * 100, v * 100]; -}; - -convert$2.hsv.rgb = function (hsv) { - var h = hsv[0] / 60; - var s = hsv[1] / 100; - var v = hsv[2] / 100; - var hi = Math.floor(h) % 6; - - var f = h - Math.floor(h); - var p = 255 * v * (1 - s); - var q = 255 * v * (1 - (s * f)); - var t = 255 * v * (1 - (s * (1 - f))); - v *= 255; - - switch (hi) { - case 0: - return [v, t, p]; - case 1: - return [q, v, p]; - case 2: - return [p, v, t]; - case 3: - return [p, q, v]; - case 4: - return [t, p, v]; - case 5: - return [v, p, q]; - } -}; - -convert$2.hsv.hsl = function (hsv) { - var h = hsv[0]; - var s = hsv[1] / 100; - var v = hsv[2] / 100; - var vmin = Math.max(v, 0.01); - var lmin; - var sl; - var l; - - l = (2 - s) * v; - lmin = (2 - s) * vmin; - sl = s * vmin; - sl /= (lmin <= 1) ? lmin : 2 - lmin; - sl = sl || 0; - l /= 2; - - return [h, sl * 100, l * 100]; -}; - -// http://dev.w3.org/csswg/css-color/#hwb-to-rgb -convert$2.hwb.rgb = function (hwb) { - var h = hwb[0] / 360; - var wh = hwb[1] / 100; - var bl = hwb[2] / 100; - var ratio = wh + bl; - var i; - var v; - var f; - var n; - - // wh + bl cant be > 1 - if (ratio > 1) { - wh /= ratio; - bl /= ratio; - } - - i = Math.floor(6 * h); - v = 1 - bl; - f = 6 * h - i; - - if ((i & 0x01) !== 0) { - f = 1 - f; - } - - n = wh + f * (v - wh); // linear interpolation - - var r; - var g; - var b; - switch (i) { - default: - case 6: - case 0: r = v; g = n; b = wh; break; - case 1: r = n; g = v; b = wh; break; - case 2: r = wh; g = v; b = n; break; - case 3: r = wh; g = n; b = v; break; - case 4: r = n; g = wh; b = v; break; - case 5: r = v; g = wh; b = n; break; - } - - return [r * 255, g * 255, b * 255]; -}; - -convert$2.cmyk.rgb = function (cmyk) { - var c = cmyk[0] / 100; - var m = cmyk[1] / 100; - var y = cmyk[2] / 100; - var k = cmyk[3] / 100; - var r; - var g; - var b; - - r = 1 - Math.min(1, c * (1 - k) + k); - g = 1 - Math.min(1, m * (1 - k) + k); - b = 1 - Math.min(1, y * (1 - k) + k); - - return [r * 255, g * 255, b * 255]; -}; - -convert$2.xyz.rgb = function (xyz) { - var x = xyz[0] / 100; - var y = xyz[1] / 100; - var z = xyz[2] / 100; - var r; - var g; - var b; - - r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); - g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); - b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); - - // assume sRGB - r = r > 0.0031308 - ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) - : r * 12.92; - - g = g > 0.0031308 - ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) - : g * 12.92; - - b = b > 0.0031308 - ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) - : b * 12.92; - - r = Math.min(Math.max(0, r), 1); - g = Math.min(Math.max(0, g), 1); - b = Math.min(Math.max(0, b), 1); - - return [r * 255, g * 255, b * 255]; -}; - -convert$2.xyz.lab = function (xyz) { - var x = xyz[0]; - var y = xyz[1]; - var z = xyz[2]; - var l; - var a; - var b; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); - - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); - - return [l, a, b]; -}; - -convert$2.lab.xyz = function (lab) { - var l = lab[0]; - var a = lab[1]; - var b = lab[2]; - var x; - var y; - var z; - - y = (l + 16) / 116; - x = a / 500 + y; - z = y - b / 200; - - var y2 = Math.pow(y, 3); - var x2 = Math.pow(x, 3); - var z2 = Math.pow(z, 3); - y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; - x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; - z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; - - x *= 95.047; - y *= 100; - z *= 108.883; - - return [x, y, z]; -}; - -convert$2.lab.lch = function (lab) { - var l = lab[0]; - var a = lab[1]; - var b = lab[2]; - var hr; - var h; - var c; - - hr = Math.atan2(b, a); - h = hr * 360 / 2 / Math.PI; - - if (h < 0) { - h += 360; - } - - c = Math.sqrt(a * a + b * b); - - return [l, c, h]; -}; - -convert$2.lch.lab = function (lch) { - var l = lch[0]; - var c = lch[1]; - var h = lch[2]; - var a; - var b; - var hr; - - hr = h / 360 * 2 * Math.PI; - a = c * Math.cos(hr); - b = c * Math.sin(hr); - - return [l, a, b]; -}; - -convert$2.rgb.ansi16 = function (args) { - var r = args[0]; - var g = args[1]; - var b = args[2]; - var value = 1 in arguments ? arguments[1] : convert$2.rgb.hsv(args)[2]; // hsv -> ansi16 optimization - - value = Math.round(value / 50); - - if (value === 0) { - return 30; - } - - var ansi = 30 - + ((Math.round(b / 255) << 2) - | (Math.round(g / 255) << 1) - | Math.round(r / 255)); - - if (value === 2) { - ansi += 60; - } - - return ansi; -}; - -convert$2.hsv.ansi16 = function (args) { - // optimization here; we already know the value and don't need to get - // it converted for us. - return convert$2.rgb.ansi16(convert$2.hsv.rgb(args), args[2]); -}; - -convert$2.rgb.ansi256 = function (args) { - var r = args[0]; - var g = args[1]; - var b = args[2]; - - // we use the extended greyscale palette here, with the exception of - // black and white. normal palette only has 4 greyscale shades. - if (r === g && g === b) { - if (r < 8) { - return 16; - } - - if (r > 248) { - return 231; - } - - return Math.round(((r - 8) / 247) * 24) + 232; - } - - var ansi = 16 - + (36 * Math.round(r / 255 * 5)) - + (6 * Math.round(g / 255 * 5)) - + Math.round(b / 255 * 5); - - return ansi; -}; - -convert$2.ansi16.rgb = function (args) { - var color = args % 10; - - // handle greyscale - if (color === 0 || color === 7) { - if (args > 50) { - color += 3.5; - } - - color = color / 10.5 * 255; - - return [color, color, color]; - } - - var mult = (~~(args > 50) + 1) * 0.5; - var r = ((color & 1) * mult) * 255; - var g = (((color >> 1) & 1) * mult) * 255; - var b = (((color >> 2) & 1) * mult) * 255; - - return [r, g, b]; -}; - -convert$2.ansi256.rgb = function (args) { - // handle greyscale - if (args >= 232) { - var c = (args - 232) * 10 + 8; - return [c, c, c]; - } - - args -= 16; - - var rem; - var r = Math.floor(args / 36) / 5 * 255; - var g = Math.floor((rem = args % 36) / 6) / 5 * 255; - var b = (rem % 6) / 5 * 255; - - return [r, g, b]; -}; - -convert$2.rgb.hex = function (args) { - var integer = ((Math.round(args[0]) & 0xFF) << 16) - + ((Math.round(args[1]) & 0xFF) << 8) - + (Math.round(args[2]) & 0xFF); - - var string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; - -convert$2.hex.rgb = function (args) { - var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); - if (!match) { - return [0, 0, 0]; - } - - var colorString = match[0]; - - if (match[0].length === 3) { - colorString = colorString.split('').map(function (char) { - return char + char; - }).join(''); - } - - var integer = parseInt(colorString, 16); - var r = (integer >> 16) & 0xFF; - var g = (integer >> 8) & 0xFF; - var b = integer & 0xFF; - - return [r, g, b]; -}; - -convert$2.rgb.hcg = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var max = Math.max(Math.max(r, g), b); - var min = Math.min(Math.min(r, g), b); - var chroma = (max - min); - var grayscale; - var hue; - - if (chroma < 1) { - grayscale = min / (1 - chroma); - } else { - grayscale = 0; - } - - if (chroma <= 0) { - hue = 0; - } else - if (max === r) { - hue = ((g - b) / chroma) % 6; - } else - if (max === g) { - hue = 2 + (b - r) / chroma; - } else { - hue = 4 + (r - g) / chroma + 4; - } - - hue /= 6; - hue %= 1; - - return [hue * 360, chroma * 100, grayscale * 100]; -}; - -convert$2.hsl.hcg = function (hsl) { - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var c = 1; - var f = 0; - - if (l < 0.5) { - c = 2.0 * s * l; - } else { - c = 2.0 * s * (1.0 - l); - } - - if (c < 1.0) { - f = (l - 0.5 * c) / (1.0 - c); - } - - return [hsl[0], c * 100, f * 100]; -}; - -convert$2.hsv.hcg = function (hsv) { - var s = hsv[1] / 100; - var v = hsv[2] / 100; - - var c = s * v; - var f = 0; - - if (c < 1.0) { - f = (v - c) / (1 - c); - } - - return [hsv[0], c * 100, f * 100]; -}; - -convert$2.hcg.rgb = function (hcg) { - var h = hcg[0] / 360; - var c = hcg[1] / 100; - var g = hcg[2] / 100; - - if (c === 0.0) { - return [g * 255, g * 255, g * 255]; - } - - var pure = [0, 0, 0]; - var hi = (h % 1) * 6; - var v = hi % 1; - var w = 1 - v; - var mg = 0; - - switch (Math.floor(hi)) { - case 0: - pure[0] = 1; pure[1] = v; pure[2] = 0; break; - case 1: - pure[0] = w; pure[1] = 1; pure[2] = 0; break; - case 2: - pure[0] = 0; pure[1] = 1; pure[2] = v; break; - case 3: - pure[0] = 0; pure[1] = w; pure[2] = 1; break; - case 4: - pure[0] = v; pure[1] = 0; pure[2] = 1; break; - default: - pure[0] = 1; pure[1] = 0; pure[2] = w; - } - - mg = (1.0 - c) * g; - - return [ - (c * pure[0] + mg) * 255, - (c * pure[1] + mg) * 255, - (c * pure[2] + mg) * 255 - ]; -}; - -convert$2.hcg.hsv = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; - - var v = c + g * (1.0 - c); - var f = 0; - - if (v > 0.0) { - f = c / v; - } - - return [hcg[0], f * 100, v * 100]; -}; - -convert$2.hcg.hsl = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; - - var l = g * (1.0 - c) + 0.5 * c; - var s = 0; - - if (l > 0.0 && l < 0.5) { - s = c / (2 * l); - } else - if (l >= 0.5 && l < 1.0) { - s = c / (2 * (1 - l)); - } - - return [hcg[0], s * 100, l * 100]; -}; - -convert$2.hcg.hwb = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; - var v = c + g * (1.0 - c); - return [hcg[0], (v - c) * 100, (1 - v) * 100]; -}; - -convert$2.hwb.hcg = function (hwb) { - var w = hwb[1] / 100; - var b = hwb[2] / 100; - var v = 1 - b; - var c = v - w; - var g = 0; - - if (c < 1) { - g = (v - c) / (1 - c); - } - - return [hwb[0], c * 100, g * 100]; -}; - -convert$2.apple.rgb = function (apple) { - return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; -}; - -convert$2.rgb.apple = function (rgb) { - return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; -}; - -convert$2.gray.rgb = function (args) { - return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; -}; - -convert$2.gray.hsl = convert$2.gray.hsv = function (args) { - return [0, 0, args[0]]; -}; - -convert$2.gray.hwb = function (gray) { - return [0, 100, gray[0]]; -}; - -convert$2.gray.cmyk = function (gray) { - return [0, 0, 0, gray[0]]; -}; - -convert$2.gray.lab = function (gray) { - return [gray[0], 0, 0]; -}; - -convert$2.gray.hex = function (gray) { - var val = Math.round(gray[0] / 100 * 255) & 0xFF; - var integer = (val << 16) + (val << 8) + val; - - var string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; - -convert$2.rgb.gray = function (rgb) { - var val = (rgb[0] + rgb[1] + rgb[2]) / 3; - return [val / 255 * 100]; -}; - -var conversions$1 = conversions$2.exports; - -/* - this function routes a model to all other models. - - all functions that are routed have a property `.conversion` attached - to the returned synthetic function. This property is an array - of strings, each with the steps in between the 'from' and 'to' - color models (inclusive). - - conversions that are not possible simply are not included. -*/ - -function buildGraph() { - var graph = {}; - // https://jsperf.com/object-keys-vs-for-in-with-closure/3 - var models = Object.keys(conversions$1); - - for (var len = models.length, i = 0; i < len; i++) { - graph[models[i]] = { - // http://jsperf.com/1-vs-infinity - // micro-opt, but this is simple. - distance: -1, - parent: null - }; - } - - return graph; -} - -// https://en.wikipedia.org/wiki/Breadth-first_search -function deriveBFS(fromModel) { - var graph = buildGraph(); - var queue = [fromModel]; // unshift -> queue -> pop - - graph[fromModel].distance = 0; - - while (queue.length) { - var current = queue.pop(); - var adjacents = Object.keys(conversions$1[current]); - - for (var len = adjacents.length, i = 0; i < len; i++) { - var adjacent = adjacents[i]; - var node = graph[adjacent]; - - if (node.distance === -1) { - node.distance = graph[current].distance + 1; - node.parent = current; - queue.unshift(adjacent); - } - } - } - - return graph; -} - -function link$1(from, to) { - return function (args) { - return to(from(args)); - }; -} - -function wrapConversion(toModel, graph) { - var path = [graph[toModel].parent, toModel]; - var fn = conversions$1[graph[toModel].parent][toModel]; - - var cur = graph[toModel].parent; - while (graph[cur].parent) { - path.unshift(graph[cur].parent); - fn = link$1(conversions$1[graph[cur].parent][cur], fn); - cur = graph[cur].parent; - } - - fn.conversion = path; - return fn; -} - -var route$1 = function (fromModel) { - var graph = deriveBFS(fromModel); - var conversion = {}; - - var models = Object.keys(graph); - for (var len = models.length, i = 0; i < len; i++) { - var toModel = models[i]; - var node = graph[toModel]; - - if (node.parent === null) { - // no possible conversion, or this node is the source model. - continue; - } - - conversion[toModel] = wrapConversion(toModel, graph); - } - - return conversion; -}; - -var conversions = conversions$2.exports; -var route = route$1; - -var convert$1 = {}; - -var models = Object.keys(conversions); - -function wrapRaw(fn) { - var wrappedFn = function (args) { - if (args === undefined || args === null) { - return args; - } - - if (arguments.length > 1) { - args = Array.prototype.slice.call(arguments); - } - - return fn(args); - }; - - // preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } - - return wrappedFn; -} - -function wrapRounded(fn) { - var wrappedFn = function (args) { - if (args === undefined || args === null) { - return args; - } - - if (arguments.length > 1) { - args = Array.prototype.slice.call(arguments); - } - - var result = fn(args); - - // we're assuming the result is an array here. - // see notice in conversions.js; don't use box types - // in conversion functions. - if (typeof result === 'object') { - for (var len = result.length, i = 0; i < len; i++) { - result[i] = Math.round(result[i]); - } - } - - return result; - }; - - // preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } - - return wrappedFn; -} - -models.forEach(function (fromModel) { - convert$1[fromModel] = {}; - - Object.defineProperty(convert$1[fromModel], 'channels', {value: conversions[fromModel].channels}); - Object.defineProperty(convert$1[fromModel], 'labels', {value: conversions[fromModel].labels}); - - var routes = route(fromModel); - var routeModels = Object.keys(routes); - - routeModels.forEach(function (toModel) { - var fn = routes[toModel]; - - convert$1[fromModel][toModel] = wrapRounded(fn); - convert$1[fromModel][toModel].raw = wrapRaw(fn); - }); -}); - -var colorConvert = convert$1; - -(function (module) { -const colorConvert$1 = colorConvert; - -const wrapAnsi16 = (fn, offset) => function () { - const code = fn.apply(colorConvert$1, arguments); - return `\u001B[${code + offset}m`; -}; - -const wrapAnsi256 = (fn, offset) => function () { - const code = fn.apply(colorConvert$1, arguments); - return `\u001B[${38 + offset};5;${code}m`; -}; - -const wrapAnsi16m = (fn, offset) => function () { - const rgb = fn.apply(colorConvert$1, arguments); - return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; -}; - -function assembleStyles() { - const codes = new Map(); - const styles = { - modifier: { - reset: [0, 0], - // 21 isn't widely supported and 22 does the same thing - bold: [1, 22], - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29] - }, - color: { - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], - gray: [90, 39], - - // Bright color - redBright: [91, 39], - greenBright: [92, 39], - yellowBright: [93, 39], - blueBright: [94, 39], - magentaBright: [95, 39], - cyanBright: [96, 39], - whiteBright: [97, 39] - }, - bgColor: { - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49], - - // Bright color - bgBlackBright: [100, 49], - bgRedBright: [101, 49], - bgGreenBright: [102, 49], - bgYellowBright: [103, 49], - bgBlueBright: [104, 49], - bgMagentaBright: [105, 49], - bgCyanBright: [106, 49], - bgWhiteBright: [107, 49] - } - }; - - // Fix humans - styles.color.grey = styles.color.gray; - - for (const groupName of Object.keys(styles)) { - const group = styles[groupName]; - - for (const styleName of Object.keys(group)) { - const style = group[styleName]; - - styles[styleName] = { - open: `\u001B[${style[0]}m`, - close: `\u001B[${style[1]}m` - }; - - group[styleName] = styles[styleName]; - - codes.set(style[0], style[1]); - } - - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false - }); - - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false - }); - } - - const ansi2ansi = n => n; - const rgb2rgb = (r, g, b) => [r, g, b]; - - styles.color.close = '\u001B[39m'; - styles.bgColor.close = '\u001B[49m'; - - styles.color.ansi = { - ansi: wrapAnsi16(ansi2ansi, 0) - }; - styles.color.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 0) - }; - styles.color.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 0) - }; - - styles.bgColor.ansi = { - ansi: wrapAnsi16(ansi2ansi, 10) - }; - styles.bgColor.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 10) - }; - styles.bgColor.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 10) - }; - - for (let key of Object.keys(colorConvert$1)) { - if (typeof colorConvert$1[key] !== 'object') { - continue; - } - - const suite = colorConvert$1[key]; - - if (key === 'ansi16') { - key = 'ansi'; - } - - if ('ansi16' in suite) { - styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0); - styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10); - } - - if ('ansi256' in suite) { - styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0); - styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10); - } - - if ('rgb' in suite) { - styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0); - styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10); - } - } - - return styles; -} - -// Make the export immutable -Object.defineProperty(module, 'exports', { - enumerable: true, - get: assembleStyles -}); -}(ansiStyles)); - -var hasFlag$2 = (flag, argv) => { - argv = argv || process.argv; - const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const pos = argv.indexOf(prefix + flag); - const terminatorPos = argv.indexOf('--'); - return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos); -}; - -const os$1 = require$$0$2; -const hasFlag$1 = hasFlag$2; - -const env$1 = process.env; - -let forceColor; -if (hasFlag$1('no-color') || - hasFlag$1('no-colors') || - hasFlag$1('color=false')) { - forceColor = false; -} else if (hasFlag$1('color') || - hasFlag$1('colors') || - hasFlag$1('color=true') || - hasFlag$1('color=always')) { - forceColor = true; -} -if ('FORCE_COLOR' in env$1) { - forceColor = env$1.FORCE_COLOR.length === 0 || parseInt(env$1.FORCE_COLOR, 10) !== 0; -} - -function translateLevel$1(level) { - if (level === 0) { - return false; - } - - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; -} - -function supportsColor$1(stream) { - if (forceColor === false) { - return 0; - } - - if (hasFlag$1('color=16m') || - hasFlag$1('color=full') || - hasFlag$1('color=truecolor')) { - return 3; - } - - if (hasFlag$1('color=256')) { - return 2; - } - - if (stream && !stream.isTTY && forceColor !== true) { - return 0; - } - - const min = forceColor ? 1 : 0; - - if (process.platform === 'win32') { - // Node.js 7.5.0 is the first version of Node.js to include a patch to - // libuv that enables 256 color output on Windows. Anything earlier and it - // won't work. However, here we target Node.js 8 at minimum as it is an LTS - // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows - // release that supports 256 colors. Windows 10 build 14931 is the first release - // that supports 16m/TrueColor. - const osRelease = os$1.release().split('.'); - if ( - Number(process.versions.node.split('.')[0]) >= 8 && - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; - } - - return 1; - } - - if ('CI' in env$1) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env$1) || env$1.CI_NAME === 'codeship') { - return 1; - } - - return min; - } - - if ('TEAMCITY_VERSION' in env$1) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env$1.TEAMCITY_VERSION) ? 1 : 0; - } - - if (env$1.COLORTERM === 'truecolor') { - return 3; - } - - if ('TERM_PROGRAM' in env$1) { - const version = parseInt((env$1.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - - switch (env$1.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default - } - } - - if (/-256(color)?$/i.test(env$1.TERM)) { - return 2; - } - - if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env$1.TERM)) { - return 1; - } - - if ('COLORTERM' in env$1) { - return 1; - } - - if (env$1.TERM === 'dumb') { - return min; - } - - return min; -} - -function getSupportLevel(stream) { - const level = supportsColor$1(stream); - return translateLevel$1(level); -} - -var supportsColor_1 = { - supportsColor: getSupportLevel, - stdout: getSupportLevel(process.stdout), - stderr: getSupportLevel(process.stderr) -}; - -const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; -const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; -const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; -const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi; - -const ESCAPES = new Map([ - ['n', '\n'], - ['r', '\r'], - ['t', '\t'], - ['b', '\b'], - ['f', '\f'], - ['v', '\v'], - ['0', '\0'], - ['\\', '\\'], - ['e', '\u001B'], - ['a', '\u0007'] -]); - -function unescape(c) { - if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { - return String.fromCharCode(parseInt(c.slice(1), 16)); - } - - return ESCAPES.get(c) || c; -} - -function parseArguments(name, args) { - const results = []; - const chunks = args.trim().split(/\s*,\s*/g); - let matches; - - for (const chunk of chunks) { - if (!isNaN(chunk)) { - results.push(Number(chunk)); - } else if ((matches = chunk.match(STRING_REGEX))) { - results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr)); - } else { - throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); - } - } - - return results; -} - -function parseStyle(style) { - STYLE_REGEX.lastIndex = 0; - - const results = []; - let matches; - - while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; - - if (matches[2]) { - const args = parseArguments(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); - } - } - - return results; -} - -function buildStyle(chalk, styles) { - const enabled = {}; - - for (const layer of styles) { - for (const style of layer.styles) { - enabled[style[0]] = layer.inverse ? null : style.slice(1); - } - } - - let current = chalk; - for (const styleName of Object.keys(enabled)) { - if (Array.isArray(enabled[styleName])) { - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } - - if (enabled[styleName].length > 0) { - current = current[styleName].apply(current, enabled[styleName]); - } else { - current = current[styleName]; - } - } - } - - return current; -} - -var templates = (chalk, tmp) => { - const styles = []; - const chunks = []; - let chunk = []; - - // eslint-disable-next-line max-params - tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { - if (escapeChar) { - chunk.push(unescape(escapeChar)); - } else if (style) { - const str = chunk.join(''); - chunk = []; - chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); - styles.push({inverse, styles: parseStyle(style)}); - } else if (close) { - if (styles.length === 0) { - throw new Error('Found extraneous } in Chalk template literal'); - } - - chunks.push(buildStyle(chalk, styles)(chunk.join(''))); - chunk = []; - styles.pop(); - } else { - chunk.push(chr); - } - }); - - chunks.push(chunk.join('')); - - if (styles.length > 0) { - const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMsg); - } - - return chunks.join(''); -}; - -(function (module) { -const escapeStringRegexp = escapeStringRegexp$1; -const ansiStyles$1 = ansiStyles.exports; -const stdoutColor = supportsColor_1.stdout; - -const template = templates; - -const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); - -// `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; - -// `color-convert` models to exclude from the Chalk API due to conflicts and such -const skipModels = new Set(['gray']); - -const styles = Object.create(null); - -function applyOptions(obj, options) { - options = options || {}; - - // Detect level if not set manually - const scLevel = stdoutColor ? stdoutColor.level : 0; - obj.level = options.level === undefined ? scLevel : options.level; - obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; -} - -function Chalk(options) { - // We check for this.template here since calling `chalk.constructor()` - // by itself will have a `this` of a previously constructed chalk object - if (!this || !(this instanceof Chalk) || this.template) { - const chalk = {}; - applyOptions(chalk, options); - - chalk.template = function () { - const args = [].slice.call(arguments); - return chalkTag.apply(null, [chalk.template].concat(args)); - }; - - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); - - chalk.template.constructor = Chalk; - - return chalk.template; - } - - applyOptions(this, options); -} - -// Use bright blue on Windows as the normal blue color is illegible -if (isSimpleWindowsTerm) { - ansiStyles$1.blue.open = '\u001B[94m'; -} - -for (const key of Object.keys(ansiStyles$1)) { - ansiStyles$1[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles$1[key].close), 'g'); - - styles[key] = { - get() { - const codes = ansiStyles$1[key]; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); - } - }; -} - -styles.visible = { - get() { - return build.call(this, this._styles || [], true, 'visible'); - } -}; - -ansiStyles$1.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles$1.color.close), 'g'); -for (const model of Object.keys(ansiStyles$1.color.ansi)) { - if (skipModels.has(model)) { - continue; - } - - styles[model] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles$1.color[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles$1.color.close, - closeRe: ansiStyles$1.color.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; -} - -ansiStyles$1.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles$1.bgColor.close), 'g'); -for (const model of Object.keys(ansiStyles$1.bgColor.ansi)) { - if (skipModels.has(model)) { - continue; - } - - const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); - styles[bgModel] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles$1.bgColor[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles$1.bgColor.close, - closeRe: ansiStyles$1.bgColor.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; -} - -const proto = Object.defineProperties(() => {}, styles); - -function build(_styles, _empty, key) { - const builder = function () { - return applyStyle.apply(builder, arguments); - }; - - builder._styles = _styles; - builder._empty = _empty; - - const self = this; - - Object.defineProperty(builder, 'level', { - enumerable: true, - get() { - return self.level; - }, - set(level) { - self.level = level; - } - }); - - Object.defineProperty(builder, 'enabled', { - enumerable: true, - get() { - return self.enabled; - }, - set(enabled) { - self.enabled = enabled; - } - }); - - // See below for fix regarding invisible grey/dim combination on Windows - builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; - - // `__proto__` is used because we must return a function, but there is - // no way to create a function with a different prototype - builder.__proto__ = proto; // eslint-disable-line no-proto - - return builder; -} - -function applyStyle() { - // Support varags, but simply cast to string in case there's only one arg - const args = arguments; - const argsLen = args.length; - let str = String(arguments[0]); - - if (argsLen === 0) { - return ''; - } - - if (argsLen > 1) { - // Don't slice `arguments`, it prevents V8 optimizations - for (let a = 1; a < argsLen; a++) { - str += ' ' + args[a]; - } - } - - if (!this.enabled || this.level <= 0 || !str) { - return this._empty ? '' : str; - } - - // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, - // see https://github.com/chalk/chalk/issues/58 - // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. - const originalDim = ansiStyles$1.dim.open; - if (isSimpleWindowsTerm && this.hasGrey) { - ansiStyles$1.dim.open = ''; - } - - for (const code of this._styles.slice().reverse()) { - // Replace any instances already present with a re-opening code - // otherwise only the part of the string until said closing code - // will be colored, and the rest will simply be 'plain'. - str = code.open + str.replace(code.closeRe, code.open) + code.close; - - // Close the styling before a linebreak and reopen - // after next line to fix a bleed issue on macOS - // https://github.com/chalk/chalk/pull/92 - str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); - } - - // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue - ansiStyles$1.dim.open = originalDim; - - return str; -} - -function chalkTag(chalk, strings) { - if (!Array.isArray(strings)) { - // If chalk() was called by itself or with a string, - // return the string itself as a string. - return [].slice.call(arguments, 1).join(' '); - } - - const args = [].slice.call(arguments, 2); - const parts = [strings.raw[0]]; - - for (let i = 1; i < strings.length; i++) { - parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); - parts.push(String(strings.raw[i])); - } - - return template(chalk, parts.join('')); -} - -Object.defineProperties(Chalk.prototype, styles); - -module.exports = Chalk(); // eslint-disable-line new-cap -module.exports.supportsColor = stdoutColor; -module.exports.default = module.exports; // For TypeScript -}(chalk)); - -Object.defineProperty(lib$3, "__esModule", { - value: true -}); -lib$3.shouldHighlight = shouldHighlight; -lib$3.getChalk = getChalk; -lib$3.default = highlight; - -var _jsTokens = jsTokens; - -var _helperValidatorIdentifier = lib$2; - -var _chalk = chalk.exports; - -const sometimesKeywords = new Set(["as", "async", "from", "get", "of", "set"]); - -function getDefs$1(chalk) { - return { - keyword: chalk.cyan, - capitalized: chalk.yellow, - jsxIdentifier: chalk.yellow, - punctuator: chalk.yellow, - number: chalk.magenta, - string: chalk.green, - regex: chalk.magenta, - comment: chalk.grey, - invalid: chalk.white.bgRed.bold - }; -} - -const NEWLINE$1 = /\r\n|[\n\r\u2028\u2029]/; -const BRACKET = /^[()[\]{}]$/; -let tokenize; -{ - const JSX_TAG = /^[a-z][\w-]*$/i; - - const getTokenType = function (token, offset, text) { - if (token.type === "name") { - if ((0, _helperValidatorIdentifier.isKeyword)(token.value) || (0, _helperValidatorIdentifier.isStrictReservedWord)(token.value, true) || sometimesKeywords.has(token.value)) { - return "keyword"; - } - - if (JSX_TAG.test(token.value) && (text[offset - 1] === "<" || text.substr(offset - 2, 2) == " colorize(str)).join("\n"); - } else { - highlighted += value; - } - } - - return highlighted; -} - -function shouldHighlight(options) { - return !!_chalk.supportsColor || options.forceColor; -} - -function getChalk(options) { - return options.forceColor ? new _chalk.constructor({ - enabled: true, - level: 1 - }) : _chalk; -} - -function highlight(code, options = {}) { - if (shouldHighlight(options)) { - const chalk = getChalk(options); - const defs = getDefs$1(chalk); - return highlightTokens(defs, code); - } else { - return code; - } -} - -Object.defineProperty(lib$4, "__esModule", { - value: true -}); -lib$4.codeFrameColumns = codeFrameColumns$1; -lib$4.default = _default; - -var _highlight = lib$3; - -let deprecationWarningShown = false; - -function getDefs(chalk) { - return { - gutter: chalk.grey, - marker: chalk.red.bold, - message: chalk.red.bold - }; -} - -const NEWLINE = /\r\n|[\n\r\u2028\u2029]/; - -function getMarkerLines(loc, source, opts) { - const startLoc = Object.assign({ - column: 0, - line: -1 - }, loc.start); - const endLoc = Object.assign({}, startLoc, loc.end); - const { - linesAbove = 2, - linesBelow = 3 - } = opts || {}; - const startLine = startLoc.line; - const startColumn = startLoc.column; - const endLine = endLoc.line; - const endColumn = endLoc.column; - let start = Math.max(startLine - (linesAbove + 1), 0); - let end = Math.min(source.length, endLine + linesBelow); - - if (startLine === -1) { - start = 0; - } - - if (endLine === -1) { - end = source.length; - } - - const lineDiff = endLine - startLine; - const markerLines = {}; - - if (lineDiff) { - for (let i = 0; i <= lineDiff; i++) { - const lineNumber = i + startLine; - - if (!startColumn) { - markerLines[lineNumber] = true; - } else if (i === 0) { - const sourceLength = source[lineNumber - 1].length; - markerLines[lineNumber] = [startColumn, sourceLength - startColumn + 1]; - } else if (i === lineDiff) { - markerLines[lineNumber] = [0, endColumn]; - } else { - const sourceLength = source[lineNumber - i].length; - markerLines[lineNumber] = [0, sourceLength]; - } - } - } else { - if (startColumn === endColumn) { - if (startColumn) { - markerLines[startLine] = [startColumn, 0]; - } else { - markerLines[startLine] = true; - } - } else { - markerLines[startLine] = [startColumn, endColumn - startColumn]; - } - } - - return { - start, - end, - markerLines - }; -} - -function codeFrameColumns$1(rawLines, loc, opts = {}) { - const highlighted = (opts.highlightCode || opts.forceColor) && (0, _highlight.shouldHighlight)(opts); - const chalk = (0, _highlight.getChalk)(opts); - const defs = getDefs(chalk); - - const maybeHighlight = (chalkFn, string) => { - return highlighted ? chalkFn(string) : string; - }; - - const lines = rawLines.split(NEWLINE); - const { - start, - end, - markerLines - } = getMarkerLines(loc, lines, opts); - const hasColumns = loc.start && typeof loc.start.column === "number"; - const numberMaxWidth = String(end).length; - const highlightedLines = highlighted ? (0, _highlight.default)(rawLines, opts) : rawLines; - let frame = highlightedLines.split(NEWLINE).slice(start, end).map((line, index) => { - const number = start + 1 + index; - const paddedNumber = ` ${number}`.slice(-numberMaxWidth); - const gutter = ` ${paddedNumber} |`; - const hasMarker = markerLines[number]; - const lastMarkerLine = !markerLines[number + 1]; - - if (hasMarker) { - let markerLine = ""; - - if (Array.isArray(hasMarker)) { - const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).replace(/[^\t]/g, " "); - const numberOfMarkers = hasMarker[1] || 1; - markerLine = ["\n ", maybeHighlight(defs.gutter, gutter.replace(/\d/g, " ")), " ", markerSpacing, maybeHighlight(defs.marker, "^").repeat(numberOfMarkers)].join(""); - - if (lastMarkerLine && opts.message) { - markerLine += " " + maybeHighlight(defs.message, opts.message); - } - } - - return [maybeHighlight(defs.marker, ">"), maybeHighlight(defs.gutter, gutter), line.length > 0 ? ` ${line}` : "", markerLine].join(""); - } else { - return ` ${maybeHighlight(defs.gutter, gutter)}${line.length > 0 ? ` ${line}` : ""}`; - } - }).join("\n"); - - if (opts.message && !hasColumns) { - frame = `${" ".repeat(numberMaxWidth + 1)}${opts.message}\n${frame}`; - } - - if (highlighted) { - return chalk.reset(frame); - } else { - return frame; - } -} - -function _default(rawLines, lineNumber, colNumber, opts = {}) { - if (!deprecationWarningShown) { - deprecationWarningShown = true; - const message = "Passing lineNumber and colNumber is deprecated to @babel/code-frame. Please use `codeFrameColumns`."; - - if (process.emitWarning) { - process.emitWarning(message, "DeprecationWarning"); - } else { - const deprecationError = new Error(message); - deprecationError.name = "DeprecationWarning"; - console.warn(new Error(message)); - } - } - - colNumber = Math.max(colNumber, 0); - const location = { - start: { - column: colNumber, - line: lineNumber - } - }; - return codeFrameColumns$1(rawLines, location, opts); -} - -const errorEx = errorEx_1; -const fallback = jsonParseEvenBetterErrors; -const {default: LinesAndColumns} = require$$2; -const {codeFrameColumns} = lib$4; - -const JSONError = errorEx('JSONError', { - fileName: errorEx.append('in %s'), - codeFrame: errorEx.append('\n\n%s\n') -}); - -const parseJson = (string, reviver, filename) => { - if (typeof reviver === 'string') { - filename = reviver; - reviver = null; - } - - try { - try { - return JSON.parse(string, reviver); - } catch (error) { - fallback(string, reviver); - throw error; - } - } catch (error) { - error.message = error.message.replace(/\n/g, ''); - const indexMatch = error.message.match(/in JSON at position (\d+) while parsing/); - - const jsonError = new JSONError(error); - if (filename) { - jsonError.fileName = filename; - } - - if (indexMatch && indexMatch.length > 0) { - const lines = new LinesAndColumns(string); - const index = Number(indexMatch[1]); - const location = lines.locationForIndex(index); - - const codeFrame = codeFrameColumns( - string, - {start: {line: location.line + 1, column: location.column + 1}}, - {highlightCode: true} - ); - - jsonError.codeFrame = codeFrame; - } - - throw jsonError; - } -}; - -parseJson.JSONError = JSONError; - -var parseJson_1 = parseJson; - -var src = {exports: {}}; - -var browser = {exports: {}}; - -/** - * Helpers. - */ - -var s = 1000; -var m = s * 60; -var h = m * 60; -var d = h * 24; -var w = d * 7; -var y = d * 365.25; - -/** - * Parse or format the given `val`. - * - * Options: - * - * - `long` verbose formatting [false] - * - * @param {String|Number} val - * @param {Object} [options] - * @throws {Error} throw an error if val is not a non-empty string or a number - * @return {String|Number} - * @api public - */ - -var ms = function(val, options) { - options = options || {}; - var type = typeof val; - if (type === 'string' && val.length > 0) { - return parse$a(val); - } else if (type === 'number' && isFinite(val)) { - return options.long ? fmtLong(val) : fmtShort(val); - } - throw new Error( - 'val is not a non-empty string or a valid number. val=' + - JSON.stringify(val) - ); -}; - -/** - * Parse the given `str` and return milliseconds. - * - * @param {String} str - * @return {Number} - * @api private - */ - -function parse$a(str) { - str = String(str); - if (str.length > 100) { - return; - } - var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( - str - ); - if (!match) { - return; - } - var n = parseFloat(match[1]); - var type = (match[2] || 'ms').toLowerCase(); - switch (type) { - case 'years': - case 'year': - case 'yrs': - case 'yr': - case 'y': - return n * y; - case 'weeks': - case 'week': - case 'w': - return n * w; - case 'days': - case 'day': - case 'd': - return n * d; - case 'hours': - case 'hour': - case 'hrs': - case 'hr': - case 'h': - return n * h; - case 'minutes': - case 'minute': - case 'mins': - case 'min': - case 'm': - return n * m; - case 'seconds': - case 'second': - case 'secs': - case 'sec': - case 's': - return n * s; - case 'milliseconds': - case 'millisecond': - case 'msecs': - case 'msec': - case 'ms': - return n; - default: - return undefined; - } -} - -/** - * Short format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - -function fmtShort(ms) { - var msAbs = Math.abs(ms); - if (msAbs >= d) { - return Math.round(ms / d) + 'd'; - } - if (msAbs >= h) { - return Math.round(ms / h) + 'h'; - } - if (msAbs >= m) { - return Math.round(ms / m) + 'm'; - } - if (msAbs >= s) { - return Math.round(ms / s) + 's'; - } - return ms + 'ms'; -} - -/** - * Long format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - -function fmtLong(ms) { - var msAbs = Math.abs(ms); - if (msAbs >= d) { - return plural$1(ms, msAbs, d, 'day'); - } - if (msAbs >= h) { - return plural$1(ms, msAbs, h, 'hour'); - } - if (msAbs >= m) { - return plural$1(ms, msAbs, m, 'minute'); - } - if (msAbs >= s) { - return plural$1(ms, msAbs, s, 'second'); - } - return ms + ' ms'; -} - -/** - * Pluralization helper. - */ - -function plural$1(ms, msAbs, n, name) { - var isPlural = msAbs >= n * 1.5; - return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); -} - -/** - * This is the common logic for both the Node.js and web browser - * implementations of `debug()`. - */ - -function setup(env) { - createDebug.debug = createDebug; - createDebug.default = createDebug; - createDebug.coerce = coerce; - createDebug.disable = disable; - createDebug.enable = enable; - createDebug.enabled = enabled; - createDebug.humanize = ms; - createDebug.destroy = destroy; - - Object.keys(env).forEach(key => { - createDebug[key] = env[key]; - }); - - /** - * The currently active debug mode names, and names to skip. - */ - - createDebug.names = []; - createDebug.skips = []; - - /** - * Map of special "%n" handling functions, for the debug "format" argument. - * - * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". - */ - createDebug.formatters = {}; - - /** - * Selects a color for a debug namespace - * @param {String} namespace The namespace string for the for the debug instance to be colored - * @return {Number|String} An ANSI color code for the given namespace - * @api private - */ - function selectColor(namespace) { - let hash = 0; - - for (let i = 0; i < namespace.length; i++) { - hash = ((hash << 5) - hash) + namespace.charCodeAt(i); - hash |= 0; // Convert to 32bit integer - } - - return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; - } - createDebug.selectColor = selectColor; - - /** - * Create a debugger with the given `namespace`. - * - * @param {String} namespace - * @return {Function} - * @api public - */ - function createDebug(namespace) { - let prevTime; - let enableOverride = null; - let namespacesCache; - let enabledCache; - - function debug(...args) { - // Disabled? - if (!debug.enabled) { - return; - } - - const self = debug; - - // Set `diff` timestamp - const curr = Number(new Date()); - const ms = curr - (prevTime || curr); - self.diff = ms; - self.prev = prevTime; - self.curr = curr; - prevTime = curr; - - args[0] = createDebug.coerce(args[0]); - - if (typeof args[0] !== 'string') { - // Anything else let's inspect with %O - args.unshift('%O'); - } - - // Apply any `formatters` transformations - let index = 0; - args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { - // If we encounter an escaped % then don't increase the array index - if (match === '%%') { - return '%'; - } - index++; - const formatter = createDebug.formatters[format]; - if (typeof formatter === 'function') { - const val = args[index]; - match = formatter.call(self, val); - - // Now we need to remove `args[index]` since it's inlined in the `format` - args.splice(index, 1); - index--; - } - return match; - }); - - // Apply env-specific formatting (colors, etc.) - createDebug.formatArgs.call(self, args); - - const logFn = self.log || createDebug.log; - logFn.apply(self, args); - } - - debug.namespace = namespace; - debug.useColors = createDebug.useColors(); - debug.color = createDebug.selectColor(namespace); - debug.extend = extend; - debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release. - - Object.defineProperty(debug, 'enabled', { - enumerable: true, - configurable: false, - get: () => { - if (enableOverride !== null) { - return enableOverride; - } - if (namespacesCache !== createDebug.namespaces) { - namespacesCache = createDebug.namespaces; - enabledCache = createDebug.enabled(namespace); - } - - return enabledCache; - }, - set: v => { - enableOverride = v; - } - }); - - // Env-specific initialization logic for debug instances - if (typeof createDebug.init === 'function') { - createDebug.init(debug); - } - - return debug; - } - - function extend(namespace, delimiter) { - const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); - newDebug.log = this.log; - return newDebug; - } - - /** - * Enables a debug mode by namespaces. This can include modes - * separated by a colon and wildcards. - * - * @param {String} namespaces - * @api public - */ - function enable(namespaces) { - createDebug.save(namespaces); - createDebug.namespaces = namespaces; - - createDebug.names = []; - createDebug.skips = []; - - let i; - const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); - const len = split.length; - - for (i = 0; i < len; i++) { - if (!split[i]) { - // ignore empty strings - continue; - } - - namespaces = split[i].replace(/\*/g, '.*?'); - - if (namespaces[0] === '-') { - createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); - } else { - createDebug.names.push(new RegExp('^' + namespaces + '$')); - } - } - } - - /** - * Disable debug output. - * - * @return {String} namespaces - * @api public - */ - function disable() { - const namespaces = [ - ...createDebug.names.map(toNamespace), - ...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace) - ].join(','); - createDebug.enable(''); - return namespaces; - } - - /** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ - function enabled(name) { - if (name[name.length - 1] === '*') { - return true; - } - - let i; - let len; - - for (i = 0, len = createDebug.skips.length; i < len; i++) { - if (createDebug.skips[i].test(name)) { - return false; - } - } - - for (i = 0, len = createDebug.names.length; i < len; i++) { - if (createDebug.names[i].test(name)) { - return true; - } - } - - return false; - } - - /** - * Convert regexp to namespace - * - * @param {RegExp} regxep - * @return {String} namespace - * @api private - */ - function toNamespace(regexp) { - return regexp.toString() - .substring(2, regexp.toString().length - 2) - .replace(/\.\*\?$/, '*'); - } - - /** - * Coerce `val`. - * - * @param {Mixed} val - * @return {Mixed} - * @api private - */ - function coerce(val) { - if (val instanceof Error) { - return val.stack || val.message; - } - return val; - } - - /** - * XXX DO NOT USE. This is a temporary stub function. - * XXX It WILL be removed in the next major release. - */ - function destroy() { - console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); - } - - createDebug.enable(createDebug.load()); - - return createDebug; -} - -var common$3 = setup; - -/* eslint-env browser */ - -(function (module, exports) { -/** - * This is the web browser implementation of `debug()`. - */ - -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; -exports.storage = localstorage(); -exports.destroy = (() => { - let warned = false; - - return () => { - if (!warned) { - warned = true; - console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); - } - }; -})(); - -/** - * Colors. - */ - -exports.colors = [ - '#0000CC', - '#0000FF', - '#0033CC', - '#0033FF', - '#0066CC', - '#0066FF', - '#0099CC', - '#0099FF', - '#00CC00', - '#00CC33', - '#00CC66', - '#00CC99', - '#00CCCC', - '#00CCFF', - '#3300CC', - '#3300FF', - '#3333CC', - '#3333FF', - '#3366CC', - '#3366FF', - '#3399CC', - '#3399FF', - '#33CC00', - '#33CC33', - '#33CC66', - '#33CC99', - '#33CCCC', - '#33CCFF', - '#6600CC', - '#6600FF', - '#6633CC', - '#6633FF', - '#66CC00', - '#66CC33', - '#9900CC', - '#9900FF', - '#9933CC', - '#9933FF', - '#99CC00', - '#99CC33', - '#CC0000', - '#CC0033', - '#CC0066', - '#CC0099', - '#CC00CC', - '#CC00FF', - '#CC3300', - '#CC3333', - '#CC3366', - '#CC3399', - '#CC33CC', - '#CC33FF', - '#CC6600', - '#CC6633', - '#CC9900', - '#CC9933', - '#CCCC00', - '#CCCC33', - '#FF0000', - '#FF0033', - '#FF0066', - '#FF0099', - '#FF00CC', - '#FF00FF', - '#FF3300', - '#FF3333', - '#FF3366', - '#FF3399', - '#FF33CC', - '#FF33FF', - '#FF6600', - '#FF6633', - '#FF9900', - '#FF9933', - '#FFCC00', - '#FFCC33' -]; - -/** - * Currently only WebKit-based Web Inspectors, Firefox >= v31, - * and the Firebug extension (any Firefox version) are known - * to support "%c" CSS customizations. - * - * TODO: add a `localStorage` variable to explicitly enable/disable colors - */ - -// eslint-disable-next-line complexity -function useColors() { - // NB: In an Electron preload script, document will be defined but not fully - // initialized. Since we know we're in Chrome, we'll just detect this case - // explicitly - if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { - return true; - } - - // Internet Explorer and Edge do not support colors. - if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { - return false; - } - - // Is webkit? http://stackoverflow.com/a/16459606/376773 - // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 - return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || - // Is firebug? http://stackoverflow.com/a/398120/376773 - (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || - // Is firefox >= v31? - // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages - (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || - // Double check webkit in userAgent just in case we are in a worker - (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); -} - -/** - * Colorize log arguments if enabled. - * - * @api public - */ - -function formatArgs(args) { - args[0] = (this.useColors ? '%c' : '') + - this.namespace + - (this.useColors ? ' %c' : ' ') + - args[0] + - (this.useColors ? '%c ' : ' ') + - '+' + module.exports.humanize(this.diff); - - if (!this.useColors) { - return; - } - - const c = 'color: ' + this.color; - args.splice(1, 0, c, 'color: inherit'); - - // The final "%c" is somewhat tricky, because there could be other - // arguments passed either before or after the %c, so we need to - // figure out the correct index to insert the CSS into - let index = 0; - let lastC = 0; - args[0].replace(/%[a-zA-Z%]/g, match => { - if (match === '%%') { - return; - } - index++; - if (match === '%c') { - // We only are interested in the *last* %c - // (the user may have provided their own) - lastC = index; - } - }); - - args.splice(lastC, 0, c); -} - -/** - * Invokes `console.debug()` when available. - * No-op when `console.debug` is not a "function". - * If `console.debug` is not available, falls back - * to `console.log`. - * - * @api public - */ -exports.log = console.debug || console.log || (() => {}); - -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ -function save(namespaces) { - try { - if (namespaces) { - exports.storage.setItem('debug', namespaces); - } else { - exports.storage.removeItem('debug'); - } - } catch (error) { - // Swallow - // XXX (@Qix-) should we be logging these? - } -} - -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ -function load() { - let r; - try { - r = exports.storage.getItem('debug'); - } catch (error) { - // Swallow - // XXX (@Qix-) should we be logging these? - } - - // If debug isn't set in LS, and we're in Electron, try to load $DEBUG - if (!r && typeof process !== 'undefined' && 'env' in process) { - r = process.env.DEBUG; - } - - return r; -} - -/** - * Localstorage attempts to return the localstorage. - * - * This is necessary because safari throws - * when a user disables cookies/localstorage - * and you attempt to access it. - * - * @return {LocalStorage} - * @api private - */ - -function localstorage() { - try { - // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context - // The Browser also has localStorage in the global context. - return localStorage; - } catch (error) { - // Swallow - // XXX (@Qix-) should we be logging these? - } -} - -module.exports = common$3(exports); - -const {formatters} = module.exports; - -/** - * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. - */ - -formatters.j = function (v) { - try { - return JSON.stringify(v); - } catch (error) { - return '[UnexpectedJSONParseError]: ' + error.message; - } -}; -}(browser, browser.exports)); - -var node = {exports: {}}; - -/** - * Module dependencies. - */ - -(function (module, exports) { -const tty = tty$1; -const util = require$$0$4; - -/** - * This is the Node.js implementation of `debug()`. - */ - -exports.init = init; -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; -exports.destroy = util.deprecate( - () => {}, - 'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.' -); - -/** - * Colors. - */ - -exports.colors = [6, 2, 3, 4, 5, 1]; - -try { - // Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json) - // eslint-disable-next-line import/no-extraneous-dependencies - const supportsColor = supportsColor_1$1; - - if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) { - exports.colors = [ - 20, - 21, - 26, - 27, - 32, - 33, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 56, - 57, - 62, - 63, - 68, - 69, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 92, - 93, - 98, - 99, - 112, - 113, - 128, - 129, - 134, - 135, - 148, - 149, - 160, - 161, - 162, - 163, - 164, - 165, - 166, - 167, - 168, - 169, - 170, - 171, - 172, - 173, - 178, - 179, - 184, - 185, - 196, - 197, - 198, - 199, - 200, - 201, - 202, - 203, - 204, - 205, - 206, - 207, - 208, - 209, - 214, - 215, - 220, - 221 - ]; - } -} catch (error) { - // Swallow - we only care if `supports-color` is available; it doesn't have to be. -} - -/** - * Build up the default `inspectOpts` object from the environment variables. - * - * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js - */ - -exports.inspectOpts = Object.keys(process.env).filter(key => { - return /^debug_/i.test(key); -}).reduce((obj, key) => { - // Camel-case - const prop = key - .substring(6) - .toLowerCase() - .replace(/_([a-z])/g, (_, k) => { - return k.toUpperCase(); - }); - - // Coerce string value into JS value - let val = process.env[key]; - if (/^(yes|on|true|enabled)$/i.test(val)) { - val = true; - } else if (/^(no|off|false|disabled)$/i.test(val)) { - val = false; - } else if (val === 'null') { - val = null; - } else { - val = Number(val); - } - - obj[prop] = val; - return obj; -}, {}); - -/** - * Is stdout a TTY? Colored output is enabled when `true`. - */ - -function useColors() { - return 'colors' in exports.inspectOpts ? - Boolean(exports.inspectOpts.colors) : - tty.isatty(process.stderr.fd); -} - -/** - * Adds ANSI color escape codes if enabled. - * - * @api public - */ - -function formatArgs(args) { - const {namespace: name, useColors} = this; - - if (useColors) { - const c = this.color; - const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c); - const prefix = ` ${colorCode};1m${name} \u001B[0m`; - - args[0] = prefix + args[0].split('\n').join('\n' + prefix); - args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m'); - } else { - args[0] = getDate() + name + ' ' + args[0]; - } -} - -function getDate() { - if (exports.inspectOpts.hideDate) { - return ''; - } - return new Date().toISOString() + ' '; -} - -/** - * Invokes `util.format()` with the specified arguments and writes to stderr. - */ - -function log(...args) { - return process.stderr.write(util.format(...args) + '\n'); -} - -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ -function save(namespaces) { - if (namespaces) { - process.env.DEBUG = namespaces; - } else { - // If you set a process.env field to null or undefined, it gets cast to the - // string 'null' or 'undefined'. Just delete instead. - delete process.env.DEBUG; - } -} - -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ - -function load() { - return process.env.DEBUG; -} - -/** - * Init logic for `debug` instances. - * - * Create a new `inspectOpts` object in case `useColors` is set - * differently for a particular `debug` instance. - */ - -function init(debug) { - debug.inspectOpts = {}; - - const keys = Object.keys(exports.inspectOpts); - for (let i = 0; i < keys.length; i++) { - debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; - } -} - -module.exports = common$3(exports); - -const {formatters} = module.exports; - -/** - * Map %o to `util.inspect()`, all on a single line. - */ - -formatters.o = function (v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts) - .split('\n') - .map(str => str.trim()) - .join(' '); -}; - -/** - * Map %O to `util.inspect()`, allowing multiple lines if needed. - */ - -formatters.O = function (v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts); -}; -}(node, node.exports)); - -/** - * Detect Electron renderer / nwjs process, which is node, but we should - * treat as a browser. - */ - -if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) { - src.exports = browser.exports; -} else { - src.exports = node.exports; -} - -var createDebug = src.exports; - -var re$6 = {exports: {}}; - -// Note: this is the semver.org version of the spec that it implements -// Not necessarily the package version of this code. -const SEMVER_SPEC_VERSION = '2.0.0'; - -const MAX_LENGTH$2 = 256; -const MAX_SAFE_INTEGER$1 = Number.MAX_SAFE_INTEGER || - /* istanbul ignore next */ 9007199254740991; - -// Max safe segment length for coercion. -const MAX_SAFE_COMPONENT_LENGTH = 16; - -var constants = { - SEMVER_SPEC_VERSION, - MAX_LENGTH: MAX_LENGTH$2, - MAX_SAFE_INTEGER: MAX_SAFE_INTEGER$1, - MAX_SAFE_COMPONENT_LENGTH -}; - -const debug$f = ( - typeof process === 'object' && - process.env && - process.env.NODE_DEBUG && - /\bsemver\b/i.test(process.env.NODE_DEBUG) -) ? (...args) => console.error('SEMVER', ...args) - : () => {}; - -var debug_1 = debug$f; - -(function (module, exports) { -const { MAX_SAFE_COMPONENT_LENGTH } = constants; -const debug = debug_1; -exports = module.exports = {}; - -// The actual regexps go on exports.re -const re = exports.re = []; -const src = exports.src = []; -const t = exports.t = {}; -let R = 0; - -const createToken = (name, value, isGlobal) => { - const index = R++; - debug(index, value); - t[name] = index; - src[index] = value; - re[index] = new RegExp(value, isGlobal ? 'g' : undefined); -}; - -// The following Regular Expressions can be used for tokenizing, -// validating, and parsing SemVer version strings. - -// ## Numeric Identifier -// A single `0`, or a non-zero digit followed by zero or more digits. - -createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*'); -createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+'); - -// ## Non-numeric Identifier -// Zero or more digits, followed by a letter or hyphen, and then zero or -// more letters, digits, or hyphens. - -createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*'); - -// ## Main Version -// Three dot-separated numeric identifiers. - -createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` + - `(${src[t.NUMERICIDENTIFIER]})\\.` + - `(${src[t.NUMERICIDENTIFIER]})`); - -createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + - `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + - `(${src[t.NUMERICIDENTIFIERLOOSE]})`); - -// ## Pre-release Version Identifier -// A numeric identifier, or a non-numeric identifier. - -createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NUMERICIDENTIFIER] -}|${src[t.NONNUMERICIDENTIFIER]})`); - -createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NUMERICIDENTIFIERLOOSE] -}|${src[t.NONNUMERICIDENTIFIER]})`); - -// ## Pre-release Version -// Hyphen, followed by one or more dot-separated pre-release version -// identifiers. - -createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER] -}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`); - -createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE] -}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`); - -// ## Build Metadata Identifier -// Any combination of digits, letters, or hyphens. - -createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+'); - -// ## Build Metadata -// Plus sign, followed by one or more period-separated build metadata -// identifiers. - -createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER] -}(?:\\.${src[t.BUILDIDENTIFIER]})*))`); - -// ## Full Version String -// A main version, followed optionally by a pre-release version and -// build metadata. - -// Note that the only major, minor, patch, and pre-release sections of -// the version string are capturing groups. The build metadata is not a -// capturing group, because it should not ever be used in version -// comparison. - -createToken('FULLPLAIN', `v?${src[t.MAINVERSION] -}${src[t.PRERELEASE]}?${ - src[t.BUILD]}?`); - -createToken('FULL', `^${src[t.FULLPLAIN]}$`); - -// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. -// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty -// common in the npm registry. -createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE] -}${src[t.PRERELEASELOOSE]}?${ - src[t.BUILD]}?`); - -createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`); - -createToken('GTLT', '((?:<|>)?=?)'); - -// Something like "2.*" or "1.2.x". -// Note that "x.x" is a valid xRange identifer, meaning "any version" -// Only the first item is strictly required. -createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`); -createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`); - -createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` + - `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + - `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + - `(?:${src[t.PRERELEASE]})?${ - src[t.BUILD]}?` + - `)?)?`); - -createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` + - `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + - `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + - `(?:${src[t.PRERELEASELOOSE]})?${ - src[t.BUILD]}?` + - `)?)?`); - -createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`); -createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`); - -// Coercion. -// Extract anything that could conceivably be a part of a valid semver -createToken('COERCE', `${'(^|[^\\d])' + - '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` + - `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + - `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + - `(?:$|[^\\d])`); -createToken('COERCERTL', src[t.COERCE], true); - -// Tilde ranges. -// Meaning is "reasonably at or greater than" -createToken('LONETILDE', '(?:~>?)'); - -createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true); -exports.tildeTrimReplace = '$1~'; - -createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`); -createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`); - -// Caret ranges. -// Meaning is "at least and backwards compatible with" -createToken('LONECARET', '(?:\\^)'); - -createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true); -exports.caretTrimReplace = '$1^'; - -createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`); -createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`); - -// A simple gt/lt/eq thing, or just "" to indicate "any version" -createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`); -createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`); - -// An expression to strip any whitespace between the gtlt and the thing -// it modifies, so that `> 1.2.3` ==> `>1.2.3` -createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT] -}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true); -exports.comparatorTrimReplace = '$1$2$3'; - -// Something like `1.2.3 - 1.2.4` -// Note that these all use the loose form, because they'll be -// checked against either the strict or loose comparator form -// later. -createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` + - `\\s+-\\s+` + - `(${src[t.XRANGEPLAIN]})` + - `\\s*$`); - -createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` + - `\\s+-\\s+` + - `(${src[t.XRANGEPLAINLOOSE]})` + - `\\s*$`); - -// Star ranges basically just allow anything at all. -createToken('STAR', '(<|>)?=?\\s*\\*'); -// >=0.0.0 is like a star -createToken('GTE0', '^\\s*>=\\s*0\.0\.0\\s*$'); -createToken('GTE0PRE', '^\\s*>=\\s*0\.0\.0-0\\s*$'); -}(re$6, re$6.exports)); - -// parse out just the options we care about so we always get a consistent -// obj with keys in a consistent order. -const opts = ['includePrerelease', 'loose', 'rtl']; -const parseOptions$4 = options => - !options ? {} - : typeof options !== 'object' ? { loose: true } - : opts.filter(k => options[k]).reduce((options, k) => { - options[k] = true; - return options - }, {}); -var parseOptions_1 = parseOptions$4; - -const numeric$1 = /^[0-9]+$/; -const compareIdentifiers$1 = (a, b) => { - const anum = numeric$1.test(a); - const bnum = numeric$1.test(b); - - if (anum && bnum) { - a = +a; - b = +b; - } - - return a === b ? 0 - : (anum && !bnum) ? -1 - : (bnum && !anum) ? 1 - : a < b ? -1 - : 1 -}; - -const rcompareIdentifiers = (a, b) => compareIdentifiers$1(b, a); - -var identifiers = { - compareIdentifiers: compareIdentifiers$1, - rcompareIdentifiers -}; - -const debug$e = debug_1; -const { MAX_LENGTH: MAX_LENGTH$1, MAX_SAFE_INTEGER } = constants; -const { re: re$5, t: t$4 } = re$6.exports; - -const parseOptions$3 = parseOptions_1; -const { compareIdentifiers } = identifiers; -class SemVer$e { - constructor (version, options) { - options = parseOptions$3(options); - - if (version instanceof SemVer$e) { - if (version.loose === !!options.loose && - version.includePrerelease === !!options.includePrerelease) { - return version - } else { - version = version.version; - } - } else if (typeof version !== 'string') { - throw new TypeError(`Invalid Version: ${version}`) - } - - if (version.length > MAX_LENGTH$1) { - throw new TypeError( - `version is longer than ${MAX_LENGTH$1} characters` - ) - } - - debug$e('SemVer', version, options); - this.options = options; - this.loose = !!options.loose; - // this isn't actually relevant for versions, but keep it so that we - // don't run into trouble passing this.options around. - this.includePrerelease = !!options.includePrerelease; - - const m = version.trim().match(options.loose ? re$5[t$4.LOOSE] : re$5[t$4.FULL]); - - if (!m) { - throw new TypeError(`Invalid Version: ${version}`) - } - - this.raw = version; - - // these are actually numbers - this.major = +m[1]; - this.minor = +m[2]; - this.patch = +m[3]; - - if (this.major > MAX_SAFE_INTEGER || this.major < 0) { - throw new TypeError('Invalid major version') - } - - if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { - throw new TypeError('Invalid minor version') - } - - if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { - throw new TypeError('Invalid patch version') - } - - // numberify any prerelease numeric ids - if (!m[4]) { - this.prerelease = []; - } else { - this.prerelease = m[4].split('.').map((id) => { - if (/^[0-9]+$/.test(id)) { - const num = +id; - if (num >= 0 && num < MAX_SAFE_INTEGER) { - return num - } - } - return id - }); - } - - this.build = m[5] ? m[5].split('.') : []; - this.format(); - } - - format () { - this.version = `${this.major}.${this.minor}.${this.patch}`; - if (this.prerelease.length) { - this.version += `-${this.prerelease.join('.')}`; - } - return this.version - } - - toString () { - return this.version - } - - compare (other) { - debug$e('SemVer.compare', this.version, this.options, other); - if (!(other instanceof SemVer$e)) { - if (typeof other === 'string' && other === this.version) { - return 0 - } - other = new SemVer$e(other, this.options); - } - - if (other.version === this.version) { - return 0 - } - - return this.compareMain(other) || this.comparePre(other) - } - - compareMain (other) { - if (!(other instanceof SemVer$e)) { - other = new SemVer$e(other, this.options); - } - - return ( - compareIdentifiers(this.major, other.major) || - compareIdentifiers(this.minor, other.minor) || - compareIdentifiers(this.patch, other.patch) - ) - } - - comparePre (other) { - if (!(other instanceof SemVer$e)) { - other = new SemVer$e(other, this.options); - } - - // NOT having a prerelease is > having one - if (this.prerelease.length && !other.prerelease.length) { - return -1 - } else if (!this.prerelease.length && other.prerelease.length) { - return 1 - } else if (!this.prerelease.length && !other.prerelease.length) { - return 0 - } - - let i = 0; - do { - const a = this.prerelease[i]; - const b = other.prerelease[i]; - debug$e('prerelease compare', i, a, b); - if (a === undefined && b === undefined) { - return 0 - } else if (b === undefined) { - return 1 - } else if (a === undefined) { - return -1 - } else if (a === b) { - continue - } else { - return compareIdentifiers(a, b) - } - } while (++i) - } - - compareBuild (other) { - if (!(other instanceof SemVer$e)) { - other = new SemVer$e(other, this.options); - } - - let i = 0; - do { - const a = this.build[i]; - const b = other.build[i]; - debug$e('prerelease compare', i, a, b); - if (a === undefined && b === undefined) { - return 0 - } else if (b === undefined) { - return 1 - } else if (a === undefined) { - return -1 - } else if (a === b) { - continue - } else { - return compareIdentifiers(a, b) - } - } while (++i) - } - - // preminor will bump the version up to the next minor release, and immediately - // down to pre-release. premajor and prepatch work the same way. - inc (release, identifier) { - switch (release) { - case 'premajor': - this.prerelease.length = 0; - this.patch = 0; - this.minor = 0; - this.major++; - this.inc('pre', identifier); - break - case 'preminor': - this.prerelease.length = 0; - this.patch = 0; - this.minor++; - this.inc('pre', identifier); - break - case 'prepatch': - // If this is already a prerelease, it will bump to the next version - // drop any prereleases that might already exist, since they are not - // relevant at this point. - this.prerelease.length = 0; - this.inc('patch', identifier); - this.inc('pre', identifier); - break - // If the input is a non-prerelease version, this acts the same as - // prepatch. - case 'prerelease': - if (this.prerelease.length === 0) { - this.inc('patch', identifier); - } - this.inc('pre', identifier); - break - - case 'major': - // If this is a pre-major version, bump up to the same major version. - // Otherwise increment major. - // 1.0.0-5 bumps to 1.0.0 - // 1.1.0 bumps to 2.0.0 - if ( - this.minor !== 0 || - this.patch !== 0 || - this.prerelease.length === 0 - ) { - this.major++; - } - this.minor = 0; - this.patch = 0; - this.prerelease = []; - break - case 'minor': - // If this is a pre-minor version, bump up to the same minor version. - // Otherwise increment minor. - // 1.2.0-5 bumps to 1.2.0 - // 1.2.1 bumps to 1.3.0 - if (this.patch !== 0 || this.prerelease.length === 0) { - this.minor++; - } - this.patch = 0; - this.prerelease = []; - break - case 'patch': - // If this is not a pre-release version, it will increment the patch. - // If it is a pre-release it will bump up to the same patch version. - // 1.2.0-5 patches to 1.2.0 - // 1.2.0 patches to 1.2.1 - if (this.prerelease.length === 0) { - this.patch++; - } - this.prerelease = []; - break - // This probably shouldn't be used publicly. - // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction. - case 'pre': - if (this.prerelease.length === 0) { - this.prerelease = [0]; - } else { - let i = this.prerelease.length; - while (--i >= 0) { - if (typeof this.prerelease[i] === 'number') { - this.prerelease[i]++; - i = -2; - } - } - if (i === -1) { - // didn't increment anything - this.prerelease.push(0); - } - } - if (identifier) { - // 1.2.0-beta.1 bumps to 1.2.0-beta.2, - // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 - if (this.prerelease[0] === identifier) { - if (isNaN(this.prerelease[1])) { - this.prerelease = [identifier, 0]; - } - } else { - this.prerelease = [identifier, 0]; - } - } - break - - default: - throw new Error(`invalid increment argument: ${release}`) - } - this.format(); - this.raw = this.version; - return this - } -} - -var semver$2 = SemVer$e; - -const {MAX_LENGTH} = constants; -const { re: re$4, t: t$3 } = re$6.exports; -const SemVer$d = semver$2; - -const parseOptions$2 = parseOptions_1; -const parse$9 = (version, options) => { - options = parseOptions$2(options); - - if (version instanceof SemVer$d) { - return version - } - - if (typeof version !== 'string') { - return null - } - - if (version.length > MAX_LENGTH) { - return null - } - - const r = options.loose ? re$4[t$3.LOOSE] : re$4[t$3.FULL]; - if (!r.test(version)) { - return null - } - - try { - return new SemVer$d(version, options) - } catch (er) { - return null - } -}; - -var parse_1 = parse$9; - -const parse$8 = parse_1; -const valid$1 = (version, options) => { - const v = parse$8(version, options); - return v ? v.version : null -}; -var valid_1 = valid$1; - -const parse$7 = parse_1; -const clean = (version, options) => { - const s = parse$7(version.trim().replace(/^[=v]+/, ''), options); - return s ? s.version : null -}; -var clean_1 = clean; - -const SemVer$c = semver$2; - -const inc = (version, release, options, identifier) => { - if (typeof (options) === 'string') { - identifier = options; - options = undefined; - } - - try { - return new SemVer$c(version, options).inc(release, identifier).version - } catch (er) { - return null - } -}; -var inc_1 = inc; - -const SemVer$b = semver$2; -const compare$b = (a, b, loose) => - new SemVer$b(a, loose).compare(new SemVer$b(b, loose)); - -var compare_1 = compare$b; - -const compare$a = compare_1; -const eq$2 = (a, b, loose) => compare$a(a, b, loose) === 0; -var eq_1 = eq$2; - -const parse$6 = parse_1; -const eq$1 = eq_1; - -const diff = (version1, version2) => { - if (eq$1(version1, version2)) { - return null - } else { - const v1 = parse$6(version1); - const v2 = parse$6(version2); - const hasPre = v1.prerelease.length || v2.prerelease.length; - const prefix = hasPre ? 'pre' : ''; - const defaultResult = hasPre ? 'prerelease' : ''; - for (const key in v1) { - if (key === 'major' || key === 'minor' || key === 'patch') { - if (v1[key] !== v2[key]) { - return prefix + key - } - } - } - return defaultResult // may be undefined - } -}; -var diff_1 = diff; - -const SemVer$a = semver$2; -const major = (a, loose) => new SemVer$a(a, loose).major; -var major_1 = major; - -const SemVer$9 = semver$2; -const minor = (a, loose) => new SemVer$9(a, loose).minor; -var minor_1 = minor; - -const SemVer$8 = semver$2; -const patch = (a, loose) => new SemVer$8(a, loose).patch; -var patch_1 = patch; - -const parse$5 = parse_1; -const prerelease = (version, options) => { - const parsed = parse$5(version, options); - return (parsed && parsed.prerelease.length) ? parsed.prerelease : null -}; -var prerelease_1 = prerelease; - -const compare$9 = compare_1; -const rcompare = (a, b, loose) => compare$9(b, a, loose); -var rcompare_1 = rcompare; - -const compare$8 = compare_1; -const compareLoose = (a, b) => compare$8(a, b, true); -var compareLoose_1 = compareLoose; - -const SemVer$7 = semver$2; -const compareBuild$2 = (a, b, loose) => { - const versionA = new SemVer$7(a, loose); - const versionB = new SemVer$7(b, loose); - return versionA.compare(versionB) || versionA.compareBuild(versionB) -}; -var compareBuild_1 = compareBuild$2; - -const compareBuild$1 = compareBuild_1; -const sort$1 = (list, loose) => list.sort((a, b) => compareBuild$1(a, b, loose)); -var sort_1 = sort$1; - -const compareBuild = compareBuild_1; -const rsort = (list, loose) => list.sort((a, b) => compareBuild(b, a, loose)); -var rsort_1 = rsort; - -const compare$7 = compare_1; -const gt$3 = (a, b, loose) => compare$7(a, b, loose) > 0; -var gt_1 = gt$3; - -const compare$6 = compare_1; -const lt$2 = (a, b, loose) => compare$6(a, b, loose) < 0; -var lt_1 = lt$2; - -const compare$5 = compare_1; -const neq$1 = (a, b, loose) => compare$5(a, b, loose) !== 0; -var neq_1 = neq$1; - -const compare$4 = compare_1; -const gte$3 = (a, b, loose) => compare$4(a, b, loose) >= 0; -var gte_1 = gte$3; - -const compare$3 = compare_1; -const lte$3 = (a, b, loose) => compare$3(a, b, loose) <= 0; -var lte_1 = lte$3; - -const eq = eq_1; -const neq = neq_1; -const gt$2 = gt_1; -const gte$2 = gte_1; -const lt$1 = lt_1; -const lte$2 = lte_1; - -const cmp$1 = (a, op, b, loose) => { - switch (op) { - case '===': - if (typeof a === 'object') - a = a.version; - if (typeof b === 'object') - b = b.version; - return a === b - - case '!==': - if (typeof a === 'object') - a = a.version; - if (typeof b === 'object') - b = b.version; - return a !== b - - case '': - case '=': - case '==': - return eq(a, b, loose) - - case '!=': - return neq(a, b, loose) - - case '>': - return gt$2(a, b, loose) - - case '>=': - return gte$2(a, b, loose) - - case '<': - return lt$1(a, b, loose) - - case '<=': - return lte$2(a, b, loose) - - default: - throw new TypeError(`Invalid operator: ${op}`) - } -}; -var cmp_1 = cmp$1; - -const SemVer$6 = semver$2; -const parse$4 = parse_1; -const {re: re$3, t: t$2} = re$6.exports; - -const coerce$2 = (version, options) => { - if (version instanceof SemVer$6) { - return version - } - - if (typeof version === 'number') { - version = String(version); - } - - if (typeof version !== 'string') { - return null - } - - options = options || {}; - - let match = null; - if (!options.rtl) { - match = version.match(re$3[t$2.COERCE]); - } else { - // Find the right-most coercible string that does not share - // a terminus with a more left-ward coercible string. - // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4' - // - // Walk through the string checking with a /g regexp - // Manually set the index so as to pick up overlapping matches. - // Stop when we get a match that ends at the string end, since no - // coercible string can be more right-ward without the same terminus. - let next; - while ((next = re$3[t$2.COERCERTL].exec(version)) && - (!match || match.index + match[0].length !== version.length) - ) { - if (!match || - next.index + next[0].length !== match.index + match[0].length) { - match = next; - } - re$3[t$2.COERCERTL].lastIndex = next.index + next[1].length + next[2].length; - } - // leave it in a clean state - re$3[t$2.COERCERTL].lastIndex = -1; - } - - if (match === null) - return null - - return parse$4(`${match[2]}.${match[3] || '0'}.${match[4] || '0'}`, options) -}; -var coerce_1 = coerce$2; - -var iterator = function (Yallist) { - Yallist.prototype[Symbol.iterator] = function* () { - for (let walker = this.head; walker; walker = walker.next) { - yield walker.value; - } - }; -}; - -var yallist = Yallist$1; - -Yallist$1.Node = Node; -Yallist$1.create = Yallist$1; - -function Yallist$1 (list) { - var self = this; - if (!(self instanceof Yallist$1)) { - self = new Yallist$1(); - } - - self.tail = null; - self.head = null; - self.length = 0; - - if (list && typeof list.forEach === 'function') { - list.forEach(function (item) { - self.push(item); - }); - } else if (arguments.length > 0) { - for (var i = 0, l = arguments.length; i < l; i++) { - self.push(arguments[i]); - } - } - - return self -} - -Yallist$1.prototype.removeNode = function (node) { - if (node.list !== this) { - throw new Error('removing node which does not belong to this list') - } - - var next = node.next; - var prev = node.prev; - - if (next) { - next.prev = prev; - } - - if (prev) { - prev.next = next; - } - - if (node === this.head) { - this.head = next; - } - if (node === this.tail) { - this.tail = prev; - } - - node.list.length--; - node.next = null; - node.prev = null; - node.list = null; - - return next -}; - -Yallist$1.prototype.unshiftNode = function (node) { - if (node === this.head) { - return - } - - if (node.list) { - node.list.removeNode(node); - } - - var head = this.head; - node.list = this; - node.next = head; - if (head) { - head.prev = node; - } - - this.head = node; - if (!this.tail) { - this.tail = node; - } - this.length++; -}; - -Yallist$1.prototype.pushNode = function (node) { - if (node === this.tail) { - return - } - - if (node.list) { - node.list.removeNode(node); - } - - var tail = this.tail; - node.list = this; - node.prev = tail; - if (tail) { - tail.next = node; - } - - this.tail = node; - if (!this.head) { - this.head = node; - } - this.length++; -}; - -Yallist$1.prototype.push = function () { - for (var i = 0, l = arguments.length; i < l; i++) { - push$2(this, arguments[i]); - } - return this.length -}; - -Yallist$1.prototype.unshift = function () { - for (var i = 0, l = arguments.length; i < l; i++) { - unshift(this, arguments[i]); - } - return this.length -}; - -Yallist$1.prototype.pop = function () { - if (!this.tail) { - return undefined - } - - var res = this.tail.value; - this.tail = this.tail.prev; - if (this.tail) { - this.tail.next = null; - } else { - this.head = null; - } - this.length--; - return res -}; - -Yallist$1.prototype.shift = function () { - if (!this.head) { - return undefined - } - - var res = this.head.value; - this.head = this.head.next; - if (this.head) { - this.head.prev = null; - } else { - this.tail = null; - } - this.length--; - return res -}; - -Yallist$1.prototype.forEach = function (fn, thisp) { - thisp = thisp || this; - for (var walker = this.head, i = 0; walker !== null; i++) { - fn.call(thisp, walker.value, i, this); - walker = walker.next; - } -}; - -Yallist$1.prototype.forEachReverse = function (fn, thisp) { - thisp = thisp || this; - for (var walker = this.tail, i = this.length - 1; walker !== null; i--) { - fn.call(thisp, walker.value, i, this); - walker = walker.prev; - } -}; - -Yallist$1.prototype.get = function (n) { - for (var i = 0, walker = this.head; walker !== null && i < n; i++) { - // abort out of the list early if we hit a cycle - walker = walker.next; - } - if (i === n && walker !== null) { - return walker.value - } -}; - -Yallist$1.prototype.getReverse = function (n) { - for (var i = 0, walker = this.tail; walker !== null && i < n; i++) { - // abort out of the list early if we hit a cycle - walker = walker.prev; - } - if (i === n && walker !== null) { - return walker.value - } -}; - -Yallist$1.prototype.map = function (fn, thisp) { - thisp = thisp || this; - var res = new Yallist$1(); - for (var walker = this.head; walker !== null;) { - res.push(fn.call(thisp, walker.value, this)); - walker = walker.next; - } - return res -}; - -Yallist$1.prototype.mapReverse = function (fn, thisp) { - thisp = thisp || this; - var res = new Yallist$1(); - for (var walker = this.tail; walker !== null;) { - res.push(fn.call(thisp, walker.value, this)); - walker = walker.prev; - } - return res -}; - -Yallist$1.prototype.reduce = function (fn, initial) { - var acc; - var walker = this.head; - if (arguments.length > 1) { - acc = initial; - } else if (this.head) { - walker = this.head.next; - acc = this.head.value; - } else { - throw new TypeError('Reduce of empty list with no initial value') - } - - for (var i = 0; walker !== null; i++) { - acc = fn(acc, walker.value, i); - walker = walker.next; - } - - return acc -}; - -Yallist$1.prototype.reduceReverse = function (fn, initial) { - var acc; - var walker = this.tail; - if (arguments.length > 1) { - acc = initial; - } else if (this.tail) { - walker = this.tail.prev; - acc = this.tail.value; - } else { - throw new TypeError('Reduce of empty list with no initial value') - } - - for (var i = this.length - 1; walker !== null; i--) { - acc = fn(acc, walker.value, i); - walker = walker.prev; - } - - return acc -}; - -Yallist$1.prototype.toArray = function () { - var arr = new Array(this.length); - for (var i = 0, walker = this.head; walker !== null; i++) { - arr[i] = walker.value; - walker = walker.next; - } - return arr -}; - -Yallist$1.prototype.toArrayReverse = function () { - var arr = new Array(this.length); - for (var i = 0, walker = this.tail; walker !== null; i++) { - arr[i] = walker.value; - walker = walker.prev; - } - return arr -}; - -Yallist$1.prototype.slice = function (from, to) { - to = to || this.length; - if (to < 0) { - to += this.length; - } - from = from || 0; - if (from < 0) { - from += this.length; - } - var ret = new Yallist$1(); - if (to < from || to < 0) { - return ret - } - if (from < 0) { - from = 0; - } - if (to > this.length) { - to = this.length; - } - for (var i = 0, walker = this.head; walker !== null && i < from; i++) { - walker = walker.next; - } - for (; walker !== null && i < to; i++, walker = walker.next) { - ret.push(walker.value); - } - return ret -}; - -Yallist$1.prototype.sliceReverse = function (from, to) { - to = to || this.length; - if (to < 0) { - to += this.length; - } - from = from || 0; - if (from < 0) { - from += this.length; - } - var ret = new Yallist$1(); - if (to < from || to < 0) { - return ret - } - if (from < 0) { - from = 0; - } - if (to > this.length) { - to = this.length; - } - for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) { - walker = walker.prev; - } - for (; walker !== null && i > from; i--, walker = walker.prev) { - ret.push(walker.value); - } - return ret -}; - -Yallist$1.prototype.splice = function (start, deleteCount, ...nodes) { - if (start > this.length) { - start = this.length - 1; - } - if (start < 0) { - start = this.length + start; - } - - for (var i = 0, walker = this.head; walker !== null && i < start; i++) { - walker = walker.next; - } - - var ret = []; - for (var i = 0; walker && i < deleteCount; i++) { - ret.push(walker.value); - walker = this.removeNode(walker); - } - if (walker === null) { - walker = this.tail; - } - - if (walker !== this.head && walker !== this.tail) { - walker = walker.prev; - } - - for (var i = 0; i < nodes.length; i++) { - walker = insert(this, walker, nodes[i]); - } - return ret; -}; - -Yallist$1.prototype.reverse = function () { - var head = this.head; - var tail = this.tail; - for (var walker = head; walker !== null; walker = walker.prev) { - var p = walker.prev; - walker.prev = walker.next; - walker.next = p; - } - this.head = tail; - this.tail = head; - return this -}; - -function insert (self, node, value) { - var inserted = node === self.head ? - new Node(value, null, node, self) : - new Node(value, node, node.next, self); - - if (inserted.next === null) { - self.tail = inserted; - } - if (inserted.prev === null) { - self.head = inserted; - } - - self.length++; - - return inserted -} - -function push$2 (self, item) { - self.tail = new Node(item, self.tail, null, self); - if (!self.head) { - self.head = self.tail; - } - self.length++; -} - -function unshift (self, item) { - self.head = new Node(item, null, self.head, self); - if (!self.tail) { - self.tail = self.head; - } - self.length++; -} - -function Node (value, prev, next, list) { - if (!(this instanceof Node)) { - return new Node(value, prev, next, list) - } - - this.list = list; - this.value = value; - - if (prev) { - prev.next = this; - this.prev = prev; - } else { - this.prev = null; - } - - if (next) { - next.prev = this; - this.next = next; - } else { - this.next = null; - } -} - -try { - // add if support for Symbol.iterator is present - iterator(Yallist$1); -} catch (er) {} - -// A linked list to keep track of recently-used-ness -const Yallist = yallist; - -const MAX = Symbol('max'); -const LENGTH = Symbol('length'); -const LENGTH_CALCULATOR = Symbol('lengthCalculator'); -const ALLOW_STALE = Symbol('allowStale'); -const MAX_AGE = Symbol('maxAge'); -const DISPOSE = Symbol('dispose'); -const NO_DISPOSE_ON_SET = Symbol('noDisposeOnSet'); -const LRU_LIST = Symbol('lruList'); -const CACHE = Symbol('cache'); -const UPDATE_AGE_ON_GET = Symbol('updateAgeOnGet'); - -const naiveLength = () => 1; - -// lruList is a yallist where the head is the youngest -// item, and the tail is the oldest. the list contains the Hit -// objects as the entries. -// Each Hit object has a reference to its Yallist.Node. This -// never changes. -// -// cache is a Map (or PseudoMap) that matches the keys to -// the Yallist.Node object. -class LRUCache { - constructor (options) { - if (typeof options === 'number') - options = { max: options }; - - if (!options) - options = {}; - - if (options.max && (typeof options.max !== 'number' || options.max < 0)) - throw new TypeError('max must be a non-negative number') - // Kind of weird to have a default max of Infinity, but oh well. - this[MAX] = options.max || Infinity; - - const lc = options.length || naiveLength; - this[LENGTH_CALCULATOR] = (typeof lc !== 'function') ? naiveLength : lc; - this[ALLOW_STALE] = options.stale || false; - if (options.maxAge && typeof options.maxAge !== 'number') - throw new TypeError('maxAge must be a number') - this[MAX_AGE] = options.maxAge || 0; - this[DISPOSE] = options.dispose; - this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false; - this[UPDATE_AGE_ON_GET] = options.updateAgeOnGet || false; - this.reset(); - } - - // resize the cache when the max changes. - set max (mL) { - if (typeof mL !== 'number' || mL < 0) - throw new TypeError('max must be a non-negative number') - - this[MAX] = mL || Infinity; - trim(this); - } - get max () { - return this[MAX] - } - - set allowStale (allowStale) { - this[ALLOW_STALE] = !!allowStale; - } - get allowStale () { - return this[ALLOW_STALE] - } - - set maxAge (mA) { - if (typeof mA !== 'number') - throw new TypeError('maxAge must be a non-negative number') - - this[MAX_AGE] = mA; - trim(this); - } - get maxAge () { - return this[MAX_AGE] - } - - // resize the cache when the lengthCalculator changes. - set lengthCalculator (lC) { - if (typeof lC !== 'function') - lC = naiveLength; - - if (lC !== this[LENGTH_CALCULATOR]) { - this[LENGTH_CALCULATOR] = lC; - this[LENGTH] = 0; - this[LRU_LIST].forEach(hit => { - hit.length = this[LENGTH_CALCULATOR](hit.value, hit.key); - this[LENGTH] += hit.length; - }); - } - trim(this); - } - get lengthCalculator () { return this[LENGTH_CALCULATOR] } - - get length () { return this[LENGTH] } - get itemCount () { return this[LRU_LIST].length } - - rforEach (fn, thisp) { - thisp = thisp || this; - for (let walker = this[LRU_LIST].tail; walker !== null;) { - const prev = walker.prev; - forEachStep(this, fn, walker, thisp); - walker = prev; - } - } - - forEach (fn, thisp) { - thisp = thisp || this; - for (let walker = this[LRU_LIST].head; walker !== null;) { - const next = walker.next; - forEachStep(this, fn, walker, thisp); - walker = next; - } - } - - keys () { - return this[LRU_LIST].toArray().map(k => k.key) - } - - values () { - return this[LRU_LIST].toArray().map(k => k.value) - } - - reset () { - if (this[DISPOSE] && - this[LRU_LIST] && - this[LRU_LIST].length) { - this[LRU_LIST].forEach(hit => this[DISPOSE](hit.key, hit.value)); - } - - this[CACHE] = new Map(); // hash of items by key - this[LRU_LIST] = new Yallist(); // list of items in order of use recency - this[LENGTH] = 0; // length of items in the list - } - - dump () { - return this[LRU_LIST].map(hit => - isStale(this, hit) ? false : { - k: hit.key, - v: hit.value, - e: hit.now + (hit.maxAge || 0) - }).toArray().filter(h => h) - } - - dumpLru () { - return this[LRU_LIST] - } - - set (key, value, maxAge) { - maxAge = maxAge || this[MAX_AGE]; - - if (maxAge && typeof maxAge !== 'number') - throw new TypeError('maxAge must be a number') - - const now = maxAge ? Date.now() : 0; - const len = this[LENGTH_CALCULATOR](value, key); - - if (this[CACHE].has(key)) { - if (len > this[MAX]) { - del(this, this[CACHE].get(key)); - return false - } - - const node = this[CACHE].get(key); - const item = node.value; - - // dispose of the old one before overwriting - // split out into 2 ifs for better coverage tracking - if (this[DISPOSE]) { - if (!this[NO_DISPOSE_ON_SET]) - this[DISPOSE](key, item.value); - } - - item.now = now; - item.maxAge = maxAge; - item.value = value; - this[LENGTH] += len - item.length; - item.length = len; - this.get(key); - trim(this); - return true - } - - const hit = new Entry(key, value, len, now, maxAge); - - // oversized objects fall out of cache automatically. - if (hit.length > this[MAX]) { - if (this[DISPOSE]) - this[DISPOSE](key, value); - - return false - } - - this[LENGTH] += hit.length; - this[LRU_LIST].unshift(hit); - this[CACHE].set(key, this[LRU_LIST].head); - trim(this); - return true - } - - has (key) { - if (!this[CACHE].has(key)) return false - const hit = this[CACHE].get(key).value; - return !isStale(this, hit) - } - - get (key) { - return get(this, key, true) - } - - peek (key) { - return get(this, key, false) - } - - pop () { - const node = this[LRU_LIST].tail; - if (!node) - return null - - del(this, node); - return node.value - } - - del (key) { - del(this, this[CACHE].get(key)); - } - - load (arr) { - // reset the cache - this.reset(); - - const now = Date.now(); - // A previous serialized cache has the most recent items first - for (let l = arr.length - 1; l >= 0; l--) { - const hit = arr[l]; - const expiresAt = hit.e || 0; - if (expiresAt === 0) - // the item was created without expiration in a non aged cache - this.set(hit.k, hit.v); - else { - const maxAge = expiresAt - now; - // dont add already expired items - if (maxAge > 0) { - this.set(hit.k, hit.v, maxAge); - } - } - } - } - - prune () { - this[CACHE].forEach((value, key) => get(this, key, false)); - } -} - -const get = (self, key, doUse) => { - const node = self[CACHE].get(key); - if (node) { - const hit = node.value; - if (isStale(self, hit)) { - del(self, node); - if (!self[ALLOW_STALE]) - return undefined - } else { - if (doUse) { - if (self[UPDATE_AGE_ON_GET]) - node.value.now = Date.now(); - self[LRU_LIST].unshiftNode(node); - } - } - return hit.value - } -}; - -const isStale = (self, hit) => { - if (!hit || (!hit.maxAge && !self[MAX_AGE])) - return false - - const diff = Date.now() - hit.now; - return hit.maxAge ? diff > hit.maxAge - : self[MAX_AGE] && (diff > self[MAX_AGE]) -}; - -const trim = self => { - if (self[LENGTH] > self[MAX]) { - for (let walker = self[LRU_LIST].tail; - self[LENGTH] > self[MAX] && walker !== null;) { - // We know that we're about to delete this one, and also - // what the next least recently used key will be, so just - // go ahead and set it now. - const prev = walker.prev; - del(self, walker); - walker = prev; - } - } -}; - -const del = (self, node) => { - if (node) { - const hit = node.value; - if (self[DISPOSE]) - self[DISPOSE](hit.key, hit.value); - - self[LENGTH] -= hit.length; - self[CACHE].delete(hit.key); - self[LRU_LIST].removeNode(node); - } -}; - -class Entry { - constructor (key, value, length, now, maxAge) { - this.key = key; - this.value = value; - this.length = length; - this.now = now; - this.maxAge = maxAge || 0; - } -} - -const forEachStep = (self, fn, node, thisp) => { - let hit = node.value; - if (isStale(self, hit)) { - del(self, node); - if (!self[ALLOW_STALE]) - hit = undefined; - } - if (hit) - fn.call(thisp, hit.value, hit.key, self); -}; - -var lruCache = LRUCache; - -// hoisted class for cyclic dependency -class Range$a { - constructor (range, options) { - options = parseOptions$1(options); - - if (range instanceof Range$a) { - if ( - range.loose === !!options.loose && - range.includePrerelease === !!options.includePrerelease - ) { - return range - } else { - return new Range$a(range.raw, options) - } - } - - if (range instanceof Comparator$3) { - // just put it in the set and return - this.raw = range.value; - this.set = [[range]]; - this.format(); - return this - } - - this.options = options; - this.loose = !!options.loose; - this.includePrerelease = !!options.includePrerelease; - - // First, split based on boolean or || - this.raw = range; - this.set = range - .split(/\s*\|\|\s*/) - // map the range to a 2d array of comparators - .map(range => this.parseRange(range.trim())) - // throw out any comparator lists that are empty - // this generally means that it was not a valid range, which is allowed - // in loose mode, but will still throw if the WHOLE range is invalid. - .filter(c => c.length); - - if (!this.set.length) { - throw new TypeError(`Invalid SemVer Range: ${range}`) - } - - // if we have any that are not the null set, throw out null sets. - if (this.set.length > 1) { - // keep the first one, in case they're all null sets - const first = this.set[0]; - this.set = this.set.filter(c => !isNullSet(c[0])); - if (this.set.length === 0) - this.set = [first]; - else if (this.set.length > 1) { - // if we have any that are *, then the range is just * - for (const c of this.set) { - if (c.length === 1 && isAny(c[0])) { - this.set = [c]; - break - } - } - } - } - - this.format(); - } - - format () { - this.range = this.set - .map((comps) => { - return comps.join(' ').trim() - }) - .join('||') - .trim(); - return this.range - } - - toString () { - return this.range - } - - parseRange (range) { - range = range.trim(); - - // memoize range parsing for performance. - // this is a very hot path, and fully deterministic. - const memoOpts = Object.keys(this.options).join(','); - const memoKey = `parseRange:${memoOpts}:${range}`; - const cached = cache.get(memoKey); - if (cached) - return cached - - const loose = this.options.loose; - // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` - const hr = loose ? re$2[t$1.HYPHENRANGELOOSE] : re$2[t$1.HYPHENRANGE]; - range = range.replace(hr, hyphenReplace(this.options.includePrerelease)); - debug$d('hyphen replace', range); - // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` - range = range.replace(re$2[t$1.COMPARATORTRIM], comparatorTrimReplace); - debug$d('comparator trim', range, re$2[t$1.COMPARATORTRIM]); - - // `~ 1.2.3` => `~1.2.3` - range = range.replace(re$2[t$1.TILDETRIM], tildeTrimReplace); - - // `^ 1.2.3` => `^1.2.3` - range = range.replace(re$2[t$1.CARETTRIM], caretTrimReplace); - - // normalize spaces - range = range.split(/\s+/).join(' '); - - // At this point, the range is completely trimmed and - // ready to be split into comparators. - - const compRe = loose ? re$2[t$1.COMPARATORLOOSE] : re$2[t$1.COMPARATOR]; - const rangeList = range - .split(' ') - .map(comp => parseComparator(comp, this.options)) - .join(' ') - .split(/\s+/) - // >=0.0.0 is equivalent to * - .map(comp => replaceGTE0(comp, this.options)) - // in loose mode, throw out any that are not valid comparators - .filter(this.options.loose ? comp => !!comp.match(compRe) : () => true) - .map(comp => new Comparator$3(comp, this.options)); - - // if any comparators are the null set, then replace with JUST null set - // if more than one comparator, remove any * comparators - // also, don't include the same comparator more than once - rangeList.length; - const rangeMap = new Map(); - for (const comp of rangeList) { - if (isNullSet(comp)) - return [comp] - rangeMap.set(comp.value, comp); - } - if (rangeMap.size > 1 && rangeMap.has('')) - rangeMap.delete(''); - - const result = [...rangeMap.values()]; - cache.set(memoKey, result); - return result - } - - intersects (range, options) { - if (!(range instanceof Range$a)) { - throw new TypeError('a Range is required') - } - - return this.set.some((thisComparators) => { - return ( - isSatisfiable(thisComparators, options) && - range.set.some((rangeComparators) => { - return ( - isSatisfiable(rangeComparators, options) && - thisComparators.every((thisComparator) => { - return rangeComparators.every((rangeComparator) => { - return thisComparator.intersects(rangeComparator, options) - }) - }) - ) - }) - ) - }) - } - - // if ANY of the sets match ALL of its comparators, then pass - test (version) { - if (!version) { - return false - } - - if (typeof version === 'string') { - try { - version = new SemVer$5(version, this.options); - } catch (er) { - return false - } - } - - for (let i = 0; i < this.set.length; i++) { - if (testSet(this.set[i], version, this.options)) { - return true - } - } - return false - } -} -var range$1 = Range$a; - -const LRU = lruCache; -const cache = new LRU({ max: 1000 }); - -const parseOptions$1 = parseOptions_1; -const Comparator$3 = comparator$1; -const debug$d = debug_1; -const SemVer$5 = semver$2; -const { - re: re$2, - t: t$1, - comparatorTrimReplace, - tildeTrimReplace, - caretTrimReplace -} = re$6.exports; - -const isNullSet = c => c.value === '<0.0.0-0'; -const isAny = c => c.value === ''; - -// take a set of comparators and determine whether there -// exists a version which can satisfy it -const isSatisfiable = (comparators, options) => { - let result = true; - const remainingComparators = comparators.slice(); - let testComparator = remainingComparators.pop(); - - while (result && remainingComparators.length) { - result = remainingComparators.every((otherComparator) => { - return testComparator.intersects(otherComparator, options) - }); - - testComparator = remainingComparators.pop(); - } - - return result -}; - -// comprised of xranges, tildes, stars, and gtlt's at this point. -// already replaced the hyphen ranges -// turn into a set of JUST comparators. -const parseComparator = (comp, options) => { - debug$d('comp', comp, options); - comp = replaceCarets(comp, options); - debug$d('caret', comp); - comp = replaceTildes(comp, options); - debug$d('tildes', comp); - comp = replaceXRanges(comp, options); - debug$d('xrange', comp); - comp = replaceStars(comp, options); - debug$d('stars', comp); - return comp -}; - -const isX = id => !id || id.toLowerCase() === 'x' || id === '*'; - -// ~, ~> --> * (any, kinda silly) -// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0-0 -// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0-0 -// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0-0 -// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0 -// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0 -const replaceTildes = (comp, options) => - comp.trim().split(/\s+/).map((comp) => { - return replaceTilde(comp, options) - }).join(' '); - -const replaceTilde = (comp, options) => { - const r = options.loose ? re$2[t$1.TILDELOOSE] : re$2[t$1.TILDE]; - return comp.replace(r, (_, M, m, p, pr) => { - debug$d('tilde', comp, _, M, m, p, pr); - let ret; - - if (isX(M)) { - ret = ''; - } else if (isX(m)) { - ret = `>=${M}.0.0 <${+M + 1}.0.0-0`; - } else if (isX(p)) { - // ~1.2 == >=1.2.0 <1.3.0-0 - ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0`; - } else if (pr) { - debug$d('replaceTilde pr', pr); - ret = `>=${M}.${m}.${p}-${pr - } <${M}.${+m + 1}.0-0`; - } else { - // ~1.2.3 == >=1.2.3 <1.3.0-0 - ret = `>=${M}.${m}.${p - } <${M}.${+m + 1}.0-0`; - } - - debug$d('tilde return', ret); - return ret - }) -}; - -// ^ --> * (any, kinda silly) -// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0-0 -// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0-0 -// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0-0 -// ^1.2.3 --> >=1.2.3 <2.0.0-0 -// ^1.2.0 --> >=1.2.0 <2.0.0-0 -const replaceCarets = (comp, options) => - comp.trim().split(/\s+/).map((comp) => { - return replaceCaret(comp, options) - }).join(' '); - -const replaceCaret = (comp, options) => { - debug$d('caret', comp, options); - const r = options.loose ? re$2[t$1.CARETLOOSE] : re$2[t$1.CARET]; - const z = options.includePrerelease ? '-0' : ''; - return comp.replace(r, (_, M, m, p, pr) => { - debug$d('caret', comp, _, M, m, p, pr); - let ret; - - if (isX(M)) { - ret = ''; - } else if (isX(m)) { - ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0`; - } else if (isX(p)) { - if (M === '0') { - ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0`; - } else { - ret = `>=${M}.${m}.0${z} <${+M + 1}.0.0-0`; - } - } else if (pr) { - debug$d('replaceCaret pr', pr); - if (M === '0') { - if (m === '0') { - ret = `>=${M}.${m}.${p}-${pr - } <${M}.${m}.${+p + 1}-0`; - } else { - ret = `>=${M}.${m}.${p}-${pr - } <${M}.${+m + 1}.0-0`; - } - } else { - ret = `>=${M}.${m}.${p}-${pr - } <${+M + 1}.0.0-0`; - } - } else { - debug$d('no pr'); - if (M === '0') { - if (m === '0') { - ret = `>=${M}.${m}.${p - }${z} <${M}.${m}.${+p + 1}-0`; - } else { - ret = `>=${M}.${m}.${p - }${z} <${M}.${+m + 1}.0-0`; - } - } else { - ret = `>=${M}.${m}.${p - } <${+M + 1}.0.0-0`; - } - } - - debug$d('caret return', ret); - return ret - }) -}; - -const replaceXRanges = (comp, options) => { - debug$d('replaceXRanges', comp, options); - return comp.split(/\s+/).map((comp) => { - return replaceXRange(comp, options) - }).join(' ') -}; - -const replaceXRange = (comp, options) => { - comp = comp.trim(); - const r = options.loose ? re$2[t$1.XRANGELOOSE] : re$2[t$1.XRANGE]; - return comp.replace(r, (ret, gtlt, M, m, p, pr) => { - debug$d('xRange', comp, ret, gtlt, M, m, p, pr); - const xM = isX(M); - const xm = xM || isX(m); - const xp = xm || isX(p); - const anyX = xp; - - if (gtlt === '=' && anyX) { - gtlt = ''; - } - - // if we're including prereleases in the match, then we need - // to fix this to -0, the lowest possible prerelease value - pr = options.includePrerelease ? '-0' : ''; - - if (xM) { - if (gtlt === '>' || gtlt === '<') { - // nothing is allowed - ret = '<0.0.0-0'; - } else { - // nothing is forbidden - ret = '*'; - } - } else if (gtlt && anyX) { - // we know patch is an x, because we have any x at all. - // replace X with 0 - if (xm) { - m = 0; - } - p = 0; - - if (gtlt === '>') { - // >1 => >=2.0.0 - // >1.2 => >=1.3.0 - gtlt = '>='; - if (xm) { - M = +M + 1; - m = 0; - p = 0; - } else { - m = +m + 1; - p = 0; - } - } else if (gtlt === '<=') { - // <=0.7.x is actually <0.8.0, since any 0.7.x should - // pass. Similarly, <=7.x is actually <8.0.0, etc. - gtlt = '<'; - if (xm) { - M = +M + 1; - } else { - m = +m + 1; - } - } - - if (gtlt === '<') - pr = '-0'; - - ret = `${gtlt + M}.${m}.${p}${pr}`; - } else if (xm) { - ret = `>=${M}.0.0${pr} <${+M + 1}.0.0-0`; - } else if (xp) { - ret = `>=${M}.${m}.0${pr - } <${M}.${+m + 1}.0-0`; - } - - debug$d('xRange return', ret); - - return ret - }) -}; - -// Because * is AND-ed with everything else in the comparator, -// and '' means "any version", just remove the *s entirely. -const replaceStars = (comp, options) => { - debug$d('replaceStars', comp, options); - // Looseness is ignored here. star is always as loose as it gets! - return comp.trim().replace(re$2[t$1.STAR], '') -}; - -const replaceGTE0 = (comp, options) => { - debug$d('replaceGTE0', comp, options); - return comp.trim() - .replace(re$2[options.includePrerelease ? t$1.GTE0PRE : t$1.GTE0], '') -}; - -// This function is passed to string.replace(re[t.HYPHENRANGE]) -// M, m, patch, prerelease, build -// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 -// 1.2.3 - 3.4 => >=1.2.0 <3.5.0-0 Any 3.4.x will do -// 1.2 - 3.4 => >=1.2.0 <3.5.0-0 -const hyphenReplace = incPr => ($0, - from, fM, fm, fp, fpr, fb, - to, tM, tm, tp, tpr, tb) => { - if (isX(fM)) { - from = ''; - } else if (isX(fm)) { - from = `>=${fM}.0.0${incPr ? '-0' : ''}`; - } else if (isX(fp)) { - from = `>=${fM}.${fm}.0${incPr ? '-0' : ''}`; - } else if (fpr) { - from = `>=${from}`; - } else { - from = `>=${from}${incPr ? '-0' : ''}`; - } - - if (isX(tM)) { - to = ''; - } else if (isX(tm)) { - to = `<${+tM + 1}.0.0-0`; - } else if (isX(tp)) { - to = `<${tM}.${+tm + 1}.0-0`; - } else if (tpr) { - to = `<=${tM}.${tm}.${tp}-${tpr}`; - } else if (incPr) { - to = `<${tM}.${tm}.${+tp + 1}-0`; - } else { - to = `<=${to}`; - } - - return (`${from} ${to}`).trim() -}; - -const testSet = (set, version, options) => { - for (let i = 0; i < set.length; i++) { - if (!set[i].test(version)) { - return false - } - } - - if (version.prerelease.length && !options.includePrerelease) { - // Find the set of versions that are allowed to have prereleases - // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 - // That should allow `1.2.3-pr.2` to pass. - // However, `1.2.4-alpha.notready` should NOT be allowed, - // even though it's within the range set by the comparators. - for (let i = 0; i < set.length; i++) { - debug$d(set[i].semver); - if (set[i].semver === Comparator$3.ANY) { - continue - } - - if (set[i].semver.prerelease.length > 0) { - const allowed = set[i].semver; - if (allowed.major === version.major && - allowed.minor === version.minor && - allowed.patch === version.patch) { - return true - } - } - } - - // Version has a -pre, but it's not one of the ones we like. - return false - } - - return true -}; - -const ANY$2 = Symbol('SemVer ANY'); -// hoisted class for cyclic dependency -class Comparator$2 { - static get ANY () { - return ANY$2 - } - constructor (comp, options) { - options = parseOptions(options); - - if (comp instanceof Comparator$2) { - if (comp.loose === !!options.loose) { - return comp - } else { - comp = comp.value; - } - } - - debug$c('comparator', comp, options); - this.options = options; - this.loose = !!options.loose; - this.parse(comp); - - if (this.semver === ANY$2) { - this.value = ''; - } else { - this.value = this.operator + this.semver.version; - } - - debug$c('comp', this); - } - - parse (comp) { - const r = this.options.loose ? re$1[t.COMPARATORLOOSE] : re$1[t.COMPARATOR]; - const m = comp.match(r); - - if (!m) { - throw new TypeError(`Invalid comparator: ${comp}`) - } - - this.operator = m[1] !== undefined ? m[1] : ''; - if (this.operator === '=') { - this.operator = ''; - } - - // if it literally is just '>' or '' then allow anything. - if (!m[2]) { - this.semver = ANY$2; - } else { - this.semver = new SemVer$4(m[2], this.options.loose); - } - } - - toString () { - return this.value - } - - test (version) { - debug$c('Comparator.test', version, this.options.loose); - - if (this.semver === ANY$2 || version === ANY$2) { - return true - } - - if (typeof version === 'string') { - try { - version = new SemVer$4(version, this.options); - } catch (er) { - return false - } - } - - return cmp(version, this.operator, this.semver, this.options) - } - - intersects (comp, options) { - if (!(comp instanceof Comparator$2)) { - throw new TypeError('a Comparator is required') - } - - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - }; - } - - if (this.operator === '') { - if (this.value === '') { - return true - } - return new Range$9(comp.value, options).test(this.value) - } else if (comp.operator === '') { - if (comp.value === '') { - return true - } - return new Range$9(this.value, options).test(comp.semver) - } - - const sameDirectionIncreasing = - (this.operator === '>=' || this.operator === '>') && - (comp.operator === '>=' || comp.operator === '>'); - const sameDirectionDecreasing = - (this.operator === '<=' || this.operator === '<') && - (comp.operator === '<=' || comp.operator === '<'); - const sameSemVer = this.semver.version === comp.semver.version; - const differentDirectionsInclusive = - (this.operator === '>=' || this.operator === '<=') && - (comp.operator === '>=' || comp.operator === '<='); - const oppositeDirectionsLessThan = - cmp(this.semver, '<', comp.semver, options) && - (this.operator === '>=' || this.operator === '>') && - (comp.operator === '<=' || comp.operator === '<'); - const oppositeDirectionsGreaterThan = - cmp(this.semver, '>', comp.semver, options) && - (this.operator === '<=' || this.operator === '<') && - (comp.operator === '>=' || comp.operator === '>'); - - return ( - sameDirectionIncreasing || - sameDirectionDecreasing || - (sameSemVer && differentDirectionsInclusive) || - oppositeDirectionsLessThan || - oppositeDirectionsGreaterThan - ) - } -} - -var comparator$1 = Comparator$2; - -const parseOptions = parseOptions_1; -const {re: re$1, t} = re$6.exports; -const cmp = cmp_1; -const debug$c = debug_1; -const SemVer$4 = semver$2; -const Range$9 = range$1; - -const Range$8 = range$1; -const satisfies$3 = (version, range, options) => { - try { - range = new Range$8(range, options); - } catch (er) { - return false - } - return range.test(version) -}; -var satisfies_1 = satisfies$3; - -const Range$7 = range$1; - -// Mostly just for testing and legacy API reasons -const toComparators = (range, options) => - new Range$7(range, options).set - .map(comp => comp.map(c => c.value).join(' ').trim().split(' ')); - -var toComparators_1 = toComparators; - -const SemVer$3 = semver$2; -const Range$6 = range$1; - -const maxSatisfying = (versions, range, options) => { - let max = null; - let maxSV = null; - let rangeObj = null; - try { - rangeObj = new Range$6(range, options); - } catch (er) { - return null - } - versions.forEach((v) => { - if (rangeObj.test(v)) { - // satisfies(v, range, options) - if (!max || maxSV.compare(v) === -1) { - // compare(max, v, true) - max = v; - maxSV = new SemVer$3(max, options); - } - } - }); - return max -}; -var maxSatisfying_1 = maxSatisfying; - -const SemVer$2 = semver$2; -const Range$5 = range$1; -const minSatisfying = (versions, range, options) => { - let min = null; - let minSV = null; - let rangeObj = null; - try { - rangeObj = new Range$5(range, options); - } catch (er) { - return null - } - versions.forEach((v) => { - if (rangeObj.test(v)) { - // satisfies(v, range, options) - if (!min || minSV.compare(v) === 1) { - // compare(min, v, true) - min = v; - minSV = new SemVer$2(min, options); - } - } - }); - return min -}; -var minSatisfying_1 = minSatisfying; - -const SemVer$1 = semver$2; -const Range$4 = range$1; -const gt$1 = gt_1; - -const minVersion = (range, loose) => { - range = new Range$4(range, loose); - - let minver = new SemVer$1('0.0.0'); - if (range.test(minver)) { - return minver - } - - minver = new SemVer$1('0.0.0-0'); - if (range.test(minver)) { - return minver - } - - minver = null; - for (let i = 0; i < range.set.length; ++i) { - const comparators = range.set[i]; - - let setMin = null; - comparators.forEach((comparator) => { - // Clone to avoid manipulating the comparator's semver object. - const compver = new SemVer$1(comparator.semver.version); - switch (comparator.operator) { - case '>': - if (compver.prerelease.length === 0) { - compver.patch++; - } else { - compver.prerelease.push(0); - } - compver.raw = compver.format(); - /* fallthrough */ - case '': - case '>=': - if (!setMin || gt$1(compver, setMin)) { - setMin = compver; - } - break - case '<': - case '<=': - /* Ignore maximum versions */ - break - /* istanbul ignore next */ - default: - throw new Error(`Unexpected operation: ${comparator.operator}`) - } - }); - if (setMin && (!minver || gt$1(minver, setMin))) - minver = setMin; - } - - if (minver && range.test(minver)) { - return minver - } - - return null -}; -var minVersion_1 = minVersion; - -const Range$3 = range$1; -const validRange = (range, options) => { - try { - // Return '*' instead of '' so that truthiness works. - // This will throw if it's invalid anyway - return new Range$3(range, options).range || '*' - } catch (er) { - return null - } -}; -var valid = validRange; - -const SemVer = semver$2; -const Comparator$1 = comparator$1; -const {ANY: ANY$1} = Comparator$1; -const Range$2 = range$1; -const satisfies$2 = satisfies_1; -const gt = gt_1; -const lt = lt_1; -const lte$1 = lte_1; -const gte$1 = gte_1; - -const outside$2 = (version, range, hilo, options) => { - version = new SemVer(version, options); - range = new Range$2(range, options); - - let gtfn, ltefn, ltfn, comp, ecomp; - switch (hilo) { - case '>': - gtfn = gt; - ltefn = lte$1; - ltfn = lt; - comp = '>'; - ecomp = '>='; - break - case '<': - gtfn = lt; - ltefn = gte$1; - ltfn = gt; - comp = '<'; - ecomp = '<='; - break - default: - throw new TypeError('Must provide a hilo val of "<" or ">"') - } - - // If it satisfies the range it is not outside - if (satisfies$2(version, range, options)) { - return false - } - - // From now on, variable terms are as if we're in "gtr" mode. - // but note that everything is flipped for the "ltr" function. - - for (let i = 0; i < range.set.length; ++i) { - const comparators = range.set[i]; - - let high = null; - let low = null; - - comparators.forEach((comparator) => { - if (comparator.semver === ANY$1) { - comparator = new Comparator$1('>=0.0.0'); - } - high = high || comparator; - low = low || comparator; - if (gtfn(comparator.semver, high.semver, options)) { - high = comparator; - } else if (ltfn(comparator.semver, low.semver, options)) { - low = comparator; - } - }); - - // If the edge version comparator has a operator then our version - // isn't outside it - if (high.operator === comp || high.operator === ecomp) { - return false - } - - // If the lowest version comparator has an operator and our version - // is less than it then it isn't higher than the range - if ((!low.operator || low.operator === comp) && - ltefn(version, low.semver)) { - return false - } else if (low.operator === ecomp && ltfn(version, low.semver)) { - return false - } - } - return true -}; - -var outside_1 = outside$2; - -// Determine if version is greater than all the versions possible in the range. -const outside$1 = outside_1; -const gtr = (version, range, options) => outside$1(version, range, '>', options); -var gtr_1 = gtr; - -const outside = outside_1; -// Determine if version is less than all the versions possible in the range -const ltr = (version, range, options) => outside(version, range, '<', options); -var ltr_1 = ltr; - -const Range$1 = range$1; -const intersects = (r1, r2, options) => { - r1 = new Range$1(r1, options); - r2 = new Range$1(r2, options); - return r1.intersects(r2) -}; -var intersects_1 = intersects; - -// given a set of versions and a range, create a "simplified" range -// that includes the same versions that the original range does -// If the original range is shorter than the simplified one, return that. -const satisfies$1 = satisfies_1; -const compare$2 = compare_1; -var simplify = (versions, range, options) => { - const set = []; - let min = null; - let prev = null; - const v = versions.sort((a, b) => compare$2(a, b, options)); - for (const version of v) { - const included = satisfies$1(version, range, options); - if (included) { - prev = version; - if (!min) - min = version; - } else { - if (prev) { - set.push([min, prev]); - } - prev = null; - min = null; - } - } - if (min) - set.push([min, null]); - - const ranges = []; - for (const [min, max] of set) { - if (min === max) - ranges.push(min); - else if (!max && min === v[0]) - ranges.push('*'); - else if (!max) - ranges.push(`>=${min}`); - else if (min === v[0]) - ranges.push(`<=${max}`); - else - ranges.push(`${min} - ${max}`); - } - const simplified = ranges.join(' || '); - const original = typeof range.raw === 'string' ? range.raw : String(range); - return simplified.length < original.length ? simplified : range -}; - -const Range = range$1; -const Comparator = comparator$1; -const { ANY } = Comparator; -const satisfies = satisfies_1; -const compare$1 = compare_1; - -// Complex range `r1 || r2 || ...` is a subset of `R1 || R2 || ...` iff: -// - Every simple range `r1, r2, ...` is a null set, OR -// - Every simple range `r1, r2, ...` which is not a null set is a subset of -// some `R1, R2, ...` -// -// Simple range `c1 c2 ...` is a subset of simple range `C1 C2 ...` iff: -// - If c is only the ANY comparator -// - If C is only the ANY comparator, return true -// - Else if in prerelease mode, return false -// - else replace c with `[>=0.0.0]` -// - If C is only the ANY comparator -// - if in prerelease mode, return true -// - else replace C with `[>=0.0.0]` -// - Let EQ be the set of = comparators in c -// - If EQ is more than one, return true (null set) -// - Let GT be the highest > or >= comparator in c -// - Let LT be the lowest < or <= comparator in c -// - If GT and LT, and GT.semver > LT.semver, return true (null set) -// - If any C is a = range, and GT or LT are set, return false -// - If EQ -// - If GT, and EQ does not satisfy GT, return true (null set) -// - If LT, and EQ does not satisfy LT, return true (null set) -// - If EQ satisfies every C, return true -// - Else return false -// - If GT -// - If GT.semver is lower than any > or >= comp in C, return false -// - If GT is >=, and GT.semver does not satisfy every C, return false -// - If GT.semver has a prerelease, and not in prerelease mode -// - If no C has a prerelease and the GT.semver tuple, return false -// - If LT -// - If LT.semver is greater than any < or <= comp in C, return false -// - If LT is <=, and LT.semver does not satisfy every C, return false -// - If GT.semver has a prerelease, and not in prerelease mode -// - If no C has a prerelease and the LT.semver tuple, return false -// - Else return true - -const subset = (sub, dom, options = {}) => { - if (sub === dom) - return true - - sub = new Range(sub, options); - dom = new Range(dom, options); - let sawNonNull = false; - - OUTER: for (const simpleSub of sub.set) { - for (const simpleDom of dom.set) { - const isSub = simpleSubset(simpleSub, simpleDom, options); - sawNonNull = sawNonNull || isSub !== null; - if (isSub) - continue OUTER - } - // the null set is a subset of everything, but null simple ranges in - // a complex range should be ignored. so if we saw a non-null range, - // then we know this isn't a subset, but if EVERY simple range was null, - // then it is a subset. - if (sawNonNull) - return false - } - return true -}; - -const simpleSubset = (sub, dom, options) => { - if (sub === dom) - return true - - if (sub.length === 1 && sub[0].semver === ANY) { - if (dom.length === 1 && dom[0].semver === ANY) - return true - else if (options.includePrerelease) - sub = [ new Comparator('>=0.0.0-0') ]; - else - sub = [ new Comparator('>=0.0.0') ]; - } - - if (dom.length === 1 && dom[0].semver === ANY) { - if (options.includePrerelease) - return true - else - dom = [ new Comparator('>=0.0.0') ]; - } - - const eqSet = new Set(); - let gt, lt; - for (const c of sub) { - if (c.operator === '>' || c.operator === '>=') - gt = higherGT(gt, c, options); - else if (c.operator === '<' || c.operator === '<=') - lt = lowerLT(lt, c, options); - else - eqSet.add(c.semver); - } - - if (eqSet.size > 1) - return null - - let gtltComp; - if (gt && lt) { - gtltComp = compare$1(gt.semver, lt.semver, options); - if (gtltComp > 0) - return null - else if (gtltComp === 0 && (gt.operator !== '>=' || lt.operator !== '<=')) - return null - } - - // will iterate one or zero times - for (const eq of eqSet) { - if (gt && !satisfies(eq, String(gt), options)) - return null - - if (lt && !satisfies(eq, String(lt), options)) - return null - - for (const c of dom) { - if (!satisfies(eq, String(c), options)) - return false - } - - return true - } - - let higher, lower; - let hasDomLT, hasDomGT; - // if the subset has a prerelease, we need a comparator in the superset - // with the same tuple and a prerelease, or it's not a subset - let needDomLTPre = lt && - !options.includePrerelease && - lt.semver.prerelease.length ? lt.semver : false; - let needDomGTPre = gt && - !options.includePrerelease && - gt.semver.prerelease.length ? gt.semver : false; - // exception: <1.2.3-0 is the same as <1.2.3 - if (needDomLTPre && needDomLTPre.prerelease.length === 1 && - lt.operator === '<' && needDomLTPre.prerelease[0] === 0) { - needDomLTPre = false; - } - - for (const c of dom) { - hasDomGT = hasDomGT || c.operator === '>' || c.operator === '>='; - hasDomLT = hasDomLT || c.operator === '<' || c.operator === '<='; - if (gt) { - if (needDomGTPre) { - if (c.semver.prerelease && c.semver.prerelease.length && - c.semver.major === needDomGTPre.major && - c.semver.minor === needDomGTPre.minor && - c.semver.patch === needDomGTPre.patch) { - needDomGTPre = false; - } - } - if (c.operator === '>' || c.operator === '>=') { - higher = higherGT(gt, c, options); - if (higher === c && higher !== gt) - return false - } else if (gt.operator === '>=' && !satisfies(gt.semver, String(c), options)) - return false - } - if (lt) { - if (needDomLTPre) { - if (c.semver.prerelease && c.semver.prerelease.length && - c.semver.major === needDomLTPre.major && - c.semver.minor === needDomLTPre.minor && - c.semver.patch === needDomLTPre.patch) { - needDomLTPre = false; - } - } - if (c.operator === '<' || c.operator === '<=') { - lower = lowerLT(lt, c, options); - if (lower === c && lower !== lt) - return false - } else if (lt.operator === '<=' && !satisfies(lt.semver, String(c), options)) - return false - } - if (!c.operator && (lt || gt) && gtltComp !== 0) - return false - } - - // if there was a < or >, and nothing in the dom, then must be false - // UNLESS it was limited by another range in the other direction. - // Eg, >1.0.0 <1.0.1 is still a subset of <2.0.0 - if (gt && hasDomLT && !lt && gtltComp !== 0) - return false - - if (lt && hasDomGT && !gt && gtltComp !== 0) - return false - - // we needed a prerelease range in a specific tuple, but didn't get one - // then this isn't a subset. eg >=1.2.3-pre is not a subset of >=1.0.0, - // because it includes prereleases in the 1.2.3 tuple - if (needDomGTPre || needDomLTPre) - return false - - return true -}; - -// >=1.2.3 is lower than >1.2.3 -const higherGT = (a, b, options) => { - if (!a) - return b - const comp = compare$1(a.semver, b.semver, options); - return comp > 0 ? a - : comp < 0 ? b - : b.operator === '>' && a.operator === '>=' ? b - : a -}; - -// <=1.2.3 is higher than <1.2.3 -const lowerLT = (a, b, options) => { - if (!a) - return b - const comp = compare$1(a.semver, b.semver, options); - return comp < 0 ? a - : comp > 0 ? b - : b.operator === '<' && a.operator === '<=' ? b - : a -}; - -var subset_1 = subset; - -// just pre-load all the stuff that index.js lazily exports -const internalRe = re$6.exports; -var semver$1 = { - re: internalRe.re, - src: internalRe.src, - tokens: internalRe.t, - SEMVER_SPEC_VERSION: constants.SEMVER_SPEC_VERSION, - SemVer: semver$2, - compareIdentifiers: identifiers.compareIdentifiers, - rcompareIdentifiers: identifiers.rcompareIdentifiers, - parse: parse_1, - valid: valid_1, - clean: clean_1, - inc: inc_1, - diff: diff_1, - major: major_1, - minor: minor_1, - patch: patch_1, - prerelease: prerelease_1, - compare: compare_1, - rcompare: rcompare_1, - compareLoose: compareLoose_1, - compareBuild: compareBuild_1, - sort: sort_1, - rsort: rsort_1, - gt: gt_1, - lt: lt_1, - eq: eq_1, - neq: neq_1, - gte: gte_1, - lte: lte_1, - cmp: cmp_1, - coerce: coerce_1, - Comparator: comparator$1, - Range: range$1, - satisfies: satisfies_1, - toComparators: toComparators_1, - maxSatisfying: maxSatisfying_1, - minSatisfying: minSatisfying_1, - minVersion: minVersion_1, - validRange: valid, - outside: outside_1, - gtr: gtr_1, - ltr: ltr_1, - intersects: intersects_1, - simplifyRange: simplify, - subset: subset_1, -}; - -var semver = semver$1; - -var builtins = function ({ - version = process.version, - experimental = false -} = {}) { - var coreModules = [ - 'assert', - 'buffer', - 'child_process', - 'cluster', - 'console', - 'constants', - 'crypto', - 'dgram', - 'dns', - 'domain', - 'events', - 'fs', - 'http', - 'https', - 'module', - 'net', - 'os', - 'path', - 'punycode', - 'querystring', - 'readline', - 'repl', - 'stream', - 'string_decoder', - 'sys', - 'timers', - 'tls', - 'tty', - 'url', - 'util', - 'vm', - 'zlib' - ]; - - if (semver.lt(version, '6.0.0')) coreModules.push('freelist'); - if (semver.gte(version, '1.0.0')) coreModules.push('v8'); - if (semver.gte(version, '1.1.0')) coreModules.push('process'); - if (semver.gte(version, '8.0.0')) coreModules.push('inspector'); - if (semver.gte(version, '8.1.0')) coreModules.push('async_hooks'); - if (semver.gte(version, '8.4.0')) coreModules.push('http2'); - if (semver.gte(version, '8.5.0')) coreModules.push('perf_hooks'); - if (semver.gte(version, '10.0.0')) coreModules.push('trace_events'); - - if ( - semver.gte(version, '10.5.0') && - (experimental || semver.gte(version, '12.0.0')) - ) { - coreModules.push('worker_threads'); - } - if (semver.gte(version, '12.16.0') && experimental) { - coreModules.push('wasi'); - } - - return coreModules -}; - -// Manually “tree shaken” from: - -const reader = {read: read$3}; -var packageJsonReader = reader; - -/** - * @param {string} jsonPath - * @returns {{string: string}} - */ -function read$3(jsonPath) { - return find$1(path$b.dirname(jsonPath)) -} - -/** - * @param {string} dir - * @returns {{string: string}} - */ -function find$1(dir) { - try { - const string = require$$0$3.readFileSync( - path$b.toNamespacedPath(path$b.join(dir, 'package.json')), - 'utf8' - ); - return {string} - } catch (error) { - if (error.code === 'ENOENT') { - const parent = path$b.dirname(dir); - if (dir !== parent) return find$1(parent) - return {string: undefined} - // Throw all other errors. - /* c8 ignore next 4 */ - } - - throw error - } -} - -// Manually “tree shaken” from: - -const isWindows$1 = process.platform === 'win32'; - -const own$e = {}.hasOwnProperty; - -const codes = {}; - -/** - * @typedef {(...args: unknown[]) => string} MessageFunction - */ - -/** @type {Map} */ -const messages = new Map(); -const nodeInternalPrefix = '__node_internal_'; -/** @type {number} */ -let userStackTraceLimit; - -codes.ERR_INVALID_MODULE_SPECIFIER = createError( - 'ERR_INVALID_MODULE_SPECIFIER', - /** - * @param {string} request - * @param {string} reason - * @param {string} [base] - */ - (request, reason, base = undefined) => { - return `Invalid module "${request}" ${reason}${ - base ? ` imported from ${base}` : '' - }` - }, - TypeError -); - -codes.ERR_INVALID_PACKAGE_CONFIG = createError( - 'ERR_INVALID_PACKAGE_CONFIG', - /** - * @param {string} path - * @param {string} [base] - * @param {string} [message] - */ - (path, base, message) => { - return `Invalid package config ${path}${ - base ? ` while importing ${base}` : '' - }${message ? `. ${message}` : ''}` - }, - Error -); - -codes.ERR_INVALID_PACKAGE_TARGET = createError( - 'ERR_INVALID_PACKAGE_TARGET', - /** - * @param {string} pkgPath - * @param {string} key - * @param {unknown} target - * @param {boolean} [isImport=false] - * @param {string} [base] - */ - (pkgPath, key, target, isImport = false, base = undefined) => { - const relError = - typeof target === 'string' && - !isImport && - target.length > 0 && - !target.startsWith('./'); - if (key === '.') { - assert$2(isImport === false); - return ( - `Invalid "exports" main target ${JSON.stringify(target)} defined ` + - `in the package config ${pkgPath}package.json${ - base ? ` imported from ${base}` : '' - }${relError ? '; targets must start with "./"' : ''}` - ) - } - - return `Invalid "${ - isImport ? 'imports' : 'exports' - }" target ${JSON.stringify( - target - )} defined for '${key}' in the package config ${pkgPath}package.json${ - base ? ` imported from ${base}` : '' - }${relError ? '; targets must start with "./"' : ''}` - }, - Error -); - -codes.ERR_MODULE_NOT_FOUND = createError( - 'ERR_MODULE_NOT_FOUND', - /** - * @param {string} path - * @param {string} base - * @param {string} [type] - */ - (path, base, type = 'package') => { - return `Cannot find ${type} '${path}' imported from ${base}` - }, - Error -); - -codes.ERR_PACKAGE_IMPORT_NOT_DEFINED = createError( - 'ERR_PACKAGE_IMPORT_NOT_DEFINED', - /** - * @param {string} specifier - * @param {string} packagePath - * @param {string} base - */ - (specifier, packagePath, base) => { - return `Package import specifier "${specifier}" is not defined${ - packagePath ? ` in package ${packagePath}package.json` : '' - } imported from ${base}` - }, - TypeError -); - -codes.ERR_PACKAGE_PATH_NOT_EXPORTED = createError( - 'ERR_PACKAGE_PATH_NOT_EXPORTED', - /** - * @param {string} pkgPath - * @param {string} subpath - * @param {string} [base] - */ - (pkgPath, subpath, base = undefined) => { - if (subpath === '.') - return `No "exports" main defined in ${pkgPath}package.json${ - base ? ` imported from ${base}` : '' - }` - return `Package subpath '${subpath}' is not defined by "exports" in ${pkgPath}package.json${ - base ? ` imported from ${base}` : '' - }` - }, - Error -); - -codes.ERR_UNSUPPORTED_DIR_IMPORT = createError( - 'ERR_UNSUPPORTED_DIR_IMPORT', - "Directory import '%s' is not supported " + - 'resolving ES modules imported from %s', - Error -); - -codes.ERR_UNKNOWN_FILE_EXTENSION = createError( - 'ERR_UNKNOWN_FILE_EXTENSION', - 'Unknown file extension "%s" for %s', - TypeError -); - -codes.ERR_INVALID_ARG_VALUE = createError( - 'ERR_INVALID_ARG_VALUE', - /** - * @param {string} name - * @param {unknown} value - * @param {string} [reason='is invalid'] - */ - (name, value, reason = 'is invalid') => { - let inspected = inspect$1(value); - - if (inspected.length > 128) { - inspected = `${inspected.slice(0, 128)}...`; - } - - const type = name.includes('.') ? 'property' : 'argument'; - - return `The ${type} '${name}' ${reason}. Received ${inspected}` - }, - TypeError - // Note: extra classes have been shaken out. - // , RangeError -); - -codes.ERR_UNSUPPORTED_ESM_URL_SCHEME = createError( - 'ERR_UNSUPPORTED_ESM_URL_SCHEME', - /** - * @param {URL} url - */ - (url) => { - let message = - 'Only file and data URLs are supported by the default ESM loader'; - - if (isWindows$1 && url.protocol.length === 2) { - message += '. On Windows, absolute paths must be valid file:// URLs'; - } - - message += `. Received protocol '${url.protocol}'`; - return message - }, - Error -); - -/** - * Utility function for registering the error codes. Only used here. Exported - * *only* to allow for testing. - * @param {string} sym - * @param {MessageFunction|string} value - * @param {ErrorConstructor} def - * @returns {new (...args: unknown[]) => Error} - */ -function createError(sym, value, def) { - // Special case for SystemError that formats the error message differently - // The SystemErrors only have SystemError as their base classes. - messages.set(sym, value); - - return makeNodeErrorWithCode(def, sym) -} - -/** - * @param {ErrorConstructor} Base - * @param {string} key - * @returns {ErrorConstructor} - */ -function makeNodeErrorWithCode(Base, key) { - // @ts-expect-error It’s a Node error. - return NodeError - /** - * @param {unknown[]} args - */ - function NodeError(...args) { - const limit = Error.stackTraceLimit; - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; - const error = new Base(); - // Reset the limit and setting the name property. - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = limit; - const message = getMessage(key, args, error); - Object.defineProperty(error, 'message', { - value: message, - enumerable: false, - writable: true, - configurable: true - }); - Object.defineProperty(error, 'toString', { - /** @this {Error} */ - value() { - return `${this.name} [${key}]: ${this.message}` - }, - enumerable: false, - writable: true, - configurable: true - }); - addCodeToName(error, Base.name, key); - // @ts-expect-error It’s a Node error. - error.code = key; - return error - } -} - -const addCodeToName = hideStackFrames( - /** - * @param {Error} error - * @param {string} name - * @param {string} code - * @returns {void} - */ - function (error, name, code) { - // Set the stack - error = captureLargerStackTrace(error); - // Add the error code to the name to include it in the stack trace. - error.name = `${name} [${code}]`; - // Access the stack to generate the error message including the error code - // from the name. - error.stack; // eslint-disable-line no-unused-expressions - // Reset the name to the actual name. - if (name === 'SystemError') { - Object.defineProperty(error, 'name', { - value: name, - enumerable: false, - writable: true, - configurable: true - }); - } else { - delete error.name; - } - } -); - -/** - * @returns {boolean} - */ -function isErrorStackTraceLimitWritable() { - const desc = Object.getOwnPropertyDescriptor(Error, 'stackTraceLimit'); - if (desc === undefined) { - return Object.isExtensible(Error) - } - - return own$e.call(desc, 'writable') ? desc.writable : desc.set !== undefined -} - -/** - * This function removes unnecessary frames from Node.js core errors. - * @template {(...args: unknown[]) => unknown} T - * @type {(fn: T) => T} - */ -function hideStackFrames(fn) { - // We rename the functions that will be hidden to cut off the stacktrace - // at the outermost one - const hidden = nodeInternalPrefix + fn.name; - Object.defineProperty(fn, 'name', {value: hidden}); - return fn -} - -const captureLargerStackTrace = hideStackFrames( - /** - * @param {Error} error - * @returns {Error} - */ - function (error) { - const stackTraceLimitIsWritable = isErrorStackTraceLimitWritable(); - if (stackTraceLimitIsWritable) { - userStackTraceLimit = Error.stackTraceLimit; - Error.stackTraceLimit = Number.POSITIVE_INFINITY; - } - - Error.captureStackTrace(error); - - // Reset the limit - if (stackTraceLimitIsWritable) Error.stackTraceLimit = userStackTraceLimit; - - return error - } -); - -/** - * @param {string} key - * @param {unknown[]} args - * @param {Error} self - * @returns {string} - */ -function getMessage(key, args, self) { - const message = messages.get(key); - - if (typeof message === 'function') { - assert$2( - message.length <= args.length, // Default options do not count. - `Code: ${key}; The provided arguments length (${args.length}) does not ` + - `match the required ones (${message.length}).` - ); - return Reflect.apply(message, self, args) - } - - const expectedLength = (message.match(/%[dfijoOs]/g) || []).length; - assert$2( - expectedLength === args.length, - `Code: ${key}; The provided arguments length (${args.length}) does not ` + - `match the required ones (${expectedLength}).` - ); - if (args.length === 0) return message - - args.unshift(message); - return Reflect.apply(format$2, null, args) -} - -// Manually “tree shaken” from: - -const {ERR_UNKNOWN_FILE_EXTENSION} = codes; - -const extensionFormatMap = { - __proto__: null, - '.cjs': 'commonjs', - '.js': 'module', - '.mjs': 'module' -}; - -/** - * @param {string} url - * @returns {{format: string|null}} - */ -function defaultGetFormat(url) { - if (url.startsWith('node:')) { - return {format: 'builtin'} - } - - const parsed = new URL$1(url); - - if (parsed.protocol === 'data:') { - const {1: mime} = /^([^/]+\/[^;,]+)[^,]*?(;base64)?,/.exec( - parsed.pathname - ) || [null, null]; - const format = mime === 'text/javascript' ? 'module' : null; - return {format} - } - - if (parsed.protocol === 'file:') { - const ext = path$b.extname(parsed.pathname); - /** @type {string} */ - let format; - if (ext === '.js') { - format = getPackageType(parsed.href) === 'module' ? 'module' : 'commonjs'; - } else { - format = extensionFormatMap[ext]; - } - - if (!format) { - throw new ERR_UNKNOWN_FILE_EXTENSION(ext, fileURLToPath(url)) - } - - return {format: format || null} - } - - return {format: null} -} - -// Manually “tree shaken” from: - -const listOfBuiltins = builtins(); - -const { - ERR_INVALID_MODULE_SPECIFIER, - ERR_INVALID_PACKAGE_CONFIG, - ERR_INVALID_PACKAGE_TARGET, - ERR_MODULE_NOT_FOUND, - ERR_PACKAGE_IMPORT_NOT_DEFINED, - ERR_PACKAGE_PATH_NOT_EXPORTED, - ERR_UNSUPPORTED_DIR_IMPORT, - ERR_UNSUPPORTED_ESM_URL_SCHEME, - ERR_INVALID_ARG_VALUE -} = codes; - -const own$d = {}.hasOwnProperty; - -const DEFAULT_CONDITIONS = Object.freeze(['node', 'import']); -const DEFAULT_CONDITIONS_SET = new Set(DEFAULT_CONDITIONS); - -const invalidSegmentRegEx = /(^|\\|\/)(\.\.?|node_modules)(\\|\/|$)/; -const patternRegEx = /\*/g; -const encodedSepRegEx = /%2f|%2c/i; -/** @type {Set} */ -const emittedPackageWarnings = new Set(); -/** @type {Map} */ -const packageJsonCache = new Map(); - -/** - * @param {string} match - * @param {URL} pjsonUrl - * @param {boolean} isExports - * @param {URL} base - * @returns {void} - */ -function emitFolderMapDeprecation(match, pjsonUrl, isExports, base) { - const pjsonPath = fileURLToPath(pjsonUrl); - - if (emittedPackageWarnings.has(pjsonPath + '|' + match)) return - emittedPackageWarnings.add(pjsonPath + '|' + match); - process.emitWarning( - `Use of deprecated folder mapping "${match}" in the ${ - isExports ? '"exports"' : '"imports"' - } field module resolution of the package at ${pjsonPath}${ - base ? ` imported from ${fileURLToPath(base)}` : '' - }.\n` + - `Update this package.json to use a subpath pattern like "${match}*".`, - 'DeprecationWarning', - 'DEP0148' - ); -} - -/** - * @param {URL} url - * @param {URL} packageJsonUrl - * @param {URL} base - * @param {unknown} [main] - * @returns {void} - */ -function emitLegacyIndexDeprecation(url, packageJsonUrl, base, main) { - const {format} = defaultGetFormat(url.href); - if (format !== 'module') return - const path = fileURLToPath(url.href); - const pkgPath = fileURLToPath(new URL$1('.', packageJsonUrl)); - const basePath = fileURLToPath(base); - if (main) - process.emitWarning( - `Package ${pkgPath} has a "main" field set to ${JSON.stringify(main)}, ` + - `excluding the full filename and extension to the resolved file at "${path.slice( - pkgPath.length - )}", imported from ${basePath}.\n Automatic extension resolution of the "main" field is` + - 'deprecated for ES modules.', - 'DeprecationWarning', - 'DEP0151' - ); - else - process.emitWarning( - `No "main" or "exports" field defined in the package.json for ${pkgPath} resolving the main entry point "${path.slice( - pkgPath.length - )}", imported from ${basePath}.\nDefault "index" lookups for the main are deprecated for ES modules.`, - 'DeprecationWarning', - 'DEP0151' - ); -} - -/** - * @param {string[]} [conditions] - * @returns {Set} - */ -function getConditionsSet(conditions) { - if (conditions !== undefined && conditions !== DEFAULT_CONDITIONS) { - if (!Array.isArray(conditions)) { - throw new ERR_INVALID_ARG_VALUE( - 'conditions', - conditions, - 'expected an array' - ) - } - - return new Set(conditions) - } - - return DEFAULT_CONDITIONS_SET -} - -/** - * @param {string} path - * @returns {Stats} - */ -function tryStatSync(path) { - // Note: from Node 15 onwards we can use `throwIfNoEntry: false` instead. - try { - return statSync(path) - } catch { - return new Stats() - } -} - -/** - * @param {string} path - * @param {string|URL} specifier Note: `specifier` is actually optional, not base. - * @param {URL} [base] - * @returns {PackageConfig} - */ -function getPackageConfig(path, specifier, base) { - const existing = packageJsonCache.get(path); - if (existing !== undefined) { - return existing - } - - const source = packageJsonReader.read(path).string; - - if (source === undefined) { - /** @type {PackageConfig} */ - const packageConfig = { - pjsonPath: path, - exists: false, - main: undefined, - name: undefined, - type: 'none', - exports: undefined, - imports: undefined - }; - packageJsonCache.set(path, packageConfig); - return packageConfig - } - - /** @type {Object.} */ - let packageJson; - try { - packageJson = JSON.parse(source); - } catch (error) { - throw new ERR_INVALID_PACKAGE_CONFIG( - path, - (base ? `"${specifier}" from ` : '') + fileURLToPath(base || specifier), - error.message - ) - } - - const {exports, imports, main, name, type} = packageJson; - - /** @type {PackageConfig} */ - const packageConfig = { - pjsonPath: path, - exists: true, - main: typeof main === 'string' ? main : undefined, - name: typeof name === 'string' ? name : undefined, - type: type === 'module' || type === 'commonjs' ? type : 'none', - // @ts-expect-error Assume `Object.`. - exports, - // @ts-expect-error Assume `Object.`. - imports: imports && typeof imports === 'object' ? imports : undefined - }; - packageJsonCache.set(path, packageConfig); - return packageConfig -} - -/** - * @param {URL|string} resolved - * @returns {PackageConfig} - */ -function getPackageScopeConfig(resolved) { - let packageJsonUrl = new URL$1('./package.json', resolved); - - while (true) { - const packageJsonPath = packageJsonUrl.pathname; - - if (packageJsonPath.endsWith('node_modules/package.json')) break - - const packageConfig = getPackageConfig( - fileURLToPath(packageJsonUrl), - resolved - ); - if (packageConfig.exists) return packageConfig - - const lastPackageJsonUrl = packageJsonUrl; - packageJsonUrl = new URL$1('../package.json', packageJsonUrl); - - // Terminates at root where ../package.json equals ../../package.json - // (can't just check "/package.json" for Windows support). - if (packageJsonUrl.pathname === lastPackageJsonUrl.pathname) break - } - - const packageJsonPath = fileURLToPath(packageJsonUrl); - /** @type {PackageConfig} */ - const packageConfig = { - pjsonPath: packageJsonPath, - exists: false, - main: undefined, - name: undefined, - type: 'none', - exports: undefined, - imports: undefined - }; - packageJsonCache.set(packageJsonPath, packageConfig); - return packageConfig -} - -/** - * Legacy CommonJS main resolution: - * 1. let M = pkg_url + (json main field) - * 2. TRY(M, M.js, M.json, M.node) - * 3. TRY(M/index.js, M/index.json, M/index.node) - * 4. TRY(pkg_url/index.js, pkg_url/index.json, pkg_url/index.node) - * 5. NOT_FOUND - * - * @param {URL} url - * @returns {boolean} - */ -function fileExists(url) { - return tryStatSync(fileURLToPath(url)).isFile() -} - -/** - * @param {URL} packageJsonUrl - * @param {PackageConfig} packageConfig - * @param {URL} base - * @returns {URL} - */ -function legacyMainResolve(packageJsonUrl, packageConfig, base) { - /** @type {URL} */ - let guess; - if (packageConfig.main !== undefined) { - guess = new URL$1(`./${packageConfig.main}`, packageJsonUrl); - // Note: fs check redundances will be handled by Descriptor cache here. - if (fileExists(guess)) return guess - - const tries = [ - `./${packageConfig.main}.js`, - `./${packageConfig.main}.json`, - `./${packageConfig.main}.node`, - `./${packageConfig.main}/index.js`, - `./${packageConfig.main}/index.json`, - `./${packageConfig.main}/index.node` - ]; - let i = -1; - - while (++i < tries.length) { - guess = new URL$1(tries[i], packageJsonUrl); - if (fileExists(guess)) break - guess = undefined; - } - - if (guess) { - emitLegacyIndexDeprecation( - guess, - packageJsonUrl, - base, - packageConfig.main - ); - return guess - } - // Fallthrough. - } - - const tries = ['./index.js', './index.json', './index.node']; - let i = -1; - - while (++i < tries.length) { - guess = new URL$1(tries[i], packageJsonUrl); - if (fileExists(guess)) break - guess = undefined; - } - - if (guess) { - emitLegacyIndexDeprecation(guess, packageJsonUrl, base, packageConfig.main); - return guess - } - - // Not found. - throw new ERR_MODULE_NOT_FOUND( - fileURLToPath(new URL$1('.', packageJsonUrl)), - fileURLToPath(base) - ) -} - -/** - * @param {URL} resolved - * @param {URL} base - * @returns {URL} - */ -function finalizeResolution(resolved, base) { - if (encodedSepRegEx.test(resolved.pathname)) - throw new ERR_INVALID_MODULE_SPECIFIER( - resolved.pathname, - 'must not include encoded "/" or "\\" characters', - fileURLToPath(base) - ) - - const path = fileURLToPath(resolved); - - const stats = tryStatSync(path.endsWith('/') ? path.slice(-1) : path); - - if (stats.isDirectory()) { - const error = new ERR_UNSUPPORTED_DIR_IMPORT(path, fileURLToPath(base)); - // @ts-expect-error Add this for `import.meta.resolve`. - error.url = String(resolved); - throw error - } - - if (!stats.isFile()) { - throw new ERR_MODULE_NOT_FOUND( - path || resolved.pathname, - base && fileURLToPath(base), - 'module' - ) - } - - return resolved -} - -/** - * @param {string} specifier - * @param {URL?} packageJsonUrl - * @param {URL} base - * @returns {never} - */ -function throwImportNotDefined(specifier, packageJsonUrl, base) { - throw new ERR_PACKAGE_IMPORT_NOT_DEFINED( - specifier, - packageJsonUrl && fileURLToPath(new URL$1('.', packageJsonUrl)), - fileURLToPath(base) - ) -} - -/** - * @param {string} subpath - * @param {URL} packageJsonUrl - * @param {URL} base - * @returns {never} - */ -function throwExportsNotFound(subpath, packageJsonUrl, base) { - throw new ERR_PACKAGE_PATH_NOT_EXPORTED( - fileURLToPath(new URL$1('.', packageJsonUrl)), - subpath, - base && fileURLToPath(base) - ) -} - -/** - * @param {string} subpath - * @param {URL} packageJsonUrl - * @param {boolean} internal - * @param {URL} [base] - * @returns {never} - */ -function throwInvalidSubpath(subpath, packageJsonUrl, internal, base) { - const reason = `request is not a valid subpath for the "${ - internal ? 'imports' : 'exports' - }" resolution of ${fileURLToPath(packageJsonUrl)}`; - - throw new ERR_INVALID_MODULE_SPECIFIER( - subpath, - reason, - base && fileURLToPath(base) - ) -} - -/** - * @param {string} subpath - * @param {unknown} target - * @param {URL} packageJsonUrl - * @param {boolean} internal - * @param {URL} [base] - * @returns {never} - */ -function throwInvalidPackageTarget( - subpath, - target, - packageJsonUrl, - internal, - base -) { - target = - typeof target === 'object' && target !== null - ? JSON.stringify(target, null, '') - : `${target}`; - - throw new ERR_INVALID_PACKAGE_TARGET( - fileURLToPath(new URL$1('.', packageJsonUrl)), - subpath, - target, - internal, - base && fileURLToPath(base) - ) -} - -/** - * @param {string} target - * @param {string} subpath - * @param {string} match - * @param {URL} packageJsonUrl - * @param {URL} base - * @param {boolean} pattern - * @param {boolean} internal - * @param {Set} conditions - * @returns {URL} - */ -function resolvePackageTargetString( - target, - subpath, - match, - packageJsonUrl, - base, - pattern, - internal, - conditions -) { - if (subpath !== '' && !pattern && target[target.length - 1] !== '/') - throwInvalidPackageTarget(match, target, packageJsonUrl, internal, base); - - if (!target.startsWith('./')) { - if (internal && !target.startsWith('../') && !target.startsWith('/')) { - let isURL = false; - - try { - new URL$1(target); - isURL = true; - } catch {} - - if (!isURL) { - const exportTarget = pattern - ? target.replace(patternRegEx, subpath) - : target + subpath; - - return packageResolve(exportTarget, packageJsonUrl, conditions) - } - } - - throwInvalidPackageTarget(match, target, packageJsonUrl, internal, base); - } - - if (invalidSegmentRegEx.test(target.slice(2))) - throwInvalidPackageTarget(match, target, packageJsonUrl, internal, base); - - const resolved = new URL$1(target, packageJsonUrl); - const resolvedPath = resolved.pathname; - const packagePath = new URL$1('.', packageJsonUrl).pathname; - - if (!resolvedPath.startsWith(packagePath)) - throwInvalidPackageTarget(match, target, packageJsonUrl, internal, base); - - if (subpath === '') return resolved - - if (invalidSegmentRegEx.test(subpath)) - throwInvalidSubpath(match + subpath, packageJsonUrl, internal, base); - - if (pattern) return new URL$1(resolved.href.replace(patternRegEx, subpath)) - return new URL$1(subpath, resolved) -} - -/** - * @param {string} key - * @returns {boolean} - */ -function isArrayIndex(key) { - const keyNumber = Number(key); - if (`${keyNumber}` !== key) return false - return keyNumber >= 0 && keyNumber < 0xffff_ffff -} - -/** - * @param {URL} packageJsonUrl - * @param {unknown} target - * @param {string} subpath - * @param {string} packageSubpath - * @param {URL} base - * @param {boolean} pattern - * @param {boolean} internal - * @param {Set} conditions - * @returns {URL} - */ -function resolvePackageTarget( - packageJsonUrl, - target, - subpath, - packageSubpath, - base, - pattern, - internal, - conditions -) { - if (typeof target === 'string') { - return resolvePackageTargetString( - target, - subpath, - packageSubpath, - packageJsonUrl, - base, - pattern, - internal, - conditions - ) - } - - if (Array.isArray(target)) { - /** @type {unknown[]} */ - const targetList = target; - if (targetList.length === 0) return null - - /** @type {Error} */ - let lastException; - let i = -1; - - while (++i < targetList.length) { - const targetItem = targetList[i]; - /** @type {URL} */ - let resolved; - try { - resolved = resolvePackageTarget( - packageJsonUrl, - targetItem, - subpath, - packageSubpath, - base, - pattern, - internal, - conditions - ); - } catch (error) { - lastException = error; - if (error.code === 'ERR_INVALID_PACKAGE_TARGET') continue - throw error - } - - if (resolved === undefined) continue - - if (resolved === null) { - lastException = null; - continue - } - - return resolved - } - - if (lastException === undefined || lastException === null) { - // @ts-expect-error The diff between `undefined` and `null` seems to be - // intentional - return lastException - } - - throw lastException - } - - if (typeof target === 'object' && target !== null) { - const keys = Object.getOwnPropertyNames(target); - let i = -1; - - while (++i < keys.length) { - const key = keys[i]; - if (isArrayIndex(key)) { - throw new ERR_INVALID_PACKAGE_CONFIG( - fileURLToPath(packageJsonUrl), - base, - '"exports" cannot contain numeric property keys.' - ) - } - } - - i = -1; - - while (++i < keys.length) { - const key = keys[i]; - if (key === 'default' || (conditions && conditions.has(key))) { - /** @type {unknown} */ - const conditionalTarget = target[key]; - const resolved = resolvePackageTarget( - packageJsonUrl, - conditionalTarget, - subpath, - packageSubpath, - base, - pattern, - internal, - conditions - ); - if (resolved === undefined) continue - return resolved - } - } - - return undefined - } - - if (target === null) { - return null - } - - throwInvalidPackageTarget( - packageSubpath, - target, - packageJsonUrl, - internal, - base - ); -} - -/** - * @param {unknown} exports - * @param {URL} packageJsonUrl - * @param {URL} base - * @returns {boolean} - */ -function isConditionalExportsMainSugar(exports, packageJsonUrl, base) { - if (typeof exports === 'string' || Array.isArray(exports)) return true - if (typeof exports !== 'object' || exports === null) return false - - const keys = Object.getOwnPropertyNames(exports); - let isConditionalSugar = false; - let i = 0; - let j = -1; - while (++j < keys.length) { - const key = keys[j]; - const curIsConditionalSugar = key === '' || key[0] !== '.'; - if (i++ === 0) { - isConditionalSugar = curIsConditionalSugar; - } else if (isConditionalSugar !== curIsConditionalSugar) { - throw new ERR_INVALID_PACKAGE_CONFIG( - fileURLToPath(packageJsonUrl), - base, - '"exports" cannot contain some keys starting with \'.\' and some not.' + - ' The exports object must either be an object of package subpath keys' + - ' or an object of main entry condition name keys only.' - ) - } - } - - return isConditionalSugar -} - -/** - * @param {URL} packageJsonUrl - * @param {string} packageSubpath - * @param {Object.} packageConfig - * @param {URL} base - * @param {Set} conditions - * @returns {ResolveObject} - */ -function packageExportsResolve( - packageJsonUrl, - packageSubpath, - packageConfig, - base, - conditions -) { - let exports = packageConfig.exports; - if (isConditionalExportsMainSugar(exports, packageJsonUrl, base)) - exports = {'.': exports}; - - if (own$d.call(exports, packageSubpath)) { - const target = exports[packageSubpath]; - const resolved = resolvePackageTarget( - packageJsonUrl, - target, - '', - packageSubpath, - base, - false, - false, - conditions - ); - if (resolved === null || resolved === undefined) - throwExportsNotFound(packageSubpath, packageJsonUrl, base); - return {resolved, exact: true} - } - - let bestMatch = ''; - const keys = Object.getOwnPropertyNames(exports); - let i = -1; - - while (++i < keys.length) { - const key = keys[i]; - if ( - key[key.length - 1] === '*' && - packageSubpath.startsWith(key.slice(0, -1)) && - packageSubpath.length >= key.length && - key.length > bestMatch.length - ) { - bestMatch = key; - } else if ( - key[key.length - 1] === '/' && - packageSubpath.startsWith(key) && - key.length > bestMatch.length - ) { - bestMatch = key; - } - } - - if (bestMatch) { - const target = exports[bestMatch]; - const pattern = bestMatch[bestMatch.length - 1] === '*'; - const subpath = packageSubpath.slice(bestMatch.length - (pattern ? 1 : 0)); - const resolved = resolvePackageTarget( - packageJsonUrl, - target, - subpath, - bestMatch, - base, - pattern, - false, - conditions - ); - if (resolved === null || resolved === undefined) - throwExportsNotFound(packageSubpath, packageJsonUrl, base); - if (!pattern) - emitFolderMapDeprecation(bestMatch, packageJsonUrl, true, base); - return {resolved, exact: pattern} - } - - throwExportsNotFound(packageSubpath, packageJsonUrl, base); -} - -/** - * @param {string} name - * @param {URL} base - * @param {Set} [conditions] - * @returns {ResolveObject} - */ -function packageImportsResolve(name, base, conditions) { - if (name === '#' || name.startsWith('#/')) { - const reason = 'is not a valid internal imports specifier name'; - throw new ERR_INVALID_MODULE_SPECIFIER(name, reason, fileURLToPath(base)) - } - - /** @type {URL} */ - let packageJsonUrl; - - const packageConfig = getPackageScopeConfig(base); - - if (packageConfig.exists) { - packageJsonUrl = pathToFileURL(packageConfig.pjsonPath); - const imports = packageConfig.imports; - if (imports) { - if (own$d.call(imports, name)) { - const resolved = resolvePackageTarget( - packageJsonUrl, - imports[name], - '', - name, - base, - false, - true, - conditions - ); - if (resolved !== null) return {resolved, exact: true} - } else { - let bestMatch = ''; - const keys = Object.getOwnPropertyNames(imports); - let i = -1; - - while (++i < keys.length) { - const key = keys[i]; - - if ( - key[key.length - 1] === '*' && - name.startsWith(key.slice(0, -1)) && - name.length >= key.length && - key.length > bestMatch.length - ) { - bestMatch = key; - } else if ( - key[key.length - 1] === '/' && - name.startsWith(key) && - key.length > bestMatch.length - ) { - bestMatch = key; - } - } - - if (bestMatch) { - const target = imports[bestMatch]; - const pattern = bestMatch[bestMatch.length - 1] === '*'; - const subpath = name.slice(bestMatch.length - (pattern ? 1 : 0)); - const resolved = resolvePackageTarget( - packageJsonUrl, - target, - subpath, - bestMatch, - base, - pattern, - true, - conditions - ); - if (resolved !== null) { - if (!pattern) - emitFolderMapDeprecation(bestMatch, packageJsonUrl, false, base); - return {resolved, exact: pattern} - } - } - } - } - } - - throwImportNotDefined(name, packageJsonUrl, base); -} - -/** - * @param {string} url - * @returns {PackageType} - */ -function getPackageType(url) { - const packageConfig = getPackageScopeConfig(url); - return packageConfig.type -} - -/** - * @param {string} specifier - * @param {URL} base - */ -function parsePackageName(specifier, base) { - let separatorIndex = specifier.indexOf('/'); - let validPackageName = true; - let isScoped = false; - if (specifier[0] === '@') { - isScoped = true; - if (separatorIndex === -1 || specifier.length === 0) { - validPackageName = false; - } else { - separatorIndex = specifier.indexOf('/', separatorIndex + 1); - } - } - - const packageName = - separatorIndex === -1 ? specifier : specifier.slice(0, separatorIndex); - - // Package name cannot have leading . and cannot have percent-encoding or - // separators. - let i = -1; - while (++i < packageName.length) { - if (packageName[i] === '%' || packageName[i] === '\\') { - validPackageName = false; - break - } - } - - if (!validPackageName) { - throw new ERR_INVALID_MODULE_SPECIFIER( - specifier, - 'is not a valid package name', - fileURLToPath(base) - ) - } - - const packageSubpath = - '.' + (separatorIndex === -1 ? '' : specifier.slice(separatorIndex)); - - return {packageName, packageSubpath, isScoped} -} - -/** - * @param {string} specifier - * @param {URL} base - * @param {Set} conditions - * @returns {URL} - */ -function packageResolve(specifier, base, conditions) { - const {packageName, packageSubpath, isScoped} = parsePackageName( - specifier, - base - ); - - // ResolveSelf - const packageConfig = getPackageScopeConfig(base); - - // Can’t test. - /* c8 ignore next 16 */ - if (packageConfig.exists) { - const packageJsonUrl = pathToFileURL(packageConfig.pjsonPath); - if ( - packageConfig.name === packageName && - packageConfig.exports !== undefined && - packageConfig.exports !== null - ) { - return packageExportsResolve( - packageJsonUrl, - packageSubpath, - packageConfig, - base, - conditions - ).resolved - } - } - - let packageJsonUrl = new URL$1( - './node_modules/' + packageName + '/package.json', - base - ); - let packageJsonPath = fileURLToPath(packageJsonUrl); - /** @type {string} */ - let lastPath; - do { - const stat = tryStatSync(packageJsonPath.slice(0, -13)); - if (!stat.isDirectory()) { - lastPath = packageJsonPath; - packageJsonUrl = new URL$1( - (isScoped ? '../../../../node_modules/' : '../../../node_modules/') + - packageName + - '/package.json', - packageJsonUrl - ); - packageJsonPath = fileURLToPath(packageJsonUrl); - continue - } - - // Package match. - const packageConfig = getPackageConfig(packageJsonPath, specifier, base); - if (packageConfig.exports !== undefined && packageConfig.exports !== null) - return packageExportsResolve( - packageJsonUrl, - packageSubpath, - packageConfig, - base, - conditions - ).resolved - if (packageSubpath === '.') - return legacyMainResolve(packageJsonUrl, packageConfig, base) - return new URL$1(packageSubpath, packageJsonUrl) - // Cross-platform root check. - } while (packageJsonPath.length !== lastPath.length) - - throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath(base)) -} - -/** - * @param {string} specifier - * @returns {boolean} - */ -function isRelativeSpecifier(specifier) { - if (specifier[0] === '.') { - if (specifier.length === 1 || specifier[1] === '/') return true - if ( - specifier[1] === '.' && - (specifier.length === 2 || specifier[2] === '/') - ) { - return true - } - } - - return false -} - -/** - * @param {string} specifier - * @returns {boolean} - */ -function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) { - if (specifier === '') return false - if (specifier[0] === '/') return true - return isRelativeSpecifier(specifier) -} - -/** - * The “Resolver Algorithm Specification” as detailed in the Node docs (which is - * sync and slightly lower-level than `resolve`). - * - * - * - * @param {string} specifier - * @param {URL} base - * @param {Set} [conditions] - * @returns {URL} - */ -function moduleResolve(specifier, base, conditions) { - // Order swapped from spec for minor perf gain. - // Ok since relative URLs cannot parse as URLs. - /** @type {URL} */ - let resolved; - - if (shouldBeTreatedAsRelativeOrAbsolutePath(specifier)) { - resolved = new URL$1(specifier, base); - } else if (specifier[0] === '#') { -({resolved} = packageImportsResolve(specifier, base, conditions)); - } else { - try { - resolved = new URL$1(specifier); - } catch { - resolved = packageResolve(specifier, base, conditions); - } - } - - return finalizeResolution(resolved, base) -} - -/** - * @param {string} specifier - * @param {{parentURL?: string, conditions?: string[]}} context - * @returns {{url: string}} - */ -function defaultResolve(specifier, context = {}) { - const {parentURL} = context; - /** @type {URL} */ - let parsed; - - try { - parsed = new URL$1(specifier); - if (parsed.protocol === 'data:') { - return {url: specifier} - } - } catch {} - - if (parsed && parsed.protocol === 'node:') return {url: specifier} - if (parsed && parsed.protocol !== 'file:' && parsed.protocol !== 'data:') - throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(parsed) - - if (listOfBuiltins.includes(specifier)) { - return {url: 'node:' + specifier} - } - - if (parentURL.startsWith('data:')) { - // This is gonna blow up, we want the error - new URL$1(specifier, parentURL); - } - - const conditions = getConditionsSet(context.conditions); - let url = moduleResolve(specifier, new URL$1(parentURL), conditions); - - const urlPath = fileURLToPath(url); - const real = realpathSync$1(urlPath); - const old = url; - url = pathToFileURL(real + (urlPath.endsWith(path$b.sep) ? '/' : '')); - url.search = old.search; - url.hash = old.hash; - - return {url: `${url}`} -} - -/** - * Provides a module-relative resolution function scoped to each module, - * returning the URL string. - * `import.meta.resolve` also accepts a second argument which is the parent - * module from which to resolve from. - * - * This function is asynchronous because the ES module resolver in Node.js is - * allowed to be asynchronous. - * - * @param {string} specifier The module specifier to resolve relative to parent. - * @param {string} parent The absolute parent module URL to resolve from. - * You should pass `import.meta.url` or something else - * @returns {Promise} - */ -async function resolve(specifier, parent) { - if (!parent) { - throw new Error( - 'Please pass `parent`: `import-meta-resolve` cannot ponyfill that' - ) - } - - try { - return defaultResolve(specifier, {parentURL: parent}).url - } catch (error) { - return error.code === 'ERR_UNSUPPORTED_DIR_IMPORT' - ? error.url - : Promise.reject(error) - } -} - -var libnpmconfig = {}; - -class FiggyPudding { - constructor (specs, opts, providers) { - this.__specs = specs || {}; - Object.keys(this.__specs).forEach(alias => { - if (typeof this.__specs[alias] === 'string') { - const key = this.__specs[alias]; - const realSpec = this.__specs[key]; - if (realSpec) { - const aliasArr = realSpec.aliases || []; - aliasArr.push(alias, key); - realSpec.aliases = [...(new Set(aliasArr))]; - this.__specs[alias] = realSpec; - } else { - throw new Error(`Alias refers to invalid key: ${key} -> ${alias}`) - } - } - }); - this.__opts = opts || {}; - this.__providers = reverse((providers).filter( - x => x != null && typeof x === 'object' - )); - this.__isFiggyPudding = true; - } - get (key) { - return pudGet(this, key, true) - } - get [Symbol.toStringTag] () { return 'FiggyPudding' } - forEach (fn, thisArg = this) { - for (let [key, value] of this.entries()) { - fn.call(thisArg, value, key, this); - } - } - toJSON () { - const obj = {}; - this.forEach((val, key) => { - obj[key] = val; - }); - return obj - } - * entries (_matcher) { - for (let key of Object.keys(this.__specs)) { - yield [key, this.get(key)]; - } - const matcher = _matcher || this.__opts.other; - if (matcher) { - const seen = new Set(); - for (let p of this.__providers) { - const iter = p.entries ? p.entries(matcher) : entries(p); - for (let [key, val] of iter) { - if (matcher(key) && !seen.has(key)) { - seen.add(key); - yield [key, val]; - } - } - } - } - } - * [Symbol.iterator] () { - for (let [key, value] of this.entries()) { - yield [key, value]; - } - } - * keys () { - for (let [key] of this.entries()) { - yield key; - } - } - * values () { - for (let [, value] of this.entries()) { - yield value; - } - } - concat (...moreConfig) { - return new Proxy(new FiggyPudding( - this.__specs, - this.__opts, - reverse(this.__providers).concat(moreConfig) - ), proxyHandler) - } -} -try { - const util = require$$0$4; - FiggyPudding.prototype[util.inspect.custom] = function (depth, opts) { - return ( - this[Symbol.toStringTag] + ' ' - ) + util.inspect(this.toJSON(), opts) - }; -} catch (e) {} - -function BadKeyError (key) { - throw Object.assign(new Error( - `invalid config key requested: ${key}` - ), {code: 'EBADKEY'}) -} - -function pudGet (pud, key, validate) { - let spec = pud.__specs[key]; - if (validate && !spec && (!pud.__opts.other || !pud.__opts.other(key))) { - BadKeyError(key); - } else { - if (!spec) { spec = {}; } - let ret; - for (let p of pud.__providers) { - ret = tryGet(key, p); - if (ret === undefined && spec.aliases && spec.aliases.length) { - for (let alias of spec.aliases) { - if (alias === key) { continue } - ret = tryGet(alias, p); - if (ret !== undefined) { - break - } - } - } - if (ret !== undefined) { - break - } - } - if (ret === undefined && spec.default !== undefined) { - if (typeof spec.default === 'function') { - return spec.default(pud) - } else { - return spec.default - } - } else { - return ret - } - } -} - -function tryGet (key, p) { - let ret; - if (p.__isFiggyPudding) { - ret = pudGet(p, key, false); - } else if (typeof p.get === 'function') { - ret = p.get(key); - } else { - ret = p[key]; - } - return ret -} - -const proxyHandler = { - has (obj, prop) { - return prop in obj.__specs && pudGet(obj, prop, false) !== undefined - }, - ownKeys (obj) { - return Object.keys(obj.__specs) - }, - get (obj, prop) { - if ( - typeof prop === 'symbol' || - prop.slice(0, 2) === '__' || - prop in FiggyPudding.prototype - ) { - return obj[prop] - } - return obj.get(prop) - }, - set (obj, prop, value) { - if ( - typeof prop === 'symbol' || - prop.slice(0, 2) === '__' - ) { - obj[prop] = value; - return true - } else { - throw new Error('figgyPudding options cannot be modified. Use .concat() instead.') - } - }, - deleteProperty () { - throw new Error('figgyPudding options cannot be deleted. Use .concat() and shadow them instead.') - } -}; - -var figgyPudding_1 = figgyPudding$1; -function figgyPudding$1 (specs, opts) { - function factory (...providers) { - return new Proxy(new FiggyPudding( - specs, - opts, - providers - ), proxyHandler) - } - return factory -} - -function reverse (arr) { - const ret = []; - arr.forEach(x => ret.unshift(x)); - return ret -} - -function entries (obj) { - return Object.keys(obj).map(k => [k, obj[k]]) -} - -var findUp$1 = {exports: {}}; - -var locatePath$1 = {exports: {}}; - -var pathExists$1 = {exports: {}}; - -const fs$5 = require$$0$3; - -pathExists$1.exports = fp => new Promise(resolve => { - fs$5.access(fp, err => { - resolve(!err); - }); -}); - -pathExists$1.exports.sync = fp => { - try { - fs$5.accessSync(fp); - return true; - } catch (err) { - return false; - } -}; - -var pLimit$2 = {exports: {}}; - -var pTry$2 = {exports: {}}; - -const pTry$1 = (fn, ...arguments_) => new Promise(resolve => { - resolve(fn(...arguments_)); -}); - -pTry$2.exports = pTry$1; -// TODO: remove this in the next major version -pTry$2.exports.default = pTry$1; - -const pTry = pTry$2.exports; - -const pLimit$1 = concurrency => { - if (!((Number.isInteger(concurrency) || concurrency === Infinity) && concurrency > 0)) { - return Promise.reject(new TypeError('Expected `concurrency` to be a number from 1 and up')); - } - - const queue = []; - let activeCount = 0; - - const next = () => { - activeCount--; - - if (queue.length > 0) { - queue.shift()(); - } - }; - - const run = (fn, resolve, ...args) => { - activeCount++; - - const result = pTry(fn, ...args); - - resolve(result); - - result.then(next, next); - }; - - const enqueue = (fn, resolve, ...args) => { - if (activeCount < concurrency) { - run(fn, resolve, ...args); - } else { - queue.push(run.bind(null, fn, resolve, ...args)); - } - }; - - const generator = (fn, ...args) => new Promise(resolve => enqueue(fn, resolve, ...args)); - Object.defineProperties(generator, { - activeCount: { - get: () => activeCount - }, - pendingCount: { - get: () => queue.length - }, - clearQueue: { - value: () => { - queue.length = 0; - } - } - }); - - return generator; -}; - -pLimit$2.exports = pLimit$1; -pLimit$2.exports.default = pLimit$1; - -const pLimit = pLimit$2.exports; - -class EndError extends Error { - constructor(value) { - super(); - this.value = value; - } -} - -// The input can also be a promise, so we `Promise.resolve()` it -const testElement = (el, tester) => Promise.resolve(el).then(tester); - -// The input can also be a promise, so we `Promise.all()` them both -const finder$1 = el => Promise.all(el).then(val => val[1] === true && Promise.reject(new EndError(val[0]))); - -var pLocate$1 = (iterable, tester, opts) => { - opts = Object.assign({ - concurrency: Infinity, - preserveOrder: true - }, opts); - - const limit = pLimit(opts.concurrency); - - // Start all the promises concurrently with optional limit - const items = [...iterable].map(el => [el, limit(testElement, el, tester)]); - - // Check the promises either serially or concurrently - const checkLimit = pLimit(opts.preserveOrder ? 1 : Infinity); - - return Promise.all(items.map(el => checkLimit(finder$1, el))) - .then(() => {}) - .catch(err => err instanceof EndError ? err.value : Promise.reject(err)); -}; - -const path$7 = path$b; -const pathExists = pathExists$1.exports; -const pLocate = pLocate$1; - -locatePath$1.exports = (iterable, options) => { - options = Object.assign({ - cwd: process.cwd() - }, options); - - return pLocate(iterable, el => pathExists(path$7.resolve(options.cwd, el)), options); -}; - -locatePath$1.exports.sync = (iterable, options) => { - options = Object.assign({ - cwd: process.cwd() - }, options); - - for (const el of iterable) { - if (pathExists.sync(path$7.resolve(options.cwd, el))) { - return el; - } - } -}; - -const path$6 = path$b; -const locatePath = locatePath$1.exports; - -findUp$1.exports = (filename, opts = {}) => { - const startDir = path$6.resolve(opts.cwd || ''); - const {root} = path$6.parse(startDir); - - const filenames = [].concat(filename); - - return new Promise(resolve => { - (function find(dir) { - locatePath(filenames, {cwd: dir}).then(file => { - if (file) { - resolve(path$6.join(dir, file)); - } else if (dir === root) { - resolve(null); - } else { - find(path$6.dirname(dir)); - } - }); - })(startDir); - }); -}; - -findUp$1.exports.sync = (filename, opts = {}) => { - let dir = path$6.resolve(opts.cwd || ''); - const {root} = path$6.parse(dir); - - const filenames = [].concat(filename); - - // eslint-disable-next-line no-constant-condition - while (true) { - const file = locatePath.sync(filenames, {cwd: dir}); - - if (file) { - return path$6.join(dir, file); - } - - if (dir === root) { - return null; - } - - dir = path$6.dirname(dir); - } -}; - -var ini$1 = {}; - -ini$1.parse = ini$1.decode = decode; - -ini$1.stringify = ini$1.encode = encode$1; - -ini$1.safe = safe$1; -ini$1.unsafe = unsafe$1; - -var eol$1 = typeof process !== 'undefined' && - process.platform === 'win32' ? '\r\n' : '\n'; - -function encode$1 (obj, opt) { - var children = []; - var out = ''; - - if (typeof opt === 'string') { - opt = { - section: opt, - whitespace: false, - }; - } else { - opt = opt || {}; - opt.whitespace = opt.whitespace === true; - } - - var separator = opt.whitespace ? ' = ' : '='; - - Object.keys(obj).forEach(function (k, _, __) { - var val = obj[k]; - if (val && Array.isArray(val)) { - val.forEach(function (item) { - out += safe$1(k + '[]') + separator + safe$1(item) + '\n'; - }); - } else if (val && typeof val === 'object') - children.push(k); - else - out += safe$1(k) + separator + safe$1(val) + eol$1; - }); - - if (opt.section && out.length) - out = '[' + safe$1(opt.section) + ']' + eol$1 + out; - - children.forEach(function (k, _, __) { - var nk = dotSplit(k).join('\\.'); - var section = (opt.section ? opt.section + '.' : '') + nk; - var child = encode$1(obj[k], { - section: section, - whitespace: opt.whitespace, - }); - if (out.length && child.length) - out += eol$1; - - out += child; - }); - - return out -} - -function dotSplit (str) { - return str.replace(/\1/g, '\u0002LITERAL\\1LITERAL\u0002') - .replace(/\\\./g, '\u0001') - .split(/\./).map(function (part) { - return part.replace(/\1/g, '\\.') - .replace(/\2LITERAL\\1LITERAL\2/g, '\u0001') - }) -} - -function decode (str) { - var out = {}; - var p = out; - var section = null; - // section |key = value - var re = /^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i; - var lines = str.split(/[\r\n]+/g); - - lines.forEach(function (line, _, __) { - if (!line || line.match(/^\s*[;#]/)) - return - var match = line.match(re); - if (!match) - return - if (match[1] !== undefined) { - section = unsafe$1(match[1]); - if (section === '__proto__') { - // not allowed - // keep parsing the section, but don't attach it. - p = {}; - return - } - p = out[section] = out[section] || {}; - return - } - var key = unsafe$1(match[2]); - if (key === '__proto__') - return - var value = match[3] ? unsafe$1(match[4]) : true; - switch (value) { - case 'true': - case 'false': - case 'null': value = JSON.parse(value); - } - - // Convert keys with '[]' suffix to an array - if (key.length > 2 && key.slice(-2) === '[]') { - key = key.substring(0, key.length - 2); - if (key === '__proto__') - return - if (!p[key]) - p[key] = []; - else if (!Array.isArray(p[key])) - p[key] = [p[key]]; - } - - // safeguard against resetting a previously defined - // array by accidentally forgetting the brackets - if (Array.isArray(p[key])) - p[key].push(value); - else - p[key] = value; - }); - - // {a:{y:1},"a.b":{x:2}} --> {a:{y:1,b:{x:2}}} - // use a filter to return the keys that have to be deleted. - Object.keys(out).filter(function (k, _, __) { - if (!out[k] || - typeof out[k] !== 'object' || - Array.isArray(out[k])) - return false - - // see if the parent section is also an object. - // if so, add it to that, and mark this one for deletion - var parts = dotSplit(k); - var p = out; - var l = parts.pop(); - var nl = l.replace(/\\\./g, '.'); - parts.forEach(function (part, _, __) { - if (part === '__proto__') - return - if (!p[part] || typeof p[part] !== 'object') - p[part] = {}; - p = p[part]; - }); - if (p === out && nl === l) - return false - - p[nl] = out[k]; - return true - }).forEach(function (del, _, __) { - delete out[del]; - }); - - return out -} - -function isQuoted (val) { - return (val.charAt(0) === '"' && val.slice(-1) === '"') || - (val.charAt(0) === "'" && val.slice(-1) === "'") -} - -function safe$1 (val) { - return (typeof val !== 'string' || - val.match(/[=\r\n]/) || - val.match(/^\[/) || - (val.length > 1 && - isQuoted(val)) || - val !== val.trim()) - ? JSON.stringify(val) - : val.replace(/;/g, '\\;').replace(/#/g, '\\#') -} - -function unsafe$1 (val, doUnesc) { - val = (val || '').trim(); - if (isQuoted(val)) { - // remove the single quotes before calling JSON.parse - if (val.charAt(0) === "'") - val = val.substr(1, val.length - 2); - - try { - val = JSON.parse(val); - } catch (_) {} - } else { - // walk the val to find the first not-escaped ; character - var esc = false; - var unesc = ''; - for (var i = 0, l = val.length; i < l; i++) { - var c = val.charAt(i); - if (esc) { - if ('\\;#'.indexOf(c) !== -1) - unesc += c; - else - unesc += '\\' + c; - - esc = false; - } else if (';#'.indexOf(c) !== -1) - break - else if (c === '\\') - esc = true; - else - unesc += c; - } - if (esc) - unesc += '\\'; - - return unesc.trim() - } - return val -} - -const fs$4 = require$$0$3; -const figgyPudding = figgyPudding_1; -const findUp = findUp$1.exports; -const ini = ini$1; -const os = require$$0$2; -const path$5 = path$b; - -const NpmConfig = figgyPudding({}, { - // Open up the pudding object. - other () { return true } -}); - -const ConfigOpts = figgyPudding({ - cache: { default: path$5.join(os.homedir(), '.npm') }, - configNames: { default: ['npmrc', '.npmrc'] }, - envPrefix: { default: /^npm_config_/i }, - cwd: { default: () => process.cwd() }, - globalconfig: { - default: () => path$5.join(getGlobalPrefix(), 'etc', 'npmrc') - }, - userconfig: { default: path$5.join(os.homedir(), '.npmrc') } -}); - -libnpmconfig.read = getNpmConfig; -function getNpmConfig (_opts, _builtin) { - const builtin = ConfigOpts(_builtin); - const env = {}; - for (let key of Object.keys(process.env)) { - if (!key.match(builtin.envPrefix)) continue - const newKey = key.toLowerCase() - .replace(builtin.envPrefix, '') - .replace(/(?!^)_/g, '-'); - env[newKey] = process.env[key]; - } - const cli = NpmConfig(_opts); - const userConfPath = ( - builtin.userconfig || - cli.userconfig || - env.userconfig - ); - const user = userConfPath && maybeReadIni(userConfPath); - const globalConfPath = ( - builtin.globalconfig || - cli.globalconfig || - env.globalconfig - ); - const global = globalConfPath && maybeReadIni(globalConfPath); - const projConfPath = findUp.sync(builtin.configNames, { cwd: builtin.cwd }); - let proj = {}; - if (projConfPath && projConfPath !== userConfPath) { - proj = maybeReadIni(projConfPath); - } - const newOpts = NpmConfig(builtin, global, user, proj, env, cli); - if (newOpts.cache) { - return newOpts.concat({ - cache: path$5.resolve( - ( - (cli.cache || env.cache) - ? builtin.cwd - : proj.cache - ? path$5.dirname(projConfPath) - : user.cache - ? path$5.dirname(userConfPath) - : global.cache - ? path$5.dirname(globalConfPath) - : path$5.dirname(userConfPath) - ), - newOpts.cache - ) - }) - } else { - return newOpts - } -} - -function maybeReadIni (f) { - let txt; - try { - txt = fs$4.readFileSync(f, 'utf8'); - } catch (err) { - if (err.code === 'ENOENT') { - return '' - } else { - throw err - } - } - return ini.parse(txt) -} - -function getGlobalPrefix () { - if (process.env.PREFIX) { - return process.env.PREFIX - } else if (process.platform === 'win32') { - // c:\node\node.exe --> prefix=c:\node\ - return path$5.dirname(process.execPath) - } else { - // /usr/local/bin/node --> prefix=/usr/local - let pref = path$5.dirname(path$5.dirname(process.execPath)); - // destdir only is respected on Unix - if (process.env.DESTDIR) { - pref = path$5.join(process.env.DESTDIR, pref); - } - return pref - } -} - -/** - * @typedef ResolveOptions - * @property {string} [prefix] - * @property {string|string[]} [cwd] - * @property {boolean} [global] - */ - -const electron = process.versions.electron !== undefined; -const windows = process.platform === 'win32'; - -const argv = process.argv[1] || /* c8 ignore next */ ''; -const nvm = process.env.NVM_BIN; -const appData = process.env.APPDATA; - -/* c8 ignore next */ -const globalsLibrary = windows ? '' : 'lib'; - -/** @type {{prefix?: string}} */ -let builtinNpmConfig; - -// The prefix config defaults to the location where node is installed. -// On Windows, this is in a place called `%AppData%`, which we have to -// pass to `libnpmconfig` explicitly: -/* c8 ignore next 4 */ -if (windows && appData) { - builtinNpmConfig = {prefix: path$b.join(appData, 'npm')}; -} - -/** - * Note: `libnpmconfig` uses `figgy-pudding` which is slated for archival. - * Either `libnpmconfig` will switch to an alternative or we’ll have to. - * @type {string} - */ -let npmPrefix = libnpmconfig.read(null, builtinNpmConfig).prefix; - -// If there is no prefix defined, use the defaults -// See: -/* c8 ignore next 5 */ -if (!npmPrefix) { - npmPrefix = windows - ? path$b.dirname(process.execPath) - : path$b.resolve(process.execPath, '../..'); -} - -const globalsDefault = electron || argv.indexOf(npmPrefix) === 0; -let globalDir = path$b.resolve(npmPrefix, globalsLibrary, 'node_modules'); - -// If we’re in Electron, we’re running in a modified Node that cannot really -// install global node modules. -// To find the actual modules, the user has to set `prefix` somewhere in an -// `.npmrc` (which is picked up by `libnpmconfig`). -// Most people don’t do that, and some use NVM instead to manage different -// versions of Node. -// Luckily NVM leaks some environment variables that we can pick up on to try -// and detect the actual modules. -/* c8 ignore next 3 */ -if (electron && nvm && !require$$0$3.existsSync(globalDir)) { - globalDir = path$b.resolve(nvm, '..', globalsLibrary, 'node_modules'); -} - -/** - * Load the plugin found using `resolvePlugin`. - * - * @param {string} name The name to import. - * @param {LoadOptions} [options] - * @returns {Promise} - */ -async function loadPlugin(name, options = {}) { - const {key = 'default', ...rest} = options; - const fp = await resolvePlugin(name, rest); - /** @type {Object.} */ - // Bug with coverage on Node@12. - /* c8 ignore next 3 */ - const mod = await import(pathToFileURL(fp).href); - return key === false ? mod : mod[key] -} - -/** - * Find a plugin. - * - * See also: - * * https://docs.npmjs.com/files/folders#node-modules - * * https://github.com/sindresorhus/resolve-from - * - * Uses the standard node module loading strategy to find `$name` in each given - * `cwd` (and optionally the global `node_modules` directory). - * - * If a prefix is given and `$name` is not a path, `$prefix-$name` is also - * searched (preferring these over non-prefixed modules). - * - * @param {string} name - * @param {ResolveOptions} [options] - * @returns {Promise.} - */ -async function resolvePlugin(name, options = {}) { - const prefix = options.prefix - ? options.prefix + - (options.prefix.charAt(options.prefix.length - 1) === '-' ? '' : '-') - : undefined; - const cwd = options.cwd; - const globals = - options.global === undefined || options.global === null - ? globalsDefault - : options.global; - const sources = Array.isArray(cwd) ? cwd.concat() : [cwd || process.cwd()]; - /** @type {string} */ - let plugin; - /** @type {Error} */ - let lastError; - - // Non-path. - if (name.charAt(0) !== '.') { - if (globals) { - sources.push(globalDir); - } - - let scope = ''; - - // Unprefix module. - if (prefix) { - // Scope? - if (name.charAt(0) === '@') { - const slash = name.indexOf('/'); - - // Let’s keep the algorithm simple. - // No need to care if this is a “valid” scope (I think?). - // But we do check for the slash. - if (slash !== -1) { - scope = name.slice(0, slash + 1); - name = name.slice(slash + 1); - } - } - - if (name.slice(0, prefix.length) !== prefix) { - plugin = scope + prefix + name; - } - - name = scope + name; - } - } - - let index = -1; - /** @type {string} */ - let fp; - - while (++index < sources.length) { - fp = plugin && (await attempt(sources[index], plugin)); - if (fp) return fp - - fp = await attempt(sources[index], name); - if (fp) return fp - } - - // There’s always an error. - // Bug with coverage on Node@12. - /* c8 ignore next 8 */ - throw lastError - - /** - * @param {string} base - * @param {string} name - * @returns {Promise} - */ - async function attempt(base, name) { - try { - // `import-meta-resolve` resolves from files, whereas `load-plugin` works - // on folders, which is why we add a `/` at the end. - return fileURLToPath( - await resolve(name, pathToFileURL(base).href + '/') - ) - // Bug with coverage on Node@12. - /* c8 ignore next 1 */ - } catch (error) { - lastError = error; - } - } -} - -function isPlainObject$1(value) { - if (Object.prototype.toString.call(value) !== '[object Object]') { - return false; - } - - const prototype = Object.getPrototypeOf(value); - return prototype === null || prototype === Object.prototype; -} - -var format$1 = {exports: {}}; - -(function (module) { -(function() { - - //// Export the API - var namespace; - - // CommonJS / Node module - { - namespace = module.exports = format; - } - - namespace.format = format; - namespace.vsprintf = vsprintf; - - if (typeof console !== 'undefined' && typeof console.log === 'function') { - namespace.printf = printf; - } - - function printf(/* ... */) { - console.log(format.apply(null, arguments)); - } - - function vsprintf(fmt, replacements) { - return format.apply(null, [fmt].concat(replacements)); - } - - function format(fmt) { - var argIndex = 1 // skip initial format argument - , args = [].slice.call(arguments) - , i = 0 - , n = fmt.length - , result = '' - , c - , escaped = false - , arg - , tmp - , leadingZero = false - , precision - , nextArg = function() { return args[argIndex++]; } - , slurpNumber = function() { - var digits = ''; - while (/\d/.test(fmt[i])) { - digits += fmt[i++]; - c = fmt[i]; - } - return digits.length > 0 ? parseInt(digits) : null; - } - ; - for (; i < n; ++i) { - c = fmt[i]; - if (escaped) { - escaped = false; - if (c == '.') { - leadingZero = false; - c = fmt[++i]; - } - else if (c == '0' && fmt[i + 1] == '.') { - leadingZero = true; - i += 2; - c = fmt[i]; - } - else { - leadingZero = true; - } - precision = slurpNumber(); - switch (c) { - case 'b': // number in binary - result += parseInt(nextArg(), 10).toString(2); - break; - case 'c': // character - arg = nextArg(); - if (typeof arg === 'string' || arg instanceof String) - result += arg; - else - result += String.fromCharCode(parseInt(arg, 10)); - break; - case 'd': // number in decimal - result += parseInt(nextArg(), 10); - break; - case 'f': // floating point number - tmp = String(parseFloat(nextArg()).toFixed(precision || 6)); - result += leadingZero ? tmp : tmp.replace(/^0/, ''); - break; - case 'j': // JSON - result += JSON.stringify(nextArg()); - break; - case 'o': // number in octal - result += '0' + parseInt(nextArg(), 10).toString(8); - break; - case 's': // string - result += nextArg(); - break; - case 'x': // lowercase hexadecimal - result += '0x' + parseInt(nextArg(), 10).toString(16); - break; - case 'X': // uppercase hexadecimal - result += '0x' + parseInt(nextArg(), 10).toString(16).toUpperCase(); - break; - default: - result += c; - break; - } - } else if (c === '%') { - escaped = true; - } else { - result += c; - } - } - return result; - } - -}()); -}(format$1)); - -var formatter = format$1.exports; - -// @ts-ignore - -var fault = Object.assign(create$1(Error), { - eval: create$1(EvalError), - range: create$1(RangeError), - reference: create$1(ReferenceError), - syntax: create$1(SyntaxError), - type: create$1(TypeError), - uri: create$1(URIError) -}); - -/** - * Create a new `EConstructor`, with the formatted `format` as a first argument. - * - * @template {Error} Fault - * @template {new (reason: string) => Fault} Class - * @param {Class} Constructor - */ -function create$1(Constructor) { - /** @type {string} */ - // @ts-ignore - FormattedError.displayName = Constructor.displayName || Constructor.name; - - return FormattedError - - /** - * @param {string} [format] - * @param {...unknown} values - * @returns {Fault} - */ - function FormattedError(format, ...values) { - /** @type {string} */ - var reason = format ? formatter(format, ...values) : format; - return new Constructor(reason) - } -} - -const debug$b = createDebug('unified-engine:find-up'); - -/** - * @template Value - */ -class FindUp { - /** - * @callback Create - * @param {Buffer} buf - * @param {string} filePath - * @returns {Promise|Value|undefined} - */ - - /** - * @callback Callback - * @param {Error|null} error - * @param {Value} [result] - * @returns {void} - */ - - /** - * @typedef Options - * @property {string} cwd - * @property {string|undefined} filePath - * @property {boolean|undefined} [detect] - * @property {string[]} names - * @property {Create} create - */ - - /** - * @param {Options} options - */ - constructor(options) { - /** @type {Record} */ - this.cache = {}; - /** @type {string} */ - this.cwd = options.cwd; - /** @type {boolean|undefined} */ - this.detect = options.detect; - /** @type {string[]} */ - this.names = options.names; - /** @type {Create} */ - this.create = options.create; - - /** @type {string|undefined} */ - this.givenFilePath = options.filePath - ? path$c.resolve(options.cwd, options.filePath) - : undefined; - - /* eslint-disable no-unused-expressions */ - /** @type {Error|Value|Callback[]|undefined} */ - this.givenFile; - /* eslint-enable no-unused-expressions */ - } - - /** - * @param {string} filePath - * @param {Callback} callback - */ - load(filePath, callback) { - const self = this; - const givenFile = this.givenFile; - const {givenFilePath} = this; - - if (givenFilePath) { - if (givenFile) { - apply(callback, givenFile); - } else { - const cbs = [callback]; - this.givenFile = cbs; - debug$b('Checking given file `%s`', givenFilePath); - fs$a.readFile(givenFilePath, (error, buf) => { - if (error) { - /** @type {NodeJS.ErrnoException} */ - const result = fault( - 'Cannot read given file `%s`\n%s', - path$c.relative(this.cwd, givenFilePath), - error.stack - ); - result.code = 'ENOENT'; - result.path = error.path; - result.syscall = error.syscall; - loaded(result); - } else { - wrap(this.create, (error, /** @type {Value} */ result) => { - if (error) { - debug$b(error.message); - loaded( - fault( - 'Cannot parse given file `%s`\n%s', - path$c.relative(this.cwd, givenFilePath), - error.stack - ) - ); - } else { - debug$b('Read given file `%s`', givenFilePath); - loaded(result); - } - })(buf, givenFilePath); - } - - /** @param {Error|Value} result */ - function loaded(result) { - self.givenFile = result; - applyAll(cbs, result); - } - }); - } - - return - } - - if (!this.detect) { - return callback(null) - } - - filePath = path$c.resolve(this.cwd, filePath); - const parent = path$c.dirname(filePath); - - if (parent in this.cache) { - apply(callback, this.cache[parent]); - } else { - this.cache[parent] = [callback]; - find(parent); - } - - /** - * @param {string} directory - */ - function find(directory) { - let index = -1; - - next(); - - function next() { - // Try to read the next file. - // We do not use `readdir` because on huge directories, that could be - // *very* slow. - if (++index < self.names.length) { - fs$a.readFile(path$c.join(directory, self.names[index]), done); - } else { - const parent = path$c.dirname(directory); - - if (directory === parent) { - debug$b('No files found for `%s`', filePath); - found(null); - } else if (parent in self.cache) { - apply(found, self.cache[parent]); - } else { - self.cache[parent] = [found]; - find(parent); - } - } - } - - /** - * @param {NodeJS.ErrnoException|null} error - * @param {Buffer} [buf] - * @returns {void} - */ - function done(error, buf) { - const fp = path$c.join(directory, self.names[index]); - - if (error) { - // Hard to test. - /* c8 ignore next 13 */ - if (error.code === 'ENOENT') { - return next() - } - - debug$b(error.message); - return found( - fault( - 'Cannot read file `%s`\n%s', - path$c.relative(self.cwd, fp), - error.message - ) - ) - } - - wrap(self.create, (error, /** @type {Value} */ result) => { - if (error) { - found( - fault( - 'Cannot parse file `%s`\n%s', - path$c.relative(self.cwd, fp), - error.message - ) - ); - } else if (result) { - debug$b('Read file `%s`', fp); - found(null, result); - } else { - next(); - } - })(buf, fp); - } - - /** - * @param {Error|null} error - * @param {Value} [result] - * @returns {void} - */ - function found(error, result) { - /** @type {Callback[]} */ - // @ts-expect-error: always a list if found. - const cbs = self.cache[directory]; - self.cache[directory] = error || result; - applyAll(cbs, error || result); - } - } - - /** - * @param {Callback[]} cbs - * @param {Value|Error|undefined} result - */ - function applyAll(cbs, result) { - let index = cbs.length; - - while (index--) { - apply(cbs[index], result); - } - } - - /** - * @param {Callback} cb - * @param {Value|Error|Callback[]|undefined} result - */ - function apply(cb, result) { - if (Array.isArray(result)) { - result.push(cb); - } else if (result instanceof Error) { - cb(result); - } else { - cb(null, result); - } - } - } -} - -/** - * @typedef {import('unified').Plugin} Plugin - * @typedef {import('unified').PluginTuple} PluginTuple - * @typedef {import('unified').PluggableList} PluggableList - * - * @typedef {Record} Settings - * - * @typedef {Record} PluginIdObject - * @typedef {Array} PluginIdList - * - * @typedef Preset - * @property {Settings} [settings] - * @property {PluggableList|PluginIdObject|PluginIdList|undefined} [plugins] - * - * @typedef Config - * @property {Settings} [settings] - * @property {Array} [plugins] - * - * @callback ConfigTransform - * @param {any} config - * @param {string} filePath - * @returns {Preset} - * - * @callback Loader - * @param {Buffer} buf - * @param {string} filePath - * @returns {Promise} - * - * @callback Callback - * @param {Error|null} error - * @param {Config} [result] - * @returns {void} - */ - -const debug$a = createDebug('unified-engine:configuration'); - -const own$c = {}.hasOwnProperty; - -/** @type {Record} */ -const loaders = { - '.json': loadJson, - '.cjs': loadScriptOrModule, - '.mjs': loadScriptOrModule, - '.js': loadScriptOrModule, - '.yaml': loadYaml, - '.yml': loadYaml -}; - -const defaultLoader = loadJson; - -/** - * @typedef Options - * @property {string} cwd - * @property {string} [packageField] - * @property {string} [pluginPrefix] - * @property {string} [rcName] - * @property {string} [rcPath] - * @property {boolean} [detectConfig] - * @property {ConfigTransform} [configTransform] - * @property {Preset} [defaultConfig] - * @property {Preset['settings']} [settings] - * @property {Preset['plugins']} [plugins] - */ - -class Configuration { - /** - * @param {Options} options - */ - constructor(options) { - /** @type {string[]} */ - const names = []; - - /** @type {string} */ - this.cwd = options.cwd; - /** @type {string|undefined} */ - this.packageField = options.packageField; - /** @type {string|undefined} */ - this.pluginPrefix = options.pluginPrefix; - /** @type {ConfigTransform|undefined} */ - this.configTransform = options.configTransform; - /** @type {Preset|undefined} */ - this.defaultConfig = options.defaultConfig; - - if (options.rcName) { - names.push( - options.rcName, - ...Object.keys(loaders).map((d) => options.rcName + d) - ); - debug$a('Looking for `%s` configuration files', names); - } - - if (options.packageField) { - names.push('package.json'); - debug$a( - 'Looking for `%s` fields in `package.json` files', - options.packageField - ); - } - - /** @type {Preset} */ - this.given = {settings: options.settings, plugins: options.plugins}; - this.create = this.create.bind(this); - - /** @type {FindUp} */ - this.findUp = new FindUp({ - cwd: options.cwd, - filePath: options.rcPath, - detect: options.detectConfig, - names, - create: this.create - }); - } - - /** - * @param {string} filePath - * @param {Callback} callback - * @returns {void} - */ - load(filePath, callback) { - this.findUp.load( - filePath || path$c.resolve(this.cwd, 'stdin.js'), - (error, file) => { - if (error || file) { - return callback(error, file) - } - - this.create(undefined, undefined).then((result) => { - callback(null, result); - }, callback); - } - ); - } - - /** - * @param {Buffer|undefined} buf - * @param {string|undefined} filePath - * @returns {Promise} - */ - async create(buf, filePath) { - const options = {prefix: this.pluginPrefix, cwd: this.cwd}; - const result = {settings: {}, plugins: []}; - const extname = filePath ? path$c.extname(filePath) : undefined; - const loader = - extname && extname in loaders ? loaders[extname] : defaultLoader; - /** @type {Preset|undefined} */ - let value; - - if (filePath && buf) { - value = await loader.call(this, buf, filePath); - - if (this.configTransform && value !== undefined) { - value = this.configTransform(value, filePath); - } - } - - // Exit if we did find a `package.json`, but it does not have configuration. - if ( - filePath && - value === undefined && - path$c.basename(filePath) === 'package.json' - ) { - return - } - - if (value === undefined) { - if (this.defaultConfig) { - await merge( - result, - this.defaultConfig, - Object.assign({}, options, {root: this.cwd}) - ); - } - } else { - await merge( - result, - value, - // @ts-expect-error: `value` can only exist if w/ `filePath`. - Object.assign({}, options, {root: path$c.dirname(filePath)}) - ); - } - - await merge( - result, - this.given, - Object.assign({}, options, {root: this.cwd}) - ); - - // C8 bug on Node@12 - /* c8 ignore next 2 */ - return result - } -} - -/** @type {Loader} */ -async function loadScriptOrModule(_, filePath) { - // C8 bug on Node@12 - /* c8 ignore next 4 */ - // @ts-expect-error: Assume it matches config. - // type-coverage:ignore-next-line - return loadFromAbsolutePath(filePath, this.cwd) -} - -/** @type {Loader} */ -async function loadYaml(buf, filePath) { - // C8 bug on Node@12 - /* c8 ignore next 4 */ - // @ts-expect-error: Assume it matches config. - return jsYaml.load(String(buf), {filename: path$c.basename(filePath)}) -} - -/** @type {Loader} */ -async function loadJson(buf, filePath) { - /** @type {Record} */ - const result = parseJson_1(String(buf), filePath); - - // C8 bug on Node@12 - /* c8 ignore next 8 */ - // @ts-expect-error: Assume it matches config. - return path$c.basename(filePath) === 'package.json' - ? // @ts-expect-error: `this` is the configuration context, TS doesn’t like - // `this` on callbacks. - // type-coverage:ignore-next-line - result[this.packageField] - : result -} - -/** - * @param {Required} target - * @param {Preset} raw - * @param {{root: string, prefix: string|undefined}} options - * @returns {Promise} - */ -async function merge(target, raw, options) { - if (typeof raw === 'object' && raw !== null) { - await addPreset(raw); - } else { - throw new Error('Expected preset, not `' + raw + '`') - } - - // C8 bug on Node@12 - /* c8 ignore next 6 */ - return target - - /** - * @param {Preset} result - */ - async function addPreset(result) { - const plugins = result.plugins; - - if (plugins === null || plugins === undefined) ; else if (typeof plugins === 'object' && plugins !== null) { - await (Array.isArray(plugins) ? addEach(plugins) : addIn(plugins)); - } else { - throw new Error( - 'Expected a list or object of plugins, not `' + plugins + '`' - ) - } - - target.settings = Object.assign({}, target.settings, result.settings); - // C8 bug on Node@12 - /* c8 ignore next 6 */ - } - - /** - * @param {PluginIdList|PluggableList} result - */ - async function addEach(result) { - let index = -1; - - while (++index < result.length) { - const value = result[index]; - - // Keep order sequential instead of parallel. - /* eslint-disable no-await-in-loop */ - // @ts-expect-error: Spreading is fine. - // type-coverage:ignore-next-line - await (Array.isArray(value) ? use(...value) : use(value, undefined)); - /* eslint-enable no-await-in-loop */ - } - // C8 bug on Node@12 - /* c8 ignore next 6 */ - } - - /** - * @param {PluginIdObject} result - */ - async function addIn(result) { - /** @type {string} */ - let key; - - for (key in result) { - if (own$c.call(result, key)) { - // Keep order sequential instead of parallel. - // eslint-disable-next-line no-await-in-loop - await use(key, result[key]); - } - } - // C8 bug on Node@12 - /* c8 ignore next 7 */ - } - - /** - * @param {string|Plugin|Preset} usable - * @param {Settings|null|undefined} value - */ - async function use(usable, value) { - if (typeof usable === 'string') { - await addModule(usable, value); - } else if (typeof usable === 'function') { - addPlugin(usable, value); - } else { - await merge(target, usable, options); - } - // C8 bug on Node@12 - /* c8 ignore next 7 */ - } - - /** - * @param {string} id - * @param {Settings|null|undefined} value - */ - async function addModule(id, value) { - /** @type {string} */ - let fp; - - try { - fp = await resolvePlugin(id, { - cwd: options.root, - prefix: options.prefix - }); - } catch (error) { - addPlugin(() => { - throw fault('Could not find module `%s`\n%s', id, error.stack) - }, value); - return - } - - const result = await loadFromAbsolutePath(fp, options.root); - - try { - if (typeof result === 'function') { - addPlugin(result, value); - } else { - await merge( - target, - result, - Object.assign({}, options, {root: path$c.dirname(fp)}) - ); - } - } catch { - throw fault( - 'Error: Expected preset or plugin, not %s, at `%s`', - result, - path$c.relative(options.root, fp) - ) - } - // C8 bug on Node@12 - /* c8 ignore next 8 */ - } - - /** - * @param {Plugin} plugin - * @param {Settings|null|undefined} value - * @returns {void} - */ - function addPlugin(plugin, value) { - const entry = find(target.plugins, plugin); - - if (value === null) { - value = undefined; - } - - if (entry) { - reconfigure(entry, value); - } else { - target.plugins.push([plugin, value]); - } - } -} - -/** - * @param {PluginTuple} entry - * @param {Settings|undefined} value - * @returns {void} - */ -function reconfigure(entry, value) { - if (isPlainObject$1(entry[1]) && isPlainObject$1(value)) { - value = Object.assign({}, entry[1], value); - } - - entry[1] = value; -} - -/** - * @param {Array} entries - * @param {Plugin} plugin - * @returns {PluginTuple|undefined} - */ -function find(entries, plugin) { - let index = -1; - - while (++index < entries.length) { - const entry = entries[index]; - if (entry[0] === plugin) { - return entry - } - } -} - -/** - * @param {string} fp - * @param {string} base - * @returns {Promise} - */ -async function loadFromAbsolutePath(fp, base) { - try { - /** @type {{default?: unknown}} */ - const result = await import(pathToFileURL$1(fp).href); - - if (!('default' in result)) { - throw new Error( - 'Expected a plugin or preset exported as the default export' - ) - } - - // @ts-expect-error: assume plugin/preset. - return result.default - // C8 bug on Node@12 - /* c8 ignore next 4 */ - } catch (error) { - throw fault('Cannot import `%s`\n%s', path$c.relative(base, fp), error.stack) - } -} - -/** - * @typedef {import('./index.js').Settings} Settings - */ - -/** - * @param {Context} context - * @param {Settings} settings - */ -function configure$3(context, settings) { - context.configuration = new Configuration(settings); -} - -// A simple implementation of make-array -function makeArray (subject) { - return Array.isArray(subject) - ? subject - : [subject] -} - -const EMPTY = ''; -const SPACE = ' '; -const ESCAPE = '\\'; -const REGEX_TEST_BLANK_LINE = /^\s+$/; -const REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/; -const REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/; -const REGEX_SPLITALL_CRLF = /\r?\n/g; -// /foo, -// ./foo, -// ../foo, -// . -// .. -const REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/; - -const SLASH = '/'; -const KEY_IGNORE = typeof Symbol !== 'undefined' - ? Symbol.for('node-ignore') - /* istanbul ignore next */ - : 'node-ignore'; - -const define = (object, key, value) => - Object.defineProperty(object, key, {value}); - -const REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g; - -// Sanitize the range of a regular expression -// The cases are complicated, see test cases for details -const sanitizeRange = range => range.replace( - REGEX_REGEXP_RANGE, - (match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0) - ? match - // Invalid range (out of order) which is ok for gitignore rules but - // fatal for JavaScript regular expression, so eliminate it. - : EMPTY -); - -// See fixtures #59 -const cleanRangeBackSlash = slashes => { - const {length} = slashes; - return slashes.slice(0, length - length % 2) -}; - -// > If the pattern ends with a slash, -// > it is removed for the purpose of the following description, -// > but it would only find a match with a directory. -// > In other words, foo/ will match a directory foo and paths underneath it, -// > but will not match a regular file or a symbolic link foo -// > (this is consistent with the way how pathspec works in general in Git). -// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`' -// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call -// you could use option `mark: true` with `glob` - -// '`foo/`' should not continue with the '`..`' -const REPLACERS = [ - - // > Trailing spaces are ignored unless they are quoted with backslash ("\") - [ - // (a\ ) -> (a ) - // (a ) -> (a) - // (a \ ) -> (a ) - /\\?\s+$/, - match => match.indexOf('\\') === 0 - ? SPACE - : EMPTY - ], - - // replace (\ ) with ' ' - [ - /\\\s/g, - () => SPACE - ], - - // Escape metacharacters - // which is written down by users but means special for regular expressions. - - // > There are 12 characters with special meanings: - // > - the backslash \, - // > - the caret ^, - // > - the dollar sign $, - // > - the period or dot ., - // > - the vertical bar or pipe symbol |, - // > - the question mark ?, - // > - the asterisk or star *, - // > - the plus sign +, - // > - the opening parenthesis (, - // > - the closing parenthesis ), - // > - and the opening square bracket [, - // > - the opening curly brace {, - // > These special characters are often called "metacharacters". - [ - /[\\$.|*+(){^]/g, - match => `\\${match}` - ], - - [ - // > a question mark (?) matches a single character - /(?!\\)\?/g, - () => '[^/]' - ], - - // leading slash - [ - - // > A leading slash matches the beginning of the pathname. - // > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c". - // A leading slash matches the beginning of the pathname - /^\//, - () => '^' - ], - - // replace special metacharacter slash after the leading slash - [ - /\//g, - () => '\\/' - ], - - [ - // > A leading "**" followed by a slash means match in all directories. - // > For example, "**/foo" matches file or directory "foo" anywhere, - // > the same as pattern "foo". - // > "**/foo/bar" matches file or directory "bar" anywhere that is directly - // > under directory "foo". - // Notice that the '*'s have been replaced as '\\*' - /^\^*\\\*\\\*\\\//, - - // '**/foo' <-> 'foo' - () => '^(?:.*\\/)?' - ], - - // starting - [ - // there will be no leading '/' - // (which has been replaced by section "leading slash") - // If starts with '**', adding a '^' to the regular expression also works - /^(?=[^^])/, - function startingReplacer () { - // If has a slash `/` at the beginning or middle - return !/\/(?!$)/.test(this) - // > Prior to 2.22.1 - // > If the pattern does not contain a slash /, - // > Git treats it as a shell glob pattern - // Actually, if there is only a trailing slash, - // git also treats it as a shell glob pattern - - // After 2.22.1 (compatible but clearer) - // > If there is a separator at the beginning or middle (or both) - // > of the pattern, then the pattern is relative to the directory - // > level of the particular .gitignore file itself. - // > Otherwise the pattern may also match at any level below - // > the .gitignore level. - ? '(?:^|\\/)' - - // > Otherwise, Git treats the pattern as a shell glob suitable for - // > consumption by fnmatch(3) - : '^' - } - ], - - // two globstars - [ - // Use lookahead assertions so that we could match more than one `'/**'` - /\\\/\\\*\\\*(?=\\\/|$)/g, - - // Zero, one or several directories - // should not use '*', or it will be replaced by the next replacer - - // Check if it is not the last `'/**'` - (_, index, str) => index + 6 < str.length - - // case: /**/ - // > A slash followed by two consecutive asterisks then a slash matches - // > zero or more directories. - // > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on. - // '/**/' - ? '(?:\\/[^\\/]+)*' - - // case: /** - // > A trailing `"/**"` matches everything inside. - - // #21: everything inside but it should not include the current folder - : '\\/.+' - ], - - // intermediate wildcards - [ - // Never replace escaped '*' - // ignore rule '\*' will match the path '*' - - // 'abc.*/' -> go - // 'abc.*' -> skip this rule - /(^|[^\\]+)\\\*(?=.+)/g, - - // '*.js' matches '.js' - // '*.js' doesn't match 'abc' - (_, p1) => `${p1}[^\\/]*` - ], - - [ - // unescape, revert step 3 except for back slash - // For example, if a user escape a '\\*', - // after step 3, the result will be '\\\\\\*' - /\\\\\\(?=[$.|*+(){^])/g, - () => ESCAPE - ], - - [ - // '\\\\' -> '\\' - /\\\\/g, - () => ESCAPE - ], - - [ - // > The range notation, e.g. [a-zA-Z], - // > can be used to match one of the characters in a range. - - // `\` is escaped by step 3 - /(\\)?\[([^\]/]*?)(\\*)($|\])/g, - (match, leadEscape, range, endEscape, close) => leadEscape === ESCAPE - // '\\[bar]' -> '\\\\[bar\\]' - ? `\\[${range}${cleanRangeBackSlash(endEscape)}${close}` - : close === ']' - ? endEscape.length % 2 === 0 - // A normal case, and it is a range notation - // '[bar]' - // '[bar\\\\]' - ? `[${sanitizeRange(range)}${endEscape}]` - // Invalid range notaton - // '[bar\\]' -> '[bar\\\\]' - : '[]' - : '[]' - ], - - // ending - [ - // 'js' will not match 'js.' - // 'ab' will not match 'abc' - /(?:[^*])$/, - - // WTF! - // https://git-scm.com/docs/gitignore - // changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1) - // which re-fixes #24, #38 - - // > If there is a separator at the end of the pattern then the pattern - // > will only match directories, otherwise the pattern can match both - // > files and directories. - - // 'js*' will not match 'a.js' - // 'js/' will not match 'a.js' - // 'js' will match 'a.js' and 'a.js/' - match => /\/$/.test(match) - // foo/ will not match 'foo' - ? `${match}$` - // foo matches 'foo' and 'foo/' - : `${match}(?=$|\\/$)` - ], - - // trailing wildcard - [ - /(\^|\\\/)?\\\*$/, - (_, p1) => { - const prefix = p1 - // '\^': - // '/*' does not match EMPTY - // '/*' does not match everything - - // '\\\/': - // 'abc/*' does not match 'abc/' - ? `${p1}[^/]+` - - // 'a*' matches 'a' - // 'a*' matches 'aa' - : '[^/]*'; - - return `${prefix}(?=$|\\/$)` - } - ], -]; - -// A simple cache, because an ignore rule only has only one certain meaning -const regexCache = Object.create(null); - -// @param {pattern} -const makeRegex = (pattern, negative, ignorecase) => { - const r = regexCache[pattern]; - if (r) { - return r - } - - // const replacers = negative - // ? NEGATIVE_REPLACERS - // : POSITIVE_REPLACERS - - const source = REPLACERS.reduce( - (prev, current) => prev.replace(current[0], current[1].bind(pattern)), - pattern - ); - - return regexCache[pattern] = ignorecase - ? new RegExp(source, 'i') - : new RegExp(source) -}; - -const isString = subject => typeof subject === 'string'; - -// > A blank line matches no files, so it can serve as a separator for readability. -const checkPattern = pattern => pattern - && isString(pattern) - && !REGEX_TEST_BLANK_LINE.test(pattern) - - // > A line starting with # serves as a comment. - && pattern.indexOf('#') !== 0; - -const splitPattern = pattern => pattern.split(REGEX_SPLITALL_CRLF); - -class IgnoreRule { - constructor ( - origin, - pattern, - negative, - regex - ) { - this.origin = origin; - this.pattern = pattern; - this.negative = negative; - this.regex = regex; - } -} - -const createRule = (pattern, ignorecase) => { - const origin = pattern; - let negative = false; - - // > An optional prefix "!" which negates the pattern; - if (pattern.indexOf('!') === 0) { - negative = true; - pattern = pattern.substr(1); - } - - pattern = pattern - // > Put a backslash ("\") in front of the first "!" for patterns that - // > begin with a literal "!", for example, `"\!important!.txt"`. - .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!') - // > Put a backslash ("\") in front of the first hash for patterns that - // > begin with a hash. - .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#'); - - const regex = makeRegex(pattern, negative, ignorecase); - - return new IgnoreRule( - origin, - pattern, - negative, - regex - ) -}; - -const throwError = (message, Ctor) => { - throw new Ctor(message) -}; - -const checkPath = (path, originalPath, doThrow) => { - if (!isString(path)) { - return doThrow( - `path must be a string, but got \`${originalPath}\``, - TypeError - ) - } - - // We don't know if we should ignore EMPTY, so throw - if (!path) { - return doThrow(`path must not be empty`, TypeError) - } - - // Check if it is a relative path - if (checkPath.isNotRelative(path)) { - const r = '`path.relative()`d'; - return doThrow( - `path should be a ${r} string, but got "${originalPath}"`, - RangeError - ) - } - - return true -}; - -const isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path); - -checkPath.isNotRelative = isNotRelative; -checkPath.convert = p => p; - -class Ignore$1 { - constructor ({ - ignorecase = true - } = {}) { - this._rules = []; - this._ignorecase = ignorecase; - define(this, KEY_IGNORE, true); - this._initCache(); - } - - _initCache () { - this._ignoreCache = Object.create(null); - this._testCache = Object.create(null); - } - - _addPattern (pattern) { - // #32 - if (pattern && pattern[KEY_IGNORE]) { - this._rules = this._rules.concat(pattern._rules); - this._added = true; - return - } - - if (checkPattern(pattern)) { - const rule = createRule(pattern, this._ignorecase); - this._added = true; - this._rules.push(rule); - } - } - - // @param {Array | string | Ignore} pattern - add (pattern) { - this._added = false; - - makeArray( - isString(pattern) - ? splitPattern(pattern) - : pattern - ).forEach(this._addPattern, this); - - // Some rules have just added to the ignore, - // making the behavior changed. - if (this._added) { - this._initCache(); - } - - return this - } - - // legacy - addPattern (pattern) { - return this.add(pattern) - } - - // | ignored : unignored - // negative | 0:0 | 0:1 | 1:0 | 1:1 - // -------- | ------- | ------- | ------- | -------- - // 0 | TEST | TEST | SKIP | X - // 1 | TESTIF | SKIP | TEST | X - - // - SKIP: always skip - // - TEST: always test - // - TESTIF: only test if checkUnignored - // - X: that never happen - - // @param {boolean} whether should check if the path is unignored, - // setting `checkUnignored` to `false` could reduce additional - // path matching. - - // @returns {TestResult} true if a file is ignored - _testOne (path, checkUnignored) { - let ignored = false; - let unignored = false; - - this._rules.forEach(rule => { - const {negative} = rule; - if ( - unignored === negative && ignored !== unignored - || negative && !ignored && !unignored && !checkUnignored - ) { - return - } - - const matched = rule.regex.test(path); - - if (matched) { - ignored = !negative; - unignored = negative; - } - }); - - return { - ignored, - unignored - } - } - - // @returns {TestResult} - _test (originalPath, cache, checkUnignored, slices) { - const path = originalPath - // Supports nullable path - && checkPath.convert(originalPath); - - checkPath(path, originalPath, throwError); - - return this._t(path, cache, checkUnignored, slices) - } - - _t (path, cache, checkUnignored, slices) { - if (path in cache) { - return cache[path] - } - - if (!slices) { - // path/to/a.js - // ['path', 'to', 'a.js'] - slices = path.split(SLASH); - } - - slices.pop(); - - // If the path has no parent directory, just test it - if (!slices.length) { - return cache[path] = this._testOne(path, checkUnignored) - } - - const parent = this._t( - slices.join(SLASH) + SLASH, - cache, - checkUnignored, - slices - ); - - // If the path contains a parent directory, check the parent first - return cache[path] = parent.ignored - // > It is not possible to re-include a file if a parent directory of - // > that file is excluded. - ? parent - : this._testOne(path, checkUnignored) - } - - ignores (path) { - return this._test(path, this._ignoreCache, false).ignored - } - - createFilter () { - return path => !this.ignores(path) - } - - filter (paths) { - return makeArray(paths).filter(this.createFilter()) - } - - // @returns {TestResult} - test (path) { - return this._test(path, this._testCache, true) - } -} - -const factory$1 = options => new Ignore$1(options); - -const returnFalse = () => false; - -const isPathValid = path => - checkPath(path && checkPath.convert(path), path, returnFalse); - -factory$1.isPathValid = isPathValid; - -// Fixes typescript -factory$1.default = factory$1; - -var ignore = factory$1; - -// Windows -// -------------------------------------------------------------- -/* istanbul ignore if */ -if ( - // Detect `process` so that it can run in browsers. - typeof process !== 'undefined' - && ( - process.env && process.env.IGNORE_TEST_WIN32 - || process.platform === 'win32' - ) -) { - /* eslint no-control-regex: "off" */ - const makePosix = str => /^\\\\\?\\/.test(str) - || /["<>|\u0000-\u001F]+/u.test(str) - ? str - : str.replace(/\\/g, '/'); - - checkPath.convert = makePosix; - - // 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/' - // 'd:\\foo' - const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i; - checkPath.isNotRelative = path => - REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path) - || isNotRelative(path); -} - -/** - * @typedef {import('ignore').Ignore & {filePath: string}} IgnoreConfig - * - * @typedef {'cwd'|'dir'} ResolveFrom - * - * @typedef Options - * @property {string} cwd - * @property {boolean|undefined} detectIgnore - * @property {string|undefined} ignoreName - * @property {string|undefined} ignorePath - * @property {ResolveFrom|undefined} ignorePathResolveFrom - * - * @callback Callback - * @param {Error|null} error - * @param {boolean|undefined} [result] - */ - -class Ignore { - /** - * @param {Options} options - */ - constructor(options) { - /** @type {string} */ - this.cwd = options.cwd; - /** @type {ResolveFrom|undefined} */ - this.ignorePathResolveFrom = options.ignorePathResolveFrom; - - /** @type {FindUp} */ - this.findUp = new FindUp({ - cwd: options.cwd, - filePath: options.ignorePath, - detect: options.detectIgnore, - names: options.ignoreName ? [options.ignoreName] : [], - create - }); - } - - /** - * @param {string} filePath - * @param {Callback} callback - */ - check(filePath, callback) { - this.findUp.load(filePath, (error, ignoreSet) => { - if (error) { - callback(error); - } else if (ignoreSet) { - const normal = path$c.relative( - path$c.resolve( - this.cwd, - this.ignorePathResolveFrom === 'cwd' ? '.' : ignoreSet.filePath - ), - path$c.resolve(this.cwd, filePath) - ); - - if ( - normal === '' || - normal === '..' || - normal.charAt(0) === path$c.sep || - normal.slice(0, 3) === '..' + path$c.sep - ) { - callback(null, false); - } else { - callback(null, ignoreSet.ignores(normal)); - } - } else { - callback(null, false); - } - }); - } -} - -/** - * @param {Buffer} buf - * @param {string} filePath - * @returns {IgnoreConfig} - */ -function create(buf, filePath) { - /** @type {IgnoreConfig} */ - return Object.assign(ignore().add(String(buf)), { - filePath: path$c.dirname(filePath) - }) -} - -var old$1 = {}; - -// 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. - -var pathModule = path$b; -var isWindows = process.platform === 'win32'; -var fs$3 = require$$0$3; - -// JavaScript implementation of realpath, ported from node pre-v6 - -var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); - -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - var callback; - if (DEBUG) { - var backtrace = new Error; - callback = debugCallback; - } else - callback = missingCallback; - - return callback; - - function debugCallback(err) { - if (err) { - backtrace.message = err.message; - err = backtrace; - missingCallback(err); - } - } - - function missingCallback(err) { - if (err) { - if (process.throwDeprecation) - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - else if (!process.noDeprecation) { - var msg = 'fs: missing callback ' + (err.stack || err.message); - if (process.traceDeprecation) - console.trace(msg); - else - console.error(msg); - } - } - } -} - -function maybeCallback(cb) { - return typeof cb === 'function' ? cb : rethrow(); -} - -pathModule.normalize; - -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} - -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; -} else { - var splitRootRe = /^[\/]*/; -} - -old$1.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs$3.lstatSync(base); - knownHard[base] = true; - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; - } - - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs$3.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } - - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; - } - } - if (linkTarget === null) { - fs$3.statSync(base); - linkTarget = fs$3.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; - } - - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } - - if (cache) cache[original] = p; - - return p; -}; - - -old$1.realpath = function realpath(p, cache, cb) { - if (typeof cb !== 'function') { - cb = maybeCallback(cache); - cache = null; - } - - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs$3.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); - } - - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); - } - - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); - } - - return fs$3.lstat(base, gotStat); - } - - function gotStat(err, stat) { - if (err) return cb(err); - - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); - } - - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } - } - fs$3.stat(base, function(err) { - if (err) return cb(err); - - fs$3.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); - } - - function gotTarget(err, target, base) { - if (err) return cb(err); - - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); - } - - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } -}; - -var fs_realpath = realpath; -realpath.realpath = realpath; -realpath.sync = realpathSync; -realpath.realpathSync = realpathSync; -realpath.monkeypatch = monkeypatch; -realpath.unmonkeypatch = unmonkeypatch; - -var fs$2 = require$$0$3; -var origRealpath = fs$2.realpath; -var origRealpathSync = fs$2.realpathSync; - -var version$2 = process.version; -var ok$1 = /^v[0-5]\./.test(version$2); -var old = old$1; - -function newError (er) { - return er && er.syscall === 'realpath' && ( - er.code === 'ELOOP' || - er.code === 'ENOMEM' || - er.code === 'ENAMETOOLONG' - ) -} - -function realpath (p, cache, cb) { - if (ok$1) { - return origRealpath(p, cache, cb) - } - - if (typeof cache === 'function') { - cb = cache; - cache = null; - } - origRealpath(p, cache, function (er, result) { - if (newError(er)) { - old.realpath(p, cache, cb); - } else { - cb(er, result); - } - }); -} - -function realpathSync (p, cache) { - if (ok$1) { - return origRealpathSync(p, cache) - } - - try { - return origRealpathSync(p, cache) - } catch (er) { - if (newError(er)) { - return old.realpathSync(p, cache) - } else { - throw er - } - } -} - -function monkeypatch () { - fs$2.realpath = realpath; - fs$2.realpathSync = realpathSync; -} - -function unmonkeypatch () { - fs$2.realpath = origRealpath; - fs$2.realpathSync = origRealpathSync; -} - -var concatMap$1 = function (xs, fn) { - var res = []; - for (var i = 0; i < xs.length; i++) { - var x = fn(xs[i], i); - if (isArray$1(x)) res.push.apply(res, x); - else res.push(x); - } - return res; -}; - -var isArray$1 = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; - -var balancedMatch = balanced$1; -function balanced$1(a, b, str) { - if (a instanceof RegExp) a = maybeMatch(a, str); - if (b instanceof RegExp) b = maybeMatch(b, str); - - var r = range(a, b, str); - - return r && { - start: r[0], - end: r[1], - pre: str.slice(0, r[0]), - body: str.slice(r[0] + a.length, r[1]), - post: str.slice(r[1] + b.length) - }; -} - -function maybeMatch(reg, str) { - var m = str.match(reg); - return m ? m[0] : null; -} - -balanced$1.range = range; -function range(a, b, str) { - var begs, beg, left, right, result; - var ai = str.indexOf(a); - var bi = str.indexOf(b, ai + 1); - var i = ai; - - if (ai >= 0 && bi > 0) { - if(a===b) { - return [ai, bi]; - } - begs = []; - left = str.length; - - while (i >= 0 && !result) { - if (i == ai) { - begs.push(i); - ai = str.indexOf(a, i + 1); - } else if (begs.length == 1) { - result = [ begs.pop(), bi ]; - } else { - beg = begs.pop(); - if (beg < left) { - left = beg; - right = bi; - } - - bi = str.indexOf(b, i + 1); - } - - i = ai < bi && ai >= 0 ? ai : bi; - } - - if (begs.length) { - result = [ left, right ]; - } - } - - return result; -} - -var concatMap = concatMap$1; -var balanced = balancedMatch; - -var braceExpansion = expandTop; - -var escSlash = '\0SLASH'+Math.random()+'\0'; -var escOpen = '\0OPEN'+Math.random()+'\0'; -var escClose = '\0CLOSE'+Math.random()+'\0'; -var escComma = '\0COMMA'+Math.random()+'\0'; -var escPeriod = '\0PERIOD'+Math.random()+'\0'; - -function numeric(str) { - return parseInt(str, 10) == str - ? parseInt(str, 10) - : str.charCodeAt(0); -} - -function escapeBraces(str) { - return str.split('\\\\').join(escSlash) - .split('\\{').join(escOpen) - .split('\\}').join(escClose) - .split('\\,').join(escComma) - .split('\\.').join(escPeriod); -} - -function unescapeBraces(str) { - return str.split(escSlash).join('\\') - .split(escOpen).join('{') - .split(escClose).join('}') - .split(escComma).join(',') - .split(escPeriod).join('.'); -} - - -// Basically just str.split(","), but handling cases -// where we have nested braced sections, which should be -// treated as individual members, like {a,{b,c},d} -function parseCommaParts(str) { - if (!str) - return ['']; - - var parts = []; - var m = balanced('{', '}', str); - - if (!m) - return str.split(','); - - var pre = m.pre; - var body = m.body; - var post = m.post; - var p = pre.split(','); - - p[p.length-1] += '{' + body + '}'; - var postParts = parseCommaParts(post); - if (post.length) { - p[p.length-1] += postParts.shift(); - p.push.apply(p, postParts); - } - - parts.push.apply(parts, p); - - return parts; -} - -function expandTop(str) { - if (!str) - return []; - - // I don't know why Bash 4.3 does this, but it does. - // Anything starting with {} will have the first two bytes preserved - // but *only* at the top level, so {},a}b will not expand to anything, - // but a{},b}c will be expanded to [a}c,abc]. - // One could argue that this is a bug in Bash, but since the goal of - // this module is to match Bash's rules, we escape a leading {} - if (str.substr(0, 2) === '{}') { - str = '\\{\\}' + str.substr(2); - } - - return expand$2(escapeBraces(str), true).map(unescapeBraces); -} - -function embrace(str) { - return '{' + str + '}'; -} -function isPadded(el) { - return /^-?0\d/.test(el); -} - -function lte(i, y) { - return i <= y; -} -function gte(i, y) { - return i >= y; -} - -function expand$2(str, isTop) { - var expansions = []; - - var m = balanced('{', '}', str); - if (!m || /\$$/.test(m.pre)) return [str]; - - var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); - var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); - var isSequence = isNumericSequence || isAlphaSequence; - var isOptions = m.body.indexOf(',') >= 0; - if (!isSequence && !isOptions) { - // {a},b} - if (m.post.match(/,.*\}/)) { - str = m.pre + '{' + m.body + escClose + m.post; - return expand$2(str); - } - return [str]; - } - - var n; - if (isSequence) { - n = m.body.split(/\.\./); - } else { - n = parseCommaParts(m.body); - if (n.length === 1) { - // x{{a,b}}y ==> x{a}y x{b}y - n = expand$2(n[0], false).map(embrace); - if (n.length === 1) { - var post = m.post.length - ? expand$2(m.post, false) - : ['']; - return post.map(function(p) { - return m.pre + n[0] + p; - }); - } - } - } - - // at this point, n is the parts, and we know it's not a comma set - // with a single entry. - - // no need to expand pre, since it is guaranteed to be free of brace-sets - var pre = m.pre; - var post = m.post.length - ? expand$2(m.post, false) - : ['']; - - var N; - - if (isSequence) { - var x = numeric(n[0]); - var y = numeric(n[1]); - var width = Math.max(n[0].length, n[1].length); - var incr = n.length == 3 - ? Math.abs(numeric(n[2])) - : 1; - var test = lte; - var reverse = y < x; - if (reverse) { - incr *= -1; - test = gte; - } - var pad = n.some(isPadded); - - N = []; - - for (var i = x; test(i, y); i += incr) { - var c; - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') - c = ''; - } else { - c = String(i); - if (pad) { - var need = width - c.length; - if (need > 0) { - var z = new Array(need + 1).join('0'); - if (i < 0) - c = '-' + z + c.slice(1); - else - c = z + c; - } - } - } - N.push(c); - } - } else { - N = concatMap(n, function(el) { return expand$2(el, false) }); - } - - for (var j = 0; j < N.length; j++) { - for (var k = 0; k < post.length; k++) { - var expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) - expansions.push(expansion); - } - } - - return expansions; -} - -var minimatch_1 = minimatch$3; -minimatch$3.Minimatch = Minimatch$1; - -var path$4 = { sep: '/' }; -try { - path$4 = path$b; -} catch (er) {} - -var GLOBSTAR = minimatch$3.GLOBSTAR = Minimatch$1.GLOBSTAR = {}; -var expand$1 = braceExpansion; - -var plTypes = { - '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, - '?': { open: '(?:', close: ')?' }, - '+': { open: '(?:', close: ')+' }, - '*': { open: '(?:', close: ')*' }, - '@': { open: '(?:', close: ')' } -}; - -// any single thing other than / -// don't need to escape / when using new RegExp() -var qmark = '[^/]'; - -// * => any number of characters -var star = qmark + '*?'; - -// ** when dots are allowed. Anything goes, except .. and . -// not (^ or / followed by one or two dots followed by $ or /), -// followed by anything, any number of times. -var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'; - -// not a ^ or / followed by a dot, -// followed by anything, any number of times. -var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'; - -// characters that need to be escaped in RegExp. -var reSpecials = charSet('().*{}+?[]^$\\!'); - -// "abc" -> { a:true, b:true, c:true } -function charSet (s) { - return s.split('').reduce(function (set, c) { - set[c] = true; - return set - }, {}) -} - -// normalizes slashes. -var slashSplit = /\/+/; - -minimatch$3.filter = filter; -function filter (pattern, options) { - options = options || {}; - return function (p, i, list) { - return minimatch$3(p, pattern, options) - } -} - -function ext (a, b) { - a = a || {}; - b = b || {}; - var t = {}; - Object.keys(b).forEach(function (k) { - t[k] = b[k]; - }); - Object.keys(a).forEach(function (k) { - t[k] = a[k]; - }); - return t -} - -minimatch$3.defaults = function (def) { - if (!def || !Object.keys(def).length) return minimatch$3 - - var orig = minimatch$3; - - var m = function minimatch (p, pattern, options) { - return orig.minimatch(p, pattern, ext(def, options)) - }; - - m.Minimatch = function Minimatch (pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)) - }; - - return m -}; - -Minimatch$1.defaults = function (def) { - if (!def || !Object.keys(def).length) return Minimatch$1 - return minimatch$3.defaults(def).Minimatch -}; - -function minimatch$3 (p, pattern, options) { - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') - } - - if (!options) options = {}; - - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - return false - } - - // "" only matches "" - if (pattern.trim() === '') return p === '' - - return new Minimatch$1(pattern, options).match(p) -} - -function Minimatch$1 (pattern, options) { - if (!(this instanceof Minimatch$1)) { - return new Minimatch$1(pattern, options) - } - - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') - } - - if (!options) options = {}; - pattern = pattern.trim(); - - // windows support: need to use /, not \ - if (path$4.sep !== '/') { - pattern = pattern.split(path$4.sep).join('/'); - } - - this.options = options; - this.set = []; - this.pattern = pattern; - this.regexp = null; - this.negate = false; - this.comment = false; - this.empty = false; - - // make the set of regexps etc. - this.make(); -} - -Minimatch$1.prototype.debug = function () {}; - -Minimatch$1.prototype.make = make; -function make () { - // don't do it more than once. - if (this._made) return - - var pattern = this.pattern; - var options = this.options; - - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true; - return - } - if (!pattern) { - this.empty = true; - return - } - - // step 1: figure out negation, etc. - this.parseNegate(); - - // step 2: expand braces - var set = this.globSet = this.braceExpand(); - - if (options.debug) this.debug = console.error; - - this.debug(this.pattern, set); - - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - set = this.globParts = set.map(function (s) { - return s.split(slashSplit) - }); - - this.debug(this.pattern, set); - - // glob --> regexps - set = set.map(function (s, si, set) { - return s.map(this.parse, this) - }, this); - - this.debug(this.pattern, set); - - // filter out everything that didn't compile properly. - set = set.filter(function (s) { - return s.indexOf(false) === -1 - }); - - this.debug(this.pattern, set); - - this.set = set; -} - -Minimatch$1.prototype.parseNegate = parseNegate; -function parseNegate () { - var pattern = this.pattern; - var negate = false; - var options = this.options; - var negateOffset = 0; - - if (options.nonegate) return - - for (var i = 0, l = pattern.length - ; i < l && pattern.charAt(i) === '!' - ; i++) { - negate = !negate; - negateOffset++; - } - - if (negateOffset) this.pattern = pattern.substr(negateOffset); - this.negate = negate; -} - -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -minimatch$3.braceExpand = function (pattern, options) { - return braceExpand(pattern, options) -}; - -Minimatch$1.prototype.braceExpand = braceExpand; - -function braceExpand (pattern, options) { - if (!options) { - if (this instanceof Minimatch$1) { - options = this.options; - } else { - options = {}; - } - } - - pattern = typeof pattern === 'undefined' - ? this.pattern : pattern; - - if (typeof pattern === 'undefined') { - throw new TypeError('undefined pattern') - } - - if (options.nobrace || - !pattern.match(/\{.*\}/)) { - // shortcut. no need to expand. - return [pattern] - } - - return expand$1(pattern) -} - -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -Minimatch$1.prototype.parse = parse$3; -var SUBPARSE = {}; -function parse$3 (pattern, isSub) { - if (pattern.length > 1024 * 64) { - throw new TypeError('pattern is too long') - } - - var options = this.options; - - // shortcuts - if (!options.noglobstar && pattern === '**') return GLOBSTAR - if (pattern === '') return '' - - var re = ''; - var hasMagic = !!options.nocase; - var escaping = false; - // ? => one single character - var patternListStack = []; - var negativeLists = []; - var stateChar; - var inClass = false; - var reClassStart = -1; - var classStart = -1; - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. - var patternStart = pattern.charAt(0) === '.' ? '' // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' - : '(?!\\.)'; - var self = this; - - function clearStateChar () { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case '*': - re += star; - hasMagic = true; - break - case '?': - re += qmark; - hasMagic = true; - break - default: - re += '\\' + stateChar; - break - } - self.debug('clearStateChar %j %j', stateChar, re); - stateChar = false; - } - } - - for (var i = 0, len = pattern.length, c - ; (i < len) && (c = pattern.charAt(i)) - ; i++) { - this.debug('%s\t%s %s %j', pattern, i, re, c); - - // skip over any that are escaped. - if (escaping && reSpecials[c]) { - re += '\\' + c; - escaping = false; - continue - } - - switch (c) { - case '/': - // completely not allowed, even escaped. - // Should already be path-split by now. - return false - - case '\\': - clearStateChar(); - escaping = true; - continue - - // the various stateChar values - // for the "extglob" stuff. - case '?': - case '*': - case '+': - case '@': - case '!': - this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c); - - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class'); - if (c === '!' && i === classStart + 1) c = '^'; - re += c; - continue - } - - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - self.debug('call clearStateChar %j', stateChar); - clearStateChar(); - stateChar = c; - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) clearStateChar(); - continue - - case '(': - if (inClass) { - re += '('; - continue - } - - if (!stateChar) { - re += '\\('; - continue - } - - patternListStack.push({ - type: stateChar, - start: i - 1, - reStart: re.length, - open: plTypes[stateChar].open, - close: plTypes[stateChar].close - }); - // negation is (?:(?!js)[^/]*) - re += stateChar === '!' ? '(?:(?!(?:' : '(?:'; - this.debug('plType %j %j', stateChar, re); - stateChar = false; - continue - - case ')': - if (inClass || !patternListStack.length) { - re += '\\)'; - continue - } - - clearStateChar(); - hasMagic = true; - var pl = patternListStack.pop(); - // negation is (?:(?!js)[^/]*) - // The others are (?:) - re += pl.close; - if (pl.type === '!') { - negativeLists.push(pl); - } - pl.reEnd = re.length; - continue - - case '|': - if (inClass || !patternListStack.length || escaping) { - re += '\\|'; - escaping = false; - continue - } - - clearStateChar(); - re += '|'; - continue - - // these are mostly the same in regexp and glob - case '[': - // swallow any state-tracking char before the [ - clearStateChar(); - - if (inClass) { - re += '\\' + c; - continue - } - - inClass = true; - classStart = i; - reClassStart = re.length; - re += c; - continue - - case ']': - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += '\\' + c; - escaping = false; - continue - } - - // handle the case where we left a class open. - // "[z-a]" is valid, equivalent to "\[z-a\]" - if (inClass) { - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - var cs = pattern.substring(classStart + 1, i); - try { - RegExp('[' + cs + ']'); - } catch (er) { - // not a valid class! - var sp = this.parse(cs, SUBPARSE); - re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'; - hasMagic = hasMagic || sp[1]; - inClass = false; - continue - } - } - - // finish up the class. - hasMagic = true; - inClass = false; - re += c; - continue - - default: - // swallow any state char that wasn't consumed - clearStateChar(); - - if (escaping) { - // no need - escaping = false; - } else if (reSpecials[c] - && !(c === '^' && inClass)) { - re += '\\'; - } - - re += c; - - } // switch - } // for - - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - cs = pattern.substr(classStart + 1); - sp = this.parse(cs, SUBPARSE); - re = re.substr(0, reClassStart) + '\\[' + sp[0]; - hasMagic = hasMagic || sp[1]; - } - - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { - var tail = re.slice(pl.reStart + pl.open.length); - this.debug('setting tail', re, pl); - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = '\\'; - } - - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + '|' - }); - - this.debug('tail=%j\n %s', tail, tail, pl, re); - var t = pl.type === '*' ? star - : pl.type === '?' ? qmark - : '\\' + pl.type; - - hasMagic = true; - re = re.slice(0, pl.reStart) + t + '\\(' + tail; - } - - // handle trailing things that only matter at the very end. - clearStateChar(); - if (escaping) { - // trailing \\ - re += '\\\\'; - } - - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - var addPatternStart = false; - switch (re.charAt(0)) { - case '.': - case '[': - case '(': addPatternStart = true; - } - - // Hack to work around lack of negative lookbehind in JS - // A pattern like: *.!(x).!(y|z) needs to ensure that a name - // like 'a.xyz.yz' doesn't match. So, the first negative - // lookahead, has to look ALL the way ahead, to the end of - // the pattern. - for (var n = negativeLists.length - 1; n > -1; n--) { - var nl = negativeLists[n]; - - var nlBefore = re.slice(0, nl.reStart); - var nlFirst = re.slice(nl.reStart, nl.reEnd - 8); - var nlLast = re.slice(nl.reEnd - 8, nl.reEnd); - var nlAfter = re.slice(nl.reEnd); - - nlLast += nlAfter; - - // Handle nested stuff like *(*.js|!(*.json)), where open parens - // mean that we should *not* include the ) in the bit that is considered - // "after" the negated section. - var openParensBefore = nlBefore.split('(').length - 1; - var cleanAfter = nlAfter; - for (i = 0; i < openParensBefore; i++) { - cleanAfter = cleanAfter.replace(/\)[+*?]?/, ''); - } - nlAfter = cleanAfter; - - var dollar = ''; - if (nlAfter === '' && isSub !== SUBPARSE) { - dollar = '$'; - } - var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast; - re = newRe; - } - - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== '' && hasMagic) { - re = '(?=.)' + re; - } - - if (addPatternStart) { - re = patternStart + re; - } - - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [re, hasMagic] - } - - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern) - } - - var flags = options.nocase ? 'i' : ''; - try { - var regExp = new RegExp('^' + re + '$', flags); - } catch (er) { - // If it was an invalid regular expression, then it can't match - // anything. This trick looks for a character after the end of - // the string, which is of course impossible, except in multi-line - // mode, but it's not a /m regex. - return new RegExp('$.') - } - - regExp._glob = pattern; - regExp._src = re; - - return regExp -} - -minimatch$3.makeRe = function (pattern, options) { - return new Minimatch$1(pattern, options || {}).makeRe() -}; - -Minimatch$1.prototype.makeRe = makeRe; -function makeRe () { - if (this.regexp || this.regexp === false) return this.regexp - - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - var set = this.set; - - if (!set.length) { - this.regexp = false; - return this.regexp - } - var options = this.options; - - var twoStar = options.noglobstar ? star - : options.dot ? twoStarDot - : twoStarNoDot; - var flags = options.nocase ? 'i' : ''; - - var re = set.map(function (pattern) { - return pattern.map(function (p) { - return (p === GLOBSTAR) ? twoStar - : (typeof p === 'string') ? regExpEscape(p) - : p._src - }).join('\\\/') - }).join('|'); - - // must match entire pattern - // ending in a * or ** will make it less strict. - re = '^(?:' + re + ')$'; - - // can match anything, as long as it's not this. - if (this.negate) re = '^(?!' + re + ').*$'; - - try { - this.regexp = new RegExp(re, flags); - } catch (ex) { - this.regexp = false; - } - return this.regexp -} - -minimatch$3.match = function (list, pattern, options) { - options = options || {}; - var mm = new Minimatch$1(pattern, options); - list = list.filter(function (f) { - return mm.match(f) - }); - if (mm.options.nonull && !list.length) { - list.push(pattern); - } - return list -}; - -Minimatch$1.prototype.match = match; -function match (f, partial) { - this.debug('match', f, this.pattern); - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) return false - if (this.empty) return f === '' - - if (f === '/' && partial) return true - - var options = this.options; - - // windows: need to use /, not \ - if (path$4.sep !== '/') { - f = f.split(path$4.sep).join('/'); - } - - // treat the test path as a set of pathparts. - f = f.split(slashSplit); - this.debug(this.pattern, 'split', f); - - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. - - var set = this.set; - this.debug(this.pattern, 'set', set); - - // Find the basename of the path by looking for the last non-empty segment - var filename; - var i; - for (i = f.length - 1; i >= 0; i--) { - filename = f[i]; - if (filename) break - } - - for (i = 0; i < set.length; i++) { - var pattern = set[i]; - var file = f; - if (options.matchBase && pattern.length === 1) { - file = [filename]; - } - var hit = this.matchOne(file, pattern, partial); - if (hit) { - if (options.flipNegate) return true - return !this.negate - } - } - - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) return false - return this.negate -} - -// set partial to true to test if, for example, -// "/a/b" matches the start of "/*/b/*/d" -// Partial means, if you run out of file before you run -// out of pattern, then that's fine, as long as all -// the parts match. -Minimatch$1.prototype.matchOne = function (file, pattern, partial) { - var options = this.options; - - this.debug('matchOne', - { 'this': this, file: file, pattern: pattern }); - - this.debug('matchOne', file.length, pattern.length); - - for (var fi = 0, - pi = 0, - fl = file.length, - pl = pattern.length - ; (fi < fl) && (pi < pl) - ; fi++, pi++) { - this.debug('matchOne loop'); - var p = pattern[pi]; - var f = file[fi]; - - this.debug(pattern, p, f); - - // should be impossible. - // some invalid regexp stuff in the set. - if (p === false) return false - - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]); - - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi; - var pr = pi + 1; - if (pr === pl) { - this.debug('** at the end'); - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for (; fi < fl; fi++) { - if (file[fi] === '.' || file[fi] === '..' || - (!options.dot && file[fi].charAt(0) === '.')) return false - } - return true - } - - // ok, let's see if we can swallow whatever we can. - while (fr < fl) { - var swallowee = file[fr]; - - this.debug('\nglobstar while', file, fr, pattern, pr, swallowee); - - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee); - // found a match. - return true - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === '.' || swallowee === '..' || - (!options.dot && swallowee.charAt(0) === '.')) { - this.debug('dot detected!', file, fr, pattern, pr); - break - } - - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue'); - fr++; - } - } - - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - // If there's more *pattern* left, then - if (partial) { - // ran out of file - this.debug('\n>>> no match, partial?', file, fr, pattern, pr); - if (fr === fl) return true - } - return false - } - - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - var hit; - if (typeof p === 'string') { - if (options.nocase) { - hit = f.toLowerCase() === p.toLowerCase(); - } else { - hit = f === p; - } - this.debug('string match', p, f, hit); - } else { - hit = f.match(p); - this.debug('pattern match', p, f, hit); - } - - if (!hit) return false - } - - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true - } else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial - } else if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - var emptyFileEnd = (fi === fl - 1) && (file[fi] === ''); - return emptyFileEnd - } - - // should be unreachable. - throw new Error('wtf?') -}; - -// replace stuff like \* with * -function globUnescape (s) { - return s.replace(/\\(.)/g, '$1') -} - -function regExpEscape (s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') -} - -var inherits$2 = {exports: {}}; - -var inherits_browser = {exports: {}}; - -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - inherits_browser.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor; - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - } - }; -} else { - // old school shim for old browsers - inherits_browser.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor; - var TempCtor = function () {}; - TempCtor.prototype = superCtor.prototype; - ctor.prototype = new TempCtor(); - ctor.prototype.constructor = ctor; - } - }; -} - -try { - var util$1 = require$$0$4; - /* istanbul ignore next */ - if (typeof util$1.inherits !== 'function') throw ''; - inherits$2.exports = util$1.inherits; -} catch (e) { - /* istanbul ignore next */ - inherits$2.exports = inherits_browser.exports; -} - -var pathIsAbsolute = {exports: {}}; - -function posix(path) { - return path.charAt(0) === '/'; -} - -function win32(path) { - // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 - var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; - var result = splitDeviceRe.exec(path); - var device = result[1] || ''; - var isUnc = Boolean(device && device.charAt(1) !== ':'); - - // UNC paths are always absolute - return Boolean(result[2] || isUnc); -} - -pathIsAbsolute.exports = process.platform === 'win32' ? win32 : posix; -pathIsAbsolute.exports.posix = posix; -pathIsAbsolute.exports.win32 = win32; - -var common$2 = {}; - -common$2.setopts = setopts$2; -common$2.ownProp = ownProp$2; -common$2.makeAbs = makeAbs; -common$2.finish = finish; -common$2.mark = mark; -common$2.isIgnored = isIgnored$2; -common$2.childrenIgnored = childrenIgnored$2; - -function ownProp$2 (obj, field) { - return Object.prototype.hasOwnProperty.call(obj, field) -} - -var path$3 = path$b; -var minimatch$2 = minimatch_1; -var isAbsolute$2 = pathIsAbsolute.exports; -var Minimatch = minimatch$2.Minimatch; - -function alphasort (a, b) { - return a.localeCompare(b, 'en') -} - -function setupIgnores (self, options) { - self.ignore = options.ignore || []; - - if (!Array.isArray(self.ignore)) - self.ignore = [self.ignore]; - - if (self.ignore.length) { - self.ignore = self.ignore.map(ignoreMap); - } -} - -// ignore patterns are always in dot:true mode. -function ignoreMap (pattern) { - var gmatcher = null; - if (pattern.slice(-3) === '/**') { - var gpattern = pattern.replace(/(\/\*\*)+$/, ''); - gmatcher = new Minimatch(gpattern, { dot: true }); - } - - return { - matcher: new Minimatch(pattern, { dot: true }), - gmatcher: gmatcher - } -} - -function setopts$2 (self, pattern, options) { - if (!options) - options = {}; - - // base-matching: just use globstar for that. - if (options.matchBase && -1 === pattern.indexOf("/")) { - if (options.noglobstar) { - throw new Error("base matching requires globstar") - } - pattern = "**/" + pattern; - } - - self.silent = !!options.silent; - self.pattern = pattern; - self.strict = options.strict !== false; - self.realpath = !!options.realpath; - self.realpathCache = options.realpathCache || Object.create(null); - self.follow = !!options.follow; - self.dot = !!options.dot; - self.mark = !!options.mark; - self.nodir = !!options.nodir; - if (self.nodir) - self.mark = true; - self.sync = !!options.sync; - self.nounique = !!options.nounique; - self.nonull = !!options.nonull; - self.nosort = !!options.nosort; - self.nocase = !!options.nocase; - self.stat = !!options.stat; - self.noprocess = !!options.noprocess; - self.absolute = !!options.absolute; - - self.maxLength = options.maxLength || Infinity; - self.cache = options.cache || Object.create(null); - self.statCache = options.statCache || Object.create(null); - self.symlinks = options.symlinks || Object.create(null); - - setupIgnores(self, options); - - self.changedCwd = false; - var cwd = process.cwd(); - if (!ownProp$2(options, "cwd")) - self.cwd = cwd; - else { - self.cwd = path$3.resolve(options.cwd); - self.changedCwd = self.cwd !== cwd; - } - - self.root = options.root || path$3.resolve(self.cwd, "/"); - self.root = path$3.resolve(self.root); - if (process.platform === "win32") - self.root = self.root.replace(/\\/g, "/"); - - // TODO: is an absolute `cwd` supposed to be resolved against `root`? - // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') - self.cwdAbs = isAbsolute$2(self.cwd) ? self.cwd : makeAbs(self, self.cwd); - if (process.platform === "win32") - self.cwdAbs = self.cwdAbs.replace(/\\/g, "/"); - self.nomount = !!options.nomount; - - // disable comments and negation in Minimatch. - // Note that they are not supported in Glob itself anyway. - options.nonegate = true; - options.nocomment = true; - - self.minimatch = new Minimatch(pattern, options); - self.options = self.minimatch.options; -} - -function finish (self) { - var nou = self.nounique; - var all = nou ? [] : Object.create(null); - - for (var i = 0, l = self.matches.length; i < l; i ++) { - var matches = self.matches[i]; - if (!matches || Object.keys(matches).length === 0) { - if (self.nonull) { - // do like the shell, and spit out the literal glob - var literal = self.minimatch.globSet[i]; - if (nou) - all.push(literal); - else - all[literal] = true; - } - } else { - // had matches - var m = Object.keys(matches); - if (nou) - all.push.apply(all, m); - else - m.forEach(function (m) { - all[m] = true; - }); - } - } - - if (!nou) - all = Object.keys(all); - - if (!self.nosort) - all = all.sort(alphasort); - - // at *some* point we statted all of these - if (self.mark) { - for (var i = 0; i < all.length; i++) { - all[i] = self._mark(all[i]); - } - if (self.nodir) { - all = all.filter(function (e) { - var notDir = !(/\/$/.test(e)); - var c = self.cache[e] || self.cache[makeAbs(self, e)]; - if (notDir && c) - notDir = c !== 'DIR' && !Array.isArray(c); - return notDir - }); - } - } - - if (self.ignore.length) - all = all.filter(function(m) { - return !isIgnored$2(self, m) - }); - - self.found = all; -} - -function mark (self, p) { - var abs = makeAbs(self, p); - var c = self.cache[abs]; - var m = p; - if (c) { - var isDir = c === 'DIR' || Array.isArray(c); - var slash = p.slice(-1) === '/'; - - if (isDir && !slash) - m += '/'; - else if (!isDir && slash) - m = m.slice(0, -1); - - if (m !== p) { - var mabs = makeAbs(self, m); - self.statCache[mabs] = self.statCache[abs]; - self.cache[mabs] = self.cache[abs]; - } - } - - return m -} - -// lotta situps... -function makeAbs (self, f) { - var abs = f; - if (f.charAt(0) === '/') { - abs = path$3.join(self.root, f); - } else if (isAbsolute$2(f) || f === '') { - abs = f; - } else if (self.changedCwd) { - abs = path$3.resolve(self.cwd, f); - } else { - abs = path$3.resolve(f); - } - - if (process.platform === 'win32') - abs = abs.replace(/\\/g, '/'); - - return abs -} - - -// Return true, if pattern ends with globstar '**', for the accompanying parent directory. -// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents -function isIgnored$2 (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) - }) -} - -function childrenIgnored$2 (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return !!(item.gmatcher && item.gmatcher.match(path)) - }) -} - -var sync$1 = globSync$1; -globSync$1.GlobSync = GlobSync$1; - -var fs$1 = require$$0$3; -var rp$1 = fs_realpath; -var minimatch$1 = minimatch_1; -var path$2 = path$b; -var assert$1 = assert$2; -var isAbsolute$1 = pathIsAbsolute.exports; -var common$1 = common$2; -var setopts$1 = common$1.setopts; -var ownProp$1 = common$1.ownProp; -var childrenIgnored$1 = common$1.childrenIgnored; -var isIgnored$1 = common$1.isIgnored; - -function globSync$1 (pattern, options) { - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - return new GlobSync$1(pattern, options).found -} - -function GlobSync$1 (pattern, options) { - if (!pattern) - throw new Error('must provide pattern') - - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - if (!(this instanceof GlobSync$1)) - return new GlobSync$1(pattern, options) - - setopts$1(this, pattern, options); - - if (this.noprocess) - return this - - var n = this.minimatch.set.length; - this.matches = new Array(n); - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false); - } - this._finish(); -} - -GlobSync$1.prototype._finish = function () { - assert$1(this instanceof GlobSync$1); - if (this.realpath) { - var self = this; - this.matches.forEach(function (matchset, index) { - var set = self.matches[index] = Object.create(null); - for (var p in matchset) { - try { - p = self._makeAbs(p); - var real = rp$1.realpathSync(p, self.realpathCache); - set[real] = true; - } catch (er) { - if (er.syscall === 'stat') - set[self._makeAbs(p)] = true; - else - throw er - } - } - }); - } - common$1.finish(this); -}; - - -GlobSync$1.prototype._process = function (pattern, index, inGlobStar) { - assert$1(this instanceof GlobSync$1); - - // Get the first [n] parts of pattern that are all strings. - var n = 0; - while (typeof pattern[n] === 'string') { - n ++; - } - // now n is the index of the first one that is *not* a string. - - // See if there's anything else - var prefix; - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index); - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null; - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/'); - break - } - - var remain = pattern.slice(n); - - // get the list of entries. - var read; - if (prefix === null) - read = '.'; - else if (isAbsolute$1(prefix) || isAbsolute$1(pattern.join('/'))) { - if (!prefix || !isAbsolute$1(prefix)) - prefix = '/' + prefix; - read = prefix; - } else - read = prefix; - - var abs = this._makeAbs(read); - - //if ignored, skip processing - if (childrenIgnored$1(this, read)) - return - - var isGlobStar = remain[0] === minimatch$1.GLOBSTAR; - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar); - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar); -}; - - -GlobSync$1.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { - var entries = this._readdir(abs, inGlobStar); - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0]; - var negate = !!this.minimatch.negate; - var rawGlob = pn._glob; - var dotOk = this.dot || rawGlob.charAt(0) === '.'; - - var matchedEntries = []; - for (var i = 0; i < entries.length; i++) { - var e = entries[i]; - if (e.charAt(0) !== '.' || dotOk) { - var m; - if (negate && !prefix) { - m = !e.match(pn); - } else { - m = e.match(pn); - } - if (m) - matchedEntries.push(e); - } - } - - var len = matchedEntries.length; - // If there are no matched entries, then nothing matches. - if (len === 0) - return - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null); - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i]; - if (prefix) { - if (prefix.slice(-1) !== '/') - e = prefix + '/' + e; - else - e = prefix + e; - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path$2.join(this.root, e); - } - this._emitMatch(index, e); - } - // This was the last one, and no stats were needed - return - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift(); - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i]; - var newPattern; - if (prefix) - newPattern = [prefix, e]; - else - newPattern = [e]; - this._process(newPattern.concat(remain), index, inGlobStar); - } -}; - - -GlobSync$1.prototype._emitMatch = function (index, e) { - if (isIgnored$1(this, e)) - return - - var abs = this._makeAbs(e); - - if (this.mark) - e = this._mark(e); - - if (this.absolute) { - e = abs; - } - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[abs]; - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true; - - if (this.stat) - this._stat(e); -}; - - -GlobSync$1.prototype._readdirInGlobStar = function (abs) { - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false) - - var entries; - var lstat; - try { - lstat = fs$1.lstatSync(abs); - } catch (er) { - if (er.code === 'ENOENT') { - // lstat failed, doesn't exist - return null - } - } - - var isSym = lstat && lstat.isSymbolicLink(); - this.symlinks[abs] = isSym; - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) - this.cache[abs] = 'FILE'; - else - entries = this._readdir(abs, false); - - return entries -}; - -GlobSync$1.prototype._readdir = function (abs, inGlobStar) { - - if (inGlobStar && !ownProp$1(this.symlinks, abs)) - return this._readdirInGlobStar(abs) - - if (ownProp$1(this.cache, abs)) { - var c = this.cache[abs]; - if (!c || c === 'FILE') - return null - - if (Array.isArray(c)) - return c - } - - try { - return this._readdirEntries(abs, fs$1.readdirSync(abs)) - } catch (er) { - this._readdirError(abs, er); - return null - } -}; - -GlobSync$1.prototype._readdirEntries = function (abs, entries) { - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i]; - if (abs === '/') - e = abs + e; - else - e = abs + '/' + e; - this.cache[e] = true; - } - } - - this.cache[abs] = entries; - - // mark and cache dir-ness - return entries -}; - -GlobSync$1.prototype._readdirError = function (f, er) { - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f); - this.cache[abs] = 'FILE'; - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd); - error.path = this.cwd; - error.code = er.code; - throw error - } - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false; - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false; - if (this.strict) - throw er - if (!this.silent) - console.error('glob error', er); - break - } -}; - -GlobSync$1.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { - - var entries = this._readdir(abs, inGlobStar); - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1); - var gspref = prefix ? [ prefix ] : []; - var noGlobStar = gspref.concat(remainWithoutGlobStar); - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false); - - var len = entries.length; - var isSym = this.symlinks[abs]; - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return - - for (var i = 0; i < len; i++) { - var e = entries[i]; - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar); - this._process(instead, index, true); - - var below = gspref.concat(entries[i], remain); - this._process(below, index, true); - } -}; - -GlobSync$1.prototype._processSimple = function (prefix, index) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var exists = this._stat(prefix); - - if (!this.matches[index]) - this.matches[index] = Object.create(null); - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return - - if (prefix && isAbsolute$1(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix); - if (prefix.charAt(0) === '/') { - prefix = path$2.join(this.root, prefix); - } else { - prefix = path$2.resolve(this.root, prefix); - if (trail) - prefix += '/'; - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/'); - - // Mark this as a match - this._emitMatch(index, prefix); -}; - -// Returns either 'DIR', 'FILE', or false -GlobSync$1.prototype._stat = function (f) { - var abs = this._makeAbs(f); - var needDir = f.slice(-1) === '/'; - - if (f.length > this.maxLength) - return false - - if (!this.stat && ownProp$1(this.cache, abs)) { - var c = this.cache[abs]; - - if (Array.isArray(c)) - c = 'DIR'; - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return c - - if (needDir && c === 'FILE') - return false - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - var stat = this.statCache[abs]; - if (!stat) { - var lstat; - try { - lstat = fs$1.lstatSync(abs); - } catch (er) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false; - return false - } - } - - if (lstat && lstat.isSymbolicLink()) { - try { - stat = fs$1.statSync(abs); - } catch (er) { - stat = lstat; - } - } else { - stat = lstat; - } - } - - this.statCache[abs] = stat; - - var c = true; - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE'; - - this.cache[abs] = this.cache[abs] || c; - - if (needDir && c === 'FILE') - return false - - return c -}; - -GlobSync$1.prototype._mark = function (p) { - return common$1.mark(this, p) -}; - -GlobSync$1.prototype._makeAbs = function (f) { - return common$1.makeAbs(this, f) -}; - -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -var wrappy_1 = wrappy$2; -function wrappy$2 (fn, cb) { - if (fn && cb) return wrappy$2(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k]; - }); - - return wrapper - - function wrapper() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i]; - } - var ret = fn.apply(this, args); - var cb = args[args.length-1]; - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k]; - }); - } - return ret - } -} - -var once$3 = {exports: {}}; - -var wrappy$1 = wrappy_1; -once$3.exports = wrappy$1(once$2); -once$3.exports.strict = wrappy$1(onceStrict); - -once$2.proto = once$2(function () { - Object.defineProperty(Function.prototype, 'once', { - value: function () { - return once$2(this) - }, - configurable: true - }); - - Object.defineProperty(Function.prototype, 'onceStrict', { - value: function () { - return onceStrict(this) - }, - configurable: true - }); -}); - -function once$2 (fn) { - var f = function () { - if (f.called) return f.value - f.called = true; - return f.value = fn.apply(this, arguments) - }; - f.called = false; - return f -} - -function onceStrict (fn) { - var f = function () { - if (f.called) - throw new Error(f.onceError) - f.called = true; - return f.value = fn.apply(this, arguments) - }; - var name = fn.name || 'Function wrapped with `once`'; - f.onceError = name + " shouldn't be called more than once"; - f.called = false; - return f -} - -var wrappy = wrappy_1; -var reqs = Object.create(null); -var once$1 = once$3.exports; - -var inflight_1 = wrappy(inflight$1); - -function inflight$1 (key, cb) { - if (reqs[key]) { - reqs[key].push(cb); - return null - } else { - reqs[key] = [cb]; - return makeres(key) - } -} - -function makeres (key) { - return once$1(function RES () { - var cbs = reqs[key]; - var len = cbs.length; - var args = slice$1(arguments); - - // XXX It's somewhat ambiguous whether a new callback added in this - // pass should be queued for later execution if something in the - // list of callbacks throws, or if it should just be discarded. - // However, it's such an edge case that it hardly matters, and either - // choice is likely as surprising as the other. - // As it happens, we do go ahead and schedule it for later execution. - try { - for (var i = 0; i < len; i++) { - cbs[i].apply(null, args); - } - } finally { - if (cbs.length > len) { - // added more in the interim. - // de-zalgo, just in case, but don't call again. - cbs.splice(0, len); - process.nextTick(function () { - RES.apply(null, args); - }); - } else { - delete reqs[key]; - } - } - }) -} - -function slice$1 (args) { - var length = args.length; - var array = []; - - for (var i = 0; i < length; i++) array[i] = args[i]; - return array -} - -// Approach: -// -// 1. Get the minimatch set -// 2. For each pattern in the set, PROCESS(pattern, false) -// 3. Store matches per-set, then uniq them -// -// PROCESS(pattern, inGlobStar) -// Get the first [n] items from pattern that are all strings -// Join these together. This is PREFIX. -// If there is no more remaining, then stat(PREFIX) and -// add to matches if it succeeds. END. -// -// If inGlobStar and PREFIX is symlink and points to dir -// set ENTRIES = [] -// else readdir(PREFIX) as ENTRIES -// If fail, END -// -// with ENTRIES -// If pattern[n] is GLOBSTAR -// // handle the case where the globstar match is empty -// // by pruning it out, and testing the resulting pattern -// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) -// // handle other cases. -// for ENTRY in ENTRIES (not dotfiles) -// // attach globstar + tail onto the entry -// // Mark that this entry is a globstar match -// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) -// -// else // not globstar -// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) -// Test ENTRY against pattern[n] -// If fails, continue -// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) -// -// Caveat: -// Cache all stats and readdirs results to minimize syscall. Since all -// we ever care about is existence and directory-ness, we can just keep -// `true` for files, and [children,...] for directories, or `false` for -// things that don't exist. - -var glob_1 = glob; - -var fs = require$$0$3; -var rp = fs_realpath; -var minimatch = minimatch_1; -var inherits$1 = inherits$2.exports; -var EE = require$$0$5.EventEmitter; -var path$1 = path$b; -var assert = assert$2; -var isAbsolute = pathIsAbsolute.exports; -var globSync = sync$1; -var common = common$2; -var setopts = common.setopts; -var ownProp = common.ownProp; -var inflight = inflight_1; -var childrenIgnored = common.childrenIgnored; -var isIgnored = common.isIgnored; - -var once = once$3.exports; - -function glob (pattern, options, cb) { - if (typeof options === 'function') cb = options, options = {}; - if (!options) options = {}; - - if (options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return globSync(pattern, options) - } - - return new Glob(pattern, options, cb) -} - -glob.sync = globSync; -var GlobSync = glob.GlobSync = globSync.GlobSync; - -// old api surface -glob.glob = glob; - -function extend$1 (origin, add) { - if (add === null || typeof add !== 'object') { - return origin - } - - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; - } - return origin -} - -glob.hasMagic = function (pattern, options_) { - var options = extend$1({}, options_); - options.noprocess = true; - - var g = new Glob(pattern, options); - var set = g.minimatch.set; - - if (!pattern) - return false - - if (set.length > 1) - return true - - for (var j = 0; j < set[0].length; j++) { - if (typeof set[0][j] !== 'string') - return true - } - - return false -}; - -glob.Glob = Glob; -inherits$1(Glob, EE); -function Glob (pattern, options, cb) { - if (typeof options === 'function') { - cb = options; - options = null; - } - - if (options && options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return new GlobSync(pattern, options) - } - - if (!(this instanceof Glob)) - return new Glob(pattern, options, cb) - - setopts(this, pattern, options); - this._didRealPath = false; - - // process each pattern in the minimatch set - var n = this.minimatch.set.length; - - // The matches are stored as {: true,...} so that - // duplicates are automagically pruned. - // Later, we do an Object.keys() on these. - // Keep them as a list so we can fill in when nonull is set. - this.matches = new Array(n); - - if (typeof cb === 'function') { - cb = once(cb); - this.on('error', cb); - this.on('end', function (matches) { - cb(null, matches); - }); - } - - var self = this; - this._processing = 0; - - this._emitQueue = []; - this._processQueue = []; - this.paused = false; - - if (this.noprocess) - return this - - if (n === 0) - return done() - - var sync = true; - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false, done); - } - sync = false; - - function done () { - --self._processing; - if (self._processing <= 0) { - if (sync) { - process.nextTick(function () { - self._finish(); - }); - } else { - self._finish(); - } - } - } -} - -Glob.prototype._finish = function () { - assert(this instanceof Glob); - if (this.aborted) - return - - if (this.realpath && !this._didRealpath) - return this._realpath() - - common.finish(this); - this.emit('end', this.found); -}; - -Glob.prototype._realpath = function () { - if (this._didRealpath) - return - - this._didRealpath = true; - - var n = this.matches.length; - if (n === 0) - return this._finish() - - var self = this; - for (var i = 0; i < this.matches.length; i++) - this._realpathSet(i, next); - - function next () { - if (--n === 0) - self._finish(); - } -}; - -Glob.prototype._realpathSet = function (index, cb) { - var matchset = this.matches[index]; - if (!matchset) - return cb() - - var found = Object.keys(matchset); - var self = this; - var n = found.length; - - if (n === 0) - return cb() - - var set = this.matches[index] = Object.create(null); - found.forEach(function (p, i) { - // If there's a problem with the stat, then it means that - // one or more of the links in the realpath couldn't be - // resolved. just return the abs value in that case. - p = self._makeAbs(p); - rp.realpath(p, self.realpathCache, function (er, real) { - if (!er) - set[real] = true; - else if (er.syscall === 'stat') - set[p] = true; - else - self.emit('error', er); // srsly wtf right here - - if (--n === 0) { - self.matches[index] = set; - cb(); - } - }); - }); -}; - -Glob.prototype._mark = function (p) { - return common.mark(this, p) -}; - -Glob.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -}; - -Glob.prototype.abort = function () { - this.aborted = true; - this.emit('abort'); -}; - -Glob.prototype.pause = function () { - if (!this.paused) { - this.paused = true; - this.emit('pause'); - } -}; - -Glob.prototype.resume = function () { - if (this.paused) { - this.emit('resume'); - this.paused = false; - if (this._emitQueue.length) { - var eq = this._emitQueue.slice(0); - this._emitQueue.length = 0; - for (var i = 0; i < eq.length; i ++) { - var e = eq[i]; - this._emitMatch(e[0], e[1]); - } - } - if (this._processQueue.length) { - var pq = this._processQueue.slice(0); - this._processQueue.length = 0; - for (var i = 0; i < pq.length; i ++) { - var p = pq[i]; - this._processing--; - this._process(p[0], p[1], p[2], p[3]); - } - } - } -}; - -Glob.prototype._process = function (pattern, index, inGlobStar, cb) { - assert(this instanceof Glob); - assert(typeof cb === 'function'); - - if (this.aborted) - return - - this._processing++; - if (this.paused) { - this._processQueue.push([pattern, index, inGlobStar, cb]); - return - } - - //console.error('PROCESS %d', this._processing, pattern) - - // Get the first [n] parts of pattern that are all strings. - var n = 0; - while (typeof pattern[n] === 'string') { - n ++; - } - // now n is the index of the first one that is *not* a string. - - // see if there's anything else - var prefix; - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index, cb); - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null; - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/'); - break - } - - var remain = pattern.slice(n); - - // get the list of entries. - var read; - if (prefix === null) - read = '.'; - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix; - read = prefix; - } else - read = prefix; - - var abs = this._makeAbs(read); - - //if ignored, skip _processing - if (childrenIgnored(this, read)) - return cb() - - var isGlobStar = remain[0] === minimatch.GLOBSTAR; - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb); - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb); -}; - -Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this; - this._readdir(abs, inGlobStar, function (er, entries) { - return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }); -}; - -Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return cb() - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0]; - var negate = !!this.minimatch.negate; - var rawGlob = pn._glob; - var dotOk = this.dot || rawGlob.charAt(0) === '.'; - - var matchedEntries = []; - for (var i = 0; i < entries.length; i++) { - var e = entries[i]; - if (e.charAt(0) !== '.' || dotOk) { - var m; - if (negate && !prefix) { - m = !e.match(pn); - } else { - m = e.match(pn); - } - if (m) - matchedEntries.push(e); - } - } - - //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) - - var len = matchedEntries.length; - // If there are no matched entries, then nothing matches. - if (len === 0) - return cb() - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null); - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i]; - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e; - else - e = prefix + e; - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path$1.join(this.root, e); - } - this._emitMatch(index, e); - } - // This was the last one, and no stats were needed - return cb() - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift(); - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i]; - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e; - else - e = prefix + e; - } - this._process([e].concat(remain), index, inGlobStar, cb); - } - cb(); -}; - -Glob.prototype._emitMatch = function (index, e) { - if (this.aborted) - return - - if (isIgnored(this, e)) - return - - if (this.paused) { - this._emitQueue.push([index, e]); - return - } - - var abs = isAbsolute(e) ? e : this._makeAbs(e); - - if (this.mark) - e = this._mark(e); - - if (this.absolute) - e = abs; - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[abs]; - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true; - - var st = this.statCache[abs]; - if (st) - this.emit('stat', e, st); - - this.emit('match', e); -}; - -Glob.prototype._readdirInGlobStar = function (abs, cb) { - if (this.aborted) - return - - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false, cb) - - var lstatkey = 'lstat\0' + abs; - var self = this; - var lstatcb = inflight(lstatkey, lstatcb_); - - if (lstatcb) - fs.lstat(abs, lstatcb); - - function lstatcb_ (er, lstat) { - if (er && er.code === 'ENOENT') - return cb() - - var isSym = lstat && lstat.isSymbolicLink(); - self.symlinks[abs] = isSym; - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) { - self.cache[abs] = 'FILE'; - cb(); - } else - self._readdir(abs, false, cb); - } -}; - -Glob.prototype._readdir = function (abs, inGlobStar, cb) { - if (this.aborted) - return - - cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb); - if (!cb) - return - - //console.error('RD %j %j', +inGlobStar, abs) - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs, cb) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs]; - if (!c || c === 'FILE') - return cb() - - if (Array.isArray(c)) - return cb(null, c) - } - fs.readdir(abs, readdirCb(this, abs, cb)); -}; - -function readdirCb (self, abs, cb) { - return function (er, entries) { - if (er) - self._readdirError(abs, er, cb); - else - self._readdirEntries(abs, entries, cb); - } -} - -Glob.prototype._readdirEntries = function (abs, entries, cb) { - if (this.aborted) - return - - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i]; - if (abs === '/') - e = abs + e; - else - e = abs + '/' + e; - this.cache[e] = true; - } - } - - this.cache[abs] = entries; - return cb(null, entries) -}; - -Glob.prototype._readdirError = function (f, er, cb) { - if (this.aborted) - return - - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f); - this.cache[abs] = 'FILE'; - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd); - error.path = this.cwd; - error.code = er.code; - this.emit('error', error); - this.abort(); - } - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false; - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false; - if (this.strict) { - this.emit('error', er); - // If the error is handled, then we abort - // if not, we threw out of here - this.abort(); - } - if (!this.silent) - console.error('glob error', er); - break - } - - return cb() -}; - -Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this; - this._readdir(abs, inGlobStar, function (er, entries) { - self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb); - }); -}; - - -Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - //console.error('pgs2', prefix, remain[0], entries) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return cb() - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1); - var gspref = prefix ? [ prefix ] : []; - var noGlobStar = gspref.concat(remainWithoutGlobStar); - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false, cb); - - var isSym = this.symlinks[abs]; - var len = entries.length; - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return cb() - - for (var i = 0; i < len; i++) { - var e = entries[i]; - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar); - this._process(instead, index, true, cb); - - var below = gspref.concat(entries[i], remain); - this._process(below, index, true, cb); - } - - cb(); -}; - -Glob.prototype._processSimple = function (prefix, index, cb) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var self = this; - this._stat(prefix, function (er, exists) { - self._processSimple2(prefix, index, er, exists, cb); - }); -}; -Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { - - //console.error('ps2', prefix, exists) - - if (!this.matches[index]) - this.matches[index] = Object.create(null); - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return cb() - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix); - if (prefix.charAt(0) === '/') { - prefix = path$1.join(this.root, prefix); - } else { - prefix = path$1.resolve(this.root, prefix); - if (trail) - prefix += '/'; - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/'); - - // Mark this as a match - this._emitMatch(index, prefix); - cb(); -}; - -// Returns either 'DIR', 'FILE', or false -Glob.prototype._stat = function (f, cb) { - var abs = this._makeAbs(f); - var needDir = f.slice(-1) === '/'; - - if (f.length > this.maxLength) - return cb() - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs]; - - if (Array.isArray(c)) - c = 'DIR'; - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return cb(null, c) - - if (needDir && c === 'FILE') - return cb() - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - var stat = this.statCache[abs]; - if (stat !== undefined) { - if (stat === false) - return cb(null, stat) - else { - var type = stat.isDirectory() ? 'DIR' : 'FILE'; - if (needDir && type === 'FILE') - return cb() - else - return cb(null, type, stat) - } - } - - var self = this; - var statcb = inflight('stat\0' + abs, lstatcb_); - if (statcb) - fs.lstat(abs, statcb); - - function lstatcb_ (er, lstat) { - if (lstat && lstat.isSymbolicLink()) { - // If it's a symlink, then treat it as the target, unless - // the target does not exist, then treat it as a file. - return fs.stat(abs, function (er, stat) { - if (er) - self._stat2(f, abs, null, lstat, cb); - else - self._stat2(f, abs, er, stat, cb); - }) - } else { - self._stat2(f, abs, er, lstat, cb); - } - } -}; - -Glob.prototype._stat2 = function (f, abs, er, stat, cb) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false; - return cb() - } - - var needDir = f.slice(-1) === '/'; - this.statCache[abs] = stat; - - if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) - return cb(null, false, stat) - - var c = true; - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE'; - this.cache[abs] = this.cache[abs] || c; - - if (needDir && c === 'FILE') - return cb() - - return cb(null, c, stat) -}; - -/*! - * Determine if an object is a Buffer - * - * @author Feross Aboukhadijeh - * @license MIT - */ - -var isBuffer = function isBuffer (obj) { - return obj != null && obj.constructor != null && - typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) -}; - -var own$b = {}.hasOwnProperty; - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Position} Position - * @typedef {import('unist').Point} Point - */ - -/** - * Stringify one point, a position (start and end points), or a node’s - * positional information. - * - * @param {Node|Position|Point} [value] - * @returns {string} - */ -function stringifyPosition$1(value) { - // Nothing. - if (!value || typeof value !== 'object') { - return '' - } - - // Node. - if (own$b.call(value, 'position') || own$b.call(value, 'type')) { - // @ts-ignore looks like a node. - return position(value.position) - } - - // Position. - if (own$b.call(value, 'start') || own$b.call(value, 'end')) { - // @ts-ignore looks like a position. - return position(value) - } - - // Point. - if (own$b.call(value, 'line') || own$b.call(value, 'column')) { - // @ts-ignore looks like a point. - return point$1(value) - } - - // ? - return '' -} - -/** - * @param {Point} point - * @returns {string} - */ -function point$1(point) { - return index$1(point && point.line) + ':' + index$1(point && point.column) -} - -/** - * @param {Position} pos - * @returns {string} - */ -function position(pos) { - return point$1(pos && pos.start) + '-' + point$1(pos && pos.end) -} - -/** - * @param {number} value - * @returns {number} - */ -function index$1(value) { - return value && typeof value === 'number' ? value : 1 -} - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Position} Position - * @typedef {import('unist').Point} Point - */ - -class VFileMessage extends Error { - /** - * Constructor of a message for `reason` at `place` from `origin`. - * When an error is passed in as `reason`, copies the `stack`. - * - * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given. - * @param {Node|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional). - * @param {string} [origin] Place in code the message originates from (`string`, optional). - */ - constructor(reason, place, origin) { - /** @type {[string?, string?]} */ - var parts = [null, null]; - /** @type {Position} */ - var position = { - start: {line: null, column: null}, - end: {line: null, column: null} - }; - /** @type {number} */ - var index; - - super(); - - if (typeof place === 'string') { - origin = place; - place = null; - } - - if (typeof origin === 'string') { - index = origin.indexOf(':'); - - if (index === -1) { - parts[1] = origin; - } else { - parts[0] = origin.slice(0, index); - parts[1] = origin.slice(index + 1); - } - } - - if (place) { - // Node. - if ('type' in place || 'position' in place) { - if (place.position) { - position = place.position; - } - } - // Position. - else if ('start' in place || 'end' in place) { - // @ts-ignore Looks like a position. - position = place; - } - // Point. - else if ('line' in place || 'column' in place) { - // @ts-ignore Looks like a point. - position.start = place; - } - } - - // Fields from `Error` - this.name = stringifyPosition$1(place) || '1:1'; - this.message = typeof reason === 'object' ? reason.message : reason; - this.stack = typeof reason === 'object' ? reason.stack : ''; - - /** - * Reason for message. - * @type {string} - */ - this.reason = this.message; - /** - * Starting line of error. - * @type {number?} - */ - this.line = position.start.line; - /** - * Starting column of error. - * @type {number?} - */ - this.column = position.start.column; - /** - * Namespace of warning. - * @type {string?} - */ - this.source = parts[0]; - /** - * Category of message. - * @type {string?} - */ - this.ruleId = parts[1]; - /** - * Full range information, when available. - * Has start and end properties, both set to an object with line and column, set to number?. - * @type {Position?} - */ - this.position = position; - - // The following fields are “well known”. - // Not standard. - // Feel free to add other non-standard fields to your messages. - - /* eslint-disable no-unused-expressions */ - /** - * You may add a file property with a path of a file (used throughout the VFile ecosystem). - * @type {string?} - */ - this.file; - /** - * If true, marks associated file as no longer processable. - * @type {boolean?} - */ - this.fatal; - /** - * You may add a url property with a link to documentation for the message. - * @type {string?} - */ - this.url; - /** - * You may add a note property with a long form description of the message (supported by vfile-reporter). - * @type {string?} - */ - this.note; - /* eslint-enable no-unused-expressions */ - } -} - -VFileMessage.prototype.file = ''; -VFileMessage.prototype.name = ''; -VFileMessage.prototype.reason = ''; -VFileMessage.prototype.message = ''; -VFileMessage.prototype.stack = ''; -VFileMessage.prototype.fatal = null; -VFileMessage.prototype.column = null; -VFileMessage.prototype.line = null; -VFileMessage.prototype.source = null; -VFileMessage.prototype.ruleId = null; -VFileMessage.prototype.position = null; - -const proc$1 = process$1; - -/** - * @typedef URL - * @property {string} hash - * @property {string} host - * @property {string} hostname - * @property {string} href - * @property {string} origin - * @property {string} password - * @property {string} pathname - * @property {string} port - * @property {string} protocol - * @property {string} search - * @property {any} searchParams - * @property {string} username - * @property {() => string} toString - * @property {() => string} toJSON - */ - -/** - * @param {unknown} fileURLOrPath - * @returns {fileURLOrPath is URL} - */ -// From: -function isUrl(fileURLOrPath) { - return ( - fileURLOrPath !== null && - typeof fileURLOrPath === 'object' && - // @ts-expect-error: indexable. - fileURLOrPath.href && - // @ts-expect-error: indexable. - fileURLOrPath.origin - ) -} - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Position} Position - * @typedef {import('unist').Point} Point - * @typedef {import('./minurl.shared.js').URL} URL - * - * @typedef {'ascii'|'utf8'|'utf-8'|'utf16le'|'ucs2'|'ucs-2'|'base64'|'latin1'|'binary'|'hex'} BufferEncoding - * Encodings supported by the buffer class. - * This is a copy of the typing from Node, copied to prevent Node globals from - * being needed. - * Copied from: - * - * @typedef {string|Uint8Array} VFileValue - * Contents of the file. - * Can either be text, or a Buffer like structure. - * This does not directly use type `Buffer`, because it can also be used in a - * browser context. - * Instead this leverages `Uint8Array` which is the base type for `Buffer`, - * and a native JavaScript construct. - * - * @typedef {VFileValue|VFileOptions|VFile|URL} VFileCompatible - * Things that can be passed to the constructor. - * - * @typedef VFileCoreOptions - * @property {VFileValue} [value] - * @property {string} [cwd] - * @property {Array.} [history] - * @property {string|URL} [path] - * @property {string} [basename] - * @property {string} [stem] - * @property {string} [extname] - * @property {string} [dirname] - * @property {Object.} [data] - * - * @typedef {{[key: string]: unknown} & VFileCoreOptions} VFileOptions - * Configuration: a bunch of keys that will be shallow copied over to the new - * file. - * - * @typedef {Object.} VFileReporterSettings - * @typedef {(files: VFile[], options: T) => string} VFileReporter - */ - -// Order of setting (least specific to most), we need this because otherwise -// `{stem: 'a', path: '~/b.js'}` would throw, as a path is needed before a -// stem can be set. -const order = ['history', 'path', 'basename', 'stem', 'extname', 'dirname']; - -class VFile { - /** - * Create a new virtual file. - * - * If `options` is `string` or `Buffer`, treats it as `{value: options}`. - * If `options` is a `VFile`, shallow copies its data over to the new file. - * All other given fields are set on the newly created `VFile`. - * - * Path related properties are set in the following order (least specific to - * most specific): `history`, `path`, `basename`, `stem`, `extname`, - * `dirname`. - * - * It’s not possible to set either `dirname` or `extname` without setting - * either `history`, `path`, `basename`, or `stem` as well. - * - * @param {VFileCompatible} [value] - */ - constructor(value) { - /** @type {VFileOptions} */ - let options; - - if (!value) { - options = {}; - } else if (typeof value === 'string' || isBuffer(value)) { - // @ts-expect-error Looks like a buffer. - options = {value}; - } else if (isUrl(value)) { - options = {path: value}; - } else { - // @ts-expect-error Looks like file or options. - options = value; - } - - /** - * Place to store custom information. - * It’s OK to store custom data directly on the file, moving it to `data` - * gives a little more privacy. - * @type {Object.} - */ - this.data = {}; - - /** - * List of messages associated with the file. - * @type {Array.} - */ - this.messages = []; - - /** - * List of file paths the file moved between. - * @type {Array.} - */ - this.history = []; - - /** - * Base of `path`. - * Defaults to `process.cwd()` (`/` in browsers). - * @type {string} - */ - this.cwd = proc$1.cwd(); - - /* eslint-disable no-unused-expressions */ - /** - * Raw value. - * @type {VFileValue} - */ - this.value; - - // The below are non-standard, they are “well-known”. - // As in, used in several tools. - - /** - * Whether a file was saved to disk. - * This is used by vfile reporters. - * @type {boolean} - */ - this.stored; - - /** - * Sometimes files have a non-string representation. - * This can be stored in the `result` field. - * One example is when turning markdown into React nodes. - * This is used by unified to store non-string results. - * @type {unknown} - */ - this.result; - - /** - * Sometimes files have a source map associated with them. - * This can be stored in the `map` field. - * This should be a `RawSourceMap` type from the `source-map` module. - * @type {unknown} - */ - this.map; - /* eslint-enable no-unused-expressions */ - - // Set path related properties in the correct order. - let index = -1; - - while (++index < order.length) { - const prop = order[index]; - - // Note: we specifically use `in` instead of `hasOwnProperty` to accept - // `vfile`s too. - if (prop in options && options[prop] !== undefined) { - // @ts-expect-error: TS is confused by the different types for `history`. - this[prop] = prop === 'history' ? [...options[prop]] : options[prop]; - } - } - - /** @type {string} */ - let prop; - - // Set non-path related properties. - for (prop in options) { - // @ts-expect-error: fine to set other things. - if (!order.includes(prop)) this[prop] = options[prop]; - } - } - - /** - * Access full path (`~/index.min.js`). - * - * @returns {string} - */ - get path() { - return this.history[this.history.length - 1] - } - - /** - * Set full path (`~/index.min.js`). - * Cannot be nullified. - * - * @param {string|URL} path - */ - set path(path) { - if (isUrl(path)) { - path = fileURLToPath(path); - } - - assertNonEmpty(path, 'path'); - - if (this.path !== path) { - this.history.push(path); - } - } - - /** - * Access parent path (`~`). - */ - get dirname() { - return typeof this.path === 'string' ? path$b.dirname(this.path) : undefined - } - - /** - * Set parent path (`~`). - * Cannot be set if there's no `path` yet. - */ - set dirname(dirname) { - assertPath(this.basename, 'dirname'); - this.path = path$b.join(dirname || '', this.basename); - } - - /** - * Access basename (including extname) (`index.min.js`). - */ - get basename() { - return typeof this.path === 'string' ? path$b.basename(this.path) : undefined - } - - /** - * Set basename (`index.min.js`). - * Cannot contain path separators. - * Cannot be nullified either (use `file.path = file.dirname` instead). - */ - set basename(basename) { - assertNonEmpty(basename, 'basename'); - assertPart(basename, 'basename'); - this.path = path$b.join(this.dirname || '', basename); - } - - /** - * Access extname (including dot) (`.js`). - */ - get extname() { - return typeof this.path === 'string' ? path$b.extname(this.path) : undefined - } - - /** - * Set extname (including dot) (`.js`). - * Cannot be set if there's no `path` yet and cannot contain path separators. - */ - set extname(extname) { - assertPart(extname, 'extname'); - assertPath(this.dirname, 'extname'); - - if (extname) { - if (extname.charCodeAt(0) !== 46 /* `.` */) { - throw new Error('`extname` must start with `.`') - } - - if (extname.includes('.', 1)) { - throw new Error('`extname` cannot contain multiple dots') - } - } - - this.path = path$b.join(this.dirname, this.stem + (extname || '')); - } - - /** - * Access stem (w/o extname) (`index.min`). - */ - get stem() { - return typeof this.path === 'string' - ? path$b.basename(this.path, this.extname) - : undefined - } - - /** - * Set stem (w/o extname) (`index.min`). - * Cannot be nullified, and cannot contain path separators. - */ - set stem(stem) { - assertNonEmpty(stem, 'stem'); - assertPart(stem, 'stem'); - this.path = path$b.join(this.dirname || '', stem + (this.extname || '')); - } - - /** - * Serialize the file. - * - * @param {BufferEncoding} [encoding='utf8'] If `file.value` is a buffer, `encoding` is used to serialize buffers. - * @returns {string} - */ - toString(encoding) { - // @ts-expect-error string’s don’t accept the parameter, but buffers do. - return (this.value || '').toString(encoding) - } - - /** - * Create a message and associates it w/ the file. - * - * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given. - * @param {Node|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional). - * @param {string} [origin] Place in code the message originates from (`string`, optional). - * @returns {VFileMessage} - */ - message(reason, place, origin) { - const message = new VFileMessage(reason, place, origin); - - if (this.path) { - message.name = this.path + ':' + message.name; - message.file = this.path; - } - - message.fatal = false; - - this.messages.push(message); - - return message - } - - /** - * Info: create a message, associate it with the file, and mark the fatality - * as `null`. - * Calls `message()` internally. - * - * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given. - * @param {Node|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional). - * @param {string} [origin] Place in code the message originates from (`string`, optional). - * @returns {VFileMessage} - */ - info(reason, place, origin) { - const message = this.message(reason, place, origin); - - message.fatal = null; - - return message - } - - /** - * Fail: create a message, associate it with the file, mark the fatality as - * `true`. - * Note: fatal errors mean a file is no longer processable. - * Calls `message()` internally. - * - * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given. - * @param {Node|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional). - * @param {string} [origin] Place in code the message originates from (`string`, optional). - * @returns {never} - */ - fail(reason, place, origin) { - const message = this.message(reason, place, origin); - - message.fatal = true; - - throw message - } -} - -/** - * Assert that `part` is not a path (as in, does not contain `path.sep`). - * - * @param {string|undefined} part - * @param {string} name - * @returns {void} - */ -function assertPart(part, name) { - if (part && part.includes(path$b.sep)) { - throw new Error( - '`' + name + '` cannot be a path: did not expect `' + path$b.sep + '`' - ) - } -} - -/** - * Assert that `part` is not empty. - * - * @param {string|undefined} part - * @param {string} name - * @returns {asserts part is string} - */ -function assertNonEmpty(part, name) { - if (!part) { - throw new Error('`' + name + '` cannot be empty') - } -} - -/** - * Assert `path` exists. - * - * @param {string|undefined} path - * @param {string} name - * @returns {asserts path is string} - */ -function assertPath(path, name) { - if (!path) { - throw new Error('Setting `' + name + '` requires `path` to be set too') - } -} - -/** - * @typedef {import('vfile').VFileValue} Value - * @typedef {import('vfile').VFileOptions} Options - * @typedef {import('vfile').BufferEncoding} BufferEncoding - * - * @typedef {number|string} Mode - * @typedef {BufferEncoding|{encoding?: null|BufferEncoding, flag?: string}} ReadOptions - * @typedef {BufferEncoding|{encoding?: null|BufferEncoding, mode: Mode?, flag?: string}} WriteOptions - * - * @typedef {string|Uint8Array} Path Path of the file. - * @typedef {Path|URL|Options|VFile} Compatible Things that can be - * passed to the function. - */ - -/** - * Create a virtual file from a description. - * If `options` is a string or a buffer, it’s used as the path. - * If it’s a VFile itself, it’s returned instead. - * In all other cases, the options are passed through to `vfile()`. - * - * @param {Compatible} [options] - * @returns {VFile} - */ -function toVFile(options) { - if (typeof options === 'string' || options instanceof URL$1) { - options = {path: options}; - } else if (isBuffer(options)) { - options = {path: String(options)}; - } - - return looksLikeAVFile$1(options) ? options : new VFile(options) -} - -/** - * Create a virtual file and read it in, synchronously. - * - * @param {Compatible} description - * @param {ReadOptions} [options] - * @returns {VFile} - */ -function readSync(description, options) { - const file = toVFile(description); - file.value = require$$0$3.readFileSync(path$b.resolve(file.cwd, file.path), options); - return file -} - -/** - * Create a virtual file and write it in, synchronously. - * - * @param {Compatible} description - * @param {WriteOptions} [options] - * @returns {VFile} - */ -function writeSync(description, options) { - const file = toVFile(description); - require$$0$3.writeFileSync(path$b.resolve(file.cwd, file.path), file.value || '', options); - return file -} - -const read$2 = - /** - * @type {{ - * (description: Compatible, options: ReadOptions, callback: Callback): void - * (description: Compatible, callback: Callback): void - * (description: Compatible, options?: ReadOptions): Promise - * }} - */ - ( - /** - * Create a virtual file and read it in, asynchronously. - * - * @param {Compatible} description - * @param {ReadOptions} [options] - * @param {Callback} [callback] - */ - function (description, options, callback) { - const file = toVFile(description); - - if (!callback && typeof options === 'function') { - callback = options; - options = null; - } - - if (!callback) { - return new Promise(executor) - } - - executor(resolve, callback); - - /** - * @param {VFile} result - */ - function resolve(result) { - callback(null, result); - } - - /** - * @param {(x: VFile) => void} resolve - * @param {(x: Error, y?: VFile) => void} reject - */ - function executor(resolve, reject) { - /** @type {string} */ - let fp; - - try { - fp = path$b.resolve(file.cwd, file.path); - } catch (error) { - return reject(error) - } - - require$$0$3.readFile(fp, options, done); - - /** - * @param {Error} error - * @param {Value} result - */ - function done(error, result) { - if (error) { - reject(error); - } else { - file.value = result; - resolve(file); - } - } - } - } - ); - -const write = - /** - * @type {{ - * (description: Compatible, options: WriteOptions, callback: Callback): void - * (description: Compatible, callback: Callback): void - * (description: Compatible, options?: WriteOptions): Promise - * }} - */ - ( - /** - * Create a virtual file and write it in, asynchronously. - * - * @param {Compatible} description - * @param {WriteOptions} [options] - * @param {Callback} [callback] - */ - function (description, options, callback) { - const file = toVFile(description); - - // Weird, right? Otherwise `fs` doesn’t accept it. - if (!callback && typeof options === 'function') { - callback = options; - options = undefined; - } - - if (!callback) { - return new Promise(executor) - } - - executor(resolve, callback); - - /** - * @param {VFile} result - */ - function resolve(result) { - callback(null, result); - } - - /** - * @param {(x: VFile) => void} resolve - * @param {(x: Error, y?: VFile) => void} reject - */ - function executor(resolve, reject) { - /** @type {string} */ - let fp; - - try { - fp = path$b.resolve(file.cwd, file.path); - } catch (error) { - return reject(error) - } - - require$$0$3.writeFile(fp, file.value || '', options, done); - - /** - * @param {Error} error - */ - function done(error) { - if (error) { - reject(error); - } else { - resolve(file); - } - } - } - } - ); - -/** - * @param {Compatible} value - * @returns {value is VFile} - */ -function looksLikeAVFile$1(value) { - return ( - value && - typeof value === 'object' && - 'message' in value && - 'messages' in value - ) -} - -toVFile.readSync = readSync; -toVFile.writeSync = writeSync; -toVFile.read = read$2; -toVFile.write = write; - -/** - * @typedef {import('fs').Stats} Stats - * @typedef {import('vfile').VFile} VFile - * @typedef {import('./ignore.js').Ignore} Ignore - * @typedef {import('ignore').Ignore} GitIgnore - * - * @typedef Options - * @property {string} cwd - * @property {Array.} extensions - * @property {boolean|undefined} silentlyIgnore - * @property {Array.} ignorePatterns - * @property {Ignore} ignore - * - * @typedef SearchResults - * @property {fs.Stats|undefined} stats - * @property {boolean|undefined} ignored - * - * @typedef Result - * @property {Array.} input - * @property {VFile[]} output - * - * @typedef CleanResult - * @property {boolean} oneFileMode - * @property {VFile[]} files - * - * @callback Callback - * @param {Error|null} error - * @param {CleanResult} [result] - */ - -/** - * Search `patterns`, a mix of globs, paths, and files. - * - * @param {Array.} input - * @param {Options} options - * @param {Callback} callback - */ -function finder(input, options, callback) { - expand(input, options, (error, result) => { - // Glob errors are unusual. - // other errors are on the vfile results. - /* c8 ignore next 2 */ - if (error || !result) { - callback(error); - } else { - callback(null, {oneFileMode: oneFileMode(result), files: result.output}); - } - }); -} - -/** - * Expand the given glob patterns, search given and found directories, and map - * to vfiles. - * - * @param {Array.} input - * @param {Options} options - * @param {(error: Error|null, result?: Result) => void} next - */ -function expand(input, options, next) { - /** @type {Array.} */ - let paths = []; - let actual = 0; - let expected = 0; - let index = -1; - /** @type {boolean|undefined} */ - let failed; - - while (++index < input.length) { - let file = input[index]; - if (typeof file === 'string') { - if (glob_1.hasMagic(file)) { - expected++; - glob_1(file, {cwd: options.cwd}, (error, files) => { - // Glob errors are unusual. - /* c8 ignore next 3 */ - if (failed) { - return - } - - // Glob errors are unusual. - /* c8 ignore next 4 */ - if (error) { - failed = true; - done1(error); - } else { - actual++; - paths = paths.concat(files); - - if (actual === expected) { - search$1(paths, options, done1); - } - } - }); - } else { - // `relative` to make the paths canonical. - file = - path$c.relative(options.cwd, path$c.resolve(options.cwd, file)) || '.'; - paths.push(file); - } - } else { - const fp = file.path ? path$c.relative(options.cwd, file.path) : options.cwd; - file.cwd = options.cwd; - file.path = fp; - file.history = [fp]; - paths.push(file); - } - } - - if (!expected) { - search$1(paths, options, done1); - } - - /** - * @param {Error|null} error - * @param {Array} [files] - */ - function done1(error, files) { - // `search` currently does not give errors. - /* c8 ignore next 2 */ - if (error || !files) { - next(error); - } else { - next(null, {input: paths, output: files}); - } - } -} - -/** - * Search `paths`. - * - * @param {Array.} input - * @param {Options & {nested?: boolean}} options - * @param {(error: Error|null, files: Array.) => void} next - */ -function search$1(input, options, next) { - const extraIgnore = ignore().add(options.ignorePatterns); - let expected = 0; - let actual = 0; - let index = -1; - /** @type {Array.} */ - let files = []; - - while (++index < input.length) { - each(input[index]); - } - - if (!expected) { - next(null, files); - } - - /** - * @param {string|VFile} file - */ - function each(file) { - const ext = typeof file === 'string' ? path$c.extname(file) : file.extname; - - // Normalise globs. - if (typeof file === 'string') { - file = file.split('/').join(path$c.sep); - } - - const part = base$1(file); - - if ( - options.nested && - part && - (part.charAt(0) === '.' || part === 'node_modules') - ) { - return - } - - expected++; - - statAndIgnore( - file, - Object.assign({}, options, {extraIgnore}), - (error, result) => { - const ignored = result && result.ignored; - const dir = result && result.stats && result.stats.isDirectory(); - - if (ignored && (options.nested || options.silentlyIgnore)) { - return one(null, []) - } - - if (!ignored && dir) { - return fs$a.readdir( - path$c.resolve(options.cwd, filePath(file)), - (error, basenames) => { - // Should not happen often: the directory is `stat`ed first, which was ok, - // but reading it is not. - /* c8 ignore next 9 */ - if (error) { - const otherFile = toVFile(filePath(file)); - otherFile.cwd = options.cwd; - - try { - otherFile.fail('Cannot read directory'); - } catch {} - - one(null, [otherFile]); - } else { - search$1( - basenames.map((name) => path$c.join(filePath(file), name)), - Object.assign({}, options, {nested: true}), - one - ); - } - } - ) - } - - if ( - !dir && - options.nested && - options.extensions.length > 0 && - (!ext || !options.extensions.includes(ext)) - ) { - return one(null, []) - } - - file = toVFile(file); - file.cwd = options.cwd; - - if (ignored) { - try { - file.fail('Cannot process specified file: it’s ignored'); - // C8 bug on Node@12 - /* c8 ignore next 1 */ - } catch {} - } - - if (error && error.code === 'ENOENT') { - try { - file.fail( - error.syscall === 'stat' ? 'No such file or directory' : error - ); - // C8 bug on Node@12 - /* c8 ignore next 1 */ - } catch {} - } - - one(null, [file]); - } - ); - - /** - * Error is never given. Always given `results`. - * - * @param {Error|null} _ - * @param {Array.} results - */ - function one(_, results) { - /* istanbul ignore else - Always given. */ - if (results) { - files = files.concat(results); - } - - actual++; - - if (actual === expected) { - next(null, files); - } - } - } -} - -/** - * @param {VFile|string} file - * @param {Options & {extraIgnore: GitIgnore}} options - * @param {(error: NodeJS.ErrnoException|null, result?: SearchResults) => void} callback - */ -function statAndIgnore(file, options, callback) { - const fp = path$c.resolve(options.cwd, filePath(file)); - const normal = path$c.relative(options.cwd, fp); - let expected = 1; - let actual = 0; - /** @type {Stats|undefined} */ - let stats; - /** @type {boolean|undefined} */ - let ignored; - - if (typeof file === 'string' || !file.value) { - expected++; - fs$a.stat(fp, (error, value) => { - stats = value; - onStartOrCheck(error); - }); - } - - options.ignore.check(fp, (error, value) => { - ignored = value; - onStartOrCheck(error); - }); - - /** - * @param {Error|null} error - */ - function onStartOrCheck(error) { - actual++; - - if (error) { - callback(error); - actual = -1; - } else if (actual === expected) { - callback(null, { - stats, - ignored: - ignored || - (normal === '' || - normal === '..' || - normal.charAt(0) === path$c.sep || - normal.slice(0, 3) === '..' + path$c.sep - ? false - : options.extraIgnore.ignores(normal)) - }); - } - } -} - -/** - * @param {string|VFile} file - * @returns {string|undefined} - */ -function base$1(file) { - return typeof file === 'string' ? path$c.basename(file) : file.basename -} - -/** - * @param {string|VFile} file - * @returns {string} - */ -function filePath(file) { - return typeof file === 'string' ? file : file.path -} - -/** - * @param {Result} result - * @returns {boolean} - */ -function oneFileMode(result) { - return ( - result.output.length === 1 && - result.input.length === 1 && - result.output[0].path === result.input[0] - ) -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Settings} Settings - * @typedef {import('./index.js').Configuration} Configuration - */ - -/** - * @param {Context} context - * @param {Settings} settings - * @param {Callback} next - */ -function fileSystem$1(context, settings, next) { - if (context.files.length === 0) { - next(); - } else { - finder( - context.files, - { - cwd: settings.cwd, - extensions: settings.extensions, - silentlyIgnore: settings.silentlyIgnore, - ignorePatterns: settings.ignorePatterns, - ignore: new Ignore({ - cwd: settings.cwd, - detectIgnore: settings.detectIgnore, - ignoreName: settings.ignoreName, - ignorePath: settings.ignorePath, - ignorePathResolveFrom: settings.ignorePathResolveFrom - }) - }, - (error, result) => { - // Glob errors typically don’t occur. - /* c8 ignore next 4 */ - if (!result) { - next(error); - return - } - - const output = result.files; - - // Sort alphabetically. - // Everything is unique so we do not care about cases where left and right - // are equal. - output.sort(sortAlphabetically); - - // Mark as given. - // This allows outputting files, which can be pretty dangerous, so it’s - // “hidden”. - let index = -1; - while (++index < output.length) { - output[index].data.unifiedEngineGiven = true; - } - - context.files = output; - - // If `out` was not set, detect it based on whether one file was given. - if (settings.out === null || settings.out === undefined) { - settings.out = result.oneFileMode; - } - - next(error); - } - ); - } - - /** - * @param {VFile} left - * @param {VFile} right - * @returns {number} - */ - function sortAlphabetically(left, right) { - return left.path < right.path ? -1 : 1 - } -} - -/* eslint-disable node/no-deprecated-api */ - -var toString$2 = Object.prototype.toString; - -var isModern = ( - typeof Buffer !== 'undefined' && - typeof Buffer.alloc === 'function' && - typeof Buffer.allocUnsafe === 'function' && - typeof Buffer.from === 'function' -); - -function isArrayBuffer (input) { - return toString$2.call(input).slice(8, -1) === 'ArrayBuffer' -} - -function fromArrayBuffer (obj, byteOffset, length) { - byteOffset >>>= 0; - - var maxLength = obj.byteLength - byteOffset; - - if (maxLength < 0) { - throw new RangeError("'offset' is out of bounds") - } - - if (length === undefined) { - length = maxLength; - } else { - length >>>= 0; - - if (length > maxLength) { - throw new RangeError("'length' is out of bounds") - } - } - - return isModern - ? Buffer.from(obj.slice(byteOffset, byteOffset + length)) - : new Buffer(new Uint8Array(obj.slice(byteOffset, byteOffset + length))) -} - -function fromString (string, encoding) { - if (typeof encoding !== 'string' || encoding === '') { - encoding = 'utf8'; - } - - if (!Buffer.isEncoding(encoding)) { - throw new TypeError('"encoding" must be a valid string encoding') - } - - return isModern - ? Buffer.from(string, encoding) - : new Buffer(string, encoding) -} - -function bufferFrom$1 (value, encodingOrOffset, length) { - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number') - } - - if (isArrayBuffer(value)) { - return fromArrayBuffer(value, encodingOrOffset, length) - } - - if (typeof value === 'string') { - return fromString(value, encodingOrOffset) - } - - return isModern - ? Buffer.from(value) - : new Buffer(value) -} - -var bufferFrom_1 = bufferFrom$1; - -var typedarray = {}; - -(function (exports) { -var undefined$1 = (void 0); // Paranoia - -// Beyond this value, index getters/setters (i.e. array[0], array[1]) are so slow to -// create, and consume so much memory, that the browser appears frozen. -var MAX_ARRAY_LENGTH = 1e5; - -// Approximations of internal ECMAScript conversion functions -var ECMAScript = (function() { - // Stash a copy in case other scripts modify these - var opts = Object.prototype.toString, - ophop = Object.prototype.hasOwnProperty; - - return { - // Class returns internal [[Class]] property, used to avoid cross-frame instanceof issues: - Class: function(v) { return opts.call(v).replace(/^\[object *|\]$/g, ''); }, - HasProperty: function(o, p) { return p in o; }, - HasOwnProperty: function(o, p) { return ophop.call(o, p); }, - IsCallable: function(o) { return typeof o === 'function'; }, - ToInt32: function(v) { return v >> 0; }, - ToUint32: function(v) { return v >>> 0; } - }; -}()); - -// Snapshot intrinsics -var LN2 = Math.LN2, - abs = Math.abs, - floor = Math.floor, - log = Math.log, - min = Math.min, - pow = Math.pow, - round = Math.round; - -// ES5: lock down object properties -function configureProperties(obj) { - if (getOwnPropNames && defineProp) { - var props = getOwnPropNames(obj), i; - for (i = 0; i < props.length; i += 1) { - defineProp(obj, props[i], { - value: obj[props[i]], - writable: false, - enumerable: false, - configurable: false - }); - } - } -} - -// emulate ES5 getter/setter API using legacy APIs -// http://blogs.msdn.com/b/ie/archive/2010/09/07/transitioning-existing-code-to-the-es5-getter-setter-apis.aspx -// (second clause tests for Object.defineProperty() in IE<9 that only supports extending DOM prototypes, but -// note that IE<9 does not support __defineGetter__ or __defineSetter__ so it just renders the method harmless) -var defineProp; -if (Object.defineProperty && (function() { - try { - Object.defineProperty({}, 'x', {}); - return true; - } catch (e) { - return false; - } - })()) { - defineProp = Object.defineProperty; -} else { - defineProp = function(o, p, desc) { - if (!o === Object(o)) throw new TypeError("Object.defineProperty called on non-object"); - if (ECMAScript.HasProperty(desc, 'get') && Object.prototype.__defineGetter__) { Object.prototype.__defineGetter__.call(o, p, desc.get); } - if (ECMAScript.HasProperty(desc, 'set') && Object.prototype.__defineSetter__) { Object.prototype.__defineSetter__.call(o, p, desc.set); } - if (ECMAScript.HasProperty(desc, 'value')) { o[p] = desc.value; } - return o; - }; -} - -var getOwnPropNames = Object.getOwnPropertyNames || function (o) { - if (o !== Object(o)) throw new TypeError("Object.getOwnPropertyNames called on non-object"); - var props = [], p; - for (p in o) { - if (ECMAScript.HasOwnProperty(o, p)) { - props.push(p); - } - } - return props; -}; - -// ES5: Make obj[index] an alias for obj._getter(index)/obj._setter(index, value) -// for index in 0 ... obj.length -function makeArrayAccessors(obj) { - if (!defineProp) { return; } - - if (obj.length > MAX_ARRAY_LENGTH) throw new RangeError("Array too large for polyfill"); - - function makeArrayAccessor(index) { - defineProp(obj, index, { - 'get': function() { return obj._getter(index); }, - 'set': function(v) { obj._setter(index, v); }, - enumerable: true, - configurable: false - }); - } - - var i; - for (i = 0; i < obj.length; i += 1) { - makeArrayAccessor(i); - } -} - -// Internal conversion functions: -// pack() - take a number (interpreted as Type), output a byte array -// unpack() - take a byte array, output a Type-like number - -function as_signed(value, bits) { var s = 32 - bits; return (value << s) >> s; } -function as_unsigned(value, bits) { var s = 32 - bits; return (value << s) >>> s; } - -function packI8(n) { return [n & 0xff]; } -function unpackI8(bytes) { return as_signed(bytes[0], 8); } - -function packU8(n) { return [n & 0xff]; } -function unpackU8(bytes) { return as_unsigned(bytes[0], 8); } - -function packU8Clamped(n) { n = round(Number(n)); return [n < 0 ? 0 : n > 0xff ? 0xff : n & 0xff]; } - -function packI16(n) { return [(n >> 8) & 0xff, n & 0xff]; } -function unpackI16(bytes) { return as_signed(bytes[0] << 8 | bytes[1], 16); } - -function packU16(n) { return [(n >> 8) & 0xff, n & 0xff]; } -function unpackU16(bytes) { return as_unsigned(bytes[0] << 8 | bytes[1], 16); } - -function packI32(n) { return [(n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff]; } -function unpackI32(bytes) { return as_signed(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], 32); } - -function packU32(n) { return [(n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff]; } -function unpackU32(bytes) { return as_unsigned(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], 32); } - -function packIEEE754(v, ebits, fbits) { - - var bias = (1 << (ebits - 1)) - 1, - s, e, f, i, bits, str, bytes; - - function roundToEven(n) { - var w = floor(n), f = n - w; - if (f < 0.5) - return w; - if (f > 0.5) - return w + 1; - return w % 2 ? w + 1 : w; - } - - // Compute sign, exponent, fraction - if (v !== v) { - // NaN - // http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping - e = (1 << ebits) - 1; f = pow(2, fbits - 1); s = 0; - } else if (v === Infinity || v === -Infinity) { - e = (1 << ebits) - 1; f = 0; s = (v < 0) ? 1 : 0; - } else if (v === 0) { - e = 0; f = 0; s = (1 / v === -Infinity) ? 1 : 0; - } else { - s = v < 0; - v = abs(v); - - if (v >= pow(2, 1 - bias)) { - e = min(floor(log(v) / LN2), 1023); - f = roundToEven(v / pow(2, e) * pow(2, fbits)); - if (f / pow(2, fbits) >= 2) { - e = e + 1; - f = 1; - } - if (e > bias) { - // Overflow - e = (1 << ebits) - 1; - f = 0; - } else { - // Normalized - e = e + bias; - f = f - pow(2, fbits); - } - } else { - // Denormalized - e = 0; - f = roundToEven(v / pow(2, 1 - bias - fbits)); - } - } - - // Pack sign, exponent, fraction - bits = []; - for (i = fbits; i; i -= 1) { bits.push(f % 2 ? 1 : 0); f = floor(f / 2); } - for (i = ebits; i; i -= 1) { bits.push(e % 2 ? 1 : 0); e = floor(e / 2); } - bits.push(s ? 1 : 0); - bits.reverse(); - str = bits.join(''); - - // Bits to bytes - bytes = []; - while (str.length) { - bytes.push(parseInt(str.substring(0, 8), 2)); - str = str.substring(8); - } - return bytes; -} - -function unpackIEEE754(bytes, ebits, fbits) { - - // Bytes to bits - var bits = [], i, j, b, str, - bias, s, e, f; - - for (i = bytes.length; i; i -= 1) { - b = bytes[i - 1]; - for (j = 8; j; j -= 1) { - bits.push(b % 2 ? 1 : 0); b = b >> 1; - } - } - bits.reverse(); - str = bits.join(''); - - // Unpack sign, exponent, fraction - bias = (1 << (ebits - 1)) - 1; - s = parseInt(str.substring(0, 1), 2) ? -1 : 1; - e = parseInt(str.substring(1, 1 + ebits), 2); - f = parseInt(str.substring(1 + ebits), 2); - - // Produce number - if (e === (1 << ebits) - 1) { - return f !== 0 ? NaN : s * Infinity; - } else if (e > 0) { - // Normalized - return s * pow(2, e - bias) * (1 + f / pow(2, fbits)); - } else if (f !== 0) { - // Denormalized - return s * pow(2, -(bias - 1)) * (f / pow(2, fbits)); - } else { - return s < 0 ? -0 : 0; - } -} - -function unpackF64(b) { return unpackIEEE754(b, 11, 52); } -function packF64(v) { return packIEEE754(v, 11, 52); } -function unpackF32(b) { return unpackIEEE754(b, 8, 23); } -function packF32(v) { return packIEEE754(v, 8, 23); } - - -// -// 3 The ArrayBuffer Type -// - -(function() { - - /** @constructor */ - var ArrayBuffer = function ArrayBuffer(length) { - length = ECMAScript.ToInt32(length); - if (length < 0) throw new RangeError('ArrayBuffer size is not a small enough positive integer'); - - this.byteLength = length; - this._bytes = []; - this._bytes.length = length; - - var i; - for (i = 0; i < this.byteLength; i += 1) { - this._bytes[i] = 0; - } - - configureProperties(this); - }; - - exports.ArrayBuffer = exports.ArrayBuffer || ArrayBuffer; - - // - // 4 The ArrayBufferView Type - // - - // NOTE: this constructor is not exported - /** @constructor */ - var ArrayBufferView = function ArrayBufferView() { - //this.buffer = null; - //this.byteOffset = 0; - //this.byteLength = 0; - }; - - // - // 5 The Typed Array View Types - // - - function makeConstructor(bytesPerElement, pack, unpack) { - // Each TypedArray type requires a distinct constructor instance with - // identical logic, which this produces. - - var ctor; - ctor = function(buffer, byteOffset, length) { - var array, sequence, i, s; - - if (!arguments.length || typeof arguments[0] === 'number') { - // Constructor(unsigned long length) - this.length = ECMAScript.ToInt32(arguments[0]); - if (length < 0) throw new RangeError('ArrayBufferView size is not a small enough positive integer'); - - this.byteLength = this.length * this.BYTES_PER_ELEMENT; - this.buffer = new ArrayBuffer(this.byteLength); - this.byteOffset = 0; - } else if (typeof arguments[0] === 'object' && arguments[0].constructor === ctor) { - // Constructor(TypedArray array) - array = arguments[0]; - - this.length = array.length; - this.byteLength = this.length * this.BYTES_PER_ELEMENT; - this.buffer = new ArrayBuffer(this.byteLength); - this.byteOffset = 0; - - for (i = 0; i < this.length; i += 1) { - this._setter(i, array._getter(i)); - } - } else if (typeof arguments[0] === 'object' && - !(arguments[0] instanceof ArrayBuffer || ECMAScript.Class(arguments[0]) === 'ArrayBuffer')) { - // Constructor(sequence array) - sequence = arguments[0]; - - this.length = ECMAScript.ToUint32(sequence.length); - this.byteLength = this.length * this.BYTES_PER_ELEMENT; - this.buffer = new ArrayBuffer(this.byteLength); - this.byteOffset = 0; - - for (i = 0; i < this.length; i += 1) { - s = sequence[i]; - this._setter(i, Number(s)); - } - } else if (typeof arguments[0] === 'object' && - (arguments[0] instanceof ArrayBuffer || ECMAScript.Class(arguments[0]) === 'ArrayBuffer')) { - // Constructor(ArrayBuffer buffer, - // optional unsigned long byteOffset, optional unsigned long length) - this.buffer = buffer; - - this.byteOffset = ECMAScript.ToUint32(byteOffset); - if (this.byteOffset > this.buffer.byteLength) { - throw new RangeError("byteOffset out of range"); - } - - if (this.byteOffset % this.BYTES_PER_ELEMENT) { - // The given byteOffset must be a multiple of the element - // size of the specific type, otherwise an exception is raised. - throw new RangeError("ArrayBuffer length minus the byteOffset is not a multiple of the element size."); - } - - if (arguments.length < 3) { - this.byteLength = this.buffer.byteLength - this.byteOffset; - - if (this.byteLength % this.BYTES_PER_ELEMENT) { - throw new RangeError("length of buffer minus byteOffset not a multiple of the element size"); - } - this.length = this.byteLength / this.BYTES_PER_ELEMENT; - } else { - this.length = ECMAScript.ToUint32(length); - this.byteLength = this.length * this.BYTES_PER_ELEMENT; - } - - if ((this.byteOffset + this.byteLength) > this.buffer.byteLength) { - throw new RangeError("byteOffset and length reference an area beyond the end of the buffer"); - } - } else { - throw new TypeError("Unexpected argument type(s)"); - } - - this.constructor = ctor; - - configureProperties(this); - makeArrayAccessors(this); - }; - - ctor.prototype = new ArrayBufferView(); - ctor.prototype.BYTES_PER_ELEMENT = bytesPerElement; - ctor.prototype._pack = pack; - ctor.prototype._unpack = unpack; - ctor.BYTES_PER_ELEMENT = bytesPerElement; - - // getter type (unsigned long index); - ctor.prototype._getter = function(index) { - if (arguments.length < 1) throw new SyntaxError("Not enough arguments"); - - index = ECMAScript.ToUint32(index); - if (index >= this.length) { - return undefined$1; - } - - var bytes = [], i, o; - for (i = 0, o = this.byteOffset + index * this.BYTES_PER_ELEMENT; - i < this.BYTES_PER_ELEMENT; - i += 1, o += 1) { - bytes.push(this.buffer._bytes[o]); - } - return this._unpack(bytes); - }; - - // NONSTANDARD: convenience alias for getter: type get(unsigned long index); - ctor.prototype.get = ctor.prototype._getter; - - // setter void (unsigned long index, type value); - ctor.prototype._setter = function(index, value) { - if (arguments.length < 2) throw new SyntaxError("Not enough arguments"); - - index = ECMAScript.ToUint32(index); - if (index >= this.length) { - return undefined$1; - } - - var bytes = this._pack(value), i, o; - for (i = 0, o = this.byteOffset + index * this.BYTES_PER_ELEMENT; - i < this.BYTES_PER_ELEMENT; - i += 1, o += 1) { - this.buffer._bytes[o] = bytes[i]; - } - }; - - // void set(TypedArray array, optional unsigned long offset); - // void set(sequence array, optional unsigned long offset); - ctor.prototype.set = function(index, value) { - if (arguments.length < 1) throw new SyntaxError("Not enough arguments"); - var array, sequence, offset, len, - i, s, d, - byteOffset, byteLength, tmp; - - if (typeof arguments[0] === 'object' && arguments[0].constructor === this.constructor) { - // void set(TypedArray array, optional unsigned long offset); - array = arguments[0]; - offset = ECMAScript.ToUint32(arguments[1]); - - if (offset + array.length > this.length) { - throw new RangeError("Offset plus length of array is out of range"); - } - - byteOffset = this.byteOffset + offset * this.BYTES_PER_ELEMENT; - byteLength = array.length * this.BYTES_PER_ELEMENT; - - if (array.buffer === this.buffer) { - tmp = []; - for (i = 0, s = array.byteOffset; i < byteLength; i += 1, s += 1) { - tmp[i] = array.buffer._bytes[s]; - } - for (i = 0, d = byteOffset; i < byteLength; i += 1, d += 1) { - this.buffer._bytes[d] = tmp[i]; - } - } else { - for (i = 0, s = array.byteOffset, d = byteOffset; - i < byteLength; i += 1, s += 1, d += 1) { - this.buffer._bytes[d] = array.buffer._bytes[s]; - } - } - } else if (typeof arguments[0] === 'object' && typeof arguments[0].length !== 'undefined') { - // void set(sequence array, optional unsigned long offset); - sequence = arguments[0]; - len = ECMAScript.ToUint32(sequence.length); - offset = ECMAScript.ToUint32(arguments[1]); - - if (offset + len > this.length) { - throw new RangeError("Offset plus length of array is out of range"); - } - - for (i = 0; i < len; i += 1) { - s = sequence[i]; - this._setter(offset + i, Number(s)); - } - } else { - throw new TypeError("Unexpected argument type(s)"); - } - }; - - // TypedArray subarray(long begin, optional long end); - ctor.prototype.subarray = function(start, end) { - function clamp(v, min, max) { return v < min ? min : v > max ? max : v; } - - start = ECMAScript.ToInt32(start); - end = ECMAScript.ToInt32(end); - - if (arguments.length < 1) { start = 0; } - if (arguments.length < 2) { end = this.length; } - - if (start < 0) { start = this.length + start; } - if (end < 0) { end = this.length + end; } - - start = clamp(start, 0, this.length); - end = clamp(end, 0, this.length); - - var len = end - start; - if (len < 0) { - len = 0; - } - - return new this.constructor( - this.buffer, this.byteOffset + start * this.BYTES_PER_ELEMENT, len); - }; - - return ctor; - } - - var Int8Array = makeConstructor(1, packI8, unpackI8); - var Uint8Array = makeConstructor(1, packU8, unpackU8); - var Uint8ClampedArray = makeConstructor(1, packU8Clamped, unpackU8); - var Int16Array = makeConstructor(2, packI16, unpackI16); - var Uint16Array = makeConstructor(2, packU16, unpackU16); - var Int32Array = makeConstructor(4, packI32, unpackI32); - var Uint32Array = makeConstructor(4, packU32, unpackU32); - var Float32Array = makeConstructor(4, packF32, unpackF32); - var Float64Array = makeConstructor(8, packF64, unpackF64); - - exports.Int8Array = exports.Int8Array || Int8Array; - exports.Uint8Array = exports.Uint8Array || Uint8Array; - exports.Uint8ClampedArray = exports.Uint8ClampedArray || Uint8ClampedArray; - exports.Int16Array = exports.Int16Array || Int16Array; - exports.Uint16Array = exports.Uint16Array || Uint16Array; - exports.Int32Array = exports.Int32Array || Int32Array; - exports.Uint32Array = exports.Uint32Array || Uint32Array; - exports.Float32Array = exports.Float32Array || Float32Array; - exports.Float64Array = exports.Float64Array || Float64Array; -}()); - -// -// 6 The DataView View Type -// - -(function() { - function r(array, index) { - return ECMAScript.IsCallable(array.get) ? array.get(index) : array[index]; - } - - var IS_BIG_ENDIAN = (function() { - var u16array = new(exports.Uint16Array)([0x1234]), - u8array = new(exports.Uint8Array)(u16array.buffer); - return r(u8array, 0) === 0x12; - }()); - - // Constructor(ArrayBuffer buffer, - // optional unsigned long byteOffset, - // optional unsigned long byteLength) - /** @constructor */ - var DataView = function DataView(buffer, byteOffset, byteLength) { - if (arguments.length === 0) { - buffer = new exports.ArrayBuffer(0); - } else if (!(buffer instanceof exports.ArrayBuffer || ECMAScript.Class(buffer) === 'ArrayBuffer')) { - throw new TypeError("TypeError"); - } - - this.buffer = buffer || new exports.ArrayBuffer(0); - - this.byteOffset = ECMAScript.ToUint32(byteOffset); - if (this.byteOffset > this.buffer.byteLength) { - throw new RangeError("byteOffset out of range"); - } - - if (arguments.length < 3) { - this.byteLength = this.buffer.byteLength - this.byteOffset; - } else { - this.byteLength = ECMAScript.ToUint32(byteLength); - } - - if ((this.byteOffset + this.byteLength) > this.buffer.byteLength) { - throw new RangeError("byteOffset and length reference an area beyond the end of the buffer"); - } - - configureProperties(this); - }; - - function makeGetter(arrayType) { - return function(byteOffset, littleEndian) { - - byteOffset = ECMAScript.ToUint32(byteOffset); - - if (byteOffset + arrayType.BYTES_PER_ELEMENT > this.byteLength) { - throw new RangeError("Array index out of range"); - } - byteOffset += this.byteOffset; - - var uint8Array = new exports.Uint8Array(this.buffer, byteOffset, arrayType.BYTES_PER_ELEMENT), - bytes = [], i; - for (i = 0; i < arrayType.BYTES_PER_ELEMENT; i += 1) { - bytes.push(r(uint8Array, i)); - } - - if (Boolean(littleEndian) === Boolean(IS_BIG_ENDIAN)) { - bytes.reverse(); - } - - return r(new arrayType(new exports.Uint8Array(bytes).buffer), 0); - }; - } - - DataView.prototype.getUint8 = makeGetter(exports.Uint8Array); - DataView.prototype.getInt8 = makeGetter(exports.Int8Array); - DataView.prototype.getUint16 = makeGetter(exports.Uint16Array); - DataView.prototype.getInt16 = makeGetter(exports.Int16Array); - DataView.prototype.getUint32 = makeGetter(exports.Uint32Array); - DataView.prototype.getInt32 = makeGetter(exports.Int32Array); - DataView.prototype.getFloat32 = makeGetter(exports.Float32Array); - DataView.prototype.getFloat64 = makeGetter(exports.Float64Array); - - function makeSetter(arrayType) { - return function(byteOffset, value, littleEndian) { - - byteOffset = ECMAScript.ToUint32(byteOffset); - if (byteOffset + arrayType.BYTES_PER_ELEMENT > this.byteLength) { - throw new RangeError("Array index out of range"); - } - - // Get bytes - var typeArray = new arrayType([value]), - byteArray = new exports.Uint8Array(typeArray.buffer), - bytes = [], i, byteView; - - for (i = 0; i < arrayType.BYTES_PER_ELEMENT; i += 1) { - bytes.push(r(byteArray, i)); - } - - // Flip if necessary - if (Boolean(littleEndian) === Boolean(IS_BIG_ENDIAN)) { - bytes.reverse(); - } - - // Write them - byteView = new exports.Uint8Array(this.buffer, byteOffset, arrayType.BYTES_PER_ELEMENT); - byteView.set(bytes); - }; - } - - DataView.prototype.setUint8 = makeSetter(exports.Uint8Array); - DataView.prototype.setInt8 = makeSetter(exports.Int8Array); - DataView.prototype.setUint16 = makeSetter(exports.Uint16Array); - DataView.prototype.setInt16 = makeSetter(exports.Int16Array); - DataView.prototype.setUint32 = makeSetter(exports.Uint32Array); - DataView.prototype.setInt32 = makeSetter(exports.Int32Array); - DataView.prototype.setFloat32 = makeSetter(exports.Float32Array); - DataView.prototype.setFloat64 = makeSetter(exports.Float64Array); - - exports.DataView = exports.DataView || DataView; - -}()); -}(typedarray)); - -var Writable = require$$1.Writable; -var inherits = inherits$2.exports; -var bufferFrom = bufferFrom_1; - -if (typeof Uint8Array === 'undefined') { - var U8 = typedarray.Uint8Array; -} else { - var U8 = Uint8Array; -} - -function ConcatStream(opts, cb) { - if (!(this instanceof ConcatStream)) return new ConcatStream(opts, cb) - - if (typeof opts === 'function') { - cb = opts; - opts = {}; - } - if (!opts) opts = {}; - - var encoding = opts.encoding; - var shouldInferEncoding = false; - - if (!encoding) { - shouldInferEncoding = true; - } else { - encoding = String(encoding).toLowerCase(); - if (encoding === 'u8' || encoding === 'uint8') { - encoding = 'uint8array'; - } - } - - Writable.call(this, { objectMode: true }); - - this.encoding = encoding; - this.shouldInferEncoding = shouldInferEncoding; - - if (cb) this.on('finish', function () { cb(this.getBody()); }); - this.body = []; -} - -var concatStream = ConcatStream; -inherits(ConcatStream, Writable); - -ConcatStream.prototype._write = function(chunk, enc, next) { - this.body.push(chunk); - next(); -}; - -ConcatStream.prototype.inferEncoding = function (buff) { - var firstBuffer = buff === undefined ? this.body[0] : buff; - if (Buffer.isBuffer(firstBuffer)) return 'buffer' - if (typeof Uint8Array !== 'undefined' && firstBuffer instanceof Uint8Array) return 'uint8array' - if (Array.isArray(firstBuffer)) return 'array' - if (typeof firstBuffer === 'string') return 'string' - if (Object.prototype.toString.call(firstBuffer) === "[object Object]") return 'object' - return 'buffer' -}; - -ConcatStream.prototype.getBody = function () { - if (!this.encoding && this.body.length === 0) return [] - if (this.shouldInferEncoding) this.encoding = this.inferEncoding(); - if (this.encoding === 'array') return arrayConcat(this.body) - if (this.encoding === 'string') return stringConcat(this.body) - if (this.encoding === 'buffer') return bufferConcat(this.body) - if (this.encoding === 'uint8array') return u8Concat(this.body) - return this.body -}; - -function isArrayish (arr) { - return /Array\]$/.test(Object.prototype.toString.call(arr)) -} - -function isBufferish (p) { - return typeof p === 'string' || isArrayish(p) || (p && typeof p.subarray === 'function') -} - -function stringConcat (parts) { - var strings = []; - for (var i = 0; i < parts.length; i++) { - var p = parts[i]; - if (typeof p === 'string') { - strings.push(p); - } else if (Buffer.isBuffer(p)) { - strings.push(p); - } else if (isBufferish(p)) { - strings.push(bufferFrom(p)); - } else { - strings.push(bufferFrom(String(p))); - } - } - if (Buffer.isBuffer(parts[0])) { - strings = Buffer.concat(strings); - strings = strings.toString('utf8'); - } else { - strings = strings.join(''); - } - return strings -} - -function bufferConcat (parts) { - var bufs = []; - for (var i = 0; i < parts.length; i++) { - var p = parts[i]; - if (Buffer.isBuffer(p)) { - bufs.push(p); - } else if (isBufferish(p)) { - bufs.push(bufferFrom(p)); - } else { - bufs.push(bufferFrom(String(p))); - } - } - return Buffer.concat(bufs) -} - -function arrayConcat (parts) { - var res = []; - for (var i = 0; i < parts.length; i++) { - res.push.apply(res, parts[i]); - } - return res -} - -function u8Concat (parts) { - var len = 0; - for (var i = 0; i < parts.length; i++) { - if (typeof parts[i] === 'string') { - parts[i] = bufferFrom(parts[i]); - } - len += parts[i].length; - } - var u8 = new U8(len); - for (var i = 0, offset = 0; i < parts.length; i++) { - var part = parts[i]; - for (var j = 0; j < part.length; j++) { - u8[offset++] = part[j]; - } - } - return u8 -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Settings} Settings - */ - -const debug$9 = createDebug('unified-engine:file-set-pipeline:stdin'); - -/** - * @param {Context} context - * @param {Settings} settings - * @param {Callback} next - */ -function stdin(context, settings, next) { - if (settings.files && settings.files.length > 0) { - debug$9('Ignoring `streamIn`'); - - /** @type {Error|undefined} */ - let error; - - if (settings.filePath) { - error = new Error( - 'Do not pass both `--file-path` and real files.\nDid you mean to pass stdin instead of files?' - ); - } - - next(error); - - return - } - - // @ts-expect-error: does exist on `stdin`. - if (settings.streamIn.isTTY) { - debug$9('Cannot read from `tty` stream'); - next(new Error('No input')); - - return - } - - debug$9('Reading from `streamIn`'); - - settings.streamIn.pipe( - concatStream({encoding: 'string'}, (value) => { - const file = toVFile(settings.filePath); - - debug$9('Read from `streamIn`'); - - file.cwd = settings.cwd; - file.value = value; - file.data.unifiedEngineGiven = true; - file.data.unifiedEngineStreamIn = true; - - context.files = [file]; - - // If `out` was not set, set `out`. - settings.out = - settings.out === null || settings.out === undefined - ? true - : settings.out; - - next(); - }) - ); -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Pipeline} Pipeline - */ - -class FileSet extends EventEmitter$1 { - /** - * FileSet constructor. - * A FileSet is created to process multiple files through unified processors. - * This set, containing all files, is exposed to plugins as an argument to the - * attacher. - */ - constructor() { - super(); - - /** @type {Array.} */ - this.files = []; - /** @type {string[]} */ - this.origins = []; - /** @type {Completer[]} */ - this.plugins = []; - /** @type {number} */ - this.expected = 0; - /** @type {number} */ - this.actual = 0; - /** @type {Pipeline} */ - this.pipeline = trough(); - - // Called when a single file has completed it’s pipeline, triggering `done` - // when all files are complete. - this.on('one', () => { - this.actual++; - - if (this.actual >= this.expected) { - this.emit('done'); - } - }); - } - - /** - * Access the files in a set. - */ - valueOf() { - return this.files - } - - /** - * Attach middleware to the pipeline on `fileSet`. - * - * @param {Completer} plugin - */ - use(plugin) { - const pipeline = this.pipeline; - let duplicate = false; - - if (plugin && plugin.pluginId) { - duplicate = this.plugins.some((fn) => fn.pluginId === plugin.pluginId); - } - - if (!duplicate && this.plugins.includes(plugin)) { - duplicate = true; - } - - if (!duplicate) { - this.plugins.push(plugin); - pipeline.use(plugin); - } - - return this - } - - /** - * Add a file to be processed. - * The given file is processed like other files with a few differences: - * - * * Ignored when their file path is already added - * * Never written to the file system or streamOut - * * Not reported for - * - * @param {string|VFile} file - */ - add(file) { - if (typeof file === 'string') { - file = toVFile(file); - } - - // Prevent files from being added multiple times. - if (this.origins.includes(file.history[0])) { - return this - } - - this.origins.push(file.history[0]); - - // Add. - this.valueOf().push(file); - this.expected++; - - // Force an asynchronous operation. - // This ensures that files which fall through the file pipeline immediately - // (such as, when already fatally failed) still queue up correctly. - setImmediate(() => { - this.emit('add', file); - }); - - return this - } -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Context} Context - */ - -const debug$8 = createDebug('unified-engine:file-pipeline:read'); - -/** - * Fill a file with its value when not already filled. - * - * @param {Context} context - * @param {VFile} file - * @param {Callback} next - */ -function read$1(context, file, next) { - let filePath = file.path; - - if (file.value || file.data.unifiedEngineStreamIn) { - debug$8('Not reading file `%s` with `value`', filePath); - next(); - } else if (statistics(file).fatal) { - debug$8('Not reading failed file `%s`', filePath); - next(); - } else { - filePath = path$c.resolve(context.settings.cwd, filePath); - - debug$8('Reading `%s` in `%s`', filePath, 'utf8'); - fs$a.readFile(filePath, 'utf8', (error, value) => { - debug$8('Read `%s` (error: %s)', filePath, error); - - file.value = value || ''; - - next(error); - }); - } -} - -/** - * Has own property. - * - * @type {Function} - */ - -var has = Object.prototype.hasOwnProperty; - -/** - * To string. - * - * @type {Function} - */ - -var toString$1 = Object.prototype.toString; - -/** - * Test whether a value is "empty". - * - * @param {Mixed} val - * @return {Boolean} - */ - -function isEmpty(val) { - // Null and Undefined... - if (val == null) return true - - // Booleans... - if ('boolean' == typeof val) return false - - // Numbers... - if ('number' == typeof val) return val === 0 - - // Strings... - if ('string' == typeof val) return val.length === 0 - - // Functions... - if ('function' == typeof val) return val.length === 0 - - // Arrays... - if (Array.isArray(val)) return val.length === 0 - - // Errors... - if (val instanceof Error) return val.message === '' - - // Objects... - if (val.toString == toString$1) { - switch (val.toString()) { - - // Maps, Sets, Files and Errors... - case '[object File]': - case '[object Map]': - case '[object Set]': { - return val.size === 0 - } - - // Plain objects... - case '[object Object]': { - for (var key in val) { - if (has.call(val, key)) return false - } - - return true - } - } - } - - // Anything else... - return false -} - -/** - * Export `isEmpty`. - * - * @type {Function} - */ - -var lib$1 = isEmpty; - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Context} Context - */ - -const debug$7 = createDebug('unified-engine:file-pipeline:configure'); - -/** - * Collect configuration for a file based on the context. - * - * @param {Context} context - * @param {VFile} file - * @param {Callback} next - */ -function configure$2(context, file, next) { - if (statistics(file).fatal) { - return next() - } - - context.configuration.load(file.path, (error, configuration) => { - let index = -1; - - if (!configuration) { - return next(error) - } - - // Could be missing if a `configTransform` returns weird things. - /* c8 ignore next 1 */ - const plugins = configuration.plugins || []; - - // Store configuration on the context object. - debug$7('Using settings `%j`', configuration.settings); - context.processor.data('settings', configuration.settings); - - debug$7('Using `%d` plugins', plugins.length); - - while (++index < plugins.length) { - const plugin = plugins[index][0]; - let options = plugins[index][1]; - - if (options === false) { - continue - } - - // Allow for default arguments in es2020. - /* c8 ignore next 6 */ - if ( - options === null || - (typeof options === 'object' && lib$1(options)) - ) { - options = undefined; - } - - debug$7( - 'Using plugin `%s`, with options `%j`', - // @ts-expect-error: `displayName` sure can exist on functions. - plugin.displayName || plugin.name || 'function', - options - ); - - try { - context.processor.use(plugin, options, context.fileSet); - /* Should not happen anymore! */ - /* c8 ignore next 3 */ - } catch (error_) { - return next(error_) - } - } - - next(); - }); -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('./index.js').Context} Context - */ - -const debug$6 = createDebug('unified-engine:file-pipeline:parse'); - -/** - * Fill a file with a tree. - * - * @param {Context} context - * @param {VFile} file - */ -function parse$2(context, file) { - if (statistics(file).fatal) { - return - } - - if (context.settings.treeIn) { - debug$6('Not parsing already parsed document'); - - try { - context.tree = parseJson_1(file.toString()); - } catch (error) { - const message = file.message( - new Error('Cannot read file as JSON\n' + error.message) - ); - message.fatal = true; - } - - // Add the preferred extension to ensure the file, when serialized, is - // correctly recognised. - // Only add it if there is a path — not if the file is for example stdin. - if (file.path) { - file.extname = context.settings.extensions[0]; - } - - file.value = ''; - - return - } - - debug$6('Parsing `%s`', file.path); - - context.tree = context.processor.parse(file); - - debug$6('Parsed document'); -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Context} Context - */ - -const debug$5 = createDebug('unified-engine:file-pipeline:transform'); - -/** - * Transform the tree associated with a file with configured plugins. - * - * @param {Context} context - * @param {VFile} file - * @param {Callback} next - */ -function transform$2(context, file, next) { - if (statistics(file).fatal) { - next(); - } else { - debug$5('Transforming document `%s`', file.path); - // @ts-expect-error: `tree` is defined at this point. - context.processor.run(context.tree, file, (error, node) => { - debug$5('Transformed document (error: %s)', error); - context.tree = node; - next(error); - }); - } -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Context} Context - */ - -const debug$4 = createDebug('unified-engine:file-pipeline:queue'); - -const own$a = {}.hasOwnProperty; - -/** - * Queue all files which came this far. - * When the last file gets here, run the file-set pipeline and flush the queue. - * - * @param {Context} context - * @param {VFile} file - * @param {Callback} next - */ -function queue(context, file, next) { - let origin = file.history[0]; - // @ts-expect-error: store a completion map on the `fileSet`. - let map = context.fileSet.complete; - let complete = true; - - if (!map) { - map = {}; - // @ts-expect-error: store a completion map on the `fileSet`. - context.fileSet.complete = map; - } - - debug$4('Queueing `%s`', origin); - - map[origin] = next; - - const files = context.fileSet.valueOf(); - let index = -1; - while (++index < files.length) { - each(files[index]); - } - - if (!complete) { - debug$4('Not flushing: some files cannot be flushed'); - return - } - - // @ts-expect-error: Reset map. - context.fileSet.complete = {}; - context.fileSet.pipeline.run(context.fileSet, done); - - /** - * @param {VFile} file - */ - function each(file) { - const key = file.history[0]; - - if (statistics(file).fatal) { - return - } - - if (typeof map[key] === 'function') { - debug$4('`%s` can be flushed', key); - } else { - debug$4('Interupting flush: `%s` is not finished', key); - complete = false; - } - } - - /** - * @param {Error|Null} error - */ - function done(error) { - debug$4('Flushing: all files can be flushed'); - - // Flush. - for (origin in map) { - if (own$a.call(map, origin)) { - map[origin](error); - } - } - } -} - -var own$9 = {}.hasOwnProperty; - -var bold = ansiColor(1, 22); -var dim = ansiColor(2, 22); -var yellow = ansiColor(33, 39); -var green = ansiColor(32, 39); - -// ANSI color regex. -/* eslint-disable-next-line no-control-regex */ -var colorExpression = /(?:(?:\u001B\[)|\u009B)(?:\d{1,3})?(?:(?:;\d{0,3})*)?[A-M|f-m]|\u001B[A-M]/g; - -/** - * Inspects a node, without using color. - * - * @param {unknown} node - * @param {InspectOptions} [options] - * @returns {string} - */ -function inspectNoColor(node, options) { - return inspectColor(node, options).replace(colorExpression, '') -} - -/** - * Inspects a node, using color. - * - * @param {unknown} tree - * @param {InspectOptions} [options] - * @returns {string} - */ -function inspectColor(tree, options) { - var positions = - !options || - options.showPositions === null || - options.showPositions === undefined - ? true - : options.showPositions; - - return inspectValue(tree) - - /** - * @param {unknown} node - * @returns {string} - */ - function inspectValue(node) { - if (node && typeof node === 'object' && 'length' in node) { - // @ts-ignore looks like a list of nodes. - return inspectNodes(node) - } - - // @ts-ignore looks like a single node. - if (node && node.type) { - // @ts-ignore looks like a single node. - return inspectTree(node) - } - - return inspectNonTree(node) - } - - /** - * @param {unknown} value - * @returns {string} - */ - function inspectNonTree(value) { - return JSON.stringify(value) - } - - /** - * @param {Node[]} nodes - * @returns {string} - */ - function inspectNodes(nodes) { - /** @type {Array.} */ - var result = []; - var index = -1; - - while (++index < nodes.length) { - result.push( - dim((index < nodes.length - 1 ? '├' : '└') + '─' + index) + - ' ' + - indent( - inspectValue(nodes[index]), - (index < nodes.length - 1 ? dim('│') : ' ') + ' ', - true - ) - ); - } - - return result.join('\n') - } - - /** - * @param {Object.} object - * @returns {string} - */ - function inspectFields(object) { - /** @type {Array.} */ - var result = []; - /** @type {string} */ - var key; - /** @type {unknown} */ - var value; - /** @type {string} */ - var formatted; - - for (key in object) { - /* c8 ignore next 1 */ - if (!own$9.call(object, key)) continue - - value = object[key]; - - if ( - value === undefined || - // Standard keys defined by unist that we format differently. - // - key === 'type' || - key === 'value' || - key === 'children' || - key === 'position' || - // Ignore `name` (from xast) and `tagName` (from `hast`) when string. - (typeof value === 'string' && (key === 'name' || key === 'tagName')) - ) { - continue - } - - // A single node. - if ( - value && - typeof value === 'object' && - // @ts-ignore looks like a node. - value.type && - key !== 'data' && - key !== 'attributes' && - key !== 'properties' - ) { - // @ts-ignore looks like a node. - formatted = inspectTree(value); - } - // A list of nodes. - else if ( - value && - typeof value === 'object' && - 'length' in value && - value[0] && - value[0].type - ) { - // @ts-ignore looks like a list of nodes. - formatted = '\n' + inspectNodes(value); - } else { - formatted = inspectNonTree(value); - } - - result.push( - key + dim(':') + (/\s/.test(formatted.charAt(0)) ? '' : ' ') + formatted - ); - } - - return indent( - result.join('\n'), - // @ts-ignore looks like a parent node. - (object.children && object.children.length > 0 ? dim('│') : ' ') + ' ' - ) - } - - /** - * @param {Node} node - * @returns {string} - */ - function inspectTree(node) { - var result = [formatNode(node)]; - var fields = inspectFields(node); - // @ts-ignore looks like a parent. - var content = inspectNodes(node.children || []); - if (fields) result.push(fields); - if (content) result.push(content); - return result.join('\n') - } - - /** - * Colored node formatter. - * - * @param {Node} node - * @returns {string} - */ - function formatNode(node) { - var result = [bold(node.type)]; - var kind = node.tagName || node.name; - var position = positions ? stringifyPosition(node.position) : ''; - - if (typeof kind === 'string') { - result.push('<', kind, '>'); - } - - if (node.children) { - // @ts-ignore looks like a parent. - result.push(dim('['), yellow(node.children.length), dim(']')); - } else if (typeof node.value === 'string') { - result.push(' ', green(inspectNonTree(node.value))); - } - - if (position) { - result.push(' ', dim('('), position, dim(')')); - } - - return result.join('') - } -} - -/** - * @param {string} value - * @param {string} indentation - * @param {boolean} [ignoreFirst=false] - * @returns {string} - */ -function indent(value, indentation, ignoreFirst) { - var lines = value.split('\n'); - var index = ignoreFirst ? 0 : -1; - - if (!value) return value - - while (++index < lines.length) { - lines[index] = indentation + lines[index]; - } - - return lines.join('\n') -} - -/** - * @param {Position} value - * @returns {string} - */ -function stringifyPosition(value) { - /** @type {Position} */ - // @ts-ignore - var position = value || {}; - /** @type {Array.} */ - var result = []; - /** @type {Array.} */ - var positions = []; - /** @type {Array.} */ - var offsets = []; - - point(position.start); - point(position.end); - - if (positions.length > 0) result.push(positions.join('-')); - if (offsets.length > 0) result.push(offsets.join('-')); - - return result.join(', ') - - /** - * @param {Point} value - */ - function point(value) { - if (value) { - positions.push((value.line || 1) + ':' + (value.column || 1)); - - if ('offset' in value) { - offsets.push(String(value.offset || 0)); - } - } - } -} - -/** - * Factory to wrap values in ANSI colours. - * - * @param {number} open - * @param {number} close - * @returns {function(string): string} - */ -function ansiColor(open, close) { - return color - - /** - * @param {string} value - * @returns {string} - */ - function color(value) { - return '\u001B[' + open + 'm' + value + '\u001B[' + close + 'm' - } -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('./index.js').Context} Context - */ - -const debug$3 = createDebug('unified-engine:file-pipeline:stringify'); - -/** - * Stringify a tree. - * - * @param {Context} context - * @param {VFile} file - */ -function stringify$1(context, file) { - /** @type {unknown} */ - let value; - - if (statistics(file).fatal) { - debug$3('Not compiling failed document'); - return - } - - if ( - !context.settings.output && - !context.settings.out && - !context.settings.alwaysStringify - ) { - debug$3('Not compiling document without output settings'); - return - } - - debug$3('Compiling `%s`', file.path); - - if (context.settings.inspect) { - // Add a `txt` extension if there is a path. - if (file.path) { - file.extname = '.txt'; - } - - value = - (context.settings.color ? inspectColor : inspectNoColor)(context.tree) + - '\n'; - } else if (context.settings.treeOut) { - // Add a `json` extension to ensure the file is correctly seen as JSON. - // Only add it if there is a path — not if the file is for example stdin. - if (file.path) { - file.extname = '.json'; - } - - // Add the line feed to create a valid UNIX file. - value = JSON.stringify(context.tree, null, 2) + '\n'; - } else { - // @ts-expect-error: `tree` is defined if we came this far. - value = context.processor.stringify(context.tree, file); - } - - if (value === undefined || value === null) ; else if (typeof value === 'string' || isBuffer(value)) { - // @ts-expect-error: `isBuffer` checks buffer. - file.value = value; - } else { - file.result = value; - } - - debug$3('Serialized document'); -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Context} Context - */ - -const debug$2 = createDebug('unified-engine:file-pipeline:copy'); - -/** - * Move a file. - * - * @param {Context} context - * @param {VFile} file - * @param {Callback} next - */ -function copy(context, file, next) { - const output = context.settings.output; - const currentPath = file.path; - - if (typeof output !== 'string') { - debug$2('Not copying'); - next(); - return - } - - const outpath = path$c.resolve(context.settings.cwd, output); - - debug$2('Copying `%s`', currentPath); - - fs$a.stat(outpath, (error, stats) => { - if (error) { - if ( - error.code !== 'ENOENT' || - output.charAt(output.length - 1) === path$c.sep - ) { - return next( - new Error('Cannot read output directory. Error:\n' + error.message) - ) - } - - // This is either given an error, or the parent exists which is a directory, - // but we should keep the basename of the given file. - fs$a.stat(path$c.dirname(outpath), (error) => { - if (error) { - next( - new Error('Cannot read parent directory. Error:\n' + error.message) - ); - } else { - done(false); - } - }); - } else { - done(stats.isDirectory()); - } - }); - - /** - * @param {boolean} directory - */ - function done(directory) { - if (!directory && context.fileSet.expected > 1) { - return next( - new Error('Cannot write multiple files to single output: ' + outpath) - ) - } - - file[directory ? 'dirname' : 'path'] = path$c.relative(file.cwd, outpath); - - debug$2('Copying document from %s to %s', currentPath, file.path); - - next(); - } -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Context} Context - */ - -const debug$1 = createDebug('unified-engine:file-pipeline:stdout'); - -/** - * Write a virtual file to `streamOut`. - * Ignored when `output` is given, more than one file was processed, or `out` - * is false. - * - * @param {Context} context - * @param {VFile} file - * @param {Callback} next - */ -function stdout(context, file, next) { - if (!file.data.unifiedEngineGiven) { - debug$1('Ignoring programmatically added file'); - next(); - } else if ( - statistics(file).fatal || - context.settings.output || - !context.settings.out - ) { - debug$1('Ignoring writing to `streamOut`'); - next(); - } else { - debug$1('Writing document to `streamOut`'); - context.settings.streamOut.write(file.toString(), next); - } -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Context} Context - */ - -const debug = createDebug('unified-engine:file-pipeline:file-system'); - -/** - * Write a virtual file to the file-system. - * Ignored when `output` is not given. - * - * @param {Context} context - * @param {VFile} file - * @param {Callback} next - */ -function fileSystem(context, file, next) { - if (!context.settings.output) { - debug('Ignoring writing to file-system'); - return next() - } - - if (!file.data.unifiedEngineGiven) { - debug('Ignoring programmatically added file'); - return next() - } - - let destinationPath = file.path; - - if (!destinationPath) { - debug('Cannot write file without a `destinationPath`'); - return next(new Error('Cannot write file without an output path')) - } - - if (statistics(file).fatal) { - debug('Cannot write file with a fatal error'); - return next() - } - - destinationPath = path$c.resolve(context.settings.cwd, destinationPath); - debug('Writing document to `%s`', destinationPath); - - file.stored = true; - fs$a.writeFile(destinationPath, file.toString(), next); -} - -/** - * @typedef {import('trough').Pipeline} Pipeline - * @typedef {import('vfile').VFile} VFile - * @typedef {import('vfile-message').VFileMessage} VFileMessage - * @typedef {import('unist').Node} Node - * @typedef {import('unified').Processor} Processor - * @typedef {import('../file-set.js').FileSet} FileSet - * @typedef {import('../configuration.js').Configuration} Configuration - * @typedef {import('../index.js').Settings} Settings - */ - -// This pipeline ensures each of the pipes always runs: even if the read pipe -// fails, queue and write run. -const filePipeline = trough() - .use(chunk(trough().use(read$1).use(configure$2).use(parse$2).use(transform$2))) - .use(chunk(trough().use(queue))) - .use(chunk(trough().use(stringify$1).use(copy).use(stdout).use(fileSystem))); - -/** - * Factory to run a pipe. - * Wraps a pipe to trigger an error on the `file` in `context`, but still call - * `next`. - * - * @param {Pipeline} pipe - */ -function chunk(pipe) { - return run - - /** - * Run the bound pipe and handle any errors. - * - * @param {Context} context - * @param {VFile} file - * @param {() => void} next - */ - function run(context, file, next) { - pipe.run(context, file, (/** @type {VFileMessage|null} */ error) => { - const messages = file.messages; - - if (error) { - const index = messages.indexOf(error); - - if (index === -1) { - Object.assign(file.message(error), {fatal: true}); - } else { - messages[index].fatal = true; - } - } - - next(); - }); - } -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Settings} Settings - * @typedef {import('./index.js').Configuration} Configuration - */ - -/** - * Transform all files. - * - * @param {Context} context - * @param {Settings} settings - * @param {Callback} next - */ -function transform$1(context, settings, next) { - const fileSet = new FileSet(); - - context.fileSet = fileSet; - - fileSet.on('add', (/** @type {VFile} */ file) => { - filePipeline.run( - { - configuration: context.configuration, - // Needed `any`s - // type-coverage:ignore-next-line - processor: settings.processor(), - fileSet, - settings - }, - file, - (/** @type {Error|null} */ error) => { - // Does not occur as all failures in `filePipeLine` are failed on each - // file. - // Still, just to ensure things work in the future, we add an extra check. - /* c8 ignore next 4 */ - if (error) { - Object.assign(file.message(error), {fatal: true}); - } - - fileSet.emit('one', file); - } - ); - }); - - fileSet.on('done', next); - - if (context.files.length === 0) { - next(); - } else { - let index = -1; - while (++index < context.files.length) { - fileSet.add(context.files[index]); - } - } -} - -function hasFlag(flag, argv = process$1.argv) { - const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const position = argv.indexOf(prefix + flag); - const terminatorPosition = argv.indexOf('--'); - return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); -} - -const {env} = process$1; - -let flagForceColor; -if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false') || - hasFlag('color=never')) { - flagForceColor = 0; -} else if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - flagForceColor = 1; -} - -function envForceColor() { - if ('FORCE_COLOR' in env) { - if (env.FORCE_COLOR === 'true') { - return 1; - } - - if (env.FORCE_COLOR === 'false') { - return 0; - } - - return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3); - } -} - -function translateLevel(level) { - if (level === 0) { - return false; - } - - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; -} - -function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) { - const noFlagForceColor = envForceColor(); - if (noFlagForceColor !== undefined) { - flagForceColor = noFlagForceColor; - } - - const forceColor = sniffFlags ? flagForceColor : noFlagForceColor; - - if (forceColor === 0) { - return 0; - } - - if (sniffFlags) { - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; - } - - if (hasFlag('color=256')) { - return 2; - } - } - - if (haveStream && !streamIsTTY && forceColor === undefined) { - return 0; - } - - const min = forceColor || 0; - - if (env.TERM === 'dumb') { - return min; - } - - if (process$1.platform === 'win32') { - // Windows 10 build 10586 is the first Windows release that supports 256 colors. - // Windows 10 build 14931 is the first release that supports 16m/TrueColor. - const osRelease = require$$0$2.release().split('.'); - if ( - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; - } - - return 1; - } - - if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; - } - - return min; - } - - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } - - if (env.COLORTERM === 'truecolor') { - return 3; - } - - if ('TERM_PROGRAM' in env) { - const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default - } - } - - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } - - if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; - } - - if ('COLORTERM' in env) { - return 1; - } - - return min; -} - -function createSupportsColor(stream, options = {}) { - const level = _supportsColor(stream, { - streamIsTTY: stream && stream.isTTY, - ...options - }); - - return translateLevel(level); -} - -const supportsColor = { - stdout: createSupportsColor({isTTY: tty$1.isatty(1)}), - stderr: createSupportsColor({isTTY: tty$1.isatty(2)}) -}; - -function ansiRegex({onlyFirst = false} = {}) { - const pattern = [ - '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', - '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))' - ].join('|'); - - return new RegExp(pattern, onlyFirst ? undefined : 'g'); -} - -function stripAnsi(string) { - if (typeof string !== 'string') { - throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``); - } - - return string.replace(ansiRegex(), ''); -} - -/* eslint-disable yoda */ - -function isFullwidthCodePoint(codePoint) { - if (!Number.isInteger(codePoint)) { - return false; - } - - // Code points are derived from: - // https://unicode.org/Public/UNIDATA/EastAsianWidth.txt - return codePoint >= 0x1100 && ( - codePoint <= 0x115F || // Hangul Jamo - codePoint === 0x2329 || // LEFT-POINTING ANGLE BRACKET - codePoint === 0x232A || // RIGHT-POINTING ANGLE BRACKET - // CJK Radicals Supplement .. Enclosed CJK Letters and Months - (0x2E80 <= codePoint && codePoint <= 0x3247 && codePoint !== 0x303F) || - // Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A - (0x3250 <= codePoint && codePoint <= 0x4DBF) || - // CJK Unified Ideographs .. Yi Radicals - (0x4E00 <= codePoint && codePoint <= 0xA4C6) || - // Hangul Jamo Extended-A - (0xA960 <= codePoint && codePoint <= 0xA97C) || - // Hangul Syllables - (0xAC00 <= codePoint && codePoint <= 0xD7A3) || - // CJK Compatibility Ideographs - (0xF900 <= codePoint && codePoint <= 0xFAFF) || - // Vertical Forms - (0xFE10 <= codePoint && codePoint <= 0xFE19) || - // CJK Compatibility Forms .. Small Form Variants - (0xFE30 <= codePoint && codePoint <= 0xFE6B) || - // Halfwidth and Fullwidth Forms - (0xFF01 <= codePoint && codePoint <= 0xFF60) || - (0xFFE0 <= codePoint && codePoint <= 0xFFE6) || - // Kana Supplement - (0x1B000 <= codePoint && codePoint <= 0x1B001) || - // Enclosed Ideographic Supplement - (0x1F200 <= codePoint && codePoint <= 0x1F251) || - // CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane - (0x20000 <= codePoint && codePoint <= 0x3FFFD) - ); -} - -var emojiRegex = function () { - // https://mths.be/emoji - return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g; -}; - -function stringWidth(string) { - if (typeof string !== 'string' || string.length === 0) { - return 0; - } - - string = stripAnsi(string); - - if (string.length === 0) { - return 0; - } - - string = string.replace(emojiRegex(), ' '); - - let width = 0; - - for (let index = 0; index < string.length; index++) { - const codePoint = string.codePointAt(index); - - // Ignore control characters - if (codePoint <= 0x1F || (codePoint >= 0x7F && codePoint <= 0x9F)) { - continue; - } - - // Ignore combining characters - if (codePoint >= 0x300 && codePoint <= 0x36F) { - continue; - } - - // Surrogates - if (codePoint > 0xFFFF) { - index++; - } - - width += isFullwidthCodePoint(codePoint) ? 2 : 1; - } - - return width; -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('vfile-message').VFileMessage} VFileMessage - */ - -var severities = {true: 2, false: 1, null: 0, undefined: 0}; - -/** - * @template {VFile} F - * @param {F} file - * @returns {F} - */ -function sort(file) { - file.messages.sort(comparator); - return file -} - -/** - * @param {VFileMessage} a - * @param {VFileMessage} b - * @returns {number} - */ -function comparator(a, b) { - return ( - check$1(a, b, 'line') || - check$1(a, b, 'column') || - severities[b.fatal] - severities[a.fatal] || - compare(a, b, 'source') || - compare(a, b, 'ruleId') || - compare(a, b, 'reason') || - 0 - ) -} - -/** - * @param {VFileMessage} a - * @param {VFileMessage} b - * @param {string} property - * @returns {number} - */ -function check$1(a, b, property) { - return (a[property] || 0) - (b[property] || 0) -} - -/** - * @param {VFileMessage} a - * @param {VFileMessage} b - * @param {string} property - * @returns {number} - */ -function compare(a, b, property) { - return String(a[property] || '').localeCompare(b[property] || '') -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('vfile-message').VFileMessage} VFileMessage - * @typedef {import('vfile-statistics').Statistics} Statistics - * - * @typedef Options - * @property {boolean} [color] - * @property {boolean} [silent=false] - * @property {boolean} [quiet=false] - * @property {boolean} [verbose=false] - * @property {string} [defaultName=''] - * - * @typedef _Row - * @property {string} place - * @property {string} label - * @property {string} reason - * @property {string} ruleId - * @property {string} source - * - * @typedef _FileRow - * @property {'file'} type - * @property {VFile} file - * @property {Statistics} stats - * - * @typedef {{[x: string]: number}} _Sizes - * - * @typedef _Info - * @property {Array.<_FileRow|_Row>} rows - * @property {Statistics} stats - * @property {_Sizes} sizes - */ - -const own$8 = {}.hasOwnProperty; - -// @ts-expect-error Types are incorrect. -const supported = supportsColor.stderr.hasBasic; - -// `log-symbols` without chalk, ignored for Windows: -/* c8 ignore next 4 */ -const chars = - process.platform === 'win32' - ? {error: '×', warning: '‼'} - : {error: '✖', warning: '⚠'}; - -const labels = { - true: 'error', - false: 'warning', - null: 'info', - undefined: 'info' -}; - -/** - * Report a file’s messages. - * - * @param {Error|VFile|Array.} [files] - * @param {Options} [options] - * @returns {string} - */ -function reporter$1(files, options = {}) { - /** @type {boolean|undefined} */ - let one; - - if (!files) { - return '' - } - - // Error. - if ('name' in files && 'message' in files) { - return String(files.stack || files) - } - - // One file. - if (!Array.isArray(files)) { - one = true; - files = [files]; - } - - return format(transform(files, options), one, options) -} - -/** - * @param {Array.} files - * @param {Options} options - * @returns {_Info} - */ -function transform(files, options) { - /** @type {Array.<_FileRow|_Row>} */ - const rows = []; - /** @type {Array.} */ - const all = []; - /** @type {_Sizes} */ - const sizes = {}; - let index = -1; - - while (++index < files.length) { - // @ts-expect-error it works fine. - const messages = sort({messages: [...files[index].messages]}).messages; - /** @type {Array.<_Row>} */ - const messageRows = []; - let offset = -1; - - while (++offset < messages.length) { - const message = messages[offset]; - - if (!options.silent || message.fatal) { - all.push(message); - - const row = { - place: stringifyPosition$1( - message.position - ? message.position.end.line && message.position.end.column - ? message.position - : message.position.start - : undefined - ), - label: labels[/** @type {keyof labels} */ (String(message.fatal))], - reason: - (message.stack || message.message) + - (options.verbose && message.note ? '\n' + message.note : ''), - ruleId: message.ruleId || '', - source: message.source || '' - }; - - /** @type {keyof row} */ - let key; - - for (key in row) { - // eslint-disable-next-line max-depth - if (own$8.call(row, key)) { - sizes[key] = Math.max(size$1(row[key]), sizes[key] || 0); - } - } - - messageRows.push(row); - } - } - - if ((!options.quiet && !options.silent) || messageRows.length > 0) { - rows.push( - {type: 'file', file: files[index], stats: statistics(messages)}, - ...messageRows - ); - } - } - - return {rows, stats: statistics(all), sizes} -} - -/** - * @param {_Info} map - * @param {boolean|undefined} one - * @param {Options} options - */ -// eslint-disable-next-line complexity -function format(map, one, options) { - /** @type {boolean} */ - const enabled = - options.color === undefined || options.color === null - ? supported - : options.color; - /** @type {Array.} */ - const lines = []; - let index = -1; - - while (++index < map.rows.length) { - const row = map.rows[index]; - - if ('type' in row) { - const stats = row.stats; - let line = row.file.history[0] || options.defaultName || ''; - - line = - one && !options.defaultName && !row.file.history[0] - ? '' - : (enabled - ? '\u001B[4m' /* Underline. */ + - (stats.fatal - ? '\u001B[31m' /* Red. */ - : stats.total - ? '\u001B[33m' /* Yellow. */ - : '\u001B[32m') /* Green. */ + - line + - '\u001B[39m\u001B[24m' - : line) + - (row.file.stored && row.file.path !== row.file.history[0] - ? ' > ' + row.file.path - : ''); - - if (!stats.total) { - line = - (line ? line + ': ' : '') + - (row.file.stored - ? enabled - ? '\u001B[33mwritten\u001B[39m' /* Yellow. */ - : 'written' - : 'no issues found'); - } - - if (line) { - if (index && !('type' in map.rows[index - 1])) { - lines.push(''); - } - - lines.push(line); - } - } else { - let reason = row.reason; - const match = /\r?\n|\r/.exec(reason); - /** @type {string} */ - let rest; - - if (match) { - rest = reason.slice(match.index); - reason = reason.slice(0, match.index); - } else { - rest = ''; - } - - lines.push( - ( - ' ' + - ' '.repeat(map.sizes.place - size$1(row.place)) + - row.place + - ' ' + - (enabled - ? (row.label === 'error' - ? '\u001B[31m' /* Red. */ - : '\u001B[33m') /* Yellow. */ + - row.label + - '\u001B[39m' - : row.label) + - ' '.repeat(map.sizes.label - size$1(row.label)) + - ' ' + - reason + - ' '.repeat(map.sizes.reason - size$1(reason)) + - ' ' + - row.ruleId + - ' '.repeat(map.sizes.ruleId - size$1(row.ruleId)) + - ' ' + - (row.source || '') - ).replace(/ +$/, '') + rest - ); - } - } - - const stats = map.stats; - - if (stats.fatal || stats.warn) { - let line = ''; - - if (stats.fatal) { - line = - (enabled - ? '\u001B[31m' /* Red. */ + chars.error + '\u001B[39m' - : chars.error) + - ' ' + - stats.fatal + - ' ' + - (labels.true + (stats.fatal === 1 ? '' : 's')); - } - - if (stats.warn) { - line = - (line ? line + ', ' : '') + - (enabled - ? '\u001B[33m' /* Yellow. */ + chars.warning + '\u001B[39m' - : chars.warning) + - ' ' + - stats.warn + - ' ' + - (labels.false + (stats.warn === 1 ? '' : 's')); - } - - if (stats.total !== stats.fatal && stats.total !== stats.warn) { - line = stats.total + ' messages (' + line + ')'; - } - - lines.push('', line); - } - - return lines.join('\n') -} - -/** - * Get the length of `value`, ignoring ANSI sequences. - * - * @param {string} value - * @returns {number} - */ -function size$1(value) { - const match = /\r?\n|\r/.exec(value); - return stringWidth(match ? value.slice(0, match.index) : value) -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('../index.js').VFileReporter} VFileReporter - * @typedef {import('./index.js').Settings} Settings - * @typedef {import('./index.js').Configuration} Configuration - */ - -/** - * @typedef Context - * @property {Array.} files - * @property {Configuration} [configuration] - */ - -/** - * @param {Context} context - * @param {Settings} settings - */ -async function log(context, settings) { - /** @type {VFileReporter} */ - let func = reporter$1; - - if (typeof settings.reporter === 'string') { - try { - // @ts-expect-error: Assume loaded value is a vfile reporter. - func = await loadPlugin(settings.reporter, { - cwd: settings.cwd, - prefix: 'vfile-reporter' - }); - } catch { - throw new Error('Could not find reporter `' + settings.reporter + '`') - } - } else if (settings.reporter) { - func = settings.reporter; - } - - let diagnostics = func( - context.files.filter((file) => file.data.unifiedEngineGiven), - Object.assign({}, settings.reporterOptions, { - quiet: settings.quiet, - silent: settings.silent, - color: settings.color - }) - ); - - if (diagnostics) { - if (diagnostics.charAt(diagnostics.length - 1) !== '\n') { - diagnostics += '\n'; - } - - return new Promise((resolve) => { - settings.streamError.write(diagnostics, resolve); - }) - } -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('../configuration.js').Configuration} Configuration - * @typedef {import('../index.js').Settings} Settings - */ - -const fileSetPipeline = trough() - .use(configure$3) - .use(fileSystem$1) - .use(stdin) - .use(transform$1) - .use(log); - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('unified').Processor} Processor - * @typedef {import('./file-set.js').FileSet} FileSet - * @typedef {import('./file-set.js').Completer} Completer - * @typedef {import('./ignore.js').ResolveFrom} ResolveFrom - * @typedef {import('./configuration.js').ConfigTransform} ConfigTransform - * @typedef {import('./configuration.js').Preset} Preset - * - * @typedef VFileReporterFields - * @property {boolean} [color] - * @property {boolean} [quiet] - * @property {boolean} [silent] - * - * @typedef {{[key: string]: unknown} & VFileReporterFields} VFileReporterOptions - * - * @callback VFileReporter - * @param {VFile[]} files - * @param {VFileReporterOptions} options - * @returns {string} - * - * @typedef Settings - * @property {Options['processor']} processor - * @property {Exclude} cwd - * @property {Exclude} files - * @property {Exclude} extensions - * @property {Exclude} streamIn - * @property {Options['filePath']} filePath - * @property {Exclude} streamOut - * @property {Exclude} streamError - * @property {Options['out']} out - * @property {Options['output']} output - * @property {Options['alwaysStringify']} alwaysStringify - * @property {Options['tree']} tree - * @property {Options['treeIn']} treeIn - * @property {Options['treeOut']} treeOut - * @property {Options['inspect']} inspect - * @property {Options['rcName']} rcName - * @property {Options['packageField']} packageField - * @property {Options['detectConfig']} detectConfig - * @property {Options['rcPath']} rcPath - * @property {Exclude} settings - * @property {Options['ignoreName']} ignoreName - * @property {Options['detectIgnore']} detectIgnore - * @property {Options['ignorePath']} ignorePath - * @property {Options['ignorePathResolveFrom']} ignorePathResolveFrom - * @property {Exclude} ignorePatterns - * @property {Options['silentlyIgnore']} silentlyIgnore - * @property {Options['plugins']} plugins - * @property {Options['pluginPrefix']} pluginPrefix - * @property {Options['configTransform']} configTransform - * @property {Options['defaultConfig']} defaultConfig - * @property {Options['reporter']} reporter - * @property {Options['reporterOptions']} reporterOptions - * @property {Options['color']} color - * @property {Options['silent']} silent - * @property {Options['quiet']} quiet - * @property {Options['frail']} frail - * - * @typedef Options - * Options for unified engine - * @property {() => Processor} processor - * Unified processor to transform files - * @property {string} [cwd] - * Directory to search files in, load plugins from, and more. - * Defaults to `process.cwd()`. - * @property {Array} [files] - * Paths or globs to files and directories, or virtual files, to process. - * @property {string[]} [extensions] - * If `files` matches directories, include `files` with `extensions` - * @property {NodeJS.ReadableStream} [streamIn] - * Stream to read from if no files are found or given. - * Defaults to `process.stdin`. - * @property {string} [filePath] - * File path to process the given file on `streamIn` as. - * @property {NodeJS.WritableStream} [streamOut] - * Stream to write processed files to. - * Defaults to `process.stdout`. - * @property {NodeJS.WritableStream} [streamError] - * Stream to write the report (if any) to. - * Defaults to `process.stderr`. - * @property {boolean} [out=false] - * Whether to write the processed file to `streamOut` - * @property {boolean|string} [output=false] - * Whether to write successfully processed files, and where to. - * - * * When `true`, overwrites the given files - * * When `false`, does not write to the file system - * * When pointing to an existing directory, files are written to that - * directory and keep their original basenames - * * When the parent directory of the given path exists and one file is - * processed, the file is written to the given path - * @property {boolean} [alwaysStringify=false] - * Whether to always serialize successfully processed files. - * @property {boolean} [tree=false] - * Whether to treat both input and output as a syntax tree. - * @property {boolean} [treeIn] - * Whether to treat input as a syntax tree. - * Defaults to `options.tree`. - * @property {boolean} [treeOut] - * Whether to treat output as a syntax tree. - * Defaults to `options.tree`. - * @property {boolean} [inspect=false] - * Whether to output a formatted syntax tree. - * @property {string} [rcName] - * Name of configuration files to load. - * @property {string} [packageField] - * Property at which configuration can be found in `package.json` files - * @property {boolean} [detectConfig] - * Whether to search for configuration files. - * Defaults to `true` if `rcName` or `packageField` are given - * @property {string} [rcPath] - * Filepath to a configuration file to load. - * @property {Preset['settings']} [settings] - * Configuration for the parser and compiler of the processor. - * @property {string} [ignoreName] - * Name of ignore files to load. - * @property {boolean} [detectIgnore] - * Whether to search for ignore files. - * Defaults to `true` if `ignoreName` is given. - * @property {string} [ignorePath] - * Filepath to an ignore file to load. - * @property {ResolveFrom} [ignorePathResolveFrom] - * Resolve patterns in `ignorePath` from the current working - * directory (`'cwd'`) or the ignore file’s directory (`'dir'`, default). - * @property {string[]} [ignorePatterns] - * Patterns to ignore in addition to ignore files - * @property {boolean} [silentlyIgnore=false] - * Skip given files if they are ignored. - * @property {Preset['plugins']} [plugins] - * Plugins to use. - * @property {string} [pluginPrefix] - * Prefix to use when searching for plugins - * @property {ConfigTransform} [configTransform] - * Transform config files from a different schema. - * @property {Preset} [defaultConfig] - * Default configuration to use if no config file is given or found. - * @property {VFileReporter|string} [reporter] - * Reporter to use - * Defaults to `vfile-reporter` - * @property {VFileReporterOptions} [reporterOptions] - * Config to pass to the used reporter. - * @property {VFileReporterOptions['color']} [color=false] - * Whether to report with ANSI color sequences. - * @property {VFileReporterOptions['silent']} [silent=false] - * Report only fatal errors - * @property {VFileReporterOptions['quiet']} [quiet=false] - * Do not report successful files - * @property {boolean} [frail=false] - * Call back with an unsuccessful (`1`) code on warnings as well as errors - * - * @typedef Context - * Processing context. - * @property {VFile[]} [files] - * Processed files. - * @property {FileSet} [fileSet] - * Internally used information - * - * @callback Callback - * Callback called when processing according to options is complete. - * Invoked with either a fatal error if processing went horribly wrong - * (probably due to incorrect configuration), or a status code and the - * processing context. - * @param {Error|null} error - * @param {0|1} [status] - * @param {Context} [context] - * @returns {void} - */ - -/** - * Run the file set pipeline once. - * `callback` is called with a fatal error, or with a status code (`0` on - * success, `1` on failure). - * - * @param {Options} options - * @param {Callback} callback - */ -function engine(options, callback) { - /** @type {Settings} */ - const settings = {}; - /** @type {NodeJS.ReadStream} */ - // @ts-expect-error: `PassThrough` sure is readable. - let stdin = new PassThrough(); - - try { - stdin = process$2.stdin; - // Obscure bug in Node (seen on Windows). - // See: , - // . - /* c8 ignore next 1 */ - } catch {} - - if (!callback) { - throw new Error('Missing `callback`') - } - - // Needed `any`s - // type-coverage:ignore-next-line - if (!options || !options.processor) { - return next(new Error('Missing `processor`')) - } - - // Processor. - // Needed `any`s - // type-coverage:ignore-next-line - settings.processor = options.processor; - - // Path to run as. - settings.cwd = options.cwd || process$2.cwd(); - - // Input. - settings.files = options.files || []; - settings.extensions = (options.extensions || []).map((ext) => - ext.charAt(0) === '.' ? ext : '.' + ext - ); - - settings.filePath = options.filePath; - settings.streamIn = options.streamIn || stdin; - - // Output. - settings.streamOut = options.streamOut || process$2.stdout; - settings.streamError = options.streamError || process$2.stderr; - settings.alwaysStringify = options.alwaysStringify; - settings.output = options.output; - settings.out = options.out; - - // Null overwrites config settings, `undefined` does not. - if (settings.output === null || settings.output === undefined) { - settings.output = undefined; - } - - if (settings.output && settings.out) { - return next(new Error('Cannot accept both `output` and `out`')) - } - - // Process phase management. - const tree = options.tree || false; - - settings.treeIn = options.treeIn; - settings.treeOut = options.treeOut; - settings.inspect = options.inspect; - - if (settings.treeIn === null || settings.treeIn === undefined) { - settings.treeIn = tree; - } - - if (settings.treeOut === null || settings.treeOut === undefined) { - settings.treeOut = tree; - } - - // Configuration. - const detectConfig = options.detectConfig; - const hasConfig = Boolean(options.rcName || options.packageField); - - if (detectConfig && !hasConfig) { - return next( - new Error('Missing `rcName` or `packageField` with `detectConfig`') - ) - } - - settings.detectConfig = - detectConfig === null || detectConfig === undefined - ? hasConfig - : detectConfig; - settings.rcName = options.rcName; - settings.rcPath = options.rcPath; - settings.packageField = options.packageField; - settings.settings = options.settings || {}; - settings.configTransform = options.configTransform; - settings.defaultConfig = options.defaultConfig; - - // Ignore. - const detectIgnore = options.detectIgnore; - const hasIgnore = Boolean(options.ignoreName); - - settings.detectIgnore = - detectIgnore === null || detectIgnore === undefined - ? hasIgnore - : detectIgnore; - settings.ignoreName = options.ignoreName; - settings.ignorePath = options.ignorePath; - settings.ignorePathResolveFrom = options.ignorePathResolveFrom || 'dir'; - settings.ignorePatterns = options.ignorePatterns || []; - settings.silentlyIgnore = Boolean(options.silentlyIgnore); - - if (detectIgnore && !hasIgnore) { - return next(new Error('Missing `ignoreName` with `detectIgnore`')) - } - - // Plugins. - settings.pluginPrefix = options.pluginPrefix; - settings.plugins = options.plugins || []; - - // Reporting. - settings.reporter = options.reporter; - settings.reporterOptions = options.reporterOptions; - settings.color = options.color || false; - settings.silent = options.silent; - settings.quiet = options.quiet; - settings.frail = options.frail; - - // Process. - fileSetPipeline.run({files: options.files || []}, settings, next); - - /** - * @param {Error|null} error - * @param {Context} [context] - */ - function next(error, context) { - const stats = statistics((context || {}).files); - const failed = Boolean( - settings.frail ? stats.fatal || stats.warn : stats.fatal - ); - - if (error) { - callback(error); - } else { - callback(null, failed ? 1 : 0, context); - } - } -} - -var textTable = function (rows_, opts) { - if (!opts) opts = {}; - var hsep = opts.hsep === undefined ? ' ' : opts.hsep; - var align = opts.align || []; - var stringLength = opts.stringLength - || function (s) { return String(s).length; } - ; - - var dotsizes = reduce(rows_, function (acc, row) { - forEach(row, function (c, ix) { - var n = dotindex(c); - if (!acc[ix] || n > acc[ix]) acc[ix] = n; - }); - return acc; - }, []); - - var rows = map$2(rows_, function (row) { - return map$2(row, function (c_, ix) { - var c = String(c_); - if (align[ix] === '.') { - var index = dotindex(c); - var size = dotsizes[ix] + (/\./.test(c) ? 1 : 2) - - (stringLength(c) - index) - ; - return c + Array(size).join(' '); - } - else return c; - }); - }); - - var sizes = reduce(rows, function (acc, row) { - forEach(row, function (c, ix) { - var n = stringLength(c); - if (!acc[ix] || n > acc[ix]) acc[ix] = n; - }); - return acc; - }, []); - - return map$2(rows, function (row) { - return map$2(row, function (c, ix) { - var n = (sizes[ix] - stringLength(c)) || 0; - var s = Array(Math.max(n + 1, 1)).join(' '); - if (align[ix] === 'r' || align[ix] === '.') { - return s + c; - } - if (align[ix] === 'c') { - return Array(Math.ceil(n / 2 + 1)).join(' ') - + c + Array(Math.floor(n / 2 + 1)).join(' ') - ; - } - - return c + s; - }).join(hsep).replace(/\s+$/, ''); - }).join('\n'); -}; - -function dotindex (c) { - var m = /\.[^.]*$/.exec(c); - return m ? m.index + 1 : c.length; -} - -function reduce (xs, f, init) { - if (xs.reduce) return xs.reduce(f, init); - var i = 0; - var acc = arguments.length >= 3 ? init : xs[i++]; - for (; i < xs.length; i++) { - f(acc, xs[i], i); - } - return acc; -} - -function forEach (xs, f) { - if (xs.forEach) return xs.forEach(f); - for (var i = 0; i < xs.length; i++) { - f.call(xs, xs[i], i); - } -} - -function map$2 (xs, f) { - if (xs.map) return xs.map(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - res.push(f.call(xs, xs[i], i)); - } - return res; -} - -var camelcase$1 = {exports: {}}; - -const preserveCamelCase = (string, locale) => { - let isLastCharLower = false; - let isLastCharUpper = false; - let isLastLastCharUpper = false; - - for (let i = 0; i < string.length; i++) { - const character = string[i]; - - if (isLastCharLower && /[\p{Lu}]/u.test(character)) { - string = string.slice(0, i) + '-' + string.slice(i); - isLastCharLower = false; - isLastLastCharUpper = isLastCharUpper; - isLastCharUpper = true; - i++; - } else if (isLastCharUpper && isLastLastCharUpper && /[\p{Ll}]/u.test(character)) { - string = string.slice(0, i - 1) + '-' + string.slice(i - 1); - isLastLastCharUpper = isLastCharUpper; - isLastCharUpper = false; - isLastCharLower = true; - } else { - isLastCharLower = character.toLocaleLowerCase(locale) === character && character.toLocaleUpperCase(locale) !== character; - isLastLastCharUpper = isLastCharUpper; - isLastCharUpper = character.toLocaleUpperCase(locale) === character && character.toLocaleLowerCase(locale) !== character; - } - } - - return string; -}; - -const preserveConsecutiveUppercase = input => { - return input.replace(/^[\p{Lu}](?![\p{Lu}])/gu, m1 => m1.toLowerCase()); -}; - -const postProcess = (input, options) => { - return input.replace(/[_.\- ]+([\p{Alpha}\p{N}_]|$)/gu, (_, p1) => p1.toLocaleUpperCase(options.locale)) - .replace(/\d+([\p{Alpha}\p{N}_]|$)/gu, m => m.toLocaleUpperCase(options.locale)); -}; - -const camelCase = (input, options) => { - if (!(typeof input === 'string' || Array.isArray(input))) { - throw new TypeError('Expected the input to be `string | string[]`'); - } - - options = { - pascalCase: false, - preserveConsecutiveUppercase: false, - ...options - }; - - if (Array.isArray(input)) { - input = input.map(x => x.trim()) - .filter(x => x.length) - .join('-'); - } else { - input = input.trim(); - } - - if (input.length === 0) { - return ''; - } - - if (input.length === 1) { - return options.pascalCase ? input.toLocaleUpperCase(options.locale) : input.toLocaleLowerCase(options.locale); - } - - const hasUpperCase = input !== input.toLocaleLowerCase(options.locale); - - if (hasUpperCase) { - input = preserveCamelCase(input, options.locale); - } - - input = input.replace(/^[_.\- ]+/, ''); - - if (options.preserveConsecutiveUppercase) { - input = preserveConsecutiveUppercase(input); - } else { - input = input.toLocaleLowerCase(); - } - - if (options.pascalCase) { - input = input.charAt(0).toLocaleUpperCase(options.locale) + input.slice(1); - } - - return postProcess(input, options); -}; - -camelcase$1.exports = camelCase; -// TODO: Remove this for the next major release -camelcase$1.exports.default = camelCase; - -var camelcase = camelcase$1.exports; - -var minimist = function (args, opts) { - if (!opts) opts = {}; - - var flags = { bools : {}, strings : {}, unknownFn: null }; - - if (typeof opts['unknown'] === 'function') { - flags.unknownFn = opts['unknown']; - } - - if (typeof opts['boolean'] === 'boolean' && opts['boolean']) { - flags.allBools = true; - } else { - [].concat(opts['boolean']).filter(Boolean).forEach(function (key) { - flags.bools[key] = true; - }); - } - - var aliases = {}; - Object.keys(opts.alias || {}).forEach(function (key) { - aliases[key] = [].concat(opts.alias[key]); - aliases[key].forEach(function (x) { - aliases[x] = [key].concat(aliases[key].filter(function (y) { - return x !== y; - })); - }); - }); - - [].concat(opts.string).filter(Boolean).forEach(function (key) { - flags.strings[key] = true; - if (aliases[key]) { - flags.strings[aliases[key]] = true; - } - }); - - var defaults = opts['default'] || {}; - - var argv = { _ : [] }; - Object.keys(flags.bools).forEach(function (key) { - setArg(key, defaults[key] === undefined ? false : defaults[key]); - }); - - var notFlags = []; - - if (args.indexOf('--') !== -1) { - notFlags = args.slice(args.indexOf('--')+1); - args = args.slice(0, args.indexOf('--')); - } - - function argDefined(key, arg) { - return (flags.allBools && /^--[^=]+$/.test(arg)) || - flags.strings[key] || flags.bools[key] || aliases[key]; - } - - function setArg (key, val, arg) { - if (arg && flags.unknownFn && !argDefined(key, arg)) { - if (flags.unknownFn(arg) === false) return; - } - - var value = !flags.strings[key] && isNumber(val) - ? Number(val) : val - ; - setKey(argv, key.split('.'), value); - - (aliases[key] || []).forEach(function (x) { - setKey(argv, x.split('.'), value); - }); - } - - function setKey (obj, keys, value) { - var o = obj; - for (var i = 0; i < keys.length-1; i++) { - var key = keys[i]; - if (key === '__proto__') return; - if (o[key] === undefined) o[key] = {}; - if (o[key] === Object.prototype || o[key] === Number.prototype - || o[key] === String.prototype) o[key] = {}; - if (o[key] === Array.prototype) o[key] = []; - o = o[key]; - } - - var key = keys[keys.length - 1]; - if (key === '__proto__') return; - if (o === Object.prototype || o === Number.prototype - || o === String.prototype) o = {}; - if (o === Array.prototype) o = []; - if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') { - o[key] = value; - } - else if (Array.isArray(o[key])) { - o[key].push(value); - } - else { - o[key] = [ o[key], value ]; - } - } - - function aliasIsBoolean(key) { - return aliases[key].some(function (x) { - return flags.bools[x]; - }); - } - - for (var i = 0; i < args.length; i++) { - var arg = args[i]; - - if (/^--.+=/.test(arg)) { - // Using [\s\S] instead of . because js doesn't support the - // 'dotall' regex modifier. See: - // http://stackoverflow.com/a/1068308/13216 - var m = arg.match(/^--([^=]+)=([\s\S]*)$/); - var key = m[1]; - var value = m[2]; - if (flags.bools[key]) { - value = value !== 'false'; - } - setArg(key, value, arg); - } - else if (/^--no-.+/.test(arg)) { - var key = arg.match(/^--no-(.+)/)[1]; - setArg(key, false, arg); - } - else if (/^--.+/.test(arg)) { - var key = arg.match(/^--(.+)/)[1]; - var next = args[i + 1]; - if (next !== undefined && !/^-/.test(next) - && !flags.bools[key] - && !flags.allBools - && (aliases[key] ? !aliasIsBoolean(key) : true)) { - setArg(key, next, arg); - i++; - } - else if (/^(true|false)$/.test(next)) { - setArg(key, next === 'true', arg); - i++; - } - else { - setArg(key, flags.strings[key] ? '' : true, arg); - } - } - else if (/^-[^-]+/.test(arg)) { - var letters = arg.slice(1,-1).split(''); - - var broken = false; - for (var j = 0; j < letters.length; j++) { - var next = arg.slice(j+2); - - if (next === '-') { - setArg(letters[j], next, arg); - continue; - } - - if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) { - setArg(letters[j], next.split('=')[1], arg); - broken = true; - break; - } - - if (/[A-Za-z]/.test(letters[j]) - && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { - setArg(letters[j], next, arg); - broken = true; - break; - } - - if (letters[j+1] && letters[j+1].match(/\W/)) { - setArg(letters[j], arg.slice(j+2), arg); - broken = true; - break; - } - else { - setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg); - } - } - - var key = arg.slice(-1)[0]; - if (!broken && key !== '-') { - if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) - && !flags.bools[key] - && (aliases[key] ? !aliasIsBoolean(key) : true)) { - setArg(key, args[i+1], arg); - i++; - } - else if (args[i+1] && /^(true|false)$/.test(args[i+1])) { - setArg(key, args[i+1] === 'true', arg); - i++; - } - else { - setArg(key, flags.strings[key] ? '' : true, arg); - } - } - } - else { - if (!flags.unknownFn || flags.unknownFn(arg) !== false) { - argv._.push( - flags.strings['_'] || !isNumber(arg) ? arg : Number(arg) - ); - } - if (opts.stopEarly) { - argv._.push.apply(argv._, args.slice(i + 1)); - break; - } - } - } - - Object.keys(defaults).forEach(function (key) { - if (!hasKey(argv, key.split('.'))) { - setKey(argv, key.split('.'), defaults[key]); - - (aliases[key] || []).forEach(function (x) { - setKey(argv, x.split('.'), defaults[key]); - }); - } - }); - - if (opts['--']) { - argv['--'] = new Array(); - notFlags.forEach(function(key) { - argv['--'].push(key); - }); - } - else { - notFlags.forEach(function(key) { - argv._.push(key); - }); - } - - return argv; -}; - -function hasKey (obj, keys) { - var o = obj; - keys.slice(0,-1).forEach(function (key) { - o = (o[key] || {}); - }); - - var key = keys[keys.length - 1]; - return key in o; -} - -function isNumber (x) { - if (typeof x === 'number') return true; - if (/^0x[0-9a-f]+$/i.test(x)) return true; - return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); -} - -// This is a generated file. Do not edit. -var Space_Separator = /[\u1680\u2000-\u200A\u202F\u205F\u3000]/; -var ID_Start = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/; -var ID_Continue = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/; - -var unicode = { - Space_Separator: Space_Separator, - ID_Start: ID_Start, - ID_Continue: ID_Continue -}; - -var util = { - isSpaceSeparator (c) { - return typeof c === 'string' && unicode.Space_Separator.test(c) - }, - - isIdStartChar (c) { - return typeof c === 'string' && ( - (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - (c === '$') || (c === '_') || - unicode.ID_Start.test(c) - ) - }, - - isIdContinueChar (c) { - return typeof c === 'string' && ( - (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - (c >= '0' && c <= '9') || - (c === '$') || (c === '_') || - (c === '\u200C') || (c === '\u200D') || - unicode.ID_Continue.test(c) - ) - }, - - isDigit (c) { - return typeof c === 'string' && /[0-9]/.test(c) - }, - - isHexDigit (c) { - return typeof c === 'string' && /[0-9A-Fa-f]/.test(c) - }, -}; - -let source; -let parseState; -let stack; -let pos; -let line; -let column; -let token; -let key; -let root$1; - -var parse$1 = function parse (text, reviver) { - source = String(text); - parseState = 'start'; - stack = []; - pos = 0; - line = 1; - column = 0; - token = undefined; - key = undefined; - root$1 = undefined; - - do { - token = lex(); - - // This code is unreachable. - // if (!parseStates[parseState]) { - // throw invalidParseState() - // } - - parseStates[parseState](); - } while (token.type !== 'eof') - - if (typeof reviver === 'function') { - return internalize({'': root$1}, '', reviver) - } - - return root$1 -}; - -function internalize (holder, name, reviver) { - const value = holder[name]; - if (value != null && typeof value === 'object') { - for (const key in value) { - const replacement = internalize(value, key, reviver); - if (replacement === undefined) { - delete value[key]; - } else { - value[key] = replacement; - } - } - } - - return reviver.call(holder, name, value) -} - -let lexState; -let buffer; -let doubleQuote; -let sign; -let c; - -function lex () { - lexState = 'default'; - buffer = ''; - doubleQuote = false; - sign = 1; - - for (;;) { - c = peek(); - - // This code is unreachable. - // if (!lexStates[lexState]) { - // throw invalidLexState(lexState) - // } - - const token = lexStates[lexState](); - if (token) { - return token - } - } -} - -function peek () { - if (source[pos]) { - return String.fromCodePoint(source.codePointAt(pos)) - } -} - -function read () { - const c = peek(); - - if (c === '\n') { - line++; - column = 0; - } else if (c) { - column += c.length; - } else { - column++; - } - - if (c) { - pos += c.length; - } - - return c -} - -const lexStates = { - default () { - switch (c) { - case '\t': - case '\v': - case '\f': - case ' ': - case '\u00A0': - case '\uFEFF': - case '\n': - case '\r': - case '\u2028': - case '\u2029': - read(); - return - - case '/': - read(); - lexState = 'comment'; - return - - case undefined: - read(); - return newToken('eof') - } - - if (util.isSpaceSeparator(c)) { - read(); - return - } - - // This code is unreachable. - // if (!lexStates[parseState]) { - // throw invalidLexState(parseState) - // } - - return lexStates[parseState]() - }, - - comment () { - switch (c) { - case '*': - read(); - lexState = 'multiLineComment'; - return - - case '/': - read(); - lexState = 'singleLineComment'; - return - } - - throw invalidChar(read()) - }, - - multiLineComment () { - switch (c) { - case '*': - read(); - lexState = 'multiLineCommentAsterisk'; - return - - case undefined: - throw invalidChar(read()) - } - - read(); - }, - - multiLineCommentAsterisk () { - switch (c) { - case '*': - read(); - return - - case '/': - read(); - lexState = 'default'; - return - - case undefined: - throw invalidChar(read()) - } - - read(); - lexState = 'multiLineComment'; - }, - - singleLineComment () { - switch (c) { - case '\n': - case '\r': - case '\u2028': - case '\u2029': - read(); - lexState = 'default'; - return - - case undefined: - read(); - return newToken('eof') - } - - read(); - }, - - value () { - switch (c) { - case '{': - case '[': - return newToken('punctuator', read()) - - case 'n': - read(); - literal('ull'); - return newToken('null', null) - - case 't': - read(); - literal('rue'); - return newToken('boolean', true) - - case 'f': - read(); - literal('alse'); - return newToken('boolean', false) - - case '-': - case '+': - if (read() === '-') { - sign = -1; - } - - lexState = 'sign'; - return - - case '.': - buffer = read(); - lexState = 'decimalPointLeading'; - return - - case '0': - buffer = read(); - lexState = 'zero'; - return - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - buffer = read(); - lexState = 'decimalInteger'; - return - - case 'I': - read(); - literal('nfinity'); - return newToken('numeric', Infinity) - - case 'N': - read(); - literal('aN'); - return newToken('numeric', NaN) - - case '"': - case "'": - doubleQuote = (read() === '"'); - buffer = ''; - lexState = 'string'; - return - } - - throw invalidChar(read()) - }, - - identifierNameStartEscape () { - if (c !== 'u') { - throw invalidChar(read()) - } - - read(); - const u = unicodeEscape(); - switch (u) { - case '$': - case '_': - break - - default: - if (!util.isIdStartChar(u)) { - throw invalidIdentifier() - } - - break - } - - buffer += u; - lexState = 'identifierName'; - }, - - identifierName () { - switch (c) { - case '$': - case '_': - case '\u200C': - case '\u200D': - buffer += read(); - return - - case '\\': - read(); - lexState = 'identifierNameEscape'; - return - } - - if (util.isIdContinueChar(c)) { - buffer += read(); - return - } - - return newToken('identifier', buffer) - }, - - identifierNameEscape () { - if (c !== 'u') { - throw invalidChar(read()) - } - - read(); - const u = unicodeEscape(); - switch (u) { - case '$': - case '_': - case '\u200C': - case '\u200D': - break - - default: - if (!util.isIdContinueChar(u)) { - throw invalidIdentifier() - } - - break - } - - buffer += u; - lexState = 'identifierName'; - }, - - sign () { - switch (c) { - case '.': - buffer = read(); - lexState = 'decimalPointLeading'; - return - - case '0': - buffer = read(); - lexState = 'zero'; - return - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - buffer = read(); - lexState = 'decimalInteger'; - return - - case 'I': - read(); - literal('nfinity'); - return newToken('numeric', sign * Infinity) - - case 'N': - read(); - literal('aN'); - return newToken('numeric', NaN) - } - - throw invalidChar(read()) - }, - - zero () { - switch (c) { - case '.': - buffer += read(); - lexState = 'decimalPoint'; - return - - case 'e': - case 'E': - buffer += read(); - lexState = 'decimalExponent'; - return - - case 'x': - case 'X': - buffer += read(); - lexState = 'hexadecimal'; - return - } - - return newToken('numeric', sign * 0) - }, - - decimalInteger () { - switch (c) { - case '.': - buffer += read(); - lexState = 'decimalPoint'; - return - - case 'e': - case 'E': - buffer += read(); - lexState = 'decimalExponent'; - return - } - - if (util.isDigit(c)) { - buffer += read(); - return - } - - return newToken('numeric', sign * Number(buffer)) - }, - - decimalPointLeading () { - if (util.isDigit(c)) { - buffer += read(); - lexState = 'decimalFraction'; - return - } - - throw invalidChar(read()) - }, - - decimalPoint () { - switch (c) { - case 'e': - case 'E': - buffer += read(); - lexState = 'decimalExponent'; - return - } - - if (util.isDigit(c)) { - buffer += read(); - lexState = 'decimalFraction'; - return - } - - return newToken('numeric', sign * Number(buffer)) - }, - - decimalFraction () { - switch (c) { - case 'e': - case 'E': - buffer += read(); - lexState = 'decimalExponent'; - return - } - - if (util.isDigit(c)) { - buffer += read(); - return - } - - return newToken('numeric', sign * Number(buffer)) - }, - - decimalExponent () { - switch (c) { - case '+': - case '-': - buffer += read(); - lexState = 'decimalExponentSign'; - return - } - - if (util.isDigit(c)) { - buffer += read(); - lexState = 'decimalExponentInteger'; - return - } - - throw invalidChar(read()) - }, - - decimalExponentSign () { - if (util.isDigit(c)) { - buffer += read(); - lexState = 'decimalExponentInteger'; - return - } - - throw invalidChar(read()) - }, - - decimalExponentInteger () { - if (util.isDigit(c)) { - buffer += read(); - return - } - - return newToken('numeric', sign * Number(buffer)) - }, - - hexadecimal () { - if (util.isHexDigit(c)) { - buffer += read(); - lexState = 'hexadecimalInteger'; - return - } - - throw invalidChar(read()) - }, - - hexadecimalInteger () { - if (util.isHexDigit(c)) { - buffer += read(); - return - } - - return newToken('numeric', sign * Number(buffer)) - }, - - string () { - switch (c) { - case '\\': - read(); - buffer += escape(); - return - - case '"': - if (doubleQuote) { - read(); - return newToken('string', buffer) - } - - buffer += read(); - return - - case "'": - if (!doubleQuote) { - read(); - return newToken('string', buffer) - } - - buffer += read(); - return - - case '\n': - case '\r': - throw invalidChar(read()) - - case '\u2028': - case '\u2029': - separatorChar(c); - break - - case undefined: - throw invalidChar(read()) - } - - buffer += read(); - }, - - start () { - switch (c) { - case '{': - case '[': - return newToken('punctuator', read()) - - // This code is unreachable since the default lexState handles eof. - // case undefined: - // return newToken('eof') - } - - lexState = 'value'; - }, - - beforePropertyName () { - switch (c) { - case '$': - case '_': - buffer = read(); - lexState = 'identifierName'; - return - - case '\\': - read(); - lexState = 'identifierNameStartEscape'; - return - - case '}': - return newToken('punctuator', read()) - - case '"': - case "'": - doubleQuote = (read() === '"'); - lexState = 'string'; - return - } - - if (util.isIdStartChar(c)) { - buffer += read(); - lexState = 'identifierName'; - return - } - - throw invalidChar(read()) - }, - - afterPropertyName () { - if (c === ':') { - return newToken('punctuator', read()) - } - - throw invalidChar(read()) - }, - - beforePropertyValue () { - lexState = 'value'; - }, - - afterPropertyValue () { - switch (c) { - case ',': - case '}': - return newToken('punctuator', read()) - } - - throw invalidChar(read()) - }, - - beforeArrayValue () { - if (c === ']') { - return newToken('punctuator', read()) - } - - lexState = 'value'; - }, - - afterArrayValue () { - switch (c) { - case ',': - case ']': - return newToken('punctuator', read()) - } - - throw invalidChar(read()) - }, - - end () { - // This code is unreachable since it's handled by the default lexState. - // if (c === undefined) { - // read() - // return newToken('eof') - // } - - throw invalidChar(read()) - }, -}; - -function newToken (type, value) { - return { - type, - value, - line, - column, - } -} - -function literal (s) { - for (const c of s) { - const p = peek(); - - if (p !== c) { - throw invalidChar(read()) - } - - read(); - } -} - -function escape () { - const c = peek(); - switch (c) { - case 'b': - read(); - return '\b' - - case 'f': - read(); - return '\f' - - case 'n': - read(); - return '\n' - - case 'r': - read(); - return '\r' - - case 't': - read(); - return '\t' - - case 'v': - read(); - return '\v' - - case '0': - read(); - if (util.isDigit(peek())) { - throw invalidChar(read()) - } - - return '\0' - - case 'x': - read(); - return hexEscape() - - case 'u': - read(); - return unicodeEscape() - - case '\n': - case '\u2028': - case '\u2029': - read(); - return '' - - case '\r': - read(); - if (peek() === '\n') { - read(); - } - - return '' - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - throw invalidChar(read()) - - case undefined: - throw invalidChar(read()) - } - - return read() -} - -function hexEscape () { - let buffer = ''; - let c = peek(); - - if (!util.isHexDigit(c)) { - throw invalidChar(read()) - } - - buffer += read(); - - c = peek(); - if (!util.isHexDigit(c)) { - throw invalidChar(read()) - } - - buffer += read(); - - return String.fromCodePoint(parseInt(buffer, 16)) -} - -function unicodeEscape () { - let buffer = ''; - let count = 4; - - while (count-- > 0) { - const c = peek(); - if (!util.isHexDigit(c)) { - throw invalidChar(read()) - } - - buffer += read(); - } - - return String.fromCodePoint(parseInt(buffer, 16)) -} - -const parseStates = { - start () { - if (token.type === 'eof') { - throw invalidEOF() - } - - push$1(); - }, - - beforePropertyName () { - switch (token.type) { - case 'identifier': - case 'string': - key = token.value; - parseState = 'afterPropertyName'; - return - - case 'punctuator': - // This code is unreachable since it's handled by the lexState. - // if (token.value !== '}') { - // throw invalidToken() - // } - - pop(); - return - - case 'eof': - throw invalidEOF() - } - - // This code is unreachable since it's handled by the lexState. - // throw invalidToken() - }, - - afterPropertyName () { - // This code is unreachable since it's handled by the lexState. - // if (token.type !== 'punctuator' || token.value !== ':') { - // throw invalidToken() - // } - - if (token.type === 'eof') { - throw invalidEOF() - } - - parseState = 'beforePropertyValue'; - }, - - beforePropertyValue () { - if (token.type === 'eof') { - throw invalidEOF() - } - - push$1(); - }, - - beforeArrayValue () { - if (token.type === 'eof') { - throw invalidEOF() - } - - if (token.type === 'punctuator' && token.value === ']') { - pop(); - return - } - - push$1(); - }, - - afterPropertyValue () { - // This code is unreachable since it's handled by the lexState. - // if (token.type !== 'punctuator') { - // throw invalidToken() - // } - - if (token.type === 'eof') { - throw invalidEOF() - } - - switch (token.value) { - case ',': - parseState = 'beforePropertyName'; - return - - case '}': - pop(); - } - - // This code is unreachable since it's handled by the lexState. - // throw invalidToken() - }, - - afterArrayValue () { - // This code is unreachable since it's handled by the lexState. - // if (token.type !== 'punctuator') { - // throw invalidToken() - // } - - if (token.type === 'eof') { - throw invalidEOF() - } - - switch (token.value) { - case ',': - parseState = 'beforeArrayValue'; - return - - case ']': - pop(); - } - - // This code is unreachable since it's handled by the lexState. - // throw invalidToken() - }, - - end () { - // This code is unreachable since it's handled by the lexState. - // if (token.type !== 'eof') { - // throw invalidToken() - // } - }, -}; - -function push$1 () { - let value; - - switch (token.type) { - case 'punctuator': - switch (token.value) { - case '{': - value = {}; - break - - case '[': - value = []; - break - } - - break - - case 'null': - case 'boolean': - case 'numeric': - case 'string': - value = token.value; - break - - // This code is unreachable. - // default: - // throw invalidToken() - } - - if (root$1 === undefined) { - root$1 = value; - } else { - const parent = stack[stack.length - 1]; - if (Array.isArray(parent)) { - parent.push(value); - } else { - parent[key] = value; - } - } - - if (value !== null && typeof value === 'object') { - stack.push(value); - - if (Array.isArray(value)) { - parseState = 'beforeArrayValue'; - } else { - parseState = 'beforePropertyName'; - } - } else { - const current = stack[stack.length - 1]; - if (current == null) { - parseState = 'end'; - } else if (Array.isArray(current)) { - parseState = 'afterArrayValue'; - } else { - parseState = 'afterPropertyValue'; - } - } -} - -function pop () { - stack.pop(); - - const current = stack[stack.length - 1]; - if (current == null) { - parseState = 'end'; - } else if (Array.isArray(current)) { - parseState = 'afterArrayValue'; - } else { - parseState = 'afterPropertyValue'; - } -} - -// This code is unreachable. -// function invalidParseState () { -// return new Error(`JSON5: invalid parse state '${parseState}'`) -// } - -// This code is unreachable. -// function invalidLexState (state) { -// return new Error(`JSON5: invalid lex state '${state}'`) -// } - -function invalidChar (c) { - if (c === undefined) { - return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) - } - - return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`) -} - -function invalidEOF () { - return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) -} - -// This code is unreachable. -// function invalidToken () { -// if (token.type === 'eof') { -// return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) -// } - -// const c = String.fromCodePoint(token.value.codePointAt(0)) -// return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`) -// } - -function invalidIdentifier () { - column -= 5; - return syntaxError(`JSON5: invalid identifier character at ${line}:${column}`) -} - -function separatorChar (c) { - console.warn(`JSON5: '${formatChar(c)}' in strings is not valid ECMAScript; consider escaping`); -} - -function formatChar (c) { - const replacements = { - "'": "\\'", - '"': '\\"', - '\\': '\\\\', - '\b': '\\b', - '\f': '\\f', - '\n': '\\n', - '\r': '\\r', - '\t': '\\t', - '\v': '\\v', - '\0': '\\0', - '\u2028': '\\u2028', - '\u2029': '\\u2029', - }; - - if (replacements[c]) { - return replacements[c] - } - - if (c < ' ') { - const hexString = c.charCodeAt(0).toString(16); - return '\\x' + ('00' + hexString).substring(hexString.length) - } - - return c -} - -function syntaxError (message) { - const err = new SyntaxError(message); - err.lineNumber = line; - err.columnNumber = column; - return err -} - -var stringify = function stringify (value, replacer, space) { - const stack = []; - let indent = ''; - let propertyList; - let replacerFunc; - let gap = ''; - let quote; - - if ( - replacer != null && - typeof replacer === 'object' && - !Array.isArray(replacer) - ) { - space = replacer.space; - quote = replacer.quote; - replacer = replacer.replacer; - } - - if (typeof replacer === 'function') { - replacerFunc = replacer; - } else if (Array.isArray(replacer)) { - propertyList = []; - for (const v of replacer) { - let item; - - if (typeof v === 'string') { - item = v; - } else if ( - typeof v === 'number' || - v instanceof String || - v instanceof Number - ) { - item = String(v); - } - - if (item !== undefined && propertyList.indexOf(item) < 0) { - propertyList.push(item); - } - } - } - - if (space instanceof Number) { - space = Number(space); - } else if (space instanceof String) { - space = String(space); - } - - if (typeof space === 'number') { - if (space > 0) { - space = Math.min(10, Math.floor(space)); - gap = ' '.substr(0, space); - } - } else if (typeof space === 'string') { - gap = space.substr(0, 10); - } - - return serializeProperty('', {'': value}) - - function serializeProperty (key, holder) { - let value = holder[key]; - if (value != null) { - if (typeof value.toJSON5 === 'function') { - value = value.toJSON5(key); - } else if (typeof value.toJSON === 'function') { - value = value.toJSON(key); - } - } - - if (replacerFunc) { - value = replacerFunc.call(holder, key, value); - } - - if (value instanceof Number) { - value = Number(value); - } else if (value instanceof String) { - value = String(value); - } else if (value instanceof Boolean) { - value = value.valueOf(); - } - - switch (value) { - case null: return 'null' - case true: return 'true' - case false: return 'false' - } - - if (typeof value === 'string') { - return quoteString(value) - } - - if (typeof value === 'number') { - return String(value) - } - - if (typeof value === 'object') { - return Array.isArray(value) ? serializeArray(value) : serializeObject(value) - } - - return undefined - } - - function quoteString (value) { - const quotes = { - "'": 0.1, - '"': 0.2, - }; - - const replacements = { - "'": "\\'", - '"': '\\"', - '\\': '\\\\', - '\b': '\\b', - '\f': '\\f', - '\n': '\\n', - '\r': '\\r', - '\t': '\\t', - '\v': '\\v', - '\0': '\\0', - '\u2028': '\\u2028', - '\u2029': '\\u2029', - }; - - let product = ''; - - for (let i = 0; i < value.length; i++) { - const c = value[i]; - switch (c) { - case "'": - case '"': - quotes[c]++; - product += c; - continue - - case '\0': - if (util.isDigit(value[i + 1])) { - product += '\\x00'; - continue - } - } - - if (replacements[c]) { - product += replacements[c]; - continue - } - - if (c < ' ') { - let hexString = c.charCodeAt(0).toString(16); - product += '\\x' + ('00' + hexString).substring(hexString.length); - continue - } - - product += c; - } - - const quoteChar = quote || Object.keys(quotes).reduce((a, b) => (quotes[a] < quotes[b]) ? a : b); - - product = product.replace(new RegExp(quoteChar, 'g'), replacements[quoteChar]); - - return quoteChar + product + quoteChar - } - - function serializeObject (value) { - if (stack.indexOf(value) >= 0) { - throw TypeError('Converting circular structure to JSON5') - } - - stack.push(value); - - let stepback = indent; - indent = indent + gap; - - let keys = propertyList || Object.keys(value); - let partial = []; - for (const key of keys) { - const propertyString = serializeProperty(key, value); - if (propertyString !== undefined) { - let member = serializeKey(key) + ':'; - if (gap !== '') { - member += ' '; - } - member += propertyString; - partial.push(member); - } - } - - let final; - if (partial.length === 0) { - final = '{}'; - } else { - let properties; - if (gap === '') { - properties = partial.join(','); - final = '{' + properties + '}'; - } else { - let separator = ',\n' + indent; - properties = partial.join(separator); - final = '{\n' + indent + properties + ',\n' + stepback + '}'; - } - } - - stack.pop(); - indent = stepback; - return final - } - - function serializeKey (key) { - if (key.length === 0) { - return quoteString(key) - } - - const firstChar = String.fromCodePoint(key.codePointAt(0)); - if (!util.isIdStartChar(firstChar)) { - return quoteString(key) - } - - for (let i = firstChar.length; i < key.length; i++) { - if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) { - return quoteString(key) - } - } - - return key - } - - function serializeArray (value) { - if (stack.indexOf(value) >= 0) { - throw TypeError('Converting circular structure to JSON5') - } - - stack.push(value); - - let stepback = indent; - indent = indent + gap; - - let partial = []; - for (let i = 0; i < value.length; i++) { - const propertyString = serializeProperty(String(i), value); - partial.push((propertyString !== undefined) ? propertyString : 'null'); - } - - let final; - if (partial.length === 0) { - final = '[]'; - } else { - if (gap === '') { - let properties = partial.join(','); - final = '[' + properties + ']'; - } else { - let separator = ',\n' + indent; - let properties = partial.join(separator); - final = '[\n' + indent + properties + ',\n' + stepback + ']'; - } - } - - stack.pop(); - indent = stepback; - return final - } -}; - -const JSON5 = { - parse: parse$1, - stringify, -}; - -var lib = JSON5; - -/** - * @typedef Option - * @property {'boolean'|'string'} [type='string'] - * @property {string} long - * @property {string} description - * @property {string} [value] - * @property {string} [short] - * @property {boolean|string} [default=''] - * @property {boolean} [truelike=false] - */ - -/** @type {Option[]} */ -const schema = [ - { - long: 'help', - description: 'output usage information', - short: 'h', - type: 'boolean', - default: false - }, - { - long: 'version', - description: 'output version number', - short: 'v', - type: 'boolean', - default: false - }, - { - long: 'output', - description: 'specify output location', - short: 'o', - value: '[path]' - }, - { - long: 'rc-path', - description: 'specify configuration file', - short: 'r', - type: 'string', - value: '' - }, - { - long: 'ignore-path', - description: 'specify ignore file', - short: 'i', - type: 'string', - value: '' - }, - { - long: 'setting', - description: 'specify settings', - short: 's', - type: 'string', - value: '' - }, - { - long: 'ext', - description: 'specify extensions', - short: 'e', - type: 'string', - value: '' - }, - { - long: 'use', - description: 'use plugins', - short: 'u', - type: 'string', - value: '' - }, - { - long: 'watch', - description: 'watch for changes and reprocess', - short: 'w', - type: 'boolean', - default: false - }, - { - long: 'quiet', - description: 'output only warnings and errors', - short: 'q', - type: 'boolean', - default: false - }, - { - long: 'silent', - description: 'output only errors', - short: 'S', - type: 'boolean', - default: false - }, - { - long: 'frail', - description: 'exit with 1 on warnings', - short: 'f', - type: 'boolean', - default: false - }, - { - long: 'tree', - description: 'specify input and output as syntax tree', - short: 't', - type: 'boolean', - default: false - }, - { - long: 'report', - description: 'specify reporter', - type: 'string', - value: '' - }, - { - long: 'file-path', - description: 'specify path to process as', - type: 'string', - value: '' - }, - { - long: 'ignore-path-resolve-from', - description: 'resolve patterns in `ignore-path` from its directory or cwd', - type: 'string', - value: 'dir|cwd', - default: 'dir' - }, - { - long: 'ignore-pattern', - description: 'specify ignore patterns', - type: 'string', - value: '' - }, - { - long: 'silently-ignore', - description: 'do not fail when given ignored files', - type: 'boolean' - }, - { - long: 'tree-in', - description: 'specify input as syntax tree', - type: 'boolean' - }, - { - long: 'tree-out', - description: 'output syntax tree', - type: 'boolean' - }, - { - long: 'inspect', - description: 'output formatted syntax tree', - type: 'boolean' - }, - { - long: 'stdout', - description: 'specify writing to stdout', - type: 'boolean', - truelike: true - }, - { - long: 'color', - description: 'specify color in report', - type: 'boolean', - default: true - }, - { - long: 'config', - description: 'search for configuration files', - type: 'boolean', - default: true - }, - { - long: 'ignore', - description: 'search for ignore files', - type: 'boolean', - default: true - } -]; - -/** - * @typedef {import('unified-engine').Options} EngineOptions - * @typedef {import('./schema.js').Option} Option - * - * @typedef {Required< - * Pick< - * EngineOptions, - * | 'extensions' - * | 'ignoreName' - * | 'packageField' - * | 'pluginPrefix' - * | 'processor' - * | 'rcName' - * > - * >} RequiredEngineOptions - * - * @typedef ArgsOptionsFields - * @property {string} name - * Name of executable - * @property {string} description - * Description of executable - * @property {string} version - * Version (semver) of executable - * - * @typedef {RequiredEngineOptions & Pick & ArgsOptionsFields} Options - */ - -const own$7 = {}.hasOwnProperty; - -/** - * Schema for `minimist`. - */ -const minischema = { - unknown: handleUnknownArgument, - /** @type {Record} */ - default: {}, - /** @type {Record} */ - alias: {}, - /** @type {string[]} */ - string: [], - /** @type {string[]} */ - boolean: [] -}; - -let index = -1; -while (++index < schema.length) { - addEach(schema[index]); -} - -/** - * Parse CLI options. - * - * @param {string[]} flags - * @param {Options} configuration - */ -function options(flags, configuration) { - const extension = configuration.extensions[0]; - const name = configuration.name; - const config = toCamelCase(minimist(flags, minischema)); - let index = -1; - - while (++index < schema.length) { - const option = schema[index]; - if (option.type === 'string' && config[option.long] === '') { - throw fault('Missing value:%s', inspect(option).join(' ')) - } - } - - const ext = commaSeparated(/** @type {string} */ (config.ext)); - const report = reporter(/** @type {string} */ (config.report)); - const help = [ - inspectAll(schema), - '', - 'Examples:', - '', - ' # Process `input.' + extension + '`', - ' $ ' + name + ' input.' + extension + ' -o output.' + extension, - '', - ' # Pipe', - ' $ ' + name + ' < input.' + extension + ' > output.' + extension, - '', - ' # Rewrite all applicable files', - ' $ ' + name + ' . -o' - ].join('\n'); - - return { - helpMessage: help, - cwd: configuration.cwd, - processor: configuration.processor, - help: config.help, - version: config.version, - files: config._, - filePath: config.filePath, - watch: config.watch, - extensions: ext.length === 0 ? configuration.extensions : ext, - output: config.output, - out: config.stdout, - tree: config.tree, - treeIn: config.treeIn, - treeOut: config.treeOut, - inspect: config.inspect, - rcName: configuration.rcName, - packageField: configuration.packageField, - rcPath: config.rcPath, - detectConfig: config.config, - settings: /** @type {Record} */ ( - settings(/** @type {string} */ (config.setting)) - ), - ignoreName: configuration.ignoreName, - ignorePath: config.ignorePath, - ignorePathResolveFrom: config.ignorePathResolveFrom, - ignorePatterns: commaSeparated( - /** @type {string} */ (config.ignorePattern) - ), - silentlyIgnore: config.silentlyIgnore, - detectIgnore: config.ignore, - pluginPrefix: configuration.pluginPrefix, - plugins: plugins$1(/** @type {string} */ (config.use)), - reporter: report[0], - reporterOptions: report[1], - color: config.color, - silent: config.silent, - quiet: config.quiet, - frail: config.frail - } -} - -/** - * @param {Option} option - */ -function addEach(option) { - const value = option.default; - - minischema.default[option.long] = value === undefined ? null : value; - - if (option.type && option.type in minischema) { - minischema[option.type].push(option.long); - } - - if (option.short) { - minischema.alias[option.short] = option.long; - } -} - -/** - * Parse `extensions`. - * - * @param {string[]|string|null|undefined} value - * @returns {string[]} - */ -function commaSeparated(value) { - return flatten(normalize(value).map((d) => splitList(d))) -} - -/** - * Parse `plugins`. - * - * @param {string[]|string|null|undefined} value - * @returns {Record|undefined>} - */ -function plugins$1(value) { - const normalized = normalize(value).map((d) => splitOptions(d)); - let index = -1; - /** @type {Record|undefined>} */ - const result = {}; - - while (++index < normalized.length) { - const value = normalized[index]; - result[value[0]] = value[1] ? parseConfig(value[1], {}) : undefined; - } - - return result -} - -/** - * Parse `reporter`: only one is accepted. - * - * @param {string[]|string|null|undefined} value - * @returns {[string|undefined, Record|undefined]} - */ -function reporter(value) { - const all = normalize(value) - .map((d) => splitOptions(d)) - .map( - /** - * @returns {[string, Record|undefined]} - */ - (value) => [value[0], value[1] ? parseConfig(value[1], {}) : undefined] - ); - - return all[all.length - 1] || [] -} - -/** - * Parse `settings`. - * - * @param {string[]|string|null|undefined} value - * @returns {Record} - */ -function settings(value) { - const normalized = normalize(value); - let index = -1; - /** @type {Record} */ - const cache = {}; - - while (++index < normalized.length) { - parseConfig(normalized[index], cache); - } - - return cache -} - -/** - * Parse configuration. - * - * @param {string} value - * @param {Record} cache - * @returns {Record} - */ -function parseConfig(value, cache) { - /** @type {Record} */ - let flags; - /** @type {string} */ - let flag; - - try { - flags = toCamelCase(parseJSON(value)); - } catch (error) { - throw fault( - 'Cannot parse `%s` as JSON: %s', - value, - // Fix position - error.message.replace(/at(?= position)/, 'around') - ) - } - - for (flag in flags) { - if (own$7.call(flags, flag)) { - cache[flag] = flags[flag]; - } - } - - return cache -} - -/** - * Handle an unknown flag. - * - * @param {string} flag - * @returns {boolean} - */ -function handleUnknownArgument(flag) { - // Not a glob. - if (flag.charAt(0) === '-') { - // Long options, always unknown. - if (flag.charAt(1) === '-') { - throw fault( - 'Unknown option `%s`, expected:\n%s', - flag, - inspectAll(schema) - ) - } - - // Short options, can be grouped. - const found = flag.slice(1).split(''); - const known = schema.filter((d) => d.short); - const knownKeys = new Set(known.map((d) => d.short)); - let index = -1; - - while (++index < found.length) { - const key = found[index]; - if (!knownKeys.has(key)) { - throw fault( - 'Unknown short option `-%s`, expected:\n%s', - key, - inspectAll(known) - ) - } - } - } - - return true -} - -/** - * Inspect all `options`. - * - * @param {Option[]} options - * @returns {string} - */ -function inspectAll(options) { - return textTable(options.map((d) => inspect(d))) -} - -/** - * Inspect one `option`. - * - * @param {Option} option - * @returns {string[]} - */ -function inspect(option) { - let description = option.description; - let long = option.long; - - if (option.default === true || option.truelike) { - description += ' (on by default)'; - long = '[no-]' + long; - } - - return [ - '', - option.short ? '-' + option.short : '', - '--' + long + (option.value ? ' ' + option.value : ''), - description - ] -} - -/** - * Normalize `value`. - * - * @param {string[]|string|null|undefined} value - * @returns {string[]} - */ -function normalize(value) { - if (!value) { - return [] - } - - if (typeof value === 'string') { - return [value] - } - - return flatten(value.map((d) => normalize(d))) -} - -/** - * Flatten `values`. - * - * @param {string|string[]|string[][]} values - * @returns {string[]} - */ -function flatten(values) { - // @ts-expect-error: TS is wrong. - return values.flat() -} - -/** - * @param {string} value - * @returns {string[]} - */ -function splitOptions(value) { - return value.split('=') -} - -/** - * @param {string} value - * @returns {string[]} - */ -function splitList(value) { - return value.split(',') -} - -/** - * Transform the keys on an object to camel-case, recursivly. - * - * @param {Record} object - * @returns {Record} - */ -function toCamelCase(object) { - /** @type {Record} */ - const result = {}; - /** @type {string} */ - let key; - - for (key in object) { - if (own$7.call(object, key)) { - let value = object[key]; - - if (value && typeof value === 'object' && !Array.isArray(value)) { - // @ts-expect-error: looks like an object. - value = toCamelCase(value); - } - - result[camelcase(key)] = value; - } - } - - return result -} - -/** - * Parse a (lazy?) JSON config. - * - * @param {string} value - * @returns {Record} - */ -function parseJSON(value) { - return lib.parse('{' + value + '}') -} - -/** - * @typedef {import('unified-engine').Options} EngineOptions - * @typedef {import('unified-engine').Context} EngineContext - * @typedef {import('unified-engine').Callback} EngineCallback - * @typedef {import('./options.js').Options} Options - */ - -// Fake TTY stream. -const ttyStream = Object.assign(new stream.Readable(), {isTTY: true}); - -// Exit, lazily, with the correct exit status code. -let exitStatus = 0; - -process$2.on('exit', onexit); - -// Handle uncaught errors, such as from unexpected async behaviour. -process$2.on('uncaughtException', fail); - -/** - * Start the CLI. - * - * @param {Options} cliConfig - */ -function args(cliConfig) { - /** @type {EngineOptions & {help: boolean, helpMessage: string, watch: boolean, version: boolean}} */ - let config; - /** @type {chokidar.FSWatcher|undefined} */ - let watcher; - /** @type {boolean|string|undefined} */ - let output; - - try { - // @ts-expect-error: Close enough. - config = options(process$2.argv.slice(2), cliConfig); - } catch (error) { - return fail(error, true) - } - - if (config.help) { - process$2.stdout.write( - [ - 'Usage: ' + cliConfig.name + ' [options] [path | glob ...]', - '', - ' ' + cliConfig.description, - '', - 'Options:', - '', - config.helpMessage, - '' - ].join('\n'), - noop$1 - ); - - return - } - - if (config.version) { - process$2.stdout.write(cliConfig.version + '\n', noop$1); - - return - } - - // Modify `config` for watching. - if (config.watch) { - output = config.output; - - // Do not read from stdin(4). - config.streamIn = ttyStream; - - // Do not write to stdout(4). - config.out = false; - - process$2.stderr.write( - source$1.bold('Watching...') + ' (press CTRL+C to exit)\n', - noop$1 - ); - - // Prevent infinite loop if set to regeneration. - if (output === true) { - config.output = false; - - process$2.stderr.write( - source$1.yellow('Note') + ': Ignoring `--output` until exit.\n', - noop$1 - ); - } - } - - // Initial run. - engine(config, done); - - /** - * Handle complete run. - * - * @type {EngineCallback} - */ - function done(error, code, context) { - if (error) { - clean(); - fail(error); - } else { - exitStatus = code || 0; - - if (config.watch && !watcher && context) { - subscribe(context); - } - } - } - - // Clean the watcher. - function clean() { - if (watcher) { - watcher.close(); - watcher = undefined; - } - } - - /** - * Subscribe a chokidar watcher to all processed files. - * - * @param {EngineContext} context - */ - function subscribe(context) { - watcher = chokidar - // @ts-expect-error: `fileSet` is available. - .watch(context.fileSet.origins, {cwd: config.cwd, ignoreInitial: true}) - .on('error', done) - .on('change', (filePath) => { - config.files = [filePath]; - engine(config, done); - }); - - process$2.on('SIGINT', onsigint); - - /** - * Handle a SIGINT. - */ - function onsigint() { - // Hide the `^C` in terminal. - process$2.stderr.write('\n', noop$1); - - clean(); - - // Do another process if `output` specified regeneration. - if (output === true) { - config.output = output; - config.watch = false; - engine(config, done); - } - } - } -} - -/** - * Print an error, optionally with stack. - * - * @param {Error} error - * @param {boolean} [pretty=false] - */ -function fail(error, pretty) { - // Old versions of Node - /* c8 ignore next 1 */ - const message = String((pretty ? error : error.stack) || error); - - exitStatus = 1; - - process$2.stderr.write(message.trim() + '\n', noop$1); -} - -function onexit() { - /* eslint-disable unicorn/no-process-exit */ - process$2.exit(exitStatus); - /* eslint-enable unicorn/no-process-exit */ -} - -function noop$1() {} - -var require$$0 = [ - "md", - "markdown", - "mdown", - "mkdn", - "mkd", - "mdwn", - "mkdown", - "ron" -]; - -var markdownExtensions = require$$0; - -/** - * Throw a given error. - * - * @param {Error | null | undefined} [error] - */ -function bail(error) { - if (error) { - throw error - } -} - -var hasOwn = Object.prototype.hasOwnProperty; -var toStr = Object.prototype.toString; -var defineProperty = Object.defineProperty; -var gOPD = Object.getOwnPropertyDescriptor; - -var isArray = function isArray(arr) { - if (typeof Array.isArray === 'function') { - return Array.isArray(arr); - } - - return toStr.call(arr) === '[object Array]'; -}; - -var isPlainObject = function isPlainObject(obj) { - if (!obj || toStr.call(obj) !== '[object Object]') { - return false; - } - - var hasOwnConstructor = hasOwn.call(obj, 'constructor'); - var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); - // Not own constructor property must be Object - if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { - return false; - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - var key; - for (key in obj) { /**/ } - - return typeof key === 'undefined' || hasOwn.call(obj, key); -}; - -// If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target -var setProperty = function setProperty(target, options) { - if (defineProperty && options.name === '__proto__') { - defineProperty(target, options.name, { - enumerable: true, - configurable: true, - value: options.newValue, - writable: true - }); - } else { - target[options.name] = options.newValue; - } -}; - -// Return undefined instead of __proto__ if '__proto__' is not an own property -var getProperty = function getProperty(obj, name) { - if (name === '__proto__') { - if (!hasOwn.call(obj, name)) { - return void 0; - } else if (gOPD) { - // In early versions of node, obj['__proto__'] is buggy when obj has - // __proto__ as an own property. Object.getOwnPropertyDescriptor() works. - return gOPD(obj, name).value; - } - } - - return obj[name]; -}; - -var extend = function extend() { - var options, name, src, copy, copyIsArray, clone; - var target = arguments[0]; - var i = 1; - var length = arguments.length; - var deep = false; - - // Handle a deep copy situation - if (typeof target === 'boolean') { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - if (target == null || (typeof target !== 'object' && typeof target !== 'function')) { - target = {}; - } - - for (; i < length; ++i) { - options = arguments[i]; - // Only deal with non-null/undefined values - if (options != null) { - // Extend the base object - for (name in options) { - src = getProperty(target, name); - copy = getProperty(options, name); - - // Prevent never-ending loop - if (target !== copy) { - // Recurse if we're merging plain objects or arrays - if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { - if (copyIsArray) { - copyIsArray = false; - clone = src && isArray(src) ? src : []; - } else { - clone = src && isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - setProperty(target, { name: name, newValue: extend(deep, clone, copy) }); - - // Don't bring in undefined values - } else if (typeof copy !== 'undefined') { - setProperty(target, { name: name, newValue: copy }); - } - } - } - } - } - - // Return the modified object - return target; -}; - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('vfile').VFileCompatible} VFileCompatible - * @typedef {import('vfile').VFileValue} VFileValue - * @typedef {import('..').Processor} Processor - * @typedef {import('..').Plugin} Plugin - * @typedef {import('..').Preset} Preset - * @typedef {import('..').Pluggable} Pluggable - * @typedef {import('..').PluggableList} PluggableList - * @typedef {import('..').Transformer} Transformer - * @typedef {import('..').Parser} Parser - * @typedef {import('..').Compiler} Compiler - * @typedef {import('..').RunCallback} RunCallback - * @typedef {import('..').ProcessCallback} ProcessCallback - * - * @typedef Context - * @property {Node} tree - * @property {VFile} file - */ - -// Expose a frozen processor. -const unified = base().freeze(); - -const own$6 = {}.hasOwnProperty; - -// Function to create the first processor. -/** - * @returns {Processor} - */ -function base() { - const transformers = trough(); - /** @type {Processor['attachers']} */ - const attachers = []; - /** @type {Record} */ - let namespace = {}; - /** @type {boolean|undefined} */ - let frozen; - let freezeIndex = -1; - - // Data management. - // @ts-expect-error: overloads are handled. - processor.data = data; - processor.Parser = undefined; - processor.Compiler = undefined; - - // Lock. - processor.freeze = freeze; - - // Plugins. - processor.attachers = attachers; - // @ts-expect-error: overloads are handled. - processor.use = use; - - // API. - processor.parse = parse; - processor.stringify = stringify; - // @ts-expect-error: overloads are handled. - processor.run = run; - processor.runSync = runSync; - // @ts-expect-error: overloads are handled. - processor.process = process; - processor.processSync = processSync; - - // Expose. - return processor - - // Create a new processor based on the processor in the current scope. - /** @type {Processor} */ - function processor() { - const destination = base(); - let index = -1; - - while (++index < attachers.length) { - destination.use(...attachers[index]); - } - - destination.data(extend(true, {}, namespace)); - - return destination - } - - /** - * @param {string|Record} [key] - * @param {unknown} [value] - * @returns {unknown} - */ - function data(key, value) { - if (typeof key === 'string') { - // Set `key`. - if (arguments.length === 2) { - assertUnfrozen('data', frozen); - namespace[key] = value; - return processor - } - - // Get `key`. - return (own$6.call(namespace, key) && namespace[key]) || null - } - - // Set space. - if (key) { - assertUnfrozen('data', frozen); - namespace = key; - return processor - } - - // Get space. - return namespace - } - - /** @type {Processor['freeze']} */ - function freeze() { - if (frozen) { - return processor - } - - while (++freezeIndex < attachers.length) { - const [attacher, ...options] = attachers[freezeIndex]; - - if (options[0] === false) { - continue - } - - if (options[0] === true) { - options[1] = undefined; - } - - /** @type {Transformer|void} */ - const transformer = attacher.call(processor, ...options); - - if (typeof transformer === 'function') { - transformers.use(transformer); - } - } - - frozen = true; - freezeIndex = Number.POSITIVE_INFINITY; - - return processor - } - - /** - * @param {Pluggable|null|undefined} [value] - * @param {...unknown} options - * @returns {Processor} - */ - function use(value, ...options) { - /** @type {Record|undefined} */ - let settings; - - assertUnfrozen('use', frozen); - - if (value === null || value === undefined) ; else if (typeof value === 'function') { - addPlugin(value, ...options); - } else if (typeof value === 'object') { - if (Array.isArray(value)) { - addList(value); - } else { - addPreset(value); - } - } else { - throw new TypeError('Expected usable value, not `' + value + '`') - } - - if (settings) { - namespace.settings = Object.assign(namespace.settings || {}, settings); - } - - return processor - - /** - * @param {import('..').Pluggable} value - * @returns {void} - */ - function add(value) { - if (typeof value === 'function') { - addPlugin(value); - } else if (typeof value === 'object') { - if (Array.isArray(value)) { - const [plugin, ...options] = value; - addPlugin(plugin, ...options); - } else { - addPreset(value); - } - } else { - throw new TypeError('Expected usable value, not `' + value + '`') - } - } - - /** - * @param {Preset} result - * @returns {void} - */ - function addPreset(result) { - addList(result.plugins); - - if (result.settings) { - settings = Object.assign(settings || {}, result.settings); - } - } - - /** - * @param {PluggableList|null|undefined} [plugins] - * @returns {void} - */ - function addList(plugins) { - let index = -1; - - if (plugins === null || plugins === undefined) ; else if (Array.isArray(plugins)) { - while (++index < plugins.length) { - const thing = plugins[index]; - add(thing); - } - } else { - throw new TypeError('Expected a list of plugins, not `' + plugins + '`') - } - } - - /** - * @param {Plugin} plugin - * @param {...unknown} [value] - * @returns {void} - */ - function addPlugin(plugin, value) { - let index = -1; - /** @type {Processor['attachers'][number]|undefined} */ - let entry; - - while (++index < attachers.length) { - if (attachers[index][0] === plugin) { - entry = attachers[index]; - break - } - } - - if (entry) { - if (isPlainObject$1(entry[1]) && isPlainObject$1(value)) { - value = extend(true, entry[1], value); - } - - entry[1] = value; - } else { - // @ts-expect-error: fine. - attachers.push([...arguments]); - } - } - } - - /** @type {Processor['parse']} */ - function parse(doc) { - processor.freeze(); - const file = vfile(doc); - const Parser = processor.Parser; - assertParser('parse', Parser); - - if (newable(Parser, 'parse')) { - // @ts-expect-error: `newable` checks this. - return new Parser(String(file), file).parse() - } - - // @ts-expect-error: `newable` checks this. - return Parser(String(file), file) // eslint-disable-line new-cap - } - - /** @type {Processor['stringify']} */ - function stringify(node, doc) { - processor.freeze(); - const file = vfile(doc); - const Compiler = processor.Compiler; - assertCompiler('stringify', Compiler); - assertNode(node); - - if (newable(Compiler, 'compile')) { - // @ts-expect-error: `newable` checks this. - return new Compiler(node, file).compile() - } - - // @ts-expect-error: `newable` checks this. - return Compiler(node, file) // eslint-disable-line new-cap - } - - /** - * @param {Node} node - * @param {VFileCompatible|RunCallback} [doc] - * @param {RunCallback} [callback] - * @returns {Promise|void} - */ - function run(node, doc, callback) { - assertNode(node); - processor.freeze(); - - if (!callback && typeof doc === 'function') { - callback = doc; - doc = undefined; - } - - if (!callback) { - return new Promise(executor) - } - - executor(null, callback); - - /** - * @param {null|((node: Node) => void)} resolve - * @param {(error: Error) => void} reject - * @returns {void} - */ - function executor(resolve, reject) { - // @ts-expect-error: `doc` can’t be a callback anymore, we checked. - transformers.run(node, vfile(doc), done); - - /** - * @param {Error|null} error - * @param {Node} tree - * @param {VFile} file - * @returns {void} - */ - function done(error, tree, file) { - tree = tree || node; - if (error) { - reject(error); - } else if (resolve) { - resolve(tree); - } else { - // @ts-expect-error: `callback` is defined if `resolve` is not. - callback(null, tree, file); - } - } - } - } - - /** @type {Processor['runSync']} */ - function runSync(node, file) { - /** @type {Node|undefined} */ - let result; - /** @type {boolean|undefined} */ - let complete; - - processor.run(node, file, done); - - assertDone('runSync', 'run', complete); - - // @ts-expect-error: we either bailed on an error or have a tree. - return result - - /** - * @param {Error|null} [error] - * @param {Node} [tree] - * @returns {void} - */ - function done(error, tree) { - bail(error); - result = tree; - complete = true; - } - } - - /** - * @param {VFileCompatible} doc - * @param {ProcessCallback} [callback] - * @returns {Promise|undefined} - */ - function process(doc, callback) { - processor.freeze(); - assertParser('process', processor.Parser); - assertCompiler('process', processor.Compiler); - - if (!callback) { - return new Promise(executor) - } - - executor(null, callback); - - /** - * @param {null|((file: VFile) => void)} resolve - * @param {(error?: Error|null|undefined) => void} reject - * @returns {void} - */ - function executor(resolve, reject) { - const file = vfile(doc); - - processor.run(processor.parse(file), file, (error, tree, file) => { - if (error || !tree || !file) { - done(error); - } else { - /** @type {unknown} */ - const result = processor.stringify(tree, file); - - if (result === undefined || result === null) ; else if (looksLikeAVFileValue(result)) { - file.value = result; - } else { - file.result = result; - } - - done(error, file); - } - }); - - /** - * @param {Error|null|undefined} [error] - * @param {VFile|undefined} [file] - * @returns {void} - */ - function done(error, file) { - if (error || !file) { - reject(error); - } else if (resolve) { - resolve(file); - } else { - // @ts-expect-error: `callback` is defined if `resolve` is not. - callback(null, file); - } - } - } - } - - /** @type {Processor['processSync']} */ - function processSync(doc) { - /** @type {boolean|undefined} */ - let complete; - - processor.freeze(); - assertParser('processSync', processor.Parser); - assertCompiler('processSync', processor.Compiler); - - const file = vfile(doc); - - processor.process(file, done); - - assertDone('processSync', 'process', complete); - - return file - - /** - * @param {Error|null|undefined} [error] - * @returns {void} - */ - function done(error) { - complete = true; - bail(error); - } - } -} - -/** - * Check if `value` is a constructor. - * - * @param {unknown} value - * @param {string} name - * @returns {boolean} - */ -function newable(value, name) { - return ( - typeof value === 'function' && - // Prototypes do exist. - // type-coverage:ignore-next-line - value.prototype && - // A function with keys in its prototype is probably a constructor. - // Classes’ prototype methods are not enumerable, so we check if some value - // exists in the prototype. - // type-coverage:ignore-next-line - (keys(value.prototype) || name in value.prototype) - ) -} - -/** - * Check if `value` is an object with keys. - * - * @param {Record} value - * @returns {boolean} - */ -function keys(value) { - /** @type {string} */ - let key; - - for (key in value) { - if (own$6.call(value, key)) { - return true - } - } - - return false -} - -/** - * Assert a parser is available. - * - * @param {string} name - * @param {unknown} value - * @returns {asserts value is Parser} - */ -function assertParser(name, value) { - if (typeof value !== 'function') { - throw new TypeError('Cannot `' + name + '` without `Parser`') - } -} - -/** - * Assert a compiler is available. - * - * @param {string} name - * @param {unknown} value - * @returns {asserts value is Compiler} - */ -function assertCompiler(name, value) { - if (typeof value !== 'function') { - throw new TypeError('Cannot `' + name + '` without `Compiler`') - } -} - -/** - * Assert the processor is not frozen. - * - * @param {string} name - * @param {unknown} frozen - * @returns {asserts frozen is false} - */ -function assertUnfrozen(name, frozen) { - if (frozen) { - throw new Error( - 'Cannot call `' + - name + - '` on a frozen processor.\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.' - ) - } -} - -/** - * Assert `node` is a unist node. - * - * @param {unknown} node - * @returns {asserts node is Node} - */ -function assertNode(node) { - // `isPlainObj` unfortunately uses `any` instead of `unknown`. - // type-coverage:ignore-next-line - if (!isPlainObject$1(node) || typeof node.type !== 'string') { - throw new TypeError('Expected node, got `' + node + '`') - // Fine. - } -} - -/** - * Assert that `complete` is `true`. - * - * @param {string} name - * @param {string} asyncName - * @param {unknown} complete - * @returns {asserts complete is true} - */ -function assertDone(name, asyncName, complete) { - if (!complete) { - throw new Error( - '`' + name + '` finished async. Use `' + asyncName + '` instead' - ) - } -} - -/** - * @param {VFileCompatible} [value] - * @returns {VFile} - */ -function vfile(value) { - return looksLikeAVFile(value) ? value : new VFile(value) -} - -/** - * @param {VFileCompatible} [value] - * @returns {value is VFile} - */ -function looksLikeAVFile(value) { - return Boolean( - value && - typeof value === 'object' && - 'message' in value && - 'messages' in value - ) -} - -/** - * @param {unknown} [value] - * @returns {value is VFileValue} - */ -function looksLikeAVFileValue(value) { - return typeof value === 'string' || isBuffer(value) -} - -/** - * @typedef Options - * @property {boolean} [includeImageAlt=true] - */ - -/** - * Get the text content of a node. - * Prefer the node’s plain-text fields, otherwise serialize its children, - * and if the given value is an array, serialize the nodes in it. - * - * @param {unknown} node - * @param {Options} [options] - * @returns {string} - */ -function toString(node, options) { - var {includeImageAlt = true} = options || {}; - return one(node, includeImageAlt) -} - -/** - * @param {unknown} node - * @param {boolean} includeImageAlt - * @returns {string} - */ -function one(node, includeImageAlt) { - return ( - (node && - typeof node === 'object' && - // @ts-ignore looks like a literal. - (node.value || - // @ts-ignore looks like an image. - (includeImageAlt ? node.alt : '') || - // @ts-ignore looks like a parent. - ('children' in node && all(node.children, includeImageAlt)) || - (Array.isArray(node) && all(node, includeImageAlt)))) || - '' - ) -} - -/** - * @param {Array.} values - * @param {boolean} includeImageAlt - * @returns {string} - */ -function all(values, includeImageAlt) { - /** @type {Array.} */ - var result = []; - var index = -1; - - while (++index < values.length) { - result[index] = one(values[index], includeImageAlt); - } - - return result.join('') -} - -/** - * Like `Array#splice`, but smarter for giant arrays. - * - * `Array#splice` takes all items to be inserted as individual argument which - * causes a stack overflow in V8 when trying to insert 100k items for instance. - * - * Otherwise, this does not return the removed items, and takes `items` as an - * array instead of rest parameters. - * - * @template {unknown} T - * @param {T[]} list - * @param {number} start - * @param {number} remove - * @param {T[]} items - * @returns {void} - */ -function splice(list, start, remove, items) { - const end = list.length; - let chunkStart = 0; - /** @type {unknown[]} */ - - let parameters; // Make start between zero and `end` (included). - - if (start < 0) { - start = -start > end ? 0 : end + start; - } else { - start = start > end ? end : start; - } - - remove = remove > 0 ? remove : 0; // No need to chunk the items if there’s only a couple (10k) items. - - if (items.length < 10000) { - parameters = Array.from(items); - parameters.unshift(start, remove) // @ts-expect-error Hush, it’s fine. - ;[].splice.apply(list, parameters); - } else { - // Delete `remove` items starting from `start` - if (remove) [].splice.apply(list, [start, remove]); // Insert the items in chunks to not cause stack overflows. - - while (chunkStart < items.length) { - parameters = items.slice(chunkStart, chunkStart + 10000); - parameters.unshift(start, 0) // @ts-expect-error Hush, it’s fine. - ;[].splice.apply(list, parameters); - chunkStart += 10000; - start += 10000; - } - } -} -/** - * Append `items` (an array) at the end of `list` (another array). - * When `list` was empty, returns `items` instead. - * - * This prevents a potentially expensive operation when `list` is empty, - * and adds items in batches to prevent V8 from hanging. - * - * @template {unknown} T - * @param {T[]} list - * @param {T[]} items - * @returns {T[]} - */ - -function push(list, items) { - if (list.length > 0) { - splice(list, list.length, 0, items); - return list - } - - return items -} - -/** - * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension - * @typedef {import('micromark-util-types').Extension} Extension - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension - */ - -const hasOwnProperty = {}.hasOwnProperty; - -/** - * Combine several syntax extensions into one. - * - * @param {Extension[]} extensions List of syntax extensions. - * @returns {NormalizedExtension} A single combined extension. - */ -function combineExtensions(extensions) { - /** @type {NormalizedExtension} */ - const all = {}; - let index = -1; - - while (++index < extensions.length) { - syntaxExtension(all, extensions[index]); - } - - return all -} - -/** - * Merge `extension` into `all`. - * - * @param {NormalizedExtension} all Extension to merge into. - * @param {Extension} extension Extension to merge. - * @returns {void} - */ -function syntaxExtension(all, extension) { - /** @type {string} */ - let hook; - - for (hook in extension) { - const maybe = hasOwnProperty.call(all, hook) ? all[hook] : undefined; - const left = maybe || (all[hook] = {}); - const right = extension[hook]; - /** @type {string} */ - let code; - - for (code in right) { - if (!hasOwnProperty.call(left, code)) left[code] = []; - const value = right[code]; - constructs( - // @ts-expect-error Looks like a list. - left[code], - Array.isArray(value) ? value : value ? [value] : [] - ); - } - } -} - -/** - * Merge `list` into `existing` (both lists of constructs). - * Mutates `existing`. - * - * @param {unknown[]} existing - * @param {unknown[]} list - * @returns {void} - */ -function constructs(existing, list) { - let index = -1; - /** @type {unknown[]} */ - const before = []; - - while (++index < list.length) { -(list[index].add === 'after' ? existing : before).push(list[index]); - } - - splice(existing, 0, 0, before); -} - -/** - * Combine several HTML extensions into one. - * - * @param {HtmlExtension[]} htmlExtensions List of HTML extensions. - * @returns {HtmlExtension} A single combined extension. - */ -function combineHtmlExtensions(htmlExtensions) { - /** @type {HtmlExtension} */ - const handlers = {}; - let index = -1; - - while (++index < htmlExtensions.length) { - htmlExtension(handlers, htmlExtensions[index]); - } - - return handlers -} - -/** - * Merge `extension` into `all`. - * - * @param {HtmlExtension} all Extension to merge into. - * @param {HtmlExtension} extension Extension to merge. - * @returns {void} - */ -function htmlExtension(all, extension) { - /** @type {string} */ - let hook; - - for (hook in extension) { - const maybe = hasOwnProperty.call(all, hook) ? all[hook] : undefined; - const left = maybe || (all[hook] = {}); - const right = extension[hook]; - /** @type {string} */ - let type; - - if (right) { - for (type in right) { - left[type] = right[type]; - } - } - } -} - -// This module is generated by `script/`. -// -// CommonMark handles attention (emphasis, strong) markers based on what comes -// before or after them. -// One such difference is if those characters are Unicode punctuation. -// This script is generated from the Unicode data. -const unicodePunctuationRegex = - /[!-/:-@[-`{-~\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/; - -/** - * @typedef {import('micromark-util-types').Code} Code - */ -/** - * Check whether the character code represents an ASCII alpha (`a` through `z`, - * case insensitive). - * - * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. - * - * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) - * to U+005A (`Z`). - * - * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) - * to U+007A (`z`). - */ - -const asciiAlpha = regexCheck(/[A-Za-z]/); -/** - * Check whether the character code represents an ASCII digit (`0` through `9`). - * - * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to - * U+0039 (`9`). - */ - -const asciiDigit = regexCheck(/\d/); -/** - * Check whether the character code represents an ASCII hex digit (`a` through - * `f`, case insensitive, or `0` through `9`). - * - * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex - * digit, or an ASCII lower hex digit. - * - * An **ASCII upper hex digit** is a character in the inclusive range U+0041 - * (`A`) to U+0046 (`F`). - * - * An **ASCII lower hex digit** is a character in the inclusive range U+0061 - * (`a`) to U+0066 (`f`). - */ - -const asciiHexDigit = regexCheck(/[\dA-Fa-f]/); -/** - * Check whether the character code represents an ASCII alphanumeric (`a` - * through `z`, case insensitive, or `0` through `9`). - * - * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha - * (see `asciiAlpha`). - */ - -const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/); -/** - * Check whether the character code represents ASCII punctuation. - * - * An **ASCII punctuation** is a character in the inclusive ranges U+0021 - * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT - * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT - * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). - */ - -const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/); -/** - * Check whether the character code represents an ASCII atext. - * - * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in - * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), - * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F - * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E - * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE - * (`{`) to U+007E TILDE (`~`). - * - * See: - * **\[RFC5322]**: - * [Internet Message Format](https://tools.ietf.org/html/rfc5322). - * P. Resnick. - * IETF. - */ - -const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/); -/** - * Check whether a character code is an ASCII control character. - * - * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) - * to U+001F (US), or U+007F (DEL). - * - * @param {Code} code - * @returns {code is number} - */ - -function asciiControl(code) { - return ( - // Special whitespace codes (which have negative values), C0 and Control - // character DEL - code !== null && (code < 32 || code === 127) - ) -} -/** - * Check whether a character code is a markdown line ending (see - * `markdownLineEnding`) or markdown space (see `markdownSpace`). - * - * @param {Code} code - * @returns {code is number} - */ - -function markdownLineEndingOrSpace(code) { - return code !== null && (code < 0 || code === 32) -} -/** - * Check whether a character code is a markdown line ending. - * - * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN - * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). - * - * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE - * RETURN (CR) are replaced by these virtual characters depending on whether - * they occurred together. - * - * @param {Code} code - * @returns {code is number} - */ - -function markdownLineEnding(code) { - return code !== null && code < -2 -} -/** - * Check whether a character code is a markdown space. - * - * A **markdown space** is the concrete character U+0020 SPACE (SP) and the - * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). - * - * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is - * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL - * SPACE (VS) characters, depending on the column at which the tab occurred. - * - * @param {Code} code - * @returns {code is number} - */ - -function markdownSpace(code) { - return code === -2 || code === -1 || code === 32 -} -/** - * Check whether the character code represents Unicode whitespace. - * - * Note that this does handle micromark specific markdown whitespace characters. - * See `markdownLineEndingOrSpace` to check that. - * - * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, - * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), - * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). - * - * See: - * **\[UNICODE]**: - * [The Unicode Standard](https://www.unicode.org/versions/). - * Unicode Consortium. - */ - -const unicodeWhitespace = regexCheck(/\s/); -/** - * Check whether the character code represents Unicode punctuation. - * - * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, - * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` - * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` - * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII - * punctuation (see `asciiPunctuation`). - * - * See: - * **\[UNICODE]**: - * [The Unicode Standard](https://www.unicode.org/versions/). - * Unicode Consortium. - */ -// Size note: removing ASCII from the regex and using `asciiPunctuation` here -// In fact adds to the bundle size. - -const unicodePunctuation = regexCheck(unicodePunctuationRegex); -/** - * Create a code check from a regex. - * - * @param {RegExp} regex - * @returns {(code: Code) => code is number} - */ - -function regexCheck(regex) { - return check - /** - * Check whether a code matches the bound regex. - * - * @param {Code} code Character code - * @returns {code is number} Whether the character code matches the bound regex - */ - - function check(code) { - return code !== null && regex.test(String.fromCharCode(code)) - } -} - -/** - * @typedef {import('micromark-util-types').Effects} Effects - * @typedef {import('micromark-util-types').State} State - */ -/** - * @param {Effects} effects - * @param {State} ok - * @param {string} type - * @param {number} [max=Infinity] - * @returns {State} - */ - -function factorySpace(effects, ok, type, max) { - const limit = max ? max - 1 : Number.POSITIVE_INFINITY; - let size = 0; - return start - /** @type {State} */ - - function start(code) { - if (markdownSpace(code)) { - effects.enter(type); - return prefix(code) - } - - return ok(code) - } - /** @type {State} */ - - function prefix(code) { - if (markdownSpace(code) && size++ < limit) { - effects.consume(code); - return prefix - } - - effects.exit(type); - return ok(code) - } -} - -/** - * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct - * @typedef {import('micromark-util-types').Initializer} Initializer - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {InitialConstruct} */ -const content$1 = { - tokenize: initializeContent -}; -/** @type {Initializer} */ - -function initializeContent(effects) { - const contentStart = effects.attempt( - this.parser.constructs.contentInitial, - afterContentStartConstruct, - paragraphInitial - ); - /** @type {Token} */ - - let previous; - return contentStart - /** @type {State} */ - - function afterContentStartConstruct(code) { - if (code === null) { - effects.consume(code); - return - } - - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return factorySpace(effects, contentStart, 'linePrefix') - } - /** @type {State} */ - - function paragraphInitial(code) { - effects.enter('paragraph'); - return lineStart(code) - } - /** @type {State} */ - - function lineStart(code) { - const token = effects.enter('chunkText', { - contentType: 'text', - previous - }); - - if (previous) { - previous.next = token; - } - - previous = token; - return data(code) - } - /** @type {State} */ - - function data(code) { - if (code === null) { - effects.exit('chunkText'); - effects.exit('paragraph'); - effects.consume(code); - return - } - - if (markdownLineEnding(code)) { - effects.consume(code); - effects.exit('chunkText'); - return lineStart - } // Data. - - effects.consume(code); - return data - } -} - -/** - * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct - * @typedef {import('micromark-util-types').Initializer} Initializer - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Point} Point - */ -/** @type {InitialConstruct} */ - -const document$2 = { - tokenize: initializeDocument -}; -/** @type {Construct} */ - -const containerConstruct = { - tokenize: tokenizeContainer -}; -/** @type {Initializer} */ - -function initializeDocument(effects) { - const self = this; - /** @type {StackItem[]} */ - - const stack = []; - let continued = 0; - /** @type {TokenizeContext|undefined} */ - - let childFlow; - /** @type {Token|undefined} */ - - let childToken; - /** @type {number} */ - - let lineStartOffset; - return start - /** @type {State} */ - - function start(code) { - // First we iterate through the open blocks, starting with the root - // document, and descending through last children down to the last open - // block. - // Each block imposes a condition that the line must satisfy if the block is - // to remain open. - // For example, a block quote requires a `>` character. - // A paragraph requires a non-blank line. - // In this phase we may match all or just some of the open blocks. - // But we cannot close unmatched blocks yet, because we may have a lazy - // continuation line. - if (continued < stack.length) { - const item = stack[continued]; - self.containerState = item[1]; - return effects.attempt( - item[0].continuation, - documentContinue, - checkNewContainers - )(code) - } // Done. - - return checkNewContainers(code) - } - /** @type {State} */ - - function documentContinue(code) { - continued++; // Note: this field is called `_closeFlow` but it also closes containers. - // Perhaps a good idea to rename it but it’s already used in the wild by - // extensions. - - if (self.containerState._closeFlow) { - self.containerState._closeFlow = undefined; - - if (childFlow) { - closeFlow(); - } // Note: this algorithm for moving events around is similar to the - // algorithm when dealing with lazy lines in `writeToChild`. - - const indexBeforeExits = self.events.length; - let indexBeforeFlow = indexBeforeExits; - /** @type {Point|undefined} */ - - let point; // Find the flow chunk. - - while (indexBeforeFlow--) { - if ( - self.events[indexBeforeFlow][0] === 'exit' && - self.events[indexBeforeFlow][1].type === 'chunkFlow' - ) { - point = self.events[indexBeforeFlow][1].end; - break - } - } - - exitContainers(continued); // Fix positions. - - let index = indexBeforeExits; - - while (index < self.events.length) { - self.events[index][1].end = Object.assign({}, point); - index++; - } // Inject the exits earlier (they’re still also at the end). - - splice( - self.events, - indexBeforeFlow + 1, - 0, - self.events.slice(indexBeforeExits) - ); // Discard the duplicate exits. - - self.events.length = index; - return checkNewContainers(code) - } - - return start(code) - } - /** @type {State} */ - - function checkNewContainers(code) { - // Next, after consuming the continuation markers for existing blocks, we - // look for new block starts (e.g. `>` for a block quote). - // If we encounter a new block start, we close any blocks unmatched in - // step 1 before creating the new block as a child of the last matched - // block. - if (continued === stack.length) { - // No need to `check` whether there’s a container, of `exitContainers` - // would be moot. - // We can instead immediately `attempt` to parse one. - if (!childFlow) { - return documentContinued(code) - } // If we have concrete content, such as block HTML or fenced code, - // we can’t have containers “pierce” into them, so we can immediately - // start. - - if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { - return flowStart(code) - } // If we do have flow, it could still be a blank line, - // but we’d be interrupting it w/ a new container if there’s a current - // construct. - - self.interrupt = Boolean(childFlow.currentConstruct); - } // Check if there is a new container. - - self.containerState = {}; - return effects.check( - containerConstruct, - thereIsANewContainer, - thereIsNoNewContainer - )(code) - } - /** @type {State} */ - - function thereIsANewContainer(code) { - if (childFlow) closeFlow(); - exitContainers(continued); - return documentContinued(code) - } - /** @type {State} */ - - function thereIsNoNewContainer(code) { - self.parser.lazy[self.now().line] = continued !== stack.length; - lineStartOffset = self.now().offset; - return flowStart(code) - } - /** @type {State} */ - - function documentContinued(code) { - // Try new containers. - self.containerState = {}; - return effects.attempt( - containerConstruct, - containerContinue, - flowStart - )(code) - } - /** @type {State} */ - - function containerContinue(code) { - continued++; - stack.push([self.currentConstruct, self.containerState]); // Try another. - - return documentContinued(code) - } - /** @type {State} */ - - function flowStart(code) { - if (code === null) { - if (childFlow) closeFlow(); - exitContainers(0); - effects.consume(code); - return - } - - childFlow = childFlow || self.parser.flow(self.now()); - effects.enter('chunkFlow', { - contentType: 'flow', - previous: childToken, - _tokenizer: childFlow - }); - return flowContinue(code) - } - /** @type {State} */ - - function flowContinue(code) { - if (code === null) { - writeToChild(effects.exit('chunkFlow'), true); - exitContainers(0); - effects.consume(code); - return - } - - if (markdownLineEnding(code)) { - effects.consume(code); - writeToChild(effects.exit('chunkFlow')); // Get ready for the next line. - - continued = 0; - self.interrupt = undefined; - return start - } - - effects.consume(code); - return flowContinue - } - /** - * @param {Token} token - * @param {boolean} [eof] - * @returns {void} - */ - - function writeToChild(token, eof) { - const stream = self.sliceStream(token); - if (eof) stream.push(null); - token.previous = childToken; - if (childToken) childToken.next = token; - childToken = token; - childFlow.defineSkip(token.start); - childFlow.write(stream); // Alright, so we just added a lazy line: - // - // ```markdown - // > a - // b. - // - // Or: - // - // > ~~~c - // d - // - // Or: - // - // > | e | - // f - // ``` - // - // The construct in the second example (fenced code) does not accept lazy - // lines, so it marked itself as done at the end of its first line, and - // then the content construct parses `d`. - // Most constructs in markdown match on the first line: if the first line - // forms a construct, a non-lazy line can’t “unmake” it. - // - // The construct in the third example is potentially a GFM table, and - // those are *weird*. - // It *could* be a table, from the first line, if the following line - // matches a condition. - // In this case, that second line is lazy, which “unmakes” the first line - // and turns the whole into one content block. - // - // We’ve now parsed the non-lazy and the lazy line, and can figure out - // whether the lazy line started a new flow block. - // If it did, we exit the current containers between the two flow blocks. - - if (self.parser.lazy[token.start.line]) { - let index = childFlow.events.length; - - while (index--) { - if ( - // The token starts before the line ending… - childFlow.events[index][1].start.offset < lineStartOffset && - (!childFlow.events[index][1].end || // …or ends after it. - childFlow.events[index][1].end.offset > lineStartOffset) - ) { - // Exit: there’s still something open, which means it’s a lazy line - // part of something. - return - } - } // Note: this algorithm for moving events around is similar to the - // algorithm when closing flow in `documentContinue`. - - const indexBeforeExits = self.events.length; - let indexBeforeFlow = indexBeforeExits; - /** @type {boolean|undefined} */ - - let seen; - /** @type {Point|undefined} */ - - let point; // Find the previous chunk (the one before the lazy line). - - while (indexBeforeFlow--) { - if ( - self.events[indexBeforeFlow][0] === 'exit' && - self.events[indexBeforeFlow][1].type === 'chunkFlow' - ) { - if (seen) { - point = self.events[indexBeforeFlow][1].end; - break - } - - seen = true; - } - } - - exitContainers(continued); // Fix positions. - - index = indexBeforeExits; - - while (index < self.events.length) { - self.events[index][1].end = Object.assign({}, point); - index++; - } // Inject the exits earlier (they’re still also at the end). - - splice( - self.events, - indexBeforeFlow + 1, - 0, - self.events.slice(indexBeforeExits) - ); // Discard the duplicate exits. - - self.events.length = index; - } - } - /** - * @param {number} size - * @returns {void} - */ - - function exitContainers(size) { - let index = stack.length; // Exit open containers. - - while (index-- > size) { - const entry = stack[index]; - self.containerState = entry[1]; - entry[0].exit.call(self, effects); - } - - stack.length = size; - } - - function closeFlow() { - childFlow.write([null]); - childToken = undefined; - childFlow = undefined; - self.containerState._closeFlow = undefined; - } -} -/** @type {Tokenizer} */ - -function tokenizeContainer(effects, ok, nok) { - return factorySpace( - effects, - effects.attempt(this.parser.constructs.document, ok, nok), - 'linePrefix', - this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 - ) -} - -/** - * @typedef {import('micromark-util-types').Code} Code - */ - -/** - * Classify whether a character code represents whitespace, punctuation, or - * something else. - * - * Used for attention (emphasis, strong), whose sequences can open or close - * based on the class of surrounding characters. - * - * Note that eof (`null`) is seen as whitespace. - * - * @param {Code} code - * @returns {number|undefined} - */ -function classifyCharacter(code) { - if ( - code === null || - markdownLineEndingOrSpace(code) || - unicodeWhitespace(code) - ) { - return 1 - } - - if (unicodePunctuation(code)) { - return 2 - } -} - -/** - * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext - * @typedef {import('micromark-util-types').Event} Event - * @typedef {import('micromark-util-types').Resolver} Resolver - */ - -/** - * Call all `resolveAll`s. - * - * @param {{resolveAll?: Resolver}[]} constructs - * @param {Event[]} events - * @param {TokenizeContext} context - * @returns {Event[]} - */ -function resolveAll(constructs, events, context) { - /** @type {Resolver[]} */ - const called = []; - let index = -1; - - while (++index < constructs.length) { - const resolve = constructs[index].resolveAll; - - if (resolve && !called.includes(resolve)) { - events = resolve(events, context); - called.push(resolve); - } - } - - return events -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').Event} Event - * @typedef {import('micromark-util-types').Code} Code - * @typedef {import('micromark-util-types').Point} Point - */ - -/** @type {Construct} */ -const attention = { - name: 'attention', - tokenize: tokenizeAttention, - resolveAll: resolveAllAttention -}; -/** - * Take all events and resolve attention to emphasis or strong. - * - * @type {Resolver} - */ - -function resolveAllAttention(events, context) { - let index = -1; - /** @type {number} */ - - let open; - /** @type {Token} */ - - let group; - /** @type {Token} */ - - let text; - /** @type {Token} */ - - let openingSequence; - /** @type {Token} */ - - let closingSequence; - /** @type {number} */ - - let use; - /** @type {Event[]} */ - - let nextEvents; - /** @type {number} */ - - let offset; // Walk through all events. - // - // Note: performance of this is fine on an mb of normal markdown, but it’s - // a bottleneck for malicious stuff. - - while (++index < events.length) { - // Find a token that can close. - if ( - events[index][0] === 'enter' && - events[index][1].type === 'attentionSequence' && - events[index][1]._close - ) { - open = index; // Now walk back to find an opener. - - while (open--) { - // Find a token that can open the closer. - if ( - events[open][0] === 'exit' && - events[open][1].type === 'attentionSequence' && - events[open][1]._open && // If the markers are the same: - context.sliceSerialize(events[open][1]).charCodeAt(0) === - context.sliceSerialize(events[index][1]).charCodeAt(0) - ) { - // If the opening can close or the closing can open, - // and the close size *is not* a multiple of three, - // but the sum of the opening and closing size *is* multiple of three, - // then don’t match. - if ( - (events[open][1]._close || events[index][1]._open) && - (events[index][1].end.offset - events[index][1].start.offset) % 3 && - !( - (events[open][1].end.offset - - events[open][1].start.offset + - events[index][1].end.offset - - events[index][1].start.offset) % - 3 - ) - ) { - continue - } // Number of markers to use from the sequence. - - use = - events[open][1].end.offset - events[open][1].start.offset > 1 && - events[index][1].end.offset - events[index][1].start.offset > 1 - ? 2 - : 1; - const start = Object.assign({}, events[open][1].end); - const end = Object.assign({}, events[index][1].start); - movePoint(start, -use); - movePoint(end, use); - openingSequence = { - type: use > 1 ? 'strongSequence' : 'emphasisSequence', - start, - end: Object.assign({}, events[open][1].end) - }; - closingSequence = { - type: use > 1 ? 'strongSequence' : 'emphasisSequence', - start: Object.assign({}, events[index][1].start), - end - }; - text = { - type: use > 1 ? 'strongText' : 'emphasisText', - start: Object.assign({}, events[open][1].end), - end: Object.assign({}, events[index][1].start) - }; - group = { - type: use > 1 ? 'strong' : 'emphasis', - start: Object.assign({}, openingSequence.start), - end: Object.assign({}, closingSequence.end) - }; - events[open][1].end = Object.assign({}, openingSequence.start); - events[index][1].start = Object.assign({}, closingSequence.end); - nextEvents = []; // If there are more markers in the opening, add them before. - - if (events[open][1].end.offset - events[open][1].start.offset) { - nextEvents = push(nextEvents, [ - ['enter', events[open][1], context], - ['exit', events[open][1], context] - ]); - } // Opening. - - nextEvents = push(nextEvents, [ - ['enter', group, context], - ['enter', openingSequence, context], - ['exit', openingSequence, context], - ['enter', text, context] - ]); // Between. - - nextEvents = push( - nextEvents, - resolveAll( - context.parser.constructs.insideSpan.null, - events.slice(open + 1, index), - context - ) - ); // Closing. - - nextEvents = push(nextEvents, [ - ['exit', text, context], - ['enter', closingSequence, context], - ['exit', closingSequence, context], - ['exit', group, context] - ]); // If there are more markers in the closing, add them after. - - if (events[index][1].end.offset - events[index][1].start.offset) { - offset = 2; - nextEvents = push(nextEvents, [ - ['enter', events[index][1], context], - ['exit', events[index][1], context] - ]); - } else { - offset = 0; - } - - splice(events, open - 1, index - open + 3, nextEvents); - index = open + nextEvents.length - offset - 2; - break - } - } - } - } // Remove remaining sequences. - - index = -1; - - while (++index < events.length) { - if (events[index][1].type === 'attentionSequence') { - events[index][1].type = 'data'; - } - } - - return events -} -/** @type {Tokenizer} */ - -function tokenizeAttention(effects, ok) { - const attentionMarkers = this.parser.constructs.attentionMarkers.null; - const previous = this.previous; - const before = classifyCharacter(previous); - /** @type {NonNullable} */ - - let marker; - return start - /** @type {State} */ - - function start(code) { - effects.enter('attentionSequence'); - marker = code; - return sequence(code) - } - /** @type {State} */ - - function sequence(code) { - if (code === marker) { - effects.consume(code); - return sequence - } - - const token = effects.exit('attentionSequence'); - const after = classifyCharacter(code); - const open = - !after || (after === 2 && before) || attentionMarkers.includes(code); - const close = - !before || (before === 2 && after) || attentionMarkers.includes(previous); - token._open = Boolean(marker === 42 ? open : open && (before || !close)); - token._close = Boolean(marker === 42 ? close : close && (after || !open)); - return ok(code) - } -} -/** - * Move a point a bit. - * - * Note: `move` only works inside lines! It’s not possible to move past other - * chunks (replacement characters, tabs, or line endings). - * - * @param {Point} point - * @param {number} offset - * @returns {void} - */ - -function movePoint(point, offset) { - point.column += offset; - point.offset += offset; - point._bufferIndex += offset; -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const autolink = { - name: 'autolink', - tokenize: tokenizeAutolink -}; -/** @type {Tokenizer} */ - -function tokenizeAutolink(effects, ok, nok) { - let size = 1; - return start - /** @type {State} */ - - function start(code) { - effects.enter('autolink'); - effects.enter('autolinkMarker'); - effects.consume(code); - effects.exit('autolinkMarker'); - effects.enter('autolinkProtocol'); - return open - } - /** @type {State} */ - - function open(code) { - if (asciiAlpha(code)) { - effects.consume(code); - return schemeOrEmailAtext - } - - return asciiAtext(code) ? emailAtext(code) : nok(code) - } - /** @type {State} */ - - function schemeOrEmailAtext(code) { - return code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code) - ? schemeInsideOrEmailAtext(code) - : emailAtext(code) - } - /** @type {State} */ - - function schemeInsideOrEmailAtext(code) { - if (code === 58) { - effects.consume(code); - return urlInside - } - - if ( - (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && - size++ < 32 - ) { - effects.consume(code); - return schemeInsideOrEmailAtext - } - - return emailAtext(code) - } - /** @type {State} */ - - function urlInside(code) { - if (code === 62) { - effects.exit('autolinkProtocol'); - return end(code) - } - - if (code === null || code === 32 || code === 60 || asciiControl(code)) { - return nok(code) - } - - effects.consume(code); - return urlInside - } - /** @type {State} */ - - function emailAtext(code) { - if (code === 64) { - effects.consume(code); - size = 0; - return emailAtSignOrDot - } - - if (asciiAtext(code)) { - effects.consume(code); - return emailAtext - } - - return nok(code) - } - /** @type {State} */ - - function emailAtSignOrDot(code) { - return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) - } - /** @type {State} */ - - function emailLabel(code) { - if (code === 46) { - effects.consume(code); - size = 0; - return emailAtSignOrDot - } - - if (code === 62) { - // Exit, then change the type. - effects.exit('autolinkProtocol').type = 'autolinkEmail'; - return end(code) - } - - return emailValue(code) - } - /** @type {State} */ - - function emailValue(code) { - if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { - effects.consume(code); - return code === 45 ? emailValue : emailLabel - } - - return nok(code) - } - /** @type {State} */ - - function end(code) { - effects.enter('autolinkMarker'); - effects.consume(code); - effects.exit('autolinkMarker'); - effects.exit('autolink'); - return ok - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const blankLine = { - tokenize: tokenizeBlankLine, - partial: true -}; -/** @type {Tokenizer} */ - -function tokenizeBlankLine(effects, ok, nok) { - return factorySpace(effects, afterWhitespace, 'linePrefix') - /** @type {State} */ - - function afterWhitespace(code) { - return code === null || markdownLineEnding(code) ? ok(code) : nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Exiter} Exiter - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const blockQuote = { - name: 'blockQuote', - tokenize: tokenizeBlockQuoteStart, - continuation: { - tokenize: tokenizeBlockQuoteContinuation - }, - exit: exit$1 -}; -/** @type {Tokenizer} */ - -function tokenizeBlockQuoteStart(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - if (code === 62) { - const state = self.containerState; - - if (!state.open) { - effects.enter('blockQuote', { - _container: true - }); - state.open = true; - } - - effects.enter('blockQuotePrefix'); - effects.enter('blockQuoteMarker'); - effects.consume(code); - effects.exit('blockQuoteMarker'); - return after - } - - return nok(code) - } - /** @type {State} */ - - function after(code) { - if (markdownSpace(code)) { - effects.enter('blockQuotePrefixWhitespace'); - effects.consume(code); - effects.exit('blockQuotePrefixWhitespace'); - effects.exit('blockQuotePrefix'); - return ok - } - - effects.exit('blockQuotePrefix'); - return ok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeBlockQuoteContinuation(effects, ok, nok) { - return factorySpace( - effects, - effects.attempt(blockQuote, ok, nok), - 'linePrefix', - this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 - ) -} -/** @type {Exiter} */ - -function exit$1(effects) { - effects.exit('blockQuote'); -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const characterEscape$1 = { - name: 'characterEscape', - tokenize: tokenizeCharacterEscape -}; -/** @type {Tokenizer} */ - -function tokenizeCharacterEscape(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.enter('characterEscape'); - effects.enter('escapeMarker'); - effects.consume(code); - effects.exit('escapeMarker'); - return open - } - /** @type {State} */ - - function open(code) { - if (asciiPunctuation(code)) { - effects.enter('characterEscapeValue'); - effects.consume(code); - effects.exit('characterEscapeValue'); - effects.exit('characterEscape'); - return ok - } - - return nok(code) - } -} - -var characterEntities = { - AEli: 'Æ', - AElig: 'Æ', - AM: '&', - AMP: '&', - Aacut: 'Á', - Aacute: 'Á', - Abreve: 'Ă', - Acir: 'Â', - Acirc: 'Â', - Acy: 'А', - Afr: '𝔄', - Agrav: 'À', - Agrave: 'À', - Alpha: 'Α', - Amacr: 'Ā', - And: '⩓', - Aogon: 'Ą', - Aopf: '𝔸', - ApplyFunction: '⁡', - Arin: 'Å', - Aring: 'Å', - Ascr: '𝒜', - Assign: '≔', - Atild: 'Ã', - Atilde: 'Ã', - Aum: 'Ä', - Auml: 'Ä', - Backslash: '∖', - Barv: '⫧', - Barwed: '⌆', - Bcy: 'Б', - Because: '∵', - Bernoullis: 'ℬ', - Beta: 'Β', - Bfr: '𝔅', - Bopf: '𝔹', - Breve: '˘', - Bscr: 'ℬ', - Bumpeq: '≎', - CHcy: 'Ч', - COP: '©', - COPY: '©', - Cacute: 'Ć', - Cap: '⋒', - CapitalDifferentialD: 'ⅅ', - Cayleys: 'ℭ', - Ccaron: 'Č', - Ccedi: 'Ç', - Ccedil: 'Ç', - Ccirc: 'Ĉ', - Cconint: '∰', - Cdot: 'Ċ', - Cedilla: '¸', - CenterDot: '·', - Cfr: 'ℭ', - Chi: 'Χ', - CircleDot: '⊙', - CircleMinus: '⊖', - CirclePlus: '⊕', - CircleTimes: '⊗', - ClockwiseContourIntegral: '∲', - CloseCurlyDoubleQuote: '”', - CloseCurlyQuote: '’', - Colon: '∷', - Colone: '⩴', - Congruent: '≡', - Conint: '∯', - ContourIntegral: '∮', - Copf: 'ℂ', - Coproduct: '∐', - CounterClockwiseContourIntegral: '∳', - Cross: '⨯', - Cscr: '𝒞', - Cup: '⋓', - CupCap: '≍', - DD: 'ⅅ', - DDotrahd: '⤑', - DJcy: 'Ђ', - DScy: 'Ѕ', - DZcy: 'Џ', - Dagger: '‡', - Darr: '↡', - Dashv: '⫤', - Dcaron: 'Ď', - Dcy: 'Д', - Del: '∇', - Delta: 'Δ', - Dfr: '𝔇', - DiacriticalAcute: '´', - DiacriticalDot: '˙', - DiacriticalDoubleAcute: '˝', - DiacriticalGrave: '`', - DiacriticalTilde: '˜', - Diamond: '⋄', - DifferentialD: 'ⅆ', - Dopf: '𝔻', - Dot: '¨', - DotDot: '⃜', - DotEqual: '≐', - DoubleContourIntegral: '∯', - DoubleDot: '¨', - DoubleDownArrow: '⇓', - DoubleLeftArrow: '⇐', - DoubleLeftRightArrow: '⇔', - DoubleLeftTee: '⫤', - DoubleLongLeftArrow: '⟸', - DoubleLongLeftRightArrow: '⟺', - DoubleLongRightArrow: '⟹', - DoubleRightArrow: '⇒', - DoubleRightTee: '⊨', - DoubleUpArrow: '⇑', - DoubleUpDownArrow: '⇕', - DoubleVerticalBar: '∥', - DownArrow: '↓', - DownArrowBar: '⤓', - DownArrowUpArrow: '⇵', - DownBreve: '̑', - DownLeftRightVector: '⥐', - DownLeftTeeVector: '⥞', - DownLeftVector: '↽', - DownLeftVectorBar: '⥖', - DownRightTeeVector: '⥟', - DownRightVector: '⇁', - DownRightVectorBar: '⥗', - DownTee: '⊤', - DownTeeArrow: '↧', - Downarrow: '⇓', - Dscr: '𝒟', - Dstrok: 'Đ', - ENG: 'Ŋ', - ET: 'Ð', - ETH: 'Ð', - Eacut: 'É', - Eacute: 'É', - Ecaron: 'Ě', - Ecir: 'Ê', - Ecirc: 'Ê', - Ecy: 'Э', - Edot: 'Ė', - Efr: '𝔈', - Egrav: 'È', - Egrave: 'È', - Element: '∈', - Emacr: 'Ē', - EmptySmallSquare: '◻', - EmptyVerySmallSquare: '▫', - Eogon: 'Ę', - Eopf: '𝔼', - Epsilon: 'Ε', - Equal: '⩵', - EqualTilde: '≂', - Equilibrium: '⇌', - Escr: 'ℰ', - Esim: '⩳', - Eta: 'Η', - Eum: 'Ë', - Euml: 'Ë', - Exists: '∃', - ExponentialE: 'ⅇ', - Fcy: 'Ф', - Ffr: '𝔉', - FilledSmallSquare: '◼', - FilledVerySmallSquare: '▪', - Fopf: '𝔽', - ForAll: '∀', - Fouriertrf: 'ℱ', - Fscr: 'ℱ', - GJcy: 'Ѓ', - G: '>', - GT: '>', - Gamma: 'Γ', - Gammad: 'Ϝ', - Gbreve: 'Ğ', - Gcedil: 'Ģ', - Gcirc: 'Ĝ', - Gcy: 'Г', - Gdot: 'Ġ', - Gfr: '𝔊', - Gg: '⋙', - Gopf: '𝔾', - GreaterEqual: '≥', - GreaterEqualLess: '⋛', - GreaterFullEqual: '≧', - GreaterGreater: '⪢', - GreaterLess: '≷', - GreaterSlantEqual: '⩾', - GreaterTilde: '≳', - Gscr: '𝒢', - Gt: '≫', - HARDcy: 'Ъ', - Hacek: 'ˇ', - Hat: '^', - Hcirc: 'Ĥ', - Hfr: 'ℌ', - HilbertSpace: 'ℋ', - Hopf: 'ℍ', - HorizontalLine: '─', - Hscr: 'ℋ', - Hstrok: 'Ħ', - HumpDownHump: '≎', - HumpEqual: '≏', - IEcy: 'Е', - IJlig: 'IJ', - IOcy: 'Ё', - Iacut: 'Í', - Iacute: 'Í', - Icir: 'Î', - Icirc: 'Î', - Icy: 'И', - Idot: 'İ', - Ifr: 'ℑ', - Igrav: 'Ì', - Igrave: 'Ì', - Im: 'ℑ', - Imacr: 'Ī', - ImaginaryI: 'ⅈ', - Implies: '⇒', - Int: '∬', - Integral: '∫', - Intersection: '⋂', - InvisibleComma: '⁣', - InvisibleTimes: '⁢', - Iogon: 'Į', - Iopf: '𝕀', - Iota: 'Ι', - Iscr: 'ℐ', - Itilde: 'Ĩ', - Iukcy: 'І', - Ium: 'Ï', - Iuml: 'Ï', - Jcirc: 'Ĵ', - Jcy: 'Й', - Jfr: '𝔍', - Jopf: '𝕁', - Jscr: '𝒥', - Jsercy: 'Ј', - Jukcy: 'Є', - KHcy: 'Х', - KJcy: 'Ќ', - Kappa: 'Κ', - Kcedil: 'Ķ', - Kcy: 'К', - Kfr: '𝔎', - Kopf: '𝕂', - Kscr: '𝒦', - LJcy: 'Љ', - L: '<', - LT: '<', - Lacute: 'Ĺ', - Lambda: 'Λ', - Lang: '⟪', - Laplacetrf: 'ℒ', - Larr: '↞', - Lcaron: 'Ľ', - Lcedil: 'Ļ', - Lcy: 'Л', - LeftAngleBracket: '⟨', - LeftArrow: '←', - LeftArrowBar: '⇤', - LeftArrowRightArrow: '⇆', - LeftCeiling: '⌈', - LeftDoubleBracket: '⟦', - LeftDownTeeVector: '⥡', - LeftDownVector: '⇃', - LeftDownVectorBar: '⥙', - LeftFloor: '⌊', - LeftRightArrow: '↔', - LeftRightVector: '⥎', - LeftTee: '⊣', - LeftTeeArrow: '↤', - LeftTeeVector: '⥚', - LeftTriangle: '⊲', - LeftTriangleBar: '⧏', - LeftTriangleEqual: '⊴', - LeftUpDownVector: '⥑', - LeftUpTeeVector: '⥠', - LeftUpVector: '↿', - LeftUpVectorBar: '⥘', - LeftVector: '↼', - LeftVectorBar: '⥒', - Leftarrow: '⇐', - Leftrightarrow: '⇔', - LessEqualGreater: '⋚', - LessFullEqual: '≦', - LessGreater: '≶', - LessLess: '⪡', - LessSlantEqual: '⩽', - LessTilde: '≲', - Lfr: '𝔏', - Ll: '⋘', - Lleftarrow: '⇚', - Lmidot: 'Ŀ', - LongLeftArrow: '⟵', - LongLeftRightArrow: '⟷', - LongRightArrow: '⟶', - Longleftarrow: '⟸', - Longleftrightarrow: '⟺', - Longrightarrow: '⟹', - Lopf: '𝕃', - LowerLeftArrow: '↙', - LowerRightArrow: '↘', - Lscr: 'ℒ', - Lsh: '↰', - Lstrok: 'Ł', - Lt: '≪', - Map: '⤅', - Mcy: 'М', - MediumSpace: ' ', - Mellintrf: 'ℳ', - Mfr: '𝔐', - MinusPlus: '∓', - Mopf: '𝕄', - Mscr: 'ℳ', - Mu: 'Μ', - NJcy: 'Њ', - Nacute: 'Ń', - Ncaron: 'Ň', - Ncedil: 'Ņ', - Ncy: 'Н', - NegativeMediumSpace: '​', - NegativeThickSpace: '​', - NegativeThinSpace: '​', - NegativeVeryThinSpace: '​', - NestedGreaterGreater: '≫', - NestedLessLess: '≪', - NewLine: '\n', - Nfr: '𝔑', - NoBreak: '⁠', - NonBreakingSpace: ' ', - Nopf: 'ℕ', - Not: '⫬', - NotCongruent: '≢', - NotCupCap: '≭', - NotDoubleVerticalBar: '∦', - NotElement: '∉', - NotEqual: '≠', - NotEqualTilde: '≂̸', - NotExists: '∄', - NotGreater: '≯', - NotGreaterEqual: '≱', - NotGreaterFullEqual: '≧̸', - NotGreaterGreater: '≫̸', - NotGreaterLess: '≹', - NotGreaterSlantEqual: '⩾̸', - NotGreaterTilde: '≵', - NotHumpDownHump: '≎̸', - NotHumpEqual: '≏̸', - NotLeftTriangle: '⋪', - NotLeftTriangleBar: '⧏̸', - NotLeftTriangleEqual: '⋬', - NotLess: '≮', - NotLessEqual: '≰', - NotLessGreater: '≸', - NotLessLess: '≪̸', - NotLessSlantEqual: '⩽̸', - NotLessTilde: '≴', - NotNestedGreaterGreater: '⪢̸', - NotNestedLessLess: '⪡̸', - NotPrecedes: '⊀', - NotPrecedesEqual: '⪯̸', - NotPrecedesSlantEqual: '⋠', - NotReverseElement: '∌', - NotRightTriangle: '⋫', - NotRightTriangleBar: '⧐̸', - NotRightTriangleEqual: '⋭', - NotSquareSubset: '⊏̸', - NotSquareSubsetEqual: '⋢', - NotSquareSuperset: '⊐̸', - NotSquareSupersetEqual: '⋣', - NotSubset: '⊂⃒', - NotSubsetEqual: '⊈', - NotSucceeds: '⊁', - NotSucceedsEqual: '⪰̸', - NotSucceedsSlantEqual: '⋡', - NotSucceedsTilde: '≿̸', - NotSuperset: '⊃⃒', - NotSupersetEqual: '⊉', - NotTilde: '≁', - NotTildeEqual: '≄', - NotTildeFullEqual: '≇', - NotTildeTilde: '≉', - NotVerticalBar: '∤', - Nscr: '𝒩', - Ntild: 'Ñ', - Ntilde: 'Ñ', - Nu: 'Ν', - OElig: 'Œ', - Oacut: 'Ó', - Oacute: 'Ó', - Ocir: 'Ô', - Ocirc: 'Ô', - Ocy: 'О', - Odblac: 'Ő', - Ofr: '𝔒', - Ograv: 'Ò', - Ograve: 'Ò', - Omacr: 'Ō', - Omega: 'Ω', - Omicron: 'Ο', - Oopf: '𝕆', - OpenCurlyDoubleQuote: '“', - OpenCurlyQuote: '‘', - Or: '⩔', - Oscr: '𝒪', - Oslas: 'Ø', - Oslash: 'Ø', - Otild: 'Õ', - Otilde: 'Õ', - Otimes: '⨷', - Oum: 'Ö', - Ouml: 'Ö', - OverBar: '‾', - OverBrace: '⏞', - OverBracket: '⎴', - OverParenthesis: '⏜', - PartialD: '∂', - Pcy: 'П', - Pfr: '𝔓', - Phi: 'Φ', - Pi: 'Π', - PlusMinus: '±', - Poincareplane: 'ℌ', - Popf: 'ℙ', - Pr: '⪻', - Precedes: '≺', - PrecedesEqual: '⪯', - PrecedesSlantEqual: '≼', - PrecedesTilde: '≾', - Prime: '″', - Product: '∏', - Proportion: '∷', - Proportional: '∝', - Pscr: '𝒫', - Psi: 'Ψ', - QUO: '"', - QUOT: '"', - Qfr: '𝔔', - Qopf: 'ℚ', - Qscr: '𝒬', - RBarr: '⤐', - RE: '®', - REG: '®', - Racute: 'Ŕ', - Rang: '⟫', - Rarr: '↠', - Rarrtl: '⤖', - Rcaron: 'Ř', - Rcedil: 'Ŗ', - Rcy: 'Р', - Re: 'ℜ', - ReverseElement: '∋', - ReverseEquilibrium: '⇋', - ReverseUpEquilibrium: '⥯', - Rfr: 'ℜ', - Rho: 'Ρ', - RightAngleBracket: '⟩', - RightArrow: '→', - RightArrowBar: '⇥', - RightArrowLeftArrow: '⇄', - RightCeiling: '⌉', - RightDoubleBracket: '⟧', - RightDownTeeVector: '⥝', - RightDownVector: '⇂', - RightDownVectorBar: '⥕', - RightFloor: '⌋', - RightTee: '⊢', - RightTeeArrow: '↦', - RightTeeVector: '⥛', - RightTriangle: '⊳', - RightTriangleBar: '⧐', - RightTriangleEqual: '⊵', - RightUpDownVector: '⥏', - RightUpTeeVector: '⥜', - RightUpVector: '↾', - RightUpVectorBar: '⥔', - RightVector: '⇀', - RightVectorBar: '⥓', - Rightarrow: '⇒', - Ropf: 'ℝ', - RoundImplies: '⥰', - Rrightarrow: '⇛', - Rscr: 'ℛ', - Rsh: '↱', - RuleDelayed: '⧴', - SHCHcy: 'Щ', - SHcy: 'Ш', - SOFTcy: 'Ь', - Sacute: 'Ś', - Sc: '⪼', - Scaron: 'Š', - Scedil: 'Ş', - Scirc: 'Ŝ', - Scy: 'С', - Sfr: '𝔖', - ShortDownArrow: '↓', - ShortLeftArrow: '←', - ShortRightArrow: '→', - ShortUpArrow: '↑', - Sigma: 'Σ', - SmallCircle: '∘', - Sopf: '𝕊', - Sqrt: '√', - Square: '□', - SquareIntersection: '⊓', - SquareSubset: '⊏', - SquareSubsetEqual: '⊑', - SquareSuperset: '⊐', - SquareSupersetEqual: '⊒', - SquareUnion: '⊔', - Sscr: '𝒮', - Star: '⋆', - Sub: '⋐', - Subset: '⋐', - SubsetEqual: '⊆', - Succeeds: '≻', - SucceedsEqual: '⪰', - SucceedsSlantEqual: '≽', - SucceedsTilde: '≿', - SuchThat: '∋', - Sum: '∑', - Sup: '⋑', - Superset: '⊃', - SupersetEqual: '⊇', - Supset: '⋑', - THOR: 'Þ', - THORN: 'Þ', - TRADE: '™', - TSHcy: 'Ћ', - TScy: 'Ц', - Tab: '\t', - Tau: 'Τ', - Tcaron: 'Ť', - Tcedil: 'Ţ', - Tcy: 'Т', - Tfr: '𝔗', - Therefore: '∴', - Theta: 'Θ', - ThickSpace: '  ', - ThinSpace: ' ', - Tilde: '∼', - TildeEqual: '≃', - TildeFullEqual: '≅', - TildeTilde: '≈', - Topf: '𝕋', - TripleDot: '⃛', - Tscr: '𝒯', - Tstrok: 'Ŧ', - Uacut: 'Ú', - Uacute: 'Ú', - Uarr: '↟', - Uarrocir: '⥉', - Ubrcy: 'Ў', - Ubreve: 'Ŭ', - Ucir: 'Û', - Ucirc: 'Û', - Ucy: 'У', - Udblac: 'Ű', - Ufr: '𝔘', - Ugrav: 'Ù', - Ugrave: 'Ù', - Umacr: 'Ū', - UnderBar: '_', - UnderBrace: '⏟', - UnderBracket: '⎵', - UnderParenthesis: '⏝', - Union: '⋃', - UnionPlus: '⊎', - Uogon: 'Ų', - Uopf: '𝕌', - UpArrow: '↑', - UpArrowBar: '⤒', - UpArrowDownArrow: '⇅', - UpDownArrow: '↕', - UpEquilibrium: '⥮', - UpTee: '⊥', - UpTeeArrow: '↥', - Uparrow: '⇑', - Updownarrow: '⇕', - UpperLeftArrow: '↖', - UpperRightArrow: '↗', - Upsi: 'ϒ', - Upsilon: 'Υ', - Uring: 'Ů', - Uscr: '𝒰', - Utilde: 'Ũ', - Uum: 'Ü', - Uuml: 'Ü', - VDash: '⊫', - Vbar: '⫫', - Vcy: 'В', - Vdash: '⊩', - Vdashl: '⫦', - Vee: '⋁', - Verbar: '‖', - Vert: '‖', - VerticalBar: '∣', - VerticalLine: '|', - VerticalSeparator: '❘', - VerticalTilde: '≀', - VeryThinSpace: ' ', - Vfr: '𝔙', - Vopf: '𝕍', - Vscr: '𝒱', - Vvdash: '⊪', - Wcirc: 'Ŵ', - Wedge: '⋀', - Wfr: '𝔚', - Wopf: '𝕎', - Wscr: '𝒲', - Xfr: '𝔛', - Xi: 'Ξ', - Xopf: '𝕏', - Xscr: '𝒳', - YAcy: 'Я', - YIcy: 'Ї', - YUcy: 'Ю', - Yacut: 'Ý', - Yacute: 'Ý', - Ycirc: 'Ŷ', - Ycy: 'Ы', - Yfr: '𝔜', - Yopf: '𝕐', - Yscr: '𝒴', - Yuml: 'Ÿ', - ZHcy: 'Ж', - Zacute: 'Ź', - Zcaron: 'Ž', - Zcy: 'З', - Zdot: 'Ż', - ZeroWidthSpace: '​', - Zeta: 'Ζ', - Zfr: 'ℨ', - Zopf: 'ℤ', - Zscr: '𝒵', - aacut: 'á', - aacute: 'á', - abreve: 'ă', - ac: '∾', - acE: '∾̳', - acd: '∿', - acir: 'â', - acirc: 'â', - acut: '´', - acute: '´', - acy: 'а', - aeli: 'æ', - aelig: 'æ', - af: '⁡', - afr: '𝔞', - agrav: 'à', - agrave: 'à', - alefsym: 'ℵ', - aleph: 'ℵ', - alpha: 'α', - amacr: 'ā', - amalg: '⨿', - am: '&', - amp: '&', - and: '∧', - andand: '⩕', - andd: '⩜', - andslope: '⩘', - andv: '⩚', - ang: '∠', - ange: '⦤', - angle: '∠', - angmsd: '∡', - angmsdaa: '⦨', - angmsdab: '⦩', - angmsdac: '⦪', - angmsdad: '⦫', - angmsdae: '⦬', - angmsdaf: '⦭', - angmsdag: '⦮', - angmsdah: '⦯', - angrt: '∟', - angrtvb: '⊾', - angrtvbd: '⦝', - angsph: '∢', - angst: 'Å', - angzarr: '⍼', - aogon: 'ą', - aopf: '𝕒', - ap: '≈', - apE: '⩰', - apacir: '⩯', - ape: '≊', - apid: '≋', - apos: "'", - approx: '≈', - approxeq: '≊', - arin: 'å', - aring: 'å', - ascr: '𝒶', - ast: '*', - asymp: '≈', - asympeq: '≍', - atild: 'ã', - atilde: 'ã', - aum: 'ä', - auml: 'ä', - awconint: '∳', - awint: '⨑', - bNot: '⫭', - backcong: '≌', - backepsilon: '϶', - backprime: '‵', - backsim: '∽', - backsimeq: '⋍', - barvee: '⊽', - barwed: '⌅', - barwedge: '⌅', - bbrk: '⎵', - bbrktbrk: '⎶', - bcong: '≌', - bcy: 'б', - bdquo: '„', - becaus: '∵', - because: '∵', - bemptyv: '⦰', - bepsi: '϶', - bernou: 'ℬ', - beta: 'β', - beth: 'ℶ', - between: '≬', - bfr: '𝔟', - bigcap: '⋂', - bigcirc: '◯', - bigcup: '⋃', - bigodot: '⨀', - bigoplus: '⨁', - bigotimes: '⨂', - bigsqcup: '⨆', - bigstar: '★', - bigtriangledown: '▽', - bigtriangleup: '△', - biguplus: '⨄', - bigvee: '⋁', - bigwedge: '⋀', - bkarow: '⤍', - blacklozenge: '⧫', - blacksquare: '▪', - blacktriangle: '▴', - blacktriangledown: '▾', - blacktriangleleft: '◂', - blacktriangleright: '▸', - blank: '␣', - blk12: '▒', - blk14: '░', - blk34: '▓', - block: '█', - bne: '=⃥', - bnequiv: '≡⃥', - bnot: '⌐', - bopf: '𝕓', - bot: '⊥', - bottom: '⊥', - bowtie: '⋈', - boxDL: '╗', - boxDR: '╔', - boxDl: '╖', - boxDr: '╓', - boxH: '═', - boxHD: '╦', - boxHU: '╩', - boxHd: '╤', - boxHu: '╧', - boxUL: '╝', - boxUR: '╚', - boxUl: '╜', - boxUr: '╙', - boxV: '║', - boxVH: '╬', - boxVL: '╣', - boxVR: '╠', - boxVh: '╫', - boxVl: '╢', - boxVr: '╟', - boxbox: '⧉', - boxdL: '╕', - boxdR: '╒', - boxdl: '┐', - boxdr: '┌', - boxh: '─', - boxhD: '╥', - boxhU: '╨', - boxhd: '┬', - boxhu: '┴', - boxminus: '⊟', - boxplus: '⊞', - boxtimes: '⊠', - boxuL: '╛', - boxuR: '╘', - boxul: '┘', - boxur: '└', - boxv: '│', - boxvH: '╪', - boxvL: '╡', - boxvR: '╞', - boxvh: '┼', - boxvl: '┤', - boxvr: '├', - bprime: '‵', - breve: '˘', - brvba: '¦', - brvbar: '¦', - bscr: '𝒷', - bsemi: '⁏', - bsim: '∽', - bsime: '⋍', - bsol: '\\', - bsolb: '⧅', - bsolhsub: '⟈', - bull: '•', - bullet: '•', - bump: '≎', - bumpE: '⪮', - bumpe: '≏', - bumpeq: '≏', - cacute: 'ć', - cap: '∩', - capand: '⩄', - capbrcup: '⩉', - capcap: '⩋', - capcup: '⩇', - capdot: '⩀', - caps: '∩︀', - caret: '⁁', - caron: 'ˇ', - ccaps: '⩍', - ccaron: 'č', - ccedi: 'ç', - ccedil: 'ç', - ccirc: 'ĉ', - ccups: '⩌', - ccupssm: '⩐', - cdot: 'ċ', - cedi: '¸', - cedil: '¸', - cemptyv: '⦲', - cen: '¢', - cent: '¢', - centerdot: '·', - cfr: '𝔠', - chcy: 'ч', - check: '✓', - checkmark: '✓', - chi: 'χ', - cir: '○', - cirE: '⧃', - circ: 'ˆ', - circeq: '≗', - circlearrowleft: '↺', - circlearrowright: '↻', - circledR: '®', - circledS: 'Ⓢ', - circledast: '⊛', - circledcirc: '⊚', - circleddash: '⊝', - cire: '≗', - cirfnint: '⨐', - cirmid: '⫯', - cirscir: '⧂', - clubs: '♣', - clubsuit: '♣', - colon: ':', - colone: '≔', - coloneq: '≔', - comma: ',', - commat: '@', - comp: '∁', - compfn: '∘', - complement: '∁', - complexes: 'ℂ', - cong: '≅', - congdot: '⩭', - conint: '∮', - copf: '𝕔', - coprod: '∐', - cop: '©', - copy: '©', - copysr: '℗', - crarr: '↵', - cross: '✗', - cscr: '𝒸', - csub: '⫏', - csube: '⫑', - csup: '⫐', - csupe: '⫒', - ctdot: '⋯', - cudarrl: '⤸', - cudarrr: '⤵', - cuepr: '⋞', - cuesc: '⋟', - cularr: '↶', - cularrp: '⤽', - cup: '∪', - cupbrcap: '⩈', - cupcap: '⩆', - cupcup: '⩊', - cupdot: '⊍', - cupor: '⩅', - cups: '∪︀', - curarr: '↷', - curarrm: '⤼', - curlyeqprec: '⋞', - curlyeqsucc: '⋟', - curlyvee: '⋎', - curlywedge: '⋏', - curre: '¤', - curren: '¤', - curvearrowleft: '↶', - curvearrowright: '↷', - cuvee: '⋎', - cuwed: '⋏', - cwconint: '∲', - cwint: '∱', - cylcty: '⌭', - dArr: '⇓', - dHar: '⥥', - dagger: '†', - daleth: 'ℸ', - darr: '↓', - dash: '‐', - dashv: '⊣', - dbkarow: '⤏', - dblac: '˝', - dcaron: 'ď', - dcy: 'д', - dd: 'ⅆ', - ddagger: '‡', - ddarr: '⇊', - ddotseq: '⩷', - de: '°', - deg: '°', - delta: 'δ', - demptyv: '⦱', - dfisht: '⥿', - dfr: '𝔡', - dharl: '⇃', - dharr: '⇂', - diam: '⋄', - diamond: '⋄', - diamondsuit: '♦', - diams: '♦', - die: '¨', - digamma: 'ϝ', - disin: '⋲', - div: '÷', - divid: '÷', - divide: '÷', - divideontimes: '⋇', - divonx: '⋇', - djcy: 'ђ', - dlcorn: '⌞', - dlcrop: '⌍', - dollar: '$', - dopf: '𝕕', - dot: '˙', - doteq: '≐', - doteqdot: '≑', - dotminus: '∸', - dotplus: '∔', - dotsquare: '⊡', - doublebarwedge: '⌆', - downarrow: '↓', - downdownarrows: '⇊', - downharpoonleft: '⇃', - downharpoonright: '⇂', - drbkarow: '⤐', - drcorn: '⌟', - drcrop: '⌌', - dscr: '𝒹', - dscy: 'ѕ', - dsol: '⧶', - dstrok: 'đ', - dtdot: '⋱', - dtri: '▿', - dtrif: '▾', - duarr: '⇵', - duhar: '⥯', - dwangle: '⦦', - dzcy: 'џ', - dzigrarr: '⟿', - eDDot: '⩷', - eDot: '≑', - eacut: 'é', - eacute: 'é', - easter: '⩮', - ecaron: 'ě', - ecir: 'ê', - ecirc: 'ê', - ecolon: '≕', - ecy: 'э', - edot: 'ė', - ee: 'ⅇ', - efDot: '≒', - efr: '𝔢', - eg: '⪚', - egrav: 'è', - egrave: 'è', - egs: '⪖', - egsdot: '⪘', - el: '⪙', - elinters: '⏧', - ell: 'ℓ', - els: '⪕', - elsdot: '⪗', - emacr: 'ē', - empty: '∅', - emptyset: '∅', - emptyv: '∅', - emsp13: ' ', - emsp14: ' ', - emsp: ' ', - eng: 'ŋ', - ensp: ' ', - eogon: 'ę', - eopf: '𝕖', - epar: '⋕', - eparsl: '⧣', - eplus: '⩱', - epsi: 'ε', - epsilon: 'ε', - epsiv: 'ϵ', - eqcirc: '≖', - eqcolon: '≕', - eqsim: '≂', - eqslantgtr: '⪖', - eqslantless: '⪕', - equals: '=', - equest: '≟', - equiv: '≡', - equivDD: '⩸', - eqvparsl: '⧥', - erDot: '≓', - erarr: '⥱', - escr: 'ℯ', - esdot: '≐', - esim: '≂', - eta: 'η', - et: 'ð', - eth: 'ð', - eum: 'ë', - euml: 'ë', - euro: '€', - excl: '!', - exist: '∃', - expectation: 'ℰ', - exponentiale: 'ⅇ', - fallingdotseq: '≒', - fcy: 'ф', - female: '♀', - ffilig: 'ffi', - fflig: 'ff', - ffllig: 'ffl', - ffr: '𝔣', - filig: 'fi', - fjlig: 'fj', - flat: '♭', - fllig: 'fl', - fltns: '▱', - fnof: 'ƒ', - fopf: '𝕗', - forall: '∀', - fork: '⋔', - forkv: '⫙', - fpartint: '⨍', - frac1: '¼', - frac12: '½', - frac13: '⅓', - frac14: '¼', - frac15: '⅕', - frac16: '⅙', - frac18: '⅛', - frac23: '⅔', - frac25: '⅖', - frac3: '¾', - frac34: '¾', - frac35: '⅗', - frac38: '⅜', - frac45: '⅘', - frac56: '⅚', - frac58: '⅝', - frac78: '⅞', - frasl: '⁄', - frown: '⌢', - fscr: '𝒻', - gE: '≧', - gEl: '⪌', - gacute: 'ǵ', - gamma: 'γ', - gammad: 'ϝ', - gap: '⪆', - gbreve: 'ğ', - gcirc: 'ĝ', - gcy: 'г', - gdot: 'ġ', - ge: '≥', - gel: '⋛', - geq: '≥', - geqq: '≧', - geqslant: '⩾', - ges: '⩾', - gescc: '⪩', - gesdot: '⪀', - gesdoto: '⪂', - gesdotol: '⪄', - gesl: '⋛︀', - gesles: '⪔', - gfr: '𝔤', - gg: '≫', - ggg: '⋙', - gimel: 'ℷ', - gjcy: 'ѓ', - gl: '≷', - glE: '⪒', - gla: '⪥', - glj: '⪤', - gnE: '≩', - gnap: '⪊', - gnapprox: '⪊', - gne: '⪈', - gneq: '⪈', - gneqq: '≩', - gnsim: '⋧', - gopf: '𝕘', - grave: '`', - gscr: 'ℊ', - gsim: '≳', - gsime: '⪎', - gsiml: '⪐', - g: '>', - gt: '>', - gtcc: '⪧', - gtcir: '⩺', - gtdot: '⋗', - gtlPar: '⦕', - gtquest: '⩼', - gtrapprox: '⪆', - gtrarr: '⥸', - gtrdot: '⋗', - gtreqless: '⋛', - gtreqqless: '⪌', - gtrless: '≷', - gtrsim: '≳', - gvertneqq: '≩︀', - gvnE: '≩︀', - hArr: '⇔', - hairsp: ' ', - half: '½', - hamilt: 'ℋ', - hardcy: 'ъ', - harr: '↔', - harrcir: '⥈', - harrw: '↭', - hbar: 'ℏ', - hcirc: 'ĥ', - hearts: '♥', - heartsuit: '♥', - hellip: '…', - hercon: '⊹', - hfr: '𝔥', - hksearow: '⤥', - hkswarow: '⤦', - hoarr: '⇿', - homtht: '∻', - hookleftarrow: '↩', - hookrightarrow: '↪', - hopf: '𝕙', - horbar: '―', - hscr: '𝒽', - hslash: 'ℏ', - hstrok: 'ħ', - hybull: '⁃', - hyphen: '‐', - iacut: 'í', - iacute: 'í', - ic: '⁣', - icir: 'î', - icirc: 'î', - icy: 'и', - iecy: 'е', - iexc: '¡', - iexcl: '¡', - iff: '⇔', - ifr: '𝔦', - igrav: 'ì', - igrave: 'ì', - ii: 'ⅈ', - iiiint: '⨌', - iiint: '∭', - iinfin: '⧜', - iiota: '℩', - ijlig: 'ij', - imacr: 'ī', - image: 'ℑ', - imagline: 'ℐ', - imagpart: 'ℑ', - imath: 'ı', - imof: '⊷', - imped: 'Ƶ', - in: '∈', - incare: '℅', - infin: '∞', - infintie: '⧝', - inodot: 'ı', - int: '∫', - intcal: '⊺', - integers: 'ℤ', - intercal: '⊺', - intlarhk: '⨗', - intprod: '⨼', - iocy: 'ё', - iogon: 'į', - iopf: '𝕚', - iota: 'ι', - iprod: '⨼', - iques: '¿', - iquest: '¿', - iscr: '𝒾', - isin: '∈', - isinE: '⋹', - isindot: '⋵', - isins: '⋴', - isinsv: '⋳', - isinv: '∈', - it: '⁢', - itilde: 'ĩ', - iukcy: 'і', - ium: 'ï', - iuml: 'ï', - jcirc: 'ĵ', - jcy: 'й', - jfr: '𝔧', - jmath: 'ȷ', - jopf: '𝕛', - jscr: '𝒿', - jsercy: 'ј', - jukcy: 'є', - kappa: 'κ', - kappav: 'ϰ', - kcedil: 'ķ', - kcy: 'к', - kfr: '𝔨', - kgreen: 'ĸ', - khcy: 'х', - kjcy: 'ќ', - kopf: '𝕜', - kscr: '𝓀', - lAarr: '⇚', - lArr: '⇐', - lAtail: '⤛', - lBarr: '⤎', - lE: '≦', - lEg: '⪋', - lHar: '⥢', - lacute: 'ĺ', - laemptyv: '⦴', - lagran: 'ℒ', - lambda: 'λ', - lang: '⟨', - langd: '⦑', - langle: '⟨', - lap: '⪅', - laqu: '«', - laquo: '«', - larr: '←', - larrb: '⇤', - larrbfs: '⤟', - larrfs: '⤝', - larrhk: '↩', - larrlp: '↫', - larrpl: '⤹', - larrsim: '⥳', - larrtl: '↢', - lat: '⪫', - latail: '⤙', - late: '⪭', - lates: '⪭︀', - lbarr: '⤌', - lbbrk: '❲', - lbrace: '{', - lbrack: '[', - lbrke: '⦋', - lbrksld: '⦏', - lbrkslu: '⦍', - lcaron: 'ľ', - lcedil: 'ļ', - lceil: '⌈', - lcub: '{', - lcy: 'л', - ldca: '⤶', - ldquo: '“', - ldquor: '„', - ldrdhar: '⥧', - ldrushar: '⥋', - ldsh: '↲', - le: '≤', - leftarrow: '←', - leftarrowtail: '↢', - leftharpoondown: '↽', - leftharpoonup: '↼', - leftleftarrows: '⇇', - leftrightarrow: '↔', - leftrightarrows: '⇆', - leftrightharpoons: '⇋', - leftrightsquigarrow: '↭', - leftthreetimes: '⋋', - leg: '⋚', - leq: '≤', - leqq: '≦', - leqslant: '⩽', - les: '⩽', - lescc: '⪨', - lesdot: '⩿', - lesdoto: '⪁', - lesdotor: '⪃', - lesg: '⋚︀', - lesges: '⪓', - lessapprox: '⪅', - lessdot: '⋖', - lesseqgtr: '⋚', - lesseqqgtr: '⪋', - lessgtr: '≶', - lesssim: '≲', - lfisht: '⥼', - lfloor: '⌊', - lfr: '𝔩', - lg: '≶', - lgE: '⪑', - lhard: '↽', - lharu: '↼', - lharul: '⥪', - lhblk: '▄', - ljcy: 'љ', - ll: '≪', - llarr: '⇇', - llcorner: '⌞', - llhard: '⥫', - lltri: '◺', - lmidot: 'ŀ', - lmoust: '⎰', - lmoustache: '⎰', - lnE: '≨', - lnap: '⪉', - lnapprox: '⪉', - lne: '⪇', - lneq: '⪇', - lneqq: '≨', - lnsim: '⋦', - loang: '⟬', - loarr: '⇽', - lobrk: '⟦', - longleftarrow: '⟵', - longleftrightarrow: '⟷', - longmapsto: '⟼', - longrightarrow: '⟶', - looparrowleft: '↫', - looparrowright: '↬', - lopar: '⦅', - lopf: '𝕝', - loplus: '⨭', - lotimes: '⨴', - lowast: '∗', - lowbar: '_', - loz: '◊', - lozenge: '◊', - lozf: '⧫', - lpar: '(', - lparlt: '⦓', - lrarr: '⇆', - lrcorner: '⌟', - lrhar: '⇋', - lrhard: '⥭', - lrm: '‎', - lrtri: '⊿', - lsaquo: '‹', - lscr: '𝓁', - lsh: '↰', - lsim: '≲', - lsime: '⪍', - lsimg: '⪏', - lsqb: '[', - lsquo: '‘', - lsquor: '‚', - lstrok: 'ł', - l: '<', - lt: '<', - ltcc: '⪦', - ltcir: '⩹', - ltdot: '⋖', - lthree: '⋋', - ltimes: '⋉', - ltlarr: '⥶', - ltquest: '⩻', - ltrPar: '⦖', - ltri: '◃', - ltrie: '⊴', - ltrif: '◂', - lurdshar: '⥊', - luruhar: '⥦', - lvertneqq: '≨︀', - lvnE: '≨︀', - mDDot: '∺', - mac: '¯', - macr: '¯', - male: '♂', - malt: '✠', - maltese: '✠', - map: '↦', - mapsto: '↦', - mapstodown: '↧', - mapstoleft: '↤', - mapstoup: '↥', - marker: '▮', - mcomma: '⨩', - mcy: 'м', - mdash: '—', - measuredangle: '∡', - mfr: '𝔪', - mho: '℧', - micr: 'µ', - micro: 'µ', - mid: '∣', - midast: '*', - midcir: '⫰', - middo: '·', - middot: '·', - minus: '−', - minusb: '⊟', - minusd: '∸', - minusdu: '⨪', - mlcp: '⫛', - mldr: '…', - mnplus: '∓', - models: '⊧', - mopf: '𝕞', - mp: '∓', - mscr: '𝓂', - mstpos: '∾', - mu: 'μ', - multimap: '⊸', - mumap: '⊸', - nGg: '⋙̸', - nGt: '≫⃒', - nGtv: '≫̸', - nLeftarrow: '⇍', - nLeftrightarrow: '⇎', - nLl: '⋘̸', - nLt: '≪⃒', - nLtv: '≪̸', - nRightarrow: '⇏', - nVDash: '⊯', - nVdash: '⊮', - nabla: '∇', - nacute: 'ń', - nang: '∠⃒', - nap: '≉', - napE: '⩰̸', - napid: '≋̸', - napos: 'ʼn', - napprox: '≉', - natur: '♮', - natural: '♮', - naturals: 'ℕ', - nbs: ' ', - nbsp: ' ', - nbump: '≎̸', - nbumpe: '≏̸', - ncap: '⩃', - ncaron: 'ň', - ncedil: 'ņ', - ncong: '≇', - ncongdot: '⩭̸', - ncup: '⩂', - ncy: 'н', - ndash: '–', - ne: '≠', - neArr: '⇗', - nearhk: '⤤', - nearr: '↗', - nearrow: '↗', - nedot: '≐̸', - nequiv: '≢', - nesear: '⤨', - nesim: '≂̸', - nexist: '∄', - nexists: '∄', - nfr: '𝔫', - ngE: '≧̸', - nge: '≱', - ngeq: '≱', - ngeqq: '≧̸', - ngeqslant: '⩾̸', - nges: '⩾̸', - ngsim: '≵', - ngt: '≯', - ngtr: '≯', - nhArr: '⇎', - nharr: '↮', - nhpar: '⫲', - ni: '∋', - nis: '⋼', - nisd: '⋺', - niv: '∋', - njcy: 'њ', - nlArr: '⇍', - nlE: '≦̸', - nlarr: '↚', - nldr: '‥', - nle: '≰', - nleftarrow: '↚', - nleftrightarrow: '↮', - nleq: '≰', - nleqq: '≦̸', - nleqslant: '⩽̸', - nles: '⩽̸', - nless: '≮', - nlsim: '≴', - nlt: '≮', - nltri: '⋪', - nltrie: '⋬', - nmid: '∤', - nopf: '𝕟', - no: '¬', - not: '¬', - notin: '∉', - notinE: '⋹̸', - notindot: '⋵̸', - notinva: '∉', - notinvb: '⋷', - notinvc: '⋶', - notni: '∌', - notniva: '∌', - notnivb: '⋾', - notnivc: '⋽', - npar: '∦', - nparallel: '∦', - nparsl: '⫽⃥', - npart: '∂̸', - npolint: '⨔', - npr: '⊀', - nprcue: '⋠', - npre: '⪯̸', - nprec: '⊀', - npreceq: '⪯̸', - nrArr: '⇏', - nrarr: '↛', - nrarrc: '⤳̸', - nrarrw: '↝̸', - nrightarrow: '↛', - nrtri: '⋫', - nrtrie: '⋭', - nsc: '⊁', - nsccue: '⋡', - nsce: '⪰̸', - nscr: '𝓃', - nshortmid: '∤', - nshortparallel: '∦', - nsim: '≁', - nsime: '≄', - nsimeq: '≄', - nsmid: '∤', - nspar: '∦', - nsqsube: '⋢', - nsqsupe: '⋣', - nsub: '⊄', - nsubE: '⫅̸', - nsube: '⊈', - nsubset: '⊂⃒', - nsubseteq: '⊈', - nsubseteqq: '⫅̸', - nsucc: '⊁', - nsucceq: '⪰̸', - nsup: '⊅', - nsupE: '⫆̸', - nsupe: '⊉', - nsupset: '⊃⃒', - nsupseteq: '⊉', - nsupseteqq: '⫆̸', - ntgl: '≹', - ntild: 'ñ', - ntilde: 'ñ', - ntlg: '≸', - ntriangleleft: '⋪', - ntrianglelefteq: '⋬', - ntriangleright: '⋫', - ntrianglerighteq: '⋭', - nu: 'ν', - num: '#', - numero: '№', - numsp: ' ', - nvDash: '⊭', - nvHarr: '⤄', - nvap: '≍⃒', - nvdash: '⊬', - nvge: '≥⃒', - nvgt: '>⃒', - nvinfin: '⧞', - nvlArr: '⤂', - nvle: '≤⃒', - nvlt: '<⃒', - nvltrie: '⊴⃒', - nvrArr: '⤃', - nvrtrie: '⊵⃒', - nvsim: '∼⃒', - nwArr: '⇖', - nwarhk: '⤣', - nwarr: '↖', - nwarrow: '↖', - nwnear: '⤧', - oS: 'Ⓢ', - oacut: 'ó', - oacute: 'ó', - oast: '⊛', - ocir: 'ô', - ocirc: 'ô', - ocy: 'о', - odash: '⊝', - odblac: 'ő', - odiv: '⨸', - odot: '⊙', - odsold: '⦼', - oelig: 'œ', - ofcir: '⦿', - ofr: '𝔬', - ogon: '˛', - ograv: 'ò', - ograve: 'ò', - ogt: '⧁', - ohbar: '⦵', - ohm: 'Ω', - oint: '∮', - olarr: '↺', - olcir: '⦾', - olcross: '⦻', - oline: '‾', - olt: '⧀', - omacr: 'ō', - omega: 'ω', - omicron: 'ο', - omid: '⦶', - ominus: '⊖', - oopf: '𝕠', - opar: '⦷', - operp: '⦹', - oplus: '⊕', - or: '∨', - orarr: '↻', - ord: 'º', - order: 'ℴ', - orderof: 'ℴ', - ordf: 'ª', - ordm: 'º', - origof: '⊶', - oror: '⩖', - orslope: '⩗', - orv: '⩛', - oscr: 'ℴ', - oslas: 'ø', - oslash: 'ø', - osol: '⊘', - otild: 'õ', - otilde: 'õ', - otimes: '⊗', - otimesas: '⨶', - oum: 'ö', - ouml: 'ö', - ovbar: '⌽', - par: '¶', - para: '¶', - parallel: '∥', - parsim: '⫳', - parsl: '⫽', - part: '∂', - pcy: 'п', - percnt: '%', - period: '.', - permil: '‰', - perp: '⊥', - pertenk: '‱', - pfr: '𝔭', - phi: 'φ', - phiv: 'ϕ', - phmmat: 'ℳ', - phone: '☎', - pi: 'π', - pitchfork: '⋔', - piv: 'ϖ', - planck: 'ℏ', - planckh: 'ℎ', - plankv: 'ℏ', - plus: '+', - plusacir: '⨣', - plusb: '⊞', - pluscir: '⨢', - plusdo: '∔', - plusdu: '⨥', - pluse: '⩲', - plusm: '±', - plusmn: '±', - plussim: '⨦', - plustwo: '⨧', - pm: '±', - pointint: '⨕', - popf: '𝕡', - poun: '£', - pound: '£', - pr: '≺', - prE: '⪳', - prap: '⪷', - prcue: '≼', - pre: '⪯', - prec: '≺', - precapprox: '⪷', - preccurlyeq: '≼', - preceq: '⪯', - precnapprox: '⪹', - precneqq: '⪵', - precnsim: '⋨', - precsim: '≾', - prime: '′', - primes: 'ℙ', - prnE: '⪵', - prnap: '⪹', - prnsim: '⋨', - prod: '∏', - profalar: '⌮', - profline: '⌒', - profsurf: '⌓', - prop: '∝', - propto: '∝', - prsim: '≾', - prurel: '⊰', - pscr: '𝓅', - psi: 'ψ', - puncsp: ' ', - qfr: '𝔮', - qint: '⨌', - qopf: '𝕢', - qprime: '⁗', - qscr: '𝓆', - quaternions: 'ℍ', - quatint: '⨖', - quest: '?', - questeq: '≟', - quo: '"', - quot: '"', - rAarr: '⇛', - rArr: '⇒', - rAtail: '⤜', - rBarr: '⤏', - rHar: '⥤', - race: '∽̱', - racute: 'ŕ', - radic: '√', - raemptyv: '⦳', - rang: '⟩', - rangd: '⦒', - range: '⦥', - rangle: '⟩', - raqu: '»', - raquo: '»', - rarr: '→', - rarrap: '⥵', - rarrb: '⇥', - rarrbfs: '⤠', - rarrc: '⤳', - rarrfs: '⤞', - rarrhk: '↪', - rarrlp: '↬', - rarrpl: '⥅', - rarrsim: '⥴', - rarrtl: '↣', - rarrw: '↝', - ratail: '⤚', - ratio: '∶', - rationals: 'ℚ', - rbarr: '⤍', - rbbrk: '❳', - rbrace: '}', - rbrack: ']', - rbrke: '⦌', - rbrksld: '⦎', - rbrkslu: '⦐', - rcaron: 'ř', - rcedil: 'ŗ', - rceil: '⌉', - rcub: '}', - rcy: 'р', - rdca: '⤷', - rdldhar: '⥩', - rdquo: '”', - rdquor: '”', - rdsh: '↳', - real: 'ℜ', - realine: 'ℛ', - realpart: 'ℜ', - reals: 'ℝ', - rect: '▭', - re: '®', - reg: '®', - rfisht: '⥽', - rfloor: '⌋', - rfr: '𝔯', - rhard: '⇁', - rharu: '⇀', - rharul: '⥬', - rho: 'ρ', - rhov: 'ϱ', - rightarrow: '→', - rightarrowtail: '↣', - rightharpoondown: '⇁', - rightharpoonup: '⇀', - rightleftarrows: '⇄', - rightleftharpoons: '⇌', - rightrightarrows: '⇉', - rightsquigarrow: '↝', - rightthreetimes: '⋌', - ring: '˚', - risingdotseq: '≓', - rlarr: '⇄', - rlhar: '⇌', - rlm: '‏', - rmoust: '⎱', - rmoustache: '⎱', - rnmid: '⫮', - roang: '⟭', - roarr: '⇾', - robrk: '⟧', - ropar: '⦆', - ropf: '𝕣', - roplus: '⨮', - rotimes: '⨵', - rpar: ')', - rpargt: '⦔', - rppolint: '⨒', - rrarr: '⇉', - rsaquo: '›', - rscr: '𝓇', - rsh: '↱', - rsqb: ']', - rsquo: '’', - rsquor: '’', - rthree: '⋌', - rtimes: '⋊', - rtri: '▹', - rtrie: '⊵', - rtrif: '▸', - rtriltri: '⧎', - ruluhar: '⥨', - rx: '℞', - sacute: 'ś', - sbquo: '‚', - sc: '≻', - scE: '⪴', - scap: '⪸', - scaron: 'š', - sccue: '≽', - sce: '⪰', - scedil: 'ş', - scirc: 'ŝ', - scnE: '⪶', - scnap: '⪺', - scnsim: '⋩', - scpolint: '⨓', - scsim: '≿', - scy: 'с', - sdot: '⋅', - sdotb: '⊡', - sdote: '⩦', - seArr: '⇘', - searhk: '⤥', - searr: '↘', - searrow: '↘', - sec: '§', - sect: '§', - semi: ';', - seswar: '⤩', - setminus: '∖', - setmn: '∖', - sext: '✶', - sfr: '𝔰', - sfrown: '⌢', - sharp: '♯', - shchcy: 'щ', - shcy: 'ш', - shortmid: '∣', - shortparallel: '∥', - sh: '­', - shy: '­', - sigma: 'σ', - sigmaf: 'ς', - sigmav: 'ς', - sim: '∼', - simdot: '⩪', - sime: '≃', - simeq: '≃', - simg: '⪞', - simgE: '⪠', - siml: '⪝', - simlE: '⪟', - simne: '≆', - simplus: '⨤', - simrarr: '⥲', - slarr: '←', - smallsetminus: '∖', - smashp: '⨳', - smeparsl: '⧤', - smid: '∣', - smile: '⌣', - smt: '⪪', - smte: '⪬', - smtes: '⪬︀', - softcy: 'ь', - sol: '/', - solb: '⧄', - solbar: '⌿', - sopf: '𝕤', - spades: '♠', - spadesuit: '♠', - spar: '∥', - sqcap: '⊓', - sqcaps: '⊓︀', - sqcup: '⊔', - sqcups: '⊔︀', - sqsub: '⊏', - sqsube: '⊑', - sqsubset: '⊏', - sqsubseteq: '⊑', - sqsup: '⊐', - sqsupe: '⊒', - sqsupset: '⊐', - sqsupseteq: '⊒', - squ: '□', - square: '□', - squarf: '▪', - squf: '▪', - srarr: '→', - sscr: '𝓈', - ssetmn: '∖', - ssmile: '⌣', - sstarf: '⋆', - star: '☆', - starf: '★', - straightepsilon: 'ϵ', - straightphi: 'ϕ', - strns: '¯', - sub: '⊂', - subE: '⫅', - subdot: '⪽', - sube: '⊆', - subedot: '⫃', - submult: '⫁', - subnE: '⫋', - subne: '⊊', - subplus: '⪿', - subrarr: '⥹', - subset: '⊂', - subseteq: '⊆', - subseteqq: '⫅', - subsetneq: '⊊', - subsetneqq: '⫋', - subsim: '⫇', - subsub: '⫕', - subsup: '⫓', - succ: '≻', - succapprox: '⪸', - succcurlyeq: '≽', - succeq: '⪰', - succnapprox: '⪺', - succneqq: '⪶', - succnsim: '⋩', - succsim: '≿', - sum: '∑', - sung: '♪', - sup: '⊃', - sup1: '¹', - sup2: '²', - sup3: '³', - supE: '⫆', - supdot: '⪾', - supdsub: '⫘', - supe: '⊇', - supedot: '⫄', - suphsol: '⟉', - suphsub: '⫗', - suplarr: '⥻', - supmult: '⫂', - supnE: '⫌', - supne: '⊋', - supplus: '⫀', - supset: '⊃', - supseteq: '⊇', - supseteqq: '⫆', - supsetneq: '⊋', - supsetneqq: '⫌', - supsim: '⫈', - supsub: '⫔', - supsup: '⫖', - swArr: '⇙', - swarhk: '⤦', - swarr: '↙', - swarrow: '↙', - swnwar: '⤪', - szli: 'ß', - szlig: 'ß', - target: '⌖', - tau: 'τ', - tbrk: '⎴', - tcaron: 'ť', - tcedil: 'ţ', - tcy: 'т', - tdot: '⃛', - telrec: '⌕', - tfr: '𝔱', - there4: '∴', - therefore: '∴', - theta: 'θ', - thetasym: 'ϑ', - thetav: 'ϑ', - thickapprox: '≈', - thicksim: '∼', - thinsp: ' ', - thkap: '≈', - thksim: '∼', - thor: 'þ', - thorn: 'þ', - tilde: '˜', - time: '×', - times: '×', - timesb: '⊠', - timesbar: '⨱', - timesd: '⨰', - tint: '∭', - toea: '⤨', - top: '⊤', - topbot: '⌶', - topcir: '⫱', - topf: '𝕥', - topfork: '⫚', - tosa: '⤩', - tprime: '‴', - trade: '™', - triangle: '▵', - triangledown: '▿', - triangleleft: '◃', - trianglelefteq: '⊴', - triangleq: '≜', - triangleright: '▹', - trianglerighteq: '⊵', - tridot: '◬', - trie: '≜', - triminus: '⨺', - triplus: '⨹', - trisb: '⧍', - tritime: '⨻', - trpezium: '⏢', - tscr: '𝓉', - tscy: 'ц', - tshcy: 'ћ', - tstrok: 'ŧ', - twixt: '≬', - twoheadleftarrow: '↞', - twoheadrightarrow: '↠', - uArr: '⇑', - uHar: '⥣', - uacut: 'ú', - uacute: 'ú', - uarr: '↑', - ubrcy: 'ў', - ubreve: 'ŭ', - ucir: 'û', - ucirc: 'û', - ucy: 'у', - udarr: '⇅', - udblac: 'ű', - udhar: '⥮', - ufisht: '⥾', - ufr: '𝔲', - ugrav: 'ù', - ugrave: 'ù', - uharl: '↿', - uharr: '↾', - uhblk: '▀', - ulcorn: '⌜', - ulcorner: '⌜', - ulcrop: '⌏', - ultri: '◸', - umacr: 'ū', - um: '¨', - uml: '¨', - uogon: 'ų', - uopf: '𝕦', - uparrow: '↑', - updownarrow: '↕', - upharpoonleft: '↿', - upharpoonright: '↾', - uplus: '⊎', - upsi: 'υ', - upsih: 'ϒ', - upsilon: 'υ', - upuparrows: '⇈', - urcorn: '⌝', - urcorner: '⌝', - urcrop: '⌎', - uring: 'ů', - urtri: '◹', - uscr: '𝓊', - utdot: '⋰', - utilde: 'ũ', - utri: '▵', - utrif: '▴', - uuarr: '⇈', - uum: 'ü', - uuml: 'ü', - uwangle: '⦧', - vArr: '⇕', - vBar: '⫨', - vBarv: '⫩', - vDash: '⊨', - vangrt: '⦜', - varepsilon: 'ϵ', - varkappa: 'ϰ', - varnothing: '∅', - varphi: 'ϕ', - varpi: 'ϖ', - varpropto: '∝', - varr: '↕', - varrho: 'ϱ', - varsigma: 'ς', - varsubsetneq: '⊊︀', - varsubsetneqq: '⫋︀', - varsupsetneq: '⊋︀', - varsupsetneqq: '⫌︀', - vartheta: 'ϑ', - vartriangleleft: '⊲', - vartriangleright: '⊳', - vcy: 'в', - vdash: '⊢', - vee: '∨', - veebar: '⊻', - veeeq: '≚', - vellip: '⋮', - verbar: '|', - vert: '|', - vfr: '𝔳', - vltri: '⊲', - vnsub: '⊂⃒', - vnsup: '⊃⃒', - vopf: '𝕧', - vprop: '∝', - vrtri: '⊳', - vscr: '𝓋', - vsubnE: '⫋︀', - vsubne: '⊊︀', - vsupnE: '⫌︀', - vsupne: '⊋︀', - vzigzag: '⦚', - wcirc: 'ŵ', - wedbar: '⩟', - wedge: '∧', - wedgeq: '≙', - weierp: '℘', - wfr: '𝔴', - wopf: '𝕨', - wp: '℘', - wr: '≀', - wreath: '≀', - wscr: '𝓌', - xcap: '⋂', - xcirc: '◯', - xcup: '⋃', - xdtri: '▽', - xfr: '𝔵', - xhArr: '⟺', - xharr: '⟷', - xi: 'ξ', - xlArr: '⟸', - xlarr: '⟵', - xmap: '⟼', - xnis: '⋻', - xodot: '⨀', - xopf: '𝕩', - xoplus: '⨁', - xotime: '⨂', - xrArr: '⟹', - xrarr: '⟶', - xscr: '𝓍', - xsqcup: '⨆', - xuplus: '⨄', - xutri: '△', - xvee: '⋁', - xwedge: '⋀', - yacut: 'ý', - yacute: 'ý', - yacy: 'я', - ycirc: 'ŷ', - ycy: 'ы', - ye: '¥', - yen: '¥', - yfr: '𝔶', - yicy: 'ї', - yopf: '𝕪', - yscr: '𝓎', - yucy: 'ю', - yum: 'ÿ', - yuml: 'ÿ', - zacute: 'ź', - zcaron: 'ž', - zcy: 'з', - zdot: 'ż', - zeetrf: 'ℨ', - zeta: 'ζ', - zfr: '𝔷', - zhcy: 'ж', - zigrarr: '⇝', - zopf: '𝕫', - zscr: '𝓏', - zwj: '‍', - zwnj: '‌' -}; - -var own$5 = {}.hasOwnProperty; - -/** - * @param {string} characters - * @returns {string|false} - */ -function decodeEntity(characters) { - return own$5.call(characterEntities, characters) - ? characterEntities[characters] - : false -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ - -/** @type {Construct} */ -const characterReference$1 = { - name: 'characterReference', - tokenize: tokenizeCharacterReference -}; -/** @type {Tokenizer} */ - -function tokenizeCharacterReference(effects, ok, nok) { - const self = this; - let size = 0; - /** @type {number} */ - - let max; - /** @type {(code: Code) => code is number} */ - - let test; - return start - /** @type {State} */ - - function start(code) { - effects.enter('characterReference'); - effects.enter('characterReferenceMarker'); - effects.consume(code); - effects.exit('characterReferenceMarker'); - return open - } - /** @type {State} */ - - function open(code) { - if (code === 35) { - effects.enter('characterReferenceMarkerNumeric'); - effects.consume(code); - effects.exit('characterReferenceMarkerNumeric'); - return numeric - } - - effects.enter('characterReferenceValue'); - max = 31; - test = asciiAlphanumeric; - return value(code) - } - /** @type {State} */ - - function numeric(code) { - if (code === 88 || code === 120) { - effects.enter('characterReferenceMarkerHexadecimal'); - effects.consume(code); - effects.exit('characterReferenceMarkerHexadecimal'); - effects.enter('characterReferenceValue'); - max = 6; - test = asciiHexDigit; - return value - } - - effects.enter('characterReferenceValue'); - max = 7; - test = asciiDigit; - return value(code) - } - /** @type {State} */ - - function value(code) { - /** @type {Token} */ - let token; - - if (code === 59 && size) { - token = effects.exit('characterReferenceValue'); - - if ( - test === asciiAlphanumeric && - !decodeEntity(self.sliceSerialize(token)) - ) { - return nok(code) - } - - effects.enter('characterReferenceMarker'); - effects.consume(code); - effects.exit('characterReferenceMarker'); - effects.exit('characterReference'); - return ok - } - - if (test(code) && size++ < max) { - effects.consume(code); - return value - } - - return nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ - -/** @type {Construct} */ -const codeFenced = { - name: 'codeFenced', - tokenize: tokenizeCodeFenced, - concrete: true -}; -/** @type {Tokenizer} */ - -function tokenizeCodeFenced(effects, ok, nok) { - const self = this; - /** @type {Construct} */ - - const closingFenceConstruct = { - tokenize: tokenizeClosingFence, - partial: true - }; - /** @type {Construct} */ - - const nonLazyLine = { - tokenize: tokenizeNonLazyLine, - partial: true - }; - const tail = this.events[this.events.length - 1]; - const initialPrefix = - tail && tail[1].type === 'linePrefix' - ? tail[2].sliceSerialize(tail[1], true).length - : 0; - let sizeOpen = 0; - /** @type {NonNullable} */ - - let marker; - return start - /** @type {State} */ - - function start(code) { - effects.enter('codeFenced'); - effects.enter('codeFencedFence'); - effects.enter('codeFencedFenceSequence'); - marker = code; - return sequenceOpen(code) - } - /** @type {State} */ - - function sequenceOpen(code) { - if (code === marker) { - effects.consume(code); - sizeOpen++; - return sequenceOpen - } - - effects.exit('codeFencedFenceSequence'); - return sizeOpen < 3 - ? nok(code) - : factorySpace(effects, infoOpen, 'whitespace')(code) - } - /** @type {State} */ - - function infoOpen(code) { - if (code === null || markdownLineEnding(code)) { - return openAfter(code) - } - - effects.enter('codeFencedFenceInfo'); - effects.enter('chunkString', { - contentType: 'string' - }); - return info(code) - } - /** @type {State} */ - - function info(code) { - if (code === null || markdownLineEndingOrSpace(code)) { - effects.exit('chunkString'); - effects.exit('codeFencedFenceInfo'); - return factorySpace(effects, infoAfter, 'whitespace')(code) - } - - if (code === 96 && code === marker) return nok(code) - effects.consume(code); - return info - } - /** @type {State} */ - - function infoAfter(code) { - if (code === null || markdownLineEnding(code)) { - return openAfter(code) - } - - effects.enter('codeFencedFenceMeta'); - effects.enter('chunkString', { - contentType: 'string' - }); - return meta(code) - } - /** @type {State} */ - - function meta(code) { - if (code === null || markdownLineEnding(code)) { - effects.exit('chunkString'); - effects.exit('codeFencedFenceMeta'); - return openAfter(code) - } - - if (code === 96 && code === marker) return nok(code) - effects.consume(code); - return meta - } - /** @type {State} */ - - function openAfter(code) { - effects.exit('codeFencedFence'); - return self.interrupt ? ok(code) : contentStart(code) - } - /** @type {State} */ - - function contentStart(code) { - if (code === null) { - return after(code) - } - - if (markdownLineEnding(code)) { - return effects.attempt( - nonLazyLine, - effects.attempt( - closingFenceConstruct, - after, - initialPrefix - ? factorySpace( - effects, - contentStart, - 'linePrefix', - initialPrefix + 1 - ) - : contentStart - ), - after - )(code) - } - - effects.enter('codeFlowValue'); - return contentContinue(code) - } - /** @type {State} */ - - function contentContinue(code) { - if (code === null || markdownLineEnding(code)) { - effects.exit('codeFlowValue'); - return contentStart(code) - } - - effects.consume(code); - return contentContinue - } - /** @type {State} */ - - function after(code) { - effects.exit('codeFenced'); - return ok(code) - } - /** @type {Tokenizer} */ - - function tokenizeNonLazyLine(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return lineStart - } - /** @type {State} */ - - function lineStart(code) { - return self.parser.lazy[self.now().line] ? nok(code) : ok(code) - } - } - /** @type {Tokenizer} */ - - function tokenizeClosingFence(effects, ok, nok) { - let size = 0; - return factorySpace( - effects, - closingSequenceStart, - 'linePrefix', - this.parser.constructs.disable.null.includes('codeIndented') - ? undefined - : 4 - ) - /** @type {State} */ - - function closingSequenceStart(code) { - effects.enter('codeFencedFence'); - effects.enter('codeFencedFenceSequence'); - return closingSequence(code) - } - /** @type {State} */ - - function closingSequence(code) { - if (code === marker) { - effects.consume(code); - size++; - return closingSequence - } - - if (size < sizeOpen) return nok(code) - effects.exit('codeFencedFenceSequence'); - return factorySpace(effects, closingSequenceEnd, 'whitespace')(code) - } - /** @type {State} */ - - function closingSequenceEnd(code) { - if (code === null || markdownLineEnding(code)) { - effects.exit('codeFencedFence'); - return ok(code) - } - - return nok(code) - } - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const codeIndented = { - name: 'codeIndented', - tokenize: tokenizeCodeIndented -}; -/** @type {Construct} */ - -const indentedContent = { - tokenize: tokenizeIndentedContent, - partial: true -}; -/** @type {Tokenizer} */ - -function tokenizeCodeIndented(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - effects.enter('codeIndented'); - return factorySpace(effects, afterStartPrefix, 'linePrefix', 4 + 1)(code) - } - /** @type {State} */ - - function afterStartPrefix(code) { - const tail = self.events[self.events.length - 1]; - return tail && - tail[1].type === 'linePrefix' && - tail[2].sliceSerialize(tail[1], true).length >= 4 - ? afterPrefix(code) - : nok(code) - } - /** @type {State} */ - - function afterPrefix(code) { - if (code === null) { - return after(code) - } - - if (markdownLineEnding(code)) { - return effects.attempt(indentedContent, afterPrefix, after)(code) - } - - effects.enter('codeFlowValue'); - return content(code) - } - /** @type {State} */ - - function content(code) { - if (code === null || markdownLineEnding(code)) { - effects.exit('codeFlowValue'); - return afterPrefix(code) - } - - effects.consume(code); - return content - } - /** @type {State} */ - - function after(code) { - effects.exit('codeIndented'); - return ok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeIndentedContent(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - // If this is a lazy line, it can’t be code. - if (self.parser.lazy[self.now().line]) { - return nok(code) - } - - if (markdownLineEnding(code)) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return start - } - - return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) - } - /** @type {State} */ - - function afterPrefix(code) { - const tail = self.events[self.events.length - 1]; - return tail && - tail[1].type === 'linePrefix' && - tail[2].sliceSerialize(tail[1], true).length >= 4 - ? ok(code) - : markdownLineEnding(code) - ? start(code) - : nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Previous} Previous - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const codeText = { - name: 'codeText', - tokenize: tokenizeCodeText, - resolve: resolveCodeText, - previous: previous$1 -}; -/** @type {Resolver} */ - -function resolveCodeText(events) { - let tailExitIndex = events.length - 4; - let headEnterIndex = 3; - /** @type {number} */ - - let index; - /** @type {number|undefined} */ - - let enter; // If we start and end with an EOL or a space. - - if ( - (events[headEnterIndex][1].type === 'lineEnding' || - events[headEnterIndex][1].type === 'space') && - (events[tailExitIndex][1].type === 'lineEnding' || - events[tailExitIndex][1].type === 'space') - ) { - index = headEnterIndex; // And we have data. - - while (++index < tailExitIndex) { - if (events[index][1].type === 'codeTextData') { - // Then we have padding. - events[headEnterIndex][1].type = 'codeTextPadding'; - events[tailExitIndex][1].type = 'codeTextPadding'; - headEnterIndex += 2; - tailExitIndex -= 2; - break - } - } - } // Merge adjacent spaces and data. - - index = headEnterIndex - 1; - tailExitIndex++; - - while (++index <= tailExitIndex) { - if (enter === undefined) { - if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { - enter = index; - } - } else if ( - index === tailExitIndex || - events[index][1].type === 'lineEnding' - ) { - events[enter][1].type = 'codeTextData'; - - if (index !== enter + 2) { - events[enter][1].end = events[index - 1][1].end; - events.splice(enter + 2, index - enter - 2); - tailExitIndex -= index - enter - 2; - index = enter + 2; - } - - enter = undefined; - } - } - - return events -} -/** @type {Previous} */ - -function previous$1(code) { - // If there is a previous code, there will always be a tail. - return ( - code !== 96 || - this.events[this.events.length - 1][1].type === 'characterEscape' - ) -} -/** @type {Tokenizer} */ - -function tokenizeCodeText(effects, ok, nok) { - let sizeOpen = 0; - /** @type {number} */ - - let size; - /** @type {Token} */ - - let token; - return start - /** @type {State} */ - - function start(code) { - effects.enter('codeText'); - effects.enter('codeTextSequence'); - return openingSequence(code) - } - /** @type {State} */ - - function openingSequence(code) { - if (code === 96) { - effects.consume(code); - sizeOpen++; - return openingSequence - } - - effects.exit('codeTextSequence'); - return gap(code) - } - /** @type {State} */ - - function gap(code) { - // EOF. - if (code === null) { - return nok(code) - } // Closing fence? - // Could also be data. - - if (code === 96) { - token = effects.enter('codeTextSequence'); - size = 0; - return closingSequence(code) - } // Tabs don’t work, and virtual spaces don’t make sense. - - if (code === 32) { - effects.enter('space'); - effects.consume(code); - effects.exit('space'); - return gap - } - - if (markdownLineEnding(code)) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return gap - } // Data. - - effects.enter('codeTextData'); - return data(code) - } // In code. - - /** @type {State} */ - - function data(code) { - if ( - code === null || - code === 32 || - code === 96 || - markdownLineEnding(code) - ) { - effects.exit('codeTextData'); - return gap(code) - } - - effects.consume(code); - return data - } // Closing fence. - - /** @type {State} */ - - function closingSequence(code) { - // More. - if (code === 96) { - effects.consume(code); - size++; - return closingSequence - } // Done! - - if (size === sizeOpen) { - effects.exit('codeTextSequence'); - effects.exit('codeText'); - return ok(code) - } // More or less accents: mark as data. - - token.type = 'codeTextData'; - return data(code) - } -} - -/** - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').Chunk} Chunk - * @typedef {import('micromark-util-types').Event} Event - */ - -/** - * Tokenize subcontent. - * - * @param {Event[]} events - * @returns {boolean} - */ -function subtokenize(events) { - /** @type {Record} */ - const jumps = {}; - let index = -1; - /** @type {Event} */ - - let event; - /** @type {number|undefined} */ - - let lineIndex; - /** @type {number} */ - - let otherIndex; - /** @type {Event} */ - - let otherEvent; - /** @type {Event[]} */ - - let parameters; - /** @type {Event[]} */ - - let subevents; - /** @type {boolean|undefined} */ - - let more; - - while (++index < events.length) { - while (index in jumps) { - index = jumps[index]; - } - - event = events[index]; // Add a hook for the GFM tasklist extension, which needs to know if text - // is in the first content of a list item. - - if ( - index && - event[1].type === 'chunkFlow' && - events[index - 1][1].type === 'listItemPrefix' - ) { - subevents = event[1]._tokenizer.events; - otherIndex = 0; - - if ( - otherIndex < subevents.length && - subevents[otherIndex][1].type === 'lineEndingBlank' - ) { - otherIndex += 2; - } - - if ( - otherIndex < subevents.length && - subevents[otherIndex][1].type === 'content' - ) { - while (++otherIndex < subevents.length) { - if (subevents[otherIndex][1].type === 'content') { - break - } - - if (subevents[otherIndex][1].type === 'chunkText') { - subevents[otherIndex][1]._isInFirstContentOfListItem = true; - otherIndex++; - } - } - } - } // Enter. - - if (event[0] === 'enter') { - if (event[1].contentType) { - Object.assign(jumps, subcontent(events, index)); - index = jumps[index]; - more = true; - } - } // Exit. - else if (event[1]._container) { - otherIndex = index; - lineIndex = undefined; - - while (otherIndex--) { - otherEvent = events[otherIndex]; - - if ( - otherEvent[1].type === 'lineEnding' || - otherEvent[1].type === 'lineEndingBlank' - ) { - if (otherEvent[0] === 'enter') { - if (lineIndex) { - events[lineIndex][1].type = 'lineEndingBlank'; - } - - otherEvent[1].type = 'lineEnding'; - lineIndex = otherIndex; - } - } else { - break - } - } - - if (lineIndex) { - // Fix position. - event[1].end = Object.assign({}, events[lineIndex][1].start); // Switch container exit w/ line endings. - - parameters = events.slice(lineIndex, index); - parameters.unshift(event); - splice(events, lineIndex, index - lineIndex + 1, parameters); - } - } - } - - return !more -} -/** - * Tokenize embedded tokens. - * - * @param {Event[]} events - * @param {number} eventIndex - * @returns {Record} - */ - -function subcontent(events, eventIndex) { - const token = events[eventIndex][1]; - const context = events[eventIndex][2]; - let startPosition = eventIndex - 1; - /** @type {number[]} */ - - const startPositions = []; - const tokenizer = - token._tokenizer || context.parser[token.contentType](token.start); - const childEvents = tokenizer.events; - /** @type {[number, number][]} */ - - const jumps = []; - /** @type {Record} */ - - const gaps = {}; - /** @type {Chunk[]} */ - - let stream; - /** @type {Token|undefined} */ - - let previous; - let index = -1; - /** @type {Token|undefined} */ - - let current = token; - let adjust = 0; - let start = 0; - const breaks = [start]; // Loop forward through the linked tokens to pass them in order to the - // subtokenizer. - - while (current) { - // Find the position of the event for this token. - while (events[++startPosition][1] !== current) { - // Empty. - } - - startPositions.push(startPosition); - - if (!current._tokenizer) { - stream = context.sliceStream(current); - - if (!current.next) { - stream.push(null); - } - - if (previous) { - tokenizer.defineSkip(current.start); - } - - if (current._isInFirstContentOfListItem) { - tokenizer._gfmTasklistFirstContentOfListItem = true; - } - - tokenizer.write(stream); - - if (current._isInFirstContentOfListItem) { - tokenizer._gfmTasklistFirstContentOfListItem = undefined; - } - } // Unravel the next token. - - previous = current; - current = current.next; - } // Now, loop back through all events (and linked tokens), to figure out which - // parts belong where. - - current = token; - - while (++index < childEvents.length) { - if ( - // Find a void token that includes a break. - childEvents[index][0] === 'exit' && - childEvents[index - 1][0] === 'enter' && - childEvents[index][1].type === childEvents[index - 1][1].type && - childEvents[index][1].start.line !== childEvents[index][1].end.line - ) { - start = index + 1; - breaks.push(start); // Help GC. - - current._tokenizer = undefined; - current.previous = undefined; - current = current.next; - } - } // Help GC. - - tokenizer.events = []; // If there’s one more token (which is the cases for lines that end in an - // EOF), that’s perfect: the last point we found starts it. - // If there isn’t then make sure any remaining content is added to it. - - if (current) { - // Help GC. - current._tokenizer = undefined; - current.previous = undefined; - } else { - breaks.pop(); - } // Now splice the events from the subtokenizer into the current events, - // moving back to front so that splice indices aren’t affected. - - index = breaks.length; - - while (index--) { - const slice = childEvents.slice(breaks[index], breaks[index + 1]); - const start = startPositions.pop(); - jumps.unshift([start, start + slice.length - 1]); - splice(events, start, 2, slice); - } - - index = -1; - - while (++index < jumps.length) { - gaps[adjust + jumps[index][0]] = adjust + jumps[index][1]; - adjust += jumps[index][1] - jumps[index][0] - 1; - } - - return gaps -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').State} State - */ - -/** - * No name because it must not be turned off. - * @type {Construct} - */ -const content = { - tokenize: tokenizeContent, - resolve: resolveContent -}; -/** @type {Construct} */ - -const continuationConstruct = { - tokenize: tokenizeContinuation, - partial: true -}; -/** - * Content is transparent: it’s parsed right now. That way, definitions are also - * parsed right now: before text in paragraphs (specifically, media) are parsed. - * - * @type {Resolver} - */ - -function resolveContent(events) { - subtokenize(events); - return events -} -/** @type {Tokenizer} */ - -function tokenizeContent(effects, ok) { - /** @type {Token} */ - let previous; - return start - /** @type {State} */ - - function start(code) { - effects.enter('content'); - previous = effects.enter('chunkContent', { - contentType: 'content' - }); - return data(code) - } - /** @type {State} */ - - function data(code) { - if (code === null) { - return contentEnd(code) - } - - if (markdownLineEnding(code)) { - return effects.check( - continuationConstruct, - contentContinue, - contentEnd - )(code) - } // Data. - - effects.consume(code); - return data - } - /** @type {State} */ - - function contentEnd(code) { - effects.exit('chunkContent'); - effects.exit('content'); - return ok(code) - } - /** @type {State} */ - - function contentContinue(code) { - effects.consume(code); - effects.exit('chunkContent'); - previous.next = effects.enter('chunkContent', { - contentType: 'content', - previous - }); - previous = previous.next; - return data - } -} -/** @type {Tokenizer} */ - -function tokenizeContinuation(effects, ok, nok) { - const self = this; - return startLookahead - /** @type {State} */ - - function startLookahead(code) { - effects.exit('chunkContent'); - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return factorySpace(effects, prefixed, 'linePrefix') - } - /** @type {State} */ - - function prefixed(code) { - if (code === null || markdownLineEnding(code)) { - return nok(code) - } - - const tail = self.events[self.events.length - 1]; - - if ( - !self.parser.constructs.disable.null.includes('codeIndented') && - tail && - tail[1].type === 'linePrefix' && - tail[2].sliceSerialize(tail[1], true).length >= 4 - ) { - return ok(code) - } - - return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) - } -} - -/** - * @typedef {import('micromark-util-types').Effects} Effects - * @typedef {import('micromark-util-types').State} State - */ - -/** - * @param {Effects} effects - * @param {State} ok - * @param {State} nok - * @param {string} type - * @param {string} literalType - * @param {string} literalMarkerType - * @param {string} rawType - * @param {string} stringType - * @param {number} [max=Infinity] - * @returns {State} - */ -// eslint-disable-next-line max-params -function factoryDestination( - effects, - ok, - nok, - type, - literalType, - literalMarkerType, - rawType, - stringType, - max -) { - const limit = max || Number.POSITIVE_INFINITY; - let balance = 0; - return start - /** @type {State} */ - - function start(code) { - if (code === 60) { - effects.enter(type); - effects.enter(literalType); - effects.enter(literalMarkerType); - effects.consume(code); - effects.exit(literalMarkerType); - return destinationEnclosedBefore - } - - if (code === null || code === 41 || asciiControl(code)) { - return nok(code) - } - - effects.enter(type); - effects.enter(rawType); - effects.enter(stringType); - effects.enter('chunkString', { - contentType: 'string' - }); - return destinationRaw(code) - } - /** @type {State} */ - - function destinationEnclosedBefore(code) { - if (code === 62) { - effects.enter(literalMarkerType); - effects.consume(code); - effects.exit(literalMarkerType); - effects.exit(literalType); - effects.exit(type); - return ok - } - - effects.enter(stringType); - effects.enter('chunkString', { - contentType: 'string' - }); - return destinationEnclosed(code) - } - /** @type {State} */ - - function destinationEnclosed(code) { - if (code === 62) { - effects.exit('chunkString'); - effects.exit(stringType); - return destinationEnclosedBefore(code) - } - - if (code === null || code === 60 || markdownLineEnding(code)) { - return nok(code) - } - - effects.consume(code); - return code === 92 ? destinationEnclosedEscape : destinationEnclosed - } - /** @type {State} */ - - function destinationEnclosedEscape(code) { - if (code === 60 || code === 62 || code === 92) { - effects.consume(code); - return destinationEnclosed - } - - return destinationEnclosed(code) - } - /** @type {State} */ - - function destinationRaw(code) { - if (code === 40) { - if (++balance > limit) return nok(code) - effects.consume(code); - return destinationRaw - } - - if (code === 41) { - if (!balance--) { - effects.exit('chunkString'); - effects.exit(stringType); - effects.exit(rawType); - effects.exit(type); - return ok(code) - } - - effects.consume(code); - return destinationRaw - } - - if (code === null || markdownLineEndingOrSpace(code)) { - if (balance) return nok(code) - effects.exit('chunkString'); - effects.exit(stringType); - effects.exit(rawType); - effects.exit(type); - return ok(code) - } - - if (asciiControl(code)) return nok(code) - effects.consume(code); - return code === 92 ? destinationRawEscape : destinationRaw - } - /** @type {State} */ - - function destinationRawEscape(code) { - if (code === 40 || code === 41 || code === 92) { - effects.consume(code); - return destinationRaw - } - - return destinationRaw(code) - } -} - -/** - * @typedef {import('micromark-util-types').Effects} Effects - * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext - * @typedef {import('micromark-util-types').State} State - */ - -/** - * @this {TokenizeContext} - * @param {Effects} effects - * @param {State} ok - * @param {State} nok - * @param {string} type - * @param {string} markerType - * @param {string} stringType - * @returns {State} - */ -// eslint-disable-next-line max-params -function factoryLabel(effects, ok, nok, type, markerType, stringType) { - const self = this; - let size = 0; - /** @type {boolean} */ - - let data; - return start - /** @type {State} */ - - function start(code) { - effects.enter(type); - effects.enter(markerType); - effects.consume(code); - effects.exit(markerType); - effects.enter(stringType); - return atBreak - } - /** @type {State} */ - - function atBreak(code) { - if ( - code === null || - code === 91 || - (code === 93 && !data) || - /* Hidden footnotes hook */ - - /* c8 ignore next 3 */ - (code === 94 && - !size && - '_hiddenFootnoteSupport' in self.parser.constructs) || - size > 999 - ) { - return nok(code) - } - - if (code === 93) { - effects.exit(stringType); - effects.enter(markerType); - effects.consume(code); - effects.exit(markerType); - effects.exit(type); - return ok - } - - if (markdownLineEnding(code)) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return atBreak - } - - effects.enter('chunkString', { - contentType: 'string' - }); - return label(code) - } - /** @type {State} */ - - function label(code) { - if ( - code === null || - code === 91 || - code === 93 || - markdownLineEnding(code) || - size++ > 999 - ) { - effects.exit('chunkString'); - return atBreak(code) - } - - effects.consume(code); - data = data || !markdownSpace(code); - return code === 92 ? labelEscape : label - } - /** @type {State} */ - - function labelEscape(code) { - if (code === 91 || code === 92 || code === 93) { - effects.consume(code); - size++; - return label - } - - return label(code) - } -} - -/** - * @typedef {import('micromark-util-types').Effects} Effects - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ - -/** - * @param {Effects} effects - * @param {State} ok - * @param {State} nok - * @param {string} type - * @param {string} markerType - * @param {string} stringType - * @returns {State} - */ -// eslint-disable-next-line max-params -function factoryTitle(effects, ok, nok, type, markerType, stringType) { - /** @type {NonNullable} */ - let marker; - return start - /** @type {State} */ - - function start(code) { - effects.enter(type); - effects.enter(markerType); - effects.consume(code); - effects.exit(markerType); - marker = code === 40 ? 41 : code; - return atFirstTitleBreak - } - /** @type {State} */ - - function atFirstTitleBreak(code) { - if (code === marker) { - effects.enter(markerType); - effects.consume(code); - effects.exit(markerType); - effects.exit(type); - return ok - } - - effects.enter(stringType); - return atTitleBreak(code) - } - /** @type {State} */ - - function atTitleBreak(code) { - if (code === marker) { - effects.exit(stringType); - return atFirstTitleBreak(marker) - } - - if (code === null) { - return nok(code) - } // Note: blank lines can’t exist in content. - - if (markdownLineEnding(code)) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return factorySpace(effects, atTitleBreak, 'linePrefix') - } - - effects.enter('chunkString', { - contentType: 'string' - }); - return title(code) - } - /** @type {State} */ - - function title(code) { - if (code === marker || code === null || markdownLineEnding(code)) { - effects.exit('chunkString'); - return atTitleBreak(code) - } - - effects.consume(code); - return code === 92 ? titleEscape : title - } - /** @type {State} */ - - function titleEscape(code) { - if (code === marker || code === 92) { - effects.consume(code); - return title - } - - return title(code) - } -} - -/** - * @typedef {import('micromark-util-types').Effects} Effects - * @typedef {import('micromark-util-types').State} State - */ - -/** - * @param {Effects} effects - * @param {State} ok - */ -function factoryWhitespace(effects, ok) { - /** @type {boolean} */ - let seen; - return start - /** @type {State} */ - - function start(code) { - if (markdownLineEnding(code)) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - seen = true; - return start - } - - if (markdownSpace(code)) { - return factorySpace( - effects, - start, - seen ? 'linePrefix' : 'lineSuffix' - )(code) - } - - return ok(code) - } -} - -/** - * Normalize an identifier (such as used in definitions). - * - * @param {string} value - * @returns {string} - */ -function normalizeIdentifier(value) { - return ( - value // Collapse Markdown whitespace. - .replace(/[\t\n\r ]+/g, ' ') // Trim. - .replace(/^ | $/g, '') // Some characters are considered “uppercase”, but if their lowercase - // counterpart is uppercased will result in a different uppercase - // character. - // Hence, to get that form, we perform both lower- and uppercase. - // Upper case makes sure keys will not interact with default prototypal - // methods: no method is uppercase. - .toLowerCase() - .toUpperCase() - ) -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const definition$1 = { - name: 'definition', - tokenize: tokenizeDefinition -}; -/** @type {Construct} */ - -const titleConstruct = { - tokenize: tokenizeTitle, - partial: true -}; -/** @type {Tokenizer} */ - -function tokenizeDefinition(effects, ok, nok) { - const self = this; - /** @type {string} */ - - let identifier; - return start - /** @type {State} */ - - function start(code) { - effects.enter('definition'); - return factoryLabel.call( - self, - effects, - labelAfter, - nok, - 'definitionLabel', - 'definitionLabelMarker', - 'definitionLabelString' - )(code) - } - /** @type {State} */ - - function labelAfter(code) { - identifier = normalizeIdentifier( - self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) - ); - - if (code === 58) { - effects.enter('definitionMarker'); - effects.consume(code); - effects.exit('definitionMarker'); // Note: blank lines can’t exist in content. - - return factoryWhitespace( - effects, - factoryDestination( - effects, - effects.attempt( - titleConstruct, - factorySpace(effects, after, 'whitespace'), - factorySpace(effects, after, 'whitespace') - ), - nok, - 'definitionDestination', - 'definitionDestinationLiteral', - 'definitionDestinationLiteralMarker', - 'definitionDestinationRaw', - 'definitionDestinationString' - ) - ) - } - - return nok(code) - } - /** @type {State} */ - - function after(code) { - if (code === null || markdownLineEnding(code)) { - effects.exit('definition'); - - if (!self.parser.defined.includes(identifier)) { - self.parser.defined.push(identifier); - } - - return ok(code) - } - - return nok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeTitle(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - return markdownLineEndingOrSpace(code) - ? factoryWhitespace(effects, before)(code) - : nok(code) - } - /** @type {State} */ - - function before(code) { - if (code === 34 || code === 39 || code === 40) { - return factoryTitle( - effects, - factorySpace(effects, after, 'whitespace'), - nok, - 'definitionTitle', - 'definitionTitleMarker', - 'definitionTitleString' - )(code) - } - - return nok(code) - } - /** @type {State} */ - - function after(code) { - return code === null || markdownLineEnding(code) ? ok(code) : nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const hardBreakEscape = { - name: 'hardBreakEscape', - tokenize: tokenizeHardBreakEscape -}; -/** @type {Tokenizer} */ - -function tokenizeHardBreakEscape(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.enter('hardBreakEscape'); - effects.enter('escapeMarker'); - effects.consume(code); - return open - } - /** @type {State} */ - - function open(code) { - if (markdownLineEnding(code)) { - effects.exit('escapeMarker'); - effects.exit('hardBreakEscape'); - return ok(code) - } - - return nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const headingAtx = { - name: 'headingAtx', - tokenize: tokenizeHeadingAtx, - resolve: resolveHeadingAtx -}; -/** @type {Resolver} */ - -function resolveHeadingAtx(events, context) { - let contentEnd = events.length - 2; - let contentStart = 3; - /** @type {Token} */ - - let content; - /** @type {Token} */ - - let text; // Prefix whitespace, part of the opening. - - if (events[contentStart][1].type === 'whitespace') { - contentStart += 2; - } // Suffix whitespace, part of the closing. - - if ( - contentEnd - 2 > contentStart && - events[contentEnd][1].type === 'whitespace' - ) { - contentEnd -= 2; - } - - if ( - events[contentEnd][1].type === 'atxHeadingSequence' && - (contentStart === contentEnd - 1 || - (contentEnd - 4 > contentStart && - events[contentEnd - 2][1].type === 'whitespace')) - ) { - contentEnd -= contentStart + 1 === contentEnd ? 2 : 4; - } - - if (contentEnd > contentStart) { - content = { - type: 'atxHeadingText', - start: events[contentStart][1].start, - end: events[contentEnd][1].end - }; - text = { - type: 'chunkText', - start: events[contentStart][1].start, - end: events[contentEnd][1].end, - // @ts-expect-error Constants are fine to assign. - contentType: 'text' - }; - splice(events, contentStart, contentEnd - contentStart + 1, [ - ['enter', content, context], - ['enter', text, context], - ['exit', text, context], - ['exit', content, context] - ]); - } - - return events -} -/** @type {Tokenizer} */ - -function tokenizeHeadingAtx(effects, ok, nok) { - const self = this; - let size = 0; - return start - /** @type {State} */ - - function start(code) { - effects.enter('atxHeading'); - effects.enter('atxHeadingSequence'); - return fenceOpenInside(code) - } - /** @type {State} */ - - function fenceOpenInside(code) { - if (code === 35 && size++ < 6) { - effects.consume(code); - return fenceOpenInside - } - - if (code === null || markdownLineEndingOrSpace(code)) { - effects.exit('atxHeadingSequence'); - return self.interrupt ? ok(code) : headingBreak(code) - } - - return nok(code) - } - /** @type {State} */ - - function headingBreak(code) { - if (code === 35) { - effects.enter('atxHeadingSequence'); - return sequence(code) - } - - if (code === null || markdownLineEnding(code)) { - effects.exit('atxHeading'); - return ok(code) - } - - if (markdownSpace(code)) { - return factorySpace(effects, headingBreak, 'whitespace')(code) - } - - effects.enter('atxHeadingText'); - return data(code) - } - /** @type {State} */ - - function sequence(code) { - if (code === 35) { - effects.consume(code); - return sequence - } - - effects.exit('atxHeadingSequence'); - return headingBreak(code) - } - /** @type {State} */ - - function data(code) { - if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { - effects.exit('atxHeadingText'); - return headingBreak(code) - } - - effects.consume(code); - return data - } -} - -/** - * List of lowercase HTML tag names which when parsing HTML (flow), result - * in more relaxed rules (condition 6): because they are known blocks, the - * HTML-like syntax doesn’t have to be strictly parsed. - * For tag names not in this list, a more strict algorithm (condition 7) is used - * to detect whether the HTML-like syntax is seen as HTML (flow) or not. - * - * This is copied from: - * . - */ -const htmlBlockNames = [ - 'address', - 'article', - 'aside', - 'base', - 'basefont', - 'blockquote', - 'body', - 'caption', - 'center', - 'col', - 'colgroup', - 'dd', - 'details', - 'dialog', - 'dir', - 'div', - 'dl', - 'dt', - 'fieldset', - 'figcaption', - 'figure', - 'footer', - 'form', - 'frame', - 'frameset', - 'h1', - 'h2', - 'h3', - 'h4', - 'h5', - 'h6', - 'head', - 'header', - 'hr', - 'html', - 'iframe', - 'legend', - 'li', - 'link', - 'main', - 'menu', - 'menuitem', - 'nav', - 'noframes', - 'ol', - 'optgroup', - 'option', - 'p', - 'param', - 'section', - 'source', - 'summary', - 'table', - 'tbody', - 'td', - 'tfoot', - 'th', - 'thead', - 'title', - 'tr', - 'track', - 'ul' -]; - -/** - * List of lowercase HTML tag names which when parsing HTML (flow), result in - * HTML that can include lines w/o exiting, until a closing tag also in this - * list is found (condition 1). - * - * This module is copied from: - * . - * - * Note that `textarea` is not available in `CommonMark@0.29` but has been - * merged to the primary branch and is slated to be released in the next release - * of CommonMark. - */ -const htmlRawNames = ['pre', 'script', 'style', 'textarea']; - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ -/** @type {Construct} */ - -const htmlFlow = { - name: 'htmlFlow', - tokenize: tokenizeHtmlFlow, - resolveTo: resolveToHtmlFlow, - concrete: true -}; -/** @type {Construct} */ - -const nextBlankConstruct = { - tokenize: tokenizeNextBlank, - partial: true -}; -/** @type {Resolver} */ - -function resolveToHtmlFlow(events) { - let index = events.length; - - while (index--) { - if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { - break - } - } - - if (index > 1 && events[index - 2][1].type === 'linePrefix') { - // Add the prefix start to the HTML token. - events[index][1].start = events[index - 2][1].start; // Add the prefix start to the HTML line token. - - events[index + 1][1].start = events[index - 2][1].start; // Remove the line prefix. - - events.splice(index - 2, 2); - } - - return events -} -/** @type {Tokenizer} */ - -function tokenizeHtmlFlow(effects, ok, nok) { - const self = this; - /** @type {number} */ - - let kind; - /** @type {boolean} */ - - let startTag; - /** @type {string} */ - - let buffer; - /** @type {number} */ - - let index; - /** @type {Code} */ - - let marker; - return start - /** @type {State} */ - - function start(code) { - effects.enter('htmlFlow'); - effects.enter('htmlFlowData'); - effects.consume(code); - return open - } - /** @type {State} */ - - function open(code) { - if (code === 33) { - effects.consume(code); - return declarationStart - } - - if (code === 47) { - effects.consume(code); - return tagCloseStart - } - - if (code === 63) { - effects.consume(code); - kind = 3; // While we’re in an instruction instead of a declaration, we’re on a `?` - // right now, so we do need to search for `>`, similar to declarations. - - return self.interrupt ? ok : continuationDeclarationInside - } - - if (asciiAlpha(code)) { - effects.consume(code); - buffer = String.fromCharCode(code); - startTag = true; - return tagName - } - - return nok(code) - } - /** @type {State} */ - - function declarationStart(code) { - if (code === 45) { - effects.consume(code); - kind = 2; - return commentOpenInside - } - - if (code === 91) { - effects.consume(code); - kind = 5; - buffer = 'CDATA['; - index = 0; - return cdataOpenInside - } - - if (asciiAlpha(code)) { - effects.consume(code); - kind = 4; - return self.interrupt ? ok : continuationDeclarationInside - } - - return nok(code) - } - /** @type {State} */ - - function commentOpenInside(code) { - if (code === 45) { - effects.consume(code); - return self.interrupt ? ok : continuationDeclarationInside - } - - return nok(code) - } - /** @type {State} */ - - function cdataOpenInside(code) { - if (code === buffer.charCodeAt(index++)) { - effects.consume(code); - return index === buffer.length - ? self.interrupt - ? ok - : continuation - : cdataOpenInside - } - - return nok(code) - } - /** @type {State} */ - - function tagCloseStart(code) { - if (asciiAlpha(code)) { - effects.consume(code); - buffer = String.fromCharCode(code); - return tagName - } - - return nok(code) - } - /** @type {State} */ - - function tagName(code) { - if ( - code === null || - code === 47 || - code === 62 || - markdownLineEndingOrSpace(code) - ) { - if ( - code !== 47 && - startTag && - htmlRawNames.includes(buffer.toLowerCase()) - ) { - kind = 1; - return self.interrupt ? ok(code) : continuation(code) - } - - if (htmlBlockNames.includes(buffer.toLowerCase())) { - kind = 6; - - if (code === 47) { - effects.consume(code); - return basicSelfClosing - } - - return self.interrupt ? ok(code) : continuation(code) - } - - kind = 7; // Do not support complete HTML when interrupting - - return self.interrupt && !self.parser.lazy[self.now().line] - ? nok(code) - : startTag - ? completeAttributeNameBefore(code) - : completeClosingTagAfter(code) - } - - if (code === 45 || asciiAlphanumeric(code)) { - effects.consume(code); - buffer += String.fromCharCode(code); - return tagName - } - - return nok(code) - } - /** @type {State} */ - - function basicSelfClosing(code) { - if (code === 62) { - effects.consume(code); - return self.interrupt ? ok : continuation - } - - return nok(code) - } - /** @type {State} */ - - function completeClosingTagAfter(code) { - if (markdownSpace(code)) { - effects.consume(code); - return completeClosingTagAfter - } - - return completeEnd(code) - } - /** @type {State} */ - - function completeAttributeNameBefore(code) { - if (code === 47) { - effects.consume(code); - return completeEnd - } - - if (code === 58 || code === 95 || asciiAlpha(code)) { - effects.consume(code); - return completeAttributeName - } - - if (markdownSpace(code)) { - effects.consume(code); - return completeAttributeNameBefore - } - - return completeEnd(code) - } - /** @type {State} */ - - function completeAttributeName(code) { - if ( - code === 45 || - code === 46 || - code === 58 || - code === 95 || - asciiAlphanumeric(code) - ) { - effects.consume(code); - return completeAttributeName - } - - return completeAttributeNameAfter(code) - } - /** @type {State} */ - - function completeAttributeNameAfter(code) { - if (code === 61) { - effects.consume(code); - return completeAttributeValueBefore - } - - if (markdownSpace(code)) { - effects.consume(code); - return completeAttributeNameAfter - } - - return completeAttributeNameBefore(code) - } - /** @type {State} */ - - function completeAttributeValueBefore(code) { - if ( - code === null || - code === 60 || - code === 61 || - code === 62 || - code === 96 - ) { - return nok(code) - } - - if (code === 34 || code === 39) { - effects.consume(code); - marker = code; - return completeAttributeValueQuoted - } - - if (markdownSpace(code)) { - effects.consume(code); - return completeAttributeValueBefore - } - - marker = null; - return completeAttributeValueUnquoted(code) - } - /** @type {State} */ - - function completeAttributeValueQuoted(code) { - if (code === null || markdownLineEnding(code)) { - return nok(code) - } - - if (code === marker) { - effects.consume(code); - return completeAttributeValueQuotedAfter - } - - effects.consume(code); - return completeAttributeValueQuoted - } - /** @type {State} */ - - function completeAttributeValueUnquoted(code) { - if ( - code === null || - code === 34 || - code === 39 || - code === 60 || - code === 61 || - code === 62 || - code === 96 || - markdownLineEndingOrSpace(code) - ) { - return completeAttributeNameAfter(code) - } - - effects.consume(code); - return completeAttributeValueUnquoted - } - /** @type {State} */ - - function completeAttributeValueQuotedAfter(code) { - if (code === 47 || code === 62 || markdownSpace(code)) { - return completeAttributeNameBefore(code) - } - - return nok(code) - } - /** @type {State} */ - - function completeEnd(code) { - if (code === 62) { - effects.consume(code); - return completeAfter - } - - return nok(code) - } - /** @type {State} */ - - function completeAfter(code) { - if (markdownSpace(code)) { - effects.consume(code); - return completeAfter - } - - return code === null || markdownLineEnding(code) - ? continuation(code) - : nok(code) - } - /** @type {State} */ - - function continuation(code) { - if (code === 45 && kind === 2) { - effects.consume(code); - return continuationCommentInside - } - - if (code === 60 && kind === 1) { - effects.consume(code); - return continuationRawTagOpen - } - - if (code === 62 && kind === 4) { - effects.consume(code); - return continuationClose - } - - if (code === 63 && kind === 3) { - effects.consume(code); - return continuationDeclarationInside - } - - if (code === 93 && kind === 5) { - effects.consume(code); - return continuationCharacterDataInside - } - - if (markdownLineEnding(code) && (kind === 6 || kind === 7)) { - return effects.check( - nextBlankConstruct, - continuationClose, - continuationAtLineEnding - )(code) - } - - if (code === null || markdownLineEnding(code)) { - return continuationAtLineEnding(code) - } - - effects.consume(code); - return continuation - } - /** @type {State} */ - - function continuationAtLineEnding(code) { - effects.exit('htmlFlowData'); - return htmlContinueStart(code) - } - /** @type {State} */ - - function htmlContinueStart(code) { - if (code === null) { - return done(code) - } - - if (markdownLineEnding(code)) { - return effects.attempt( - { - tokenize: htmlLineEnd, - partial: true - }, - htmlContinueStart, - done - )(code) - } - - effects.enter('htmlFlowData'); - return continuation(code) - } - /** @type {Tokenizer} */ - - function htmlLineEnd(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return lineStart - } - /** @type {State} */ - - function lineStart(code) { - return self.parser.lazy[self.now().line] ? nok(code) : ok(code) - } - } - /** @type {State} */ - - function continuationCommentInside(code) { - if (code === 45) { - effects.consume(code); - return continuationDeclarationInside - } - - return continuation(code) - } - /** @type {State} */ - - function continuationRawTagOpen(code) { - if (code === 47) { - effects.consume(code); - buffer = ''; - return continuationRawEndTag - } - - return continuation(code) - } - /** @type {State} */ - - function continuationRawEndTag(code) { - if (code === 62 && htmlRawNames.includes(buffer.toLowerCase())) { - effects.consume(code); - return continuationClose - } - - if (asciiAlpha(code) && buffer.length < 8) { - effects.consume(code); - buffer += String.fromCharCode(code); - return continuationRawEndTag - } - - return continuation(code) - } - /** @type {State} */ - - function continuationCharacterDataInside(code) { - if (code === 93) { - effects.consume(code); - return continuationDeclarationInside - } - - return continuation(code) - } - /** @type {State} */ - - function continuationDeclarationInside(code) { - if (code === 62) { - effects.consume(code); - return continuationClose - } - - return continuation(code) - } - /** @type {State} */ - - function continuationClose(code) { - if (code === null || markdownLineEnding(code)) { - effects.exit('htmlFlowData'); - return done(code) - } - - effects.consume(code); - return continuationClose - } - /** @type {State} */ - - function done(code) { - effects.exit('htmlFlow'); - return ok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeNextBlank(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.exit('htmlFlowData'); - effects.enter('lineEndingBlank'); - effects.consume(code); - effects.exit('lineEndingBlank'); - return effects.attempt(blankLine, ok, nok) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ - -/** @type {Construct} */ -const htmlText = { - name: 'htmlText', - tokenize: tokenizeHtmlText -}; -/** @type {Tokenizer} */ - -function tokenizeHtmlText(effects, ok, nok) { - const self = this; - /** @type {NonNullable|undefined} */ - - let marker; - /** @type {string} */ - - let buffer; - /** @type {number} */ - - let index; - /** @type {State} */ - - let returnState; - return start - /** @type {State} */ - - function start(code) { - effects.enter('htmlText'); - effects.enter('htmlTextData'); - effects.consume(code); - return open - } - /** @type {State} */ - - function open(code) { - if (code === 33) { - effects.consume(code); - return declarationOpen - } - - if (code === 47) { - effects.consume(code); - return tagCloseStart - } - - if (code === 63) { - effects.consume(code); - return instruction - } - - if (asciiAlpha(code)) { - effects.consume(code); - return tagOpen - } - - return nok(code) - } - /** @type {State} */ - - function declarationOpen(code) { - if (code === 45) { - effects.consume(code); - return commentOpen - } - - if (code === 91) { - effects.consume(code); - buffer = 'CDATA['; - index = 0; - return cdataOpen - } - - if (asciiAlpha(code)) { - effects.consume(code); - return declaration - } - - return nok(code) - } - /** @type {State} */ - - function commentOpen(code) { - if (code === 45) { - effects.consume(code); - return commentStart - } - - return nok(code) - } - /** @type {State} */ - - function commentStart(code) { - if (code === null || code === 62) { - return nok(code) - } - - if (code === 45) { - effects.consume(code); - return commentStartDash - } - - return comment(code) - } - /** @type {State} */ - - function commentStartDash(code) { - if (code === null || code === 62) { - return nok(code) - } - - return comment(code) - } - /** @type {State} */ - - function comment(code) { - if (code === null) { - return nok(code) - } - - if (code === 45) { - effects.consume(code); - return commentClose - } - - if (markdownLineEnding(code)) { - returnState = comment; - return atLineEnding(code) - } - - effects.consume(code); - return comment - } - /** @type {State} */ - - function commentClose(code) { - if (code === 45) { - effects.consume(code); - return end - } - - return comment(code) - } - /** @type {State} */ - - function cdataOpen(code) { - if (code === buffer.charCodeAt(index++)) { - effects.consume(code); - return index === buffer.length ? cdata : cdataOpen - } - - return nok(code) - } - /** @type {State} */ - - function cdata(code) { - if (code === null) { - return nok(code) - } - - if (code === 93) { - effects.consume(code); - return cdataClose - } - - if (markdownLineEnding(code)) { - returnState = cdata; - return atLineEnding(code) - } - - effects.consume(code); - return cdata - } - /** @type {State} */ - - function cdataClose(code) { - if (code === 93) { - effects.consume(code); - return cdataEnd - } - - return cdata(code) - } - /** @type {State} */ - - function cdataEnd(code) { - if (code === 62) { - return end(code) - } - - if (code === 93) { - effects.consume(code); - return cdataEnd - } - - return cdata(code) - } - /** @type {State} */ - - function declaration(code) { - if (code === null || code === 62) { - return end(code) - } - - if (markdownLineEnding(code)) { - returnState = declaration; - return atLineEnding(code) - } - - effects.consume(code); - return declaration - } - /** @type {State} */ - - function instruction(code) { - if (code === null) { - return nok(code) - } - - if (code === 63) { - effects.consume(code); - return instructionClose - } - - if (markdownLineEnding(code)) { - returnState = instruction; - return atLineEnding(code) - } - - effects.consume(code); - return instruction - } - /** @type {State} */ - - function instructionClose(code) { - return code === 62 ? end(code) : instruction(code) - } - /** @type {State} */ - - function tagCloseStart(code) { - if (asciiAlpha(code)) { - effects.consume(code); - return tagClose - } - - return nok(code) - } - /** @type {State} */ - - function tagClose(code) { - if (code === 45 || asciiAlphanumeric(code)) { - effects.consume(code); - return tagClose - } - - return tagCloseBetween(code) - } - /** @type {State} */ - - function tagCloseBetween(code) { - if (markdownLineEnding(code)) { - returnState = tagCloseBetween; - return atLineEnding(code) - } - - if (markdownSpace(code)) { - effects.consume(code); - return tagCloseBetween - } - - return end(code) - } - /** @type {State} */ - - function tagOpen(code) { - if (code === 45 || asciiAlphanumeric(code)) { - effects.consume(code); - return tagOpen - } - - if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { - return tagOpenBetween(code) - } - - return nok(code) - } - /** @type {State} */ - - function tagOpenBetween(code) { - if (code === 47) { - effects.consume(code); - return end - } - - if (code === 58 || code === 95 || asciiAlpha(code)) { - effects.consume(code); - return tagOpenAttributeName - } - - if (markdownLineEnding(code)) { - returnState = tagOpenBetween; - return atLineEnding(code) - } - - if (markdownSpace(code)) { - effects.consume(code); - return tagOpenBetween - } - - return end(code) - } - /** @type {State} */ - - function tagOpenAttributeName(code) { - if ( - code === 45 || - code === 46 || - code === 58 || - code === 95 || - asciiAlphanumeric(code) - ) { - effects.consume(code); - return tagOpenAttributeName - } - - return tagOpenAttributeNameAfter(code) - } - /** @type {State} */ - - function tagOpenAttributeNameAfter(code) { - if (code === 61) { - effects.consume(code); - return tagOpenAttributeValueBefore - } - - if (markdownLineEnding(code)) { - returnState = tagOpenAttributeNameAfter; - return atLineEnding(code) - } - - if (markdownSpace(code)) { - effects.consume(code); - return tagOpenAttributeNameAfter - } - - return tagOpenBetween(code) - } - /** @type {State} */ - - function tagOpenAttributeValueBefore(code) { - if ( - code === null || - code === 60 || - code === 61 || - code === 62 || - code === 96 - ) { - return nok(code) - } - - if (code === 34 || code === 39) { - effects.consume(code); - marker = code; - return tagOpenAttributeValueQuoted - } - - if (markdownLineEnding(code)) { - returnState = tagOpenAttributeValueBefore; - return atLineEnding(code) - } - - if (markdownSpace(code)) { - effects.consume(code); - return tagOpenAttributeValueBefore - } - - effects.consume(code); - marker = undefined; - return tagOpenAttributeValueUnquoted - } - /** @type {State} */ - - function tagOpenAttributeValueQuoted(code) { - if (code === marker) { - effects.consume(code); - return tagOpenAttributeValueQuotedAfter - } - - if (code === null) { - return nok(code) - } - - if (markdownLineEnding(code)) { - returnState = tagOpenAttributeValueQuoted; - return atLineEnding(code) - } - - effects.consume(code); - return tagOpenAttributeValueQuoted - } - /** @type {State} */ - - function tagOpenAttributeValueQuotedAfter(code) { - if (code === 62 || code === 47 || markdownLineEndingOrSpace(code)) { - return tagOpenBetween(code) - } - - return nok(code) - } - /** @type {State} */ - - function tagOpenAttributeValueUnquoted(code) { - if ( - code === null || - code === 34 || - code === 39 || - code === 60 || - code === 61 || - code === 96 - ) { - return nok(code) - } - - if (code === 62 || markdownLineEndingOrSpace(code)) { - return tagOpenBetween(code) - } - - effects.consume(code); - return tagOpenAttributeValueUnquoted - } // We can’t have blank lines in content, so no need to worry about empty - // tokens. - - /** @type {State} */ - - function atLineEnding(code) { - effects.exit('htmlTextData'); - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return factorySpace( - effects, - afterPrefix, - 'linePrefix', - self.parser.constructs.disable.null.includes('codeIndented') - ? undefined - : 4 - ) - } - /** @type {State} */ - - function afterPrefix(code) { - effects.enter('htmlTextData'); - return returnState(code) - } - /** @type {State} */ - - function end(code) { - if (code === 62) { - effects.consume(code); - effects.exit('htmlTextData'); - effects.exit('htmlText'); - return ok - } - - return nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Event} Event - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ - -/** @type {Construct} */ -const labelEnd = { - name: 'labelEnd', - tokenize: tokenizeLabelEnd, - resolveTo: resolveToLabelEnd, - resolveAll: resolveAllLabelEnd -}; -/** @type {Construct} */ - -const resourceConstruct = { - tokenize: tokenizeResource -}; -/** @type {Construct} */ - -const fullReferenceConstruct = { - tokenize: tokenizeFullReference -}; -/** @type {Construct} */ - -const collapsedReferenceConstruct = { - tokenize: tokenizeCollapsedReference -}; -/** @type {Resolver} */ - -function resolveAllLabelEnd(events) { - let index = -1; - /** @type {Token} */ - - let token; - - while (++index < events.length) { - token = events[index][1]; - - if ( - token.type === 'labelImage' || - token.type === 'labelLink' || - token.type === 'labelEnd' - ) { - // Remove the marker. - events.splice(index + 1, token.type === 'labelImage' ? 4 : 2); - token.type = 'data'; - index++; - } - } - - return events -} -/** @type {Resolver} */ - -function resolveToLabelEnd(events, context) { - let index = events.length; - let offset = 0; - /** @type {Token} */ - - let token; - /** @type {number|undefined} */ - - let open; - /** @type {number|undefined} */ - - let close; - /** @type {Event[]} */ - - let media; // Find an opening. - - while (index--) { - token = events[index][1]; - - if (open) { - // If we see another link, or inactive link label, we’ve been here before. - if ( - token.type === 'link' || - (token.type === 'labelLink' && token._inactive) - ) { - break - } // Mark other link openings as inactive, as we can’t have links in - // links. - - if (events[index][0] === 'enter' && token.type === 'labelLink') { - token._inactive = true; - } - } else if (close) { - if ( - events[index][0] === 'enter' && - (token.type === 'labelImage' || token.type === 'labelLink') && - !token._balanced - ) { - open = index; - - if (token.type !== 'labelLink') { - offset = 2; - break - } - } - } else if (token.type === 'labelEnd') { - close = index; - } - } - - const group = { - type: events[open][1].type === 'labelLink' ? 'link' : 'image', - start: Object.assign({}, events[open][1].start), - end: Object.assign({}, events[events.length - 1][1].end) - }; - const label = { - type: 'label', - start: Object.assign({}, events[open][1].start), - end: Object.assign({}, events[close][1].end) - }; - const text = { - type: 'labelText', - start: Object.assign({}, events[open + offset + 2][1].end), - end: Object.assign({}, events[close - 2][1].start) - }; - media = [ - ['enter', group, context], - ['enter', label, context] - ]; // Opening marker. - - media = push(media, events.slice(open + 1, open + offset + 3)); // Text open. - - media = push(media, [['enter', text, context]]); // Between. - - media = push( - media, - resolveAll( - context.parser.constructs.insideSpan.null, - events.slice(open + offset + 4, close - 3), - context - ) - ); // Text close, marker close, label close. - - media = push(media, [ - ['exit', text, context], - events[close - 2], - events[close - 1], - ['exit', label, context] - ]); // Reference, resource, or so. - - media = push(media, events.slice(close + 1)); // Media close. - - media = push(media, [['exit', group, context]]); - splice(events, open, events.length, media); - return events -} -/** @type {Tokenizer} */ - -function tokenizeLabelEnd(effects, ok, nok) { - const self = this; - let index = self.events.length; - /** @type {Token} */ - - let labelStart; - /** @type {boolean} */ - - let defined; // Find an opening. - - while (index--) { - if ( - (self.events[index][1].type === 'labelImage' || - self.events[index][1].type === 'labelLink') && - !self.events[index][1]._balanced - ) { - labelStart = self.events[index][1]; - break - } - } - - return start - /** @type {State} */ - - function start(code) { - if (!labelStart) { - return nok(code) - } // It’s a balanced bracket, but contains a link. - - if (labelStart._inactive) return balanced(code) - defined = self.parser.defined.includes( - normalizeIdentifier( - self.sliceSerialize({ - start: labelStart.end, - end: self.now() - }) - ) - ); - effects.enter('labelEnd'); - effects.enter('labelMarker'); - effects.consume(code); - effects.exit('labelMarker'); - effects.exit('labelEnd'); - return afterLabelEnd - } - /** @type {State} */ - - function afterLabelEnd(code) { - // Resource: `[asd](fgh)`. - if (code === 40) { - return effects.attempt( - resourceConstruct, - ok, - defined ? ok : balanced - )(code) - } // Collapsed (`[asd][]`) or full (`[asd][fgh]`) reference? - - if (code === 91) { - return effects.attempt( - fullReferenceConstruct, - ok, - defined - ? effects.attempt(collapsedReferenceConstruct, ok, balanced) - : balanced - )(code) - } // Shortcut reference: `[asd]`? - - return defined ? ok(code) : balanced(code) - } - /** @type {State} */ - - function balanced(code) { - labelStart._balanced = true; - return nok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeResource(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.enter('resource'); - effects.enter('resourceMarker'); - effects.consume(code); - effects.exit('resourceMarker'); - return factoryWhitespace(effects, open) - } - /** @type {State} */ - - function open(code) { - if (code === 41) { - return end(code) - } - - return factoryDestination( - effects, - destinationAfter, - nok, - 'resourceDestination', - 'resourceDestinationLiteral', - 'resourceDestinationLiteralMarker', - 'resourceDestinationRaw', - 'resourceDestinationString', - 3 - )(code) - } - /** @type {State} */ - - function destinationAfter(code) { - return markdownLineEndingOrSpace(code) - ? factoryWhitespace(effects, between)(code) - : end(code) - } - /** @type {State} */ - - function between(code) { - if (code === 34 || code === 39 || code === 40) { - return factoryTitle( - effects, - factoryWhitespace(effects, end), - nok, - 'resourceTitle', - 'resourceTitleMarker', - 'resourceTitleString' - )(code) - } - - return end(code) - } - /** @type {State} */ - - function end(code) { - if (code === 41) { - effects.enter('resourceMarker'); - effects.consume(code); - effects.exit('resourceMarker'); - effects.exit('resource'); - return ok - } - - return nok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeFullReference(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - return factoryLabel.call( - self, - effects, - afterLabel, - nok, - 'reference', - 'referenceMarker', - 'referenceString' - )(code) - } - /** @type {State} */ - - function afterLabel(code) { - return self.parser.defined.includes( - normalizeIdentifier( - self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) - ) - ) - ? ok(code) - : nok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeCollapsedReference(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.enter('reference'); - effects.enter('referenceMarker'); - effects.consume(code); - effects.exit('referenceMarker'); - return open - } - /** @type {State} */ - - function open(code) { - if (code === 93) { - effects.enter('referenceMarker'); - effects.consume(code); - effects.exit('referenceMarker'); - effects.exit('reference'); - return ok - } - - return nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - */ -/** @type {Construct} */ - -const labelStartImage = { - name: 'labelStartImage', - tokenize: tokenizeLabelStartImage, - resolveAll: labelEnd.resolveAll -}; -/** @type {Tokenizer} */ - -function tokenizeLabelStartImage(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - effects.enter('labelImage'); - effects.enter('labelImageMarker'); - effects.consume(code); - effects.exit('labelImageMarker'); - return open - } - /** @type {State} */ - - function open(code) { - if (code === 91) { - effects.enter('labelMarker'); - effects.consume(code); - effects.exit('labelMarker'); - effects.exit('labelImage'); - return after - } - - return nok(code) - } - /** @type {State} */ - - function after(code) { - /* Hidden footnotes hook */ - - /* c8 ignore next 3 */ - return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs - ? nok(code) - : ok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - */ -/** @type {Construct} */ - -const labelStartLink = { - name: 'labelStartLink', - tokenize: tokenizeLabelStartLink, - resolveAll: labelEnd.resolveAll -}; -/** @type {Tokenizer} */ - -function tokenizeLabelStartLink(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - effects.enter('labelLink'); - effects.enter('labelMarker'); - effects.consume(code); - effects.exit('labelMarker'); - effects.exit('labelLink'); - return after - } - /** @type {State} */ - - function after(code) { - /* Hidden footnotes hook. */ - - /* c8 ignore next 3 */ - return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs - ? nok(code) - : ok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const lineEnding = { - name: 'lineEnding', - tokenize: tokenizeLineEnding -}; -/** @type {Tokenizer} */ - -function tokenizeLineEnding(effects, ok) { - return start - /** @type {State} */ - - function start(code) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return factorySpace(effects, ok, 'linePrefix') - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ - -/** @type {Construct} */ -const thematicBreak$1 = { - name: 'thematicBreak', - tokenize: tokenizeThematicBreak -}; -/** @type {Tokenizer} */ - -function tokenizeThematicBreak(effects, ok, nok) { - let size = 0; - /** @type {NonNullable} */ - - let marker; - return start - /** @type {State} */ - - function start(code) { - effects.enter('thematicBreak'); - marker = code; - return atBreak(code) - } - /** @type {State} */ - - function atBreak(code) { - if (code === marker) { - effects.enter('thematicBreakSequence'); - return sequence(code) - } - - if (markdownSpace(code)) { - return factorySpace(effects, atBreak, 'whitespace')(code) - } - - if (size < 3 || (code !== null && !markdownLineEnding(code))) { - return nok(code) - } - - effects.exit('thematicBreak'); - return ok(code) - } - /** @type {State} */ - - function sequence(code) { - if (code === marker) { - effects.consume(code); - size++; - return sequence - } - - effects.exit('thematicBreakSequence'); - return atBreak(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext - * @typedef {import('micromark-util-types').Exiter} Exiter - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ -/** @type {Construct} */ - -const list$1 = { - name: 'list', - tokenize: tokenizeListStart, - continuation: { - tokenize: tokenizeListContinuation - }, - exit: tokenizeListEnd -}; -/** @type {Construct} */ - -const listItemPrefixWhitespaceConstruct = { - tokenize: tokenizeListItemPrefixWhitespace, - partial: true -}; -/** @type {Construct} */ - -const indentConstruct = { - tokenize: tokenizeIndent, - partial: true -}; -/** - * @type {Tokenizer} - * @this {TokenizeContextWithState} - */ - -function tokenizeListStart(effects, ok, nok) { - const self = this; - const tail = self.events[self.events.length - 1]; - let initialSize = - tail && tail[1].type === 'linePrefix' - ? tail[2].sliceSerialize(tail[1], true).length - : 0; - let size = 0; - return start - /** @type {State} */ - - function start(code) { - const kind = - self.containerState.type || - (code === 42 || code === 43 || code === 45 - ? 'listUnordered' - : 'listOrdered'); - - if ( - kind === 'listUnordered' - ? !self.containerState.marker || code === self.containerState.marker - : asciiDigit(code) - ) { - if (!self.containerState.type) { - self.containerState.type = kind; - effects.enter(kind, { - _container: true - }); - } - - if (kind === 'listUnordered') { - effects.enter('listItemPrefix'); - return code === 42 || code === 45 - ? effects.check(thematicBreak$1, nok, atMarker)(code) - : atMarker(code) - } - - if (!self.interrupt || code === 49) { - effects.enter('listItemPrefix'); - effects.enter('listItemValue'); - return inside(code) - } - } - - return nok(code) - } - /** @type {State} */ - - function inside(code) { - if (asciiDigit(code) && ++size < 10) { - effects.consume(code); - return inside - } - - if ( - (!self.interrupt || size < 2) && - (self.containerState.marker - ? code === self.containerState.marker - : code === 41 || code === 46) - ) { - effects.exit('listItemValue'); - return atMarker(code) - } - - return nok(code) - } - /** - * @type {State} - **/ - - function atMarker(code) { - effects.enter('listItemMarker'); - effects.consume(code); - effects.exit('listItemMarker'); - self.containerState.marker = self.containerState.marker || code; - return effects.check( - blankLine, // Can’t be empty when interrupting. - self.interrupt ? nok : onBlank, - effects.attempt( - listItemPrefixWhitespaceConstruct, - endOfPrefix, - otherPrefix - ) - ) - } - /** @type {State} */ - - function onBlank(code) { - self.containerState.initialBlankLine = true; - initialSize++; - return endOfPrefix(code) - } - /** @type {State} */ - - function otherPrefix(code) { - if (markdownSpace(code)) { - effects.enter('listItemPrefixWhitespace'); - effects.consume(code); - effects.exit('listItemPrefixWhitespace'); - return endOfPrefix - } - - return nok(code) - } - /** @type {State} */ - - function endOfPrefix(code) { - self.containerState.size = - initialSize + - self.sliceSerialize(effects.exit('listItemPrefix'), true).length; - return ok(code) - } -} -/** - * @type {Tokenizer} - * @this {TokenizeContextWithState} - */ - -function tokenizeListContinuation(effects, ok, nok) { - const self = this; - self.containerState._closeFlow = undefined; - return effects.check(blankLine, onBlank, notBlank) - /** @type {State} */ - - function onBlank(code) { - self.containerState.furtherBlankLines = - self.containerState.furtherBlankLines || - self.containerState.initialBlankLine; // We have a blank line. - // Still, try to consume at most the items size. - - return factorySpace( - effects, - ok, - 'listItemIndent', - self.containerState.size + 1 - )(code) - } - /** @type {State} */ - - function notBlank(code) { - if (self.containerState.furtherBlankLines || !markdownSpace(code)) { - self.containerState.furtherBlankLines = undefined; - self.containerState.initialBlankLine = undefined; - return notInCurrentItem(code) - } - - self.containerState.furtherBlankLines = undefined; - self.containerState.initialBlankLine = undefined; - return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) - } - /** @type {State} */ - - function notInCurrentItem(code) { - // While we do continue, we signal that the flow should be closed. - self.containerState._closeFlow = true; // As we’re closing flow, we’re no longer interrupting. - - self.interrupt = undefined; - return factorySpace( - effects, - effects.attempt(list$1, ok, nok), - 'linePrefix', - self.parser.constructs.disable.null.includes('codeIndented') - ? undefined - : 4 - )(code) - } -} -/** - * @type {Tokenizer} - * @this {TokenizeContextWithState} - */ - -function tokenizeIndent(effects, ok, nok) { - const self = this; - return factorySpace( - effects, - afterPrefix, - 'listItemIndent', - self.containerState.size + 1 - ) - /** @type {State} */ - - function afterPrefix(code) { - const tail = self.events[self.events.length - 1]; - return tail && - tail[1].type === 'listItemIndent' && - tail[2].sliceSerialize(tail[1], true).length === self.containerState.size - ? ok(code) - : nok(code) - } -} -/** - * @type {Exiter} - * @this {TokenizeContextWithState} - */ - -function tokenizeListEnd(effects) { - effects.exit(this.containerState.type); -} -/** - * @type {Tokenizer} - * @this {TokenizeContextWithState} - */ - -function tokenizeListItemPrefixWhitespace(effects, ok, nok) { - const self = this; - return factorySpace( - effects, - afterPrefix, - 'listItemPrefixWhitespace', - self.parser.constructs.disable.null.includes('codeIndented') - ? undefined - : 4 + 1 - ) - /** @type {State} */ - - function afterPrefix(code) { - const tail = self.events[self.events.length - 1]; - return !markdownSpace(code) && - tail && - tail[1].type === 'listItemPrefixWhitespace' - ? ok(code) - : nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ - -/** @type {Construct} */ -const setextUnderline = { - name: 'setextUnderline', - tokenize: tokenizeSetextUnderline, - resolveTo: resolveToSetextUnderline -}; -/** @type {Resolver} */ - -function resolveToSetextUnderline(events, context) { - let index = events.length; - /** @type {number|undefined} */ - - let content; - /** @type {number|undefined} */ - - let text; - /** @type {number|undefined} */ - - let definition; // Find the opening of the content. - // It’ll always exist: we don’t tokenize if it isn’t there. - - while (index--) { - if (events[index][0] === 'enter') { - if (events[index][1].type === 'content') { - content = index; - break - } - - if (events[index][1].type === 'paragraph') { - text = index; - } - } // Exit - else { - if (events[index][1].type === 'content') { - // Remove the content end (if needed we’ll add it later) - events.splice(index, 1); - } - - if (!definition && events[index][1].type === 'definition') { - definition = index; - } - } - } - - const heading = { - type: 'setextHeading', - start: Object.assign({}, events[text][1].start), - end: Object.assign({}, events[events.length - 1][1].end) - }; // Change the paragraph to setext heading text. - - events[text][1].type = 'setextHeadingText'; // If we have definitions in the content, we’ll keep on having content, - // but we need move it. - - if (definition) { - events.splice(text, 0, ['enter', heading, context]); - events.splice(definition + 1, 0, ['exit', events[content][1], context]); - events[content][1].end = Object.assign({}, events[definition][1].end); - } else { - events[content][1] = heading; - } // Add the heading exit at the end. - - events.push(['exit', heading, context]); - return events -} -/** @type {Tokenizer} */ - -function tokenizeSetextUnderline(effects, ok, nok) { - const self = this; - let index = self.events.length; - /** @type {NonNullable} */ - - let marker; - /** @type {boolean} */ - - let paragraph; // Find an opening. - - while (index--) { - // Skip enter/exit of line ending, line prefix, and content. - // We can now either have a definition or a paragraph. - if ( - self.events[index][1].type !== 'lineEnding' && - self.events[index][1].type !== 'linePrefix' && - self.events[index][1].type !== 'content' - ) { - paragraph = self.events[index][1].type === 'paragraph'; - break - } - } - - return start - /** @type {State} */ - - function start(code) { - if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { - effects.enter('setextHeadingLine'); - effects.enter('setextHeadingLineSequence'); - marker = code; - return closingSequence(code) - } - - return nok(code) - } - /** @type {State} */ - - function closingSequence(code) { - if (code === marker) { - effects.consume(code); - return closingSequence - } - - effects.exit('setextHeadingLineSequence'); - return factorySpace(effects, closingSequenceEnd, 'lineSuffix')(code) - } - /** @type {State} */ - - function closingSequenceEnd(code) { - if (code === null || markdownLineEnding(code)) { - effects.exit('setextHeadingLine'); - return ok(code) - } - - return nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct - * @typedef {import('micromark-util-types').Initializer} Initializer - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {InitialConstruct} */ -const flow$1 = { - tokenize: initializeFlow -}; -/** @type {Initializer} */ - -function initializeFlow(effects) { - const self = this; - const initial = effects.attempt( - // Try to parse a blank line. - blankLine, - atBlankEnding, // Try to parse initial flow (essentially, only code). - effects.attempt( - this.parser.constructs.flowInitial, - afterConstruct, - factorySpace( - effects, - effects.attempt( - this.parser.constructs.flow, - afterConstruct, - effects.attempt(content, afterConstruct) - ), - 'linePrefix' - ) - ) - ); - return initial - /** @type {State} */ - - function atBlankEnding(code) { - if (code === null) { - effects.consume(code); - return - } - - effects.enter('lineEndingBlank'); - effects.consume(code); - effects.exit('lineEndingBlank'); - self.currentConstruct = undefined; - return initial - } - /** @type {State} */ - - function afterConstruct(code) { - if (code === null) { - effects.consume(code); - return - } - - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - self.currentConstruct = undefined; - return initial - } -} - -/** - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Initializer} Initializer - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ -const resolver = { - resolveAll: createResolver() -}; -const string$1 = initializeFactory('string'); -const text$3 = initializeFactory('text'); -/** - * @param {'string'|'text'} field - * @returns {InitialConstruct} - */ - -function initializeFactory(field) { - return { - tokenize: initializeText, - resolveAll: createResolver( - field === 'text' ? resolveAllLineSuffixes : undefined - ) - } - /** @type {Initializer} */ - - function initializeText(effects) { - const self = this; - const constructs = this.parser.constructs[field]; - const text = effects.attempt(constructs, start, notText); - return start - /** @type {State} */ - - function start(code) { - return atBreak(code) ? text(code) : notText(code) - } - /** @type {State} */ - - function notText(code) { - if (code === null) { - effects.consume(code); - return - } - - effects.enter('data'); - effects.consume(code); - return data - } - /** @type {State} */ - - function data(code) { - if (atBreak(code)) { - effects.exit('data'); - return text(code) - } // Data. - - effects.consume(code); - return data - } - /** - * @param {Code} code - * @returns {boolean} - */ - - function atBreak(code) { - if (code === null) { - return true - } - - const list = constructs[code]; - let index = -1; - - if (list) { - while (++index < list.length) { - const item = list[index]; - - if (!item.previous || item.previous.call(self, self.previous)) { - return true - } - } - } - - return false - } - } -} -/** - * @param {Resolver} [extraResolver] - * @returns {Resolver} - */ - -function createResolver(extraResolver) { - return resolveAllText - /** @type {Resolver} */ - - function resolveAllText(events, context) { - let index = -1; - /** @type {number|undefined} */ - - let enter; // A rather boring computation (to merge adjacent `data` events) which - // improves mm performance by 29%. - - while (++index <= events.length) { - if (enter === undefined) { - if (events[index] && events[index][1].type === 'data') { - enter = index; - index++; - } - } else if (!events[index] || events[index][1].type !== 'data') { - // Don’t do anything if there is one data token. - if (index !== enter + 2) { - events[enter][1].end = events[index - 1][1].end; - events.splice(enter + 2, index - enter - 2); - index = enter + 2; - } - - enter = undefined; - } - } - - return extraResolver ? extraResolver(events, context) : events - } -} -/** - * A rather ugly set of instructions which again looks at chunks in the input - * stream. - * The reason to do this here is that it is *much* faster to parse in reverse. - * And that we can’t hook into `null` to split the line suffix before an EOF. - * To do: figure out if we can make this into a clean utility, or even in core. - * As it will be useful for GFMs literal autolink extension (and maybe even - * tables?) - * - * @type {Resolver} - */ - -function resolveAllLineSuffixes(events, context) { - let eventIndex = -1; - - while (++eventIndex <= events.length) { - if ( - (eventIndex === events.length || - events[eventIndex][1].type === 'lineEnding') && - events[eventIndex - 1][1].type === 'data' - ) { - const data = events[eventIndex - 1][1]; - const chunks = context.sliceStream(data); - let index = chunks.length; - let bufferIndex = -1; - let size = 0; - /** @type {boolean|undefined} */ - - let tabs; - - while (index--) { - const chunk = chunks[index]; - - if (typeof chunk === 'string') { - bufferIndex = chunk.length; - - while (chunk.charCodeAt(bufferIndex - 1) === 32) { - size++; - bufferIndex--; - } - - if (bufferIndex) break - bufferIndex = -1; - } // Number - else if (chunk === -2) { - tabs = true; - size++; - } else if (chunk === -1) ; else { - // Replacement character, exit. - index++; - break - } - } - - if (size) { - const token = { - type: - eventIndex === events.length || tabs || size < 2 - ? 'lineSuffix' - : 'hardBreakTrailing', - start: { - line: data.end.line, - column: data.end.column - size, - offset: data.end.offset - size, - _index: data.start._index + index, - _bufferIndex: index - ? bufferIndex - : data.start._bufferIndex + bufferIndex - }, - end: Object.assign({}, data.end) - }; - data.end = Object.assign({}, token.start); - - if (data.start.offset === data.end.offset) { - Object.assign(data, token); - } else { - events.splice( - eventIndex, - 0, - ['enter', token, context], - ['exit', token, context] - ); - eventIndex += 2; - } - } - - eventIndex++; - } - } - - return events -} - -/** - * @typedef {import('micromark-util-types').Code} Code - * @typedef {import('micromark-util-types').Chunk} Chunk - * @typedef {import('micromark-util-types').Point} Point - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').Effects} Effects - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct - * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord - * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext - * @typedef {import('micromark-util-types').ParseContext} ParseContext - */ - -/** - * Create a tokenizer. - * Tokenizers deal with one type of data (e.g., containers, flow, text). - * The parser is the object dealing with it all. - * `initialize` works like other constructs, except that only its `tokenize` - * function is used, in which case it doesn’t receive an `ok` or `nok`. - * `from` can be given to set the point before the first character, although - * when further lines are indented, they must be set with `defineSkip`. - * - * @param {ParseContext} parser - * @param {InitialConstruct} initialize - * @param {Omit} [from] - * @returns {TokenizeContext} - */ -function createTokenizer(parser, initialize, from) { - /** @type {Point} */ - let point = Object.assign( - from - ? Object.assign({}, from) - : { - line: 1, - column: 1, - offset: 0 - }, - { - _index: 0, - _bufferIndex: -1 - } - ); - /** @type {Record} */ - - const columnStart = {}; - /** @type {Construct[]} */ - - const resolveAllConstructs = []; - /** @type {Chunk[]} */ - - let chunks = []; - /** @type {Token[]} */ - - let stack = []; - /** - * Tools used for tokenizing. - * - * @type {Effects} - */ - - const effects = { - consume, - enter, - exit, - attempt: constructFactory(onsuccessfulconstruct), - check: constructFactory(onsuccessfulcheck), - interrupt: constructFactory(onsuccessfulcheck, { - interrupt: true - }) - }; - /** - * State and tools for resolving and serializing. - * - * @type {TokenizeContext} - */ - - const context = { - previous: null, - code: null, - containerState: {}, - events: [], - parser, - sliceStream, - sliceSerialize, - now, - defineSkip, - write - }; - /** - * The state function. - * - * @type {State|void} - */ - - let state = initialize.tokenize.call(context, effects); - - if (initialize.resolveAll) { - resolveAllConstructs.push(initialize); - } - - return context - /** @type {TokenizeContext['write']} */ - - function write(slice) { - chunks = push(chunks, slice); - main(); // Exit if we’re not done, resolve might change stuff. - - if (chunks[chunks.length - 1] !== null) { - return [] - } - - addResult(initialize, 0); // Otherwise, resolve, and exit. - - context.events = resolveAll(resolveAllConstructs, context.events, context); - return context.events - } // - // Tools. - // - - /** @type {TokenizeContext['sliceSerialize']} */ - - function sliceSerialize(token, expandTabs) { - return serializeChunks(sliceStream(token), expandTabs) - } - /** @type {TokenizeContext['sliceStream']} */ - - function sliceStream(token) { - return sliceChunks(chunks, token) - } - /** @type {TokenizeContext['now']} */ - - function now() { - return Object.assign({}, point) - } - /** @type {TokenizeContext['defineSkip']} */ - - function defineSkip(value) { - columnStart[value.line] = value.column; - accountForPotentialSkip(); - } // - // State management. - // - - /** - * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by - * `consume`). - * Here is where we walk through the chunks, which either include strings of - * several characters, or numerical character codes. - * The reason to do this in a loop instead of a call is so the stack can - * drain. - * - * @returns {void} - */ - - function main() { - /** @type {number} */ - let chunkIndex; - - while (point._index < chunks.length) { - const chunk = chunks[point._index]; // If we’re in a buffer chunk, loop through it. - - if (typeof chunk === 'string') { - chunkIndex = point._index; - - if (point._bufferIndex < 0) { - point._bufferIndex = 0; - } - - while ( - point._index === chunkIndex && - point._bufferIndex < chunk.length - ) { - go(chunk.charCodeAt(point._bufferIndex)); - } - } else { - go(chunk); - } - } - } - /** - * Deal with one code. - * - * @param {Code} code - * @returns {void} - */ - - function go(code) { - state = state(code); - } - /** @type {Effects['consume']} */ - - function consume(code) { - if (markdownLineEnding(code)) { - point.line++; - point.column = 1; - point.offset += code === -3 ? 2 : 1; - accountForPotentialSkip(); - } else if (code !== -1) { - point.column++; - point.offset++; - } // Not in a string chunk. - - if (point._bufferIndex < 0) { - point._index++; - } else { - point._bufferIndex++; // At end of string chunk. - // @ts-expect-error Points w/ non-negative `_bufferIndex` reference - // strings. - - if (point._bufferIndex === chunks[point._index].length) { - point._bufferIndex = -1; - point._index++; - } - } // Expose the previous character. - - context.previous = code; // Mark as consumed. - } - /** @type {Effects['enter']} */ - - function enter(type, fields) { - /** @type {Token} */ - // @ts-expect-error Patch instead of assign required fields to help GC. - const token = fields || {}; - token.type = type; - token.start = now(); - context.events.push(['enter', token, context]); - stack.push(token); - return token - } - /** @type {Effects['exit']} */ - - function exit(type) { - const token = stack.pop(); - token.end = now(); - context.events.push(['exit', token, context]); - return token - } - /** - * Use results. - * - * @type {ReturnHandle} - */ - - function onsuccessfulconstruct(construct, info) { - addResult(construct, info.from); - } - /** - * Discard results. - * - * @type {ReturnHandle} - */ - - function onsuccessfulcheck(_, info) { - info.restore(); - } - /** - * Factory to attempt/check/interrupt. - * - * @param {ReturnHandle} onreturn - * @param {Record} [fields] - */ - - function constructFactory(onreturn, fields) { - return hook - /** - * Handle either an object mapping codes to constructs, a list of - * constructs, or a single construct. - * - * @param {Construct|Construct[]|ConstructRecord} constructs - * @param {State} returnState - * @param {State} [bogusState] - * @returns {State} - */ - - function hook(constructs, returnState, bogusState) { - /** @type {Construct[]} */ - let listOfConstructs; - /** @type {number} */ - - let constructIndex; - /** @type {Construct} */ - - let currentConstruct; - /** @type {Info} */ - - let info; - return Array.isArray(constructs) - ? /* c8 ignore next 1 */ - handleListOfConstructs(constructs) - : 'tokenize' in constructs // @ts-expect-error Looks like a construct. - ? handleListOfConstructs([constructs]) - : handleMapOfConstructs(constructs) - /** - * Handle a list of construct. - * - * @param {ConstructRecord} map - * @returns {State} - */ - - function handleMapOfConstructs(map) { - return start - /** @type {State} */ - - function start(code) { - const def = code !== null && map[code]; - const all = code !== null && map.null; - const list = [ - // To do: add more extension tests. - - /* c8 ignore next 2 */ - ...(Array.isArray(def) ? def : def ? [def] : []), - ...(Array.isArray(all) ? all : all ? [all] : []) - ]; - return handleListOfConstructs(list)(code) - } - } - /** - * Handle a list of construct. - * - * @param {Construct[]} list - * @returns {State} - */ - - function handleListOfConstructs(list) { - listOfConstructs = list; - constructIndex = 0; - - if (list.length === 0) { - return bogusState - } - - return handleConstruct(list[constructIndex]) - } - /** - * Handle a single construct. - * - * @param {Construct} construct - * @returns {State} - */ - - function handleConstruct(construct) { - return start - /** @type {State} */ - - function start(code) { - // To do: not needed to store if there is no bogus state, probably? - // Currently doesn’t work because `inspect` in document does a check - // w/o a bogus, which doesn’t make sense. But it does seem to help perf - // by not storing. - info = store(); - currentConstruct = construct; - - if (!construct.partial) { - context.currentConstruct = construct; - } - - if ( - construct.name && - context.parser.constructs.disable.null.includes(construct.name) - ) { - return nok() - } - - return construct.tokenize.call( - // If we do have fields, create an object w/ `context` as its - // prototype. - // This allows a “live binding”, which is needed for `interrupt`. - fields ? Object.assign(Object.create(context), fields) : context, - effects, - ok, - nok - )(code) - } - } - /** @type {State} */ - - function ok(code) { - onreturn(currentConstruct, info); - return returnState - } - /** @type {State} */ - - function nok(code) { - info.restore(); - - if (++constructIndex < listOfConstructs.length) { - return handleConstruct(listOfConstructs[constructIndex]) - } - - return bogusState - } - } - } - /** - * @param {Construct} construct - * @param {number} from - * @returns {void} - */ - - function addResult(construct, from) { - if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { - resolveAllConstructs.push(construct); - } - - if (construct.resolve) { - splice( - context.events, - from, - context.events.length - from, - construct.resolve(context.events.slice(from), context) - ); - } - - if (construct.resolveTo) { - context.events = construct.resolveTo(context.events, context); - } - } - /** - * Store state. - * - * @returns {Info} - */ - - function store() { - const startPoint = now(); - const startPrevious = context.previous; - const startCurrentConstruct = context.currentConstruct; - const startEventsIndex = context.events.length; - const startStack = Array.from(stack); - return { - restore, - from: startEventsIndex - } - /** - * Restore state. - * - * @returns {void} - */ - - function restore() { - point = startPoint; - context.previous = startPrevious; - context.currentConstruct = startCurrentConstruct; - context.events.length = startEventsIndex; - stack = startStack; - accountForPotentialSkip(); - } - } - /** - * Move the current point a bit forward in the line when it’s on a column - * skip. - * - * @returns {void} - */ - - function accountForPotentialSkip() { - if (point.line in columnStart && point.column < 2) { - point.column = columnStart[point.line]; - point.offset += columnStart[point.line] - 1; - } - } -} -/** - * Get the chunks from a slice of chunks in the range of a token. - * - * @param {Chunk[]} chunks - * @param {Pick} token - * @returns {Chunk[]} - */ - -function sliceChunks(chunks, token) { - const startIndex = token.start._index; - const startBufferIndex = token.start._bufferIndex; - const endIndex = token.end._index; - const endBufferIndex = token.end._bufferIndex; - /** @type {Chunk[]} */ - - let view; - - if (startIndex === endIndex) { - // @ts-expect-error `_bufferIndex` is used on string chunks. - view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)]; - } else { - view = chunks.slice(startIndex, endIndex); - - if (startBufferIndex > -1) { - // @ts-expect-error `_bufferIndex` is used on string chunks. - view[0] = view[0].slice(startBufferIndex); - } - - if (endBufferIndex > 0) { - // @ts-expect-error `_bufferIndex` is used on string chunks. - view.push(chunks[endIndex].slice(0, endBufferIndex)); - } - } - - return view -} -/** - * Get the string value of a slice of chunks. - * - * @param {Chunk[]} chunks - * @param {boolean} [expandTabs=false] - * @returns {string} - */ - -function serializeChunks(chunks, expandTabs) { - let index = -1; - /** @type {string[]} */ - - const result = []; - /** @type {boolean|undefined} */ - - let atTab; - - while (++index < chunks.length) { - const chunk = chunks[index]; - /** @type {string} */ - - let value; - - if (typeof chunk === 'string') { - value = chunk; - } else - switch (chunk) { - case -5: { - value = '\r'; - break - } - - case -4: { - value = '\n'; - break - } - - case -3: { - value = '\r' + '\n'; - break - } - - case -2: { - value = expandTabs ? ' ' : '\t'; - break - } - - case -1: { - if (!expandTabs && atTab) continue - value = ' '; - break - } - - default: { - // Currently only replacement character. - value = String.fromCharCode(chunk); - } - } - - atTab = chunk === -2; - result.push(value); - } - - return result.join('') -} - -/** - * @typedef {import('micromark-util-types').Extension} Extension - */ -/** @type {Extension['document']} */ - -const document$1 = { - [42]: list$1, - [43]: list$1, - [45]: list$1, - [48]: list$1, - [49]: list$1, - [50]: list$1, - [51]: list$1, - [52]: list$1, - [53]: list$1, - [54]: list$1, - [55]: list$1, - [56]: list$1, - [57]: list$1, - [62]: blockQuote -}; -/** @type {Extension['contentInitial']} */ - -const contentInitial = { - [91]: definition$1 -}; -/** @type {Extension['flowInitial']} */ - -const flowInitial = { - [-2]: codeIndented, - [-1]: codeIndented, - [32]: codeIndented -}; -/** @type {Extension['flow']} */ - -const flow = { - [35]: headingAtx, - [42]: thematicBreak$1, - [45]: [setextUnderline, thematicBreak$1], - [60]: htmlFlow, - [61]: setextUnderline, - [95]: thematicBreak$1, - [96]: codeFenced, - [126]: codeFenced -}; -/** @type {Extension['string']} */ - -const string = { - [38]: characterReference$1, - [92]: characterEscape$1 -}; -/** @type {Extension['text']} */ - -const text$2 = { - [-5]: lineEnding, - [-4]: lineEnding, - [-3]: lineEnding, - [33]: labelStartImage, - [38]: characterReference$1, - [42]: attention, - [60]: [autolink, htmlText], - [91]: labelStartLink, - [92]: [hardBreakEscape, characterEscape$1], - [93]: labelEnd, - [95]: attention, - [96]: codeText -}; -/** @type {Extension['insideSpan']} */ - -const insideSpan = { - null: [attention, resolver] -}; -/** @type {Extension['attentionMarkers']} */ - -const attentionMarkers = { - null: [42, 95] -}; -/** @type {Extension['disable']} */ - -const disable = { - null: [] -}; - -var defaultConstructs = /*#__PURE__*/Object.freeze({ - __proto__: null, - document: document$1, - contentInitial: contentInitial, - flowInitial: flowInitial, - flow: flow, - string: string, - text: text$2, - insideSpan: insideSpan, - attentionMarkers: attentionMarkers, - disable: disable -}); - -/** - * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct - * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension - * @typedef {import('micromark-util-types').ParseOptions} ParseOptions - * @typedef {import('micromark-util-types').ParseContext} ParseContext - * @typedef {import('micromark-util-types').Create} Create - */ -/** - * @param {ParseOptions} [options] - * @returns {ParseContext} - */ - -function parse(options = {}) { - /** @type {FullNormalizedExtension} */ - // @ts-expect-error `defaultConstructs` is full, so the result will be too. - const constructs = combineExtensions( - // @ts-expect-error Same as above. - [defaultConstructs].concat(options.extensions || []) - ); - /** @type {ParseContext} */ - - const parser = { - defined: [], - lazy: {}, - constructs, - content: create(content$1), - document: create(document$2), - flow: create(flow$1), - string: create(string$1), - text: create(text$3) - }; - return parser - /** - * @param {InitialConstruct} initial - */ - - function create(initial) { - return creator - /** @type {Create} */ - - function creator(from) { - return createTokenizer(parser, initial, from) - } - } -} - -/** - * @typedef {import('micromark-util-types').Encoding} Encoding - * @typedef {import('micromark-util-types').Value} Value - * @typedef {import('micromark-util-types').Chunk} Chunk - * @typedef {import('micromark-util-types').Code} Code - */ - -/** - * @callback Preprocessor - * @param {Value} value - * @param {Encoding} [encoding] - * @param {boolean} [end=false] - * @returns {Chunk[]} - */ -const search = /[\0\t\n\r]/g; -/** - * @returns {Preprocessor} - */ - -function preprocess() { - let column = 1; - let buffer = ''; - /** @type {boolean|undefined} */ - - let start = true; - /** @type {boolean|undefined} */ - - let atCarriageReturn; - return preprocessor - /** @type {Preprocessor} */ - - function preprocessor(value, encoding, end) { - /** @type {Chunk[]} */ - const chunks = []; - /** @type {RegExpMatchArray|null} */ - - let match; - /** @type {number} */ - - let next; - /** @type {number} */ - - let startPosition; - /** @type {number} */ - - let endPosition; - /** @type {Code} */ - - let code; // @ts-expect-error `Buffer` does allow an encoding. - - value = buffer + value.toString(encoding); - startPosition = 0; - buffer = ''; - - if (start) { - if (value.charCodeAt(0) === 65279) { - startPosition++; - } - - start = undefined; - } - - while (startPosition < value.length) { - search.lastIndex = startPosition; - match = search.exec(value); - endPosition = - match && match.index !== undefined ? match.index : value.length; - code = value.charCodeAt(endPosition); - - if (!match) { - buffer = value.slice(startPosition); - break - } - - if (code === 10 && startPosition === endPosition && atCarriageReturn) { - chunks.push(-3); - atCarriageReturn = undefined; - } else { - if (atCarriageReturn) { - chunks.push(-5); - atCarriageReturn = undefined; - } - - if (startPosition < endPosition) { - chunks.push(value.slice(startPosition, endPosition)); - column += endPosition - startPosition; - } - - switch (code) { - case 0: { - chunks.push(65533); - column++; - break - } - - case 9: { - next = Math.ceil(column / 4) * 4; - chunks.push(-2); - - while (column++ < next) chunks.push(-1); - - break - } - - case 10: { - chunks.push(-4); - column = 1; - break - } - - default: { - atCarriageReturn = true; - column = 1; - } - } - } - - startPosition = endPosition + 1; - } - - if (end) { - if (atCarriageReturn) chunks.push(-5); - if (buffer) chunks.push(buffer); - chunks.push(null); - } - - return chunks - } -} - -/** - * @typedef {import('micromark-util-types').Event} Event - */ -/** - * @param {Event[]} events - * @returns {Event[]} - */ - -function postprocess(events) { - while (!subtokenize(events)) { - // Empty - } - - return events -} - -/** - * Turn the number (in string form as either hexa- or plain decimal) coming from - * a numeric character reference into a character. - * - * @param {string} value - * Value to decode. - * @param {number} base - * Numeric base. - * @returns {string} - */ -function decodeNumericCharacterReference(value, base) { - const code = Number.parseInt(value, base); - - if ( - // C0 except for HT, LF, FF, CR, space - code < 9 || - code === 11 || - (code > 13 && code < 32) || // Control character (DEL) of the basic block and C1 controls. - (code > 126 && code < 160) || // Lone high surrogates and low surrogates. - (code > 55295 && code < 57344) || // Noncharacters. - (code > 64975 && code < 65008) || - (code & 65535) === 65535 || - (code & 65535) === 65534 || // Out of range - code > 1114111 - ) { - return '\uFFFD' - } - - return String.fromCharCode(code) -} - -/** - * @typedef {import('micromark-util-types').Encoding} Encoding - * @typedef {import('micromark-util-types').Event} Event - * @typedef {import('micromark-util-types').ParseOptions} ParseOptions - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext - * @typedef {import('micromark-util-types').Value} Value - * @typedef {Root|Root['children'][number]} Node - * @typedef {import('unist').Parent} Parent - * @typedef {import('unist').Point} Point - * @typedef {import('mdast').Break} Break - * @typedef {import('mdast').Blockquote} Blockquote - * @typedef {import('mdast').Code} Code - * @typedef {import('mdast').Definition} Definition - * @typedef {import('mdast').Emphasis} Emphasis - * @typedef {import('mdast').Heading} Heading - * @typedef {import('mdast').HTML} HTML - * @typedef {import('mdast').Image} Image - * @typedef {import('mdast').InlineCode} InlineCode - * @typedef {import('mdast').Link} Link - * @typedef {import('mdast').List} List - * @typedef {import('mdast').ListItem} ListItem - * @typedef {import('mdast').Paragraph} Paragraph - * @typedef {import('mdast').Root} Root - * @typedef {import('mdast').Strong} Strong - * @typedef {import('mdast').Text} Text - * @typedef {import('mdast').ThematicBreak} ThematicBreak - */ -const own$4 = {}.hasOwnProperty; -/** - * @param value Markdown to parse (`string` or `Buffer`). - * @param [encoding] Character encoding to understand `value` as when it’s a `Buffer` (`string`, default: `'utf8'`). - * @param [options] Configuration - */ - -const fromMarkdown = - /** - * @type {( - * ((value: Value, encoding: Encoding, options?: Options) => Root) & - * ((value: Value, options?: Options) => Root) - * )} - */ - - /** - * @param {Value} value - * @param {Encoding} [encoding] - * @param {Options} [options] - * @returns {Root} - */ - function (value, encoding, options) { - if (typeof encoding !== 'string') { - options = encoding; - encoding = undefined; - } - - return compiler(options)( - postprocess( - parse(options).document().write(preprocess()(value, encoding, true)) - ) - ) - }; -/** - * Note this compiler only understand complete buffering, not streaming. - * - * @param {Options} [options] - */ - -function compiler(options = {}) { - /** @type {NormalizedExtension} */ - // @ts-expect-error: our base has all required fields, so the result will too. - const config = configure$1( - { - transforms: [], - canContainEols: [ - 'emphasis', - 'fragment', - 'heading', - 'paragraph', - 'strong' - ], - enter: { - autolink: opener(link), - autolinkProtocol: onenterdata, - autolinkEmail: onenterdata, - atxHeading: opener(heading), - blockQuote: opener(blockQuote), - characterEscape: onenterdata, - characterReference: onenterdata, - codeFenced: opener(codeFlow), - codeFencedFenceInfo: buffer, - codeFencedFenceMeta: buffer, - codeIndented: opener(codeFlow, buffer), - codeText: opener(codeText, buffer), - codeTextData: onenterdata, - data: onenterdata, - codeFlowValue: onenterdata, - definition: opener(definition), - definitionDestinationString: buffer, - definitionLabelString: buffer, - definitionTitleString: buffer, - emphasis: opener(emphasis), - hardBreakEscape: opener(hardBreak), - hardBreakTrailing: opener(hardBreak), - htmlFlow: opener(html, buffer), - htmlFlowData: onenterdata, - htmlText: opener(html, buffer), - htmlTextData: onenterdata, - image: opener(image), - label: buffer, - link: opener(link), - listItem: opener(listItem), - listItemValue: onenterlistitemvalue, - listOrdered: opener(list, onenterlistordered), - listUnordered: opener(list), - paragraph: opener(paragraph), - reference: onenterreference, - referenceString: buffer, - resourceDestinationString: buffer, - resourceTitleString: buffer, - setextHeading: opener(heading), - strong: opener(strong), - thematicBreak: opener(thematicBreak) - }, - exit: { - atxHeading: closer(), - atxHeadingSequence: onexitatxheadingsequence, - autolink: closer(), - autolinkEmail: onexitautolinkemail, - autolinkProtocol: onexitautolinkprotocol, - blockQuote: closer(), - characterEscapeValue: onexitdata, - characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, - characterReferenceMarkerNumeric: onexitcharacterreferencemarker, - characterReferenceValue: onexitcharacterreferencevalue, - codeFenced: closer(onexitcodefenced), - codeFencedFence: onexitcodefencedfence, - codeFencedFenceInfo: onexitcodefencedfenceinfo, - codeFencedFenceMeta: onexitcodefencedfencemeta, - codeFlowValue: onexitdata, - codeIndented: closer(onexitcodeindented), - codeText: closer(onexitcodetext), - codeTextData: onexitdata, - data: onexitdata, - definition: closer(), - definitionDestinationString: onexitdefinitiondestinationstring, - definitionLabelString: onexitdefinitionlabelstring, - definitionTitleString: onexitdefinitiontitlestring, - emphasis: closer(), - hardBreakEscape: closer(onexithardbreak), - hardBreakTrailing: closer(onexithardbreak), - htmlFlow: closer(onexithtmlflow), - htmlFlowData: onexitdata, - htmlText: closer(onexithtmltext), - htmlTextData: onexitdata, - image: closer(onexitimage), - label: onexitlabel, - labelText: onexitlabeltext, - lineEnding: onexitlineending, - link: closer(onexitlink), - listItem: closer(), - listOrdered: closer(), - listUnordered: closer(), - paragraph: closer(), - referenceString: onexitreferencestring, - resourceDestinationString: onexitresourcedestinationstring, - resourceTitleString: onexitresourcetitlestring, - resource: onexitresource, - setextHeading: closer(onexitsetextheading), - setextHeadingLineSequence: onexitsetextheadinglinesequence, - setextHeadingText: onexitsetextheadingtext, - strong: closer(), - thematicBreak: closer() - } - }, - options.mdastExtensions || [] - ); - /** @type {CompileData} */ - - const data = {}; - return compile - /** - * @param {Array.} events - * @returns {Root} - */ - - function compile(events) { - /** @type {Root} */ - let tree = { - type: 'root', - children: [] - }; - /** @type {CompileContext['stack']} */ - - const stack = [tree]; - /** @type {CompileContext['tokenStack']} */ - - const tokenStack = []; - /** @type {Array.} */ - - const listStack = []; - /** @type {Omit} */ - - const context = { - stack, - tokenStack, - config, - enter, - exit, - buffer, - resume, - setData, - getData - }; - let index = -1; - - while (++index < events.length) { - // We preprocess lists to add `listItem` tokens, and to infer whether - // items the list itself are spread out. - if ( - events[index][1].type === 'listOrdered' || - events[index][1].type === 'listUnordered' - ) { - if (events[index][0] === 'enter') { - listStack.push(index); - } else { - const tail = listStack.pop(); - index = prepareList(events, tail, index); - } - } - } - - index = -1; - - while (++index < events.length) { - const handler = config[events[index][0]]; - - if (own$4.call(handler, events[index][1].type)) { - handler[events[index][1].type].call( - Object.assign( - { - sliceSerialize: events[index][2].sliceSerialize - }, - context - ), - events[index][1] - ); - } - } - - if (tokenStack.length > 0) { - throw new Error( - 'Cannot close document, a token (`' + - tokenStack[tokenStack.length - 1].type + - '`, ' + - stringifyPosition$1({ - start: tokenStack[tokenStack.length - 1].start, - end: tokenStack[tokenStack.length - 1].end - }) + - ') is still open' - ) - } // Figure out `root` position. - - tree.position = { - start: point( - events.length > 0 - ? events[0][1].start - : { - line: 1, - column: 1, - offset: 0 - } - ), - end: point( - events.length > 0 - ? events[events.length - 2][1].end - : { - line: 1, - column: 1, - offset: 0 - } - ) - }; - index = -1; - - while (++index < config.transforms.length) { - tree = config.transforms[index](tree) || tree; - } - - return tree - } - /** - * @param {Array.} events - * @param {number} start - * @param {number} length - * @returns {number} - */ - - function prepareList(events, start, length) { - let index = start - 1; - let containerBalance = -1; - let listSpread = false; - /** @type {Token|undefined} */ - - let listItem; - /** @type {number|undefined} */ - - let lineIndex; - /** @type {number|undefined} */ - - let firstBlankLineIndex; - /** @type {boolean|undefined} */ - - let atMarker; - - while (++index <= length) { - const event = events[index]; - - if ( - event[1].type === 'listUnordered' || - event[1].type === 'listOrdered' || - event[1].type === 'blockQuote' - ) { - if (event[0] === 'enter') { - containerBalance++; - } else { - containerBalance--; - } - - atMarker = undefined; - } else if (event[1].type === 'lineEndingBlank') { - if (event[0] === 'enter') { - if ( - listItem && - !atMarker && - !containerBalance && - !firstBlankLineIndex - ) { - firstBlankLineIndex = index; - } - - atMarker = undefined; - } - } else if ( - event[1].type === 'linePrefix' || - event[1].type === 'listItemValue' || - event[1].type === 'listItemMarker' || - event[1].type === 'listItemPrefix' || - event[1].type === 'listItemPrefixWhitespace' - ) ; else { - atMarker = undefined; - } - - if ( - (!containerBalance && - event[0] === 'enter' && - event[1].type === 'listItemPrefix') || - (containerBalance === -1 && - event[0] === 'exit' && - (event[1].type === 'listUnordered' || - event[1].type === 'listOrdered')) - ) { - if (listItem) { - let tailIndex = index; - lineIndex = undefined; - - while (tailIndex--) { - const tailEvent = events[tailIndex]; - - if ( - tailEvent[1].type === 'lineEnding' || - tailEvent[1].type === 'lineEndingBlank' - ) { - if (tailEvent[0] === 'exit') continue - - if (lineIndex) { - events[lineIndex][1].type = 'lineEndingBlank'; - listSpread = true; - } - - tailEvent[1].type = 'lineEnding'; - lineIndex = tailIndex; - } else if ( - tailEvent[1].type === 'linePrefix' || - tailEvent[1].type === 'blockQuotePrefix' || - tailEvent[1].type === 'blockQuotePrefixWhitespace' || - tailEvent[1].type === 'blockQuoteMarker' || - tailEvent[1].type === 'listItemIndent' - ) ; else { - break - } - } - - if ( - firstBlankLineIndex && - (!lineIndex || firstBlankLineIndex < lineIndex) - ) { - // @ts-expect-error Patched. - listItem._spread = true; - } // Fix position. - - listItem.end = Object.assign( - {}, - lineIndex ? events[lineIndex][1].start : event[1].end - ); - events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]); - index++; - length++; - } // Create a new list item. - - if (event[1].type === 'listItemPrefix') { - listItem = { - type: 'listItem', - // @ts-expect-error Patched - _spread: false, - start: Object.assign({}, event[1].start) - }; // @ts-expect-error: `listItem` is most definitely defined, TS... - - events.splice(index, 0, ['enter', listItem, event[2]]); - index++; - length++; - firstBlankLineIndex = undefined; - atMarker = true; - } - } - } // @ts-expect-error Patched. - - events[start][1]._spread = listSpread; - return length - } - /** - * @type {CompileContext['setData']} - * @param [value] - */ - - function setData(key, value) { - data[key] = value; - } - /** - * @type {CompileContext['getData']} - * @template {string} K - * @param {K} key - * @returns {CompileData[K]} - */ - - function getData(key) { - return data[key] - } - /** - * @param {Point} d - * @returns {Point} - */ - - function point(d) { - return { - line: d.line, - column: d.column, - offset: d.offset - } - } - /** - * @param {(token: Token) => Node} create - * @param {Handle} [and] - * @returns {Handle} - */ - - function opener(create, and) { - return open - /** - * @this {CompileContext} - * @param {Token} token - * @returns {void} - */ - - function open(token) { - enter.call(this, create(token), token); - if (and) and.call(this, token); - } - } - /** @type {CompileContext['buffer']} */ - - function buffer() { - // @ts-expect-error: Custom node type to collect text. - this.stack.push({ - type: 'fragment', - children: [] - }); - } - /** - * @type {CompileContext['enter']} - * @template {Node} N - * @this {CompileContext} - * @param {N} node - * @param {Token} token - * @returns {N} - */ - - function enter(node, token) { - /** @type {Parent} */ - // @ts-expect-error: Assume parent. - const parent = this.stack[this.stack.length - 1]; - parent.children.push(node); - this.stack.push(node); - this.tokenStack.push(token); // @ts-expect-error: `end` will be patched later. - - node.position = { - start: point(token.start) - }; - return node - } - /** - * @param {Handle} [and] - * @returns {Handle} - */ - - function closer(and) { - return close - /** - * @this {CompileContext} - * @param {Token} token - * @returns {void} - */ - - function close(token) { - if (and) and.call(this, token); - exit.call(this, token); - } - } - /** @type {CompileContext['exit']} */ - - function exit(token) { - const node = this.stack.pop(); - const open = this.tokenStack.pop(); - - if (!open) { - throw new Error( - 'Cannot close `' + - token.type + - '` (' + - stringifyPosition$1({ - start: token.start, - end: token.end - }) + - '): it’s not open' - ) - } else if (open.type !== token.type) { - throw new Error( - 'Cannot close `' + - token.type + - '` (' + - stringifyPosition$1({ - start: token.start, - end: token.end - }) + - '): a different token (`' + - open.type + - '`, ' + - stringifyPosition$1({ - start: open.start, - end: open.end - }) + - ') is open' - ) - } - - node.position.end = point(token.end); - return node - } - /** - * @this {CompileContext} - * @returns {string} - */ - - function resume() { - return toString(this.stack.pop()) - } // - // Handlers. - // - - /** @type {Handle} */ - - function onenterlistordered() { - setData('expectingFirstListItemValue', true); - } - /** @type {Handle} */ - - function onenterlistitemvalue(token) { - if (getData('expectingFirstListItemValue')) { - this.stack[this.stack.length - 2].start = Number.parseInt( - this.sliceSerialize(token), - 10 - ); - setData('expectingFirstListItemValue'); - } - } - /** @type {Handle} */ - - function onexitcodefencedfenceinfo() { - const data = this.resume(); - this.stack[this.stack.length - 1].lang = data; - } - /** @type {Handle} */ - - function onexitcodefencedfencemeta() { - const data = this.resume(); - this.stack[this.stack.length - 1].meta = data; - } - /** @type {Handle} */ - - function onexitcodefencedfence() { - // Exit if this is the closing fence. - if (getData('flowCodeInside')) return - this.buffer(); - setData('flowCodeInside', true); - } - /** @type {Handle} */ - - function onexitcodefenced() { - const data = this.resume(); - this.stack[this.stack.length - 1].value = data.replace( - /^(\r?\n|\r)|(\r?\n|\r)$/g, - '' - ); - setData('flowCodeInside'); - } - /** @type {Handle} */ - - function onexitcodeindented() { - const data = this.resume(); - this.stack[this.stack.length - 1].value = data.replace(/(\r?\n|\r)$/g, ''); - } - /** @type {Handle} */ - - function onexitdefinitionlabelstring(token) { - // Discard label, use the source content instead. - const label = this.resume(); - this.stack[this.stack.length - 1].label = label; - this.stack[this.stack.length - 1].identifier = normalizeIdentifier( - this.sliceSerialize(token) - ).toLowerCase(); - } - /** @type {Handle} */ - - function onexitdefinitiontitlestring() { - const data = this.resume(); - this.stack[this.stack.length - 1].title = data; - } - /** @type {Handle} */ - - function onexitdefinitiondestinationstring() { - const data = this.resume(); - this.stack[this.stack.length - 1].url = data; - } - /** @type {Handle} */ - - function onexitatxheadingsequence(token) { - if (!this.stack[this.stack.length - 1].depth) { - this.stack[this.stack.length - 1].depth = - this.sliceSerialize(token).length; - } - } - /** @type {Handle} */ - - function onexitsetextheadingtext() { - setData('setextHeadingSlurpLineEnding', true); - } - /** @type {Handle} */ - - function onexitsetextheadinglinesequence(token) { - this.stack[this.stack.length - 1].depth = - this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2; - } - /** @type {Handle} */ - - function onexitsetextheading() { - setData('setextHeadingSlurpLineEnding'); - } - /** @type {Handle} */ - - function onenterdata(token) { - /** @type {Parent} */ - // @ts-expect-error: assume parent. - const parent = this.stack[this.stack.length - 1]; - /** @type {Node} */ - // @ts-expect-error: assume child. - - let tail = parent.children[parent.children.length - 1]; - - if (!tail || tail.type !== 'text') { - // Add a new text node. - tail = text(); // @ts-expect-error: we’ll add `end` later. - - tail.position = { - start: point(token.start) - }; - parent.children.push(tail); - } - - this.stack.push(tail); - } - /** @type {Handle} */ - - function onexitdata(token) { - const tail = this.stack.pop(); - tail.value += this.sliceSerialize(token); - tail.position.end = point(token.end); - } - /** @type {Handle} */ - - function onexitlineending(token) { - /** @type {Parent} */ - // @ts-expect-error: supposed to be a parent. - const context = this.stack[this.stack.length - 1]; - - // If we’re at a hard break, include the line ending in there. - if (getData('atHardBreak')) { - const tail = context.children[context.children.length - 1]; - tail.position.end = point(token.end); - setData('atHardBreak'); - return - } - - if ( - !getData('setextHeadingSlurpLineEnding') && - config.canContainEols.includes(context.type) - ) { - onenterdata.call(this, token); - onexitdata.call(this, token); - } - } - /** @type {Handle} */ - - function onexithardbreak() { - setData('atHardBreak', true); - } - /** @type {Handle} */ - - function onexithtmlflow() { - const data = this.resume(); - this.stack[this.stack.length - 1].value = data; - } - /** @type {Handle} */ - - function onexithtmltext() { - const data = this.resume(); - this.stack[this.stack.length - 1].value = data; - } - /** @type {Handle} */ - - function onexitcodetext() { - const data = this.resume(); - this.stack[this.stack.length - 1].value = data; - } - /** @type {Handle} */ - - function onexitlink() { - const context = this.stack[this.stack.length - 1]; // To do: clean. - - if (getData('inReference')) { - context.type += 'Reference'; - context.referenceType = getData('referenceType') || 'shortcut'; - delete context.url; - delete context.title; - } else { - delete context.identifier; - delete context.label; - delete context.referenceType; - } - - setData('referenceType'); - } - /** @type {Handle} */ - - function onexitimage() { - const context = this.stack[this.stack.length - 1]; // To do: clean. - - if (getData('inReference')) { - context.type += 'Reference'; - context.referenceType = getData('referenceType') || 'shortcut'; - delete context.url; - delete context.title; - } else { - delete context.identifier; - delete context.label; - delete context.referenceType; - } - - setData('referenceType'); - } - /** @type {Handle} */ - - function onexitlabeltext(token) { - this.stack[this.stack.length - 2].identifier = normalizeIdentifier( - this.sliceSerialize(token) - ).toLowerCase(); - } - /** @type {Handle} */ - - function onexitlabel() { - const fragment = this.stack[this.stack.length - 1]; - const value = this.resume(); - this.stack[this.stack.length - 1].label = value; // Assume a reference. - - setData('inReference', true); - - if (this.stack[this.stack.length - 1].type === 'link') { - this.stack[this.stack.length - 1].children = fragment.children; - } else { - this.stack[this.stack.length - 1].alt = value; - } - } - /** @type {Handle} */ - - function onexitresourcedestinationstring() { - const data = this.resume(); - this.stack[this.stack.length - 1].url = data; - } - /** @type {Handle} */ - - function onexitresourcetitlestring() { - const data = this.resume(); - this.stack[this.stack.length - 1].title = data; - } - /** @type {Handle} */ - - function onexitresource() { - setData('inReference'); - } - /** @type {Handle} */ - - function onenterreference() { - setData('referenceType', 'collapsed'); - } - /** @type {Handle} */ - - function onexitreferencestring(token) { - const label = this.resume(); - this.stack[this.stack.length - 1].label = label; - this.stack[this.stack.length - 1].identifier = normalizeIdentifier( - this.sliceSerialize(token) - ).toLowerCase(); - setData('referenceType', 'full'); - } - /** @type {Handle} */ - - function onexitcharacterreferencemarker(token) { - setData('characterReferenceType', token.type); - } - /** @type {Handle} */ - - function onexitcharacterreferencevalue(token) { - const data = this.sliceSerialize(token); - const type = getData('characterReferenceType'); - /** @type {string} */ - - let value; - - if (type) { - value = decodeNumericCharacterReference( - data, - type === 'characterReferenceMarkerNumeric' ? 10 : 16 - ); - setData('characterReferenceType'); - } else { - // @ts-expect-error `decodeEntity` can return false for invalid named - // character references, but everything we’ve tokenized is valid. - value = decodeEntity(data); - } - - const tail = this.stack.pop(); - tail.value += value; - tail.position.end = point(token.end); - } - /** @type {Handle} */ - - function onexitautolinkprotocol(token) { - onexitdata.call(this, token); - this.stack[this.stack.length - 1].url = this.sliceSerialize(token); - } - /** @type {Handle} */ - - function onexitautolinkemail(token) { - onexitdata.call(this, token); - this.stack[this.stack.length - 1].url = - 'mailto:' + this.sliceSerialize(token); - } // - // Creaters. - // - - /** @returns {Blockquote} */ - - function blockQuote() { - return { - type: 'blockquote', - children: [] - } - } - /** @returns {Code} */ - - function codeFlow() { - // @ts-expect-error: we’ve always used `null`. - return { - type: 'code', - lang: null, - meta: null, - value: '' - } - } - /** @returns {InlineCode} */ - - function codeText() { - return { - type: 'inlineCode', - value: '' - } - } - /** @returns {Definition} */ - - function definition() { - return { - type: 'definition', - identifier: '', - // @ts-expect-error: we’ve always used `null`. - label: null, - // @ts-expect-error: we’ve always used `null`. - title: null, - url: '' - } - } - /** @returns {Emphasis} */ - - function emphasis() { - return { - type: 'emphasis', - children: [] - } - } - /** @returns {Heading} */ - - function heading() { - // @ts-expect-error `depth` will be set later. - return { - type: 'heading', - depth: undefined, - children: [] - } - } - /** @returns {Break} */ - - function hardBreak() { - return { - type: 'break' - } - } - /** @returns {HTML} */ - - function html() { - return { - type: 'html', - value: '' - } - } - /** @returns {Image} */ - - function image() { - // @ts-expect-error: we’ve always used `null`. - return { - type: 'image', - title: null, - url: '', - alt: null - } - } - /** @returns {Link} */ - - function link() { - // @ts-expect-error: we’ve always used `null`. - return { - type: 'link', - title: null, - url: '', - children: [] - } - } - /** - * @param {Token} token - * @returns {List} - */ - - function list(token) { - return { - type: 'list', - ordered: token.type === 'listOrdered', - // @ts-expect-error: we’ve always used `null`. - start: null, - // @ts-expect-error Patched. - spread: token._spread, - children: [] - } - } - /** - * @param {Token} token - * @returns {ListItem} - */ - - function listItem(token) { - return { - type: 'listItem', - // @ts-expect-error Patched. - spread: token._spread, - // @ts-expect-error: we’ve always used `null`. - checked: null, - children: [] - } - } - /** @returns {Paragraph} */ - - function paragraph() { - return { - type: 'paragraph', - children: [] - } - } - /** @returns {Strong} */ - - function strong() { - return { - type: 'strong', - children: [] - } - } - /** @returns {Text} */ - - function text() { - return { - type: 'text', - value: '' - } - } - /** @returns {ThematicBreak} */ - - function thematicBreak() { - return { - type: 'thematicBreak' - } - } -} -/** - * @param {Extension} combined - * @param {Array.>} extensions - * @returns {Extension} - */ - -function configure$1(combined, extensions) { - let index = -1; - - while (++index < extensions.length) { - const value = extensions[index]; - - if (Array.isArray(value)) { - configure$1(combined, value); - } else { - extension(combined, value); - } - } - - return combined -} -/** - * @param {Extension} combined - * @param {Extension} extension - * @returns {void} - */ - -function extension(combined, extension) { - /** @type {string} */ - let key; - - for (key in extension) { - if (own$4.call(extension, key)) { - const list = key === 'canContainEols' || key === 'transforms'; - const maybe = own$4.call(combined, key) ? combined[key] : undefined; - /* c8 ignore next */ - - const left = maybe || (combined[key] = list ? [] : {}); - const right = extension[key]; - - if (right) { - if (list) { - // @ts-expect-error: `left` is an array. - combined[key] = [...left, ...right]; - } else { - Object.assign(left, right); - } - } - } - } -} - -/** - * @typedef {import('mdast').Root} Root - * @typedef {import('mdast-util-from-markdown').Options} Options - */ - -/** @type {import('unified').Plugin<[Options?] | void[], string, Root>} */ -function remarkParse(options) { - /** @type {import('unified').ParserFunction} */ - const parser = (doc) => { - // Assume options. - const settings = /** @type {Options} */ (this.data('settings')); - - return fromMarkdown( - doc, - Object.assign({}, settings, options, { - // Note: these options are not in the readme. - // The goal is for them to be set by plugins on `data` instead of being - // passed by users. - extensions: this.data('micromarkExtensions') || [], - mdastExtensions: this.data('fromMarkdownExtensions') || [] - }) - ) - }; - - Object.assign(this, {Parser: parser}); -} - -var own$3 = {}.hasOwnProperty; - -/** - * @callback Handler - * @param {...unknown} value - * @return {unknown} - * - * @typedef {Record} Handlers - * - * @typedef {Object} Options - * @property {Handler} [unknown] - * @property {Handler} [invalid] - * @property {Handlers} [handlers] - */ - -/** - * Handle values based on a property. - * - * @param {string} key - * @param {Options} [options] - */ -function zwitch(key, options) { - var settings = options || {}; - - /** - * Handle one value. - * Based on the bound `key`, a respective handler will be called. - * If `value` is not an object, or doesn’t have a `key` property, the special - * “invalid” handler will be called. - * If `value` has an unknown `key`, the special “unknown” handler will be - * called. - * - * All arguments, and the context object, are passed through to the handler, - * and it’s result is returned. - * - * @param {...unknown} [value] - * @this {unknown} - * @returns {unknown} - * @property {Handler} invalid - * @property {Handler} unknown - * @property {Handlers} handlers - */ - function one(value) { - var fn = one.invalid; - var handlers = one.handlers; - - if (value && own$3.call(value, key)) { - fn = own$3.call(handlers, value[key]) ? handlers[value[key]] : one.unknown; - } - - if (fn) { - return fn.apply(this, arguments) - } - } - - one.handlers = settings.handlers || {}; - one.invalid = settings.invalid; - one.unknown = settings.unknown; - - return one -} - -/** - * @typedef {import('./types.js').Options} Options - * @typedef {import('./types.js').Context} Context - */ - -/** - * @param {Context} base - * @param {Options} extension - * @returns {Context} - */ -function configure(base, extension) { - let index = -1; - /** @type {string} */ - let key; - - // First do subextensions. - if (extension.extensions) { - while (++index < extension.extensions.length) { - configure(base, extension.extensions[index]); - } - } - - for (key in extension) { - if (key === 'extensions') ; else if (key === 'unsafe' || key === 'join') { - /* c8 ignore next 2 */ - // @ts-expect-error: hush. - base[key] = [...(base[key] || []), ...(extension[key] || [])]; - } else if (key === 'handlers') { - base[key] = Object.assign(base[key], extension[key] || {}); - } else { - // @ts-expect-error: hush. - base.options[key] = extension[key]; - } - } - - return base -} - -/** - * @typedef {import('../types.js').Node} Node - * @typedef {import('../types.js').Parent} Parent - * @typedef {import('../types.js').Join} Join - * @typedef {import('../types.js').Context} Context - */ - -/** - * @param {Parent} parent - * @param {Context} context - * @returns {string} - */ -function containerFlow(parent, context) { - const indexStack = context.indexStack; - const children = parent.children || []; - /** @type {Array.} */ - const results = []; - let index = -1; - - indexStack.push(-1); - - while (++index < children.length) { - const child = children[index]; - - indexStack[indexStack.length - 1] = index; - - results.push( - context.handle(child, parent, context, {before: '\n', after: '\n'}) - ); - - if (child.type !== 'list') { - context.bulletLastUsed = undefined; - } - - if (index < children.length - 1) { - results.push(between(child, children[index + 1])); - } - } - - indexStack.pop(); - - return results.join('') - - /** - * @param {Node} left - * @param {Node} right - * @returns {string} - */ - function between(left, right) { - let index = context.join.length; - - while (index--) { - const result = context.join[index](left, right, parent, context); - - if (result === true || result === 1) { - break - } - - if (typeof result === 'number') { - return '\n'.repeat(1 + result) - } - - if (result === false) { - return '\n\n\n\n' - } - } - - return '\n\n' - } -} - -/** - * @callback Map - * @param {string} value - * @param {number} line - * @param {boolean} blank - * @returns {string} - */ - -const eol = /\r?\n|\r/g; - -/** - * @param {string} value - * @param {Map} map - * @returns {string} - */ -function indentLines(value, map) { - /** @type {Array.} */ - const result = []; - let start = 0; - let line = 0; - /** @type {RegExpExecArray|null} */ - let match; - - while ((match = eol.exec(value))) { - one(value.slice(start, match.index)); - result.push(match[0]); - start = match.index + match[0].length; - line++; - } - - one(value.slice(start)); - - return result.join('') - - /** - * @param {string} value - */ - function one(value) { - result.push(map(value, line, !value)); - } -} - -/** - * @typedef {import('mdast').Blockquote} Blockquote - * @typedef {import('../types.js').Handle} Handle - * @typedef {import('../util/indent-lines.js').Map} Map - */ - -/** - * @type {Handle} - * @param {Blockquote} node - */ -function blockquote(node, _, context) { - const exit = context.enter('blockquote'); - const value = indentLines(containerFlow(node, context), map$1); - exit(); - return value -} - -/** @type {Map} */ -function map$1(line, _, blank) { - return '>' + (blank ? '' : ' ') + line -} - -/** - * @typedef {import('../types.js').Unsafe} Unsafe - */ - -/** - * @param {Array.} stack - * @param {Unsafe} pattern - * @returns {boolean} - */ -function patternInScope(stack, pattern) { - return ( - listInScope(stack, pattern.inConstruct, true) && - !listInScope(stack, pattern.notInConstruct, false) - ) -} - -/** - * @param {Array.} stack - * @param {Unsafe['inConstruct']} list - * @param {boolean} none - * @returns {boolean} - */ -function listInScope(stack, list, none) { - if (!list) { - return none - } - - if (typeof list === 'string') { - list = [list]; - } - - let index = -1; - - while (++index < list.length) { - if (stack.includes(list[index])) { - return true - } - } - - return false -} - -/** - * @typedef {import('../types.js').Handle} Handle - * @typedef {import('mdast').Break} Break - */ - -/** - * @type {Handle} - * @param {Break} _ - */ -function hardBreak(_, _1, context, safe) { - let index = -1; - - while (++index < context.unsafe.length) { - // If we can’t put eols in this construct (setext headings, tables), use a - // space instead. - if ( - context.unsafe[index].character === '\n' && - patternInScope(context.stack, context.unsafe[index]) - ) { - return /[ \t]/.test(safe.before) ? '' : ' ' - } - } - - return '\\\n' -} - -/** - * Get the count of the longest repeating streak of `character` in `value`. - * - * @param {string} value Content. - * @param {string} character Single character to look for - * @returns {number} Count of most frequent adjacent `character`s in `value` - */ -function longestStreak(value, character) { - var source = String(value); - var index = source.indexOf(character); - var expected = index; - var count = 0; - var max = 0; - - if (typeof character !== 'string' || character.length !== 1) { - throw new Error('Expected character') - } - - while (index !== -1) { - if (index === expected) { - if (++count > max) { - max = count; - } - } else { - count = 1; - } - - expected = index + 1; - index = source.indexOf(character, expected); - } - - return max -} - -/** - * @typedef {import('mdast').Code} Code - * @typedef {import('../types.js').Context} Context - */ - -/** - * @param {Code} node - * @param {Context} context - * @returns {boolean} - */ -function formatCodeAsIndented(node, context) { - return Boolean( - !context.options.fences && - node.value && - // If there’s no info… - !node.lang && - // And there’s a non-whitespace character… - /[^ \r\n]/.test(node.value) && - // And the value doesn’t start or end in a blank… - !/^[\t ]*(?:[\r\n]|$)|(?:^|[\r\n])[\t ]*$/.test(node.value) - ) -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkFence(context) { - const marker = context.options.fence || '`'; - - if (marker !== '`' && marker !== '~') { - throw new Error( - 'Cannot serialize code with `' + - marker + - '` for `options.fence`, expected `` ` `` or `~`' - ) - } - - return marker -} - -/** - * @typedef {import('../types.js').Unsafe} Unsafe - */ - -/** - * @param {Unsafe} pattern - * @returns {RegExp} - */ -function patternCompile(pattern) { - if (!pattern._compiled) { - const before = - (pattern.atBreak ? '[\\r\\n][\\t ]*' : '') + - (pattern.before ? '(?:' + pattern.before + ')' : ''); - - pattern._compiled = new RegExp( - (before ? '(' + before + ')' : '') + - (/[|\\{}()[\]^$+*?.-]/.test(pattern.character) ? '\\' : '') + - pattern.character + - (pattern.after ? '(?:' + pattern.after + ')' : ''), - 'g' - ); - } - - return pattern._compiled -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').SafeOptions} SafeOptions - */ - -/** - * @param {Context} context - * @param {string|null|undefined} input - * @param {SafeOptions & {encode?: Array.}} config - * @returns {string} - */ -function safe(context, input, config) { - const value = (config.before || '') + (input || '') + (config.after || ''); - /** @type {Array.} */ - const positions = []; - /** @type {Array.} */ - const result = []; - /** @type {Record} */ - const infos = {}; - let index = -1; - - while (++index < context.unsafe.length) { - const pattern = context.unsafe[index]; - - if (!patternInScope(context.stack, pattern)) { - continue - } - - const expression = patternCompile(pattern); - /** @type {RegExpExecArray|null} */ - let match; - - while ((match = expression.exec(value))) { - const before = 'before' in pattern || Boolean(pattern.atBreak); - const after = 'after' in pattern; - const position = match.index + (before ? match[1].length : 0); - - if (positions.includes(position)) { - if (infos[position].before && !before) { - infos[position].before = false; - } - - if (infos[position].after && !after) { - infos[position].after = false; - } - } else { - positions.push(position); - infos[position] = {before, after}; - } - } - } - - positions.sort(numerical); - - let start = config.before ? config.before.length : 0; - const end = value.length - (config.after ? config.after.length : 0); - index = -1; - - while (++index < positions.length) { - const position = positions[index]; - - // Character before or after matched: - if (position < start || position >= end) { - continue - } - - // If this character is supposed to be escaped because it has a condition on - // the next character, and the next character is definitly being escaped, - // then skip this escape. - if ( - (position + 1 < end && - positions[index + 1] === position + 1 && - infos[position].after && - !infos[position + 1].before && - !infos[position + 1].after) || - (positions[index - 1] === position - 1 && - infos[position].before && - !infos[position - 1].before && - !infos[position - 1].after) - ) { - continue - } - - if (start !== position) { - // If we have to use a character reference, an ampersand would be more - // correct, but as backslashes only care about punctuation, either will - // do the trick - result.push(escapeBackslashes(value.slice(start, position), '\\')); - } - - start = position; - - if ( - /[!-/:-@[-`{-~]/.test(value.charAt(position)) && - (!config.encode || !config.encode.includes(value.charAt(position))) - ) { - // Character escape. - result.push('\\'); - } else { - // Character reference. - result.push( - '&#x' + value.charCodeAt(position).toString(16).toUpperCase() + ';' - ); - start++; - } - } - - result.push(escapeBackslashes(value.slice(start, end), config.after)); - - return result.join('') -} - -/** - * @param {number} a - * @param {number} b - * @returns {number} - */ -function numerical(a, b) { - return a - b -} - -/** - * @param {string} value - * @param {string} after - * @returns {string} - */ -function escapeBackslashes(value, after) { - const expression = /\\(?=[!-/:-@[-`{-~])/g; - /** @type {Array.} */ - const positions = []; - /** @type {Array.} */ - const results = []; - const whole = value + after; - let index = -1; - let start = 0; - /** @type {RegExpExecArray|null} */ - let match; - - while ((match = expression.exec(whole))) { - positions.push(match.index); - } - - while (++index < positions.length) { - if (start !== positions[index]) { - results.push(value.slice(start, positions[index])); - } - - results.push('\\'); - start = positions[index]; - } - - results.push(value.slice(start)); - - return results.join('') -} - -/** - * @typedef {import('mdast').Code} Code - * @typedef {import('../types.js').Handle} Handle - * @typedef {import('../types.js').Exit} Exit - * @typedef {import('../util/indent-lines.js').Map} Map - */ - -/** - * @type {Handle} - * @param {Code} node - */ -function code$1(node, _, context) { - const marker = checkFence(context); - const raw = node.value || ''; - const suffix = marker === '`' ? 'GraveAccent' : 'Tilde'; - /** @type {string} */ - let value; - /** @type {Exit} */ - let exit; - - if (formatCodeAsIndented(node, context)) { - exit = context.enter('codeIndented'); - value = indentLines(raw, map); - } else { - const sequence = marker.repeat(Math.max(longestStreak(raw, marker) + 1, 3)); - /** @type {Exit} */ - let subexit; - exit = context.enter('codeFenced'); - value = sequence; - - if (node.lang) { - subexit = context.enter('codeFencedLang' + suffix); - value += safe(context, node.lang, { - before: '`', - after: ' ', - encode: ['`'] - }); - subexit(); - } - - if (node.lang && node.meta) { - subexit = context.enter('codeFencedMeta' + suffix); - value += - ' ' + - safe(context, node.meta, { - before: ' ', - after: '\n', - encode: ['`'] - }); - subexit(); - } - - value += '\n'; - - if (raw) { - value += raw + '\n'; - } - - value += sequence; - } - - exit(); - return value -} - -/** @type {Map} */ -function map(line, _, blank) { - return (blank ? '' : ' ') + line -} - -/** - * @typedef {import('mdast').Association} Association - */ - -const characterEscape = /\\([!-/:-@[-`{-~])/g; -const characterReference = /&(#(\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi; - -/** - * The `label` of an association is the string value: character escapes and - * references work, and casing is intact. - * The `identifier` is used to match one association to another: controversially, - * character escapes and references don’t work in this matching: `©` does - * not match `©`, and `\+` does not match `+`. - * But casing is ignored (and whitespace) is trimmed and collapsed: ` A\nb` - * matches `a b`. - * So, we do prefer the label when figuring out how we’re going to serialize: - * it has whitespace, casing, and we can ignore most useless character escapes - * and all character references. - * - * @param {Association} node - * @returns {string} - */ -function association(node) { - if (node.label || !node.identifier) { - return node.label || '' - } - - return node.identifier - .replace(characterEscape, '$1') - .replace(characterReference, decodeIfPossible) -} - -/** - * @param {string} $0 - * @param {string} $1 - * @returns {string} - */ -function decodeIfPossible($0, $1) { - return decodeEntity($1) || $0 -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkQuote(context) { - const marker = context.options.quote || '"'; - - if (marker !== '"' && marker !== "'") { - throw new Error( - 'Cannot serialize title with `' + - marker + - '` for `options.quote`, expected `"`, or `\'`' - ) - } - - return marker -} - -/** - * @typedef {import('mdast').Definition} Definition - * @typedef {import('../types.js').Handle} Handle - */ - -/** - * @type {Handle} - * @param {Definition} node - */ -function definition(node, _, context) { - const marker = checkQuote(context); - const suffix = marker === '"' ? 'Quote' : 'Apostrophe'; - const exit = context.enter('definition'); - let subexit = context.enter('label'); - let value = - '[' + safe(context, association(node), {before: '[', after: ']'}) + ']: '; - - subexit(); - - if ( - // If there’s no url, or… - !node.url || - // If there’s whitespace, enclosed is prettier. - /[ \t\r\n]/.test(node.url) - ) { - subexit = context.enter('destinationLiteral'); - value += '<' + safe(context, node.url, {before: '<', after: '>'}) + '>'; - } else { - // No whitespace, raw is prettier. - subexit = context.enter('destinationRaw'); - value += safe(context, node.url, {before: ' ', after: ' '}); - } - - subexit(); - - if (node.title) { - subexit = context.enter('title' + suffix); - value += - ' ' + - marker + - safe(context, node.title, {before: marker, after: marker}) + - marker; - subexit(); - } - - exit(); - - return value -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkEmphasis(context) { - const marker = context.options.emphasis || '*'; - - if (marker !== '*' && marker !== '_') { - throw new Error( - 'Cannot serialize emphasis with `' + - marker + - '` for `options.emphasis`, expected `*`, or `_`' - ) - } - - return marker -} - -/** - * @typedef {import('../types.js').Node} Node - * @typedef {import('../types.js').Parent} Parent - * @typedef {import('../types.js').SafeOptions} SafeOptions - * @typedef {import('../types.js').Context} Context - */ - -/** - * @param {Parent} parent - * @param {Context} context - * @param {SafeOptions} safeOptions - * @returns {string} - */ -function containerPhrasing(parent, context, safeOptions) { - const indexStack = context.indexStack; - const children = parent.children || []; - /** @type {Array.} */ - const results = []; - let index = -1; - let before = safeOptions.before; - - indexStack.push(-1); - - while (++index < children.length) { - const child = children[index]; - /** @type {string} */ - let after; - - indexStack[indexStack.length - 1] = index; - - if (index + 1 < children.length) { - // @ts-expect-error: hush, it’s actually a `zwitch`. - let handle = context.handle.handlers[children[index + 1].type]; - if (handle && handle.peek) handle = handle.peek; - after = handle - ? handle(children[index + 1], parent, context, { - before: '', - after: '' - }).charAt(0) - : ''; - } else { - after = safeOptions.after; - } - - // In some cases, html (text) can be found in phrasing right after an eol. - // When we’d serialize that, in most cases that would be seen as html - // (flow). - // As we can’t escape or so to prevent it from happening, we take a somewhat - // reasonable approach: replace that eol with a space. - // See: - if ( - results.length > 0 && - (before === '\r' || before === '\n') && - child.type === 'html' - ) { - results[results.length - 1] = results[results.length - 1].replace( - /(\r?\n|\r)$/, - ' ' - ); - before = ' '; - } - - results.push(context.handle(child, parent, context, {before, after})); - - before = results[results.length - 1].slice(-1); - } - - indexStack.pop(); - - return results.join('') -} - -/** - * @typedef {import('mdast').Emphasis} Emphasis - * @typedef {import('../types.js').Handle} Handle - */ - -emphasis.peek = emphasisPeek; - -// To do: there are cases where emphasis cannot “form” depending on the -// previous or next character of sequences. -// There’s no way around that though, except for injecting zero-width stuff. -// Do we need to safeguard against that? -/** - * @type {Handle} - * @param {Emphasis} node - */ -function emphasis(node, _, context) { - const marker = checkEmphasis(context); - const exit = context.enter('emphasis'); - const value = containerPhrasing(node, context, { - before: marker, - after: marker - }); - exit(); - return marker + value + marker -} - -/** - * @type {Handle} - * @param {Emphasis} _ - */ -function emphasisPeek(_, _1, context) { - return context.options.emphasis || '*' -} - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Parent} Parent - * - * @typedef {string} Type - * @typedef {Object} Props - * - * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.} Test - */ - -const convert = - /** - * @type {( - * ((test: T['type']|Partial|TestFunctionPredicate) => AssertPredicate) & - * ((test?: Test) => AssertAnything) - * )} - */ - ( - /** - * Generate an assertion from a check. - * @param {Test} [test] - * When nullish, checks if `node` is a `Node`. - * When `string`, works like passing `function (node) {return node.type === test}`. - * When `function` checks if function passed the node is true. - * When `object`, checks that all keys in test are in node, and that they have (strictly) equal values. - * When `array`, checks any one of the subtests pass. - * @returns {AssertAnything} - */ - function (test) { - if (test === undefined || test === null) { - return ok - } - - if (typeof test === 'string') { - return typeFactory(test) - } - - if (typeof test === 'object') { - return Array.isArray(test) ? anyFactory(test) : propsFactory(test) - } - - if (typeof test === 'function') { - return castFactory(test) - } - - throw new Error('Expected function, string, or object as test') - } - ); -/** - * @param {Array.} tests - * @returns {AssertAnything} - */ -function anyFactory(tests) { - /** @type {Array.} */ - const checks = []; - let index = -1; - - while (++index < tests.length) { - checks[index] = convert(tests[index]); - } - - return castFactory(any) - - /** - * @this {unknown} - * @param {unknown[]} parameters - * @returns {boolean} - */ - function any(...parameters) { - let index = -1; - - while (++index < checks.length) { - if (checks[index].call(this, ...parameters)) return true - } - - return false - } -} - -/** - * Utility to assert each property in `test` is represented in `node`, and each - * values are strictly equal. - * - * @param {Props} check - * @returns {AssertAnything} - */ -function propsFactory(check) { - return castFactory(all) - - /** - * @param {Node} node - * @returns {boolean} - */ - function all(node) { - /** @type {string} */ - let key; - - for (key in check) { - // @ts-expect-error: hush, it sure works as an index. - if (node[key] !== check[key]) return false - } - - return true - } -} - -/** - * Utility to convert a string into a function which checks a given node’s type - * for said string. - * - * @param {Type} check - * @returns {AssertAnything} - */ -function typeFactory(check) { - return castFactory(type) - - /** - * @param {Node} node - */ - function type(node) { - return node && node.type === check - } -} - -/** - * Utility to convert a string into a function which checks a given node’s type - * for said string. - * @param {TestFunctionAnything} check - * @returns {AssertAnything} - */ -function castFactory(check) { - return assertion - - /** - * @this {unknown} - * @param {Array.} parameters - * @returns {boolean} - */ - function assertion(...parameters) { - // @ts-expect-error: spreading is fine. - return Boolean(check.call(this, ...parameters)) - } -} - -// Utility to return true. -function ok() { - return true -} - -/** - * @param {string} d - * @returns {string} - */ -function color$1(d) { - return '\u001B[33m' + d + '\u001B[39m' -} - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Parent} Parent - * @typedef {import('unist-util-is').Test} Test - */ - -/** - * Continue traversing as normal - */ -const CONTINUE$1 = true; -/** - * Do not traverse this node’s children - */ -const SKIP$1 = 'skip'; -/** - * Stop traversing immediately - */ -const EXIT$1 = false; - -/** - * Visit children of tree which pass a test - * - * @param tree Abstract syntax tree to walk - * @param test Test node, optional - * @param visitor Function to run for each node - * @param reverse Visit the tree in reverse order, defaults to false - */ -const visitParents$1 = - /** - * @type {( - * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & - * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) - * )} - */ - ( - /** - * @param {Node} tree - * @param {Test} test - * @param {Visitor} visitor - * @param {boolean} [reverse] - */ - function (tree, test, visitor, reverse) { - if (typeof test === 'function' && typeof visitor !== 'function') { - reverse = visitor; - // @ts-expect-error no visitor given, so `visitor` is test. - visitor = test; - test = null; - } - - const is = convert(test); - const step = reverse ? -1 : 1; - - factory(tree, null, [])(); - - /** - * @param {Node} node - * @param {number?} index - * @param {Array.} parents - */ - function factory(node, index, parents) { - /** @type {Object.} */ - // @ts-expect-error: hush - const value = typeof node === 'object' && node !== null ? node : {}; - /** @type {string|undefined} */ - let name; - - if (typeof value.type === 'string') { - name = - typeof value.tagName === 'string' - ? value.tagName - : typeof value.name === 'string' - ? value.name - : undefined; - - Object.defineProperty(visit, 'name', { - value: - 'node (' + - color$1(value.type + (name ? '<' + name + '>' : '')) + - ')' - }); - } - - return visit - - function visit() { - /** @type {ActionTuple} */ - let result = []; - /** @type {ActionTuple} */ - let subresult; - /** @type {number} */ - let offset; - /** @type {Array.} */ - let grandparents; - - if (!test || is(node, index, parents[parents.length - 1] || null)) { - result = toResult$1(visitor(node, parents)); - - if (result[0] === EXIT$1) { - return result - } - } - - // @ts-expect-error looks like a parent. - if (node.children && result[0] !== SKIP$1) { - // @ts-expect-error looks like a parent. - offset = (reverse ? node.children.length : -1) + step; - // @ts-expect-error looks like a parent. - grandparents = parents.concat(node); - - // @ts-expect-error looks like a parent. - while (offset > -1 && offset < node.children.length) { - // @ts-expect-error looks like a parent. - subresult = factory(node.children[offset], offset, grandparents)(); - - if (subresult[0] === EXIT$1) { - return subresult - } - - offset = - typeof subresult[1] === 'number' ? subresult[1] : offset + step; - } - } - - return result - } - } - } - ); - -/** - * @param {VisitorResult} value - * @returns {ActionTuple} - */ -function toResult$1(value) { - if (Array.isArray(value)) { - return value - } - - if (typeof value === 'number') { - return [CONTINUE$1, value] - } - - return [value] -} - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Parent} Parent - * @typedef {import('unist-util-is').Test} Test - * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult - */ - -/** - * Visit children of tree which pass a test - * - * @param tree Abstract syntax tree to walk - * @param test Test, optional - * @param visitor Function to run for each node - * @param reverse Fisit the tree in reverse, defaults to false - */ -const visit$1 = - /** - * @type {( - * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & - * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) - * )} - */ - ( - /** - * @param {Node} tree - * @param {Test} test - * @param {Visitor} visitor - * @param {boolean} [reverse] - */ - function (tree, test, visitor, reverse) { - if (typeof test === 'function' && typeof visitor !== 'function') { - reverse = visitor; - visitor = test; - test = null; - } - - visitParents$1(tree, test, overload, reverse); - - /** - * @param {Node} node - * @param {Array.} parents - */ - function overload(node, parents) { - const parent = parents[parents.length - 1]; - return visitor( - node, - parent ? parent.children.indexOf(node) : null, - parent - ) - } - } - ); - -/** - * @typedef {import('mdast').Heading} Heading - * @typedef {import('../types.js').Context} Context - */ - -/** - * @param {Heading} node - * @param {Context} context - * @returns {boolean} - */ -function formatHeadingAsSetext(node, context) { - let literalWithBreak = false; - - // Look for literals with a line break. - // Note that this also - visit$1(node, (node) => { - if ( - ('value' in node && /\r?\n|\r/.test(node.value)) || - node.type === 'break' - ) { - literalWithBreak = true; - return EXIT$1 - } - }); - - return Boolean( - (!node.depth || node.depth < 3) && - toString(node) && - (context.options.setext || literalWithBreak) - ) -} - -/** - * @typedef {import('mdast').Heading} Heading - * @typedef {import('../types.js').Handle} Handle - * @typedef {import('../types.js').Exit} Exit - */ - -/** - * @type {Handle} - * @param {Heading} node - */ -function heading(node, _, context) { - const rank = Math.max(Math.min(6, node.depth || 1), 1); - - if (formatHeadingAsSetext(node, context)) { - const exit = context.enter('headingSetext'); - const subexit = context.enter('phrasing'); - const value = containerPhrasing(node, context, {before: '\n', after: '\n'}); - subexit(); - exit(); - - return ( - value + - '\n' + - (rank === 1 ? '=' : '-').repeat( - // The whole size… - value.length - - // Minus the position of the character after the last EOL (or - // 0 if there is none)… - (Math.max(value.lastIndexOf('\r'), value.lastIndexOf('\n')) + 1) - ) - ) - } - - const sequence = '#'.repeat(rank); - const exit = context.enter('headingAtx'); - const subexit = context.enter('phrasing'); - let value = containerPhrasing(node, context, {before: '# ', after: '\n'}); - - if (/^[\t ]/.test(value)) { - value = - '&#x' + - value.charCodeAt(0).toString(16).toUpperCase() + - ';' + - value.slice(1); - } - - value = value ? sequence + ' ' + value : sequence; - - if (context.options.closeAtx) { - value += ' ' + sequence; - } - - subexit(); - exit(); - - return value -} - -/** - * @typedef {import('mdast').HTML} HTML - * @typedef {import('../types.js').Handle} Handle - */ - -html.peek = htmlPeek; - -/** - * @type {Handle} - * @param {HTML} node - */ -function html(node) { - return node.value || '' -} - -/** - * @type {Handle} - */ -function htmlPeek() { - return '<' -} - -/** - * @typedef {import('mdast').Image} Image - * @typedef {import('../types.js').Handle} Handle - */ - -image.peek = imagePeek; - -/** - * @type {Handle} - * @param {Image} node - */ -function image(node, _, context) { - const quote = checkQuote(context); - const suffix = quote === '"' ? 'Quote' : 'Apostrophe'; - const exit = context.enter('image'); - let subexit = context.enter('label'); - let value = '![' + safe(context, node.alt, {before: '[', after: ']'}) + ']('; - - subexit(); - - if ( - // If there’s no url but there is a title… - (!node.url && node.title) || - // Or if there’s markdown whitespace or an eol, enclose. - /[ \t\r\n]/.test(node.url) - ) { - subexit = context.enter('destinationLiteral'); - value += '<' + safe(context, node.url, {before: '<', after: '>'}) + '>'; - } else { - // No whitespace, raw is prettier. - subexit = context.enter('destinationRaw'); - value += safe(context, node.url, { - before: '(', - after: node.title ? ' ' : ')' - }); - } - - subexit(); - - if (node.title) { - subexit = context.enter('title' + suffix); - value += - ' ' + - quote + - safe(context, node.title, {before: quote, after: quote}) + - quote; - subexit(); - } - - value += ')'; - exit(); - - return value -} - -/** - * @type {Handle} - */ -function imagePeek() { - return '!' -} - -/** - * @typedef {import('mdast').ImageReference} ImageReference - * @typedef {import('../types.js').Handle} Handle - */ - -imageReference.peek = imageReferencePeek; - -/** - * @type {Handle} - * @param {ImageReference} node - */ -function imageReference(node, _, context) { - const type = node.referenceType; - const exit = context.enter('imageReference'); - let subexit = context.enter('label'); - const alt = safe(context, node.alt, {before: '[', after: ']'}); - let value = '![' + alt + ']'; - - subexit(); - // Hide the fact that we’re in phrasing, because escapes don’t work. - const stack = context.stack; - context.stack = []; - subexit = context.enter('reference'); - const reference = safe(context, association(node), {before: '[', after: ']'}); - subexit(); - context.stack = stack; - exit(); - - if (type === 'full' || !alt || alt !== reference) { - value += '[' + reference + ']'; - } else if (type !== 'shortcut') { - value += '[]'; - } - - return value -} - -/** - * @type {Handle} - */ -function imageReferencePeek() { - return '!' -} - -/** - * @typedef {import('mdast').InlineCode} InlineCode - * @typedef {import('../types.js').Handle} Handle - */ - -inlineCode.peek = inlineCodePeek; - -/** - * @type {Handle} - * @param {InlineCode} node - */ -function inlineCode(node, _, context) { - let value = node.value || ''; - let sequence = '`'; - let index = -1; - - // If there is a single grave accent on its own in the code, use a fence of - // two. - // If there are two in a row, use one. - while (new RegExp('(^|[^`])' + sequence + '([^`]|$)').test(value)) { - sequence += '`'; - } - - // If this is not just spaces or eols (tabs don’t count), and either the - // first or last character are a space, eol, or tick, then pad with spaces. - if ( - /[^ \r\n]/.test(value) && - ((/^[ \r\n]/.test(value) && /[ \r\n]$/.test(value)) || /^`|`$/.test(value)) - ) { - value = ' ' + value + ' '; - } - - // We have a potential problem: certain characters after eols could result in - // blocks being seen. - // For example, if someone injected the string `'\n# b'`, then that would - // result in an ATX heading. - // We can’t escape characters in `inlineCode`, but because eols are - // transformed to spaces when going from markdown to HTML anyway, we can swap - // them out. - while (++index < context.unsafe.length) { - const pattern = context.unsafe[index]; - const expression = patternCompile(pattern); - /** @type {RegExpExecArray|null} */ - let match; - - // Only look for `atBreak`s. - // Btw: note that `atBreak` patterns will always start the regex at LF or - // CR. - if (!pattern.atBreak) continue - - while ((match = expression.exec(value))) { - let position = match.index; - - // Support CRLF (patterns only look for one of the characters). - if ( - value.charCodeAt(position) === 10 /* `\n` */ && - value.charCodeAt(position - 1) === 13 /* `\r` */ - ) { - position--; - } - - value = value.slice(0, position) + ' ' + value.slice(match.index + 1); - } - } - - return sequence + value + sequence -} - -/** - * @type {Handle} - */ -function inlineCodePeek() { - return '`' -} - -/** - * @typedef {import('mdast').Link} Link - * @typedef {import('../types.js').Context} Context - */ - -/** - * @param {Link} node - * @param {Context} context - * @returns {boolean} - */ -function formatLinkAsAutolink(node, context) { - const raw = toString(node); - - return Boolean( - !context.options.resourceLink && - // If there’s a url… - node.url && - // And there’s a no title… - !node.title && - // And the content of `node` is a single text node… - node.children && - node.children.length === 1 && - node.children[0].type === 'text' && - // And if the url is the same as the content… - (raw === node.url || 'mailto:' + raw === node.url) && - // And that starts w/ a protocol… - /^[a-z][a-z+.-]+:/i.test(node.url) && - // And that doesn’t contain ASCII control codes (character escapes and - // references don’t work) or angle brackets… - !/[\0- <>\u007F]/.test(node.url) - ) -} - -/** - * @typedef {import('mdast').Link} Link - * @typedef {import('../types.js').Handle} Handle - * @typedef {import('../types.js').Exit} Exit - */ - -link.peek = linkPeek; - -/** - * @type {Handle} - * @param {Link} node - */ -function link(node, _, context) { - const quote = checkQuote(context); - const suffix = quote === '"' ? 'Quote' : 'Apostrophe'; - /** @type {Exit} */ - let exit; - /** @type {Exit} */ - let subexit; - /** @type {string} */ - let value; - - if (formatLinkAsAutolink(node, context)) { - // Hide the fact that we’re in phrasing, because escapes don’t work. - const stack = context.stack; - context.stack = []; - exit = context.enter('autolink'); - value = - '<' + containerPhrasing(node, context, {before: '<', after: '>'}) + '>'; - exit(); - context.stack = stack; - return value - } - - exit = context.enter('link'); - subexit = context.enter('label'); - value = - '[' + containerPhrasing(node, context, {before: '[', after: ']'}) + ']('; - subexit(); - - if ( - // If there’s no url but there is a title… - (!node.url && node.title) || - // Or if there’s markdown whitespace or an eol, enclose. - /[ \t\r\n]/.test(node.url) - ) { - subexit = context.enter('destinationLiteral'); - value += '<' + safe(context, node.url, {before: '<', after: '>'}) + '>'; - } else { - // No whitespace, raw is prettier. - subexit = context.enter('destinationRaw'); - value += safe(context, node.url, { - before: '(', - after: node.title ? ' ' : ')' - }); - } - - subexit(); - - if (node.title) { - subexit = context.enter('title' + suffix); - value += - ' ' + - quote + - safe(context, node.title, {before: quote, after: quote}) + - quote; - subexit(); - } - - value += ')'; - - exit(); - return value -} - -/** - * @type {Handle} - * @param {Link} node - */ -function linkPeek(node, _, context) { - return formatLinkAsAutolink(node, context) ? '<' : '[' -} - -/** - * @typedef {import('mdast').LinkReference} LinkReference - * @typedef {import('../types.js').Handle} Handle - */ - -linkReference.peek = linkReferencePeek; - -/** - * @type {Handle} - * @param {LinkReference} node - */ -function linkReference(node, _, context) { - const type = node.referenceType; - const exit = context.enter('linkReference'); - let subexit = context.enter('label'); - const text = containerPhrasing(node, context, {before: '[', after: ']'}); - let value = '[' + text + ']'; - - subexit(); - // Hide the fact that we’re in phrasing, because escapes don’t work. - const stack = context.stack; - context.stack = []; - subexit = context.enter('reference'); - const reference = safe(context, association(node), {before: '[', after: ']'}); - subexit(); - context.stack = stack; - exit(); - - if (type === 'full' || !text || text !== reference) { - value += '[' + reference + ']'; - } else if (type !== 'shortcut') { - value += '[]'; - } - - return value -} - -/** - * @type {Handle} - */ -function linkReferencePeek() { - return '[' -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkBullet(context) { - const marker = context.options.bullet || '*'; - - if (marker !== '*' && marker !== '+' && marker !== '-') { - throw new Error( - 'Cannot serialize items with `' + - marker + - '` for `options.bullet`, expected `*`, `+`, or `-`' - ) - } - - return marker -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkBulletOther(context) { - const bullet = checkBullet(context); - const bulletOther = context.options.bulletOther; - - if (!bulletOther) { - return bullet === '*' ? '-' : '*' - } - - if (bulletOther !== '*' && bulletOther !== '+' && bulletOther !== '-') { - throw new Error( - 'Cannot serialize items with `' + - bulletOther + - '` for `options.bulletOther`, expected `*`, `+`, or `-`' - ) - } - - if (bulletOther === bullet) { - throw new Error( - 'Expected `bullet` (`' + - bullet + - '`) and `bulletOther` (`' + - bulletOther + - '`) to be different' - ) - } - - return bulletOther -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkBulletOrdered(context) { - const marker = context.options.bulletOrdered || '.'; - - if (marker !== '.' && marker !== ')') { - throw new Error( - 'Cannot serialize items with `' + - marker + - '` for `options.bulletOrdered`, expected `.` or `)`' - ) - } - - return marker -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkBulletOrderedOther(context) { - const bulletOrdered = checkBulletOrdered(context); - const bulletOrderedOther = context.options.bulletOrderedOther; - - if (!bulletOrderedOther) { - return bulletOrdered === '.' ? ')' : '.' - } - - if (bulletOrderedOther !== '.' && bulletOrderedOther !== ')') { - throw new Error( - 'Cannot serialize items with `' + - bulletOrderedOther + - '` for `options.bulletOrderedOther`, expected `*`, `+`, or `-`' - ) - } - - if (bulletOrderedOther === bulletOrdered) { - throw new Error( - 'Expected `bulletOrdered` (`' + - bulletOrdered + - '`) and `bulletOrderedOther` (`' + - bulletOrderedOther + - '`) to be different' - ) - } - - return bulletOrderedOther -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkRule(context) { - const marker = context.options.rule || '*'; - - if (marker !== '*' && marker !== '-' && marker !== '_') { - throw new Error( - 'Cannot serialize rules with `' + - marker + - '` for `options.rule`, expected `*`, `-`, or `_`' - ) - } - - return marker -} - -/** - * @typedef {import('mdast').List} List - * @typedef {import('../types.js').Handle} Handle - */ - -/** - * @type {Handle} - * @param {List} node - */ -function list(node, parent, context) { - const exit = context.enter('list'); - const bulletCurrent = context.bulletCurrent; - /** @type {string} */ - let bullet = node.ordered ? checkBulletOrdered(context) : checkBullet(context); - /** @type {string} */ - const bulletOther = node.ordered - ? checkBulletOrderedOther(context) - : checkBulletOther(context); - const bulletLastUsed = context.bulletLastUsed; - let useDifferentMarker = false; - - if ( - parent && - // Explicit `other` set. - (node.ordered - ? context.options.bulletOrderedOther - : context.options.bulletOther) && - bulletLastUsed && - bullet === bulletLastUsed - ) { - useDifferentMarker = true; - } - - if (!node.ordered) { - const firstListItem = node.children ? node.children[0] : undefined; - - // If there’s an empty first list item directly in two list items, - // we have to use a different bullet: - // - // ```markdown - // * - * - // ``` - // - // …because otherwise it would become one big thematic break. - if ( - // Bullet could be used as a thematic break marker: - (bullet === '*' || bullet === '-') && - // Empty first list item: - firstListItem && - (!firstListItem.children || !firstListItem.children[0]) && - // Directly in two other list items: - context.stack[context.stack.length - 1] === 'list' && - context.stack[context.stack.length - 2] === 'listItem' && - context.stack[context.stack.length - 3] === 'list' && - context.stack[context.stack.length - 4] === 'listItem' && - // That are each the first child. - context.indexStack[context.indexStack.length - 1] === 0 && - context.indexStack[context.indexStack.length - 2] === 0 && - context.indexStack[context.indexStack.length - 3] === 0 && - context.indexStack[context.indexStack.length - 4] === 0 - ) { - useDifferentMarker = true; - } - - // If there’s a thematic break at the start of the first list item, - // we have to use a different bullet: - // - // ```markdown - // * --- - // ``` - // - // …because otherwise it would become one big thematic break. - if (checkRule(context) === bullet && firstListItem) { - let index = -1; - - while (++index < node.children.length) { - const item = node.children[index]; - - if ( - item && - item.type === 'listItem' && - item.children && - item.children[0] && - item.children[0].type === 'thematicBreak' - ) { - useDifferentMarker = true; - break - } - } - } - } - - if (useDifferentMarker) { - bullet = bulletOther; - } - - context.bulletCurrent = bullet; - const value = containerFlow(node, context); - context.bulletLastUsed = bullet; - context.bulletCurrent = bulletCurrent; - exit(); - return value -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkListItemIndent(context) { - const style = context.options.listItemIndent || 'tab'; - - // To do: remove in a major. - // @ts-expect-error: deprecated. - if (style === 1 || style === '1') { - return 'one' - } - - if (style !== 'tab' && style !== 'one' && style !== 'mixed') { - throw new Error( - 'Cannot serialize items with `' + - style + - '` for `options.listItemIndent`, expected `tab`, `one`, or `mixed`' - ) - } - - return style -} - -/** - * @typedef {import('mdast').ListItem} ListItem - * @typedef {import('mdast').List} List - * @typedef {import('../util/indent-lines.js').Map} Map - * @typedef {import('../types.js').Options} Options - * @typedef {import('../types.js').Handle} Handle - */ - -/** - * @type {Handle} - * @param {ListItem} node - */ -function listItem(node, parent, context) { - const listItemIndent = checkListItemIndent(context); - let bullet = context.bulletCurrent || checkBullet(context); - - // Add the marker value for ordered lists. - if (parent && parent.type === 'list' && parent.ordered) { - bullet = - (typeof parent.start === 'number' && parent.start > -1 - ? parent.start - : 1) + - (context.options.incrementListMarker === false - ? 0 - : parent.children.indexOf(node)) + - bullet; - } - - let size = bullet.length + 1; - - if ( - listItemIndent === 'tab' || - (listItemIndent === 'mixed' && - ((parent && parent.type === 'list' && parent.spread) || node.spread)) - ) { - size = Math.ceil(size / 4) * 4; - } - - const exit = context.enter('listItem'); - const value = indentLines(containerFlow(node, context), map); - exit(); - - return value - - /** @type {Map} */ - function map(line, index, blank) { - if (index) { - return (blank ? '' : ' '.repeat(size)) + line - } - - return (blank ? bullet : bullet + ' '.repeat(size - bullet.length)) + line - } -} - -/** - * @typedef {import('mdast').Paragraph} Paragraph - * @typedef {import('../types.js').Handle} Handle - */ - -/** - * @type {Handle} - * @param {Paragraph} node - */ -function paragraph(node, _, context) { - const exit = context.enter('paragraph'); - const subexit = context.enter('phrasing'); - const value = containerPhrasing(node, context, {before: '\n', after: '\n'}); - subexit(); - exit(); - return value -} - -/** - * @typedef {import('mdast').Root} Root - * @typedef {import('../types.js').Handle} Handle - */ - -/** - * @type {Handle} - * @param {Root} node - */ -function root(node, _, context) { - return containerFlow(node, context) -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkStrong(context) { - const marker = context.options.strong || '*'; - - if (marker !== '*' && marker !== '_') { - throw new Error( - 'Cannot serialize strong with `' + - marker + - '` for `options.strong`, expected `*`, or `_`' - ) - } - - return marker -} - -/** - * @typedef {import('mdast').Strong} Strong - * @typedef {import('../types.js').Handle} Handle - */ - -strong.peek = strongPeek; - -// To do: there are cases where emphasis cannot “form” depending on the -// previous or next character of sequences. -// There’s no way around that though, except for injecting zero-width stuff. -// Do we need to safeguard against that? -/** - * @type {Handle} - * @param {Strong} node - */ -function strong(node, _, context) { - const marker = checkStrong(context); - const exit = context.enter('strong'); - const value = containerPhrasing(node, context, { - before: marker, - after: marker - }); - exit(); - return marker + marker + value + marker + marker -} - -/** - * @type {Handle} - * @param {Strong} _ - */ -function strongPeek(_, _1, context) { - return context.options.strong || '*' -} - -/** - * @typedef {import('mdast').Text} Text - * @typedef {import('../types.js').Handle} Handle - */ - -/** - * @type {Handle} - * @param {Text} node - */ -function text$1(node, _, context, safeOptions) { - return safe(context, node.value, safeOptions) -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkRuleRepetition(context) { - const repetition = context.options.ruleRepetition || 3; - - if (repetition < 3) { - throw new Error( - 'Cannot serialize rules with repetition `' + - repetition + - '` for `options.ruleRepetition`, expected `3` or more' - ) - } - - return repetition -} - -/** - * @typedef {import('../types.js').Handle} Handle - * @typedef {import('mdast').ThematicBreak} ThematicBreak - */ - -/** - * @type {Handle} - * @param {ThematicBreak} _ - */ -function thematicBreak(_, _1, context) { - const value = ( - checkRule(context) + (context.options.ruleSpaces ? ' ' : '') - ).repeat(checkRuleRepetition(context)); - - return context.options.ruleSpaces ? value.slice(0, -1) : value -} - -const handle = { - blockquote, - break: hardBreak, - code: code$1, - definition, - emphasis, - hardBreak, - heading, - html, - image, - imageReference, - inlineCode, - link, - linkReference, - list, - listItem, - paragraph, - root, - strong, - text: text$1, - thematicBreak -}; - -/** - * @typedef {import('./types.js').Join} Join - */ - -/** @type {Array.} */ -const join = [joinDefaults]; - -/** @type {Join} */ -function joinDefaults(left, right, parent, context) { - // Indented code after list or another indented code. - if ( - right.type === 'code' && - formatCodeAsIndented(right, context) && - (left.type === 'list' || - (left.type === right.type && formatCodeAsIndented(left, context))) - ) { - return false - } - - // Two lists with the same marker. - if ( - left.type === 'list' && - left.type === right.type && - Boolean(left.ordered) === Boolean(right.ordered) && - !(left.ordered - ? context.options.bulletOrderedOther - : context.options.bulletOther) - ) { - return false - } - - // Join children of a list or an item. - // In which case, `parent` has a `spread` field. - if ('spread' in parent && typeof parent.spread === 'boolean') { - if ( - left.type === 'paragraph' && - // Two paragraphs. - (left.type === right.type || - right.type === 'definition' || - // Paragraph followed by a setext heading. - (right.type === 'heading' && formatHeadingAsSetext(right, context))) - ) { - return - } - - return parent.spread ? 1 : 0 - } -} - -/** - * @typedef {import('./types.js').Unsafe} Unsafe - */ - -/** @type {Array.} */ -const unsafe = [ - {character: '\t', after: '[\\r\\n]', inConstruct: 'phrasing'}, - {character: '\t', before: '[\\r\\n]', inConstruct: 'phrasing'}, - { - character: '\t', - inConstruct: ['codeFencedLangGraveAccent', 'codeFencedLangTilde'] - }, - { - character: '\r', - inConstruct: [ - 'codeFencedLangGraveAccent', - 'codeFencedLangTilde', - 'codeFencedMetaGraveAccent', - 'codeFencedMetaTilde', - 'destinationLiteral', - 'headingAtx' - ] - }, - { - character: '\n', - inConstruct: [ - 'codeFencedLangGraveAccent', - 'codeFencedLangTilde', - 'codeFencedMetaGraveAccent', - 'codeFencedMetaTilde', - 'destinationLiteral', - 'headingAtx' - ] - }, - {character: ' ', after: '[\\r\\n]', inConstruct: 'phrasing'}, - {character: ' ', before: '[\\r\\n]', inConstruct: 'phrasing'}, - { - character: ' ', - inConstruct: ['codeFencedLangGraveAccent', 'codeFencedLangTilde'] - }, - // An exclamation mark can start an image, if it is followed by a link or - // a link reference. - {character: '!', after: '\\[', inConstruct: 'phrasing'}, - // A quote can break out of a title. - {character: '"', inConstruct: 'titleQuote'}, - // A number sign could start an ATX heading if it starts a line. - {atBreak: true, character: '#'}, - {character: '#', inConstruct: 'headingAtx', after: '(?:[\r\n]|$)'}, - // Dollar sign and percentage are not used in markdown. - // An ampersand could start a character reference. - {character: '&', after: '[#A-Za-z]', inConstruct: 'phrasing'}, - // An apostrophe can break out of a title. - {character: "'", inConstruct: 'titleApostrophe'}, - // A left paren could break out of a destination raw. - {character: '(', inConstruct: 'destinationRaw'}, - {before: '\\]', character: '(', inConstruct: 'phrasing'}, - // A right paren could start a list item or break out of a destination - // raw. - {atBreak: true, before: '\\d+', character: ')'}, - {character: ')', inConstruct: 'destinationRaw'}, - // An asterisk can start thematic breaks, list items, emphasis, strong. - {atBreak: true, character: '*'}, - {character: '*', inConstruct: 'phrasing'}, - // A plus sign could start a list item. - {atBreak: true, character: '+'}, - // A dash can start thematic breaks, list items, and setext heading - // underlines. - {atBreak: true, character: '-'}, - // A dot could start a list item. - {atBreak: true, before: '\\d+', character: '.', after: '(?:[ \t\r\n]|$)'}, - // Slash, colon, and semicolon are not used in markdown for constructs. - // A less than can start html (flow or text) or an autolink. - // HTML could start with an exclamation mark (declaration, cdata, comment), - // slash (closing tag), question mark (instruction), or a letter (tag). - // An autolink also starts with a letter. - // Finally, it could break out of a destination literal. - {atBreak: true, character: '<', after: '[!/?A-Za-z]'}, - {character: '<', after: '[!/?A-Za-z]', inConstruct: 'phrasing'}, - {character: '<', inConstruct: 'destinationLiteral'}, - // An equals to can start setext heading underlines. - {atBreak: true, character: '='}, - // A greater than can start block quotes and it can break out of a - // destination literal. - {atBreak: true, character: '>'}, - {character: '>', inConstruct: 'destinationLiteral'}, - // Question mark and at sign are not used in markdown for constructs. - // A left bracket can start definitions, references, labels, - {atBreak: true, character: '['}, - {character: '[', inConstruct: ['phrasing', 'label', 'reference']}, - // A backslash can start an escape (when followed by punctuation) or a - // hard break (when followed by an eol). - // Note: typical escapes are handled in `safe`! - {character: '\\', after: '[\\r\\n]', inConstruct: 'phrasing'}, - // A right bracket can exit labels. - {character: ']', inConstruct: ['label', 'reference']}, - // Caret is not used in markdown for constructs. - // An underscore can start emphasis, strong, or a thematic break. - {atBreak: true, character: '_'}, - {before: '[^A-Za-z]', character: '_', inConstruct: 'phrasing'}, - {character: '_', after: '[^A-Za-z]', inConstruct: 'phrasing'}, - // A grave accent can start code (fenced or text), or it can break out of - // a grave accent code fence. - {atBreak: true, character: '`'}, - { - character: '`', - inConstruct: [ - 'codeFencedLangGraveAccent', - 'codeFencedMetaGraveAccent', - 'phrasing' - ] - }, - // Left brace, vertical bar, right brace are not used in markdown for - // constructs. - // A tilde can start code (fenced). - {atBreak: true, character: '~'} -]; - -/** - * @typedef {import('./types.js').Node} Node - * @typedef {import('./types.js').Options} Options - * @typedef {import('./types.js').Context} Context - * @typedef {import('./types.js').Handle} Handle - * @typedef {import('./types.js').Join} Join - * @typedef {import('./types.js').Unsafe} Unsafe - */ - -/** - * @param {Node} tree - * @param {Options} [options] - * @returns {string} - */ -function toMarkdown(tree, options = {}) { - /** @type {Context} */ - // @ts-expect-error: we’ll add `handle` later. - const context = { - enter, - stack: [], - unsafe: [], - join: [], - handlers: {}, - options: {}, - indexStack: [] - }; - - configure(context, {unsafe, join, handlers: handle}); - configure(context, options); - - if (context.options.tightDefinitions) { - configure(context, {join: [joinDefinition]}); - } - - /** @type {Handle} */ - context.handle = zwitch('type', { - invalid, - // @ts-expect-error: hush. - unknown, - // @ts-expect-error: hush. - handlers: context.handlers - }); - - let result = context.handle(tree, null, context, {before: '\n', after: '\n'}); - - if ( - result && - result.charCodeAt(result.length - 1) !== 10 && - result.charCodeAt(result.length - 1) !== 13 - ) { - result += '\n'; - } - - return result - - /** @type {Context['enter']} */ - function enter(name) { - context.stack.push(name); - return exit - - function exit() { - context.stack.pop(); - } - } -} - -/** - * @type {Handle} - * @param {unknown} value - */ -function invalid(value) { - throw new Error('Cannot handle value `' + value + '`, expected node') -} - -/** - * @type {Handle} - * @param {Node} node - */ -function unknown(node) { - throw new Error('Cannot handle unknown node `' + node.type + '`') -} - -/** @type {Join} */ -function joinDefinition(left, right) { - // No blank line between adjacent definitions. - if (left.type === 'definition' && left.type === right.type) { - return 0 - } -} - -/** - * @typedef {import('mdast').Root|import('mdast').Content} Node - * @typedef {import('mdast-util-to-markdown').Options} Options - */ - -/** @type {import('unified').Plugin<[Options]|void[], Node, string>} */ -function remarkStringify(options) { - /** @type {import('unified').CompilerFunction} */ - const compiler = (tree) => { - // Assume options. - const settings = /** @type {Options} */ (this.data('settings')); - - return toMarkdown( - tree, - Object.assign({}, settings, options, { - // Note: this option is not in the readme. - // The goal is for it to be set by plugins on `data` instead of being - // passed by users. - extensions: this.data('toMarkdownExtensions') || [] - }) - ) - }; - - Object.assign(this, {Compiler: compiler}); -} - -const remark = unified().use(remarkParse).use(remarkStringify).freeze(); - -const name$1 = "remark"; -const version$1 = "14.0.1"; -const description$1 = "Markdown processor powered by plugins part of the unified collective"; -const license = "MIT"; -const keywords = [ - "unified", - "remark", - "markdown", - "mdast", - "abstract", - "syntax", - "tree", - "ast", - "parse", - "stringify", - "serialize", - "compile", - "process" -]; -const homepage = "https://remark.js.org"; -const repository = "https://github.com/remarkjs/remark/tree/main/packages/remark"; -const bugs = "https://github.com/remarkjs/remark/issues"; -const funding = { - type: "opencollective", - url: "https://opencollective.com/unified" -}; -const author = "Titus Wormer (https://wooorm.com)"; -const contributors = [ - "Titus Wormer (https://wooorm.com)" -]; -const sideEffects = false; -const type = "module"; -const main$1 = "index.js"; -const types = "index.d.ts"; -const files = [ - "index.d.ts", - "index.js" -]; -const dependencies$1 = { - "@types/mdast": "^3.0.0", - "remark-parse": "^10.0.0", - "remark-stringify": "^10.0.0", - unified: "^10.0.0" -}; -const scripts$1 = { - test: "node --conditions development test.js", - build: "rimraf \"*.d.ts\" && tsc && type-coverage" -}; -const xo = false; -const typeCoverage = { - atLeast: 100, - detail: true, - strict: true, - ignoreCatch: true -}; -var proc = { - name: name$1, - version: version$1, - description: description$1, - license: license, - keywords: keywords, - homepage: homepage, - repository: repository, - bugs: bugs, - funding: funding, - author: author, - contributors: contributors, - sideEffects: sideEffects, - type: type, - main: main$1, - types: types, - files: files, - dependencies: dependencies$1, - scripts: scripts$1, - xo: xo, - typeCoverage: typeCoverage -}; - -const name = "node-lint-md-cli-rollup"; -const description = "remark packaged for Node.js Markdown linting"; -const version = "2.0.2"; -const devDependencies = { - "@rollup/plugin-commonjs": "^20.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.4", - rollup: "^2.56.3", - shx: "^0.3.3" -}; -const dependencies = { - "markdown-extensions": "^1.1.1", - remark: "^14.0.1", - "remark-gfm": "^2.0.0", - "remark-preset-lint-node": "^3.0.1", - "unified-args": "^9.0.2" -}; -const main = "dist/index.js"; -const scripts = { - build: "npx rollup -c", - "build-node": "npm run build && npx shx cp dist/index.mjs ../lint-md.mjs" -}; -var cli = { - name: name, - description: description, - version: version, - devDependencies: devDependencies, - dependencies: dependencies, - main: main, - scripts: scripts -}; - -/** - * @typedef {import('unist').Point} Point - * @typedef {import('vfile').VFile} VFile - * - * @typedef {Pick} PositionalPoint - * @typedef {Required} FullPoint - * @typedef {NonNullable} Offset - */ - -/** - * Get transform functions for the given `document`. - * - * @param {string|Uint8Array|VFile} file - */ -function location(file) { - var value = String(file); - /** @type {Array.} */ - var indices = []; - var search = /\r?\n|\r/g; - - while (search.test(value)) { - indices.push(search.lastIndex); - } - - indices.push(value.length + 1); - - return {toPoint, toOffset} - - /** - * Get the line and column-based `point` for `offset` in the bound indices. - * Returns a point with `undefined` values when given invalid or out of bounds - * input. - * - * @param {Offset} offset - * @returns {FullPoint} - */ - function toPoint(offset) { - var index = -1; - - if (offset > -1 && offset < indices[indices.length - 1]) { - while (++index < indices.length) { - if (indices[index] > offset) { - return { - line: index + 1, - column: offset - (indices[index - 1] || 0) + 1, - offset - } - } - } - } - - return {line: undefined, column: undefined, offset: undefined} - } - - /** - * Get the `offset` for a line and column-based `point` in the bound indices. - * Returns `-1` when given invalid or out of bounds input. - * - * @param {PositionalPoint} point - * @returns {Offset} - */ - function toOffset(point) { - var line = point && point.line; - var column = point && point.column; - /** @type {number} */ - var offset; - - if ( - typeof line === 'number' && - typeof column === 'number' && - !Number.isNaN(line) && - !Number.isNaN(column) && - line - 1 in indices - ) { - offset = (indices[line - 2] || 0) + column - 1 || 0; - } - - return offset > -1 && offset < indices[indices.length - 1] ? offset : -1 - } -} - -/** - * @param {string} d - * @returns {string} - */ -function color(d) { - return '\u001B[33m' + d + '\u001B[39m' -} - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Parent} Parent - * @typedef {import('unist-util-is').Test} Test - */ - -/** - * Continue traversing as normal - */ -const CONTINUE = true; -/** - * Do not traverse this node’s children - */ -const SKIP = 'skip'; -/** - * Stop traversing immediately - */ -const EXIT = false; - -const visitParents = - /** - * @type {( - * ((tree: Node, test: T['type']|Partial|import('unist-util-is').TestFunctionPredicate|Array.|import('unist-util-is').TestFunctionPredicate>, visitor: Visitor, reverse?: boolean) => void) & - * ((tree: Node, test: Test, visitor: Visitor, reverse?: boolean) => void) & - * ((tree: Node, visitor: Visitor, reverse?: boolean) => void) - * )} - */ - ( - /** - * Visit children of tree which pass a test - * - * @param {Node} tree Abstract syntax tree to walk - * @param {Test} test test Test node - * @param {Visitor} visitor Function to run for each node - * @param {boolean} [reverse] Fisit the tree in reverse, defaults to false - */ - function (tree, test, visitor, reverse) { - if (typeof test === 'function' && typeof visitor !== 'function') { - reverse = visitor; - // @ts-ignore no visitor given, so `visitor` is test. - visitor = test; - test = null; - } - - var is = convert(test); - var step = reverse ? -1 : 1; - - factory(tree, null, [])(); - - /** - * @param {Node} node - * @param {number?} index - * @param {Array.} parents - */ - function factory(node, index, parents) { - /** @type {Object.} */ - var value = typeof node === 'object' && node !== null ? node : {}; - /** @type {string} */ - var name; - - if (typeof value.type === 'string') { - name = - typeof value.tagName === 'string' - ? value.tagName - : typeof value.name === 'string' - ? value.name - : undefined; - - Object.defineProperty(visit, 'name', { - value: - 'node (' + - color(value.type + (name ? '<' + name + '>' : '')) + - ')' - }); - } - - return visit - - function visit() { - /** @type {ActionTuple} */ - var result = []; - /** @type {ActionTuple} */ - var subresult; - /** @type {number} */ - var offset; - /** @type {Array.} */ - var grandparents; - - if (!test || is(node, index, parents[parents.length - 1] || null)) { - result = toResult(visitor(node, parents)); - - if (result[0] === EXIT) { - return result - } - } - - if (node.children && result[0] !== SKIP) { - // @ts-ignore looks like a parent. - offset = (reverse ? node.children.length : -1) + step; - // @ts-ignore looks like a parent. - grandparents = parents.concat(node); - - // @ts-ignore looks like a parent. - while (offset > -1 && offset < node.children.length) { - subresult = factory(node.children[offset], offset, grandparents)(); - - if (subresult[0] === EXIT) { - return subresult - } - - offset = - typeof subresult[1] === 'number' ? subresult[1] : offset + step; - } - } - - return result - } - } - } - ); - -/** - * @param {VisitorResult} value - * @returns {ActionTuple} - */ -function toResult(value) { - if (Array.isArray(value)) { - return value - } - - if (typeof value === 'number') { - return [CONTINUE, value] - } - - return [value] -} - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Parent} Parent - * @typedef {import('unist-util-is').Test} Test - * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult - */ - -const visit = - /** - * @type {( - * ((tree: Node, test: T['type']|Partial|import('unist-util-is').TestFunctionPredicate|Array.|import('unist-util-is').TestFunctionPredicate>, visitor: Visitor, reverse?: boolean) => void) & - * ((tree: Node, test: Test, visitor: Visitor, reverse?: boolean) => void) & - * ((tree: Node, visitor: Visitor, reverse?: boolean) => void) - * )} - */ - ( - /** - * Visit children of tree which pass a test - * - * @param {Node} tree Abstract syntax tree to walk - * @param {Test} test test Test node - * @param {Visitor} visitor Function to run for each node - * @param {boolean} [reverse] Fisit the tree in reverse, defaults to false - */ - function (tree, test, visitor, reverse) { - if (typeof test === 'function' && typeof visitor !== 'function') { - reverse = visitor; - visitor = test; - test = null; - } - - visitParents(tree, test, overload, reverse); - - /** - * @param {Node} node - * @param {Array.} parents - */ - function overload(node, parents) { - var parent = parents[parents.length - 1]; - return visitor( - node, - parent ? parent.children.indexOf(node) : null, - parent - ) - } - } - ); - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Parent} Parent - * @typedef {import('unist').Point} Point - * @typedef {import('unist-util-is').Test} Test - * @typedef {import('vfile').VFile} VFile - * @typedef {import('vfile-message').VFileMessage} VFileMessage - * - * @typedef {OptionsWithoutReset|OptionsWithReset} Options - * @typedef {OptionsBaseFields & OptionsWithoutResetFields} OptionsWithoutReset - * @typedef {OptionsBaseFields & OptionsWithResetFields} OptionsWithReset - * - * @typedef OptionsWithoutResetFields - * @property {false} [reset] - * Whether to treat all messages as turned off initially. - * @property {string[]} [disable] - * List of `ruleId`s to turn off. - * - * @typedef OptionsWithResetFields - * @property {true} reset - * Whether to treat all messages as turned off initially. - * @property {string[]} [enable] - * List of `ruleId`s to initially turn on. - * - * @typedef OptionsBaseFields - * @property {string} name - * Name of markers that can control the message sources. - * - * For example, `{name: 'alpha'}` controls `alpha` markers: - * - * ```html - * - * ``` - * @property {MarkerParser} marker - * Parse a possible marker to a comment marker object (Marker). - * If the marker isn't a marker, should return `null`. - * @property {Test} [test] - * Test for possible markers - * @property {string[]} [known] - * List of allowed `ruleId`s. When given a warning is shown - * when someone tries to control an unknown rule. - * - * For example, `{name: 'alpha', known: ['bravo']}` results in a warning if - * `charlie` is configured: - * - * ```html - * - * ``` - * @property {string|string[]} [source] - * Sources that can be controlled with `name` markers. - * Defaults to `name`. - * - * @callback MarkerParser - * Parse a possible comment marker node to a Marker. - * @param {Node} node - * Node to parse - * - * @typedef Marker - * A comment marker. - * @property {string} name - * Name of marker. - * @property {string} attributes - * Value after name. - * @property {Record} parameters - * Parsed attributes. - * @property {Node} node - * Reference to given node. - * - * @typedef Mark - * @property {Point|undefined} point - * @property {boolean} state - */ - -const own$2 = {}.hasOwnProperty; - -/** - * @type {import('unified').Plugin<[Options]>} - * @returns {(tree: Node, file: VFile) => void} - */ -function messageControl(options) { - if (!options || typeof options !== 'object' || !options.name) { - throw new Error( - 'Expected `name` in `options`, got `' + (options || {}).name + '`' - ) - } - - if (!options.marker) { - throw new Error( - 'Expected `marker` in `options`, got `' + options.marker + '`' - ) - } - - const enable = 'enable' in options && options.enable ? options.enable : []; - const disable = 'disable' in options && options.disable ? options.disable : []; - let reset = options.reset; - const sources = - typeof options.source === 'string' - ? [options.source] - : options.source || [options.name]; - - return transformer - - /** - * @param {Node} tree - * @param {VFile} file - */ - function transformer(tree, file) { - const toOffset = location(file).toOffset; - const initial = !reset; - const gaps = detectGaps(tree, file); - /** @type {Record} */ - const scope = {}; - /** @type {Mark[]} */ - const globals = []; - - visit(tree, options.test, visitor); - - file.messages = file.messages.filter((m) => filter(m)); - - /** - * @param {Node} node - * @param {number|null} position - * @param {Parent|null} parent - */ - function visitor(node, position, parent) { - /** @type {Marker|null} */ - const mark = options.marker(node); - - if (!mark || mark.name !== options.name) { - return - } - - const ruleIds = mark.attributes.split(/\s/g); - const point = mark.node.position && mark.node.position.start; - const next = - (parent && position !== null && parent.children[position + 1]) || - undefined; - const tail = (next && next.position && next.position.end) || undefined; - let index = -1; - - /** @type {string} */ - // @ts-expect-error: we’ll check for unknown values next. - const verb = ruleIds.shift(); - - if (verb !== 'enable' && verb !== 'disable' && verb !== 'ignore') { - file.fail( - 'Unknown keyword `' + - verb + - '`: expected ' + - "`'enable'`, `'disable'`, or `'ignore'`", - mark.node - ); - } - - // Apply to all rules. - if (ruleIds.length > 0) { - while (++index < ruleIds.length) { - const ruleId = ruleIds[index]; - - if (isKnown(ruleId, verb, mark.node)) { - toggle(point, verb === 'enable', ruleId); - - if (verb === 'ignore') { - toggle(tail, true, ruleId); - } - } - } - } else if (verb === 'ignore') { - toggle(point, false); - toggle(tail, true); - } else { - toggle(point, verb === 'enable'); - reset = verb !== 'enable'; - } - } - - /** - * @param {VFileMessage} message - * @returns {boolean} - */ - function filter(message) { - let gapIndex = gaps.length; - - // Keep messages from a different source. - if (!message.source || !sources.includes(message.source)) { - return true - } - - // We only ignore messages if they‘re disabled, *not* when they’re not in - // the document. - if (!message.line) { - message.line = 1; - } - - if (!message.column) { - message.column = 1; - } - - // Check whether the warning is inside a gap. - // @ts-expect-error: we just normalized `null` to `number`s. - const offset = toOffset(message); - - while (gapIndex--) { - if (gaps[gapIndex][0] <= offset && gaps[gapIndex][1] > offset) { - return false - } - } - - // Check whether allowed by specific and global states. - return ( - (!message.ruleId || - check(message, scope[message.ruleId], message.ruleId)) && - check(message, globals) - ) - } - - /** - * Helper to check (and possibly warn) if a `ruleId` is unknown. - * - * @param {string} ruleId - * @param {string} verb - * @param {Node} node - * @returns {boolean} - */ - function isKnown(ruleId, verb, node) { - const result = options.known ? options.known.includes(ruleId) : true; - - if (!result) { - file.message( - 'Unknown rule: cannot ' + verb + " `'" + ruleId + "'`", - node - ); - } - - return result - } - - /** - * Get the latest state of a rule. - * When without `ruleId`, gets global state. - * - * @param {string|undefined} ruleId - * @returns {boolean} - */ - function getState(ruleId) { - const ranges = ruleId ? scope[ruleId] : globals; - - if (ranges && ranges.length > 0) { - return ranges[ranges.length - 1].state - } - - if (!ruleId) { - return !reset - } - - return reset ? enable.includes(ruleId) : !disable.includes(ruleId) - } - - /** - * Handle a rule. - * - * @param {Point|undefined} point - * @param {boolean} state - * @param {string|undefined} [ruleId] - * @returns {void} - */ - function toggle(point, state, ruleId) { - let markers = ruleId ? scope[ruleId] : globals; - - if (!markers) { - markers = []; - scope[String(ruleId)] = markers; - } - - const previousState = getState(ruleId); - - if (state !== previousState) { - markers.push({state, point}); - } - - // Toggle all known rules. - if (!ruleId) { - for (ruleId in scope) { - if (own$2.call(scope, ruleId)) { - toggle(point, state, ruleId); - } - } - } - } - - /** - * Check all `ranges` for `message`. - * - * @param {VFileMessage} message - * @param {Mark[]|undefined} ranges - * @param {string|undefined} [ruleId] - * @returns {boolean} - */ - function check(message, ranges, ruleId) { - if (ranges && ranges.length > 0) { - // Check the state at the message’s position. - let index = ranges.length; - - while (index--) { - const range = ranges[index]; - - if ( - message.line && - message.column && - range.point && - range.point.line && - range.point.column && - (range.point.line < message.line || - (range.point.line === message.line && - range.point.column <= message.column)) - ) { - return range.state === true - } - } - } - - // The first marker ocurred after the first message, so we check the - // initial state. - if (!ruleId) { - return Boolean(initial || reset) - } - - return reset ? enable.includes(ruleId) : !disable.includes(ruleId) - } - } -} - -/** - * Detect gaps in `tree`. - * - * @param {Node} tree - * @param {VFile} file - */ -function detectGaps(tree, file) { - /** @type {Node[]} */ - // @ts-expect-error: fine. - const children = tree.children || []; - const lastNode = children[children.length - 1]; - /** @type {[number, number][]} */ - const gaps = []; - let offset = 0; - /** @type {boolean|undefined} */ - let gap; - - // Find all gaps. - visit(tree, one); - - // Get the end of the document. - // This detects if the last node was the last node. - // If not, there’s an extra gap between the last node and the end of the - // document. - if ( - lastNode && - lastNode.position && - lastNode.position.end && - offset === lastNode.position.end.offset && - file.toString().slice(offset).trim() !== '' - ) { - update(); - - update( - tree && - tree.position && - tree.position.end && - tree.position.end.offset && - tree.position.end.offset - 1 - ); - } - - return gaps - - /** - * @param {Node} node - */ - function one(node) { - update(node.position && node.position.start && node.position.start.offset); - - if (!('children' in node)) { - update(node.position && node.position.end && node.position.end.offset); - } - } - - /** - * Detect a new position. - * - * @param {number|undefined} [latest] - * @returns {void} - */ - function update(latest) { - if (latest === null || latest === undefined) { - gap = true; - } else if (offset < latest) { - if (gap) { - gaps.push([offset, latest]); - gap = undefined; - } - - offset = latest; - } - } -} - -/** - * @typedef {string|number|boolean} MarkerParameterValue - * @typedef {Object.} MarkerParameters - * - * @typedef HtmlNode - * @property {'html'} type - * @property {string} value - * - * @typedef CommentNode - * @property {'comment'} type - * @property {string} value - * - * @typedef Marker - * @property {string} name - * @property {string} attributes - * @property {MarkerParameters|null} parameters - * @property {HtmlNode|CommentNode} node - */ - -var commentExpression = /\s*([a-zA-Z\d-]+)(\s+([\s\S]*))?\s*/; - -var markerExpression = new RegExp( - '(\\s*\\s*)' -); - -/** - * Parse a comment marker. - * @param {unknown} node - * @returns {Marker|null} - */ -function commentMarker(node) { - /** @type {RegExpMatchArray} */ - var match; - /** @type {number} */ - var offset; - /** @type {MarkerParameters} */ - var parameters; - - if ( - node && - typeof node === 'object' && - // @ts-ignore hush - (node.type === 'html' || node.type === 'comment') - ) { - // @ts-ignore hush - match = node.value.match( - // @ts-ignore hush - node.type === 'comment' ? commentExpression : markerExpression - ); - - // @ts-ignore hush - if (match && match[0].length === node.value.length) { - // @ts-ignore hush - offset = node.type === 'comment' ? 1 : 2; - parameters = parseParameters(match[offset + 1] || ''); - - if (parameters) { - return { - name: match[offset], - attributes: match[offset + 2] || '', - parameters, - // @ts-ignore hush - node - } - } - } - } - - return null -} - -/** - * Parse `value` into an object. - * - * @param {string} value - * @returns {MarkerParameters|null} - */ -function parseParameters(value) { - /** @type {MarkerParameters} */ - var parameters = {}; - - return value - .replace( - /\s+([-\w]+)(?:=(?:"((?:\\[\s\S]|[^"])+)"|'((?:\\[\s\S]|[^'])+)'|((?:\\[\s\S]|[^"'\s])+)))?/gi, - replacer - ) - .replace(/\s+/g, '') - ? null - : parameters - - /** - * @param {string} _ - * @param {string} $1 - * @param {string} $2 - * @param {string} $3 - * @param {string} $4 - */ - // eslint-disable-next-line max-params - function replacer(_, $1, $2, $3, $4) { - /** @type {MarkerParameterValue} */ - var value = $2 || $3 || $4 || ''; - - if (value === 'true' || value === '') { - value = true; - } else if (value === 'false') { - value = false; - } else if (!Number.isNaN(Number(value))) { - value = Number(value); - } - - parameters[$1] = value; - - return '' - } -} - -/** - * @typedef {import('mdast').Root} Root - * @typedef {import('vfile').VFile} VFile - * @typedef {import('unified-message-control')} MessageControl - * @typedef {Omit|Omit} Options - */ - -const test = [ - 'html', // Comments are `html` nodes in mdast. - 'comment' // In MDX, comments have their own node. -]; - -/** - * Plugin to enable, disable, and ignore messages. - * - * @type {import('unified').Plugin<[Options], Root>} - * @returns {(node: Root, file: VFile) => void} - */ -function remarkMessageControl(options) { - return messageControl( - Object.assign({marker: commentMarker, test}, options) - ) -} - -/** - * @typedef {import('mdast').Root} Root - */ - -/** - * The core plugin for `remark-lint`. - * This adds support for ignoring stuff from messages (``). - * All rules are in their own packages and presets. - * - * @type {import('unified').Plugin} - */ -function remarkLint() { - this.use(lintMessageControl); -} - -/** @type {import('unified').Plugin} */ -function lintMessageControl() { - return remarkMessageControl({name: 'lint', source: 'remark-lint'}) -} - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('vfile').VFile} VFile - * - * @typedef {0|1|2} Severity - * @typedef {'warn'|'on'|'off'|'error'} Label - * @typedef {[Severity, ...unknown[]]} SeverityTuple - * - * @callback Rule - * @param {Node} tree - * @param {VFile} file - * @param {unknown} options - * @returns {void} - */ - -const primitives = new Set(['string', 'number', 'boolean']); - -/** - * @param {string} id - * @param {Rule} rule - */ -function lintRule(id, rule) { - const parts = id.split(':'); - // Possibly useful if externalised later. - /* c8 ignore next */ - const source = parts[1] ? parts[0] : undefined; - const ruleId = parts[1]; - - Object.defineProperty(plugin, 'name', {value: id}); - - return plugin - - /** @type {import('unified').Plugin<[unknown]|void[]>} */ - function plugin(raw) { - const [severity, options] = coerce$1(ruleId, raw); - - if (!severity) return - - const fatal = severity === 2; - - return (tree, file, next) => { - let index = file.messages.length - 1; - - wrap(rule, (error) => { - const messages = file.messages; - - // Add the error, if not already properly added. - // Only happens for incorrect plugins. - /* c8 ignore next 6 */ - // @ts-expect-error: errors could be `messages`. - if (error && !messages.includes(error)) { - try { - file.fail(error); - } catch {} - } - - while (++index < messages.length) { - Object.assign(messages[index], {ruleId, source, fatal}); - } - - next(); - })(tree, file, options); - } - } -} - -/** - * Coerce a value to a severity--options tuple. - * - * @param {string} name - * @param {unknown} value - * @returns {SeverityTuple} - */ -function coerce$1(name, value) { - /** @type {unknown[]} */ - let result; - - if (typeof value === 'boolean') { - result = [value]; - } else if (value === null || value === undefined) { - result = [1]; - } else if ( - Array.isArray(value) && - // `isArray(unknown)` is turned into `any[]`: - // type-coverage:ignore-next-line - primitives.has(typeof value[0]) - ) { - // `isArray(unknown)` is turned into `any[]`: - // type-coverage:ignore-next-line - result = [...value]; - } else { - result = [1, value]; - } - - let level = result[0]; - - if (typeof level === 'boolean') { - level = level ? 1 : 0; - } else if (typeof level === 'string') { - if (level === 'off') { - level = 0; - } else if (level === 'on' || level === 'warn') { - level = 1; - } else if (level === 'error') { - level = 2; - } else { - level = 1; - result = [level, result]; - } - } - - if (typeof level !== 'number' || level < 0 || level > 2) { - throw new Error( - 'Incorrect severity `' + - level + - '` for `' + - name + - '`, ' + - 'expected 0, 1, or 2' - ) - } - - result[0] = level; - - // @ts-expect-error: it’s now a valid tuple. - return result -} - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module final-newline - * @fileoverview - * Warn when a line feed at the end of a file is missing. - * Empty files are allowed. - * - * See [StackExchange](https://unix.stackexchange.com/questions/18743) for why. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * always adds a final line feed to files. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * ## Example - * - * ##### `ok.md` - * - * ###### In - * - * Note: `␊` represents LF. - * - * ```markdown - * Alpha␊ - * ``` - * - * ###### Out - * - * No messages. - * - * ##### `not-ok.md` - * - * ###### In - * - * Note: The below file does not have a final newline. - * - * ```markdown - * Bravo - * ``` - * - * ###### Out - * - * ```text - * 1:1: Missing newline character at end of file - * ``` - */ - -const remarkLintFinalNewline = lintRule( - 'remark-lint:final-newline', - /** @type {import('unified-lint-rule').Rule} */ - (_, file) => { - const value = String(file); - const last = value.length - 1; - - if (last > -1 && value.charAt(last) !== '\n') { - file.message('Missing newline character at end of file'); - } - } -); - -var remarkLintFinalNewline$1 = remarkLintFinalNewline; - -var pluralize = {exports: {}}; - -/* global define */ - -(function (module, exports) { -(function (root, pluralize) { - /* istanbul ignore else */ - if (typeof commonjsRequire === 'function' && 'object' === 'object' && 'object' === 'object') { - // Node. - module.exports = pluralize(); - } else { - // Browser global. - root.pluralize = pluralize(); - } -})(commonjsGlobal, function () { - // Rule storage - pluralize and singularize need to be run sequentially, - // while other rules can be optimized using an object for instant lookups. - var pluralRules = []; - var singularRules = []; - var uncountables = {}; - var irregularPlurals = {}; - var irregularSingles = {}; - - /** - * Sanitize a pluralization rule to a usable regular expression. - * - * @param {(RegExp|string)} rule - * @return {RegExp} - */ - function sanitizeRule (rule) { - if (typeof rule === 'string') { - return new RegExp('^' + rule + '$', 'i'); - } - - return rule; - } - - /** - * Pass in a word token to produce a function that can replicate the case on - * another word. - * - * @param {string} word - * @param {string} token - * @return {Function} - */ - function restoreCase (word, token) { - // Tokens are an exact match. - if (word === token) return token; - - // Lower cased words. E.g. "hello". - if (word === word.toLowerCase()) return token.toLowerCase(); - - // Upper cased words. E.g. "WHISKY". - if (word === word.toUpperCase()) return token.toUpperCase(); - - // Title cased words. E.g. "Title". - if (word[0] === word[0].toUpperCase()) { - return token.charAt(0).toUpperCase() + token.substr(1).toLowerCase(); - } - - // Lower cased words. E.g. "test". - return token.toLowerCase(); - } - - /** - * Interpolate a regexp string. - * - * @param {string} str - * @param {Array} args - * @return {string} - */ - function interpolate (str, args) { - return str.replace(/\$(\d{1,2})/g, function (match, index) { - return args[index] || ''; - }); - } - - /** - * Replace a word using a rule. - * - * @param {string} word - * @param {Array} rule - * @return {string} - */ - function replace (word, rule) { - return word.replace(rule[0], function (match, index) { - var result = interpolate(rule[1], arguments); - - if (match === '') { - return restoreCase(word[index - 1], result); - } - - return restoreCase(match, result); - }); - } - - /** - * Sanitize a word by passing in the word and sanitization rules. - * - * @param {string} token - * @param {string} word - * @param {Array} rules - * @return {string} - */ - function sanitizeWord (token, word, rules) { - // Empty string or doesn't need fixing. - if (!token.length || uncountables.hasOwnProperty(token)) { - return word; - } - - var len = rules.length; - - // Iterate over the sanitization rules and use the first one to match. - while (len--) { - var rule = rules[len]; - - if (rule[0].test(word)) return replace(word, rule); - } - - return word; - } - - /** - * Replace a word with the updated word. - * - * @param {Object} replaceMap - * @param {Object} keepMap - * @param {Array} rules - * @return {Function} - */ - function replaceWord (replaceMap, keepMap, rules) { - return function (word) { - // Get the correct token and case restoration functions. - var token = word.toLowerCase(); - - // Check against the keep object map. - if (keepMap.hasOwnProperty(token)) { - return restoreCase(word, token); - } - - // Check against the replacement map for a direct word replacement. - if (replaceMap.hasOwnProperty(token)) { - return restoreCase(word, replaceMap[token]); - } - - // Run all the rules against the word. - return sanitizeWord(token, word, rules); - }; - } - - /** - * Check if a word is part of the map. - */ - function checkWord (replaceMap, keepMap, rules, bool) { - return function (word) { - var token = word.toLowerCase(); - - if (keepMap.hasOwnProperty(token)) return true; - if (replaceMap.hasOwnProperty(token)) return false; - - return sanitizeWord(token, token, rules) === token; - }; - } - - /** - * Pluralize or singularize a word based on the passed in count. - * - * @param {string} word The word to pluralize - * @param {number} count How many of the word exist - * @param {boolean} inclusive Whether to prefix with the number (e.g. 3 ducks) - * @return {string} - */ - function pluralize (word, count, inclusive) { - var pluralized = count === 1 - ? pluralize.singular(word) : pluralize.plural(word); - - return (inclusive ? count + ' ' : '') + pluralized; - } - - /** - * Pluralize a word. - * - * @type {Function} - */ - pluralize.plural = replaceWord( - irregularSingles, irregularPlurals, pluralRules - ); - - /** - * Check if a word is plural. - * - * @type {Function} - */ - pluralize.isPlural = checkWord( - irregularSingles, irregularPlurals, pluralRules - ); - - /** - * Singularize a word. - * - * @type {Function} - */ - pluralize.singular = replaceWord( - irregularPlurals, irregularSingles, singularRules - ); - - /** - * Check if a word is singular. - * - * @type {Function} - */ - pluralize.isSingular = checkWord( - irregularPlurals, irregularSingles, singularRules - ); - - /** - * Add a pluralization rule to the collection. - * - * @param {(string|RegExp)} rule - * @param {string} replacement - */ - pluralize.addPluralRule = function (rule, replacement) { - pluralRules.push([sanitizeRule(rule), replacement]); - }; - - /** - * Add a singularization rule to the collection. - * - * @param {(string|RegExp)} rule - * @param {string} replacement - */ - pluralize.addSingularRule = function (rule, replacement) { - singularRules.push([sanitizeRule(rule), replacement]); - }; - - /** - * Add an uncountable word rule. - * - * @param {(string|RegExp)} word - */ - pluralize.addUncountableRule = function (word) { - if (typeof word === 'string') { - uncountables[word.toLowerCase()] = true; - return; - } - - // Set singular and plural references for the word. - pluralize.addPluralRule(word, '$0'); - pluralize.addSingularRule(word, '$0'); - }; - - /** - * Add an irregular word definition. - * - * @param {string} single - * @param {string} plural - */ - pluralize.addIrregularRule = function (single, plural) { - plural = plural.toLowerCase(); - single = single.toLowerCase(); - - irregularSingles[single] = plural; - irregularPlurals[plural] = single; - }; - - /** - * Irregular rules. - */ - [ - // Pronouns. - ['I', 'we'], - ['me', 'us'], - ['he', 'they'], - ['she', 'they'], - ['them', 'them'], - ['myself', 'ourselves'], - ['yourself', 'yourselves'], - ['itself', 'themselves'], - ['herself', 'themselves'], - ['himself', 'themselves'], - ['themself', 'themselves'], - ['is', 'are'], - ['was', 'were'], - ['has', 'have'], - ['this', 'these'], - ['that', 'those'], - // Words ending in with a consonant and `o`. - ['echo', 'echoes'], - ['dingo', 'dingoes'], - ['volcano', 'volcanoes'], - ['tornado', 'tornadoes'], - ['torpedo', 'torpedoes'], - // Ends with `us`. - ['genus', 'genera'], - ['viscus', 'viscera'], - // Ends with `ma`. - ['stigma', 'stigmata'], - ['stoma', 'stomata'], - ['dogma', 'dogmata'], - ['lemma', 'lemmata'], - ['schema', 'schemata'], - ['anathema', 'anathemata'], - // Other irregular rules. - ['ox', 'oxen'], - ['axe', 'axes'], - ['die', 'dice'], - ['yes', 'yeses'], - ['foot', 'feet'], - ['eave', 'eaves'], - ['goose', 'geese'], - ['tooth', 'teeth'], - ['quiz', 'quizzes'], - ['human', 'humans'], - ['proof', 'proofs'], - ['carve', 'carves'], - ['valve', 'valves'], - ['looey', 'looies'], - ['thief', 'thieves'], - ['groove', 'grooves'], - ['pickaxe', 'pickaxes'], - ['passerby', 'passersby'] - ].forEach(function (rule) { - return pluralize.addIrregularRule(rule[0], rule[1]); - }); - - /** - * Pluralization rules. - */ - [ - [/s?$/i, 's'], - [/[^\u0000-\u007F]$/i, '$0'], - [/([^aeiou]ese)$/i, '$1'], - [/(ax|test)is$/i, '$1es'], - [/(alias|[^aou]us|t[lm]as|gas|ris)$/i, '$1es'], - [/(e[mn]u)s?$/i, '$1s'], - [/([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$/i, '$1'], - [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1i'], - [/(alumn|alg|vertebr)(?:a|ae)$/i, '$1ae'], - [/(seraph|cherub)(?:im)?$/i, '$1im'], - [/(her|at|gr)o$/i, '$1oes'], - [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i, '$1a'], - [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i, '$1a'], - [/sis$/i, 'ses'], - [/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i, '$1$2ves'], - [/([^aeiouy]|qu)y$/i, '$1ies'], - [/([^ch][ieo][ln])ey$/i, '$1ies'], - [/(x|ch|ss|sh|zz)$/i, '$1es'], - [/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i, '$1ices'], - [/\b((?:tit)?m|l)(?:ice|ouse)$/i, '$1ice'], - [/(pe)(?:rson|ople)$/i, '$1ople'], - [/(child)(?:ren)?$/i, '$1ren'], - [/eaux$/i, '$0'], - [/m[ae]n$/i, 'men'], - ['thou', 'you'] - ].forEach(function (rule) { - return pluralize.addPluralRule(rule[0], rule[1]); - }); - - /** - * Singularization rules. - */ - [ - [/s$/i, ''], - [/(ss)$/i, '$1'], - [/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i, '$1fe'], - [/(ar|(?:wo|[ae])l|[eo][ao])ves$/i, '$1f'], - [/ies$/i, 'y'], - [/\b([pl]|zomb|(?:neck|cross)?t|coll|faer|food|gen|goon|group|lass|talk|goal|cut)ies$/i, '$1ie'], - [/\b(mon|smil)ies$/i, '$1ey'], - [/\b((?:tit)?m|l)ice$/i, '$1ouse'], - [/(seraph|cherub)im$/i, '$1'], - [/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$/i, '$1'], - [/(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$/i, '$1sis'], - [/(movie|twelve|abuse|e[mn]u)s$/i, '$1'], - [/(test)(?:is|es)$/i, '$1is'], - [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1us'], - [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i, '$1um'], - [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i, '$1on'], - [/(alumn|alg|vertebr)ae$/i, '$1a'], - [/(cod|mur|sil|vert|ind)ices$/i, '$1ex'], - [/(matr|append)ices$/i, '$1ix'], - [/(pe)(rson|ople)$/i, '$1rson'], - [/(child)ren$/i, '$1'], - [/(eau)x?$/i, '$1'], - [/men$/i, 'man'] - ].forEach(function (rule) { - return pluralize.addSingularRule(rule[0], rule[1]); - }); - - /** - * Uncountable rules. - */ - [ - // Singular words with no plurals. - 'adulthood', - 'advice', - 'agenda', - 'aid', - 'aircraft', - 'alcohol', - 'ammo', - 'analytics', - 'anime', - 'athletics', - 'audio', - 'bison', - 'blood', - 'bream', - 'buffalo', - 'butter', - 'carp', - 'cash', - 'chassis', - 'chess', - 'clothing', - 'cod', - 'commerce', - 'cooperation', - 'corps', - 'debris', - 'diabetes', - 'digestion', - 'elk', - 'energy', - 'equipment', - 'excretion', - 'expertise', - 'firmware', - 'flounder', - 'fun', - 'gallows', - 'garbage', - 'graffiti', - 'hardware', - 'headquarters', - 'health', - 'herpes', - 'highjinks', - 'homework', - 'housework', - 'information', - 'jeans', - 'justice', - 'kudos', - 'labour', - 'literature', - 'machinery', - 'mackerel', - 'mail', - 'media', - 'mews', - 'moose', - 'music', - 'mud', - 'manga', - 'news', - 'only', - 'personnel', - 'pike', - 'plankton', - 'pliers', - 'police', - 'pollution', - 'premises', - 'rain', - 'research', - 'rice', - 'salmon', - 'scissors', - 'series', - 'sewage', - 'shambles', - 'shrimp', - 'software', - 'species', - 'staff', - 'swine', - 'tennis', - 'traffic', - 'transportation', - 'trout', - 'tuna', - 'wealth', - 'welfare', - 'whiting', - 'wildebeest', - 'wildlife', - 'you', - /pok[eé]mon$/i, - // Regexes. - /[^aeiou]ese$/i, // "chinese", "japanese" - /deer$/i, // "deer", "reindeer" - /fish$/i, // "fish", "blowfish", "angelfish" - /measles$/i, - /o[iu]s$/i, // "carnivorous" - /pox$/i, // "chickpox", "smallpox" - /sheep$/i - ].forEach(pluralize.addUncountableRule); - - return pluralize; -}); -}(pluralize)); - -var plural = pluralize.exports; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module list-item-bullet-indent - * @fileoverview - * Warn when list item bullets are indented. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * removes all indentation before bullets. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * Paragraph. - * - * * List item - * * List item - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * Paragraph. - * - * ·* List item - * ·* List item - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 3:2: Incorrect indentation before bullet: remove 1 space - * 4:2: Incorrect indentation before bullet: remove 1 space - */ - -const remarkLintListItemBulletIndent = lintRule( - 'remark-lint:list-item-bullet-indent', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - visit$1(tree, 'list', (list, _, grandparent) => { - let index = -1; - - while (++index < list.children.length) { - const item = list.children[index]; - - if ( - grandparent && - grandparent.type === 'root' && - grandparent.position && - typeof grandparent.position.start.column === 'number' && - item.position && - typeof item.position.start.column === 'number' - ) { - const indent = - item.position.start.column - grandparent.position.start.column; - - if (indent) { - file.message( - 'Incorrect indentation before bullet: remove ' + - indent + - ' ' + - plural('space', indent), - item.position.start - ); - } - } - } - }); - } -); - -var remarkLintListItemBulletIndent$1 = remarkLintListItemBulletIndent; - -/** - * @typedef {import('unist').Position} Position - * @typedef {import('unist').Point} Point - * - * @typedef {Partial} PointLike - * - * @typedef {Object} PositionLike - * @property {PointLike} [start] - * @property {PointLike} [end] - * - * @typedef {Object} NodeLike - * @property {PositionLike} [position] - */ - -var pointStart = point('start'); -var pointEnd = point('end'); - -/** - * Get the positional info of `node`. - * - * @param {'start'|'end'} type - */ -function point(type) { - return point - - /** - * Get the positional info of `node`. - * - * @param {NodeLike} [node] - * @returns {Point} - */ - function point(node) { - /** @type {Point} */ - // @ts-ignore looks like a point - var point = (node && node.position && node.position[type]) || {}; - - return { - line: point.line || null, - column: point.column || null, - offset: point.offset > -1 ? point.offset : null - } - } -} - -/** - * @typedef {Object} PointLike - * @property {number} [line] - * @property {number} [column] - * @property {number} [offset] - * - * @typedef {Object} PositionLike - * @property {PointLike} [start] - * @property {PointLike} [end] - * - * @typedef {Object} NodeLike - * @property {PositionLike} [position] - */ - -/** - * Check if `node` is *generated*. - * - * @param {NodeLike} [node] - * @returns {boolean} - */ -function generated(node) { - return ( - !node || - !node.position || - !node.position.start || - !node.position.start.line || - !node.position.start.column || - !node.position.end || - !node.position.end.line || - !node.position.end.column - ) -} - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module list-item-indent - * @fileoverview - * Warn when the spacing between a list item’s bullet and its content violates - * a given style. - * - * Options: `'tab-size'`, `'mixed'`, or `'space'`, default: `'tab-size'`. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * uses `'tab-size'` (named `'tab'` there) by default to ensure Markdown is - * seen the same way across vendors. - * This can be configured with the - * [`listItemIndent`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionslistitemindent) - * option. - * This rule’s `'space'` option is named `'1'` there. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * *···List - * ····item. - * - * Paragraph. - * - * 11.·List - * ····item. - * - * Paragraph. - * - * *···List - * ····item. - * - * *···List - * ····item. - * - * @example - * {"name": "ok.md", "setting": "mixed"} - * - * *·List item. - * - * Paragraph. - * - * 11.·List item - * - * Paragraph. - * - * *···List - * ····item. - * - * *···List - * ····item. - * - * @example - * {"name": "ok.md", "setting": "space"} - * - * *·List item. - * - * Paragraph. - * - * 11.·List item - * - * Paragraph. - * - * *·List - * ··item. - * - * *·List - * ··item. - * - * @example - * {"name": "not-ok.md", "setting": "space", "label": "input"} - * - * *···List - * ····item. - * - * @example - * {"name": "not-ok.md", "setting": "space", "label": "output"} - * - * 1:5: Incorrect list-item indent: remove 2 spaces - * - * @example - * {"name": "not-ok.md", "setting": "tab-size", "label": "input"} - * - * *·List - * ··item. - * - * @example - * {"name": "not-ok.md", "setting": "tab-size", "label": "output"} - * - * 1:3: Incorrect list-item indent: add 2 spaces - * - * @example - * {"name": "not-ok.md", "setting": "mixed", "label": "input"} - * - * *···List item. - * - * @example - * {"name": "not-ok.md", "setting": "mixed", "label": "output"} - * - * 1:5: Incorrect list-item indent: remove 2 spaces - * - * @example - * {"name": "not-ok.md", "setting": "💩", "label": "output", "positionless": true} - * - * 1:1: Incorrect list-item indent style `💩`: use either `'tab-size'`, `'space'`, or `'mixed'` - */ - -const remarkLintListItemIndent = lintRule( - 'remark-lint:list-item-indent', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'tab-size') => { - const value = String(file); - - if (option !== 'tab-size' && option !== 'space' && option !== 'mixed') { - file.fail( - 'Incorrect list-item indent style `' + - option + - "`: use either `'tab-size'`, `'space'`, or `'mixed'`" - ); - } - - visit$1(tree, 'list', (node) => { - if (generated(node)) return - - const spread = node.spread; - let index = -1; - - while (++index < node.children.length) { - const item = node.children[index]; - const head = item.children[0]; - const final = pointStart(head); - - const marker = value - .slice(pointStart(item).offset, final.offset) - .replace(/\[[x ]?]\s*$/i, ''); - - const bulletSize = marker.replace(/\s+$/, '').length; - - const style = - option === 'tab-size' || (option === 'mixed' && spread) - ? Math.ceil(bulletSize / 4) * 4 - : bulletSize + 1; - - if (marker.length !== style) { - const diff = style - marker.length; - const abs = Math.abs(diff); - - file.message( - 'Incorrect list-item indent: ' + - (diff > 0 ? 'add' : 'remove') + - ' ' + - abs + - ' ' + - plural('space', abs), - final - ); - } - } - }); - } -); - -var remarkLintListItemIndent$1 = remarkLintListItemIndent; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-auto-link-without-protocol - * @fileoverview - * Warn for autolinks without protocol. - * Autolinks are URLs enclosed in `<` (less than) and `>` (greater than) - * characters. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * adds a protocol where needed. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * - * - * - * Most Markdown vendors don’t recognize the following as a link: - * - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:1-1:14: All automatic links must start with a protocol - */ - -// Protocol expression. -// See: . -const protocol = /^[a-z][a-z+.-]+:\/?/i; - -const remarkLintNoAutoLinkWithoutProtocol = lintRule( - 'remark-lint:no-auto-link-without-protocol', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - visit$1(tree, 'link', (node) => { - if ( - !generated(node) && - pointStart(node).column === pointStart(node.children[0]).column - 1 && - pointEnd(node).column === - pointEnd(node.children[node.children.length - 1]).column + 1 && - !protocol.test(toString(node)) - ) { - file.message('All automatic links must start with a protocol', node); - } - }); - } -); - -var remarkLintNoAutoLinkWithoutProtocol$1 = remarkLintNoAutoLinkWithoutProtocol; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-blockquote-without-marker - * @fileoverview - * Warn when blank lines without `>` (greater than) markers are found in a - * block quote. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * adds markers to every line in a block quote. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * > Foo… - * > …bar… - * > …baz. - * - * @example - * {"name": "ok-tabs.md"} - * - * >»Foo… - * >»…bar… - * >»…baz. - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * > Foo… - * …bar… - * > …baz. - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 2:1: Missing marker in block quote - * - * @example - * {"name": "not-ok-tabs.md", "label": "input"} - * - * >»Foo… - * »…bar… - * …baz. - * - * @example - * {"name": "not-ok-tabs.md", "label": "output"} - * - * 2:1: Missing marker in block quote - * 3:1: Missing marker in block quote - */ - -const remarkLintNoBlockquoteWithoutMarker = lintRule( - 'remark-lint:no-blockquote-without-marker', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - const value = String(file); - const loc = location(file); - - visit$1(tree, 'blockquote', (node) => { - let index = -1; - - while (++index < node.children.length) { - const child = node.children[index]; - - if (child.type === 'paragraph' && !generated(child)) { - const end = pointEnd(child).line; - const column = pointStart(child).column; - let line = pointStart(child).line; - - // Skip past the first line. - while (++line <= end) { - const offset = loc.toOffset({line, column}); - - if (/>[\t ]+$/.test(value.slice(offset - 5, offset))) { - continue - } - - // Roughly here. - file.message('Missing marker in block quote', { - line, - column: column - 2 - }); - } - } - } - }); - } -); - -var remarkLintNoBlockquoteWithoutMarker$1 = remarkLintNoBlockquoteWithoutMarker; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-literal-urls - * @fileoverview - * Warn for literal URLs in text. - * URLs are treated as links in some Markdown vendors, but not in others. - * To make sure they are always linked, wrap them in `<` (less than) and `>` - * (greater than). - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * never creates literal URLs and always uses `<` (less than) and `>` - * (greater than). - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * - * - * @example - * {"name": "not-ok.md", "label": "input", "gfm": true} - * - * http://foo.bar/baz - * - * @example - * {"name": "not-ok.md", "label": "output", "gfm": true} - * - * 1:1-1:19: Don’t use literal URLs without angle brackets - */ - -const remarkLintNoLiteralUrls = lintRule( - 'remark-lint:no-literal-urls', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - visit$1(tree, 'link', (node) => { - const value = toString(node); - - if ( - !generated(node) && - pointStart(node).column === pointStart(node.children[0]).column && - pointEnd(node).column === - pointEnd(node.children[node.children.length - 1]).column && - (node.url === 'mailto:' + value || node.url === value) - ) { - file.message('Don’t use literal URLs without angle brackets', node); - } - }); - } -); - -var remarkLintNoLiteralUrls$1 = remarkLintNoLiteralUrls; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module ordered-list-marker-style - * @fileoverview - * Warn when the list item marker style of ordered lists violate a given style. - * - * Options: `'consistent'`, `'.'`, or `')'`, default: `'consistent'`. - * - * `'consistent'` detects the first used list style and warns when subsequent - * lists use different styles. - * - * @example - * {"name": "ok.md"} - * - * 1. Foo - * - * - * 1. Bar - * - * Unordered lists are not affected by this rule. - * - * * Foo - * - * @example - * {"name": "ok.md", "setting": "."} - * - * 1. Foo - * - * 2. Bar - * - * @example - * {"name": "ok.md", "setting": ")"} - * - * 1) Foo - * - * 2) Bar - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * 1. Foo - * - * 2) Bar - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 3:1-3:8: Marker style should be `.` - * - * @example - * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} - * - * 1:1: Incorrect ordered list item marker style `💩`: use either `'.'` or `')'` - */ - -const remarkLintOrderedListMarkerStyle = lintRule( - 'remark-lint:ordered-list-marker-style', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - const value = String(file); - - if (option !== 'consistent' && option !== '.' && option !== ')') { - file.fail( - 'Incorrect ordered list item marker style `' + - option + - "`: use either `'.'` or `')'`" - ); - } - - visit$1(tree, 'list', (node) => { - let index = -1; - - if (!node.ordered) return - - while (++index < node.children.length) { - const child = node.children[index]; - - if (!generated(child)) { - const marker = /** @type {Marker} */ ( - value - .slice( - pointStart(child).offset, - pointStart(child.children[0]).offset - ) - .replace(/\s|\d/g, '') - .replace(/\[[x ]?]\s*$/i, '') - ); - - if (option === 'consistent') { - option = marker; - } else if (marker !== option) { - file.message('Marker style should be `' + option + '`', child); - } - } - } - }); - } -); - -var remarkLintOrderedListMarkerStyle$1 = remarkLintOrderedListMarkerStyle; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module hard-break-spaces - * @fileoverview - * Warn when too many spaces are used to create a hard break. - * - * @example - * {"name": "ok.md"} - * - * Lorem ipsum·· - * dolor sit amet - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * Lorem ipsum··· - * dolor sit amet. - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:12-2:1: Use two spaces for hard line breaks - */ - -const remarkLintHardBreakSpaces = lintRule( - 'remark-lint:hard-break-spaces', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - const value = String(file); - - visit$1(tree, 'break', (node) => { - if (!generated(node)) { - const slice = value - .slice(pointStart(node).offset, pointEnd(node).offset) - .split('\n', 1)[0] - .replace(/\r$/, ''); - - if (slice.length > 2) { - file.message('Use two spaces for hard line breaks', node); - } - } - }); - } -); - -var remarkLintHardBreakSpaces$1 = remarkLintHardBreakSpaces; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-duplicate-definitions - * @fileoverview - * Warn when duplicate definitions are found. - * - * @example - * {"name": "ok.md"} - * - * [foo]: bar - * [baz]: qux - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * [foo]: bar - * [foo]: qux - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 2:1-2:11: Do not use definitions with the same identifier (1:1) - */ - -const remarkLintNoDuplicateDefinitions = lintRule( - 'remark-lint:no-duplicate-definitions', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - /** @type {Record} */ - const map = Object.create(null); - - visit$1(tree, (node) => { - if ( - (node.type === 'definition' || node.type === 'footnoteDefinition') && - !generated(node) - ) { - const identifier = node.identifier; - const duplicate = map[identifier]; - - if (duplicate) { - file.message( - 'Do not use definitions with the same identifier (' + - duplicate + - ')', - node - ); - } - - map[identifier] = stringifyPosition$1(pointStart(node)); - } - }); - } -); - -var remarkLintNoDuplicateDefinitions$1 = remarkLintNoDuplicateDefinitions; - -/** - * @typedef {import('mdast').Heading} Heading - * @typedef {'atx'|'atx-closed'|'setext'} Style - */ - -/** - * @param {Heading} node - * @param {Style} [relative] - * @returns {Style|null} - */ -function headingStyle(node, relative) { - var last = node.children[node.children.length - 1]; - var depth = node.depth; - var pos = node && node.position && node.position.end; - var final = last && last.position && last.position.end; - - if (!pos) { - return null - } - - // This can only occur for `'atx'` and `'atx-closed'` headings. - // This might incorrectly match `'atx'` headings with lots of trailing white - // space as an `'atx-closed'` heading. - if (!last) { - if (pos.column - 1 <= depth * 2) { - return consolidate(depth, relative) - } - - return 'atx-closed' - } - - if (final.line + 1 === pos.line) { - return 'setext' - } - - if (final.column + depth < pos.column) { - return 'atx-closed' - } - - return consolidate(depth, relative) -} - -/** - * Get the probable style of an atx-heading, depending on preferred style. - * - * @param {number} depth - * @param {Style} relative - * @returns {Style|null} - */ -function consolidate(depth, relative) { - return depth < 3 - ? 'atx' - : relative === 'atx' || relative === 'setext' - ? relative - : null -} - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-heading-content-indent - * @fileoverview - * Warn when content of headings is indented. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * removes all unneeded padding around content in headings. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * #·Foo - * - * ## Bar·## - * - * ##·Baz - * - * Setext headings are not affected. - * - * Baz - * === - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * #··Foo - * - * ## Bar··## - * - * ##··Baz - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:4: Remove 1 space before this heading’s content - * 3:7: Remove 1 space after this heading’s content - * 5:7: Remove 1 space before this heading’s content - * - * @example - * {"name": "empty-heading.md"} - * - * #·· - */ - -const remarkLintNoHeadingContentIndent = lintRule( - 'remark-lint:no-heading-content-indent', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - visit$1(tree, 'heading', (node) => { - if (generated(node)) { - return - } - - const type = headingStyle(node, 'atx'); - - if (type === 'atx' || type === 'atx-closed') { - const head = pointStart(node.children[0]).column; - - // Ignore empty headings. - if (!head) { - return - } - - const diff = head - pointStart(node).column - 1 - node.depth; - - if (diff) { - file.message( - 'Remove ' + - Math.abs(diff) + - ' ' + - plural('space', Math.abs(diff)) + - ' before this heading’s content', - pointStart(node.children[0]) - ); - } - } - - // Closed ATX headings always must have a space between their content and - // the final hashes, thus, there is no `add x spaces`. - if (type === 'atx-closed') { - const final = pointEnd(node.children[node.children.length - 1]); - const diff = pointEnd(node).column - final.column - 1 - node.depth; - - if (diff) { - file.message( - 'Remove ' + - diff + - ' ' + - plural('space', diff) + - ' after this heading’s content', - final - ); - } - } - }); - } -); - -var remarkLintNoHeadingContentIndent$1 = remarkLintNoHeadingContentIndent; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-inline-padding - * @fileoverview - * Warn when phrasing content is padded with spaces between their markers and - * content. - * - * Warns for emphasis, strong, delete, image, and link. - * - * @example - * {"name": "ok.md"} - * - * Alpha [bravo](http://echo.fox/trot) - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * Alpha [ bravo ](http://echo.fox/trot) - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:7-1:38: Don’t pad `link` with inner spaces - */ - -const remarkLintNoInlinePadding = lintRule( - 'remark-lint:no-inline-padding', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - // Note: `emphasis`, `strong`, `delete` (GFM) can’t have padding anymore - // since CM. - visit$1(tree, (node) => { - if ( - (node.type === 'link' || node.type === 'linkReference') && - !generated(node) - ) { - const value = toString(node); - - if (value.charAt(0) === ' ' || value.charAt(value.length - 1) === ' ') { - file.message('Don’t pad `' + node.type + '` with inner spaces', node); - } - } - }); - } -); - -var remarkLintNoInlinePadding$1 = remarkLintNoInlinePadding; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-shortcut-reference-image - * @fileoverview - * Warn when shortcut reference images are used. - * - * Shortcut references render as images when a definition is found, and as - * plain text without definition. - * Sometimes, you don’t intend to create an image from the reference, but this - * rule still warns anyway. - * In that case, you can escape the reference like so: `!\[foo]`. - * - * @example - * {"name": "ok.md"} - * - * ![foo][] - * - * [foo]: http://foo.bar/baz.png - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * ![foo] - * - * [foo]: http://foo.bar/baz.png - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:1-1:7: Use the trailing [] on reference images - */ - -const remarkLintNoShortcutReferenceImage = lintRule( - 'remark-lint:no-shortcut-reference-image', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - visit$1(tree, 'imageReference', (node) => { - if (!generated(node) && node.referenceType === 'shortcut') { - file.message('Use the trailing [] on reference images', node); - } - }); - } -); - -var remarkLintNoShortcutReferenceImage$1 = remarkLintNoShortcutReferenceImage; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-shortcut-reference-link - * @fileoverview - * Warn when shortcut reference links are used. - * - * Shortcut references render as links when a definition is found, and as - * plain text without definition. - * Sometimes, you don’t intend to create a link from the reference, but this - * rule still warns anyway. - * In that case, you can escape the reference like so: `\[foo]`. - * - * @example - * {"name": "ok.md"} - * - * [foo][] - * - * [foo]: http://foo.bar/baz - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * [foo] - * - * [foo]: http://foo.bar/baz - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:1-1:6: Use the trailing `[]` on reference links - */ - -const remarkLintNoShortcutReferenceLink = lintRule( - 'remark-lint:no-shortcut-reference-link', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - visit$1(tree, 'linkReference', (node) => { - if (!generated(node) && node.referenceType === 'shortcut') { - file.message('Use the trailing `[]` on reference links', node); - } - }); - } -); - -var remarkLintNoShortcutReferenceLink$1 = remarkLintNoShortcutReferenceLink; - -/** - * @author Titus Wormer - * @copyright 2016 Titus Wormer - * @license MIT - * @module no-undefined-references - * @fileoverview - * Warn when references to undefined definitions are found. - * - * Options: `Object`, optional. - * - * The object can have an `allow` field, set to an array of strings that may - * appear between `[` and `]`, but that should not be treated as link - * identifiers. - * - * @example - * {"name": "ok.md"} - * - * [foo][] - * - * Just a [ bracket. - * - * Typically, you’d want to use escapes (with a backslash: \\) to escape what - * could turn into a \[reference otherwise]. - * - * Just two braces can’t link: []. - * - * [foo]: https://example.com - * - * @example - * {"name": "ok-allow.md", "setting": {"allow": ["...", "…"]}} - * - * > Eliding a portion of a quoted passage […] is acceptable. - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * [bar] - * - * [baz][] - * - * [text][qux] - * - * Spread [over - * lines][] - * - * > in [a - * > block quote][] - * - * [asd][a - * - * Can include [*emphasis*]. - * - * Multiple pairs: [a][b][c]. - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:1-1:6: Found reference to undefined definition - * 3:1-3:8: Found reference to undefined definition - * 5:1-5:12: Found reference to undefined definition - * 7:8-8:9: Found reference to undefined definition - * 10:6-11:17: Found reference to undefined definition - * 13:1-13:6: Found reference to undefined definition - * 15:13-15:25: Found reference to undefined definition - * 17:17-17:23: Found reference to undefined definition - * 17:23-17:26: Found reference to undefined definition - */ - -const remarkLintNoUndefinedReferences = lintRule( - 'remark-lint:no-undefined-references', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = {}) => { - const contents = String(file); - const loc = location(file); - const lineEnding = /(\r?\n|\r)[\t ]*(>[\t ]*)*/g; - const allow = new Set( - (option.allow || []).map((d) => normalizeIdentifier(d)) - ); - /** @type {Record} */ - const map = Object.create(null); - - visit$1(tree, (node) => { - if ( - (node.type === 'definition' || node.type === 'footnoteDefinition') && - !generated(node) - ) { - map[normalizeIdentifier(node.identifier)] = true; - } - }); - - visit$1(tree, (node) => { - // CM specifiers that references only form when defined. - // Still, they could be added by plugins, so let’s keep it. - /* c8 ignore next 10 */ - if ( - (node.type === 'imageReference' || - node.type === 'linkReference' || - node.type === 'footnoteReference') && - !generated(node) && - !(normalizeIdentifier(node.identifier) in map) && - !allow.has(normalizeIdentifier(node.identifier)) - ) { - file.message('Found reference to undefined definition', node); - } - - if (node.type === 'paragraph' || node.type === 'heading') { - findInPhrasing(node); - } - }); - - /** - * @param {Heading|Paragraph} node - */ - function findInPhrasing(node) { - /** @type {Range[]} */ - let ranges = []; - - visit$1(node, (child) => { - // Ignore the node itself. - if (child === node) return - - // Can’t have links in links, so reset ranges. - if (child.type === 'link' || child.type === 'linkReference') { - ranges = []; - return SKIP$1 - } - - // Enter non-text. - if (child.type !== 'text') return - - const start = pointStart(child).offset; - const end = pointEnd(child).offset; - - // Bail if there’s no positional info. - if (typeof start !== 'number' || typeof end !== 'number') { - return EXIT$1 - } - - const source = contents.slice(start, end); - /** @type {Array.<[number, string]>} */ - const lines = [[start, '']]; - let last = 0; - - lineEnding.lastIndex = 0; - let match = lineEnding.exec(source); - - while (match) { - const index = match.index; - lines[lines.length - 1][1] = source.slice(last, index); - last = index + match[0].length; - lines.push([start + last, '']); - match = lineEnding.exec(source); - } - - lines[lines.length - 1][1] = source.slice(last); - let lineIndex = -1; - - while (++lineIndex < lines.length) { - const line = lines[lineIndex][1]; - let index = 0; - - while (index < line.length) { - const code = line.charCodeAt(index); - - // Skip past escaped brackets. - if (code === 92) { - const next = line.charCodeAt(index + 1); - index++; - - if (next === 91 || next === 93) { - index++; - } - } - // Opening bracket. - else if (code === 91) { - ranges.push([lines[lineIndex][0] + index]); - index++; - } - // Close bracket. - else if (code === 93) { - // No opening. - if (ranges.length === 0) { - index++; - } else if (line.charCodeAt(index + 1) === 91) { - index++; - - // Collapsed or full. - let range = ranges.pop(); - - // Range should always exist. - // eslint-disable-next-line max-depth - if (range) { - range.push(lines[lineIndex][0] + index); - - // This is the end of a reference already. - // eslint-disable-next-line max-depth - if (range.length === 4) { - handleRange(range); - range = []; - } - - range.push(lines[lineIndex][0] + index); - ranges.push(range); - index++; - } - } else { - index++; - - // Shortcut or typical end of a reference. - const range = ranges.pop(); - - // Range should always exist. - // eslint-disable-next-line max-depth - if (range) { - range.push(lines[lineIndex][0] + index); - handleRange(range); - } - } - } - // Anything else. - else { - index++; - } - } - } - }); - - let index = -1; - - while (++index < ranges.length) { - handleRange(ranges[index]); - } - - return SKIP$1 - - /** - * @param {Range} range - */ - function handleRange(range) { - if (range.length === 1) return - if (range.length === 3) range.length = 2; - - // No need to warn for just `[]`. - if (range.length === 2 && range[0] + 2 === range[1]) return - - const offset = range.length === 4 && range[2] + 2 !== range[3] ? 2 : 0; - const id = contents - .slice(range[0 + offset] + 1, range[1 + offset] - 1) - .replace(lineEnding, ' '); - const pos = { - start: loc.toPoint(range[0]), - end: loc.toPoint(range[range.length - 1]) - }; - - if ( - !generated({position: pos}) && - !(normalizeIdentifier(id) in map) && - !allow.has(normalizeIdentifier(id)) - ) { - file.message('Found reference to undefined definition', pos); - } - } - } - } -); - -var remarkLintNoUndefinedReferences$1 = remarkLintNoUndefinedReferences; - -/** - * @author Titus Wormer - * @copyright 2016 Titus Wormer - * @license MIT - * @module no-unused-definitions - * @fileoverview - * Warn when unused definitions are found. - * - * @example - * {"name": "ok.md"} - * - * [foo][] - * - * [foo]: https://example.com - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * [bar]: https://example.com - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:1-1:27: Found unused definition - */ - -const own$1 = {}.hasOwnProperty; - -const remarkLintNoUnusedDefinitions = lintRule( - 'remark-lint:no-unused-definitions', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - /** @type {Record} */ - const map = Object.create(null); - - visit$1(tree, (node) => { - if ( - (node.type === 'definition' || node.type === 'footnoteDefinition') && - !generated(node) - ) { - map[node.identifier.toUpperCase()] = {node, used: false}; - } - }); - - visit$1(tree, (node) => { - if ( - node.type === 'imageReference' || - node.type === 'linkReference' || - node.type === 'footnoteReference' - ) { - const info = map[node.identifier.toUpperCase()]; - - if (!generated(node) && info) { - info.used = true; - } - } - }); - - /** @type {string} */ - let identifier; - - for (identifier in map) { - if (own$1.call(map, identifier)) { - const entry = map[identifier]; - - if (!entry.used) { - file.message('Found unused definition', entry.node); - } - } - } - } -); - -var remarkLintNoUnusedDefinitions$1 = remarkLintNoUnusedDefinitions; - -/** - * @fileoverview - * remark preset to configure `remark-lint` with settings that prevent - * mistakes or stuff that fails across vendors. - */ - -/** @type {Preset} */ -const remarkPresetLintRecommended = { - plugins: [ - remarkLint, - // Unix compatibility. - remarkLintFinalNewline$1, - // Rendering across vendors differs greatly if using other styles. - remarkLintListItemBulletIndent$1, - [remarkLintListItemIndent$1, 'tab-size'], - // Differs or unsupported across vendors. - remarkLintNoAutoLinkWithoutProtocol$1, - remarkLintNoBlockquoteWithoutMarker$1, - remarkLintNoLiteralUrls$1, - [remarkLintOrderedListMarkerStyle$1, '.'], - // Mistakes. - remarkLintHardBreakSpaces$1, - remarkLintNoDuplicateDefinitions$1, - remarkLintNoHeadingContentIndent$1, - remarkLintNoInlinePadding$1, - remarkLintNoShortcutReferenceImage$1, - remarkLintNoShortcutReferenceLink$1, - remarkLintNoUndefinedReferences$1, - remarkLintNoUnusedDefinitions$1 - ] -}; - -var remarkPresetLintRecommended$1 = remarkPresetLintRecommended; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module blockquote-indentation - * @fileoverview - * Warn when block quotes are indented too much or too little. - * - * Options: `number` or `'consistent'`, default: `'consistent'`. - * - * `'consistent'` detects the first used indentation and will warn when - * other block quotes use a different indentation. - * - * @example - * {"name": "ok.md", "setting": 4} - * - * > Hello - * - * Paragraph. - * - * > World - * @example - * {"name": "ok.md", "setting": 2} - * - * > Hello - * - * Paragraph. - * - * > World - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * > Hello - * - * Paragraph. - * - * > World - * - * Paragraph. - * - * > World - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 5:5: Remove 1 space between block quote and content - * 9:3: Add 1 space between block quote and content - */ - -const remarkLintBlockquoteIndentation = lintRule( - 'remark-lint:blockquote-indentation', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - visit$1(tree, 'blockquote', (node) => { - if (generated(node) || node.children.length === 0) { - return - } - - if (option === 'consistent') { - option = check(node); - } else { - const diff = option - check(node); - - if (diff !== 0) { - const abs = Math.abs(diff); - - file.message( - (diff > 0 ? 'Add' : 'Remove') + - ' ' + - abs + - ' ' + - plural('space', abs) + - ' between block quote and content', - pointStart(node.children[0]) - ); - } - } - }); - } -); - -var remarkLintBlockquoteIndentation$1 = remarkLintBlockquoteIndentation; - -/** - * @param {Blockquote} node - * @returns {number} - */ -function check(node) { - return pointStart(node.children[0]).column - pointStart(node).column -} - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module checkbox-character-style - * @fileoverview - * Warn when list item checkboxes violate a given style. - * - * Options: `Object` or `'consistent'`, default: `'consistent'`. - * - * `'consistent'` detects the first used checked and unchecked checkbox - * styles and warns when subsequent checkboxes use different styles. - * - * Styles can also be passed in like so: - * - * ```js - * {checked: 'x', unchecked: ' '} - * ``` - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * formats checked checkboxes using `x` (lowercase X) and unchecked checkboxes - * as `·` (a single space). - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md", "setting": {"checked": "x"}, "gfm": true} - * - * - [x] List item - * - [x] List item - * - * @example - * {"name": "ok.md", "setting": {"checked": "X"}, "gfm": true} - * - * - [X] List item - * - [X] List item - * - * @example - * {"name": "ok.md", "setting": {"unchecked": " "}, "gfm": true} - * - * - [ ] List item - * - [ ] List item - * - [ ]·· - * - [ ] - * - * @example - * {"name": "ok.md", "setting": {"unchecked": "\t"}, "gfm": true} - * - * - [»] List item - * - [»] List item - * - * @example - * {"name": "not-ok.md", "label": "input", "gfm": true} - * - * - [x] List item - * - [X] List item - * - [ ] List item - * - [»] List item - * - * @example - * {"name": "not-ok.md", "label": "output", "gfm": true} - * - * 2:5: Checked checkboxes should use `x` as a marker - * 4:5: Unchecked checkboxes should use ` ` as a marker - * - * @example - * {"setting": {"unchecked": "💩"}, "name": "not-ok.md", "label": "output", "positionless": true, "gfm": true} - * - * 1:1: Incorrect unchecked checkbox marker `💩`: use either `'\t'`, or `' '` - * - * @example - * {"setting": {"checked": "💩"}, "name": "not-ok.md", "label": "output", "positionless": true, "gfm": true} - * - * 1:1: Incorrect checked checkbox marker `💩`: use either `'x'`, or `'X'` - */ - -const remarkLintCheckboxCharacterStyle = lintRule( - 'remark-lint:checkbox-character-style', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - const value = String(file); - /** @type {'x'|'X'|'consistent'} */ - let checked = 'consistent'; - /** @type {' '|'\x09'|'consistent'} */ - let unchecked = 'consistent'; - - if (typeof option === 'object') { - checked = option.checked || 'consistent'; - unchecked = option.unchecked || 'consistent'; - } - - if (unchecked !== 'consistent' && unchecked !== ' ' && unchecked !== '\t') { - file.fail( - 'Incorrect unchecked checkbox marker `' + - unchecked + - "`: use either `'\\t'`, or `' '`" - ); - } - - if (checked !== 'consistent' && checked !== 'x' && checked !== 'X') { - file.fail( - 'Incorrect checked checkbox marker `' + - checked + - "`: use either `'x'`, or `'X'`" - ); - } - - visit$1(tree, 'listItem', (node) => { - const head = node.children[0]; - const point = pointStart(head); - - // Exit early for items without checkbox. - // A list item cannot be checked and empty, according to GFM. - if ( - typeof node.checked !== 'boolean' || - !head || - typeof point.offset !== 'number' - ) { - return - } - - // Move back to before `] `. - point.offset -= 2; - point.column -= 2; - - // Assume we start with a checkbox, because well, `checked` is set. - const match = /\[([\t Xx])]/.exec( - value.slice(point.offset - 2, point.offset + 1) - ); - - // Failsafe to make sure we don‘t crash if there actually isn’t a checkbox. - /* c8 ignore next */ - if (!match) return - - const style = node.checked ? checked : unchecked; - - if (style === 'consistent') { - if (node.checked) { - // @ts-expect-error: valid marker. - checked = match[1]; - } else { - // @ts-expect-error: valid marker. - unchecked = match[1]; - } - } else if (match[1] !== style) { - file.message( - (node.checked ? 'Checked' : 'Unchecked') + - ' checkboxes should use `' + - style + - '` as a marker', - point - ); - } - }); - } -); - -var remarkLintCheckboxCharacterStyle$1 = remarkLintCheckboxCharacterStyle; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module checkbox-content-indent - * @fileoverview - * Warn when list item checkboxes are followed by too much whitespace. - * - * @example - * {"name": "ok.md", "gfm": true} - * - * - [ ] List item - * + [x] List Item - * * [X] List item - * - [ ] List item - * - * @example - * {"name": "not-ok.md", "label": "input", "gfm": true} - * - * - [ ] List item - * + [x] List item - * * [X] List item - * - [ ] List item - * - * @example - * {"name": "not-ok.md", "label": "output", "gfm": true} - * - * 2:7-2:8: Checkboxes should be followed by a single character - * 3:7-3:9: Checkboxes should be followed by a single character - * 4:7-4:10: Checkboxes should be followed by a single character - */ - -const remarkLintCheckboxContentIndent = lintRule( - 'remark-lint:checkbox-content-indent', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - const value = String(file); - const loc = location(file); - - visit$1(tree, 'listItem', (node) => { - const head = node.children[0]; - const point = pointStart(head); - - // Exit early for items without checkbox. - // A list item cannot be checked and empty, according to GFM. - if ( - typeof node.checked !== 'boolean' || - !head || - typeof point.offset !== 'number' - ) { - return - } - - // Assume we start with a checkbox, because well, `checked` is set. - const match = /\[([\t xX])]/.exec( - value.slice(point.offset - 4, point.offset + 1) - ); - - // Failsafe to make sure we don‘t crash if there actually isn’t a checkbox. - /* c8 ignore next */ - if (!match) return - - // Move past checkbox. - const initial = point.offset; - let final = initial; - - while (/[\t ]/.test(value.charAt(final))) final++; - - if (final - initial > 0) { - file.message('Checkboxes should be followed by a single character', { - start: loc.toPoint(initial), - end: loc.toPoint(final) - }); - } - }); - } -); - -var remarkLintCheckboxContentIndent$1 = remarkLintCheckboxContentIndent; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module code-block-style - * @fileoverview - * Warn when code blocks do not adhere to a given style. - * - * Options: `'consistent'`, `'fenced'`, or `'indented'`, default: `'consistent'`. - * - * `'consistent'` detects the first used code block style and warns when - * subsequent code blocks uses different styles. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * formats code blocks using a fence if they have a language flag and - * indentation if not. - * Pass - * [`fences: true`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsfences) - * to always use fences for code blocks. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"setting": "indented", "name": "ok.md"} - * - * alpha() - * - * Paragraph. - * - * bravo() - * - * @example - * {"setting": "indented", "name": "not-ok.md", "label": "input"} - * - * ``` - * alpha() - * ``` - * - * Paragraph. - * - * ``` - * bravo() - * ``` - * - * @example - * {"setting": "indented", "name": "not-ok.md", "label": "output"} - * - * 1:1-3:4: Code blocks should be indented - * 7:1-9:4: Code blocks should be indented - * - * @example - * {"setting": "fenced", "name": "ok.md"} - * - * ``` - * alpha() - * ``` - * - * Paragraph. - * - * ``` - * bravo() - * ``` - * - * @example - * {"setting": "fenced", "name": "not-ok-fenced.md", "label": "input"} - * - * alpha() - * - * Paragraph. - * - * bravo() - * - * @example - * {"setting": "fenced", "name": "not-ok-fenced.md", "label": "output"} - * - * 1:1-1:12: Code blocks should be fenced - * 5:1-5:12: Code blocks should be fenced - * - * @example - * {"name": "not-ok-consistent.md", "label": "input"} - * - * alpha() - * - * Paragraph. - * - * ``` - * bravo() - * ``` - * - * @example - * {"name": "not-ok-consistent.md", "label": "output"} - * - * 5:1-7:4: Code blocks should be indented - * - * @example - * {"setting": "💩", "name": "not-ok-incorrect.md", "label": "output", "positionless": true} - * - * 1:1: Incorrect code block style `💩`: use either `'consistent'`, `'fenced'`, or `'indented'` - */ - -const remarkLintCodeBlockStyle = lintRule( - 'remark-lint:code-block-style', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - const value = String(file); - - if ( - option !== 'consistent' && - option !== 'fenced' && - option !== 'indented' - ) { - file.fail( - 'Incorrect code block style `' + - option + - "`: use either `'consistent'`, `'fenced'`, or `'indented'`" - ); - } - - visit$1(tree, 'code', (node) => { - if (generated(node)) { - return - } - - const initial = pointStart(node).offset; - const final = pointEnd(node).offset; - - const current = - node.lang || /^\s*([~`])\1{2,}/.test(value.slice(initial, final)) - ? 'fenced' - : 'indented'; - - if (option === 'consistent') { - option = current; - } else if (option !== current) { - file.message('Code blocks should be ' + option, node); - } - }); - } -); - -var remarkLintCodeBlockStyle$1 = remarkLintCodeBlockStyle; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module definition-spacing - * @fileoverview - * Warn when consecutive whitespace is used in a definition. - * - * @example - * {"name": "ok.md"} - * - * [example domain]: http://example.com "Example Domain" - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * [example····domain]: http://example.com "Example Domain" - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:1-1:57: Do not use consecutive whitespace in definition labels - */ - -const label = /^\s*\[((?:\\[\s\S]|[^[\]])+)]/; - -const remarkLintDefinitionSpacing = lintRule( - 'remark-lint:definition-spacing', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - const value = String(file); - - visit$1(tree, (node) => { - if (node.type === 'definition' || node.type === 'footnoteDefinition') { - const start = pointStart(node).offset; - const end = pointEnd(node).offset; - - if (typeof start === 'number' && typeof end === 'number') { - const match = value.slice(start, end).match(label); - - if (match && /[ \t\n]{2,}/.test(match[1])) { - file.message( - 'Do not use consecutive whitespace in definition labels', - node - ); - } - } - } - }); - } -); - -var remarkLintDefinitionSpacing$1 = remarkLintDefinitionSpacing; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module fenced-code-flag - * @fileoverview - * Check fenced code block flags. - * - * Options: `Array.` or `Object`, optional. - * - * Providing an array is as passing `{flags: Array}`. - * - * The object can have an array of `'flags'` which are allowed: other flags - * will not be allowed. - * An `allowEmpty` field (`boolean`, default: `false`) can be set to allow - * code blocks without language flags. - * - * @example - * {"name": "ok.md"} - * - * ```alpha - * bravo() - * ``` - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * ``` - * alpha() - * ``` - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:1-3:4: Missing code language flag - * - * @example - * {"name": "ok.md", "setting": {"allowEmpty": true}} - * - * ``` - * alpha() - * ``` - * - * @example - * {"name": "not-ok.md", "setting": {"allowEmpty": false}, "label": "input"} - * - * ``` - * alpha() - * ``` - * - * @example - * {"name": "not-ok.md", "setting": {"allowEmpty": false}, "label": "output"} - * - * 1:1-3:4: Missing code language flag - * - * @example - * {"name": "ok.md", "setting": ["alpha"]} - * - * ```alpha - * bravo() - * ``` - * - * @example - * {"name": "ok.md", "setting": {"flags":["alpha"]}} - * - * ```alpha - * bravo() - * ``` - * - * @example - * {"name": "not-ok.md", "setting": ["charlie"], "label": "input"} - * - * ```alpha - * bravo() - * ``` - * - * @example - * {"name": "not-ok.md", "setting": ["charlie"], "label": "output"} - * - * 1:1-3:4: Incorrect code language flag - */ - -const fence = /^ {0,3}([~`])\1{2,}/; - -const remarkLintFencedCodeFlag = lintRule( - 'remark-lint:fenced-code-flag', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option) => { - const value = String(file); - let allowEmpty = false; - /** @type {string[]} */ - let allowed = []; - - if (typeof option === 'object') { - if (Array.isArray(option)) { - allowed = option; - } else { - allowEmpty = Boolean(option.allowEmpty); - - if (option.flags) { - allowed = option.flags; - } - } - } - - visit$1(tree, 'code', (node) => { - if (!generated(node)) { - if (node.lang) { - if (allowed.length > 0 && !allowed.includes(node.lang)) { - file.message('Incorrect code language flag', node); - } - } else { - const slice = value.slice( - pointStart(node).offset, - pointEnd(node).offset - ); - - if (!allowEmpty && fence.test(slice)) { - file.message('Missing code language flag', node); - } - } - } - }); - } -); - -var remarkLintFencedCodeFlag$1 = remarkLintFencedCodeFlag; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module fenced-code-marker - * @fileoverview - * Warn for violating fenced code markers. - * - * Options: `` '`' ``, `'~'`, or `'consistent'`, default: `'consistent'`. - * - * `'consistent'` detects the first used fenced code marker style and warns - * when subsequent fenced code blocks use different styles. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * formats fences using ``'`'`` (grave accent) by default. - * Pass - * [`fence: '~'`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsfence) - * to use `~` (tilde) instead. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * Indented code blocks are not affected by this rule: - * - * bravo() - * - * @example - * {"name": "ok.md", "setting": "`"} - * - * ```alpha - * bravo() - * ``` - * - * ``` - * charlie() - * ``` - * - * @example - * {"name": "ok.md", "setting": "~"} - * - * ~~~alpha - * bravo() - * ~~~ - * - * ~~~ - * charlie() - * ~~~ - * - * @example - * {"name": "not-ok-consistent-tick.md", "label": "input"} - * - * ```alpha - * bravo() - * ``` - * - * ~~~ - * charlie() - * ~~~ - * - * @example - * {"name": "not-ok-consistent-tick.md", "label": "output"} - * - * 5:1-7:4: Fenced code should use `` ` `` as a marker - * - * @example - * {"name": "not-ok-consistent-tilde.md", "label": "input"} - * - * ~~~alpha - * bravo() - * ~~~ - * - * ``` - * charlie() - * ``` - * - * @example - * {"name": "not-ok-consistent-tilde.md", "label": "output"} - * - * 5:1-7:4: Fenced code should use `~` as a marker - * - * @example - * {"name": "not-ok-incorrect.md", "setting": "💩", "label": "output", "positionless": true} - * - * 1:1: Incorrect fenced code marker `💩`: use either `'consistent'`, `` '`' ``, or `'~'` - */ - -const remarkLintFencedCodeMarker = lintRule( - 'remark-lint:fenced-code-marker', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - const contents = String(file); - - if (option !== 'consistent' && option !== '~' && option !== '`') { - file.fail( - 'Incorrect fenced code marker `' + - option + - "`: use either `'consistent'`, `` '`' ``, or `'~'`" - ); - } - - visit$1(tree, 'code', (node) => { - const start = pointStart(node).offset; - - if (typeof start === 'number') { - const marker = contents - .slice(start, start + 4) - .replace(/^\s+/, '') - .charAt(0); - - // Ignore unfenced code blocks. - if (marker === '~' || marker === '`') { - if (option === 'consistent') { - option = marker; - } else if (marker !== option) { - file.message( - 'Fenced code should use `' + - (option === '~' ? option : '` ` `') + - '` as a marker', - node - ); - } - } - } - }); - } -); - -var remarkLintFencedCodeMarker$1 = remarkLintFencedCodeMarker; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module file-extension - * @fileoverview - * Warn when the file extension differ from the preferred extension. - * - * Does not warn when given documents have no file extensions (such as - * `AUTHORS` or `LICENSE`). - * - * Options: `string`, default: `'md'` — Expected file extension. - * - * @example - * {"name": "readme.md"} - * - * @example - * {"name": "readme"} - * - * @example - * {"name": "readme.mkd", "label": "output", "positionless": true} - * - * 1:1: Incorrect extension: use `md` - * - * @example - * {"name": "readme.mkd", "setting": "mkd"} - */ - -const remarkLintFileExtension = lintRule( - 'remark-lint:file-extension', - /** @type {import('unified-lint-rule').Rule} */ - (_, file, option = 'md') => { - const ext = file.extname; - - if (ext && ext.slice(1) !== option) { - file.message('Incorrect extension: use `' + option + '`'); - } - } -); - -var remarkLintFileExtension$1 = remarkLintFileExtension; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module final-definition - * @fileoverview - * Warn when definitions are placed somewhere other than at the end of - * the file. - * - * @example - * {"name": "ok.md"} - * - * Paragraph. - * - * [example]: http://example.com "Example Domain" - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * Paragraph. - * - * [example]: http://example.com "Example Domain" - * - * Another paragraph. - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 3:1-3:47: Move definitions to the end of the file (after the node at line `5`) - * - * @example - * {"name": "ok-comments.md"} - * - * Paragraph. - * - * [example-1]: http://example.com/one/ - * - * - * - * [example-2]: http://example.com/two/ - */ - -const remarkLintFinalDefinition = lintRule( - 'remark-lint:final-definition', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - let last = 0; - - visit$1( - tree, - (node) => { - // Ignore generated and HTML comment nodes. - if ( - node.type === 'root' || - generated(node) || - (node.type === 'html' && /^\s*".length)); - - validateMeta(node, file, meta); - } catch (e) { - file.message(e, node); - } - }); -} - -const remarkLintNodejsYamlComments = lintRule( - "remark-lint:nodejs-yaml-comments", - validateYAMLComments -); - -function escapeStringRegexp(string) { - if (typeof string !== 'string') { - throw new TypeError('Expected a string'); - } - - // Escape characters with special meaning either inside or outside character sets. - // Use a simple backslash escape when it’s always valid, and a `\xnn` escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar. - return string - .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') - .replace(/-/g, '\\x2d'); -} - -const remarkLintProhibitedStrings = lintRule('remark-lint:prohibited-strings', prohibitedStrings); - -function testProhibited (val, content) { - let regexpFlags = 'g'; - let no = val.no; - - if (!no) { - no = escapeStringRegexp(val.yes); - regexpFlags += 'i'; - } - - let regexpString = '(? { - const results = testProhibited(val, content); - if (results.length) { - results.forEach(({ result, index, yes }) => { - const message = val.yes ? `Use "${yes}" instead of "${result}"` : `Do not use "${result}"`; - file.message(message, { - start: myLocation.toPoint(initial + index), - end: myLocation.toPoint(initial + index + [...result].length) - }); - }); - } - }); - } -} - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module rule-style - * @fileoverview - * Warn when the thematic breaks (horizontal rules) violate a given or - * detected style. - * - * Options: `string`, either a corect thematic breaks such as `***`, or - * `'consistent'`, default: `'consistent'`. - * - * `'consistent'` detects the first used thematic break style and warns when - * subsequent rules use different styles. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * has three settings that define how rules are created: - * - * * [`rule`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrule) - * (default: `*`) — Marker to use - * * [`ruleRepetition`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrulerepetition) - * (default: `3`) — Number of markers to use - * * [`ruleSpaces`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrulespaces) - * (default: `true`) — Whether to pad markers with spaces - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md", "setting": "* * *"} - * - * * * * - * - * * * * - * - * @example - * {"name": "ok.md", "setting": "_______"} - * - * _______ - * - * _______ - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * *** - * - * * * * - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 3:1-3:6: Rules should use `***` - * - * @example - * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} - * - * 1:1: Incorrect preferred rule style: provide a correct markdown rule or `'consistent'` - */ - -const remarkLintRuleStyle = lintRule( - 'remark-lint:rule-style', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - const value = String(file); - - if (option !== 'consistent' && /[^-_* ]/.test(option)) { - file.fail( - "Incorrect preferred rule style: provide a correct markdown rule or `'consistent'`" - ); - } - - visit$1(tree, 'thematicBreak', (node) => { - const initial = pointStart(node).offset; - const final = pointEnd(node).offset; - - if (typeof initial === 'number' && typeof final === 'number') { - const rule = value.slice(initial, final); - - if (option === 'consistent') { - option = rule; - } else if (rule !== option) { - file.message('Rules should use `' + option + '`', node); - } - } - }); - } -); - -var remarkLintRuleStyle$1 = remarkLintRuleStyle; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module strong-marker - * @fileoverview - * Warn for violating importance (strong) markers. - * - * Options: `'consistent'`, `'*'`, or `'_'`, default: `'consistent'`. - * - * `'consistent'` detects the first used importance style and warns when - * subsequent importance sequences use different styles. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * formats importance using an `*` (asterisk) by default. - * Pass - * [`strong: '_'`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsstrong) - * to use `_` (underscore) instead. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * **foo** and **bar**. - * - * @example - * {"name": "also-ok.md"} - * - * __foo__ and __bar__. - * - * @example - * {"name": "ok.md", "setting": "*"} - * - * **foo**. - * - * @example - * {"name": "ok.md", "setting": "_"} - * - * __foo__. - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * **foo** and __bar__. - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:13-1:20: Strong should use `*` as a marker - * - * @example - * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} - * - * 1:1: Incorrect strong marker `💩`: use either `'consistent'`, `'*'`, or `'_'` - */ - -const remarkLintStrongMarker = lintRule( - 'remark-lint:strong-marker', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - const value = String(file); - - if (option !== '*' && option !== '_' && option !== 'consistent') { - file.fail( - 'Incorrect strong marker `' + - option + - "`: use either `'consistent'`, `'*'`, or `'_'`" - ); - } - - visit$1(tree, 'strong', (node) => { - const start = pointStart(node).offset; - - if (typeof start === 'number') { - const marker = /** @type {Marker} */ (value.charAt(start)); - - if (option === 'consistent') { - option = marker; - } else if (marker !== option) { - file.message('Strong should use `' + option + '` as a marker', node); - } - } - }); - } -); - -var remarkLintStrongMarker$1 = remarkLintStrongMarker; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module table-cell-padding - * @fileoverview - * Warn when table cells are incorrectly padded. - * - * Options: `'consistent'`, `'padded'`, or `'compact'`, default: `'consistent'`. - * - * `'consistent'` detects the first used cell padding style and warns when - * subsequent cells use different styles. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * formats tables with padding by default. - * Pass - * [`spacedTable: false`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsspacedtable) - * to not use padding. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md", "setting": "padded", "gfm": true} - * - * | A | B | - * | ----- | ----- | - * | Alpha | Bravo | - * - * @example - * {"name": "not-ok.md", "label": "input", "setting": "padded", "gfm": true} - * - * | A | B | - * | :----|----: | - * | Alpha|Bravo | - * - * | C | D | - * | :----- | ---: | - * |Charlie | Delta| - * - * Too much padding isn’t good either: - * - * | E | F | G | H | - * | :---- | -------- | :----: | -----: | - * | Echo | Foxtrot | Golf | Hotel | - * - * @example - * {"name": "not-ok.md", "label": "output", "setting": "padded", "gfm": true} - * - * 3:8: Cell should be padded - * 3:9: Cell should be padded - * 7:2: Cell should be padded - * 7:17: Cell should be padded - * 13:9: Cell should be padded with 1 space, not 2 - * 13:20: Cell should be padded with 1 space, not 2 - * 13:21: Cell should be padded with 1 space, not 2 - * 13:29: Cell should be padded with 1 space, not 2 - * 13:30: Cell should be padded with 1 space, not 2 - * - * @example - * {"name": "ok.md", "setting": "compact", "gfm": true} - * - * |A |B | - * |-----|-----| - * |Alpha|Bravo| - * - * @example - * {"name": "not-ok.md", "label": "input", "setting": "compact", "gfm": true} - * - * | A | B | - * | -----| -----| - * | Alpha| Bravo| - * - * |C | D| - * |:------|-----:| - * |Charlie|Delta | - * - * @example - * {"name": "not-ok.md", "label": "output", "setting": "compact", "gfm": true} - * - * 3:2: Cell should be compact - * 3:11: Cell should be compact - * 7:16: Cell should be compact - * - * @example - * {"name": "ok-padded.md", "setting": "consistent", "gfm": true} - * - * | A | B | - * | ----- | ----- | - * | Alpha | Bravo | - * - * | C | D | - * | ------- | ----- | - * | Charlie | Delta | - * - * @example - * {"name": "not-ok-padded.md", "label": "input", "setting": "consistent", "gfm": true} - * - * | A | B | - * | ----- | ----- | - * | Alpha | Bravo | - * - * | C | D | - * | :----- | ----: | - * |Charlie | Delta | - * - * @example - * {"name": "not-ok-padded.md", "label": "output", "setting": "consistent", "gfm": true} - * - * 7:2: Cell should be padded - * - * @example - * {"name": "ok-compact.md", "setting": "consistent", "gfm": true} - * - * |A |B | - * |-----|-----| - * |Alpha|Bravo| - * - * |C |D | - * |-------|-----| - * |Charlie|Delta| - * - * @example - * {"name": "not-ok-compact.md", "label": "input", "setting": "consistent", "gfm": true} - * - * |A |B | - * |-----|-----| - * |Alpha|Bravo| - * - * |C | D| - * |:------|-----:| - * |Charlie|Delta | - * - * @example - * {"name": "not-ok-compact.md", "label": "output", "setting": "consistent", "gfm": true} - * - * 7:16: Cell should be compact - * - * @example - * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true, "gfm": true} - * - * 1:1: Incorrect table cell padding style `💩`, expected `'padded'`, `'compact'`, or `'consistent'` - * - * @example - * {"name": "empty.md", "label": "input", "setting": "padded", "gfm": true} - * - * - * - * | | Alpha | Bravo| - * | ------ | ----- | ---: | - * | Charlie| | Echo| - * - * @example - * {"name": "empty.md", "label": "output", "setting": "padded", "gfm": true} - * - * 3:25: Cell should be padded - * 5:10: Cell should be padded - * 5:25: Cell should be padded - * - * @example - * {"name": "missing-body.md", "setting": "padded", "gfm": true} - * - * - * - * | Alpha | Bravo | Charlie | - * | ----- | ------- | ------- | - * | Delta | - * | Echo | Foxtrot | - */ - -const remarkLintTableCellPadding = lintRule( - 'remark-lint:table-cell-padding', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - if ( - option !== 'padded' && - option !== 'compact' && - option !== 'consistent' - ) { - file.fail( - 'Incorrect table cell padding style `' + - option + - "`, expected `'padded'`, `'compact'`, or `'consistent'`" - ); - } - - visit$1(tree, 'table', (node) => { - const rows = node.children; - // To do: fix types to always have `align` defined. - /* c8 ignore next */ - const align = node.align || []; - /** @type {number[]} */ - const sizes = Array.from({length: align.length}); - /** @type {Entry[]} */ - const entries = []; - let index = -1; - - // Check rows. - while (++index < rows.length) { - const row = rows[index]; - let column = -1; - - // Check fences (before, between, and after cells). - while (++column < row.children.length) { - const cell = row.children[column]; - - if (cell.children.length > 0) { - const cellStart = pointStart(cell).offset; - const cellEnd = pointEnd(cell).offset; - const contentStart = pointStart(cell.children[0]).offset; - const contentEnd = pointEnd( - cell.children[cell.children.length - 1] - ).offset; - - if ( - typeof cellStart !== 'number' || - typeof cellEnd !== 'number' || - typeof contentStart !== 'number' || - typeof contentEnd !== 'number' - ) { - continue - } - - entries.push({ - node: cell, - start: contentStart - cellStart - (column ? 0 : 1), - end: cellEnd - contentEnd - 1, - column - }); - - // Detect max space per column. - sizes[column] = Math.max( - sizes[column] || 0, - contentEnd - contentStart - ); - } - } - } - - const style = - option === 'consistent' - ? entries[0] && (!entries[0].start || !entries[0].end) - ? 0 - : 1 - : option === 'padded' - ? 1 - : 0; - - index = -1; - - while (++index < entries.length) { - checkSide('start', entries[index], style, sizes); - checkSide('end', entries[index], style, sizes); - } - - return SKIP$1 - }); - - /** - * @param {'start'|'end'} side - * @param {Entry} entry - * @param {0|1} style - * @param {number[]} sizes - */ - function checkSide(side, entry, style, sizes) { - const cell = entry.node; - const column = entry.column; - const spacing = entry[side]; - - if (spacing === undefined || spacing === style) { - return - } - - let reason = 'Cell should be '; - - if (style === 0) { - // Ignore every cell except the biggest in the column. - if (size(cell) < sizes[column]) { - return - } - - reason += 'compact'; - } else { - reason += 'padded'; - - if (spacing > style) { - // May be right or center aligned. - if (size(cell) < sizes[column]) { - return - } - - reason += ' with 1 space, not ' + spacing; - } - } - - /** @type {Point} */ - let point; - - if (side === 'start') { - point = pointStart(cell); - if (!column) { - point.column++; - - if (typeof point.offset === 'number') { - point.offset++; - } - } - } else { - point = pointEnd(cell); - point.column--; - - if (typeof point.offset === 'number') { - point.offset--; - } - } - - file.message(reason, point); - } - } -); - -var remarkLintTableCellPadding$1 = remarkLintTableCellPadding; - -/** - * @param {TableCell} node - * @returns {number} - */ -function size(node) { - const head = pointStart(node.children[0]).offset; - const tail = pointEnd(node.children[node.children.length - 1]).offset; - // Only called when we’re sure offsets exist. - /* c8 ignore next */ - return typeof head === 'number' && typeof tail === 'number' ? tail - head : 0 -} - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module table-pipes - * @fileoverview - * Warn when table rows are not fenced with pipes. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * creates fenced rows with initial and final pipes by default. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md", "gfm": true} - * - * | A | B | - * | ----- | ----- | - * | Alpha | Bravo | - * - * @example - * {"name": "not-ok.md", "label": "input", "gfm": true} - * - * A | B - * ----- | ----- - * Alpha | Bravo - * - * @example - * {"name": "not-ok.md", "label": "output", "gfm": true} - * - * 1:1: Missing initial pipe in table fence - * 1:10: Missing final pipe in table fence - * 3:1: Missing initial pipe in table fence - * 3:14: Missing final pipe in table fence - */ - -const reasonStart = 'Missing initial pipe in table fence'; -const reasonEnd = 'Missing final pipe in table fence'; - -const remarkLintTablePipes = lintRule( - 'remark-lint:table-pipes', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - const value = String(file); - - visit$1(tree, 'table', (node) => { - let index = -1; - - while (++index < node.children.length) { - const row = node.children[index]; - const start = pointStart(row); - const end = pointEnd(row); - - if ( - typeof start.offset === 'number' && - value.charCodeAt(start.offset) !== 124 - ) { - file.message(reasonStart, start); - } - - if ( - typeof end.offset === 'number' && - value.charCodeAt(end.offset - 1) !== 124 - ) { - file.message(reasonEnd, end); - } - } - }); - } -); - -var remarkLintTablePipes$1 = remarkLintTablePipes; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module unordered-list-marker-style - * @fileoverview - * Warn when the list item marker style of unordered lists violate a given - * style. - * - * Options: `'consistent'`, `'-'`, `'*'`, or `'+'`, default: `'consistent'`. - * - * `'consistent'` detects the first used list style and warns when subsequent - * lists use different styles. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * formats unordered lists using `-` (hyphen-minus) by default. - * Pass - * [`bullet: '*'` or `bullet: '+'`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsbullet) - * to use `*` (asterisk) or `+` (plus sign) instead. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * By default (`'consistent'`), if the file uses only one marker, - * that’s OK. - * - * * Foo - * * Bar - * * Baz - * - * Ordered lists are not affected. - * - * 1. Foo - * 2. Bar - * 3. Baz - * - * @example - * {"name": "ok.md", "setting": "*"} - * - * * Foo - * - * @example - * {"name": "ok.md", "setting": "-"} - * - * - Foo - * - * @example - * {"name": "ok.md", "setting": "+"} - * - * + Foo - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * * Foo - * - Bar - * + Baz - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 2:1-2:6: Marker style should be `*` - * 3:1-3:6: Marker style should be `*` - * - * @example - * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} - * - * 1:1: Incorrect unordered list item marker style `💩`: use either `'-'`, `'*'`, or `'+'` - */ - -const markers = new Set(['-', '*', '+']); - -const remarkLintUnorderedListMarkerStyle = lintRule( - 'remark-lint:unordered-list-marker-style', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - const value = String(file); - - if (option !== 'consistent' && !markers.has(option)) { - file.fail( - 'Incorrect unordered list item marker style `' + - option + - "`: use either `'-'`, `'*'`, or `'+'`" - ); - } - - visit$1(tree, 'list', (node) => { - if (node.ordered) return - - let index = -1; - - while (++index < node.children.length) { - const child = node.children[index]; - - if (!generated(child)) { - const marker = /** @type {Marker} */ ( - value - .slice( - pointStart(child).offset, - pointStart(child.children[0]).offset - ) - .replace(/\[[x ]?]\s*$/i, '') - .replace(/\s/g, '') - ); - - if (option === 'consistent') { - option = marker; - } else if (marker !== option) { - file.message('Marker style should be `' + option + '`', child); - } - } - } - }); - } -); - -var remarkLintUnorderedListMarkerStyle$1 = remarkLintUnorderedListMarkerStyle; - -// @see https://github.com/nodejs/node/blob/HEAD/doc/guides/doc-style-guide.md - -// Add in rules alphabetically -const plugins = [ - // Leave preset at the top so it can be overridden - remarkPresetLintRecommended$1, - [remarkLintBlockquoteIndentation$1, 2], - [remarkLintCheckboxCharacterStyle$1, { checked: "x", unchecked: " " }], - remarkLintCheckboxContentIndent$1, - [remarkLintCodeBlockStyle$1, "fenced"], - remarkLintDefinitionSpacing$1, - [ - remarkLintFencedCodeFlag$1, - { - flags: [ - "bash", - "c", - "cjs", - "coffee", - "console", - "cpp", - "diff", - "http", - "js", - "json", - "markdown", - "mjs", - "powershell", - "r", - "text", - ], - }, - ], - [remarkLintFencedCodeMarker$1, "`"], - [remarkLintFileExtension$1, "md"], - remarkLintFinalDefinition$1, - [remarkLintFirstHeadingLevel$1, 1], - [remarkLintHeadingStyle$1, "atx"], - [remarkLintListItemIndent$1, "space"], - remarkLintMaximumLineLength$1, - remarkLintNoConsecutiveBlankLines$1, - remarkLintNoFileNameArticles$1, - remarkLintNoFileNameConsecutiveDashes$1, - remarkLintNofileNameOuterDashes$1, - remarkLintNoHeadingIndent$1, - remarkLintNoMultipleToplevelHeadings$1, - remarkLintNoShellDollars$1, - remarkLintNoTableIndentation$1, - remarkLintNoTabs$1, - remarkLintNoTrailingSpaces, - remarkLintNodejsLinks, - remarkLintNodejsYamlComments, - [ - remarkLintProhibitedStrings, - [ - { yes: "End-of-Life" }, - { yes: "GitHub" }, - { no: "hostname", yes: "host name" }, - { yes: "JavaScript" }, - { no: "[Ll]ong[ -][Tt]erm [Ss]upport", yes: "Long Term Support" }, - { no: "Node", yes: "Node.js", ignoreNextTo: "-API" }, - { yes: "Node.js" }, - { no: "Node[Jj][Ss]", yes: "Node.js" }, - { no: "Node\\.js's?", yes: "the Node.js" }, - { no: "[Nn]ote that", yes: "" }, - { yes: "RFC" }, - { no: "[Rr][Ff][Cc]\\d+", yes: "RFC " }, - { yes: "Unix" }, - { yes: "V8" }, - ], - ], - remarkLintRuleStyle$1, - [remarkLintStrongMarker$1, "*"], - [remarkLintTableCellPadding$1, "padded"], - remarkLintTablePipes$1, - [remarkLintUnorderedListMarkerStyle$1, "*"], -]; - -const remarkPresetLintNode = { plugins }; - -/** - * @typedef {import('micromark-util-types').Extension} Extension - * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Previous} Previous - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Event} Event - * @typedef {import('micromark-util-types').Code} Code - */ -const www = { - tokenize: tokenizeWww, - partial: true -}; -const domain = { - tokenize: tokenizeDomain, - partial: true -}; -const path = { - tokenize: tokenizePath, - partial: true -}; -const punctuation = { - tokenize: tokenizePunctuation, - partial: true -}; -const namedCharacterReference = { - tokenize: tokenizeNamedCharacterReference, - partial: true -}; -const wwwAutolink = { - tokenize: tokenizeWwwAutolink, - previous: previousWww -}; -const httpAutolink = { - tokenize: tokenizeHttpAutolink, - previous: previousHttp -}; -const emailAutolink = { - tokenize: tokenizeEmailAutolink, - previous: previousEmail -}; -/** @type {ConstructRecord} */ - -const text = {}; -/** @type {Extension} */ - -const gfmAutolinkLiteral = { - text -}; -let code = 48; // Add alphanumerics. - -while (code < 123) { - text[code] = emailAutolink; - code++; - if (code === 58) code = 65; - else if (code === 91) code = 97; -} - -text[43] = emailAutolink; -text[45] = emailAutolink; -text[46] = emailAutolink; -text[95] = emailAutolink; -text[72] = [emailAutolink, httpAutolink]; -text[104] = [emailAutolink, httpAutolink]; -text[87] = [emailAutolink, wwwAutolink]; -text[119] = [emailAutolink, wwwAutolink]; -/** @type {Tokenizer} */ - -function tokenizeEmailAutolink(effects, ok, nok) { - const self = this; - /** @type {boolean} */ - - let hasDot; - /** @type {boolean|undefined} */ - - let hasDigitInLastSegment; - return start - /** @type {State} */ - - function start(code) { - if ( - !gfmAtext(code) || - !previousEmail(self.previous) || - previousUnbalanced(self.events) - ) { - return nok(code) - } - - effects.enter('literalAutolink'); - effects.enter('literalAutolinkEmail'); - return atext(code) - } - /** @type {State} */ - - function atext(code) { - if (gfmAtext(code)) { - effects.consume(code); - return atext - } - - if (code === 64) { - effects.consume(code); - return label - } - - return nok(code) - } - /** @type {State} */ - - function label(code) { - if (code === 46) { - return effects.check(punctuation, done, dotContinuation)(code) - } - - if (code === 45 || code === 95) { - return effects.check(punctuation, nok, dashOrUnderscoreContinuation)(code) - } - - if (asciiAlphanumeric(code)) { - if (!hasDigitInLastSegment && asciiDigit(code)) { - hasDigitInLastSegment = true; - } - - effects.consume(code); - return label - } - - return done(code) - } - /** @type {State} */ - - function dotContinuation(code) { - effects.consume(code); - hasDot = true; - hasDigitInLastSegment = undefined; - return label - } - /** @type {State} */ - - function dashOrUnderscoreContinuation(code) { - effects.consume(code); - return afterDashOrUnderscore - } - /** @type {State} */ - - function afterDashOrUnderscore(code) { - if (code === 46) { - return effects.check(punctuation, nok, dotContinuation)(code) - } - - return label(code) - } - /** @type {State} */ - - function done(code) { - if (hasDot && !hasDigitInLastSegment) { - effects.exit('literalAutolinkEmail'); - effects.exit('literalAutolink'); - return ok(code) - } - - return nok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeWwwAutolink(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - if ( - (code !== 87 && code !== 119) || - !previousWww(self.previous) || - previousUnbalanced(self.events) - ) { - return nok(code) - } - - effects.enter('literalAutolink'); - effects.enter('literalAutolinkWww'); // For `www.` we check instead of attempt, because when it matches, GH - // treats it as part of a domain (yes, it says a valid domain must come - // after `www.`, but that’s not how it’s implemented by them). - - return effects.check( - www, - effects.attempt(domain, effects.attempt(path, done), nok), - nok - )(code) - } - /** @type {State} */ - - function done(code) { - effects.exit('literalAutolinkWww'); - effects.exit('literalAutolink'); - return ok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeHttpAutolink(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - if ( - (code !== 72 && code !== 104) || - !previousHttp(self.previous) || - previousUnbalanced(self.events) - ) { - return nok(code) - } - - effects.enter('literalAutolink'); - effects.enter('literalAutolinkHttp'); - effects.consume(code); - return t1 - } - /** @type {State} */ - - function t1(code) { - if (code === 84 || code === 116) { - effects.consume(code); - return t2 - } - - return nok(code) - } - /** @type {State} */ - - function t2(code) { - if (code === 84 || code === 116) { - effects.consume(code); - return p - } - - return nok(code) - } - /** @type {State} */ - - function p(code) { - if (code === 80 || code === 112) { - effects.consume(code); - return s - } - - return nok(code) - } - /** @type {State} */ - - function s(code) { - if (code === 83 || code === 115) { - effects.consume(code); - return colon - } - - return colon(code) - } - /** @type {State} */ - - function colon(code) { - if (code === 58) { - effects.consume(code); - return slash1 - } - - return nok(code) - } - /** @type {State} */ - - function slash1(code) { - if (code === 47) { - effects.consume(code); - return slash2 - } - - return nok(code) - } - /** @type {State} */ - - function slash2(code) { - if (code === 47) { - effects.consume(code); - return after - } - - return nok(code) - } - /** @type {State} */ - - function after(code) { - return code === null || - asciiControl(code) || - unicodeWhitespace(code) || - unicodePunctuation(code) - ? nok(code) - : effects.attempt(domain, effects.attempt(path, done), nok)(code) - } - /** @type {State} */ - - function done(code) { - effects.exit('literalAutolinkHttp'); - effects.exit('literalAutolink'); - return ok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeWww(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.consume(code); - return w2 - } - /** @type {State} */ - - function w2(code) { - if (code === 87 || code === 119) { - effects.consume(code); - return w3 - } - - return nok(code) - } - /** @type {State} */ - - function w3(code) { - if (code === 87 || code === 119) { - effects.consume(code); - return dot - } - - return nok(code) - } - /** @type {State} */ - - function dot(code) { - if (code === 46) { - effects.consume(code); - return after - } - - return nok(code) - } - /** @type {State} */ - - function after(code) { - return code === null || markdownLineEnding(code) ? nok(code) : ok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeDomain(effects, ok, nok) { - /** @type {boolean|undefined} */ - let hasUnderscoreInLastSegment; - /** @type {boolean|undefined} */ - - let hasUnderscoreInLastLastSegment; - return domain - /** @type {State} */ - - function domain(code) { - if (code === 38) { - return effects.check( - namedCharacterReference, - done, - punctuationContinuation - )(code) - } - - if (code === 46 || code === 95) { - return effects.check(punctuation, done, punctuationContinuation)(code) - } // GH documents that only alphanumerics (other than `-`, `.`, and `_`) can - // occur, which sounds like ASCII only, but they also support `www.點看.com`, - // so that’s Unicode. - // Instead of some new production for Unicode alphanumerics, markdown - // already has that for Unicode punctuation and whitespace, so use those. - - if ( - code === null || - asciiControl(code) || - unicodeWhitespace(code) || - (code !== 45 && unicodePunctuation(code)) - ) { - return done(code) - } - - effects.consume(code); - return domain - } - /** @type {State} */ - - function punctuationContinuation(code) { - if (code === 46) { - hasUnderscoreInLastLastSegment = hasUnderscoreInLastSegment; - hasUnderscoreInLastSegment = undefined; - effects.consume(code); - return domain - } - - if (code === 95) hasUnderscoreInLastSegment = true; - effects.consume(code); - return domain - } - /** @type {State} */ - - function done(code) { - if (!hasUnderscoreInLastLastSegment && !hasUnderscoreInLastSegment) { - return ok(code) - } - - return nok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizePath(effects, ok) { - let balance = 0; - return inPath - /** @type {State} */ - - function inPath(code) { - if (code === 38) { - return effects.check( - namedCharacterReference, - ok, - continuedPunctuation - )(code) - } - - if (code === 40) { - balance++; - } - - if (code === 41) { - return effects.check( - punctuation, - parenAtPathEnd, - continuedPunctuation - )(code) - } - - if (pathEnd(code)) { - return ok(code) - } - - if (trailingPunctuation(code)) { - return effects.check(punctuation, ok, continuedPunctuation)(code) - } - - effects.consume(code); - return inPath - } - /** @type {State} */ - - function continuedPunctuation(code) { - effects.consume(code); - return inPath - } - /** @type {State} */ - - function parenAtPathEnd(code) { - balance--; - return balance < 0 ? ok(code) : continuedPunctuation(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeNamedCharacterReference(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.consume(code); - return inside - } - /** @type {State} */ - - function inside(code) { - if (asciiAlpha(code)) { - effects.consume(code); - return inside - } - - if (code === 59) { - effects.consume(code); - return after - } - - return nok(code) - } - /** @type {State} */ - - function after(code) { - // If the named character reference is followed by the end of the path, it’s - // not continued punctuation. - return pathEnd(code) ? ok(code) : nok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizePunctuation(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.consume(code); - return after - } - /** @type {State} */ - - function after(code) { - // Check the next. - if (trailingPunctuation(code)) { - effects.consume(code); - return after - } // If the punctuation marker is followed by the end of the path, it’s not - // continued punctuation. - - return pathEnd(code) ? ok(code) : nok(code) - } -} -/** - * @param {Code} code - * @returns {boolean} - */ - -function trailingPunctuation(code) { - return ( - code === 33 || - code === 34 || - code === 39 || - code === 41 || - code === 42 || - code === 44 || - code === 46 || - code === 58 || - code === 59 || - code === 60 || - code === 63 || - code === 95 || - code === 126 - ) -} -/** - * @param {Code} code - * @returns {boolean} - */ - -function pathEnd(code) { - return code === null || code === 60 || markdownLineEndingOrSpace(code) -} -/** - * @param {Code} code - * @returns {boolean} - */ - -function gfmAtext(code) { - return ( - code === 43 || - code === 45 || - code === 46 || - code === 95 || - asciiAlphanumeric(code) - ) -} -/** @type {Previous} */ - -function previousWww(code) { - return ( - code === null || - code === 40 || - code === 42 || - code === 95 || - code === 126 || - markdownLineEndingOrSpace(code) - ) -} -/** @type {Previous} */ - -function previousHttp(code) { - return code === null || !asciiAlpha(code) -} -/** @type {Previous} */ - -function previousEmail(code) { - return code !== 47 && previousHttp(code) -} -/** - * @param {Event[]} events - * @returns {boolean} - */ - -function previousUnbalanced(events) { - let index = events.length; - let result = false; - - while (index--) { - const token = events[index][1]; - - if ( - (token.type === 'labelLink' || token.type === 'labelImage') && - !token._balanced - ) { - result = true; - break - } // @ts-expect-error If we’ve seen this token, and it was marked as not - // having any unbalanced bracket before it, we can exit. - - if (token._gfmAutolinkLiteralWalkedInto) { - result = false; - break - } - } - - if (events.length > 0 && !result) { - // @ts-expect-error Mark the last token as “walked into” w/o finding - // anything. - events[events.length - 1][1]._gfmAutolinkLiteralWalkedInto = true; - } - - return result -} - -const characterReferences = {'"': 'quot', '&': 'amp', '<': 'lt', '>': 'gt'}; - -/** - * Encode only the dangerous HTML characters. - * - * This ensures that certain characters which have special meaning in HTML are - * dealt with. - * Technically, we can skip `>` and `"` in many cases, but CM includes them. - * - * @param {string} value - * @returns {string} - */ -function encode(value) { - return value.replace(/["&<>]/g, replace) - - /** - * @param {string} value - * @returns {string} - */ - function replace(value) { - // @ts-expect-error Hush, it’s fine. - return '&' + characterReferences[value] + ';' - } -} - -/** - * Make a value safe for injection as a URL. - * - * This encodes unsafe characters with percent-encoding and skips already - * encoded sequences (see `normalizeUri` below). - * Further unsafe characters are encoded as character references (see - * `micromark-util-encode`). - * - * Then, a regex of allowed protocols can be given, in which case the URL is - * sanitized. - * For example, `/^(https?|ircs?|mailto|xmpp)$/i` can be used for `a[href]`, - * or `/^https?$/i` for `img[src]`. - * If the URL includes an unknown protocol (one not matched by `protocol`, such - * as a dangerous example, `javascript:`), the value is ignored. - * - * @param {string|undefined} url - * @param {RegExp} [protocol] - * @returns {string} - */ -function sanitizeUri(url, protocol) { - const value = encode(normalizeUri(url || '')); - - if (!protocol) { - return value - } - - const colon = value.indexOf(':'); - const questionMark = value.indexOf('?'); - const numberSign = value.indexOf('#'); - const slash = value.indexOf('/'); - - if ( - // If there is no protocol, it’s relative. - colon < 0 || // If the first colon is after a `?`, `#`, or `/`, it’s not a protocol. - (slash > -1 && colon > slash) || - (questionMark > -1 && colon > questionMark) || - (numberSign > -1 && colon > numberSign) || // It is a protocol, it should be allowed. - protocol.test(value.slice(0, colon)) - ) { - return value - } - - return '' -} -/** - * Normalize a URL (such as used in definitions). - * - * Encode unsafe characters with percent-encoding, skipping already encoded - * sequences. - * - * @param {string} value - * @returns {string} - */ - -function normalizeUri(value) { - /** @type {string[]} */ - const result = []; - let index = -1; - let start = 0; - let skip = 0; - - while (++index < value.length) { - const code = value.charCodeAt(index); - /** @type {string} */ - - let replace = ''; // A correct percent encoded value. - - if ( - code === 37 && - asciiAlphanumeric(value.charCodeAt(index + 1)) && - asciiAlphanumeric(value.charCodeAt(index + 2)) - ) { - skip = 2; - } // ASCII. - else if (code < 128) { - if (!/[!#$&-;=?-Z_a-z~]/.test(String.fromCharCode(code))) { - replace = String.fromCharCode(code); - } - } // Astral. - else if (code > 55295 && code < 57344) { - const next = value.charCodeAt(index + 1); // A correct surrogate pair. - - if (code < 56320 && next > 56319 && next < 57344) { - replace = String.fromCharCode(code, next); - skip = 1; - } // Lone surrogate. - else { - replace = '\uFFFD'; - } - } // Unicode. - else { - replace = String.fromCharCode(code); - } - - if (replace) { - result.push(value.slice(start, index), encodeURIComponent(replace)); - start = index + skip + 1; - replace = ''; - } - - if (skip) { - index += skip; - skip = 0; - } - } - - return result.join('') + value.slice(start) -} - -/** - * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension - * @typedef {import('micromark-util-types').Handle} Handle - * @typedef {import('micromark-util-types').CompileContext} CompileContext - * @typedef {import('micromark-util-types').Token} Token - */ -/** @type {HtmlExtension} */ - -const gfmAutolinkLiteralHtml = { - exit: { - literalAutolinkEmail, - literalAutolinkHttp, - literalAutolinkWww - } -}; -/** @type {Handle} */ - -function literalAutolinkWww(token) { - anchorFromToken.call(this, token, 'http://'); -} -/** @type {Handle} */ - -function literalAutolinkEmail(token) { - anchorFromToken.call(this, token, 'mailto:'); -} -/** @type {Handle} */ - -function literalAutolinkHttp(token) { - anchorFromToken.call(this, token); -} -/** - * @this CompileContext - * @param {Token} token - * @param {string} [protocol] - * @returns {void} - */ - -function anchorFromToken(token, protocol) { - const url = this.sliceSerialize(token); - this.tag(''); - this.raw(this.encode(url)); - this.tag(''); -} - -/** - * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension - */ - -/** @type {HtmlExtension} */ -const gfmStrikethroughHtml = { - enter: { - strikethrough() { - this.tag(''); - } - }, - exit: { - strikethrough() { - this.tag(''); - } - } -}; - -/** - * @typedef {import('micromark-util-types').Extension} Extension - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').Event} Event - */ - -/** - * @param {Options} [options] - * @returns {Extension} - */ -function gfmStrikethrough(options = {}) { - let single = options.singleTilde; - const tokenizer = { - tokenize: tokenizeStrikethrough, - resolveAll: resolveAllStrikethrough - }; - - if (single === null || single === undefined) { - single = true; - } - - return { - text: { - [126]: tokenizer - }, - insideSpan: { - null: [tokenizer] - }, - attentionMarkers: { - null: [126] - } - } - /** - * Take events and resolve strikethrough. - * - * @type {Resolver} - */ - - function resolveAllStrikethrough(events, context) { - let index = -1; - /** @type {Token} */ - - let strikethrough; - /** @type {Token} */ - - let text; - /** @type {number} */ - - let open; - /** @type {Event[]} */ - - let nextEvents; // Walk through all events. - - while (++index < events.length) { - // Find a token that can close. - if ( - events[index][0] === 'enter' && - events[index][1].type === 'strikethroughSequenceTemporary' && - events[index][1]._close - ) { - open = index; // Now walk back to find an opener. - - while (open--) { - // Find a token that can open the closer. - if ( - events[open][0] === 'exit' && - events[open][1].type === 'strikethroughSequenceTemporary' && - events[open][1]._open && // If the sizes are the same: - events[index][1].end.offset - events[index][1].start.offset === - events[open][1].end.offset - events[open][1].start.offset - ) { - events[index][1].type = 'strikethroughSequence'; - events[open][1].type = 'strikethroughSequence'; - strikethrough = { - type: 'strikethrough', - start: Object.assign({}, events[open][1].start), - end: Object.assign({}, events[index][1].end) - }; - text = { - type: 'strikethroughText', - start: Object.assign({}, events[open][1].end), - end: Object.assign({}, events[index][1].start) - }; // Opening. - - nextEvents = [ - ['enter', strikethrough, context], - ['enter', events[open][1], context], - ['exit', events[open][1], context], - ['enter', text, context] - ]; // Between. - - splice( - nextEvents, - nextEvents.length, - 0, - resolveAll( - context.parser.constructs.insideSpan.null, - events.slice(open + 1, index), - context - ) - ); // Closing. - - splice(nextEvents, nextEvents.length, 0, [ - ['exit', text, context], - ['enter', events[index][1], context], - ['exit', events[index][1], context], - ['exit', strikethrough, context] - ]); - splice(events, open - 1, index - open + 3, nextEvents); - index = open + nextEvents.length - 2; - break - } - } - } - } - - index = -1; - - while (++index < events.length) { - if (events[index][1].type === 'strikethroughSequenceTemporary') { - events[index][1].type = 'data'; - } - } - - return events - } - /** @type {Tokenizer} */ - - function tokenizeStrikethrough(effects, ok, nok) { - const previous = this.previous; - const events = this.events; - let size = 0; - return start - /** @type {State} */ - - function start(code) { - if ( - code !== 126 || - (previous === 126 && - events[events.length - 1][1].type !== 'characterEscape') - ) { - return nok(code) - } - - effects.enter('strikethroughSequenceTemporary'); - return more(code) - } - /** @type {State} */ - - function more(code) { - const before = classifyCharacter(previous); - - if (code === 126) { - // If this is the third marker, exit. - if (size > 1) return nok(code) - effects.consume(code); - size++; - return more - } - - if (size < 2 && !single) return nok(code) - const token = effects.exit('strikethroughSequenceTemporary'); - const after = classifyCharacter(code); - token._open = !after || (after === 2 && Boolean(before)); - token._close = !before || (before === 2 && Boolean(after)); - return ok(code) - } - } -} - -/** - * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension - */ - -/** - * @typedef {import('./syntax.js').Align} Align - */ -const alignment = { - null: '', - left: ' align="left"', - right: ' align="right"', - center: ' align="center"' -}; -/** @type {HtmlExtension} */ - -const gfmTableHtml = { - enter: { - table(token) { - this.lineEndingIfNeeded(); - this.tag(''); // @ts-expect-error Custom. - - this.setData('tableAlign', token._align); - }, - - tableBody() { - // Clear slurping line ending from the delimiter row. - this.setData('slurpOneLineEnding'); - this.tag(''); - }, - - tableData() { - /** @type {string|undefined} */ - const align = // @ts-expect-error Custom. - alignment[this.getData('tableAlign')[this.getData('tableColumn')]]; - - if (align === undefined) { - // Capture results to ignore them. - this.buffer(); - } else { - this.lineEndingIfNeeded(); - this.tag(''); - } - }, - - tableHead() { - this.lineEndingIfNeeded(); - this.tag(''); - }, - - tableHeader() { - this.lineEndingIfNeeded(); - this.tag( - '' - ); - }, - - tableRow() { - this.setData('tableColumn', 0); - this.lineEndingIfNeeded(); - this.tag(''); - } - }, - exit: { - // Overwrite the default code text data handler to unescape escaped pipes when - // they are in tables. - codeTextData(token) { - let value = this.sliceSerialize(token); - - if (this.getData('tableAlign')) { - value = value.replace(/\\([\\|])/g, replace$1); - } - - this.raw(this.encode(value)); - }, - - table() { - this.setData('tableAlign'); // If there was no table body, make sure the slurping from the delimiter row - // is cleared. - - this.setData('slurpAllLineEndings'); - this.lineEndingIfNeeded(); - this.tag('
'); - }, - - tableBody() { - this.lineEndingIfNeeded(); - this.tag(''); - }, - - tableData() { - /** @type {number} */ - // @ts-expect-error Custom. - const column = this.getData('tableColumn'); // @ts-expect-error Custom. - - if (column in this.getData('tableAlign')) { - this.tag(''); - this.setData('tableColumn', column + 1); - } else { - // Stop capturing. - this.resume(); - } - }, - - tableHead() { - this.lineEndingIfNeeded(); - this.tag(''); - this.setData('slurpOneLineEnding', true); // Slurp the line ending from the delimiter row. - }, - - tableHeader() { - this.tag(''); // @ts-expect-error Custom. - - this.setData('tableColumn', this.getData('tableColumn') + 1); - }, - - tableRow() { - /** @type {Align[]} */ - // @ts-expect-error Custom. - const align = this.getData('tableAlign'); - /** @type {number} */ - // @ts-expect-error Custom. - - let column = this.getData('tableColumn'); - - while (column < align.length) { - this.lineEndingIfNeeded(); // @ts-expect-error `null` is fine as an index. - - this.tag(''); - column++; - } - - this.setData('tableColumn', column); - this.lineEndingIfNeeded(); - this.tag(''); - } - } -}; -/** - * @param {string} $0 - * @param {string} $1 - * @returns {string} - */ - -function replace$1($0, $1) { - // Pipes work, backslashes don’t (but can’t escape pipes). - return $1 === '|' ? $1 : $0 -} - -/** - * @typedef {import('micromark-util-types').Extension} Extension - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Token} Token - */ - -/** @type {Extension} */ -const gfmTable = { - flow: { - null: { - tokenize: tokenizeTable, - resolve: resolveTable - } - } -}; -const setextUnderlineMini = { - tokenize: tokenizeSetextUnderlineMini, - partial: true -}; -const nextPrefixedOrBlank = { - tokenize: tokenizeNextPrefixedOrBlank, - partial: true -}; -/** @type {Resolver} */ - -function resolveTable(events, context) { - let index = -1; - /** @type {Token} */ - - let token; - /** @type {boolean|undefined} */ - - let inHead; - /** @type {boolean|undefined} */ - - let inDelimiterRow; - /** @type {boolean|undefined} */ - - let inRow; - /** @type {Token} */ - - let cell; - /** @type {Token} */ - - let content; - /** @type {Token} */ - - let text; - /** @type {number|undefined} */ - - let contentStart; - /** @type {number|undefined} */ - - let contentEnd; - /** @type {number|undefined} */ - - let cellStart; - - while (++index < events.length) { - token = events[index][1]; - - if (inRow) { - if (token.type === 'temporaryTableCellContent') { - contentStart = contentStart || index; - contentEnd = index; - } - - if ( - // Combine separate content parts into one. - (token.type === 'tableCellDivider' || token.type === 'tableRow') && - contentEnd - ) { - content = { - type: 'tableContent', - // @ts-expect-error `contentStart` is defined if `contentEnd` is too. - start: events[contentStart][1].start, - end: events[contentEnd][1].end - }; - text = { - type: 'chunkText', - start: content.start, - end: content.end, - // @ts-expect-error It’s fine. - contentType: 'text' - }; - events.splice( - // @ts-expect-error `contentStart` is defined if `contentEnd` is too. - contentStart, // @ts-expect-error `contentStart` is defined if `contentEnd` is too. - contentEnd - contentStart + 1, - ['enter', content, context], - ['enter', text, context], - ['exit', text, context], - ['exit', content, context] - ); // @ts-expect-error `contentStart` is defined if `contentEnd` is too. - - index -= contentEnd - contentStart - 3; - contentStart = undefined; - contentEnd = undefined; - } - } - - if ( - events[index][0] === 'exit' && - cellStart && - cellStart + 1 < index && - (token.type === 'tableCellDivider' || - (token.type === 'tableRow' && - (cellStart + 3 < index || - events[cellStart][1].type !== 'whitespace'))) - ) { - cell = { - type: inDelimiterRow - ? 'tableDelimiter' - : inHead - ? 'tableHeader' - : 'tableData', - start: events[cellStart][1].start, - end: events[index][1].end - }; - events.splice(index + (token.type === 'tableCellDivider' ? 1 : 0), 0, [ - 'exit', - cell, - context - ]); - events.splice(cellStart, 0, ['enter', cell, context]); - index += 2; - cellStart = index + 1; - } - - if (token.type === 'tableRow') { - inRow = events[index][0] === 'enter'; - - if (inRow) { - cellStart = index + 1; - } - } - - if (token.type === 'tableDelimiterRow') { - inDelimiterRow = events[index][0] === 'enter'; - - if (inDelimiterRow) { - cellStart = index + 1; - } - } - - if (token.type === 'tableHead') { - inHead = events[index][0] === 'enter'; - } - } - - return events -} -/** @type {Tokenizer} */ - -function tokenizeTable(effects, ok, nok) { - const self = this; - /** @type {Align[]} */ - - const align = []; - let tableHeaderCount = 0; - /** @type {boolean|undefined} */ - - let seenDelimiter; - /** @type {boolean|undefined} */ - - let hasDash; - return start - /** @type {State} */ - - function start(code) { - // @ts-expect-error Custom. - effects.enter('table')._align = align; - effects.enter('tableHead'); - effects.enter('tableRow'); // If we start with a pipe, we open a cell marker. - - if (code === 124) { - return cellDividerHead(code) - } - - tableHeaderCount++; - effects.enter('temporaryTableCellContent'); // Can’t be space or eols at the start of a construct, so we’re in a cell. - - return inCellContentHead(code) - } - /** @type {State} */ - - function cellDividerHead(code) { - effects.enter('tableCellDivider'); - effects.consume(code); - effects.exit('tableCellDivider'); - seenDelimiter = true; - return cellBreakHead - } - /** @type {State} */ - - function cellBreakHead(code) { - if (code === null || markdownLineEnding(code)) { - return atRowEndHead(code) - } - - if (markdownSpace(code)) { - effects.enter('whitespace'); - effects.consume(code); - return inWhitespaceHead - } - - if (seenDelimiter) { - seenDelimiter = undefined; - tableHeaderCount++; - } - - if (code === 124) { - return cellDividerHead(code) - } // Anything else is cell content. - - effects.enter('temporaryTableCellContent'); - return inCellContentHead(code) - } - /** @type {State} */ - - function inWhitespaceHead(code) { - if (markdownSpace(code)) { - effects.consume(code); - return inWhitespaceHead - } - - effects.exit('whitespace'); - return cellBreakHead(code) - } - /** @type {State} */ - - function inCellContentHead(code) { - // EOF, whitespace, pipe - if (code === null || code === 124 || markdownLineEndingOrSpace(code)) { - effects.exit('temporaryTableCellContent'); - return cellBreakHead(code) - } - - effects.consume(code); - return code === 92 ? inCellContentEscapeHead : inCellContentHead - } - /** @type {State} */ - - function inCellContentEscapeHead(code) { - if (code === 92 || code === 124) { - effects.consume(code); - return inCellContentHead - } // Anything else. - - return inCellContentHead(code) - } - /** @type {State} */ - - function atRowEndHead(code) { - if (code === null) { - return nok(code) - } - - effects.exit('tableRow'); - effects.exit('tableHead'); - return effects.attempt( - { - tokenize: tokenizeRowEnd, - partial: true - }, - atDelimiterLineStart, - nok - )(code) - } - /** @type {State} */ - - function atDelimiterLineStart(code) { - // To do: is the lazy setext thing still needed? - return effects.check( - setextUnderlineMini, - nok, // Support an indent before the delimiter row. - factorySpace(effects, rowStartDelimiter, 'linePrefix', 4) - )(code) - } - /** @type {State} */ - - function rowStartDelimiter(code) { - // If there’s another space, or we’re at the EOL/EOF, exit. - if (code === null || markdownLineEndingOrSpace(code)) { - return nok(code) - } - - effects.enter('tableDelimiterRow'); - return atDelimiterRowBreak(code) - } - /** @type {State} */ - - function atDelimiterRowBreak(code) { - if (code === null || markdownLineEnding(code)) { - return rowEndDelimiter(code) - } - - if (markdownSpace(code)) { - effects.enter('whitespace'); - effects.consume(code); - return inWhitespaceDelimiter - } - - if (code === 45) { - effects.enter('tableDelimiterFiller'); - effects.consume(code); - hasDash = true; - align.push(null); - return inFillerDelimiter - } - - if (code === 58) { - effects.enter('tableDelimiterAlignment'); - effects.consume(code); - effects.exit('tableDelimiterAlignment'); - align.push('left'); - return afterLeftAlignment - } // If we start with a pipe, we open a cell marker. - - if (code === 124) { - effects.enter('tableCellDivider'); - effects.consume(code); - effects.exit('tableCellDivider'); - return atDelimiterRowBreak - } - - return nok(code) - } - /** @type {State} */ - - function inWhitespaceDelimiter(code) { - if (markdownSpace(code)) { - effects.consume(code); - return inWhitespaceDelimiter - } - - effects.exit('whitespace'); - return atDelimiterRowBreak(code) - } - /** @type {State} */ - - function inFillerDelimiter(code) { - if (code === 45) { - effects.consume(code); - return inFillerDelimiter - } - - effects.exit('tableDelimiterFiller'); - - if (code === 58) { - effects.enter('tableDelimiterAlignment'); - effects.consume(code); - effects.exit('tableDelimiterAlignment'); - align[align.length - 1] = - align[align.length - 1] === 'left' ? 'center' : 'right'; - return afterRightAlignment - } - - return atDelimiterRowBreak(code) - } - /** @type {State} */ - - function afterLeftAlignment(code) { - if (code === 45) { - effects.enter('tableDelimiterFiller'); - effects.consume(code); - hasDash = true; - return inFillerDelimiter - } // Anything else is not ok. - - return nok(code) - } - /** @type {State} */ - - function afterRightAlignment(code) { - if (code === null || markdownLineEnding(code)) { - return rowEndDelimiter(code) - } - - if (markdownSpace(code)) { - effects.enter('whitespace'); - effects.consume(code); - return inWhitespaceDelimiter - } // `|` - - if (code === 124) { - effects.enter('tableCellDivider'); - effects.consume(code); - effects.exit('tableCellDivider'); - return atDelimiterRowBreak - } - - return nok(code) - } - /** @type {State} */ - - function rowEndDelimiter(code) { - effects.exit('tableDelimiterRow'); // Exit if there was no dash at all, or if the header cell count is not the - // delimiter cell count. - - if (!hasDash || tableHeaderCount !== align.length) { - return nok(code) - } - - if (code === null) { - return tableClose(code) - } - - return effects.check( - nextPrefixedOrBlank, - tableClose, - effects.attempt( - { - tokenize: tokenizeRowEnd, - partial: true - }, - factorySpace(effects, bodyStart, 'linePrefix', 4), - tableClose - ) - )(code) - } - /** @type {State} */ - - function tableClose(code) { - effects.exit('table'); - return ok(code) - } - /** @type {State} */ - - function bodyStart(code) { - effects.enter('tableBody'); - return rowStartBody(code) - } - /** @type {State} */ - - function rowStartBody(code) { - effects.enter('tableRow'); // If we start with a pipe, we open a cell marker. - - if (code === 124) { - return cellDividerBody(code) - } - - effects.enter('temporaryTableCellContent'); // Can’t be space or eols at the start of a construct, so we’re in a cell. - - return inCellContentBody(code) - } - /** @type {State} */ - - function cellDividerBody(code) { - effects.enter('tableCellDivider'); - effects.consume(code); - effects.exit('tableCellDivider'); - return cellBreakBody - } - /** @type {State} */ - - function cellBreakBody(code) { - if (code === null || markdownLineEnding(code)) { - return atRowEndBody(code) - } - - if (markdownSpace(code)) { - effects.enter('whitespace'); - effects.consume(code); - return inWhitespaceBody - } // `|` - - if (code === 124) { - return cellDividerBody(code) - } // Anything else is cell content. - - effects.enter('temporaryTableCellContent'); - return inCellContentBody(code) - } - /** @type {State} */ - - function inWhitespaceBody(code) { - if (markdownSpace(code)) { - effects.consume(code); - return inWhitespaceBody - } - - effects.exit('whitespace'); - return cellBreakBody(code) - } - /** @type {State} */ - - function inCellContentBody(code) { - // EOF, whitespace, pipe - if (code === null || code === 124 || markdownLineEndingOrSpace(code)) { - effects.exit('temporaryTableCellContent'); - return cellBreakBody(code) - } - - effects.consume(code); - return code === 92 ? inCellContentEscapeBody : inCellContentBody - } - /** @type {State} */ - - function inCellContentEscapeBody(code) { - if (code === 92 || code === 124) { - effects.consume(code); - return inCellContentBody - } // Anything else. - - return inCellContentBody(code) - } - /** @type {State} */ - - function atRowEndBody(code) { - effects.exit('tableRow'); - - if (code === null) { - return tableBodyClose(code) - } - - return effects.check( - nextPrefixedOrBlank, - tableBodyClose, - effects.attempt( - { - tokenize: tokenizeRowEnd, - partial: true - }, - factorySpace(effects, rowStartBody, 'linePrefix', 4), - tableBodyClose - ) - )(code) - } - /** @type {State} */ - - function tableBodyClose(code) { - effects.exit('tableBody'); - return tableClose(code) - } - /** @type {Tokenizer} */ - - function tokenizeRowEnd(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return lineStart - } - /** @type {State} */ - - function lineStart(code) { - return self.parser.lazy[self.now().line] ? nok(code) : ok(code) - } - } -} // Based on micromark, but that won’t work as we’re in a table, and that expects -// content. -// - -/** @type {Tokenizer} */ - -function tokenizeSetextUnderlineMini(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - if (code !== 45) { - return nok(code) - } - - effects.enter('setextUnderline'); - return sequence(code) - } - /** @type {State} */ - - function sequence(code) { - if (code === 45) { - effects.consume(code); - return sequence - } - - return whitespace(code) - } - /** @type {State} */ - - function whitespace(code) { - if (code === null || markdownLineEnding(code)) { - return ok(code) - } - - if (markdownSpace(code)) { - effects.consume(code); - return whitespace - } - - return nok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeNextPrefixedOrBlank(effects, ok, nok) { - let size = 0; - return start - /** @type {State} */ - - function start(code) { - // This is a check, so we don’t care about tokens, but we open a bogus one - // so we’re valid. - effects.enter('check'); // EOL. - - effects.consume(code); - return whitespace - } - /** @type {State} */ - - function whitespace(code) { - if (code === -1 || code === 32) { - effects.consume(code); - size++; - return size === 4 ? ok : whitespace - } // EOF or whitespace - - if (code === null || markdownLineEndingOrSpace(code)) { - return ok(code) - } // Anything else. - - return nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').CompileContext} CompileContext - */ - -/** - * An opening or closing tag, followed by a case-insensitive specific tag name, - * followed by HTML whitespace, a greater than, or a slash. - */ -const reFlow = - /<(\/?)(iframe|noembed|noframes|plaintext|script|style|title|textarea|xmp)(?=[\t\n\f\r />])/gi; - -/** - * As HTML (text) parses tags separately (and v. strictly), we don’t need to be - * global. - */ -const reText = new RegExp('^' + reFlow.source, 'i'); - -/** @type {HtmlExtension} */ -const gfmTagfilterHtml = { - exit: { - htmlFlowData(token) { - exitHtmlData.call(this, token, reFlow); - }, - htmlTextData(token) { - exitHtmlData.call(this, token, reText); - } - } -}; - -/** - * @this {CompileContext} - * @param {Token} token - * @param {RegExp} filter - */ -function exitHtmlData(token, filter) { - let value = this.sliceSerialize(token); - - if (this.options.allowDangerousHtml) { - value = value.replace(filter, '<$1$2'); - } - - this.raw(this.encode(value)); -} - -/** - * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension - */ - -/** @type {HtmlExtension} */ -const gfmTaskListItemHtml = { - enter: { - taskListCheck() { - this.tag(''); - }, - - taskListCheckValueChecked() { - this.tag('checked="" '); - } - } -}; - -/** - * @typedef {import('micromark-util-types').Extension} Extension - * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Previous} Previous - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Event} Event - * @typedef {import('micromark-util-types').Code} Code - */ -const tasklistCheck = { - tokenize: tokenizeTasklistCheck -}; -const gfmTaskListItem = { - text: { - [91]: tasklistCheck - } -}; -/** @type {Tokenizer} */ - -function tokenizeTasklistCheck(effects, ok, nok) { - const self = this; - return open - /** @type {State} */ - - function open(code) { - if ( - // Exit if there’s stuff before. - self.previous !== null || // Exit if not in the first content that is the first child of a list - // item. - !self._gfmTasklistFirstContentOfListItem - ) { - return nok(code) - } - - effects.enter('taskListCheck'); - effects.enter('taskListCheckMarker'); - effects.consume(code); - effects.exit('taskListCheckMarker'); - return inside - } - /** @type {State} */ - - function inside(code) { - if (markdownSpace(code)) { - effects.enter('taskListCheckValueUnchecked'); - effects.consume(code); - effects.exit('taskListCheckValueUnchecked'); - return close - } - - if (code === 88 || code === 120) { - effects.enter('taskListCheckValueChecked'); - effects.consume(code); - effects.exit('taskListCheckValueChecked'); - return close - } - - return nok(code) - } - /** @type {State} */ - - function close(code) { - if (code === 93) { - effects.enter('taskListCheckMarker'); - effects.consume(code); - effects.exit('taskListCheckMarker'); - effects.exit('taskListCheck'); - return effects.check( - { - tokenize: spaceThenNonSpace - }, - ok, - nok - ) - } - - return nok(code) - } -} -/** @type {Tokenizer} */ - -function spaceThenNonSpace(effects, ok, nok) { - const self = this; - return factorySpace(effects, after, 'whitespace') - /** @type {State} */ - - function after(code) { - const tail = self.events[self.events.length - 1]; - return tail && - tail[1].type === 'whitespace' && - code !== null && - !markdownLineEndingOrSpace(code) - ? ok(code) - : nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Extension} Extension - * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension - * @typedef {import('micromark-extension-gfm-strikethrough').Options} Options - */ - -/** - * Support GFM or markdown on github.com. - * - * @param {Options} [options] - * @returns {Extension} - */ -function gfm(options) { - return combineExtensions([ - gfmAutolinkLiteral, - gfmStrikethrough(options), - gfmTable, - gfmTaskListItem - ]) -} - -/** @type {HtmlExtension} */ -combineHtmlExtensions([ - gfmAutolinkLiteralHtml, - gfmStrikethroughHtml, - gfmTableHtml, - gfmTagfilterHtml, - gfmTaskListItemHtml -]); - -/** - * Get the total count of `character` in `value`. - * - * @param {any} value Content, coerced to string - * @param {string} character Single character to look for - * @return {number} Number of times `character` occurred in `value`. - */ -function ccount(value, character) { - var source = String(value); - var count = 0; - var index; - - if (typeof character !== 'string') { - throw new Error('Expected character') - } - - index = source.indexOf(character); - - while (index !== -1) { - count++; - index = source.indexOf(character, index + character.length); - } - - return count -} - -/** - * @typedef Options Configuration. - * @property {Test} [ignore] `unist-util-is` test used to assert parents - * - * @typedef {import('mdast').Root} Root - * @typedef {import('mdast').Content} Content - * @typedef {import('mdast').PhrasingContent} PhrasingContent - * @typedef {import('mdast').Text} Text - * @typedef {Content|Root} Node - * @typedef {Extract} Parent - * - * @typedef {import('unist-util-visit-parents').Test} Test - * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult - * - * @typedef RegExpMatchObject - * @property {number} index - * @property {string} input - * - * @typedef {string|RegExp} Find - * @typedef {string|ReplaceFunction} Replace - * - * @typedef {[Find, Replace]} FindAndReplaceTuple - * @typedef {Object.} FindAndReplaceSchema - * @typedef {Array.} FindAndReplaceList - * - * @typedef {[RegExp, ReplaceFunction]} Pair - * @typedef {Array.} Pairs - */ - -const own = {}.hasOwnProperty; - -/** - * @param tree mdast tree - * @param find Value to find and remove. When `string`, escaped and made into a global `RegExp` - * @param [replace] Value to insert. - * * When `string`, turned into a Text node. - * * When `Function`, called with the results of calling `RegExp.exec` as - * arguments, in which case it can return a single or a list of `Node`, - * a `string` (which is wrapped in a `Text` node), or `false` to not replace - * @param [options] Configuration. - */ -const findAndReplace = - /** - * @type {( - * ((tree: Node, find: Find, replace?: Replace, options?: Options) => Node) & - * ((tree: Node, schema: FindAndReplaceSchema|FindAndReplaceList, options?: Options) => Node) - * )} - **/ - ( - /** - * @param {Node} tree - * @param {Find|FindAndReplaceSchema|FindAndReplaceList} find - * @param {Replace|Options} [replace] - * @param {Options} [options] - */ - function (tree, find, replace, options) { - /** @type {Options|undefined} */ - let settings; - /** @type {FindAndReplaceSchema|FindAndReplaceList} */ - let schema; - - if (typeof find === 'string' || find instanceof RegExp) { - // @ts-expect-error don’t expect options twice. - schema = [[find, replace]]; - settings = options; - } else { - schema = find; - // @ts-expect-error don’t expect replace twice. - settings = replace; - } - - if (!settings) { - settings = {}; - } - - const ignored = convert(settings.ignore || []); - const pairs = toPairs(schema); - let pairIndex = -1; - - while (++pairIndex < pairs.length) { - visitParents(tree, 'text', visitor); - } - - return tree - - /** @type {import('unist-util-visit-parents').Visitor} */ - function visitor(node, parents) { - let index = -1; - /** @type {Parent|undefined} */ - let grandparent; - - while (++index < parents.length) { - const parent = /** @type {Parent} */ (parents[index]); - - if ( - ignored( - parent, - // @ts-expect-error mdast vs. unist parent. - grandparent ? grandparent.children.indexOf(parent) : undefined, - grandparent - ) - ) { - return - } - - grandparent = parent; - } - - if (grandparent) { - return handler(node, grandparent) - } - } - - /** - * @param {Text} node - * @param {Parent} parent - * @returns {VisitorResult} - */ - function handler(node, parent) { - const find = pairs[pairIndex][0]; - const replace = pairs[pairIndex][1]; - let start = 0; - // @ts-expect-error: TS is wrong, some of these children can be text. - let index = parent.children.indexOf(node); - /** @type {Array.} */ - let nodes = []; - /** @type {number|undefined} */ - let position; - - find.lastIndex = 0; - - let match = find.exec(node.value); - - while (match) { - position = match.index; - // @ts-expect-error this is perfectly fine, typescript. - let value = replace(...match, { - index: match.index, - input: match.input - }); - - if (typeof value === 'string') { - value = value.length > 0 ? {type: 'text', value} : undefined; - } - - if (value !== false) { - if (start !== position) { - nodes.push({ - type: 'text', - value: node.value.slice(start, position) - }); - } - - if (Array.isArray(value)) { - nodes.push(...value); - } else if (value) { - nodes.push(value); - } - - start = position + match[0].length; - } - - if (!find.global) { - break - } - - match = find.exec(node.value); - } - - if (position === undefined) { - nodes = [node]; - index--; - } else { - if (start < node.value.length) { - nodes.push({type: 'text', value: node.value.slice(start)}); - } - - parent.children.splice(index, 1, ...nodes); - } - - return index + nodes.length + 1 - } - } - ); - -/** - * @param {FindAndReplaceSchema|FindAndReplaceList} schema - * @returns {Pairs} - */ -function toPairs(schema) { - /** @type {Pairs} */ - const result = []; - - if (typeof schema !== 'object') { - throw new TypeError('Expected array or object as schema') - } - - if (Array.isArray(schema)) { - let index = -1; - - while (++index < schema.length) { - result.push([ - toExpression(schema[index][0]), - toFunction(schema[index][1]) - ]); - } - } else { - /** @type {string} */ - let key; - - for (key in schema) { - if (own.call(schema, key)) { - result.push([toExpression(key), toFunction(schema[key])]); - } - } - } - - return result -} - -/** - * @param {Find} find - * @returns {RegExp} - */ -function toExpression(find) { - return typeof find === 'string' ? new RegExp(escapeStringRegexp(find), 'g') : find -} - -/** - * @param {Replace} replace - * @returns {ReplaceFunction} - */ -function toFunction(replace) { - return typeof replace === 'function' ? replace : () => replace -} - -/** - * @typedef {import('mdast').Link} Link - * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension - * @typedef {import('mdast-util-from-markdown').Transform} FromMarkdownTransform - * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle - * @typedef {import('mdast-util-to-markdown/lib/types.js').Options} ToMarkdownExtension - * @typedef {import('mdast-util-find-and-replace').ReplaceFunction} ReplaceFunction - * @typedef {import('mdast-util-find-and-replace').RegExpMatchObject} RegExpMatchObject - * @typedef {import('mdast-util-find-and-replace').PhrasingContent} PhrasingContent - */ - -const inConstruct = 'phrasing'; -const notInConstruct = ['autolink', 'link', 'image', 'label']; - -/** @type {FromMarkdownExtension} */ -const gfmAutolinkLiteralFromMarkdown = { - transforms: [transformGfmAutolinkLiterals], - enter: { - literalAutolink: enterLiteralAutolink, - literalAutolinkEmail: enterLiteralAutolinkValue, - literalAutolinkHttp: enterLiteralAutolinkValue, - literalAutolinkWww: enterLiteralAutolinkValue - }, - exit: { - literalAutolink: exitLiteralAutolink, - literalAutolinkEmail: exitLiteralAutolinkEmail, - literalAutolinkHttp: exitLiteralAutolinkHttp, - literalAutolinkWww: exitLiteralAutolinkWww - } -}; - -/** @type {ToMarkdownExtension} */ -const gfmAutolinkLiteralToMarkdown = { - unsafe: [ - { - character: '@', - before: '[+\\-.\\w]', - after: '[\\-.\\w]', - inConstruct, - notInConstruct - }, - { - character: '.', - before: '[Ww]', - after: '[\\-.\\w]', - inConstruct, - notInConstruct - }, - {character: ':', before: '[ps]', after: '\\/', inConstruct, notInConstruct} - ] -}; - -/** @type {FromMarkdownHandle} */ -function enterLiteralAutolink(token) { - this.enter({type: 'link', title: null, url: '', children: []}, token); -} - -/** @type {FromMarkdownHandle} */ -function enterLiteralAutolinkValue(token) { - this.config.enter.autolinkProtocol.call(this, token); -} - -/** @type {FromMarkdownHandle} */ -function exitLiteralAutolinkHttp(token) { - this.config.exit.autolinkProtocol.call(this, token); -} - -/** @type {FromMarkdownHandle} */ -function exitLiteralAutolinkWww(token) { - this.config.exit.data.call(this, token); - const node = /** @type {Link} */ (this.stack[this.stack.length - 1]); - node.url = 'http://' + this.sliceSerialize(token); -} - -/** @type {FromMarkdownHandle} */ -function exitLiteralAutolinkEmail(token) { - this.config.exit.autolinkEmail.call(this, token); -} - -/** @type {FromMarkdownHandle} */ -function exitLiteralAutolink(token) { - this.exit(token); -} - -/** @type {FromMarkdownTransform} */ -function transformGfmAutolinkLiterals(tree) { - findAndReplace( - tree, - [ - [/(https?:\/\/|www(?=\.))([-.\w]+)([^ \t\r\n]*)/gi, findUrl], - [/([-.\w+]+)@([-\w]+(?:\.[-\w]+)+)/g, findEmail] - ], - {ignore: ['link', 'linkReference']} - ); -} - -/** - * @type {ReplaceFunction} - * @param {string} _ - * @param {string} protocol - * @param {string} domain - * @param {string} path - * @param {RegExpMatchObject} match - */ -// eslint-disable-next-line max-params -function findUrl(_, protocol, domain, path, match) { - let prefix = ''; - - // Not an expected previous character. - if (!previous(match)) { - return false - } - - // Treat `www` as part of the domain. - if (/^w/i.test(protocol)) { - domain = protocol + domain; - protocol = ''; - prefix = 'http://'; - } - - if (!isCorrectDomain(domain)) { - return false - } - - const parts = splitUrl(domain + path); - - if (!parts[0]) return false - - /** @type {PhrasingContent} */ - const result = { - type: 'link', - title: null, - url: prefix + protocol + parts[0], - children: [{type: 'text', value: protocol + parts[0]}] - }; - - if (parts[1]) { - return [result, {type: 'text', value: parts[1]}] - } - - return result -} - -/** - * @type {ReplaceFunction} - * @param {string} _ - * @param {string} atext - * @param {string} label - * @param {RegExpMatchObject} match - */ -function findEmail(_, atext, label, match) { - // Not an expected previous character. - if (!previous(match, true) || /[_-]$/.test(label)) { - return false - } - - return { - type: 'link', - title: null, - url: 'mailto:' + atext + '@' + label, - children: [{type: 'text', value: atext + '@' + label}] - } -} - -/** - * @param {string} domain - * @returns {boolean} - */ -function isCorrectDomain(domain) { - const parts = domain.split('.'); - - if ( - parts.length < 2 || - (parts[parts.length - 1] && - (/_/.test(parts[parts.length - 1]) || - !/[a-zA-Z\d]/.test(parts[parts.length - 1]))) || - (parts[parts.length - 2] && - (/_/.test(parts[parts.length - 2]) || - !/[a-zA-Z\d]/.test(parts[parts.length - 2]))) - ) { - return false - } - - return true -} - -/** - * @param {string} url - * @returns {[string, string|undefined]} - */ -function splitUrl(url) { - const trailExec = /[!"&'),.:;<>?\]}]+$/.exec(url); - /** @type {number} */ - let closingParenIndex; - /** @type {number} */ - let openingParens; - /** @type {number} */ - let closingParens; - /** @type {string|undefined} */ - let trail; - - if (trailExec) { - url = url.slice(0, trailExec.index); - trail = trailExec[0]; - closingParenIndex = trail.indexOf(')'); - openingParens = ccount(url, '('); - closingParens = ccount(url, ')'); - - while (closingParenIndex !== -1 && openingParens > closingParens) { - url += trail.slice(0, closingParenIndex + 1); - trail = trail.slice(closingParenIndex + 1); - closingParenIndex = trail.indexOf(')'); - closingParens++; - } - } - - return [url, trail] -} - -/** - * @param {RegExpMatchObject} match - * @param {boolean} [email=false] - * @returns {boolean} - */ -function previous(match, email) { - const code = match.input.charCodeAt(match.index - 1); - - return ( - (match.index === 0 || - unicodeWhitespace(code) || - unicodePunctuation(code)) && - (!email || code !== 47) - ) -} - -/** - * @typedef {import('mdast').Delete} Delete - * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension - * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle - * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension - * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle - */ - -/** @type {FromMarkdownExtension} */ -const gfmStrikethroughFromMarkdown = { - canContainEols: ['delete'], - enter: {strikethrough: enterStrikethrough}, - exit: {strikethrough: exitStrikethrough} -}; - -/** @type {ToMarkdownExtension} */ -const gfmStrikethroughToMarkdown = { - unsafe: [{character: '~', inConstruct: 'phrasing'}], - handlers: {delete: handleDelete} -}; - -handleDelete.peek = peekDelete; - -/** @type {FromMarkdownHandle} */ -function enterStrikethrough(token) { - this.enter({type: 'delete', children: []}, token); -} - -/** @type {FromMarkdownHandle} */ -function exitStrikethrough(token) { - this.exit(token); -} - -/** - * @type {ToMarkdownHandle} - * @param {Delete} node - */ -function handleDelete(node, _, context) { - const exit = context.enter('emphasis'); - const value = containerPhrasing(node, context, {before: '~', after: '~'}); - exit(); - return '~~' + value + '~~' -} - -/** @type {ToMarkdownHandle} */ -function peekDelete() { - return '~' -} - -/** - * @typedef MarkdownTableOptions - * @property {string|null|Array.} [align] - * @property {boolean} [padding=true] - * @property {boolean} [delimiterStart=true] - * @property {boolean} [delimiterStart=true] - * @property {boolean} [delimiterEnd=true] - * @property {boolean} [alignDelimiters=true] - * @property {(value: string) => number} [stringLength] - */ - -/** - * Create a table from a matrix of strings. - * - * @param {Array.>} table - * @param {MarkdownTableOptions} [options] - * @returns {string} - */ -function markdownTable(table, options) { - const settings = options || {}; - const align = (settings.align || []).concat(); - const stringLength = settings.stringLength || defaultStringLength; - /** @type {number[]} Character codes as symbols for alignment per column. */ - const alignments = []; - let rowIndex = -1; - /** @type {string[][]} Cells per row. */ - const cellMatrix = []; - /** @type {number[][]} Sizes of each cell per row. */ - const sizeMatrix = []; - /** @type {number[]} */ - const longestCellByColumn = []; - let mostCellsPerRow = 0; - /** @type {number} */ - let columnIndex; - /** @type {string[]} Cells of current row */ - let row; - /** @type {number[]} Sizes of current row */ - let sizes; - /** @type {number} Sizes of current cell */ - let size; - /** @type {string} Current cell */ - let cell; - /** @type {string[]} Chunks of current line. */ - let line; - /** @type {string} */ - let before; - /** @type {string} */ - let after; - /** @type {number} */ - let code; - - // This is a superfluous loop if we don’t align delimiters, but otherwise we’d - // do superfluous work when aligning, so optimize for aligning. - while (++rowIndex < table.length) { - columnIndex = -1; - row = []; - sizes = []; - - if (table[rowIndex].length > mostCellsPerRow) { - mostCellsPerRow = table[rowIndex].length; - } - - while (++columnIndex < table[rowIndex].length) { - cell = serialize(table[rowIndex][columnIndex]); - - if (settings.alignDelimiters !== false) { - size = stringLength(cell); - sizes[columnIndex] = size; - - if ( - longestCellByColumn[columnIndex] === undefined || - size > longestCellByColumn[columnIndex] - ) { - longestCellByColumn[columnIndex] = size; - } - } - - row.push(cell); - } - - cellMatrix[rowIndex] = row; - sizeMatrix[rowIndex] = sizes; - } - - // Figure out which alignments to use. - columnIndex = -1; - - if (typeof align === 'object' && 'length' in align) { - while (++columnIndex < mostCellsPerRow) { - alignments[columnIndex] = toAlignment(align[columnIndex]); - } - } else { - code = toAlignment(align); - - while (++columnIndex < mostCellsPerRow) { - alignments[columnIndex] = code; - } - } - - // Inject the alignment row. - columnIndex = -1; - row = []; - sizes = []; - - while (++columnIndex < mostCellsPerRow) { - code = alignments[columnIndex]; - before = ''; - after = ''; - - if (code === 99 /* `c` */) { - before = ':'; - after = ':'; - } else if (code === 108 /* `l` */) { - before = ':'; - } else if (code === 114 /* `r` */) { - after = ':'; - } - - // There *must* be at least one hyphen-minus in each alignment cell. - size = - settings.alignDelimiters === false - ? 1 - : Math.max( - 1, - longestCellByColumn[columnIndex] - before.length - after.length - ); - - cell = before + '-'.repeat(size) + after; - - if (settings.alignDelimiters !== false) { - size = before.length + size + after.length; - - if (size > longestCellByColumn[columnIndex]) { - longestCellByColumn[columnIndex] = size; - } - - sizes[columnIndex] = size; - } - - row[columnIndex] = cell; - } - - // Inject the alignment row. - cellMatrix.splice(1, 0, row); - sizeMatrix.splice(1, 0, sizes); - - rowIndex = -1; - /** @type {string[]} */ - const lines = []; - - while (++rowIndex < cellMatrix.length) { - row = cellMatrix[rowIndex]; - sizes = sizeMatrix[rowIndex]; - columnIndex = -1; - line = []; - - while (++columnIndex < mostCellsPerRow) { - cell = row[columnIndex] || ''; - before = ''; - after = ''; - - if (settings.alignDelimiters !== false) { - size = longestCellByColumn[columnIndex] - (sizes[columnIndex] || 0); - code = alignments[columnIndex]; - - if (code === 114 /* `r` */) { - before = ' '.repeat(size); - } else if (code === 99 /* `c` */) { - if (size % 2) { - before = ' '.repeat(size / 2 + 0.5); - after = ' '.repeat(size / 2 - 0.5); - } else { - before = ' '.repeat(size / 2); - after = before; - } - } else { - after = ' '.repeat(size); - } - } - - if (settings.delimiterStart !== false && !columnIndex) { - line.push('|'); - } - - if ( - settings.padding !== false && - // Don’t add the opening space if we’re not aligning and the cell is - // empty: there will be a closing space. - !(settings.alignDelimiters === false && cell === '') && - (settings.delimiterStart !== false || columnIndex) - ) { - line.push(' '); - } - - if (settings.alignDelimiters !== false) { - line.push(before); - } - - line.push(cell); - - if (settings.alignDelimiters !== false) { - line.push(after); - } - - if (settings.padding !== false) { - line.push(' '); - } - - if ( - settings.delimiterEnd !== false || - columnIndex !== mostCellsPerRow - 1 - ) { - line.push('|'); - } - } - - lines.push( - settings.delimiterEnd === false - ? line.join('').replace(/ +$/, '') - : line.join('') - ); - } - - return lines.join('\n') -} - -/** - * @param {string|null|undefined} [value] - * @returns {string} - */ -function serialize(value) { - return value === null || value === undefined ? '' : String(value) -} - -/** - * @param {string} value - * @returns {number} - */ -function defaultStringLength(value) { - return value.length -} - -/** - * @param {string|null|undefined} value - * @returns {number} - */ -function toAlignment(value) { - const code = typeof value === 'string' ? value.charCodeAt(0) : 0; - - return code === 67 /* `C` */ || code === 99 /* `c` */ - ? 99 /* `c` */ - : code === 76 /* `L` */ || code === 108 /* `l` */ - ? 108 /* `l` */ - : code === 82 /* `R` */ || code === 114 /* `r` */ - ? 114 /* `r` */ - : 0 -} - -/** - * @typedef {import('mdast').AlignType} AlignType - * @typedef {import('mdast').Table} Table - * @typedef {import('mdast').TableRow} TableRow - * @typedef {import('mdast').TableCell} TableCell - * @typedef {import('mdast').InlineCode} InlineCode - * @typedef {import('markdown-table').MarkdownTableOptions} MarkdownTableOptions - * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension - * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle - * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension - * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle - * @typedef {import('mdast-util-to-markdown').Context} ToMarkdownContext - * - * @typedef Options - * @property {boolean} [tableCellPadding=true] - * @property {boolean} [tablePipeAlign=true] - * @property {MarkdownTableOptions['stringLength']} [stringLength] - */ - -/** @type {FromMarkdownExtension} */ -const gfmTableFromMarkdown = { - enter: { - table: enterTable, - tableData: enterCell, - tableHeader: enterCell, - tableRow: enterRow - }, - exit: { - codeText: exitCodeText, - table: exitTable, - tableData: exit, - tableHeader: exit, - tableRow: exit - } -}; - -/** @type {FromMarkdownHandle} */ -function enterTable(token) { - /** @type {AlignType[]} */ - // @ts-expect-error: `align` is custom. - const align = token._align; - this.enter({type: 'table', align, children: []}, token); - this.setData('inTable', true); -} - -/** @type {FromMarkdownHandle} */ -function exitTable(token) { - this.exit(token); - this.setData('inTable'); -} - -/** @type {FromMarkdownHandle} */ -function enterRow(token) { - this.enter({type: 'tableRow', children: []}, token); -} - -/** @type {FromMarkdownHandle} */ -function exit(token) { - this.exit(token); -} - -/** @type {FromMarkdownHandle} */ -function enterCell(token) { - this.enter({type: 'tableCell', children: []}, token); -} - -// Overwrite the default code text data handler to unescape escaped pipes when -// they are in tables. -/** @type {FromMarkdownHandle} */ -function exitCodeText(token) { - let value = this.resume(); - - if (this.getData('inTable')) { - value = value.replace(/\\([\\|])/g, replace); - } - - const node = /** @type {InlineCode} */ (this.stack[this.stack.length - 1]); - node.value = value; - this.exit(token); -} - -/** - * @param {string} $0 - * @param {string} $1 - * @returns {string} - */ -function replace($0, $1) { - // Pipes work, backslashes don’t (but can’t escape pipes). - return $1 === '|' ? $1 : $0 -} - -/** - * @param {Options} [options] - * @returns {ToMarkdownExtension} - */ -function gfmTableToMarkdown(options) { - const settings = options || {}; - const padding = settings.tableCellPadding; - const alignDelimiters = settings.tablePipeAlign; - const stringLength = settings.stringLength; - const around = padding ? ' ' : '|'; - - return { - unsafe: [ - {character: '\r', inConstruct: 'tableCell'}, - {character: '\n', inConstruct: 'tableCell'}, - // A pipe, when followed by a tab or space (padding), or a dash or colon - // (unpadded delimiter row), could result in a table. - {atBreak: true, character: '|', after: '[\t :-]'}, - // A pipe in a cell must be encoded. - {character: '|', inConstruct: 'tableCell'}, - // A colon must be followed by a dash, in which case it could start a - // delimiter row. - {atBreak: true, character: ':', after: '-'}, - // A delimiter row can also start with a dash, when followed by more - // dashes, a colon, or a pipe. - // This is a stricter version than the built in check for lists, thematic - // breaks, and setex heading underlines though: - // - {atBreak: true, character: '-', after: '[:|-]'} - ], - handlers: { - table: handleTable, - tableRow: handleTableRow, - tableCell: handleTableCell, - inlineCode: inlineCodeWithTable - } - } - - /** - * @type {ToMarkdownHandle} - * @param {Table} node - */ - function handleTable(node, _, context) { - // @ts-expect-error: fixed in `markdown-table@3.0.1`. - return serializeData(handleTableAsData(node, context), node.align) - } - - /** - * This function isn’t really used normally, because we handle rows at the - * table level. - * But, if someone passes in a table row, this ensures we make somewhat sense. - * - * @type {ToMarkdownHandle} - * @param {TableRow} node - */ - function handleTableRow(node, _, context) { - const row = handleTableRowAsData(node, context); - // `markdown-table` will always add an align row - const value = serializeData([row]); - return value.slice(0, value.indexOf('\n')) - } - - /** - * @type {ToMarkdownHandle} - * @param {TableCell} node - */ - function handleTableCell(node, _, context) { - const exit = context.enter('tableCell'); - const subexit = context.enter('phrasing'); - const value = containerPhrasing(node, context, { - before: around, - after: around - }); - subexit(); - exit(); - return value - } - - /** - * @param {Array.>} matrix - * @param {Array.} [align] - */ - function serializeData(matrix, align) { - return markdownTable(matrix, { - align, - alignDelimiters, - padding, - stringLength - }) - } - - /** - * @param {Table} node - * @param {ToMarkdownContext} context - */ - function handleTableAsData(node, context) { - const children = node.children; - let index = -1; - /** @type {Array.>} */ - const result = []; - const subexit = context.enter('table'); - - while (++index < children.length) { - result[index] = handleTableRowAsData(children[index], context); - } - - subexit(); - - return result - } - - /** - * @param {TableRow} node - * @param {ToMarkdownContext} context - */ - function handleTableRowAsData(node, context) { - const children = node.children; - let index = -1; - /** @type {Array.} */ - const result = []; - const subexit = context.enter('tableRow'); - - while (++index < children.length) { - result[index] = handleTableCell(children[index], node, context); - } - - subexit(); - - return result - } - - /** - * @type {ToMarkdownHandle} - * @param {InlineCode} node - */ - function inlineCodeWithTable(node, parent, context) { - let value = inlineCode(node, parent, context); - - if (context.stack.includes('tableCell')) { - value = value.replace(/\|/g, '\\$&'); - } - - return value - } -} - -/** - * @typedef {import('mdast').ListItem} ListItem - * @typedef {import('mdast').Paragraph} Paragraph - * @typedef {import('mdast').BlockContent} BlockContent - * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension - * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle - * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension - * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle - */ - -/** @type {FromMarkdownExtension} */ -const gfmTaskListItemFromMarkdown = { - exit: { - taskListCheckValueChecked: exitCheck, - taskListCheckValueUnchecked: exitCheck, - paragraph: exitParagraphWithTaskListItem - } -}; - -/** @type {ToMarkdownExtension} */ -const gfmTaskListItemToMarkdown = { - unsafe: [{atBreak: true, character: '-', after: '[:|-]'}], - handlers: {listItem: listItemWithTaskListItem} -}; - -/** @type {FromMarkdownHandle} */ -function exitCheck(token) { - // We’re always in a paragraph, in a list item. - this.stack[this.stack.length - 2].checked = - token.type === 'taskListCheckValueChecked'; -} - -/** @type {FromMarkdownHandle} */ -function exitParagraphWithTaskListItem(token) { - const parent = this.stack[this.stack.length - 2]; - /** @type {Paragraph} */ - // @ts-expect-error: must be true. - const node = this.stack[this.stack.length - 1]; - /** @type {BlockContent[]} */ - // @ts-expect-error: check whether `parent` is a `listItem` later. - const siblings = parent.children; - const head = node.children[0]; - let index = -1; - /** @type {Paragraph|undefined} */ - let firstParaghraph; - - if ( - parent && - parent.type === 'listItem' && - typeof parent.checked === 'boolean' && - head && - head.type === 'text' - ) { - while (++index < siblings.length) { - const sibling = siblings[index]; - if (sibling.type === 'paragraph') { - firstParaghraph = sibling; - break - } - } - - if (firstParaghraph === node) { - // Must start with a space or a tab. - head.value = head.value.slice(1); - - if (head.value.length === 0) { - node.children.shift(); - } else { - // @ts-expect-error: must be true. - head.position.start.column++; - // @ts-expect-error: must be true. - head.position.start.offset++; - // @ts-expect-error: must be true. - node.position.start = Object.assign({}, head.position.start); - } - } - } - - this.exit(token); -} - -/** - * @type {ToMarkdownHandle} - * @param {ListItem} node - */ -function listItemWithTaskListItem(node, parent, context) { - const head = node.children[0]; - let value = listItem(node, parent, context); - - if (typeof node.checked === 'boolean' && head && head.type === 'paragraph') { - value = value.replace(/^(?:[*+-]|\d+\.)([\r\n]| {1,3})/, check); - } - - return value - - /** - * @param {string} $0 - * @returns {string} - */ - function check($0) { - return $0 + '[' + (node.checked ? 'x' : ' ') + '] ' - } -} - -/** - * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension - * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension - * - * @typedef {import('mdast-util-gfm-table').Options} Options - */ - -/** - * @type {Array.} - */ -const gfmFromMarkdown = [ - gfmAutolinkLiteralFromMarkdown, - gfmStrikethroughFromMarkdown, - gfmTableFromMarkdown, - gfmTaskListItemFromMarkdown -]; - -/** - * @param {Options} [options] - * @returns {ToMarkdownExtension} - */ -function gfmToMarkdown(options) { - return { - extensions: [ - gfmAutolinkLiteralToMarkdown, - gfmStrikethroughToMarkdown, - gfmTableToMarkdown(options), - gfmTaskListItemToMarkdown - ] - } -} - -/** - * @typedef {import('mdast').Root} Root - * @typedef {import('micromark-extension-gfm').Options & import('mdast-util-gfm').Options} Options - */ - -/** - * Plugin to support GitHub Flavored Markdown (GFM). - * - * @type {import('unified').Plugin<[Options?]|void[], Root>} - */ -function remarkGfm(options = {}) { - const data = this.data(); - - add('micromarkExtensions', gfm(options)); - add('fromMarkdownExtensions', gfmFromMarkdown); - add('toMarkdownExtensions', gfmToMarkdown(options)); - - /** - * @param {string} field - * @param {unknown} value - */ - function add(field, value) { - const list = /** @type {unknown[]} */ ( - // Other extensions - /* c8 ignore next 2 */ - data[field] ? data[field] : (data[field] = []) - ); - - list.push(value); - } -} - -// To aid in future maintenance, this layout closely matches remark-cli/cli.js. - -args({ - processor: remark().use(remarkGfm).use(remarkPresetLintNode), - name: proc.name, - description: cli.description, - version: [ - proc.name + ': ' + proc.version, - cli.name + ': ' + cli.version, - ].join(', '), - pluginPrefix: proc.name, - presetPrefix: proc.name + '-preset', - packageField: proc.name + 'Config', - rcName: '.' + proc.name + 'rc', - ignoreName: '.' + proc.name + 'ignore', - extensions: markdownExtensions, - detectConfig: false, -}); diff --git a/tools/lint-md/.gitignore b/tools/lint-md/.gitignore new file mode 100644 index 00000000000000..3c3629e647f5dd --- /dev/null +++ b/tools/lint-md/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/tools/lint-md/lint-md.mjs b/tools/lint-md/lint-md.mjs new file mode 100644 index 00000000000000..85dff3eea640ef --- /dev/null +++ b/tools/lint-md/lint-md.mjs @@ -0,0 +1,29172 @@ +import fs from 'fs'; +import path$1 from 'path'; +import { fileURLToPath, pathToFileURL, URL as URL$1 } from 'url'; +import process$1 from 'process'; +import os from 'os'; +import tty from 'tty'; + +/** + * Throw a given error. + * + * @param {Error | null | undefined} [error] + */ +function bail(error) { + if (error) { + throw error + } +} + +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +function commonjsRequire (path) { + throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.'); +} + +/*! + * Determine if an object is a Buffer + * + * @author Feross Aboukhadijeh + * @license MIT + */ + +var isBuffer = function isBuffer (obj) { + return obj != null && obj.constructor != null && + typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) +}; + +var hasOwn = Object.prototype.hasOwnProperty; +var toStr = Object.prototype.toString; +var defineProperty = Object.defineProperty; +var gOPD = Object.getOwnPropertyDescriptor; + +var isArray = function isArray(arr) { + if (typeof Array.isArray === 'function') { + return Array.isArray(arr); + } + + return toStr.call(arr) === '[object Array]'; +}; + +var isPlainObject$1 = function isPlainObject(obj) { + if (!obj || toStr.call(obj) !== '[object Object]') { + return false; + } + + var hasOwnConstructor = hasOwn.call(obj, 'constructor'); + var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); + // Not own constructor property must be Object + if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + var key; + for (key in obj) { /**/ } + + return typeof key === 'undefined' || hasOwn.call(obj, key); +}; + +// If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target +var setProperty = function setProperty(target, options) { + if (defineProperty && options.name === '__proto__') { + defineProperty(target, options.name, { + enumerable: true, + configurable: true, + value: options.newValue, + writable: true + }); + } else { + target[options.name] = options.newValue; + } +}; + +// Return undefined instead of __proto__ if '__proto__' is not an own property +var getProperty = function getProperty(obj, name) { + if (name === '__proto__') { + if (!hasOwn.call(obj, name)) { + return void 0; + } else if (gOPD) { + // In early versions of node, obj['__proto__'] is buggy when obj has + // __proto__ as an own property. Object.getOwnPropertyDescriptor() works. + return gOPD(obj, name).value; + } + } + + return obj[name]; +}; + +var extend$1 = function extend() { + var options, name, src, copy, copyIsArray, clone; + var target = arguments[0]; + var i = 1; + var length = arguments.length; + var deep = false; + + // Handle a deep copy situation + if (typeof target === 'boolean') { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + if (target == null || (typeof target !== 'object' && typeof target !== 'function')) { + target = {}; + } + + for (; i < length; ++i) { + options = arguments[i]; + // Only deal with non-null/undefined values + if (options != null) { + // Extend the base object + for (name in options) { + src = getProperty(target, name); + copy = getProperty(options, name); + + // Prevent never-ending loop + if (target !== copy) { + // Recurse if we're merging plain objects or arrays + if (deep && copy && (isPlainObject$1(copy) || (copyIsArray = isArray(copy)))) { + if (copyIsArray) { + copyIsArray = false; + clone = src && isArray(src) ? src : []; + } else { + clone = src && isPlainObject$1(src) ? src : {}; + } + + // Never move original objects, clone them + setProperty(target, { name: name, newValue: extend(deep, clone, copy) }); + + // Don't bring in undefined values + } else if (typeof copy !== 'undefined') { + setProperty(target, { name: name, newValue: copy }); + } + } + } + } + } + + // Return the modified object + return target; +}; + +function isPlainObject(value) { + if (Object.prototype.toString.call(value) !== '[object Object]') { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === null || prototype === Object.prototype; +} + +/** + * @typedef {(error?: Error|null|undefined, ...output: any[]) => void} Callback + * @typedef {(...input: any[]) => any} Middleware + * + * @typedef {(...input: any[]) => void} Run Call all middleware. + * @typedef {(fn: Middleware) => Pipeline} Use Add `fn` (middleware) to the list. + * @typedef {{run: Run, use: Use}} Pipeline + */ + +/** + * Create new middleware. + * + * @returns {Pipeline} + */ +function trough() { + /** @type {Middleware[]} */ + const fns = []; + /** @type {Pipeline} */ + const pipeline = {run, use}; + + return pipeline + + /** @type {Run} */ + function run(...values) { + let middlewareIndex = -1; + /** @type {Callback} */ + const callback = values.pop(); + + if (typeof callback !== 'function') { + throw new TypeError('Expected function as last argument, not ' + callback) + } + + next(null, ...values); + + /** + * Run the next `fn`, or we’re done. + * + * @param {Error|null|undefined} error + * @param {any[]} output + */ + function next(error, ...output) { + const fn = fns[++middlewareIndex]; + let index = -1; + + if (error) { + callback(error); + return + } + + // Copy non-nullish input into values. + while (++index < values.length) { + if (output[index] === null || output[index] === undefined) { + output[index] = values[index]; + } + } + + // Save the newly created `output` for the next call. + values = output; + + // Next or done. + if (fn) { + wrap(fn, next)(...output); + } else { + callback(null, ...output); + } + } + } + + /** @type {Use} */ + function use(middelware) { + if (typeof middelware !== 'function') { + throw new TypeError( + 'Expected `middelware` to be a function, not ' + middelware + ) + } + + fns.push(middelware); + return pipeline + } +} + +/** + * Wrap `middleware`. + * Can be sync or async; return a promise, receive a callback, or return new + * values and errors. + * + * @param {Middleware} middleware + * @param {Callback} callback + */ +function wrap(middleware, callback) { + /** @type {boolean} */ + let called; + + return wrapped + + /** + * Call `middleware`. + * @param {any[]} parameters + * @returns {void} + */ + function wrapped(...parameters) { + const fnExpectsCallback = middleware.length > parameters.length; + /** @type {any} */ + let result; + + if (fnExpectsCallback) { + parameters.push(done); + } + + try { + result = middleware(...parameters); + } catch (error) { + /** @type {Error} */ + const exception = error; + + // Well, this is quite the pickle. + // `middleware` received a callback and called it synchronously, but that + // threw an error. + // The only thing left to do is to throw the thing instead. + if (fnExpectsCallback && called) { + throw exception + } + + return done(exception) + } + + if (!fnExpectsCallback) { + if (result instanceof Promise) { + result.then(then, done); + } else if (result instanceof Error) { + done(result); + } else { + then(result); + } + } + } + + /** + * Call `callback`, only once. + * @type {Callback} + */ + function done(error, ...output) { + if (!called) { + called = true; + callback(error, ...output); + } + } + + /** + * Call `done` with one value. + * + * @param {any} [value] + */ + function then(value) { + done(null, value); + } +} + +var own$8 = {}.hasOwnProperty; + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Position} Position + * @typedef {import('unist').Point} Point + */ + +/** + * Stringify one point, a position (start and end points), or a node’s + * positional information. + * + * @param {Node|Position|Point} [value] + * @returns {string} + */ +function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if (own$8.call(value, 'position') || own$8.call(value, 'type')) { + // @ts-ignore looks like a node. + return position(value.position) + } + + // Position. + if (own$8.call(value, 'start') || own$8.call(value, 'end')) { + // @ts-ignore looks like a position. + return position(value) + } + + // Point. + if (own$8.call(value, 'line') || own$8.call(value, 'column')) { + // @ts-ignore looks like a point. + return point$1(value) + } + + // ? + return '' +} + +/** + * @param {Point} point + * @returns {string} + */ +function point$1(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position} pos + * @returns {string} + */ +function position(pos) { + return point$1(pos && pos.start) + '-' + point$1(pos && pos.end) +} + +/** + * @param {number} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Position} Position + * @typedef {import('unist').Point} Point + */ + +class VFileMessage extends Error { + /** + * Constructor of a message for `reason` at `place` from `origin`. + * When an error is passed in as `reason`, copies the `stack`. + * + * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given. + * @param {Node|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional). + * @param {string} [origin] Place in code the message originates from (`string`, optional). + */ + constructor(reason, place, origin) { + /** @type {[string?, string?]} */ + var parts = [null, null]; + /** @type {Position} */ + var position = { + start: {line: null, column: null}, + end: {line: null, column: null} + }; + /** @type {number} */ + var index; + + super(); + + if (typeof place === 'string') { + origin = place; + place = null; + } + + if (typeof origin === 'string') { + index = origin.indexOf(':'); + + if (index === -1) { + parts[1] = origin; + } else { + parts[0] = origin.slice(0, index); + parts[1] = origin.slice(index + 1); + } + } + + if (place) { + // Node. + if ('type' in place || 'position' in place) { + if (place.position) { + position = place.position; + } + } + // Position. + else if ('start' in place || 'end' in place) { + // @ts-ignore Looks like a position. + position = place; + } + // Point. + else if ('line' in place || 'column' in place) { + // @ts-ignore Looks like a point. + position.start = place; + } + } + + // Fields from `Error` + this.name = stringifyPosition(place) || '1:1'; + this.message = typeof reason === 'object' ? reason.message : reason; + this.stack = typeof reason === 'object' ? reason.stack : ''; + + /** + * Reason for message. + * @type {string} + */ + this.reason = this.message; + /** + * Starting line of error. + * @type {number?} + */ + this.line = position.start.line; + /** + * Starting column of error. + * @type {number?} + */ + this.column = position.start.column; + /** + * Namespace of warning. + * @type {string?} + */ + this.source = parts[0]; + /** + * Category of message. + * @type {string?} + */ + this.ruleId = parts[1]; + /** + * Full range information, when available. + * Has start and end properties, both set to an object with line and column, set to number?. + * @type {Position?} + */ + this.position = position; + + // The following fields are “well known”. + // Not standard. + // Feel free to add other non-standard fields to your messages. + + /* eslint-disable no-unused-expressions */ + /** + * You may add a file property with a path of a file (used throughout the VFile ecosystem). + * @type {string?} + */ + this.file; + /** + * If true, marks associated file as no longer processable. + * @type {boolean?} + */ + this.fatal; + /** + * You may add a url property with a link to documentation for the message. + * @type {string?} + */ + this.url; + /** + * You may add a note property with a long form description of the message (supported by vfile-reporter). + * @type {string?} + */ + this.note; + /* eslint-enable no-unused-expressions */ + } +} + +VFileMessage.prototype.file = ''; +VFileMessage.prototype.name = ''; +VFileMessage.prototype.reason = ''; +VFileMessage.prototype.message = ''; +VFileMessage.prototype.stack = ''; +VFileMessage.prototype.fatal = null; +VFileMessage.prototype.column = null; +VFileMessage.prototype.line = null; +VFileMessage.prototype.source = null; +VFileMessage.prototype.ruleId = null; +VFileMessage.prototype.position = null; + +const proc = process$1; + +/** + * @typedef URL + * @property {string} hash + * @property {string} host + * @property {string} hostname + * @property {string} href + * @property {string} origin + * @property {string} password + * @property {string} pathname + * @property {string} port + * @property {string} protocol + * @property {string} search + * @property {any} searchParams + * @property {string} username + * @property {() => string} toString + * @property {() => string} toJSON + */ + +/** + * @param {unknown} fileURLOrPath + * @returns {fileURLOrPath is URL} + */ +// From: +function isUrl(fileURLOrPath) { + return ( + fileURLOrPath !== null && + typeof fileURLOrPath === 'object' && + // @ts-expect-error: indexable. + fileURLOrPath.href && + // @ts-expect-error: indexable. + fileURLOrPath.origin + ) +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Position} Position + * @typedef {import('unist').Point} Point + * @typedef {import('./minurl.shared.js').URL} URL + * + * @typedef {'ascii'|'utf8'|'utf-8'|'utf16le'|'ucs2'|'ucs-2'|'base64'|'latin1'|'binary'|'hex'} BufferEncoding + * Encodings supported by the buffer class. + * This is a copy of the typing from Node, copied to prevent Node globals from + * being needed. + * Copied from: + * + * @typedef {string|Uint8Array} VFileValue + * Contents of the file. + * Can either be text, or a Buffer like structure. + * This does not directly use type `Buffer`, because it can also be used in a + * browser context. + * Instead this leverages `Uint8Array` which is the base type for `Buffer`, + * and a native JavaScript construct. + * + * @typedef {VFileValue|VFileOptions|VFile|URL} VFileCompatible + * Things that can be passed to the constructor. + * + * @typedef VFileCoreOptions + * @property {VFileValue} [value] + * @property {string} [cwd] + * @property {Array.} [history] + * @property {string|URL} [path] + * @property {string} [basename] + * @property {string} [stem] + * @property {string} [extname] + * @property {string} [dirname] + * @property {Object.} [data] + * + * @typedef {{[key: string]: unknown} & VFileCoreOptions} VFileOptions + * Configuration: a bunch of keys that will be shallow copied over to the new + * file. + * + * @typedef {Object.} VFileReporterSettings + * @typedef {(files: VFile[], options: T) => string} VFileReporter + */ + +// Order of setting (least specific to most), we need this because otherwise +// `{stem: 'a', path: '~/b.js'}` would throw, as a path is needed before a +// stem can be set. +const order = ['history', 'path', 'basename', 'stem', 'extname', 'dirname']; + +class VFile { + /** + * Create a new virtual file. + * + * If `options` is `string` or `Buffer`, treats it as `{value: options}`. + * If `options` is a `VFile`, shallow copies its data over to the new file. + * All other given fields are set on the newly created `VFile`. + * + * Path related properties are set in the following order (least specific to + * most specific): `history`, `path`, `basename`, `stem`, `extname`, + * `dirname`. + * + * It’s not possible to set either `dirname` or `extname` without setting + * either `history`, `path`, `basename`, or `stem` as well. + * + * @param {VFileCompatible} [value] + */ + constructor(value) { + /** @type {VFileOptions} */ + let options; + + if (!value) { + options = {}; + } else if (typeof value === 'string' || isBuffer(value)) { + // @ts-expect-error Looks like a buffer. + options = {value}; + } else if (isUrl(value)) { + options = {path: value}; + } else { + // @ts-expect-error Looks like file or options. + options = value; + } + + /** + * Place to store custom information. + * It’s OK to store custom data directly on the file, moving it to `data` + * gives a little more privacy. + * @type {Object.} + */ + this.data = {}; + + /** + * List of messages associated with the file. + * @type {Array.} + */ + this.messages = []; + + /** + * List of file paths the file moved between. + * @type {Array.} + */ + this.history = []; + + /** + * Base of `path`. + * Defaults to `process.cwd()` (`/` in browsers). + * @type {string} + */ + this.cwd = proc.cwd(); + + /* eslint-disable no-unused-expressions */ + /** + * Raw value. + * @type {VFileValue} + */ + this.value; + + // The below are non-standard, they are “well-known”. + // As in, used in several tools. + + /** + * Whether a file was saved to disk. + * This is used by vfile reporters. + * @type {boolean} + */ + this.stored; + + /** + * Sometimes files have a non-string representation. + * This can be stored in the `result` field. + * One example is when turning markdown into React nodes. + * This is used by unified to store non-string results. + * @type {unknown} + */ + this.result; + + /** + * Sometimes files have a source map associated with them. + * This can be stored in the `map` field. + * This should be a `RawSourceMap` type from the `source-map` module. + * @type {unknown} + */ + this.map; + /* eslint-enable no-unused-expressions */ + + // Set path related properties in the correct order. + let index = -1; + + while (++index < order.length) { + const prop = order[index]; + + // Note: we specifically use `in` instead of `hasOwnProperty` to accept + // `vfile`s too. + if (prop in options && options[prop] !== undefined) { + // @ts-expect-error: TS is confused by the different types for `history`. + this[prop] = prop === 'history' ? [...options[prop]] : options[prop]; + } + } + + /** @type {string} */ + let prop; + + // Set non-path related properties. + for (prop in options) { + // @ts-expect-error: fine to set other things. + if (!order.includes(prop)) this[prop] = options[prop]; + } + } + + /** + * Access full path (`~/index.min.js`). + * + * @returns {string} + */ + get path() { + return this.history[this.history.length - 1] + } + + /** + * Set full path (`~/index.min.js`). + * Cannot be nullified. + * + * @param {string|URL} path + */ + set path(path) { + if (isUrl(path)) { + path = fileURLToPath(path); + } + + assertNonEmpty(path, 'path'); + + if (this.path !== path) { + this.history.push(path); + } + } + + /** + * Access parent path (`~`). + */ + get dirname() { + return typeof this.path === 'string' ? path$1.dirname(this.path) : undefined + } + + /** + * Set parent path (`~`). + * Cannot be set if there's no `path` yet. + */ + set dirname(dirname) { + assertPath(this.basename, 'dirname'); + this.path = path$1.join(dirname || '', this.basename); + } + + /** + * Access basename (including extname) (`index.min.js`). + */ + get basename() { + return typeof this.path === 'string' ? path$1.basename(this.path) : undefined + } + + /** + * Set basename (`index.min.js`). + * Cannot contain path separators. + * Cannot be nullified either (use `file.path = file.dirname` instead). + */ + set basename(basename) { + assertNonEmpty(basename, 'basename'); + assertPart(basename, 'basename'); + this.path = path$1.join(this.dirname || '', basename); + } + + /** + * Access extname (including dot) (`.js`). + */ + get extname() { + return typeof this.path === 'string' ? path$1.extname(this.path) : undefined + } + + /** + * Set extname (including dot) (`.js`). + * Cannot be set if there's no `path` yet and cannot contain path separators. + */ + set extname(extname) { + assertPart(extname, 'extname'); + assertPath(this.dirname, 'extname'); + + if (extname) { + if (extname.charCodeAt(0) !== 46 /* `.` */) { + throw new Error('`extname` must start with `.`') + } + + if (extname.includes('.', 1)) { + throw new Error('`extname` cannot contain multiple dots') + } + } + + this.path = path$1.join(this.dirname, this.stem + (extname || '')); + } + + /** + * Access stem (w/o extname) (`index.min`). + */ + get stem() { + return typeof this.path === 'string' + ? path$1.basename(this.path, this.extname) + : undefined + } + + /** + * Set stem (w/o extname) (`index.min`). + * Cannot be nullified, and cannot contain path separators. + */ + set stem(stem) { + assertNonEmpty(stem, 'stem'); + assertPart(stem, 'stem'); + this.path = path$1.join(this.dirname || '', stem + (this.extname || '')); + } + + /** + * Serialize the file. + * + * @param {BufferEncoding} [encoding='utf8'] If `file.value` is a buffer, `encoding` is used to serialize buffers. + * @returns {string} + */ + toString(encoding) { + // @ts-expect-error string’s don’t accept the parameter, but buffers do. + return (this.value || '').toString(encoding) + } + + /** + * Create a message and associates it w/ the file. + * + * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given. + * @param {Node|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional). + * @param {string} [origin] Place in code the message originates from (`string`, optional). + * @returns {VFileMessage} + */ + message(reason, place, origin) { + const message = new VFileMessage(reason, place, origin); + + if (this.path) { + message.name = this.path + ':' + message.name; + message.file = this.path; + } + + message.fatal = false; + + this.messages.push(message); + + return message + } + + /** + * Info: create a message, associate it with the file, and mark the fatality + * as `null`. + * Calls `message()` internally. + * + * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given. + * @param {Node|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional). + * @param {string} [origin] Place in code the message originates from (`string`, optional). + * @returns {VFileMessage} + */ + info(reason, place, origin) { + const message = this.message(reason, place, origin); + + message.fatal = null; + + return message + } + + /** + * Fail: create a message, associate it with the file, mark the fatality as + * `true`. + * Note: fatal errors mean a file is no longer processable. + * Calls `message()` internally. + * + * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given. + * @param {Node|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional). + * @param {string} [origin] Place in code the message originates from (`string`, optional). + * @returns {never} + */ + fail(reason, place, origin) { + const message = this.message(reason, place, origin); + + message.fatal = true; + + throw message + } +} + +/** + * Assert that `part` is not a path (as in, does not contain `path.sep`). + * + * @param {string|undefined} part + * @param {string} name + * @returns {void} + */ +function assertPart(part, name) { + if (part && part.includes(path$1.sep)) { + throw new Error( + '`' + name + '` cannot be a path: did not expect `' + path$1.sep + '`' + ) + } +} + +/** + * Assert that `part` is not empty. + * + * @param {string|undefined} part + * @param {string} name + * @returns {asserts part is string} + */ +function assertNonEmpty(part, name) { + if (!part) { + throw new Error('`' + name + '` cannot be empty') + } +} + +/** + * Assert `path` exists. + * + * @param {string|undefined} path + * @param {string} name + * @returns {asserts path is string} + */ +function assertPath(path, name) { + if (!path) { + throw new Error('Setting `' + name + '` requires `path` to be set too') + } +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('vfile').VFileCompatible} VFileCompatible + * @typedef {import('vfile').VFileValue} VFileValue + * @typedef {import('..').Processor} Processor + * @typedef {import('..').Plugin} Plugin + * @typedef {import('..').Preset} Preset + * @typedef {import('..').Pluggable} Pluggable + * @typedef {import('..').PluggableList} PluggableList + * @typedef {import('..').Transformer} Transformer + * @typedef {import('..').Parser} Parser + * @typedef {import('..').Compiler} Compiler + * @typedef {import('..').RunCallback} RunCallback + * @typedef {import('..').ProcessCallback} ProcessCallback + * + * @typedef Context + * @property {Node} tree + * @property {VFile} file + */ + +// Expose a frozen processor. +const unified = base().freeze(); + +const own$7 = {}.hasOwnProperty; + +// Function to create the first processor. +/** + * @returns {Processor} + */ +function base() { + const transformers = trough(); + /** @type {Processor['attachers']} */ + const attachers = []; + /** @type {Record} */ + let namespace = {}; + /** @type {boolean|undefined} */ + let frozen; + let freezeIndex = -1; + + // Data management. + // @ts-expect-error: overloads are handled. + processor.data = data; + processor.Parser = undefined; + processor.Compiler = undefined; + + // Lock. + processor.freeze = freeze; + + // Plugins. + processor.attachers = attachers; + // @ts-expect-error: overloads are handled. + processor.use = use; + + // API. + processor.parse = parse; + processor.stringify = stringify; + // @ts-expect-error: overloads are handled. + processor.run = run; + processor.runSync = runSync; + // @ts-expect-error: overloads are handled. + processor.process = process; + processor.processSync = processSync; + + // Expose. + return processor + + // Create a new processor based on the processor in the current scope. + /** @type {Processor} */ + function processor() { + const destination = base(); + let index = -1; + + while (++index < attachers.length) { + destination.use(...attachers[index]); + } + + destination.data(extend$1(true, {}, namespace)); + + return destination + } + + /** + * @param {string|Record} [key] + * @param {unknown} [value] + * @returns {unknown} + */ + function data(key, value) { + if (typeof key === 'string') { + // Set `key`. + if (arguments.length === 2) { + assertUnfrozen('data', frozen); + namespace[key] = value; + return processor + } + + // Get `key`. + return (own$7.call(namespace, key) && namespace[key]) || null + } + + // Set space. + if (key) { + assertUnfrozen('data', frozen); + namespace = key; + return processor + } + + // Get space. + return namespace + } + + /** @type {Processor['freeze']} */ + function freeze() { + if (frozen) { + return processor + } + + while (++freezeIndex < attachers.length) { + const [attacher, ...options] = attachers[freezeIndex]; + + if (options[0] === false) { + continue + } + + if (options[0] === true) { + options[1] = undefined; + } + + /** @type {Transformer|void} */ + const transformer = attacher.call(processor, ...options); + + if (typeof transformer === 'function') { + transformers.use(transformer); + } + } + + frozen = true; + freezeIndex = Number.POSITIVE_INFINITY; + + return processor + } + + /** + * @param {Pluggable|null|undefined} [value] + * @param {...unknown} options + * @returns {Processor} + */ + function use(value, ...options) { + /** @type {Record|undefined} */ + let settings; + + assertUnfrozen('use', frozen); + + if (value === null || value === undefined) ; else if (typeof value === 'function') { + addPlugin(value, ...options); + } else if (typeof value === 'object') { + if (Array.isArray(value)) { + addList(value); + } else { + addPreset(value); + } + } else { + throw new TypeError('Expected usable value, not `' + value + '`') + } + + if (settings) { + namespace.settings = Object.assign(namespace.settings || {}, settings); + } + + return processor + + /** + * @param {import('..').Pluggable} value + * @returns {void} + */ + function add(value) { + if (typeof value === 'function') { + addPlugin(value); + } else if (typeof value === 'object') { + if (Array.isArray(value)) { + const [plugin, ...options] = value; + addPlugin(plugin, ...options); + } else { + addPreset(value); + } + } else { + throw new TypeError('Expected usable value, not `' + value + '`') + } + } + + /** + * @param {Preset} result + * @returns {void} + */ + function addPreset(result) { + addList(result.plugins); + + if (result.settings) { + settings = Object.assign(settings || {}, result.settings); + } + } + + /** + * @param {PluggableList|null|undefined} [plugins] + * @returns {void} + */ + function addList(plugins) { + let index = -1; + + if (plugins === null || plugins === undefined) ; else if (Array.isArray(plugins)) { + while (++index < plugins.length) { + const thing = plugins[index]; + add(thing); + } + } else { + throw new TypeError('Expected a list of plugins, not `' + plugins + '`') + } + } + + /** + * @param {Plugin} plugin + * @param {...unknown} [value] + * @returns {void} + */ + function addPlugin(plugin, value) { + let index = -1; + /** @type {Processor['attachers'][number]|undefined} */ + let entry; + + while (++index < attachers.length) { + if (attachers[index][0] === plugin) { + entry = attachers[index]; + break + } + } + + if (entry) { + if (isPlainObject(entry[1]) && isPlainObject(value)) { + value = extend$1(true, entry[1], value); + } + + entry[1] = value; + } else { + // @ts-expect-error: fine. + attachers.push([...arguments]); + } + } + } + + /** @type {Processor['parse']} */ + function parse(doc) { + processor.freeze(); + const file = vfile(doc); + const Parser = processor.Parser; + assertParser('parse', Parser); + + if (newable(Parser, 'parse')) { + // @ts-expect-error: `newable` checks this. + return new Parser(String(file), file).parse() + } + + // @ts-expect-error: `newable` checks this. + return Parser(String(file), file) // eslint-disable-line new-cap + } + + /** @type {Processor['stringify']} */ + function stringify(node, doc) { + processor.freeze(); + const file = vfile(doc); + const Compiler = processor.Compiler; + assertCompiler('stringify', Compiler); + assertNode(node); + + if (newable(Compiler, 'compile')) { + // @ts-expect-error: `newable` checks this. + return new Compiler(node, file).compile() + } + + // @ts-expect-error: `newable` checks this. + return Compiler(node, file) // eslint-disable-line new-cap + } + + /** + * @param {Node} node + * @param {VFileCompatible|RunCallback} [doc] + * @param {RunCallback} [callback] + * @returns {Promise|void} + */ + function run(node, doc, callback) { + assertNode(node); + processor.freeze(); + + if (!callback && typeof doc === 'function') { + callback = doc; + doc = undefined; + } + + if (!callback) { + return new Promise(executor) + } + + executor(null, callback); + + /** + * @param {null|((node: Node) => void)} resolve + * @param {(error: Error) => void} reject + * @returns {void} + */ + function executor(resolve, reject) { + // @ts-expect-error: `doc` can’t be a callback anymore, we checked. + transformers.run(node, vfile(doc), done); + + /** + * @param {Error|null} error + * @param {Node} tree + * @param {VFile} file + * @returns {void} + */ + function done(error, tree, file) { + tree = tree || node; + if (error) { + reject(error); + } else if (resolve) { + resolve(tree); + } else { + // @ts-expect-error: `callback` is defined if `resolve` is not. + callback(null, tree, file); + } + } + } + } + + /** @type {Processor['runSync']} */ + function runSync(node, file) { + /** @type {Node|undefined} */ + let result; + /** @type {boolean|undefined} */ + let complete; + + processor.run(node, file, done); + + assertDone('runSync', 'run', complete); + + // @ts-expect-error: we either bailed on an error or have a tree. + return result + + /** + * @param {Error|null} [error] + * @param {Node} [tree] + * @returns {void} + */ + function done(error, tree) { + bail(error); + result = tree; + complete = true; + } + } + + /** + * @param {VFileCompatible} doc + * @param {ProcessCallback} [callback] + * @returns {Promise|undefined} + */ + function process(doc, callback) { + processor.freeze(); + assertParser('process', processor.Parser); + assertCompiler('process', processor.Compiler); + + if (!callback) { + return new Promise(executor) + } + + executor(null, callback); + + /** + * @param {null|((file: VFile) => void)} resolve + * @param {(error?: Error|null|undefined) => void} reject + * @returns {void} + */ + function executor(resolve, reject) { + const file = vfile(doc); + + processor.run(processor.parse(file), file, (error, tree, file) => { + if (error || !tree || !file) { + done(error); + } else { + /** @type {unknown} */ + const result = processor.stringify(tree, file); + + if (result === undefined || result === null) ; else if (looksLikeAVFileValue(result)) { + file.value = result; + } else { + file.result = result; + } + + done(error, file); + } + }); + + /** + * @param {Error|null|undefined} [error] + * @param {VFile|undefined} [file] + * @returns {void} + */ + function done(error, file) { + if (error || !file) { + reject(error); + } else if (resolve) { + resolve(file); + } else { + // @ts-expect-error: `callback` is defined if `resolve` is not. + callback(null, file); + } + } + } + } + + /** @type {Processor['processSync']} */ + function processSync(doc) { + /** @type {boolean|undefined} */ + let complete; + + processor.freeze(); + assertParser('processSync', processor.Parser); + assertCompiler('processSync', processor.Compiler); + + const file = vfile(doc); + + processor.process(file, done); + + assertDone('processSync', 'process', complete); + + return file + + /** + * @param {Error|null|undefined} [error] + * @returns {void} + */ + function done(error) { + complete = true; + bail(error); + } + } +} + +/** + * Check if `value` is a constructor. + * + * @param {unknown} value + * @param {string} name + * @returns {boolean} + */ +function newable(value, name) { + return ( + typeof value === 'function' && + // Prototypes do exist. + // type-coverage:ignore-next-line + value.prototype && + // A function with keys in its prototype is probably a constructor. + // Classes’ prototype methods are not enumerable, so we check if some value + // exists in the prototype. + // type-coverage:ignore-next-line + (keys(value.prototype) || name in value.prototype) + ) +} + +/** + * Check if `value` is an object with keys. + * + * @param {Record} value + * @returns {boolean} + */ +function keys(value) { + /** @type {string} */ + let key; + + for (key in value) { + if (own$7.call(value, key)) { + return true + } + } + + return false +} + +/** + * Assert a parser is available. + * + * @param {string} name + * @param {unknown} value + * @returns {asserts value is Parser} + */ +function assertParser(name, value) { + if (typeof value !== 'function') { + throw new TypeError('Cannot `' + name + '` without `Parser`') + } +} + +/** + * Assert a compiler is available. + * + * @param {string} name + * @param {unknown} value + * @returns {asserts value is Compiler} + */ +function assertCompiler(name, value) { + if (typeof value !== 'function') { + throw new TypeError('Cannot `' + name + '` without `Compiler`') + } +} + +/** + * Assert the processor is not frozen. + * + * @param {string} name + * @param {unknown} frozen + * @returns {asserts frozen is false} + */ +function assertUnfrozen(name, frozen) { + if (frozen) { + throw new Error( + 'Cannot call `' + + name + + '` on a frozen processor.\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.' + ) + } +} + +/** + * Assert `node` is a unist node. + * + * @param {unknown} node + * @returns {asserts node is Node} + */ +function assertNode(node) { + // `isPlainObj` unfortunately uses `any` instead of `unknown`. + // type-coverage:ignore-next-line + if (!isPlainObject(node) || typeof node.type !== 'string') { + throw new TypeError('Expected node, got `' + node + '`') + // Fine. + } +} + +/** + * Assert that `complete` is `true`. + * + * @param {string} name + * @param {string} asyncName + * @param {unknown} complete + * @returns {asserts complete is true} + */ +function assertDone(name, asyncName, complete) { + if (!complete) { + throw new Error( + '`' + name + '` finished async. Use `' + asyncName + '` instead' + ) + } +} + +/** + * @param {VFileCompatible} [value] + * @returns {VFile} + */ +function vfile(value) { + return looksLikeAVFile$1(value) ? value : new VFile(value) +} + +/** + * @param {VFileCompatible} [value] + * @returns {value is VFile} + */ +function looksLikeAVFile$1(value) { + return Boolean( + value && + typeof value === 'object' && + 'message' in value && + 'messages' in value + ) +} + +/** + * @param {unknown} [value] + * @returns {value is VFileValue} + */ +function looksLikeAVFileValue(value) { + return typeof value === 'string' || isBuffer(value) +} + +/** + * @typedef Options + * @property {boolean} [includeImageAlt=true] + */ + +/** + * Get the text content of a node. + * Prefer the node’s plain-text fields, otherwise serialize its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} node + * @param {Options} [options] + * @returns {string} + */ +function toString(node, options) { + var {includeImageAlt = true} = options || {}; + return one(node, includeImageAlt) +} + +/** + * @param {unknown} node + * @param {boolean} includeImageAlt + * @returns {string} + */ +function one(node, includeImageAlt) { + return ( + (node && + typeof node === 'object' && + // @ts-ignore looks like a literal. + (node.value || + // @ts-ignore looks like an image. + (includeImageAlt ? node.alt : '') || + // @ts-ignore looks like a parent. + ('children' in node && all(node.children, includeImageAlt)) || + (Array.isArray(node) && all(node, includeImageAlt)))) || + '' + ) +} + +/** + * @param {Array.} values + * @param {boolean} includeImageAlt + * @returns {string} + */ +function all(values, includeImageAlt) { + /** @type {Array.} */ + var result = []; + var index = -1; + + while (++index < values.length) { + result[index] = one(values[index], includeImageAlt); + } + + return result.join('') +} + +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * @param {T[]} list + * @param {number} start + * @param {number} remove + * @param {T[]} items + * @returns {void} + */ +function splice(list, start, remove, items) { + const end = list.length; + let chunkStart = 0; + /** @type {unknown[]} */ + + let parameters; // Make start between zero and `end` (included). + + if (start < 0) { + start = -start > end ? 0 : end + start; + } else { + start = start > end ? end : start; + } + + remove = remove > 0 ? remove : 0; // No need to chunk the items if there’s only a couple (10k) items. + + if (items.length < 10000) { + parameters = Array.from(items); + parameters.unshift(start, remove) // @ts-expect-error Hush, it’s fine. + ;[].splice.apply(list, parameters); + } else { + // Delete `remove` items starting from `start` + if (remove) [].splice.apply(list, [start, remove]); // Insert the items in chunks to not cause stack overflows. + + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000); + parameters.unshift(start, 0) // @ts-expect-error Hush, it’s fine. + ;[].splice.apply(list, parameters); + chunkStart += 10000; + start += 10000; + } + } +} +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * @param {T[]} list + * @param {T[]} items + * @returns {T[]} + */ + +function push(list, items) { + if (list.length > 0) { + splice(list, list.length, 0, items); + return list + } + + return items +} + +/** + * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + */ + +const hasOwnProperty = {}.hasOwnProperty; + +/** + * Combine several syntax extensions into one. + * + * @param {Extension[]} extensions List of syntax extensions. + * @returns {NormalizedExtension} A single combined extension. + */ +function combineExtensions(extensions) { + /** @type {NormalizedExtension} */ + const all = {}; + let index = -1; + + while (++index < extensions.length) { + syntaxExtension(all, extensions[index]); + } + + return all +} + +/** + * Merge `extension` into `all`. + * + * @param {NormalizedExtension} all Extension to merge into. + * @param {Extension} extension Extension to merge. + * @returns {void} + */ +function syntaxExtension(all, extension) { + /** @type {string} */ + let hook; + + for (hook in extension) { + const maybe = hasOwnProperty.call(all, hook) ? all[hook] : undefined; + const left = maybe || (all[hook] = {}); + const right = extension[hook]; + /** @type {string} */ + let code; + + for (code in right) { + if (!hasOwnProperty.call(left, code)) left[code] = []; + const value = right[code]; + constructs( + // @ts-expect-error Looks like a list. + left[code], + Array.isArray(value) ? value : value ? [value] : [] + ); + } + } +} + +/** + * Merge `list` into `existing` (both lists of constructs). + * Mutates `existing`. + * + * @param {unknown[]} existing + * @param {unknown[]} list + * @returns {void} + */ +function constructs(existing, list) { + let index = -1; + /** @type {unknown[]} */ + const before = []; + + while (++index < list.length) { +(list[index].add === 'after' ? existing : before).push(list[index]); + } + + splice(existing, 0, 0, before); +} + +/** + * Combine several HTML extensions into one. + * + * @param {HtmlExtension[]} htmlExtensions List of HTML extensions. + * @returns {HtmlExtension} A single combined extension. + */ +function combineHtmlExtensions(htmlExtensions) { + /** @type {HtmlExtension} */ + const handlers = {}; + let index = -1; + + while (++index < htmlExtensions.length) { + htmlExtension(handlers, htmlExtensions[index]); + } + + return handlers +} + +/** + * Merge `extension` into `all`. + * + * @param {HtmlExtension} all Extension to merge into. + * @param {HtmlExtension} extension Extension to merge. + * @returns {void} + */ +function htmlExtension(all, extension) { + /** @type {string} */ + let hook; + + for (hook in extension) { + const maybe = hasOwnProperty.call(all, hook) ? all[hook] : undefined; + const left = maybe || (all[hook] = {}); + const right = extension[hook]; + /** @type {string} */ + let type; + + if (right) { + for (type in right) { + left[type] = right[type]; + } + } + } +} + +// This module is generated by `script/`. +// +// CommonMark handles attention (emphasis, strong) markers based on what comes +// before or after them. +// One such difference is if those characters are Unicode punctuation. +// This script is generated from the Unicode data. +const unicodePunctuationRegex = + /[!-/:-@[-`{-~\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/; + +/** + * @typedef {import('micromark-util-types').Code} Code + */ +/** + * Check whether the character code represents an ASCII alpha (`a` through `z`, + * case insensitive). + * + * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. + * + * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) + * to U+005A (`Z`). + * + * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) + * to U+007A (`z`). + */ + +const asciiAlpha = regexCheck(/[A-Za-z]/); +/** + * Check whether the character code represents an ASCII digit (`0` through `9`). + * + * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to + * U+0039 (`9`). + */ + +const asciiDigit = regexCheck(/\d/); +/** + * Check whether the character code represents an ASCII hex digit (`a` through + * `f`, case insensitive, or `0` through `9`). + * + * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex + * digit, or an ASCII lower hex digit. + * + * An **ASCII upper hex digit** is a character in the inclusive range U+0041 + * (`A`) to U+0046 (`F`). + * + * An **ASCII lower hex digit** is a character in the inclusive range U+0061 + * (`a`) to U+0066 (`f`). + */ + +const asciiHexDigit = regexCheck(/[\dA-Fa-f]/); +/** + * Check whether the character code represents an ASCII alphanumeric (`a` + * through `z`, case insensitive, or `0` through `9`). + * + * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha + * (see `asciiAlpha`). + */ + +const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/); +/** + * Check whether the character code represents ASCII punctuation. + * + * An **ASCII punctuation** is a character in the inclusive ranges U+0021 + * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT + * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT + * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). + */ + +const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/); +/** + * Check whether the character code represents an ASCII atext. + * + * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in + * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), + * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F + * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E + * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE + * (`{`) to U+007E TILDE (`~`). + * + * See: + * **\[RFC5322]**: + * [Internet Message Format](https://tools.ietf.org/html/rfc5322). + * P. Resnick. + * IETF. + */ + +const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/); +/** + * Check whether a character code is an ASCII control character. + * + * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) + * to U+001F (US), or U+007F (DEL). + * + * @param {Code} code + * @returns {code is number} + */ + +function asciiControl(code) { + return ( + // Special whitespace codes (which have negative values), C0 and Control + // character DEL + code !== null && (code < 32 || code === 127) + ) +} +/** + * Check whether a character code is a markdown line ending (see + * `markdownLineEnding`) or markdown space (see `markdownSpace`). + * + * @param {Code} code + * @returns {code is number} + */ + +function markdownLineEndingOrSpace(code) { + return code !== null && (code < 0 || code === 32) +} +/** + * Check whether a character code is a markdown line ending. + * + * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN + * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). + * + * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE + * RETURN (CR) are replaced by these virtual characters depending on whether + * they occurred together. + * + * @param {Code} code + * @returns {code is number} + */ + +function markdownLineEnding(code) { + return code !== null && code < -2 +} +/** + * Check whether a character code is a markdown space. + * + * A **markdown space** is the concrete character U+0020 SPACE (SP) and the + * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). + * + * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is + * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL + * SPACE (VS) characters, depending on the column at which the tab occurred. + * + * @param {Code} code + * @returns {code is number} + */ + +function markdownSpace(code) { + return code === -2 || code === -1 || code === 32 +} +/** + * Check whether the character code represents Unicode whitespace. + * + * Note that this does handle micromark specific markdown whitespace characters. + * See `markdownLineEndingOrSpace` to check that. + * + * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, + * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), + * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + */ + +const unicodeWhitespace = regexCheck(/\s/); +/** + * Check whether the character code represents Unicode punctuation. + * + * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, + * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` + * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` + * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII + * punctuation (see `asciiPunctuation`). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + */ +// Size note: removing ASCII from the regex and using `asciiPunctuation` here +// In fact adds to the bundle size. + +const unicodePunctuation = regexCheck(unicodePunctuationRegex); +/** + * Create a code check from a regex. + * + * @param {RegExp} regex + * @returns {(code: Code) => code is number} + */ + +function regexCheck(regex) { + return check + /** + * Check whether a code matches the bound regex. + * + * @param {Code} code Character code + * @returns {code is number} Whether the character code matches the bound regex + */ + + function check(code) { + return code !== null && regex.test(String.fromCharCode(code)) + } +} + +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ +/** + * @param {Effects} effects + * @param {State} ok + * @param {string} type + * @param {number} [max=Infinity] + * @returns {State} + */ + +function factorySpace(effects, ok, type, max) { + const limit = max ? max - 1 : Number.POSITIVE_INFINITY; + let size = 0; + return start + /** @type {State} */ + + function start(code) { + if (markdownSpace(code)) { + effects.enter(type); + return prefix(code) + } + + return ok(code) + } + /** @type {State} */ + + function prefix(code) { + if (markdownSpace(code) && size++ < limit) { + effects.consume(code); + return prefix + } + + effects.exit(type); + return ok(code) + } +} + +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {InitialConstruct} */ +const content$1 = { + tokenize: initializeContent +}; +/** @type {Initializer} */ + +function initializeContent(effects) { + const contentStart = effects.attempt( + this.parser.constructs.contentInitial, + afterContentStartConstruct, + paragraphInitial + ); + /** @type {Token} */ + + let previous; + return contentStart + /** @type {State} */ + + function afterContentStartConstruct(code) { + if (code === null) { + effects.consume(code); + return + } + + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return factorySpace(effects, contentStart, 'linePrefix') + } + /** @type {State} */ + + function paragraphInitial(code) { + effects.enter('paragraph'); + return lineStart(code) + } + /** @type {State} */ + + function lineStart(code) { + const token = effects.enter('chunkText', { + contentType: 'text', + previous + }); + + if (previous) { + previous.next = token; + } + + previous = token; + return data(code) + } + /** @type {State} */ + + function data(code) { + if (code === null) { + effects.exit('chunkText'); + effects.exit('paragraph'); + effects.consume(code); + return + } + + if (markdownLineEnding(code)) { + effects.consume(code); + effects.exit('chunkText'); + return lineStart + } // Data. + + effects.consume(code); + return data + } +} + +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Point} Point + */ +/** @type {InitialConstruct} */ + +const document$1 = { + tokenize: initializeDocument +}; +/** @type {Construct} */ + +const containerConstruct = { + tokenize: tokenizeContainer +}; +/** @type {Initializer} */ + +function initializeDocument(effects) { + const self = this; + /** @type {StackItem[]} */ + + const stack = []; + let continued = 0; + /** @type {TokenizeContext|undefined} */ + + let childFlow; + /** @type {Token|undefined} */ + + let childToken; + /** @type {number} */ + + let lineStartOffset; + return start + /** @type {State} */ + + function start(code) { + // First we iterate through the open blocks, starting with the root + // document, and descending through last children down to the last open + // block. + // Each block imposes a condition that the line must satisfy if the block is + // to remain open. + // For example, a block quote requires a `>` character. + // A paragraph requires a non-blank line. + // In this phase we may match all or just some of the open blocks. + // But we cannot close unmatched blocks yet, because we may have a lazy + // continuation line. + if (continued < stack.length) { + const item = stack[continued]; + self.containerState = item[1]; + return effects.attempt( + item[0].continuation, + documentContinue, + checkNewContainers + )(code) + } // Done. + + return checkNewContainers(code) + } + /** @type {State} */ + + function documentContinue(code) { + continued++; // Note: this field is called `_closeFlow` but it also closes containers. + // Perhaps a good idea to rename it but it’s already used in the wild by + // extensions. + + if (self.containerState._closeFlow) { + self.containerState._closeFlow = undefined; + + if (childFlow) { + closeFlow(); + } // Note: this algorithm for moving events around is similar to the + // algorithm when dealing with lazy lines in `writeToChild`. + + const indexBeforeExits = self.events.length; + let indexBeforeFlow = indexBeforeExits; + /** @type {Point|undefined} */ + + let point; // Find the flow chunk. + + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + point = self.events[indexBeforeFlow][1].end; + break + } + } + + exitContainers(continued); // Fix positions. + + let index = indexBeforeExits; + + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point); + index++; + } // Inject the exits earlier (they’re still also at the end). + + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ); // Discard the duplicate exits. + + self.events.length = index; + return checkNewContainers(code) + } + + return start(code) + } + /** @type {State} */ + + function checkNewContainers(code) { + // Next, after consuming the continuation markers for existing blocks, we + // look for new block starts (e.g. `>` for a block quote). + // If we encounter a new block start, we close any blocks unmatched in + // step 1 before creating the new block as a child of the last matched + // block. + if (continued === stack.length) { + // No need to `check` whether there’s a container, of `exitContainers` + // would be moot. + // We can instead immediately `attempt` to parse one. + if (!childFlow) { + return documentContinued(code) + } // If we have concrete content, such as block HTML or fenced code, + // we can’t have containers “pierce” into them, so we can immediately + // start. + + if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { + return flowStart(code) + } // If we do have flow, it could still be a blank line, + // but we’d be interrupting it w/ a new container if there’s a current + // construct. + + self.interrupt = Boolean(childFlow.currentConstruct); + } // Check if there is a new container. + + self.containerState = {}; + return effects.check( + containerConstruct, + thereIsANewContainer, + thereIsNoNewContainer + )(code) + } + /** @type {State} */ + + function thereIsANewContainer(code) { + if (childFlow) closeFlow(); + exitContainers(continued); + return documentContinued(code) + } + /** @type {State} */ + + function thereIsNoNewContainer(code) { + self.parser.lazy[self.now().line] = continued !== stack.length; + lineStartOffset = self.now().offset; + return flowStart(code) + } + /** @type {State} */ + + function documentContinued(code) { + // Try new containers. + self.containerState = {}; + return effects.attempt( + containerConstruct, + containerContinue, + flowStart + )(code) + } + /** @type {State} */ + + function containerContinue(code) { + continued++; + stack.push([self.currentConstruct, self.containerState]); // Try another. + + return documentContinued(code) + } + /** @type {State} */ + + function flowStart(code) { + if (code === null) { + if (childFlow) closeFlow(); + exitContainers(0); + effects.consume(code); + return + } + + childFlow = childFlow || self.parser.flow(self.now()); + effects.enter('chunkFlow', { + contentType: 'flow', + previous: childToken, + _tokenizer: childFlow + }); + return flowContinue(code) + } + /** @type {State} */ + + function flowContinue(code) { + if (code === null) { + writeToChild(effects.exit('chunkFlow'), true); + exitContainers(0); + effects.consume(code); + return + } + + if (markdownLineEnding(code)) { + effects.consume(code); + writeToChild(effects.exit('chunkFlow')); // Get ready for the next line. + + continued = 0; + self.interrupt = undefined; + return start + } + + effects.consume(code); + return flowContinue + } + /** + * @param {Token} token + * @param {boolean} [eof] + * @returns {void} + */ + + function writeToChild(token, eof) { + const stream = self.sliceStream(token); + if (eof) stream.push(null); + token.previous = childToken; + if (childToken) childToken.next = token; + childToken = token; + childFlow.defineSkip(token.start); + childFlow.write(stream); // Alright, so we just added a lazy line: + // + // ```markdown + // > a + // b. + // + // Or: + // + // > ~~~c + // d + // + // Or: + // + // > | e | + // f + // ``` + // + // The construct in the second example (fenced code) does not accept lazy + // lines, so it marked itself as done at the end of its first line, and + // then the content construct parses `d`. + // Most constructs in markdown match on the first line: if the first line + // forms a construct, a non-lazy line can’t “unmake” it. + // + // The construct in the third example is potentially a GFM table, and + // those are *weird*. + // It *could* be a table, from the first line, if the following line + // matches a condition. + // In this case, that second line is lazy, which “unmakes” the first line + // and turns the whole into one content block. + // + // We’ve now parsed the non-lazy and the lazy line, and can figure out + // whether the lazy line started a new flow block. + // If it did, we exit the current containers between the two flow blocks. + + if (self.parser.lazy[token.start.line]) { + let index = childFlow.events.length; + + while (index--) { + if ( + // The token starts before the line ending… + childFlow.events[index][1].start.offset < lineStartOffset && + (!childFlow.events[index][1].end || // …or ends after it. + childFlow.events[index][1].end.offset > lineStartOffset) + ) { + // Exit: there’s still something open, which means it’s a lazy line + // part of something. + return + } + } // Note: this algorithm for moving events around is similar to the + // algorithm when closing flow in `documentContinue`. + + const indexBeforeExits = self.events.length; + let indexBeforeFlow = indexBeforeExits; + /** @type {boolean|undefined} */ + + let seen; + /** @type {Point|undefined} */ + + let point; // Find the previous chunk (the one before the lazy line). + + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + if (seen) { + point = self.events[indexBeforeFlow][1].end; + break + } + + seen = true; + } + } + + exitContainers(continued); // Fix positions. + + index = indexBeforeExits; + + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point); + index++; + } // Inject the exits earlier (they’re still also at the end). + + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ); // Discard the duplicate exits. + + self.events.length = index; + } + } + /** + * @param {number} size + * @returns {void} + */ + + function exitContainers(size) { + let index = stack.length; // Exit open containers. + + while (index-- > size) { + const entry = stack[index]; + self.containerState = entry[1]; + entry[0].exit.call(self, effects); + } + + stack.length = size; + } + + function closeFlow() { + childFlow.write([null]); + childToken = undefined; + childFlow = undefined; + self.containerState._closeFlow = undefined; + } +} +/** @type {Tokenizer} */ + +function tokenizeContainer(effects, ok, nok) { + return factorySpace( + effects, + effects.attempt(this.parser.constructs.document, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} + +/** + * @typedef {import('micromark-util-types').Code} Code + */ + +/** + * Classify whether a character code represents whitespace, punctuation, or + * something else. + * + * Used for attention (emphasis, strong), whose sequences can open or close + * based on the class of surrounding characters. + * + * Note that eof (`null`) is seen as whitespace. + * + * @param {Code} code + * @returns {number|undefined} + */ +function classifyCharacter(code) { + if ( + code === null || + markdownLineEndingOrSpace(code) || + unicodeWhitespace(code) + ) { + return 1 + } + + if (unicodePunctuation(code)) { + return 2 + } +} + +/** + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + */ + +/** + * Call all `resolveAll`s. + * + * @param {{resolveAll?: Resolver}[]} constructs + * @param {Event[]} events + * @param {TokenizeContext} context + * @returns {Event[]} + */ +function resolveAll(constructs, events, context) { + /** @type {Resolver[]} */ + const called = []; + let index = -1; + + while (++index < constructs.length) { + const resolve = constructs[index].resolveAll; + + if (resolve && !called.includes(resolve)) { + events = resolve(events, context); + called.push(resolve); + } + } + + return events +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Point} Point + */ + +/** @type {Construct} */ +const attention = { + name: 'attention', + tokenize: tokenizeAttention, + resolveAll: resolveAllAttention +}; +/** + * Take all events and resolve attention to emphasis or strong. + * + * @type {Resolver} + */ + +function resolveAllAttention(events, context) { + let index = -1; + /** @type {number} */ + + let open; + /** @type {Token} */ + + let group; + /** @type {Token} */ + + let text; + /** @type {Token} */ + + let openingSequence; + /** @type {Token} */ + + let closingSequence; + /** @type {number} */ + + let use; + /** @type {Event[]} */ + + let nextEvents; + /** @type {number} */ + + let offset; // Walk through all events. + // + // Note: performance of this is fine on an mb of normal markdown, but it’s + // a bottleneck for malicious stuff. + + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'attentionSequence' && + events[index][1]._close + ) { + open = index; // Now walk back to find an opener. + + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'attentionSequence' && + events[open][1]._open && // If the markers are the same: + context.sliceSerialize(events[open][1]).charCodeAt(0) === + context.sliceSerialize(events[index][1]).charCodeAt(0) + ) { + // If the opening can close or the closing can open, + // and the close size *is not* a multiple of three, + // but the sum of the opening and closing size *is* multiple of three, + // then don’t match. + if ( + (events[open][1]._close || events[index][1]._open) && + (events[index][1].end.offset - events[index][1].start.offset) % 3 && + !( + (events[open][1].end.offset - + events[open][1].start.offset + + events[index][1].end.offset - + events[index][1].start.offset) % + 3 + ) + ) { + continue + } // Number of markers to use from the sequence. + + use = + events[open][1].end.offset - events[open][1].start.offset > 1 && + events[index][1].end.offset - events[index][1].start.offset > 1 + ? 2 + : 1; + const start = Object.assign({}, events[open][1].end); + const end = Object.assign({}, events[index][1].start); + movePoint(start, -use); + movePoint(end, use); + openingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start, + end: Object.assign({}, events[open][1].end) + }; + closingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start: Object.assign({}, events[index][1].start), + end + }; + text = { + type: use > 1 ? 'strongText' : 'emphasisText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + }; + group = { + type: use > 1 ? 'strong' : 'emphasis', + start: Object.assign({}, openingSequence.start), + end: Object.assign({}, closingSequence.end) + }; + events[open][1].end = Object.assign({}, openingSequence.start); + events[index][1].start = Object.assign({}, closingSequence.end); + nextEvents = []; // If there are more markers in the opening, add them before. + + if (events[open][1].end.offset - events[open][1].start.offset) { + nextEvents = push(nextEvents, [ + ['enter', events[open][1], context], + ['exit', events[open][1], context] + ]); + } // Opening. + + nextEvents = push(nextEvents, [ + ['enter', group, context], + ['enter', openingSequence, context], + ['exit', openingSequence, context], + ['enter', text, context] + ]); // Between. + + nextEvents = push( + nextEvents, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ); // Closing. + + nextEvents = push(nextEvents, [ + ['exit', text, context], + ['enter', closingSequence, context], + ['exit', closingSequence, context], + ['exit', group, context] + ]); // If there are more markers in the closing, add them after. + + if (events[index][1].end.offset - events[index][1].start.offset) { + offset = 2; + nextEvents = push(nextEvents, [ + ['enter', events[index][1], context], + ['exit', events[index][1], context] + ]); + } else { + offset = 0; + } + + splice(events, open - 1, index - open + 3, nextEvents); + index = open + nextEvents.length - offset - 2; + break + } + } + } + } // Remove remaining sequences. + + index = -1; + + while (++index < events.length) { + if (events[index][1].type === 'attentionSequence') { + events[index][1].type = 'data'; + } + } + + return events +} +/** @type {Tokenizer} */ + +function tokenizeAttention(effects, ok) { + const attentionMarkers = this.parser.constructs.attentionMarkers.null; + const previous = this.previous; + const before = classifyCharacter(previous); + /** @type {NonNullable} */ + + let marker; + return start + /** @type {State} */ + + function start(code) { + effects.enter('attentionSequence'); + marker = code; + return sequence(code) + } + /** @type {State} */ + + function sequence(code) { + if (code === marker) { + effects.consume(code); + return sequence + } + + const token = effects.exit('attentionSequence'); + const after = classifyCharacter(code); + const open = + !after || (after === 2 && before) || attentionMarkers.includes(code); + const close = + !before || (before === 2 && after) || attentionMarkers.includes(previous); + token._open = Boolean(marker === 42 ? open : open && (before || !close)); + token._close = Boolean(marker === 42 ? close : close && (after || !open)); + return ok(code) + } +} +/** + * Move a point a bit. + * + * Note: `move` only works inside lines! It’s not possible to move past other + * chunks (replacement characters, tabs, or line endings). + * + * @param {Point} point + * @param {number} offset + * @returns {void} + */ + +function movePoint(point, offset) { + point.column += offset; + point.offset += offset; + point._bufferIndex += offset; +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const autolink = { + name: 'autolink', + tokenize: tokenizeAutolink +}; +/** @type {Tokenizer} */ + +function tokenizeAutolink(effects, ok, nok) { + let size = 1; + return start + /** @type {State} */ + + function start(code) { + effects.enter('autolink'); + effects.enter('autolinkMarker'); + effects.consume(code); + effects.exit('autolinkMarker'); + effects.enter('autolinkProtocol'); + return open + } + /** @type {State} */ + + function open(code) { + if (asciiAlpha(code)) { + effects.consume(code); + return schemeOrEmailAtext + } + + return asciiAtext(code) ? emailAtext(code) : nok(code) + } + /** @type {State} */ + + function schemeOrEmailAtext(code) { + return code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code) + ? schemeInsideOrEmailAtext(code) + : emailAtext(code) + } + /** @type {State} */ + + function schemeInsideOrEmailAtext(code) { + if (code === 58) { + effects.consume(code); + return urlInside + } + + if ( + (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && + size++ < 32 + ) { + effects.consume(code); + return schemeInsideOrEmailAtext + } + + return emailAtext(code) + } + /** @type {State} */ + + function urlInside(code) { + if (code === 62) { + effects.exit('autolinkProtocol'); + return end(code) + } + + if (code === null || code === 32 || code === 60 || asciiControl(code)) { + return nok(code) + } + + effects.consume(code); + return urlInside + } + /** @type {State} */ + + function emailAtext(code) { + if (code === 64) { + effects.consume(code); + size = 0; + return emailAtSignOrDot + } + + if (asciiAtext(code)) { + effects.consume(code); + return emailAtext + } + + return nok(code) + } + /** @type {State} */ + + function emailAtSignOrDot(code) { + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + } + /** @type {State} */ + + function emailLabel(code) { + if (code === 46) { + effects.consume(code); + size = 0; + return emailAtSignOrDot + } + + if (code === 62) { + // Exit, then change the type. + effects.exit('autolinkProtocol').type = 'autolinkEmail'; + return end(code) + } + + return emailValue(code) + } + /** @type {State} */ + + function emailValue(code) { + if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { + effects.consume(code); + return code === 45 ? emailValue : emailLabel + } + + return nok(code) + } + /** @type {State} */ + + function end(code) { + effects.enter('autolinkMarker'); + effects.consume(code); + effects.exit('autolinkMarker'); + effects.exit('autolink'); + return ok + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const blankLine = { + tokenize: tokenizeBlankLine, + partial: true +}; +/** @type {Tokenizer} */ + +function tokenizeBlankLine(effects, ok, nok) { + return factorySpace(effects, afterWhitespace, 'linePrefix') + /** @type {State} */ + + function afterWhitespace(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const blockQuote = { + name: 'blockQuote', + tokenize: tokenizeBlockQuoteStart, + continuation: { + tokenize: tokenizeBlockQuoteContinuation + }, + exit: exit$1 +}; +/** @type {Tokenizer} */ + +function tokenizeBlockQuoteStart(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + if (code === 62) { + const state = self.containerState; + + if (!state.open) { + effects.enter('blockQuote', { + _container: true + }); + state.open = true; + } + + effects.enter('blockQuotePrefix'); + effects.enter('blockQuoteMarker'); + effects.consume(code); + effects.exit('blockQuoteMarker'); + return after + } + + return nok(code) + } + /** @type {State} */ + + function after(code) { + if (markdownSpace(code)) { + effects.enter('blockQuotePrefixWhitespace'); + effects.consume(code); + effects.exit('blockQuotePrefixWhitespace'); + effects.exit('blockQuotePrefix'); + return ok + } + + effects.exit('blockQuotePrefix'); + return ok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeBlockQuoteContinuation(effects, ok, nok) { + return factorySpace( + effects, + effects.attempt(blockQuote, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} +/** @type {Exiter} */ + +function exit$1(effects) { + effects.exit('blockQuote'); +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const characterEscape = { + name: 'characterEscape', + tokenize: tokenizeCharacterEscape +}; +/** @type {Tokenizer} */ + +function tokenizeCharacterEscape(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.enter('characterEscape'); + effects.enter('escapeMarker'); + effects.consume(code); + effects.exit('escapeMarker'); + return open + } + /** @type {State} */ + + function open(code) { + if (asciiPunctuation(code)) { + effects.enter('characterEscapeValue'); + effects.consume(code); + effects.exit('characterEscapeValue'); + effects.exit('characterEscape'); + return ok + } + + return nok(code) + } +} + +var characterEntities = { + AEli: 'Æ', + AElig: 'Æ', + AM: '&', + AMP: '&', + Aacut: 'Á', + Aacute: 'Á', + Abreve: 'Ă', + Acir: 'Â', + Acirc: 'Â', + Acy: 'А', + Afr: '𝔄', + Agrav: 'À', + Agrave: 'À', + Alpha: 'Α', + Amacr: 'Ā', + And: '⩓', + Aogon: 'Ą', + Aopf: '𝔸', + ApplyFunction: '⁡', + Arin: 'Å', + Aring: 'Å', + Ascr: '𝒜', + Assign: '≔', + Atild: 'Ã', + Atilde: 'Ã', + Aum: 'Ä', + Auml: 'Ä', + Backslash: '∖', + Barv: '⫧', + Barwed: '⌆', + Bcy: 'Б', + Because: '∵', + Bernoullis: 'ℬ', + Beta: 'Β', + Bfr: '𝔅', + Bopf: '𝔹', + Breve: '˘', + Bscr: 'ℬ', + Bumpeq: '≎', + CHcy: 'Ч', + COP: '©', + COPY: '©', + Cacute: 'Ć', + Cap: '⋒', + CapitalDifferentialD: 'ⅅ', + Cayleys: 'ℭ', + Ccaron: 'Č', + Ccedi: 'Ç', + Ccedil: 'Ç', + Ccirc: 'Ĉ', + Cconint: '∰', + Cdot: 'Ċ', + Cedilla: '¸', + CenterDot: '·', + Cfr: 'ℭ', + Chi: 'Χ', + CircleDot: '⊙', + CircleMinus: '⊖', + CirclePlus: '⊕', + CircleTimes: '⊗', + ClockwiseContourIntegral: '∲', + CloseCurlyDoubleQuote: '”', + CloseCurlyQuote: '’', + Colon: '∷', + Colone: '⩴', + Congruent: '≡', + Conint: '∯', + ContourIntegral: '∮', + Copf: 'ℂ', + Coproduct: '∐', + CounterClockwiseContourIntegral: '∳', + Cross: '⨯', + Cscr: '𝒞', + Cup: '⋓', + CupCap: '≍', + DD: 'ⅅ', + DDotrahd: '⤑', + DJcy: 'Ђ', + DScy: 'Ѕ', + DZcy: 'Џ', + Dagger: '‡', + Darr: '↡', + Dashv: '⫤', + Dcaron: 'Ď', + Dcy: 'Д', + Del: '∇', + Delta: 'Δ', + Dfr: '𝔇', + DiacriticalAcute: '´', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + DiacriticalGrave: '`', + DiacriticalTilde: '˜', + Diamond: '⋄', + DifferentialD: 'ⅆ', + Dopf: '𝔻', + Dot: '¨', + DotDot: '⃜', + DotEqual: '≐', + DoubleContourIntegral: '∯', + DoubleDot: '¨', + DoubleDownArrow: '⇓', + DoubleLeftArrow: '⇐', + DoubleLeftRightArrow: '⇔', + DoubleLeftTee: '⫤', + DoubleLongLeftArrow: '⟸', + DoubleLongLeftRightArrow: '⟺', + DoubleLongRightArrow: '⟹', + DoubleRightArrow: '⇒', + DoubleRightTee: '⊨', + DoubleUpArrow: '⇑', + DoubleUpDownArrow: '⇕', + DoubleVerticalBar: '∥', + DownArrow: '↓', + DownArrowBar: '⤓', + DownArrowUpArrow: '⇵', + DownBreve: '̑', + DownLeftRightVector: '⥐', + DownLeftTeeVector: '⥞', + DownLeftVector: '↽', + DownLeftVectorBar: '⥖', + DownRightTeeVector: '⥟', + DownRightVector: '⇁', + DownRightVectorBar: '⥗', + DownTee: '⊤', + DownTeeArrow: '↧', + Downarrow: '⇓', + Dscr: '𝒟', + Dstrok: 'Đ', + ENG: 'Ŋ', + ET: 'Ð', + ETH: 'Ð', + Eacut: 'É', + Eacute: 'É', + Ecaron: 'Ě', + Ecir: 'Ê', + Ecirc: 'Ê', + Ecy: 'Э', + Edot: 'Ė', + Efr: '𝔈', + Egrav: 'È', + Egrave: 'È', + Element: '∈', + Emacr: 'Ē', + EmptySmallSquare: '◻', + EmptyVerySmallSquare: '▫', + Eogon: 'Ę', + Eopf: '𝔼', + Epsilon: 'Ε', + Equal: '⩵', + EqualTilde: '≂', + Equilibrium: '⇌', + Escr: 'ℰ', + Esim: '⩳', + Eta: 'Η', + Eum: 'Ë', + Euml: 'Ë', + Exists: '∃', + ExponentialE: 'ⅇ', + Fcy: 'Ф', + Ffr: '𝔉', + FilledSmallSquare: '◼', + FilledVerySmallSquare: '▪', + Fopf: '𝔽', + ForAll: '∀', + Fouriertrf: 'ℱ', + Fscr: 'ℱ', + GJcy: 'Ѓ', + G: '>', + GT: '>', + Gamma: 'Γ', + Gammad: 'Ϝ', + Gbreve: 'Ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + Gcy: 'Г', + Gdot: 'Ġ', + Gfr: '𝔊', + Gg: '⋙', + Gopf: '𝔾', + GreaterEqual: '≥', + GreaterEqualLess: '⋛', + GreaterFullEqual: '≧', + GreaterGreater: '⪢', + GreaterLess: '≷', + GreaterSlantEqual: '⩾', + GreaterTilde: '≳', + Gscr: '𝒢', + Gt: '≫', + HARDcy: 'Ъ', + Hacek: 'ˇ', + Hat: '^', + Hcirc: 'Ĥ', + Hfr: 'ℌ', + HilbertSpace: 'ℋ', + Hopf: 'ℍ', + HorizontalLine: '─', + Hscr: 'ℋ', + Hstrok: 'Ħ', + HumpDownHump: '≎', + HumpEqual: '≏', + IEcy: 'Е', + IJlig: 'IJ', + IOcy: 'Ё', + Iacut: 'Í', + Iacute: 'Í', + Icir: 'Î', + Icirc: 'Î', + Icy: 'И', + Idot: 'İ', + Ifr: 'ℑ', + Igrav: 'Ì', + Igrave: 'Ì', + Im: 'ℑ', + Imacr: 'Ī', + ImaginaryI: 'ⅈ', + Implies: '⇒', + Int: '∬', + Integral: '∫', + Intersection: '⋂', + InvisibleComma: '⁣', + InvisibleTimes: '⁢', + Iogon: 'Į', + Iopf: '𝕀', + Iota: 'Ι', + Iscr: 'ℐ', + Itilde: 'Ĩ', + Iukcy: 'І', + Ium: 'Ï', + Iuml: 'Ï', + Jcirc: 'Ĵ', + Jcy: 'Й', + Jfr: '𝔍', + Jopf: '𝕁', + Jscr: '𝒥', + Jsercy: 'Ј', + Jukcy: 'Є', + KHcy: 'Х', + KJcy: 'Ќ', + Kappa: 'Κ', + Kcedil: 'Ķ', + Kcy: 'К', + Kfr: '𝔎', + Kopf: '𝕂', + Kscr: '𝒦', + LJcy: 'Љ', + L: '<', + LT: '<', + Lacute: 'Ĺ', + Lambda: 'Λ', + Lang: '⟪', + Laplacetrf: 'ℒ', + Larr: '↞', + Lcaron: 'Ľ', + Lcedil: 'Ļ', + Lcy: 'Л', + LeftAngleBracket: '⟨', + LeftArrow: '←', + LeftArrowBar: '⇤', + LeftArrowRightArrow: '⇆', + LeftCeiling: '⌈', + LeftDoubleBracket: '⟦', + LeftDownTeeVector: '⥡', + LeftDownVector: '⇃', + LeftDownVectorBar: '⥙', + LeftFloor: '⌊', + LeftRightArrow: '↔', + LeftRightVector: '⥎', + LeftTee: '⊣', + LeftTeeArrow: '↤', + LeftTeeVector: '⥚', + LeftTriangle: '⊲', + LeftTriangleBar: '⧏', + LeftTriangleEqual: '⊴', + LeftUpDownVector: '⥑', + LeftUpTeeVector: '⥠', + LeftUpVector: '↿', + LeftUpVectorBar: '⥘', + LeftVector: '↼', + LeftVectorBar: '⥒', + Leftarrow: '⇐', + Leftrightarrow: '⇔', + LessEqualGreater: '⋚', + LessFullEqual: '≦', + LessGreater: '≶', + LessLess: '⪡', + LessSlantEqual: '⩽', + LessTilde: '≲', + Lfr: '𝔏', + Ll: '⋘', + Lleftarrow: '⇚', + Lmidot: 'Ŀ', + LongLeftArrow: '⟵', + LongLeftRightArrow: '⟷', + LongRightArrow: '⟶', + Longleftarrow: '⟸', + Longleftrightarrow: '⟺', + Longrightarrow: '⟹', + Lopf: '𝕃', + LowerLeftArrow: '↙', + LowerRightArrow: '↘', + Lscr: 'ℒ', + Lsh: '↰', + Lstrok: 'Ł', + Lt: '≪', + Map: '⤅', + Mcy: 'М', + MediumSpace: ' ', + Mellintrf: 'ℳ', + Mfr: '𝔐', + MinusPlus: '∓', + Mopf: '𝕄', + Mscr: 'ℳ', + Mu: 'Μ', + NJcy: 'Њ', + Nacute: 'Ń', + Ncaron: 'Ň', + Ncedil: 'Ņ', + Ncy: 'Н', + NegativeMediumSpace: '​', + NegativeThickSpace: '​', + NegativeThinSpace: '​', + NegativeVeryThinSpace: '​', + NestedGreaterGreater: '≫', + NestedLessLess: '≪', + NewLine: '\n', + Nfr: '𝔑', + NoBreak: '⁠', + NonBreakingSpace: ' ', + Nopf: 'ℕ', + Not: '⫬', + NotCongruent: '≢', + NotCupCap: '≭', + NotDoubleVerticalBar: '∦', + NotElement: '∉', + NotEqual: '≠', + NotEqualTilde: '≂̸', + NotExists: '∄', + NotGreater: '≯', + NotGreaterEqual: '≱', + NotGreaterFullEqual: '≧̸', + NotGreaterGreater: '≫̸', + NotGreaterLess: '≹', + NotGreaterSlantEqual: '⩾̸', + NotGreaterTilde: '≵', + NotHumpDownHump: '≎̸', + NotHumpEqual: '≏̸', + NotLeftTriangle: '⋪', + NotLeftTriangleBar: '⧏̸', + NotLeftTriangleEqual: '⋬', + NotLess: '≮', + NotLessEqual: '≰', + NotLessGreater: '≸', + NotLessLess: '≪̸', + NotLessSlantEqual: '⩽̸', + NotLessTilde: '≴', + NotNestedGreaterGreater: '⪢̸', + NotNestedLessLess: '⪡̸', + NotPrecedes: '⊀', + NotPrecedesEqual: '⪯̸', + NotPrecedesSlantEqual: '⋠', + NotReverseElement: '∌', + NotRightTriangle: '⋫', + NotRightTriangleBar: '⧐̸', + NotRightTriangleEqual: '⋭', + NotSquareSubset: '⊏̸', + NotSquareSubsetEqual: '⋢', + NotSquareSuperset: '⊐̸', + NotSquareSupersetEqual: '⋣', + NotSubset: '⊂⃒', + NotSubsetEqual: '⊈', + NotSucceeds: '⊁', + NotSucceedsEqual: '⪰̸', + NotSucceedsSlantEqual: '⋡', + NotSucceedsTilde: '≿̸', + NotSuperset: '⊃⃒', + NotSupersetEqual: '⊉', + NotTilde: '≁', + NotTildeEqual: '≄', + NotTildeFullEqual: '≇', + NotTildeTilde: '≉', + NotVerticalBar: '∤', + Nscr: '𝒩', + Ntild: 'Ñ', + Ntilde: 'Ñ', + Nu: 'Ν', + OElig: 'Œ', + Oacut: 'Ó', + Oacute: 'Ó', + Ocir: 'Ô', + Ocirc: 'Ô', + Ocy: 'О', + Odblac: 'Ő', + Ofr: '𝔒', + Ograv: 'Ò', + Ograve: 'Ò', + Omacr: 'Ō', + Omega: 'Ω', + Omicron: 'Ο', + Oopf: '𝕆', + OpenCurlyDoubleQuote: '“', + OpenCurlyQuote: '‘', + Or: '⩔', + Oscr: '𝒪', + Oslas: 'Ø', + Oslash: 'Ø', + Otild: 'Õ', + Otilde: 'Õ', + Otimes: '⨷', + Oum: 'Ö', + Ouml: 'Ö', + OverBar: '‾', + OverBrace: '⏞', + OverBracket: '⎴', + OverParenthesis: '⏜', + PartialD: '∂', + Pcy: 'П', + Pfr: '𝔓', + Phi: 'Φ', + Pi: 'Π', + PlusMinus: '±', + Poincareplane: 'ℌ', + Popf: 'ℙ', + Pr: '⪻', + Precedes: '≺', + PrecedesEqual: '⪯', + PrecedesSlantEqual: '≼', + PrecedesTilde: '≾', + Prime: '″', + Product: '∏', + Proportion: '∷', + Proportional: '∝', + Pscr: '𝒫', + Psi: 'Ψ', + QUO: '"', + QUOT: '"', + Qfr: '𝔔', + Qopf: 'ℚ', + Qscr: '𝒬', + RBarr: '⤐', + RE: '®', + REG: '®', + Racute: 'Ŕ', + Rang: '⟫', + Rarr: '↠', + Rarrtl: '⤖', + Rcaron: 'Ř', + Rcedil: 'Ŗ', + Rcy: 'Р', + Re: 'ℜ', + ReverseElement: '∋', + ReverseEquilibrium: '⇋', + ReverseUpEquilibrium: '⥯', + Rfr: 'ℜ', + Rho: 'Ρ', + RightAngleBracket: '⟩', + RightArrow: '→', + RightArrowBar: '⇥', + RightArrowLeftArrow: '⇄', + RightCeiling: '⌉', + RightDoubleBracket: '⟧', + RightDownTeeVector: '⥝', + RightDownVector: '⇂', + RightDownVectorBar: '⥕', + RightFloor: '⌋', + RightTee: '⊢', + RightTeeArrow: '↦', + RightTeeVector: '⥛', + RightTriangle: '⊳', + RightTriangleBar: '⧐', + RightTriangleEqual: '⊵', + RightUpDownVector: '⥏', + RightUpTeeVector: '⥜', + RightUpVector: '↾', + RightUpVectorBar: '⥔', + RightVector: '⇀', + RightVectorBar: '⥓', + Rightarrow: '⇒', + Ropf: 'ℝ', + RoundImplies: '⥰', + Rrightarrow: '⇛', + Rscr: 'ℛ', + Rsh: '↱', + RuleDelayed: '⧴', + SHCHcy: 'Щ', + SHcy: 'Ш', + SOFTcy: 'Ь', + Sacute: 'Ś', + Sc: '⪼', + Scaron: 'Š', + Scedil: 'Ş', + Scirc: 'Ŝ', + Scy: 'С', + Sfr: '𝔖', + ShortDownArrow: '↓', + ShortLeftArrow: '←', + ShortRightArrow: '→', + ShortUpArrow: '↑', + Sigma: 'Σ', + SmallCircle: '∘', + Sopf: '𝕊', + Sqrt: '√', + Square: '□', + SquareIntersection: '⊓', + SquareSubset: '⊏', + SquareSubsetEqual: '⊑', + SquareSuperset: '⊐', + SquareSupersetEqual: '⊒', + SquareUnion: '⊔', + Sscr: '𝒮', + Star: '⋆', + Sub: '⋐', + Subset: '⋐', + SubsetEqual: '⊆', + Succeeds: '≻', + SucceedsEqual: '⪰', + SucceedsSlantEqual: '≽', + SucceedsTilde: '≿', + SuchThat: '∋', + Sum: '∑', + Sup: '⋑', + Superset: '⊃', + SupersetEqual: '⊇', + Supset: '⋑', + THOR: 'Þ', + THORN: 'Þ', + TRADE: '™', + TSHcy: 'Ћ', + TScy: 'Ц', + Tab: '\t', + Tau: 'Τ', + Tcaron: 'Ť', + Tcedil: 'Ţ', + Tcy: 'Т', + Tfr: '𝔗', + Therefore: '∴', + Theta: 'Θ', + ThickSpace: '  ', + ThinSpace: ' ', + Tilde: '∼', + TildeEqual: '≃', + TildeFullEqual: '≅', + TildeTilde: '≈', + Topf: '𝕋', + TripleDot: '⃛', + Tscr: '𝒯', + Tstrok: 'Ŧ', + Uacut: 'Ú', + Uacute: 'Ú', + Uarr: '↟', + Uarrocir: '⥉', + Ubrcy: 'Ў', + Ubreve: 'Ŭ', + Ucir: 'Û', + Ucirc: 'Û', + Ucy: 'У', + Udblac: 'Ű', + Ufr: '𝔘', + Ugrav: 'Ù', + Ugrave: 'Ù', + Umacr: 'Ū', + UnderBar: '_', + UnderBrace: '⏟', + UnderBracket: '⎵', + UnderParenthesis: '⏝', + Union: '⋃', + UnionPlus: '⊎', + Uogon: 'Ų', + Uopf: '𝕌', + UpArrow: '↑', + UpArrowBar: '⤒', + UpArrowDownArrow: '⇅', + UpDownArrow: '↕', + UpEquilibrium: '⥮', + UpTee: '⊥', + UpTeeArrow: '↥', + Uparrow: '⇑', + Updownarrow: '⇕', + UpperLeftArrow: '↖', + UpperRightArrow: '↗', + Upsi: 'ϒ', + Upsilon: 'Υ', + Uring: 'Ů', + Uscr: '𝒰', + Utilde: 'Ũ', + Uum: 'Ü', + Uuml: 'Ü', + VDash: '⊫', + Vbar: '⫫', + Vcy: 'В', + Vdash: '⊩', + Vdashl: '⫦', + Vee: '⋁', + Verbar: '‖', + Vert: '‖', + VerticalBar: '∣', + VerticalLine: '|', + VerticalSeparator: '❘', + VerticalTilde: '≀', + VeryThinSpace: ' ', + Vfr: '𝔙', + Vopf: '𝕍', + Vscr: '𝒱', + Vvdash: '⊪', + Wcirc: 'Ŵ', + Wedge: '⋀', + Wfr: '𝔚', + Wopf: '𝕎', + Wscr: '𝒲', + Xfr: '𝔛', + Xi: 'Ξ', + Xopf: '𝕏', + Xscr: '𝒳', + YAcy: 'Я', + YIcy: 'Ї', + YUcy: 'Ю', + Yacut: 'Ý', + Yacute: 'Ý', + Ycirc: 'Ŷ', + Ycy: 'Ы', + Yfr: '𝔜', + Yopf: '𝕐', + Yscr: '𝒴', + Yuml: 'Ÿ', + ZHcy: 'Ж', + Zacute: 'Ź', + Zcaron: 'Ž', + Zcy: 'З', + Zdot: 'Ż', + ZeroWidthSpace: '​', + Zeta: 'Ζ', + Zfr: 'ℨ', + Zopf: 'ℤ', + Zscr: '𝒵', + aacut: 'á', + aacute: 'á', + abreve: 'ă', + ac: '∾', + acE: '∾̳', + acd: '∿', + acir: 'â', + acirc: 'â', + acut: '´', + acute: '´', + acy: 'а', + aeli: 'æ', + aelig: 'æ', + af: '⁡', + afr: '𝔞', + agrav: 'à', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + alpha: 'α', + amacr: 'ā', + amalg: '⨿', + am: '&', + amp: '&', + and: '∧', + andand: '⩕', + andd: '⩜', + andslope: '⩘', + andv: '⩚', + ang: '∠', + ange: '⦤', + angle: '∠', + angmsd: '∡', + angmsdaa: '⦨', + angmsdab: '⦩', + angmsdac: '⦪', + angmsdad: '⦫', + angmsdae: '⦬', + angmsdaf: '⦭', + angmsdag: '⦮', + angmsdah: '⦯', + angrt: '∟', + angrtvb: '⊾', + angrtvbd: '⦝', + angsph: '∢', + angst: 'Å', + angzarr: '⍼', + aogon: 'ą', + aopf: '𝕒', + ap: '≈', + apE: '⩰', + apacir: '⩯', + ape: '≊', + apid: '≋', + apos: "'", + approx: '≈', + approxeq: '≊', + arin: 'å', + aring: 'å', + ascr: '𝒶', + ast: '*', + asymp: '≈', + asympeq: '≍', + atild: 'ã', + atilde: 'ã', + aum: 'ä', + auml: 'ä', + awconint: '∳', + awint: '⨑', + bNot: '⫭', + backcong: '≌', + backepsilon: '϶', + backprime: '‵', + backsim: '∽', + backsimeq: '⋍', + barvee: '⊽', + barwed: '⌅', + barwedge: '⌅', + bbrk: '⎵', + bbrktbrk: '⎶', + bcong: '≌', + bcy: 'б', + bdquo: '„', + becaus: '∵', + because: '∵', + bemptyv: '⦰', + bepsi: '϶', + bernou: 'ℬ', + beta: 'β', + beth: 'ℶ', + between: '≬', + bfr: '𝔟', + bigcap: '⋂', + bigcirc: '◯', + bigcup: '⋃', + bigodot: '⨀', + bigoplus: '⨁', + bigotimes: '⨂', + bigsqcup: '⨆', + bigstar: '★', + bigtriangledown: '▽', + bigtriangleup: '△', + biguplus: '⨄', + bigvee: '⋁', + bigwedge: '⋀', + bkarow: '⤍', + blacklozenge: '⧫', + blacksquare: '▪', + blacktriangle: '▴', + blacktriangledown: '▾', + blacktriangleleft: '◂', + blacktriangleright: '▸', + blank: '␣', + blk12: '▒', + blk14: '░', + blk34: '▓', + block: '█', + bne: '=⃥', + bnequiv: '≡⃥', + bnot: '⌐', + bopf: '𝕓', + bot: '⊥', + bottom: '⊥', + bowtie: '⋈', + boxDL: '╗', + boxDR: '╔', + boxDl: '╖', + boxDr: '╓', + boxH: '═', + boxHD: '╦', + boxHU: '╩', + boxHd: '╤', + boxHu: '╧', + boxUL: '╝', + boxUR: '╚', + boxUl: '╜', + boxUr: '╙', + boxV: '║', + boxVH: '╬', + boxVL: '╣', + boxVR: '╠', + boxVh: '╫', + boxVl: '╢', + boxVr: '╟', + boxbox: '⧉', + boxdL: '╕', + boxdR: '╒', + boxdl: '┐', + boxdr: '┌', + boxh: '─', + boxhD: '╥', + boxhU: '╨', + boxhd: '┬', + boxhu: '┴', + boxminus: '⊟', + boxplus: '⊞', + boxtimes: '⊠', + boxuL: '╛', + boxuR: '╘', + boxul: '┘', + boxur: '└', + boxv: '│', + boxvH: '╪', + boxvL: '╡', + boxvR: '╞', + boxvh: '┼', + boxvl: '┤', + boxvr: '├', + bprime: '‵', + breve: '˘', + brvba: '¦', + brvbar: '¦', + bscr: '𝒷', + bsemi: '⁏', + bsim: '∽', + bsime: '⋍', + bsol: '\\', + bsolb: '⧅', + bsolhsub: '⟈', + bull: '•', + bullet: '•', + bump: '≎', + bumpE: '⪮', + bumpe: '≏', + bumpeq: '≏', + cacute: 'ć', + cap: '∩', + capand: '⩄', + capbrcup: '⩉', + capcap: '⩋', + capcup: '⩇', + capdot: '⩀', + caps: '∩︀', + caret: '⁁', + caron: 'ˇ', + ccaps: '⩍', + ccaron: 'č', + ccedi: 'ç', + ccedil: 'ç', + ccirc: 'ĉ', + ccups: '⩌', + ccupssm: '⩐', + cdot: 'ċ', + cedi: '¸', + cedil: '¸', + cemptyv: '⦲', + cen: '¢', + cent: '¢', + centerdot: '·', + cfr: '𝔠', + chcy: 'ч', + check: '✓', + checkmark: '✓', + chi: 'χ', + cir: '○', + cirE: '⧃', + circ: 'ˆ', + circeq: '≗', + circlearrowleft: '↺', + circlearrowright: '↻', + circledR: '®', + circledS: 'Ⓢ', + circledast: '⊛', + circledcirc: '⊚', + circleddash: '⊝', + cire: '≗', + cirfnint: '⨐', + cirmid: '⫯', + cirscir: '⧂', + clubs: '♣', + clubsuit: '♣', + colon: ':', + colone: '≔', + coloneq: '≔', + comma: ',', + commat: '@', + comp: '∁', + compfn: '∘', + complement: '∁', + complexes: 'ℂ', + cong: '≅', + congdot: '⩭', + conint: '∮', + copf: '𝕔', + coprod: '∐', + cop: '©', + copy: '©', + copysr: '℗', + crarr: '↵', + cross: '✗', + cscr: '𝒸', + csub: '⫏', + csube: '⫑', + csup: '⫐', + csupe: '⫒', + ctdot: '⋯', + cudarrl: '⤸', + cudarrr: '⤵', + cuepr: '⋞', + cuesc: '⋟', + cularr: '↶', + cularrp: '⤽', + cup: '∪', + cupbrcap: '⩈', + cupcap: '⩆', + cupcup: '⩊', + cupdot: '⊍', + cupor: '⩅', + cups: '∪︀', + curarr: '↷', + curarrm: '⤼', + curlyeqprec: '⋞', + curlyeqsucc: '⋟', + curlyvee: '⋎', + curlywedge: '⋏', + curre: '¤', + curren: '¤', + curvearrowleft: '↶', + curvearrowright: '↷', + cuvee: '⋎', + cuwed: '⋏', + cwconint: '∲', + cwint: '∱', + cylcty: '⌭', + dArr: '⇓', + dHar: '⥥', + dagger: '†', + daleth: 'ℸ', + darr: '↓', + dash: '‐', + dashv: '⊣', + dbkarow: '⤏', + dblac: '˝', + dcaron: 'ď', + dcy: 'д', + dd: 'ⅆ', + ddagger: '‡', + ddarr: '⇊', + ddotseq: '⩷', + de: '°', + deg: '°', + delta: 'δ', + demptyv: '⦱', + dfisht: '⥿', + dfr: '𝔡', + dharl: '⇃', + dharr: '⇂', + diam: '⋄', + diamond: '⋄', + diamondsuit: '♦', + diams: '♦', + die: '¨', + digamma: 'ϝ', + disin: '⋲', + div: '÷', + divid: '÷', + divide: '÷', + divideontimes: '⋇', + divonx: '⋇', + djcy: 'ђ', + dlcorn: '⌞', + dlcrop: '⌍', + dollar: '$', + dopf: '𝕕', + dot: '˙', + doteq: '≐', + doteqdot: '≑', + dotminus: '∸', + dotplus: '∔', + dotsquare: '⊡', + doublebarwedge: '⌆', + downarrow: '↓', + downdownarrows: '⇊', + downharpoonleft: '⇃', + downharpoonright: '⇂', + drbkarow: '⤐', + drcorn: '⌟', + drcrop: '⌌', + dscr: '𝒹', + dscy: 'ѕ', + dsol: '⧶', + dstrok: 'đ', + dtdot: '⋱', + dtri: '▿', + dtrif: '▾', + duarr: '⇵', + duhar: '⥯', + dwangle: '⦦', + dzcy: 'џ', + dzigrarr: '⟿', + eDDot: '⩷', + eDot: '≑', + eacut: 'é', + eacute: 'é', + easter: '⩮', + ecaron: 'ě', + ecir: 'ê', + ecirc: 'ê', + ecolon: '≕', + ecy: 'э', + edot: 'ė', + ee: 'ⅇ', + efDot: '≒', + efr: '𝔢', + eg: '⪚', + egrav: 'è', + egrave: 'è', + egs: '⪖', + egsdot: '⪘', + el: '⪙', + elinters: '⏧', + ell: 'ℓ', + els: '⪕', + elsdot: '⪗', + emacr: 'ē', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + emsp13: ' ', + emsp14: ' ', + emsp: ' ', + eng: 'ŋ', + ensp: ' ', + eogon: 'ę', + eopf: '𝕖', + epar: '⋕', + eparsl: '⧣', + eplus: '⩱', + epsi: 'ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '≖', + eqcolon: '≕', + eqsim: '≂', + eqslantgtr: '⪖', + eqslantless: '⪕', + equals: '=', + equest: '≟', + equiv: '≡', + equivDD: '⩸', + eqvparsl: '⧥', + erDot: '≓', + erarr: '⥱', + escr: 'ℯ', + esdot: '≐', + esim: '≂', + eta: 'η', + et: 'ð', + eth: 'ð', + eum: 'ë', + euml: 'ë', + euro: '€', + excl: '!', + exist: '∃', + expectation: 'ℰ', + exponentiale: 'ⅇ', + fallingdotseq: '≒', + fcy: 'ф', + female: '♀', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + ffr: '𝔣', + filig: 'fi', + fjlig: 'fj', + flat: '♭', + fllig: 'fl', + fltns: '▱', + fnof: 'ƒ', + fopf: '𝕗', + forall: '∀', + fork: '⋔', + forkv: '⫙', + fpartint: '⨍', + frac1: '¼', + frac12: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac3: '¾', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', + frown: '⌢', + fscr: '𝒻', + gE: '≧', + gEl: '⪌', + gacute: 'ǵ', + gamma: 'γ', + gammad: 'ϝ', + gap: '⪆', + gbreve: 'ğ', + gcirc: 'ĝ', + gcy: 'г', + gdot: 'ġ', + ge: '≥', + gel: '⋛', + geq: '≥', + geqq: '≧', + geqslant: '⩾', + ges: '⩾', + gescc: '⪩', + gesdot: '⪀', + gesdoto: '⪂', + gesdotol: '⪄', + gesl: '⋛︀', + gesles: '⪔', + gfr: '𝔤', + gg: '≫', + ggg: '⋙', + gimel: 'ℷ', + gjcy: 'ѓ', + gl: '≷', + glE: '⪒', + gla: '⪥', + glj: '⪤', + gnE: '≩', + gnap: '⪊', + gnapprox: '⪊', + gne: '⪈', + gneq: '⪈', + gneqq: '≩', + gnsim: '⋧', + gopf: '𝕘', + grave: '`', + gscr: 'ℊ', + gsim: '≳', + gsime: '⪎', + gsiml: '⪐', + g: '>', + gt: '>', + gtcc: '⪧', + gtcir: '⩺', + gtdot: '⋗', + gtlPar: '⦕', + gtquest: '⩼', + gtrapprox: '⪆', + gtrarr: '⥸', + gtrdot: '⋗', + gtreqless: '⋛', + gtreqqless: '⪌', + gtrless: '≷', + gtrsim: '≳', + gvertneqq: '≩︀', + gvnE: '≩︀', + hArr: '⇔', + hairsp: ' ', + half: '½', + hamilt: 'ℋ', + hardcy: 'ъ', + harr: '↔', + harrcir: '⥈', + harrw: '↭', + hbar: 'ℏ', + hcirc: 'ĥ', + hearts: '♥', + heartsuit: '♥', + hellip: '…', + hercon: '⊹', + hfr: '𝔥', + hksearow: '⤥', + hkswarow: '⤦', + hoarr: '⇿', + homtht: '∻', + hookleftarrow: '↩', + hookrightarrow: '↪', + hopf: '𝕙', + horbar: '―', + hscr: '𝒽', + hslash: 'ℏ', + hstrok: 'ħ', + hybull: '⁃', + hyphen: '‐', + iacut: 'í', + iacute: 'í', + ic: '⁣', + icir: 'î', + icirc: 'î', + icy: 'и', + iecy: 'е', + iexc: '¡', + iexcl: '¡', + iff: '⇔', + ifr: '𝔦', + igrav: 'ì', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '⨌', + iiint: '∭', + iinfin: '⧜', + iiota: '℩', + ijlig: 'ij', + imacr: 'ī', + image: 'ℑ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '⊷', + imped: 'Ƶ', + in: '∈', + incare: '℅', + infin: '∞', + infintie: '⧝', + inodot: 'ı', + int: '∫', + intcal: '⊺', + integers: 'ℤ', + intercal: '⊺', + intlarhk: '⨗', + intprod: '⨼', + iocy: 'ё', + iogon: 'į', + iopf: '𝕚', + iota: 'ι', + iprod: '⨼', + iques: '¿', + iquest: '¿', + iscr: '𝒾', + isin: '∈', + isinE: '⋹', + isindot: '⋵', + isins: '⋴', + isinsv: '⋳', + isinv: '∈', + it: '⁢', + itilde: 'ĩ', + iukcy: 'і', + ium: 'ï', + iuml: 'ï', + jcirc: 'ĵ', + jcy: 'й', + jfr: '𝔧', + jmath: 'ȷ', + jopf: '𝕛', + jscr: '𝒿', + jsercy: 'ј', + jukcy: 'є', + kappa: 'κ', + kappav: 'ϰ', + kcedil: 'ķ', + kcy: 'к', + kfr: '𝔨', + kgreen: 'ĸ', + khcy: 'х', + kjcy: 'ќ', + kopf: '𝕜', + kscr: '𝓀', + lAarr: '⇚', + lArr: '⇐', + lAtail: '⤛', + lBarr: '⤎', + lE: '≦', + lEg: '⪋', + lHar: '⥢', + lacute: 'ĺ', + laemptyv: '⦴', + lagran: 'ℒ', + lambda: 'λ', + lang: '⟨', + langd: '⦑', + langle: '⟨', + lap: '⪅', + laqu: '«', + laquo: '«', + larr: '←', + larrb: '⇤', + larrbfs: '⤟', + larrfs: '⤝', + larrhk: '↩', + larrlp: '↫', + larrpl: '⤹', + larrsim: '⥳', + larrtl: '↢', + lat: '⪫', + latail: '⤙', + late: '⪭', + lates: '⪭︀', + lbarr: '⤌', + lbbrk: '❲', + lbrace: '{', + lbrack: '[', + lbrke: '⦋', + lbrksld: '⦏', + lbrkslu: '⦍', + lcaron: 'ľ', + lcedil: 'ļ', + lceil: '⌈', + lcub: '{', + lcy: 'л', + ldca: '⤶', + ldquo: '“', + ldquor: '„', + ldrdhar: '⥧', + ldrushar: '⥋', + ldsh: '↲', + le: '≤', + leftarrow: '←', + leftarrowtail: '↢', + leftharpoondown: '↽', + leftharpoonup: '↼', + leftleftarrows: '⇇', + leftrightarrow: '↔', + leftrightarrows: '⇆', + leftrightharpoons: '⇋', + leftrightsquigarrow: '↭', + leftthreetimes: '⋋', + leg: '⋚', + leq: '≤', + leqq: '≦', + leqslant: '⩽', + les: '⩽', + lescc: '⪨', + lesdot: '⩿', + lesdoto: '⪁', + lesdotor: '⪃', + lesg: '⋚︀', + lesges: '⪓', + lessapprox: '⪅', + lessdot: '⋖', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + lessgtr: '≶', + lesssim: '≲', + lfisht: '⥼', + lfloor: '⌊', + lfr: '𝔩', + lg: '≶', + lgE: '⪑', + lhard: '↽', + lharu: '↼', + lharul: '⥪', + lhblk: '▄', + ljcy: 'љ', + ll: '≪', + llarr: '⇇', + llcorner: '⌞', + llhard: '⥫', + lltri: '◺', + lmidot: 'ŀ', + lmoust: '⎰', + lmoustache: '⎰', + lnE: '≨', + lnap: '⪉', + lnapprox: '⪉', + lne: '⪇', + lneq: '⪇', + lneqq: '≨', + lnsim: '⋦', + loang: '⟬', + loarr: '⇽', + lobrk: '⟦', + longleftarrow: '⟵', + longleftrightarrow: '⟷', + longmapsto: '⟼', + longrightarrow: '⟶', + looparrowleft: '↫', + looparrowright: '↬', + lopar: '⦅', + lopf: '𝕝', + loplus: '⨭', + lotimes: '⨴', + lowast: '∗', + lowbar: '_', + loz: '◊', + lozenge: '◊', + lozf: '⧫', + lpar: '(', + lparlt: '⦓', + lrarr: '⇆', + lrcorner: '⌟', + lrhar: '⇋', + lrhard: '⥭', + lrm: '‎', + lrtri: '⊿', + lsaquo: '‹', + lscr: '𝓁', + lsh: '↰', + lsim: '≲', + lsime: '⪍', + lsimg: '⪏', + lsqb: '[', + lsquo: '‘', + lsquor: '‚', + lstrok: 'ł', + l: '<', + lt: '<', + ltcc: '⪦', + ltcir: '⩹', + ltdot: '⋖', + lthree: '⋋', + ltimes: '⋉', + ltlarr: '⥶', + ltquest: '⩻', + ltrPar: '⦖', + ltri: '◃', + ltrie: '⊴', + ltrif: '◂', + lurdshar: '⥊', + luruhar: '⥦', + lvertneqq: '≨︀', + lvnE: '≨︀', + mDDot: '∺', + mac: '¯', + macr: '¯', + male: '♂', + malt: '✠', + maltese: '✠', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + mapstoleft: '↤', + mapstoup: '↥', + marker: '▮', + mcomma: '⨩', + mcy: 'м', + mdash: '—', + measuredangle: '∡', + mfr: '𝔪', + mho: '℧', + micr: 'µ', + micro: 'µ', + mid: '∣', + midast: '*', + midcir: '⫰', + middo: '·', + middot: '·', + minus: '−', + minusb: '⊟', + minusd: '∸', + minusdu: '⨪', + mlcp: '⫛', + mldr: '…', + mnplus: '∓', + models: '⊧', + mopf: '𝕞', + mp: '∓', + mscr: '𝓂', + mstpos: '∾', + mu: 'μ', + multimap: '⊸', + mumap: '⊸', + nGg: '⋙̸', + nGt: '≫⃒', + nGtv: '≫̸', + nLeftarrow: '⇍', + nLeftrightarrow: '⇎', + nLl: '⋘̸', + nLt: '≪⃒', + nLtv: '≪̸', + nRightarrow: '⇏', + nVDash: '⊯', + nVdash: '⊮', + nabla: '∇', + nacute: 'ń', + nang: '∠⃒', + nap: '≉', + napE: '⩰̸', + napid: '≋̸', + napos: 'ʼn', + napprox: '≉', + natur: '♮', + natural: '♮', + naturals: 'ℕ', + nbs: ' ', + nbsp: ' ', + nbump: '≎̸', + nbumpe: '≏̸', + ncap: '⩃', + ncaron: 'ň', + ncedil: 'ņ', + ncong: '≇', + ncongdot: '⩭̸', + ncup: '⩂', + ncy: 'н', + ndash: '–', + ne: '≠', + neArr: '⇗', + nearhk: '⤤', + nearr: '↗', + nearrow: '↗', + nedot: '≐̸', + nequiv: '≢', + nesear: '⤨', + nesim: '≂̸', + nexist: '∄', + nexists: '∄', + nfr: '𝔫', + ngE: '≧̸', + nge: '≱', + ngeq: '≱', + ngeqq: '≧̸', + ngeqslant: '⩾̸', + nges: '⩾̸', + ngsim: '≵', + ngt: '≯', + ngtr: '≯', + nhArr: '⇎', + nharr: '↮', + nhpar: '⫲', + ni: '∋', + nis: '⋼', + nisd: '⋺', + niv: '∋', + njcy: 'њ', + nlArr: '⇍', + nlE: '≦̸', + nlarr: '↚', + nldr: '‥', + nle: '≰', + nleftarrow: '↚', + nleftrightarrow: '↮', + nleq: '≰', + nleqq: '≦̸', + nleqslant: '⩽̸', + nles: '⩽̸', + nless: '≮', + nlsim: '≴', + nlt: '≮', + nltri: '⋪', + nltrie: '⋬', + nmid: '∤', + nopf: '𝕟', + no: '¬', + not: '¬', + notin: '∉', + notinE: '⋹̸', + notindot: '⋵̸', + notinva: '∉', + notinvb: '⋷', + notinvc: '⋶', + notni: '∌', + notniva: '∌', + notnivb: '⋾', + notnivc: '⋽', + npar: '∦', + nparallel: '∦', + nparsl: '⫽⃥', + npart: '∂̸', + npolint: '⨔', + npr: '⊀', + nprcue: '⋠', + npre: '⪯̸', + nprec: '⊀', + npreceq: '⪯̸', + nrArr: '⇏', + nrarr: '↛', + nrarrc: '⤳̸', + nrarrw: '↝̸', + nrightarrow: '↛', + nrtri: '⋫', + nrtrie: '⋭', + nsc: '⊁', + nsccue: '⋡', + nsce: '⪰̸', + nscr: '𝓃', + nshortmid: '∤', + nshortparallel: '∦', + nsim: '≁', + nsime: '≄', + nsimeq: '≄', + nsmid: '∤', + nspar: '∦', + nsqsube: '⋢', + nsqsupe: '⋣', + nsub: '⊄', + nsubE: '⫅̸', + nsube: '⊈', + nsubset: '⊂⃒', + nsubseteq: '⊈', + nsubseteqq: '⫅̸', + nsucc: '⊁', + nsucceq: '⪰̸', + nsup: '⊅', + nsupE: '⫆̸', + nsupe: '⊉', + nsupset: '⊃⃒', + nsupseteq: '⊉', + nsupseteqq: '⫆̸', + ntgl: '≹', + ntild: 'ñ', + ntilde: 'ñ', + ntlg: '≸', + ntriangleleft: '⋪', + ntrianglelefteq: '⋬', + ntriangleright: '⋫', + ntrianglerighteq: '⋭', + nu: 'ν', + num: '#', + numero: '№', + numsp: ' ', + nvDash: '⊭', + nvHarr: '⤄', + nvap: '≍⃒', + nvdash: '⊬', + nvge: '≥⃒', + nvgt: '>⃒', + nvinfin: '⧞', + nvlArr: '⤂', + nvle: '≤⃒', + nvlt: '<⃒', + nvltrie: '⊴⃒', + nvrArr: '⤃', + nvrtrie: '⊵⃒', + nvsim: '∼⃒', + nwArr: '⇖', + nwarhk: '⤣', + nwarr: '↖', + nwarrow: '↖', + nwnear: '⤧', + oS: 'Ⓢ', + oacut: 'ó', + oacute: 'ó', + oast: '⊛', + ocir: 'ô', + ocirc: 'ô', + ocy: 'о', + odash: '⊝', + odblac: 'ő', + odiv: '⨸', + odot: '⊙', + odsold: '⦼', + oelig: 'œ', + ofcir: '⦿', + ofr: '𝔬', + ogon: '˛', + ograv: 'ò', + ograve: 'ò', + ogt: '⧁', + ohbar: '⦵', + ohm: 'Ω', + oint: '∮', + olarr: '↺', + olcir: '⦾', + olcross: '⦻', + oline: '‾', + olt: '⧀', + omacr: 'ō', + omega: 'ω', + omicron: 'ο', + omid: '⦶', + ominus: '⊖', + oopf: '𝕠', + opar: '⦷', + operp: '⦹', + oplus: '⊕', + or: '∨', + orarr: '↻', + ord: 'º', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '⊶', + oror: '⩖', + orslope: '⩗', + orv: '⩛', + oscr: 'ℴ', + oslas: 'ø', + oslash: 'ø', + osol: '⊘', + otild: 'õ', + otilde: 'õ', + otimes: '⊗', + otimesas: '⨶', + oum: 'ö', + ouml: 'ö', + ovbar: '⌽', + par: '¶', + para: '¶', + parallel: '∥', + parsim: '⫳', + parsl: '⫽', + part: '∂', + pcy: 'п', + percnt: '%', + period: '.', + permil: '‰', + perp: '⊥', + pertenk: '‱', + pfr: '𝔭', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '☎', + pi: 'π', + pitchfork: '⋔', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '⨣', + plusb: '⊞', + pluscir: '⨢', + plusdo: '∔', + plusdu: '⨥', + pluse: '⩲', + plusm: '±', + plusmn: '±', + plussim: '⨦', + plustwo: '⨧', + pm: '±', + pointint: '⨕', + popf: '𝕡', + poun: '£', + pound: '£', + pr: '≺', + prE: '⪳', + prap: '⪷', + prcue: '≼', + pre: '⪯', + prec: '≺', + precapprox: '⪷', + preccurlyeq: '≼', + preceq: '⪯', + precnapprox: '⪹', + precneqq: '⪵', + precnsim: '⋨', + precsim: '≾', + prime: '′', + primes: 'ℙ', + prnE: '⪵', + prnap: '⪹', + prnsim: '⋨', + prod: '∏', + profalar: '⌮', + profline: '⌒', + profsurf: '⌓', + prop: '∝', + propto: '∝', + prsim: '≾', + prurel: '⊰', + pscr: '𝓅', + psi: 'ψ', + puncsp: ' ', + qfr: '𝔮', + qint: '⨌', + qopf: '𝕢', + qprime: '⁗', + qscr: '𝓆', + quaternions: 'ℍ', + quatint: '⨖', + quest: '?', + questeq: '≟', + quo: '"', + quot: '"', + rAarr: '⇛', + rArr: '⇒', + rAtail: '⤜', + rBarr: '⤏', + rHar: '⥤', + race: '∽̱', + racute: 'ŕ', + radic: '√', + raemptyv: '⦳', + rang: '⟩', + rangd: '⦒', + range: '⦥', + rangle: '⟩', + raqu: '»', + raquo: '»', + rarr: '→', + rarrap: '⥵', + rarrb: '⇥', + rarrbfs: '⤠', + rarrc: '⤳', + rarrfs: '⤞', + rarrhk: '↪', + rarrlp: '↬', + rarrpl: '⥅', + rarrsim: '⥴', + rarrtl: '↣', + rarrw: '↝', + ratail: '⤚', + ratio: '∶', + rationals: 'ℚ', + rbarr: '⤍', + rbbrk: '❳', + rbrace: '}', + rbrack: ']', + rbrke: '⦌', + rbrksld: '⦎', + rbrkslu: '⦐', + rcaron: 'ř', + rcedil: 'ŗ', + rceil: '⌉', + rcub: '}', + rcy: 'р', + rdca: '⤷', + rdldhar: '⥩', + rdquo: '”', + rdquor: '”', + rdsh: '↳', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '▭', + re: '®', + reg: '®', + rfisht: '⥽', + rfloor: '⌋', + rfr: '𝔯', + rhard: '⇁', + rharu: '⇀', + rharul: '⥬', + rho: 'ρ', + rhov: 'ϱ', + rightarrow: '→', + rightarrowtail: '↣', + rightharpoondown: '⇁', + rightharpoonup: '⇀', + rightleftarrows: '⇄', + rightleftharpoons: '⇌', + rightrightarrows: '⇉', + rightsquigarrow: '↝', + rightthreetimes: '⋌', + ring: '˚', + risingdotseq: '≓', + rlarr: '⇄', + rlhar: '⇌', + rlm: '‏', + rmoust: '⎱', + rmoustache: '⎱', + rnmid: '⫮', + roang: '⟭', + roarr: '⇾', + robrk: '⟧', + ropar: '⦆', + ropf: '𝕣', + roplus: '⨮', + rotimes: '⨵', + rpar: ')', + rpargt: '⦔', + rppolint: '⨒', + rrarr: '⇉', + rsaquo: '›', + rscr: '𝓇', + rsh: '↱', + rsqb: ']', + rsquo: '’', + rsquor: '’', + rthree: '⋌', + rtimes: '⋊', + rtri: '▹', + rtrie: '⊵', + rtrif: '▸', + rtriltri: '⧎', + ruluhar: '⥨', + rx: '℞', + sacute: 'ś', + sbquo: '‚', + sc: '≻', + scE: '⪴', + scap: '⪸', + scaron: 'š', + sccue: '≽', + sce: '⪰', + scedil: 'ş', + scirc: 'ŝ', + scnE: '⪶', + scnap: '⪺', + scnsim: '⋩', + scpolint: '⨓', + scsim: '≿', + scy: 'с', + sdot: '⋅', + sdotb: '⊡', + sdote: '⩦', + seArr: '⇘', + searhk: '⤥', + searr: '↘', + searrow: '↘', + sec: '§', + sect: '§', + semi: ';', + seswar: '⤩', + setminus: '∖', + setmn: '∖', + sext: '✶', + sfr: '𝔰', + sfrown: '⌢', + sharp: '♯', + shchcy: 'щ', + shcy: 'ш', + shortmid: '∣', + shortparallel: '∥', + sh: '­', + shy: '­', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '∼', + simdot: '⩪', + sime: '≃', + simeq: '≃', + simg: '⪞', + simgE: '⪠', + siml: '⪝', + simlE: '⪟', + simne: '≆', + simplus: '⨤', + simrarr: '⥲', + slarr: '←', + smallsetminus: '∖', + smashp: '⨳', + smeparsl: '⧤', + smid: '∣', + smile: '⌣', + smt: '⪪', + smte: '⪬', + smtes: '⪬︀', + softcy: 'ь', + sol: '/', + solb: '⧄', + solbar: '⌿', + sopf: '𝕤', + spades: '♠', + spadesuit: '♠', + spar: '∥', + sqcap: '⊓', + sqcaps: '⊓︀', + sqcup: '⊔', + sqcups: '⊔︀', + sqsub: '⊏', + sqsube: '⊑', + sqsubset: '⊏', + sqsubseteq: '⊑', + sqsup: '⊐', + sqsupe: '⊒', + sqsupset: '⊐', + sqsupseteq: '⊒', + squ: '□', + square: '□', + squarf: '▪', + squf: '▪', + srarr: '→', + sscr: '𝓈', + ssetmn: '∖', + ssmile: '⌣', + sstarf: '⋆', + star: '☆', + starf: '★', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '¯', + sub: '⊂', + subE: '⫅', + subdot: '⪽', + sube: '⊆', + subedot: '⫃', + submult: '⫁', + subnE: '⫋', + subne: '⊊', + subplus: '⪿', + subrarr: '⥹', + subset: '⊂', + subseteq: '⊆', + subseteqq: '⫅', + subsetneq: '⊊', + subsetneqq: '⫋', + subsim: '⫇', + subsub: '⫕', + subsup: '⫓', + succ: '≻', + succapprox: '⪸', + succcurlyeq: '≽', + succeq: '⪰', + succnapprox: '⪺', + succneqq: '⪶', + succnsim: '⋩', + succsim: '≿', + sum: '∑', + sung: '♪', + sup: '⊃', + sup1: '¹', + sup2: '²', + sup3: '³', + supE: '⫆', + supdot: '⪾', + supdsub: '⫘', + supe: '⊇', + supedot: '⫄', + suphsol: '⟉', + suphsub: '⫗', + suplarr: '⥻', + supmult: '⫂', + supnE: '⫌', + supne: '⊋', + supplus: '⫀', + supset: '⊃', + supseteq: '⊇', + supseteqq: '⫆', + supsetneq: '⊋', + supsetneqq: '⫌', + supsim: '⫈', + supsub: '⫔', + supsup: '⫖', + swArr: '⇙', + swarhk: '⤦', + swarr: '↙', + swarrow: '↙', + swnwar: '⤪', + szli: 'ß', + szlig: 'ß', + target: '⌖', + tau: 'τ', + tbrk: '⎴', + tcaron: 'ť', + tcedil: 'ţ', + tcy: 'т', + tdot: '⃛', + telrec: '⌕', + tfr: '𝔱', + there4: '∴', + therefore: '∴', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '≈', + thicksim: '∼', + thinsp: ' ', + thkap: '≈', + thksim: '∼', + thor: 'þ', + thorn: 'þ', + tilde: '˜', + time: '×', + times: '×', + timesb: '⊠', + timesbar: '⨱', + timesd: '⨰', + tint: '∭', + toea: '⤨', + top: '⊤', + topbot: '⌶', + topcir: '⫱', + topf: '𝕥', + topfork: '⫚', + tosa: '⤩', + tprime: '‴', + trade: '™', + triangle: '▵', + triangledown: '▿', + triangleleft: '◃', + trianglelefteq: '⊴', + triangleq: '≜', + triangleright: '▹', + trianglerighteq: '⊵', + tridot: '◬', + trie: '≜', + triminus: '⨺', + triplus: '⨹', + trisb: '⧍', + tritime: '⨻', + trpezium: '⏢', + tscr: '𝓉', + tscy: 'ц', + tshcy: 'ћ', + tstrok: 'ŧ', + twixt: '≬', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + uArr: '⇑', + uHar: '⥣', + uacut: 'ú', + uacute: 'ú', + uarr: '↑', + ubrcy: 'ў', + ubreve: 'ŭ', + ucir: 'û', + ucirc: 'û', + ucy: 'у', + udarr: '⇅', + udblac: 'ű', + udhar: '⥮', + ufisht: '⥾', + ufr: '𝔲', + ugrav: 'ù', + ugrave: 'ù', + uharl: '↿', + uharr: '↾', + uhblk: '▀', + ulcorn: '⌜', + ulcorner: '⌜', + ulcrop: '⌏', + ultri: '◸', + umacr: 'ū', + um: '¨', + uml: '¨', + uogon: 'ų', + uopf: '𝕦', + uparrow: '↑', + updownarrow: '↕', + upharpoonleft: '↿', + upharpoonright: '↾', + uplus: '⊎', + upsi: 'υ', + upsih: 'ϒ', + upsilon: 'υ', + upuparrows: '⇈', + urcorn: '⌝', + urcorner: '⌝', + urcrop: '⌎', + uring: 'ů', + urtri: '◹', + uscr: '𝓊', + utdot: '⋰', + utilde: 'ũ', + utri: '▵', + utrif: '▴', + uuarr: '⇈', + uum: 'ü', + uuml: 'ü', + uwangle: '⦧', + vArr: '⇕', + vBar: '⫨', + vBarv: '⫩', + vDash: '⊨', + vangrt: '⦜', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '∅', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '∝', + varr: '↕', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '⊊︀', + varsubsetneqq: '⫋︀', + varsupsetneq: '⊋︀', + varsupsetneqq: '⫌︀', + vartheta: 'ϑ', + vartriangleleft: '⊲', + vartriangleright: '⊳', + vcy: 'в', + vdash: '⊢', + vee: '∨', + veebar: '⊻', + veeeq: '≚', + vellip: '⋮', + verbar: '|', + vert: '|', + vfr: '𝔳', + vltri: '⊲', + vnsub: '⊂⃒', + vnsup: '⊃⃒', + vopf: '𝕧', + vprop: '∝', + vrtri: '⊳', + vscr: '𝓋', + vsubnE: '⫋︀', + vsubne: '⊊︀', + vsupnE: '⫌︀', + vsupne: '⊋︀', + vzigzag: '⦚', + wcirc: 'ŵ', + wedbar: '⩟', + wedge: '∧', + wedgeq: '≙', + weierp: '℘', + wfr: '𝔴', + wopf: '𝕨', + wp: '℘', + wr: '≀', + wreath: '≀', + wscr: '𝓌', + xcap: '⋂', + xcirc: '◯', + xcup: '⋃', + xdtri: '▽', + xfr: '𝔵', + xhArr: '⟺', + xharr: '⟷', + xi: 'ξ', + xlArr: '⟸', + xlarr: '⟵', + xmap: '⟼', + xnis: '⋻', + xodot: '⨀', + xopf: '𝕩', + xoplus: '⨁', + xotime: '⨂', + xrArr: '⟹', + xrarr: '⟶', + xscr: '𝓍', + xsqcup: '⨆', + xuplus: '⨄', + xutri: '△', + xvee: '⋁', + xwedge: '⋀', + yacut: 'ý', + yacute: 'ý', + yacy: 'я', + ycirc: 'ŷ', + ycy: 'ы', + ye: '¥', + yen: '¥', + yfr: '𝔶', + yicy: 'ї', + yopf: '𝕪', + yscr: '𝓎', + yucy: 'ю', + yum: 'ÿ', + yuml: 'ÿ', + zacute: 'ź', + zcaron: 'ž', + zcy: 'з', + zdot: 'ż', + zeetrf: 'ℨ', + zeta: 'ζ', + zfr: '𝔷', + zhcy: 'ж', + zigrarr: '⇝', + zopf: '𝕫', + zscr: '𝓏', + zwj: '‍', + zwnj: '‌' +}; + +var own$6 = {}.hasOwnProperty; + +/** + * @param {string} characters + * @returns {string|false} + */ +function decodeEntity(characters) { + return own$6.call(characterEntities, characters) + ? characterEntities[characters] + : false +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ + +/** @type {Construct} */ +const characterReference = { + name: 'characterReference', + tokenize: tokenizeCharacterReference +}; +/** @type {Tokenizer} */ + +function tokenizeCharacterReference(effects, ok, nok) { + const self = this; + let size = 0; + /** @type {number} */ + + let max; + /** @type {(code: Code) => code is number} */ + + let test; + return start + /** @type {State} */ + + function start(code) { + effects.enter('characterReference'); + effects.enter('characterReferenceMarker'); + effects.consume(code); + effects.exit('characterReferenceMarker'); + return open + } + /** @type {State} */ + + function open(code) { + if (code === 35) { + effects.enter('characterReferenceMarkerNumeric'); + effects.consume(code); + effects.exit('characterReferenceMarkerNumeric'); + return numeric + } + + effects.enter('characterReferenceValue'); + max = 31; + test = asciiAlphanumeric; + return value(code) + } + /** @type {State} */ + + function numeric(code) { + if (code === 88 || code === 120) { + effects.enter('characterReferenceMarkerHexadecimal'); + effects.consume(code); + effects.exit('characterReferenceMarkerHexadecimal'); + effects.enter('characterReferenceValue'); + max = 6; + test = asciiHexDigit; + return value + } + + effects.enter('characterReferenceValue'); + max = 7; + test = asciiDigit; + return value(code) + } + /** @type {State} */ + + function value(code) { + /** @type {Token} */ + let token; + + if (code === 59 && size) { + token = effects.exit('characterReferenceValue'); + + if ( + test === asciiAlphanumeric && + !decodeEntity(self.sliceSerialize(token)) + ) { + return nok(code) + } + + effects.enter('characterReferenceMarker'); + effects.consume(code); + effects.exit('characterReferenceMarker'); + effects.exit('characterReference'); + return ok + } + + if (test(code) && size++ < max) { + effects.consume(code); + return value + } + + return nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ + +/** @type {Construct} */ +const codeFenced = { + name: 'codeFenced', + tokenize: tokenizeCodeFenced, + concrete: true +}; +/** @type {Tokenizer} */ + +function tokenizeCodeFenced(effects, ok, nok) { + const self = this; + /** @type {Construct} */ + + const closingFenceConstruct = { + tokenize: tokenizeClosingFence, + partial: true + }; + /** @type {Construct} */ + + const nonLazyLine = { + tokenize: tokenizeNonLazyLine, + partial: true + }; + const tail = this.events[this.events.length - 1]; + const initialPrefix = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0; + let sizeOpen = 0; + /** @type {NonNullable} */ + + let marker; + return start + /** @type {State} */ + + function start(code) { + effects.enter('codeFenced'); + effects.enter('codeFencedFence'); + effects.enter('codeFencedFenceSequence'); + marker = code; + return sequenceOpen(code) + } + /** @type {State} */ + + function sequenceOpen(code) { + if (code === marker) { + effects.consume(code); + sizeOpen++; + return sequenceOpen + } + + effects.exit('codeFencedFenceSequence'); + return sizeOpen < 3 + ? nok(code) + : factorySpace(effects, infoOpen, 'whitespace')(code) + } + /** @type {State} */ + + function infoOpen(code) { + if (code === null || markdownLineEnding(code)) { + return openAfter(code) + } + + effects.enter('codeFencedFenceInfo'); + effects.enter('chunkString', { + contentType: 'string' + }); + return info(code) + } + /** @type {State} */ + + function info(code) { + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('chunkString'); + effects.exit('codeFencedFenceInfo'); + return factorySpace(effects, infoAfter, 'whitespace')(code) + } + + if (code === 96 && code === marker) return nok(code) + effects.consume(code); + return info + } + /** @type {State} */ + + function infoAfter(code) { + if (code === null || markdownLineEnding(code)) { + return openAfter(code) + } + + effects.enter('codeFencedFenceMeta'); + effects.enter('chunkString', { + contentType: 'string' + }); + return meta(code) + } + /** @type {State} */ + + function meta(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString'); + effects.exit('codeFencedFenceMeta'); + return openAfter(code) + } + + if (code === 96 && code === marker) return nok(code) + effects.consume(code); + return meta + } + /** @type {State} */ + + function openAfter(code) { + effects.exit('codeFencedFence'); + return self.interrupt ? ok(code) : contentStart(code) + } + /** @type {State} */ + + function contentStart(code) { + if (code === null) { + return after(code) + } + + if (markdownLineEnding(code)) { + return effects.attempt( + nonLazyLine, + effects.attempt( + closingFenceConstruct, + after, + initialPrefix + ? factorySpace( + effects, + contentStart, + 'linePrefix', + initialPrefix + 1 + ) + : contentStart + ), + after + )(code) + } + + effects.enter('codeFlowValue'); + return contentContinue(code) + } + /** @type {State} */ + + function contentContinue(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue'); + return contentStart(code) + } + + effects.consume(code); + return contentContinue + } + /** @type {State} */ + + function after(code) { + effects.exit('codeFenced'); + return ok(code) + } + /** @type {Tokenizer} */ + + function tokenizeNonLazyLine(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return lineStart + } + /** @type {State} */ + + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } + } + /** @type {Tokenizer} */ + + function tokenizeClosingFence(effects, ok, nok) { + let size = 0; + return factorySpace( + effects, + closingSequenceStart, + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + ) + /** @type {State} */ + + function closingSequenceStart(code) { + effects.enter('codeFencedFence'); + effects.enter('codeFencedFenceSequence'); + return closingSequence(code) + } + /** @type {State} */ + + function closingSequence(code) { + if (code === marker) { + effects.consume(code); + size++; + return closingSequence + } + + if (size < sizeOpen) return nok(code) + effects.exit('codeFencedFenceSequence'); + return factorySpace(effects, closingSequenceEnd, 'whitespace')(code) + } + /** @type {State} */ + + function closingSequenceEnd(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence'); + return ok(code) + } + + return nok(code) + } + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const codeIndented = { + name: 'codeIndented', + tokenize: tokenizeCodeIndented +}; +/** @type {Construct} */ + +const indentedContent = { + tokenize: tokenizeIndentedContent, + partial: true +}; +/** @type {Tokenizer} */ + +function tokenizeCodeIndented(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + effects.enter('codeIndented'); + return factorySpace(effects, afterStartPrefix, 'linePrefix', 4 + 1)(code) + } + /** @type {State} */ + + function afterStartPrefix(code) { + const tail = self.events[self.events.length - 1]; + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? afterPrefix(code) + : nok(code) + } + /** @type {State} */ + + function afterPrefix(code) { + if (code === null) { + return after(code) + } + + if (markdownLineEnding(code)) { + return effects.attempt(indentedContent, afterPrefix, after)(code) + } + + effects.enter('codeFlowValue'); + return content(code) + } + /** @type {State} */ + + function content(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue'); + return afterPrefix(code) + } + + effects.consume(code); + return content + } + /** @type {State} */ + + function after(code) { + effects.exit('codeIndented'); + return ok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeIndentedContent(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + // If this is a lazy line, it can’t be code. + if (self.parser.lazy[self.now().line]) { + return nok(code) + } + + if (markdownLineEnding(code)) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return start + } + + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + /** @type {State} */ + + function afterPrefix(code) { + const tail = self.events[self.events.length - 1]; + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? ok(code) + : markdownLineEnding(code) + ? start(code) + : nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const codeText = { + name: 'codeText', + tokenize: tokenizeCodeText, + resolve: resolveCodeText, + previous: previous$1 +}; +/** @type {Resolver} */ + +function resolveCodeText(events) { + let tailExitIndex = events.length - 4; + let headEnterIndex = 3; + /** @type {number} */ + + let index; + /** @type {number|undefined} */ + + let enter; // If we start and end with an EOL or a space. + + if ( + (events[headEnterIndex][1].type === 'lineEnding' || + events[headEnterIndex][1].type === 'space') && + (events[tailExitIndex][1].type === 'lineEnding' || + events[tailExitIndex][1].type === 'space') + ) { + index = headEnterIndex; // And we have data. + + while (++index < tailExitIndex) { + if (events[index][1].type === 'codeTextData') { + // Then we have padding. + events[headEnterIndex][1].type = 'codeTextPadding'; + events[tailExitIndex][1].type = 'codeTextPadding'; + headEnterIndex += 2; + tailExitIndex -= 2; + break + } + } + } // Merge adjacent spaces and data. + + index = headEnterIndex - 1; + tailExitIndex++; + + while (++index <= tailExitIndex) { + if (enter === undefined) { + if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + enter = index; + } + } else if ( + index === tailExitIndex || + events[index][1].type === 'lineEnding' + ) { + events[enter][1].type = 'codeTextData'; + + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end; + events.splice(enter + 2, index - enter - 2); + tailExitIndex -= index - enter - 2; + index = enter + 2; + } + + enter = undefined; + } + } + + return events +} +/** @type {Previous} */ + +function previous$1(code) { + // If there is a previous code, there will always be a tail. + return ( + code !== 96 || + this.events[this.events.length - 1][1].type === 'characterEscape' + ) +} +/** @type {Tokenizer} */ + +function tokenizeCodeText(effects, ok, nok) { + let sizeOpen = 0; + /** @type {number} */ + + let size; + /** @type {Token} */ + + let token; + return start + /** @type {State} */ + + function start(code) { + effects.enter('codeText'); + effects.enter('codeTextSequence'); + return openingSequence(code) + } + /** @type {State} */ + + function openingSequence(code) { + if (code === 96) { + effects.consume(code); + sizeOpen++; + return openingSequence + } + + effects.exit('codeTextSequence'); + return gap(code) + } + /** @type {State} */ + + function gap(code) { + // EOF. + if (code === null) { + return nok(code) + } // Closing fence? + // Could also be data. + + if (code === 96) { + token = effects.enter('codeTextSequence'); + size = 0; + return closingSequence(code) + } // Tabs don’t work, and virtual spaces don’t make sense. + + if (code === 32) { + effects.enter('space'); + effects.consume(code); + effects.exit('space'); + return gap + } + + if (markdownLineEnding(code)) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return gap + } // Data. + + effects.enter('codeTextData'); + return data(code) + } // In code. + + /** @type {State} */ + + function data(code) { + if ( + code === null || + code === 32 || + code === 96 || + markdownLineEnding(code) + ) { + effects.exit('codeTextData'); + return gap(code) + } + + effects.consume(code); + return data + } // Closing fence. + + /** @type {State} */ + + function closingSequence(code) { + // More. + if (code === 96) { + effects.consume(code); + size++; + return closingSequence + } // Done! + + if (size === sizeOpen) { + effects.exit('codeTextSequence'); + effects.exit('codeText'); + return ok(code) + } // More or less accents: mark as data. + + token.type = 'codeTextData'; + return data(code) + } +} + +/** + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Event} Event + */ + +/** + * Tokenize subcontent. + * + * @param {Event[]} events + * @returns {boolean} + */ +function subtokenize(events) { + /** @type {Record} */ + const jumps = {}; + let index = -1; + /** @type {Event} */ + + let event; + /** @type {number|undefined} */ + + let lineIndex; + /** @type {number} */ + + let otherIndex; + /** @type {Event} */ + + let otherEvent; + /** @type {Event[]} */ + + let parameters; + /** @type {Event[]} */ + + let subevents; + /** @type {boolean|undefined} */ + + let more; + + while (++index < events.length) { + while (index in jumps) { + index = jumps[index]; + } + + event = events[index]; // Add a hook for the GFM tasklist extension, which needs to know if text + // is in the first content of a list item. + + if ( + index && + event[1].type === 'chunkFlow' && + events[index - 1][1].type === 'listItemPrefix' + ) { + subevents = event[1]._tokenizer.events; + otherIndex = 0; + + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'lineEndingBlank' + ) { + otherIndex += 2; + } + + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'content' + ) { + while (++otherIndex < subevents.length) { + if (subevents[otherIndex][1].type === 'content') { + break + } + + if (subevents[otherIndex][1].type === 'chunkText') { + subevents[otherIndex][1]._isInFirstContentOfListItem = true; + otherIndex++; + } + } + } + } // Enter. + + if (event[0] === 'enter') { + if (event[1].contentType) { + Object.assign(jumps, subcontent(events, index)); + index = jumps[index]; + more = true; + } + } // Exit. + else if (event[1]._container) { + otherIndex = index; + lineIndex = undefined; + + while (otherIndex--) { + otherEvent = events[otherIndex]; + + if ( + otherEvent[1].type === 'lineEnding' || + otherEvent[1].type === 'lineEndingBlank' + ) { + if (otherEvent[0] === 'enter') { + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank'; + } + + otherEvent[1].type = 'lineEnding'; + lineIndex = otherIndex; + } + } else { + break + } + } + + if (lineIndex) { + // Fix position. + event[1].end = Object.assign({}, events[lineIndex][1].start); // Switch container exit w/ line endings. + + parameters = events.slice(lineIndex, index); + parameters.unshift(event); + splice(events, lineIndex, index - lineIndex + 1, parameters); + } + } + } + + return !more +} +/** + * Tokenize embedded tokens. + * + * @param {Event[]} events + * @param {number} eventIndex + * @returns {Record} + */ + +function subcontent(events, eventIndex) { + const token = events[eventIndex][1]; + const context = events[eventIndex][2]; + let startPosition = eventIndex - 1; + /** @type {number[]} */ + + const startPositions = []; + const tokenizer = + token._tokenizer || context.parser[token.contentType](token.start); + const childEvents = tokenizer.events; + /** @type {[number, number][]} */ + + const jumps = []; + /** @type {Record} */ + + const gaps = {}; + /** @type {Chunk[]} */ + + let stream; + /** @type {Token|undefined} */ + + let previous; + let index = -1; + /** @type {Token|undefined} */ + + let current = token; + let adjust = 0; + let start = 0; + const breaks = [start]; // Loop forward through the linked tokens to pass them in order to the + // subtokenizer. + + while (current) { + // Find the position of the event for this token. + while (events[++startPosition][1] !== current) { + // Empty. + } + + startPositions.push(startPosition); + + if (!current._tokenizer) { + stream = context.sliceStream(current); + + if (!current.next) { + stream.push(null); + } + + if (previous) { + tokenizer.defineSkip(current.start); + } + + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = true; + } + + tokenizer.write(stream); + + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = undefined; + } + } // Unravel the next token. + + previous = current; + current = current.next; + } // Now, loop back through all events (and linked tokens), to figure out which + // parts belong where. + + current = token; + + while (++index < childEvents.length) { + if ( + // Find a void token that includes a break. + childEvents[index][0] === 'exit' && + childEvents[index - 1][0] === 'enter' && + childEvents[index][1].type === childEvents[index - 1][1].type && + childEvents[index][1].start.line !== childEvents[index][1].end.line + ) { + start = index + 1; + breaks.push(start); // Help GC. + + current._tokenizer = undefined; + current.previous = undefined; + current = current.next; + } + } // Help GC. + + tokenizer.events = []; // If there’s one more token (which is the cases for lines that end in an + // EOF), that’s perfect: the last point we found starts it. + // If there isn’t then make sure any remaining content is added to it. + + if (current) { + // Help GC. + current._tokenizer = undefined; + current.previous = undefined; + } else { + breaks.pop(); + } // Now splice the events from the subtokenizer into the current events, + // moving back to front so that splice indices aren’t affected. + + index = breaks.length; + + while (index--) { + const slice = childEvents.slice(breaks[index], breaks[index + 1]); + const start = startPositions.pop(); + jumps.unshift([start, start + slice.length - 1]); + splice(events, start, 2, slice); + } + + index = -1; + + while (++index < jumps.length) { + gaps[adjust + jumps[index][0]] = adjust + jumps[index][1]; + adjust += jumps[index][1] - jumps[index][0] - 1; + } + + return gaps +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').State} State + */ + +/** + * No name because it must not be turned off. + * @type {Construct} + */ +const content = { + tokenize: tokenizeContent, + resolve: resolveContent +}; +/** @type {Construct} */ + +const continuationConstruct = { + tokenize: tokenizeContinuation, + partial: true +}; +/** + * Content is transparent: it’s parsed right now. That way, definitions are also + * parsed right now: before text in paragraphs (specifically, media) are parsed. + * + * @type {Resolver} + */ + +function resolveContent(events) { + subtokenize(events); + return events +} +/** @type {Tokenizer} */ + +function tokenizeContent(effects, ok) { + /** @type {Token} */ + let previous; + return start + /** @type {State} */ + + function start(code) { + effects.enter('content'); + previous = effects.enter('chunkContent', { + contentType: 'content' + }); + return data(code) + } + /** @type {State} */ + + function data(code) { + if (code === null) { + return contentEnd(code) + } + + if (markdownLineEnding(code)) { + return effects.check( + continuationConstruct, + contentContinue, + contentEnd + )(code) + } // Data. + + effects.consume(code); + return data + } + /** @type {State} */ + + function contentEnd(code) { + effects.exit('chunkContent'); + effects.exit('content'); + return ok(code) + } + /** @type {State} */ + + function contentContinue(code) { + effects.consume(code); + effects.exit('chunkContent'); + previous.next = effects.enter('chunkContent', { + contentType: 'content', + previous + }); + previous = previous.next; + return data + } +} +/** @type {Tokenizer} */ + +function tokenizeContinuation(effects, ok, nok) { + const self = this; + return startLookahead + /** @type {State} */ + + function startLookahead(code) { + effects.exit('chunkContent'); + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return factorySpace(effects, prefixed, 'linePrefix') + } + /** @type {State} */ + + function prefixed(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + const tail = self.events[self.events.length - 1]; + + if ( + !self.parser.constructs.disable.null.includes('codeIndented') && + tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ) { + return ok(code) + } + + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + } +} + +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + +/** + * @param {Effects} effects + * @param {State} ok + * @param {State} nok + * @param {string} type + * @param {string} literalType + * @param {string} literalMarkerType + * @param {string} rawType + * @param {string} stringType + * @param {number} [max=Infinity] + * @returns {State} + */ +// eslint-disable-next-line max-params +function factoryDestination( + effects, + ok, + nok, + type, + literalType, + literalMarkerType, + rawType, + stringType, + max +) { + const limit = max || Number.POSITIVE_INFINITY; + let balance = 0; + return start + /** @type {State} */ + + function start(code) { + if (code === 60) { + effects.enter(type); + effects.enter(literalType); + effects.enter(literalMarkerType); + effects.consume(code); + effects.exit(literalMarkerType); + return destinationEnclosedBefore + } + + if (code === null || code === 41 || asciiControl(code)) { + return nok(code) + } + + effects.enter(type); + effects.enter(rawType); + effects.enter(stringType); + effects.enter('chunkString', { + contentType: 'string' + }); + return destinationRaw(code) + } + /** @type {State} */ + + function destinationEnclosedBefore(code) { + if (code === 62) { + effects.enter(literalMarkerType); + effects.consume(code); + effects.exit(literalMarkerType); + effects.exit(literalType); + effects.exit(type); + return ok + } + + effects.enter(stringType); + effects.enter('chunkString', { + contentType: 'string' + }); + return destinationEnclosed(code) + } + /** @type {State} */ + + function destinationEnclosed(code) { + if (code === 62) { + effects.exit('chunkString'); + effects.exit(stringType); + return destinationEnclosedBefore(code) + } + + if (code === null || code === 60 || markdownLineEnding(code)) { + return nok(code) + } + + effects.consume(code); + return code === 92 ? destinationEnclosedEscape : destinationEnclosed + } + /** @type {State} */ + + function destinationEnclosedEscape(code) { + if (code === 60 || code === 62 || code === 92) { + effects.consume(code); + return destinationEnclosed + } + + return destinationEnclosed(code) + } + /** @type {State} */ + + function destinationRaw(code) { + if (code === 40) { + if (++balance > limit) return nok(code) + effects.consume(code); + return destinationRaw + } + + if (code === 41) { + if (!balance--) { + effects.exit('chunkString'); + effects.exit(stringType); + effects.exit(rawType); + effects.exit(type); + return ok(code) + } + + effects.consume(code); + return destinationRaw + } + + if (code === null || markdownLineEndingOrSpace(code)) { + if (balance) return nok(code) + effects.exit('chunkString'); + effects.exit(stringType); + effects.exit(rawType); + effects.exit(type); + return ok(code) + } + + if (asciiControl(code)) return nok(code) + effects.consume(code); + return code === 92 ? destinationRawEscape : destinationRaw + } + /** @type {State} */ + + function destinationRawEscape(code) { + if (code === 40 || code === 41 || code === 92) { + effects.consume(code); + return destinationRaw + } + + return destinationRaw(code) + } +} + +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').State} State + */ + +/** + * @this {TokenizeContext} + * @param {Effects} effects + * @param {State} ok + * @param {State} nok + * @param {string} type + * @param {string} markerType + * @param {string} stringType + * @returns {State} + */ +// eslint-disable-next-line max-params +function factoryLabel(effects, ok, nok, type, markerType, stringType) { + const self = this; + let size = 0; + /** @type {boolean} */ + + let data; + return start + /** @type {State} */ + + function start(code) { + effects.enter(type); + effects.enter(markerType); + effects.consume(code); + effects.exit(markerType); + effects.enter(stringType); + return atBreak + } + /** @type {State} */ + + function atBreak(code) { + if ( + code === null || + code === 91 || + (code === 93 && !data) || + /* Hidden footnotes hook */ + + /* c8 ignore next 3 */ + (code === 94 && + !size && + '_hiddenFootnoteSupport' in self.parser.constructs) || + size > 999 + ) { + return nok(code) + } + + if (code === 93) { + effects.exit(stringType); + effects.enter(markerType); + effects.consume(code); + effects.exit(markerType); + effects.exit(type); + return ok + } + + if (markdownLineEnding(code)) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return atBreak + } + + effects.enter('chunkString', { + contentType: 'string' + }); + return label(code) + } + /** @type {State} */ + + function label(code) { + if ( + code === null || + code === 91 || + code === 93 || + markdownLineEnding(code) || + size++ > 999 + ) { + effects.exit('chunkString'); + return atBreak(code) + } + + effects.consume(code); + data = data || !markdownSpace(code); + return code === 92 ? labelEscape : label + } + /** @type {State} */ + + function labelEscape(code) { + if (code === 91 || code === 92 || code === 93) { + effects.consume(code); + size++; + return label + } + + return label(code) + } +} + +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ + +/** + * @param {Effects} effects + * @param {State} ok + * @param {State} nok + * @param {string} type + * @param {string} markerType + * @param {string} stringType + * @returns {State} + */ +// eslint-disable-next-line max-params +function factoryTitle(effects, ok, nok, type, markerType, stringType) { + /** @type {NonNullable} */ + let marker; + return start + /** @type {State} */ + + function start(code) { + effects.enter(type); + effects.enter(markerType); + effects.consume(code); + effects.exit(markerType); + marker = code === 40 ? 41 : code; + return atFirstTitleBreak + } + /** @type {State} */ + + function atFirstTitleBreak(code) { + if (code === marker) { + effects.enter(markerType); + effects.consume(code); + effects.exit(markerType); + effects.exit(type); + return ok + } + + effects.enter(stringType); + return atTitleBreak(code) + } + /** @type {State} */ + + function atTitleBreak(code) { + if (code === marker) { + effects.exit(stringType); + return atFirstTitleBreak(marker) + } + + if (code === null) { + return nok(code) + } // Note: blank lines can’t exist in content. + + if (markdownLineEnding(code)) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return factorySpace(effects, atTitleBreak, 'linePrefix') + } + + effects.enter('chunkString', { + contentType: 'string' + }); + return title(code) + } + /** @type {State} */ + + function title(code) { + if (code === marker || code === null || markdownLineEnding(code)) { + effects.exit('chunkString'); + return atTitleBreak(code) + } + + effects.consume(code); + return code === 92 ? titleEscape : title + } + /** @type {State} */ + + function titleEscape(code) { + if (code === marker || code === 92) { + effects.consume(code); + return title + } + + return title(code) + } +} + +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + +/** + * @param {Effects} effects + * @param {State} ok + */ +function factoryWhitespace(effects, ok) { + /** @type {boolean} */ + let seen; + return start + /** @type {State} */ + + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + seen = true; + return start + } + + if (markdownSpace(code)) { + return factorySpace( + effects, + start, + seen ? 'linePrefix' : 'lineSuffix' + )(code) + } + + return ok(code) + } +} + +/** + * Normalize an identifier (such as used in definitions). + * + * @param {string} value + * @returns {string} + */ +function normalizeIdentifier(value) { + return ( + value // Collapse Markdown whitespace. + .replace(/[\t\n\r ]+/g, ' ') // Trim. + .replace(/^ | $/g, '') // Some characters are considered “uppercase”, but if their lowercase + // counterpart is uppercased will result in a different uppercase + // character. + // Hence, to get that form, we perform both lower- and uppercase. + // Upper case makes sure keys will not interact with default prototypal + // methods: no method is uppercase. + .toLowerCase() + .toUpperCase() + ) +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const definition$1 = { + name: 'definition', + tokenize: tokenizeDefinition +}; +/** @type {Construct} */ + +const titleConstruct = { + tokenize: tokenizeTitle, + partial: true +}; +/** @type {Tokenizer} */ + +function tokenizeDefinition(effects, ok, nok) { + const self = this; + /** @type {string} */ + + let identifier; + return start + /** @type {State} */ + + function start(code) { + effects.enter('definition'); + return factoryLabel.call( + self, + effects, + labelAfter, + nok, + 'definitionLabel', + 'definitionLabelMarker', + 'definitionLabelString' + )(code) + } + /** @type {State} */ + + function labelAfter(code) { + identifier = normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ); + + if (code === 58) { + effects.enter('definitionMarker'); + effects.consume(code); + effects.exit('definitionMarker'); // Note: blank lines can’t exist in content. + + return factoryWhitespace( + effects, + factoryDestination( + effects, + effects.attempt( + titleConstruct, + factorySpace(effects, after, 'whitespace'), + factorySpace(effects, after, 'whitespace') + ), + nok, + 'definitionDestination', + 'definitionDestinationLiteral', + 'definitionDestinationLiteralMarker', + 'definitionDestinationRaw', + 'definitionDestinationString' + ) + ) + } + + return nok(code) + } + /** @type {State} */ + + function after(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('definition'); + + if (!self.parser.defined.includes(identifier)) { + self.parser.defined.push(identifier); + } + + return ok(code) + } + + return nok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeTitle(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, before)(code) + : nok(code) + } + /** @type {State} */ + + function before(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + factorySpace(effects, after, 'whitespace'), + nok, + 'definitionTitle', + 'definitionTitleMarker', + 'definitionTitleString' + )(code) + } + + return nok(code) + } + /** @type {State} */ + + function after(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const hardBreakEscape = { + name: 'hardBreakEscape', + tokenize: tokenizeHardBreakEscape +}; +/** @type {Tokenizer} */ + +function tokenizeHardBreakEscape(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.enter('hardBreakEscape'); + effects.enter('escapeMarker'); + effects.consume(code); + return open + } + /** @type {State} */ + + function open(code) { + if (markdownLineEnding(code)) { + effects.exit('escapeMarker'); + effects.exit('hardBreakEscape'); + return ok(code) + } + + return nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const headingAtx = { + name: 'headingAtx', + tokenize: tokenizeHeadingAtx, + resolve: resolveHeadingAtx +}; +/** @type {Resolver} */ + +function resolveHeadingAtx(events, context) { + let contentEnd = events.length - 2; + let contentStart = 3; + /** @type {Token} */ + + let content; + /** @type {Token} */ + + let text; // Prefix whitespace, part of the opening. + + if (events[contentStart][1].type === 'whitespace') { + contentStart += 2; + } // Suffix whitespace, part of the closing. + + if ( + contentEnd - 2 > contentStart && + events[contentEnd][1].type === 'whitespace' + ) { + contentEnd -= 2; + } + + if ( + events[contentEnd][1].type === 'atxHeadingSequence' && + (contentStart === contentEnd - 1 || + (contentEnd - 4 > contentStart && + events[contentEnd - 2][1].type === 'whitespace')) + ) { + contentEnd -= contentStart + 1 === contentEnd ? 2 : 4; + } + + if (contentEnd > contentStart) { + content = { + type: 'atxHeadingText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end + }; + text = { + type: 'chunkText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end, + // @ts-expect-error Constants are fine to assign. + contentType: 'text' + }; + splice(events, contentStart, contentEnd - contentStart + 1, [ + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ]); + } + + return events +} +/** @type {Tokenizer} */ + +function tokenizeHeadingAtx(effects, ok, nok) { + const self = this; + let size = 0; + return start + /** @type {State} */ + + function start(code) { + effects.enter('atxHeading'); + effects.enter('atxHeadingSequence'); + return fenceOpenInside(code) + } + /** @type {State} */ + + function fenceOpenInside(code) { + if (code === 35 && size++ < 6) { + effects.consume(code); + return fenceOpenInside + } + + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingSequence'); + return self.interrupt ? ok(code) : headingBreak(code) + } + + return nok(code) + } + /** @type {State} */ + + function headingBreak(code) { + if (code === 35) { + effects.enter('atxHeadingSequence'); + return sequence(code) + } + + if (code === null || markdownLineEnding(code)) { + effects.exit('atxHeading'); + return ok(code) + } + + if (markdownSpace(code)) { + return factorySpace(effects, headingBreak, 'whitespace')(code) + } + + effects.enter('atxHeadingText'); + return data(code) + } + /** @type {State} */ + + function sequence(code) { + if (code === 35) { + effects.consume(code); + return sequence + } + + effects.exit('atxHeadingSequence'); + return headingBreak(code) + } + /** @type {State} */ + + function data(code) { + if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingText'); + return headingBreak(code) + } + + effects.consume(code); + return data + } +} + +/** + * List of lowercase HTML tag names which when parsing HTML (flow), result + * in more relaxed rules (condition 6): because they are known blocks, the + * HTML-like syntax doesn’t have to be strictly parsed. + * For tag names not in this list, a more strict algorithm (condition 7) is used + * to detect whether the HTML-like syntax is seen as HTML (flow) or not. + * + * This is copied from: + * . + */ +const htmlBlockNames = [ + 'address', + 'article', + 'aside', + 'base', + 'basefont', + 'blockquote', + 'body', + 'caption', + 'center', + 'col', + 'colgroup', + 'dd', + 'details', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hr', + 'html', + 'iframe', + 'legend', + 'li', + 'link', + 'main', + 'menu', + 'menuitem', + 'nav', + 'noframes', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'section', + 'source', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'title', + 'tr', + 'track', + 'ul' +]; + +/** + * List of lowercase HTML tag names which when parsing HTML (flow), result in + * HTML that can include lines w/o exiting, until a closing tag also in this + * list is found (condition 1). + * + * This module is copied from: + * . + * + * Note that `textarea` is not available in `CommonMark@0.29` but has been + * merged to the primary branch and is slated to be released in the next release + * of CommonMark. + */ +const htmlRawNames = ['pre', 'script', 'style', 'textarea']; + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ +/** @type {Construct} */ + +const htmlFlow = { + name: 'htmlFlow', + tokenize: tokenizeHtmlFlow, + resolveTo: resolveToHtmlFlow, + concrete: true +}; +/** @type {Construct} */ + +const nextBlankConstruct = { + tokenize: tokenizeNextBlank, + partial: true +}; +/** @type {Resolver} */ + +function resolveToHtmlFlow(events) { + let index = events.length; + + while (index--) { + if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { + break + } + } + + if (index > 1 && events[index - 2][1].type === 'linePrefix') { + // Add the prefix start to the HTML token. + events[index][1].start = events[index - 2][1].start; // Add the prefix start to the HTML line token. + + events[index + 1][1].start = events[index - 2][1].start; // Remove the line prefix. + + events.splice(index - 2, 2); + } + + return events +} +/** @type {Tokenizer} */ + +function tokenizeHtmlFlow(effects, ok, nok) { + const self = this; + /** @type {number} */ + + let kind; + /** @type {boolean} */ + + let startTag; + /** @type {string} */ + + let buffer; + /** @type {number} */ + + let index; + /** @type {Code} */ + + let marker; + return start + /** @type {State} */ + + function start(code) { + effects.enter('htmlFlow'); + effects.enter('htmlFlowData'); + effects.consume(code); + return open + } + /** @type {State} */ + + function open(code) { + if (code === 33) { + effects.consume(code); + return declarationStart + } + + if (code === 47) { + effects.consume(code); + return tagCloseStart + } + + if (code === 63) { + effects.consume(code); + kind = 3; // While we’re in an instruction instead of a declaration, we’re on a `?` + // right now, so we do need to search for `>`, similar to declarations. + + return self.interrupt ? ok : continuationDeclarationInside + } + + if (asciiAlpha(code)) { + effects.consume(code); + buffer = String.fromCharCode(code); + startTag = true; + return tagName + } + + return nok(code) + } + /** @type {State} */ + + function declarationStart(code) { + if (code === 45) { + effects.consume(code); + kind = 2; + return commentOpenInside + } + + if (code === 91) { + effects.consume(code); + kind = 5; + buffer = 'CDATA['; + index = 0; + return cdataOpenInside + } + + if (asciiAlpha(code)) { + effects.consume(code); + kind = 4; + return self.interrupt ? ok : continuationDeclarationInside + } + + return nok(code) + } + /** @type {State} */ + + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code); + return self.interrupt ? ok : continuationDeclarationInside + } + + return nok(code) + } + /** @type {State} */ + + function cdataOpenInside(code) { + if (code === buffer.charCodeAt(index++)) { + effects.consume(code); + return index === buffer.length + ? self.interrupt + ? ok + : continuation + : cdataOpenInside + } + + return nok(code) + } + /** @type {State} */ + + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code); + buffer = String.fromCharCode(code); + return tagName + } + + return nok(code) + } + /** @type {State} */ + + function tagName(code) { + if ( + code === null || + code === 47 || + code === 62 || + markdownLineEndingOrSpace(code) + ) { + if ( + code !== 47 && + startTag && + htmlRawNames.includes(buffer.toLowerCase()) + ) { + kind = 1; + return self.interrupt ? ok(code) : continuation(code) + } + + if (htmlBlockNames.includes(buffer.toLowerCase())) { + kind = 6; + + if (code === 47) { + effects.consume(code); + return basicSelfClosing + } + + return self.interrupt ? ok(code) : continuation(code) + } + + kind = 7; // Do not support complete HTML when interrupting + + return self.interrupt && !self.parser.lazy[self.now().line] + ? nok(code) + : startTag + ? completeAttributeNameBefore(code) + : completeClosingTagAfter(code) + } + + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code); + buffer += String.fromCharCode(code); + return tagName + } + + return nok(code) + } + /** @type {State} */ + + function basicSelfClosing(code) { + if (code === 62) { + effects.consume(code); + return self.interrupt ? ok : continuation + } + + return nok(code) + } + /** @type {State} */ + + function completeClosingTagAfter(code) { + if (markdownSpace(code)) { + effects.consume(code); + return completeClosingTagAfter + } + + return completeEnd(code) + } + /** @type {State} */ + + function completeAttributeNameBefore(code) { + if (code === 47) { + effects.consume(code); + return completeEnd + } + + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code); + return completeAttributeName + } + + if (markdownSpace(code)) { + effects.consume(code); + return completeAttributeNameBefore + } + + return completeEnd(code) + } + /** @type {State} */ + + function completeAttributeName(code) { + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code); + return completeAttributeName + } + + return completeAttributeNameAfter(code) + } + /** @type {State} */ + + function completeAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code); + return completeAttributeValueBefore + } + + if (markdownSpace(code)) { + effects.consume(code); + return completeAttributeNameAfter + } + + return completeAttributeNameBefore(code) + } + /** @type {State} */ + + function completeAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + + if (code === 34 || code === 39) { + effects.consume(code); + marker = code; + return completeAttributeValueQuoted + } + + if (markdownSpace(code)) { + effects.consume(code); + return completeAttributeValueBefore + } + + marker = null; + return completeAttributeValueUnquoted(code) + } + /** @type {State} */ + + function completeAttributeValueQuoted(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + if (code === marker) { + effects.consume(code); + return completeAttributeValueQuotedAfter + } + + effects.consume(code); + return completeAttributeValueQuoted + } + /** @type {State} */ + + function completeAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 62 || + code === 96 || + markdownLineEndingOrSpace(code) + ) { + return completeAttributeNameAfter(code) + } + + effects.consume(code); + return completeAttributeValueUnquoted + } + /** @type {State} */ + + function completeAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownSpace(code)) { + return completeAttributeNameBefore(code) + } + + return nok(code) + } + /** @type {State} */ + + function completeEnd(code) { + if (code === 62) { + effects.consume(code); + return completeAfter + } + + return nok(code) + } + /** @type {State} */ + + function completeAfter(code) { + if (markdownSpace(code)) { + effects.consume(code); + return completeAfter + } + + return code === null || markdownLineEnding(code) + ? continuation(code) + : nok(code) + } + /** @type {State} */ + + function continuation(code) { + if (code === 45 && kind === 2) { + effects.consume(code); + return continuationCommentInside + } + + if (code === 60 && kind === 1) { + effects.consume(code); + return continuationRawTagOpen + } + + if (code === 62 && kind === 4) { + effects.consume(code); + return continuationClose + } + + if (code === 63 && kind === 3) { + effects.consume(code); + return continuationDeclarationInside + } + + if (code === 93 && kind === 5) { + effects.consume(code); + return continuationCharacterDataInside + } + + if (markdownLineEnding(code) && (kind === 6 || kind === 7)) { + return effects.check( + nextBlankConstruct, + continuationClose, + continuationAtLineEnding + )(code) + } + + if (code === null || markdownLineEnding(code)) { + return continuationAtLineEnding(code) + } + + effects.consume(code); + return continuation + } + /** @type {State} */ + + function continuationAtLineEnding(code) { + effects.exit('htmlFlowData'); + return htmlContinueStart(code) + } + /** @type {State} */ + + function htmlContinueStart(code) { + if (code === null) { + return done(code) + } + + if (markdownLineEnding(code)) { + return effects.attempt( + { + tokenize: htmlLineEnd, + partial: true + }, + htmlContinueStart, + done + )(code) + } + + effects.enter('htmlFlowData'); + return continuation(code) + } + /** @type {Tokenizer} */ + + function htmlLineEnd(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return lineStart + } + /** @type {State} */ + + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } + } + /** @type {State} */ + + function continuationCommentInside(code) { + if (code === 45) { + effects.consume(code); + return continuationDeclarationInside + } + + return continuation(code) + } + /** @type {State} */ + + function continuationRawTagOpen(code) { + if (code === 47) { + effects.consume(code); + buffer = ''; + return continuationRawEndTag + } + + return continuation(code) + } + /** @type {State} */ + + function continuationRawEndTag(code) { + if (code === 62 && htmlRawNames.includes(buffer.toLowerCase())) { + effects.consume(code); + return continuationClose + } + + if (asciiAlpha(code) && buffer.length < 8) { + effects.consume(code); + buffer += String.fromCharCode(code); + return continuationRawEndTag + } + + return continuation(code) + } + /** @type {State} */ + + function continuationCharacterDataInside(code) { + if (code === 93) { + effects.consume(code); + return continuationDeclarationInside + } + + return continuation(code) + } + /** @type {State} */ + + function continuationDeclarationInside(code) { + if (code === 62) { + effects.consume(code); + return continuationClose + } + + return continuation(code) + } + /** @type {State} */ + + function continuationClose(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData'); + return done(code) + } + + effects.consume(code); + return continuationClose + } + /** @type {State} */ + + function done(code) { + effects.exit('htmlFlow'); + return ok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeNextBlank(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.exit('htmlFlowData'); + effects.enter('lineEndingBlank'); + effects.consume(code); + effects.exit('lineEndingBlank'); + return effects.attempt(blankLine, ok, nok) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ + +/** @type {Construct} */ +const htmlText = { + name: 'htmlText', + tokenize: tokenizeHtmlText +}; +/** @type {Tokenizer} */ + +function tokenizeHtmlText(effects, ok, nok) { + const self = this; + /** @type {NonNullable|undefined} */ + + let marker; + /** @type {string} */ + + let buffer; + /** @type {number} */ + + let index; + /** @type {State} */ + + let returnState; + return start + /** @type {State} */ + + function start(code) { + effects.enter('htmlText'); + effects.enter('htmlTextData'); + effects.consume(code); + return open + } + /** @type {State} */ + + function open(code) { + if (code === 33) { + effects.consume(code); + return declarationOpen + } + + if (code === 47) { + effects.consume(code); + return tagCloseStart + } + + if (code === 63) { + effects.consume(code); + return instruction + } + + if (asciiAlpha(code)) { + effects.consume(code); + return tagOpen + } + + return nok(code) + } + /** @type {State} */ + + function declarationOpen(code) { + if (code === 45) { + effects.consume(code); + return commentOpen + } + + if (code === 91) { + effects.consume(code); + buffer = 'CDATA['; + index = 0; + return cdataOpen + } + + if (asciiAlpha(code)) { + effects.consume(code); + return declaration + } + + return nok(code) + } + /** @type {State} */ + + function commentOpen(code) { + if (code === 45) { + effects.consume(code); + return commentStart + } + + return nok(code) + } + /** @type {State} */ + + function commentStart(code) { + if (code === null || code === 62) { + return nok(code) + } + + if (code === 45) { + effects.consume(code); + return commentStartDash + } + + return comment(code) + } + /** @type {State} */ + + function commentStartDash(code) { + if (code === null || code === 62) { + return nok(code) + } + + return comment(code) + } + /** @type {State} */ + + function comment(code) { + if (code === null) { + return nok(code) + } + + if (code === 45) { + effects.consume(code); + return commentClose + } + + if (markdownLineEnding(code)) { + returnState = comment; + return atLineEnding(code) + } + + effects.consume(code); + return comment + } + /** @type {State} */ + + function commentClose(code) { + if (code === 45) { + effects.consume(code); + return end + } + + return comment(code) + } + /** @type {State} */ + + function cdataOpen(code) { + if (code === buffer.charCodeAt(index++)) { + effects.consume(code); + return index === buffer.length ? cdata : cdataOpen + } + + return nok(code) + } + /** @type {State} */ + + function cdata(code) { + if (code === null) { + return nok(code) + } + + if (code === 93) { + effects.consume(code); + return cdataClose + } + + if (markdownLineEnding(code)) { + returnState = cdata; + return atLineEnding(code) + } + + effects.consume(code); + return cdata + } + /** @type {State} */ + + function cdataClose(code) { + if (code === 93) { + effects.consume(code); + return cdataEnd + } + + return cdata(code) + } + /** @type {State} */ + + function cdataEnd(code) { + if (code === 62) { + return end(code) + } + + if (code === 93) { + effects.consume(code); + return cdataEnd + } + + return cdata(code) + } + /** @type {State} */ + + function declaration(code) { + if (code === null || code === 62) { + return end(code) + } + + if (markdownLineEnding(code)) { + returnState = declaration; + return atLineEnding(code) + } + + effects.consume(code); + return declaration + } + /** @type {State} */ + + function instruction(code) { + if (code === null) { + return nok(code) + } + + if (code === 63) { + effects.consume(code); + return instructionClose + } + + if (markdownLineEnding(code)) { + returnState = instruction; + return atLineEnding(code) + } + + effects.consume(code); + return instruction + } + /** @type {State} */ + + function instructionClose(code) { + return code === 62 ? end(code) : instruction(code) + } + /** @type {State} */ + + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code); + return tagClose + } + + return nok(code) + } + /** @type {State} */ + + function tagClose(code) { + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code); + return tagClose + } + + return tagCloseBetween(code) + } + /** @type {State} */ + + function tagCloseBetween(code) { + if (markdownLineEnding(code)) { + returnState = tagCloseBetween; + return atLineEnding(code) + } + + if (markdownSpace(code)) { + effects.consume(code); + return tagCloseBetween + } + + return end(code) + } + /** @type {State} */ + + function tagOpen(code) { + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code); + return tagOpen + } + + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + + return nok(code) + } + /** @type {State} */ + + function tagOpenBetween(code) { + if (code === 47) { + effects.consume(code); + return end + } + + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code); + return tagOpenAttributeName + } + + if (markdownLineEnding(code)) { + returnState = tagOpenBetween; + return atLineEnding(code) + } + + if (markdownSpace(code)) { + effects.consume(code); + return tagOpenBetween + } + + return end(code) + } + /** @type {State} */ + + function tagOpenAttributeName(code) { + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code); + return tagOpenAttributeName + } + + return tagOpenAttributeNameAfter(code) + } + /** @type {State} */ + + function tagOpenAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code); + return tagOpenAttributeValueBefore + } + + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeNameAfter; + return atLineEnding(code) + } + + if (markdownSpace(code)) { + effects.consume(code); + return tagOpenAttributeNameAfter + } + + return tagOpenBetween(code) + } + /** @type {State} */ + + function tagOpenAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + + if (code === 34 || code === 39) { + effects.consume(code); + marker = code; + return tagOpenAttributeValueQuoted + } + + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueBefore; + return atLineEnding(code) + } + + if (markdownSpace(code)) { + effects.consume(code); + return tagOpenAttributeValueBefore + } + + effects.consume(code); + marker = undefined; + return tagOpenAttributeValueUnquoted + } + /** @type {State} */ + + function tagOpenAttributeValueQuoted(code) { + if (code === marker) { + effects.consume(code); + return tagOpenAttributeValueQuotedAfter + } + + if (code === null) { + return nok(code) + } + + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueQuoted; + return atLineEnding(code) + } + + effects.consume(code); + return tagOpenAttributeValueQuoted + } + /** @type {State} */ + + function tagOpenAttributeValueQuotedAfter(code) { + if (code === 62 || code === 47 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + + return nok(code) + } + /** @type {State} */ + + function tagOpenAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 96 + ) { + return nok(code) + } + + if (code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + + effects.consume(code); + return tagOpenAttributeValueUnquoted + } // We can’t have blank lines in content, so no need to worry about empty + // tokens. + + /** @type {State} */ + + function atLineEnding(code) { + effects.exit('htmlTextData'); + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return factorySpace( + effects, + afterPrefix, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + ) + } + /** @type {State} */ + + function afterPrefix(code) { + effects.enter('htmlTextData'); + return returnState(code) + } + /** @type {State} */ + + function end(code) { + if (code === 62) { + effects.consume(code); + effects.exit('htmlTextData'); + effects.exit('htmlText'); + return ok + } + + return nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ + +/** @type {Construct} */ +const labelEnd = { + name: 'labelEnd', + tokenize: tokenizeLabelEnd, + resolveTo: resolveToLabelEnd, + resolveAll: resolveAllLabelEnd +}; +/** @type {Construct} */ + +const resourceConstruct = { + tokenize: tokenizeResource +}; +/** @type {Construct} */ + +const fullReferenceConstruct = { + tokenize: tokenizeFullReference +}; +/** @type {Construct} */ + +const collapsedReferenceConstruct = { + tokenize: tokenizeCollapsedReference +}; +/** @type {Resolver} */ + +function resolveAllLabelEnd(events) { + let index = -1; + /** @type {Token} */ + + let token; + + while (++index < events.length) { + token = events[index][1]; + + if ( + token.type === 'labelImage' || + token.type === 'labelLink' || + token.type === 'labelEnd' + ) { + // Remove the marker. + events.splice(index + 1, token.type === 'labelImage' ? 4 : 2); + token.type = 'data'; + index++; + } + } + + return events +} +/** @type {Resolver} */ + +function resolveToLabelEnd(events, context) { + let index = events.length; + let offset = 0; + /** @type {Token} */ + + let token; + /** @type {number|undefined} */ + + let open; + /** @type {number|undefined} */ + + let close; + /** @type {Event[]} */ + + let media; // Find an opening. + + while (index--) { + token = events[index][1]; + + if (open) { + // If we see another link, or inactive link label, we’ve been here before. + if ( + token.type === 'link' || + (token.type === 'labelLink' && token._inactive) + ) { + break + } // Mark other link openings as inactive, as we can’t have links in + // links. + + if (events[index][0] === 'enter' && token.type === 'labelLink') { + token._inactive = true; + } + } else if (close) { + if ( + events[index][0] === 'enter' && + (token.type === 'labelImage' || token.type === 'labelLink') && + !token._balanced + ) { + open = index; + + if (token.type !== 'labelLink') { + offset = 2; + break + } + } + } else if (token.type === 'labelEnd') { + close = index; + } + } + + const group = { + type: events[open][1].type === 'labelLink' ? 'link' : 'image', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + }; + const label = { + type: 'label', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[close][1].end) + }; + const text = { + type: 'labelText', + start: Object.assign({}, events[open + offset + 2][1].end), + end: Object.assign({}, events[close - 2][1].start) + }; + media = [ + ['enter', group, context], + ['enter', label, context] + ]; // Opening marker. + + media = push(media, events.slice(open + 1, open + offset + 3)); // Text open. + + media = push(media, [['enter', text, context]]); // Between. + + media = push( + media, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + offset + 4, close - 3), + context + ) + ); // Text close, marker close, label close. + + media = push(media, [ + ['exit', text, context], + events[close - 2], + events[close - 1], + ['exit', label, context] + ]); // Reference, resource, or so. + + media = push(media, events.slice(close + 1)); // Media close. + + media = push(media, [['exit', group, context]]); + splice(events, open, events.length, media); + return events +} +/** @type {Tokenizer} */ + +function tokenizeLabelEnd(effects, ok, nok) { + const self = this; + let index = self.events.length; + /** @type {Token} */ + + let labelStart; + /** @type {boolean} */ + + let defined; // Find an opening. + + while (index--) { + if ( + (self.events[index][1].type === 'labelImage' || + self.events[index][1].type === 'labelLink') && + !self.events[index][1]._balanced + ) { + labelStart = self.events[index][1]; + break + } + } + + return start + /** @type {State} */ + + function start(code) { + if (!labelStart) { + return nok(code) + } // It’s a balanced bracket, but contains a link. + + if (labelStart._inactive) return balanced(code) + defined = self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }) + ) + ); + effects.enter('labelEnd'); + effects.enter('labelMarker'); + effects.consume(code); + effects.exit('labelMarker'); + effects.exit('labelEnd'); + return afterLabelEnd + } + /** @type {State} */ + + function afterLabelEnd(code) { + // Resource: `[asd](fgh)`. + if (code === 40) { + return effects.attempt( + resourceConstruct, + ok, + defined ? ok : balanced + )(code) + } // Collapsed (`[asd][]`) or full (`[asd][fgh]`) reference? + + if (code === 91) { + return effects.attempt( + fullReferenceConstruct, + ok, + defined + ? effects.attempt(collapsedReferenceConstruct, ok, balanced) + : balanced + )(code) + } // Shortcut reference: `[asd]`? + + return defined ? ok(code) : balanced(code) + } + /** @type {State} */ + + function balanced(code) { + labelStart._balanced = true; + return nok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeResource(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.enter('resource'); + effects.enter('resourceMarker'); + effects.consume(code); + effects.exit('resourceMarker'); + return factoryWhitespace(effects, open) + } + /** @type {State} */ + + function open(code) { + if (code === 41) { + return end(code) + } + + return factoryDestination( + effects, + destinationAfter, + nok, + 'resourceDestination', + 'resourceDestinationLiteral', + 'resourceDestinationLiteralMarker', + 'resourceDestinationRaw', + 'resourceDestinationString', + 3 + )(code) + } + /** @type {State} */ + + function destinationAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, between)(code) + : end(code) + } + /** @type {State} */ + + function between(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + factoryWhitespace(effects, end), + nok, + 'resourceTitle', + 'resourceTitleMarker', + 'resourceTitleString' + )(code) + } + + return end(code) + } + /** @type {State} */ + + function end(code) { + if (code === 41) { + effects.enter('resourceMarker'); + effects.consume(code); + effects.exit('resourceMarker'); + effects.exit('resource'); + return ok + } + + return nok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeFullReference(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + return factoryLabel.call( + self, + effects, + afterLabel, + nok, + 'reference', + 'referenceMarker', + 'referenceString' + )(code) + } + /** @type {State} */ + + function afterLabel(code) { + return self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + ) + ? ok(code) + : nok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeCollapsedReference(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.enter('reference'); + effects.enter('referenceMarker'); + effects.consume(code); + effects.exit('referenceMarker'); + return open + } + /** @type {State} */ + + function open(code) { + if (code === 93) { + effects.enter('referenceMarker'); + effects.consume(code); + effects.exit('referenceMarker'); + effects.exit('reference'); + return ok + } + + return nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + */ +/** @type {Construct} */ + +const labelStartImage = { + name: 'labelStartImage', + tokenize: tokenizeLabelStartImage, + resolveAll: labelEnd.resolveAll +}; +/** @type {Tokenizer} */ + +function tokenizeLabelStartImage(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + effects.enter('labelImage'); + effects.enter('labelImageMarker'); + effects.consume(code); + effects.exit('labelImageMarker'); + return open + } + /** @type {State} */ + + function open(code) { + if (code === 91) { + effects.enter('labelMarker'); + effects.consume(code); + effects.exit('labelMarker'); + effects.exit('labelImage'); + return after + } + + return nok(code) + } + /** @type {State} */ + + function after(code) { + /* Hidden footnotes hook */ + + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + */ +/** @type {Construct} */ + +const labelStartLink = { + name: 'labelStartLink', + tokenize: tokenizeLabelStartLink, + resolveAll: labelEnd.resolveAll +}; +/** @type {Tokenizer} */ + +function tokenizeLabelStartLink(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + effects.enter('labelLink'); + effects.enter('labelMarker'); + effects.consume(code); + effects.exit('labelMarker'); + effects.exit('labelLink'); + return after + } + /** @type {State} */ + + function after(code) { + /* Hidden footnotes hook. */ + + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const lineEnding = { + name: 'lineEnding', + tokenize: tokenizeLineEnding +}; +/** @type {Tokenizer} */ + +function tokenizeLineEnding(effects, ok) { + return start + /** @type {State} */ + + function start(code) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return factorySpace(effects, ok, 'linePrefix') + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ + +/** @type {Construct} */ +const thematicBreak$1 = { + name: 'thematicBreak', + tokenize: tokenizeThematicBreak +}; +/** @type {Tokenizer} */ + +function tokenizeThematicBreak(effects, ok, nok) { + let size = 0; + /** @type {NonNullable} */ + + let marker; + return start + /** @type {State} */ + + function start(code) { + effects.enter('thematicBreak'); + marker = code; + return atBreak(code) + } + /** @type {State} */ + + function atBreak(code) { + if (code === marker) { + effects.enter('thematicBreakSequence'); + return sequence(code) + } + + if (markdownSpace(code)) { + return factorySpace(effects, atBreak, 'whitespace')(code) + } + + if (size < 3 || (code !== null && !markdownLineEnding(code))) { + return nok(code) + } + + effects.exit('thematicBreak'); + return ok(code) + } + /** @type {State} */ + + function sequence(code) { + if (code === marker) { + effects.consume(code); + size++; + return sequence + } + + effects.exit('thematicBreakSequence'); + return atBreak(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ +/** @type {Construct} */ + +const list$1 = { + name: 'list', + tokenize: tokenizeListStart, + continuation: { + tokenize: tokenizeListContinuation + }, + exit: tokenizeListEnd +}; +/** @type {Construct} */ + +const listItemPrefixWhitespaceConstruct = { + tokenize: tokenizeListItemPrefixWhitespace, + partial: true +}; +/** @type {Construct} */ + +const indentConstruct = { + tokenize: tokenizeIndent, + partial: true +}; +/** + * @type {Tokenizer} + * @this {TokenizeContextWithState} + */ + +function tokenizeListStart(effects, ok, nok) { + const self = this; + const tail = self.events[self.events.length - 1]; + let initialSize = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0; + let size = 0; + return start + /** @type {State} */ + + function start(code) { + const kind = + self.containerState.type || + (code === 42 || code === 43 || code === 45 + ? 'listUnordered' + : 'listOrdered'); + + if ( + kind === 'listUnordered' + ? !self.containerState.marker || code === self.containerState.marker + : asciiDigit(code) + ) { + if (!self.containerState.type) { + self.containerState.type = kind; + effects.enter(kind, { + _container: true + }); + } + + if (kind === 'listUnordered') { + effects.enter('listItemPrefix'); + return code === 42 || code === 45 + ? effects.check(thematicBreak$1, nok, atMarker)(code) + : atMarker(code) + } + + if (!self.interrupt || code === 49) { + effects.enter('listItemPrefix'); + effects.enter('listItemValue'); + return inside(code) + } + } + + return nok(code) + } + /** @type {State} */ + + function inside(code) { + if (asciiDigit(code) && ++size < 10) { + effects.consume(code); + return inside + } + + if ( + (!self.interrupt || size < 2) && + (self.containerState.marker + ? code === self.containerState.marker + : code === 41 || code === 46) + ) { + effects.exit('listItemValue'); + return atMarker(code) + } + + return nok(code) + } + /** + * @type {State} + **/ + + function atMarker(code) { + effects.enter('listItemMarker'); + effects.consume(code); + effects.exit('listItemMarker'); + self.containerState.marker = self.containerState.marker || code; + return effects.check( + blankLine, // Can’t be empty when interrupting. + self.interrupt ? nok : onBlank, + effects.attempt( + listItemPrefixWhitespaceConstruct, + endOfPrefix, + otherPrefix + ) + ) + } + /** @type {State} */ + + function onBlank(code) { + self.containerState.initialBlankLine = true; + initialSize++; + return endOfPrefix(code) + } + /** @type {State} */ + + function otherPrefix(code) { + if (markdownSpace(code)) { + effects.enter('listItemPrefixWhitespace'); + effects.consume(code); + effects.exit('listItemPrefixWhitespace'); + return endOfPrefix + } + + return nok(code) + } + /** @type {State} */ + + function endOfPrefix(code) { + self.containerState.size = + initialSize + + self.sliceSerialize(effects.exit('listItemPrefix'), true).length; + return ok(code) + } +} +/** + * @type {Tokenizer} + * @this {TokenizeContextWithState} + */ + +function tokenizeListContinuation(effects, ok, nok) { + const self = this; + self.containerState._closeFlow = undefined; + return effects.check(blankLine, onBlank, notBlank) + /** @type {State} */ + + function onBlank(code) { + self.containerState.furtherBlankLines = + self.containerState.furtherBlankLines || + self.containerState.initialBlankLine; // We have a blank line. + // Still, try to consume at most the items size. + + return factorySpace( + effects, + ok, + 'listItemIndent', + self.containerState.size + 1 + )(code) + } + /** @type {State} */ + + function notBlank(code) { + if (self.containerState.furtherBlankLines || !markdownSpace(code)) { + self.containerState.furtherBlankLines = undefined; + self.containerState.initialBlankLine = undefined; + return notInCurrentItem(code) + } + + self.containerState.furtherBlankLines = undefined; + self.containerState.initialBlankLine = undefined; + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + } + /** @type {State} */ + + function notInCurrentItem(code) { + // While we do continue, we signal that the flow should be closed. + self.containerState._closeFlow = true; // As we’re closing flow, we’re no longer interrupting. + + self.interrupt = undefined; + return factorySpace( + effects, + effects.attempt(list$1, ok, nok), + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } +} +/** + * @type {Tokenizer} + * @this {TokenizeContextWithState} + */ + +function tokenizeIndent(effects, ok, nok) { + const self = this; + return factorySpace( + effects, + afterPrefix, + 'listItemIndent', + self.containerState.size + 1 + ) + /** @type {State} */ + + function afterPrefix(code) { + const tail = self.events[self.events.length - 1]; + return tail && + tail[1].type === 'listItemIndent' && + tail[2].sliceSerialize(tail[1], true).length === self.containerState.size + ? ok(code) + : nok(code) + } +} +/** + * @type {Exiter} + * @this {TokenizeContextWithState} + */ + +function tokenizeListEnd(effects) { + effects.exit(this.containerState.type); +} +/** + * @type {Tokenizer} + * @this {TokenizeContextWithState} + */ + +function tokenizeListItemPrefixWhitespace(effects, ok, nok) { + const self = this; + return factorySpace( + effects, + afterPrefix, + 'listItemPrefixWhitespace', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + 1 + ) + /** @type {State} */ + + function afterPrefix(code) { + const tail = self.events[self.events.length - 1]; + return !markdownSpace(code) && + tail && + tail[1].type === 'listItemPrefixWhitespace' + ? ok(code) + : nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ + +/** @type {Construct} */ +const setextUnderline = { + name: 'setextUnderline', + tokenize: tokenizeSetextUnderline, + resolveTo: resolveToSetextUnderline +}; +/** @type {Resolver} */ + +function resolveToSetextUnderline(events, context) { + let index = events.length; + /** @type {number|undefined} */ + + let content; + /** @type {number|undefined} */ + + let text; + /** @type {number|undefined} */ + + let definition; // Find the opening of the content. + // It’ll always exist: we don’t tokenize if it isn’t there. + + while (index--) { + if (events[index][0] === 'enter') { + if (events[index][1].type === 'content') { + content = index; + break + } + + if (events[index][1].type === 'paragraph') { + text = index; + } + } // Exit + else { + if (events[index][1].type === 'content') { + // Remove the content end (if needed we’ll add it later) + events.splice(index, 1); + } + + if (!definition && events[index][1].type === 'definition') { + definition = index; + } + } + } + + const heading = { + type: 'setextHeading', + start: Object.assign({}, events[text][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + }; // Change the paragraph to setext heading text. + + events[text][1].type = 'setextHeadingText'; // If we have definitions in the content, we’ll keep on having content, + // but we need move it. + + if (definition) { + events.splice(text, 0, ['enter', heading, context]); + events.splice(definition + 1, 0, ['exit', events[content][1], context]); + events[content][1].end = Object.assign({}, events[definition][1].end); + } else { + events[content][1] = heading; + } // Add the heading exit at the end. + + events.push(['exit', heading, context]); + return events +} +/** @type {Tokenizer} */ + +function tokenizeSetextUnderline(effects, ok, nok) { + const self = this; + let index = self.events.length; + /** @type {NonNullable} */ + + let marker; + /** @type {boolean} */ + + let paragraph; // Find an opening. + + while (index--) { + // Skip enter/exit of line ending, line prefix, and content. + // We can now either have a definition or a paragraph. + if ( + self.events[index][1].type !== 'lineEnding' && + self.events[index][1].type !== 'linePrefix' && + self.events[index][1].type !== 'content' + ) { + paragraph = self.events[index][1].type === 'paragraph'; + break + } + } + + return start + /** @type {State} */ + + function start(code) { + if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { + effects.enter('setextHeadingLine'); + effects.enter('setextHeadingLineSequence'); + marker = code; + return closingSequence(code) + } + + return nok(code) + } + /** @type {State} */ + + function closingSequence(code) { + if (code === marker) { + effects.consume(code); + return closingSequence + } + + effects.exit('setextHeadingLineSequence'); + return factorySpace(effects, closingSequenceEnd, 'lineSuffix')(code) + } + /** @type {State} */ + + function closingSequenceEnd(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('setextHeadingLine'); + return ok(code) + } + + return nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {InitialConstruct} */ +const flow$1 = { + tokenize: initializeFlow +}; +/** @type {Initializer} */ + +function initializeFlow(effects) { + const self = this; + const initial = effects.attempt( + // Try to parse a blank line. + blankLine, + atBlankEnding, // Try to parse initial flow (essentially, only code). + effects.attempt( + this.parser.constructs.flowInitial, + afterConstruct, + factorySpace( + effects, + effects.attempt( + this.parser.constructs.flow, + afterConstruct, + effects.attempt(content, afterConstruct) + ), + 'linePrefix' + ) + ) + ); + return initial + /** @type {State} */ + + function atBlankEnding(code) { + if (code === null) { + effects.consume(code); + return + } + + effects.enter('lineEndingBlank'); + effects.consume(code); + effects.exit('lineEndingBlank'); + self.currentConstruct = undefined; + return initial + } + /** @type {State} */ + + function afterConstruct(code) { + if (code === null) { + effects.consume(code); + return + } + + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + self.currentConstruct = undefined; + return initial + } +} + +/** + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ +const resolver = { + resolveAll: createResolver() +}; +const string$1 = initializeFactory('string'); +const text$3 = initializeFactory('text'); +/** + * @param {'string'|'text'} field + * @returns {InitialConstruct} + */ + +function initializeFactory(field) { + return { + tokenize: initializeText, + resolveAll: createResolver( + field === 'text' ? resolveAllLineSuffixes : undefined + ) + } + /** @type {Initializer} */ + + function initializeText(effects) { + const self = this; + const constructs = this.parser.constructs[field]; + const text = effects.attempt(constructs, start, notText); + return start + /** @type {State} */ + + function start(code) { + return atBreak(code) ? text(code) : notText(code) + } + /** @type {State} */ + + function notText(code) { + if (code === null) { + effects.consume(code); + return + } + + effects.enter('data'); + effects.consume(code); + return data + } + /** @type {State} */ + + function data(code) { + if (atBreak(code)) { + effects.exit('data'); + return text(code) + } // Data. + + effects.consume(code); + return data + } + /** + * @param {Code} code + * @returns {boolean} + */ + + function atBreak(code) { + if (code === null) { + return true + } + + const list = constructs[code]; + let index = -1; + + if (list) { + while (++index < list.length) { + const item = list[index]; + + if (!item.previous || item.previous.call(self, self.previous)) { + return true + } + } + } + + return false + } + } +} +/** + * @param {Resolver} [extraResolver] + * @returns {Resolver} + */ + +function createResolver(extraResolver) { + return resolveAllText + /** @type {Resolver} */ + + function resolveAllText(events, context) { + let index = -1; + /** @type {number|undefined} */ + + let enter; // A rather boring computation (to merge adjacent `data` events) which + // improves mm performance by 29%. + + while (++index <= events.length) { + if (enter === undefined) { + if (events[index] && events[index][1].type === 'data') { + enter = index; + index++; + } + } else if (!events[index] || events[index][1].type !== 'data') { + // Don’t do anything if there is one data token. + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end; + events.splice(enter + 2, index - enter - 2); + index = enter + 2; + } + + enter = undefined; + } + } + + return extraResolver ? extraResolver(events, context) : events + } +} +/** + * A rather ugly set of instructions which again looks at chunks in the input + * stream. + * The reason to do this here is that it is *much* faster to parse in reverse. + * And that we can’t hook into `null` to split the line suffix before an EOF. + * To do: figure out if we can make this into a clean utility, or even in core. + * As it will be useful for GFMs literal autolink extension (and maybe even + * tables?) + * + * @type {Resolver} + */ + +function resolveAllLineSuffixes(events, context) { + let eventIndex = -1; + + while (++eventIndex <= events.length) { + if ( + (eventIndex === events.length || + events[eventIndex][1].type === 'lineEnding') && + events[eventIndex - 1][1].type === 'data' + ) { + const data = events[eventIndex - 1][1]; + const chunks = context.sliceStream(data); + let index = chunks.length; + let bufferIndex = -1; + let size = 0; + /** @type {boolean|undefined} */ + + let tabs; + + while (index--) { + const chunk = chunks[index]; + + if (typeof chunk === 'string') { + bufferIndex = chunk.length; + + while (chunk.charCodeAt(bufferIndex - 1) === 32) { + size++; + bufferIndex--; + } + + if (bufferIndex) break + bufferIndex = -1; + } // Number + else if (chunk === -2) { + tabs = true; + size++; + } else if (chunk === -1) ; else { + // Replacement character, exit. + index++; + break + } + } + + if (size) { + const token = { + type: + eventIndex === events.length || tabs || size < 2 + ? 'lineSuffix' + : 'hardBreakTrailing', + start: { + line: data.end.line, + column: data.end.column - size, + offset: data.end.offset - size, + _index: data.start._index + index, + _bufferIndex: index + ? bufferIndex + : data.start._bufferIndex + bufferIndex + }, + end: Object.assign({}, data.end) + }; + data.end = Object.assign({}, token.start); + + if (data.start.offset === data.end.offset) { + Object.assign(data, token); + } else { + events.splice( + eventIndex, + 0, + ['enter', token, context], + ['exit', token, context] + ); + eventIndex += 2; + } + } + + eventIndex++; + } + } + + return events +} + +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').ParseContext} ParseContext + */ + +/** + * Create a tokenizer. + * Tokenizers deal with one type of data (e.g., containers, flow, text). + * The parser is the object dealing with it all. + * `initialize` works like other constructs, except that only its `tokenize` + * function is used, in which case it doesn’t receive an `ok` or `nok`. + * `from` can be given to set the point before the first character, although + * when further lines are indented, they must be set with `defineSkip`. + * + * @param {ParseContext} parser + * @param {InitialConstruct} initialize + * @param {Omit} [from] + * @returns {TokenizeContext} + */ +function createTokenizer(parser, initialize, from) { + /** @type {Point} */ + let point = Object.assign( + from + ? Object.assign({}, from) + : { + line: 1, + column: 1, + offset: 0 + }, + { + _index: 0, + _bufferIndex: -1 + } + ); + /** @type {Record} */ + + const columnStart = {}; + /** @type {Construct[]} */ + + const resolveAllConstructs = []; + /** @type {Chunk[]} */ + + let chunks = []; + /** @type {Token[]} */ + + let stack = []; + /** + * Tools used for tokenizing. + * + * @type {Effects} + */ + + const effects = { + consume, + enter, + exit, + attempt: constructFactory(onsuccessfulconstruct), + check: constructFactory(onsuccessfulcheck), + interrupt: constructFactory(onsuccessfulcheck, { + interrupt: true + }) + }; + /** + * State and tools for resolving and serializing. + * + * @type {TokenizeContext} + */ + + const context = { + previous: null, + code: null, + containerState: {}, + events: [], + parser, + sliceStream, + sliceSerialize, + now, + defineSkip, + write + }; + /** + * The state function. + * + * @type {State|void} + */ + + let state = initialize.tokenize.call(context, effects); + + if (initialize.resolveAll) { + resolveAllConstructs.push(initialize); + } + + return context + /** @type {TokenizeContext['write']} */ + + function write(slice) { + chunks = push(chunks, slice); + main(); // Exit if we’re not done, resolve might change stuff. + + if (chunks[chunks.length - 1] !== null) { + return [] + } + + addResult(initialize, 0); // Otherwise, resolve, and exit. + + context.events = resolveAll(resolveAllConstructs, context.events, context); + return context.events + } // + // Tools. + // + + /** @type {TokenizeContext['sliceSerialize']} */ + + function sliceSerialize(token, expandTabs) { + return serializeChunks(sliceStream(token), expandTabs) + } + /** @type {TokenizeContext['sliceStream']} */ + + function sliceStream(token) { + return sliceChunks(chunks, token) + } + /** @type {TokenizeContext['now']} */ + + function now() { + return Object.assign({}, point) + } + /** @type {TokenizeContext['defineSkip']} */ + + function defineSkip(value) { + columnStart[value.line] = value.column; + accountForPotentialSkip(); + } // + // State management. + // + + /** + * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by + * `consume`). + * Here is where we walk through the chunks, which either include strings of + * several characters, or numerical character codes. + * The reason to do this in a loop instead of a call is so the stack can + * drain. + * + * @returns {void} + */ + + function main() { + /** @type {number} */ + let chunkIndex; + + while (point._index < chunks.length) { + const chunk = chunks[point._index]; // If we’re in a buffer chunk, loop through it. + + if (typeof chunk === 'string') { + chunkIndex = point._index; + + if (point._bufferIndex < 0) { + point._bufferIndex = 0; + } + + while ( + point._index === chunkIndex && + point._bufferIndex < chunk.length + ) { + go(chunk.charCodeAt(point._bufferIndex)); + } + } else { + go(chunk); + } + } + } + /** + * Deal with one code. + * + * @param {Code} code + * @returns {void} + */ + + function go(code) { + state = state(code); + } + /** @type {Effects['consume']} */ + + function consume(code) { + if (markdownLineEnding(code)) { + point.line++; + point.column = 1; + point.offset += code === -3 ? 2 : 1; + accountForPotentialSkip(); + } else if (code !== -1) { + point.column++; + point.offset++; + } // Not in a string chunk. + + if (point._bufferIndex < 0) { + point._index++; + } else { + point._bufferIndex++; // At end of string chunk. + // @ts-expect-error Points w/ non-negative `_bufferIndex` reference + // strings. + + if (point._bufferIndex === chunks[point._index].length) { + point._bufferIndex = -1; + point._index++; + } + } // Expose the previous character. + + context.previous = code; // Mark as consumed. + } + /** @type {Effects['enter']} */ + + function enter(type, fields) { + /** @type {Token} */ + // @ts-expect-error Patch instead of assign required fields to help GC. + const token = fields || {}; + token.type = type; + token.start = now(); + context.events.push(['enter', token, context]); + stack.push(token); + return token + } + /** @type {Effects['exit']} */ + + function exit(type) { + const token = stack.pop(); + token.end = now(); + context.events.push(['exit', token, context]); + return token + } + /** + * Use results. + * + * @type {ReturnHandle} + */ + + function onsuccessfulconstruct(construct, info) { + addResult(construct, info.from); + } + /** + * Discard results. + * + * @type {ReturnHandle} + */ + + function onsuccessfulcheck(_, info) { + info.restore(); + } + /** + * Factory to attempt/check/interrupt. + * + * @param {ReturnHandle} onreturn + * @param {Record} [fields] + */ + + function constructFactory(onreturn, fields) { + return hook + /** + * Handle either an object mapping codes to constructs, a list of + * constructs, or a single construct. + * + * @param {Construct|Construct[]|ConstructRecord} constructs + * @param {State} returnState + * @param {State} [bogusState] + * @returns {State} + */ + + function hook(constructs, returnState, bogusState) { + /** @type {Construct[]} */ + let listOfConstructs; + /** @type {number} */ + + let constructIndex; + /** @type {Construct} */ + + let currentConstruct; + /** @type {Info} */ + + let info; + return Array.isArray(constructs) + ? /* c8 ignore next 1 */ + handleListOfConstructs(constructs) + : 'tokenize' in constructs // @ts-expect-error Looks like a construct. + ? handleListOfConstructs([constructs]) + : handleMapOfConstructs(constructs) + /** + * Handle a list of construct. + * + * @param {ConstructRecord} map + * @returns {State} + */ + + function handleMapOfConstructs(map) { + return start + /** @type {State} */ + + function start(code) { + const def = code !== null && map[code]; + const all = code !== null && map.null; + const list = [ + // To do: add more extension tests. + + /* c8 ignore next 2 */ + ...(Array.isArray(def) ? def : def ? [def] : []), + ...(Array.isArray(all) ? all : all ? [all] : []) + ]; + return handleListOfConstructs(list)(code) + } + } + /** + * Handle a list of construct. + * + * @param {Construct[]} list + * @returns {State} + */ + + function handleListOfConstructs(list) { + listOfConstructs = list; + constructIndex = 0; + + if (list.length === 0) { + return bogusState + } + + return handleConstruct(list[constructIndex]) + } + /** + * Handle a single construct. + * + * @param {Construct} construct + * @returns {State} + */ + + function handleConstruct(construct) { + return start + /** @type {State} */ + + function start(code) { + // To do: not needed to store if there is no bogus state, probably? + // Currently doesn’t work because `inspect` in document does a check + // w/o a bogus, which doesn’t make sense. But it does seem to help perf + // by not storing. + info = store(); + currentConstruct = construct; + + if (!construct.partial) { + context.currentConstruct = construct; + } + + if ( + construct.name && + context.parser.constructs.disable.null.includes(construct.name) + ) { + return nok() + } + + return construct.tokenize.call( + // If we do have fields, create an object w/ `context` as its + // prototype. + // This allows a “live binding”, which is needed for `interrupt`. + fields ? Object.assign(Object.create(context), fields) : context, + effects, + ok, + nok + )(code) + } + } + /** @type {State} */ + + function ok(code) { + onreturn(currentConstruct, info); + return returnState + } + /** @type {State} */ + + function nok(code) { + info.restore(); + + if (++constructIndex < listOfConstructs.length) { + return handleConstruct(listOfConstructs[constructIndex]) + } + + return bogusState + } + } + } + /** + * @param {Construct} construct + * @param {number} from + * @returns {void} + */ + + function addResult(construct, from) { + if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { + resolveAllConstructs.push(construct); + } + + if (construct.resolve) { + splice( + context.events, + from, + context.events.length - from, + construct.resolve(context.events.slice(from), context) + ); + } + + if (construct.resolveTo) { + context.events = construct.resolveTo(context.events, context); + } + } + /** + * Store state. + * + * @returns {Info} + */ + + function store() { + const startPoint = now(); + const startPrevious = context.previous; + const startCurrentConstruct = context.currentConstruct; + const startEventsIndex = context.events.length; + const startStack = Array.from(stack); + return { + restore, + from: startEventsIndex + } + /** + * Restore state. + * + * @returns {void} + */ + + function restore() { + point = startPoint; + context.previous = startPrevious; + context.currentConstruct = startCurrentConstruct; + context.events.length = startEventsIndex; + stack = startStack; + accountForPotentialSkip(); + } + } + /** + * Move the current point a bit forward in the line when it’s on a column + * skip. + * + * @returns {void} + */ + + function accountForPotentialSkip() { + if (point.line in columnStart && point.column < 2) { + point.column = columnStart[point.line]; + point.offset += columnStart[point.line] - 1; + } + } +} +/** + * Get the chunks from a slice of chunks in the range of a token. + * + * @param {Chunk[]} chunks + * @param {Pick} token + * @returns {Chunk[]} + */ + +function sliceChunks(chunks, token) { + const startIndex = token.start._index; + const startBufferIndex = token.start._bufferIndex; + const endIndex = token.end._index; + const endBufferIndex = token.end._bufferIndex; + /** @type {Chunk[]} */ + + let view; + + if (startIndex === endIndex) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)]; + } else { + view = chunks.slice(startIndex, endIndex); + + if (startBufferIndex > -1) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view[0] = view[0].slice(startBufferIndex); + } + + if (endBufferIndex > 0) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view.push(chunks[endIndex].slice(0, endBufferIndex)); + } + } + + return view +} +/** + * Get the string value of a slice of chunks. + * + * @param {Chunk[]} chunks + * @param {boolean} [expandTabs=false] + * @returns {string} + */ + +function serializeChunks(chunks, expandTabs) { + let index = -1; + /** @type {string[]} */ + + const result = []; + /** @type {boolean|undefined} */ + + let atTab; + + while (++index < chunks.length) { + const chunk = chunks[index]; + /** @type {string} */ + + let value; + + if (typeof chunk === 'string') { + value = chunk; + } else + switch (chunk) { + case -5: { + value = '\r'; + break + } + + case -4: { + value = '\n'; + break + } + + case -3: { + value = '\r' + '\n'; + break + } + + case -2: { + value = expandTabs ? ' ' : '\t'; + break + } + + case -1: { + if (!expandTabs && atTab) continue + value = ' '; + break + } + + default: { + // Currently only replacement character. + value = String.fromCharCode(chunk); + } + } + + atTab = chunk === -2; + result.push(value); + } + + return result.join('') +} + +/** + * @typedef {import('micromark-util-types').Extension} Extension + */ +/** @type {Extension['document']} */ + +const document = { + [42]: list$1, + [43]: list$1, + [45]: list$1, + [48]: list$1, + [49]: list$1, + [50]: list$1, + [51]: list$1, + [52]: list$1, + [53]: list$1, + [54]: list$1, + [55]: list$1, + [56]: list$1, + [57]: list$1, + [62]: blockQuote +}; +/** @type {Extension['contentInitial']} */ + +const contentInitial = { + [91]: definition$1 +}; +/** @type {Extension['flowInitial']} */ + +const flowInitial = { + [-2]: codeIndented, + [-1]: codeIndented, + [32]: codeIndented +}; +/** @type {Extension['flow']} */ + +const flow = { + [35]: headingAtx, + [42]: thematicBreak$1, + [45]: [setextUnderline, thematicBreak$1], + [60]: htmlFlow, + [61]: setextUnderline, + [95]: thematicBreak$1, + [96]: codeFenced, + [126]: codeFenced +}; +/** @type {Extension['string']} */ + +const string = { + [38]: characterReference, + [92]: characterEscape +}; +/** @type {Extension['text']} */ + +const text$2 = { + [-5]: lineEnding, + [-4]: lineEnding, + [-3]: lineEnding, + [33]: labelStartImage, + [38]: characterReference, + [42]: attention, + [60]: [autolink, htmlText], + [91]: labelStartLink, + [92]: [hardBreakEscape, characterEscape], + [93]: labelEnd, + [95]: attention, + [96]: codeText +}; +/** @type {Extension['insideSpan']} */ + +const insideSpan = { + null: [attention, resolver] +}; +/** @type {Extension['attentionMarkers']} */ + +const attentionMarkers = { + null: [42, 95] +}; +/** @type {Extension['disable']} */ + +const disable = { + null: [] +}; + +var defaultConstructs = /*#__PURE__*/Object.freeze({ + __proto__: null, + document: document, + contentInitial: contentInitial, + flowInitial: flowInitial, + flow: flow, + string: string, + text: text$2, + insideSpan: insideSpan, + attentionMarkers: attentionMarkers, + disable: disable +}); + +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').Create} Create + */ +/** + * @param {ParseOptions} [options] + * @returns {ParseContext} + */ + +function parse$1(options = {}) { + /** @type {FullNormalizedExtension} */ + // @ts-expect-error `defaultConstructs` is full, so the result will be too. + const constructs = combineExtensions( + // @ts-expect-error Same as above. + [defaultConstructs].concat(options.extensions || []) + ); + /** @type {ParseContext} */ + + const parser = { + defined: [], + lazy: {}, + constructs, + content: create(content$1), + document: create(document$1), + flow: create(flow$1), + string: create(string$1), + text: create(text$3) + }; + return parser + /** + * @param {InitialConstruct} initial + */ + + function create(initial) { + return creator + /** @type {Create} */ + + function creator(from) { + return createTokenizer(parser, initial, from) + } + } +} + +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Value} Value + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + */ + +/** + * @callback Preprocessor + * @param {Value} value + * @param {Encoding} [encoding] + * @param {boolean} [end=false] + * @returns {Chunk[]} + */ +const search = /[\0\t\n\r]/g; +/** + * @returns {Preprocessor} + */ + +function preprocess() { + let column = 1; + let buffer = ''; + /** @type {boolean|undefined} */ + + let start = true; + /** @type {boolean|undefined} */ + + let atCarriageReturn; + return preprocessor + /** @type {Preprocessor} */ + + function preprocessor(value, encoding, end) { + /** @type {Chunk[]} */ + const chunks = []; + /** @type {RegExpMatchArray|null} */ + + let match; + /** @type {number} */ + + let next; + /** @type {number} */ + + let startPosition; + /** @type {number} */ + + let endPosition; + /** @type {Code} */ + + let code; // @ts-expect-error `Buffer` does allow an encoding. + + value = buffer + value.toString(encoding); + startPosition = 0; + buffer = ''; + + if (start) { + if (value.charCodeAt(0) === 65279) { + startPosition++; + } + + start = undefined; + } + + while (startPosition < value.length) { + search.lastIndex = startPosition; + match = search.exec(value); + endPosition = + match && match.index !== undefined ? match.index : value.length; + code = value.charCodeAt(endPosition); + + if (!match) { + buffer = value.slice(startPosition); + break + } + + if (code === 10 && startPosition === endPosition && atCarriageReturn) { + chunks.push(-3); + atCarriageReturn = undefined; + } else { + if (atCarriageReturn) { + chunks.push(-5); + atCarriageReturn = undefined; + } + + if (startPosition < endPosition) { + chunks.push(value.slice(startPosition, endPosition)); + column += endPosition - startPosition; + } + + switch (code) { + case 0: { + chunks.push(65533); + column++; + break + } + + case 9: { + next = Math.ceil(column / 4) * 4; + chunks.push(-2); + + while (column++ < next) chunks.push(-1); + + break + } + + case 10: { + chunks.push(-4); + column = 1; + break + } + + default: { + atCarriageReturn = true; + column = 1; + } + } + } + + startPosition = endPosition + 1; + } + + if (end) { + if (atCarriageReturn) chunks.push(-5); + if (buffer) chunks.push(buffer); + chunks.push(null); + } + + return chunks + } +} + +/** + * @typedef {import('micromark-util-types').Event} Event + */ +/** + * @param {Event[]} events + * @returns {Event[]} + */ + +function postprocess(events) { + while (!subtokenize(events)) { + // Empty + } + + return events +} + +/** + * Turn the number (in string form as either hexa- or plain decimal) coming from + * a numeric character reference into a character. + * + * @param {string} value + * Value to decode. + * @param {number} base + * Numeric base. + * @returns {string} + */ +function decodeNumericCharacterReference(value, base) { + const code = Number.parseInt(value, base); + + if ( + // C0 except for HT, LF, FF, CR, space + code < 9 || + code === 11 || + (code > 13 && code < 32) || // Control character (DEL) of the basic block and C1 controls. + (code > 126 && code < 160) || // Lone high surrogates and low surrogates. + (code > 55295 && code < 57344) || // Noncharacters. + (code > 64975 && code < 65008) || + (code & 65535) === 65535 || + (code & 65535) === 65534 || // Out of range + code > 1114111 + ) { + return '\uFFFD' + } + + return String.fromCharCode(code) +} + +const characterEscapeOrReference = + /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi; +/** + * Utility to decode markdown strings (which occur in places such as fenced + * code info strings, destinations, labels, and titles). + * The “string” content type allows character escapes and -references. + * This decodes those. + * + * @param {string} value + * @returns {string} + */ + +function decodeString(value) { + return value.replace(characterEscapeOrReference, decode) +} +/** + * @param {string} $0 + * @param {string} $1 + * @param {string} $2 + * @returns {string} + */ + +function decode($0, $1, $2) { + if ($1) { + // Escape. + return $1 + } // Reference. + + const head = $2.charCodeAt(0); + + if (head === 35) { + const head = $2.charCodeAt(1); + const hex = head === 120 || head === 88; + return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10) + } + + return decodeEntity($2) || $0 +} + +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Value} Value + * @typedef {import('unist').Parent} UnistParent + * @typedef {import('unist').Point} Point + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').Content} Content + * @typedef {Root|Content} Node + * @typedef {Extract} Parent + * @typedef {import('mdast').Break} Break + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('mdast').Code} Code + * @typedef {import('mdast').Definition} Definition + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('mdast').Heading} Heading + * @typedef {import('mdast').HTML} HTML + * @typedef {import('mdast').Image} Image + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('mdast').List} List + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Strong} Strong + * @typedef {import('mdast').Text} Text + * @typedef {import('mdast').ThematicBreak} ThematicBreak + * + * @typedef {UnistParent & {type: 'fragment', children: PhrasingContent[]}} Fragment + */ +const own$5 = {}.hasOwnProperty; +/** + * @param value Markdown to parse (`string` or `Buffer`). + * @param [encoding] Character encoding to understand `value` as when it’s a `Buffer` (`string`, default: `'utf8'`). + * @param [options] Configuration + */ + +const fromMarkdown = + /** + * @param {Value} value + * @param {Encoding} [encoding] + * @param {Options} [options] + * @returns {Root} + */ + function (value, encoding, options) { + if (typeof encoding !== 'string') { + options = encoding; + encoding = undefined; + } + + return compiler(options)( + postprocess( + parse$1(options).document().write(preprocess()(value, encoding, true)) + ) + ) + }; +/** + * Note this compiler only understand complete buffering, not streaming. + * + * @param {Options} [options] + */ + +function compiler(options = {}) { + /** @type {NormalizedExtension} */ + // @ts-expect-error: our base has all required fields, so the result will too. + const config = configure$1( + { + transforms: [], + canContainEols: [ + 'emphasis', + 'fragment', + 'heading', + 'paragraph', + 'strong' + ], + enter: { + autolink: opener(link), + autolinkProtocol: onenterdata, + autolinkEmail: onenterdata, + atxHeading: opener(heading), + blockQuote: opener(blockQuote), + characterEscape: onenterdata, + characterReference: onenterdata, + codeFenced: opener(codeFlow), + codeFencedFenceInfo: buffer, + codeFencedFenceMeta: buffer, + codeIndented: opener(codeFlow, buffer), + codeText: opener(codeText, buffer), + codeTextData: onenterdata, + data: onenterdata, + codeFlowValue: onenterdata, + definition: opener(definition), + definitionDestinationString: buffer, + definitionLabelString: buffer, + definitionTitleString: buffer, + emphasis: opener(emphasis), + hardBreakEscape: opener(hardBreak), + hardBreakTrailing: opener(hardBreak), + htmlFlow: opener(html, buffer), + htmlFlowData: onenterdata, + htmlText: opener(html, buffer), + htmlTextData: onenterdata, + image: opener(image), + label: buffer, + link: opener(link), + listItem: opener(listItem), + listItemValue: onenterlistitemvalue, + listOrdered: opener(list, onenterlistordered), + listUnordered: opener(list), + paragraph: opener(paragraph), + reference: onenterreference, + referenceString: buffer, + resourceDestinationString: buffer, + resourceTitleString: buffer, + setextHeading: opener(heading), + strong: opener(strong), + thematicBreak: opener(thematicBreak) + }, + exit: { + atxHeading: closer(), + atxHeadingSequence: onexitatxheadingsequence, + autolink: closer(), + autolinkEmail: onexitautolinkemail, + autolinkProtocol: onexitautolinkprotocol, + blockQuote: closer(), + characterEscapeValue: onexitdata, + characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, + characterReferenceMarkerNumeric: onexitcharacterreferencemarker, + characterReferenceValue: onexitcharacterreferencevalue, + codeFenced: closer(onexitcodefenced), + codeFencedFence: onexitcodefencedfence, + codeFencedFenceInfo: onexitcodefencedfenceinfo, + codeFencedFenceMeta: onexitcodefencedfencemeta, + codeFlowValue: onexitdata, + codeIndented: closer(onexitcodeindented), + codeText: closer(onexitcodetext), + codeTextData: onexitdata, + data: onexitdata, + definition: closer(), + definitionDestinationString: onexitdefinitiondestinationstring, + definitionLabelString: onexitdefinitionlabelstring, + definitionTitleString: onexitdefinitiontitlestring, + emphasis: closer(), + hardBreakEscape: closer(onexithardbreak), + hardBreakTrailing: closer(onexithardbreak), + htmlFlow: closer(onexithtmlflow), + htmlFlowData: onexitdata, + htmlText: closer(onexithtmltext), + htmlTextData: onexitdata, + image: closer(onexitimage), + label: onexitlabel, + labelText: onexitlabeltext, + lineEnding: onexitlineending, + link: closer(onexitlink), + listItem: closer(), + listOrdered: closer(), + listUnordered: closer(), + paragraph: closer(), + referenceString: onexitreferencestring, + resourceDestinationString: onexitresourcedestinationstring, + resourceTitleString: onexitresourcetitlestring, + resource: onexitresource, + setextHeading: closer(onexitsetextheading), + setextHeadingLineSequence: onexitsetextheadinglinesequence, + setextHeadingText: onexitsetextheadingtext, + strong: closer(), + thematicBreak: closer() + } + }, + options.mdastExtensions || [] + ); + /** @type {CompileData} */ + + const data = {}; + return compile + /** + * @param {Array.} events + * @returns {Root} + */ + + function compile(events) { + /** @type {Root} */ + let tree = { + type: 'root', + children: [] + }; + /** @type {CompileContext['stack']} */ + + const stack = [tree]; + /** @type {CompileContext['tokenStack']} */ + + const tokenStack = []; + /** @type {Array.} */ + + const listStack = []; + /** @type {Omit} */ + + const context = { + stack, + tokenStack, + config, + enter, + exit, + buffer, + resume, + setData, + getData + }; + let index = -1; + + while (++index < events.length) { + // We preprocess lists to add `listItem` tokens, and to infer whether + // items the list itself are spread out. + if ( + events[index][1].type === 'listOrdered' || + events[index][1].type === 'listUnordered' + ) { + if (events[index][0] === 'enter') { + listStack.push(index); + } else { + const tail = listStack.pop(); + index = prepareList(events, tail, index); + } + } + } + + index = -1; + + while (++index < events.length) { + const handler = config[events[index][0]]; + + if (own$5.call(handler, events[index][1].type)) { + handler[events[index][1].type].call( + Object.assign( + { + sliceSerialize: events[index][2].sliceSerialize + }, + context + ), + events[index][1] + ); + } + } + + if (tokenStack.length > 0) { + throw new Error( + 'Cannot close document, a token (`' + + tokenStack[tokenStack.length - 1].type + + '`, ' + + stringifyPosition({ + start: tokenStack[tokenStack.length - 1].start, + end: tokenStack[tokenStack.length - 1].end + }) + + ') is still open' + ) + } // Figure out `root` position. + + tree.position = { + start: point( + events.length > 0 + ? events[0][1].start + : { + line: 1, + column: 1, + offset: 0 + } + ), + end: point( + events.length > 0 + ? events[events.length - 2][1].end + : { + line: 1, + column: 1, + offset: 0 + } + ) + }; + index = -1; + + while (++index < config.transforms.length) { + tree = config.transforms[index](tree) || tree; + } + + return tree + } + /** + * @param {Array.} events + * @param {number} start + * @param {number} length + * @returns {number} + */ + + function prepareList(events, start, length) { + let index = start - 1; + let containerBalance = -1; + let listSpread = false; + /** @type {Token|undefined} */ + + let listItem; + /** @type {number|undefined} */ + + let lineIndex; + /** @type {number|undefined} */ + + let firstBlankLineIndex; + /** @type {boolean|undefined} */ + + let atMarker; + + while (++index <= length) { + const event = events[index]; + + if ( + event[1].type === 'listUnordered' || + event[1].type === 'listOrdered' || + event[1].type === 'blockQuote' + ) { + if (event[0] === 'enter') { + containerBalance++; + } else { + containerBalance--; + } + + atMarker = undefined; + } else if (event[1].type === 'lineEndingBlank') { + if (event[0] === 'enter') { + if ( + listItem && + !atMarker && + !containerBalance && + !firstBlankLineIndex + ) { + firstBlankLineIndex = index; + } + + atMarker = undefined; + } + } else if ( + event[1].type === 'linePrefix' || + event[1].type === 'listItemValue' || + event[1].type === 'listItemMarker' || + event[1].type === 'listItemPrefix' || + event[1].type === 'listItemPrefixWhitespace' + ) ; else { + atMarker = undefined; + } + + if ( + (!containerBalance && + event[0] === 'enter' && + event[1].type === 'listItemPrefix') || + (containerBalance === -1 && + event[0] === 'exit' && + (event[1].type === 'listUnordered' || + event[1].type === 'listOrdered')) + ) { + if (listItem) { + let tailIndex = index; + lineIndex = undefined; + + while (tailIndex--) { + const tailEvent = events[tailIndex]; + + if ( + tailEvent[1].type === 'lineEnding' || + tailEvent[1].type === 'lineEndingBlank' + ) { + if (tailEvent[0] === 'exit') continue + + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank'; + listSpread = true; + } + + tailEvent[1].type = 'lineEnding'; + lineIndex = tailIndex; + } else if ( + tailEvent[1].type === 'linePrefix' || + tailEvent[1].type === 'blockQuotePrefix' || + tailEvent[1].type === 'blockQuotePrefixWhitespace' || + tailEvent[1].type === 'blockQuoteMarker' || + tailEvent[1].type === 'listItemIndent' + ) ; else { + break + } + } + + if ( + firstBlankLineIndex && + (!lineIndex || firstBlankLineIndex < lineIndex) + ) { + // @ts-expect-error Patched. + listItem._spread = true; + } // Fix position. + + listItem.end = Object.assign( + {}, + lineIndex ? events[lineIndex][1].start : event[1].end + ); + events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]); + index++; + length++; + } // Create a new list item. + + if (event[1].type === 'listItemPrefix') { + listItem = { + type: 'listItem', + // @ts-expect-error Patched + _spread: false, + start: Object.assign({}, event[1].start) + }; // @ts-expect-error: `listItem` is most definitely defined, TS... + + events.splice(index, 0, ['enter', listItem, event[2]]); + index++; + length++; + firstBlankLineIndex = undefined; + atMarker = true; + } + } + } // @ts-expect-error Patched. + + events[start][1]._spread = listSpread; + return length + } + /** + * @type {CompileContext['setData']} + * @param [value] + */ + + function setData(key, value) { + data[key] = value; + } + /** + * @type {CompileContext['getData']} + * @template {string} K + * @param {K} key + * @returns {CompileData[K]} + */ + + function getData(key) { + return data[key] + } + /** + * @param {Point} d + * @returns {Point} + */ + + function point(d) { + return { + line: d.line, + column: d.column, + offset: d.offset + } + } + /** + * @param {(token: Token) => Node} create + * @param {Handle} [and] + * @returns {Handle} + */ + + function opener(create, and) { + return open + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + + function open(token) { + enter.call(this, create(token), token); + if (and) and.call(this, token); + } + } + /** @type {CompileContext['buffer']} */ + + function buffer() { + this.stack.push({ + type: 'fragment', + children: [] + }); + } + /** + * @type {CompileContext['enter']} + * @template {Node} N + * @this {CompileContext} + * @param {N} node + * @param {Token} token + * @returns {N} + */ + + function enter(node, token) { + const parent = this.stack[this.stack.length - 1]; + // @ts-expect-error: Assume `Node` can exist as a child of `parent`. + parent.children.push(node); + this.stack.push(node); + this.tokenStack.push(token); // @ts-expect-error: `end` will be patched later. + + node.position = { + start: point(token.start) + }; + return node + } + /** + * @param {Handle} [and] + * @returns {Handle} + */ + + function closer(and) { + return close + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + + function close(token) { + if (and) and.call(this, token); + exit.call(this, token); + } + } + /** @type {CompileContext['exit']} */ + + function exit(token) { + const node = this.stack.pop(); + const open = this.tokenStack.pop(); + + if (!open) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): it’s not open' + ) + } else if (open.type !== token.type) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): a different token (`' + + open.type + + '`, ' + + stringifyPosition({ + start: open.start, + end: open.end + }) + + ') is open' + ) + } + + node.position.end = point(token.end); + return node + } + /** + * @this {CompileContext} + * @returns {string} + */ + + function resume() { + return toString(this.stack.pop()) + } // + // Handlers. + // + + /** @type {Handle} */ + + function onenterlistordered() { + setData('expectingFirstListItemValue', true); + } + /** @type {Handle} */ + + function onenterlistitemvalue(token) { + if (getData('expectingFirstListItemValue')) { + const ancestor = this.stack[this.stack.length - 2]; + ancestor.start = Number.parseInt(this.sliceSerialize(token), 10); + setData('expectingFirstListItemValue'); + } + } + /** @type {Handle} */ + + function onexitcodefencedfenceinfo() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.lang = data; + } + /** @type {Handle} */ + + function onexitcodefencedfencemeta() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.meta = data; + } + /** @type {Handle} */ + + function onexitcodefencedfence() { + // Exit if this is the closing fence. + if (getData('flowCodeInside')) return + this.buffer(); + setData('flowCodeInside', true); + } + /** @type {Handle} */ + + function onexitcodefenced() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, ''); + setData('flowCodeInside'); + } + /** @type {Handle} */ + + function onexitcodeindented() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.value = data.replace(/(\r?\n|\r)$/g, ''); + } + /** @type {Handle} */ + + function onexitdefinitionlabelstring(token) { + // Discard label, use the source content instead. + const label = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.label = label; + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase(); + } + /** @type {Handle} */ + + function onexitdefinitiontitlestring() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.title = data; + } + /** @type {Handle} */ + + function onexitdefinitiondestinationstring() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.url = data; + } + /** @type {Handle} */ + + function onexitatxheadingsequence(token) { + const node = this.stack[this.stack.length - 1]; + + if (!node.depth) { + const depth = this.sliceSerialize(token).length; + node.depth = depth; + } + } + /** @type {Handle} */ + + function onexitsetextheadingtext() { + setData('setextHeadingSlurpLineEnding', true); + } + /** @type {Handle} */ + + function onexitsetextheadinglinesequence(token) { + const node = this.stack[this.stack.length - 1]; + node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2; + } + /** @type {Handle} */ + + function onexitsetextheading() { + setData('setextHeadingSlurpLineEnding'); + } + /** @type {Handle} */ + + function onenterdata(token) { + const parent = this.stack[this.stack.length - 1]; + /** @type {Node} */ + + let tail = parent.children[parent.children.length - 1]; + + if (!tail || tail.type !== 'text') { + // Add a new text node. + tail = text(); // @ts-expect-error: we’ll add `end` later. + + tail.position = { + start: point(token.start) + }; // @ts-expect-error: Assume `parent` accepts `text`. + + parent.children.push(tail); + } + + this.stack.push(tail); + } + /** @type {Handle} */ + + function onexitdata(token) { + const tail = this.stack.pop(); + tail.value += this.sliceSerialize(token); + tail.position.end = point(token.end); + } + /** @type {Handle} */ + + function onexitlineending(token) { + const context = this.stack[this.stack.length - 1]; + + // If we’re at a hard break, include the line ending in there. + if (getData('atHardBreak')) { + const tail = context.children[context.children.length - 1]; + tail.position.end = point(token.end); + setData('atHardBreak'); + return + } + + if ( + !getData('setextHeadingSlurpLineEnding') && + config.canContainEols.includes(context.type) + ) { + onenterdata.call(this, token); + onexitdata.call(this, token); + } + } + /** @type {Handle} */ + + function onexithardbreak() { + setData('atHardBreak', true); + } + /** @type {Handle} */ + + function onexithtmlflow() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.value = data; + } + /** @type {Handle} */ + + function onexithtmltext() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.value = data; + } + /** @type {Handle} */ + + function onexitcodetext() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.value = data; + } + /** @type {Handle} */ + + function onexitlink() { + const context = this.stack[this.stack.length - 1]; // To do: clean. + + if (getData('inReference')) { + context.type += 'Reference'; // @ts-expect-error: mutate. + + context.referenceType = getData('referenceType') || 'shortcut'; // @ts-expect-error: mutate. + + delete context.url; + delete context.title; + } else { + // @ts-expect-error: mutate. + delete context.identifier; // @ts-expect-error: mutate. + + delete context.label; + } + + setData('referenceType'); + } + /** @type {Handle} */ + + function onexitimage() { + const context = this.stack[this.stack.length - 1]; // To do: clean. + + if (getData('inReference')) { + context.type += 'Reference'; // @ts-expect-error: mutate. + + context.referenceType = getData('referenceType') || 'shortcut'; // @ts-expect-error: mutate. + + delete context.url; + delete context.title; + } else { + // @ts-expect-error: mutate. + delete context.identifier; // @ts-expect-error: mutate. + + delete context.label; + } + + setData('referenceType'); + } + /** @type {Handle} */ + + function onexitlabeltext(token) { + const ancestor = this.stack[this.stack.length - 2]; + const string = this.sliceSerialize(token); + ancestor.label = decodeString(string); + ancestor.identifier = normalizeIdentifier(string).toLowerCase(); + } + /** @type {Handle} */ + + function onexitlabel() { + const fragment = this.stack[this.stack.length - 1]; + const value = this.resume(); + const node = this.stack[this.stack.length - 1]; // Assume a reference. + + setData('inReference', true); + + if (node.type === 'link') { + // @ts-expect-error: Assume static phrasing content. + node.children = fragment.children; + } else { + node.alt = value; + } + } + /** @type {Handle} */ + + function onexitresourcedestinationstring() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.url = data; + } + /** @type {Handle} */ + + function onexitresourcetitlestring() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.title = data; + } + /** @type {Handle} */ + + function onexitresource() { + setData('inReference'); + } + /** @type {Handle} */ + + function onenterreference() { + setData('referenceType', 'collapsed'); + } + /** @type {Handle} */ + + function onexitreferencestring(token) { + const label = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.label = label; + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase(); + setData('referenceType', 'full'); + } + /** @type {Handle} */ + + function onexitcharacterreferencemarker(token) { + setData('characterReferenceType', token.type); + } + /** @type {Handle} */ + + function onexitcharacterreferencevalue(token) { + const data = this.sliceSerialize(token); + const type = getData('characterReferenceType'); + /** @type {string} */ + + let value; + + if (type) { + value = decodeNumericCharacterReference( + data, + type === 'characterReferenceMarkerNumeric' ? 10 : 16 + ); + setData('characterReferenceType'); + } else { + // @ts-expect-error `decodeEntity` can return false for invalid named + // character references, but everything we’ve tokenized is valid. + value = decodeEntity(data); + } + + const tail = this.stack.pop(); + tail.value += value; + tail.position.end = point(token.end); + } + /** @type {Handle} */ + + function onexitautolinkprotocol(token) { + onexitdata.call(this, token); + const node = this.stack[this.stack.length - 1]; + node.url = this.sliceSerialize(token); + } + /** @type {Handle} */ + + function onexitautolinkemail(token) { + onexitdata.call(this, token); + const node = this.stack[this.stack.length - 1]; + node.url = 'mailto:' + this.sliceSerialize(token); + } // + // Creaters. + // + + /** @returns {Blockquote} */ + + function blockQuote() { + return { + type: 'blockquote', + children: [] + } + } + /** @returns {Code} */ + + function codeFlow() { + return { + type: 'code', + lang: null, + meta: null, + value: '' + } + } + /** @returns {InlineCode} */ + + function codeText() { + return { + type: 'inlineCode', + value: '' + } + } + /** @returns {Definition} */ + + function definition() { + return { + type: 'definition', + identifier: '', + label: null, + title: null, + url: '' + } + } + /** @returns {Emphasis} */ + + function emphasis() { + return { + type: 'emphasis', + children: [] + } + } + /** @returns {Heading} */ + + function heading() { + // @ts-expect-error `depth` will be set later. + return { + type: 'heading', + depth: undefined, + children: [] + } + } + /** @returns {Break} */ + + function hardBreak() { + return { + type: 'break' + } + } + /** @returns {HTML} */ + + function html() { + return { + type: 'html', + value: '' + } + } + /** @returns {Image} */ + + function image() { + return { + type: 'image', + title: null, + url: '', + alt: null + } + } + /** @returns {Link} */ + + function link() { + return { + type: 'link', + title: null, + url: '', + children: [] + } + } + /** + * @param {Token} token + * @returns {List} + */ + + function list(token) { + return { + type: 'list', + ordered: token.type === 'listOrdered', + start: null, + // @ts-expect-error Patched. + spread: token._spread, + children: [] + } + } + /** + * @param {Token} token + * @returns {ListItem} + */ + + function listItem(token) { + return { + type: 'listItem', + // @ts-expect-error Patched. + spread: token._spread, + checked: null, + children: [] + } + } + /** @returns {Paragraph} */ + + function paragraph() { + return { + type: 'paragraph', + children: [] + } + } + /** @returns {Strong} */ + + function strong() { + return { + type: 'strong', + children: [] + } + } + /** @returns {Text} */ + + function text() { + return { + type: 'text', + value: '' + } + } + /** @returns {ThematicBreak} */ + + function thematicBreak() { + return { + type: 'thematicBreak' + } + } +} +/** + * @param {Extension} combined + * @param {Array.>} extensions + * @returns {Extension} + */ + +function configure$1(combined, extensions) { + let index = -1; + + while (++index < extensions.length) { + const value = extensions[index]; + + if (Array.isArray(value)) { + configure$1(combined, value); + } else { + extension(combined, value); + } + } + + return combined +} +/** + * @param {Extension} combined + * @param {Extension} extension + * @returns {void} + */ + +function extension(combined, extension) { + /** @type {string} */ + let key; + + for (key in extension) { + if (own$5.call(extension, key)) { + const list = key === 'canContainEols' || key === 'transforms'; + const maybe = own$5.call(combined, key) ? combined[key] : undefined; + /* c8 ignore next */ + + const left = maybe || (combined[key] = list ? [] : {}); + const right = extension[key]; + + if (right) { + if (list) { + // @ts-expect-error: `left` is an array. + combined[key] = [...left, ...right]; + } else { + Object.assign(left, right); + } + } + } + } +} + +/** + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast-util-from-markdown').Options} Options + */ + +/** @type {import('unified').Plugin<[Options?] | void[], string, Root>} */ +function remarkParse(options) { + /** @type {import('unified').ParserFunction} */ + const parser = (doc) => { + // Assume options. + const settings = /** @type {Options} */ (this.data('settings')); + + return fromMarkdown( + doc, + Object.assign({}, settings, options, { + // Note: these options are not in the readme. + // The goal is for them to be set by plugins on `data` instead of being + // passed by users. + extensions: this.data('micromarkExtensions') || [], + mdastExtensions: this.data('fromMarkdownExtensions') || [] + }) + ) + }; + + Object.assign(this, {Parser: parser}); +} + +var own$4 = {}.hasOwnProperty; + +/** + * @callback Handler + * @param {...unknown} value + * @return {unknown} + * + * @typedef {Record} Handlers + * + * @typedef {Object} Options + * @property {Handler} [unknown] + * @property {Handler} [invalid] + * @property {Handlers} [handlers] + */ + +/** + * Handle values based on a property. + * + * @param {string} key + * @param {Options} [options] + */ +function zwitch(key, options) { + var settings = options || {}; + + /** + * Handle one value. + * Based on the bound `key`, a respective handler will be called. + * If `value` is not an object, or doesn’t have a `key` property, the special + * “invalid” handler will be called. + * If `value` has an unknown `key`, the special “unknown” handler will be + * called. + * + * All arguments, and the context object, are passed through to the handler, + * and it’s result is returned. + * + * @param {...unknown} [value] + * @this {unknown} + * @returns {unknown} + * @property {Handler} invalid + * @property {Handler} unknown + * @property {Handlers} handlers + */ + function one(value) { + var fn = one.invalid; + var handlers = one.handlers; + + if (value && own$4.call(value, key)) { + fn = own$4.call(handlers, value[key]) ? handlers[value[key]] : one.unknown; + } + + if (fn) { + return fn.apply(this, arguments) + } + } + + one.handlers = settings.handlers || {}; + one.invalid = settings.invalid; + one.unknown = settings.unknown; + + return one +} + +/** + * @typedef {import('./types.js').Options} Options + * @typedef {import('./types.js').Context} Context + */ + +/** + * @param {Context} base + * @param {Options} extension + * @returns {Context} + */ +function configure(base, extension) { + let index = -1; + /** @type {string} */ + let key; + + // First do subextensions. + if (extension.extensions) { + while (++index < extension.extensions.length) { + configure(base, extension.extensions[index]); + } + } + + for (key in extension) { + if (key === 'extensions') ; else if (key === 'unsafe' || key === 'join') { + /* c8 ignore next 2 */ + // @ts-expect-error: hush. + base[key] = [...(base[key] || []), ...(extension[key] || [])]; + } else if (key === 'handlers') { + base[key] = Object.assign(base[key], extension[key] || {}); + } else { + // @ts-expect-error: hush. + base.options[key] = extension[key]; + } + } + + return base +} + +/** + * @typedef {import('../types.js').Node} Node + * @typedef {import('../types.js').Parent} Parent + * @typedef {import('../types.js').Join} Join + * @typedef {import('../types.js').Context} Context + */ + +/** + * @param {Parent} parent + * @param {Context} context + * @returns {string} + */ +function containerFlow(parent, context) { + const indexStack = context.indexStack; + const children = parent.children || []; + /** @type {Array.} */ + const results = []; + let index = -1; + + indexStack.push(-1); + + while (++index < children.length) { + const child = children[index]; + + indexStack[indexStack.length - 1] = index; + + results.push( + context.handle(child, parent, context, {before: '\n', after: '\n'}) + ); + + if (child.type !== 'list') { + context.bulletLastUsed = undefined; + } + + if (index < children.length - 1) { + results.push(between(child, children[index + 1])); + } + } + + indexStack.pop(); + + return results.join('') + + /** + * @param {Node} left + * @param {Node} right + * @returns {string} + */ + function between(left, right) { + let index = context.join.length; + + while (index--) { + const result = context.join[index](left, right, parent, context); + + if (result === true || result === 1) { + break + } + + if (typeof result === 'number') { + return '\n'.repeat(1 + result) + } + + if (result === false) { + return '\n\n\n\n' + } + } + + return '\n\n' + } +} + +/** + * @callback Map + * @param {string} value + * @param {number} line + * @param {boolean} blank + * @returns {string} + */ + +const eol = /\r?\n|\r/g; + +/** + * @param {string} value + * @param {Map} map + * @returns {string} + */ +function indentLines(value, map) { + /** @type {Array.} */ + const result = []; + let start = 0; + let line = 0; + /** @type {RegExpExecArray|null} */ + let match; + + while ((match = eol.exec(value))) { + one(value.slice(start, match.index)); + result.push(match[0]); + start = match.index + match[0].length; + line++; + } + + one(value.slice(start)); + + return result.join('') + + /** + * @param {string} value + */ + function one(value) { + result.push(map(value, line, !value)); + } +} + +/** + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('../types.js').Handle} Handle + * @typedef {import('../util/indent-lines.js').Map} Map + */ + +/** + * @type {Handle} + * @param {Blockquote} node + */ +function blockquote(node, _, context) { + const exit = context.enter('blockquote'); + const value = indentLines(containerFlow(node, context), map$2); + exit(); + return value +} + +/** @type {Map} */ +function map$2(line, _, blank) { + return '>' + (blank ? '' : ' ') + line +} + +/** + * @typedef {import('../types.js').Unsafe} Unsafe + */ + +/** + * @param {Array.} stack + * @param {Unsafe} pattern + * @returns {boolean} + */ +function patternInScope(stack, pattern) { + return ( + listInScope(stack, pattern.inConstruct, true) && + !listInScope(stack, pattern.notInConstruct, false) + ) +} + +/** + * @param {Array.} stack + * @param {Unsafe['inConstruct']} list + * @param {boolean} none + * @returns {boolean} + */ +function listInScope(stack, list, none) { + if (!list) { + return none + } + + if (typeof list === 'string') { + list = [list]; + } + + let index = -1; + + while (++index < list.length) { + if (stack.includes(list[index])) { + return true + } + } + + return false +} + +/** + * @typedef {import('../types.js').Handle} Handle + * @typedef {import('mdast').Break} Break + */ + +/** + * @type {Handle} + * @param {Break} _ + */ +function hardBreak(_, _1, context, safe) { + let index = -1; + + while (++index < context.unsafe.length) { + // If we can’t put eols in this construct (setext headings, tables), use a + // space instead. + if ( + context.unsafe[index].character === '\n' && + patternInScope(context.stack, context.unsafe[index]) + ) { + return /[ \t]/.test(safe.before) ? '' : ' ' + } + } + + return '\\\n' +} + +/** + * Get the count of the longest repeating streak of `character` in `value`. + * + * @param {string} value Content. + * @param {string} character Single character to look for + * @returns {number} Count of most frequent adjacent `character`s in `value` + */ +function longestStreak(value, character) { + var source = String(value); + var index = source.indexOf(character); + var expected = index; + var count = 0; + var max = 0; + + if (typeof character !== 'string' || character.length !== 1) { + throw new Error('Expected character') + } + + while (index !== -1) { + if (index === expected) { + if (++count > max) { + max = count; + } + } else { + count = 1; + } + + expected = index + 1; + index = source.indexOf(character, expected); + } + + return max +} + +/** + * @typedef {import('mdast').Code} Code + * @typedef {import('../types.js').Context} Context + */ + +/** + * @param {Code} node + * @param {Context} context + * @returns {boolean} + */ +function formatCodeAsIndented(node, context) { + return Boolean( + !context.options.fences && + node.value && + // If there’s no info… + !node.lang && + // And there’s a non-whitespace character… + /[^ \r\n]/.test(node.value) && + // And the value doesn’t start or end in a blank… + !/^[\t ]*(?:[\r\n]|$)|(?:^|[\r\n])[\t ]*$/.test(node.value) + ) +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkFence(context) { + const marker = context.options.fence || '`'; + + if (marker !== '`' && marker !== '~') { + throw new Error( + 'Cannot serialize code with `' + + marker + + '` for `options.fence`, expected `` ` `` or `~`' + ) + } + + return marker +} + +/** + * @typedef {import('../types.js').Unsafe} Unsafe + */ + +/** + * @param {Unsafe} pattern + * @returns {RegExp} + */ +function patternCompile(pattern) { + if (!pattern._compiled) { + const before = + (pattern.atBreak ? '[\\r\\n][\\t ]*' : '') + + (pattern.before ? '(?:' + pattern.before + ')' : ''); + + pattern._compiled = new RegExp( + (before ? '(' + before + ')' : '') + + (/[|\\{}()[\]^$+*?.-]/.test(pattern.character) ? '\\' : '') + + pattern.character + + (pattern.after ? '(?:' + pattern.after + ')' : ''), + 'g' + ); + } + + return pattern._compiled +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').SafeOptions} SafeOptions + */ + +/** + * @param {Context} context + * @param {string|null|undefined} input + * @param {SafeOptions & {encode?: Array.}} config + * @returns {string} + */ +function safe(context, input, config) { + const value = (config.before || '') + (input || '') + (config.after || ''); + /** @type {Array.} */ + const positions = []; + /** @type {Array.} */ + const result = []; + /** @type {Record} */ + const infos = {}; + let index = -1; + + while (++index < context.unsafe.length) { + const pattern = context.unsafe[index]; + + if (!patternInScope(context.stack, pattern)) { + continue + } + + const expression = patternCompile(pattern); + /** @type {RegExpExecArray|null} */ + let match; + + while ((match = expression.exec(value))) { + const before = 'before' in pattern || Boolean(pattern.atBreak); + const after = 'after' in pattern; + const position = match.index + (before ? match[1].length : 0); + + if (positions.includes(position)) { + if (infos[position].before && !before) { + infos[position].before = false; + } + + if (infos[position].after && !after) { + infos[position].after = false; + } + } else { + positions.push(position); + infos[position] = {before, after}; + } + } + } + + positions.sort(numerical); + + let start = config.before ? config.before.length : 0; + const end = value.length - (config.after ? config.after.length : 0); + index = -1; + + while (++index < positions.length) { + const position = positions[index]; + + // Character before or after matched: + if (position < start || position >= end) { + continue + } + + // If this character is supposed to be escaped because it has a condition on + // the next character, and the next character is definitly being escaped, + // then skip this escape. + if ( + (position + 1 < end && + positions[index + 1] === position + 1 && + infos[position].after && + !infos[position + 1].before && + !infos[position + 1].after) || + (positions[index - 1] === position - 1 && + infos[position].before && + !infos[position - 1].before && + !infos[position - 1].after) + ) { + continue + } + + if (start !== position) { + // If we have to use a character reference, an ampersand would be more + // correct, but as backslashes only care about punctuation, either will + // do the trick + result.push(escapeBackslashes(value.slice(start, position), '\\')); + } + + start = position; + + if ( + /[!-/:-@[-`{-~]/.test(value.charAt(position)) && + (!config.encode || !config.encode.includes(value.charAt(position))) + ) { + // Character escape. + result.push('\\'); + } else { + // Character reference. + result.push( + '&#x' + value.charCodeAt(position).toString(16).toUpperCase() + ';' + ); + start++; + } + } + + result.push(escapeBackslashes(value.slice(start, end), config.after)); + + return result.join('') +} + +/** + * @param {number} a + * @param {number} b + * @returns {number} + */ +function numerical(a, b) { + return a - b +} + +/** + * @param {string} value + * @param {string} after + * @returns {string} + */ +function escapeBackslashes(value, after) { + const expression = /\\(?=[!-/:-@[-`{-~])/g; + /** @type {Array.} */ + const positions = []; + /** @type {Array.} */ + const results = []; + const whole = value + after; + let index = -1; + let start = 0; + /** @type {RegExpExecArray|null} */ + let match; + + while ((match = expression.exec(whole))) { + positions.push(match.index); + } + + while (++index < positions.length) { + if (start !== positions[index]) { + results.push(value.slice(start, positions[index])); + } + + results.push('\\'); + start = positions[index]; + } + + results.push(value.slice(start)); + + return results.join('') +} + +/** + * @typedef {import('mdast').Code} Code + * @typedef {import('../types.js').Handle} Handle + * @typedef {import('../types.js').Exit} Exit + * @typedef {import('../util/indent-lines.js').Map} Map + */ + +/** + * @type {Handle} + * @param {Code} node + */ +function code$1(node, _, context) { + const marker = checkFence(context); + const raw = node.value || ''; + const suffix = marker === '`' ? 'GraveAccent' : 'Tilde'; + /** @type {string} */ + let value; + /** @type {Exit} */ + let exit; + + if (formatCodeAsIndented(node, context)) { + exit = context.enter('codeIndented'); + value = indentLines(raw, map$1); + } else { + const sequence = marker.repeat(Math.max(longestStreak(raw, marker) + 1, 3)); + /** @type {Exit} */ + let subexit; + exit = context.enter('codeFenced'); + value = sequence; + + if (node.lang) { + subexit = context.enter('codeFencedLang' + suffix); + value += safe(context, node.lang, { + before: '`', + after: ' ', + encode: ['`'] + }); + subexit(); + } + + if (node.lang && node.meta) { + subexit = context.enter('codeFencedMeta' + suffix); + value += + ' ' + + safe(context, node.meta, { + before: ' ', + after: '\n', + encode: ['`'] + }); + subexit(); + } + + value += '\n'; + + if (raw) { + value += raw + '\n'; + } + + value += sequence; + } + + exit(); + return value +} + +/** @type {Map} */ +function map$1(line, _, blank) { + return (blank ? '' : ' ') + line +} + +/** + * @typedef {import('mdast').Association} Association + */ + +/** + * The `label` of an association is the string value: character escapes and + * references work, and casing is intact. + * The `identifier` is used to match one association to another: controversially, + * character escapes and references don’t work in this matching: `©` does + * not match `©`, and `\+` does not match `+`. + * But casing is ignored (and whitespace) is trimmed and collapsed: ` A\nb` + * matches `a b`. + * So, we do prefer the label when figuring out how we’re going to serialize: + * it has whitespace, casing, and we can ignore most useless character escapes + * and all character references. + * + * @param {Association} node + * @returns {string} + */ +function association(node) { + if (node.label || !node.identifier) { + return node.label || '' + } + + return decodeString(node.identifier) +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkQuote(context) { + const marker = context.options.quote || '"'; + + if (marker !== '"' && marker !== "'") { + throw new Error( + 'Cannot serialize title with `' + + marker + + '` for `options.quote`, expected `"`, or `\'`' + ) + } + + return marker +} + +/** + * @typedef {import('mdast').Definition} Definition + * @typedef {import('../types.js').Handle} Handle + */ + +/** + * @type {Handle} + * @param {Definition} node + */ +function definition(node, _, context) { + const marker = checkQuote(context); + const suffix = marker === '"' ? 'Quote' : 'Apostrophe'; + const exit = context.enter('definition'); + let subexit = context.enter('label'); + let value = + '[' + safe(context, association(node), {before: '[', after: ']'}) + ']: '; + + subexit(); + + if ( + // If there’s no url, or… + !node.url || + // If there’s whitespace, enclosed is prettier. + /[ \t\r\n]/.test(node.url) + ) { + subexit = context.enter('destinationLiteral'); + value += '<' + safe(context, node.url, {before: '<', after: '>'}) + '>'; + } else { + // No whitespace, raw is prettier. + subexit = context.enter('destinationRaw'); + value += safe(context, node.url, {before: ' ', after: ' '}); + } + + subexit(); + + if (node.title) { + subexit = context.enter('title' + suffix); + value += + ' ' + + marker + + safe(context, node.title, {before: marker, after: marker}) + + marker; + subexit(); + } + + exit(); + + return value +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkEmphasis(context) { + const marker = context.options.emphasis || '*'; + + if (marker !== '*' && marker !== '_') { + throw new Error( + 'Cannot serialize emphasis with `' + + marker + + '` for `options.emphasis`, expected `*`, or `_`' + ) + } + + return marker +} + +/** + * @typedef {import('../types.js').Node} Node + * @typedef {import('../types.js').Parent} Parent + * @typedef {import('../types.js').SafeOptions} SafeOptions + * @typedef {import('../types.js').Context} Context + */ + +/** + * @param {Parent} parent + * @param {Context} context + * @param {SafeOptions} safeOptions + * @returns {string} + */ +function containerPhrasing(parent, context, safeOptions) { + const indexStack = context.indexStack; + const children = parent.children || []; + /** @type {Array.} */ + const results = []; + let index = -1; + let before = safeOptions.before; + + indexStack.push(-1); + + while (++index < children.length) { + const child = children[index]; + /** @type {string} */ + let after; + + indexStack[indexStack.length - 1] = index; + + if (index + 1 < children.length) { + // @ts-expect-error: hush, it’s actually a `zwitch`. + let handle = context.handle.handlers[children[index + 1].type]; + if (handle && handle.peek) handle = handle.peek; + after = handle + ? handle(children[index + 1], parent, context, { + before: '', + after: '' + }).charAt(0) + : ''; + } else { + after = safeOptions.after; + } + + // In some cases, html (text) can be found in phrasing right after an eol. + // When we’d serialize that, in most cases that would be seen as html + // (flow). + // As we can’t escape or so to prevent it from happening, we take a somewhat + // reasonable approach: replace that eol with a space. + // See: + if ( + results.length > 0 && + (before === '\r' || before === '\n') && + child.type === 'html' + ) { + results[results.length - 1] = results[results.length - 1].replace( + /(\r?\n|\r)$/, + ' ' + ); + before = ' '; + } + + results.push(context.handle(child, parent, context, {before, after})); + + before = results[results.length - 1].slice(-1); + } + + indexStack.pop(); + + return results.join('') +} + +/** + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('../types.js').Handle} Handle + */ + +emphasis.peek = emphasisPeek; + +// To do: there are cases where emphasis cannot “form” depending on the +// previous or next character of sequences. +// There’s no way around that though, except for injecting zero-width stuff. +// Do we need to safeguard against that? +/** + * @type {Handle} + * @param {Emphasis} node + */ +function emphasis(node, _, context) { + const marker = checkEmphasis(context); + const exit = context.enter('emphasis'); + const value = containerPhrasing(node, context, { + before: marker, + after: marker + }); + exit(); + return marker + value + marker +} + +/** + * @type {Handle} + * @param {Emphasis} _ + */ +function emphasisPeek(_, _1, context) { + return context.options.emphasis || '*' +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * + * @typedef {string} Type + * @typedef {Object} Props + * + * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.} Test + */ + +const convert = + /** + * @type {( + * ((test: T['type']|Partial|TestFunctionPredicate) => AssertPredicate) & + * ((test?: Test) => AssertAnything) + * )} + */ + ( + /** + * Generate an assertion from a check. + * @param {Test} [test] + * When nullish, checks if `node` is a `Node`. + * When `string`, works like passing `function (node) {return node.type === test}`. + * When `function` checks if function passed the node is true. + * When `object`, checks that all keys in test are in node, and that they have (strictly) equal values. + * When `array`, checks any one of the subtests pass. + * @returns {AssertAnything} + */ + function (test) { + if (test === undefined || test === null) { + return ok + } + + if (typeof test === 'string') { + return typeFactory(test) + } + + if (typeof test === 'object') { + return Array.isArray(test) ? anyFactory(test) : propsFactory(test) + } + + if (typeof test === 'function') { + return castFactory(test) + } + + throw new Error('Expected function, string, or object as test') + } + ); +/** + * @param {Array.} tests + * @returns {AssertAnything} + */ +function anyFactory(tests) { + /** @type {Array.} */ + const checks = []; + let index = -1; + + while (++index < tests.length) { + checks[index] = convert(tests[index]); + } + + return castFactory(any) + + /** + * @this {unknown} + * @param {unknown[]} parameters + * @returns {boolean} + */ + function any(...parameters) { + let index = -1; + + while (++index < checks.length) { + if (checks[index].call(this, ...parameters)) return true + } + + return false + } +} + +/** + * Utility to assert each property in `test` is represented in `node`, and each + * values are strictly equal. + * + * @param {Props} check + * @returns {AssertAnything} + */ +function propsFactory(check) { + return castFactory(all) + + /** + * @param {Node} node + * @returns {boolean} + */ + function all(node) { + /** @type {string} */ + let key; + + for (key in check) { + // @ts-expect-error: hush, it sure works as an index. + if (node[key] !== check[key]) return false + } + + return true + } +} + +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * + * @param {Type} check + * @returns {AssertAnything} + */ +function typeFactory(check) { + return castFactory(type) + + /** + * @param {Node} node + */ + function type(node) { + return node && node.type === check + } +} + +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * @param {TestFunctionAnything} check + * @returns {AssertAnything} + */ +function castFactory(check) { + return assertion + + /** + * @this {unknown} + * @param {Array.} parameters + * @returns {boolean} + */ + function assertion(...parameters) { + // @ts-expect-error: spreading is fine. + return Boolean(check.call(this, ...parameters)) + } +} + +// Utility to return true. +function ok() { + return true +} + +/** + * @param {string} d + * @returns {string} + */ +function color$1(d) { + return '\u001B[33m' + d + '\u001B[39m' +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('./complex-types').Action} Action + * @typedef {import('./complex-types').Index} Index + * @typedef {import('./complex-types').ActionTuple} ActionTuple + * @typedef {import('./complex-types').VisitorResult} VisitorResult + * @typedef {import('./complex-types').Visitor} Visitor + */ + +/** + * Continue traversing as normal + */ +const CONTINUE$1 = true; +/** + * Do not traverse this node’s children + */ +const SKIP$1 = 'skip'; +/** + * Stop traversing immediately + */ +const EXIT$1 = false; + +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test node, optional + * @param visitor Function to run for each node + * @param reverse Visit the tree in reverse order, defaults to false + */ +const visitParents$1 = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: import('./complex-types').BuildVisitor, reverse?: boolean) => void) & + * ((tree: Tree, visitor: import('./complex-types').BuildVisitor, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {import('./complex-types').Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + // @ts-expect-error no visitor given, so `visitor` is test. + visitor = test; + test = null; + } + + const is = convert(test); + const step = reverse ? -1 : 1; + + factory(tree, null, [])(); + + /** + * @param {Node} node + * @param {number?} index + * @param {Array.} parents + */ + function factory(node, index, parents) { + /** @type {Object.} */ + // @ts-expect-error: hush + const value = typeof node === 'object' && node !== null ? node : {}; + /** @type {string|undefined} */ + let name; + + if (typeof value.type === 'string') { + name = + typeof value.tagName === 'string' + ? value.tagName + : typeof value.name === 'string' + ? value.name + : undefined; + + Object.defineProperty(visit, 'name', { + value: + 'node (' + + color$1(value.type + (name ? '<' + name + '>' : '')) + + ')' + }); + } + + return visit + + function visit() { + /** @type {ActionTuple} */ + let result = []; + /** @type {ActionTuple} */ + let subresult; + /** @type {number} */ + let offset; + /** @type {Array.} */ + let grandparents; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$1(visitor(node, parents)); + + if (result[0] === EXIT$1) { + return result + } + } + + // @ts-expect-error looks like a parent. + if (node.children && result[0] !== SKIP$1) { + // @ts-expect-error looks like a parent. + offset = (reverse ? node.children.length : -1) + step; + // @ts-expect-error looks like a parent. + grandparents = parents.concat(node); + + // @ts-expect-error looks like a parent. + while (offset > -1 && offset < node.children.length) { + // @ts-expect-error looks like a parent. + subresult = factory(node.children[offset], offset, grandparents)(); + + if (subresult[0] === EXIT$1) { + return subresult + } + + offset = + typeof subresult[1] === 'number' ? subresult[1] : offset + step; + } + } + + return result + } + } + } + ); + +/** + * @param {VisitorResult} value + * @returns {ActionTuple} + */ +function toResult$1(value) { + if (Array.isArray(value)) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$1, value] + } + + return [value] +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult + */ + +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test, optional + * @param visitor Function to run for each node + * @param reverse Fisit the tree in reverse, defaults to false + */ +const visit$1 = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + visitParents$1(tree, test, overload, reverse); + + /** + * @param {Node} node + * @param {Array.} parents + */ + function overload(node, parents) { + const parent = parents[parents.length - 1]; + return visitor( + node, + parent ? parent.children.indexOf(node) : null, + parent + ) + } + } + ); + +/** + * @typedef {import('mdast').Heading} Heading + * @typedef {import('../types.js').Context} Context + */ + +/** + * @param {Heading} node + * @param {Context} context + * @returns {boolean} + */ +function formatHeadingAsSetext(node, context) { + let literalWithBreak = false; + + // Look for literals with a line break. + // Note that this also + visit$1(node, (node) => { + if ( + ('value' in node && /\r?\n|\r/.test(node.value)) || + node.type === 'break' + ) { + literalWithBreak = true; + return EXIT$1 + } + }); + + return Boolean( + (!node.depth || node.depth < 3) && + toString(node) && + (context.options.setext || literalWithBreak) + ) +} + +/** + * @typedef {import('mdast').Heading} Heading + * @typedef {import('../types.js').Handle} Handle + * @typedef {import('../types.js').Exit} Exit + */ + +/** + * @type {Handle} + * @param {Heading} node + */ +function heading(node, _, context) { + const rank = Math.max(Math.min(6, node.depth || 1), 1); + + if (formatHeadingAsSetext(node, context)) { + const exit = context.enter('headingSetext'); + const subexit = context.enter('phrasing'); + const value = containerPhrasing(node, context, {before: '\n', after: '\n'}); + subexit(); + exit(); + + return ( + value + + '\n' + + (rank === 1 ? '=' : '-').repeat( + // The whole size… + value.length - + // Minus the position of the character after the last EOL (or + // 0 if there is none)… + (Math.max(value.lastIndexOf('\r'), value.lastIndexOf('\n')) + 1) + ) + ) + } + + const sequence = '#'.repeat(rank); + const exit = context.enter('headingAtx'); + const subexit = context.enter('phrasing'); + let value = containerPhrasing(node, context, {before: '# ', after: '\n'}); + + if (/^[\t ]/.test(value)) { + value = + '&#x' + + value.charCodeAt(0).toString(16).toUpperCase() + + ';' + + value.slice(1); + } + + value = value ? sequence + ' ' + value : sequence; + + if (context.options.closeAtx) { + value += ' ' + sequence; + } + + subexit(); + exit(); + + return value +} + +/** + * @typedef {import('mdast').HTML} HTML + * @typedef {import('../types.js').Handle} Handle + */ + +html.peek = htmlPeek; + +/** + * @type {Handle} + * @param {HTML} node + */ +function html(node) { + return node.value || '' +} + +/** + * @type {Handle} + */ +function htmlPeek() { + return '<' +} + +/** + * @typedef {import('mdast').Image} Image + * @typedef {import('../types.js').Handle} Handle + */ + +image.peek = imagePeek; + +/** + * @type {Handle} + * @param {Image} node + */ +function image(node, _, context) { + const quote = checkQuote(context); + const suffix = quote === '"' ? 'Quote' : 'Apostrophe'; + const exit = context.enter('image'); + let subexit = context.enter('label'); + let value = '![' + safe(context, node.alt, {before: '[', after: ']'}) + ']('; + + subexit(); + + if ( + // If there’s no url but there is a title… + (!node.url && node.title) || + // Or if there’s markdown whitespace or an eol, enclose. + /[ \t\r\n]/.test(node.url) + ) { + subexit = context.enter('destinationLiteral'); + value += '<' + safe(context, node.url, {before: '<', after: '>'}) + '>'; + } else { + // No whitespace, raw is prettier. + subexit = context.enter('destinationRaw'); + value += safe(context, node.url, { + before: '(', + after: node.title ? ' ' : ')' + }); + } + + subexit(); + + if (node.title) { + subexit = context.enter('title' + suffix); + value += + ' ' + + quote + + safe(context, node.title, {before: quote, after: quote}) + + quote; + subexit(); + } + + value += ')'; + exit(); + + return value +} + +/** + * @type {Handle} + */ +function imagePeek() { + return '!' +} + +/** + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('../types.js').Handle} Handle + */ + +imageReference.peek = imageReferencePeek; + +/** + * @type {Handle} + * @param {ImageReference} node + */ +function imageReference(node, _, context) { + const type = node.referenceType; + const exit = context.enter('imageReference'); + let subexit = context.enter('label'); + const alt = safe(context, node.alt, {before: '[', after: ']'}); + let value = '![' + alt + ']'; + + subexit(); + // Hide the fact that we’re in phrasing, because escapes don’t work. + const stack = context.stack; + context.stack = []; + subexit = context.enter('reference'); + const reference = safe(context, association(node), {before: '[', after: ']'}); + subexit(); + context.stack = stack; + exit(); + + if (type === 'full' || !alt || alt !== reference) { + value += '[' + reference + ']'; + } else if (type !== 'shortcut') { + value += '[]'; + } + + return value +} + +/** + * @type {Handle} + */ +function imageReferencePeek() { + return '!' +} + +/** + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('../types.js').Handle} Handle + */ + +inlineCode.peek = inlineCodePeek; + +/** + * @type {Handle} + * @param {InlineCode} node + */ +function inlineCode(node, _, context) { + let value = node.value || ''; + let sequence = '`'; + let index = -1; + + // If there is a single grave accent on its own in the code, use a fence of + // two. + // If there are two in a row, use one. + while (new RegExp('(^|[^`])' + sequence + '([^`]|$)').test(value)) { + sequence += '`'; + } + + // If this is not just spaces or eols (tabs don’t count), and either the + // first or last character are a space, eol, or tick, then pad with spaces. + if ( + /[^ \r\n]/.test(value) && + ((/^[ \r\n]/.test(value) && /[ \r\n]$/.test(value)) || /^`|`$/.test(value)) + ) { + value = ' ' + value + ' '; + } + + // We have a potential problem: certain characters after eols could result in + // blocks being seen. + // For example, if someone injected the string `'\n# b'`, then that would + // result in an ATX heading. + // We can’t escape characters in `inlineCode`, but because eols are + // transformed to spaces when going from markdown to HTML anyway, we can swap + // them out. + while (++index < context.unsafe.length) { + const pattern = context.unsafe[index]; + const expression = patternCompile(pattern); + /** @type {RegExpExecArray|null} */ + let match; + + // Only look for `atBreak`s. + // Btw: note that `atBreak` patterns will always start the regex at LF or + // CR. + if (!pattern.atBreak) continue + + while ((match = expression.exec(value))) { + let position = match.index; + + // Support CRLF (patterns only look for one of the characters). + if ( + value.charCodeAt(position) === 10 /* `\n` */ && + value.charCodeAt(position - 1) === 13 /* `\r` */ + ) { + position--; + } + + value = value.slice(0, position) + ' ' + value.slice(match.index + 1); + } + } + + return sequence + value + sequence +} + +/** + * @type {Handle} + */ +function inlineCodePeek() { + return '`' +} + +/** + * @typedef {import('mdast').Link} Link + * @typedef {import('../types.js').Context} Context + */ + +/** + * @param {Link} node + * @param {Context} context + * @returns {boolean} + */ +function formatLinkAsAutolink(node, context) { + const raw = toString(node); + + return Boolean( + !context.options.resourceLink && + // If there’s a url… + node.url && + // And there’s a no title… + !node.title && + // And the content of `node` is a single text node… + node.children && + node.children.length === 1 && + node.children[0].type === 'text' && + // And if the url is the same as the content… + (raw === node.url || 'mailto:' + raw === node.url) && + // And that starts w/ a protocol… + /^[a-z][a-z+.-]+:/i.test(node.url) && + // And that doesn’t contain ASCII control codes (character escapes and + // references don’t work) or angle brackets… + !/[\0- <>\u007F]/.test(node.url) + ) +} + +/** + * @typedef {import('mdast').Link} Link + * @typedef {import('../types.js').Handle} Handle + * @typedef {import('../types.js').Exit} Exit + */ + +link.peek = linkPeek; + +/** + * @type {Handle} + * @param {Link} node + */ +function link(node, _, context) { + const quote = checkQuote(context); + const suffix = quote === '"' ? 'Quote' : 'Apostrophe'; + /** @type {Exit} */ + let exit; + /** @type {Exit} */ + let subexit; + /** @type {string} */ + let value; + + if (formatLinkAsAutolink(node, context)) { + // Hide the fact that we’re in phrasing, because escapes don’t work. + const stack = context.stack; + context.stack = []; + exit = context.enter('autolink'); + value = + '<' + containerPhrasing(node, context, {before: '<', after: '>'}) + '>'; + exit(); + context.stack = stack; + return value + } + + exit = context.enter('link'); + subexit = context.enter('label'); + value = + '[' + containerPhrasing(node, context, {before: '[', after: ']'}) + ']('; + subexit(); + + if ( + // If there’s no url but there is a title… + (!node.url && node.title) || + // Or if there’s markdown whitespace or an eol, enclose. + /[ \t\r\n]/.test(node.url) + ) { + subexit = context.enter('destinationLiteral'); + value += '<' + safe(context, node.url, {before: '<', after: '>'}) + '>'; + } else { + // No whitespace, raw is prettier. + subexit = context.enter('destinationRaw'); + value += safe(context, node.url, { + before: '(', + after: node.title ? ' ' : ')' + }); + } + + subexit(); + + if (node.title) { + subexit = context.enter('title' + suffix); + value += + ' ' + + quote + + safe(context, node.title, {before: quote, after: quote}) + + quote; + subexit(); + } + + value += ')'; + + exit(); + return value +} + +/** + * @type {Handle} + * @param {Link} node + */ +function linkPeek(node, _, context) { + return formatLinkAsAutolink(node, context) ? '<' : '[' +} + +/** + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('../types.js').Handle} Handle + */ + +linkReference.peek = linkReferencePeek; + +/** + * @type {Handle} + * @param {LinkReference} node + */ +function linkReference(node, _, context) { + const type = node.referenceType; + const exit = context.enter('linkReference'); + let subexit = context.enter('label'); + const text = containerPhrasing(node, context, {before: '[', after: ']'}); + let value = '[' + text + ']'; + + subexit(); + // Hide the fact that we’re in phrasing, because escapes don’t work. + const stack = context.stack; + context.stack = []; + subexit = context.enter('reference'); + const reference = safe(context, association(node), {before: '[', after: ']'}); + subexit(); + context.stack = stack; + exit(); + + if (type === 'full' || !text || text !== reference) { + value += '[' + reference + ']'; + } else if (type !== 'shortcut') { + value += '[]'; + } + + return value +} + +/** + * @type {Handle} + */ +function linkReferencePeek() { + return '[' +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkBullet(context) { + const marker = context.options.bullet || '*'; + + if (marker !== '*' && marker !== '+' && marker !== '-') { + throw new Error( + 'Cannot serialize items with `' + + marker + + '` for `options.bullet`, expected `*`, `+`, or `-`' + ) + } + + return marker +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkBulletOther(context) { + const bullet = checkBullet(context); + const bulletOther = context.options.bulletOther; + + if (!bulletOther) { + return bullet === '*' ? '-' : '*' + } + + if (bulletOther !== '*' && bulletOther !== '+' && bulletOther !== '-') { + throw new Error( + 'Cannot serialize items with `' + + bulletOther + + '` for `options.bulletOther`, expected `*`, `+`, or `-`' + ) + } + + if (bulletOther === bullet) { + throw new Error( + 'Expected `bullet` (`' + + bullet + + '`) and `bulletOther` (`' + + bulletOther + + '`) to be different' + ) + } + + return bulletOther +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkBulletOrdered(context) { + const marker = context.options.bulletOrdered || '.'; + + if (marker !== '.' && marker !== ')') { + throw new Error( + 'Cannot serialize items with `' + + marker + + '` for `options.bulletOrdered`, expected `.` or `)`' + ) + } + + return marker +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkBulletOrderedOther(context) { + const bulletOrdered = checkBulletOrdered(context); + const bulletOrderedOther = context.options.bulletOrderedOther; + + if (!bulletOrderedOther) { + return bulletOrdered === '.' ? ')' : '.' + } + + if (bulletOrderedOther !== '.' && bulletOrderedOther !== ')') { + throw new Error( + 'Cannot serialize items with `' + + bulletOrderedOther + + '` for `options.bulletOrderedOther`, expected `*`, `+`, or `-`' + ) + } + + if (bulletOrderedOther === bulletOrdered) { + throw new Error( + 'Expected `bulletOrdered` (`' + + bulletOrdered + + '`) and `bulletOrderedOther` (`' + + bulletOrderedOther + + '`) to be different' + ) + } + + return bulletOrderedOther +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkRule(context) { + const marker = context.options.rule || '*'; + + if (marker !== '*' && marker !== '-' && marker !== '_') { + throw new Error( + 'Cannot serialize rules with `' + + marker + + '` for `options.rule`, expected `*`, `-`, or `_`' + ) + } + + return marker +} + +/** + * @typedef {import('mdast').List} List + * @typedef {import('../types.js').Handle} Handle + */ + +/** + * @type {Handle} + * @param {List} node + */ +function list(node, parent, context) { + const exit = context.enter('list'); + const bulletCurrent = context.bulletCurrent; + /** @type {string} */ + let bullet = node.ordered ? checkBulletOrdered(context) : checkBullet(context); + /** @type {string} */ + const bulletOther = node.ordered + ? checkBulletOrderedOther(context) + : checkBulletOther(context); + const bulletLastUsed = context.bulletLastUsed; + let useDifferentMarker = false; + + if ( + parent && + // Explicit `other` set. + (node.ordered + ? context.options.bulletOrderedOther + : context.options.bulletOther) && + bulletLastUsed && + bullet === bulletLastUsed + ) { + useDifferentMarker = true; + } + + if (!node.ordered) { + const firstListItem = node.children ? node.children[0] : undefined; + + // If there’s an empty first list item directly in two list items, + // we have to use a different bullet: + // + // ```markdown + // * - * + // ``` + // + // …because otherwise it would become one big thematic break. + if ( + // Bullet could be used as a thematic break marker: + (bullet === '*' || bullet === '-') && + // Empty first list item: + firstListItem && + (!firstListItem.children || !firstListItem.children[0]) && + // Directly in two other list items: + context.stack[context.stack.length - 1] === 'list' && + context.stack[context.stack.length - 2] === 'listItem' && + context.stack[context.stack.length - 3] === 'list' && + context.stack[context.stack.length - 4] === 'listItem' && + // That are each the first child. + context.indexStack[context.indexStack.length - 1] === 0 && + context.indexStack[context.indexStack.length - 2] === 0 && + context.indexStack[context.indexStack.length - 3] === 0 && + context.indexStack[context.indexStack.length - 4] === 0 + ) { + useDifferentMarker = true; + } + + // If there’s a thematic break at the start of the first list item, + // we have to use a different bullet: + // + // ```markdown + // * --- + // ``` + // + // …because otherwise it would become one big thematic break. + if (checkRule(context) === bullet && firstListItem) { + let index = -1; + + while (++index < node.children.length) { + const item = node.children[index]; + + if ( + item && + item.type === 'listItem' && + item.children && + item.children[0] && + item.children[0].type === 'thematicBreak' + ) { + useDifferentMarker = true; + break + } + } + } + } + + if (useDifferentMarker) { + bullet = bulletOther; + } + + context.bulletCurrent = bullet; + const value = containerFlow(node, context); + context.bulletLastUsed = bullet; + context.bulletCurrent = bulletCurrent; + exit(); + return value +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkListItemIndent(context) { + const style = context.options.listItemIndent || 'tab'; + + // To do: remove in a major. + // @ts-expect-error: deprecated. + if (style === 1 || style === '1') { + return 'one' + } + + if (style !== 'tab' && style !== 'one' && style !== 'mixed') { + throw new Error( + 'Cannot serialize items with `' + + style + + '` for `options.listItemIndent`, expected `tab`, `one`, or `mixed`' + ) + } + + return style +} + +/** + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').List} List + * @typedef {import('../util/indent-lines.js').Map} Map + * @typedef {import('../types.js').Options} Options + * @typedef {import('../types.js').Handle} Handle + */ + +/** + * @type {Handle} + * @param {ListItem} node + */ +function listItem(node, parent, context) { + const listItemIndent = checkListItemIndent(context); + let bullet = context.bulletCurrent || checkBullet(context); + + // Add the marker value for ordered lists. + if (parent && parent.type === 'list' && parent.ordered) { + bullet = + (typeof parent.start === 'number' && parent.start > -1 + ? parent.start + : 1) + + (context.options.incrementListMarker === false + ? 0 + : parent.children.indexOf(node)) + + bullet; + } + + let size = bullet.length + 1; + + if ( + listItemIndent === 'tab' || + (listItemIndent === 'mixed' && + ((parent && parent.type === 'list' && parent.spread) || node.spread)) + ) { + size = Math.ceil(size / 4) * 4; + } + + const exit = context.enter('listItem'); + const value = indentLines(containerFlow(node, context), map); + exit(); + + return value + + /** @type {Map} */ + function map(line, index, blank) { + if (index) { + return (blank ? '' : ' '.repeat(size)) + line + } + + return (blank ? bullet : bullet + ' '.repeat(size - bullet.length)) + line + } +} + +/** + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('../types.js').Handle} Handle + */ + +/** + * @type {Handle} + * @param {Paragraph} node + */ +function paragraph(node, _, context) { + const exit = context.enter('paragraph'); + const subexit = context.enter('phrasing'); + const value = containerPhrasing(node, context, {before: '\n', after: '\n'}); + subexit(); + exit(); + return value +} + +/** + * @typedef {import('mdast').Root} Root + * @typedef {import('../types.js').Handle} Handle + */ + +/** + * @type {Handle} + * @param {Root} node + */ +function root(node, _, context) { + return containerFlow(node, context) +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkStrong(context) { + const marker = context.options.strong || '*'; + + if (marker !== '*' && marker !== '_') { + throw new Error( + 'Cannot serialize strong with `' + + marker + + '` for `options.strong`, expected `*`, or `_`' + ) + } + + return marker +} + +/** + * @typedef {import('mdast').Strong} Strong + * @typedef {import('../types.js').Handle} Handle + */ + +strong.peek = strongPeek; + +// To do: there are cases where emphasis cannot “form” depending on the +// previous or next character of sequences. +// There’s no way around that though, except for injecting zero-width stuff. +// Do we need to safeguard against that? +/** + * @type {Handle} + * @param {Strong} node + */ +function strong(node, _, context) { + const marker = checkStrong(context); + const exit = context.enter('strong'); + const value = containerPhrasing(node, context, { + before: marker, + after: marker + }); + exit(); + return marker + marker + value + marker + marker +} + +/** + * @type {Handle} + * @param {Strong} _ + */ +function strongPeek(_, _1, context) { + return context.options.strong || '*' +} + +/** + * @typedef {import('mdast').Text} Text + * @typedef {import('../types.js').Handle} Handle + */ + +/** + * @type {Handle} + * @param {Text} node + */ +function text$1(node, _, context, safeOptions) { + return safe(context, node.value, safeOptions) +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkRuleRepetition(context) { + const repetition = context.options.ruleRepetition || 3; + + if (repetition < 3) { + throw new Error( + 'Cannot serialize rules with repetition `' + + repetition + + '` for `options.ruleRepetition`, expected `3` or more' + ) + } + + return repetition +} + +/** + * @typedef {import('../types.js').Handle} Handle + * @typedef {import('mdast').ThematicBreak} ThematicBreak + */ + +/** + * @type {Handle} + * @param {ThematicBreak} _ + */ +function thematicBreak(_, _1, context) { + const value = ( + checkRule(context) + (context.options.ruleSpaces ? ' ' : '') + ).repeat(checkRuleRepetition(context)); + + return context.options.ruleSpaces ? value.slice(0, -1) : value +} + +const handle = { + blockquote, + break: hardBreak, + code: code$1, + definition, + emphasis, + hardBreak, + heading, + html, + image, + imageReference, + inlineCode, + link, + linkReference, + list, + listItem, + paragraph, + root, + strong, + text: text$1, + thematicBreak +}; + +/** + * @typedef {import('./types.js').Join} Join + */ + +/** @type {Array.} */ +const join = [joinDefaults]; + +/** @type {Join} */ +function joinDefaults(left, right, parent, context) { + // Indented code after list or another indented code. + if ( + right.type === 'code' && + formatCodeAsIndented(right, context) && + (left.type === 'list' || + (left.type === right.type && formatCodeAsIndented(left, context))) + ) { + return false + } + + // Two lists with the same marker. + if ( + left.type === 'list' && + left.type === right.type && + Boolean(left.ordered) === Boolean(right.ordered) && + !(left.ordered + ? context.options.bulletOrderedOther + : context.options.bulletOther) + ) { + return false + } + + // Join children of a list or an item. + // In which case, `parent` has a `spread` field. + if ('spread' in parent && typeof parent.spread === 'boolean') { + if ( + left.type === 'paragraph' && + // Two paragraphs. + (left.type === right.type || + right.type === 'definition' || + // Paragraph followed by a setext heading. + (right.type === 'heading' && formatHeadingAsSetext(right, context))) + ) { + return + } + + return parent.spread ? 1 : 0 + } +} + +/** + * @typedef {import('./types.js').Unsafe} Unsafe + */ + +/** @type {Array.} */ +const unsafe = [ + {character: '\t', after: '[\\r\\n]', inConstruct: 'phrasing'}, + {character: '\t', before: '[\\r\\n]', inConstruct: 'phrasing'}, + { + character: '\t', + inConstruct: ['codeFencedLangGraveAccent', 'codeFencedLangTilde'] + }, + { + character: '\r', + inConstruct: [ + 'codeFencedLangGraveAccent', + 'codeFencedLangTilde', + 'codeFencedMetaGraveAccent', + 'codeFencedMetaTilde', + 'destinationLiteral', + 'headingAtx' + ] + }, + { + character: '\n', + inConstruct: [ + 'codeFencedLangGraveAccent', + 'codeFencedLangTilde', + 'codeFencedMetaGraveAccent', + 'codeFencedMetaTilde', + 'destinationLiteral', + 'headingAtx' + ] + }, + {character: ' ', after: '[\\r\\n]', inConstruct: 'phrasing'}, + {character: ' ', before: '[\\r\\n]', inConstruct: 'phrasing'}, + { + character: ' ', + inConstruct: ['codeFencedLangGraveAccent', 'codeFencedLangTilde'] + }, + // An exclamation mark can start an image, if it is followed by a link or + // a link reference. + {character: '!', after: '\\[', inConstruct: 'phrasing'}, + // A quote can break out of a title. + {character: '"', inConstruct: 'titleQuote'}, + // A number sign could start an ATX heading if it starts a line. + {atBreak: true, character: '#'}, + {character: '#', inConstruct: 'headingAtx', after: '(?:[\r\n]|$)'}, + // Dollar sign and percentage are not used in markdown. + // An ampersand could start a character reference. + {character: '&', after: '[#A-Za-z]', inConstruct: 'phrasing'}, + // An apostrophe can break out of a title. + {character: "'", inConstruct: 'titleApostrophe'}, + // A left paren could break out of a destination raw. + {character: '(', inConstruct: 'destinationRaw'}, + {before: '\\]', character: '(', inConstruct: 'phrasing'}, + // A right paren could start a list item or break out of a destination + // raw. + {atBreak: true, before: '\\d+', character: ')'}, + {character: ')', inConstruct: 'destinationRaw'}, + // An asterisk can start thematic breaks, list items, emphasis, strong. + {atBreak: true, character: '*'}, + {character: '*', inConstruct: 'phrasing'}, + // A plus sign could start a list item. + {atBreak: true, character: '+'}, + // A dash can start thematic breaks, list items, and setext heading + // underlines. + {atBreak: true, character: '-'}, + // A dot could start a list item. + {atBreak: true, before: '\\d+', character: '.', after: '(?:[ \t\r\n]|$)'}, + // Slash, colon, and semicolon are not used in markdown for constructs. + // A less than can start html (flow or text) or an autolink. + // HTML could start with an exclamation mark (declaration, cdata, comment), + // slash (closing tag), question mark (instruction), or a letter (tag). + // An autolink also starts with a letter. + // Finally, it could break out of a destination literal. + {atBreak: true, character: '<', after: '[!/?A-Za-z]'}, + {character: '<', after: '[!/?A-Za-z]', inConstruct: 'phrasing'}, + {character: '<', inConstruct: 'destinationLiteral'}, + // An equals to can start setext heading underlines. + {atBreak: true, character: '='}, + // A greater than can start block quotes and it can break out of a + // destination literal. + {atBreak: true, character: '>'}, + {character: '>', inConstruct: 'destinationLiteral'}, + // Question mark and at sign are not used in markdown for constructs. + // A left bracket can start definitions, references, labels, + {atBreak: true, character: '['}, + {character: '[', inConstruct: ['phrasing', 'label', 'reference']}, + // A backslash can start an escape (when followed by punctuation) or a + // hard break (when followed by an eol). + // Note: typical escapes are handled in `safe`! + {character: '\\', after: '[\\r\\n]', inConstruct: 'phrasing'}, + // A right bracket can exit labels. + {character: ']', inConstruct: ['label', 'reference']}, + // Caret is not used in markdown for constructs. + // An underscore can start emphasis, strong, or a thematic break. + {atBreak: true, character: '_'}, + {character: '_', inConstruct: 'phrasing'}, + // A grave accent can start code (fenced or text), or it can break out of + // a grave accent code fence. + {atBreak: true, character: '`'}, + { + character: '`', + inConstruct: [ + 'codeFencedLangGraveAccent', + 'codeFencedMetaGraveAccent', + 'phrasing' + ] + }, + // Left brace, vertical bar, right brace are not used in markdown for + // constructs. + // A tilde can start code (fenced). + {atBreak: true, character: '~'} +]; + +/** + * @typedef {import('./types.js').Node} Node + * @typedef {import('./types.js').Options} Options + * @typedef {import('./types.js').Context} Context + * @typedef {import('./types.js').Handle} Handle + * @typedef {import('./types.js').Join} Join + * @typedef {import('./types.js').Unsafe} Unsafe + */ + +/** + * @param {Node} tree + * @param {Options} [options] + * @returns {string} + */ +function toMarkdown(tree, options = {}) { + /** @type {Context} */ + // @ts-expect-error: we’ll add `handle` later. + const context = { + enter, + stack: [], + unsafe: [], + join: [], + handlers: {}, + options: {}, + indexStack: [] + }; + + configure(context, {unsafe, join, handlers: handle}); + configure(context, options); + + if (context.options.tightDefinitions) { + configure(context, {join: [joinDefinition]}); + } + + /** @type {Handle} */ + context.handle = zwitch('type', { + invalid, + // @ts-expect-error: hush. + unknown, + // @ts-expect-error: hush. + handlers: context.handlers + }); + + let result = context.handle(tree, null, context, {before: '\n', after: '\n'}); + + if ( + result && + result.charCodeAt(result.length - 1) !== 10 && + result.charCodeAt(result.length - 1) !== 13 + ) { + result += '\n'; + } + + return result + + /** @type {Context['enter']} */ + function enter(name) { + context.stack.push(name); + return exit + + function exit() { + context.stack.pop(); + } + } +} + +/** + * @type {Handle} + * @param {unknown} value + */ +function invalid(value) { + throw new Error('Cannot handle value `' + value + '`, expected node') +} + +/** + * @type {Handle} + * @param {Node} node + */ +function unknown(node) { + throw new Error('Cannot handle unknown node `' + node.type + '`') +} + +/** @type {Join} */ +function joinDefinition(left, right) { + // No blank line between adjacent definitions. + if (left.type === 'definition' && left.type === right.type) { + return 0 + } +} + +/** + * @typedef {import('mdast').Root|import('mdast').Content} Node + * @typedef {import('mdast-util-to-markdown').Options} Options + */ + +/** @type {import('unified').Plugin<[Options]|void[], Node, string>} */ +function remarkStringify(options) { + /** @type {import('unified').CompilerFunction} */ + const compiler = (tree) => { + // Assume options. + const settings = /** @type {Options} */ (this.data('settings')); + + return toMarkdown( + tree, + Object.assign({}, settings, options, { + // Note: this option is not in the readme. + // The goal is for it to be set by plugins on `data` instead of being + // passed by users. + extensions: this.data('toMarkdownExtensions') || [] + }) + ) + }; + + Object.assign(this, {Compiler: compiler}); +} + +/** + * @typedef {import('unist').Point} Point + * @typedef {import('vfile').VFile} VFile + * + * @typedef {Pick} PositionalPoint + * @typedef {Required} FullPoint + * @typedef {NonNullable} Offset + */ + +/** + * Get transform functions for the given `document`. + * + * @param {string|Uint8Array|VFile} file + */ +function location(file) { + var value = String(file); + /** @type {Array.} */ + var indices = []; + var search = /\r?\n|\r/g; + + while (search.test(value)) { + indices.push(search.lastIndex); + } + + indices.push(value.length + 1); + + return {toPoint, toOffset} + + /** + * Get the line and column-based `point` for `offset` in the bound indices. + * Returns a point with `undefined` values when given invalid or out of bounds + * input. + * + * @param {Offset} offset + * @returns {FullPoint} + */ + function toPoint(offset) { + var index = -1; + + if (offset > -1 && offset < indices[indices.length - 1]) { + while (++index < indices.length) { + if (indices[index] > offset) { + return { + line: index + 1, + column: offset - (indices[index - 1] || 0) + 1, + offset + } + } + } + } + + return {line: undefined, column: undefined, offset: undefined} + } + + /** + * Get the `offset` for a line and column-based `point` in the bound indices. + * Returns `-1` when given invalid or out of bounds input. + * + * @param {PositionalPoint} point + * @returns {Offset} + */ + function toOffset(point) { + var line = point && point.line; + var column = point && point.column; + /** @type {number} */ + var offset; + + if ( + typeof line === 'number' && + typeof column === 'number' && + !Number.isNaN(line) && + !Number.isNaN(column) && + line - 1 in indices + ) { + offset = (indices[line - 2] || 0) + column - 1 || 0; + } + + return offset > -1 && offset < indices[indices.length - 1] ? offset : -1 + } +} + +/** + * @param {string} d + * @returns {string} + */ +function color(d) { + return '\u001B[33m' + d + '\u001B[39m' +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + */ + +/** + * Continue traversing as normal + */ +const CONTINUE = true; +/** + * Do not traverse this node’s children + */ +const SKIP = 'skip'; +/** + * Stop traversing immediately + */ +const EXIT = false; + +const visitParents = + /** + * @type {( + * ((tree: Node, test: T['type']|Partial|import('unist-util-is').TestFunctionPredicate|Array.|import('unist-util-is').TestFunctionPredicate>, visitor: Visitor, reverse?: boolean) => void) & + * ((tree: Node, test: Test, visitor: Visitor, reverse?: boolean) => void) & + * ((tree: Node, visitor: Visitor, reverse?: boolean) => void) + * )} + */ + ( + /** + * Visit children of tree which pass a test + * + * @param {Node} tree Abstract syntax tree to walk + * @param {Test} test test Test node + * @param {Visitor} visitor Function to run for each node + * @param {boolean} [reverse] Fisit the tree in reverse, defaults to false + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + // @ts-ignore no visitor given, so `visitor` is test. + visitor = test; + test = null; + } + + var is = convert(test); + var step = reverse ? -1 : 1; + + factory(tree, null, [])(); + + /** + * @param {Node} node + * @param {number?} index + * @param {Array.} parents + */ + function factory(node, index, parents) { + /** @type {Object.} */ + var value = typeof node === 'object' && node !== null ? node : {}; + /** @type {string} */ + var name; + + if (typeof value.type === 'string') { + name = + typeof value.tagName === 'string' + ? value.tagName + : typeof value.name === 'string' + ? value.name + : undefined; + + Object.defineProperty(visit, 'name', { + value: + 'node (' + + color(value.type + (name ? '<' + name + '>' : '')) + + ')' + }); + } + + return visit + + function visit() { + /** @type {ActionTuple} */ + var result = []; + /** @type {ActionTuple} */ + var subresult; + /** @type {number} */ + var offset; + /** @type {Array.} */ + var grandparents; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult(visitor(node, parents)); + + if (result[0] === EXIT) { + return result + } + } + + if (node.children && result[0] !== SKIP) { + // @ts-ignore looks like a parent. + offset = (reverse ? node.children.length : -1) + step; + // @ts-ignore looks like a parent. + grandparents = parents.concat(node); + + // @ts-ignore looks like a parent. + while (offset > -1 && offset < node.children.length) { + subresult = factory(node.children[offset], offset, grandparents)(); + + if (subresult[0] === EXIT) { + return subresult + } + + offset = + typeof subresult[1] === 'number' ? subresult[1] : offset + step; + } + } + + return result + } + } + } + ); + +/** + * @param {VisitorResult} value + * @returns {ActionTuple} + */ +function toResult(value) { + if (Array.isArray(value)) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE, value] + } + + return [value] +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult + */ + +const visit = + /** + * @type {( + * ((tree: Node, test: T['type']|Partial|import('unist-util-is').TestFunctionPredicate|Array.|import('unist-util-is').TestFunctionPredicate>, visitor: Visitor, reverse?: boolean) => void) & + * ((tree: Node, test: Test, visitor: Visitor, reverse?: boolean) => void) & + * ((tree: Node, visitor: Visitor, reverse?: boolean) => void) + * )} + */ + ( + /** + * Visit children of tree which pass a test + * + * @param {Node} tree Abstract syntax tree to walk + * @param {Test} test test Test node + * @param {Visitor} visitor Function to run for each node + * @param {boolean} [reverse] Fisit the tree in reverse, defaults to false + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + visitParents(tree, test, overload, reverse); + + /** + * @param {Node} node + * @param {Array.} parents + */ + function overload(node, parents) { + var parent = parents[parents.length - 1]; + return visitor( + node, + parent ? parent.children.indexOf(node) : null, + parent + ) + } + } + ); + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist').Point} Point + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('vfile').VFile} VFile + * @typedef {import('vfile-message').VFileMessage} VFileMessage + * + * @typedef {OptionsWithoutReset|OptionsWithReset} Options + * @typedef {OptionsBaseFields & OptionsWithoutResetFields} OptionsWithoutReset + * @typedef {OptionsBaseFields & OptionsWithResetFields} OptionsWithReset + * + * @typedef OptionsWithoutResetFields + * @property {false} [reset] + * Whether to treat all messages as turned off initially. + * @property {string[]} [disable] + * List of `ruleId`s to turn off. + * + * @typedef OptionsWithResetFields + * @property {true} reset + * Whether to treat all messages as turned off initially. + * @property {string[]} [enable] + * List of `ruleId`s to initially turn on. + * + * @typedef OptionsBaseFields + * @property {string} name + * Name of markers that can control the message sources. + * + * For example, `{name: 'alpha'}` controls `alpha` markers: + * + * ```html + * + * ``` + * @property {MarkerParser} marker + * Parse a possible marker to a comment marker object (Marker). + * If the marker isn't a marker, should return `null`. + * @property {Test} [test] + * Test for possible markers + * @property {string[]} [known] + * List of allowed `ruleId`s. When given a warning is shown + * when someone tries to control an unknown rule. + * + * For example, `{name: 'alpha', known: ['bravo']}` results in a warning if + * `charlie` is configured: + * + * ```html + * + * ``` + * @property {string|string[]} [source] + * Sources that can be controlled with `name` markers. + * Defaults to `name`. + * + * @callback MarkerParser + * Parse a possible comment marker node to a Marker. + * @param {Node} node + * Node to parse + * + * @typedef Marker + * A comment marker. + * @property {string} name + * Name of marker. + * @property {string} attributes + * Value after name. + * @property {Record} parameters + * Parsed attributes. + * @property {Node} node + * Reference to given node. + * + * @typedef Mark + * @property {Point|undefined} point + * @property {boolean} state + */ + +const own$3 = {}.hasOwnProperty; + +/** + * @type {import('unified').Plugin<[Options]>} + * @returns {(tree: Node, file: VFile) => void} + */ +function messageControl(options) { + if (!options || typeof options !== 'object' || !options.name) { + throw new Error( + 'Expected `name` in `options`, got `' + (options || {}).name + '`' + ) + } + + if (!options.marker) { + throw new Error( + 'Expected `marker` in `options`, got `' + options.marker + '`' + ) + } + + const enable = 'enable' in options && options.enable ? options.enable : []; + const disable = 'disable' in options && options.disable ? options.disable : []; + let reset = options.reset; + const sources = + typeof options.source === 'string' + ? [options.source] + : options.source || [options.name]; + + return transformer + + /** + * @param {Node} tree + * @param {VFile} file + */ + function transformer(tree, file) { + const toOffset = location(file).toOffset; + const initial = !reset; + const gaps = detectGaps(tree, file); + /** @type {Record} */ + const scope = {}; + /** @type {Mark[]} */ + const globals = []; + + visit(tree, options.test, visitor); + + file.messages = file.messages.filter((m) => filter(m)); + + /** + * @param {Node} node + * @param {number|null} position + * @param {Parent|null} parent + */ + function visitor(node, position, parent) { + /** @type {Marker|null} */ + const mark = options.marker(node); + + if (!mark || mark.name !== options.name) { + return + } + + const ruleIds = mark.attributes.split(/\s/g); + const point = mark.node.position && mark.node.position.start; + const next = + (parent && position !== null && parent.children[position + 1]) || + undefined; + const tail = (next && next.position && next.position.end) || undefined; + let index = -1; + + /** @type {string} */ + // @ts-expect-error: we’ll check for unknown values next. + const verb = ruleIds.shift(); + + if (verb !== 'enable' && verb !== 'disable' && verb !== 'ignore') { + file.fail( + 'Unknown keyword `' + + verb + + '`: expected ' + + "`'enable'`, `'disable'`, or `'ignore'`", + mark.node + ); + } + + // Apply to all rules. + if (ruleIds.length > 0) { + while (++index < ruleIds.length) { + const ruleId = ruleIds[index]; + + if (isKnown(ruleId, verb, mark.node)) { + toggle(point, verb === 'enable', ruleId); + + if (verb === 'ignore') { + toggle(tail, true, ruleId); + } + } + } + } else if (verb === 'ignore') { + toggle(point, false); + toggle(tail, true); + } else { + toggle(point, verb === 'enable'); + reset = verb !== 'enable'; + } + } + + /** + * @param {VFileMessage} message + * @returns {boolean} + */ + function filter(message) { + let gapIndex = gaps.length; + + // Keep messages from a different source. + if (!message.source || !sources.includes(message.source)) { + return true + } + + // We only ignore messages if they‘re disabled, *not* when they’re not in + // the document. + if (!message.line) { + message.line = 1; + } + + if (!message.column) { + message.column = 1; + } + + // Check whether the warning is inside a gap. + // @ts-expect-error: we just normalized `null` to `number`s. + const offset = toOffset(message); + + while (gapIndex--) { + if (gaps[gapIndex][0] <= offset && gaps[gapIndex][1] > offset) { + return false + } + } + + // Check whether allowed by specific and global states. + return ( + (!message.ruleId || + check(message, scope[message.ruleId], message.ruleId)) && + check(message, globals) + ) + } + + /** + * Helper to check (and possibly warn) if a `ruleId` is unknown. + * + * @param {string} ruleId + * @param {string} verb + * @param {Node} node + * @returns {boolean} + */ + function isKnown(ruleId, verb, node) { + const result = options.known ? options.known.includes(ruleId) : true; + + if (!result) { + file.message( + 'Unknown rule: cannot ' + verb + " `'" + ruleId + "'`", + node + ); + } + + return result + } + + /** + * Get the latest state of a rule. + * When without `ruleId`, gets global state. + * + * @param {string|undefined} ruleId + * @returns {boolean} + */ + function getState(ruleId) { + const ranges = ruleId ? scope[ruleId] : globals; + + if (ranges && ranges.length > 0) { + return ranges[ranges.length - 1].state + } + + if (!ruleId) { + return !reset + } + + return reset ? enable.includes(ruleId) : !disable.includes(ruleId) + } + + /** + * Handle a rule. + * + * @param {Point|undefined} point + * @param {boolean} state + * @param {string|undefined} [ruleId] + * @returns {void} + */ + function toggle(point, state, ruleId) { + let markers = ruleId ? scope[ruleId] : globals; + + if (!markers) { + markers = []; + scope[String(ruleId)] = markers; + } + + const previousState = getState(ruleId); + + if (state !== previousState) { + markers.push({state, point}); + } + + // Toggle all known rules. + if (!ruleId) { + for (ruleId in scope) { + if (own$3.call(scope, ruleId)) { + toggle(point, state, ruleId); + } + } + } + } + + /** + * Check all `ranges` for `message`. + * + * @param {VFileMessage} message + * @param {Mark[]|undefined} ranges + * @param {string|undefined} [ruleId] + * @returns {boolean} + */ + function check(message, ranges, ruleId) { + if (ranges && ranges.length > 0) { + // Check the state at the message’s position. + let index = ranges.length; + + while (index--) { + const range = ranges[index]; + + if ( + message.line && + message.column && + range.point && + range.point.line && + range.point.column && + (range.point.line < message.line || + (range.point.line === message.line && + range.point.column <= message.column)) + ) { + return range.state === true + } + } + } + + // The first marker ocurred after the first message, so we check the + // initial state. + if (!ruleId) { + return Boolean(initial || reset) + } + + return reset ? enable.includes(ruleId) : !disable.includes(ruleId) + } + } +} + +/** + * Detect gaps in `tree`. + * + * @param {Node} tree + * @param {VFile} file + */ +function detectGaps(tree, file) { + /** @type {Node[]} */ + // @ts-expect-error: fine. + const children = tree.children || []; + const lastNode = children[children.length - 1]; + /** @type {[number, number][]} */ + const gaps = []; + let offset = 0; + /** @type {boolean|undefined} */ + let gap; + + // Find all gaps. + visit(tree, one); + + // Get the end of the document. + // This detects if the last node was the last node. + // If not, there’s an extra gap between the last node and the end of the + // document. + if ( + lastNode && + lastNode.position && + lastNode.position.end && + offset === lastNode.position.end.offset && + file.toString().slice(offset).trim() !== '' + ) { + update(); + + update( + tree && + tree.position && + tree.position.end && + tree.position.end.offset && + tree.position.end.offset - 1 + ); + } + + return gaps + + /** + * @param {Node} node + */ + function one(node) { + update(node.position && node.position.start && node.position.start.offset); + + if (!('children' in node)) { + update(node.position && node.position.end && node.position.end.offset); + } + } + + /** + * Detect a new position. + * + * @param {number|undefined} [latest] + * @returns {void} + */ + function update(latest) { + if (latest === null || latest === undefined) { + gap = true; + } else if (offset < latest) { + if (gap) { + gaps.push([offset, latest]); + gap = undefined; + } + + offset = latest; + } + } +} + +/** + * @typedef {string|number|boolean} MarkerParameterValue + * @typedef {Object.} MarkerParameters + * + * @typedef HtmlNode + * @property {'html'} type + * @property {string} value + * + * @typedef CommentNode + * @property {'comment'} type + * @property {string} value + * + * @typedef Marker + * @property {string} name + * @property {string} attributes + * @property {MarkerParameters|null} parameters + * @property {HtmlNode|CommentNode} node + */ + +var commentExpression = /\s*([a-zA-Z\d-]+)(\s+([\s\S]*))?\s*/; + +var markerExpression = new RegExp( + '(\\s*\\s*)' +); + +/** + * Parse a comment marker. + * @param {unknown} node + * @returns {Marker|null} + */ +function commentMarker(node) { + /** @type {RegExpMatchArray} */ + var match; + /** @type {number} */ + var offset; + /** @type {MarkerParameters} */ + var parameters; + + if ( + node && + typeof node === 'object' && + // @ts-ignore hush + (node.type === 'html' || node.type === 'comment') + ) { + // @ts-ignore hush + match = node.value.match( + // @ts-ignore hush + node.type === 'comment' ? commentExpression : markerExpression + ); + + // @ts-ignore hush + if (match && match[0].length === node.value.length) { + // @ts-ignore hush + offset = node.type === 'comment' ? 1 : 2; + parameters = parseParameters(match[offset + 1] || ''); + + if (parameters) { + return { + name: match[offset], + attributes: match[offset + 2] || '', + parameters, + // @ts-ignore hush + node + } + } + } + } + + return null +} + +/** + * Parse `value` into an object. + * + * @param {string} value + * @returns {MarkerParameters|null} + */ +function parseParameters(value) { + /** @type {MarkerParameters} */ + var parameters = {}; + + return value + .replace( + /\s+([-\w]+)(?:=(?:"((?:\\[\s\S]|[^"])+)"|'((?:\\[\s\S]|[^'])+)'|((?:\\[\s\S]|[^"'\s])+)))?/gi, + replacer + ) + .replace(/\s+/g, '') + ? null + : parameters + + /** + * @param {string} _ + * @param {string} $1 + * @param {string} $2 + * @param {string} $3 + * @param {string} $4 + */ + // eslint-disable-next-line max-params + function replacer(_, $1, $2, $3, $4) { + /** @type {MarkerParameterValue} */ + var value = $2 || $3 || $4 || ''; + + if (value === 'true' || value === '') { + value = true; + } else if (value === 'false') { + value = false; + } else if (!Number.isNaN(Number(value))) { + value = Number(value); + } + + parameters[$1] = value; + + return '' + } +} + +/** + * @typedef {import('mdast').Root} Root + * @typedef {import('vfile').VFile} VFile + * @typedef {import('unified-message-control')} MessageControl + * @typedef {Omit|Omit} Options + */ + +const test = [ + 'html', // Comments are `html` nodes in mdast. + 'comment' // In MDX, comments have their own node. +]; + +/** + * Plugin to enable, disable, and ignore messages. + * + * @type {import('unified').Plugin<[Options], Root>} + * @returns {(node: Root, file: VFile) => void} + */ +function remarkMessageControl(options) { + return messageControl( + Object.assign({marker: commentMarker, test}, options) + ) +} + +/** + * @typedef {import('mdast').Root} Root + */ + +/** + * The core plugin for `remark-lint`. + * This adds support for ignoring stuff from messages (``). + * All rules are in their own packages and presets. + * + * @type {import('unified').Plugin} + */ +function remarkLint() { + this.use(lintMessageControl); +} + +/** @type {import('unified').Plugin} */ +function lintMessageControl() { + return remarkMessageControl({name: 'lint', source: 'remark-lint'}) +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('vfile').VFile} VFile + * + * @typedef {0|1|2} Severity + * @typedef {'warn'|'on'|'off'|'error'} Label + * @typedef {[Severity, ...unknown[]]} SeverityTuple + * + * @typedef RuleMeta + * @property {string} origin name of the lint rule + * @property {string} [url] link to documentation + * + * @callback Rule + * @param {Node} tree + * @param {VFile} file + * @param {unknown} options + * @returns {void} + */ + +const primitives = new Set(['string', 'number', 'boolean']); + +/** + * @param {string|RuleMeta} meta + * @param {Rule} rule + */ +function lintRule(meta, rule) { + const id = typeof meta === 'string' ? meta : meta.origin; + const url = typeof meta === 'string' ? undefined : meta.url; + const parts = id.split(':'); + // Possibly useful if externalised later. + /* c8 ignore next */ + const source = parts[1] ? parts[0] : undefined; + const ruleId = parts[1]; + + Object.defineProperty(plugin, 'name', {value: id}); + + return plugin + + /** @type {import('unified').Plugin<[unknown]|void[]>} */ + function plugin(raw) { + const [severity, options] = coerce$1(ruleId, raw); + + if (!severity) return + + const fatal = severity === 2; + + return (tree, file, next) => { + let index = file.messages.length - 1; + + wrap(rule, (error) => { + const messages = file.messages; + + // Add the error, if not already properly added. + // Only happens for incorrect plugins. + /* c8 ignore next 6 */ + // @ts-expect-error: errors could be `messages`. + if (error && !messages.includes(error)) { + try { + file.fail(error); + } catch {} + } + + while (++index < messages.length) { + Object.assign(messages[index], {ruleId, source, fatal, url}); + } + + next(); + })(tree, file, options); + } + } +} + +/** + * Coerce a value to a severity--options tuple. + * + * @param {string} name + * @param {unknown} value + * @returns {SeverityTuple} + */ +function coerce$1(name, value) { + /** @type {unknown[]} */ + let result; + + if (typeof value === 'boolean') { + result = [value]; + } else if (value === null || value === undefined) { + result = [1]; + } else if ( + Array.isArray(value) && + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + primitives.has(typeof value[0]) + ) { + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + result = [...value]; + } else { + result = [1, value]; + } + + let level = result[0]; + + if (typeof level === 'boolean') { + level = level ? 1 : 0; + } else if (typeof level === 'string') { + if (level === 'off') { + level = 0; + } else if (level === 'on' || level === 'warn') { + level = 1; + } else if (level === 'error') { + level = 2; + } else { + level = 1; + result = [level, result]; + } + } + + if (typeof level !== 'number' || level < 0 || level > 2) { + throw new Error( + 'Incorrect severity `' + + level + + '` for `' + + name + + '`, ' + + 'expected 0, 1, or 2' + ) + } + + result[0] = level; + + // @ts-expect-error: it’s now a valid tuple. + return result +} + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module final-newline + * @fileoverview + * Warn when a line feed at the end of a file is missing. + * Empty files are allowed. + * + * See [StackExchange](https://unix.stackexchange.com/questions/18743) for why. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * always adds a final line feed to files. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * ## Example + * + * ##### `ok.md` + * + * ###### In + * + * Note: `␊` represents LF. + * + * ```markdown + * Alpha␊ + * ``` + * + * ###### Out + * + * No messages. + * + * ##### `not-ok.md` + * + * ###### In + * + * Note: The below file does not have a final newline. + * + * ```markdown + * Bravo + * ``` + * + * ###### Out + * + * ```text + * 1:1: Missing newline character at end of file + * ``` + */ + +const remarkLintFinalNewline = lintRule( + { + origin: 'remark-lint:final-newline', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-final-newline#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (_, file) => { + const value = String(file); + const last = value.length - 1; + + if (last > -1 && value.charAt(last) !== '\n') { + file.message('Missing newline character at end of file'); + } + } +); + +var remarkLintFinalNewline$1 = remarkLintFinalNewline; + +var pluralize = {exports: {}}; + +/* global define */ + +(function (module, exports) { +(function (root, pluralize) { + /* istanbul ignore else */ + if (typeof commonjsRequire === 'function' && 'object' === 'object' && 'object' === 'object') { + // Node. + module.exports = pluralize(); + } else { + // Browser global. + root.pluralize = pluralize(); + } +})(commonjsGlobal, function () { + // Rule storage - pluralize and singularize need to be run sequentially, + // while other rules can be optimized using an object for instant lookups. + var pluralRules = []; + var singularRules = []; + var uncountables = {}; + var irregularPlurals = {}; + var irregularSingles = {}; + + /** + * Sanitize a pluralization rule to a usable regular expression. + * + * @param {(RegExp|string)} rule + * @return {RegExp} + */ + function sanitizeRule (rule) { + if (typeof rule === 'string') { + return new RegExp('^' + rule + '$', 'i'); + } + + return rule; + } + + /** + * Pass in a word token to produce a function that can replicate the case on + * another word. + * + * @param {string} word + * @param {string} token + * @return {Function} + */ + function restoreCase (word, token) { + // Tokens are an exact match. + if (word === token) return token; + + // Lower cased words. E.g. "hello". + if (word === word.toLowerCase()) return token.toLowerCase(); + + // Upper cased words. E.g. "WHISKY". + if (word === word.toUpperCase()) return token.toUpperCase(); + + // Title cased words. E.g. "Title". + if (word[0] === word[0].toUpperCase()) { + return token.charAt(0).toUpperCase() + token.substr(1).toLowerCase(); + } + + // Lower cased words. E.g. "test". + return token.toLowerCase(); + } + + /** + * Interpolate a regexp string. + * + * @param {string} str + * @param {Array} args + * @return {string} + */ + function interpolate (str, args) { + return str.replace(/\$(\d{1,2})/g, function (match, index) { + return args[index] || ''; + }); + } + + /** + * Replace a word using a rule. + * + * @param {string} word + * @param {Array} rule + * @return {string} + */ + function replace (word, rule) { + return word.replace(rule[0], function (match, index) { + var result = interpolate(rule[1], arguments); + + if (match === '') { + return restoreCase(word[index - 1], result); + } + + return restoreCase(match, result); + }); + } + + /** + * Sanitize a word by passing in the word and sanitization rules. + * + * @param {string} token + * @param {string} word + * @param {Array} rules + * @return {string} + */ + function sanitizeWord (token, word, rules) { + // Empty string or doesn't need fixing. + if (!token.length || uncountables.hasOwnProperty(token)) { + return word; + } + + var len = rules.length; + + // Iterate over the sanitization rules and use the first one to match. + while (len--) { + var rule = rules[len]; + + if (rule[0].test(word)) return replace(word, rule); + } + + return word; + } + + /** + * Replace a word with the updated word. + * + * @param {Object} replaceMap + * @param {Object} keepMap + * @param {Array} rules + * @return {Function} + */ + function replaceWord (replaceMap, keepMap, rules) { + return function (word) { + // Get the correct token and case restoration functions. + var token = word.toLowerCase(); + + // Check against the keep object map. + if (keepMap.hasOwnProperty(token)) { + return restoreCase(word, token); + } + + // Check against the replacement map for a direct word replacement. + if (replaceMap.hasOwnProperty(token)) { + return restoreCase(word, replaceMap[token]); + } + + // Run all the rules against the word. + return sanitizeWord(token, word, rules); + }; + } + + /** + * Check if a word is part of the map. + */ + function checkWord (replaceMap, keepMap, rules, bool) { + return function (word) { + var token = word.toLowerCase(); + + if (keepMap.hasOwnProperty(token)) return true; + if (replaceMap.hasOwnProperty(token)) return false; + + return sanitizeWord(token, token, rules) === token; + }; + } + + /** + * Pluralize or singularize a word based on the passed in count. + * + * @param {string} word The word to pluralize + * @param {number} count How many of the word exist + * @param {boolean} inclusive Whether to prefix with the number (e.g. 3 ducks) + * @return {string} + */ + function pluralize (word, count, inclusive) { + var pluralized = count === 1 + ? pluralize.singular(word) : pluralize.plural(word); + + return (inclusive ? count + ' ' : '') + pluralized; + } + + /** + * Pluralize a word. + * + * @type {Function} + */ + pluralize.plural = replaceWord( + irregularSingles, irregularPlurals, pluralRules + ); + + /** + * Check if a word is plural. + * + * @type {Function} + */ + pluralize.isPlural = checkWord( + irregularSingles, irregularPlurals, pluralRules + ); + + /** + * Singularize a word. + * + * @type {Function} + */ + pluralize.singular = replaceWord( + irregularPlurals, irregularSingles, singularRules + ); + + /** + * Check if a word is singular. + * + * @type {Function} + */ + pluralize.isSingular = checkWord( + irregularPlurals, irregularSingles, singularRules + ); + + /** + * Add a pluralization rule to the collection. + * + * @param {(string|RegExp)} rule + * @param {string} replacement + */ + pluralize.addPluralRule = function (rule, replacement) { + pluralRules.push([sanitizeRule(rule), replacement]); + }; + + /** + * Add a singularization rule to the collection. + * + * @param {(string|RegExp)} rule + * @param {string} replacement + */ + pluralize.addSingularRule = function (rule, replacement) { + singularRules.push([sanitizeRule(rule), replacement]); + }; + + /** + * Add an uncountable word rule. + * + * @param {(string|RegExp)} word + */ + pluralize.addUncountableRule = function (word) { + if (typeof word === 'string') { + uncountables[word.toLowerCase()] = true; + return; + } + + // Set singular and plural references for the word. + pluralize.addPluralRule(word, '$0'); + pluralize.addSingularRule(word, '$0'); + }; + + /** + * Add an irregular word definition. + * + * @param {string} single + * @param {string} plural + */ + pluralize.addIrregularRule = function (single, plural) { + plural = plural.toLowerCase(); + single = single.toLowerCase(); + + irregularSingles[single] = plural; + irregularPlurals[plural] = single; + }; + + /** + * Irregular rules. + */ + [ + // Pronouns. + ['I', 'we'], + ['me', 'us'], + ['he', 'they'], + ['she', 'they'], + ['them', 'them'], + ['myself', 'ourselves'], + ['yourself', 'yourselves'], + ['itself', 'themselves'], + ['herself', 'themselves'], + ['himself', 'themselves'], + ['themself', 'themselves'], + ['is', 'are'], + ['was', 'were'], + ['has', 'have'], + ['this', 'these'], + ['that', 'those'], + // Words ending in with a consonant and `o`. + ['echo', 'echoes'], + ['dingo', 'dingoes'], + ['volcano', 'volcanoes'], + ['tornado', 'tornadoes'], + ['torpedo', 'torpedoes'], + // Ends with `us`. + ['genus', 'genera'], + ['viscus', 'viscera'], + // Ends with `ma`. + ['stigma', 'stigmata'], + ['stoma', 'stomata'], + ['dogma', 'dogmata'], + ['lemma', 'lemmata'], + ['schema', 'schemata'], + ['anathema', 'anathemata'], + // Other irregular rules. + ['ox', 'oxen'], + ['axe', 'axes'], + ['die', 'dice'], + ['yes', 'yeses'], + ['foot', 'feet'], + ['eave', 'eaves'], + ['goose', 'geese'], + ['tooth', 'teeth'], + ['quiz', 'quizzes'], + ['human', 'humans'], + ['proof', 'proofs'], + ['carve', 'carves'], + ['valve', 'valves'], + ['looey', 'looies'], + ['thief', 'thieves'], + ['groove', 'grooves'], + ['pickaxe', 'pickaxes'], + ['passerby', 'passersby'] + ].forEach(function (rule) { + return pluralize.addIrregularRule(rule[0], rule[1]); + }); + + /** + * Pluralization rules. + */ + [ + [/s?$/i, 's'], + [/[^\u0000-\u007F]$/i, '$0'], + [/([^aeiou]ese)$/i, '$1'], + [/(ax|test)is$/i, '$1es'], + [/(alias|[^aou]us|t[lm]as|gas|ris)$/i, '$1es'], + [/(e[mn]u)s?$/i, '$1s'], + [/([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$/i, '$1'], + [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1i'], + [/(alumn|alg|vertebr)(?:a|ae)$/i, '$1ae'], + [/(seraph|cherub)(?:im)?$/i, '$1im'], + [/(her|at|gr)o$/i, '$1oes'], + [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i, '$1a'], + [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i, '$1a'], + [/sis$/i, 'ses'], + [/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i, '$1$2ves'], + [/([^aeiouy]|qu)y$/i, '$1ies'], + [/([^ch][ieo][ln])ey$/i, '$1ies'], + [/(x|ch|ss|sh|zz)$/i, '$1es'], + [/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i, '$1ices'], + [/\b((?:tit)?m|l)(?:ice|ouse)$/i, '$1ice'], + [/(pe)(?:rson|ople)$/i, '$1ople'], + [/(child)(?:ren)?$/i, '$1ren'], + [/eaux$/i, '$0'], + [/m[ae]n$/i, 'men'], + ['thou', 'you'] + ].forEach(function (rule) { + return pluralize.addPluralRule(rule[0], rule[1]); + }); + + /** + * Singularization rules. + */ + [ + [/s$/i, ''], + [/(ss)$/i, '$1'], + [/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i, '$1fe'], + [/(ar|(?:wo|[ae])l|[eo][ao])ves$/i, '$1f'], + [/ies$/i, 'y'], + [/\b([pl]|zomb|(?:neck|cross)?t|coll|faer|food|gen|goon|group|lass|talk|goal|cut)ies$/i, '$1ie'], + [/\b(mon|smil)ies$/i, '$1ey'], + [/\b((?:tit)?m|l)ice$/i, '$1ouse'], + [/(seraph|cherub)im$/i, '$1'], + [/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$/i, '$1'], + [/(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$/i, '$1sis'], + [/(movie|twelve|abuse|e[mn]u)s$/i, '$1'], + [/(test)(?:is|es)$/i, '$1is'], + [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1us'], + [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i, '$1um'], + [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i, '$1on'], + [/(alumn|alg|vertebr)ae$/i, '$1a'], + [/(cod|mur|sil|vert|ind)ices$/i, '$1ex'], + [/(matr|append)ices$/i, '$1ix'], + [/(pe)(rson|ople)$/i, '$1rson'], + [/(child)ren$/i, '$1'], + [/(eau)x?$/i, '$1'], + [/men$/i, 'man'] + ].forEach(function (rule) { + return pluralize.addSingularRule(rule[0], rule[1]); + }); + + /** + * Uncountable rules. + */ + [ + // Singular words with no plurals. + 'adulthood', + 'advice', + 'agenda', + 'aid', + 'aircraft', + 'alcohol', + 'ammo', + 'analytics', + 'anime', + 'athletics', + 'audio', + 'bison', + 'blood', + 'bream', + 'buffalo', + 'butter', + 'carp', + 'cash', + 'chassis', + 'chess', + 'clothing', + 'cod', + 'commerce', + 'cooperation', + 'corps', + 'debris', + 'diabetes', + 'digestion', + 'elk', + 'energy', + 'equipment', + 'excretion', + 'expertise', + 'firmware', + 'flounder', + 'fun', + 'gallows', + 'garbage', + 'graffiti', + 'hardware', + 'headquarters', + 'health', + 'herpes', + 'highjinks', + 'homework', + 'housework', + 'information', + 'jeans', + 'justice', + 'kudos', + 'labour', + 'literature', + 'machinery', + 'mackerel', + 'mail', + 'media', + 'mews', + 'moose', + 'music', + 'mud', + 'manga', + 'news', + 'only', + 'personnel', + 'pike', + 'plankton', + 'pliers', + 'police', + 'pollution', + 'premises', + 'rain', + 'research', + 'rice', + 'salmon', + 'scissors', + 'series', + 'sewage', + 'shambles', + 'shrimp', + 'software', + 'species', + 'staff', + 'swine', + 'tennis', + 'traffic', + 'transportation', + 'trout', + 'tuna', + 'wealth', + 'welfare', + 'whiting', + 'wildebeest', + 'wildlife', + 'you', + /pok[eé]mon$/i, + // Regexes. + /[^aeiou]ese$/i, // "chinese", "japanese" + /deer$/i, // "deer", "reindeer" + /fish$/i, // "fish", "blowfish", "angelfish" + /measles$/i, + /o[iu]s$/i, // "carnivorous" + /pox$/i, // "chickpox", "smallpox" + /sheep$/i + ].forEach(pluralize.addUncountableRule); + + return pluralize; +}); +}(pluralize)); + +var plural = pluralize.exports; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module list-item-bullet-indent + * @fileoverview + * Warn when list item bullets are indented. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * removes all indentation before bullets. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * Paragraph. + * + * * List item + * * List item + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * Paragraph. + * + * ·* List item + * ·* List item + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 3:2: Incorrect indentation before bullet: remove 1 space + * 4:2: Incorrect indentation before bullet: remove 1 space + */ + +const remarkLintListItemBulletIndent = lintRule( + { + origin: 'remark-lint:list-item-bullet-indent', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-list-item-bullet-indent#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + visit$1(tree, 'list', (list, _, grandparent) => { + let index = -1; + + while (++index < list.children.length) { + const item = list.children[index]; + + if ( + grandparent && + grandparent.type === 'root' && + grandparent.position && + typeof grandparent.position.start.column === 'number' && + item.position && + typeof item.position.start.column === 'number' + ) { + const indent = + item.position.start.column - grandparent.position.start.column; + + if (indent) { + file.message( + 'Incorrect indentation before bullet: remove ' + + indent + + ' ' + + plural('space', indent), + item.position.start + ); + } + } + } + }); + } +); + +var remarkLintListItemBulletIndent$1 = remarkLintListItemBulletIndent; + +/** + * @typedef {import('unist').Position} Position + * @typedef {import('unist').Point} Point + * + * @typedef {Partial} PointLike + * + * @typedef {Object} PositionLike + * @property {PointLike} [start] + * @property {PointLike} [end] + * + * @typedef {Object} NodeLike + * @property {PositionLike} [position] + */ + +var pointStart = point('start'); +var pointEnd = point('end'); + +/** + * Get the positional info of `node`. + * + * @param {'start'|'end'} type + */ +function point(type) { + return point + + /** + * Get the positional info of `node`. + * + * @param {NodeLike} [node] + * @returns {Point} + */ + function point(node) { + /** @type {Point} */ + // @ts-ignore looks like a point + var point = (node && node.position && node.position[type]) || {}; + + return { + line: point.line || null, + column: point.column || null, + offset: point.offset > -1 ? point.offset : null + } + } +} + +/** + * @typedef {Object} PointLike + * @property {number} [line] + * @property {number} [column] + * @property {number} [offset] + * + * @typedef {Object} PositionLike + * @property {PointLike} [start] + * @property {PointLike} [end] + * + * @typedef {Object} NodeLike + * @property {PositionLike} [position] + */ + +/** + * Check if `node` is *generated*. + * + * @param {NodeLike} [node] + * @returns {boolean} + */ +function generated(node) { + return ( + !node || + !node.position || + !node.position.start || + !node.position.start.line || + !node.position.start.column || + !node.position.end || + !node.position.end.line || + !node.position.end.column + ) +} + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module list-item-indent + * @fileoverview + * Warn when the spacing between a list item’s bullet and its content violates + * a given style. + * + * Options: `'tab-size'`, `'mixed'`, or `'space'`, default: `'tab-size'`. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * uses `'tab-size'` (named `'tab'` there) by default to ensure Markdown is + * seen the same way across vendors. + * This can be configured with the + * [`listItemIndent`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionslistitemindent) + * option. + * This rule’s `'space'` option is named `'1'` there. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * *···List + * ····item. + * + * Paragraph. + * + * 11.·List + * ····item. + * + * Paragraph. + * + * *···List + * ····item. + * + * *···List + * ····item. + * + * @example + * {"name": "ok.md", "setting": "mixed"} + * + * *·List item. + * + * Paragraph. + * + * 11.·List item + * + * Paragraph. + * + * *···List + * ····item. + * + * *···List + * ····item. + * + * @example + * {"name": "ok.md", "setting": "space"} + * + * *·List item. + * + * Paragraph. + * + * 11.·List item + * + * Paragraph. + * + * *·List + * ··item. + * + * *·List + * ··item. + * + * @example + * {"name": "not-ok.md", "setting": "space", "label": "input"} + * + * *···List + * ····item. + * + * @example + * {"name": "not-ok.md", "setting": "space", "label": "output"} + * + * 1:5: Incorrect list-item indent: remove 2 spaces + * + * @example + * {"name": "not-ok.md", "setting": "tab-size", "label": "input"} + * + * *·List + * ··item. + * + * @example + * {"name": "not-ok.md", "setting": "tab-size", "label": "output"} + * + * 1:3: Incorrect list-item indent: add 2 spaces + * + * @example + * {"name": "not-ok.md", "setting": "mixed", "label": "input"} + * + * *···List item. + * + * @example + * {"name": "not-ok.md", "setting": "mixed", "label": "output"} + * + * 1:5: Incorrect list-item indent: remove 2 spaces + * + * @example + * {"name": "not-ok.md", "setting": "💩", "label": "output", "positionless": true} + * + * 1:1: Incorrect list-item indent style `💩`: use either `'tab-size'`, `'space'`, or `'mixed'` + */ + +const remarkLintListItemIndent = lintRule( + { + origin: 'remark-lint:list-item-indent', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-list-item-indent#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'tab-size') => { + const value = String(file); + + if (option !== 'tab-size' && option !== 'space' && option !== 'mixed') { + file.fail( + 'Incorrect list-item indent style `' + + option + + "`: use either `'tab-size'`, `'space'`, or `'mixed'`" + ); + } + + visit$1(tree, 'list', (node) => { + if (generated(node)) return + + const spread = node.spread; + let index = -1; + + while (++index < node.children.length) { + const item = node.children[index]; + const head = item.children[0]; + const final = pointStart(head); + + const marker = value + .slice(pointStart(item).offset, final.offset) + .replace(/\[[x ]?]\s*$/i, ''); + + const bulletSize = marker.replace(/\s+$/, '').length; + + const style = + option === 'tab-size' || (option === 'mixed' && spread) + ? Math.ceil(bulletSize / 4) * 4 + : bulletSize + 1; + + if (marker.length !== style) { + const diff = style - marker.length; + const abs = Math.abs(diff); + + file.message( + 'Incorrect list-item indent: ' + + (diff > 0 ? 'add' : 'remove') + + ' ' + + abs + + ' ' + + plural('space', abs), + final + ); + } + } + }); + } +); + +var remarkLintListItemIndent$1 = remarkLintListItemIndent; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module no-auto-link-without-protocol + * @fileoverview + * Warn for autolinks without protocol. + * Autolinks are URLs enclosed in `<` (less than) and `>` (greater than) + * characters. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * adds a protocol where needed. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * + * + * + * Most Markdown vendors don’t recognize the following as a link: + * + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:1-1:14: All automatic links must start with a protocol + */ + +// Protocol expression. +// See: . +const protocol = /^[a-z][a-z+.-]+:\/?/i; + +const remarkLintNoAutoLinkWithoutProtocol = lintRule( + { + origin: 'remark-lint:no-auto-link-without-protocol', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-auto-link-without-protocol#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + visit$1(tree, 'link', (node) => { + if ( + !generated(node) && + pointStart(node).column === pointStart(node.children[0]).column - 1 && + pointEnd(node).column === + pointEnd(node.children[node.children.length - 1]).column + 1 && + !protocol.test(toString(node)) + ) { + file.message('All automatic links must start with a protocol', node); + } + }); + } +); + +var remarkLintNoAutoLinkWithoutProtocol$1 = remarkLintNoAutoLinkWithoutProtocol; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module no-blockquote-without-marker + * @fileoverview + * Warn when blank lines without `>` (greater than) markers are found in a + * block quote. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * adds markers to every line in a block quote. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * > Foo… + * > …bar… + * > …baz. + * + * @example + * {"name": "ok-tabs.md"} + * + * >»Foo… + * >»…bar… + * >»…baz. + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * > Foo… + * …bar… + * > …baz. + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 2:1: Missing marker in block quote + * + * @example + * {"name": "not-ok-tabs.md", "label": "input"} + * + * >»Foo… + * »…bar… + * …baz. + * + * @example + * {"name": "not-ok-tabs.md", "label": "output"} + * + * 2:1: Missing marker in block quote + * 3:1: Missing marker in block quote + */ + +const remarkLintNoBlockquoteWithoutMarker = lintRule( + { + origin: 'remark-lint:no-blockquote-without-marker', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-blockquote-without-marker#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + const value = String(file); + const loc = location(file); + + visit$1(tree, 'blockquote', (node) => { + let index = -1; + + while (++index < node.children.length) { + const child = node.children[index]; + + if (child.type === 'paragraph' && !generated(child)) { + const end = pointEnd(child).line; + const column = pointStart(child).column; + let line = pointStart(child).line; + + // Skip past the first line. + while (++line <= end) { + const offset = loc.toOffset({line, column}); + + if (/>[\t ]+$/.test(value.slice(offset - 5, offset))) { + continue + } + + // Roughly here. + file.message('Missing marker in block quote', { + line, + column: column - 2 + }); + } + } + } + }); + } +); + +var remarkLintNoBlockquoteWithoutMarker$1 = remarkLintNoBlockquoteWithoutMarker; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module no-literal-urls + * @fileoverview + * Warn for literal URLs in text. + * URLs are treated as links in some Markdown vendors, but not in others. + * To make sure they are always linked, wrap them in `<` (less than) and `>` + * (greater than). + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * never creates literal URLs and always uses `<` (less than) and `>` + * (greater than). + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * + * + * @example + * {"name": "not-ok.md", "label": "input", "gfm": true} + * + * http://foo.bar/baz + * + * @example + * {"name": "not-ok.md", "label": "output", "gfm": true} + * + * 1:1-1:19: Don’t use literal URLs without angle brackets + */ + +const remarkLintNoLiteralUrls = lintRule( + { + origin: 'remark-lint:no-literal-urls', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-literal-urls#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + visit$1(tree, 'link', (node) => { + const value = toString(node); + + if ( + !generated(node) && + pointStart(node).column === pointStart(node.children[0]).column && + pointEnd(node).column === + pointEnd(node.children[node.children.length - 1]).column && + (node.url === 'mailto:' + value || node.url === value) + ) { + file.message('Don’t use literal URLs without angle brackets', node); + } + }); + } +); + +var remarkLintNoLiteralUrls$1 = remarkLintNoLiteralUrls; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module ordered-list-marker-style + * @fileoverview + * Warn when the list item marker style of ordered lists violate a given style. + * + * Options: `'consistent'`, `'.'`, or `')'`, default: `'consistent'`. + * + * `'consistent'` detects the first used list style and warns when subsequent + * lists use different styles. + * + * @example + * {"name": "ok.md"} + * + * 1. Foo + * + * + * 1. Bar + * + * Unordered lists are not affected by this rule. + * + * * Foo + * + * @example + * {"name": "ok.md", "setting": "."} + * + * 1. Foo + * + * 2. Bar + * + * @example + * {"name": "ok.md", "setting": ")"} + * + * 1) Foo + * + * 2) Bar + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * 1. Foo + * + * 2) Bar + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 3:1-3:8: Marker style should be `.` + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} + * + * 1:1: Incorrect ordered list item marker style `💩`: use either `'.'` or `')'` + */ + +const remarkLintOrderedListMarkerStyle = lintRule( + { + origin: 'remark-lint:ordered-list-marker-style', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-ordered-list-marker-style#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + const value = String(file); + + if (option !== 'consistent' && option !== '.' && option !== ')') { + file.fail( + 'Incorrect ordered list item marker style `' + + option + + "`: use either `'.'` or `')'`" + ); + } + + visit$1(tree, 'list', (node) => { + let index = -1; + + if (!node.ordered) return + + while (++index < node.children.length) { + const child = node.children[index]; + + if (!generated(child)) { + const marker = /** @type {Marker} */ ( + value + .slice( + pointStart(child).offset, + pointStart(child.children[0]).offset + ) + .replace(/\s|\d/g, '') + .replace(/\[[x ]?]\s*$/i, '') + ); + + if (option === 'consistent') { + option = marker; + } else if (marker !== option) { + file.message('Marker style should be `' + option + '`', child); + } + } + } + }); + } +); + +var remarkLintOrderedListMarkerStyle$1 = remarkLintOrderedListMarkerStyle; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module hard-break-spaces + * @fileoverview + * Warn when too many spaces are used to create a hard break. + * + * @example + * {"name": "ok.md"} + * + * Lorem ipsum·· + * dolor sit amet + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * Lorem ipsum··· + * dolor sit amet. + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:12-2:1: Use two spaces for hard line breaks + */ + +const remarkLintHardBreakSpaces = lintRule( + { + origin: 'remark-lint:hard-break-spaces', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-hard-break-spaces#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + const value = String(file); + + visit$1(tree, 'break', (node) => { + if (!generated(node)) { + const slice = value + .slice(pointStart(node).offset, pointEnd(node).offset) + .split('\n', 1)[0] + .replace(/\r$/, ''); + + if (slice.length > 2) { + file.message('Use two spaces for hard line breaks', node); + } + } + }); + } +); + +var remarkLintHardBreakSpaces$1 = remarkLintHardBreakSpaces; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module no-duplicate-definitions + * @fileoverview + * Warn when duplicate definitions are found. + * + * @example + * {"name": "ok.md"} + * + * [foo]: bar + * [baz]: qux + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * [foo]: bar + * [foo]: qux + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 2:1-2:11: Do not use definitions with the same identifier (1:1) + */ + +const remarkLintNoDuplicateDefinitions = lintRule( + { + origin: 'remark-lint:no-duplicate-definitions', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-duplicate-definitions#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + /** @type {Record} */ + const map = Object.create(null); + + visit$1(tree, (node) => { + if ( + (node.type === 'definition' || node.type === 'footnoteDefinition') && + !generated(node) + ) { + const identifier = node.identifier; + const duplicate = map[identifier]; + + if (duplicate) { + file.message( + 'Do not use definitions with the same identifier (' + + duplicate + + ')', + node + ); + } + + map[identifier] = stringifyPosition(pointStart(node)); + } + }); + } +); + +var remarkLintNoDuplicateDefinitions$1 = remarkLintNoDuplicateDefinitions; + +/** + * @typedef {import('mdast').Heading} Heading + * @typedef {'atx'|'atx-closed'|'setext'} Style + */ + +/** + * @param {Heading} node + * @param {Style} [relative] + * @returns {Style|null} + */ +function headingStyle(node, relative) { + var last = node.children[node.children.length - 1]; + var depth = node.depth; + var pos = node && node.position && node.position.end; + var final = last && last.position && last.position.end; + + if (!pos) { + return null + } + + // This can only occur for `'atx'` and `'atx-closed'` headings. + // This might incorrectly match `'atx'` headings with lots of trailing white + // space as an `'atx-closed'` heading. + if (!last) { + if (pos.column - 1 <= depth * 2) { + return consolidate(depth, relative) + } + + return 'atx-closed' + } + + if (final.line + 1 === pos.line) { + return 'setext' + } + + if (final.column + depth < pos.column) { + return 'atx-closed' + } + + return consolidate(depth, relative) +} + +/** + * Get the probable style of an atx-heading, depending on preferred style. + * + * @param {number} depth + * @param {Style} relative + * @returns {Style|null} + */ +function consolidate(depth, relative) { + return depth < 3 + ? 'atx' + : relative === 'atx' || relative === 'setext' + ? relative + : null +} + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module no-heading-content-indent + * @fileoverview + * Warn when content of headings is indented. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * removes all unneeded padding around content in headings. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * #·Foo + * + * ## Bar·## + * + * ##·Baz + * + * Setext headings are not affected. + * + * Baz + * === + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * #··Foo + * + * ## Bar··## + * + * ##··Baz + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:4: Remove 1 space before this heading’s content + * 3:7: Remove 1 space after this heading’s content + * 5:7: Remove 1 space before this heading’s content + * + * @example + * {"name": "empty-heading.md"} + * + * #·· + */ + +const remarkLintNoHeadingContentIndent = lintRule( + { + origin: 'remark-lint:no-heading-content-indent', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-heading-content-indent#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + visit$1(tree, 'heading', (node) => { + if (generated(node)) { + return + } + + const type = headingStyle(node, 'atx'); + + if (type === 'atx' || type === 'atx-closed') { + const head = pointStart(node.children[0]).column; + + // Ignore empty headings. + if (!head) { + return + } + + const diff = head - pointStart(node).column - 1 - node.depth; + + if (diff) { + file.message( + 'Remove ' + + Math.abs(diff) + + ' ' + + plural('space', Math.abs(diff)) + + ' before this heading’s content', + pointStart(node.children[0]) + ); + } + } + + // Closed ATX headings always must have a space between their content and + // the final hashes, thus, there is no `add x spaces`. + if (type === 'atx-closed') { + const final = pointEnd(node.children[node.children.length - 1]); + const diff = pointEnd(node).column - final.column - 1 - node.depth; + + if (diff) { + file.message( + 'Remove ' + + diff + + ' ' + + plural('space', diff) + + ' after this heading’s content', + final + ); + } + } + }); + } +); + +var remarkLintNoHeadingContentIndent$1 = remarkLintNoHeadingContentIndent; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module no-inline-padding + * @fileoverview + * Warn when phrasing content is padded with spaces between their markers and + * content. + * + * Warns for emphasis, strong, delete, image, and link. + * + * @example + * {"name": "ok.md"} + * + * Alpha [bravo](http://echo.fox/trot) + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * Alpha [ bravo ](http://echo.fox/trot) + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:7-1:38: Don’t pad `link` with inner spaces + */ + +const remarkLintNoInlinePadding = lintRule( + { + origin: 'remark-lint:no-inline-padding', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-inline-padding#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + // Note: `emphasis`, `strong`, `delete` (GFM) can’t have padding anymore + // since CM. + visit$1(tree, (node) => { + if ( + (node.type === 'link' || node.type === 'linkReference') && + !generated(node) + ) { + const value = toString(node); + + if (value.charAt(0) === ' ' || value.charAt(value.length - 1) === ' ') { + file.message('Don’t pad `' + node.type + '` with inner spaces', node); + } + } + }); + } +); + +var remarkLintNoInlinePadding$1 = remarkLintNoInlinePadding; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module no-shortcut-reference-image + * @fileoverview + * Warn when shortcut reference images are used. + * + * Shortcut references render as images when a definition is found, and as + * plain text without definition. + * Sometimes, you don’t intend to create an image from the reference, but this + * rule still warns anyway. + * In that case, you can escape the reference like so: `!\[foo]`. + * + * @example + * {"name": "ok.md"} + * + * ![foo][] + * + * [foo]: http://foo.bar/baz.png + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * ![foo] + * + * [foo]: http://foo.bar/baz.png + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:1-1:7: Use the trailing [] on reference images + */ + +const remarkLintNoShortcutReferenceImage = lintRule( + { + origin: 'remark-lint:no-shortcut-reference-image', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-shortcut-reference-image#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + visit$1(tree, 'imageReference', (node) => { + if (!generated(node) && node.referenceType === 'shortcut') { + file.message('Use the trailing [] on reference images', node); + } + }); + } +); + +var remarkLintNoShortcutReferenceImage$1 = remarkLintNoShortcutReferenceImage; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module no-shortcut-reference-link + * @fileoverview + * Warn when shortcut reference links are used. + * + * Shortcut references render as links when a definition is found, and as + * plain text without definition. + * Sometimes, you don’t intend to create a link from the reference, but this + * rule still warns anyway. + * In that case, you can escape the reference like so: `\[foo]`. + * + * @example + * {"name": "ok.md"} + * + * [foo][] + * + * [foo]: http://foo.bar/baz + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * [foo] + * + * [foo]: http://foo.bar/baz + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:1-1:6: Use the trailing `[]` on reference links + */ + +const remarkLintNoShortcutReferenceLink = lintRule( + { + origin: 'remark-lint:no-shortcut-reference-link', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-shortcut-reference-link#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + visit$1(tree, 'linkReference', (node) => { + if (!generated(node) && node.referenceType === 'shortcut') { + file.message('Use the trailing `[]` on reference links', node); + } + }); + } +); + +var remarkLintNoShortcutReferenceLink$1 = remarkLintNoShortcutReferenceLink; + +/** + * @author Titus Wormer + * @copyright 2016 Titus Wormer + * @license MIT + * @module no-undefined-references + * @fileoverview + * Warn when references to undefined definitions are found. + * + * Options: `Object`, optional. + * + * The object can have an `allow` field, set to an array of strings that may + * appear between `[` and `]`, but that should not be treated as link + * identifiers. + * + * @example + * {"name": "ok.md"} + * + * [foo][] + * + * Just a [ bracket. + * + * Typically, you’d want to use escapes (with a backslash: \\) to escape what + * could turn into a \[reference otherwise]. + * + * Just two braces can’t link: []. + * + * [foo]: https://example.com + * + * @example + * {"name": "ok-allow.md", "setting": {"allow": ["...", "…"]}} + * + * > Eliding a portion of a quoted passage […] is acceptable. + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * [bar] + * + * [baz][] + * + * [text][qux] + * + * Spread [over + * lines][] + * + * > in [a + * > block quote][] + * + * [asd][a + * + * Can include [*emphasis*]. + * + * Multiple pairs: [a][b][c]. + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:1-1:6: Found reference to undefined definition + * 3:1-3:8: Found reference to undefined definition + * 5:1-5:12: Found reference to undefined definition + * 7:8-8:9: Found reference to undefined definition + * 10:6-11:17: Found reference to undefined definition + * 13:1-13:6: Found reference to undefined definition + * 15:13-15:25: Found reference to undefined definition + * 17:17-17:23: Found reference to undefined definition + * 17:23-17:26: Found reference to undefined definition + */ + +const remarkLintNoUndefinedReferences = lintRule( + { + origin: 'remark-lint:no-undefined-references', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-undefined-references#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = {}) => { + const contents = String(file); + const loc = location(file); + const lineEnding = /(\r?\n|\r)[\t ]*(>[\t ]*)*/g; + const allow = new Set( + (option.allow || []).map((d) => normalizeIdentifier(d)) + ); + /** @type {Record} */ + const map = Object.create(null); + + visit$1(tree, (node) => { + if ( + (node.type === 'definition' || node.type === 'footnoteDefinition') && + !generated(node) + ) { + map[normalizeIdentifier(node.identifier)] = true; + } + }); + + visit$1(tree, (node) => { + // CM specifiers that references only form when defined. + // Still, they could be added by plugins, so let’s keep it. + /* c8 ignore next 10 */ + if ( + (node.type === 'imageReference' || + node.type === 'linkReference' || + node.type === 'footnoteReference') && + !generated(node) && + !(normalizeIdentifier(node.identifier) in map) && + !allow.has(normalizeIdentifier(node.identifier)) + ) { + file.message('Found reference to undefined definition', node); + } + + if (node.type === 'paragraph' || node.type === 'heading') { + findInPhrasing(node); + } + }); + + /** + * @param {Heading|Paragraph} node + */ + function findInPhrasing(node) { + /** @type {Range[]} */ + let ranges = []; + + visit$1(node, (child) => { + // Ignore the node itself. + if (child === node) return + + // Can’t have links in links, so reset ranges. + if (child.type === 'link' || child.type === 'linkReference') { + ranges = []; + return SKIP$1 + } + + // Enter non-text. + if (child.type !== 'text') return + + const start = pointStart(child).offset; + const end = pointEnd(child).offset; + + // Bail if there’s no positional info. + if (typeof start !== 'number' || typeof end !== 'number') { + return EXIT$1 + } + + const source = contents.slice(start, end); + /** @type {Array.<[number, string]>} */ + const lines = [[start, '']]; + let last = 0; + + lineEnding.lastIndex = 0; + let match = lineEnding.exec(source); + + while (match) { + const index = match.index; + lines[lines.length - 1][1] = source.slice(last, index); + last = index + match[0].length; + lines.push([start + last, '']); + match = lineEnding.exec(source); + } + + lines[lines.length - 1][1] = source.slice(last); + let lineIndex = -1; + + while (++lineIndex < lines.length) { + const line = lines[lineIndex][1]; + let index = 0; + + while (index < line.length) { + const code = line.charCodeAt(index); + + // Skip past escaped brackets. + if (code === 92) { + const next = line.charCodeAt(index + 1); + index++; + + if (next === 91 || next === 93) { + index++; + } + } + // Opening bracket. + else if (code === 91) { + ranges.push([lines[lineIndex][0] + index]); + index++; + } + // Close bracket. + else if (code === 93) { + // No opening. + if (ranges.length === 0) { + index++; + } else if (line.charCodeAt(index + 1) === 91) { + index++; + + // Collapsed or full. + let range = ranges.pop(); + + // Range should always exist. + // eslint-disable-next-line max-depth + if (range) { + range.push(lines[lineIndex][0] + index); + + // This is the end of a reference already. + // eslint-disable-next-line max-depth + if (range.length === 4) { + handleRange(range); + range = []; + } + + range.push(lines[lineIndex][0] + index); + ranges.push(range); + index++; + } + } else { + index++; + + // Shortcut or typical end of a reference. + const range = ranges.pop(); + + // Range should always exist. + // eslint-disable-next-line max-depth + if (range) { + range.push(lines[lineIndex][0] + index); + handleRange(range); + } + } + } + // Anything else. + else { + index++; + } + } + } + }); + + let index = -1; + + while (++index < ranges.length) { + handleRange(ranges[index]); + } + + return SKIP$1 + + /** + * @param {Range} range + */ + function handleRange(range) { + if (range.length === 1) return + if (range.length === 3) range.length = 2; + + // No need to warn for just `[]`. + if (range.length === 2 && range[0] + 2 === range[1]) return + + const offset = range.length === 4 && range[2] + 2 !== range[3] ? 2 : 0; + const id = contents + .slice(range[0 + offset] + 1, range[1 + offset] - 1) + .replace(lineEnding, ' '); + const pos = { + start: loc.toPoint(range[0]), + end: loc.toPoint(range[range.length - 1]) + }; + + if ( + !generated({position: pos}) && + !(normalizeIdentifier(id) in map) && + !allow.has(normalizeIdentifier(id)) + ) { + file.message('Found reference to undefined definition', pos); + } + } + } + } +); + +var remarkLintNoUndefinedReferences$1 = remarkLintNoUndefinedReferences; + +/** + * @author Titus Wormer + * @copyright 2016 Titus Wormer + * @license MIT + * @module no-unused-definitions + * @fileoverview + * Warn when unused definitions are found. + * + * @example + * {"name": "ok.md"} + * + * [foo][] + * + * [foo]: https://example.com + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * [bar]: https://example.com + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:1-1:27: Found unused definition + */ + +const own$2 = {}.hasOwnProperty; + +const remarkLintNoUnusedDefinitions = lintRule( + { + origin: 'remark-lint:no-unused-definitions', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-unused-definitions#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + /** @type {Record} */ + const map = Object.create(null); + + visit$1(tree, (node) => { + if ( + (node.type === 'definition' || node.type === 'footnoteDefinition') && + !generated(node) + ) { + map[node.identifier.toUpperCase()] = {node, used: false}; + } + }); + + visit$1(tree, (node) => { + if ( + node.type === 'imageReference' || + node.type === 'linkReference' || + node.type === 'footnoteReference' + ) { + const info = map[node.identifier.toUpperCase()]; + + if (!generated(node) && info) { + info.used = true; + } + } + }); + + /** @type {string} */ + let identifier; + + for (identifier in map) { + if (own$2.call(map, identifier)) { + const entry = map[identifier]; + + if (!entry.used) { + file.message('Found unused definition', entry.node); + } + } + } + } +); + +var remarkLintNoUnusedDefinitions$1 = remarkLintNoUnusedDefinitions; + +/** + * @fileoverview + * remark preset to configure `remark-lint` with settings that prevent + * mistakes or stuff that fails across vendors. + */ + +/** @type {Preset} */ +const remarkPresetLintRecommended = { + plugins: [ + remarkLint, + // Unix compatibility. + remarkLintFinalNewline$1, + // Rendering across vendors differs greatly if using other styles. + remarkLintListItemBulletIndent$1, + [remarkLintListItemIndent$1, 'tab-size'], + // Differs or unsupported across vendors. + remarkLintNoAutoLinkWithoutProtocol$1, + remarkLintNoBlockquoteWithoutMarker$1, + remarkLintNoLiteralUrls$1, + [remarkLintOrderedListMarkerStyle$1, '.'], + // Mistakes. + remarkLintHardBreakSpaces$1, + remarkLintNoDuplicateDefinitions$1, + remarkLintNoHeadingContentIndent$1, + remarkLintNoInlinePadding$1, + remarkLintNoShortcutReferenceImage$1, + remarkLintNoShortcutReferenceLink$1, + remarkLintNoUndefinedReferences$1, + remarkLintNoUnusedDefinitions$1 + ] +}; + +var remarkPresetLintRecommended$1 = remarkPresetLintRecommended; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module blockquote-indentation + * @fileoverview + * Warn when block quotes are indented too much or too little. + * + * Options: `number` or `'consistent'`, default: `'consistent'`. + * + * `'consistent'` detects the first used indentation and will warn when + * other block quotes use a different indentation. + * + * @example + * {"name": "ok.md", "setting": 4} + * + * > Hello + * + * Paragraph. + * + * > World + * @example + * {"name": "ok.md", "setting": 2} + * + * > Hello + * + * Paragraph. + * + * > World + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * > Hello + * + * Paragraph. + * + * > World + * + * Paragraph. + * + * > World + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 5:5: Remove 1 space between block quote and content + * 9:3: Add 1 space between block quote and content + */ + +const remarkLintBlockquoteIndentation = lintRule( + { + origin: 'remark-lint:blockquote-indentation', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-blockquote-indentation#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + visit$1(tree, 'blockquote', (node) => { + if (generated(node) || node.children.length === 0) { + return + } + + if (option === 'consistent') { + option = check$1(node); + } else { + const diff = option - check$1(node); + + if (diff !== 0) { + const abs = Math.abs(diff); + + file.message( + (diff > 0 ? 'Add' : 'Remove') + + ' ' + + abs + + ' ' + + plural('space', abs) + + ' between block quote and content', + pointStart(node.children[0]) + ); + } + } + }); + } +); + +var remarkLintBlockquoteIndentation$1 = remarkLintBlockquoteIndentation; + +/** + * @param {Blockquote} node + * @returns {number} + */ +function check$1(node) { + return pointStart(node.children[0]).column - pointStart(node).column +} + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module checkbox-character-style + * @fileoverview + * Warn when list item checkboxes violate a given style. + * + * Options: `Object` or `'consistent'`, default: `'consistent'`. + * + * `'consistent'` detects the first used checked and unchecked checkbox + * styles and warns when subsequent checkboxes use different styles. + * + * Styles can also be passed in like so: + * + * ```js + * {checked: 'x', unchecked: ' '} + * ``` + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * formats checked checkboxes using `x` (lowercase X) and unchecked checkboxes + * as `·` (a single space). + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md", "setting": {"checked": "x"}, "gfm": true} + * + * - [x] List item + * - [x] List item + * + * @example + * {"name": "ok.md", "setting": {"checked": "X"}, "gfm": true} + * + * - [X] List item + * - [X] List item + * + * @example + * {"name": "ok.md", "setting": {"unchecked": " "}, "gfm": true} + * + * - [ ] List item + * - [ ] List item + * - [ ]·· + * - [ ] + * + * @example + * {"name": "ok.md", "setting": {"unchecked": "\t"}, "gfm": true} + * + * - [»] List item + * - [»] List item + * + * @example + * {"name": "not-ok.md", "label": "input", "gfm": true} + * + * - [x] List item + * - [X] List item + * - [ ] List item + * - [»] List item + * + * @example + * {"name": "not-ok.md", "label": "output", "gfm": true} + * + * 2:5: Checked checkboxes should use `x` as a marker + * 4:5: Unchecked checkboxes should use ` ` as a marker + * + * @example + * {"setting": {"unchecked": "💩"}, "name": "not-ok.md", "label": "output", "positionless": true, "gfm": true} + * + * 1:1: Incorrect unchecked checkbox marker `💩`: use either `'\t'`, or `' '` + * + * @example + * {"setting": {"checked": "💩"}, "name": "not-ok.md", "label": "output", "positionless": true, "gfm": true} + * + * 1:1: Incorrect checked checkbox marker `💩`: use either `'x'`, or `'X'` + */ + +const remarkLintCheckboxCharacterStyle = lintRule( + { + origin: 'remark-lint:checkbox-character-style', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-checkbox-character-style#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + const value = String(file); + /** @type {'x'|'X'|'consistent'} */ + let checked = 'consistent'; + /** @type {' '|'\x09'|'consistent'} */ + let unchecked = 'consistent'; + + if (typeof option === 'object') { + checked = option.checked || 'consistent'; + unchecked = option.unchecked || 'consistent'; + } + + if (unchecked !== 'consistent' && unchecked !== ' ' && unchecked !== '\t') { + file.fail( + 'Incorrect unchecked checkbox marker `' + + unchecked + + "`: use either `'\\t'`, or `' '`" + ); + } + + if (checked !== 'consistent' && checked !== 'x' && checked !== 'X') { + file.fail( + 'Incorrect checked checkbox marker `' + + checked + + "`: use either `'x'`, or `'X'`" + ); + } + + visit$1(tree, 'listItem', (node) => { + const head = node.children[0]; + const point = pointStart(head); + + // Exit early for items without checkbox. + // A list item cannot be checked and empty, according to GFM. + if ( + typeof node.checked !== 'boolean' || + !head || + typeof point.offset !== 'number' + ) { + return + } + + // Move back to before `] `. + point.offset -= 2; + point.column -= 2; + + // Assume we start with a checkbox, because well, `checked` is set. + const match = /\[([\t Xx])]/.exec( + value.slice(point.offset - 2, point.offset + 1) + ); + + // Failsafe to make sure we don‘t crash if there actually isn’t a checkbox. + /* c8 ignore next */ + if (!match) return + + const style = node.checked ? checked : unchecked; + + if (style === 'consistent') { + if (node.checked) { + // @ts-expect-error: valid marker. + checked = match[1]; + } else { + // @ts-expect-error: valid marker. + unchecked = match[1]; + } + } else if (match[1] !== style) { + file.message( + (node.checked ? 'Checked' : 'Unchecked') + + ' checkboxes should use `' + + style + + '` as a marker', + point + ); + } + }); + } +); + +var remarkLintCheckboxCharacterStyle$1 = remarkLintCheckboxCharacterStyle; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module checkbox-content-indent + * @fileoverview + * Warn when list item checkboxes are followed by too much whitespace. + * + * @example + * {"name": "ok.md", "gfm": true} + * + * - [ ] List item + * + [x] List Item + * * [X] List item + * - [ ] List item + * + * @example + * {"name": "not-ok.md", "label": "input", "gfm": true} + * + * - [ ] List item + * + [x] List item + * * [X] List item + * - [ ] List item + * + * @example + * {"name": "not-ok.md", "label": "output", "gfm": true} + * + * 2:7-2:8: Checkboxes should be followed by a single character + * 3:7-3:9: Checkboxes should be followed by a single character + * 4:7-4:10: Checkboxes should be followed by a single character + */ + +const remarkLintCheckboxContentIndent = lintRule( + { + origin: 'remark-lint:checkbox-content-indent', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-checkbox-content-indent#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + const value = String(file); + const loc = location(file); + + visit$1(tree, 'listItem', (node) => { + const head = node.children[0]; + const point = pointStart(head); + + // Exit early for items without checkbox. + // A list item cannot be checked and empty, according to GFM. + if ( + typeof node.checked !== 'boolean' || + !head || + typeof point.offset !== 'number' + ) { + return + } + + // Assume we start with a checkbox, because well, `checked` is set. + const match = /\[([\t xX])]/.exec( + value.slice(point.offset - 4, point.offset + 1) + ); + + // Failsafe to make sure we don‘t crash if there actually isn’t a checkbox. + /* c8 ignore next */ + if (!match) return + + // Move past checkbox. + const initial = point.offset; + let final = initial; + + while (/[\t ]/.test(value.charAt(final))) final++; + + if (final - initial > 0) { + file.message('Checkboxes should be followed by a single character', { + start: loc.toPoint(initial), + end: loc.toPoint(final) + }); + } + }); + } +); + +var remarkLintCheckboxContentIndent$1 = remarkLintCheckboxContentIndent; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module code-block-style + * @fileoverview + * Warn when code blocks do not adhere to a given style. + * + * Options: `'consistent'`, `'fenced'`, or `'indented'`, default: `'consistent'`. + * + * `'consistent'` detects the first used code block style and warns when + * subsequent code blocks uses different styles. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * formats code blocks using a fence if they have a language flag and + * indentation if not. + * Pass + * [`fences: true`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsfences) + * to always use fences for code blocks. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"setting": "indented", "name": "ok.md"} + * + * alpha() + * + * Paragraph. + * + * bravo() + * + * @example + * {"setting": "indented", "name": "not-ok.md", "label": "input"} + * + * ``` + * alpha() + * ``` + * + * Paragraph. + * + * ``` + * bravo() + * ``` + * + * @example + * {"setting": "indented", "name": "not-ok.md", "label": "output"} + * + * 1:1-3:4: Code blocks should be indented + * 7:1-9:4: Code blocks should be indented + * + * @example + * {"setting": "fenced", "name": "ok.md"} + * + * ``` + * alpha() + * ``` + * + * Paragraph. + * + * ``` + * bravo() + * ``` + * + * @example + * {"setting": "fenced", "name": "not-ok-fenced.md", "label": "input"} + * + * alpha() + * + * Paragraph. + * + * bravo() + * + * @example + * {"setting": "fenced", "name": "not-ok-fenced.md", "label": "output"} + * + * 1:1-1:12: Code blocks should be fenced + * 5:1-5:12: Code blocks should be fenced + * + * @example + * {"name": "not-ok-consistent.md", "label": "input"} + * + * alpha() + * + * Paragraph. + * + * ``` + * bravo() + * ``` + * + * @example + * {"name": "not-ok-consistent.md", "label": "output"} + * + * 5:1-7:4: Code blocks should be indented + * + * @example + * {"setting": "💩", "name": "not-ok-incorrect.md", "label": "output", "positionless": true} + * + * 1:1: Incorrect code block style `💩`: use either `'consistent'`, `'fenced'`, or `'indented'` + */ + +const remarkLintCodeBlockStyle = lintRule( + { + origin: 'remark-lint:code-block-style', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-code-block-style#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + const value = String(file); + + if ( + option !== 'consistent' && + option !== 'fenced' && + option !== 'indented' + ) { + file.fail( + 'Incorrect code block style `' + + option + + "`: use either `'consistent'`, `'fenced'`, or `'indented'`" + ); + } + + visit$1(tree, 'code', (node) => { + if (generated(node)) { + return + } + + const initial = pointStart(node).offset; + const final = pointEnd(node).offset; + + const current = + node.lang || /^\s*([~`])\1{2,}/.test(value.slice(initial, final)) + ? 'fenced' + : 'indented'; + + if (option === 'consistent') { + option = current; + } else if (option !== current) { + file.message('Code blocks should be ' + option, node); + } + }); + } +); + +var remarkLintCodeBlockStyle$1 = remarkLintCodeBlockStyle; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module definition-spacing + * @fileoverview + * Warn when consecutive whitespace is used in a definition. + * + * @example + * {"name": "ok.md"} + * + * [example domain]: http://example.com "Example Domain" + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * [example····domain]: http://example.com "Example Domain" + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:1-1:57: Do not use consecutive whitespace in definition labels + */ + +const label = /^\s*\[((?:\\[\s\S]|[^[\]])+)]/; + +const remarkLintDefinitionSpacing = lintRule( + { + origin: 'remark-lint:definition-spacing', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-definition-spacing#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + const value = String(file); + + visit$1(tree, (node) => { + if (node.type === 'definition' || node.type === 'footnoteDefinition') { + const start = pointStart(node).offset; + const end = pointEnd(node).offset; + + if (typeof start === 'number' && typeof end === 'number') { + const match = value.slice(start, end).match(label); + + if (match && /[ \t\n]{2,}/.test(match[1])) { + file.message( + 'Do not use consecutive whitespace in definition labels', + node + ); + } + } + } + }); + } +); + +var remarkLintDefinitionSpacing$1 = remarkLintDefinitionSpacing; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module fenced-code-flag + * @fileoverview + * Check fenced code block flags. + * + * Options: `Array.` or `Object`, optional. + * + * Providing an array is as passing `{flags: Array}`. + * + * The object can have an array of `'flags'` which are allowed: other flags + * will not be allowed. + * An `allowEmpty` field (`boolean`, default: `false`) can be set to allow + * code blocks without language flags. + * + * @example + * {"name": "ok.md"} + * + * ```alpha + * bravo() + * ``` + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * ``` + * alpha() + * ``` + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:1-3:4: Missing code language flag + * + * @example + * {"name": "ok.md", "setting": {"allowEmpty": true}} + * + * ``` + * alpha() + * ``` + * + * @example + * {"name": "not-ok.md", "setting": {"allowEmpty": false}, "label": "input"} + * + * ``` + * alpha() + * ``` + * + * @example + * {"name": "not-ok.md", "setting": {"allowEmpty": false}, "label": "output"} + * + * 1:1-3:4: Missing code language flag + * + * @example + * {"name": "ok.md", "setting": ["alpha"]} + * + * ```alpha + * bravo() + * ``` + * + * @example + * {"name": "ok.md", "setting": {"flags":["alpha"]}} + * + * ```alpha + * bravo() + * ``` + * + * @example + * {"name": "not-ok.md", "setting": ["charlie"], "label": "input"} + * + * ```alpha + * bravo() + * ``` + * + * @example + * {"name": "not-ok.md", "setting": ["charlie"], "label": "output"} + * + * 1:1-3:4: Incorrect code language flag + */ + +const fence = /^ {0,3}([~`])\1{2,}/; + +const remarkLintFencedCodeFlag = lintRule( + { + origin: 'remark-lint:fenced-code-flag', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-fenced-code-flag#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option) => { + const value = String(file); + let allowEmpty = false; + /** @type {string[]} */ + let allowed = []; + + if (typeof option === 'object') { + if (Array.isArray(option)) { + allowed = option; + } else { + allowEmpty = Boolean(option.allowEmpty); + + if (option.flags) { + allowed = option.flags; + } + } + } + + visit$1(tree, 'code', (node) => { + if (!generated(node)) { + if (node.lang) { + if (allowed.length > 0 && !allowed.includes(node.lang)) { + file.message('Incorrect code language flag', node); + } + } else { + const slice = value.slice( + pointStart(node).offset, + pointEnd(node).offset + ); + + if (!allowEmpty && fence.test(slice)) { + file.message('Missing code language flag', node); + } + } + } + }); + } +); + +var remarkLintFencedCodeFlag$1 = remarkLintFencedCodeFlag; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module fenced-code-marker + * @fileoverview + * Warn for violating fenced code markers. + * + * Options: `` '`' ``, `'~'`, or `'consistent'`, default: `'consistent'`. + * + * `'consistent'` detects the first used fenced code marker style and warns + * when subsequent fenced code blocks use different styles. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * formats fences using ``'`'`` (grave accent) by default. + * Pass + * [`fence: '~'`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsfence) + * to use `~` (tilde) instead. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * Indented code blocks are not affected by this rule: + * + * bravo() + * + * @example + * {"name": "ok.md", "setting": "`"} + * + * ```alpha + * bravo() + * ``` + * + * ``` + * charlie() + * ``` + * + * @example + * {"name": "ok.md", "setting": "~"} + * + * ~~~alpha + * bravo() + * ~~~ + * + * ~~~ + * charlie() + * ~~~ + * + * @example + * {"name": "not-ok-consistent-tick.md", "label": "input"} + * + * ```alpha + * bravo() + * ``` + * + * ~~~ + * charlie() + * ~~~ + * + * @example + * {"name": "not-ok-consistent-tick.md", "label": "output"} + * + * 5:1-7:4: Fenced code should use `` ` `` as a marker + * + * @example + * {"name": "not-ok-consistent-tilde.md", "label": "input"} + * + * ~~~alpha + * bravo() + * ~~~ + * + * ``` + * charlie() + * ``` + * + * @example + * {"name": "not-ok-consistent-tilde.md", "label": "output"} + * + * 5:1-7:4: Fenced code should use `~` as a marker + * + * @example + * {"name": "not-ok-incorrect.md", "setting": "💩", "label": "output", "positionless": true} + * + * 1:1: Incorrect fenced code marker `💩`: use either `'consistent'`, `` '`' ``, or `'~'` + */ + +const remarkLintFencedCodeMarker = lintRule( + { + origin: 'remark-lint:fenced-code-marker', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-fenced-code-marker#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + const contents = String(file); + + if (option !== 'consistent' && option !== '~' && option !== '`') { + file.fail( + 'Incorrect fenced code marker `' + + option + + "`: use either `'consistent'`, `` '`' ``, or `'~'`" + ); + } + + visit$1(tree, 'code', (node) => { + const start = pointStart(node).offset; + + if (typeof start === 'number') { + const marker = contents + .slice(start, start + 4) + .replace(/^\s+/, '') + .charAt(0); + + // Ignore unfenced code blocks. + if (marker === '~' || marker === '`') { + if (option === 'consistent') { + option = marker; + } else if (marker !== option) { + file.message( + 'Fenced code should use `' + + (option === '~' ? option : '` ` `') + + '` as a marker', + node + ); + } + } + } + }); + } +); + +var remarkLintFencedCodeMarker$1 = remarkLintFencedCodeMarker; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module file-extension + * @fileoverview + * Warn when the file extension differ from the preferred extension. + * + * Does not warn when given documents have no file extensions (such as + * `AUTHORS` or `LICENSE`). + * + * Options: `string`, default: `'md'` — Expected file extension. + * + * @example + * {"name": "readme.md"} + * + * @example + * {"name": "readme"} + * + * @example + * {"name": "readme.mkd", "label": "output", "positionless": true} + * + * 1:1: Incorrect extension: use `md` + * + * @example + * {"name": "readme.mkd", "setting": "mkd"} + */ + +const remarkLintFileExtension = lintRule( + { + origin: 'remark-lint:file-extension', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-file-extension#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (_, file, option = 'md') => { + const ext = file.extname; + + if (ext && ext.slice(1) !== option) { + file.message('Incorrect extension: use `' + option + '`'); + } + } +); + +var remarkLintFileExtension$1 = remarkLintFileExtension; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module final-definition + * @fileoverview + * Warn when definitions are placed somewhere other than at the end of + * the file. + * + * @example + * {"name": "ok.md"} + * + * Paragraph. + * + * [example]: http://example.com "Example Domain" + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * Paragraph. + * + * [example]: http://example.com "Example Domain" + * + * Another paragraph. + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 3:1-3:47: Move definitions to the end of the file (after the node at line `5`) + * + * @example + * {"name": "ok-comments.md"} + * + * Paragraph. + * + * [example-1]: http://example.com/one/ + * + * + * + * [example-2]: http://example.com/two/ + */ + +const remarkLintFinalDefinition = lintRule( + { + origin: 'remark-lint:final-definition', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-final-definition#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + let last = 0; + + visit$1( + tree, + (node) => { + // Ignore generated and HTML comment nodes. + if ( + node.type === 'root' || + generated(node) || + (node.type === 'html' && /^\s*".length)); + + validateMeta(node, file, meta); + } catch (e) { + file.message(e, node); + } + }); +} + +const remarkLintNodejsYamlComments = lintRule( + "remark-lint:nodejs-yaml-comments", + validateYAMLComments +); + +function escapeStringRegexp(string) { + if (typeof string !== 'string') { + throw new TypeError('Expected a string'); + } + + // Escape characters with special meaning either inside or outside character sets. + // Use a simple backslash escape when it’s always valid, and a `\xnn` escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar. + return string + .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') + .replace(/-/g, '\\x2d'); +} + +const remarkLintProhibitedStrings = lintRule('remark-lint:prohibited-strings', prohibitedStrings); + +function testProhibited (val, content) { + let regexpFlags = 'g'; + let no = val.no; + + if (!no) { + no = escapeStringRegexp(val.yes); + regexpFlags += 'i'; + } + + let regexpString = '(? { + const results = testProhibited(val, content); + if (results.length) { + results.forEach(({ result, index, yes }) => { + const message = val.yes ? `Use "${yes}" instead of "${result}"` : `Do not use "${result}"`; + file.message(message, { + start: myLocation.toPoint(initial + index), + end: myLocation.toPoint(initial + index + [...result].length) + }); + }); + } + }); + } +} + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module rule-style + * @fileoverview + * Warn when the thematic breaks (horizontal rules) violate a given or + * detected style. + * + * Options: `string`, either a corect thematic breaks such as `***`, or + * `'consistent'`, default: `'consistent'`. + * + * `'consistent'` detects the first used thematic break style and warns when + * subsequent rules use different styles. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * has three settings that define how rules are created: + * + * * [`rule`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrule) + * (default: `*`) — Marker to use + * * [`ruleRepetition`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrulerepetition) + * (default: `3`) — Number of markers to use + * * [`ruleSpaces`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrulespaces) + * (default: `true`) — Whether to pad markers with spaces + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md", "setting": "* * *"} + * + * * * * + * + * * * * + * + * @example + * {"name": "ok.md", "setting": "_______"} + * + * _______ + * + * _______ + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * *** + * + * * * * + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 3:1-3:6: Rules should use `***` + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} + * + * 1:1: Incorrect preferred rule style: provide a correct markdown rule or `'consistent'` + */ + +const remarkLintRuleStyle = lintRule( + { + origin: 'remark-lint:rule-style', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-rule-style#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + const value = String(file); + + if (option !== 'consistent' && /[^-_* ]/.test(option)) { + file.fail( + "Incorrect preferred rule style: provide a correct markdown rule or `'consistent'`" + ); + } + + visit$1(tree, 'thematicBreak', (node) => { + const initial = pointStart(node).offset; + const final = pointEnd(node).offset; + + if (typeof initial === 'number' && typeof final === 'number') { + const rule = value.slice(initial, final); + + if (option === 'consistent') { + option = rule; + } else if (rule !== option) { + file.message('Rules should use `' + option + '`', node); + } + } + }); + } +); + +var remarkLintRuleStyle$1 = remarkLintRuleStyle; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module strong-marker + * @fileoverview + * Warn for violating importance (strong) markers. + * + * Options: `'consistent'`, `'*'`, or `'_'`, default: `'consistent'`. + * + * `'consistent'` detects the first used importance style and warns when + * subsequent importance sequences use different styles. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * formats importance using an `*` (asterisk) by default. + * Pass + * [`strong: '_'`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsstrong) + * to use `_` (underscore) instead. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * **foo** and **bar**. + * + * @example + * {"name": "also-ok.md"} + * + * __foo__ and __bar__. + * + * @example + * {"name": "ok.md", "setting": "*"} + * + * **foo**. + * + * @example + * {"name": "ok.md", "setting": "_"} + * + * __foo__. + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * **foo** and __bar__. + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:13-1:20: Strong should use `*` as a marker + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} + * + * 1:1: Incorrect strong marker `💩`: use either `'consistent'`, `'*'`, or `'_'` + */ + +const remarkLintStrongMarker = lintRule( + { + origin: 'remark-lint:strong-marker', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-strong-marker#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + const value = String(file); + + if (option !== '*' && option !== '_' && option !== 'consistent') { + file.fail( + 'Incorrect strong marker `' + + option + + "`: use either `'consistent'`, `'*'`, or `'_'`" + ); + } + + visit$1(tree, 'strong', (node) => { + const start = pointStart(node).offset; + + if (typeof start === 'number') { + const marker = /** @type {Marker} */ (value.charAt(start)); + + if (option === 'consistent') { + option = marker; + } else if (marker !== option) { + file.message('Strong should use `' + option + '` as a marker', node); + } + } + }); + } +); + +var remarkLintStrongMarker$1 = remarkLintStrongMarker; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module table-cell-padding + * @fileoverview + * Warn when table cells are incorrectly padded. + * + * Options: `'consistent'`, `'padded'`, or `'compact'`, default: `'consistent'`. + * + * `'consistent'` detects the first used cell padding style and warns when + * subsequent cells use different styles. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * formats tables with padding by default. + * Pass + * [`spacedTable: false`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsspacedtable) + * to not use padding. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md", "setting": "padded", "gfm": true} + * + * | A | B | + * | ----- | ----- | + * | Alpha | Bravo | + * + * @example + * {"name": "not-ok.md", "label": "input", "setting": "padded", "gfm": true} + * + * | A | B | + * | :----|----: | + * | Alpha|Bravo | + * + * | C | D | + * | :----- | ---: | + * |Charlie | Delta| + * + * Too much padding isn’t good either: + * + * | E | F | G | H | + * | :---- | -------- | :----: | -----: | + * | Echo | Foxtrot | Golf | Hotel | + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "padded", "gfm": true} + * + * 3:8: Cell should be padded + * 3:9: Cell should be padded + * 7:2: Cell should be padded + * 7:17: Cell should be padded + * 13:9: Cell should be padded with 1 space, not 2 + * 13:20: Cell should be padded with 1 space, not 2 + * 13:21: Cell should be padded with 1 space, not 2 + * 13:29: Cell should be padded with 1 space, not 2 + * 13:30: Cell should be padded with 1 space, not 2 + * + * @example + * {"name": "ok.md", "setting": "compact", "gfm": true} + * + * |A |B | + * |-----|-----| + * |Alpha|Bravo| + * + * @example + * {"name": "not-ok.md", "label": "input", "setting": "compact", "gfm": true} + * + * | A | B | + * | -----| -----| + * | Alpha| Bravo| + * + * |C | D| + * |:------|-----:| + * |Charlie|Delta | + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "compact", "gfm": true} + * + * 3:2: Cell should be compact + * 3:11: Cell should be compact + * 7:16: Cell should be compact + * + * @example + * {"name": "ok-padded.md", "setting": "consistent", "gfm": true} + * + * | A | B | + * | ----- | ----- | + * | Alpha | Bravo | + * + * | C | D | + * | ------- | ----- | + * | Charlie | Delta | + * + * @example + * {"name": "not-ok-padded.md", "label": "input", "setting": "consistent", "gfm": true} + * + * | A | B | + * | ----- | ----- | + * | Alpha | Bravo | + * + * | C | D | + * | :----- | ----: | + * |Charlie | Delta | + * + * @example + * {"name": "not-ok-padded.md", "label": "output", "setting": "consistent", "gfm": true} + * + * 7:2: Cell should be padded + * + * @example + * {"name": "ok-compact.md", "setting": "consistent", "gfm": true} + * + * |A |B | + * |-----|-----| + * |Alpha|Bravo| + * + * |C |D | + * |-------|-----| + * |Charlie|Delta| + * + * @example + * {"name": "not-ok-compact.md", "label": "input", "setting": "consistent", "gfm": true} + * + * |A |B | + * |-----|-----| + * |Alpha|Bravo| + * + * |C | D| + * |:------|-----:| + * |Charlie|Delta | + * + * @example + * {"name": "not-ok-compact.md", "label": "output", "setting": "consistent", "gfm": true} + * + * 7:16: Cell should be compact + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true, "gfm": true} + * + * 1:1: Incorrect table cell padding style `💩`, expected `'padded'`, `'compact'`, or `'consistent'` + * + * @example + * {"name": "empty.md", "label": "input", "setting": "padded", "gfm": true} + * + * + * + * | | Alpha | Bravo| + * | ------ | ----- | ---: | + * | Charlie| | Echo| + * + * @example + * {"name": "empty.md", "label": "output", "setting": "padded", "gfm": true} + * + * 3:25: Cell should be padded + * 5:10: Cell should be padded + * 5:25: Cell should be padded + * + * @example + * {"name": "missing-body.md", "setting": "padded", "gfm": true} + * + * + * + * | Alpha | Bravo | Charlie | + * | ----- | ------- | ------- | + * | Delta | + * | Echo | Foxtrot | + */ + +const remarkLintTableCellPadding = lintRule( + { + origin: 'remark-lint:table-cell-padding', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-table-cell-padding#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + if ( + option !== 'padded' && + option !== 'compact' && + option !== 'consistent' + ) { + file.fail( + 'Incorrect table cell padding style `' + + option + + "`, expected `'padded'`, `'compact'`, or `'consistent'`" + ); + } + + visit$1(tree, 'table', (node) => { + const rows = node.children; + // To do: fix types to always have `align` defined. + /* c8 ignore next */ + const align = node.align || []; + /** @type {number[]} */ + const sizes = Array.from({length: align.length}); + /** @type {Entry[]} */ + const entries = []; + let index = -1; + + // Check rows. + while (++index < rows.length) { + const row = rows[index]; + let column = -1; + + // Check fences (before, between, and after cells). + while (++column < row.children.length) { + const cell = row.children[column]; + + if (cell.children.length > 0) { + const cellStart = pointStart(cell).offset; + const cellEnd = pointEnd(cell).offset; + const contentStart = pointStart(cell.children[0]).offset; + const contentEnd = pointEnd( + cell.children[cell.children.length - 1] + ).offset; + + if ( + typeof cellStart !== 'number' || + typeof cellEnd !== 'number' || + typeof contentStart !== 'number' || + typeof contentEnd !== 'number' + ) { + continue + } + + entries.push({ + node: cell, + start: contentStart - cellStart - (column ? 0 : 1), + end: cellEnd - contentEnd - 1, + column + }); + + // Detect max space per column. + sizes[column] = Math.max( + sizes[column] || 0, + contentEnd - contentStart + ); + } + } + } + + const style = + option === 'consistent' + ? entries[0] && (!entries[0].start || !entries[0].end) + ? 0 + : 1 + : option === 'padded' + ? 1 + : 0; + + index = -1; + + while (++index < entries.length) { + checkSide('start', entries[index], style, sizes); + checkSide('end', entries[index], style, sizes); + } + + return SKIP$1 + }); + + /** + * @param {'start'|'end'} side + * @param {Entry} entry + * @param {0|1} style + * @param {number[]} sizes + */ + function checkSide(side, entry, style, sizes) { + const cell = entry.node; + const column = entry.column; + const spacing = entry[side]; + + if (spacing === undefined || spacing === style) { + return + } + + let reason = 'Cell should be '; + + if (style === 0) { + // Ignore every cell except the biggest in the column. + if (size$1(cell) < sizes[column]) { + return + } + + reason += 'compact'; + } else { + reason += 'padded'; + + if (spacing > style) { + // May be right or center aligned. + if (size$1(cell) < sizes[column]) { + return + } + + reason += ' with 1 space, not ' + spacing; + } + } + + /** @type {Point} */ + let point; + + if (side === 'start') { + point = pointStart(cell); + if (!column) { + point.column++; + + if (typeof point.offset === 'number') { + point.offset++; + } + } + } else { + point = pointEnd(cell); + point.column--; + + if (typeof point.offset === 'number') { + point.offset--; + } + } + + file.message(reason, point); + } + } +); + +var remarkLintTableCellPadding$1 = remarkLintTableCellPadding; + +/** + * @param {TableCell} node + * @returns {number} + */ +function size$1(node) { + const head = pointStart(node.children[0]).offset; + const tail = pointEnd(node.children[node.children.length - 1]).offset; + // Only called when we’re sure offsets exist. + /* c8 ignore next */ + return typeof head === 'number' && typeof tail === 'number' ? tail - head : 0 +} + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module table-pipes + * @fileoverview + * Warn when table rows are not fenced with pipes. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * creates fenced rows with initial and final pipes by default. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md", "gfm": true} + * + * | A | B | + * | ----- | ----- | + * | Alpha | Bravo | + * + * @example + * {"name": "not-ok.md", "label": "input", "gfm": true} + * + * A | B + * ----- | ----- + * Alpha | Bravo + * + * @example + * {"name": "not-ok.md", "label": "output", "gfm": true} + * + * 1:1: Missing initial pipe in table fence + * 1:10: Missing final pipe in table fence + * 3:1: Missing initial pipe in table fence + * 3:14: Missing final pipe in table fence + */ + +const reasonStart = 'Missing initial pipe in table fence'; +const reasonEnd = 'Missing final pipe in table fence'; + +const remarkLintTablePipes = lintRule( + { + origin: 'remark-lint:table-pipes', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-table-pipes#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + const value = String(file); + + visit$1(tree, 'table', (node) => { + let index = -1; + + while (++index < node.children.length) { + const row = node.children[index]; + const start = pointStart(row); + const end = pointEnd(row); + + if ( + typeof start.offset === 'number' && + value.charCodeAt(start.offset) !== 124 + ) { + file.message(reasonStart, start); + } + + if ( + typeof end.offset === 'number' && + value.charCodeAt(end.offset - 1) !== 124 + ) { + file.message(reasonEnd, end); + } + } + }); + } +); + +var remarkLintTablePipes$1 = remarkLintTablePipes; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module unordered-list-marker-style + * @fileoverview + * Warn when the list item marker style of unordered lists violate a given + * style. + * + * Options: `'consistent'`, `'-'`, `'*'`, or `'+'`, default: `'consistent'`. + * + * `'consistent'` detects the first used list style and warns when subsequent + * lists use different styles. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * formats unordered lists using `-` (hyphen-minus) by default. + * Pass + * [`bullet: '*'` or `bullet: '+'`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsbullet) + * to use `*` (asterisk) or `+` (plus sign) instead. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * By default (`'consistent'`), if the file uses only one marker, + * that’s OK. + * + * * Foo + * * Bar + * * Baz + * + * Ordered lists are not affected. + * + * 1. Foo + * 2. Bar + * 3. Baz + * + * @example + * {"name": "ok.md", "setting": "*"} + * + * * Foo + * + * @example + * {"name": "ok.md", "setting": "-"} + * + * - Foo + * + * @example + * {"name": "ok.md", "setting": "+"} + * + * + Foo + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * * Foo + * - Bar + * + Baz + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 2:1-2:6: Marker style should be `*` + * 3:1-3:6: Marker style should be `*` + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} + * + * 1:1: Incorrect unordered list item marker style `💩`: use either `'-'`, `'*'`, or `'+'` + */ + +const markers = new Set(['-', '*', '+']); + +const remarkLintUnorderedListMarkerStyle = lintRule( + { + origin: 'remark-lint:unordered-list-marker-style', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-unordered-list-marker-style#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + const value = String(file); + + if (option !== 'consistent' && !markers.has(option)) { + file.fail( + 'Incorrect unordered list item marker style `' + + option + + "`: use either `'-'`, `'*'`, or `'+'`" + ); + } + + visit$1(tree, 'list', (node) => { + if (node.ordered) return + + let index = -1; + + while (++index < node.children.length) { + const child = node.children[index]; + + if (!generated(child)) { + const marker = /** @type {Marker} */ ( + value + .slice( + pointStart(child).offset, + pointStart(child.children[0]).offset + ) + .replace(/\[[x ]?]\s*$/i, '') + .replace(/\s/g, '') + ); + + if (option === 'consistent') { + option = marker; + } else if (marker !== option) { + file.message('Marker style should be `' + option + '`', child); + } + } + } + }); + } +); + +var remarkLintUnorderedListMarkerStyle$1 = remarkLintUnorderedListMarkerStyle; + +// @see https://github.com/nodejs/node/blob/HEAD/doc/guides/doc-style-guide.md + +// Add in rules alphabetically +const plugins = [ + // Leave preset at the top so it can be overridden + remarkPresetLintRecommended$1, + [remarkLintBlockquoteIndentation$1, 2], + [remarkLintCheckboxCharacterStyle$1, { checked: "x", unchecked: " " }], + remarkLintCheckboxContentIndent$1, + [remarkLintCodeBlockStyle$1, "fenced"], + remarkLintDefinitionSpacing$1, + [ + remarkLintFencedCodeFlag$1, + { + flags: [ + "bash", + "c", + "cjs", + "coffee", + "console", + "cpp", + "diff", + "http", + "js", + "json", + "markdown", + "mjs", + "powershell", + "r", + "text", + ], + }, + ], + [remarkLintFencedCodeMarker$1, "`"], + [remarkLintFileExtension$1, "md"], + remarkLintFinalDefinition$1, + [remarkLintFirstHeadingLevel$1, 1], + [remarkLintHeadingStyle$1, "atx"], + [remarkLintListItemIndent$1, "space"], + remarkLintMaximumLineLength$1, + remarkLintNoConsecutiveBlankLines$1, + remarkLintNoFileNameArticles$1, + remarkLintNoFileNameConsecutiveDashes$1, + remarkLintNofileNameOuterDashes$1, + remarkLintNoHeadingIndent$1, + remarkLintNoMultipleToplevelHeadings$1, + remarkLintNoShellDollars$1, + remarkLintNoTableIndentation$1, + remarkLintNoTabs$1, + remarkLintNoTrailingSpaces, + remarkLintNodejsLinks, + remarkLintNodejsYamlComments, + [ + remarkLintProhibitedStrings, + [ + { yes: "End-of-Life" }, + { yes: "GitHub" }, + { no: "hostname", yes: "host name" }, + { yes: "JavaScript" }, + { no: "[Ll]ong[ -][Tt]erm [Ss]upport", yes: "Long Term Support" }, + { no: "Node", yes: "Node.js", ignoreNextTo: "-API" }, + { yes: "Node.js" }, + { no: "Node[Jj][Ss]", yes: "Node.js" }, + { no: "Node\\.js's?", yes: "the Node.js" }, + { no: "[Nn]ote that", yes: "" }, + { yes: "RFC" }, + { no: "[Rr][Ff][Cc]\\d+", yes: "RFC " }, + { yes: "Unix" }, + { yes: "V8" }, + ], + ], + remarkLintRuleStyle$1, + [remarkLintStrongMarker$1, "*"], + [remarkLintTableCellPadding$1, "padded"], + remarkLintTablePipes$1, + [remarkLintUnorderedListMarkerStyle$1, "*"], +]; + +const settings = { + emphasis: "_", + listItemIndent: 1, + tightDefinitions: true, +}; + +const remarkPresetLintNode = { plugins, settings }; + +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Code} Code + */ +const www = { + tokenize: tokenizeWww, + partial: true +}; +const domain = { + tokenize: tokenizeDomain, + partial: true +}; +const path = { + tokenize: tokenizePath, + partial: true +}; +const punctuation = { + tokenize: tokenizePunctuation, + partial: true +}; +const namedCharacterReference = { + tokenize: tokenizeNamedCharacterReference, + partial: true +}; +const wwwAutolink = { + tokenize: tokenizeWwwAutolink, + previous: previousWww +}; +const httpAutolink = { + tokenize: tokenizeHttpAutolink, + previous: previousHttp +}; +const emailAutolink = { + tokenize: tokenizeEmailAutolink, + previous: previousEmail +}; +/** @type {ConstructRecord} */ + +const text = {}; +/** @type {Extension} */ + +const gfmAutolinkLiteral = { + text +}; +let code = 48; // Add alphanumerics. + +while (code < 123) { + text[code] = emailAutolink; + code++; + if (code === 58) code = 65; + else if (code === 91) code = 97; +} + +text[43] = emailAutolink; +text[45] = emailAutolink; +text[46] = emailAutolink; +text[95] = emailAutolink; +text[72] = [emailAutolink, httpAutolink]; +text[104] = [emailAutolink, httpAutolink]; +text[87] = [emailAutolink, wwwAutolink]; +text[119] = [emailAutolink, wwwAutolink]; +/** @type {Tokenizer} */ + +function tokenizeEmailAutolink(effects, ok, nok) { + const self = this; + /** @type {boolean} */ + + let hasDot; + /** @type {boolean|undefined} */ + + let hasDigitInLastSegment; + return start + /** @type {State} */ + + function start(code) { + if ( + !gfmAtext(code) || + !previousEmail(self.previous) || + previousUnbalanced(self.events) + ) { + return nok(code) + } + + effects.enter('literalAutolink'); + effects.enter('literalAutolinkEmail'); + return atext(code) + } + /** @type {State} */ + + function atext(code) { + if (gfmAtext(code)) { + effects.consume(code); + return atext + } + + if (code === 64) { + effects.consume(code); + return label + } + + return nok(code) + } + /** @type {State} */ + + function label(code) { + if (code === 46) { + return effects.check(punctuation, done, dotContinuation)(code) + } + + if (code === 45 || code === 95) { + return effects.check(punctuation, nok, dashOrUnderscoreContinuation)(code) + } + + if (asciiAlphanumeric(code)) { + if (!hasDigitInLastSegment && asciiDigit(code)) { + hasDigitInLastSegment = true; + } + + effects.consume(code); + return label + } + + return done(code) + } + /** @type {State} */ + + function dotContinuation(code) { + effects.consume(code); + hasDot = true; + hasDigitInLastSegment = undefined; + return label + } + /** @type {State} */ + + function dashOrUnderscoreContinuation(code) { + effects.consume(code); + return afterDashOrUnderscore + } + /** @type {State} */ + + function afterDashOrUnderscore(code) { + if (code === 46) { + return effects.check(punctuation, nok, dotContinuation)(code) + } + + return label(code) + } + /** @type {State} */ + + function done(code) { + if (hasDot && !hasDigitInLastSegment) { + effects.exit('literalAutolinkEmail'); + effects.exit('literalAutolink'); + return ok(code) + } + + return nok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeWwwAutolink(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + if ( + (code !== 87 && code !== 119) || + !previousWww(self.previous) || + previousUnbalanced(self.events) + ) { + return nok(code) + } + + effects.enter('literalAutolink'); + effects.enter('literalAutolinkWww'); // For `www.` we check instead of attempt, because when it matches, GH + // treats it as part of a domain (yes, it says a valid domain must come + // after `www.`, but that’s not how it’s implemented by them). + + return effects.check( + www, + effects.attempt(domain, effects.attempt(path, done), nok), + nok + )(code) + } + /** @type {State} */ + + function done(code) { + effects.exit('literalAutolinkWww'); + effects.exit('literalAutolink'); + return ok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeHttpAutolink(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + if ( + (code !== 72 && code !== 104) || + !previousHttp(self.previous) || + previousUnbalanced(self.events) + ) { + return nok(code) + } + + effects.enter('literalAutolink'); + effects.enter('literalAutolinkHttp'); + effects.consume(code); + return t1 + } + /** @type {State} */ + + function t1(code) { + if (code === 84 || code === 116) { + effects.consume(code); + return t2 + } + + return nok(code) + } + /** @type {State} */ + + function t2(code) { + if (code === 84 || code === 116) { + effects.consume(code); + return p + } + + return nok(code) + } + /** @type {State} */ + + function p(code) { + if (code === 80 || code === 112) { + effects.consume(code); + return s + } + + return nok(code) + } + /** @type {State} */ + + function s(code) { + if (code === 83 || code === 115) { + effects.consume(code); + return colon + } + + return colon(code) + } + /** @type {State} */ + + function colon(code) { + if (code === 58) { + effects.consume(code); + return slash1 + } + + return nok(code) + } + /** @type {State} */ + + function slash1(code) { + if (code === 47) { + effects.consume(code); + return slash2 + } + + return nok(code) + } + /** @type {State} */ + + function slash2(code) { + if (code === 47) { + effects.consume(code); + return after + } + + return nok(code) + } + /** @type {State} */ + + function after(code) { + return code === null || + asciiControl(code) || + unicodeWhitespace(code) || + unicodePunctuation(code) + ? nok(code) + : effects.attempt(domain, effects.attempt(path, done), nok)(code) + } + /** @type {State} */ + + function done(code) { + effects.exit('literalAutolinkHttp'); + effects.exit('literalAutolink'); + return ok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeWww(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.consume(code); + return w2 + } + /** @type {State} */ + + function w2(code) { + if (code === 87 || code === 119) { + effects.consume(code); + return w3 + } + + return nok(code) + } + /** @type {State} */ + + function w3(code) { + if (code === 87 || code === 119) { + effects.consume(code); + return dot + } + + return nok(code) + } + /** @type {State} */ + + function dot(code) { + if (code === 46) { + effects.consume(code); + return after + } + + return nok(code) + } + /** @type {State} */ + + function after(code) { + return code === null || markdownLineEnding(code) ? nok(code) : ok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeDomain(effects, ok, nok) { + /** @type {boolean|undefined} */ + let hasUnderscoreInLastSegment; + /** @type {boolean|undefined} */ + + let hasUnderscoreInLastLastSegment; + return domain + /** @type {State} */ + + function domain(code) { + if (code === 38) { + return effects.check( + namedCharacterReference, + done, + punctuationContinuation + )(code) + } + + if (code === 46 || code === 95) { + return effects.check(punctuation, done, punctuationContinuation)(code) + } // GH documents that only alphanumerics (other than `-`, `.`, and `_`) can + // occur, which sounds like ASCII only, but they also support `www.點看.com`, + // so that’s Unicode. + // Instead of some new production for Unicode alphanumerics, markdown + // already has that for Unicode punctuation and whitespace, so use those. + + if ( + code === null || + asciiControl(code) || + unicodeWhitespace(code) || + (code !== 45 && unicodePunctuation(code)) + ) { + return done(code) + } + + effects.consume(code); + return domain + } + /** @type {State} */ + + function punctuationContinuation(code) { + if (code === 46) { + hasUnderscoreInLastLastSegment = hasUnderscoreInLastSegment; + hasUnderscoreInLastSegment = undefined; + effects.consume(code); + return domain + } + + if (code === 95) hasUnderscoreInLastSegment = true; + effects.consume(code); + return domain + } + /** @type {State} */ + + function done(code) { + if (!hasUnderscoreInLastLastSegment && !hasUnderscoreInLastSegment) { + return ok(code) + } + + return nok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizePath(effects, ok) { + let balance = 0; + return inPath + /** @type {State} */ + + function inPath(code) { + if (code === 38) { + return effects.check( + namedCharacterReference, + ok, + continuedPunctuation + )(code) + } + + if (code === 40) { + balance++; + } + + if (code === 41) { + return effects.check( + punctuation, + parenAtPathEnd, + continuedPunctuation + )(code) + } + + if (pathEnd(code)) { + return ok(code) + } + + if (trailingPunctuation(code)) { + return effects.check(punctuation, ok, continuedPunctuation)(code) + } + + effects.consume(code); + return inPath + } + /** @type {State} */ + + function continuedPunctuation(code) { + effects.consume(code); + return inPath + } + /** @type {State} */ + + function parenAtPathEnd(code) { + balance--; + return balance < 0 ? ok(code) : continuedPunctuation(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeNamedCharacterReference(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.consume(code); + return inside + } + /** @type {State} */ + + function inside(code) { + if (asciiAlpha(code)) { + effects.consume(code); + return inside + } + + if (code === 59) { + effects.consume(code); + return after + } + + return nok(code) + } + /** @type {State} */ + + function after(code) { + // If the named character reference is followed by the end of the path, it’s + // not continued punctuation. + return pathEnd(code) ? ok(code) : nok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizePunctuation(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.consume(code); + return after + } + /** @type {State} */ + + function after(code) { + // Check the next. + if (trailingPunctuation(code)) { + effects.consume(code); + return after + } // If the punctuation marker is followed by the end of the path, it’s not + // continued punctuation. + + return pathEnd(code) ? ok(code) : nok(code) + } +} +/** + * @param {Code} code + * @returns {boolean} + */ + +function trailingPunctuation(code) { + return ( + code === 33 || + code === 34 || + code === 39 || + code === 41 || + code === 42 || + code === 44 || + code === 46 || + code === 58 || + code === 59 || + code === 60 || + code === 63 || + code === 95 || + code === 126 + ) +} +/** + * @param {Code} code + * @returns {boolean} + */ + +function pathEnd(code) { + return code === null || code === 60 || markdownLineEndingOrSpace(code) +} +/** + * @param {Code} code + * @returns {boolean} + */ + +function gfmAtext(code) { + return ( + code === 43 || + code === 45 || + code === 46 || + code === 95 || + asciiAlphanumeric(code) + ) +} +/** @type {Previous} */ + +function previousWww(code) { + return ( + code === null || + code === 40 || + code === 42 || + code === 95 || + code === 126 || + markdownLineEndingOrSpace(code) + ) +} +/** @type {Previous} */ + +function previousHttp(code) { + return code === null || !asciiAlpha(code) +} +/** @type {Previous} */ + +function previousEmail(code) { + return code !== 47 && previousHttp(code) +} +/** + * @param {Event[]} events + * @returns {boolean} + */ + +function previousUnbalanced(events) { + let index = events.length; + let result = false; + + while (index--) { + const token = events[index][1]; + + if ( + (token.type === 'labelLink' || token.type === 'labelImage') && + !token._balanced + ) { + result = true; + break + } // @ts-expect-error If we’ve seen this token, and it was marked as not + // having any unbalanced bracket before it, we can exit. + + if (token._gfmAutolinkLiteralWalkedInto) { + result = false; + break + } + } + + if (events.length > 0 && !result) { + // @ts-expect-error Mark the last token as “walked into” w/o finding + // anything. + events[events.length - 1][1]._gfmAutolinkLiteralWalkedInto = true; + } + + return result +} + +const characterReferences = {'"': 'quot', '&': 'amp', '<': 'lt', '>': 'gt'}; + +/** + * Encode only the dangerous HTML characters. + * + * This ensures that certain characters which have special meaning in HTML are + * dealt with. + * Technically, we can skip `>` and `"` in many cases, but CM includes them. + * + * @param {string} value + * @returns {string} + */ +function encode(value) { + return value.replace(/["&<>]/g, replace) + + /** + * @param {string} value + * @returns {string} + */ + function replace(value) { + // @ts-expect-error Hush, it’s fine. + return '&' + characterReferences[value] + ';' + } +} + +/** + * Make a value safe for injection as a URL. + * + * This encodes unsafe characters with percent-encoding and skips already + * encoded sequences (see `normalizeUri` below). + * Further unsafe characters are encoded as character references (see + * `micromark-util-encode`). + * + * Then, a regex of allowed protocols can be given, in which case the URL is + * sanitized. + * For example, `/^(https?|ircs?|mailto|xmpp)$/i` can be used for `a[href]`, + * or `/^https?$/i` for `img[src]`. + * If the URL includes an unknown protocol (one not matched by `protocol`, such + * as a dangerous example, `javascript:`), the value is ignored. + * + * @param {string|undefined} url + * @param {RegExp} [protocol] + * @returns {string} + */ +function sanitizeUri(url, protocol) { + const value = encode(normalizeUri(url || '')); + + if (!protocol) { + return value + } + + const colon = value.indexOf(':'); + const questionMark = value.indexOf('?'); + const numberSign = value.indexOf('#'); + const slash = value.indexOf('/'); + + if ( + // If there is no protocol, it’s relative. + colon < 0 || // If the first colon is after a `?`, `#`, or `/`, it’s not a protocol. + (slash > -1 && colon > slash) || + (questionMark > -1 && colon > questionMark) || + (numberSign > -1 && colon > numberSign) || // It is a protocol, it should be allowed. + protocol.test(value.slice(0, colon)) + ) { + return value + } + + return '' +} +/** + * Normalize a URL (such as used in definitions). + * + * Encode unsafe characters with percent-encoding, skipping already encoded + * sequences. + * + * @param {string} value + * @returns {string} + */ + +function normalizeUri(value) { + /** @type {string[]} */ + const result = []; + let index = -1; + let start = 0; + let skip = 0; + + while (++index < value.length) { + const code = value.charCodeAt(index); + /** @type {string} */ + + let replace = ''; // A correct percent encoded value. + + if ( + code === 37 && + asciiAlphanumeric(value.charCodeAt(index + 1)) && + asciiAlphanumeric(value.charCodeAt(index + 2)) + ) { + skip = 2; + } // ASCII. + else if (code < 128) { + if (!/[!#$&-;=?-Z_a-z~]/.test(String.fromCharCode(code))) { + replace = String.fromCharCode(code); + } + } // Astral. + else if (code > 55295 && code < 57344) { + const next = value.charCodeAt(index + 1); // A correct surrogate pair. + + if (code < 56320 && next > 56319 && next < 57344) { + replace = String.fromCharCode(code, next); + skip = 1; + } // Lone surrogate. + else { + replace = '\uFFFD'; + } + } // Unicode. + else { + replace = String.fromCharCode(code); + } + + if (replace) { + result.push(value.slice(start, index), encodeURIComponent(replace)); + start = index + skip + 1; + replace = ''; + } + + if (skip) { + index += skip; + skip = 0; + } + } + + return result.join('') + value.slice(start) +} + +/** + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').Handle} Handle + * @typedef {import('micromark-util-types').CompileContext} CompileContext + * @typedef {import('micromark-util-types').Token} Token + */ +/** @type {HtmlExtension} */ + +const gfmAutolinkLiteralHtml = { + exit: { + literalAutolinkEmail, + literalAutolinkHttp, + literalAutolinkWww + } +}; +/** @type {Handle} */ + +function literalAutolinkWww(token) { + anchorFromToken.call(this, token, 'http://'); +} +/** @type {Handle} */ + +function literalAutolinkEmail(token) { + anchorFromToken.call(this, token, 'mailto:'); +} +/** @type {Handle} */ + +function literalAutolinkHttp(token) { + anchorFromToken.call(this, token); +} +/** + * @this CompileContext + * @param {Token} token + * @param {string} [protocol] + * @returns {void} + */ + +function anchorFromToken(token, protocol) { + const url = this.sliceSerialize(token); + this.tag(''); + this.raw(this.encode(url)); + this.tag(''); +} + +/** + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + */ + +/** @type {HtmlExtension} */ +const gfmStrikethroughHtml = { + enter: { + strikethrough() { + this.tag(''); + } + }, + exit: { + strikethrough() { + this.tag(''); + } + } +}; + +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').Event} Event + */ + +/** + * @param {Options} [options] + * @returns {Extension} + */ +function gfmStrikethrough(options = {}) { + let single = options.singleTilde; + const tokenizer = { + tokenize: tokenizeStrikethrough, + resolveAll: resolveAllStrikethrough + }; + + if (single === null || single === undefined) { + single = true; + } + + return { + text: { + [126]: tokenizer + }, + insideSpan: { + null: [tokenizer] + }, + attentionMarkers: { + null: [126] + } + } + /** + * Take events and resolve strikethrough. + * + * @type {Resolver} + */ + + function resolveAllStrikethrough(events, context) { + let index = -1; + /** @type {Token} */ + + let strikethrough; + /** @type {Token} */ + + let text; + /** @type {number} */ + + let open; + /** @type {Event[]} */ + + let nextEvents; // Walk through all events. + + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'strikethroughSequenceTemporary' && + events[index][1]._close + ) { + open = index; // Now walk back to find an opener. + + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'strikethroughSequenceTemporary' && + events[open][1]._open && // If the sizes are the same: + events[index][1].end.offset - events[index][1].start.offset === + events[open][1].end.offset - events[open][1].start.offset + ) { + events[index][1].type = 'strikethroughSequence'; + events[open][1].type = 'strikethroughSequence'; + strikethrough = { + type: 'strikethrough', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[index][1].end) + }; + text = { + type: 'strikethroughText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + }; // Opening. + + nextEvents = [ + ['enter', strikethrough, context], + ['enter', events[open][1], context], + ['exit', events[open][1], context], + ['enter', text, context] + ]; // Between. + + splice( + nextEvents, + nextEvents.length, + 0, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ); // Closing. + + splice(nextEvents, nextEvents.length, 0, [ + ['exit', text, context], + ['enter', events[index][1], context], + ['exit', events[index][1], context], + ['exit', strikethrough, context] + ]); + splice(events, open - 1, index - open + 3, nextEvents); + index = open + nextEvents.length - 2; + break + } + } + } + } + + index = -1; + + while (++index < events.length) { + if (events[index][1].type === 'strikethroughSequenceTemporary') { + events[index][1].type = 'data'; + } + } + + return events + } + /** @type {Tokenizer} */ + + function tokenizeStrikethrough(effects, ok, nok) { + const previous = this.previous; + const events = this.events; + let size = 0; + return start + /** @type {State} */ + + function start(code) { + if ( + code !== 126 || + (previous === 126 && + events[events.length - 1][1].type !== 'characterEscape') + ) { + return nok(code) + } + + effects.enter('strikethroughSequenceTemporary'); + return more(code) + } + /** @type {State} */ + + function more(code) { + const before = classifyCharacter(previous); + + if (code === 126) { + // If this is the third marker, exit. + if (size > 1) return nok(code) + effects.consume(code); + size++; + return more + } + + if (size < 2 && !single) return nok(code) + const token = effects.exit('strikethroughSequenceTemporary'); + const after = classifyCharacter(code); + token._open = !after || (after === 2 && Boolean(before)); + token._close = !before || (before === 2 && Boolean(after)); + return ok(code) + } + } +} + +/** + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + */ + +/** + * @typedef {import('./syntax.js').Align} Align + */ +const alignment = { + null: '', + left: ' align="left"', + right: ' align="right"', + center: ' align="center"' +}; +/** @type {HtmlExtension} */ + +const gfmTableHtml = { + enter: { + table(token) { + this.lineEndingIfNeeded(); + this.tag(''); // @ts-expect-error Custom. + + this.setData('tableAlign', token._align); + }, + + tableBody() { + // Clear slurping line ending from the delimiter row. + this.setData('slurpOneLineEnding'); + this.tag(''); + }, + + tableData() { + /** @type {string|undefined} */ + const align = // @ts-expect-error Custom. + alignment[this.getData('tableAlign')[this.getData('tableColumn')]]; + + if (align === undefined) { + // Capture results to ignore them. + this.buffer(); + } else { + this.lineEndingIfNeeded(); + this.tag(''); + } + }, + + tableHead() { + this.lineEndingIfNeeded(); + this.tag(''); + }, + + tableHeader() { + this.lineEndingIfNeeded(); + this.tag( + '' + ); + }, + + tableRow() { + this.setData('tableColumn', 0); + this.lineEndingIfNeeded(); + this.tag(''); + } + }, + exit: { + // Overwrite the default code text data handler to unescape escaped pipes when + // they are in tables. + codeTextData(token) { + let value = this.sliceSerialize(token); + + if (this.getData('tableAlign')) { + value = value.replace(/\\([\\|])/g, replace$1); + } + + this.raw(this.encode(value)); + }, + + table() { + this.setData('tableAlign'); // If there was no table body, make sure the slurping from the delimiter row + // is cleared. + + this.setData('slurpAllLineEndings'); + this.lineEndingIfNeeded(); + this.tag('
'); + }, + + tableBody() { + this.lineEndingIfNeeded(); + this.tag(''); + }, + + tableData() { + /** @type {number} */ + // @ts-expect-error Custom. + const column = this.getData('tableColumn'); // @ts-expect-error Custom. + + if (column in this.getData('tableAlign')) { + this.tag(''); + this.setData('tableColumn', column + 1); + } else { + // Stop capturing. + this.resume(); + } + }, + + tableHead() { + this.lineEndingIfNeeded(); + this.tag(''); + this.setData('slurpOneLineEnding', true); // Slurp the line ending from the delimiter row. + }, + + tableHeader() { + this.tag(''); // @ts-expect-error Custom. + + this.setData('tableColumn', this.getData('tableColumn') + 1); + }, + + tableRow() { + /** @type {Align[]} */ + // @ts-expect-error Custom. + const align = this.getData('tableAlign'); + /** @type {number} */ + // @ts-expect-error Custom. + + let column = this.getData('tableColumn'); + + while (column < align.length) { + this.lineEndingIfNeeded(); // @ts-expect-error `null` is fine as an index. + + this.tag(''); + column++; + } + + this.setData('tableColumn', column); + this.lineEndingIfNeeded(); + this.tag(''); + } + } +}; +/** + * @param {string} $0 + * @param {string} $1 + * @returns {string} + */ + +function replace$1($0, $1) { + // Pipes work, backslashes don’t (but can’t escape pipes). + return $1 === '|' ? $1 : $0 +} + +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + */ + +/** @type {Extension} */ +const gfmTable = { + flow: { + null: { + tokenize: tokenizeTable, + resolve: resolveTable + } + } +}; +const setextUnderlineMini = { + tokenize: tokenizeSetextUnderlineMini, + partial: true +}; +const nextPrefixedOrBlank = { + tokenize: tokenizeNextPrefixedOrBlank, + partial: true +}; +/** @type {Resolver} */ + +function resolveTable(events, context) { + let index = -1; + /** @type {Token} */ + + let token; + /** @type {boolean|undefined} */ + + let inHead; + /** @type {boolean|undefined} */ + + let inDelimiterRow; + /** @type {boolean|undefined} */ + + let inRow; + /** @type {Token} */ + + let cell; + /** @type {Token} */ + + let content; + /** @type {Token} */ + + let text; + /** @type {number|undefined} */ + + let contentStart; + /** @type {number|undefined} */ + + let contentEnd; + /** @type {number|undefined} */ + + let cellStart; + + while (++index < events.length) { + token = events[index][1]; + + if (inRow) { + if (token.type === 'temporaryTableCellContent') { + contentStart = contentStart || index; + contentEnd = index; + } + + if ( + // Combine separate content parts into one. + (token.type === 'tableCellDivider' || token.type === 'tableRow') && + contentEnd + ) { + content = { + type: 'tableContent', + // @ts-expect-error `contentStart` is defined if `contentEnd` is too. + start: events[contentStart][1].start, + end: events[contentEnd][1].end + }; + text = { + type: 'chunkText', + start: content.start, + end: content.end, + // @ts-expect-error It’s fine. + contentType: 'text' + }; + events.splice( + // @ts-expect-error `contentStart` is defined if `contentEnd` is too. + contentStart, // @ts-expect-error `contentStart` is defined if `contentEnd` is too. + contentEnd - contentStart + 1, + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ); // @ts-expect-error `contentStart` is defined if `contentEnd` is too. + + index -= contentEnd - contentStart - 3; + contentStart = undefined; + contentEnd = undefined; + } + } + + if ( + events[index][0] === 'exit' && + cellStart && + cellStart + 1 < index && + (token.type === 'tableCellDivider' || + (token.type === 'tableRow' && + (cellStart + 3 < index || + events[cellStart][1].type !== 'whitespace'))) + ) { + cell = { + type: inDelimiterRow + ? 'tableDelimiter' + : inHead + ? 'tableHeader' + : 'tableData', + start: events[cellStart][1].start, + end: events[index][1].end + }; + events.splice(index + (token.type === 'tableCellDivider' ? 1 : 0), 0, [ + 'exit', + cell, + context + ]); + events.splice(cellStart, 0, ['enter', cell, context]); + index += 2; + cellStart = index + 1; + } + + if (token.type === 'tableRow') { + inRow = events[index][0] === 'enter'; + + if (inRow) { + cellStart = index + 1; + } + } + + if (token.type === 'tableDelimiterRow') { + inDelimiterRow = events[index][0] === 'enter'; + + if (inDelimiterRow) { + cellStart = index + 1; + } + } + + if (token.type === 'tableHead') { + inHead = events[index][0] === 'enter'; + } + } + + return events +} +/** @type {Tokenizer} */ + +function tokenizeTable(effects, ok, nok) { + const self = this; + /** @type {Align[]} */ + + const align = []; + let tableHeaderCount = 0; + /** @type {boolean|undefined} */ + + let seenDelimiter; + /** @type {boolean|undefined} */ + + let hasDash; + return start + /** @type {State} */ + + function start(code) { + // @ts-expect-error Custom. + effects.enter('table')._align = align; + effects.enter('tableHead'); + effects.enter('tableRow'); // If we start with a pipe, we open a cell marker. + + if (code === 124) { + return cellDividerHead(code) + } + + tableHeaderCount++; + effects.enter('temporaryTableCellContent'); // Can’t be space or eols at the start of a construct, so we’re in a cell. + + return inCellContentHead(code) + } + /** @type {State} */ + + function cellDividerHead(code) { + effects.enter('tableCellDivider'); + effects.consume(code); + effects.exit('tableCellDivider'); + seenDelimiter = true; + return cellBreakHead + } + /** @type {State} */ + + function cellBreakHead(code) { + if (code === null || markdownLineEnding(code)) { + return atRowEndHead(code) + } + + if (markdownSpace(code)) { + effects.enter('whitespace'); + effects.consume(code); + return inWhitespaceHead + } + + if (seenDelimiter) { + seenDelimiter = undefined; + tableHeaderCount++; + } + + if (code === 124) { + return cellDividerHead(code) + } // Anything else is cell content. + + effects.enter('temporaryTableCellContent'); + return inCellContentHead(code) + } + /** @type {State} */ + + function inWhitespaceHead(code) { + if (markdownSpace(code)) { + effects.consume(code); + return inWhitespaceHead + } + + effects.exit('whitespace'); + return cellBreakHead(code) + } + /** @type {State} */ + + function inCellContentHead(code) { + // EOF, whitespace, pipe + if (code === null || code === 124 || markdownLineEndingOrSpace(code)) { + effects.exit('temporaryTableCellContent'); + return cellBreakHead(code) + } + + effects.consume(code); + return code === 92 ? inCellContentEscapeHead : inCellContentHead + } + /** @type {State} */ + + function inCellContentEscapeHead(code) { + if (code === 92 || code === 124) { + effects.consume(code); + return inCellContentHead + } // Anything else. + + return inCellContentHead(code) + } + /** @type {State} */ + + function atRowEndHead(code) { + if (code === null) { + return nok(code) + } + + effects.exit('tableRow'); + effects.exit('tableHead'); + return effects.attempt( + { + tokenize: tokenizeRowEnd, + partial: true + }, + atDelimiterLineStart, + nok + )(code) + } + /** @type {State} */ + + function atDelimiterLineStart(code) { + // To do: is the lazy setext thing still needed? + return effects.check( + setextUnderlineMini, + nok, // Support an indent before the delimiter row. + factorySpace(effects, rowStartDelimiter, 'linePrefix', 4) + )(code) + } + /** @type {State} */ + + function rowStartDelimiter(code) { + // If there’s another space, or we’re at the EOL/EOF, exit. + if (code === null || markdownLineEndingOrSpace(code)) { + return nok(code) + } + + effects.enter('tableDelimiterRow'); + return atDelimiterRowBreak(code) + } + /** @type {State} */ + + function atDelimiterRowBreak(code) { + if (code === null || markdownLineEnding(code)) { + return rowEndDelimiter(code) + } + + if (markdownSpace(code)) { + effects.enter('whitespace'); + effects.consume(code); + return inWhitespaceDelimiter + } + + if (code === 45) { + effects.enter('tableDelimiterFiller'); + effects.consume(code); + hasDash = true; + align.push(null); + return inFillerDelimiter + } + + if (code === 58) { + effects.enter('tableDelimiterAlignment'); + effects.consume(code); + effects.exit('tableDelimiterAlignment'); + align.push('left'); + return afterLeftAlignment + } // If we start with a pipe, we open a cell marker. + + if (code === 124) { + effects.enter('tableCellDivider'); + effects.consume(code); + effects.exit('tableCellDivider'); + return atDelimiterRowBreak + } + + return nok(code) + } + /** @type {State} */ + + function inWhitespaceDelimiter(code) { + if (markdownSpace(code)) { + effects.consume(code); + return inWhitespaceDelimiter + } + + effects.exit('whitespace'); + return atDelimiterRowBreak(code) + } + /** @type {State} */ + + function inFillerDelimiter(code) { + if (code === 45) { + effects.consume(code); + return inFillerDelimiter + } + + effects.exit('tableDelimiterFiller'); + + if (code === 58) { + effects.enter('tableDelimiterAlignment'); + effects.consume(code); + effects.exit('tableDelimiterAlignment'); + align[align.length - 1] = + align[align.length - 1] === 'left' ? 'center' : 'right'; + return afterRightAlignment + } + + return atDelimiterRowBreak(code) + } + /** @type {State} */ + + function afterLeftAlignment(code) { + if (code === 45) { + effects.enter('tableDelimiterFiller'); + effects.consume(code); + hasDash = true; + return inFillerDelimiter + } // Anything else is not ok. + + return nok(code) + } + /** @type {State} */ + + function afterRightAlignment(code) { + if (code === null || markdownLineEnding(code)) { + return rowEndDelimiter(code) + } + + if (markdownSpace(code)) { + effects.enter('whitespace'); + effects.consume(code); + return inWhitespaceDelimiter + } // `|` + + if (code === 124) { + effects.enter('tableCellDivider'); + effects.consume(code); + effects.exit('tableCellDivider'); + return atDelimiterRowBreak + } + + return nok(code) + } + /** @type {State} */ + + function rowEndDelimiter(code) { + effects.exit('tableDelimiterRow'); // Exit if there was no dash at all, or if the header cell count is not the + // delimiter cell count. + + if (!hasDash || tableHeaderCount !== align.length) { + return nok(code) + } + + if (code === null) { + return tableClose(code) + } + + return effects.check( + nextPrefixedOrBlank, + tableClose, + effects.attempt( + { + tokenize: tokenizeRowEnd, + partial: true + }, + factorySpace(effects, bodyStart, 'linePrefix', 4), + tableClose + ) + )(code) + } + /** @type {State} */ + + function tableClose(code) { + effects.exit('table'); + return ok(code) + } + /** @type {State} */ + + function bodyStart(code) { + effects.enter('tableBody'); + return rowStartBody(code) + } + /** @type {State} */ + + function rowStartBody(code) { + effects.enter('tableRow'); // If we start with a pipe, we open a cell marker. + + if (code === 124) { + return cellDividerBody(code) + } + + effects.enter('temporaryTableCellContent'); // Can’t be space or eols at the start of a construct, so we’re in a cell. + + return inCellContentBody(code) + } + /** @type {State} */ + + function cellDividerBody(code) { + effects.enter('tableCellDivider'); + effects.consume(code); + effects.exit('tableCellDivider'); + return cellBreakBody + } + /** @type {State} */ + + function cellBreakBody(code) { + if (code === null || markdownLineEnding(code)) { + return atRowEndBody(code) + } + + if (markdownSpace(code)) { + effects.enter('whitespace'); + effects.consume(code); + return inWhitespaceBody + } // `|` + + if (code === 124) { + return cellDividerBody(code) + } // Anything else is cell content. + + effects.enter('temporaryTableCellContent'); + return inCellContentBody(code) + } + /** @type {State} */ + + function inWhitespaceBody(code) { + if (markdownSpace(code)) { + effects.consume(code); + return inWhitespaceBody + } + + effects.exit('whitespace'); + return cellBreakBody(code) + } + /** @type {State} */ + + function inCellContentBody(code) { + // EOF, whitespace, pipe + if (code === null || code === 124 || markdownLineEndingOrSpace(code)) { + effects.exit('temporaryTableCellContent'); + return cellBreakBody(code) + } + + effects.consume(code); + return code === 92 ? inCellContentEscapeBody : inCellContentBody + } + /** @type {State} */ + + function inCellContentEscapeBody(code) { + if (code === 92 || code === 124) { + effects.consume(code); + return inCellContentBody + } // Anything else. + + return inCellContentBody(code) + } + /** @type {State} */ + + function atRowEndBody(code) { + effects.exit('tableRow'); + + if (code === null) { + return tableBodyClose(code) + } + + return effects.check( + nextPrefixedOrBlank, + tableBodyClose, + effects.attempt( + { + tokenize: tokenizeRowEnd, + partial: true + }, + factorySpace(effects, rowStartBody, 'linePrefix', 4), + tableBodyClose + ) + )(code) + } + /** @type {State} */ + + function tableBodyClose(code) { + effects.exit('tableBody'); + return tableClose(code) + } + /** @type {Tokenizer} */ + + function tokenizeRowEnd(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return lineStart + } + /** @type {State} */ + + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } + } +} // Based on micromark, but that won’t work as we’re in a table, and that expects +// content. +// + +/** @type {Tokenizer} */ + +function tokenizeSetextUnderlineMini(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + if (code !== 45) { + return nok(code) + } + + effects.enter('setextUnderline'); + return sequence(code) + } + /** @type {State} */ + + function sequence(code) { + if (code === 45) { + effects.consume(code); + return sequence + } + + return whitespace(code) + } + /** @type {State} */ + + function whitespace(code) { + if (code === null || markdownLineEnding(code)) { + return ok(code) + } + + if (markdownSpace(code)) { + effects.consume(code); + return whitespace + } + + return nok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeNextPrefixedOrBlank(effects, ok, nok) { + let size = 0; + return start + /** @type {State} */ + + function start(code) { + // This is a check, so we don’t care about tokens, but we open a bogus one + // so we’re valid. + effects.enter('check'); // EOL. + + effects.consume(code); + return whitespace + } + /** @type {State} */ + + function whitespace(code) { + if (code === -1 || code === 32) { + effects.consume(code); + size++; + return size === 4 ? ok : whitespace + } // EOF or whitespace + + if (code === null || markdownLineEndingOrSpace(code)) { + return ok(code) + } // Anything else. + + return nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').CompileContext} CompileContext + */ + +/** + * An opening or closing tag, followed by a case-insensitive specific tag name, + * followed by HTML whitespace, a greater than, or a slash. + */ +const reFlow = + /<(\/?)(iframe|noembed|noframes|plaintext|script|style|title|textarea|xmp)(?=[\t\n\f\r />])/gi; + +/** + * As HTML (text) parses tags separately (and v. strictly), we don’t need to be + * global. + */ +const reText = new RegExp('^' + reFlow.source, 'i'); + +/** @type {HtmlExtension} */ +const gfmTagfilterHtml = { + exit: { + htmlFlowData(token) { + exitHtmlData.call(this, token, reFlow); + }, + htmlTextData(token) { + exitHtmlData.call(this, token, reText); + } + } +}; + +/** + * @this {CompileContext} + * @param {Token} token + * @param {RegExp} filter + */ +function exitHtmlData(token, filter) { + let value = this.sliceSerialize(token); + + if (this.options.allowDangerousHtml) { + value = value.replace(filter, '<$1$2'); + } + + this.raw(this.encode(value)); +} + +/** + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + */ + +/** @type {HtmlExtension} */ +const gfmTaskListItemHtml = { + enter: { + taskListCheck() { + this.tag(''); + }, + + taskListCheckValueChecked() { + this.tag('checked="" '); + } + } +}; + +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Code} Code + */ +const tasklistCheck = { + tokenize: tokenizeTasklistCheck +}; +const gfmTaskListItem = { + text: { + [91]: tasklistCheck + } +}; +/** @type {Tokenizer} */ + +function tokenizeTasklistCheck(effects, ok, nok) { + const self = this; + return open + /** @type {State} */ + + function open(code) { + if ( + // Exit if there’s stuff before. + self.previous !== null || // Exit if not in the first content that is the first child of a list + // item. + !self._gfmTasklistFirstContentOfListItem + ) { + return nok(code) + } + + effects.enter('taskListCheck'); + effects.enter('taskListCheckMarker'); + effects.consume(code); + effects.exit('taskListCheckMarker'); + return inside + } + /** @type {State} */ + + function inside(code) { + if (markdownSpace(code)) { + effects.enter('taskListCheckValueUnchecked'); + effects.consume(code); + effects.exit('taskListCheckValueUnchecked'); + return close + } + + if (code === 88 || code === 120) { + effects.enter('taskListCheckValueChecked'); + effects.consume(code); + effects.exit('taskListCheckValueChecked'); + return close + } + + return nok(code) + } + /** @type {State} */ + + function close(code) { + if (code === 93) { + effects.enter('taskListCheckMarker'); + effects.consume(code); + effects.exit('taskListCheckMarker'); + effects.exit('taskListCheck'); + return effects.check( + { + tokenize: spaceThenNonSpace + }, + ok, + nok + ) + } + + return nok(code) + } +} +/** @type {Tokenizer} */ + +function spaceThenNonSpace(effects, ok, nok) { + const self = this; + return factorySpace(effects, after, 'whitespace') + /** @type {State} */ + + function after(code) { + const tail = self.events[self.events.length - 1]; + return tail && + tail[1].type === 'whitespace' && + code !== null && + !markdownLineEndingOrSpace(code) + ? ok(code) + : nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-extension-gfm-strikethrough').Options} Options + */ + +/** + * Support GFM or markdown on github.com. + * + * @param {Options} [options] + * @returns {Extension} + */ +function gfm(options) { + return combineExtensions([ + gfmAutolinkLiteral, + gfmStrikethrough(options), + gfmTable, + gfmTaskListItem + ]) +} + +/** @type {HtmlExtension} */ +combineHtmlExtensions([ + gfmAutolinkLiteralHtml, + gfmStrikethroughHtml, + gfmTableHtml, + gfmTagfilterHtml, + gfmTaskListItemHtml +]); + +/** + * Get the total count of `character` in `value`. + * + * @param {any} value Content, coerced to string + * @param {string} character Single character to look for + * @return {number} Number of times `character` occurred in `value`. + */ +function ccount(value, character) { + var source = String(value); + var count = 0; + var index; + + if (typeof character !== 'string') { + throw new Error('Expected character') + } + + index = source.indexOf(character); + + while (index !== -1) { + count++; + index = source.indexOf(character, index + character.length); + } + + return count +} + +/** + * @typedef Options Configuration. + * @property {Test} [ignore] `unist-util-is` test used to assert parents + * + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Content} Content + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').Text} Text + * @typedef {Content|Root} Node + * @typedef {Extract} Parent + * + * @typedef {import('unist-util-visit-parents').Test} Test + * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult + * + * @typedef RegExpMatchObject + * @property {number} index + * @property {string} input + * + * @typedef {string|RegExp} Find + * @typedef {string|ReplaceFunction} Replace + * + * @typedef {[Find, Replace]} FindAndReplaceTuple + * @typedef {Object.} FindAndReplaceSchema + * @typedef {Array.} FindAndReplaceList + * + * @typedef {[RegExp, ReplaceFunction]} Pair + * @typedef {Array.} Pairs + */ + +const own$1 = {}.hasOwnProperty; + +/** + * @param tree mdast tree + * @param find Value to find and remove. When `string`, escaped and made into a global `RegExp` + * @param [replace] Value to insert. + * * When `string`, turned into a Text node. + * * When `Function`, called with the results of calling `RegExp.exec` as + * arguments, in which case it can return a single or a list of `Node`, + * a `string` (which is wrapped in a `Text` node), or `false` to not replace + * @param [options] Configuration. + */ +const findAndReplace = + /** + * @type {( + * ((tree: Node, find: Find, replace?: Replace, options?: Options) => Node) & + * ((tree: Node, schema: FindAndReplaceSchema|FindAndReplaceList, options?: Options) => Node) + * )} + **/ + ( + /** + * @param {Node} tree + * @param {Find|FindAndReplaceSchema|FindAndReplaceList} find + * @param {Replace|Options} [replace] + * @param {Options} [options] + */ + function (tree, find, replace, options) { + /** @type {Options|undefined} */ + let settings; + /** @type {FindAndReplaceSchema|FindAndReplaceList} */ + let schema; + + if (typeof find === 'string' || find instanceof RegExp) { + // @ts-expect-error don’t expect options twice. + schema = [[find, replace]]; + settings = options; + } else { + schema = find; + // @ts-expect-error don’t expect replace twice. + settings = replace; + } + + if (!settings) { + settings = {}; + } + + const ignored = convert(settings.ignore || []); + const pairs = toPairs(schema); + let pairIndex = -1; + + while (++pairIndex < pairs.length) { + visitParents(tree, 'text', visitor); + } + + return tree + + /** @type {import('unist-util-visit-parents').Visitor} */ + function visitor(node, parents) { + let index = -1; + /** @type {Parent|undefined} */ + let grandparent; + + while (++index < parents.length) { + const parent = /** @type {Parent} */ (parents[index]); + + if ( + ignored( + parent, + // @ts-expect-error mdast vs. unist parent. + grandparent ? grandparent.children.indexOf(parent) : undefined, + grandparent + ) + ) { + return + } + + grandparent = parent; + } + + if (grandparent) { + return handler(node, grandparent) + } + } + + /** + * @param {Text} node + * @param {Parent} parent + * @returns {VisitorResult} + */ + function handler(node, parent) { + const find = pairs[pairIndex][0]; + const replace = pairs[pairIndex][1]; + let start = 0; + // @ts-expect-error: TS is wrong, some of these children can be text. + let index = parent.children.indexOf(node); + /** @type {Array.} */ + let nodes = []; + /** @type {number|undefined} */ + let position; + + find.lastIndex = 0; + + let match = find.exec(node.value); + + while (match) { + position = match.index; + // @ts-expect-error this is perfectly fine, typescript. + let value = replace(...match, { + index: match.index, + input: match.input + }); + + if (typeof value === 'string') { + value = value.length > 0 ? {type: 'text', value} : undefined; + } + + if (value !== false) { + if (start !== position) { + nodes.push({ + type: 'text', + value: node.value.slice(start, position) + }); + } + + if (Array.isArray(value)) { + nodes.push(...value); + } else if (value) { + nodes.push(value); + } + + start = position + match[0].length; + } + + if (!find.global) { + break + } + + match = find.exec(node.value); + } + + if (position === undefined) { + nodes = [node]; + index--; + } else { + if (start < node.value.length) { + nodes.push({type: 'text', value: node.value.slice(start)}); + } + + parent.children.splice(index, 1, ...nodes); + } + + return index + nodes.length + 1 + } + } + ); + +/** + * @param {FindAndReplaceSchema|FindAndReplaceList} schema + * @returns {Pairs} + */ +function toPairs(schema) { + /** @type {Pairs} */ + const result = []; + + if (typeof schema !== 'object') { + throw new TypeError('Expected array or object as schema') + } + + if (Array.isArray(schema)) { + let index = -1; + + while (++index < schema.length) { + result.push([ + toExpression(schema[index][0]), + toFunction(schema[index][1]) + ]); + } + } else { + /** @type {string} */ + let key; + + for (key in schema) { + if (own$1.call(schema, key)) { + result.push([toExpression(key), toFunction(schema[key])]); + } + } + } + + return result +} + +/** + * @param {Find} find + * @returns {RegExp} + */ +function toExpression(find) { + return typeof find === 'string' ? new RegExp(escapeStringRegexp(find), 'g') : find +} + +/** + * @param {Replace} replace + * @returns {ReplaceFunction} + */ +function toFunction(replace) { + return typeof replace === 'function' ? replace : () => replace +} + +/** + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension + * @typedef {import('mdast-util-from-markdown').Transform} FromMarkdownTransform + * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle + * @typedef {import('mdast-util-to-markdown/lib/types.js').Options} ToMarkdownExtension + * @typedef {import('mdast-util-find-and-replace').ReplaceFunction} ReplaceFunction + * @typedef {import('mdast-util-find-and-replace').RegExpMatchObject} RegExpMatchObject + * @typedef {import('mdast-util-find-and-replace').PhrasingContent} PhrasingContent + */ + +const inConstruct = 'phrasing'; +const notInConstruct = ['autolink', 'link', 'image', 'label']; + +/** @type {FromMarkdownExtension} */ +const gfmAutolinkLiteralFromMarkdown = { + transforms: [transformGfmAutolinkLiterals], + enter: { + literalAutolink: enterLiteralAutolink, + literalAutolinkEmail: enterLiteralAutolinkValue, + literalAutolinkHttp: enterLiteralAutolinkValue, + literalAutolinkWww: enterLiteralAutolinkValue + }, + exit: { + literalAutolink: exitLiteralAutolink, + literalAutolinkEmail: exitLiteralAutolinkEmail, + literalAutolinkHttp: exitLiteralAutolinkHttp, + literalAutolinkWww: exitLiteralAutolinkWww + } +}; + +/** @type {ToMarkdownExtension} */ +const gfmAutolinkLiteralToMarkdown = { + unsafe: [ + { + character: '@', + before: '[+\\-.\\w]', + after: '[\\-.\\w]', + inConstruct, + notInConstruct + }, + { + character: '.', + before: '[Ww]', + after: '[\\-.\\w]', + inConstruct, + notInConstruct + }, + {character: ':', before: '[ps]', after: '\\/', inConstruct, notInConstruct} + ] +}; + +/** @type {FromMarkdownHandle} */ +function enterLiteralAutolink(token) { + this.enter({type: 'link', title: null, url: '', children: []}, token); +} + +/** @type {FromMarkdownHandle} */ +function enterLiteralAutolinkValue(token) { + this.config.enter.autolinkProtocol.call(this, token); +} + +/** @type {FromMarkdownHandle} */ +function exitLiteralAutolinkHttp(token) { + this.config.exit.autolinkProtocol.call(this, token); +} + +/** @type {FromMarkdownHandle} */ +function exitLiteralAutolinkWww(token) { + this.config.exit.data.call(this, token); + const node = /** @type {Link} */ (this.stack[this.stack.length - 1]); + node.url = 'http://' + this.sliceSerialize(token); +} + +/** @type {FromMarkdownHandle} */ +function exitLiteralAutolinkEmail(token) { + this.config.exit.autolinkEmail.call(this, token); +} + +/** @type {FromMarkdownHandle} */ +function exitLiteralAutolink(token) { + this.exit(token); +} + +/** @type {FromMarkdownTransform} */ +function transformGfmAutolinkLiterals(tree) { + findAndReplace( + tree, + [ + [/(https?:\/\/|www(?=\.))([-.\w]+)([^ \t\r\n]*)/gi, findUrl], + [/([-.\w+]+)@([-\w]+(?:\.[-\w]+)+)/g, findEmail] + ], + {ignore: ['link', 'linkReference']} + ); +} + +/** + * @type {ReplaceFunction} + * @param {string} _ + * @param {string} protocol + * @param {string} domain + * @param {string} path + * @param {RegExpMatchObject} match + */ +// eslint-disable-next-line max-params +function findUrl(_, protocol, domain, path, match) { + let prefix = ''; + + // Not an expected previous character. + if (!previous(match)) { + return false + } + + // Treat `www` as part of the domain. + if (/^w/i.test(protocol)) { + domain = protocol + domain; + protocol = ''; + prefix = 'http://'; + } + + if (!isCorrectDomain(domain)) { + return false + } + + const parts = splitUrl(domain + path); + + if (!parts[0]) return false + + /** @type {PhrasingContent} */ + const result = { + type: 'link', + title: null, + url: prefix + protocol + parts[0], + children: [{type: 'text', value: protocol + parts[0]}] + }; + + if (parts[1]) { + return [result, {type: 'text', value: parts[1]}] + } + + return result +} + +/** + * @type {ReplaceFunction} + * @param {string} _ + * @param {string} atext + * @param {string} label + * @param {RegExpMatchObject} match + */ +function findEmail(_, atext, label, match) { + // Not an expected previous character. + if (!previous(match, true) || /[_-]$/.test(label)) { + return false + } + + return { + type: 'link', + title: null, + url: 'mailto:' + atext + '@' + label, + children: [{type: 'text', value: atext + '@' + label}] + } +} + +/** + * @param {string} domain + * @returns {boolean} + */ +function isCorrectDomain(domain) { + const parts = domain.split('.'); + + if ( + parts.length < 2 || + (parts[parts.length - 1] && + (/_/.test(parts[parts.length - 1]) || + !/[a-zA-Z\d]/.test(parts[parts.length - 1]))) || + (parts[parts.length - 2] && + (/_/.test(parts[parts.length - 2]) || + !/[a-zA-Z\d]/.test(parts[parts.length - 2]))) + ) { + return false + } + + return true +} + +/** + * @param {string} url + * @returns {[string, string|undefined]} + */ +function splitUrl(url) { + const trailExec = /[!"&'),.:;<>?\]}]+$/.exec(url); + /** @type {number} */ + let closingParenIndex; + /** @type {number} */ + let openingParens; + /** @type {number} */ + let closingParens; + /** @type {string|undefined} */ + let trail; + + if (trailExec) { + url = url.slice(0, trailExec.index); + trail = trailExec[0]; + closingParenIndex = trail.indexOf(')'); + openingParens = ccount(url, '('); + closingParens = ccount(url, ')'); + + while (closingParenIndex !== -1 && openingParens > closingParens) { + url += trail.slice(0, closingParenIndex + 1); + trail = trail.slice(closingParenIndex + 1); + closingParenIndex = trail.indexOf(')'); + closingParens++; + } + } + + return [url, trail] +} + +/** + * @param {RegExpMatchObject} match + * @param {boolean} [email=false] + * @returns {boolean} + */ +function previous(match, email) { + const code = match.input.charCodeAt(match.index - 1); + + return ( + (match.index === 0 || + unicodeWhitespace(code) || + unicodePunctuation(code)) && + (!email || code !== 47) + ) +} + +/** + * @typedef {import('mdast').Delete} Delete + * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension + * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle + * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension + * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle + */ + +/** @type {FromMarkdownExtension} */ +const gfmStrikethroughFromMarkdown = { + canContainEols: ['delete'], + enter: {strikethrough: enterStrikethrough}, + exit: {strikethrough: exitStrikethrough} +}; + +/** @type {ToMarkdownExtension} */ +const gfmStrikethroughToMarkdown = { + unsafe: [{character: '~', inConstruct: 'phrasing'}], + handlers: {delete: handleDelete} +}; + +handleDelete.peek = peekDelete; + +/** @type {FromMarkdownHandle} */ +function enterStrikethrough(token) { + this.enter({type: 'delete', children: []}, token); +} + +/** @type {FromMarkdownHandle} */ +function exitStrikethrough(token) { + this.exit(token); +} + +/** + * @type {ToMarkdownHandle} + * @param {Delete} node + */ +function handleDelete(node, _, context) { + const exit = context.enter('emphasis'); + const value = containerPhrasing(node, context, {before: '~', after: '~'}); + exit(); + return '~~' + value + '~~' +} + +/** @type {ToMarkdownHandle} */ +function peekDelete() { + return '~' +} + +/** + * @typedef MarkdownTableOptions + * @property {string|null|Array.} [align] + * @property {boolean} [padding=true] + * @property {boolean} [delimiterStart=true] + * @property {boolean} [delimiterStart=true] + * @property {boolean} [delimiterEnd=true] + * @property {boolean} [alignDelimiters=true] + * @property {(value: string) => number} [stringLength] + */ + +/** + * Create a table from a matrix of strings. + * + * @param {Array.>} table + * @param {MarkdownTableOptions} [options] + * @returns {string} + */ +function markdownTable(table, options) { + const settings = options || {}; + const align = (settings.align || []).concat(); + const stringLength = settings.stringLength || defaultStringLength; + /** @type {number[]} Character codes as symbols for alignment per column. */ + const alignments = []; + let rowIndex = -1; + /** @type {string[][]} Cells per row. */ + const cellMatrix = []; + /** @type {number[][]} Sizes of each cell per row. */ + const sizeMatrix = []; + /** @type {number[]} */ + const longestCellByColumn = []; + let mostCellsPerRow = 0; + /** @type {number} */ + let columnIndex; + /** @type {string[]} Cells of current row */ + let row; + /** @type {number[]} Sizes of current row */ + let sizes; + /** @type {number} Sizes of current cell */ + let size; + /** @type {string} Current cell */ + let cell; + /** @type {string[]} Chunks of current line. */ + let line; + /** @type {string} */ + let before; + /** @type {string} */ + let after; + /** @type {number} */ + let code; + + // This is a superfluous loop if we don’t align delimiters, but otherwise we’d + // do superfluous work when aligning, so optimize for aligning. + while (++rowIndex < table.length) { + columnIndex = -1; + row = []; + sizes = []; + + if (table[rowIndex].length > mostCellsPerRow) { + mostCellsPerRow = table[rowIndex].length; + } + + while (++columnIndex < table[rowIndex].length) { + cell = serialize(table[rowIndex][columnIndex]); + + if (settings.alignDelimiters !== false) { + size = stringLength(cell); + sizes[columnIndex] = size; + + if ( + longestCellByColumn[columnIndex] === undefined || + size > longestCellByColumn[columnIndex] + ) { + longestCellByColumn[columnIndex] = size; + } + } + + row.push(cell); + } + + cellMatrix[rowIndex] = row; + sizeMatrix[rowIndex] = sizes; + } + + // Figure out which alignments to use. + columnIndex = -1; + + if (typeof align === 'object' && 'length' in align) { + while (++columnIndex < mostCellsPerRow) { + alignments[columnIndex] = toAlignment(align[columnIndex]); + } + } else { + code = toAlignment(align); + + while (++columnIndex < mostCellsPerRow) { + alignments[columnIndex] = code; + } + } + + // Inject the alignment row. + columnIndex = -1; + row = []; + sizes = []; + + while (++columnIndex < mostCellsPerRow) { + code = alignments[columnIndex]; + before = ''; + after = ''; + + if (code === 99 /* `c` */) { + before = ':'; + after = ':'; + } else if (code === 108 /* `l` */) { + before = ':'; + } else if (code === 114 /* `r` */) { + after = ':'; + } + + // There *must* be at least one hyphen-minus in each alignment cell. + size = + settings.alignDelimiters === false + ? 1 + : Math.max( + 1, + longestCellByColumn[columnIndex] - before.length - after.length + ); + + cell = before + '-'.repeat(size) + after; + + if (settings.alignDelimiters !== false) { + size = before.length + size + after.length; + + if (size > longestCellByColumn[columnIndex]) { + longestCellByColumn[columnIndex] = size; + } + + sizes[columnIndex] = size; + } + + row[columnIndex] = cell; + } + + // Inject the alignment row. + cellMatrix.splice(1, 0, row); + sizeMatrix.splice(1, 0, sizes); + + rowIndex = -1; + /** @type {string[]} */ + const lines = []; + + while (++rowIndex < cellMatrix.length) { + row = cellMatrix[rowIndex]; + sizes = sizeMatrix[rowIndex]; + columnIndex = -1; + line = []; + + while (++columnIndex < mostCellsPerRow) { + cell = row[columnIndex] || ''; + before = ''; + after = ''; + + if (settings.alignDelimiters !== false) { + size = longestCellByColumn[columnIndex] - (sizes[columnIndex] || 0); + code = alignments[columnIndex]; + + if (code === 114 /* `r` */) { + before = ' '.repeat(size); + } else if (code === 99 /* `c` */) { + if (size % 2) { + before = ' '.repeat(size / 2 + 0.5); + after = ' '.repeat(size / 2 - 0.5); + } else { + before = ' '.repeat(size / 2); + after = before; + } + } else { + after = ' '.repeat(size); + } + } + + if (settings.delimiterStart !== false && !columnIndex) { + line.push('|'); + } + + if ( + settings.padding !== false && + // Don’t add the opening space if we’re not aligning and the cell is + // empty: there will be a closing space. + !(settings.alignDelimiters === false && cell === '') && + (settings.delimiterStart !== false || columnIndex) + ) { + line.push(' '); + } + + if (settings.alignDelimiters !== false) { + line.push(before); + } + + line.push(cell); + + if (settings.alignDelimiters !== false) { + line.push(after); + } + + if (settings.padding !== false) { + line.push(' '); + } + + if ( + settings.delimiterEnd !== false || + columnIndex !== mostCellsPerRow - 1 + ) { + line.push('|'); + } + } + + lines.push( + settings.delimiterEnd === false + ? line.join('').replace(/ +$/, '') + : line.join('') + ); + } + + return lines.join('\n') +} + +/** + * @param {string|null|undefined} [value] + * @returns {string} + */ +function serialize(value) { + return value === null || value === undefined ? '' : String(value) +} + +/** + * @param {string} value + * @returns {number} + */ +function defaultStringLength(value) { + return value.length +} + +/** + * @param {string|null|undefined} value + * @returns {number} + */ +function toAlignment(value) { + const code = typeof value === 'string' ? value.charCodeAt(0) : 0; + + return code === 67 /* `C` */ || code === 99 /* `c` */ + ? 99 /* `c` */ + : code === 76 /* `L` */ || code === 108 /* `l` */ + ? 108 /* `l` */ + : code === 82 /* `R` */ || code === 114 /* `r` */ + ? 114 /* `r` */ + : 0 +} + +/** + * @typedef {import('mdast').AlignType} AlignType + * @typedef {import('mdast').Table} Table + * @typedef {import('mdast').TableRow} TableRow + * @typedef {import('mdast').TableCell} TableCell + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('markdown-table').MarkdownTableOptions} MarkdownTableOptions + * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension + * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle + * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension + * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle + * @typedef {import('mdast-util-to-markdown').Context} ToMarkdownContext + * + * @typedef Options + * @property {boolean} [tableCellPadding=true] + * @property {boolean} [tablePipeAlign=true] + * @property {MarkdownTableOptions['stringLength']} [stringLength] + */ + +/** @type {FromMarkdownExtension} */ +const gfmTableFromMarkdown = { + enter: { + table: enterTable, + tableData: enterCell, + tableHeader: enterCell, + tableRow: enterRow + }, + exit: { + codeText: exitCodeText, + table: exitTable, + tableData: exit, + tableHeader: exit, + tableRow: exit + } +}; + +/** @type {FromMarkdownHandle} */ +function enterTable(token) { + /** @type {AlignType[]} */ + // @ts-expect-error: `align` is custom. + const align = token._align; + this.enter({type: 'table', align, children: []}, token); + this.setData('inTable', true); +} + +/** @type {FromMarkdownHandle} */ +function exitTable(token) { + this.exit(token); + this.setData('inTable'); +} + +/** @type {FromMarkdownHandle} */ +function enterRow(token) { + this.enter({type: 'tableRow', children: []}, token); +} + +/** @type {FromMarkdownHandle} */ +function exit(token) { + this.exit(token); +} + +/** @type {FromMarkdownHandle} */ +function enterCell(token) { + this.enter({type: 'tableCell', children: []}, token); +} + +// Overwrite the default code text data handler to unescape escaped pipes when +// they are in tables. +/** @type {FromMarkdownHandle} */ +function exitCodeText(token) { + let value = this.resume(); + + if (this.getData('inTable')) { + value = value.replace(/\\([\\|])/g, replace); + } + + const node = /** @type {InlineCode} */ (this.stack[this.stack.length - 1]); + node.value = value; + this.exit(token); +} + +/** + * @param {string} $0 + * @param {string} $1 + * @returns {string} + */ +function replace($0, $1) { + // Pipes work, backslashes don’t (but can’t escape pipes). + return $1 === '|' ? $1 : $0 +} + +/** + * @param {Options} [options] + * @returns {ToMarkdownExtension} + */ +function gfmTableToMarkdown(options) { + const settings = options || {}; + const padding = settings.tableCellPadding; + const alignDelimiters = settings.tablePipeAlign; + const stringLength = settings.stringLength; + const around = padding ? ' ' : '|'; + + return { + unsafe: [ + {character: '\r', inConstruct: 'tableCell'}, + {character: '\n', inConstruct: 'tableCell'}, + // A pipe, when followed by a tab or space (padding), or a dash or colon + // (unpadded delimiter row), could result in a table. + {atBreak: true, character: '|', after: '[\t :-]'}, + // A pipe in a cell must be encoded. + {character: '|', inConstruct: 'tableCell'}, + // A colon must be followed by a dash, in which case it could start a + // delimiter row. + {atBreak: true, character: ':', after: '-'}, + // A delimiter row can also start with a dash, when followed by more + // dashes, a colon, or a pipe. + // This is a stricter version than the built in check for lists, thematic + // breaks, and setex heading underlines though: + // + {atBreak: true, character: '-', after: '[:|-]'} + ], + handlers: { + table: handleTable, + tableRow: handleTableRow, + tableCell: handleTableCell, + inlineCode: inlineCodeWithTable + } + } + + /** + * @type {ToMarkdownHandle} + * @param {Table} node + */ + function handleTable(node, _, context) { + // @ts-expect-error: fixed in `markdown-table@3.0.1`. + return serializeData(handleTableAsData(node, context), node.align) + } + + /** + * This function isn’t really used normally, because we handle rows at the + * table level. + * But, if someone passes in a table row, this ensures we make somewhat sense. + * + * @type {ToMarkdownHandle} + * @param {TableRow} node + */ + function handleTableRow(node, _, context) { + const row = handleTableRowAsData(node, context); + // `markdown-table` will always add an align row + const value = serializeData([row]); + return value.slice(0, value.indexOf('\n')) + } + + /** + * @type {ToMarkdownHandle} + * @param {TableCell} node + */ + function handleTableCell(node, _, context) { + const exit = context.enter('tableCell'); + const subexit = context.enter('phrasing'); + const value = containerPhrasing(node, context, { + before: around, + after: around + }); + subexit(); + exit(); + return value + } + + /** + * @param {Array.>} matrix + * @param {Array.} [align] + */ + function serializeData(matrix, align) { + return markdownTable(matrix, { + align, + alignDelimiters, + padding, + stringLength + }) + } + + /** + * @param {Table} node + * @param {ToMarkdownContext} context + */ + function handleTableAsData(node, context) { + const children = node.children; + let index = -1; + /** @type {Array.>} */ + const result = []; + const subexit = context.enter('table'); + + while (++index < children.length) { + result[index] = handleTableRowAsData(children[index], context); + } + + subexit(); + + return result + } + + /** + * @param {TableRow} node + * @param {ToMarkdownContext} context + */ + function handleTableRowAsData(node, context) { + const children = node.children; + let index = -1; + /** @type {Array.} */ + const result = []; + const subexit = context.enter('tableRow'); + + while (++index < children.length) { + result[index] = handleTableCell(children[index], node, context); + } + + subexit(); + + return result + } + + /** + * @type {ToMarkdownHandle} + * @param {InlineCode} node + */ + function inlineCodeWithTable(node, parent, context) { + let value = inlineCode(node, parent, context); + + if (context.stack.includes('tableCell')) { + value = value.replace(/\|/g, '\\$&'); + } + + return value + } +} + +/** + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').BlockContent} BlockContent + * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension + * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle + * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension + * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle + */ + +/** @type {FromMarkdownExtension} */ +const gfmTaskListItemFromMarkdown = { + exit: { + taskListCheckValueChecked: exitCheck, + taskListCheckValueUnchecked: exitCheck, + paragraph: exitParagraphWithTaskListItem + } +}; + +/** @type {ToMarkdownExtension} */ +const gfmTaskListItemToMarkdown = { + unsafe: [{atBreak: true, character: '-', after: '[:|-]'}], + handlers: {listItem: listItemWithTaskListItem} +}; + +/** @type {FromMarkdownHandle} */ +function exitCheck(token) { + // We’re always in a paragraph, in a list item. + this.stack[this.stack.length - 2].checked = + token.type === 'taskListCheckValueChecked'; +} + +/** @type {FromMarkdownHandle} */ +function exitParagraphWithTaskListItem(token) { + const parent = this.stack[this.stack.length - 2]; + /** @type {Paragraph} */ + // @ts-expect-error: must be true. + const node = this.stack[this.stack.length - 1]; + /** @type {BlockContent[]} */ + // @ts-expect-error: check whether `parent` is a `listItem` later. + const siblings = parent.children; + const head = node.children[0]; + let index = -1; + /** @type {Paragraph|undefined} */ + let firstParaghraph; + + if ( + parent && + parent.type === 'listItem' && + typeof parent.checked === 'boolean' && + head && + head.type === 'text' + ) { + while (++index < siblings.length) { + const sibling = siblings[index]; + if (sibling.type === 'paragraph') { + firstParaghraph = sibling; + break + } + } + + if (firstParaghraph === node) { + // Must start with a space or a tab. + head.value = head.value.slice(1); + + if (head.value.length === 0) { + node.children.shift(); + } else { + // @ts-expect-error: must be true. + head.position.start.column++; + // @ts-expect-error: must be true. + head.position.start.offset++; + // @ts-expect-error: must be true. + node.position.start = Object.assign({}, head.position.start); + } + } + } + + this.exit(token); +} + +/** + * @type {ToMarkdownHandle} + * @param {ListItem} node + */ +function listItemWithTaskListItem(node, parent, context) { + const head = node.children[0]; + let value = listItem(node, parent, context); + + if (typeof node.checked === 'boolean' && head && head.type === 'paragraph') { + value = value.replace(/^(?:[*+-]|\d+\.)([\r\n]| {1,3})/, check); + } + + return value + + /** + * @param {string} $0 + * @returns {string} + */ + function check($0) { + return $0 + '[' + (node.checked ? 'x' : ' ') + '] ' + } +} + +/** + * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension + * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension + * + * @typedef {import('mdast-util-gfm-table').Options} Options + */ + +/** + * @type {Array.} + */ +const gfmFromMarkdown = [ + gfmAutolinkLiteralFromMarkdown, + gfmStrikethroughFromMarkdown, + gfmTableFromMarkdown, + gfmTaskListItemFromMarkdown +]; + +/** + * @param {Options} [options] + * @returns {ToMarkdownExtension} + */ +function gfmToMarkdown(options) { + return { + extensions: [ + gfmAutolinkLiteralToMarkdown, + gfmStrikethroughToMarkdown, + gfmTableToMarkdown(options), + gfmTaskListItemToMarkdown + ] + } +} + +/** + * @typedef {import('mdast').Root} Root + * @typedef {import('micromark-extension-gfm').Options & import('mdast-util-gfm').Options} Options + */ + +/** + * Plugin to support GitHub Flavored Markdown (GFM). + * + * @type {import('unified').Plugin<[Options?]|void[], Root>} + */ +function remarkGfm(options = {}) { + const data = this.data(); + + add('micromarkExtensions', gfm(options)); + add('fromMarkdownExtensions', gfmFromMarkdown); + add('toMarkdownExtensions', gfmToMarkdown(options)); + + /** + * @param {string} field + * @param {unknown} value + */ + function add(field, value) { + const list = /** @type {unknown[]} */ ( + // Other extensions + /* c8 ignore next 2 */ + data[field] ? data[field] : (data[field] = []) + ); + + list.push(value); + } +} + +/** + * @typedef {import('vfile').VFileValue} Value + * @typedef {import('vfile').VFileOptions} Options + * @typedef {import('vfile').BufferEncoding} BufferEncoding + * + * @typedef {number|string} Mode + * @typedef {BufferEncoding|{encoding?: null|BufferEncoding, flag?: string}} ReadOptions + * @typedef {BufferEncoding|{encoding?: null|BufferEncoding, mode: Mode?, flag?: string}} WriteOptions + * + * @typedef {string|Uint8Array} Path Path of the file. + * @typedef {Path|URL|Options|VFile} Compatible Things that can be + * passed to the function. + */ + +/** + * Create a virtual file from a description. + * If `options` is a string or a buffer, it’s used as the path. + * If it’s a VFile itself, it’s returned instead. + * In all other cases, the options are passed through to `vfile()`. + * + * @param {Compatible} [options] + * @returns {VFile} + */ +function toVFile(options) { + if (typeof options === 'string' || options instanceof URL$1) { + options = {path: options}; + } else if (isBuffer(options)) { + options = {path: String(options)}; + } + + return looksLikeAVFile(options) ? options : new VFile(options) +} + +/** + * Create a virtual file and read it in, synchronously. + * + * @param {Compatible} description + * @param {ReadOptions} [options] + * @returns {VFile} + */ +function readSync(description, options) { + const file = toVFile(description); + file.value = fs.readFileSync(path$1.resolve(file.cwd, file.path), options); + return file +} + +/** + * Create a virtual file and write it in, synchronously. + * + * @param {Compatible} description + * @param {WriteOptions} [options] + * @returns {VFile} + */ +function writeSync(description, options) { + const file = toVFile(description); + fs.writeFileSync(path$1.resolve(file.cwd, file.path), file.value || '', options); + return file +} + +const read = + /** + * @type {{ + * (description: Compatible, options: ReadOptions, callback: Callback): void + * (description: Compatible, callback: Callback): void + * (description: Compatible, options?: ReadOptions): Promise + * }} + */ + ( + /** + * Create a virtual file and read it in, asynchronously. + * + * @param {Compatible} description + * @param {ReadOptions} [options] + * @param {Callback} [callback] + */ + function (description, options, callback) { + const file = toVFile(description); + + if (!callback && typeof options === 'function') { + callback = options; + options = null; + } + + if (!callback) { + return new Promise(executor) + } + + executor(resolve, callback); + + /** + * @param {VFile} result + */ + function resolve(result) { + callback(null, result); + } + + /** + * @param {(x: VFile) => void} resolve + * @param {(x: Error, y?: VFile) => void} reject + */ + function executor(resolve, reject) { + /** @type {string} */ + let fp; + + try { + fp = path$1.resolve(file.cwd, file.path); + } catch (error) { + return reject(error) + } + + fs.readFile(fp, options, done); + + /** + * @param {Error} error + * @param {Value} result + */ + function done(error, result) { + if (error) { + reject(error); + } else { + file.value = result; + resolve(file); + } + } + } + } + ); + +const write = + /** + * @type {{ + * (description: Compatible, options: WriteOptions, callback: Callback): void + * (description: Compatible, callback: Callback): void + * (description: Compatible, options?: WriteOptions): Promise + * }} + */ + ( + /** + * Create a virtual file and write it in, asynchronously. + * + * @param {Compatible} description + * @param {WriteOptions} [options] + * @param {Callback} [callback] + */ + function (description, options, callback) { + const file = toVFile(description); + + // Weird, right? Otherwise `fs` doesn’t accept it. + if (!callback && typeof options === 'function') { + callback = options; + options = undefined; + } + + if (!callback) { + return new Promise(executor) + } + + executor(resolve, callback); + + /** + * @param {VFile} result + */ + function resolve(result) { + callback(null, result); + } + + /** + * @param {(x: VFile) => void} resolve + * @param {(x: Error, y?: VFile) => void} reject + */ + function executor(resolve, reject) { + /** @type {string} */ + let fp; + + try { + fp = path$1.resolve(file.cwd, file.path); + } catch (error) { + return reject(error) + } + + fs.writeFile(fp, file.value || '', options, done); + + /** + * @param {Error} error + */ + function done(error) { + if (error) { + reject(error); + } else { + resolve(file); + } + } + } + } + ); + +/** + * @param {Compatible} value + * @returns {value is VFile} + */ +function looksLikeAVFile(value) { + return ( + value && + typeof value === 'object' && + 'message' in value && + 'messages' in value + ) +} + +toVFile.readSync = readSync; +toVFile.writeSync = writeSync; +toVFile.read = read; +toVFile.write = write; + +function hasFlag(flag, argv = process$1.argv) { + const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); + const position = argv.indexOf(prefix + flag); + const terminatorPosition = argv.indexOf('--'); + return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); +} + +const {env} = process$1; + +let flagForceColor; +if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false') || + hasFlag('color=never')) { + flagForceColor = 0; +} else if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + flagForceColor = 1; +} + +function envForceColor() { + if ('FORCE_COLOR' in env) { + if (env.FORCE_COLOR === 'true') { + return 1; + } + + if (env.FORCE_COLOR === 'false') { + return 0; + } + + return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3); + } +} + +function translateLevel(level) { + if (level === 0) { + return false; + } + + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 + }; +} + +function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) { + const noFlagForceColor = envForceColor(); + if (noFlagForceColor !== undefined) { + flagForceColor = noFlagForceColor; + } + + const forceColor = sniffFlags ? flagForceColor : noFlagForceColor; + + if (forceColor === 0) { + return 0; + } + + if (sniffFlags) { + if (hasFlag('color=16m') || + hasFlag('color=full') || + hasFlag('color=truecolor')) { + return 3; + } + + if (hasFlag('color=256')) { + return 2; + } + } + + if (haveStream && !streamIsTTY && forceColor === undefined) { + return 0; + } + + const min = forceColor || 0; + + if (env.TERM === 'dumb') { + return min; + } + + if (process$1.platform === 'win32') { + // Windows 10 build 10586 is the first Windows release that supports 256 colors. + // Windows 10 build 14931 is the first release that supports 16m/TrueColor. + const osRelease = os.release().split('.'); + if ( + Number(osRelease[0]) >= 10 && + Number(osRelease[2]) >= 10586 + ) { + return Number(osRelease[2]) >= 14931 ? 3 : 2; + } + + return 1; + } + + if ('CI' in env) { + if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') { + return 1; + } + + return min; + } + + if ('TEAMCITY_VERSION' in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } + + if (env.COLORTERM === 'truecolor') { + return 3; + } + + if ('TERM_PROGRAM' in env) { + const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + + switch (env.TERM_PROGRAM) { + case 'iTerm.app': + return version >= 3 ? 3 : 2; + case 'Apple_Terminal': + return 2; + // No default + } + } + + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } + + if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; + } + + if ('COLORTERM' in env) { + return 1; + } + + return min; +} + +function createSupportsColor(stream, options = {}) { + const level = _supportsColor(stream, { + streamIsTTY: stream && stream.isTTY, + ...options + }); + + return translateLevel(level); +} + +const supportsColor = { + stdout: createSupportsColor({isTTY: tty.isatty(1)}), + stderr: createSupportsColor({isTTY: tty.isatty(2)}) +}; + +function ansiRegex({onlyFirst = false} = {}) { + const pattern = [ + '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', + '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))' + ].join('|'); + + return new RegExp(pattern, onlyFirst ? undefined : 'g'); +} + +function stripAnsi(string) { + if (typeof string !== 'string') { + throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``); + } + + return string.replace(ansiRegex(), ''); +} + +/* eslint-disable yoda */ + +function isFullwidthCodePoint(codePoint) { + if (!Number.isInteger(codePoint)) { + return false; + } + + // Code points are derived from: + // https://unicode.org/Public/UNIDATA/EastAsianWidth.txt + return codePoint >= 0x1100 && ( + codePoint <= 0x115F || // Hangul Jamo + codePoint === 0x2329 || // LEFT-POINTING ANGLE BRACKET + codePoint === 0x232A || // RIGHT-POINTING ANGLE BRACKET + // CJK Radicals Supplement .. Enclosed CJK Letters and Months + (0x2E80 <= codePoint && codePoint <= 0x3247 && codePoint !== 0x303F) || + // Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A + (0x3250 <= codePoint && codePoint <= 0x4DBF) || + // CJK Unified Ideographs .. Yi Radicals + (0x4E00 <= codePoint && codePoint <= 0xA4C6) || + // Hangul Jamo Extended-A + (0xA960 <= codePoint && codePoint <= 0xA97C) || + // Hangul Syllables + (0xAC00 <= codePoint && codePoint <= 0xD7A3) || + // CJK Compatibility Ideographs + (0xF900 <= codePoint && codePoint <= 0xFAFF) || + // Vertical Forms + (0xFE10 <= codePoint && codePoint <= 0xFE19) || + // CJK Compatibility Forms .. Small Form Variants + (0xFE30 <= codePoint && codePoint <= 0xFE6B) || + // Halfwidth and Fullwidth Forms + (0xFF01 <= codePoint && codePoint <= 0xFF60) || + (0xFFE0 <= codePoint && codePoint <= 0xFFE6) || + // Kana Supplement + (0x1B000 <= codePoint && codePoint <= 0x1B001) || + // Enclosed Ideographic Supplement + (0x1F200 <= codePoint && codePoint <= 0x1F251) || + // CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane + (0x20000 <= codePoint && codePoint <= 0x3FFFD) + ); +} + +var emojiRegex = function () { + // https://mths.be/emoji + return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g; +}; + +function stringWidth(string) { + if (typeof string !== 'string' || string.length === 0) { + return 0; + } + + string = stripAnsi(string); + + if (string.length === 0) { + return 0; + } + + string = string.replace(emojiRegex(), ' '); + + let width = 0; + + for (let index = 0; index < string.length; index++) { + const codePoint = string.codePointAt(index); + + // Ignore control characters + if (codePoint <= 0x1F || (codePoint >= 0x7F && codePoint <= 0x9F)) { + continue; + } + + // Ignore combining characters + if (codePoint >= 0x300 && codePoint <= 0x36F) { + continue; + } + + // Surrogates + if (codePoint > 0xFFFF) { + index++; + } + + width += isFullwidthCodePoint(codePoint) ? 2 : 1; + } + + return width; +} + +/** + * @typedef {import('vfile').VFile} VFile + * @typedef {import('vfile-message').VFileMessage} VFileMessage + * + * @typedef Statistics + * @property {number} fatal Fatal errors (`fatal: true`) + * @property {number} warn warning errors (`fatal: false`) + * @property {number} info informational messages (`fatal: null|undefined`) + * @property {number} nonfatal warning + info + * @property {number} total nonfatal + fatal + */ + +/** + * Get stats for a file, list of files, or list of messages. + * + * @param {Array.|VFile|VFileMessage} [value] + * @returns {Statistics} + */ +function statistics(value) { + var result = {true: 0, false: 0, null: 0}; + + if (value) { + if (Array.isArray(value)) { + list(value); + } else { + one(value); + } + } + + return { + fatal: result.true, + nonfatal: result.false + result.null, + warn: result.false, + info: result.null, + total: result.true + result.false + result.null + } + + /** + * @param {Array.} value + * @returns {void} + */ + function list(value) { + var index = -1; + + while (++index < value.length) { + one(value[index]); + } + } + + /** + * @param {VFile|VFileMessage} value + * @returns {void} + */ + function one(value) { + if ('messages' in value) return list(value.messages) + + result[ + value.fatal === undefined || value.fatal === null + ? null + : Boolean(value.fatal) + ]++; + } +} + +/** + * @typedef {import('vfile').VFile} VFile + * @typedef {import('vfile-message').VFileMessage} VFileMessage + */ + +var severities = {true: 2, false: 1, null: 0, undefined: 0}; + +/** + * @template {VFile} F + * @param {F} file + * @returns {F} + */ +function sort(file) { + file.messages.sort(comparator); + return file +} + +/** + * @param {VFileMessage} a + * @param {VFileMessage} b + * @returns {number} + */ +function comparator(a, b) { + return ( + check(a, b, 'line') || + check(a, b, 'column') || + severities[b.fatal] - severities[a.fatal] || + compare(a, b, 'source') || + compare(a, b, 'ruleId') || + compare(a, b, 'reason') || + 0 + ) +} + +/** + * @param {VFileMessage} a + * @param {VFileMessage} b + * @param {string} property + * @returns {number} + */ +function check(a, b, property) { + return (a[property] || 0) - (b[property] || 0) +} + +/** + * @param {VFileMessage} a + * @param {VFileMessage} b + * @param {string} property + * @returns {number} + */ +function compare(a, b, property) { + return String(a[property] || '').localeCompare(b[property] || '') +} + +/** + * @typedef {import('vfile').VFile} VFile + * @typedef {import('vfile-message').VFileMessage} VFileMessage + * @typedef {import('vfile-statistics').Statistics} Statistics + * + * @typedef Options + * @property {boolean} [color] + * @property {boolean} [silent=false] + * @property {boolean} [quiet=false] + * @property {boolean} [verbose=false] + * @property {string} [defaultName=''] + * + * @typedef _Row + * @property {string} place + * @property {string} label + * @property {string} reason + * @property {string} ruleId + * @property {string} source + * + * @typedef _FileRow + * @property {'file'} type + * @property {VFile} file + * @property {Statistics} stats + * + * @typedef {{[x: string]: number}} _Sizes + * + * @typedef _Info + * @property {Array.<_FileRow|_Row>} rows + * @property {Statistics} stats + * @property {_Sizes} sizes + */ + +const own = {}.hasOwnProperty; + +// @ts-expect-error Types are incorrect. +const supported = supportsColor.stderr.hasBasic; + +// `log-symbols` without chalk, ignored for Windows: +/* c8 ignore next 4 */ +const chars = + process.platform === 'win32' + ? {error: '×', warning: '‼'} + : {error: '✖', warning: '⚠'}; + +const labels = { + true: 'error', + false: 'warning', + null: 'info', + undefined: 'info' +}; + +/** + * Report a file’s messages. + * + * @param {Error|VFile|Array.} [files] + * @param {Options} [options] + * @returns {string} + */ +function reporter(files, options = {}) { + /** @type {boolean|undefined} */ + let one; + + if (!files) { + return '' + } + + // Error. + if ('name' in files && 'message' in files) { + return String(files.stack || files) + } + + // One file. + if (!Array.isArray(files)) { + one = true; + files = [files]; + } + + return format(transform(files, options), one, options) +} + +/** + * @param {Array.} files + * @param {Options} options + * @returns {_Info} + */ +function transform(files, options) { + /** @type {Array.<_FileRow|_Row>} */ + const rows = []; + /** @type {Array.} */ + const all = []; + /** @type {_Sizes} */ + const sizes = {}; + let index = -1; + + while (++index < files.length) { + // @ts-expect-error it works fine. + const messages = sort({messages: [...files[index].messages]}).messages; + /** @type {Array.<_Row>} */ + const messageRows = []; + let offset = -1; + + while (++offset < messages.length) { + const message = messages[offset]; + + if (!options.silent || message.fatal) { + all.push(message); + + const row = { + place: stringifyPosition( + message.position + ? message.position.end.line && message.position.end.column + ? message.position + : message.position.start + : undefined + ), + label: labels[/** @type {keyof labels} */ (String(message.fatal))], + reason: + (message.stack || message.message) + + (options.verbose && message.note ? '\n' + message.note : ''), + ruleId: message.ruleId || '', + source: message.source || '' + }; + + /** @type {keyof row} */ + let key; + + for (key in row) { + // eslint-disable-next-line max-depth + if (own.call(row, key)) { + sizes[key] = Math.max(size(row[key]), sizes[key] || 0); + } + } + + messageRows.push(row); + } + } + + if ((!options.quiet && !options.silent) || messageRows.length > 0) { + rows.push( + {type: 'file', file: files[index], stats: statistics(messages)}, + ...messageRows + ); + } + } + + return {rows, stats: statistics(all), sizes} +} + +/** + * @param {_Info} map + * @param {boolean|undefined} one + * @param {Options} options + */ +// eslint-disable-next-line complexity +function format(map, one, options) { + /** @type {boolean} */ + const enabled = + options.color === undefined || options.color === null + ? supported + : options.color; + /** @type {Array.} */ + const lines = []; + let index = -1; + + while (++index < map.rows.length) { + const row = map.rows[index]; + + if ('type' in row) { + const stats = row.stats; + let line = row.file.history[0] || options.defaultName || ''; + + line = + one && !options.defaultName && !row.file.history[0] + ? '' + : (enabled + ? '\u001B[4m' /* Underline. */ + + (stats.fatal + ? '\u001B[31m' /* Red. */ + : stats.total + ? '\u001B[33m' /* Yellow. */ + : '\u001B[32m') /* Green. */ + + line + + '\u001B[39m\u001B[24m' + : line) + + (row.file.stored && row.file.path !== row.file.history[0] + ? ' > ' + row.file.path + : ''); + + if (!stats.total) { + line = + (line ? line + ': ' : '') + + (row.file.stored + ? enabled + ? '\u001B[33mwritten\u001B[39m' /* Yellow. */ + : 'written' + : 'no issues found'); + } + + if (line) { + if (index && !('type' in map.rows[index - 1])) { + lines.push(''); + } + + lines.push(line); + } + } else { + let reason = row.reason; + const match = /\r?\n|\r/.exec(reason); + /** @type {string} */ + let rest; + + if (match) { + rest = reason.slice(match.index); + reason = reason.slice(0, match.index); + } else { + rest = ''; + } + + lines.push( + ( + ' ' + + ' '.repeat(map.sizes.place - size(row.place)) + + row.place + + ' ' + + (enabled + ? (row.label === 'error' + ? '\u001B[31m' /* Red. */ + : '\u001B[33m') /* Yellow. */ + + row.label + + '\u001B[39m' + : row.label) + + ' '.repeat(map.sizes.label - size(row.label)) + + ' ' + + reason + + ' '.repeat(map.sizes.reason - size(reason)) + + ' ' + + row.ruleId + + ' '.repeat(map.sizes.ruleId - size(row.ruleId)) + + ' ' + + (row.source || '') + ).replace(/ +$/, '') + rest + ); + } + } + + const stats = map.stats; + + if (stats.fatal || stats.warn) { + let line = ''; + + if (stats.fatal) { + line = + (enabled + ? '\u001B[31m' /* Red. */ + chars.error + '\u001B[39m' + : chars.error) + + ' ' + + stats.fatal + + ' ' + + (labels.true + (stats.fatal === 1 ? '' : 's')); + } + + if (stats.warn) { + line = + (line ? line + ', ' : '') + + (enabled + ? '\u001B[33m' /* Yellow. */ + chars.warning + '\u001B[39m' + : chars.warning) + + ' ' + + stats.warn + + ' ' + + (labels.false + (stats.warn === 1 ? '' : 's')); + } + + if (stats.total !== stats.fatal && stats.total !== stats.warn) { + line = stats.total + ' messages (' + line + ')'; + } + + lines.push('', line); + } + + return lines.join('\n') +} + +/** + * Get the length of `value`, ignoring ANSI sequences. + * + * @param {string} value + * @returns {number} + */ +function size(value) { + const match = /\r?\n|\r/.exec(value); + return stringWidth(match ? value.slice(0, match.index) : value) +} + +const paths = process.argv.slice(2); + +const linter = unified() + .use(remarkParse) + .use(remarkGfm) + .use(remarkPresetLintNode) + .use(remarkStringify); + +paths.forEach(async (path) => { + const file = await read(path); + const result = await linter.process(file); + if (result.messages.length) { + process.exitCode = 1; + console.error(reporter(result)); + } + // TODO: allow reformatting by writing `String(result)` to the input file +}); diff --git a/tools/lint-md/lint-md.src.mjs b/tools/lint-md/lint-md.src.mjs new file mode 100644 index 00000000000000..5dfc247ca51f80 --- /dev/null +++ b/tools/lint-md/lint-md.src.mjs @@ -0,0 +1,25 @@ +import { unified } from 'unified'; +import remarkParse from 'remark-parse'; +import remarkStringify from 'remark-stringify'; +import presetLintNode from 'remark-preset-lint-node'; +import gfm from 'remark-gfm'; +import { read } from 'to-vfile'; +import { reporter } from 'vfile-reporter'; + +const paths = process.argv.slice(2); + +const linter = unified() + .use(remarkParse) + .use(gfm) + .use(presetLintNode) + .use(remarkStringify); + +paths.forEach(async (path) => { + const file = await read(path); + const result = await linter.process(file); + if (result.messages.length) { + process.exitCode = 1; + console.error(reporter(result)); + } + // TODO: allow reformatting by writing `String(result)` to the input file +}); diff --git a/tools/node-lint-md-cli-rollup/src/list-released-versions-from-changelogs.mjs b/tools/lint-md/list-released-versions-from-changelogs.mjs similarity index 92% rename from tools/node-lint-md-cli-rollup/src/list-released-versions-from-changelogs.mjs rename to tools/lint-md/list-released-versions-from-changelogs.mjs index f134e122985d85..52eb50d673e3a7 100755 --- a/tools/node-lint-md-cli-rollup/src/list-released-versions-from-changelogs.mjs +++ b/tools/lint-md/list-released-versions-from-changelogs.mjs @@ -3,7 +3,7 @@ import fs from 'node:fs'; import { createInterface } from 'node:readline'; -const dataFolder = new URL('../../../doc/changelogs/', import.meta.url); +const dataFolder = new URL('../../doc/changelogs/', import.meta.url); const result = []; async function getVersionsFromFile(file) { diff --git a/tools/node-lint-md-cli-rollup/package-lock.json b/tools/lint-md/package-lock.json similarity index 69% rename from tools/node-lint-md-cli-rollup/package-lock.json rename to tools/lint-md/package-lock.json index fd8ca9c653065a..17bdb8e0d6b812 100644 --- a/tools/node-lint-md-cli-rollup/package-lock.json +++ b/tools/lint-md/package-lock.json @@ -1,121 +1,25 @@ { - "name": "node-lint-md-cli-rollup", - "version": "2.0.2", + "name": "lint-md", + "version": "1.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "node-lint-md-cli-rollup", - "version": "2.0.2", + "name": "lint-md", + "version": "1.0.0", "dependencies": { - "markdown-extensions": "^1.1.1", - "remark": "^14.0.1", "remark-gfm": "^2.0.0", + "remark-parse": "^10.0.0", "remark-preset-lint-node": "^3.0.1", - "unified-args": "^9.0.2" + "remark-stringify": "^10.0.0", + "to-vfile": "^7.2.2", + "unified": "^10.1.0", + "vfile-reporter": "^7.0.2" }, "devDependencies": { "@rollup/plugin-commonjs": "^20.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.4", - "rollup": "^2.56.3", - "shx": "^0.3.3" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dependencies": { - "@babel/highlight": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", - "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" + "@rollup/plugin-node-resolve": "^13.0.5", + "rollup": "^2.57.0" } }, "node_modules/@rollup/plugin-commonjs": { @@ -139,22 +43,16 @@ "rollup": "^2.38.3" } }, - "node_modules/@rollup/plugin-json": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", - "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^3.0.8" - }, - "peerDependencies": { - "rollup": "^1.20.0 || ^2.0.0" - } + "node_modules/@rollup/plugin-commonjs/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true }, "node_modules/@rollup/plugin-node-resolve": { - "version": "13.0.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.4.tgz", - "integrity": "sha512-eYq4TFy40O8hjeDs+sIxEH/jc9lyuI2k9DM557WN6rO5OpnC2qXMBNj4IKH1oHrnAazL49C5p0tgP0/VpqJ+/w==", + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.5.tgz", + "integrity": "sha512-mVaw6uxtvuGx/XCI4qBQXsDZJUfyx5vp39iE0J/7Hd6wDhEbjHr6aES7Nr9yWbuE0BY+oKp6N7Bq6jX5NCGNmQ==", "dev": true, "dependencies": { "@rollup/pluginutils": "^3.1.0", @@ -188,20 +86,6 @@ "rollup": "^1.20.0||^2.0.0" } }, - "node_modules/@rollup/pluginutils/node_modules/estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", - "dev": true - }, - "node_modules/@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/debug": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", @@ -224,16 +108,6 @@ "@types/unist": "*" } }, - "node_modules/@types/is-empty": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/is-empty/-/is-empty-1.2.0.tgz", - "integrity": "sha512-brJKf2boFhUxTDxlpI7cstwiUtA2ovm38UzFTi9aZI6//ARncaV+Q5ALjCaJqXaMtdZk/oPTJnSutugsZR6h8A==" - }, - "node_modules/@types/js-yaml": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.3.tgz", - "integrity": "sha512-5t9BhoORasuF5uCPr+d5/hdB++zRFUTMIZOzbNkr+jZh3yQht4HYbRDyj9fY8n2TZT30iW9huzav73x4NikqWg==" - }, "node_modules/@types/mdast": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", @@ -248,9 +122,10 @@ "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" }, "node_modules/@types/node": { - "version": "16.7.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.13.tgz", - "integrity": "sha512-pLUPDn+YG3FYEt/pHI74HmnJOWzeR+tOIQzUx93pi9M7D8OE7PSLr97HboXwk5F+JS+TLtWuzCOW97AHjmOXXA==" + "version": "16.9.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.6.tgz", + "integrity": "sha512-YHUZhBOMTM3mjFkXVcK+WwAcYmyhe1wL4lfqNtzI0b3qAy7yuSetnM7QJazgE5PFmgVTNGiLOgRFfJMqW7XpSQ==", + "dev": true }, "node_modules/@types/parse5": { "version": "6.0.1", @@ -271,11 +146,6 @@ "resolved": "https://registry.npmjs.org/@types/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-dPWnWsf+kzIG140B8z2w3fr5D03TLWbOAFQl45xUpI3vcizeXriNR5VYkWZ+WTMsUHqZ9Xlt3hrxGNANFyNQfw==" }, - "node_modules/@types/text-table": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@types/text-table/-/text-table-0.2.2.tgz", - "integrity": "sha512-dGoI5Af7To0R2XE8wJuc6vwlavWARsCh3UKJPjWs1YEqGUqfgBI/j/4GX0yf19/DsDPPf0YAXWAp8psNeIehLg==" - }, "node_modules/@types/unist": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", @@ -292,32 +162,6 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -335,41 +179,19 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "engines": { - "node": ">=8" - } + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, "node_modules/builtin-modules": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", @@ -382,25 +204,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/builtins": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-4.0.0.tgz", - "integrity": "sha512-qC0E2Dxgou1IHhvJSLwGDSTvokbRovU5zZFuDY6oY8Y2lF3nGt5Ad8YZK7GMtqzY84Wu7pXTPeHQeHcXSXsRhw==", - "dependencies": { - "semver": "^7.0.0" - } - }, - "node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ccount": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.0.tgz", @@ -410,21 +213,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/character-entities": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.0.tgz", @@ -461,47 +249,11 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "node_modules/co": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", "integrity": "sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g=" }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, "node_modules/comma-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz", @@ -520,21 +272,8 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "engines": [ - "node >= 6.0" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "node_modules/debug": { "version": "4.3.2", @@ -566,14 +305,6 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, "node_modules/escape-string-regexp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", @@ -586,9 +317,9 @@ } }, "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", "dev": true }, "node_modules/extend": { @@ -596,62 +327,17 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, - "node_modules/fault": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.0.tgz", - "integrity": "sha512-JsDj9LFcoC+4ChII1QpXPA7YIaY8zmqPYw7h9j5n7St7a0BBKfNnwEBAUQRBx70o2q4rs+BeSNHk8Exm6xE7fQ==", - "dependencies": { - "format": "^0.2.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==" - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=", - "engines": { - "node": ">=0.4.x" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -671,6 +357,7 @@ "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -686,17 +373,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -710,11 +386,14 @@ } }, "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-5.0.1.tgz", + "integrity": "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/hast-util-from-parse5": { @@ -816,30 +495,11 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-meta-resolve": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-1.1.1.tgz", - "integrity": "sha512-JiTuIvVyPaUg11eTrNDx5bgQ/yMKMZffc7YSjvQeSMXy58DO2SQ8BtAf3xteZvmzvjYh14wnqNjL8XVeDy2o9A==", - "dependencies": { - "builtins": "^4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -848,21 +508,8 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/is-alphabetical": { "version": "2.0.0", @@ -886,22 +533,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-buffer": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", @@ -945,19 +576,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-empty": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-empty/-/is-empty-1.2.0.tgz", - "integrity": "sha1-3pu1snhzigWgsJpX4ftNSjQan2s=" - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-fullwidth-code-point": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", @@ -969,17 +587,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-hexadecimal": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.0.tgz", @@ -995,14 +602,6 @@ "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/is-plain-obj": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", @@ -1023,11 +622,6 @@ "@types/estree": "*" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -1039,65 +633,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/libnpmconfig": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/libnpmconfig/-/libnpmconfig-1.2.1.tgz", - "integrity": "sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA==", - "dependencies": { - "figgy-pudding": "^3.5.1", - "find-up": "^3.0.0", - "ini": "^1.3.5" - } - }, - "node_modules/lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" - }, - "node_modules/load-plugin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-4.0.1.tgz", - "integrity": "sha512-4kMi+mOSn/TR51pDo4tgxROHfBHXsrcyEYSGHcJ1o6TtRaP2PsRM5EwmYbj1uiLDvbfA/ohwuSWZJzqGiai8Dw==", - "dependencies": { - "import-meta-resolve": "^1.0.0", - "libnpmconfig": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/longest-streak": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.0.0.tgz", @@ -1127,14 +662,6 @@ "sourcemap-codec": "^1.4.4" } }, - "node_modules/markdown-extensions": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz", - "integrity": "sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/markdown-table": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.1.tgz", @@ -1168,15 +695,16 @@ } }, "node_modules/mdast-util-from-markdown": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.0.0.tgz", - "integrity": "sha512-uj2G60sb7z1PNOeElFwCC9b/Se/lFXuLhVKFOAY2EHz/VvgbupTQRNXPoZl7rGpXYL6BNZgcgaybrlSWbo7n/g==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.0.1.tgz", + "integrity": "sha512-KGPH5sDqbov0PWOEtElsLqLYC9tGGaOzznl6ss+rjDJP4bPe1t7T/K3oYwXPKTn+YzPUdorYirbz9pXEkapyYQ==", "dependencies": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", - "mdast-util-to-string": "^3.0.0", + "mdast-util-to-string": "^3.1.0", "micromark": "^3.0.0", "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", "micromark-util-normalize-identifier": "^1.0.0", "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.0", @@ -1270,15 +798,15 @@ } }, "node_modules/mdast-util-to-markdown": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.2.1.tgz", - "integrity": "sha512-yj0UexEfdH0Zqw9CztzC5+J6OZKgCY6K0ommn56SBlPKIV3NGqk1Wo/zw1Q0e/kHb50wmQ8O9cwbOl7vmaJjxg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.2.3.tgz", + "integrity": "sha512-040jJYtjOUdbvYAXCfPrpLJRdvMOmR33KRqlhT4r+fEbVM+jao1RMbA8RmGeRmw8RAj3vQ+HvhIaJPijvnOwCg==", "dependencies": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", "longest-streak": "^3.0.0", "mdast-util-to-string": "^3.0.0", - "parse-entities": "^3.0.0", + "micromark-util-decode-string": "^1.0.0", "unist-util-visit": "^4.0.0", "zwitch": "^2.0.0" }, @@ -1647,6 +1175,26 @@ "micromark-util-symbol": "^1.0.0" } }, + "node_modules/micromark-util-decode-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.0.0.tgz", + "integrity": "sha512-4g5UJ8P/J8wuRKUXCcB7udQuOBXpLyvBQSLSuznfBLCG+thKG6UTwFnXfHkrr/1wddprkUbPatCzxDjrJ+5zDg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "parse-entities": "^3.0.0" + } + }, "node_modules/micromark-util-encode": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.0.0.tgz", @@ -1787,6 +1335,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1794,65 +1343,20 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "dependencies": { "wrappy": "1" } }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, "node_modules/parse-entities": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-3.0.0.tgz", @@ -1870,40 +1374,16 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "engines": { - "node": ">=4" - } - }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -1918,6 +1398,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true, "engines": { "node": ">=8.6" }, @@ -1942,42 +1423,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/rehype": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/rehype/-/rehype-12.0.0.tgz", @@ -2022,21 +1467,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/remark": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/remark/-/remark-14.0.1.tgz", - "integrity": "sha512-7zLG3u8EUjOGuaAS9gUNJPD2j+SqDqAFHv2g6WMpE5CU9rZ6e3IKDM12KHZ3x+YNje+NMAuN55yx8S5msGSx7Q==", - "dependencies": { - "@types/mdast": "^3.0.0", - "remark-parse": "^10.0.0", - "remark-stringify": "^10.0.0", - "unified": "^10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/remark-gfm": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-2.0.0.tgz", @@ -2053,9 +1483,9 @@ } }, "node_modules/remark-lint": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-9.0.1.tgz", - "integrity": "sha512-q4VFsA7LEG4REJhR2P4A6CU9b4cCQL53845CX74Z4N/W0EgB9mm/GXpYzjbEqgkMPl5ctP8yp/vBYTNmjfUCtw==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-9.1.0.tgz", + "integrity": "sha512-47ZaPj1HSs17nqsu3CPg4nIhaj+XTEXJM9cpFybhyA4lzVRZiRXy43BokbEjBt0f1fhY3coQoOh16jJeGBvrJg==", "dependencies": { "@types/mdast": "^3.0.0", "remark-message-control": "^7.0.0", @@ -2067,9 +1497,9 @@ } }, "node_modules/remark-lint-blockquote-indentation": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-3.0.1.tgz", - "integrity": "sha512-CfjXeaomk3bxt1Y0Z4T/cKVoE+8lm5jw5C+jz8EieWNIziGNUlDxIAbMk1F1sO8EXc4LjkbTSq4zz8h1vOHkew==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-3.1.0.tgz", + "integrity": "sha512-BX9XhW7yjnEp7kEMasBIQnIGOeQJYLrrQSMFoBNURLjPMBslSUrABFXUZI6hwFo5fd0dF9Wv1xt9zvSbrU9B7g==", "dependencies": { "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", @@ -2085,9 +1515,9 @@ } }, "node_modules/remark-lint-checkbox-character-style": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-4.0.1.tgz", - "integrity": "sha512-f/Dvcw4tsWWv0vx4POVZXZmiytsyGMCKmPiMefz4zfy9hTwTGngp9EZhbDivHXiqd5YTUhvjYXFITEfVdxH4qA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-4.1.0.tgz", + "integrity": "sha512-wV3NN4j21XoC3l76mmbU/kSl4Yx0SK91lHTEpimx9PBbRtb0cb/YZiyE3bkNSXGoj6iWDcB2asF4U4rRcT5t5A==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2101,9 +1531,9 @@ } }, "node_modules/remark-lint-checkbox-content-indent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-4.0.1.tgz", - "integrity": "sha512-uv4qIBdIxGshQ1a84a2RClbX39lYfWgPm3Wg35EJbSWPpe+KWt4rYi9nxB51dIEUXw3KAujlOVougPwhAZROuA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-4.1.0.tgz", + "integrity": "sha512-K2R9V1C/ezs2SfLsh5SdXlOuJVWaUwA2LsbjIp+jcd+Dt8otJ4Rul741ypL4Sji/vaxrQi5f4+iLYpfrUtjfDQ==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2118,9 +1548,9 @@ } }, "node_modules/remark-lint-code-block-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-3.0.1.tgz", - "integrity": "sha512-B6338x1UggrAMe4gdmk1No2L/OkK1d1uCelekj6cnl+Pi5/HLlSw3lXIaOTRNIXOccT1zMmNApA4sDZ5qsQWtw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-3.1.0.tgz", + "integrity": "sha512-Hv4YQ8ueLGpjItla4CkcOkcfGj+nlquqylDgCm1/xKnW+Ke2a4qVTMVJrP9Krp4FWmXgktJLDHjhRH+pzhDXLg==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2135,9 +1565,9 @@ } }, "node_modules/remark-lint-definition-spacing": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-3.0.1.tgz", - "integrity": "sha512-jtCUaZ+6KP4nNutBoiWoqBfa2sMsD4uvvFbuU5MOlzI0wlMmaeAq1pxWuNtkK+w8AEk/8CzfCUrLct5w65KSLQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-3.1.0.tgz", + "integrity": "sha512-cJlT3+tjTTA3mv3k2ogdOELSdbkpGKDNZ1qwba0ReSCdNCVbxcejZ/rrU96n/guv34XgqFyDrzoc7kcxU8oyEg==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2151,9 +1581,9 @@ } }, "node_modules/remark-lint-fenced-code-flag": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-3.0.1.tgz", - "integrity": "sha512-HsEhvalGxCauZO6OAnaVzIBycfaHLuyZxy1KlniWXQJKZ6EjRAsWwkZHYx9qfPl/ZW7zDG+xAoWTqdHjZW/BTg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-3.1.0.tgz", + "integrity": "sha512-s96DWERWUeDi3kcDbW6TQo4vRUsGJUNhT1XEsmUzYlwJJ+2uGit9O5dAxvEnwF3gZxp/09hPsQ+QSxilC1sxLg==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2168,9 +1598,9 @@ } }, "node_modules/remark-lint-fenced-code-marker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-3.0.1.tgz", - "integrity": "sha512-vFRjlzyxtG3zdvmlTn6cV1YiZAivQwOzYRNnH5KavC39EZHDxqjQl84QTXshgfCzFupvYCi6ykATIa7obgx9jg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-3.1.0.tgz", + "integrity": "sha512-klvbiQBINePA51Icprq7biFCyZzbtsASwOa6WCzW/KpAFz2V9a57PTuZkO9MtdDhW0vLoHgsQ4b0P1MD7JHMEw==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2184,9 +1614,9 @@ } }, "node_modules/remark-lint-file-extension": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-2.0.1.tgz", - "integrity": "sha512-A2N6XoLPbYyRhgXyTI7WlW9Nb9QvXQNXG514hjHdNNd0cL+5P4JU6vivgZiYfViCzOLgsys6hwhXBSC9ZQ45tw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-2.1.0.tgz", + "integrity": "sha512-3T2n5/FsQ2CcDDubO5F8h7a/GyzTCy+R9XF8L9L9dVuZoxl4AWr1J6AmxE02bTy4g/TMH90juLELT08WGR6D9Q==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2198,9 +1628,9 @@ } }, "node_modules/remark-lint-final-definition": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-3.0.1.tgz", - "integrity": "sha512-bzha13GTKFnQ0h4ZvaHadK6HxM2eRJj/yj59aXyvJkHFNx7i0sQn1884t3yYM4ppdDmO+cCMMgsVo8DxE8ifFA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-3.1.0.tgz", + "integrity": "sha512-XUbCNX7EFc/f8PvdQeXl2d5eu2Nksb2dCxIri+QvL/ykQ0MluXTNUfVsasDfNp9OYFBbTuBf27WiffOTOwOHRw==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2215,9 +1645,9 @@ } }, "node_modules/remark-lint-final-newline": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-2.0.1.tgz", - "integrity": "sha512-vv1LT36frgc0FVc7V52CdOxqh1TqGcNvAVD89935sb9wpEELiUfbGG1Xb9PVZoIaVQcFo8qEDWCvfhsKTKk8Nw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-2.1.0.tgz", + "integrity": "sha512-jD9zIfk+DYAhho7mGkNtT4+3Bn6eiOVYzEJUUqNZp1GMtCY69gyVCK7Oef3S2Z6xLJUlZvC2vZmezhn0URUl7w==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2229,9 +1659,9 @@ } }, "node_modules/remark-lint-first-heading-level": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-first-heading-level/-/remark-lint-first-heading-level-3.0.1.tgz", - "integrity": "sha512-3ym0v/aMFpHTGv2/DPln6NHB2DFnx6Nbd+3Z9kf6wfnJCzXNA3zXyCKt11i5MPzUV5wlwButcW+JkPDtDJsfog==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-first-heading-level/-/remark-lint-first-heading-level-3.1.0.tgz", + "integrity": "sha512-8OV6BEjB5JSUCQRNk+z8MFyqu5Cdtk7TCR6Y6slC4b8vYlj26VecG5Fo4nLXdSj9/Tx01z59Od2FzBRV+6A1Xg==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2245,9 +1675,9 @@ } }, "node_modules/remark-lint-hard-break-spaces": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-3.0.1.tgz", - "integrity": "sha512-CPjbfc9DcV4Qy3d8jyhh/QXsLD5uRtweb0d04p2MyzMDrqwXAq5X4MW3rId3JbVVl7o1AKXq1FdvqIMrh9Rpuw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-3.1.0.tgz", + "integrity": "sha512-0nUJpsH0ibYtsxv3QS29C3axzyVZBz6RD28XWmelcuCfApWluDlW4pM8r0qa1lE1UrLVd3MocKpa4i1AKbkcsg==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2262,9 +1692,9 @@ } }, "node_modules/remark-lint-heading-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-3.0.1.tgz", - "integrity": "sha512-/9rsTE+coYdUgT/spxg4ioorG2W5XdabLHajKjTOOQ4ME8Wa5fXHMJ3WpK3Vnz8ZKP7WQwTTPsKWIHcy5d6C+w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-3.1.0.tgz", + "integrity": "sha512-wQliHPDoK+YwMcuD3kxw6wudlXhYW5OUz0+z5sFIpg06vx7OfJEASo6d6G1zYG+KkEesZx1SP0SoyHV4urKYmg==", "dependencies": { "@types/mdast": "^3.0.0", "mdast-util-heading-style": "^2.0.0", @@ -2279,9 +1709,9 @@ } }, "node_modules/remark-lint-list-item-bullet-indent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-4.0.1.tgz", - "integrity": "sha512-7XjtSLUwvxHi28/q9XMzYy7A+agpArvLlTksD0r1jj5MpGYTSUW9b54rRRV3JxHJMoX+ZJ9juId6GmVaUZwsTg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-4.1.0.tgz", + "integrity": "sha512-KmVTNeaTXkAzm21wLv0GKYXMDU5EwlBncGNb9z4fyQx/mAsX+KWVw71b6+zdeai+hAF8ErENaN48DgLxQ/Z3Ug==", "dependencies": { "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", @@ -2295,9 +1725,9 @@ } }, "node_modules/remark-lint-list-item-indent": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-3.0.1.tgz", - "integrity": "sha512-5/H5B2g6TTpJZiwMmBa/Drexwq5Dw50QoypTUgXwFETz91s7zvjy+IGGVoVv0L0LM0rCwblmgtLomqeWIyo9sA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-3.1.0.tgz", + "integrity": "sha512-+dTStrxiMz9beP+oe48ItMUHzIpMOivBs1+FU44o1AT6mExDGvDdt4jMtLCpPrZVFbzzIS00kf5FEDLqjNiaHg==", "dependencies": { "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", @@ -2313,9 +1743,9 @@ } }, "node_modules/remark-lint-maximum-line-length": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-3.0.1.tgz", - "integrity": "sha512-R4hiRRx46xa3NE/AY8IKzPTRVyq1ZWrtWVd2KfWwNHmj7a6ASjb75DPzGyckZ46UAQq9mSBPsgL5Rfhq5XmggA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-3.1.0.tgz", + "integrity": "sha512-EfXXQsrmdyoMdzlZ0yDjSPeEHv+os444SsTvrwPwrJWxj39fudakweM3xAk2NgDJc7UrcCZzKH+4yNDmL0NcvQ==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2330,9 +1760,9 @@ } }, "node_modules/remark-lint-no-auto-link-without-protocol": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-3.0.1.tgz", - "integrity": "sha512-FdbB9O4SegELBreglpOXhMyusKORPS0X7KrBY/V+tDo4+2sJHMEEdiN4RbK2ofWwRP7V+muZ5WrscLliuAExQg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-3.1.0.tgz", + "integrity": "sha512-GqZXDu/xfajWCEPhS8UjO9dYMTlY5lD8ShoYIaouUgz3nNQvLwX33pTKqfRpd/R9EmV1uQw0PCJ6TYwhBrnOXQ==", "dependencies": { "@types/mdast": "^3.0.0", "mdast-util-to-string": "^3.0.0", @@ -2348,9 +1778,9 @@ } }, "node_modules/remark-lint-no-blockquote-without-marker": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-5.0.1.tgz", - "integrity": "sha512-3aUFCV1BSqO15MuJ6fQept36An/vLo9VgAj1TRWk4Gsnaewbq7haT/m6eiYn5Ia8t2sSBbv4LKz1lwnj5nOVPQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-5.1.0.tgz", + "integrity": "sha512-t9ohZSpHIZdlCp+h2nemFD/sM3Am6ZZEczaBpmTQn+OoKrZjpDRrMTb/60OBGXJXHNazfqRwm96unvM4qDs4+Q==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2366,9 +1796,9 @@ } }, "node_modules/remark-lint-no-consecutive-blank-lines": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-4.0.1.tgz", - "integrity": "sha512-nvwglXFdR8ubTjSduK3cVdgBaKCH/DqV0kVkCKSQmLEl8NyozFH03VB/bhQDCrmSeNt6rYClBF0ppaHT27OmpA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-4.1.0.tgz", + "integrity": "sha512-4gn7lPXAw9hw08apENVNvWjdtuNtgtHPA0mjqgjTszXC92IY1YW8zGfxChCLvCJ1bG4/isI6Ctx+ZmmQoZEW1Q==", "dependencies": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", @@ -2385,9 +1815,9 @@ } }, "node_modules/remark-lint-no-duplicate-definitions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-3.0.1.tgz", - "integrity": "sha512-gwQe65dW2fkMQR02hwlHtc0OOvshst+gXMOEwd1/fpIb6OORpMiK6ueoNBxCnKSsKqftjWV0JXVdZ7MfKKxQQw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-3.1.0.tgz", + "integrity": "sha512-kBBKK/btn6p0yOiVhB6mnasem7+RUCRjifoe58y/Um56qQsh1GtX6YHVNnboO7fp9aq46MKC2Yc93pEj5yEbDg==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2403,9 +1833,9 @@ } }, "node_modules/remark-lint-no-file-name-articles": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-2.0.1.tgz", - "integrity": "sha512-9kZ/ydzJlntswJjsQEbPPx0tc6uAPuowmG/3aOCSE+6CjJ+bCQZiVLL3VhjktNyzFxDGTDN6LlbVwiyIHEUMwA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-2.1.0.tgz", + "integrity": "sha512-+4gembcykiLnrsTxk4ld2fg3n3TgvHGBO6qMsRmjh5k2m2riwnewM80xfCGXrEVi5cciGIhmv4iU7uicp+WEVQ==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2417,9 +1847,9 @@ } }, "node_modules/remark-lint-no-file-name-consecutive-dashes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-2.0.1.tgz", - "integrity": "sha512-e9ei9KwQSRzUQeYHEhCKUMDeavFOIj46NtuyZxYtrklOcblvaZLAV133UcFHk5CimdUj3dzTtFZebHdpvu5omw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-2.1.0.tgz", + "integrity": "sha512-jnQcsYaV8OkUMmFcXr/RWkJFKw30lqEtYTfmb9n/AUsBFeQt53cYYZjA+6AgvKSUW3be7CY2XptReTuM4jSHpQ==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2431,9 +1861,9 @@ } }, "node_modules/remark-lint-no-file-name-outer-dashes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-2.0.1.tgz", - "integrity": "sha512-INp+0gW5T2j6+sHglmDmCLL7/goVKCryXyf+ZApB5oWYBpVr2fLnHEHTUmkbQkksxe7me+VsB+WW/KN1PXGrtw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-2.1.0.tgz", + "integrity": "sha512-R0eXcFpsfjXI4djN/AF734kydS+p5frZW6NsUzpEfLt5Eu/MhOuii2LvV/G1ujyclZAELpvZlV+sW4083SHi3g==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2445,9 +1875,9 @@ } }, "node_modules/remark-lint-no-heading-content-indent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-4.0.1.tgz", - "integrity": "sha512-IRYlydfT0Xt4AEs5OKSBGP9hLNDckd1mKcV8crnNu91HhcmFVJznzsLV1QrUTTI94cwkSmSWqpjNzsDrKGPbIw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-4.1.0.tgz", + "integrity": "sha512-+V92BV7r4Ajc8/oe5DhHeMrn3pZHIoLyqLYM6YgkW2hPMn+eCLVAcrfdOiiVrBpgUNpZMIM9x7UwOq0O4hAr8A==", "dependencies": { "@types/mdast": "^3.0.0", "mdast-util-heading-style": "^2.0.0", @@ -2464,9 +1894,9 @@ } }, "node_modules/remark-lint-no-heading-indent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-4.0.1.tgz", - "integrity": "sha512-LjRsRJOPT1M5MwvGxGEPIHzB713chWgJF5v/FNaHnniLgBrwIbpmsqEhAAam/+i593B5tx84ZyaCf8ujXTP0gg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-4.1.0.tgz", + "integrity": "sha512-hy9W3YoHWR1AbsOAbhZDwzJAKmdLekmKhc5iC9VfEWVfXsSNHwjAoct4mrBNMEUcfFYhcOTKfyrIXwy1D7fXaw==", "dependencies": { "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", @@ -2482,9 +1912,9 @@ } }, "node_modules/remark-lint-no-inline-padding": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-4.0.1.tgz", - "integrity": "sha512-UcjJ2XTf7kOmQo5mU/5AV+Gth1YYGcp+gYU4gS/CzdOLYstqsS/W+IN6ALJjEbdbtSyfWCElpxI4p/mW16Z90A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-4.1.0.tgz", + "integrity": "sha512-0dbIgBUhVIkIn8xji2b/j1tG+ETbzE+ZEYNtCRTsNCjFwvyvgzElWKMLHoLzTpXYAN8I5dQhyFcy8Qa/RXg3AA==", "dependencies": { "@types/mdast": "^3.0.0", "mdast-util-to-string": "^3.0.0", @@ -2499,9 +1929,9 @@ } }, "node_modules/remark-lint-no-literal-urls": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-3.0.1.tgz", - "integrity": "sha512-3OAFcaZawfrFgZGrpuZlNPyuvfIURtUzDN7/Bl2X42ivqx4ih1OH9LtiBgz+J0g1DEWnC5ebOmDr7x6XLM76Fw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-3.1.0.tgz", + "integrity": "sha512-FvSE16bvwMLh89kZzvyXnWh8MZ2WU+msSqfbF3pU/0YpnpxfRev9ShFRS1k8wVm5BdzSqhwplv4chLnAWg53yw==", "dependencies": { "@types/mdast": "^3.0.0", "mdast-util-to-string": "^3.0.0", @@ -2517,9 +1947,9 @@ } }, "node_modules/remark-lint-no-multiple-toplevel-headings": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-3.0.1.tgz", - "integrity": "sha512-K62PKOOanFiFM4R0oHlo1PKWJa0dPPasQl28yzk6G2xZzqc5eJm5S3d0grU479jqEUbDQMaDQw282hO6WR/MbA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-3.1.0.tgz", + "integrity": "sha512-F4z867UaYjWdWFzR4ZpPi+EIzoUcU/QtdEVftdVKNdBEy1pq2A/vdTUa/PGtc+LLeQn04mJ/SGPC2s7eMWAZfg==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2535,9 +1965,9 @@ } }, "node_modules/remark-lint-no-shell-dollars": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-3.0.1.tgz", - "integrity": "sha512-QvnA8Ltj3FPaAqUu0DebKYv66LFndTk0fXVZ9rQWOjTEVIKImy9Dy59kVqwYMpCwZbJkpigu2bMl/7UG/BA0XA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-3.1.0.tgz", + "integrity": "sha512-f4+NPey3yzd9TpDka5Bs3W+MMJBPz6bQ7zK3M9Qc133lqZ81hKMGVRrOBafS1RNqD5htLZbbGyCoJa476QtW1w==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2551,9 +1981,9 @@ } }, "node_modules/remark-lint-no-shortcut-reference-image": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-3.0.1.tgz", - "integrity": "sha512-0o0YO88Atib0eWloy5ZbL2IZ1axMNysbJI5j58sxMjEwLq1JORtGOR9Z6aHsOccS5yseeenw5w3DoMLB9PtJtw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-3.1.0.tgz", + "integrity": "sha512-uTXysJw749c42QnFt+DfG5NJTjfcQdM5gYGLugb/vgUwN8dzPu6DiGM3ih1Erwha6qEseV00FpFvDexHbQvJNw==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2567,9 +1997,9 @@ } }, "node_modules/remark-lint-no-shortcut-reference-link": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-3.0.1.tgz", - "integrity": "sha512-uXujnVm5LXLtGyJkTIbn/uxDRu507B9vC8TieiX6HX8OjVeDWUjtcVJOaqeyLJGjV0Ri1Y+AegMNWx5eDBHTDQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-3.1.0.tgz", + "integrity": "sha512-SmM/sICFnlMx4PcuXIMJmyqTyI1+FQMOGh51GmLDWoyjbblP2hXD4UqrYLhAeV0aPQSNKwMXNNW0aysjdoWL0A==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2583,9 +2013,9 @@ } }, "node_modules/remark-lint-no-table-indentation": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-4.0.1.tgz", - "integrity": "sha512-GYBX5P1Vj0gO7S7JLU2tpYR5rg9xbeccPQ0ZgHYK4d7T9FjDwfE1hrdvlha3k8s3CFKqQ7MC0OgQw/2IN413MA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-4.1.0.tgz", + "integrity": "sha512-OJg95FHBZKyEUlnmHyMQ2j9qs5dnxk3oX1TQuREpFDgzQMh/Bcyc+CegmsDMDiyNyrs1QgDwubCWmAYWgdy4Gw==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2600,9 +2030,9 @@ } }, "node_modules/remark-lint-no-tabs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-tabs/-/remark-lint-no-tabs-3.0.1.tgz", - "integrity": "sha512-B2q1I+fyRDvWTQxCC91NoEvz0KzI9e6Yhu1TdOLkwc02hMWj869G165Rh+EcBKGW/CLKuMPhIn2XtL86emqZRw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-tabs/-/remark-lint-no-tabs-3.1.0.tgz", + "integrity": "sha512-QjMDKdwoKtZyvqHvRQS6Wwy/sy2KwLGbjGJumGXhzYS6fU7r/EimYcCbNb0NgxJhs3sLhWKZB9m/W0hH6LYbnA==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2635,9 +2065,9 @@ } }, "node_modules/remark-lint-no-undefined-references": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-4.0.1.tgz", - "integrity": "sha512-mmNJO30TYMxwfFJPHkwKNRaW63sU9ffhpb4xkyhyHDmnsplQ96RVYR4WGOXw0/wR+gZECmFtBU+OIWz0cbaiEw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-4.1.0.tgz", + "integrity": "sha512-xnBd6ZLWv9Lnf1dH6bC/IYywbzxloUNJwiJY2OzhtZUMsqH8Xw5ZAidhxIW3k+3K8Fs2WSwp7HjIzjp7ZSiuDA==", "dependencies": { "@types/mdast": "^3.0.0", "micromark-util-normalize-identifier": "^1.0.0", @@ -2654,9 +2084,9 @@ } }, "node_modules/remark-lint-no-unused-definitions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-3.0.1.tgz", - "integrity": "sha512-bcbboInyb8vAPtYakZdaxRQsDIdQnV5WvUdc03PWFlG8YtGOhRQ57SPc+4uVH+VwHoq+lsEsRszr4sOXuuopxw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-3.1.0.tgz", + "integrity": "sha512-poSmPeY5wZYLXhiUV+rbrkWNNENjoUq2lUb/Ho34zorMeV70FNBEV+zv1A6Ri8+jplUDeLi1lqC0uBTlTAUuLQ==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2670,9 +2100,9 @@ } }, "node_modules/remark-lint-ordered-list-marker-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-3.0.1.tgz", - "integrity": "sha512-CGXvolLwfZIxG9hm4o7OXQXEEpu3r5oyTpYGteJDtOSrpVrBSqFKNq7lfhKYFQkcg2AMJYrH9XEexrYvAoUQOQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-3.1.0.tgz", + "integrity": "sha512-/sYOjCK+FkAhwheIHjL65TxQKJ8infTVsDi5Dbl6XHaXiAzKjvZhwW4uJqgduufozlriI63DF68YMv5y6tyXsw==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2699,9 +2129,9 @@ } }, "node_modules/remark-lint-rule-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-3.0.1.tgz", - "integrity": "sha512-j1e60nfZJk0C6mvDZkiFwVu0b58f219ATlMNaZ9h8QdQhdxD/0kUnizJ7xW3wS4sHtCgkKGctAp04Ma0c+Dkhg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-3.1.0.tgz", + "integrity": "sha512-Z2tW9kBNCdD8l+kG7bTKanfciqGGJt8HnBmV9eE3oIqVDzqWJoIQ8kVBDGh6efeOAlWDDDHGIp/jb4i/CJ/kvg==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2715,9 +2145,9 @@ } }, "node_modules/remark-lint-strong-marker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-3.0.1.tgz", - "integrity": "sha512-J5dJviBd747vXBkFuA2j/Ni7RjTg+Mg2GgXlPHtbgDnal51CdN2WXDmbVG/A98+3P18MlysvQ7KnBrSiiuGBpQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-3.1.0.tgz", + "integrity": "sha512-YkGZ2J1vayVa/uSWUOuqKzB3ot1RgtsAd/Kz7L2ve8lDDIjnxn+bUufaS6cN9K5/ADprryd1hdE29YRVj6Vs3g==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2731,9 +2161,9 @@ } }, "node_modules/remark-lint-table-cell-padding": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-4.0.1.tgz", - "integrity": "sha512-NdF0WHFOaMjeumRIrGHXVadwWkgnfJuMb96FGbf1HvSEv9l41PHkS1KTsL6Zoe1Cva57niAuarMv6xzcJqVjrA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-4.1.0.tgz", + "integrity": "sha512-2FqYGR6IsO5HdmvBe15iwD8XI9xjyMBegKuJWK50bWAsIVdR1b80nfXxKDQ6lRDK6LZ7+iATxzTo0Fl3+TLmgw==", "dependencies": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", @@ -2748,9 +2178,9 @@ } }, "node_modules/remark-lint-table-pipes": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-4.0.1.tgz", - "integrity": "sha512-om6i8SMSjMsR/mYlx5cMSoxXK+EFI8/n73qCVx/RAhFCIsW4TFR+gYmgFTyLr5Mp4vqjV3uYBIR9Ucv6Johauw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-4.1.0.tgz", + "integrity": "sha512-kI50VXlEW9zUdMh8Y9T7vornqpnMr+Ywy+sUzEuhhmWeFIYcIsBbZTHA1253FgjA/iMkLPzByYWj1xGlUGL1jw==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2764,9 +2194,9 @@ } }, "node_modules/remark-lint-unordered-list-marker-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-3.0.1.tgz", - "integrity": "sha512-DPveL2hhkcY608Bkn/Hx+C7pxviufpYyRiu0CnfFxkbLBlMgVdvVIOGCCOlhbvKuGtozmH/RCRsdIfzjlkXiew==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-3.1.0.tgz", + "integrity": "sha512-oUThfe8/34DpXkGjOghOkSOqk8tGthnDNIMBtNVY+aMIkkuvCSxqFj9D/R37Al7/tqqgZ1D6ezpwxIOsa15JTA==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2812,9 +2242,9 @@ } }, "node_modules/remark-preset-lint-node": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-preset-lint-node/-/remark-preset-lint-node-3.0.1.tgz", - "integrity": "sha512-L7yhho9q9vmpsfMHO2gRKFNj36106iFM4KpodE+3k3rGg5dcmhV+zcsftNh5NGzbKKKYsGQj9C5XxCR/0NwKDg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-preset-lint-node/-/remark-preset-lint-node-3.1.0.tgz", + "integrity": "sha512-jWEl5ljKYmIiM2cnZbp7dIYmpFND33RWOCcm5cbp8m2GbOLMOaAW2cVBZe47XLAzpQcOIKaT2BjSsi7Y1h/cig==", "dependencies": { "js-yaml": "^4.0.0", "remark-lint-blockquote-indentation": "^3.0.0", @@ -2856,9 +2286,9 @@ } }, "node_modules/remark-preset-lint-recommended": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-6.0.1.tgz", - "integrity": "sha512-8ZlwP2aDCGf+3UFPP1K8CofWI/WLoq8hPhQiuKotCFNSdTe98/27XYqWXpbMt4feWtX4+tcJY1y0duuLK5lhBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-6.1.0.tgz", + "integrity": "sha512-1jUbuzRAP5idWu9GZ5x7M96Z1TcTWwJu0C8ziz5RLezWL9rChhw9kV6s0beR0lrY5Kl5E5pjA6SKaP7NyGi2ug==", "dependencies": { "@types/mdast": "^3.0.0", "remark-lint": "^9.0.0", @@ -2912,9 +2342,9 @@ } }, "node_modules/rollup": { - "version": "2.56.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.56.3.tgz", - "integrity": "sha512-Au92NuznFklgQCUcV96iXlxUbHuB1vQMaH76DHl5M11TotjOHwqk9CwcrT78+Tnv4FN9uTBxq6p4EJoYkpyekg==", + "version": "2.57.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.57.0.tgz", + "integrity": "sha512-bKQIh1rWKofRee6mv8SrF2HdP6pea5QkwBZSMImJysFj39gQuiV8MEPBjXOCpzk3wSYp63M2v2wkWBmFC8O/rg==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -2926,25 +2356,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -2959,39 +2370,6 @@ "node": ">=10" } }, - "node_modules/shelljs": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", - "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", - "dev": true, - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/shx": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.3.tgz", - "integrity": "sha512-nZJ3HFWVoTSyyB+evEKjJ1STiixGztlqwKLTUNV5KqMWtGey9fTd4KU1gdZ1X9BV6215pswQ/Jew9NsuS/fNDA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.3", - "shelljs": "^0.8.4" - }, - "bin": { - "shx": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/sliced": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", @@ -3012,22 +2390,14 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string-width": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.0.0.tgz", - "integrity": "sha512-zwXcRmLUdiWhMPrHz6EXITuyTgcEnUqDzspTkCLhQovxywWz6NP9VHgqfVg20V/1mUg0B95AKbXxNT+ALRmqCw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.0.1.tgz", + "integrity": "sha512-5ohWO/M4//8lErlUUtrFy3b11GtNOuMOU0ysKCDXFcfXuuvUXu95akgj/i8ofmaGdN0hCqyl6uu9i8dS/mQp5g==", "dependencies": { "emoji-regex": "^9.2.2", "is-fullwidth-code-point": "^4.0.0", - "strip-ansi": "^7.0.0" + "strip-ansi": "^7.0.1" }, "engines": { "node": ">=12" @@ -3050,11 +2420,11 @@ } }, "node_modules/strip-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.0.tgz", - "integrity": "sha512-UhDTSnGF1dc0DRbUqr1aXwNoY3RgVkSWG8BrpnuFIxhP57IqbS7IRta2Gfiavds4yCxc5+fEAVVOgBZWnYkvzg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", "dependencies": { - "ansi-regex": "^6.0.0" + "ansi-regex": "^6.0.1" }, "engines": { "node": ">=12" @@ -3064,30 +2434,17 @@ } }, "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.0.2.tgz", + "integrity": "sha512-ii6tc8ImGFrgMPYq7RVAMKkhPo9vk8uA+D3oKbJq/3Pk2YSMv1+9dUAesa9UxMbxBTvxwKTQffBahNVNxEvM8Q==", "dependencies": { - "has-flag": "^4.0.0" + "has-flag": "^5.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "^7.0.0" + "node": ">=12" }, - "engines": { - "node": ">=8.0" + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/to-vfile": { @@ -3112,11 +2469,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, "node_modules/unified": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", @@ -3135,64 +2487,10 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unified-args": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/unified-args/-/unified-args-9.0.2.tgz", - "integrity": "sha512-qSqryjoqfJSII4E4Z2Jx7MhXX2MuUIn6DsrlmL8UnWFdGtrWvEtvm7Rx5fKT5TPUz7q/Fb4oxwIHLCttvAuRLQ==", - "dependencies": { - "@types/text-table": "^0.2.0", - "camelcase": "^6.0.0", - "chalk": "^4.0.0", - "chokidar": "^3.0.0", - "fault": "^2.0.0", - "json5": "^2.0.0", - "minimist": "^1.0.0", - "text-table": "^0.2.0", - "unified-engine": "^9.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unified-engine": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/unified-engine/-/unified-engine-9.0.4.tgz", - "integrity": "sha512-NFI+jC3DWZ23eBsWkOW2havz47DPG/DSyJEvBH+qA5cQHF6zlgiJYev7ksb/naOypZZ+cfhaCxCRo2BqrysYEw==", - "dependencies": { - "@types/concat-stream": "^1.0.0", - "@types/debug": "^4.0.0", - "@types/is-empty": "^1.0.0", - "@types/js-yaml": "^4.0.0", - "@types/node": "^16.0.0", - "@types/unist": "^2.0.0", - "concat-stream": "^2.0.0", - "debug": "^4.0.0", - "fault": "^2.0.0", - "glob": "^7.0.0", - "ignore": "^5.0.0", - "is-buffer": "^2.0.0", - "is-empty": "^1.0.0", - "is-plain-obj": "^4.0.0", - "js-yaml": "^4.0.0", - "load-plugin": "^4.0.0", - "parse-json": "^5.0.0", - "to-vfile": "^7.0.0", - "trough": "^2.0.0", - "unist-util-inspect": "^7.0.0", - "vfile-message": "^3.0.0", - "vfile-reporter": "^7.0.0", - "vfile-statistics": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/unified-lint-rule": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.1.tgz", - "integrity": "sha512-2RzZuuuWW+ifftM0zd/ZEng0Hb5lah+Zi+ZL/ybj8BrLO/TH2aQAMYvG+iC95aCg2FkWu/pcvVvHqsh2UMmzPg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.1.0.tgz", + "integrity": "sha512-pB2Uht3w+A9ceWXMYI0YWwxCTqC5on6jrApWDWSsYDBjaljSv8s64qdHHMCXFIUAGdd6V/XWrVMxiboHOAXo3Q==", "dependencies": { "@types/unist": "^2.0.0", "trough": "^2.0.0", @@ -3244,18 +2542,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-inspect": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/unist-util-inspect/-/unist-util-inspect-7.0.0.tgz", - "integrity": "sha512-2Utgv78I7PUu461Y9cdo+IUiiKSKpDV5CE/XD6vTj849a3xlpDAScvSJ6cQmtFBGgAmCn2wR7jLuXhpg1XLlJw==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/unist-util-is": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", @@ -3314,9 +2600,9 @@ } }, "node_modules/unist-util-visit/node_modules/unist-util-visit-parents": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", - "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.0.tgz", + "integrity": "sha512-y+QVLcY5eR/YVpqDsLf/xh9R3Q2Y4HxkZTp7ViLDU6WtJCEcPmRzW1gpdWDCDIqIlhuPDXOgttqPlykrHYDekg==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0" @@ -3326,11 +2612,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, "node_modules/vfile": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.1.0.tgz", @@ -3389,31 +2670,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-reporter/node_modules/has-flag": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-5.0.1.tgz", - "integrity": "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vfile-reporter/node_modules/supports-color": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.0.2.tgz", - "integrity": "sha512-ii6tc8ImGFrgMPYq7RVAMKkhPo9vk8uA+D3oKbJq/3Pk2YSMv1+9dUAesa9UxMbxBTvxwKTQffBahNVNxEvM8Q==", - "dependencies": { - "has-flag": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/vfile-sort": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-3.0.0.tgz", @@ -3459,7 +2715,8 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "node_modules/yallist": { "version": "4.0.0", @@ -3477,80 +2734,6 @@ } }, "dependencies": { - "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", - "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==" - }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, "@rollup/plugin-commonjs": { "version": "20.0.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-20.0.0.tgz", @@ -3564,21 +2747,20 @@ "is-reference": "^1.2.1", "magic-string": "^0.25.7", "resolve": "^1.17.0" - } - }, - "@rollup/plugin-json": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", - "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^3.0.8" + }, + "dependencies": { + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + } } }, "@rollup/plugin-node-resolve": { - "version": "13.0.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.4.tgz", - "integrity": "sha512-eYq4TFy40O8hjeDs+sIxEH/jc9lyuI2k9DM557WN6rO5OpnC2qXMBNj4IKH1oHrnAazL49C5p0tgP0/VpqJ+/w==", + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.5.tgz", + "integrity": "sha512-mVaw6uxtvuGx/XCI4qBQXsDZJUfyx5vp39iE0J/7Hd6wDhEbjHr6aES7Nr9yWbuE0BY+oKp6N7Bq6jX5NCGNmQ==", "dev": true, "requires": { "@rollup/pluginutils": "^3.1.0", @@ -3598,22 +2780,6 @@ "@types/estree": "0.0.39", "estree-walker": "^1.0.1", "picomatch": "^2.2.2" - }, - "dependencies": { - "estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", - "dev": true - } - } - }, - "@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "requires": { - "@types/node": "*" } }, "@types/debug": { @@ -3638,16 +2804,6 @@ "@types/unist": "*" } }, - "@types/is-empty": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/is-empty/-/is-empty-1.2.0.tgz", - "integrity": "sha512-brJKf2boFhUxTDxlpI7cstwiUtA2ovm38UzFTi9aZI6//ARncaV+Q5ALjCaJqXaMtdZk/oPTJnSutugsZR6h8A==" - }, - "@types/js-yaml": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.3.tgz", - "integrity": "sha512-5t9BhoORasuF5uCPr+d5/hdB++zRFUTMIZOzbNkr+jZh3yQht4HYbRDyj9fY8n2TZT30iW9huzav73x4NikqWg==" - }, "@types/mdast": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", @@ -3662,9 +2818,10 @@ "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" }, "@types/node": { - "version": "16.7.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.13.tgz", - "integrity": "sha512-pLUPDn+YG3FYEt/pHI74HmnJOWzeR+tOIQzUx93pi9M7D8OE7PSLr97HboXwk5F+JS+TLtWuzCOW97AHjmOXXA==" + "version": "16.9.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.6.tgz", + "integrity": "sha512-YHUZhBOMTM3mjFkXVcK+WwAcYmyhe1wL4lfqNtzI0b3qAy7yuSetnM7QJazgE5PFmgVTNGiLOgRFfJMqW7XpSQ==", + "dev": true }, "@types/parse5": { "version": "6.0.1", @@ -3685,11 +2842,6 @@ "resolved": "https://registry.npmjs.org/@types/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-dPWnWsf+kzIG140B8z2w3fr5D03TLWbOAFQl45xUpI3vcizeXriNR5VYkWZ+WTMsUHqZ9Xlt3hrxGNANFyNQfw==" }, - "@types/text-table": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@types/text-table/-/text-table-0.2.2.tgz", - "integrity": "sha512-dGoI5Af7To0R2XE8wJuc6vwlavWARsCh3UKJPjWs1YEqGUqfgBI/j/4GX0yf19/DsDPPf0YAXWAp8psNeIehLg==" - }, "@types/unist": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", @@ -3700,23 +2852,6 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -3730,68 +2865,30 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, "builtin-modules": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", "dev": true }, - "builtins": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-4.0.0.tgz", - "integrity": "sha512-qC0E2Dxgou1IHhvJSLwGDSTvokbRovU5zZFuDY6oY8Y2lF3nGt5Ad8YZK7GMtqzY84Wu7pXTPeHQeHcXSXsRhw==", - "requires": { - "semver": "^7.0.0" - } - }, - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" - }, "ccount": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.0.tgz", "integrity": "sha512-VOR0NWFYX65n9gELQdcpqsie5L5ihBXuZGAgaPEp/U7IOSjnPMEH6geE+2f6lcekaNEfWzAHS45mPvSo5bqsUA==" }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, "character-entities": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.0.tgz", @@ -3812,39 +2909,11 @@ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.0.tgz", "integrity": "sha512-pE3Z15lLRxDzWJy7bBHBopRwfI20sbrMVLQTC7xsPglCHf4Wv1e167OgYAFP78co2XlhojDyAqA+IAJse27//g==" }, - "chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, "co": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", "integrity": "sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g=" }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, "comma-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz", @@ -3859,18 +2928,8 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "debug": { "version": "4.3.2", @@ -3891,73 +2950,33 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, "escape-string-regexp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==" }, - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "fault": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.0.tgz", - "integrity": "sha512-JsDj9LFcoC+4ChII1QpXPA7YIaY8zmqPYw7h9j5n7St7a0BBKfNnwEBAUQRBx70o2q4rs+BeSNHk8Exm6xE7fQ==", - "requires": { - "format": "^0.2.0" - } - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==" - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true }, - "format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=" + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "optional": true }, "function-bind": { @@ -3970,6 +2989,7 @@ "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3979,14 +2999,6 @@ "path-is-absolute": "^1.0.0" } }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" - } - }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -3997,9 +3009,9 @@ } }, "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-5.0.1.tgz", + "integrity": "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==" }, "hast-util-from-parse5": { "version": "7.1.0", @@ -4072,23 +3084,11 @@ "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.0.tgz", "integrity": "sha512-4OYzQQsBt0G9bJ/nM9/DDsjm4+fVdzAaPJJcWk5QwA3GIAPxQEeOR0rsI8HbDHQz5Gta8pVvGnnTNSbZVEVvkQ==" }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" - }, - "import-meta-resolve": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-1.1.1.tgz", - "integrity": "sha512-JiTuIvVyPaUg11eTrNDx5bgQ/yMKMZffc7YSjvQeSMXy58DO2SQ8BtAf3xteZvmzvjYh14wnqNjL8XVeDy2o9A==", - "requires": { - "builtins": "^4.0.0" - } - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -4097,17 +3097,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "is-alphabetical": { @@ -4124,19 +3114,6 @@ "is-decimal": "^2.0.0" } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, "is-buffer": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", @@ -4156,29 +3133,11 @@ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.0.tgz", "integrity": "sha512-QfrfjQV0LjoWQ1K1XSoEZkTAzSa14RKVMa5zg3SdAfzEmQzRM4+tbSFWb78creCeA9rNBzaZal92opi1TwPWZw==" }, - "is-empty": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-empty/-/is-empty-1.2.0.tgz", - "integrity": "sha1-3pu1snhzigWgsJpX4ftNSjQan2s=" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, "is-fullwidth-code-point": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==" }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, "is-hexadecimal": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.0.tgz", @@ -4190,11 +3149,6 @@ "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, "is-plain-obj": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", @@ -4209,11 +3163,6 @@ "@types/estree": "*" } }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -4222,52 +3171,6 @@ "argparse": "^2.0.1" } }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "libnpmconfig": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/libnpmconfig/-/libnpmconfig-1.2.1.tgz", - "integrity": "sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA==", - "requires": { - "figgy-pudding": "^3.5.1", - "find-up": "^3.0.0", - "ini": "^1.3.5" - } - }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" - }, - "load-plugin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-4.0.1.tgz", - "integrity": "sha512-4kMi+mOSn/TR51pDo4tgxROHfBHXsrcyEYSGHcJ1o6TtRaP2PsRM5EwmYbj1uiLDvbfA/ohwuSWZJzqGiai8Dw==", - "requires": { - "import-meta-resolve": "^1.0.0", - "libnpmconfig": "^1.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, "longest-streak": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.0.0.tgz", @@ -4290,11 +3193,6 @@ "sourcemap-codec": "^1.4.4" } }, - "markdown-extensions": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz", - "integrity": "sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==" - }, "markdown-table": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.1.tgz", @@ -4316,15 +3214,16 @@ } }, "mdast-util-from-markdown": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.0.0.tgz", - "integrity": "sha512-uj2G60sb7z1PNOeElFwCC9b/Se/lFXuLhVKFOAY2EHz/VvgbupTQRNXPoZl7rGpXYL6BNZgcgaybrlSWbo7n/g==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.0.1.tgz", + "integrity": "sha512-KGPH5sDqbov0PWOEtElsLqLYC9tGGaOzznl6ss+rjDJP4bPe1t7T/K3oYwXPKTn+YzPUdorYirbz9pXEkapyYQ==", "requires": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", - "mdast-util-to-string": "^3.0.0", + "mdast-util-to-string": "^3.1.0", "micromark": "^3.0.0", "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", "micromark-util-normalize-identifier": "^1.0.0", "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.0", @@ -4390,15 +3289,15 @@ } }, "mdast-util-to-markdown": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.2.1.tgz", - "integrity": "sha512-yj0UexEfdH0Zqw9CztzC5+J6OZKgCY6K0ommn56SBlPKIV3NGqk1Wo/zw1Q0e/kHb50wmQ8O9cwbOl7vmaJjxg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.2.3.tgz", + "integrity": "sha512-040jJYtjOUdbvYAXCfPrpLJRdvMOmR33KRqlhT4r+fEbVM+jao1RMbA8RmGeRmw8RAj3vQ+HvhIaJPijvnOwCg==", "requires": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", "longest-streak": "^3.0.0", "mdast-util-to-string": "^3.0.0", - "parse-entities": "^3.0.0", + "micromark-util-decode-string": "^1.0.0", "unist-util-visit": "^4.0.0", "zwitch": "^2.0.0" } @@ -4615,6 +3514,16 @@ "micromark-util-symbol": "^1.0.0" } }, + "micromark-util-decode-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.0.0.tgz", + "integrity": "sha512-4g5UJ8P/J8wuRKUXCcB7udQuOBXpLyvBQSLSuznfBLCG+thKG6UTwFnXfHkrr/1wddprkUbPatCzxDjrJ+5zDg==", + "requires": { + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "parse-entities": "^3.0.0" + } + }, "micromark-util-encode": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.0.0.tgz", @@ -4675,54 +3584,25 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "requires": { "wrappy": "1" } }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, "parse-entities": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-3.0.0.tgz", @@ -4736,31 +3616,16 @@ "is-hexadecimal": "^2.0.0" } }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, "parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true }, "path-parse": { "version": "1.0.7", @@ -4771,7 +3636,8 @@ "picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true }, "pluralize": { "version": "8.0.0", @@ -4783,33 +3649,6 @@ "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.0.1.tgz", "integrity": "sha512-F4WUUAF7fMeF4/JUFHNBWDaKDXi2jbvqBW/y6o5wsf3j19wTZ7S60TmtB5HoBhtgw7NKQRMWuz5vk2PR0CygUg==" }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, "rehype": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/rehype/-/rehype-12.0.0.tgz", @@ -4842,17 +3681,6 @@ "unified": "^10.0.0" } }, - "remark": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/remark/-/remark-14.0.1.tgz", - "integrity": "sha512-7zLG3u8EUjOGuaAS9gUNJPD2j+SqDqAFHv2g6WMpE5CU9rZ6e3IKDM12KHZ3x+YNje+NMAuN55yx8S5msGSx7Q==", - "requires": { - "@types/mdast": "^3.0.0", - "remark-parse": "^10.0.0", - "remark-stringify": "^10.0.0", - "unified": "^10.0.0" - } - }, "remark-gfm": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-2.0.0.tgz", @@ -4865,9 +3693,9 @@ } }, "remark-lint": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-9.0.1.tgz", - "integrity": "sha512-q4VFsA7LEG4REJhR2P4A6CU9b4cCQL53845CX74Z4N/W0EgB9mm/GXpYzjbEqgkMPl5ctP8yp/vBYTNmjfUCtw==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-9.1.0.tgz", + "integrity": "sha512-47ZaPj1HSs17nqsu3CPg4nIhaj+XTEXJM9cpFybhyA4lzVRZiRXy43BokbEjBt0f1fhY3coQoOh16jJeGBvrJg==", "requires": { "@types/mdast": "^3.0.0", "remark-message-control": "^7.0.0", @@ -4875,9 +3703,9 @@ } }, "remark-lint-blockquote-indentation": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-3.0.1.tgz", - "integrity": "sha512-CfjXeaomk3bxt1Y0Z4T/cKVoE+8lm5jw5C+jz8EieWNIziGNUlDxIAbMk1F1sO8EXc4LjkbTSq4zz8h1vOHkew==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-3.1.0.tgz", + "integrity": "sha512-BX9XhW7yjnEp7kEMasBIQnIGOeQJYLrrQSMFoBNURLjPMBslSUrABFXUZI6hwFo5fd0dF9Wv1xt9zvSbrU9B7g==", "requires": { "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", @@ -4889,9 +3717,9 @@ } }, "remark-lint-checkbox-character-style": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-4.0.1.tgz", - "integrity": "sha512-f/Dvcw4tsWWv0vx4POVZXZmiytsyGMCKmPiMefz4zfy9hTwTGngp9EZhbDivHXiqd5YTUhvjYXFITEfVdxH4qA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-4.1.0.tgz", + "integrity": "sha512-wV3NN4j21XoC3l76mmbU/kSl4Yx0SK91lHTEpimx9PBbRtb0cb/YZiyE3bkNSXGoj6iWDcB2asF4U4rRcT5t5A==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4901,9 +3729,9 @@ } }, "remark-lint-checkbox-content-indent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-4.0.1.tgz", - "integrity": "sha512-uv4qIBdIxGshQ1a84a2RClbX39lYfWgPm3Wg35EJbSWPpe+KWt4rYi9nxB51dIEUXw3KAujlOVougPwhAZROuA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-4.1.0.tgz", + "integrity": "sha512-K2R9V1C/ezs2SfLsh5SdXlOuJVWaUwA2LsbjIp+jcd+Dt8otJ4Rul741ypL4Sji/vaxrQi5f4+iLYpfrUtjfDQ==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4914,9 +3742,9 @@ } }, "remark-lint-code-block-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-3.0.1.tgz", - "integrity": "sha512-B6338x1UggrAMe4gdmk1No2L/OkK1d1uCelekj6cnl+Pi5/HLlSw3lXIaOTRNIXOccT1zMmNApA4sDZ5qsQWtw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-3.1.0.tgz", + "integrity": "sha512-Hv4YQ8ueLGpjItla4CkcOkcfGj+nlquqylDgCm1/xKnW+Ke2a4qVTMVJrP9Krp4FWmXgktJLDHjhRH+pzhDXLg==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4927,9 +3755,9 @@ } }, "remark-lint-definition-spacing": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-3.0.1.tgz", - "integrity": "sha512-jtCUaZ+6KP4nNutBoiWoqBfa2sMsD4uvvFbuU5MOlzI0wlMmaeAq1pxWuNtkK+w8AEk/8CzfCUrLct5w65KSLQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-3.1.0.tgz", + "integrity": "sha512-cJlT3+tjTTA3mv3k2ogdOELSdbkpGKDNZ1qwba0ReSCdNCVbxcejZ/rrU96n/guv34XgqFyDrzoc7kcxU8oyEg==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4939,9 +3767,9 @@ } }, "remark-lint-fenced-code-flag": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-3.0.1.tgz", - "integrity": "sha512-HsEhvalGxCauZO6OAnaVzIBycfaHLuyZxy1KlniWXQJKZ6EjRAsWwkZHYx9qfPl/ZW7zDG+xAoWTqdHjZW/BTg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-3.1.0.tgz", + "integrity": "sha512-s96DWERWUeDi3kcDbW6TQo4vRUsGJUNhT1XEsmUzYlwJJ+2uGit9O5dAxvEnwF3gZxp/09hPsQ+QSxilC1sxLg==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4952,9 +3780,9 @@ } }, "remark-lint-fenced-code-marker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-3.0.1.tgz", - "integrity": "sha512-vFRjlzyxtG3zdvmlTn6cV1YiZAivQwOzYRNnH5KavC39EZHDxqjQl84QTXshgfCzFupvYCi6ykATIa7obgx9jg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-3.1.0.tgz", + "integrity": "sha512-klvbiQBINePA51Icprq7biFCyZzbtsASwOa6WCzW/KpAFz2V9a57PTuZkO9MtdDhW0vLoHgsQ4b0P1MD7JHMEw==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4964,9 +3792,9 @@ } }, "remark-lint-file-extension": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-2.0.1.tgz", - "integrity": "sha512-A2N6XoLPbYyRhgXyTI7WlW9Nb9QvXQNXG514hjHdNNd0cL+5P4JU6vivgZiYfViCzOLgsys6hwhXBSC9ZQ45tw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-2.1.0.tgz", + "integrity": "sha512-3T2n5/FsQ2CcDDubO5F8h7a/GyzTCy+R9XF8L9L9dVuZoxl4AWr1J6AmxE02bTy4g/TMH90juLELT08WGR6D9Q==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4974,9 +3802,9 @@ } }, "remark-lint-final-definition": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-3.0.1.tgz", - "integrity": "sha512-bzha13GTKFnQ0h4ZvaHadK6HxM2eRJj/yj59aXyvJkHFNx7i0sQn1884t3yYM4ppdDmO+cCMMgsVo8DxE8ifFA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-3.1.0.tgz", + "integrity": "sha512-XUbCNX7EFc/f8PvdQeXl2d5eu2Nksb2dCxIri+QvL/ykQ0MluXTNUfVsasDfNp9OYFBbTuBf27WiffOTOwOHRw==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4987,9 +3815,9 @@ } }, "remark-lint-final-newline": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-2.0.1.tgz", - "integrity": "sha512-vv1LT36frgc0FVc7V52CdOxqh1TqGcNvAVD89935sb9wpEELiUfbGG1Xb9PVZoIaVQcFo8qEDWCvfhsKTKk8Nw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-2.1.0.tgz", + "integrity": "sha512-jD9zIfk+DYAhho7mGkNtT4+3Bn6eiOVYzEJUUqNZp1GMtCY69gyVCK7Oef3S2Z6xLJUlZvC2vZmezhn0URUl7w==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4997,9 +3825,9 @@ } }, "remark-lint-first-heading-level": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-first-heading-level/-/remark-lint-first-heading-level-3.0.1.tgz", - "integrity": "sha512-3ym0v/aMFpHTGv2/DPln6NHB2DFnx6Nbd+3Z9kf6wfnJCzXNA3zXyCKt11i5MPzUV5wlwButcW+JkPDtDJsfog==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-first-heading-level/-/remark-lint-first-heading-level-3.1.0.tgz", + "integrity": "sha512-8OV6BEjB5JSUCQRNk+z8MFyqu5Cdtk7TCR6Y6slC4b8vYlj26VecG5Fo4nLXdSj9/Tx01z59Od2FzBRV+6A1Xg==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5009,9 +3837,9 @@ } }, "remark-lint-hard-break-spaces": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-3.0.1.tgz", - "integrity": "sha512-CPjbfc9DcV4Qy3d8jyhh/QXsLD5uRtweb0d04p2MyzMDrqwXAq5X4MW3rId3JbVVl7o1AKXq1FdvqIMrh9Rpuw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-3.1.0.tgz", + "integrity": "sha512-0nUJpsH0ibYtsxv3QS29C3axzyVZBz6RD28XWmelcuCfApWluDlW4pM8r0qa1lE1UrLVd3MocKpa4i1AKbkcsg==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5022,9 +3850,9 @@ } }, "remark-lint-heading-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-3.0.1.tgz", - "integrity": "sha512-/9rsTE+coYdUgT/spxg4ioorG2W5XdabLHajKjTOOQ4ME8Wa5fXHMJ3WpK3Vnz8ZKP7WQwTTPsKWIHcy5d6C+w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-3.1.0.tgz", + "integrity": "sha512-wQliHPDoK+YwMcuD3kxw6wudlXhYW5OUz0+z5sFIpg06vx7OfJEASo6d6G1zYG+KkEesZx1SP0SoyHV4urKYmg==", "requires": { "@types/mdast": "^3.0.0", "mdast-util-heading-style": "^2.0.0", @@ -5035,9 +3863,9 @@ } }, "remark-lint-list-item-bullet-indent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-4.0.1.tgz", - "integrity": "sha512-7XjtSLUwvxHi28/q9XMzYy7A+agpArvLlTksD0r1jj5MpGYTSUW9b54rRRV3JxHJMoX+ZJ9juId6GmVaUZwsTg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-4.1.0.tgz", + "integrity": "sha512-KmVTNeaTXkAzm21wLv0GKYXMDU5EwlBncGNb9z4fyQx/mAsX+KWVw71b6+zdeai+hAF8ErENaN48DgLxQ/Z3Ug==", "requires": { "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", @@ -5047,9 +3875,9 @@ } }, "remark-lint-list-item-indent": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-3.0.1.tgz", - "integrity": "sha512-5/H5B2g6TTpJZiwMmBa/Drexwq5Dw50QoypTUgXwFETz91s7zvjy+IGGVoVv0L0LM0rCwblmgtLomqeWIyo9sA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-3.1.0.tgz", + "integrity": "sha512-+dTStrxiMz9beP+oe48ItMUHzIpMOivBs1+FU44o1AT6mExDGvDdt4jMtLCpPrZVFbzzIS00kf5FEDLqjNiaHg==", "requires": { "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", @@ -5061,9 +3889,9 @@ } }, "remark-lint-maximum-line-length": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-3.0.1.tgz", - "integrity": "sha512-R4hiRRx46xa3NE/AY8IKzPTRVyq1ZWrtWVd2KfWwNHmj7a6ASjb75DPzGyckZ46UAQq9mSBPsgL5Rfhq5XmggA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-3.1.0.tgz", + "integrity": "sha512-EfXXQsrmdyoMdzlZ0yDjSPeEHv+os444SsTvrwPwrJWxj39fudakweM3xAk2NgDJc7UrcCZzKH+4yNDmL0NcvQ==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5074,9 +3902,9 @@ } }, "remark-lint-no-auto-link-without-protocol": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-3.0.1.tgz", - "integrity": "sha512-FdbB9O4SegELBreglpOXhMyusKORPS0X7KrBY/V+tDo4+2sJHMEEdiN4RbK2ofWwRP7V+muZ5WrscLliuAExQg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-3.1.0.tgz", + "integrity": "sha512-GqZXDu/xfajWCEPhS8UjO9dYMTlY5lD8ShoYIaouUgz3nNQvLwX33pTKqfRpd/R9EmV1uQw0PCJ6TYwhBrnOXQ==", "requires": { "@types/mdast": "^3.0.0", "mdast-util-to-string": "^3.0.0", @@ -5088,9 +3916,9 @@ } }, "remark-lint-no-blockquote-without-marker": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-5.0.1.tgz", - "integrity": "sha512-3aUFCV1BSqO15MuJ6fQept36An/vLo9VgAj1TRWk4Gsnaewbq7haT/m6eiYn5Ia8t2sSBbv4LKz1lwnj5nOVPQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-5.1.0.tgz", + "integrity": "sha512-t9ohZSpHIZdlCp+h2nemFD/sM3Am6ZZEczaBpmTQn+OoKrZjpDRrMTb/60OBGXJXHNazfqRwm96unvM4qDs4+Q==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5102,9 +3930,9 @@ } }, "remark-lint-no-consecutive-blank-lines": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-4.0.1.tgz", - "integrity": "sha512-nvwglXFdR8ubTjSduK3cVdgBaKCH/DqV0kVkCKSQmLEl8NyozFH03VB/bhQDCrmSeNt6rYClBF0ppaHT27OmpA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-4.1.0.tgz", + "integrity": "sha512-4gn7lPXAw9hw08apENVNvWjdtuNtgtHPA0mjqgjTszXC92IY1YW8zGfxChCLvCJ1bG4/isI6Ctx+ZmmQoZEW1Q==", "requires": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", @@ -5117,9 +3945,9 @@ } }, "remark-lint-no-duplicate-definitions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-3.0.1.tgz", - "integrity": "sha512-gwQe65dW2fkMQR02hwlHtc0OOvshst+gXMOEwd1/fpIb6OORpMiK6ueoNBxCnKSsKqftjWV0JXVdZ7MfKKxQQw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-3.1.0.tgz", + "integrity": "sha512-kBBKK/btn6p0yOiVhB6mnasem7+RUCRjifoe58y/Um56qQsh1GtX6YHVNnboO7fp9aq46MKC2Yc93pEj5yEbDg==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5131,9 +3959,9 @@ } }, "remark-lint-no-file-name-articles": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-2.0.1.tgz", - "integrity": "sha512-9kZ/ydzJlntswJjsQEbPPx0tc6uAPuowmG/3aOCSE+6CjJ+bCQZiVLL3VhjktNyzFxDGTDN6LlbVwiyIHEUMwA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-2.1.0.tgz", + "integrity": "sha512-+4gembcykiLnrsTxk4ld2fg3n3TgvHGBO6qMsRmjh5k2m2riwnewM80xfCGXrEVi5cciGIhmv4iU7uicp+WEVQ==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5141,9 +3969,9 @@ } }, "remark-lint-no-file-name-consecutive-dashes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-2.0.1.tgz", - "integrity": "sha512-e9ei9KwQSRzUQeYHEhCKUMDeavFOIj46NtuyZxYtrklOcblvaZLAV133UcFHk5CimdUj3dzTtFZebHdpvu5omw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-2.1.0.tgz", + "integrity": "sha512-jnQcsYaV8OkUMmFcXr/RWkJFKw30lqEtYTfmb9n/AUsBFeQt53cYYZjA+6AgvKSUW3be7CY2XptReTuM4jSHpQ==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5151,9 +3979,9 @@ } }, "remark-lint-no-file-name-outer-dashes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-2.0.1.tgz", - "integrity": "sha512-INp+0gW5T2j6+sHglmDmCLL7/goVKCryXyf+ZApB5oWYBpVr2fLnHEHTUmkbQkksxe7me+VsB+WW/KN1PXGrtw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-2.1.0.tgz", + "integrity": "sha512-R0eXcFpsfjXI4djN/AF734kydS+p5frZW6NsUzpEfLt5Eu/MhOuii2LvV/G1ujyclZAELpvZlV+sW4083SHi3g==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5161,9 +3989,9 @@ } }, "remark-lint-no-heading-content-indent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-4.0.1.tgz", - "integrity": "sha512-IRYlydfT0Xt4AEs5OKSBGP9hLNDckd1mKcV8crnNu91HhcmFVJznzsLV1QrUTTI94cwkSmSWqpjNzsDrKGPbIw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-4.1.0.tgz", + "integrity": "sha512-+V92BV7r4Ajc8/oe5DhHeMrn3pZHIoLyqLYM6YgkW2hPMn+eCLVAcrfdOiiVrBpgUNpZMIM9x7UwOq0O4hAr8A==", "requires": { "@types/mdast": "^3.0.0", "mdast-util-heading-style": "^2.0.0", @@ -5176,9 +4004,9 @@ } }, "remark-lint-no-heading-indent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-4.0.1.tgz", - "integrity": "sha512-LjRsRJOPT1M5MwvGxGEPIHzB713chWgJF5v/FNaHnniLgBrwIbpmsqEhAAam/+i593B5tx84ZyaCf8ujXTP0gg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-4.1.0.tgz", + "integrity": "sha512-hy9W3YoHWR1AbsOAbhZDwzJAKmdLekmKhc5iC9VfEWVfXsSNHwjAoct4mrBNMEUcfFYhcOTKfyrIXwy1D7fXaw==", "requires": { "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", @@ -5190,9 +4018,9 @@ } }, "remark-lint-no-inline-padding": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-4.0.1.tgz", - "integrity": "sha512-UcjJ2XTf7kOmQo5mU/5AV+Gth1YYGcp+gYU4gS/CzdOLYstqsS/W+IN6ALJjEbdbtSyfWCElpxI4p/mW16Z90A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-4.1.0.tgz", + "integrity": "sha512-0dbIgBUhVIkIn8xji2b/j1tG+ETbzE+ZEYNtCRTsNCjFwvyvgzElWKMLHoLzTpXYAN8I5dQhyFcy8Qa/RXg3AA==", "requires": { "@types/mdast": "^3.0.0", "mdast-util-to-string": "^3.0.0", @@ -5203,9 +4031,9 @@ } }, "remark-lint-no-literal-urls": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-3.0.1.tgz", - "integrity": "sha512-3OAFcaZawfrFgZGrpuZlNPyuvfIURtUzDN7/Bl2X42ivqx4ih1OH9LtiBgz+J0g1DEWnC5ebOmDr7x6XLM76Fw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-3.1.0.tgz", + "integrity": "sha512-FvSE16bvwMLh89kZzvyXnWh8MZ2WU+msSqfbF3pU/0YpnpxfRev9ShFRS1k8wVm5BdzSqhwplv4chLnAWg53yw==", "requires": { "@types/mdast": "^3.0.0", "mdast-util-to-string": "^3.0.0", @@ -5217,9 +4045,9 @@ } }, "remark-lint-no-multiple-toplevel-headings": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-3.0.1.tgz", - "integrity": "sha512-K62PKOOanFiFM4R0oHlo1PKWJa0dPPasQl28yzk6G2xZzqc5eJm5S3d0grU479jqEUbDQMaDQw282hO6WR/MbA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-3.1.0.tgz", + "integrity": "sha512-F4z867UaYjWdWFzR4ZpPi+EIzoUcU/QtdEVftdVKNdBEy1pq2A/vdTUa/PGtc+LLeQn04mJ/SGPC2s7eMWAZfg==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5231,9 +4059,9 @@ } }, "remark-lint-no-shell-dollars": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-3.0.1.tgz", - "integrity": "sha512-QvnA8Ltj3FPaAqUu0DebKYv66LFndTk0fXVZ9rQWOjTEVIKImy9Dy59kVqwYMpCwZbJkpigu2bMl/7UG/BA0XA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-3.1.0.tgz", + "integrity": "sha512-f4+NPey3yzd9TpDka5Bs3W+MMJBPz6bQ7zK3M9Qc133lqZ81hKMGVRrOBafS1RNqD5htLZbbGyCoJa476QtW1w==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5243,9 +4071,9 @@ } }, "remark-lint-no-shortcut-reference-image": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-3.0.1.tgz", - "integrity": "sha512-0o0YO88Atib0eWloy5ZbL2IZ1axMNysbJI5j58sxMjEwLq1JORtGOR9Z6aHsOccS5yseeenw5w3DoMLB9PtJtw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-3.1.0.tgz", + "integrity": "sha512-uTXysJw749c42QnFt+DfG5NJTjfcQdM5gYGLugb/vgUwN8dzPu6DiGM3ih1Erwha6qEseV00FpFvDexHbQvJNw==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5255,9 +4083,9 @@ } }, "remark-lint-no-shortcut-reference-link": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-3.0.1.tgz", - "integrity": "sha512-uXujnVm5LXLtGyJkTIbn/uxDRu507B9vC8TieiX6HX8OjVeDWUjtcVJOaqeyLJGjV0Ri1Y+AegMNWx5eDBHTDQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-3.1.0.tgz", + "integrity": "sha512-SmM/sICFnlMx4PcuXIMJmyqTyI1+FQMOGh51GmLDWoyjbblP2hXD4UqrYLhAeV0aPQSNKwMXNNW0aysjdoWL0A==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5267,9 +4095,9 @@ } }, "remark-lint-no-table-indentation": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-4.0.1.tgz", - "integrity": "sha512-GYBX5P1Vj0gO7S7JLU2tpYR5rg9xbeccPQ0ZgHYK4d7T9FjDwfE1hrdvlha3k8s3CFKqQ7MC0OgQw/2IN413MA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-4.1.0.tgz", + "integrity": "sha512-OJg95FHBZKyEUlnmHyMQ2j9qs5dnxk3oX1TQuREpFDgzQMh/Bcyc+CegmsDMDiyNyrs1QgDwubCWmAYWgdy4Gw==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5280,9 +4108,9 @@ } }, "remark-lint-no-tabs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-tabs/-/remark-lint-no-tabs-3.0.1.tgz", - "integrity": "sha512-B2q1I+fyRDvWTQxCC91NoEvz0KzI9e6Yhu1TdOLkwc02hMWj869G165Rh+EcBKGW/CLKuMPhIn2XtL86emqZRw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-tabs/-/remark-lint-no-tabs-3.1.0.tgz", + "integrity": "sha512-QjMDKdwoKtZyvqHvRQS6Wwy/sy2KwLGbjGJumGXhzYS6fU7r/EimYcCbNb0NgxJhs3sLhWKZB9m/W0hH6LYbnA==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5309,9 +4137,9 @@ } }, "remark-lint-no-undefined-references": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-4.0.1.tgz", - "integrity": "sha512-mmNJO30TYMxwfFJPHkwKNRaW63sU9ffhpb4xkyhyHDmnsplQ96RVYR4WGOXw0/wR+gZECmFtBU+OIWz0cbaiEw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-4.1.0.tgz", + "integrity": "sha512-xnBd6ZLWv9Lnf1dH6bC/IYywbzxloUNJwiJY2OzhtZUMsqH8Xw5ZAidhxIW3k+3K8Fs2WSwp7HjIzjp7ZSiuDA==", "requires": { "@types/mdast": "^3.0.0", "micromark-util-normalize-identifier": "^1.0.0", @@ -5324,9 +4152,9 @@ } }, "remark-lint-no-unused-definitions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-3.0.1.tgz", - "integrity": "sha512-bcbboInyb8vAPtYakZdaxRQsDIdQnV5WvUdc03PWFlG8YtGOhRQ57SPc+4uVH+VwHoq+lsEsRszr4sOXuuopxw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-3.1.0.tgz", + "integrity": "sha512-poSmPeY5wZYLXhiUV+rbrkWNNENjoUq2lUb/Ho34zorMeV70FNBEV+zv1A6Ri8+jplUDeLi1lqC0uBTlTAUuLQ==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5336,9 +4164,9 @@ } }, "remark-lint-ordered-list-marker-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-3.0.1.tgz", - "integrity": "sha512-CGXvolLwfZIxG9hm4o7OXQXEEpu3r5oyTpYGteJDtOSrpVrBSqFKNq7lfhKYFQkcg2AMJYrH9XEexrYvAoUQOQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-3.1.0.tgz", + "integrity": "sha512-/sYOjCK+FkAhwheIHjL65TxQKJ8infTVsDi5Dbl6XHaXiAzKjvZhwW4uJqgduufozlriI63DF68YMv5y6tyXsw==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5361,9 +4189,9 @@ } }, "remark-lint-rule-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-3.0.1.tgz", - "integrity": "sha512-j1e60nfZJk0C6mvDZkiFwVu0b58f219ATlMNaZ9h8QdQhdxD/0kUnizJ7xW3wS4sHtCgkKGctAp04Ma0c+Dkhg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-3.1.0.tgz", + "integrity": "sha512-Z2tW9kBNCdD8l+kG7bTKanfciqGGJt8HnBmV9eE3oIqVDzqWJoIQ8kVBDGh6efeOAlWDDDHGIp/jb4i/CJ/kvg==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5373,9 +4201,9 @@ } }, "remark-lint-strong-marker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-3.0.1.tgz", - "integrity": "sha512-J5dJviBd747vXBkFuA2j/Ni7RjTg+Mg2GgXlPHtbgDnal51CdN2WXDmbVG/A98+3P18MlysvQ7KnBrSiiuGBpQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-3.1.0.tgz", + "integrity": "sha512-YkGZ2J1vayVa/uSWUOuqKzB3ot1RgtsAd/Kz7L2ve8lDDIjnxn+bUufaS6cN9K5/ADprryd1hdE29YRVj6Vs3g==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5385,9 +4213,9 @@ } }, "remark-lint-table-cell-padding": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-4.0.1.tgz", - "integrity": "sha512-NdF0WHFOaMjeumRIrGHXVadwWkgnfJuMb96FGbf1HvSEv9l41PHkS1KTsL6Zoe1Cva57niAuarMv6xzcJqVjrA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-4.1.0.tgz", + "integrity": "sha512-2FqYGR6IsO5HdmvBe15iwD8XI9xjyMBegKuJWK50bWAsIVdR1b80nfXxKDQ6lRDK6LZ7+iATxzTo0Fl3+TLmgw==", "requires": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", @@ -5398,9 +4226,9 @@ } }, "remark-lint-table-pipes": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-4.0.1.tgz", - "integrity": "sha512-om6i8SMSjMsR/mYlx5cMSoxXK+EFI8/n73qCVx/RAhFCIsW4TFR+gYmgFTyLr5Mp4vqjV3uYBIR9Ucv6Johauw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-4.1.0.tgz", + "integrity": "sha512-kI50VXlEW9zUdMh8Y9T7vornqpnMr+Ywy+sUzEuhhmWeFIYcIsBbZTHA1253FgjA/iMkLPzByYWj1xGlUGL1jw==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5410,9 +4238,9 @@ } }, "remark-lint-unordered-list-marker-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-3.0.1.tgz", - "integrity": "sha512-DPveL2hhkcY608Bkn/Hx+C7pxviufpYyRiu0CnfFxkbLBlMgVdvVIOGCCOlhbvKuGtozmH/RCRsdIfzjlkXiew==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-3.1.0.tgz", + "integrity": "sha512-oUThfe8/34DpXkGjOghOkSOqk8tGthnDNIMBtNVY+aMIkkuvCSxqFj9D/R37Al7/tqqgZ1D6ezpwxIOsa15JTA==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5446,9 +4274,9 @@ } }, "remark-preset-lint-node": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-preset-lint-node/-/remark-preset-lint-node-3.0.1.tgz", - "integrity": "sha512-L7yhho9q9vmpsfMHO2gRKFNj36106iFM4KpodE+3k3rGg5dcmhV+zcsftNh5NGzbKKKYsGQj9C5XxCR/0NwKDg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-preset-lint-node/-/remark-preset-lint-node-3.1.0.tgz", + "integrity": "sha512-jWEl5ljKYmIiM2cnZbp7dIYmpFND33RWOCcm5cbp8m2GbOLMOaAW2cVBZe47XLAzpQcOIKaT2BjSsi7Y1h/cig==", "requires": { "js-yaml": "^4.0.0", "remark-lint-blockquote-indentation": "^3.0.0", @@ -5487,9 +4315,9 @@ } }, "remark-preset-lint-recommended": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-6.0.1.tgz", - "integrity": "sha512-8ZlwP2aDCGf+3UFPP1K8CofWI/WLoq8hPhQiuKotCFNSdTe98/27XYqWXpbMt4feWtX4+tcJY1y0duuLK5lhBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-6.1.0.tgz", + "integrity": "sha512-1jUbuzRAP5idWu9GZ5x7M96Z1TcTWwJu0C8ziz5RLezWL9rChhw9kV6s0beR0lrY5Kl5E5pjA6SKaP7NyGi2ug==", "requires": { "@types/mdast": "^3.0.0", "remark-lint": "^9.0.0", @@ -5532,19 +4360,14 @@ } }, "rollup": { - "version": "2.56.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.56.3.tgz", - "integrity": "sha512-Au92NuznFklgQCUcV96iXlxUbHuB1vQMaH76DHl5M11TotjOHwqk9CwcrT78+Tnv4FN9uTBxq6p4EJoYkpyekg==", + "version": "2.57.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.57.0.tgz", + "integrity": "sha512-bKQIh1rWKofRee6mv8SrF2HdP6pea5QkwBZSMImJysFj39gQuiV8MEPBjXOCpzk3wSYp63M2v2wkWBmFC8O/rg==", "dev": true, "requires": { "fsevents": "~2.3.2" } }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -5553,27 +4376,6 @@ "lru-cache": "^6.0.0" } }, - "shelljs": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", - "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", - "dev": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "shx": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.3.tgz", - "integrity": "sha512-nZJ3HFWVoTSyyB+evEKjJ1STiixGztlqwKLTUNV5KqMWtGey9fTd4KU1gdZ1X9BV6215pswQ/Jew9NsuS/fNDA==", - "dev": true, - "requires": { - "minimist": "^1.2.3", - "shelljs": "^0.8.4" - } - }, "sliced": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", @@ -5590,22 +4392,14 @@ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.1.tgz", "integrity": "sha512-ekwEbFp5aqSPKaqeY1PGrlGQxPNaq+Cnx4+bE2D8sciBQrHpbwoBbawqTN2+6jPs9IdWxxiUcN0K2pkczD3zmw==" }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, "string-width": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.0.0.tgz", - "integrity": "sha512-zwXcRmLUdiWhMPrHz6EXITuyTgcEnUqDzspTkCLhQovxywWz6NP9VHgqfVg20V/1mUg0B95AKbXxNT+ALRmqCw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.0.1.tgz", + "integrity": "sha512-5ohWO/M4//8lErlUUtrFy3b11GtNOuMOU0ysKCDXFcfXuuvUXu95akgj/i8ofmaGdN0hCqyl6uu9i8dS/mQp5g==", "requires": { "emoji-regex": "^9.2.2", "is-fullwidth-code-point": "^4.0.0", - "strip-ansi": "^7.0.0" + "strip-ansi": "^7.0.1" } }, "stringify-entities": { @@ -5618,32 +4412,19 @@ } }, "strip-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.0.tgz", - "integrity": "sha512-UhDTSnGF1dc0DRbUqr1aXwNoY3RgVkSWG8BrpnuFIxhP57IqbS7IRta2Gfiavds4yCxc5+fEAVVOgBZWnYkvzg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", "requires": { - "ansi-regex": "^6.0.0" + "ansi-regex": "^6.0.1" } }, "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.0.2.tgz", + "integrity": "sha512-ii6tc8ImGFrgMPYq7RVAMKkhPo9vk8uA+D3oKbJq/3Pk2YSMv1+9dUAesa9UxMbxBTvxwKTQffBahNVNxEvM8Q==", "requires": { - "is-number": "^7.0.0" + "has-flag": "^5.0.0" } }, "to-vfile": { @@ -5660,11 +4441,6 @@ "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, "unified": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", @@ -5679,56 +4455,10 @@ "vfile": "^5.0.0" } }, - "unified-args": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/unified-args/-/unified-args-9.0.2.tgz", - "integrity": "sha512-qSqryjoqfJSII4E4Z2Jx7MhXX2MuUIn6DsrlmL8UnWFdGtrWvEtvm7Rx5fKT5TPUz7q/Fb4oxwIHLCttvAuRLQ==", - "requires": { - "@types/text-table": "^0.2.0", - "camelcase": "^6.0.0", - "chalk": "^4.0.0", - "chokidar": "^3.0.0", - "fault": "^2.0.0", - "json5": "^2.0.0", - "minimist": "^1.0.0", - "text-table": "^0.2.0", - "unified-engine": "^9.0.0" - } - }, - "unified-engine": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/unified-engine/-/unified-engine-9.0.4.tgz", - "integrity": "sha512-NFI+jC3DWZ23eBsWkOW2havz47DPG/DSyJEvBH+qA5cQHF6zlgiJYev7ksb/naOypZZ+cfhaCxCRo2BqrysYEw==", - "requires": { - "@types/concat-stream": "^1.0.0", - "@types/debug": "^4.0.0", - "@types/is-empty": "^1.0.0", - "@types/js-yaml": "^4.0.0", - "@types/node": "^16.0.0", - "@types/unist": "^2.0.0", - "concat-stream": "^2.0.0", - "debug": "^4.0.0", - "fault": "^2.0.0", - "glob": "^7.0.0", - "ignore": "^5.0.0", - "is-buffer": "^2.0.0", - "is-empty": "^1.0.0", - "is-plain-obj": "^4.0.0", - "js-yaml": "^4.0.0", - "load-plugin": "^4.0.0", - "parse-json": "^5.0.0", - "to-vfile": "^7.0.0", - "trough": "^2.0.0", - "unist-util-inspect": "^7.0.0", - "vfile-message": "^3.0.0", - "vfile-reporter": "^7.0.0", - "vfile-statistics": "^2.0.0" - } - }, "unified-lint-rule": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.1.tgz", - "integrity": "sha512-2RzZuuuWW+ifftM0zd/ZEng0Hb5lah+Zi+ZL/ybj8BrLO/TH2aQAMYvG+iC95aCg2FkWu/pcvVvHqsh2UMmzPg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.1.0.tgz", + "integrity": "sha512-pB2Uht3w+A9ceWXMYI0YWwxCTqC5on6jrApWDWSsYDBjaljSv8s64qdHHMCXFIUAGdd6V/XWrVMxiboHOAXo3Q==", "requires": { "@types/unist": "^2.0.0", "trough": "^2.0.0", @@ -5766,14 +4496,6 @@ "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.0.tgz", "integrity": "sha512-TiWE6DVtVe7Ye2QxOVW9kqybs6cZexNwTwSMVgkfjEReqy/xwGpAXb99OxktoWwmL+Z+Epb0Dn8/GNDYP1wnUw==" }, - "unist-util-inspect": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/unist-util-inspect/-/unist-util-inspect-7.0.0.tgz", - "integrity": "sha512-2Utgv78I7PUu461Y9cdo+IUiiKSKpDV5CE/XD6vTj849a3xlpDAScvSJ6cQmtFBGgAmCn2wR7jLuXhpg1XLlJw==", - "requires": { - "@types/unist": "^2.0.0" - } - }, "unist-util-is": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", @@ -5803,9 +4525,9 @@ }, "dependencies": { "unist-util-visit-parents": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", - "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.0.tgz", + "integrity": "sha512-y+QVLcY5eR/YVpqDsLf/xh9R3Q2Y4HxkZTp7ViLDU6WtJCEcPmRzW1gpdWDCDIqIlhuPDXOgttqPlykrHYDekg==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0" @@ -5822,11 +4544,6 @@ "unist-util-is": "^5.0.0" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, "vfile": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.1.0.tgz", @@ -5867,21 +4584,6 @@ "unist-util-stringify-position": "^3.0.0", "vfile-sort": "^3.0.0", "vfile-statistics": "^2.0.0" - }, - "dependencies": { - "has-flag": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-5.0.1.tgz", - "integrity": "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==" - }, - "supports-color": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.0.2.tgz", - "integrity": "sha512-ii6tc8ImGFrgMPYq7RVAMKkhPo9vk8uA+D3oKbJq/3Pk2YSMv1+9dUAesa9UxMbxBTvxwKTQffBahNVNxEvM8Q==", - "requires": { - "has-flag": "^5.0.0" - } - } } }, "vfile-sort": { @@ -5917,7 +4619,8 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "yallist": { "version": "4.0.0", diff --git a/tools/lint-md/package.json b/tools/lint-md/package.json new file mode 100644 index 00000000000000..31b740744d186e --- /dev/null +++ b/tools/lint-md/package.json @@ -0,0 +1,22 @@ +{ + "name": "lint-md", + "description": "markdown linting", + "version": "1.0.0", + "scripts": { + "build": "rollup -f es -p '@rollup/plugin-node-resolve={exportConditions: [\"node\"]}' -p @rollup/plugin-commonjs lint-md.src.mjs --file lint-md.mjs" + }, + "dependencies": { + "remark-gfm": "^2.0.0", + "remark-parse": "^10.0.0", + "remark-preset-lint-node": "^3.0.1", + "remark-stringify": "^10.0.0", + "to-vfile": "^7.2.2", + "unified": "^10.1.0", + "vfile-reporter": "^7.0.2" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^20.0.0", + "@rollup/plugin-node-resolve": "^13.0.5", + "rollup": "^2.57.0" + } +} diff --git a/tools/node-lint-md-cli-rollup/.gitignore b/tools/node-lint-md-cli-rollup/.gitignore deleted file mode 100644 index ab9ffa17b3a6dd..00000000000000 --- a/tools/node-lint-md-cli-rollup/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/node_modules/ -/remark-preset-lint-node/node_modules/ -/dist/ diff --git a/tools/node-lint-md-cli-rollup/LICENSE b/tools/node-lint-md-cli-rollup/LICENSE deleted file mode 100644 index 3ffee7a3be6993..00000000000000 --- a/tools/node-lint-md-cli-rollup/LICENSE +++ /dev/null @@ -1,32 +0,0 @@ -Copyright (c) 2018 Refael Ackermann - -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. - ---- - -(The MIT License for `remark` https://github.com/remarkjs/remark/blob/master/LICENSE) - -Copyright (c) 2014-2016 Titus Wormer -Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/) - -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. \ No newline at end of file diff --git a/tools/node-lint-md-cli-rollup/package.json b/tools/node-lint-md-cli-rollup/package.json deleted file mode 100644 index 0b4e23ab09eed6..00000000000000 --- a/tools/node-lint-md-cli-rollup/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "node-lint-md-cli-rollup", - "description": "remark packaged for Node.js Markdown linting", - "version": "2.0.2", - "devDependencies": { - "@rollup/plugin-commonjs": "^20.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.4", - "rollup": "^2.56.3", - "shx": "^0.3.3" - }, - "dependencies": { - "markdown-extensions": "^1.1.1", - "remark": "^14.0.1", - "remark-gfm": "^2.0.0", - "remark-preset-lint-node": "^3.0.1", - "unified-args": "^9.0.2" - }, - "main": "dist/index.js", - "scripts": { - "build": "npx rollup -c", - "build-node": "npm run build && npx shx cp dist/index.mjs ../lint-md.mjs" - } -} diff --git a/tools/node-lint-md-cli-rollup/rollup.config.js b/tools/node-lint-md-cli-rollup/rollup.config.js deleted file mode 100644 index 0a2b2098e69dd6..00000000000000 --- a/tools/node-lint-md-cli-rollup/rollup.config.js +++ /dev/null @@ -1,57 +0,0 @@ -'use strict'; - -const { nodeResolve } = require('@rollup/plugin-node-resolve'); -const commonjs = require('@rollup/plugin-commonjs'); -const json = require('@rollup/plugin-json'); - -module.exports = { - input: 'src/cli-entry.mjs', - output: { - file: 'dist/index.mjs', - format: 'es', - sourcemap: false, - exports: 'none', - }, - external: [ - 'node:events', - 'node:fs', - 'node:path', - 'node:process', - 'node:stream', - 'node:url', - ], - plugins: [ - { - name: 'brute-replace', - transform(code, id) { - const normID = id.replace(__dirname, '').replace(/\\+/g, '/'); - if (normID === '/node_modules/concat-stream/index.js') { - return code.replace('\'readable-stream\'', '\'stream\''); - } - if (normID === '/node_modules/unified-args/lib/options.js') { - return code.replace('\'./schema\'', '\'./schema.json\''); - } - if (normID === '/node_modules/chokidar/lib/fsevents-handler.js') { - return code.replace( - 'fsevents = require(\'fsevents\');', 'fsevents = undefined;' - ); - } - // Remove circular dependency in glob that messes up rollup - return code.replace("var Glob = require('./glob.js').Glob", ''); - } - }, - json({ - preferConst: true - }), - nodeResolve({ exportConditions: ['node'] }), - commonjs(), - { - name: 'banner', - renderChunk(code) { - const banner = '// Don\'t change this file manually,\n' + - '// it is generated from tools/node-lint-md-cli-rollup'; - return code.replace('\'use strict\';', '\'use strict\';\n\n' + banner); - } - }, - ] -}; diff --git a/tools/node-lint-md-cli-rollup/src/cli-entry.mjs b/tools/node-lint-md-cli-rollup/src/cli-entry.mjs deleted file mode 100644 index 71e2563926b26c..00000000000000 --- a/tools/node-lint-md-cli-rollup/src/cli-entry.mjs +++ /dev/null @@ -1,27 +0,0 @@ -// To aid in future maintenance, this layout closely matches remark-cli/cli.js. -// https://github.com/remarkjs/remark/blob/HEAD/packages/remark-cli/cli.js - -import { args } from 'unified-args'; -import extensions from 'markdown-extensions'; -import { remark } from 'remark'; -import proc from 'remark/package.json'; -import cli from '../package.json'; -import lintNode from 'remark-preset-lint-node'; -import gfm from 'remark-gfm'; - -args({ - processor: remark().use(gfm).use(lintNode), - name: proc.name, - description: cli.description, - version: [ - proc.name + ': ' + proc.version, - cli.name + ': ' + cli.version, - ].join(', '), - pluginPrefix: proc.name, - presetPrefix: proc.name + '-preset', - packageField: proc.name + 'Config', - rcName: '.' + proc.name + 'rc', - ignoreName: '.' + proc.name + 'ignore', - extensions: extensions, - detectConfig: false, -}); diff --git a/vcbuild.bat b/vcbuild.bat index a91ee9b64c20f0..ec30fca533a0af 100644 --- a/vcbuild.bat +++ b/vcbuild.bat @@ -722,7 +722,7 @@ for /D %%D IN (doc\*) do ( set "lint_md_files="%%F" !lint_md_files!" ) ) -%node_exe% tools\lint-md.mjs -q -f %lint_md_files% +%node_exe% tools\lint-md\lint-md.mjs %lint_md_files% ENDLOCAL goto exit