X-Git-Url: https://git.josue.xyz/?p=dotfiles%2F.git;a=blobdiff_plain;f=.config%2Fcoc%2Fextensions%2Fnode_modules%2Fcoc-prettier%2Fnode_modules%2Fprettier%2Findex.js;h=ac945de92c62da5140f7bc4652852b7c6a0d04ea;hp=00433813e4aa5c81a11ccf5e3ecdec90a6200ac6;hb=4d07c77cf4d78cab8639e13ddc3c22495e585b0b;hpb=b3950616b54221c40a7dab9099bda675007e5b6e diff --git a/.config/coc/extensions/node_modules/coc-prettier/node_modules/prettier/index.js b/.config/coc/extensions/node_modules/coc-prettier/node_modules/prettier/index.js index 00433813..ac945de9 100755 --- a/.config/coc/extensions/node_modules/coc-prettier/node_modules/prettier/index.js +++ b/.config/coc/extensions/node_modules/coc-prettier/node_modules/prettier/index.js @@ -1,18 +1,27 @@ 'use strict'; -function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } - -var fs$3 = _interopDefault(require('fs')); -var path$2 = _interopDefault(require('path')); -var os$1 = _interopDefault(require('os')); -var tty$1 = _interopDefault(require('tty')); -var assert$1 = _interopDefault(require('assert')); -var util$3 = _interopDefault(require('util')); -var stream$6 = _interopDefault(require('stream')); -var events$1 = _interopDefault(require('events')); +var fs$4 = require('fs'); +var path$3 = require('path'); +var os$2 = require('os'); +var tty$2 = require('tty'); +var assert$2 = require('assert'); +var util$6 = require('util'); +var stream_1 = require('stream'); +var events_1 = require('events'); + +function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } + +var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs$4); +var path__default = /*#__PURE__*/_interopDefaultLegacy(path$3); +var os__default = /*#__PURE__*/_interopDefaultLegacy(os$2); +var tty__default = /*#__PURE__*/_interopDefaultLegacy(tty$2); +var assert__default = /*#__PURE__*/_interopDefaultLegacy(assert$2); +var util__default = /*#__PURE__*/_interopDefaultLegacy(util$6); +var stream_1__default = /*#__PURE__*/_interopDefaultLegacy(stream_1); +var events_1__default = /*#__PURE__*/_interopDefaultLegacy(events_1); var name = "prettier"; -var version = "2.0.5"; +var version = "2.2.1"; var description = "Prettier is an opinionated code formatter"; var bin = "./bin/prettier.js"; var repository = "prettier/prettier"; @@ -20,131 +29,156 @@ var homepage = "https://prettier.io"; var author = "James Long"; var license = "MIT"; var main = "./index.js"; +var browser = "./standalone.js"; +var unpkg = "./standalone.js"; var engines = { node: ">=10.13.0" }; +var files = [ + "index.js", + "standalone.js", + "src", + "bin" +]; var dependencies = { - "@angular/compiler": "9.0.5", - "@babel/code-frame": "7.8.0", - "@babel/parser": "7.9.4", - "@glimmer/syntax": "0.50.0", - "@iarna/toml": "2.2.3", - "@typescript-eslint/typescript-estree": "2.26.0", - "angular-estree-parser": "1.3.0", - "angular-html-parser": "1.4.0", - camelcase: "5.3.1", - chalk: "4.0.0", + "@angular/compiler": "10.2.3", + "@babel/code-frame": "7.10.4", + "@babel/parser": "7.12.5", + "@glimmer/syntax": "0.66.0", + "@iarna/toml": "2.2.5", + "@typescript-eslint/typescript-estree": "4.8.1", + "angular-estree-parser": "2.2.1", + "angular-html-parser": "1.7.1", + camelcase: "6.2.0", + chalk: "4.1.0", "ci-info": "watson/ci-info#f43f6a1cefff47fb361c88cf4b943fdbcaafe540", "cjk-regex": "2.0.0", - cosmiconfig: "6.0.0", + cosmiconfig: "7.0.0", dashify: "2.0.0", - dedent: "0.7.0", - diff: "4.0.2", + diff: "5.0.0", editorconfig: "0.15.3", - "editorconfig-to-prettier": "0.1.1", - "escape-string-regexp": "2.0.0", + "editorconfig-to-prettier": "0.2.0", + "escape-string-regexp": "4.0.0", + espree: "7.3.0", esutils: "2.0.3", - "fast-glob": "3.2.2", + "fast-glob": "3.2.4", + "fast-json-stable-stringify": "2.1.0", "find-parent-dir": "0.3.0", - "find-project-root": "1.1.1", - "flow-parser": "0.122.0", - "get-stream": "5.1.0", - globby: "11.0.0", - graphql: "15.0.0", - "html-element-attributes": "2.2.1", + "flow-parser": "0.138.0", + "get-stdin": "8.0.0", + globby: "11.0.1", + graphql: "15.4.0", + "html-element-attributes": "2.3.0", "html-styles": "1.0.0", "html-tag-names": "1.1.5", + "html-void-elements": "1.0.5", ignore: "4.0.6", - "jest-docblock": "25.2.6", - "json-stable-stringify": "1.0.1", + "jest-docblock": "26.0.0", + json5: "2.1.3", leven: "3.1.0", "lines-and-columns": "1.1.6", - "linguist-languages": "7.9.0", - lodash: "4.17.15", - mem: "6.0.1", + "linguist-languages": "7.12.1", + lodash: "4.17.20", + mem: "8.0.0", + meriyah: "3.1.6", minimatch: "3.0.4", minimist: "1.2.5", - "n-readlines": "1.0.0", + "n-readlines": "1.0.1", + outdent: "0.7.1", + "parse-srcset": "ikatyang/parse-srcset#54eb9c1cb21db5c62b4d0e275d7249516df6f0ee", "please-upgrade-node": "3.2.0", "postcss-less": "3.1.4", "postcss-media-query-parser": "0.2.3", - "postcss-scss": "2.0.0", + "postcss-scss": "2.1.1", "postcss-selector-parser": "2.2.3", "postcss-values-parser": "2.0.1", "regexp-util": "1.2.2", - "remark-math": "1.0.6", - "remark-parse": "5.0.0", - resolve: "1.16.1", - semver: "7.1.3", - srcset: "2.0.1", + "remark-footnotes": "2.0.0", + "remark-math": "3.0.1", + "remark-parse": "8.0.3", + resolve: "1.19.0", + semver: "7.3.2", "string-width": "4.2.0", - typescript: "3.8.3", + typescript: "4.1.2", "unicode-regex": "3.0.0", - unified: "9.0.0", + unified: "9.2.0", vnopts: "1.0.2", - "yaml-unist-parser": "1.1.1" + "yaml-unist-parser": "1.3.1" }; var devDependencies = { - "@babel/core": "7.9.0", - "@babel/preset-env": "7.9.0", - "@rollup/plugin-alias": "3.0.1", - "@rollup/plugin-commonjs": "11.0.2", - "@rollup/plugin-json": "4.0.2", - "@rollup/plugin-node-resolve": "7.1.1", - "@rollup/plugin-replace": "2.3.1", - "babel-loader": "8.1.0", + "@babel/core": "7.12.3", + "@babel/preset-env": "7.12.1", + "@babel/types": "7.12.6", + "@glimmer/reference": "0.66.0", + "@rollup/plugin-alias": "3.1.1", + "@rollup/plugin-babel": "5.2.1", + "@rollup/plugin-commonjs": "16.0.0", + "@rollup/plugin-json": "4.1.0", + "@rollup/plugin-node-resolve": "10.0.0", + "@rollup/plugin-replace": "2.3.4", + "@types/estree": "0.0.45", + "@types/node": "14.14.0", + "@typescript-eslint/types": "4.8.1", + "babel-jest": "26.6.3", + "babel-loader": "8.2.1", benchmark: "2.1.4", "builtin-modules": "3.1.0", - codecov: "3.6.5", "cross-env": "7.0.2", - cspell: "4.0.55", - eslint: "6.8.0", - "eslint-config-prettier": "6.10.1", + cspell: "4.2.2", + eslint: "7.13.0", + "eslint-config-prettier": "6.15.0", "eslint-formatter-friendly": "7.0.0", - "eslint-plugin-import": "2.20.2", - "eslint-plugin-prettier": "3.1.2", - "eslint-plugin-react": "7.19.0", - "eslint-plugin-unicorn": "18.0.1", - execa: "4.0.0", - jest: "25.2.7", + "eslint-plugin-import": "2.22.1", + "eslint-plugin-jest": "24.1.3", + "eslint-plugin-prettier-internal-rules": "file:scripts/tools/eslint-plugin-prettier-internal-rules", + "eslint-plugin-react": "7.21.5", + "eslint-plugin-unicorn": "23.0.0", + execa: "4.1.0", + jest: "26.6.3", "jest-snapshot-serializer-ansi": "1.0.0", "jest-snapshot-serializer-raw": "1.1.0", - "jest-watch-typeahead": "0.5.0", - prettier: "2.0.4", + "jest-watch-typeahead": "0.6.1", + "npm-run-all": "4.1.5", + "path-browserify": "1.0.1", + prettier: "2.2.0", rimraf: "3.0.2", - rollup: "2.3.2", - "rollup-plugin-babel": "4.4.0", + rollup: "2.33.3", "rollup-plugin-node-globals": "1.4.0", - "rollup-plugin-terser": "5.3.0", - shelljs: "0.8.3", - "snapshot-diff": "0.7.0", + "rollup-plugin-terser": "7.0.2", + shelljs: "0.8.4", + "snapshot-diff": "0.8.1", "strip-ansi": "6.0.0", - "synchronous-promise": "2.0.10", - tempy: "0.5.0", - "terser-webpack-plugin": "2.3.5", - webpack: "4.42.1" + "synchronous-promise": "2.0.15", + tempy: "1.0.0", + "terser-webpack-plugin": "5.0.3", + webpack: "5.5.1" }; var scripts = { prepublishOnly: "echo \"Error: must publish from dist/\" && exit 1", "prepare-release": "yarn && yarn build && yarn test:dist", test: "jest", + "test:dev-package": "cross-env INSTALL_PACKAGE=1 jest", "test:dist": "cross-env NODE_ENV=production jest", - "test:dist-standalone": "cross-env NODE_ENV=production TEST_STANDALONE=1 jest tests/", + "test:dist-standalone": "cross-env NODE_ENV=production TEST_STANDALONE=1 jest", "test:integration": "jest tests_integration", "perf:repeat": "yarn && yarn build && cross-env NODE_ENV=production node ./dist/bin-prettier.js --debug-repeat ${PERF_REPEAT:-1000} --loglevel debug ${PERF_FILE:-./index.js} > /dev/null", "perf:repeat-inspect": "yarn && yarn build && cross-env NODE_ENV=production node --inspect-brk ./dist/bin-prettier.js --debug-repeat ${PERF_REPEAT:-1000} --loglevel debug ${PERF_FILE:-./index.js} > /dev/null", "perf:benchmark": "yarn && yarn build && cross-env NODE_ENV=production node ./dist/bin-prettier.js --debug-benchmark --loglevel debug ${PERF_FILE:-./index.js} > /dev/null", + lint: "run-p lint:*", "lint:typecheck": "tsc", "lint:eslint": "cross-env EFF_NO_LINK_RULES=true eslint . --format friendly", "lint:changelog": "node ./scripts/lint-changelog.js", - "lint:prettier": "prettier \"**/*.{md,json,yml,html,css}\" --check", - "lint:dist": "eslint --no-eslintrc --no-ignore --env=es6,browser --parser-options=ecmaVersion:2016 \"dist/!(bin-prettier|index|third-party).js\"", - "lint:spellcheck": "cspell {bin,scripts,src,website}/**/*.js {docs,website/blog,changelog_unreleased}/**/*.md", + "lint:prettier": "prettier . \"!test*\" --check", + "lint:dist": "eslint --no-eslintrc --no-ignore --env=es6,browser --parser-options=ecmaVersion:2018 \"dist/!(bin-prettier|index|third-party).js\"", + "lint:spellcheck": "cspell \"**/*\" \".github/**/*\"", "lint:deps": "node ./scripts/check-deps.js", + fix: "run-s fix:eslint fix:prettier", + "fix:eslint": "yarn lint:eslint --fix", + "fix:prettier": "yarn lint:prettier --write", build: "node --max-old-space-size=3072 ./scripts/build/build.js", "build-docs": "node ./scripts/build-docs.js" }; -var _package = { +var require$$0 = { name: name, version: version, description: description, @@ -154,30 +188,15 @@ var _package = { author: author, license: license, main: main, + browser: browser, + unpkg: unpkg, engines: engines, + files: files, dependencies: dependencies, devDependencies: devDependencies, scripts: scripts }; -var _package$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - name: name, - version: version, - description: description, - bin: bin, - repository: repository, - homepage: homepage, - author: author, - license: license, - main: main, - engines: engines, - dependencies: dependencies, - devDependencies: devDependencies, - scripts: scripts, - 'default': _package -}); - function Diff() {} Diff.prototype = { @@ -487,7 +506,8 @@ wordDiff.equals = function (left, right) { }; wordDiff.tokenize = function (value) { - var tokens = value.split(/(\s+|[()[\]{}'"]|\b)/); // Join the boundary splits that we do not consider to be boundaries. This is primarily the extended Latin character set. + // All whitespace symbols except newline group into one token, each newline - in separate token + var tokens = value.split(/([^\S\r\n]+|[()[\]{}'"\r\n]|\b)/); // Join the boundary splits that we do not consider to be boundaries. This is primarily the extended Latin character set. for (var i = 0; i < tokens.length - 1; i++) { // If we have an empty string in the next field and we have only word chars before and after, merge @@ -572,6 +592,8 @@ function diffCss(oldStr, newStr, callback) { } function _typeof(obj) { + "@babel/helpers - typeof"; + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function (obj) { return typeof obj; @@ -586,23 +608,36 @@ function _typeof(obj) { } function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) { - for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; - - return arr2; - } + if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _iterableToArray(iter) { - if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); +} + +function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); +} + +function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + + return arr2; } function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance"); + throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var objectPrototypeToString = Object.prototype.toString; @@ -792,12 +827,23 @@ function parsePatch(uniDiff) { chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/); var hunk = { oldStart: +chunkHeader[1], - oldLines: +chunkHeader[2] || 1, + oldLines: typeof chunkHeader[2] === 'undefined' ? 1 : +chunkHeader[2], newStart: +chunkHeader[3], - newLines: +chunkHeader[4] || 1, + newLines: typeof chunkHeader[4] === 'undefined' ? 1 : +chunkHeader[4], lines: [], linedelimiters: [] - }; + }; // Unified Diff Format quirk: If the chunk size is 0, + // the first number is one lower than one would expect. + // https://www.artima.com/weblogs/viewpost.jsp?thread=164293 + + if (hunk.oldLines === 0) { + hunk.oldStart += 1; + } + + if (hunk.newLines === 0) { + hunk.newStart += 1; + } + var addCount = 0, removeCount = 0; @@ -990,11 +1036,6 @@ function applyPatch(source, uniDiff) { diffOffset += _hunk.newLines - _hunk.oldLines; - if (_toPos < 0) { - // Creating a new file - _toPos = 0; - } - for (var j = 0; j < _hunk.lines.length; j++) { var line = _hunk.lines[j], operation = line.length > 0 ? line[0] : ' ', @@ -1166,8 +1207,9 @@ function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, ne var newEOFNewline = /\n$/.test(newStr); var noNlBeforeAdds = lines.length == 0 && curRange.length > hunk.oldLines; - if (!oldEOFNewline && noNlBeforeAdds) { + if (!oldEOFNewline && noNlBeforeAdds && oldStr.length > 0) { // special case: old has no eol and no trailing context; no-nl can end up before adds + // however, if the old file is empty, do not output the no-nl line curRange.splice(hunk.oldLines, 0, '\\ No newline at end of file'); } @@ -1201,12 +1243,11 @@ function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, ne }; } -function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { - var diff = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options); +function formatPatch(diff) { var ret = []; - if (oldFileName == newFileName) { - ret.push('Index: ' + oldFileName); + if (diff.oldFileName == diff.newFileName) { + ret.push('Index: ' + diff.oldFileName); } ret.push('==================================================================='); @@ -1214,7 +1255,18 @@ function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader ret.push('+++ ' + diff.newFileName + (typeof diff.newHeader === 'undefined' ? '' : '\t' + diff.newHeader)); for (var i = 0; i < diff.hunks.length; i++) { - var hunk = diff.hunks[i]; + var hunk = diff.hunks[i]; // Unified Diff Format quirk: If the chunk size is 0, + // the first number is one lower than one would expect. + // https://www.artima.com/weblogs/viewpost.jsp?thread=164293 + + if (hunk.oldLines === 0) { + hunk.oldStart -= 1; + } + + if (hunk.newLines === 0) { + hunk.newStart -= 1; + } + ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines + ' +' + hunk.newStart + ',' + hunk.newLines + ' @@'); ret.push.apply(ret, hunk.lines); } @@ -1222,6 +1274,10 @@ function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader return ret.join('\n') + '\n'; } +function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { + return formatPatch(structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options)); +} + function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) { return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options); } @@ -1706,222 +1762,376 @@ function escapeHTML(s) { var index_es6 = /*#__PURE__*/Object.freeze({ __proto__: null, Diff: Diff, - diffChars: diffChars, - diffWords: diffWords, - diffWordsWithSpace: diffWordsWithSpace, - diffLines: diffLines, - diffTrimmedLines: diffTrimmedLines, - diffSentences: diffSentences, - diffCss: diffCss, - diffJson: diffJson, - diffArrays: diffArrays, - structuredPatch: structuredPatch, - createTwoFilesPatch: createTwoFilesPatch, - createPatch: createPatch, applyPatch: applyPatch, applyPatches: applyPatches, - parsePatch: parsePatch, - merge: merge, + canonicalize: canonicalize, convertChangesToDMP: convertChangesToDMP, convertChangesToXML: convertChangesToXML, - canonicalize: canonicalize + createPatch: createPatch, + createTwoFilesPatch: createTwoFilesPatch, + diffArrays: diffArrays, + diffChars: diffChars, + diffCss: diffCss, + diffJson: diffJson, + diffLines: diffLines, + diffSentences: diffSentences, + diffTrimmedLines: diffTrimmedLines, + diffWords: diffWords, + diffWordsWithSpace: diffWordsWithSpace, + merge: merge, + parsePatch: parsePatch, + structuredPatch: structuredPatch }); /** - * @class + * @param {Doc[]} parts + * @returns Doc */ -class LineByLine { - constructor(file, options) { - options = options || {}; - if (!options.readChunk) options.readChunk = 1024; +function concat(parts) { + // access the internals of a document directly. + // if(parts.length === 1) { + // // If it's a single document, no need to concat it. + // return parts[0]; + // } - if (!options.newLineCharacter) { - options.newLineCharacter = 0x0a; //linux line ending - } else { - options.newLineCharacter = options.newLineCharacter.charCodeAt(0); - } - if (typeof file === 'number') { - this.fd = file; - } else { - this.fd = fs$3.openSync(file, 'r'); - } + return { + type: "concat", + parts + }; +} +/** + * @param {Doc} contents + * @returns Doc + */ - this.options = options; - this.newLineCharacter = options.newLineCharacter; - this.reset(); - } - _searchInBuffer(buffer, hexNeedle) { - let found = -1; +function indent(contents) { - for (let i = 0; i <= buffer.length; i++) { - let b_byte = buffer[i]; + return { + type: "indent", + contents + }; +} +/** + * @param {number | string} n + * @param {Doc} contents + * @returns Doc + */ - if (b_byte === hexNeedle) { - found = i; - break; - } - } - return found; - } +function align(n, contents) { - reset() { - this.eofReached = false; - this.linesCache = []; - this.fdPosition = 0; - } + return { + type: "align", + contents, + n + }; +} +/** + * @param {Doc} contents + * @param {object} [opts] - TBD ??? + * @returns Doc + */ - close() { - fs$3.closeSync(this.fd); - this.fd = null; - } - _extractLines(buffer) { - let line; - const lines = []; - let bufferPosition = 0; - let lastNewLineBufferPosition = 0; +function group(contents, opts) { + opts = opts || {}; - while (true) { - let bufferPositionValue = buffer[bufferPosition++]; + return { + type: "group", + id: opts.id, + contents, + break: !!opts.shouldBreak, + expandedStates: opts.expandedStates + }; +} +/** + * @param {Doc} contents + * @returns Doc + */ - if (bufferPositionValue === this.newLineCharacter) { - line = buffer.slice(lastNewLineBufferPosition, bufferPosition); - lines.push(line); - lastNewLineBufferPosition = bufferPosition; - } else if (!bufferPositionValue) { - break; - } - } - let leftovers = buffer.slice(lastNewLineBufferPosition, bufferPosition); +function dedentToRoot(contents) { + return align(-Infinity, contents); +} +/** + * @param {Doc} contents + * @returns Doc + */ - if (leftovers.length) { - lines.push(leftovers); - } - return lines; - } +function markAsRoot(contents) { + // @ts-ignore - TBD ???: + return align({ + type: "root" + }, contents); +} +/** + * @param {Doc} contents + * @returns Doc + */ - _readChunk(lineLeftovers) { - let totalBytesRead = 0; - let bytesRead; - const buffers = []; - do { - const readBuffer = new Buffer(this.options.readChunk); - bytesRead = fs$3.readSync(this.fd, readBuffer, 0, this.options.readChunk, this.fdPosition); - totalBytesRead = totalBytesRead + bytesRead; - this.fdPosition = this.fdPosition + bytesRead; - buffers.push(readBuffer); - } while (bytesRead && this._searchInBuffer(buffers[buffers.length - 1], this.options.newLineCharacter) === -1); +function dedent(contents) { + return align(-1, contents); +} +/** + * @param {Doc[]} states + * @param {object} [opts] - TBD ??? + * @returns Doc + */ - let bufferData = Buffer.concat(buffers); - if (bytesRead < this.options.readChunk) { - this.eofReached = true; - bufferData = bufferData.slice(0, totalBytesRead); - } +function conditionalGroup(states, opts) { + return group(states[0], Object.assign({}, opts, { + expandedStates: states + })); +} +/** + * @param {Doc[]} parts + * @returns Doc + */ - if (totalBytesRead) { - this.linesCache = this._extractLines(bufferData); - if (lineLeftovers) { - this.linesCache[0] = Buffer.concat([lineLeftovers, this.linesCache[0]]); - } - } +function fill(parts) { - return totalBytesRead; - } + return { + type: "fill", + parts + }; +} +/** + * @param {Doc} [breakContents] + * @param {Doc} [flatContents] + * @param {object} [opts] - TBD ??? + * @returns Doc + */ - next() { - if (!this.fd) return false; - let line = false; - if (this.eofReached && this.linesCache.length === 0) { - return line; - } +function ifBreak(breakContents, flatContents, opts) { + opts = opts || {}; - let bytesRead; + return { + type: "if-break", + breakContents, + flatContents, + groupId: opts.groupId + }; +} +/** + * @param {Doc} contents + * @returns Doc + */ - if (!this.linesCache.length) { - bytesRead = this._readChunk(); - } - if (this.linesCache.length) { - line = this.linesCache.shift(); - const lastLineCharacter = line[line.length - 1]; +function lineSuffix(contents) { - if (lastLineCharacter !== 0x0a) { - bytesRead = this._readChunk(line); + return { + type: "line-suffix", + contents + }; +} - if (bytesRead) { - line = this.linesCache.shift(); - } - } - } +const lineSuffixBoundary = { + type: "line-suffix-boundary" +}; +const breakParent = { + type: "break-parent" +}; +const trim = { + type: "trim" +}; +const line = { + type: "line" +}; +const softline = { + type: "line", + soft: true +}; +const hardline = concat([{ + type: "line", + hard: true +}, breakParent]); +const literalline = concat([{ + type: "line", + hard: true, + literal: true +}, breakParent]); +const cursor = { + type: "cursor", + placeholder: Symbol("cursor") +}; +/** + * @param {Doc} sep + * @param {Doc[]} arr + * @returns Doc + */ - if (this.eofReached && this.linesCache.length === 0) { - this.close(); - } +function join(sep, arr) { + const res = []; - if (line && line[line.length - 1] === this.newLineCharacter) { - line = line.slice(0, line.length - 1); + for (let i = 0; i < arr.length; i++) { + if (i !== 0) { + res.push(sep); } - return line; + res.push(arr[i]); } + return concat(res); } - -var readlines = LineByLine; - /** - * The inverse of `_.toPairs`; this method returns an object composed - * from key-value `pairs`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} pairs The key-value pairs. - * @returns {Object} Returns the new object. - * @example - * - * _.fromPairs([['a', 1], ['b', 2]]); - * // => { 'a': 1, 'b': 2 } + * @param {Doc} doc + * @param {number} size + * @param {number} tabWidth */ -function fromPairs(pairs) { - var index = -1, - length = pairs == null ? 0 : pairs.length, - result = {}; - while (++index < length) { - var pair = pairs[index]; - result[pair[0]] = pair[1]; + +function addAlignmentToDoc(doc, size, tabWidth) { + let aligned = doc; + + if (size > 0) { + // Use indent to add tabs for all the levels of tabs we need + for (let i = 0; i < Math.floor(size / tabWidth); ++i) { + aligned = indent(aligned); + } // Use align for all the spaces that are needed + + + aligned = align(size % tabWidth, aligned); // size is absolute from 0 and not relative to the current + // indentation, so we use -Infinity to reset the indentation to 0 + + aligned = align(-Infinity, aligned); } - return result; + return aligned; } -var fromPairs_1 = fromPairs; +var docBuilders = { + concat, + join, + line, + softline, + hardline, + literalline, + group, + conditionalGroup, + fill, + lineSuffix, + lineSuffixBoundary, + cursor, + breakParent, + ifBreak, + trim, + indent, + align, + addAlignmentToDoc, + markAsRoot, + dedentToRoot, + dedent +}; -class ConfigError extends Error {} +var ansiRegex = ({ + onlyFirst = false +} = {}) => { + const pattern = ['[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[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'); +}; -class DebugError extends Error {} +var stripAnsi = string => typeof string === 'string' ? string.replace(ansiRegex(), '') : string; -class UndefinedParserError extends Error {} +/* eslint-disable yoda */ -var errors = { - ConfigError, - DebugError, - UndefinedParserError +const isFullwidthCodePoint = codePoint => { + if (Number.isNaN(codePoint)) { + return false; + } // Code points are derived from: + // http://www.unix.org/Public/UNIDATA/EastAsianWidth.txt + + + if (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)) { + return true; + } + + return false; +}; + +var isFullwidthCodePoint_1 = isFullwidthCodePoint; +var _default = isFullwidthCodePoint; +isFullwidthCodePoint_1.default = _default; + +var emojiRegex = function () { + // https://mths.be/emoji + return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\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\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])|\uD83C[\uDF3E\uDF73\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])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\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])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\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\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\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\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\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\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*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\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\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\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[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g; +}; + +const stringWidth = string => { + string = string.replace(emojiRegex(), ' '); + + if (typeof string !== 'string' || string.length === 0) { + return 0; + } + + string = stripAnsi(string); + let width = 0; + + for (let i = 0; i < string.length; i++) { + const code = string.codePointAt(i); // Ignore control characters + + if (code <= 0x1F || code >= 0x7F && code <= 0x9F) { + continue; + } // Ignore combining characters + + + if (code >= 0x300 && code <= 0x36F) { + continue; + } // Surrogates + + + if (code > 0xFFFF) { + i++; + } + + width += isFullwidthCodePoint_1(code) ? 2 : 1; + } + + return width; }; +var stringWidth_1 = stringWidth; // TODO: remove this in the next major version + +var _default$1 = stringWidth; +stringWidth_1.default = _default$1; + +var 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 \unnnn escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar. + + + return string.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d'); +}; + +var getLast = arr => arr[arr.length - 1]; + function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; @@ -1956,16 +2166,22 @@ var constants = { MAX_SAFE_COMPONENT_LENGTH }; -function unwrapExports (x) { - return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; +function createCommonjsModule(fn, basedir, module) { + return module = { + path: basedir, + exports: {}, + require: function (path, base) { + return commonjsRequire(path, (base === undefined || base === null) ? module.path : base); + } + }, fn(module, module.exports), module.exports; } -function createCommonjsModule(fn, module) { - return module = { exports: {} }, fn(module, module.exports), module.exports; +function getDefaultExportFromNamespaceIfPresent (n) { + return n && Object.prototype.hasOwnProperty.call(n, 'default') ? n['default'] : n; } -function getCjsExportFromNamespace (n) { - return n && n['default'] || n; +function commonjsRequire () { + throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs'); } var re_1 = createCommonjsModule(function (module, exports) { @@ -2073,14 +2289,11 @@ var re_1 = createCommonjsModule(function (module, exports) { 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*\\*'); + 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*$'); }); -var re_2 = re_1.re; -var re_3 = re_1.src; -var re_4 = re_1.t; -var re_5 = re_1.tildeTrimReplace; -var re_6 = re_1.caretTrimReplace; -var re_7 = re_1.comparatorTrimReplace; const numeric = /^[0-9]+$/; @@ -2431,66 +2644,222 @@ var arrayify = (object, keyName) => Object.entries(object).map(([key, value]) => [keyName]: key }, value)); -var dedent_1 = createCommonjsModule(function (module) { +var lib = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); // In the absence of a WeakSet or WeakMap implementation, don't break, but don't cache either. + + function noop() { + var args = []; - function dedent(strings) { - var raw = void 0; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + } - if (typeof strings === "string") { - // dedent can be used as a plain function - raw = [strings]; + function createWeakMap() { + if (typeof WeakMap !== 'undefined') { + return new WeakMap(); } else { - raw = strings.raw; - } // first, perform interpolation + return fakeSetOrMap(); + } + } + /** + * Creates and returns a no-op implementation of a WeakMap / WeakSet that never stores anything. + */ + + + function fakeSetOrMap() { + return { + add: noop, + delete: noop, + get: noop, + set: noop, + has: function (k) { + return false; + } + }; + } // Safe hasOwnProperty - var result = ""; + var hop = Object.prototype.hasOwnProperty; - for (var i = 0; i < raw.length; i++) { - result += raw[i]. // join lines when there is a suppressed newline - replace(/\\\n[ \t]*/g, ""). // handle escaped backticks - replace(/\\`/g, "`"); + var has = function (obj, prop) { + return hop.call(obj, prop); + }; // Copy all own enumerable properties from source to target - if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) { - result += arguments.length <= i + 1 ? undefined : arguments[i + 1]; + + function extend(target, source) { + for (var prop in source) { + if (has(source, prop)) { + target[prop] = source[prop]; } - } // now strip indentation + } + return target; + } - var lines = result.split("\n"); - var mindent = null; - lines.forEach(function (l) { - var m = l.match(/^(\s+)\S+/); + var reLeadingNewline = /^[ \t]*(?:\r\n|\r|\n)/; + var reTrailingNewline = /(?:\r\n|\r|\n)[ \t]*$/; + var reStartsWithNewlineOrIsEmpty = /^(?:[\r\n]|$)/; + var reDetectIndentation = /(?:\r\n|\r|\n)([ \t]*)(?:[^ \t\r\n]|$)/; + var reOnlyWhitespaceWithAtLeastOneNewline = /^[ \t]*[\r\n][ \t\r\n]*$/; - if (m) { - var indent = m[1].length; + function _outdentArray(strings, firstInterpolatedValueSetsIndentationLevel, options) { + // If first interpolated value is a reference to outdent, + // determine indentation level from the indentation of the interpolated value. + var indentationLevel = 0; + var match = strings[0].match(reDetectIndentation); - if (!mindent) { - // this is the first indented line - mindent = indent; - } else { - mindent = Math.min(mindent, indent); - } + if (match) { + indentationLevel = match[1].length; + } + + var reSource = "(\\r\\n|\\r|\\n).{0," + indentationLevel + "}"; + var reMatchIndent = new RegExp(reSource, 'g'); + + if (firstInterpolatedValueSetsIndentationLevel) { + strings = strings.slice(1); + } + + var newline = options.newline, + trimLeadingNewline = options.trimLeadingNewline, + trimTrailingNewline = options.trimTrailingNewline; + var normalizeNewlines = typeof newline === 'string'; + var l = strings.length; + var outdentedStrings = strings.map(function (v, i) { + // Remove leading indentation from all lines + v = v.replace(reMatchIndent, '$1'); // Trim a leading newline from the first string + + if (i === 0 && trimLeadingNewline) { + v = v.replace(reLeadingNewline, ''); + } // Trim a trailing newline from the last string + + + if (i === l - 1 && trimTrailingNewline) { + v = v.replace(reTrailingNewline, ''); + } // Normalize newlines + + + if (normalizeNewlines) { + v = v.replace(/\r\n|\n|\r/g, function (_) { + return newline; + }); } + + return v; }); + return outdentedStrings; + } + + function concatStringsAndValues(strings, values) { + var ret = ''; + + for (var i = 0, l = strings.length; i < l; i++) { + ret += strings[i]; + + if (i < l - 1) { + ret += values[i]; + } + } + + return ret; + } + + function isTemplateStringsArray(v) { + return has(v, 'raw') && has(v, 'length'); + } + /** + * It is assumed that opts will not change. If this is a problem, clone your options object and pass the clone to + * makeInstance + * @param options + * @return {outdent} + */ + + + function createInstance(options) { + /** Cache of pre-processed template literal arrays */ + var arrayAutoIndentCache = createWeakMap(); + /** + * Cache of pre-processed template literal arrays, where first interpolated value is a reference to outdent, + * before interpolated values are injected. + */ + + var arrayFirstInterpSetsIndentCache = createWeakMap(); + + function outdent(stringsOrOptions) { + var values = []; + + for (var _i = 1; _i < arguments.length; _i++) { + values[_i - 1] = arguments[_i]; + } + /* tslint:enable:no-shadowed-variable */ + + + if (isTemplateStringsArray(stringsOrOptions)) { + var strings = stringsOrOptions; // Is first interpolated value a reference to outdent, alone on its own line, without any preceding non-whitespace? + + var firstInterpolatedValueSetsIndentationLevel = (values[0] === outdent || values[0] === defaultOutdent) && reOnlyWhitespaceWithAtLeastOneNewline.test(strings[0]) && reStartsWithNewlineOrIsEmpty.test(strings[1]); // Perform outdentation + + var cache = firstInterpolatedValueSetsIndentationLevel ? arrayFirstInterpSetsIndentCache : arrayAutoIndentCache; + var renderedArray = cache.get(strings); + + if (!renderedArray) { + renderedArray = _outdentArray(strings, firstInterpolatedValueSetsIndentationLevel, options); + cache.set(strings, renderedArray); + } + /** If no interpolated values, skip concatenation step */ + - if (mindent !== null) { - result = lines.map(function (l) { - return l[0] === " " ? l.slice(mindent) : l; - }).join("\n"); - } // dedent eats leading and trailing whitespace too + if (values.length === 0) { + return renderedArray[0]; + } + /** Concatenate string literals with interpolated values */ - result = result.trim(); // handle escaped newlines at the end to ensure they don't get stripped too + var rendered = concatStringsAndValues(renderedArray, firstInterpolatedValueSetsIndentationLevel ? values.slice(1) : values); + return rendered; + } else { + // Create and return a new instance of outdent with the given options + return createInstance(extend(extend({}, options), stringsOrOptions || {})); + } + } - return result.replace(/\\n/g, "\n"); + var fullOutdent = extend(outdent, { + string: function (str) { + return _outdentArray([str], false, options)[0]; + } + }); + return fullOutdent; } + var defaultOutdent = createInstance({ + trimLeadingNewline: true, + trimTrailingNewline: true + }); + exports.outdent = defaultOutdent; // Named exports. Simple and preferred. + // import outdent from 'outdent'; + + exports.default = defaultOutdent; + { - module.exports = dedent; + // In webpack harmony-modules environments, module.exports is read-only, + // so we fail gracefully. + try { + module.exports = defaultOutdent; + Object.defineProperty(defaultOutdent, '__esModule', { + value: true + }); + defaultOutdent.default = defaultOutdent; + defaultOutdent.outdent = defaultOutdent; + } catch (e) {} } }); +const { + outdent +} = lib; const CATEGORY_CONFIG = "Config"; const CATEGORY_EDITOR = "Editor"; const CATEGORY_FORMAT = "Format"; @@ -2548,7 +2917,7 @@ const options = { end: Infinity, step: 1 }, - description: dedent_1` + description: outdent` Print (to stderr) where a cursor at the given position would move to after formatting. This option cannot be used with --range-start and --range-end. `, @@ -2577,7 +2946,7 @@ const options = { description: "Carriage Return character only (\\r), used very rarely" }, { value: "auto", - description: dedent_1` + description: outdent` Maintain existing (mixed values within one file are normalised by looking at what's used after the first line) ` @@ -2632,6 +3001,14 @@ const options = { value: "typescript", since: "1.4.0", description: "TypeScript" + }, { + value: "espree", + since: "2.2.0", + description: "JavaScript" + }, { + value: "meriyah", + since: "2.2.0", + description: "JavaScript" }, { value: "css", since: "1.7.1", @@ -2715,7 +3092,7 @@ const options = { value: [] }], category: CATEGORY_GLOBAL, - description: dedent_1` + description: outdent` Custom directory that contains prettier plugins in node_modules subdirectory. Overrides default behavior when plugins are searched relatively to the location of Prettier. Multiple values are accepted. @@ -2746,7 +3123,7 @@ const options = { end: Infinity, step: 1 }, - description: dedent_1` + description: outdent` Format code ending at a given character offset (exclusive). The range will extend forwards to the end of the selected statement. This option cannot be used with --cursor-offset. @@ -2763,7 +3140,7 @@ const options = { end: Infinity, step: 1 }, - description: dedent_1` + description: outdent` Format code starting at a given character offset. The range will extend backwards to the start of the first line containing the selected statement. This option cannot be used with --cursor-offset. @@ -2775,7 +3152,7 @@ const options = { category: CATEGORY_SPECIAL, type: "boolean", default: false, - description: dedent_1` + description: outdent` Require either '@prettier' or '@format' to be present in the file's first docblock comment in order for it to be formatted. `, @@ -2798,6 +3175,23 @@ const options = { type: "boolean", default: false, description: "Indent with tabs instead of spaces." + }, + embeddedLanguageFormatting: { + since: "2.1.0", + category: CATEGORY_GLOBAL, + type: "choice", + default: [{ + since: "2.1.0", + value: "auto" + }], + description: "Control how Prettier formats quoted code embedded in the file.", + choices: [{ + value: "auto", + description: "Format embedded code if Prettier can automatically identify it." + }, { + value: "off", + description: "Never automatically format embedded code." + }] } }; var coreOptions = { @@ -2811,8 +3205,6 @@ var coreOptions = { options }; -var require$$0 = getCjsExportFromNamespace(_package$1); - const semver$1 = { compare: compare_1, lt: lt_1, @@ -2840,6 +3232,7 @@ function getSupportInfo({ // pre-release version is smaller than the normal version in semver, // we need to treat it as the normal one so as to test new features. const version = currentVersion.split("-", 1)[0]; + const languages = plugins.reduce((all, plugin) => all.concat(plugin.languages || []), []).filter(filterSince); const options = arrayify(Object.assign({}, ...plugins.map(({ options }) => options), coreOptions$1), "name").filter(option => filterSince(option) && filterDeprecated(option)).sort((a, b) => a.name === b.name ? 0 : a.name < b.name ? -1 : 1).map(mapInternal).map(option => { @@ -2851,10 +3244,13 @@ function getSupportInfo({ if (Array.isArray(option.choices)) { option.choices = option.choices.filter(option => filterSince(option) && filterDeprecated(option)); + + if (option.name === "parser") { + collectParsersFromLanguages(option, languages, plugins); + } } - const filteredPlugins = plugins.filter(plugin => plugin.defaultOptions && plugin.defaultOptions[option.name] !== undefined); - const pluginDefaults = filteredPlugins.reduce((reduced, plugin) => { + const pluginDefaults = plugins.filter(plugin => plugin.defaultOptions && plugin.defaultOptions[option.name] !== undefined).reduce((reduced, plugin) => { reduced[plugin.name] = plugin.defaultOptions[option.name]; return reduced; }, {}); @@ -2862,7 +3258,6 @@ function getSupportInfo({ pluginDefaults }); }); - const languages = plugins.reduce((all, plugin) => all.concat(plugin.languages || []), []).filter(filterSince); return { languages, options @@ -2887,323 +3282,2296 @@ function getSupportInfo({ } } +function collectParsersFromLanguages(option, languages, plugins) { + const existingValues = new Set(option.choices.map(choice => choice.value)); + + for (const language of languages) { + if (language.parsers) { + for (const value of language.parsers) { + if (!existingValues.has(value)) { + existingValues.add(value); + const plugin = plugins.find(plugin => plugin.parsers && plugin.parsers[value]); + let description = language.name; + + if (plugin && plugin.name) { + description += ` (plugin: ${plugin.name})`; + } + + option.choices.push({ + value, + description + }); + } + } + } + } +} + var support = { getSupportInfo }; -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. All rights reserved. -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at http://www.apache.org/licenses/LICENSE-2.0 - -THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. - -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -***************************************************************************** */ +const { + getSupportInfo: getSupportInfo$1 +} = support; +const notAsciiRegex = /[^\x20-\x7F]/; -/* global Reflect, Promise */ -var extendStatics = function (d, b) { - extendStatics = Object.setPrototypeOf || { - __proto__: [] - } instanceof Array && function (d, b) { - d.__proto__ = b; - } || function (d, b) { - for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; - }; +const getPenultimate = arr => arr[arr.length - 2]; +/** + * @typedef {{backwards?: boolean}} SkipOptions + */ - return extendStatics(d, b); -}; +/** + * @param {string | RegExp} chars + * @returns {(text: string, index: number | false, opts?: SkipOptions) => number | false} + */ -function __extends(d, b) { - extendStatics(d, b); - function __() { - this.constructor = d; - } +function skip(chars) { + return (text, index, opts) => { + const backwards = opts && opts.backwards; // Allow `skip` functions to be threaded together without having + // to check for failures (did someone say monads?). - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -} -var __assign = function () { - __assign = Object.assign || function __assign(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; + /* istanbul ignore next */ - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + if (index === false) { + return false; } - return t; - }; - - return __assign.apply(this, arguments); -}; -function __rest(s, e) { - var t = {}; + const { + length + } = text; + let cursor = index; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; + while (cursor >= 0 && cursor < length) { + const c = text.charAt(cursor); - if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { - if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; - } - return t; -} -function __decorate(decorators, target, key, desc) { - var c = arguments.length, - r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, - d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -} -function __param(paramIndex, decorator) { - return function (target, key) { - decorator(target, key, paramIndex); - }; -} -function __metadata(metadataKey, metadataValue) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); -} -function __awaiter(thisArg, _arguments, P, generator) { - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { - try { - step(generator.next(value)); - } catch (e) { - reject(e); + if (chars instanceof RegExp) { + if (!chars.test(c)) { + return cursor; + } + } else if (!chars.includes(c)) { + return cursor; } - } - function rejected(value) { - try { - step(generator["throw"](value)); - } catch (e) { - reject(e); - } + backwards ? cursor-- : cursor++; } - function step(result) { - result.done ? resolve(result.value) : new P(function (resolve) { - resolve(result.value); - }).then(fulfilled, rejected); + if (cursor === -1 || cursor === length) { + // If we reached the beginning or end of the file, return the + // out-of-bounds cursor. It's up to the caller to handle this + // correctly. We don't want to indicate `false` though if it + // actually skipped valid characters. + return cursor; } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); + return false; + }; } -function __generator(thisArg, body) { - var _ = { - label: 0, - sent: function () { - if (t[0] & 1) throw t[1]; - return t[1]; - }, - trys: [], - ops: [] - }, - f, - y, - t, - g; - return g = { - next: verb(0), - "throw": verb(1), - "return": verb(2) - }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { - return this; - }), g; +/** + * @type {(text: string, index: number | false, opts?: SkipOptions) => number | false} + */ - function verb(n) { - return function (v) { - return step([n, v]); - }; - } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); +const skipWhitespace = skip(/\s/); +/** + * @type {(text: string, index: number | false, opts?: SkipOptions) => number | false} + */ - while (_) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; +const skipSpaces = skip(" \t"); +/** + * @type {(text: string, index: number | false, opts?: SkipOptions) => number | false} + */ - switch (op[0]) { - case 0: - case 1: - t = op; - break; +const skipToLineEnd = skip(",; \t"); +/** + * @type {(text: string, index: number | false, opts?: SkipOptions) => number | false} + */ - case 4: - _.label++; - return { - value: op[1], - done: false - }; +const skipEverythingButNewLine = skip(/[^\n\r]/); +/** + * @param {string} text + * @param {number | false} index + * @returns {number | false} + */ - case 5: - _.label++; - y = op[1]; - op = [0]; - continue; +function skipInlineComment(text, index) { + /* istanbul ignore next */ + if (index === false) { + return false; + } - case 7: - op = _.ops.pop(); + if (text.charAt(index) === "/" && text.charAt(index + 1) === "*") { + for (let i = index + 2; i < text.length; ++i) { + if (text.charAt(i) === "*" && text.charAt(i + 1) === "/") { + return i + 2; + } + } + } - _.trys.pop(); + return index; +} +/** + * @param {string} text + * @param {number | false} index + * @returns {number | false} + */ - continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { - _ = 0; - continue; - } +function skipTrailingComment(text, index) { + /* istanbul ignore next */ + if (index === false) { + return false; + } - if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { - _.label = op[1]; - break; - } + if (text.charAt(index) === "/" && text.charAt(index + 1) === "/") { + return skipEverythingButNewLine(text, index); + } - if (op[0] === 6 && _.label < t[1]) { - _.label = t[1]; - t = op; - break; - } + return index; +} // This one doesn't use the above helper function because it wants to +// test \r\n in order and `skip` doesn't support ordering and we only +// want to skip one newline. It's simple to implement. - if (t && _.label < t[2]) { - _.label = t[2]; +/** + * @param {string} text + * @param {number | false} index + * @param {SkipOptions=} opts + * @returns {number | false} + */ - _.ops.push(op); - break; - } +function skipNewline(text, index, opts) { + const backwards = opts && opts.backwards; - if (t[2]) _.ops.pop(); + if (index === false) { + return false; + } - _.trys.pop(); + const atIndex = text.charAt(index); - continue; - } + if (backwards) { + // We already replace `\r\n` with `\n` before parsing - op = body.call(thisArg, _); - } catch (e) { - op = [6, e]; - y = 0; - } finally { - f = t = 0; + /* istanbul ignore next */ + if (text.charAt(index - 1) === "\r" && atIndex === "\n") { + return index - 2; } - if (op[0] & 5) throw op[1]; - return { - value: op[0] ? op[1] : void 0, - done: true - }; - } -} -function __exportStar(m, exports) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; -} -function __values(o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], - i = 0; - if (m) return m.call(o); - return { - next: function () { - if (o && i >= o.length) o = void 0; - return { - value: o && o[i++], - done: !o - }; + if (atIndex === "\n" || atIndex === "\r" || atIndex === "\u2028" || atIndex === "\u2029") { + return index - 1; } - }; -} -function __read(o, n) { - var m = typeof Symbol === "function" && o[Symbol.iterator]; - if (!m) return o; - var i = m.call(o), - r, - ar = [], - e; + } else { + // We already replace `\r\n` with `\n` before parsing - try { - while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); - } catch (error) { - e = { - error: error - }; - } finally { - try { - if (r && !r.done && (m = i["return"])) m.call(i); - } finally { - if (e) throw e.error; + /* istanbul ignore next */ + if (atIndex === "\r" && text.charAt(index + 1) === "\n") { + return index + 2; } - } - return ar; -} -function __spread() { - for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); + if (atIndex === "\n" || atIndex === "\r" || atIndex === "\u2028" || atIndex === "\u2029") { + return index + 1; + } + } - return ar; + return index; } -function __spreadArrays() { - for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; +/** + * @param {string} text + * @param {number} index + * @param {SkipOptions=} opts + * @returns {boolean} + */ - for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; - return r; -} -function __await(v) { - return this instanceof __await ? (this.v = v, this) : new __await(v); +function hasNewline(text, index, opts) { + opts = opts || {}; + const idx = skipSpaces(text, opts.backwards ? index - 1 : index, opts); + const idx2 = skipNewline(text, idx, opts); + return idx !== idx2; } -function __asyncGenerator(thisArg, _arguments, generator) { - if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); - var g = generator.apply(thisArg, _arguments || []), - i, - q = []; - return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { - return this; - }, i; +/** + * @param {string} text + * @param {number} start + * @param {number} end + * @returns {boolean} + */ - function verb(n) { - if (g[n]) i[n] = function (v) { - return new Promise(function (a, b) { - q.push([n, v, a, b]) > 1 || resume(n, v); - }); - }; - } - function resume(n, v) { - try { - step(g[n](v)); - } catch (e) { - settle(q[0][3], e); +function hasNewlineInRange(text, start, end) { + for (let i = start; i < end; ++i) { + if (text.charAt(i) === "\n") { + return true; } } - function step(r) { - r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); - } + return false; +} // Note: this function doesn't ignore leading comments unlike isNextLineEmpty - function fulfill(value) { - resume("next", value); - } +/** + * @template N + * @param {string} text + * @param {N} node + * @param {(node: N) => number} locStart + */ - function reject(value) { - resume("throw", value); - } - function settle(f, v) { - if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); - } +function isPreviousLineEmpty(text, node, locStart) { + /** @type {number | false} */ + let idx = locStart(node) - 1; + idx = skipSpaces(text, idx, { + backwards: true + }); + idx = skipNewline(text, idx, { + backwards: true + }); + idx = skipSpaces(text, idx, { + backwards: true + }); + const idx2 = skipNewline(text, idx, { + backwards: true + }); + return idx !== idx2; } -function __asyncDelegator(o) { - var i, p; - return i = {}, verb("next"), verb("throw", function (e) { - throw e; - }), verb("return"), i[Symbol.iterator] = function () { - return this; +/** + * @param {string} text + * @param {number} index + * @returns {boolean} + */ + + +function isNextLineEmptyAfterIndex(text, index) { + /** @type {number | false} */ + let oldIdx = null; + /** @type {number | false} */ + + let idx = index; + + while (idx !== oldIdx) { + // We need to skip all the potential trailing inline comments + oldIdx = idx; + idx = skipToLineEnd(text, idx); + idx = skipInlineComment(text, idx); + idx = skipSpaces(text, idx); + } + + idx = skipTrailingComment(text, idx); + idx = skipNewline(text, idx); + return idx !== false && hasNewline(text, idx); +} +/** + * @template N + * @param {string} text + * @param {N} node + * @param {(node: N) => number} locEnd + * @returns {boolean} + */ + + +function isNextLineEmpty(text, node, locEnd) { + return isNextLineEmptyAfterIndex(text, locEnd(node)); +} +/** + * @param {string} text + * @param {number} idx + * @returns {number | false} + */ + + +function getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, idx) { + /** @type {number | false} */ + let oldIdx = null; + /** @type {number | false} */ + + let nextIdx = idx; + + while (nextIdx !== oldIdx) { + oldIdx = nextIdx; + nextIdx = skipSpaces(text, nextIdx); + nextIdx = skipInlineComment(text, nextIdx); + nextIdx = skipTrailingComment(text, nextIdx); + nextIdx = skipNewline(text, nextIdx); + } + + return nextIdx; +} +/** + * @template N + * @param {string} text + * @param {N} node + * @param {(node: N) => number} locEnd + * @returns {number | false} + */ + + +function getNextNonSpaceNonCommentCharacterIndex(text, node, locEnd) { + return getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, locEnd(node)); +} +/** + * @template N + * @param {string} text + * @param {N} node + * @param {(node: N) => number} locEnd + * @returns {string} + */ + + +function getNextNonSpaceNonCommentCharacter(text, node, locEnd) { + return text.charAt( // @ts-ignore => TBD: can return false, should we define a fallback? + getNextNonSpaceNonCommentCharacterIndex(text, node, locEnd)); +} // Not using, but it's public utils + +/* istanbul ignore next */ + +/** + * @param {string} text + * @param {number} index + * @param {SkipOptions=} opts + * @returns {boolean} + */ + + +function hasSpaces(text, index, opts) { + opts = opts || {}; + const idx = skipSpaces(text, opts.backwards ? index - 1 : index, opts); + return idx !== index; +} +/** + * @param {string} value + * @param {number} tabWidth + * @param {number=} startIndex + * @returns {number} + */ + + +function getAlignmentSize(value, tabWidth, startIndex) { + startIndex = startIndex || 0; + let size = 0; + + for (let i = startIndex; i < value.length; ++i) { + if (value[i] === "\t") { + // Tabs behave in a way that they are aligned to the nearest + // multiple of tabWidth: + // 0 -> 4, 1 -> 4, 2 -> 4, 3 -> 4 + // 4 -> 8, 5 -> 8, 6 -> 8, 7 -> 8 ... + size = size + tabWidth - size % tabWidth; + } else { + size++; + } + } + + return size; +} +/** + * @param {string} value + * @param {number} tabWidth + * @returns {number} + */ + + +function getIndentSize(value, tabWidth) { + const lastNewlineIndex = value.lastIndexOf("\n"); + + if (lastNewlineIndex === -1) { + return 0; + } + + return getAlignmentSize( // All the leading whitespaces + value.slice(lastNewlineIndex + 1).match(/^[\t ]*/)[0], tabWidth); +} +/** + * @typedef {'"' | "'"} Quote + */ + +/** + * + * @param {string} raw + * @param {Quote} preferredQuote + * @returns {Quote} + */ + + +function getPreferredQuote(raw, preferredQuote) { + // `rawContent` is the string exactly like it appeared in the input source + // code, without its enclosing quotes. + const rawContent = raw.slice(1, -1); + /** @type {{ quote: '"', regex: RegExp }} */ + + const double = { + quote: '"', + regex: /"/g + }; + /** @type {{ quote: "'", regex: RegExp }} */ + + const single = { + quote: "'", + regex: /'/g + }; + const preferred = preferredQuote === "'" ? single : double; + const alternate = preferred === single ? double : single; + let result = preferred.quote; // If `rawContent` contains at least one of the quote preferred for enclosing + // the string, we might want to enclose with the alternate quote instead, to + // minimize the number of escaped quotes. + + if (rawContent.includes(preferred.quote) || rawContent.includes(alternate.quote)) { + const numPreferredQuotes = (rawContent.match(preferred.regex) || []).length; + const numAlternateQuotes = (rawContent.match(alternate.regex) || []).length; + result = numPreferredQuotes > numAlternateQuotes ? alternate.quote : preferred.quote; + } + + return result; +} + +function printString(raw, options, isDirectiveLiteral) { + // `rawContent` is the string exactly like it appeared in the input source + // code, without its enclosing quotes. + const rawContent = raw.slice(1, -1); // Check for the alternate quote, to determine if we're allowed to swap + // the quotes on a DirectiveLiteral. + + const canChangeDirectiveQuotes = !rawContent.includes('"') && !rawContent.includes("'"); + /** @type {Quote} */ + + const enclosingQuote = options.parser === "json" ? '"' : options.__isInHtmlAttribute ? "'" : getPreferredQuote(raw, options.singleQuote ? "'" : '"'); // Directives are exact code unit sequences, which means that you can't + // change the escape sequences they use. + // See https://github.com/prettier/prettier/issues/1555 + // and https://tc39.github.io/ecma262/#directive-prologue + + if (isDirectiveLiteral) { + if (canChangeDirectiveQuotes) { + return enclosingQuote + rawContent + enclosingQuote; + } + + return raw; + } // It might sound unnecessary to use `makeString` even if the string already + // is enclosed with `enclosingQuote`, but it isn't. The string could contain + // unnecessary escapes (such as in `"\'"`). Always using `makeString` makes + // sure that we consistently output the minimum amount of escaped quotes. + + + return makeString(rawContent, enclosingQuote, !(options.parser === "css" || options.parser === "less" || options.parser === "scss" || options.embeddedInHtml)); +} +/** + * @param {string} rawContent + * @param {Quote} enclosingQuote + * @param {boolean=} unescapeUnnecessaryEscapes + * @returns {string} + */ + + +function makeString(rawContent, enclosingQuote, unescapeUnnecessaryEscapes) { + const otherQuote = enclosingQuote === '"' ? "'" : '"'; // Matches _any_ escape and unescaped quotes (both single and double). + + const regex = /\\([\S\s])|(["'])/g; // Escape and unescape single and double quotes as needed to be able to + // enclose `rawContent` with `enclosingQuote`. + + const newContent = rawContent.replace(regex, (match, escaped, quote) => { + // If we matched an escape, and the escaped character is a quote of the + // other type than we intend to enclose the string with, there's no need for + // it to be escaped, so return it _without_ the backslash. + if (escaped === otherQuote) { + return escaped; + } // If we matched an unescaped quote and it is of the _same_ type as we + // intend to enclose the string with, it must be escaped, so return it with + // a backslash. + + + if (quote === enclosingQuote) { + return "\\" + quote; + } + + if (quote) { + return quote; + } // Unescape any unnecessarily escaped character. + // Adapted from https://github.com/eslint/eslint/blob/de0b4ad7bd820ade41b1f606008bea68683dc11a/lib/rules/no-useless-escape.js#L27 + + + return unescapeUnnecessaryEscapes && /^[^\n\r"'0-7\\bfnrt-vx\u2028\u2029]$/.test(escaped) ? escaped : "\\" + escaped; + }); + return enclosingQuote + newContent + enclosingQuote; +} + +function printNumber(rawNumber) { + return rawNumber.toLowerCase() // Remove unnecessary plus and zeroes from scientific notation. + .replace(/^([+-]?[\d.]+e)(?:\+|(-))?0*(\d)/, "$1$2$3") // Remove unnecessary scientific notation (1e0). + .replace(/^([+-]?[\d.]+)e[+-]?0+$/, "$1") // Make sure numbers always start with a digit. + .replace(/^([+-])?\./, "$10.") // Remove extraneous trailing decimal zeroes. + .replace(/(\.\d+?)0+(?=e|$)/, "$1") // Remove trailing dot. + .replace(/\.(?=e|$)/, ""); +} +/** + * @param {string} str + * @param {string} target + * @returns {number} + */ + + +function getMaxContinuousCount(str, target) { + const results = str.match(new RegExp(`(${escapeStringRegexp(target)})+`, "g")); + + if (results === null) { + return 0; + } + + return results.reduce((maxCount, result) => Math.max(maxCount, result.length / target.length), 0); +} + +function getMinNotPresentContinuousCount(str, target) { + const matches = str.match(new RegExp(`(${escapeStringRegexp(target)})+`, "g")); + + if (matches === null) { + return 0; + } + + const countPresent = new Map(); + let max = 0; + + for (const match of matches) { + const count = match.length / target.length; + countPresent.set(count, true); + + if (count > max) { + max = count; + } + } + + for (let i = 1; i < max; i++) { + if (!countPresent.get(i)) { + return i; + } + } + + return max + 1; +} +/** + * @param {string} text + * @returns {number} + */ + + +function getStringWidth(text) { + if (!text) { + return 0; + } // shortcut to avoid needless string `RegExp`s, replacements, and allocations within `string-width` + + + if (!notAsciiRegex.test(text)) { + return text.length; + } + + return stringWidth_1(text); +} + +function isNodeIgnoreComment(comment) { + return comment.value.trim() === "prettier-ignore"; +} + +function addCommentHelper(node, comment) { + const comments = node.comments || (node.comments = []); + comments.push(comment); + comment.printed = false; // For some reason, TypeScript parses `// x` inside of JSXText as a comment + // We already "print" it via the raw text, we don't need to re-print it as a + // comment + + /* istanbul ignore next */ + + if (node.type === "JSXText") { + comment.printed = true; + } +} + +function addLeadingComment(node, comment) { + comment.leading = true; + comment.trailing = false; + addCommentHelper(node, comment); +} + +function addDanglingComment(node, comment, marker) { + comment.leading = false; + comment.trailing = false; + + if (marker) { + comment.marker = marker; + } + + addCommentHelper(node, comment); +} + +function addTrailingComment(node, comment) { + comment.leading = false; + comment.trailing = true; + addCommentHelper(node, comment); +} + +function replaceEndOfLineWith(text, replacement) { + const parts = []; + + for (const part of text.split("\n")) { + if (parts.length !== 0) { + parts.push(replacement); + } + + parts.push(part); + } + + return parts; +} + +function inferParserByLanguage(language, options) { + const { + languages + } = getSupportInfo$1({ + plugins: options.plugins + }); + const matched = languages.find(({ + name + }) => name.toLowerCase() === language) || languages.find(({ + aliases + }) => Array.isArray(aliases) && aliases.includes(language)) || languages.find(({ + extensions + }) => Array.isArray(extensions) && extensions.includes(`.${language}`)); + return matched && matched.parsers[0]; +} + +function isFrontMatterNode(node) { + return node && node.type === "front-matter"; +} + +function getShebang(text) { + if (!text.startsWith("#!")) { + return ""; + } + + const index = text.indexOf("\n"); + + if (index === -1) { + return text; + } + + return text.slice(0, index); +} + +var util = { + inferParserByLanguage, + replaceEndOfLineWith, + getStringWidth, + getMaxContinuousCount, + getMinNotPresentContinuousCount, + getPenultimate, + getLast, + getNextNonSpaceNonCommentCharacterIndexWithStartIndex, + getNextNonSpaceNonCommentCharacterIndex, + getNextNonSpaceNonCommentCharacter, + skip, + skipWhitespace, + skipSpaces, + skipToLineEnd, + skipEverythingButNewLine, + skipInlineComment, + skipTrailingComment, + skipNewline, + isNextLineEmptyAfterIndex, + isNextLineEmpty, + isPreviousLineEmpty, + hasNewline, + hasNewlineInRange, + hasSpaces, + getAlignmentSize, + getIndentSize, + getPreferredQuote, + printString, + printNumber, + isNodeIgnoreComment, + makeString, + addLeadingComment, + addDanglingComment, + addTrailingComment, + isFrontMatterNode, + getShebang +}; + +function guessEndOfLine(text) { + const index = text.indexOf("\r"); + + if (index >= 0) { + return text.charAt(index + 1) === "\n" ? "crlf" : "cr"; + } + + return "lf"; +} + +function convertEndOfLineToChars(value) { + switch (value) { + case "cr": + return "\r"; + + case "crlf": + return "\r\n"; + + default: + return "\n"; + } +} + +function countEndOfLineChars(text, eol) { + let regex; + /* istanbul ignore else */ + + if (eol === "\n") { + regex = /\n/g; + } else if (eol === "\r") { + regex = /\r/g; + } else if (eol === "\r\n") { + regex = /\r\n/g; + } else { + throw new Error(`Unexpected "eol" ${JSON.stringify(eol)}.`); + } + + const endOfLines = text.match(regex); + return endOfLines ? endOfLines.length : 0; +} + +function normalizeEndOfLine(text) { + return text.replace(/\r\n?/g, "\n"); +} + +var endOfLine = { + guessEndOfLine, + convertEndOfLineToChars, + countEndOfLineChars, + normalizeEndOfLine +}; + +const { + getStringWidth: getStringWidth$1 +} = util; +const { + convertEndOfLineToChars: convertEndOfLineToChars$1 +} = endOfLine; +const { + concat: concat$1, + fill: fill$1, + cursor: cursor$1 +} = docBuilders; +/** @type {Record} */ + +let groupModeMap; +const MODE_BREAK = 1; +const MODE_FLAT = 2; + +function rootIndent() { + return { + value: "", + length: 0, + queue: [] + }; +} + +function makeIndent(ind, options) { + return generateInd(ind, { + type: "indent" + }, options); +} + +function makeAlign(indent, n, options) { + if (n === -Infinity) { + return indent.root || rootIndent(); + } + + if (n < 0) { + return generateInd(indent, { + type: "dedent" + }, options); + } + + if (!n) { + return indent; + } + + if (n.type === "root") { + return Object.assign({}, indent, { + root: indent + }); + } + + const alignType = typeof n === "string" ? "stringAlign" : "numberAlign"; + return generateInd(indent, { + type: alignType, + n + }, options); +} + +function generateInd(ind, newPart, options) { + const queue = newPart.type === "dedent" ? ind.queue.slice(0, -1) : ind.queue.concat(newPart); + let value = ""; + let length = 0; + let lastTabs = 0; + let lastSpaces = 0; + + for (const part of queue) { + switch (part.type) { + case "indent": + flush(); + + if (options.useTabs) { + addTabs(1); + } else { + addSpaces(options.tabWidth); + } + + break; + + case "stringAlign": + flush(); + value += part.n; + length += part.n.length; + break; + + case "numberAlign": + lastTabs += 1; + lastSpaces += part.n; + break; + + /* istanbul ignore next */ + + default: + throw new Error(`Unexpected type '${part.type}'`); + } + } + + flushSpaces(); + return Object.assign({}, ind, { + value, + length, + queue + }); + + function addTabs(count) { + value += "\t".repeat(count); + length += options.tabWidth * count; + } + + function addSpaces(count) { + value += " ".repeat(count); + length += count; + } + + function flush() { + if (options.useTabs) { + flushTabs(); + } else { + flushSpaces(); + } + } + + function flushTabs() { + if (lastTabs > 0) { + addTabs(lastTabs); + } + + resetLast(); + } + + function flushSpaces() { + if (lastSpaces > 0) { + addSpaces(lastSpaces); + } + + resetLast(); + } + + function resetLast() { + lastTabs = 0; + lastSpaces = 0; + } +} + +function trim$1(out) { + if (out.length === 0) { + return 0; + } + + let trimCount = 0; // Trim whitespace at the end of line + + while (out.length > 0 && typeof out[out.length - 1] === "string" && out[out.length - 1].match(/^[\t ]*$/)) { + trimCount += out.pop().length; + } + + if (out.length && typeof out[out.length - 1] === "string") { + const trimmed = out[out.length - 1].replace(/[\t ]*$/, ""); + trimCount += out[out.length - 1].length - trimmed.length; + out[out.length - 1] = trimmed; + } + + return trimCount; +} + +function fits(next, restCommands, width, options, mustBeFlat) { + let restIdx = restCommands.length; + const cmds = [next]; // `out` is only used for width counting because `trim` requires to look + // backwards for space characters. + + const out = []; + + while (width >= 0) { + if (cmds.length === 0) { + if (restIdx === 0) { + return true; + } + + cmds.push(restCommands[restIdx - 1]); + restIdx--; + continue; + } + + const [ind, mode, doc] = cmds.pop(); + + if (typeof doc === "string") { + out.push(doc); + width -= getStringWidth$1(doc); + } else { + switch (doc.type) { + case "concat": + for (let i = doc.parts.length - 1; i >= 0; i--) { + cmds.push([ind, mode, doc.parts[i]]); + } + + break; + + case "indent": + cmds.push([makeIndent(ind, options), mode, doc.contents]); + break; + + case "align": + cmds.push([makeAlign(ind, doc.n, options), mode, doc.contents]); + break; + + case "trim": + width += trim$1(out); + break; + + case "group": + if (mustBeFlat && doc.break) { + return false; + } + + cmds.push([ind, doc.break ? MODE_BREAK : mode, doc.contents]); + + if (doc.id) { + groupModeMap[doc.id] = cmds[cmds.length - 1][1]; + } + + break; + + case "fill": + for (let i = doc.parts.length - 1; i >= 0; i--) { + cmds.push([ind, mode, doc.parts[i]]); + } + + break; + + case "if-break": + { + const groupMode = doc.groupId ? groupModeMap[doc.groupId] : mode; + + if (groupMode === MODE_BREAK) { + if (doc.breakContents) { + cmds.push([ind, mode, doc.breakContents]); + } + } + + if (groupMode === MODE_FLAT) { + if (doc.flatContents) { + cmds.push([ind, mode, doc.flatContents]); + } + } + + break; + } + + case "line": + switch (mode) { + // fallthrough + case MODE_FLAT: + if (!doc.hard) { + if (!doc.soft) { + out.push(" "); + width -= 1; + } + + break; + } + + return true; + + case MODE_BREAK: + return true; + } + + break; + } + } + } + + return false; +} + +function printDocToString(doc, options) { + groupModeMap = {}; + const width = options.printWidth; + const newLine = convertEndOfLineToChars$1(options.endOfLine); + let pos = 0; // cmds is basically a stack. We've turned a recursive call into a + // while loop which is much faster. The while loop below adds new + // cmds to the array instead of recursively calling `print`. + + const cmds = [[rootIndent(), MODE_BREAK, doc]]; + const out = []; + let shouldRemeasure = false; + let lineSuffix = []; + + while (cmds.length !== 0) { + const [ind, mode, doc] = cmds.pop(); + + if (typeof doc === "string") { + const formatted = newLine !== "\n" && doc.includes("\n") ? doc.replace(/\n/g, newLine) : doc; + out.push(formatted); + pos += getStringWidth$1(formatted); + } else { + switch (doc.type) { + case "cursor": + out.push(cursor$1.placeholder); + break; + + case "concat": + for (let i = doc.parts.length - 1; i >= 0; i--) { + cmds.push([ind, mode, doc.parts[i]]); + } + + break; + + case "indent": + cmds.push([makeIndent(ind, options), mode, doc.contents]); + break; + + case "align": + cmds.push([makeAlign(ind, doc.n, options), mode, doc.contents]); + break; + + case "trim": + pos -= trim$1(out); + break; + + case "group": + switch (mode) { + case MODE_FLAT: + if (!shouldRemeasure) { + cmds.push([ind, doc.break ? MODE_BREAK : MODE_FLAT, doc.contents]); + break; + } + + // fallthrough + + case MODE_BREAK: + { + shouldRemeasure = false; + const next = [ind, MODE_FLAT, doc.contents]; + const rem = width - pos; + + if (!doc.break && fits(next, cmds, rem, options)) { + cmds.push(next); + } else { + // Expanded states are a rare case where a document + // can manually provide multiple representations of + // itself. It provides an array of documents + // going from the least expanded (most flattened) + // representation first to the most expanded. If a + // group has these, we need to manually go through + // these states and find the first one that fits. + if (doc.expandedStates) { + const mostExpanded = doc.expandedStates[doc.expandedStates.length - 1]; + + if (doc.break) { + cmds.push([ind, MODE_BREAK, mostExpanded]); + break; + } else { + for (let i = 1; i < doc.expandedStates.length + 1; i++) { + if (i >= doc.expandedStates.length) { + cmds.push([ind, MODE_BREAK, mostExpanded]); + break; + } else { + const state = doc.expandedStates[i]; + const cmd = [ind, MODE_FLAT, state]; + + if (fits(cmd, cmds, rem, options)) { + cmds.push(cmd); + break; + } + } + } + } + } else { + cmds.push([ind, MODE_BREAK, doc.contents]); + } + } + + break; + } + } + + if (doc.id) { + groupModeMap[doc.id] = cmds[cmds.length - 1][1]; + } + + break; + // Fills each line with as much code as possible before moving to a new + // line with the same indentation. + // + // Expects doc.parts to be an array of alternating content and + // whitespace. The whitespace contains the linebreaks. + // + // For example: + // ["I", line, "love", line, "monkeys"] + // or + // [{ type: group, ... }, softline, { type: group, ... }] + // + // It uses this parts structure to handle three main layout cases: + // * The first two content items fit on the same line without + // breaking + // -> output the first content item and the whitespace "flat". + // * Only the first content item fits on the line without breaking + // -> output the first content item "flat" and the whitespace with + // "break". + // * Neither content item fits on the line without breaking + // -> output the first content item and the whitespace with "break". + + case "fill": + { + const rem = width - pos; + const { + parts + } = doc; + + if (parts.length === 0) { + break; + } + + const [content, whitespace] = parts; + const contentFlatCmd = [ind, MODE_FLAT, content]; + const contentBreakCmd = [ind, MODE_BREAK, content]; + const contentFits = fits(contentFlatCmd, [], rem, options, true); + + if (parts.length === 1) { + if (contentFits) { + cmds.push(contentFlatCmd); + } else { + cmds.push(contentBreakCmd); + } + + break; + } + + const whitespaceFlatCmd = [ind, MODE_FLAT, whitespace]; + const whitespaceBreakCmd = [ind, MODE_BREAK, whitespace]; + + if (parts.length === 2) { + if (contentFits) { + cmds.push(whitespaceFlatCmd); + cmds.push(contentFlatCmd); + } else { + cmds.push(whitespaceBreakCmd); + cmds.push(contentBreakCmd); + } + + break; + } // At this point we've handled the first pair (context, separator) + // and will create a new fill doc for the rest of the content. + // Ideally we wouldn't mutate the array here but copying all the + // elements to a new array would make this algorithm quadratic, + // which is unusable for large arrays (e.g. large texts in JSX). + + + parts.splice(0, 2); + const remainingCmd = [ind, mode, fill$1(parts)]; + const secondContent = parts[0]; + const firstAndSecondContentFlatCmd = [ind, MODE_FLAT, concat$1([content, whitespace, secondContent])]; + const firstAndSecondContentFits = fits(firstAndSecondContentFlatCmd, [], rem, options, true); + + if (firstAndSecondContentFits) { + cmds.push(remainingCmd); + cmds.push(whitespaceFlatCmd); + cmds.push(contentFlatCmd); + } else if (contentFits) { + cmds.push(remainingCmd); + cmds.push(whitespaceBreakCmd); + cmds.push(contentFlatCmd); + } else { + cmds.push(remainingCmd); + cmds.push(whitespaceBreakCmd); + cmds.push(contentBreakCmd); + } + + break; + } + + case "if-break": + { + const groupMode = doc.groupId ? groupModeMap[doc.groupId] : mode; + + if (groupMode === MODE_BREAK) { + if (doc.breakContents) { + cmds.push([ind, mode, doc.breakContents]); + } + } + + if (groupMode === MODE_FLAT) { + if (doc.flatContents) { + cmds.push([ind, mode, doc.flatContents]); + } + } + + break; + } + + case "line-suffix": + lineSuffix.push([ind, mode, doc.contents]); + break; + + case "line-suffix-boundary": + if (lineSuffix.length > 0) { + cmds.push([ind, mode, { + type: "line", + hard: true + }]); + } + + break; + + case "line": + switch (mode) { + case MODE_FLAT: + if (!doc.hard) { + if (!doc.soft) { + out.push(" "); + pos += 1; + } + + break; + } else { + // This line was forced into the output even if we + // were in flattened mode, so we need to tell the next + // group that no matter what, it needs to remeasure + // because the previous measurement didn't accurately + // capture the entire expression (this is necessary + // for nested groups) + shouldRemeasure = true; + } + + // fallthrough + + case MODE_BREAK: + if (lineSuffix.length) { + cmds.push([ind, mode, doc]); + cmds.push(...lineSuffix.reverse()); + lineSuffix = []; + break; + } + + if (doc.literal) { + if (ind.root) { + out.push(newLine, ind.root.value); + pos = ind.root.length; + } else { + out.push(newLine); + pos = 0; + } + } else { + pos -= trim$1(out); + out.push(newLine + ind.value); + pos = ind.length; + } + + break; + } + + break; + } + } // Flush remaining line-suffix contents at the end of the document, in case + // there is no new line after the line-suffix. + + + if (cmds.length === 0 && lineSuffix.length) { + cmds.push(...lineSuffix.reverse()); + lineSuffix = []; + } + } + + const cursorPlaceholderIndex = out.indexOf(cursor$1.placeholder); + + if (cursorPlaceholderIndex !== -1) { + const otherCursorPlaceholderIndex = out.indexOf(cursor$1.placeholder, cursorPlaceholderIndex + 1); + const beforeCursor = out.slice(0, cursorPlaceholderIndex).join(""); + const aroundCursor = out.slice(cursorPlaceholderIndex + 1, otherCursorPlaceholderIndex).join(""); + const afterCursor = out.slice(otherCursorPlaceholderIndex + 1).join(""); + return { + formatted: beforeCursor + aroundCursor + afterCursor, + cursorNodeStart: beforeCursor.length, + cursorNodeText: aroundCursor + }; + } + + return { + formatted: out.join("") + }; +} + +var docPrinter = { + printDocToString +}; + +const { + literalline: literalline$1, + concat: concat$2 +} = docBuilders; // Using a unique object to compare by reference. + +const traverseDocOnExitStackMarker = {}; + +function traverseDoc(doc, onEnter, onExit, shouldTraverseConditionalGroups) { + const docsStack = [doc]; + + while (docsStack.length !== 0) { + const doc = docsStack.pop(); + + if (doc === traverseDocOnExitStackMarker) { + onExit(docsStack.pop()); + continue; + } + + if (onExit) { + docsStack.push(doc, traverseDocOnExitStackMarker); + } + + if ( // Should Recurse + !onEnter || onEnter(doc) !== false) { + // When there are multiple parts to process, + // the parts need to be pushed onto the stack in reverse order, + // so that they are processed in the original order + // when the stack is popped. + if (doc.type === "concat" || doc.type === "fill") { + for (let ic = doc.parts.length, i = ic - 1; i >= 0; --i) { + docsStack.push(doc.parts[i]); + } + } else if (doc.type === "if-break") { + if (doc.flatContents) { + docsStack.push(doc.flatContents); + } + + if (doc.breakContents) { + docsStack.push(doc.breakContents); + } + } else if (doc.type === "group" && doc.expandedStates) { + if (shouldTraverseConditionalGroups) { + for (let ic = doc.expandedStates.length, i = ic - 1; i >= 0; --i) { + docsStack.push(doc.expandedStates[i]); + } + } else { + docsStack.push(doc.contents); + } + } else if (doc.contents) { + docsStack.push(doc.contents); + } + } + } +} + +function mapDoc(doc, cb) { + if (doc.type === "concat" || doc.type === "fill") { + const parts = doc.parts.map(part => mapDoc(part, cb)); + return cb(Object.assign({}, doc, { + parts + })); + } else if (doc.type === "if-break") { + const breakContents = doc.breakContents && mapDoc(doc.breakContents, cb); + const flatContents = doc.flatContents && mapDoc(doc.flatContents, cb); + return cb(Object.assign({}, doc, { + breakContents, + flatContents + })); + } else if (doc.contents) { + const contents = mapDoc(doc.contents, cb); + return cb(Object.assign({}, doc, { + contents + })); + } + + return cb(doc); +} + +function findInDoc(doc, fn, defaultValue) { + let result = defaultValue; + let hasStopped = false; + + function findInDocOnEnterFn(doc) { + const maybeResult = fn(doc); + + if (maybeResult !== undefined) { + hasStopped = true; + result = maybeResult; + } + + if (hasStopped) { + return false; + } + } + + traverseDoc(doc, findInDocOnEnterFn); + return result; +} + +function isEmpty(n) { + return typeof n === "string" && n.length === 0; +} + +function isLineNextFn(doc) { + if (typeof doc === "string") { + return false; + } + + if (doc.type === "line") { + return true; + } +} + +function isLineNext(doc) { + return findInDoc(doc, isLineNextFn, false); +} + +function willBreakFn(doc) { + if (doc.type === "group" && doc.break) { + return true; + } + + if (doc.type === "line" && doc.hard) { + return true; + } + + if (doc.type === "break-parent") { + return true; + } +} + +function willBreak(doc) { + return findInDoc(doc, willBreakFn, false); +} + +function breakParentGroup(groupStack) { + if (groupStack.length > 0) { + const parentGroup = groupStack[groupStack.length - 1]; // Breaks are not propagated through conditional groups because + // the user is expected to manually handle what breaks. + + if (!parentGroup.expandedStates) { + parentGroup.break = true; + } + } + + return null; +} + +function propagateBreaks(doc) { + const alreadyVisitedSet = new Set(); + const groupStack = []; + + function propagateBreaksOnEnterFn(doc) { + if (doc.type === "break-parent") { + breakParentGroup(groupStack); + } + + if (doc.type === "group") { + groupStack.push(doc); + + if (alreadyVisitedSet.has(doc)) { + return false; + } + + alreadyVisitedSet.add(doc); + } + } + + function propagateBreaksOnExitFn(doc) { + if (doc.type === "group") { + const group = groupStack.pop(); + + if (group.break) { + breakParentGroup(groupStack); + } + } + } + + traverseDoc(doc, propagateBreaksOnEnterFn, propagateBreaksOnExitFn, + /* shouldTraverseConditionalGroups */ + true); +} + +function removeLinesFn(doc) { + // Force this doc into flat mode by statically converting all + // lines into spaces (or soft lines into nothing). Hard lines + // should still output because there's too great of a chance + // of breaking existing assumptions otherwise. + if (doc.type === "line" && !doc.hard) { + return doc.soft ? "" : " "; + } else if (doc.type === "if-break") { + return doc.flatContents || ""; + } + + return doc; +} + +function removeLines(doc) { + return mapDoc(doc, removeLinesFn); +} + +function getInnerParts(doc) { + let { + parts + } = doc; + let lastPart; // Avoid a falsy element like "" + + for (let i = doc.parts.length; i > 0 && !lastPart; i--) { + lastPart = parts[i - 1]; + } + + if (lastPart.type === "group") { + parts = lastPart.contents.parts; + } + + return parts; +} + +function stripTrailingHardline(doc, withInnerParts = false) { + // HACK remove ending hardline, original PR: #1984 + if (doc.type === "concat" && doc.parts.length !== 0) { + const parts = withInnerParts ? getInnerParts(doc) : doc.parts; + const lastPart = parts[parts.length - 1]; + + if (lastPart.type === "concat") { + if (lastPart.parts.length === 2 && lastPart.parts[0].hard && lastPart.parts[1].type === "break-parent") { + return { + type: "concat", + parts: parts.slice(0, -1) + }; + } + + return { + type: "concat", + parts: doc.parts.slice(0, -1).concat(stripTrailingHardline(lastPart)) + }; + } + } + + return doc; +} + +function normalizeParts(parts) { + const newParts = []; + const restParts = parts.filter(Boolean); + + while (restParts.length !== 0) { + const part = restParts.shift(); + + if (!part) { + continue; + } + + if (part.type === "concat") { + restParts.unshift(...part.parts); + continue; + } + + if (newParts.length !== 0 && typeof newParts[newParts.length - 1] === "string" && typeof part === "string") { + newParts[newParts.length - 1] += part; + continue; + } + + newParts.push(part); + } + + return newParts; +} + +function normalizeDoc(doc) { + return mapDoc(doc, currentDoc => { + if (!currentDoc.parts) { + return currentDoc; + } + + return Object.assign({}, currentDoc, { + parts: normalizeParts(currentDoc.parts) + }); + }); +} + +function replaceNewlinesWithLiterallines(doc) { + return mapDoc(doc, currentDoc => typeof currentDoc === "string" && currentDoc.includes("\n") ? concat$2(currentDoc.split(/(\n)/g).map((v, i) => i % 2 === 0 ? v : literalline$1)) : currentDoc); +} + +var docUtils = { + isEmpty, + willBreak, + isLineNext, + traverseDoc, + findInDoc, + mapDoc, + propagateBreaks, + removeLines, + stripTrailingHardline, + normalizeParts, + normalizeDoc, + replaceNewlinesWithLiterallines +}; + +function flattenDoc(doc) { + if (doc.type === "concat") { + const res = []; + + for (let i = 0; i < doc.parts.length; ++i) { + const doc2 = doc.parts[i]; + + if (typeof doc2 !== "string" && doc2.type === "concat") { + res.push(...flattenDoc(doc2).parts); + } else { + const flattened = flattenDoc(doc2); + + if (flattened !== "") { + res.push(flattened); + } + } + } + + return Object.assign({}, doc, { + parts: res + }); + } else if (doc.type === "if-break") { + return Object.assign({}, doc, { + breakContents: doc.breakContents != null ? flattenDoc(doc.breakContents) : null, + flatContents: doc.flatContents != null ? flattenDoc(doc.flatContents) : null + }); + } else if (doc.type === "group") { + return Object.assign({}, doc, { + contents: flattenDoc(doc.contents), + expandedStates: doc.expandedStates ? doc.expandedStates.map(flattenDoc) : doc.expandedStates + }); + } else if (doc.contents) { + return Object.assign({}, doc, { + contents: flattenDoc(doc.contents) + }); + } + + return doc; +} + +function printDoc(doc) { + if (typeof doc === "string") { + return JSON.stringify(doc); + } + + if (doc.type === "line") { + if (doc.literal) { + return "literalline"; + } + + if (doc.hard) { + return "hardline"; + } + + if (doc.soft) { + return "softline"; + } + + return "line"; + } + + if (doc.type === "break-parent") { + return "breakParent"; + } + + if (doc.type === "trim") { + return "trim"; + } + + if (doc.type === "concat") { + return "[" + doc.parts.map(printDoc).join(", ") + "]"; + } + + if (doc.type === "indent") { + return "indent(" + printDoc(doc.contents) + ")"; + } + + if (doc.type === "align") { + return doc.n === -Infinity ? "dedentToRoot(" + printDoc(doc.contents) + ")" : doc.n < 0 ? "dedent(" + printDoc(doc.contents) + ")" : doc.n.type === "root" ? "markAsRoot(" + printDoc(doc.contents) + ")" : "align(" + JSON.stringify(doc.n) + ", " + printDoc(doc.contents) + ")"; + } + + if (doc.type === "if-break") { + return "ifBreak(" + printDoc(doc.breakContents) + (doc.flatContents ? ", " + printDoc(doc.flatContents) : "") + ")"; + } + + if (doc.type === "group") { + if (doc.expandedStates) { + return "conditionalGroup(" + "[" + doc.expandedStates.map(printDoc).join(",") + "])"; + } + + return (doc.break ? "wrappedGroup" : "group") + "(" + printDoc(doc.contents) + ")"; + } + + if (doc.type === "fill") { + return "fill" + "(" + doc.parts.map(printDoc).join(", ") + ")"; + } + + if (doc.type === "line-suffix") { + return "lineSuffix(" + printDoc(doc.contents) + ")"; + } + + if (doc.type === "line-suffix-boundary") { + return "lineSuffixBoundary"; + } + + throw new Error("Unknown doc type " + doc.type); +} + +var docDebug = { + printDocToDebug(doc) { + return printDoc(flattenDoc(doc)); + } + +}; + +/** + * @typedef {import("./doc-builders").Doc} Doc + */ + + +var document = { + builders: docBuilders, + printer: docPrinter, + utils: docUtils, + debug: docDebug +}; + +/** + * @class + */ + + +class LineByLine { + constructor(file, options) { + options = options || {}; + if (!options.readChunk) options.readChunk = 1024; + + if (!options.newLineCharacter) { + options.newLineCharacter = 0x0a; //linux line ending + } else { + options.newLineCharacter = options.newLineCharacter.charCodeAt(0); + } + + if (typeof file === 'number') { + this.fd = file; + } else { + this.fd = fs__default['default'].openSync(file, 'r'); + } + + this.options = options; + this.newLineCharacter = options.newLineCharacter; + this.reset(); + } + + _searchInBuffer(buffer, hexNeedle) { + let found = -1; + + for (let i = 0; i <= buffer.length; i++) { + let b_byte = buffer[i]; + + if (b_byte === hexNeedle) { + found = i; + break; + } + } + + return found; + } + + reset() { + this.eofReached = false; + this.linesCache = []; + this.fdPosition = 0; + } + + close() { + fs__default['default'].closeSync(this.fd); + this.fd = null; + } + + _extractLines(buffer) { + let line; + const lines = []; + let bufferPosition = 0; + let lastNewLineBufferPosition = 0; + + while (true) { + let bufferPositionValue = buffer[bufferPosition++]; + + if (bufferPositionValue === this.newLineCharacter) { + line = buffer.slice(lastNewLineBufferPosition, bufferPosition); + lines.push(line); + lastNewLineBufferPosition = bufferPosition; + } else if (bufferPositionValue === undefined) { + break; + } + } + + let leftovers = buffer.slice(lastNewLineBufferPosition, bufferPosition); + + if (leftovers.length) { + lines.push(leftovers); + } + + return lines; + } + + _readChunk(lineLeftovers) { + let totalBytesRead = 0; + let bytesRead; + const buffers = []; + + do { + const readBuffer = new Buffer(this.options.readChunk); + bytesRead = fs__default['default'].readSync(this.fd, readBuffer, 0, this.options.readChunk, this.fdPosition); + totalBytesRead = totalBytesRead + bytesRead; + this.fdPosition = this.fdPosition + bytesRead; + buffers.push(readBuffer); + } while (bytesRead && this._searchInBuffer(buffers[buffers.length - 1], this.options.newLineCharacter) === -1); + + let bufferData = Buffer.concat(buffers); + + if (bytesRead < this.options.readChunk) { + this.eofReached = true; + bufferData = bufferData.slice(0, totalBytesRead); + } + + if (totalBytesRead) { + this.linesCache = this._extractLines(bufferData); + + if (lineLeftovers) { + this.linesCache[0] = Buffer.concat([lineLeftovers, this.linesCache[0]]); + } + } + + return totalBytesRead; + } + + next() { + if (!this.fd) return false; + let line = false; + + if (this.eofReached && this.linesCache.length === 0) { + return line; + } + + let bytesRead; + + if (!this.linesCache.length) { + bytesRead = this._readChunk(); + } + + if (this.linesCache.length) { + line = this.linesCache.shift(); + const lastLineCharacter = line[line.length - 1]; + + if (lastLineCharacter !== this.newLineCharacter) { + bytesRead = this._readChunk(line); + + if (bytesRead) { + line = this.linesCache.shift(); + } + } + } + + if (this.eofReached && this.linesCache.length === 0) { + this.close(); + } + + if (line && line[line.length - 1] === this.newLineCharacter) { + line = line.slice(0, line.length - 1); + } + + return line; + } + +} + +var readlines = LineByLine; + +/** + * The inverse of `_.toPairs`; this method returns an object composed + * from key-value `pairs`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Array + * @param {Array} pairs The key-value pairs. + * @returns {Object} Returns the new object. + * @example + * + * _.fromPairs([['a', 1], ['b', 2]]); + * // => { 'a': 1, 'b': 2 } + */ +function fromPairs(pairs) { + var index = -1, + length = pairs == null ? 0 : pairs.length, + result = {}; + + while (++index < length) { + var pair = pairs[index]; + result[pair[0]] = pair[1]; + } + + return result; +} + +var fromPairs_1 = fromPairs; + +class ConfigError extends Error {} + +class DebugError extends Error {} + +class UndefinedParserError extends Error {} + +var errors = { + ConfigError, + DebugError, + UndefinedParserError +}; + +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ + +/* global Reflect, Promise */ +var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + }; + + return extendStatics(d, b); +}; + +function __extends(d, b) { + extendStatics(d, b); + + function __() { + this.constructor = d; + } + + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} +var __assign = function () { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + + return t; + }; + + return __assign.apply(this, arguments); +}; +function __rest(s, e) { + var t = {}; + + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; + + if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; + } + return t; +} +function __decorate(decorators, target, key, desc) { + var c = arguments.length, + r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, + d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +} +function __param(paramIndex, decorator) { + return function (target, key) { + decorator(target, key, paramIndex); + }; +} +function __metadata(metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); +} +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function (resolve) { + resolve(value); + }); + } + + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} +function __generator(thisArg, body) { + var _ = { + label: 0, + sent: function () { + if (t[0] & 1) throw t[1]; + return t[1]; + }, + trys: [], + ops: [] + }, + f, + y, + t, + g; + return g = { + next: verb(0), + "throw": verb(1), + "return": verb(2) + }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { + return this; + }), g; + + function verb(n) { + return function (v) { + return step([n, v]); + }; + } + + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + + switch (op[0]) { + case 0: + case 1: + t = op; + break; + + case 4: + _.label++; + return { + value: op[1], + done: false + }; + + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + + case 7: + op = _.ops.pop(); + + _.trys.pop(); + + continue; + + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } + + if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { + _.label = op[1]; + break; + } + + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + + if (t && _.label < t[2]) { + _.label = t[2]; + + _.ops.push(op); + + break; + } + + if (t[2]) _.ops.pop(); + + _.trys.pop(); + + continue; + } + + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } + + if (op[0] & 5) throw op[1]; + return { + value: op[0] ? op[1] : void 0, + done: true + }; + } +} +function __createBinding(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +} +function __exportStar(m, exports) { + for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) exports[p] = m[p]; +} +function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, + m = s && o[s], + i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { + value: o && o[i++], + done: !o + }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); +} +function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), + r, + ar = [], + e; + + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } catch (error) { + e = { + error: error + }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + + return ar; +} +function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); + + return ar; +} +function __spreadArrays() { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + + for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; + + return r; +} +function __await(v) { + return this instanceof __await ? (this.v = v, this) : new __await(v); +} +function __asyncGenerator(thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), + i, + q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { + return this; + }, i; + + function verb(n) { + if (g[n]) i[n] = function (v) { + return new Promise(function (a, b) { + q.push([n, v, a, b]) > 1 || resume(n, v); + }); + }; + } + + function resume(n, v) { + try { + step(g[n](v)); + } catch (e) { + settle(q[0][3], e); + } + } + + function step(r) { + r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); + } + + function fulfill(value) { + resume("next", value); + } + + function reject(value) { + resume("throw", value); + } + + function settle(f, v) { + if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); + } +} +function __asyncDelegator(o) { + var i, p; + return i = {}, verb("next"), verb("throw", function (e) { + throw e; + }), verb("return"), i[Symbol.iterator] = function () { + return this; }, i; function verb(n, f) { @@ -3263,6 +5631,21 @@ function __importDefault(mod) { default: mod }; } +function __classPrivateFieldGet(receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + + return privateMap.get(receiver); +} +function __classPrivateFieldSet(receiver, privateMap, value) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to set private field on non-instance"); + } + + privateMap.set(receiver, value); + return value; +} var tslib_es6 = /*#__PURE__*/Object.freeze({ __proto__: null, @@ -3274,6 +5657,7 @@ var tslib_es6 = /*#__PURE__*/Object.freeze({ __metadata: __metadata, __awaiter: __awaiter, __generator: __generator, + __createBinding: __createBinding, __exportStar: __exportStar, __values: __values, __read: __read, @@ -3285,7 +5669,9 @@ var tslib_es6 = /*#__PURE__*/Object.freeze({ __asyncValues: __asyncValues, __makeTemplateObject: __makeTemplateObject, __importStar: __importStar, - __importDefault: __importDefault + __importDefault: __importDefault, + __classPrivateFieldGet: __classPrivateFieldGet, + __classPrivateFieldSet: __classPrivateFieldSet }); var api = createCommonjsModule(function (module, exports) { @@ -3317,8 +5703,6 @@ var api = createCommonjsModule(function (module, exports) { }) }; }); -unwrapExports(api); -var api_1 = api.apiDescriptor; var descriptors = createCommonjsModule(function (module, exports) { @@ -3328,11 +5712,10 @@ var descriptors = createCommonjsModule(function (module, exports) { tslib_es6.__exportStar(api, exports); }); -unwrapExports(descriptors); var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; -var escapeStringRegexp = function (str) { +var escapeStringRegexp$1 = function (str) { if (typeof str !== 'string') { throw new TypeError('Expected a string'); } @@ -4387,21 +6770,6 @@ var conversions = createCommonjsModule(function (module) { return [val / 255 * 100]; }; }); -var conversions_1 = conversions.rgb; -var conversions_2 = conversions.hsl; -var conversions_3 = conversions.hsv; -var conversions_4 = conversions.hwb; -var conversions_5 = conversions.cmyk; -var conversions_6 = conversions.xyz; -var conversions_7 = conversions.lab; -var conversions_8 = conversions.lch; -var conversions_9 = conversions.hex; -var conversions_10 = conversions.keyword; -var conversions_11 = conversions.ansi16; -var conversions_12 = conversions.ansi256; -var conversions_13 = conversions.hcg; -var conversions_14 = conversions.apple; -var conversions_15 = conversions.gray; /* this function routes a model to all other models. @@ -4789,7 +7157,7 @@ function supportsColor(stream) { // 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('.'); + const osRelease = os__default['default'].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; @@ -5019,7 +7387,7 @@ var chalk = createCommonjsModule(function (module) { } for (const key of Object.keys(ansiStyles)) { - ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); + ansiStyles[key].closeRe = new RegExp(escapeStringRegexp$1(ansiStyles[key].close), 'g'); styles[key] = { get() { const codes = ansiStyles[key]; @@ -5035,7 +7403,7 @@ var chalk = createCommonjsModule(function (module) { } }; - ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); + ansiStyles.color.closeRe = new RegExp(escapeStringRegexp$1(ansiStyles.color.close), 'g'); for (const model of Object.keys(ansiStyles.color.ansi)) { if (skipModels.has(model)) { @@ -5059,7 +7427,7 @@ var chalk = createCommonjsModule(function (module) { }; } - ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); + ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp$1(ansiStyles.bgColor.close), 'g'); for (const model of Object.keys(ansiStyles.bgColor.ansi)) { if (skipModels.has(model)) { @@ -5197,7 +7565,6 @@ var chalk = createCommonjsModule(function (module) { module.exports.supportsColor = stdoutColor; module.exports.default = module.exports; // For TypeScript }); -var chalk_1 = chalk.supportsColor; var common = createCommonjsModule(function (module, exports) { @@ -5217,8 +7584,6 @@ var common = createCommonjsModule(function (module, exports) { return messages.join('; ') + '.'; }; }); -unwrapExports(common); -var common_1 = common.commonDeprecatedHandler; var deprecated = createCommonjsModule(function (module, exports) { @@ -5228,7 +7593,6 @@ var deprecated = createCommonjsModule(function (module, exports) { tslib_es6.__exportStar(common, exports); }); -unwrapExports(deprecated); var common$1 = createCommonjsModule(function (module, exports) { @@ -5238,8 +7602,6 @@ var common$1 = createCommonjsModule(function (module, exports) { exports.commonInvalidHandler = (key, value, utils) => [`Invalid ${chalk.default.red(utils.descriptor.key(key))} value.`, `Expected ${chalk.default.blue(utils.schemas[key].expected(utils))},`, `but received ${chalk.default.red(utils.descriptor.value(value))}.`].join(' '); }); -unwrapExports(common$1); -var common_1$1 = common$1.commonInvalidHandler; var invalid = createCommonjsModule(function (module, exports) { @@ -5249,7 +7611,6 @@ var invalid = createCommonjsModule(function (module, exports) { tslib_es6.__exportStar(common$1, exports); }); -unwrapExports(invalid); /* eslint-disable no-nested-ternary */ @@ -5360,8 +7721,6 @@ var leven_1 = createCommonjsModule(function (module, exports) { logger.warn(messages.join(' ')); }; }); -unwrapExports(leven_1); -var leven_2 = leven_1.levenUnknownHandler; var unknown = createCommonjsModule(function (module, exports) { @@ -5371,7 +7730,6 @@ var unknown = createCommonjsModule(function (module, exports) { tslib_es6.__exportStar(leven_1, exports); }); -unwrapExports(unknown); var handlers = createCommonjsModule(function (module, exports) { @@ -5385,7 +7743,6 @@ var handlers = createCommonjsModule(function (module, exports) { tslib_es6.__exportStar(unknown, exports); }); -unwrapExports(handlers); var schema = createCommonjsModule(function (module, exports) { @@ -5465,9 +7822,6 @@ var schema = createCommonjsModule(function (module, exports) { return typeof handler === 'function' ? (...args) => handler(...args.slice(0, handlerArgumentsLength - 1), superSchema, ...args.slice(handlerArgumentsLength - 1)) : () => handler; } }); -unwrapExports(schema); -var schema_1 = schema.createSchema; -var schema_2 = schema.Schema; var alias = createCommonjsModule(function (module, exports) { @@ -5497,8 +7851,6 @@ var alias = createCommonjsModule(function (module, exports) { exports.AliasSchema = AliasSchema; }); -unwrapExports(alias); -var alias_1 = alias.AliasSchema; var any = createCommonjsModule(function (module, exports) { @@ -5519,8 +7871,6 @@ var any = createCommonjsModule(function (module, exports) { exports.AnySchema = AnySchema; }); -unwrapExports(any); -var any_1 = any.AnySchema; var array = createCommonjsModule(function (module, exports) { @@ -5635,8 +7985,6 @@ var array = createCommonjsModule(function (module, exports) { }; } }); -unwrapExports(array); -var array_1 = array.ArraySchema; var boolean_1 = createCommonjsModule(function (module, exports) { @@ -5657,8 +8005,6 @@ var boolean_1 = createCommonjsModule(function (module, exports) { exports.BooleanSchema = BooleanSchema; }); -unwrapExports(boolean_1); -var boolean_2 = boolean_1.BooleanSchema; var utils = createCommonjsModule(function (module, exports) { @@ -5822,19 +8168,6 @@ var utils = createCommonjsModule(function (module, exports) { exports.normalizeRedirectResult = normalizeRedirectResult; }); -unwrapExports(utils); -var utils_1 = utils.recordFromArray; -var utils_2 = utils.mapFromArray; -var utils_3 = utils.createAutoChecklist; -var utils_4 = utils.partition; -var utils_5 = utils.isInt; -var utils_6 = utils.comparePrimitive; -var utils_7 = utils.normalizeDefaultResult; -var utils_8 = utils.normalizeValidateResult; -var utils_9 = utils.normalizeDeprecatedResult; -var utils_10 = utils.normalizeTransferResult; -var utils_11 = utils.normalizeForwardResult; -var utils_12 = utils.normalizeRedirectResult; var choice = createCommonjsModule(function (module, exports) { @@ -5887,8 +8220,6 @@ var choice = createCommonjsModule(function (module, exports) { exports.ChoiceSchema = ChoiceSchema; }); -unwrapExports(choice); -var choice_1 = choice.ChoiceSchema; var number = createCommonjsModule(function (module, exports) { @@ -5909,8 +8240,6 @@ var number = createCommonjsModule(function (module, exports) { exports.NumberSchema = NumberSchema; }); -unwrapExports(number); -var number_1 = number.NumberSchema; var integer = createCommonjsModule(function (module, exports) { @@ -5931,8 +8260,6 @@ var integer = createCommonjsModule(function (module, exports) { exports.IntegerSchema = IntegerSchema; }); -unwrapExports(integer); -var integer_1 = integer.IntegerSchema; var string = createCommonjsModule(function (module, exports) { @@ -5953,8 +8280,6 @@ var string = createCommonjsModule(function (module, exports) { exports.StringSchema = StringSchema; }); -unwrapExports(string); -var string_1 = string.StringSchema; var schemas = createCommonjsModule(function (module, exports) { @@ -5978,7 +8303,6 @@ var schemas = createCommonjsModule(function (module, exports) { tslib_es6.__exportStar(string, exports); }); -unwrapExports(schemas); var defaults = createCommonjsModule(function (module, exports) { @@ -5990,11 +8314,6 @@ var defaults = createCommonjsModule(function (module, exports) { exports.defaultInvalidHandler = invalid.commonInvalidHandler; exports.defaultDeprecatedHandler = common.commonDeprecatedHandler; }); -unwrapExports(defaults); -var defaults_1 = defaults.defaultDescriptor; -var defaults_2 = defaults.defaultUnknownHandler; -var defaults_3 = defaults.defaultInvalidHandler; -var defaults_4 = defaults.defaultDeprecatedHandler; var normalize = createCommonjsModule(function (module, exports) { @@ -6201,11 +8520,8 @@ var normalize = createCommonjsModule(function (module, exports) { exports.Normalizer = Normalizer; }); -unwrapExports(normalize); -var normalize_1 = normalize.normalize; -var normalize_2 = normalize.Normalizer; -var lib = createCommonjsModule(function (module, exports) { +var lib$1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true @@ -6221,7 +8537,6 @@ var lib = createCommonjsModule(function (module, exports) { tslib_es6.__exportStar(schema, exports); }); -unwrapExports(lib); const array$1 = []; const charCodeCache$1 = []; @@ -6296,8 +8611,8 @@ const leven$1 = (left, right) => { var leven_1$1 = leven$1; // TODO: Remove this for the next major release -var default_1 = leven$1; -leven_1$1.default = default_1; +var _default$2 = leven$1; +leven_1$1.default = _default$2; var colorName$1 = { "aliceblue": [240, 248, 255], @@ -7716,7 +10031,7 @@ function supportsColor$1(haveStream, streamIsTTY) { 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$1.release().split('.'); + const osRelease = os__default['default'].release().split('.'); if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) { return Number(osRelease[2]) >= 14931 ? 3 : 2; @@ -7780,8 +10095,8 @@ function getSupportLevel$1(stream) { var supportsColor_1$1 = { supportsColor: getSupportLevel$1, - stdout: translateLevel$1(supportsColor$1(true, tty$1.isatty(1))), - stderr: translateLevel$1(supportsColor$1(true, tty$1.isatty(2))) + stdout: translateLevel$1(supportsColor$1(true, tty__default['default'].isatty(1))), + stderr: translateLevel$1(supportsColor$1(true, tty__default['default'].isatty(2))) }; const stringReplaceAll = (string, substring, replacer) => { @@ -7820,7 +10135,7 @@ const stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => { return returnValue; }; -var util = { +var util$1 = { stringReplaceAll, stringEncaseCRLFWithFirstIndex }; @@ -7956,7 +10271,10 @@ const { const { stringReplaceAll: stringReplaceAll$1, stringEncaseCRLFWithFirstIndex: stringEncaseCRLFWithFirstIndex$1 -} = util; // `supportsColor.level` → `ansiStyles.color[name]` mapping +} = util$1; +const { + isArray +} = Array; // `supportsColor.level` → `ansiStyles.color[name]` mapping const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; const styles = Object.create(null); @@ -8056,142 +10374,467 @@ for (const model of usedModels) { }; } -const proto = Object.defineProperties(() => {}, Object.assign({}, styles, { - level: { - enumerable: true, +const proto = Object.defineProperties(() => {}, Object.assign({}, 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(arguments_[0]) && isArray(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$1(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$1(string, closeAll, openAll, lfIndex); + } + + return openAll + string + closeAll; +}; + +let template; + +const chalkTag = (chalk, ...strings) => { + const [firstString] = strings; + + if (!isArray(firstString) || !isArray(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 = chalk$1; + +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + + return array; +} + +var _arrayPush = arrayPush; + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; +var _freeGlobal = freeGlobal; + +/** Detect free variable `self`. */ + +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; +/** Used as a reference to the global object. */ + +var root = _freeGlobal || freeSelf || Function('return this')(); +var _root = root; + +/** Built-in value references. */ + +var Symbol$1 = _root.Symbol; +var _Symbol = Symbol$1; + +/** Used for built-in method references. */ + +var objectProto = Object.prototype; +/** Used to check objects for own properties. */ + +var hasOwnProperty = objectProto.hasOwnProperty; +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + +var nativeObjectToString = objectProto.toString; +/** Built-in value references. */ + +var symToStringTag = _Symbol ? _Symbol.toStringTag : undefined; +/** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ + +function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + + return result; +} + +var _getRawTag = getRawTag; + +/** Used for built-in method references. */ +var objectProto$1 = Object.prototype; +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + +var nativeObjectToString$1 = objectProto$1.toString; +/** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ + +function objectToString(value) { + return nativeObjectToString$1.call(value); +} + +var _objectToString = objectToString; + +/** `Object#toString` result references. */ + +var nullTag = '[object Null]', + undefinedTag = '[object Undefined]'; +/** Built-in value references. */ + +var symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined; +/** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + +function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + + return symToStringTag$1 && symToStringTag$1 in Object(value) ? _getRawTag(value) : _objectToString(value); +} + +var _baseGetTag = baseGetTag; + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return value != null && typeof value == 'object'; +} + +var isObjectLike_1 = isObjectLike; - get() { - return this._generator.level; - }, +/** `Object#toString` result references. */ - set(level) { - this._generator.level = level; - } +var argsTag = '[object Arguments]'; +/** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ - } -})); +function baseIsArguments(value) { + return isObjectLike_1(value) && _baseGetTag(value) == argsTag; +} -const createStyler = (open, close, parent) => { - let openAll; - let closeAll; +var _baseIsArguments = baseIsArguments; - if (parent === undefined) { - openAll = open; - closeAll = close; - } else { - openAll = parent.openAll + open; - closeAll = close + parent.closeAll; - } +/** Used for built-in method references. */ - return { - open, - close, - openAll, - closeAll, - parent - }; -}; +var objectProto$2 = Object.prototype; +/** Used to check objects for own properties. */ -const createBuilder = (self, _styler, _isEmpty) => { - const 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 +var hasOwnProperty$1 = objectProto$2.hasOwnProperty; +/** Built-in value references. */ +var propertyIsEnumerable = objectProto$2.propertyIsEnumerable; +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ - Object.setPrototypeOf(builder, proto); - builder._generator = self; - builder._styler = _styler; - builder._isEmpty = _isEmpty; - return builder; +var isArguments = _baseIsArguments(function () { + return arguments; +}()) ? _baseIsArguments : function (value) { + return isObjectLike_1(value) && hasOwnProperty$1.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); }; +var isArguments_1 = isArguments; -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$1(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 - +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray$1 = Array.isArray; +var isArray_1 = isArray$1; - const lfIndex = string.indexOf('\n'); +/** Built-in value references. */ - if (lfIndex !== -1) { - string = stringEncaseCRLFWithFirstIndex$1(string, closeAll, openAll, lfIndex); - } +var spreadableSymbol = _Symbol ? _Symbol.isConcatSpreadable : undefined; +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ - return openAll + string + closeAll; -}; +function isFlattenable(value) { + return isArray_1(value) || isArguments_1(value) || !!(spreadableSymbol && value && value[spreadableSymbol]); +} -let template; +var _isFlattenable = isFlattenable; -const chalkTag = (chalk, ...strings) => { - const [firstString] = strings; +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ - if (!Array.isArray(firstString)) { - // If chalk() was called by itself or with a string, - // return the string itself as a string. - return strings.join(' '); - } +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + predicate || (predicate = _isFlattenable); + result || (result = []); - const arguments_ = strings.slice(1); - const parts = [firstString.raw[0]]; + while (++index < length) { + var value = array[index]; - for (let i = 1; i < firstString.length; i++) { - parts.push(String(arguments_[i - 1]).replace(/[{}\\]/g, '\\$&'), String(firstString.raw[i])); + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + _arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } } - if (template === undefined) { - template = templates$1; - } + return result; +} - return template(chalk, parts.join('')); -}; +var _baseFlatten = baseFlatten; -Object.defineProperties(Chalk.prototype, styles); -const chalk$1 = Chalk(); // eslint-disable-line new-cap +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ -chalk$1.supportsColor = stdoutColor; -chalk$1.stderr = Chalk({ - level: stderrColor ? stderrColor.level : 0 -}); // eslint-disable-line new-cap +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? _baseFlatten(array, 1) : []; +} -chalk$1.stderr.supportsColor = stderrColor; -var source = chalk$1; +var flatten_1 = flatten; const cliDescriptor = { key: key => key.length === 1 ? `-${key}` : `--${key}`, - value: value => lib.apiDescriptor.value(value), + value: value => lib$1.apiDescriptor.value(value), pair: ({ key, value }) => value === false ? `--no-${key}` : value === true ? cliDescriptor.key(key) : value === "" ? `${cliDescriptor.key(key)} without an argument` : `${cliDescriptor.key(key)}=${value}` }; -class FlagSchema extends lib.ChoiceSchema { +class FlagSchema extends lib$1.ChoiceSchema { constructor({ name, flags @@ -8229,16 +10872,24 @@ function normalizeOptions(options, optionInfos, { isCLI = false, passThrough = false } = {}) { - const unknown = !passThrough ? lib.levenUnknownHandler : Array.isArray(passThrough) ? (key, value) => !passThrough.includes(key) ? undefined : { + const unknown = !passThrough ? (key, value, options) => { + // Don't suggest `_` for unknown flags + const _options$schemas = options.schemas, + schemas = _objectWithoutPropertiesLoose(_options$schemas, ["_"]); + + return lib$1.levenUnknownHandler(key, value, Object.assign({}, options, { + schemas + })); + } : Array.isArray(passThrough) ? (key, value) => !passThrough.includes(key) ? undefined : { [key]: value } : (key, value) => ({ [key]: value }); - const descriptor = isCLI ? cliDescriptor : lib.apiDescriptor; + const descriptor = isCLI ? cliDescriptor : lib$1.apiDescriptor; const schemas = optionInfosToSchemas(optionInfos, { isCLI }); - const normalizer = new lib.Normalizer(schemas, { + const normalizer = new lib$1.Normalizer(schemas, { logger, unknown, descriptor @@ -8258,789 +10909,417 @@ function normalizeOptions(options, optionInfos, { return normalized; } -function optionInfosToSchemas(optionInfos, { - isCLI -}) { - const schemas = []; - - if (isCLI) { - schemas.push(lib.AnySchema.create({ - name: "_" - })); - } - - for (const optionInfo of optionInfos) { - schemas.push(optionInfoToSchema(optionInfo, { - isCLI, - optionInfos - })); - - if (optionInfo.alias && isCLI) { - schemas.push(lib.AliasSchema.create({ - name: optionInfo.alias, - sourceName: optionInfo.name - })); - } - } - - return schemas; -} - -function optionInfoToSchema(optionInfo, { - isCLI, - optionInfos -}) { - let SchemaConstructor; - const parameters = { - name: optionInfo.name - }; - const handlers = {}; - - switch (optionInfo.type) { - case "int": - SchemaConstructor = lib.IntegerSchema; - - if (isCLI) { - parameters.preprocess = value => Number(value); - } - - break; - - case "string": - SchemaConstructor = lib.StringSchema; - break; - - case "choice": - SchemaConstructor = lib.ChoiceSchema; - parameters.choices = optionInfo.choices.map(choiceInfo => typeof choiceInfo === "object" && choiceInfo.redirect ? Object.assign({}, choiceInfo, { - redirect: { - to: { - key: optionInfo.name, - value: choiceInfo.redirect - } - } - }) : choiceInfo); - break; - - case "boolean": - SchemaConstructor = lib.BooleanSchema; - break; - - case "flag": - SchemaConstructor = FlagSchema; - parameters.flags = optionInfos.map(optionInfo => [].concat(optionInfo.alias || [], optionInfo.description ? optionInfo.name : [], optionInfo.oppositeDescription ? `no-${optionInfo.name}` : [])).reduce((a, b) => a.concat(b), []); - break; - - case "path": - SchemaConstructor = lib.StringSchema; - break; - - default: - throw new Error(`Unexpected type ${optionInfo.type}`); - } - - if (optionInfo.exception) { - parameters.validate = (value, schema, utils) => { - return optionInfo.exception(value) || schema.validate(value, utils); - }; - } else { - parameters.validate = (value, schema, utils) => { - return value === undefined || schema.validate(value, utils); - }; - } - - if (optionInfo.redirect) { - handlers.redirect = value => !value ? undefined : { - to: { - key: optionInfo.redirect.option, - value: optionInfo.redirect.value - } - }; - } - - if (optionInfo.deprecated) { - handlers.deprecated = true; - } // allow CLI overriding, e.g., prettier package.json --tab-width 1 --tab-width 2 - - - if (isCLI && !optionInfo.array) { - const originalPreprocess = parameters.preprocess || (x => x); - - parameters.preprocess = (value, schema, utils) => schema.preprocess(originalPreprocess(Array.isArray(value) ? value[value.length - 1] : value), utils); - } - - return optionInfo.array ? lib.ArraySchema.create(Object.assign({}, isCLI ? { - preprocess: v => [].concat(v) - } : {}, {}, handlers, { - valueSchema: SchemaConstructor.create(parameters) - })) : SchemaConstructor.create(Object.assign({}, parameters, {}, handlers)); -} - -function normalizeApiOptions(options, optionInfos, opts) { - return normalizeOptions(options, optionInfos, opts); -} - -function normalizeCliOptions(options, optionInfos, opts) { - return normalizeOptions(options, optionInfos, Object.assign({ - isCLI: true - }, opts)); -} - -var optionsNormalizer = { - normalizeApiOptions, - normalizeCliOptions -}; - -var getLast = arr => arr[arr.length - 1]; - -function locStart(node, opts) { - opts = opts || {}; // Handle nodes with decorators. They should start at the first decorator - - if (!opts.ignoreDecorators && node.declaration && node.declaration.decorators && node.declaration.decorators.length > 0) { - return locStart(node.declaration.decorators[0]); - } - - if (!opts.ignoreDecorators && node.decorators && node.decorators.length > 0) { - return locStart(node.decorators[0]); - } - - if (node.__location) { - return node.__location.startOffset; - } - - if (node.range) { - return node.range[0]; - } - - if (typeof node.start === "number") { - return node.start; - } - - if (node.loc) { - return node.loc.start; - } - - return null; -} - -function locEnd(node) { - const endNode = node.nodes && getLast(node.nodes); - - if (endNode && node.source && !node.source.end) { - node = endNode; - } - - if (node.__location) { - return node.__location.endOffset; - } - - const loc = node.range ? node.range[1] : typeof node.end === "number" ? node.end : null; - - if (node.typeAnnotation) { - return Math.max(loc, locEnd(node.typeAnnotation)); - } - - if (node.loc && !loc) { - return node.loc.end; - } - - return loc; -} - -function composeLoc(startNode, endNodeOrLength = startNode) { - const length = typeof endNodeOrLength === "number" ? endNodeOrLength : -1; - const start = locStart(startNode); - const end = length !== -1 ? start + length : locEnd(endNodeOrLength); - const startLoc = startNode.loc.start; - return { - start, - end, - range: [start, end], - loc: { - start: startLoc, - end: length !== -1 ? { - line: startLoc.line, - column: startLoc.column + length - } : endNodeOrLength.loc.end - } - }; -} - -var loc = { - locStart, - locEnd, - composeLoc -}; - -var jsTokens = createCommonjsModule(function (module, exports) { - // Copyright 2014, 2015, 2016, 2017, 2018 Simon Lydell - // License: MIT. (See LICENSE.) - Object.defineProperty(exports, "__esModule", { - value: true - }); // This regex comes from regex.coffee, and is inserted here by generate-index.js - // (run `npm run build`). - - exports.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; - - exports.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; - }; -}); -unwrapExports(jsTokens); -var jsTokens_1 = jsTokens.matchToToken; - -var ast = createCommonjsModule(function (module) { - /* - Copyright (C) 2013 Yusuke Suzuki - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - (function () { - - function isExpression(node) { - if (node == null) { - return false; - } - - switch (node.type) { - case 'ArrayExpression': - case 'AssignmentExpression': - case 'BinaryExpression': - case 'CallExpression': - case 'ConditionalExpression': - case 'FunctionExpression': - case 'Identifier': - case 'Literal': - case 'LogicalExpression': - case 'MemberExpression': - case 'NewExpression': - case 'ObjectExpression': - case 'SequenceExpression': - case 'ThisExpression': - case 'UnaryExpression': - case 'UpdateExpression': - return true; - } - - return false; - } - - function isIterationStatement(node) { - if (node == null) { - return false; - } - - switch (node.type) { - case 'DoWhileStatement': - case 'ForInStatement': - case 'ForStatement': - case 'WhileStatement': - return true; - } - - return false; - } - - function isStatement(node) { - if (node == null) { - return false; - } - - switch (node.type) { - case 'BlockStatement': - case 'BreakStatement': - case 'ContinueStatement': - case 'DebuggerStatement': - case 'DoWhileStatement': - case 'EmptyStatement': - case 'ExpressionStatement': - case 'ForInStatement': - case 'ForStatement': - case 'IfStatement': - case 'LabeledStatement': - case 'ReturnStatement': - case 'SwitchStatement': - case 'ThrowStatement': - case 'TryStatement': - case 'VariableDeclaration': - case 'WhileStatement': - case 'WithStatement': - return true; - } - - return false; - } - - function isSourceElement(node) { - return isStatement(node) || node != null && node.type === 'FunctionDeclaration'; - } - - function trailingStatement(node) { - switch (node.type) { - case 'IfStatement': - if (node.alternate != null) { - return node.alternate; - } +function optionInfosToSchemas(optionInfos, { + isCLI +}) { + const schemas = []; - return node.consequent; + if (isCLI) { + schemas.push(lib$1.AnySchema.create({ + name: "_" + })); + } - case 'LabeledStatement': - case 'ForStatement': - case 'ForInStatement': - case 'WhileStatement': - case 'WithStatement': - return node.body; - } + for (const optionInfo of optionInfos) { + schemas.push(optionInfoToSchema(optionInfo, { + isCLI, + optionInfos + })); - return null; + if (optionInfo.alias && isCLI) { + schemas.push(lib$1.AliasSchema.create({ + name: optionInfo.alias, + sourceName: optionInfo.name + })); } + } - function isProblematicIfStatement(node) { - var current; + return schemas; +} - if (node.type !== 'IfStatement') { - return false; - } +function optionInfoToSchema(optionInfo, { + isCLI, + optionInfos +}) { + let SchemaConstructor; + const parameters = { + name: optionInfo.name + }; + const handlers = {}; - if (node.alternate == null) { - return false; + switch (optionInfo.type) { + case "int": + SchemaConstructor = lib$1.IntegerSchema; + + if (isCLI) { + parameters.preprocess = value => Number(value); } - current = node.consequent; + break; - do { - if (current.type === 'IfStatement') { - if (current.alternate == null) { - return true; + case "string": + SchemaConstructor = lib$1.StringSchema; + break; + + case "choice": + SchemaConstructor = lib$1.ChoiceSchema; + parameters.choices = optionInfo.choices.map(choiceInfo => typeof choiceInfo === "object" && choiceInfo.redirect ? Object.assign({}, choiceInfo, { + redirect: { + to: { + key: optionInfo.name, + value: choiceInfo.redirect } } + }) : choiceInfo); + break; - current = trailingStatement(current); - } while (current); - - return false; - } - - module.exports = { - isExpression: isExpression, - isStatement: isStatement, - isIterationStatement: isIterationStatement, - isSourceElement: isSourceElement, - isProblematicIfStatement: isProblematicIfStatement, - trailingStatement: trailingStatement - }; - })(); - /* vim: set sw=4 ts=4 et tw=80 : */ + case "boolean": + SchemaConstructor = lib$1.BooleanSchema; + break; -}); -var ast_1 = ast.isExpression; -var ast_2 = ast.isStatement; -var ast_3 = ast.isIterationStatement; -var ast_4 = ast.isSourceElement; -var ast_5 = ast.isProblematicIfStatement; -var ast_6 = ast.trailingStatement; + case "flag": + SchemaConstructor = FlagSchema; + parameters.flags = flatten_1(optionInfos.map(optionInfo => [optionInfo.alias, optionInfo.description && optionInfo.name, optionInfo.oppositeDescription && `no-${optionInfo.name}`].filter(Boolean))); + break; -var code = createCommonjsModule(function (module) { - /* - Copyright (C) 2013-2014 Yusuke Suzuki - Copyright (C) 2014 Ivan Nikulin - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - (function () { + case "path": + SchemaConstructor = lib$1.StringSchema; + break; - var ES6Regex, ES5Regex, NON_ASCII_WHITESPACES, IDENTIFIER_START, IDENTIFIER_PART, ch; // See `tools/generate-identifier-regex.js`. + default: + /* istanbul ignore next */ + throw new Error(`Unexpected type ${optionInfo.type}`); + } - ES5Regex = { - // ECMAScript 5.1/Unicode v9.0.0 NonAsciiIdentifierStart: - NonAsciiIdentifierStart: /[\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\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\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-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\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]/, - // ECMAScript 5.1/Unicode v9.0.0 NonAsciiIdentifierPart: - NonAsciiIdentifierPart: /[\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\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\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\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\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\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-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\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\u200C\u200D\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-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\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]/ + if (optionInfo.exception) { + parameters.validate = (value, schema, utils) => { + return optionInfo.exception(value) || schema.validate(value, utils); }; - ES6Regex = { - // ECMAScript 6/Unicode v9.0.0 NonAsciiIdentifierStart: - NonAsciiIdentifierStart: /[\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\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\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-\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\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-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\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\uDF30-\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\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\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]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00\uDC01]|\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]|\uD87E[\uDC00-\uDE1D]/, - // ECMAScript 6/Unicode v9.0.0 NonAsciiIdentifierPart: - NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\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\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\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\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\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\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\u1369-\u1371\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-\u19DA\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-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\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\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\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-\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\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\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\uDF30-\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\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\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]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00\uDC01]|\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]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/ + } else { + parameters.validate = (value, schema, utils) => { + return value === undefined || schema.validate(value, utils); }; + } + /* istanbul ignore next */ - function isDecimalDigit(ch) { - return 0x30 <= ch && ch <= 0x39; // 0..9 - } - - function isHexDigit(ch) { - return 0x30 <= ch && ch <= 0x39 || // 0..9 - 0x61 <= ch && ch <= 0x66 || // a..f - 0x41 <= ch && ch <= 0x46; // A..F - } - - function isOctalDigit(ch) { - return ch >= 0x30 && ch <= 0x37; // 0..7 - } // 7.2 White Space + if (optionInfo.redirect) { + handlers.redirect = value => !value ? undefined : { + to: { + key: optionInfo.redirect.option, + value: optionInfo.redirect.value + } + }; + } + /* istanbul ignore next */ - NON_ASCII_WHITESPACES = [0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF]; - function isWhiteSpace(ch) { - return ch === 0x20 || ch === 0x09 || ch === 0x0B || ch === 0x0C || ch === 0xA0 || ch >= 0x1680 && NON_ASCII_WHITESPACES.indexOf(ch) >= 0; - } // 7.3 Line Terminators + if (optionInfo.deprecated) { + handlers.deprecated = true; + } // allow CLI overriding, e.g., prettier package.json --tab-width 1 --tab-width 2 - function isLineTerminator(ch) { - return ch === 0x0A || ch === 0x0D || ch === 0x2028 || ch === 0x2029; - } // 7.6 Identifier Names and Identifiers + if (isCLI && !optionInfo.array) { + const originalPreprocess = parameters.preprocess || (x => x); + parameters.preprocess = (value, schema, utils) => schema.preprocess(originalPreprocess(Array.isArray(value) ? value[value.length - 1] : value), utils); + } - function fromCodePoint(cp) { - if (cp <= 0xFFFF) { - return String.fromCharCode(cp); - } + return optionInfo.array ? lib$1.ArraySchema.create(Object.assign({}, isCLI ? { + preprocess: v => [].concat(v) + } : {}, handlers, { + valueSchema: SchemaConstructor.create(parameters) + })) : SchemaConstructor.create(Object.assign({}, parameters, handlers)); +} - var cu1 = String.fromCharCode(Math.floor((cp - 0x10000) / 0x400) + 0xD800); - var cu2 = String.fromCharCode((cp - 0x10000) % 0x400 + 0xDC00); - return cu1 + cu2; - } +function normalizeApiOptions(options, optionInfos, opts) { + return normalizeOptions(options, optionInfos, opts); +} - IDENTIFIER_START = new Array(0x80); +function normalizeCliOptions(options, optionInfos, opts) { + return normalizeOptions(options, optionInfos, Object.assign({ + isCLI: true + }, opts)); +} - for (ch = 0; ch < 0x80; ++ch) { - IDENTIFIER_START[ch] = ch >= 0x61 && ch <= 0x7A || // a..z - ch >= 0x41 && ch <= 0x5A || // A..Z - ch === 0x24 || ch === 0x5F; // $ (dollar) and _ (underscore) - } +var optionsNormalizer = { + normalizeApiOptions, + normalizeCliOptions +}; - IDENTIFIER_PART = new Array(0x80); +/** + * @typedef {import("./types/estree").Node} Node + */ - for (ch = 0; ch < 0x80; ++ch) { - IDENTIFIER_PART[ch] = ch >= 0x61 && ch <= 0x7A || // a..z - ch >= 0x41 && ch <= 0x5A || // A..Z - ch >= 0x30 && ch <= 0x39 || // 0..9 - ch === 0x24 || ch === 0x5F; // $ (dollar) and _ (underscore) - } +function locStart(node, opts) { + const { + ignoreDecorators + } = opts || {}; // Handle nodes with decorators. They should start at the first decorator - function isIdentifierStartES5(ch) { - return ch < 0x80 ? IDENTIFIER_START[ch] : ES5Regex.NonAsciiIdentifierStart.test(fromCodePoint(ch)); - } + if (!ignoreDecorators) { + const decorators = node.declaration && node.declaration.decorators || node.decorators; - function isIdentifierPartES5(ch) { - return ch < 0x80 ? IDENTIFIER_PART[ch] : ES5Regex.NonAsciiIdentifierPart.test(fromCodePoint(ch)); + if (decorators && decorators.length > 0) { + return locStart(decorators[0]); } + } - function isIdentifierStartES6(ch) { - return ch < 0x80 ? IDENTIFIER_START[ch] : ES6Regex.NonAsciiIdentifierStart.test(fromCodePoint(ch)); - } + return node.range ? node.range[0] : node.start; +} - function isIdentifierPartES6(ch) { - return ch < 0x80 ? IDENTIFIER_PART[ch] : ES6Regex.NonAsciiIdentifierPart.test(fromCodePoint(ch)); - } +function locEnd(node) { + const end = node.range ? node.range[1] : node.end; + return node.typeAnnotation ? Math.max(end, locEnd(node.typeAnnotation)) : end; +} +/** + * @param {Node} startNode + * @param {Node | number} endNodeOrLength + * @returns {number[]} + */ - module.exports = { - isDecimalDigit: isDecimalDigit, - isHexDigit: isHexDigit, - isOctalDigit: isOctalDigit, - isWhiteSpace: isWhiteSpace, - isLineTerminator: isLineTerminator, - isIdentifierStartES5: isIdentifierStartES5, - isIdentifierPartES5: isIdentifierPartES5, - isIdentifierStartES6: isIdentifierStartES6, - isIdentifierPartES6: isIdentifierPartES6 - }; - })(); - /* vim: set sw=4 ts=4 et tw=80 : */ -}); -var code_1 = code.isDecimalDigit; -var code_2 = code.isHexDigit; -var code_3 = code.isOctalDigit; -var code_4 = code.isWhiteSpace; -var code_5 = code.isLineTerminator; -var code_6 = code.isIdentifierStartES5; -var code_7 = code.isIdentifierPartES5; -var code_8 = code.isIdentifierStartES6; -var code_9 = code.isIdentifierPartES6; - -var keyword = createCommonjsModule(function (module) { - /* - Copyright (C) 2013 Yusuke Suzuki - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - (function () { +function composeLoc(startNode, endNodeOrLength = startNode) { + const start = locStart(startNode); + const end = typeof endNodeOrLength === "number" ? start + endNodeOrLength : locEnd(endNodeOrLength); + return [start, end]; +} +/** + * @param {Node} nodeA + * @param {Node} nodeB + * @returns {boolean} + */ - var code$1 = code; - function isStrictModeReservedWordES6(id) { - switch (id) { - case 'implements': - case 'interface': - case 'package': - case 'private': - case 'protected': - case 'public': - case 'static': - case 'let': - return true; +function hasSameLocStart(nodeA, nodeB) { + return locStart(nodeA) === locStart(nodeB); +} +/** + * @param {Node} nodeA + * @param {Node} nodeB + * @returns {boolean} + */ - default: - return false; - } - } - function isKeywordES5(id, strict) { - // yield should not be treated as keyword under non-strict mode. - if (!strict && id === 'yield') { - return false; - } +function hasSameLocEnd(nodeA, nodeB) { + return locEnd(nodeA) === locEnd(nodeB); +} +/** + * @param {Node} nodeA + * @param {Node} nodeB + * @returns {boolean} + */ - return isKeywordES6(id, strict); - } - function isKeywordES6(id, strict) { - if (strict && isStrictModeReservedWordES6(id)) { - return true; - } +function hasSameLoc(nodeA, nodeB) { + return hasSameLocStart(nodeA, nodeB) && hasSameLocEnd(nodeA, nodeB); +} - switch (id.length) { - case 2: - return id === 'if' || id === 'in' || id === 'do'; +var loc = { + locStart, + locEnd, + composeLoc, + hasSameLocStart, + hasSameLoc +}; - case 3: - return id === 'var' || id === 'for' || id === 'new' || id === 'try'; +var jsTokens = createCommonjsModule(function (module, exports) { + // Copyright 2014, 2015, 2016, 2017, 2018 Simon Lydell + // License: MIT. (See LICENSE.) + Object.defineProperty(exports, "__esModule", { + value: true + }); // This regex comes from regex.coffee, and is inserted here by generate-index.js + // (run `npm run build`). - case 4: - return id === 'this' || id === 'else' || id === 'case' || id === 'void' || id === 'with' || id === 'enum'; + exports.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; - case 5: - return id === 'while' || id === 'break' || id === 'catch' || id === 'throw' || id === 'const' || id === 'yield' || id === 'class' || id === 'super'; + exports.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; + }; +}); - case 6: - return id === 'return' || id === 'typeof' || id === 'delete' || id === 'switch' || id === 'export' || id === 'import'; +var identifier = createCommonjsModule(function (module, exports) { - case 7: - return id === 'default' || id === 'finally' || id === 'extends'; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.isIdentifierStart = isIdentifierStart; + exports.isIdentifierChar = isIdentifierChar; + exports.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; + } - case 8: - return id === 'function' || id === 'continue' || id === 'debugger'; + return false; + } - case 10: - return id === 'instanceof'; + 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; - default: - return false; - } + if (code <= 0xffff) { + return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)); } - function isReservedWordES5(id, strict) { - return id === 'null' || id === 'true' || id === 'false' || isKeywordES5(id, strict); - } + return isInAstralSet(code, astralIdentifierStartCodes); + } - function isReservedWordES6(id, strict) { - return id === 'null' || id === 'true' || id === 'false' || isKeywordES6(id, strict); - } + 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; - function isRestrictedWord(id) { - return id === 'eval' || id === 'arguments'; + if (code <= 0xffff) { + return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)); } - function isIdentifierNameES5(id) { - var i, iz, ch; - - if (id.length === 0) { - return false; - } - - ch = id.charCodeAt(0); + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes); + } - if (!code$1.isIdentifierStartES5(ch)) { - return false; - } + function isIdentifierName(name) { + let isFirst = true; - for (i = 1, iz = id.length; i < iz; ++i) { - ch = id.charCodeAt(i); + for (let _i = 0, _Array$from = Array.from(name); _i < _Array$from.length; _i++) { + const char = _Array$from[_i]; + const cp = char.codePointAt(0); - if (!code$1.isIdentifierPartES5(ch)) { + if (isFirst) { + if (!isIdentifierStart(cp)) { return false; } - } - - return true; - } - - function decodeUtf16(lead, trail) { - return (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000; - } - - function isIdentifierNameES6(id) { - var i, iz, ch, lowCh, check; - if (id.length === 0) { + isFirst = false; + } else if (!isIdentifierChar(cp)) { return false; } + } - check = code$1.isIdentifierStartES6; + return !isFirst; + } +}); - for (i = 0, iz = id.length; i < iz; ++i) { - ch = id.charCodeAt(i); +var keyword = createCommonjsModule(function (module, exports) { - if (0xD800 <= ch && ch <= 0xDBFF) { - ++i; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.isReservedWord = isReservedWord; + exports.isStrictReservedWord = isStrictReservedWord; + exports.isStrictBindOnlyReservedWord = isStrictBindOnlyReservedWord; + exports.isStrictBindReservedWord = isStrictBindReservedWord; + exports.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 = new Set(reservedWords.keyword); + const reservedWordsStrictSet = new Set(reservedWords.strict); + const reservedWordsStrictBindSet = new Set(reservedWords.strictBind); - if (i >= iz) { - return false; - } + function isReservedWord(word, inModule) { + return inModule && word === "await" || word === "enum"; + } - lowCh = id.charCodeAt(i); + function isStrictReservedWord(word, inModule) { + return isReservedWord(word, inModule) || reservedWordsStrictSet.has(word); + } - if (!(0xDC00 <= lowCh && lowCh <= 0xDFFF)) { - return false; - } + function isStrictBindOnlyReservedWord(word) { + return reservedWordsStrictBindSet.has(word); + } - ch = decodeUtf16(ch, lowCh); - } + function isStrictBindReservedWord(word, inModule) { + return isStrictReservedWord(word, inModule) || isStrictBindOnlyReservedWord(word); + } - if (!check(ch)) { - return false; - } + function isKeyword(word) { + return keywords.has(word); + } +}); - check = code$1.isIdentifierPartES6; - } +var lib$2 = createCommonjsModule(function (module, exports) { - return true; + Object.defineProperty(exports, "__esModule", { + value: true + }); + Object.defineProperty(exports, "isIdentifierName", { + enumerable: true, + get: function () { + return identifier.isIdentifierName; } - - function isIdentifierES5(id, strict) { - return isIdentifierNameES5(id) && !isReservedWordES5(id, strict); + }); + Object.defineProperty(exports, "isIdentifierChar", { + enumerable: true, + get: function () { + return identifier.isIdentifierChar; } - - function isIdentifierES6(id, strict) { - return isIdentifierNameES6(id) && !isReservedWordES6(id, strict); + }); + Object.defineProperty(exports, "isIdentifierStart", { + enumerable: true, + get: function () { + return identifier.isIdentifierStart; } - - module.exports = { - isKeywordES5: isKeywordES5, - isKeywordES6: isKeywordES6, - isReservedWordES5: isReservedWordES5, - isReservedWordES6: isReservedWordES6, - isRestrictedWord: isRestrictedWord, - isIdentifierNameES5: isIdentifierNameES5, - isIdentifierNameES6: isIdentifierNameES6, - isIdentifierES5: isIdentifierES5, - isIdentifierES6: isIdentifierES6 - }; - })(); - /* vim: set sw=4 ts=4 et tw=80 : */ - -}); -var keyword_1 = keyword.isKeywordES5; -var keyword_2 = keyword.isKeywordES6; -var keyword_3 = keyword.isReservedWordES5; -var keyword_4 = keyword.isReservedWordES6; -var keyword_5 = keyword.isRestrictedWord; -var keyword_6 = keyword.isIdentifierNameES5; -var keyword_7 = keyword.isIdentifierNameES6; -var keyword_8 = keyword.isIdentifierES5; -var keyword_9 = keyword.isIdentifierES6; - -var utils$1 = createCommonjsModule(function (module, exports) { - /* - Copyright (C) 2013 Yusuke Suzuki - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - (function () { - - exports.ast = ast; - exports.code = code; - exports.keyword = keyword; - })(); - /* vim: set sw=4 ts=4 et tw=80 : */ - + }); + 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 utils_1$1 = utils$1.ast; -var utils_2$1 = utils$1.code; -var utils_3$1 = utils$1.keyword; var matchOperatorsRe$1 = /[|\\{}()[\]^$+*?.]/g; -var escapeStringRegexp$1 = function (str) { +var escapeStringRegexp$2 = function (str) { if (typeof str !== 'string') { throw new TypeError('Expected a string'); } @@ -10095,21 +12374,6 @@ var conversions$2 = createCommonjsModule(function (module) { return [val / 255 * 100]; }; }); -var conversions_1$1 = conversions$2.rgb; -var conversions_2$1 = conversions$2.hsl; -var conversions_3$1 = conversions$2.hsv; -var conversions_4$1 = conversions$2.hwb; -var conversions_5$1 = conversions$2.cmyk; -var conversions_6$1 = conversions$2.xyz; -var conversions_7$1 = conversions$2.lab; -var conversions_8$1 = conversions$2.lch; -var conversions_9$1 = conversions$2.hex; -var conversions_10$1 = conversions$2.keyword; -var conversions_11$1 = conversions$2.ansi16; -var conversions_12$1 = conversions$2.ansi256; -var conversions_13$1 = conversions$2.hcg; -var conversions_14$1 = conversions$2.apple; -var conversions_15$1 = conversions$2.gray; /* this function routes a model to all other models. @@ -10489,7 +12753,7 @@ function supportsColor$2(stream) { // 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('.'); + const osRelease = os__default['default'].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; @@ -10719,7 +12983,7 @@ var chalk$2 = createCommonjsModule(function (module) { } for (const key of Object.keys(ansiStyles$2)) { - ansiStyles$2[key].closeRe = new RegExp(escapeStringRegexp$1(ansiStyles$2[key].close), 'g'); + ansiStyles$2[key].closeRe = new RegExp(escapeStringRegexp$2(ansiStyles$2[key].close), 'g'); styles[key] = { get() { const codes = ansiStyles$2[key]; @@ -10735,7 +12999,7 @@ var chalk$2 = createCommonjsModule(function (module) { } }; - ansiStyles$2.color.closeRe = new RegExp(escapeStringRegexp$1(ansiStyles$2.color.close), 'g'); + ansiStyles$2.color.closeRe = new RegExp(escapeStringRegexp$2(ansiStyles$2.color.close), 'g'); for (const model of Object.keys(ansiStyles$2.color.ansi)) { if (skipModels.has(model)) { @@ -10759,7 +13023,7 @@ var chalk$2 = createCommonjsModule(function (module) { }; } - ansiStyles$2.bgColor.closeRe = new RegExp(escapeStringRegexp$1(ansiStyles$2.bgColor.close), 'g'); + ansiStyles$2.bgColor.closeRe = new RegExp(escapeStringRegexp$2(ansiStyles$2.bgColor.close), 'g'); for (const model of Object.keys(ansiStyles$2.bgColor.ansi)) { if (skipModels.has(model)) { @@ -10897,9 +13161,8 @@ var chalk$2 = createCommonjsModule(function (module) { module.exports.supportsColor = stdoutColor; module.exports.default = module.exports; // For TypeScript }); -var chalk_1$1 = chalk$2.supportsColor; -var lib$1 = createCommonjsModule(function (module, exports) { +var lib$3 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true @@ -10910,8 +13173,6 @@ var lib$1 = createCommonjsModule(function (module, exports) { var _jsTokens = _interopRequireWildcard(jsTokens); - var _esutils = _interopRequireDefault(utils$1); - var _chalk = _interopRequireDefault(chalk$2); function _interopRequireDefault(obj) { @@ -10995,7 +13256,7 @@ var lib$1 = createCommonjsModule(function (module, exports) { const token = (0, _jsTokens.matchToToken)(match); if (token.type === "name") { - if (_esutils.default.keyword.isReservedWordES6(token.value)) { + if ((0, lib$2.isKeyword)(token.value) || (0, lib$2.isReservedWord)(token.value)) { return "keyword"; } @@ -11059,11 +13320,8 @@ var lib$1 = createCommonjsModule(function (module, exports) { } } }); -unwrapExports(lib$1); -var lib_1 = lib$1.shouldHighlight; -var lib_2 = lib$1.getChalk; -var lib$2 = createCommonjsModule(function (module, exports) { +var lib$4 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true @@ -11071,7 +13329,7 @@ var lib$2 = createCommonjsModule(function (module, exports) { exports.codeFrameColumns = codeFrameColumns; exports.default = _default; - var _highlight = _interopRequireWildcard(lib$1); + var _highlight = _interopRequireWildcard(lib$3); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; @@ -11142,7 +13400,7 @@ var lib$2 = createCommonjsModule(function (module, exports) { column: 0, line: -1 }, loc.start); - const endLoc = Object.assign({}, startLoc, {}, loc.end); + const endLoc = Object.assign({}, startLoc, loc.end); const { linesAbove = 2, linesBelow = 3 @@ -11279,8 +13537,6 @@ var lib$2 = createCommonjsModule(function (module, exports) { return codeFrameColumns(rawLines, location, opts); } }); -unwrapExports(lib$2); -var lib_1$1 = lib$2.codeFrameColumns; const { ConfigError: ConfigError$1 @@ -11298,6 +13554,9 @@ function getParsers(options) { const parsers = {}; for (const plugin of options.plugins) { + // TODO: test this with plugins + + /* istanbul ignore next */ if (!plugin.parsers) { continue; } @@ -11327,21 +13586,17 @@ function resolveParser(opts, parsers) { if (Object.prototype.hasOwnProperty.call(parsers, opts.parser)) { return parsers[opts.parser]; } - /* istanbul ignore next */ - - { - try { - return { - parse: require(path$2.resolve(process.cwd(), opts.parser)), - astFormat: "estree", - locStart: locStart$1, - locEnd: locEnd$1 - }; - } catch (err) { - /* istanbul ignore next */ - throw new ConfigError$1(`Couldn't resolve parser "${opts.parser}"`); - } + try { + return { + parse: require(path__default['default'].resolve(process.cwd(), opts.parser)), + astFormat: "estree", + locStart: locStart$1, + locEnd: locEnd$1 + }; + } catch (err) { + /* istanbul ignore next */ + throw new ConfigError$1(`Couldn't resolve parser "${opts.parser}"`); } } } @@ -11375,8 +13630,10 @@ function parse(text, opts) { } = error; if (loc) { - const codeFrame = lib$2; - error.codeFrame = codeFrame.codeFrameColumns(text, loc, { + const { + codeFrameColumns + } = lib$4; + error.codeFrame = codeFrameColumns(text, loc, { highlightCode: true }); error.message += "\n" + error.codeFrame; @@ -11398,7 +13655,7 @@ const { UndefinedParserError: UndefinedParserError$1 } = errors; const { - getSupportInfo: getSupportInfo$1 + getSupportInfo: getSupportInfo$2 } = support; const { resolveParser: resolveParser$1 @@ -11414,12 +13671,12 @@ const hiddenDefaults = { function normalize$1(options, opts) { opts = opts || {}; const rawOptions = Object.assign({}, options); - const supportOptions = getSupportInfo$1({ + const supportOptions = getSupportInfo$2({ plugins: options.plugins, showUnreleased: true, showDeprecated: true }).options; - const defaults = Object.assign({}, hiddenDefaults, {}, fromPairs_1(supportOptions.filter(optionInfo => optionInfo.default !== undefined).map(option => [option.name, option.default]))); + const defaults = Object.assign({}, hiddenDefaults, fromPairs_1(supportOptions.filter(optionInfo => optionInfo.default !== undefined).map(option => [option.name, option.default]))); if (!rawOptions.parser) { if (!rawOptions.filepath) { @@ -11447,7 +13704,7 @@ function normalize$1(options, opts) { const pluginDefaults = supportOptions.filter(optionInfo => optionInfo.pluginDefaults && optionInfo.pluginDefaults[plugin.name] !== undefined).reduce((reduced, optionInfo) => Object.assign(reduced, { [optionInfo.name]: optionInfo.pluginDefaults[plugin.name] }), {}); - const mixedDefaults = Object.assign({}, defaults, {}, pluginDefaults); + const mixedDefaults = Object.assign({}, defaults, pluginDefaults); Object.keys(mixedDefaults).forEach(k => { if (rawOptions[k] == null) { rawOptions[k] = mixedDefaults[k]; @@ -11466,13 +13723,17 @@ function normalize$1(options, opts) { function getPlugin(options) { const { astFormat - } = options; + } = options; // TODO: test this with plugins + + /* istanbul ignore next */ if (!astFormat) { throw new Error("getPlugin() requires astFormat to be set"); } - const printerPlugin = options.plugins.find(plugin => plugin.printers && plugin.printers[astFormat]); + const printerPlugin = options.plugins.find(plugin => plugin.printers && plugin.printers[astFormat]); // TODO: test this with plugins + + /* istanbul ignore next */ if (!printerPlugin) { throw new Error(`Couldn't find plugin for AST format "${astFormat}"`); @@ -11482,6 +13743,7 @@ function getPlugin(options) { } function getInterpreter(filepath) { + /* istanbul ignore next */ if (typeof filepath !== "string") { return ""; } @@ -11489,7 +13751,7 @@ function getInterpreter(filepath) { let fd; try { - fd = fs$3.openSync(filepath, "r"); + fd = fs__default['default'].openSync(filepath, "r"); } catch (err) { // istanbul ignore next return ""; @@ -11516,26 +13778,28 @@ function getInterpreter(filepath) { } catch (err) { // There are some weird cases where paths are missing, causing Jest // failures. It's unclear what these correspond to in the real world. + + /* istanbul ignore next */ return ""; } finally { try { // There are some weird cases where paths are missing, causing Jest // failures. It's unclear what these correspond to in the real world. - fs$3.closeSync(fd); + fs__default['default'].closeSync(fd); } catch (err) {// nop } } } function inferParser(filepath, plugins) { - const filename = path$2.basename(filepath).toLowerCase(); - const languages = getSupportInfo$1({ + const filename = path__default['default'].basename(filepath).toLowerCase(); + const languages = getSupportInfo$2({ plugins }).languages.filter(language => language.since !== null); // If the file has no extension, we can try to infer the language from the // interpreter in the shebang line, if any; but since this requires FS access, // do it last. - let language = languages.find(language => language.extensions && language.extensions.some(extension => filename.endsWith(extension)) || language.filenames && language.filenames.find(name => name.toLowerCase() === filename)); + let language = languages.find(language => language.extensions && language.extensions.some(extension => filename.endsWith(extension)) || language.filenames && language.filenames.some(name => name.toLowerCase() === filename)); if (!language && !filename.includes(".")) { const interpreter = getInterpreter(filepath); @@ -11560,19 +13824,28 @@ function massageAST(ast, options, parent) { return ast; } + const cleanFunction = options.printer.massageAstNode; + let ignoredProperties; + + if (cleanFunction && cleanFunction.ignoredProperties) { + ignoredProperties = cleanFunction.ignoredProperties; + } else { + ignoredProperties = new Set(); + } + const newObj = {}; for (const key of Object.keys(ast)) { - if (typeof ast[key] !== "function") { + if (!ignoredProperties.has(key) && typeof ast[key] !== "function") { newObj[key] = massageAST(ast[key], options, ast); } } - if (options.printer.massageAstNode) { - const result = options.printer.massageAstNode(ast, newObj, parent); + if (cleanFunction) { + const result = cleanFunction(ast, newObj, parent); if (result === null) { - return undefined; + return; } if (result) { @@ -11585,17923 +13858,18990 @@ function massageAST(ast, options, parent) { var massageAst = massageAST; -/** - * @param {Doc[]} parts - * @returns Doc - */ +/** @type {import("assert")} */ -function concat(parts) { - // access the internals of a document directly. - // if(parts.length === 1) { - // // If it's a single document, no need to concat it. - // return parts[0]; - // } +const { + builders: { + concat: concat$3, + line: line$1, + hardline: hardline$1, + breakParent: breakParent$1, + indent: indent$1, + lineSuffix: lineSuffix$1, + join: join$1, + cursor: cursor$2 + } +} = document; +const { + hasNewline: hasNewline$1, + skipNewline: skipNewline$1, + skipSpaces: skipSpaces$1, + isPreviousLineEmpty: isPreviousLineEmpty$1, + addLeadingComment: addLeadingComment$1, + addDanglingComment: addDanglingComment$1, + addTrailingComment: addTrailingComment$1 +} = util; +const childNodesCacheKey = Symbol("child-nodes"); +function getSortedChildNodes(node, options, resultArray) { + if (!node) { + return; + } - return { - type: "concat", - parts - }; -} -/** - * @param {Doc} contents - * @returns Doc - */ + const { + printer, + locStart, + locEnd + } = options; + if (resultArray) { + if (printer.canAttachComment && printer.canAttachComment(node)) { + // This reverse insertion sort almost always takes constant + // time because we almost always (maybe always?) append the + // nodes in order anyway. + let i; -function indent(contents) { + for (i = resultArray.length - 1; i >= 0; --i) { + if (locStart(resultArray[i]) <= locStart(node) && locEnd(resultArray[i]) <= locEnd(node)) { + break; + } + } - return { - type: "indent", - contents - }; -} -/** - * @param {number} n - * @param {Doc} contents - * @returns Doc - */ + resultArray.splice(i + 1, 0, node); + return; + } + } else if (node[childNodesCacheKey]) { + return node[childNodesCacheKey]; + } + const childNodes = printer.getCommentChildNodes && printer.getCommentChildNodes(node, options) || typeof node === "object" && Object.keys(node).filter(n => n !== "enclosingNode" && n !== "precedingNode" && n !== "followingNode" && n !== "tokens" && n !== "comments").map(n => node[n]); -function align(n, contents) { + if (!childNodes) { + return; + } - return { - type: "align", - contents, - n - }; -} -/** - * @param {Doc} contents - * @param {object} [opts] - TBD ??? - * @returns Doc - */ + if (!resultArray) { + Object.defineProperty(node, childNodesCacheKey, { + value: resultArray = [], + enumerable: false + }); + } + childNodes.forEach(childNode => { + getSortedChildNodes(childNode, options, resultArray); + }); + return resultArray; +} // As efficiently as possible, decorate the comment object with +// .precedingNode, .enclosingNode, and/or .followingNode properties, at +// least one of which is guaranteed to be defined. -function group(contents, opts) { - opts = opts || {}; - return { - type: "group", - id: opts.id, - contents, - break: !!opts.shouldBreak, - expandedStates: opts.expandedStates - }; -} -/** - * @param {Doc} contents - * @returns Doc - */ +function decorateComment(node, comment, options) { + const { + locStart, + locEnd + } = options; + const commentStart = locStart(comment); + const commentEnd = locEnd(comment); + const childNodes = getSortedChildNodes(node, options); + let precedingNode; + let followingNode; // Time to dust off the old binary search robes and wizard hat. + let left = 0; + let right = childNodes.length; -function dedentToRoot(contents) { - return align(-Infinity, contents); -} -/** - * @param {Doc} contents - * @returns Doc - */ + while (left < right) { + const middle = left + right >> 1; + const child = childNodes[middle]; + const start = locStart(child); + const end = locEnd(child); + if (start <= commentStart && commentEnd <= end) { + // The comment is completely contained by this child node. + comment.enclosingNode = child; + decorateComment(child, comment, options); + return; // Abandon the binary search at this level. + } -function markAsRoot(contents) { - // @ts-ignore - TBD ???: - return align({ - type: "root" - }, contents); -} -/** - * @param {Doc} contents - * @returns Doc - */ + if (start <= commentStart) { + // This child node falls completely before the comment. + // Because we will never consider this node or any nodes + // before it again, this node must be the closest preceding + // node we have encountered so far. + precedingNode = child; + left = middle + 1; + continue; + } + if (commentEnd <= start) { + // This child node falls completely after the comment. + // Because we will never consider this node or any nodes after + // it again, this node must be the closest following node we + // have encountered so far. + followingNode = child; + right = middle; + continue; + } + /* istanbul ignore next */ -function dedent(contents) { - return align(-1, contents); + + throw new Error("Comment location overlaps with node location"); + } // We don't want comments inside of different expressions inside of the same + // template literal to move to another expression. + + + if (comment.enclosingNode && comment.enclosingNode.type === "TemplateLiteral") { + const { + quasis + } = comment.enclosingNode; + const commentIndex = findExpressionIndexForComment(quasis, comment, options); + + if (precedingNode && findExpressionIndexForComment(quasis, precedingNode, options) !== commentIndex) { + precedingNode = null; + } + + if (followingNode && findExpressionIndexForComment(quasis, followingNode, options) !== commentIndex) { + followingNode = null; + } + } + + if (precedingNode) { + comment.precedingNode = precedingNode; + } + + if (followingNode) { + comment.followingNode = followingNode; + } } -/** - * @param {Doc[]} states - * @param {object} [opts] - TBD ??? - * @returns Doc - */ +function attach(comments, ast, text, options) { + if (!Array.isArray(comments)) { + return; + } -function conditionalGroup(states, opts) { - return group(states[0], Object.assign({}, opts, { - expandedStates: states - })); + const tiesToBreak = []; + const { + locStart, + locEnd + } = options; + comments.forEach((comment, i) => { + if (options.parser === "json" || options.parser === "json5" || options.parser === "__js_expression" || options.parser === "__vue_expression") { + if (locStart(comment) - locStart(ast) <= 0) { + addLeadingComment$1(ast, comment); + return; + } + + if (locEnd(comment) - locEnd(ast) >= 0) { + addTrailingComment$1(ast, comment); + return; + } + } + + decorateComment(ast, comment, options); + const { + precedingNode, + enclosingNode, + followingNode + } = comment; + const pluginHandleOwnLineComment = options.printer.handleComments && options.printer.handleComments.ownLine ? options.printer.handleComments.ownLine : () => false; + const pluginHandleEndOfLineComment = options.printer.handleComments && options.printer.handleComments.endOfLine ? options.printer.handleComments.endOfLine : () => false; + const pluginHandleRemainingComment = options.printer.handleComments && options.printer.handleComments.remaining ? options.printer.handleComments.remaining : () => false; + const isLastComment = comments.length - 1 === i; + + if (hasNewline$1(text, locStart(comment), { + backwards: true + })) { + // If a comment exists on its own line, prefer a leading comment. + // We also need to check if it's the first line of the file. + if (pluginHandleOwnLineComment(comment, text, options, ast, isLastComment)) ; else if (followingNode) { + // Always a leading comment. + addLeadingComment$1(followingNode, comment); + } else if (precedingNode) { + addTrailingComment$1(precedingNode, comment); + } else if (enclosingNode) { + addDanglingComment$1(enclosingNode, comment); + } else { + // There are no nodes, let's attach it to the root of the ast + + /* istanbul ignore next */ + addDanglingComment$1(ast, comment); + } + } else if (hasNewline$1(text, locEnd(comment))) { + if (pluginHandleEndOfLineComment(comment, text, options, ast, isLastComment)) ; else if (precedingNode) { + // There is content before this comment on the same line, but + // none after it, so prefer a trailing comment of the previous node. + addTrailingComment$1(precedingNode, comment); + } else if (followingNode) { + addLeadingComment$1(followingNode, comment); + } else if (enclosingNode) { + addDanglingComment$1(enclosingNode, comment); + } else { + // There are no nodes, let's attach it to the root of the ast + + /* istanbul ignore next */ + addDanglingComment$1(ast, comment); + } + } else { + if (pluginHandleRemainingComment(comment, text, options, ast, isLastComment)) ; else if (precedingNode && followingNode) { + // Otherwise, text exists both before and after the comment on + // the same line. If there is both a preceding and following + // node, use a tie-breaking algorithm to determine if it should + // be attached to the next or previous node. In the last case, + // simply attach the right node; + const tieCount = tiesToBreak.length; + + if (tieCount > 0) { + const lastTie = tiesToBreak[tieCount - 1]; + + if (lastTie.followingNode !== comment.followingNode) { + breakTies(tiesToBreak, text, options); + } + } + + tiesToBreak.push(comment); + } else if (precedingNode) { + addTrailingComment$1(precedingNode, comment); + } else if (followingNode) { + addLeadingComment$1(followingNode, comment); + } else if (enclosingNode) { + addDanglingComment$1(enclosingNode, comment); + } else { + // There are no nodes, let's attach it to the root of the ast + + /* istanbul ignore next */ + addDanglingComment$1(ast, comment); + } + } + }); + breakTies(tiesToBreak, text, options); + comments.forEach(comment => { + // These node references were useful for breaking ties, but we + // don't need them anymore, and they create cycles in the AST that + // may lead to infinite recursion if we don't delete them here. + delete comment.precedingNode; + delete comment.enclosingNode; + delete comment.followingNode; + }); } -/** - * @param {Doc[]} parts - * @returns Doc - */ +function breakTies(tiesToBreak, text, options) { + const tieCount = tiesToBreak.length; + + if (tieCount === 0) { + return; + } + + const { + precedingNode, + followingNode, + enclosingNode + } = tiesToBreak[0]; + const gapRegExp = options.printer.getGapRegex && options.printer.getGapRegex(enclosingNode) || /^[\s(]*$/; + let gapEndPos = options.locStart(followingNode); // Iterate backwards through tiesToBreak, examining the gaps + // between the tied comments. In order to qualify as leading, a + // comment must be separated from followingNode by an unbroken series of + // gaps (or other comments). Gaps should only contain whitespace or open + // parentheses. + + let indexOfFirstLeadingComment; + + for (indexOfFirstLeadingComment = tieCount; indexOfFirstLeadingComment > 0; --indexOfFirstLeadingComment) { + const comment = tiesToBreak[indexOfFirstLeadingComment - 1]; + assert__default['default'].strictEqual(comment.precedingNode, precedingNode); + assert__default['default'].strictEqual(comment.followingNode, followingNode); + const gap = text.slice(options.locEnd(comment), gapEndPos); + + if (gapRegExp.test(gap)) { + gapEndPos = options.locStart(comment); + } else { + // The gap string contained something other than whitespace or open + // parentheses. + break; + } + } + + tiesToBreak.forEach((comment, i) => { + if (i < indexOfFirstLeadingComment) { + addTrailingComment$1(precedingNode, comment); + } else { + addLeadingComment$1(followingNode, comment); + } + }); -function fill(parts) { + for (const node of [precedingNode, followingNode]) { + if (node.comments && node.comments.length > 1) { + node.comments.sort((a, b) => options.locStart(a) - options.locStart(b)); + } + } - return { - type: "fill", - parts - }; + tiesToBreak.length = 0; } -/** - * @param {Doc} [breakContents] - * @param {Doc} [flatContents] - * @param {object} [opts] - TBD ??? - * @returns Doc - */ +function printComment(commentPath, options) { + const comment = commentPath.getValue(); + comment.printed = true; + return options.printer.printComment(commentPath, options); +} -function ifBreak(breakContents, flatContents, opts) { - opts = opts || {}; +function findExpressionIndexForComment(quasis, comment, options) { + const startPos = options.locStart(comment) - 1; - return { - type: "if-break", - breakContents, - flatContents, - groupId: opts.groupId - }; -} -/** - * @param {Doc} contents - * @returns Doc - */ + for (let i = 1; i < quasis.length; ++i) { + if (startPos < options.locStart(quasis[i])) { + return i - 1; + } + } // We haven't found it, it probably means that some of the locations are off. + // Let's just return the first one. + /* istanbul ignore next */ -function lineSuffix(contents) { - return { - type: "line-suffix", - contents - }; + return 0; } -const lineSuffixBoundary = { - type: "line-suffix-boundary" -}; -const breakParent = { - type: "break-parent" -}; -const trim = { - type: "trim" -}; -const line = { - type: "line" -}; -const softline = { - type: "line", - soft: true -}; -const hardline = concat([{ - type: "line", - hard: true -}, breakParent]); -const literalline = concat([{ - type: "line", - hard: true, - literal: true -}, breakParent]); -const cursor = { - type: "cursor", - placeholder: Symbol("cursor") -}; -/** - * @param {Doc} sep - * @param {Doc[]} arr - * @returns Doc - */ +function printLeadingComment(commentPath, options) { + const comment = commentPath.getValue(); + const contents = printComment(commentPath, options); + /* istanbul ignore next */ -function join(sep, arr) { - const res = []; + if (!contents) { + return ""; + } - for (let i = 0; i < arr.length; i++) { - if (i !== 0) { - res.push(sep); - } + const isBlock = options.printer.isBlockComment && options.printer.isBlockComment(comment); // Leading block comments should see if they need to stay on the + // same line or not. - res.push(arr[i]); + if (isBlock) { + const lineBreak = hasNewline$1(options.originalText, options.locEnd(comment)) ? hasNewline$1(options.originalText, options.locStart(comment), { + backwards: true + }) ? hardline$1 : line$1 : " "; + return concat$3([contents, lineBreak]); } - return concat(res); + return concat$3([contents, hardline$1]); } -/** - * @param {Doc} doc - * @param {number} size - * @param {number} tabWidth - */ +function printTrailingComment(commentPath, options) { + const comment = commentPath.getValue(); + const contents = printComment(commentPath, options); + /* istanbul ignore next */ -function addAlignmentToDoc(doc, size, tabWidth) { - let aligned = doc; + if (!contents) { + return ""; + } - if (size > 0) { - // Use indent to add tabs for all the levels of tabs we need - for (let i = 0; i < Math.floor(size / tabWidth); ++i) { - aligned = indent(aligned); - } // Use align for all the spaces that are needed + const { + printer, + originalText, + locStart + } = options; + const isBlock = printer.isBlockComment && printer.isBlockComment(comment); + if (hasNewline$1(originalText, locStart(comment), { + backwards: true + })) { + // This allows comments at the end of nested structures: + // { + // x: 1, + // y: 2 + // // A comment + // } + // Those kinds of comments are almost always leading comments, but + // here it doesn't go "outside" the block and turns it into a + // trailing comment for `2`. We can simulate the above by checking + // if this a comment on its own line; normal trailing comments are + // always at the end of another expression. + const isLineBeforeEmpty = isPreviousLineEmpty$1(originalText, comment, locStart); + return lineSuffix$1(concat$3([hardline$1, isLineBeforeEmpty ? hardline$1 : "", contents])); + } - aligned = align(size % tabWidth, aligned); // size is absolute from 0 and not relative to the current - // indentation, so we use -Infinity to reset the indentation to 0 + let printed = concat$3([" ", contents]); // Trailing block comments never need a newline - aligned = align(-Infinity, aligned); + if (!isBlock) { + printed = concat$3([lineSuffix$1(printed), breakParent$1]); } - return aligned; + return printed; } -var docBuilders = { - concat, - join, - line, - softline, - hardline, - literalline, - group, - conditionalGroup, - fill, - lineSuffix, - lineSuffixBoundary, - cursor, - breakParent, - ifBreak, - trim, - indent, - align, - addAlignmentToDoc, - markAsRoot, - dedentToRoot, - dedent -}; - -var ansiRegex = ({ - onlyFirst = false -} = {}) => { - const pattern = ['[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[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 printDanglingComments(path, options, sameIndent, filter) { + const parts = []; + const node = path.getValue(); -var stripAnsi = string => typeof string === 'string' ? string.replace(ansiRegex(), '') : string; + if (!node || !node.comments) { + return ""; + } -/* eslint-disable yoda */ + path.each(commentPath => { + const comment = commentPath.getValue(); -const isFullwidthCodePoint = codePoint => { - if (Number.isNaN(codePoint)) { - return false; - } // Code points are derived from: - // http://www.unix.org/Public/UNIDATA/EastAsianWidth.txt + if (comment && !comment.leading && !comment.trailing && (!filter || filter(comment))) { + parts.push(printComment(commentPath, options)); + } + }, "comments"); + if (parts.length === 0) { + return ""; + } - if (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)) { - return true; + if (sameIndent) { + return join$1(hardline$1, parts); } - return false; -}; + return indent$1(concat$3([hardline$1, join$1(hardline$1, parts)])); +} -var isFullwidthCodePoint_1 = isFullwidthCodePoint; -var default_1$1 = isFullwidthCodePoint; -isFullwidthCodePoint_1.default = default_1$1; +function prependCursorPlaceholder(path, options, printed) { + if (path.getNode() === options.cursorNode && path.getValue()) { + return concat$3([cursor$2, printed, cursor$2]); + } -var emojiRegex = function () { - // https://mths.be/emoji - return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\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\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])|\uD83C[\uDF3E\uDF73\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])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\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])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\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\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\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\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\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\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*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\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\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\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[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g; -}; + return printed; +} -const stringWidth = string => { - string = string.replace(emojiRegex(), ' '); +function printComments(path, print, options, needsSemi) { + const value = path.getValue(); + const printed = print(path); + const comments = value && value.comments; - if (typeof string !== 'string' || string.length === 0) { - return 0; + if (!comments || comments.length === 0) { + return prependCursorPlaceholder(path, options, printed); } - string = stripAnsi(string); - let width = 0; + const leadingParts = []; + const trailingParts = [needsSemi ? ";" : "", printed]; + path.each(commentPath => { + const comment = commentPath.getValue(); + const { + leading, + trailing + } = comment; - for (let i = 0; i < string.length; i++) { - const code = string.codePointAt(i); // Ignore control characters + if (leading) { + const contents = printLeadingComment(commentPath, options); + /* istanbul ignore next */ - if (code <= 0x1F || code >= 0x7F && code <= 0x9F) { - continue; - } // Ignore combining characters + if (!contents) { + return; + } + leadingParts.push(contents); + const text = options.originalText; + const index = skipNewline$1(text, skipSpaces$1(text, options.locEnd(comment))); - if (code >= 0x300 && code <= 0x36F) { - continue; - } // Surrogates + if (index !== false && hasNewline$1(text, index)) { + leadingParts.push(hardline$1); + } + } else if (trailing) { + trailingParts.push(printTrailingComment(commentPath, options)); + } + }, "comments"); + return prependCursorPlaceholder(path, options, concat$3(leadingParts.concat(trailingParts))); +} +function ensureAllCommentsPrinted(astComments) { + if (!astComments) { + return; + } - if (code > 0xFFFF) { - i++; + astComments.forEach(comment => { + if (!comment.printed) { + throw new Error('Comment "' + comment.value.trim() + '" was not printed. Please report this error!'); } - width += isFullwidthCodePoint_1(code) ? 2 : 1; - } + delete comment.printed; + }); +} - return width; +var comments = { + attach, + printComments, + printDanglingComments, + getSortedChildNodes, + ensureAllCommentsPrinted }; -var stringWidth_1 = stringWidth; // TODO: remove this in the next major version - -var default_1$2 = stringWidth; -stringWidth_1.default = default_1$2; +function getNodeHelper(path, count) { + const stackIndex = getNodeStackIndexHelper(path.stack, count); + return stackIndex === -1 ? null : path.stack[stackIndex]; +} -const matchOperatorsRegex = /[|\\{}()[\]^$+*?.-]/g; +function getNodeStackIndexHelper(stack, count) { + for (let i = stack.length - 1; i >= 0; i -= 2) { + const value = stack[i]; -var escapeStringRegexp$2 = string => { - if (typeof string !== 'string') { - throw new TypeError('Expected a string'); + if (value && !Array.isArray(value) && --count < 0) { + return i; + } } - return string.replace(matchOperatorsRegex, '\\$&'); -}; + return -1; +} -const notAsciiRegex = /[^\x20-\x7F]/; +class FastPath { + constructor(value) { + this.stack = [value]; + } // The name of the current property is always the penultimate element of + // this.stack, and always a String. -function getPenultimate(arr) { - if (arr.length > 1) { - return arr[arr.length - 2]; - } - return null; -} -/** - * @typedef {{backwards?: boolean}} SkipOptions - */ + getName() { + const { + stack + } = this; + const { + length + } = stack; -/** - * @param {string | RegExp} chars - * @returns {(text: string, index: number | false, opts?: SkipOptions) => number | false} - */ + if (length > 1) { + return stack[length - 2]; + } // Since the name is always a string, null is a safe sentinel value to + // return if we do not know the name of the (root) value. + /* istanbul ignore next */ -function skip(chars) { - return (text, index, opts) => { - const backwards = opts && opts.backwards; // Allow `skip` functions to be threaded together without having - // to check for failures (did someone say monads?). - if (index === false) { - return false; - } + return null; + } // The value of the current property is always the final element of + // this.stack. - const { - length - } = text; - let cursor = index; - while (cursor >= 0 && cursor < length) { - const c = text.charAt(cursor); + getValue() { + return getLast(this.stack); + } - if (chars instanceof RegExp) { - if (!chars.test(c)) { - return cursor; - } - } else if (!chars.includes(c)) { - return cursor; - } + getNode(count = 0) { + return getNodeHelper(this, count); + } - backwards ? cursor-- : cursor++; - } + getParentNode(count = 0) { + return getNodeHelper(this, count + 1); + } // Temporarily push properties named by string arguments given after the + // callback function onto this.stack, then call the callback with a + // reference to this (modified) FastPath object. Note that the stack will + // be restored to its original state after the callback is finished, so it + // is probably a mistake to retain a reference to the path. - if (cursor === -1 || cursor === length) { - // If we reached the beginning or end of the file, return the - // out-of-bounds cursor. It's up to the caller to handle this - // correctly. We don't want to indicate `false` though if it - // actually skipped valid characters. - return cursor; - } - return false; - }; -} -/** - * @type {(text: string, index: number | false, opts?: SkipOptions) => number | false} - */ + call(callback, ...names) { + const { + stack + } = this; + const { + length + } = stack; + let value = getLast(stack); + for (const name of names) { + value = value[name]; + stack.push(name, value); + } -const skipWhitespace = skip(/\s/); -/** - * @type {(text: string, index: number | false, opts?: SkipOptions) => number | false} - */ + const result = callback(this); + stack.length = length; + return result; + } -const skipSpaces = skip(" \t"); -/** - * @type {(text: string, index: number | false, opts?: SkipOptions) => number | false} - */ + callParent(callback, count = 0) { + const stackIndex = getNodeStackIndexHelper(this.stack, count + 1); + const parentValues = this.stack.splice(stackIndex + 1); + const result = callback(this); + this.stack.push(...parentValues); + return result; + } // Similar to FastPath.prototype.call, except that the value obtained by + // accessing this.getValue()[name1][name2]... should be array. The + // callback will be called with a reference to this path object for each + // element of the array. -const skipToLineEnd = skip(",; \t"); -/** - * @type {(text: string, index: number | false, opts?: SkipOptions) => number | false} - */ -const skipEverythingButNewLine = skip(/[^\r\n]/); -/** - * @param {string} text - * @param {number | false} index - * @returns {number | false} - */ + each(callback, ...names) { + const { + stack + } = this; + const { + length + } = stack; + let value = getLast(stack); -function skipInlineComment(text, index) { - if (index === false) { - return false; - } + for (const name of names) { + value = value[name]; + stack.push(name, value); + } - if (text.charAt(index) === "/" && text.charAt(index + 1) === "*") { - for (let i = index + 2; i < text.length; ++i) { - if (text.charAt(i) === "*" && text.charAt(i + 1) === "/") { - return i + 2; - } + for (let i = 0; i < value.length; ++i) { + stack.push(i, value[i]); + callback(this, i); + stack.length -= 2; } - } - return index; -} -/** - * @param {string} text - * @param {number | false} index - * @returns {number | false} - */ + stack.length = length; + } // Similar to FastPath.prototype.each, except that the results of the + // callback function invocations are stored in an array and returned at + // the end of the iteration. -function skipTrailingComment(text, index) { - if (index === false) { - return false; + map(callback, ...names) { + const result = []; + this.each((path, index) => { + result[index] = callback(path, index); + }, ...names); + return result; } + /** + * @param {...( + * | ((node: any, name: string | null, number: number | null) => boolean) + * | undefined + * )} predicates + */ - if (text.charAt(index) === "/" && text.charAt(index + 1) === "/") { - return skipEverythingButNewLine(text, index); - } - return index; -} // This one doesn't use the above helper function because it wants to -// test \r\n in order and `skip` doesn't support ordering and we only -// want to skip one newline. It's simple to implement. + match(...predicates) { + let stackPointer = this.stack.length - 1; + let name = null; + let node = this.stack[stackPointer--]; -/** - * @param {string} text - * @param {number | false} index - * @param {SkipOptions=} opts - * @returns {number | false} - */ + for (const predicate of predicates) { + /* istanbul ignore next */ + if (node === undefined) { + return false; + } // skip index/array + + + let number = null; + + if (typeof name === "number") { + number = name; + name = this.stack[stackPointer--]; + node = this.stack[stackPointer--]; + } + + if (predicate && !predicate(node, name, number)) { + return false; + } + + name = this.stack[stackPointer--]; + node = this.stack[stackPointer--]; + } + return true; + } -function skipNewline(text, index, opts) { - const backwards = opts && opts.backwards; +} - if (index === false) { - return false; +var fastPath = FastPath; + +const { + utils: { + stripTrailingHardline: stripTrailingHardline$1 } +} = document; +const { + normalize: normalize$2 +} = options$1; - const atIndex = text.charAt(index); +function printSubtree(path, print, options, printAstToDoc) { + if (options.printer.embed && options.embeddedLanguageFormatting === "auto") { + return options.printer.embed(path, print, (text, partialNextOptions, textToDocOptions) => textToDoc(text, partialNextOptions, options, printAstToDoc, textToDocOptions), options); + } +} - if (backwards) { - if (text.charAt(index - 1) === "\r" && atIndex === "\n") { - return index - 2; - } +function textToDoc(text, partialNextOptions, parentOptions, printAstToDoc, // TODO: remove `stripTrailingHardline` in v3.0.0 +{ + stripTrailingHardline: shouldStripTrailingHardline = false +} = {}) { + const nextOptions = normalize$2(Object.assign({}, parentOptions, partialNextOptions, { + parentParser: parentOptions.parser, + embeddedInHtml: !!(parentOptions.embeddedInHtml || parentOptions.parser === "html" || parentOptions.parser === "vue" || parentOptions.parser === "angular" || parentOptions.parser === "lwc"), + originalText: text + }), { + passThrough: true + }); + const result = parser.parse(text, nextOptions); + const { + ast + } = result; + text = result.text; + const astComments = ast.comments; + delete ast.comments; + comments.attach(astComments, ast, text, nextOptions); + nextOptions[Symbol.for("comments")] = astComments || []; + nextOptions[Symbol.for("tokens")] = ast.tokens || []; + const doc = printAstToDoc(ast, nextOptions); + comments.ensureAllCommentsPrinted(astComments); - if (atIndex === "\n" || atIndex === "\r" || atIndex === "\u2028" || atIndex === "\u2029") { - return index - 1; - } - } else { - if (atIndex === "\r" && text.charAt(index + 1) === "\n") { - return index + 2; + if (shouldStripTrailingHardline) { + // TODO: move this to `stripTrailingHardline` function in `/src/document/doc-utils.js` + if (typeof doc === "string") { + return doc.replace(/(?:\r?\n)*$/, ""); } - if (atIndex === "\n" || atIndex === "\r" || atIndex === "\u2028" || atIndex === "\u2029") { - return index + 1; - } + return stripTrailingHardline$1(doc, true); } + /* istanbul ignore next */ - return index; + + return doc; } -/** - * @param {string} text - * @param {number} index - * @param {SkipOptions=} opts - * @returns {boolean} - */ +var multiparser = { + printSubtree +}; -function hasNewline(text, index, opts) { - opts = opts || {}; - const idx = skipSpaces(text, opts.backwards ? index - 1 : index, opts); - const idx2 = skipNewline(text, idx, opts); - return idx !== idx2; -} +const doc = document; +const docBuilders$1 = doc.builders; +const { + concat: concat$4, + hardline: hardline$2, + addAlignmentToDoc: addAlignmentToDoc$1 +} = docBuilders$1; +const docUtils$1 = doc.utils; /** - * @param {string} text - * @param {number} start - * @param {number} end - * @returns {boolean} + * Takes an abstract syntax tree (AST) and recursively converts it to a + * document (series of printing primitives). + * + * This is done by descending down the AST recursively. The recursion + * involves two functions that call each other: + * + * 1. printGenerically(), which is defined as an inner function here. + * It basically takes care of node caching. + * 2. callPluginPrintFunction(), which checks for some options, and + * ultimately calls the print() function provided by the plugin. + * + * The plugin function will call printGenerically() again for child nodes + * of the current node, which will do its housekeeping, then call the + * plugin function again, and so on. + * + * All the while, these functions pass a "path" variable around, which + * is a stack-like data structure (FastPath) that maintains the current + * state of the recursion. It is called "path", because it represents + * the path to the current node through the Abstract Syntax Tree. */ +function printAstToDoc(ast, options, alignmentSize = 0) { + const { + printer + } = options; -function hasNewlineInRange(text, start, end) { - for (let i = start; i < end; ++i) { - if (text.charAt(i) === "\n") { - return true; - } + if (printer.preprocess) { + ast = printer.preprocess(ast, options); } - return false; -} // Note: this function doesn't ignore leading comments unlike isNextLineEmpty + const cache = new Map(); -/** - * @template N - * @param {string} text - * @param {N} node - * @param {(node: N) => number} locStart - */ + function printGenerically(path, args) { + const node = path.getValue(); + const shouldCache = node && typeof node === "object" && args === undefined; + if (shouldCache && cache.has(node)) { + return cache.get(node); + } // We let JSXElement print its comments itself because it adds () around + // UnionTypeAnnotation has to align the child without the comments -function isPreviousLineEmpty(text, node, locStart) { - /** @type {number | false} */ - let idx = locStart(node) - 1; - idx = skipSpaces(text, idx, { - backwards: true - }); - idx = skipNewline(text, idx, { - backwards: true - }); - idx = skipSpaces(text, idx, { - backwards: true - }); - const idx2 = skipNewline(text, idx, { - backwards: true - }); - return idx !== idx2; -} -/** - * @param {string} text - * @param {number} index - * @returns {boolean} - */ + let res; -function isNextLineEmptyAfterIndex(text, index) { - /** @type {number | false} */ - let oldIdx = null; - /** @type {number | false} */ + if (printer.willPrintOwnComments && printer.willPrintOwnComments(path, options)) { + res = callPluginPrintFunction(path, options, printGenerically, args); + } else { + // printComments will call the plugin print function and check for + // comments to print + res = comments.printComments(path, p => callPluginPrintFunction(p, options, printGenerically, args), options, args && args.needsSemi); + } - let idx = index; + if (shouldCache) { + cache.set(node, res); + } - while (idx !== oldIdx) { - // We need to skip all the potential trailing inline comments - oldIdx = idx; - idx = skipToLineEnd(text, idx); - idx = skipInlineComment(text, idx); - idx = skipSpaces(text, idx); + return res; } - idx = skipTrailingComment(text, idx); - idx = skipNewline(text, idx); - return idx !== false && hasNewline(text, idx); -} -/** - * @template N - * @param {string} text - * @param {N} node - * @param {(node: N) => number} locEnd - * @returns {boolean} - */ + let doc = printGenerically(new fastPath(ast)); + if (alignmentSize > 0) { + // Add a hardline to make the indents take effect + // It should be removed in index.js format() + doc = addAlignmentToDoc$1(concat$4([hardline$2, doc]), alignmentSize, options.tabWidth); + } -function isNextLineEmpty(text, node, locEnd) { - return isNextLineEmptyAfterIndex(text, locEnd(node)); + docUtils$1.propagateBreaks(doc); + return doc; } -/** - * @param {string} text - * @param {number} idx - * @returns {number | false} - */ - - -function getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, idx) { - /** @type {number | false} */ - let oldIdx = null; - /** @type {number | false} */ - let nextIdx = idx; +function printPrettierIgnoredNode(node, options) { + const { + originalText, + [Symbol.for("comments")]: comments, + locStart, + locEnd + } = options; + const start = locStart(node); + const end = locEnd(node); - while (nextIdx !== oldIdx) { - oldIdx = nextIdx; - nextIdx = skipSpaces(text, nextIdx); - nextIdx = skipInlineComment(text, nextIdx); - nextIdx = skipTrailingComment(text, nextIdx); - nextIdx = skipNewline(text, nextIdx); + for (const comment of comments) { + if (locStart(comment) >= start && locEnd(comment) <= end) { + comment.printed = true; + } } - return nextIdx; + return originalText.slice(start, end); } -/** - * @template N - * @param {string} text - * @param {N} node - * @param {(node: N) => number} locEnd - * @returns {number | false} - */ +function callPluginPrintFunction(path, options, printPath, args) { + assert__default['default'].ok(path instanceof fastPath); + const node = path.getValue(); + const { + printer + } = options; // Escape hatch -function getNextNonSpaceNonCommentCharacterIndex(text, node, locEnd) { - return getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, locEnd(node)); -} -/** - * @template N - * @param {string} text - * @param {N} node - * @param {(node: N) => number} locEnd - * @returns {string} - */ + if (printer.hasPrettierIgnore && printer.hasPrettierIgnore(path)) { + return printPrettierIgnoredNode(node, options); + } + if (node) { + try { + // Potentially switch to a different parser + const sub = multiparser.printSubtree(path, printPath, options, printAstToDoc); -function getNextNonSpaceNonCommentCharacter(text, node, locEnd) { - return text.charAt( // @ts-ignore => TBD: can return false, should we define a fallback? - getNextNonSpaceNonCommentCharacterIndex(text, node, locEnd)); -} -/** - * @param {string} text - * @param {number} index - * @param {SkipOptions=} opts - * @returns {boolean} - */ + if (sub) { + return sub; + } + } catch (error) { + /* istanbul ignore if */ + if (process.env.PRETTIER_DEBUG) { + throw error; + } // Continue with current parser + } + } -function hasSpaces(text, index, opts) { - opts = opts || {}; - const idx = skipSpaces(text, opts.backwards ? index - 1 : index, opts); - return idx !== index; + return printer.print(path, options, printPath, args); } -/** - * @param {{range?: [number, number], start?: number}} node - * @param {number} index - */ +var astToDoc = printAstToDoc; + +function findSiblingAncestors(startNodeAndParents, endNodeAndParents, opts) { + let resultStartNode = startNodeAndParents.node; + let resultEndNode = endNodeAndParents.node; -function setLocStart(node, index) { - if (node.range) { - node.range[0] = index; - } else { - node.start = index; + if (resultStartNode === resultEndNode) { + return { + startNode: resultStartNode, + endNode: resultEndNode + }; } -} -/** - * @param {{range?: [number, number], end?: number}} node - * @param {number} index - */ - -function setLocEnd(node, index) { - if (node.range) { - node.range[1] = index; - } else { - node.end = index; + for (const endParent of endNodeAndParents.parentNodes) { + if (endParent.type !== "Program" && endParent.type !== "File" && opts.locStart(endParent) >= opts.locStart(startNodeAndParents.node)) { + resultEndNode = endParent; + } else { + break; + } } -} -const PRECEDENCE = {}; -[["|>"], ["??"], ["||"], ["&&"], ["|"], ["^"], ["&"], ["==", "===", "!=", "!=="], ["<", ">", "<=", ">=", "in", "instanceof"], [">>", "<<", ">>>"], ["+", "-"], ["*", "/", "%"], ["**"]].forEach((tier, i) => { - tier.forEach(op => { - PRECEDENCE[op] = i; - }); -}); + for (const startParent of startNodeAndParents.parentNodes) { + if (startParent.type !== "Program" && startParent.type !== "File" && opts.locEnd(startParent) <= opts.locEnd(endNodeAndParents.node)) { + resultStartNode = startParent; + } else { + break; + } + } -function getPrecedence(op) { - return PRECEDENCE[op]; + return { + startNode: resultStartNode, + endNode: resultEndNode + }; } -const equalityOperators = { - "==": true, - "!=": true, - "===": true, - "!==": true -}; -const multiplicativeOperators = { - "*": true, - "/": true, - "%": true -}; -const bitshiftOperators = { - ">>": true, - ">>>": true, - "<<": true -}; +function findNodeAtOffset(node, offset, options, predicate, parentNodes = []) { + if (offset < options.locStart(node) || offset > options.locEnd(node)) { + return; + } -function shouldFlatten(parentOp, nodeOp) { - if (getPrecedence(nodeOp) !== getPrecedence(parentOp)) { - return false; - } // ** is right-associative - // x ** y ** z --> x ** (y ** z) + for (const childNode of comments.getSortedChildNodes(node, options)) { + const childResult = findNodeAtOffset(childNode, offset, options, predicate, [node, ...parentNodes]); + if (childResult) { + return childResult; + } + } - if (parentOp === "**") { - return false; - } // x == y == z --> (x == y) == z + if (!predicate || predicate(node)) { + return { + node, + parentNodes + }; + } +} // See https://www.ecma-international.org/ecma-262/5.1/#sec-A.5 - if (equalityOperators[parentOp] && equalityOperators[nodeOp]) { - return false; - } // x * y % z --> (x * y) % z +function isJsSourceElement(type) { + return type === "Directive" || type === "TypeAlias" || type === "TSExportAssignment" || type.startsWith("Declare") || type.startsWith("TSDeclare") || type.endsWith("Statement") || type.endsWith("Declaration"); +} +const jsonSourceElements = new Set(["ObjectExpression", "ArrayExpression", "StringLiteral", "NumericLiteral", "BooleanLiteral", "NullLiteral"]); +const graphqlSourceElements = new Set(["OperationDefinition", "FragmentDefinition", "VariableDefinition", "TypeExtensionDefinition", "ObjectTypeDefinition", "FieldDefinition", "DirectiveDefinition", "EnumTypeDefinition", "EnumValueDefinition", "InputValueDefinition", "InputObjectTypeDefinition", "SchemaDefinition", "OperationTypeDefinition", "InterfaceTypeDefinition", "UnionTypeDefinition", "ScalarTypeDefinition"]); - if (nodeOp === "%" && multiplicativeOperators[parentOp] || parentOp === "%" && multiplicativeOperators[nodeOp]) { +function isSourceElement(opts, node) { + /* istanbul ignore next */ + if (node == null) { return false; - } // x * y / z --> (x * y) / z - // x / y * z --> (x / y) * z + } + switch (opts.parser) { + case "flow": + case "babel": + case "babel-flow": + case "babel-ts": + case "typescript": + case "espree": + case "meriyah": + return isJsSourceElement(node.type); - if (nodeOp !== parentOp && multiplicativeOperators[nodeOp] && multiplicativeOperators[parentOp]) { - return false; - } // x << y << z --> (x << y) << z + case "json": + return jsonSourceElements.has(node.type); + case "graphql": + return graphqlSourceElements.has(node.kind); - if (bitshiftOperators[parentOp] && bitshiftOperators[nodeOp]) { - return false; + case "vue": + return node.tag !== "root"; } - return true; + return false; } -function isBitwiseOperator(operator) { - return !!bitshiftOperators[operator] || operator === "|" || operator === "^" || operator === "&"; -} // Tests if an expression starts with `{`, or (if forbidFunctionClassAndDoExpr -// holds) `function`, `class`, or `do {}`. Will be overzealous if there's -// already necessary grouping parentheses. - - -function startsWithNoLookaheadToken(node, forbidFunctionClassAndDoExpr) { - node = getLeftMost(node); - - switch (node.type) { - case "FunctionExpression": - case "ClassExpression": - case "DoExpression": - return forbidFunctionClassAndDoExpr; - - case "ObjectExpression": - return true; - - case "MemberExpression": - case "OptionalMemberExpression": - return startsWithNoLookaheadToken(node.object, forbidFunctionClassAndDoExpr); - - case "TaggedTemplateExpression": - if (node.tag.type === "FunctionExpression") { - // IIFEs are always already parenthesized - return false; - } - - return startsWithNoLookaheadToken(node.tag, forbidFunctionClassAndDoExpr); +function calculateRange(text, opts, ast) { + // Contract the range so that it has non-whitespace characters at its endpoints. + // This ensures we can format a range that doesn't end on a node. + const rangeStringOrig = text.slice(opts.rangeStart, opts.rangeEnd); + const startNonWhitespace = Math.max(opts.rangeStart + rangeStringOrig.search(/\S/), opts.rangeStart); + let endNonWhitespace; - case "CallExpression": - case "OptionalCallExpression": - if (node.callee.type === "FunctionExpression") { - // IIFEs are always already parenthesized - return false; - } + for (endNonWhitespace = opts.rangeEnd; endNonWhitespace > opts.rangeStart; --endNonWhitespace) { + if (/\S/.test(text[endNonWhitespace - 1])) { + break; + } + } - return startsWithNoLookaheadToken(node.callee, forbidFunctionClassAndDoExpr); + const startNodeAndParents = findNodeAtOffset(ast, startNonWhitespace, opts, node => isSourceElement(opts, node)); + const endNodeAndParents = findNodeAtOffset(ast, endNonWhitespace, opts, node => isSourceElement(opts, node)); - case "ConditionalExpression": - return startsWithNoLookaheadToken(node.test, forbidFunctionClassAndDoExpr); + if (!startNodeAndParents || !endNodeAndParents) { + return { + rangeStart: 0, + rangeEnd: 0 + }; + } - case "UpdateExpression": - return !node.prefix && startsWithNoLookaheadToken(node.argument, forbidFunctionClassAndDoExpr); + const { + startNode, + endNode + } = findSiblingAncestors(startNodeAndParents, endNodeAndParents, opts); + return { + rangeStart: Math.min(opts.locStart(startNode), opts.locStart(endNode)), + rangeEnd: Math.max(opts.locEnd(startNode), opts.locEnd(endNode)) + }; +} - case "BindExpression": - return node.object && startsWithNoLookaheadToken(node.object, forbidFunctionClassAndDoExpr); +var rangeUtil = { + calculateRange, + findNodeAtOffset +}; - case "SequenceExpression": - return startsWithNoLookaheadToken(node.expressions[0], forbidFunctionClassAndDoExpr); +const { + printer: { + printDocToString: printDocToString$1 + }, + debug: { + printDocToDebug + } +} = document; +const { + getAlignmentSize: getAlignmentSize$1 +} = util; +const { + guessEndOfLine: guessEndOfLine$1, + convertEndOfLineToChars: convertEndOfLineToChars$2, + countEndOfLineChars: countEndOfLineChars$1, + normalizeEndOfLine: normalizeEndOfLine$1 +} = endOfLine; +const normalizeOptions$1 = options$1.normalize; +const BOM = "\uFEFF"; +const CURSOR = Symbol("cursor"); - case "TSAsExpression": - return startsWithNoLookaheadToken(node.expression, forbidFunctionClassAndDoExpr); +function attachComments(text, ast, opts) { + const astComments = ast.comments; - default: - return false; + if (astComments) { + delete ast.comments; + comments.attach(astComments, ast, text, opts); } + + opts[Symbol.for("comments")] = astComments || []; + opts[Symbol.for("tokens")] = ast.tokens || []; + opts.originalText = text; + return astComments; } -function getLeftMost(node) { - if (node.left) { - return getLeftMost(node.left); +function coreFormat(originalText, opts, addAlignmentSize) { + if (!originalText || !originalText.trim().length) { + return { + formatted: "", + cursorOffset: -1 + }; } - return node; -} -/** - * @param {string} value - * @param {number} tabWidth - * @param {number=} startIndex - * @returns {number} - */ - + addAlignmentSize = addAlignmentSize || 0; + const { + ast, + text + } = parser.parse(originalText, opts); -function getAlignmentSize(value, tabWidth, startIndex) { - startIndex = startIndex || 0; - let size = 0; + if (opts.cursorOffset >= 0) { + const nodeResult = rangeUtil.findNodeAtOffset(ast, opts.cursorOffset, opts); - for (let i = startIndex; i < value.length; ++i) { - if (value[i] === "\t") { - // Tabs behave in a way that they are aligned to the nearest - // multiple of tabWidth: - // 0 -> 4, 1 -> 4, 2 -> 4, 3 -> 4 - // 4 -> 8, 5 -> 8, 6 -> 8, 7 -> 8 ... - size = size + tabWidth - size % tabWidth; - } else { - size++; + if (nodeResult && nodeResult.node) { + opts.cursorNode = nodeResult.node; } } - return size; -} -/** - * @param {string} value - * @param {number} tabWidth - * @returns {number} - */ + const astComments = attachComments(text, ast, opts); + const doc = astToDoc(ast, opts, addAlignmentSize); + const result = printDocToString$1(doc, opts); + comments.ensureAllCommentsPrinted(astComments); // Remove extra leading indentation as well as the added indentation after last newline + if (addAlignmentSize > 0) { + const trimmed = result.formatted.trim(); -function getIndentSize(value, tabWidth) { - const lastNewlineIndex = value.lastIndexOf("\n"); + if (result.cursorNodeStart !== undefined) { + result.cursorNodeStart -= result.formatted.indexOf(trimmed); + } - if (lastNewlineIndex === -1) { - return 0; + result.formatted = trimmed + convertEndOfLineToChars$2(opts.endOfLine); } - return getAlignmentSize( // All the leading whitespaces - value.slice(lastNewlineIndex + 1).match(/^[ \t]*/)[0], tabWidth); -} -/** - * @typedef {'"' | "'"} Quote - */ + if (opts.cursorOffset >= 0) { + let oldCursorNodeStart; + let oldCursorNodeText; + let cursorOffsetRelativeToOldCursorNode; + let newCursorNodeStart; + let newCursorNodeText; -/** - * - * @param {string} raw - * @param {Quote} preferredQuote - * @returns {Quote} - */ + if (opts.cursorNode && result.cursorNodeText) { + oldCursorNodeStart = opts.locStart(opts.cursorNode); + oldCursorNodeText = text.slice(oldCursorNodeStart, opts.locEnd(opts.cursorNode)); + cursorOffsetRelativeToOldCursorNode = opts.cursorOffset - oldCursorNodeStart; + newCursorNodeStart = result.cursorNodeStart; + newCursorNodeText = result.cursorNodeText; + } else { + oldCursorNodeStart = 0; + oldCursorNodeText = text; + cursorOffsetRelativeToOldCursorNode = opts.cursorOffset; + newCursorNodeStart = 0; + newCursorNodeText = result.formatted; + } + if (oldCursorNodeText === newCursorNodeText) { + return { + formatted: result.formatted, + cursorOffset: newCursorNodeStart + cursorOffsetRelativeToOldCursorNode + }; + } // diff old and new cursor node texts, with a special cursor + // symbol inserted to find out where it moves to -function getPreferredQuote(raw, preferredQuote) { - // `rawContent` is the string exactly like it appeared in the input source - // code, without its enclosing quotes. - const rawContent = raw.slice(1, -1); - /** @type {{ quote: '"', regex: RegExp }} */ - const double = { - quote: '"', - regex: /"/g - }; - /** @type {{ quote: "'", regex: RegExp }} */ + const oldCursorNodeCharArray = oldCursorNodeText.split(""); + oldCursorNodeCharArray.splice(cursorOffsetRelativeToOldCursorNode, 0, CURSOR); + const newCursorNodeCharArray = newCursorNodeText.split(""); + const cursorNodeDiff = index_es6.diffArrays(oldCursorNodeCharArray, newCursorNodeCharArray); + let cursorOffset = newCursorNodeStart; - const single = { - quote: "'", - regex: /'/g - }; - const preferred = preferredQuote === "'" ? single : double; - const alternate = preferred === single ? double : single; - let result = preferred.quote; // If `rawContent` contains at least one of the quote preferred for enclosing - // the string, we might want to enclose with the alternate quote instead, to - // minimize the number of escaped quotes. + for (const entry of cursorNodeDiff) { + if (entry.removed) { + if (entry.value.includes(CURSOR)) { + break; + } + } else { + cursorOffset += entry.count; + } + } - if (rawContent.includes(preferred.quote) || rawContent.includes(alternate.quote)) { - const numPreferredQuotes = (rawContent.match(preferred.regex) || []).length; - const numAlternateQuotes = (rawContent.match(alternate.regex) || []).length; - result = numPreferredQuotes > numAlternateQuotes ? alternate.quote : preferred.quote; + return { + formatted: result.formatted, + cursorOffset + }; } - return result; + return { + formatted: result.formatted, + cursorOffset: -1 + }; } -function printString(raw, options, isDirectiveLiteral) { - // `rawContent` is the string exactly like it appeared in the input source - // code, without its enclosing quotes. - const rawContent = raw.slice(1, -1); // Check for the alternate quote, to determine if we're allowed to swap - // the quotes on a DirectiveLiteral. - - const canChangeDirectiveQuotes = !rawContent.includes('"') && !rawContent.includes("'"); - /** @type {Quote} */ - - const enclosingQuote = options.parser === "json" ? '"' : options.__isInHtmlAttribute ? "'" : getPreferredQuote(raw, options.singleQuote ? "'" : '"'); // Directives are exact code unit sequences, which means that you can't - // change the escape sequences they use. - // See https://github.com/prettier/prettier/issues/1555 - // and https://tc39.github.io/ecma262/#directive-prologue - - if (isDirectiveLiteral) { - if (canChangeDirectiveQuotes) { - return enclosingQuote + rawContent + enclosingQuote; - } +function formatRange(originalText, opts) { + const { + ast, + text + } = parser.parse(originalText, opts); + const { + rangeStart, + rangeEnd + } = rangeUtil.calculateRange(text, opts, ast); + const rangeString = text.slice(rangeStart, rangeEnd); // Try to extend the range backwards to the beginning of the line. + // This is so we can detect indentation correctly and restore it. + // Use `Math.min` since `lastIndexOf` returns 0 when `rangeStart` is 0 - return raw; - } // It might sound unnecessary to use `makeString` even if the string already - // is enclosed with `enclosingQuote`, but it isn't. The string could contain - // unnecessary escapes (such as in `"\'"`). Always using `makeString` makes - // sure that we consistently output the minimum amount of escaped quotes. + const rangeStart2 = Math.min(rangeStart, text.lastIndexOf("\n", rangeStart) + 1); + const indentString = text.slice(rangeStart2, rangeStart).match(/^\s*/)[0]; + const alignmentSize = getAlignmentSize$1(indentString, opts.tabWidth); + const rangeResult = coreFormat(rangeString, Object.assign({}, opts, { + rangeStart: 0, + rangeEnd: Infinity, + // Track the cursor offset only if it's within our range + cursorOffset: opts.cursorOffset > rangeStart && opts.cursorOffset < rangeEnd ? opts.cursorOffset - rangeStart : -1, + // Always use `lf` to format, we'll replace it later + endOfLine: "lf" + }), alignmentSize); // Since the range contracts to avoid trailing whitespace, + // we need to remove the newline that was inserted by the `format` call. + const rangeTrimmed = rangeResult.formatted.trimEnd(); + let { + cursorOffset + } = opts; - return makeString(rawContent, enclosingQuote, !(options.parser === "css" || options.parser === "less" || options.parser === "scss" || options.embeddedInHtml)); -} -/** - * @param {string} rawContent - * @param {Quote} enclosingQuote - * @param {boolean=} unescapeUnnecessaryEscapes - * @returns {string} - */ + if (cursorOffset >= rangeEnd) { + // handle the case where the cursor was past the end of the range + cursorOffset = opts.cursorOffset + (rangeTrimmed.length - rangeString.length); + } else if (rangeResult.cursorOffset >= 0) { + // handle the case where the cursor was in the range + cursorOffset = rangeResult.cursorOffset + rangeStart; + } // keep the cursor as it was if it was before the start of the range -function makeString(rawContent, enclosingQuote, unescapeUnnecessaryEscapes) { - const otherQuote = enclosingQuote === '"' ? "'" : '"'; // Matches _any_ escape and unescaped quotes (both single and double). + let formatted = text.slice(0, rangeStart) + rangeTrimmed + text.slice(rangeEnd); - const regex = /\\([\s\S])|(['"])/g; // Escape and unescape single and double quotes as needed to be able to - // enclose `rawContent` with `enclosingQuote`. + if (opts.endOfLine !== "lf") { + const eol = convertEndOfLineToChars$2(opts.endOfLine); - const newContent = rawContent.replace(regex, (match, escaped, quote) => { - // If we matched an escape, and the escaped character is a quote of the - // other type than we intend to enclose the string with, there's no need for - // it to be escaped, so return it _without_ the backslash. - if (escaped === otherQuote) { - return escaped; - } // If we matched an unescaped quote and it is of the _same_ type as we - // intend to enclose the string with, it must be escaped, so return it with - // a backslash. + if (cursorOffset >= 0 && eol === "\r\n") { + cursorOffset += countEndOfLineChars$1(formatted.slice(0, cursorOffset), "\n"); + } + formatted = formatted.replace(/\n/g, eol); + } - if (quote === enclosingQuote) { - return "\\" + quote; - } + return { + formatted, + cursorOffset + }; +} - if (quote) { - return quote; - } // Unescape any unnecessarily escaped character. - // Adapted from https://github.com/eslint/eslint/blob/de0b4ad7bd820ade41b1f606008bea68683dc11a/lib/rules/no-useless-escape.js#L27 +function ensureIndexInText(text, index, defaultValue) { + if (typeof index !== "number" || isNaN(index) || index < 0 || index > text.length) { + return defaultValue; + } + return index; +} - return unescapeUnnecessaryEscapes && /^[^\\nrvtbfux\r\n\u2028\u2029"'0-7]$/.test(escaped) ? escaped : "\\" + escaped; +function normalizeIndexes(text, options) { + let { + cursorOffset, + rangeStart, + rangeEnd + } = options; + cursorOffset = ensureIndexInText(text, cursorOffset, -1); + rangeStart = ensureIndexInText(text, rangeStart, 0); + rangeEnd = ensureIndexInText(text, rangeEnd, text.length); + return Object.assign({}, options, { + cursorOffset, + rangeStart, + rangeEnd }); - return enclosingQuote + newContent + enclosingQuote; } -function printNumber(rawNumber) { - return rawNumber.toLowerCase() // Remove unnecessary plus and zeroes from scientific notation. - .replace(/^([+-]?[\d.]+e)(?:\+|(-))?0*(\d)/, "$1$2$3") // Remove unnecessary scientific notation (1e0). - .replace(/^([+-]?[\d.]+)e[+-]?0+$/, "$1") // Make sure numbers always start with a digit. - .replace(/^([+-])?\./, "$10.") // Remove extraneous trailing decimal zeroes. - .replace(/(\.\d+?)0+(?=e|$)/, "$1") // Remove trailing dot. - .replace(/\.(?=e|$)/, ""); -} -/** - * @param {string} str - * @param {string} target - * @returns {number} - */ +function normalizeInputAndOptions(text, options) { + let { + cursorOffset, + rangeStart, + rangeEnd, + endOfLine + } = normalizeIndexes(text, options); + const hasBOM = text.charAt(0) === BOM; + if (hasBOM) { + text = text.slice(1); + cursorOffset--; + rangeStart--; + rangeEnd--; + } -function getMaxContinuousCount(str, target) { - const results = str.match(new RegExp(`(${escapeStringRegexp$2(target)})+`, "g")); + if (endOfLine === "auto") { + endOfLine = guessEndOfLine$1(text); + } // get rid of CR/CRLF parsing - if (results === null) { - return 0; + + if (text.includes("\r")) { + const countCrlfBefore = index => countEndOfLineChars$1(text.slice(0, Math.max(index, 0)), "\r\n"); + + cursorOffset -= countCrlfBefore(cursorOffset); + rangeStart -= countCrlfBefore(rangeStart); + rangeEnd -= countCrlfBefore(rangeEnd); + text = normalizeEndOfLine$1(text); } - return results.reduce((maxCount, result) => Math.max(maxCount, result.length / target.length), 0); + return { + hasBOM, + text, + options: normalizeIndexes(text, Object.assign({}, options, { + cursorOffset, + rangeStart, + rangeEnd, + endOfLine + })) + }; } -function getMinNotPresentContinuousCount(str, target) { - const matches = str.match(new RegExp(`(${escapeStringRegexp$2(target)})+`, "g")); +function format(originalText, originalOptions) { + let { + hasBOM, + text, + options + } = normalizeInputAndOptions(originalText, normalizeOptions$1(originalOptions)); + const selectedParser = parser.resolveParser(options); + const hasPragma = !selectedParser.hasPragma || selectedParser.hasPragma(text); - if (matches === null) { - return 0; + if (options.requirePragma && !hasPragma) { + return { + formatted: originalText, + cursorOffset: originalOptions.cursorOffset + }; } - const countPresent = new Map(); - let max = 0; - - for (const match of matches) { - const count = match.length / target.length; - countPresent.set(count, true); + let result; - if (count > max) { - max = count; + if (options.rangeStart > 0 || options.rangeEnd < text.length) { + result = formatRange(text, options); + } else { + if (!hasPragma && options.insertPragma && options.printer.insertPragma) { + text = options.printer.insertPragma(text); } + + result = coreFormat(text, options); } - for (let i = 1; i < max; i++) { - if (!countPresent.get(i)) { - return i; + if (hasBOM) { + result.formatted = BOM + result.formatted; + + if (result.cursorOffset >= 0) { + result.cursorOffset++; } } - return max + 1; + return result; } -/** - * @param {string} text - * @returns {number} - */ +var core = { + formatWithCursor: format, -function getStringWidth(text) { - if (!text) { - return 0; - } // shortcut to avoid needless string `RegExp`s, replacements, and allocations within `string-width` + parse(originalText, originalOptions, massage) { + const { + text, + options + } = normalizeInputAndOptions(originalText, normalizeOptions$1(originalOptions)); + const parsed = parser.parse(text, options); + if (massage) { + parsed.ast = massageAst(parsed.ast, options); + } - if (!notAsciiRegex.test(text)) { - return text.length; - } + return parsed; + }, - return stringWidth_1(text); -} + formatAST(ast, options) { + options = normalizeOptions$1(options); + const doc = astToDoc(ast, options); + return printDocToString$1(doc, options); + }, -function hasIgnoreComment(path) { - const node = path.getValue(); - return hasNodeIgnoreComment(node); -} + // Doesn't handle shebang for now + formatDoc(doc, options) { + return format(printDocToDebug(doc), Object.assign({}, options, { + parser: "babel" + })).formatted; + }, -function hasNodeIgnoreComment(node) { - return node && (node.comments && node.comments.length > 0 && node.comments.some(comment => isNodeIgnoreComment(comment) && !comment.unignore) || node.prettierIgnore); -} + printToDoc(originalText, options) { + options = normalizeOptions$1(options); + const { + ast, + text + } = parser.parse(originalText, options); + attachComments(text, ast, options); + return astToDoc(ast, options); + }, -function isNodeIgnoreComment(comment) { - return comment.value.trim() === "prettier-ignore"; -} + printDocToString(doc, options) { + return printDocToString$1(doc, normalizeOptions$1(options)); + } -function addCommentHelper(node, comment) { - const comments = node.comments || (node.comments = []); - comments.push(comment); - comment.printed = false; // For some reason, TypeScript parses `// x` inside of JSXText as a comment - // We already "print" it via the raw text, we don't need to re-print it as a - // comment +}; - if (node.type === "JSXText") { - comment.printed = true; +var concatMap = function (xs, fn) { + var res = []; + + for (var i = 0; i < xs.length; i++) { + var x = fn(xs[i], i); + if (isArray$2(x)) res.push.apply(res, x);else res.push(x); } -} -function addLeadingComment(node, comment) { - comment.leading = true; - comment.trailing = false; - addCommentHelper(node, comment); -} + return res; +}; -function addDanglingComment(node, comment) { - comment.leading = false; - comment.trailing = false; - addCommentHelper(node, comment); +var isArray$2 = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +var balancedMatch = balanced; + +function balanced(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 addTrailingComment(node, comment) { - comment.leading = false; - comment.trailing = true; - addCommentHelper(node, comment); +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; } -function isWithinParentArrayProperty(path, propertyName) { - const node = path.getValue(); - const parent = path.getParentNode(); +balanced.range = range; - if (parent == null) { - return false; - } +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 (!Array.isArray(parent[propertyName])) { - return false; - } + if (ai >= 0 && bi > 0) { + begs = []; + left = str.length; - const key = path.getName(); - return parent[propertyName][key] === node; -} + 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(); -function replaceEndOfLineWith(text, replacement) { - const parts = []; + if (beg < left) { + left = beg; + right = bi; + } - for (const part of text.split("\n")) { - if (parts.length !== 0) { - parts.push(replacement); + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; } - parts.push(part); + if (begs.length) { + result = [left, right]; + } } - return parts; + return result; } -var util$1 = { - replaceEndOfLineWith, - getStringWidth, - getMaxContinuousCount, - getMinNotPresentContinuousCount, - getPrecedence, - shouldFlatten, - isBitwiseOperator, - getPenultimate, - getLast, - getNextNonSpaceNonCommentCharacterIndexWithStartIndex, - getNextNonSpaceNonCommentCharacterIndex, - getNextNonSpaceNonCommentCharacter, - skip, - skipWhitespace, - skipSpaces, - skipToLineEnd, - skipEverythingButNewLine, - skipInlineComment, - skipTrailingComment, - skipNewline, - isNextLineEmptyAfterIndex, - isNextLineEmpty, - isPreviousLineEmpty, - hasNewline, - hasNewlineInRange, - hasSpaces, - setLocStart, - setLocEnd, - startsWithNoLookaheadToken, - getAlignmentSize, - getIndentSize, - getPreferredQuote, - printString, - printNumber, - hasIgnoreComment, - hasNodeIgnoreComment, - isNodeIgnoreComment, - makeString, - addLeadingComment, - addDanglingComment, - addTrailingComment, - isWithinParentArrayProperty -}; - -function guessEndOfLine(text) { - const index = text.indexOf("\r"); - - if (index >= 0) { - return text.charAt(index + 1) === "\n" ? "crlf" : "cr"; - } +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'; - return "lf"; +function numeric$1(str) { + return parseInt(str, 10) == str ? parseInt(str, 10) : str.charCodeAt(0); } -function convertEndOfLineToChars(value) { - switch (value) { - case "cr": - return "\r"; - - case "crlf": - return "\r\n"; - - default: - return "\n"; - } +function escapeBraces(str) { + return str.split('\\\\').join(escSlash).split('\\{').join(escOpen).split('\\}').join(escClose).split('\\,').join(escComma).split('\\.').join(escPeriod); } -var endOfLine = { - guessEndOfLine, - convertEndOfLineToChars -}; - -const { - getStringWidth: getStringWidth$1 -} = util$1; -const { - convertEndOfLineToChars: convertEndOfLineToChars$1 -} = endOfLine; -const { - concat: concat$1, - fill: fill$1, - cursor: cursor$1 -} = docBuilders; -/** @type {Record} */ +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} -let groupModeMap; -const MODE_BREAK = 1; -const MODE_FLAT = 2; -function rootIndent() { - return { - value: "", - length: 0, - queue: [] - }; -} +function parseCommaParts(str) { + if (!str) return ['']; + var parts = []; + var m = balancedMatch('{', '}', 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); -function makeIndent(ind, options) { - return generateInd(ind, { - type: "indent" - }, options); -} + if (post.length) { + p[p.length - 1] += postParts.shift(); + p.push.apply(p, postParts); + } -function makeAlign(ind, n, options) { - return n === -Infinity ? ind.root || rootIndent() : n < 0 ? generateInd(ind, { - type: "dedent" - }, options) : !n ? ind : n.type === "root" ? Object.assign({}, ind, { - root: ind - }) : typeof n === "string" ? generateInd(ind, { - type: "stringAlign", - n - }, options) : generateInd(ind, { - type: "numberAlign", - n - }, options); + parts.push.apply(parts, p); + return parts; } -function generateInd(ind, newPart, options) { - const queue = newPart.type === "dedent" ? ind.queue.slice(0, -1) : ind.queue.concat(newPart); - let value = ""; - let length = 0; - let lastTabs = 0; - let lastSpaces = 0; - - for (const part of queue) { - switch (part.type) { - case "indent": - flush(); - - if (options.useTabs) { - addTabs(1); - } else { - addSpaces(options.tabWidth); - } - - break; +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 {} - case "stringAlign": - flush(); - value += part.n; - length += part.n.length; - break; + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } - case "numberAlign": - lastTabs += 1; - lastSpaces += part.n; - break; + return expand(escapeBraces(str), true).map(unescapeBraces); +} - /* istanbul ignore next */ +function embrace(str) { + return '{' + str + '}'; +} - default: - throw new Error(`Unexpected type '${part.type}'`); - } - } +function isPadded(el) { + return /^-?0\d/.test(el); +} - flushSpaces(); - return Object.assign({}, ind, { - value, - length, - queue - }); +function lte(i, y) { + return i <= y; +} - function addTabs(count) { - value += "\t".repeat(count); - length += options.tabWidth * count; - } +function gte$1(i, y) { + return i >= y; +} - function addSpaces(count) { - value += " ".repeat(count); - length += count; - } +function expand(str, isTop) { + var expansions = []; + var m = balancedMatch('{', '}', 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; - function flush() { - if (options.useTabs) { - flushTabs(); - } else { - flushSpaces(); + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); } + + return [str]; } - function flushTabs() { - if (lastTabs > 0) { - addTabs(lastTabs); - } + var n; - resetLast(); - } + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); - function flushSpaces() { - if (lastSpaces > 0) { - addSpaces(lastSpaces); - } + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); - resetLast(); - } + if (n.length === 1) { + var post = m.post.length ? expand(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 - function resetLast() { - lastTabs = 0; - lastSpaces = 0; - } -} -function trim$1(out) { - if (out.length === 0) { - return 0; - } + var pre = m.pre; + var post = m.post.length ? expand(m.post, false) : ['']; + var N; - let trimCount = 0; // Trim whitespace at the end of line + if (isSequence) { + var x = numeric$1(n[0]); + var y = numeric$1(n[1]); + var width = Math.max(n[0].length, n[1].length); + var incr = n.length == 3 ? Math.abs(numeric$1(n[2])) : 1; + var test = lte; + var reverse = y < x; - while (out.length > 0 && typeof out[out.length - 1] === "string" && out[out.length - 1].match(/^[ \t]*$/)) { - trimCount += out.pop().length; - } + if (reverse) { + incr *= -1; + test = gte$1; + } - if (out.length && typeof out[out.length - 1] === "string") { - const trimmed = out[out.length - 1].replace(/[ \t]*$/, ""); - trimCount += out[out.length - 1].length - trimmed.length; - out[out.length - 1] = trimmed; - } + var pad = n.some(isPadded); + N = []; - return trimCount; -} + for (var i = x; test(i, y); i += incr) { + var c; -function fits(next, restCommands, width, options, mustBeFlat) { - let restIdx = restCommands.length; - const cmds = [next]; // `out` is only used for width counting because `trim` requires to look - // backwards for space characters. + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') c = ''; + } else { + c = String(i); - const out = []; + if (pad) { + var need = width - c.length; - while (width >= 0) { - if (cmds.length === 0) { - if (restIdx === 0) { - return true; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) c = '-' + z + c.slice(1);else c = z + c; + } + } } - cmds.push(restCommands[restIdx - 1]); - restIdx--; - continue; + N.push(c); } + } else { + N = concatMap(n, function (el) { + return expand(el, false); + }); + } - const [ind, mode, doc] = cmds.pop(); + 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); + } + } - if (typeof doc === "string") { - out.push(doc); - width -= getStringWidth$1(doc); - } else { - switch (doc.type) { - case "concat": - for (let i = doc.parts.length - 1; i >= 0; i--) { - cmds.push([ind, mode, doc.parts[i]]); - } + return expansions; +} - break; +var minimatch_1 = minimatch; +minimatch.Minimatch = Minimatch; +var path = { + sep: '/' +}; - case "indent": - cmds.push([makeIndent(ind, options), mode, doc.contents]); - break; +try { + path = path__default['default']; +} catch (er) {} - case "align": - cmds.push([makeAlign(ind, doc.n, options), mode, doc.contents]); - break; +var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}; +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() - case "trim": - width += trim$1(out); - break; +var qmark = '[^/]'; // * => any number of characters - case "group": - if (mustBeFlat && doc.break) { - return false; - } +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. - cmds.push([ind, doc.break ? MODE_BREAK : mode, doc.contents]); +var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'; // not a ^ or / followed by a dot, +// followed by anything, any number of times. - if (doc.id) { - groupModeMap[doc.id] = cmds[cmds.length - 1][1]; - } +var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'; // characters that need to be escaped in RegExp. - break; +var reSpecials = charSet('().*{}+?[]^$\\!'); // "abc" -> { a:true, b:true, c:true } - case "fill": - for (let i = doc.parts.length - 1; i >= 0; i--) { - cmds.push([ind, mode, doc.parts[i]]); - } +function charSet(s) { + return s.split('').reduce(function (set, c) { + set[c] = true; + return set; + }, {}); +} // normalizes slashes. - break; - case "if-break": - { - const groupMode = doc.groupId ? groupModeMap[doc.groupId] : mode; +var slashSplit = /\/+/; +minimatch.filter = filter; - if (groupMode === MODE_BREAK) { - if (doc.breakContents) { - cmds.push([ind, mode, doc.breakContents]); - } - } +function filter(pattern, options) { + options = options || {}; + return function (p, i, list) { + return minimatch(p, pattern, options); + }; +} - if (groupMode === MODE_FLAT) { - if (doc.flatContents) { - cmds.push([ind, mode, doc.flatContents]); - } - } +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; +} - break; - } +minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return minimatch; + var orig = minimatch; - case "line": - switch (mode) { - // fallthrough - case MODE_FLAT: - if (!doc.hard) { - if (!doc.soft) { - out.push(" "); - width -= 1; - } + var m = function minimatch(p, pattern, options) { + return orig.minimatch(p, pattern, ext(def, options)); + }; - break; - } + m.Minimatch = function Minimatch(pattern, options) { + return new orig.Minimatch(pattern, ext(def, options)); + }; - return true; + return m; +}; - case MODE_BREAK: - return true; - } +Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch; + return minimatch.defaults(def).Minimatch; +}; - break; - } - } +function minimatch(p, pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required'); } - return false; -} - -function printDocToString(doc, options) { - groupModeMap = {}; - const width = options.printWidth; - const newLine = convertEndOfLineToChars$1(options.endOfLine); - let pos = 0; // cmds is basically a stack. We've turned a recursive call into a - // while loop which is much faster. The while loop below adds new - // cmds to the array instead of recursively calling `print`. - - const cmds = [[rootIndent(), MODE_BREAK, doc]]; - const out = []; - let shouldRemeasure = false; - let lineSuffix = []; + if (!options) options = {}; // shortcut: comments match nothing. - while (cmds.length !== 0) { - const [ind, mode, doc] = cmds.pop(); + if (!options.nocomment && pattern.charAt(0) === '#') { + return false; + } // "" only matches "" - if (typeof doc === "string") { - const formatted = newLine !== "\n" && doc.includes("\n") ? doc.replace(/\n/g, newLine) : doc; - out.push(formatted); - pos += getStringWidth$1(formatted); - } else { - switch (doc.type) { - case "cursor": - out.push(cursor$1.placeholder); - break; - case "concat": - for (let i = doc.parts.length - 1; i >= 0; i--) { - cmds.push([ind, mode, doc.parts[i]]); - } + if (pattern.trim() === '') return p === ''; + return new Minimatch(pattern, options).match(p); +} - break; +function Minimatch(pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options); + } - case "indent": - cmds.push([makeIndent(ind, options), mode, doc.contents]); - break; + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required'); + } - case "align": - cmds.push([makeAlign(ind, doc.n, options), mode, doc.contents]); - break; + if (!options) options = {}; + pattern = pattern.trim(); // windows support: need to use /, not \ - case "trim": - pos -= trim$1(out); - break; + if (path.sep !== '/') { + pattern = pattern.split(path.sep).join('/'); + } - case "group": - switch (mode) { - case MODE_FLAT: - if (!shouldRemeasure) { - cmds.push([ind, doc.break ? MODE_BREAK : MODE_FLAT, doc.contents]); - break; - } + 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. - // fallthrough + this.make(); +} - case MODE_BREAK: - { - shouldRemeasure = false; - const next = [ind, MODE_FLAT, doc.contents]; - const rem = width - pos; +Minimatch.prototype.debug = function () {}; - if (!doc.break && fits(next, cmds, rem, options)) { - cmds.push(next); - } else { - // Expanded states are a rare case where a document - // can manually provide multiple representations of - // itself. It provides an array of documents - // going from the least expanded (most flattened) - // representation first to the most expanded. If a - // group has these, we need to manually go through - // these states and find the first one that fits. - if (doc.expandedStates) { - const mostExpanded = doc.expandedStates[doc.expandedStates.length - 1]; +Minimatch.prototype.make = make; - if (doc.break) { - cmds.push([ind, MODE_BREAK, mostExpanded]); - break; - } else { - for (let i = 1; i < doc.expandedStates.length + 1; i++) { - if (i >= doc.expandedStates.length) { - cmds.push([ind, MODE_BREAK, mostExpanded]); - break; - } else { - const state = doc.expandedStates[i]; - const cmd = [ind, MODE_FLAT, state]; +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 (fits(cmd, cmds, rem, options)) { - cmds.push(cmd); - break; - } - } - } - } - } else { - cmds.push([ind, MODE_BREAK, doc.contents]); - } - } + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true; + return; + } - break; - } - } + if (!pattern) { + this.empty = true; + return; + } // step 1: figure out negation, etc. - if (doc.id) { - groupModeMap[doc.id] = cmds[cmds.length - 1][1]; - } - break; - // Fills each line with as much code as possible before moving to a new - // line with the same indentation. - // - // Expects doc.parts to be an array of alternating content and - // whitespace. The whitespace contains the linebreaks. - // - // For example: - // ["I", line, "love", line, "monkeys"] - // or - // [{ type: group, ... }, softline, { type: group, ... }] - // - // It uses this parts structure to handle three main layout cases: - // * The first two content items fit on the same line without - // breaking - // -> output the first content item and the whitespace "flat". - // * Only the first content item fits on the line without breaking - // -> output the first content item "flat" and the whitespace with - // "break". - // * Neither content item fits on the line without breaking - // -> output the first content item and the whitespace with "break". + this.parseNegate(); // step 2: expand braces - case "fill": - { - const rem = width - pos; - const { - parts - } = doc; + 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 - if (parts.length === 0) { - break; - } + set = this.globParts = set.map(function (s) { + return s.split(slashSplit); + }); + this.debug(this.pattern, set); // glob --> regexps - const [content, whitespace] = parts; - const contentFlatCmd = [ind, MODE_FLAT, content]; - const contentBreakCmd = [ind, MODE_BREAK, content]; - const contentFits = fits(contentFlatCmd, [], rem, options, true); + 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. - if (parts.length === 1) { - if (contentFits) { - cmds.push(contentFlatCmd); - } else { - cmds.push(contentBreakCmd); - } + set = set.filter(function (s) { + return s.indexOf(false) === -1; + }); + this.debug(this.pattern, set); + this.set = set; +} - break; - } +Minimatch.prototype.parseNegate = parseNegate; - const whitespaceFlatCmd = [ind, MODE_FLAT, whitespace]; - const whitespaceBreakCmd = [ind, MODE_BREAK, whitespace]; +function parseNegate() { + var pattern = this.pattern; + var negate = false; + var options = this.options; + var negateOffset = 0; + if (options.nonegate) return; - if (parts.length === 2) { - if (contentFits) { - cmds.push(whitespaceFlatCmd); - cmds.push(contentFlatCmd); - } else { - cmds.push(whitespaceBreakCmd); - cmds.push(contentBreakCmd); - } + for (var i = 0, l = pattern.length; i < l && pattern.charAt(i) === '!'; i++) { + negate = !negate; + negateOffset++; + } - break; - } // At this point we've handled the first pair (context, separator) - // and will create a new fill doc for the rest of the content. - // Ideally we wouldn't mutate the array here but copying all the - // elements to a new array would make this algorithm quadratic, - // which is unusable for large arrays (e.g. large texts in JSX). + 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 - parts.splice(0, 2); - const remainingCmd = [ind, mode, fill$1(parts)]; - const secondContent = parts[0]; - const firstAndSecondContentFlatCmd = [ind, MODE_FLAT, concat$1([content, whitespace, secondContent])]; - const firstAndSecondContentFits = fits(firstAndSecondContentFlatCmd, [], rem, options, true); +minimatch.braceExpand = function (pattern, options) { + return braceExpand(pattern, options); +}; - if (firstAndSecondContentFits) { - cmds.push(remainingCmd); - cmds.push(whitespaceFlatCmd); - cmds.push(contentFlatCmd); - } else if (contentFits) { - cmds.push(remainingCmd); - cmds.push(whitespaceBreakCmd); - cmds.push(contentFlatCmd); - } else { - cmds.push(remainingCmd); - cmds.push(whitespaceBreakCmd); - cmds.push(contentBreakCmd); - } +Minimatch.prototype.braceExpand = braceExpand; - break; - } +function braceExpand(pattern, options) { + if (!options) { + if (this instanceof Minimatch) { + options = this.options; + } else { + options = {}; + } + } - case "if-break": - { - const groupMode = doc.groupId ? groupModeMap[doc.groupId] : mode; + pattern = typeof pattern === 'undefined' ? this.pattern : pattern; - if (groupMode === MODE_BREAK) { - if (doc.breakContents) { - cmds.push([ind, mode, doc.breakContents]); - } - } + if (typeof pattern === 'undefined') { + throw new TypeError('undefined pattern'); + } - if (groupMode === MODE_FLAT) { - if (doc.flatContents) { - cmds.push([ind, mode, doc.flatContents]); - } - } + if (options.nobrace || !pattern.match(/\{.*\}/)) { + // shortcut. no need to expand. + return [pattern]; + } - break; - } + return braceExpansion(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. - case "line-suffix": - lineSuffix.push([ind, mode, doc.contents]); - break; - case "line-suffix-boundary": - if (lineSuffix.length > 0) { - cmds.push([ind, mode, { - type: "line", - hard: true - }]); - } +Minimatch.prototype.parse = parse$1; +var SUBPARSE = {}; - break; +function parse$1(pattern, isSub) { + if (pattern.length > 1024 * 64) { + throw new TypeError('pattern is too long'); + } - case "line": - switch (mode) { - case MODE_FLAT: - if (!doc.hard) { - if (!doc.soft) { - out.push(" "); - pos += 1; - } + var options = this.options; // shortcuts - break; - } else { - // This line was forced into the output even if we - // were in flattened mode, so we need to tell the next - // group that no matter what, it needs to remeasure - // because the previous measurement didn't accurately - // capture the entire expression (this is necessary - // for nested groups) - shouldRemeasure = true; - } + if (!options.noglobstar && pattern === '**') return GLOBSTAR; + if (pattern === '') return ''; + var re = ''; + var hasMagic = !!options.nocase; + var escaping = false; // ? => one single character - // fallthrough + 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. - case MODE_BREAK: - if (lineSuffix.length) { - cmds.push([ind, mode, doc]); - cmds.push(...lineSuffix.reverse()); - lineSuffix = []; - break; - } + var patternStart = pattern.charAt(0) === '.' ? '' // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' : '(?!\\.)'; + var self = this; - if (doc.literal) { - if (ind.root) { - out.push(newLine, ind.root.value); - pos = ind.root.length; - } else { - out.push(newLine); - pos = 0; - } - } else { - pos -= trim$1(out); - out.push(newLine + ind.value); - pos = ind.length; - } + 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; - break; - } + case '?': + re += qmark; + hasMagic = true; + break; + default: + re += '\\' + stateChar; break; } + + self.debug('clearStateChar %j %j', stateChar, re); + stateChar = false; } } - const cursorPlaceholderIndex = out.indexOf(cursor$1.placeholder); + 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 (cursorPlaceholderIndex !== -1) { - const otherCursorPlaceholderIndex = out.indexOf(cursor$1.placeholder, cursorPlaceholderIndex + 1); - const beforeCursor = out.slice(0, cursorPlaceholderIndex).join(""); - const aroundCursor = out.slice(cursorPlaceholderIndex + 1, otherCursorPlaceholderIndex).join(""); - const afterCursor = out.slice(otherCursorPlaceholderIndex + 1).join(""); - return { - formatted: beforeCursor + aroundCursor + afterCursor, - cursorNodeStart: beforeCursor.length, - cursorNodeText: aroundCursor - }; - } + if (escaping && reSpecials[c]) { + re += '\\' + c; + escaping = false; + continue; + } - return { - formatted: out.join("") - }; -} + switch (c) { + case '/': + // completely not allowed, even escaped. + // Should already be path-split by now. + return false; -var docPrinter = { - printDocToString -}; + case '\\': + clearStateChar(); + escaping = true; + continue; + // the various stateChar values + // for the "extglob" stuff. -const traverseDocOnExitStackMarker = {}; + 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 -function traverseDoc(doc, onEnter, onExit, shouldTraverseConditionalGroups) { - const docsStack = [doc]; + 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. - while (docsStack.length !== 0) { - const doc = docsStack.pop(); - if (doc === traverseDocOnExitStackMarker) { - onExit(docsStack.pop()); - continue; - } + 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. - let shouldRecurse = true; + if (options.noext) clearStateChar(); + continue; - if (onEnter) { - if (onEnter(doc) === false) { - shouldRecurse = false; - } - } + case '(': + if (inClass) { + re += '('; + continue; + } - if (onExit) { - docsStack.push(doc); - docsStack.push(traverseDocOnExitStackMarker); - } + if (!stateChar) { + re += '\\('; + continue; + } - if (shouldRecurse) { - // When there are multiple parts to process, - // the parts need to be pushed onto the stack in reverse order, - // so that they are processed in the original order - // when the stack is popped. - if (doc.type === "concat" || doc.type === "fill") { - for (let ic = doc.parts.length, i = ic - 1; i >= 0; --i) { - docsStack.push(doc.parts[i]); + 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; } - } else if (doc.type === "if-break") { - if (doc.flatContents) { - docsStack.push(doc.flatContents); + + clearStateChar(); + hasMagic = true; + var pl = patternListStack.pop(); // negation is (?:(?!js)[^/]*) + // The others are (?:) + + re += pl.close; + + if (pl.type === '!') { + negativeLists.push(pl); } - if (doc.breakContents) { - docsStack.push(doc.breakContents); + pl.reEnd = re.length; + continue; + + case '|': + if (inClass || !patternListStack.length || escaping) { + re += '\\|'; + escaping = false; + continue; } - } else if (doc.type === "group" && doc.expandedStates) { - if (shouldTraverseConditionalGroups) { - for (let ic = doc.expandedStates.length, i = ic - 1; i >= 0; --i) { - docsStack.push(doc.expandedStates[i]); - } - } else { - docsStack.push(doc.contents); + + 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; } - } else if (doc.contents) { - docsStack.push(doc.contents); - } - } - } -} -function mapDoc(doc, cb) { - if (doc.type === "concat" || doc.type === "fill") { - const parts = doc.parts.map(part => mapDoc(part, cb)); - return cb(Object.assign({}, doc, { - parts - })); - } else if (doc.type === "if-break") { - const breakContents = doc.breakContents && mapDoc(doc.breakContents, cb); - const flatContents = doc.flatContents && mapDoc(doc.flatContents, cb); - return cb(Object.assign({}, doc, { - breakContents, - flatContents - })); - } else if (doc.contents) { - const contents = mapDoc(doc.contents, cb); - return cb(Object.assign({}, doc, { - contents - })); - } + inClass = true; + classStart = i; + reClassStart = re.length; + re += c; + continue; - return cb(doc); -} + 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\]" -function findInDoc(doc, fn, defaultValue) { - let result = defaultValue; - let hasStopped = false; - function findInDocOnEnterFn(doc) { - const maybeResult = fn(doc); + 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); - if (maybeResult !== undefined) { - hasStopped = true; - result = maybeResult; - } + 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. - if (hasStopped) { - return false; - } - } - traverseDoc(doc, findInDocOnEnterFn); - return result; -} + hasMagic = true; + inClass = false; + re += c; + continue; -function isEmpty(n) { - return typeof n === "string" && n.length === 0; -} + default: + // swallow any state char that wasn't consumed + clearStateChar(); -function isLineNextFn(doc) { - if (typeof doc === "string") { - return false; - } + if (escaping) { + // no need + escaping = false; + } else if (reSpecials[c] && !(c === '^' && inClass)) { + re += '\\'; + } - if (doc.type === "line") { - return true; - } -} + re += c; + } // switch -function isLineNext(doc) { - return findInDoc(doc, isLineNextFn, false); -} + } // for + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" -function willBreakFn(doc) { - if (doc.type === "group" && doc.break) { - return true; - } - if (doc.type === "line" && doc.hard) { - return true; - } + 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. - if (doc.type === "break-parent") { - return true; - } -} -function willBreak(doc) { - return findInDoc(doc, willBreakFn, false); -} + clearStateChar(); -function breakParentGroup(groupStack) { - if (groupStack.length > 0) { - const parentGroup = groupStack[groupStack.length - 1]; // Breaks are not propagated through conditional groups because - // the user is expected to manually handle what breaks. + if (escaping) { + // trailing \\ + re += '\\\\'; + } // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot - if (!parentGroup.expandedStates) { - parentGroup.break = true; - } - } - return null; -} + var addPatternStart = false; -function propagateBreaks(doc) { - const alreadyVisitedSet = new Set(); - const groupStack = []; + 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. - function propagateBreaksOnEnterFn(doc) { - if (doc.type === "break-parent") { - breakParentGroup(groupStack); - } - if (doc.type === "group") { - groupStack.push(doc); + 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. - if (alreadyVisitedSet.has(doc)) { - return false; - } + var openParensBefore = nlBefore.split('(').length - 1; + var cleanAfter = nlAfter; - alreadyVisitedSet.add(doc); + for (i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, ''); } - } - function propagateBreaksOnExitFn(doc) { - if (doc.type === "group") { - const group = groupStack.pop(); + nlAfter = cleanAfter; + var dollar = ''; - if (group.break) { - breakParentGroup(groupStack); - } + if (nlAfter === '' && isSub !== SUBPARSE) { + dollar = '$'; } - } - traverseDoc(doc, propagateBreaksOnEnterFn, propagateBreaksOnExitFn, - /* shouldTraverseConditionalGroups */ - true); -} + 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. -function removeLinesFn(doc) { - // Force this doc into flat mode by statically converting all - // lines into spaces (or soft lines into nothing). Hard lines - // should still output because there's too great of a chance - // of breaking existing assumptions otherwise. - if (doc.type === "line" && !doc.hard) { - return doc.soft ? "" : " "; - } else if (doc.type === "if-break") { - return doc.flatContents || ""; + + if (re !== '' && hasMagic) { + re = '(?=.)' + re; } - return doc; -} + if (addPatternStart) { + re = patternStart + re; + } // parsing just a piece of a larger pattern. -function removeLines(doc) { - return mapDoc(doc, removeLinesFn); -} -function stripTrailingHardline(doc) { - // HACK remove ending hardline, original PR: #1984 - if (doc.type === "concat" && doc.parts.length !== 0) { - const lastPart = doc.parts[doc.parts.length - 1]; + 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 (lastPart.type === "concat") { - if (lastPart.parts.length === 2 && lastPart.parts[0].hard && lastPart.parts[1].type === "break-parent") { - return { - type: "concat", - parts: doc.parts.slice(0, -1) - }; - } - return { - type: "concat", - parts: doc.parts.slice(0, -1).concat(stripTrailingHardline(lastPart)) - }; - } + if (!hasMagic) { + return globUnescape(pattern); } - return doc; + 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; } -var docUtils = { - isEmpty, - willBreak, - isLineNext, - traverseDoc, - findInDoc, - mapDoc, - propagateBreaks, - removeLines, - stripTrailingHardline +minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe(); }; -function flattenDoc(doc) { - if (doc.type === "concat") { - const res = []; +Minimatch.prototype.makeRe = makeRe; - for (let i = 0; i < doc.parts.length; ++i) { - const doc2 = doc.parts[i]; +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. - if (typeof doc2 !== "string" && doc2.type === "concat") { - res.push(...flattenDoc(doc2).parts); - } else { - const flattened = flattenDoc(doc2); + var set = this.set; - if (flattened !== "") { - res.push(flattened); - } - } - } + if (!set.length) { + this.regexp = false; + return this.regexp; + } - return Object.assign({}, doc, { - parts: res - }); - } else if (doc.type === "if-break") { - return Object.assign({}, doc, { - breakContents: doc.breakContents != null ? flattenDoc(doc.breakContents) : null, - flatContents: doc.flatContents != null ? flattenDoc(doc.flatContents) : null - }); - } else if (doc.type === "group") { - return Object.assign({}, doc, { - contents: flattenDoc(doc.contents), - expandedStates: doc.expandedStates ? doc.expandedStates.map(flattenDoc) : doc.expandedStates - }); - } else if (doc.contents) { - return Object.assign({}, doc, { - contents: flattenDoc(doc.contents) - }); + 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 doc; + return this.regexp; } -function printDoc(doc) { - if (typeof doc === "string") { - return JSON.stringify(doc); +minimatch.match = function (list, pattern, options) { + options = options || {}; + var mm = new Minimatch(pattern, options); + list = list.filter(function (f) { + return mm.match(f); + }); + + if (mm.options.nonull && !list.length) { + list.push(pattern); } - if (doc.type === "line") { - if (doc.literal) { - return "literalline"; - } + return list; +}; - if (doc.hard) { - return "hardline"; - } +Minimatch.prototype.match = match; - if (doc.soft) { - return "softline"; - } +function match(f, partial) { + this.debug('match', f, this.pattern); // short-circuit in the case of busted things. + // comments, etc. - return "line"; - } + 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 (doc.type === "break-parent") { - return "breakParent"; - } + if (path.sep !== '/') { + f = f.split(path.sep).join('/'); + } // treat the test path as a set of pathparts. - if (doc.type === "trim") { - return "trim"; - } - if (doc.type === "concat") { - return "[" + doc.parts.map(printDoc).join(", ") + "]"; - } + 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. - if (doc.type === "indent") { - return "indent(" + printDoc(doc.contents) + ")"; - } + var set = this.set; + this.debug(this.pattern, 'set', set); // Find the basename of the path by looking for the last non-empty segment - if (doc.type === "align") { - return doc.n === -Infinity ? "dedentToRoot(" + printDoc(doc.contents) + ")" : doc.n < 0 ? "dedent(" + printDoc(doc.contents) + ")" : doc.n.type === "root" ? "markAsRoot(" + printDoc(doc.contents) + ")" : "align(" + JSON.stringify(doc.n) + ", " + printDoc(doc.contents) + ")"; - } + var filename; + var i; - if (doc.type === "if-break") { - return "ifBreak(" + printDoc(doc.breakContents) + (doc.flatContents ? ", " + printDoc(doc.flatContents) : "") + ")"; + for (i = f.length - 1; i >= 0; i--) { + filename = f[i]; + if (filename) break; } - if (doc.type === "group") { - if (doc.expandedStates) { - return "conditionalGroup(" + "[" + doc.expandedStates.map(printDoc).join(",") + "])"; - } - - return (doc.break ? "wrappedGroup" : "group") + "(" + printDoc(doc.contents) + ")"; - } + for (i = 0; i < set.length; i++) { + var pattern = set[i]; + var file = f; - if (doc.type === "fill") { - return "fill" + "(" + doc.parts.map(printDoc).join(", ") + ")"; - } + if (options.matchBase && pattern.length === 1) { + file = [filename]; + } - if (doc.type === "line-suffix") { - return "lineSuffix(" + printDoc(doc.contents) + ")"; - } + var hit = this.matchOne(file, pattern, partial); - if (doc.type === "line-suffix-boundary") { - return "lineSuffixBoundary"; - } + 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. - throw new Error("Unknown doc type " + doc.type); -} -var docDebug = { - printDocToDebug(doc) { - return printDoc(flattenDoc(doc)); - } + 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. -}; -var document = { - builders: docBuilders, - printer: docPrinter, - utils: docUtils, - debug: docDebug -}; +Minimatch.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); -const { - getMaxContinuousCount: getMaxContinuousCount$1, - getStringWidth: getStringWidth$2, - getAlignmentSize: getAlignmentSize$1, - getIndentSize: getIndentSize$1, - skip: skip$1, - skipWhitespace: skipWhitespace$1, - skipSpaces: skipSpaces$1, - skipNewline: skipNewline$1, - skipToLineEnd: skipToLineEnd$1, - skipEverythingButNewLine: skipEverythingButNewLine$1, - skipInlineComment: skipInlineComment$1, - skipTrailingComment: skipTrailingComment$1, - hasNewline: hasNewline$1, - hasNewlineInRange: hasNewlineInRange$1, - hasSpaces: hasSpaces$1, - isNextLineEmpty: isNextLineEmpty$1, - isNextLineEmptyAfterIndex: isNextLineEmptyAfterIndex$1, - isPreviousLineEmpty: isPreviousLineEmpty$1, - getNextNonSpaceNonCommentCharacterIndex: getNextNonSpaceNonCommentCharacterIndex$1, - makeString: makeString$1, - addLeadingComment: addLeadingComment$1, - addDanglingComment: addDanglingComment$1, - addTrailingComment: addTrailingComment$1 -} = util$1; -var utilShared = { - getMaxContinuousCount: getMaxContinuousCount$1, - getStringWidth: getStringWidth$2, - getAlignmentSize: getAlignmentSize$1, - getIndentSize: getIndentSize$1, - skip: skip$1, - skipWhitespace: skipWhitespace$1, - skipSpaces: skipSpaces$1, - skipNewline: skipNewline$1, - skipToLineEnd: skipToLineEnd$1, - skipEverythingButNewLine: skipEverythingButNewLine$1, - skipInlineComment: skipInlineComment$1, - skipTrailingComment: skipTrailingComment$1, - hasNewline: hasNewline$1, - hasNewlineInRange: hasNewlineInRange$1, - hasSpaces: hasSpaces$1, - isNextLineEmpty: isNextLineEmpty$1, - isNextLineEmptyAfterIndex: isNextLineEmptyAfterIndex$1, - isPreviousLineEmpty: isPreviousLineEmpty$1, - getNextNonSpaceNonCommentCharacterIndex: getNextNonSpaceNonCommentCharacterIndex$1, - makeString: makeString$1, - addLeadingComment: addLeadingComment$1, - addDanglingComment: addDanglingComment$1, - addTrailingComment: addTrailingComment$1 -}; + 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. -const { - concat: concat$2, - line: line$1, - hardline: hardline$1, - breakParent: breakParent$1, - indent: indent$1, - lineSuffix: lineSuffix$1, - join: join$1, - cursor: cursor$2 -} = document.builders; -const { - hasNewline: hasNewline$2, - skipNewline: skipNewline$2, - isPreviousLineEmpty: isPreviousLineEmpty$2 -} = util$1; -const { - addLeadingComment: addLeadingComment$2, - addDanglingComment: addDanglingComment$2, - addTrailingComment: addTrailingComment$2 -} = utilShared; -const childNodesCacheKey = Symbol("child-nodes"); + if (p === false) return false; -function getSortedChildNodes(node, options, resultArray) { - if (!node) { - return; - } + 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 - const { - printer, - locStart, - locEnd - } = options; + var fr = fi; + var pr = pi + 1; - if (resultArray) { - if (printer.canAttachComment && printer.canAttachComment(node)) { - // This reverse insertion sort almost always takes constant - // time because we almost always (maybe always?) append the - // nodes in order anyway. - let i; + 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 (i = resultArray.length - 1; i >= 0; --i) { - if (locStart(resultArray[i]) <= locStart(node) && locEnd(resultArray[i]) <= locEnd(node)) { - break; + for (; fi < fl; fi++) { + if (file[fi] === '.' || file[fi] === '..' || !options.dot && file[fi].charAt(0) === '.') return false; } - } - resultArray.splice(i + 1, 0, node); - return; - } - } else if (node[childNodesCacheKey]) { - return node[childNodesCacheKey]; - } + return true; + } // ok, let's see if we can swallow whatever we can. - const childNodes = printer.getCommentChildNodes && printer.getCommentChildNodes(node, options) || typeof node === "object" && Object.keys(node).filter(n => n !== "enclosingNode" && n !== "precedingNode" && n !== "followingNode").map(n => node[n]); - if (!childNodes) { - return; - } + 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 (!resultArray) { - Object.defineProperty(node, childNodesCacheKey, { - value: resultArray = [], - enumerable: false - }); - } + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee); // found a match. - childNodes.forEach(childNode => { - getSortedChildNodes(childNode, options, resultArray); - }); - return resultArray; -} // As efficiently as possible, decorate the comment object with -// .precedingNode, .enclosingNode, and/or .followingNode properties, at -// least one of which is guaranteed to be defined. + 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. -function decorateComment(node, comment, options) { - const { - locStart, - locEnd - } = options; - const childNodes = getSortedChildNodes(node, options); - let precedingNode; - let followingNode; // Time to dust off the old binary search robes and wizard hat. + 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 - let left = 0; - let right = childNodes.length; - while (left < right) { - const middle = left + right >> 1; - const child = childNodes[middle]; + 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. - if (locStart(child) - locStart(comment) <= 0 && locEnd(comment) - locEnd(child) <= 0) { - // The comment is completely contained by this child node. - comment.enclosingNode = child; - decorateComment(child, comment, options); - return; // Abandon the binary search at this level. - } - if (locEnd(child) - locStart(comment) <= 0) { - // This child node falls completely before the comment. - // Because we will never consider this node or any nodes - // before it again, this node must be the closest preceding - // node we have encountered so far. - precedingNode = child; - left = middle + 1; - continue; - } + var hit; - if (locEnd(comment) - locStart(child) <= 0) { - // This child node falls completely after the comment. - // Because we will never consider this node or any nodes after - // it again, this node must be the closest following node we - // have encountered so far. - followingNode = child; - right = middle; - continue; + 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); } - /* istanbul ignore next */ + 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. - throw new Error("Comment location overlaps with node location"); - } // We don't want comments inside of different expressions inside of the same - // template literal to move to another expression. + 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. - if (comment.enclosingNode && comment.enclosingNode.type === "TemplateLiteral") { - const { - quasis - } = comment.enclosingNode; - const commentIndex = findExpressionIndexForComment(quasis, comment, options); - if (precedingNode && findExpressionIndexForComment(quasis, precedingNode, options) !== commentIndex) { - precedingNode = null; - } + throw new Error('wtf?'); +}; // replace stuff like \* with * - if (followingNode && findExpressionIndexForComment(quasis, followingNode, options) !== commentIndex) { - followingNode = null; - } - } - if (precedingNode) { - comment.precedingNode = precedingNode; - } +function globUnescape(s) { + return s.replace(/\\(.)/g, '$1'); +} - if (followingNode) { - comment.followingNode = followingNode; - } +function regExpEscape(s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); } -function attach(comments, ast, text, options) { - if (!Array.isArray(comments)) { +const copyProperty = (to, from, property, ignoreNonConfigurable) => { + // `Function#length` should reflect the parameters of `to` not `from` since we keep its body. + // `Function#prototype` is non-writable and non-configurable so can never be modified. + if (property === 'length' || property === 'prototype') { + return; + } // `Function#arguments` and `Function#caller` should not be copied. They were reported to be present in `Reflect.ownKeys` for some devices in React Native (#41), so we explicitly ignore them here. + + + if (property === 'arguments' || property === 'caller') { return; } - const tiesToBreak = []; - const { - locStart, - locEnd - } = options; - comments.forEach((comment, i) => { - if (options.parser === "json" || options.parser === "json5" || options.parser === "__js_expression" || options.parser === "__vue_expression") { - if (locStart(comment) - locStart(ast) <= 0) { - addLeadingComment$2(ast, comment); - return; - } + const toDescriptor = Object.getOwnPropertyDescriptor(to, property); + const fromDescriptor = Object.getOwnPropertyDescriptor(from, property); - if (locEnd(comment) - locEnd(ast) >= 0) { - addTrailingComment$2(ast, comment); - return; - } - } + if (!canCopyProperty(toDescriptor, fromDescriptor) && ignoreNonConfigurable) { + return; + } - decorateComment(ast, comment, options); - const { - precedingNode, - enclosingNode, - followingNode - } = comment; - const pluginHandleOwnLineComment = options.printer.handleComments && options.printer.handleComments.ownLine ? options.printer.handleComments.ownLine : () => false; - const pluginHandleEndOfLineComment = options.printer.handleComments && options.printer.handleComments.endOfLine ? options.printer.handleComments.endOfLine : () => false; - const pluginHandleRemainingComment = options.printer.handleComments && options.printer.handleComments.remaining ? options.printer.handleComments.remaining : () => false; - const isLastComment = comments.length - 1 === i; + Object.defineProperty(to, property, fromDescriptor); +}; // `Object.defineProperty()` throws if the property exists, is not configurable and either: +// - one its descriptors is changed +// - it is non-writable and its value is changed - if (hasNewline$2(text, locStart(comment), { - backwards: true - })) { - // If a comment exists on its own line, prefer a leading comment. - // We also need to check if it's the first line of the file. - if (pluginHandleOwnLineComment(comment, text, options, ast, isLastComment)) ; else if (followingNode) { - // Always a leading comment. - addLeadingComment$2(followingNode, comment); - } else if (precedingNode) { - addTrailingComment$2(precedingNode, comment); - } else if (enclosingNode) { - addDanglingComment$2(enclosingNode, comment); - } else { - // There are no nodes, let's attach it to the root of the ast - /* istanbul ignore next */ - addDanglingComment$2(ast, comment); - } - } else if (hasNewline$2(text, locEnd(comment))) { - if (pluginHandleEndOfLineComment(comment, text, options, ast, isLastComment)) ; else if (precedingNode) { - // There is content before this comment on the same line, but - // none after it, so prefer a trailing comment of the previous node. - addTrailingComment$2(precedingNode, comment); - } else if (followingNode) { - addLeadingComment$2(followingNode, comment); - } else if (enclosingNode) { - addDanglingComment$2(enclosingNode, comment); - } else { - // There are no nodes, let's attach it to the root of the ast +const canCopyProperty = function (toDescriptor, fromDescriptor) { + return toDescriptor === undefined || toDescriptor.configurable || toDescriptor.writable === fromDescriptor.writable && toDescriptor.enumerable === fromDescriptor.enumerable && toDescriptor.configurable === fromDescriptor.configurable && (toDescriptor.writable || toDescriptor.value === fromDescriptor.value); +}; - /* istanbul ignore next */ - addDanglingComment$2(ast, comment); - } - } else { - if (pluginHandleRemainingComment(comment, text, options, ast, isLastComment)) ; else if (precedingNode && followingNode) { - // Otherwise, text exists both before and after the comment on - // the same line. If there is both a preceding and following - // node, use a tie-breaking algorithm to determine if it should - // be attached to the next or previous node. In the last case, - // simply attach the right node; - const tieCount = tiesToBreak.length; +const changePrototype = (to, from) => { + const fromPrototype = Object.getPrototypeOf(from); - if (tieCount > 0) { - const lastTie = tiesToBreak[tieCount - 1]; + if (fromPrototype === Object.getPrototypeOf(to)) { + return; + } - if (lastTie.followingNode !== comment.followingNode) { - breakTies(tiesToBreak, text, options); - } - } + Object.setPrototypeOf(to, fromPrototype); +}; - tiesToBreak.push(comment); - } else if (precedingNode) { - addTrailingComment$2(precedingNode, comment); - } else if (followingNode) { - addLeadingComment$2(followingNode, comment); - } else if (enclosingNode) { - addDanglingComment$2(enclosingNode, comment); - } else { - // There are no nodes, let's attach it to the root of the ast +const wrappedToString = (withName, fromBody) => `/* Wrapped ${withName}*/\n${fromBody}`; - /* istanbul ignore next */ - addDanglingComment$2(ast, comment); - } - } - }); - breakTies(tiesToBreak, text, options); - comments.forEach(comment => { - // These node references were useful for breaking ties, but we - // don't need them anymore, and they create cycles in the AST that - // may lead to infinite recursion if we don't delete them here. - delete comment.precedingNode; - delete comment.enclosingNode; - delete comment.followingNode; - }); -} +const toStringDescriptor = Object.getOwnPropertyDescriptor(Function.prototype, 'toString'); +const toStringName = Object.getOwnPropertyDescriptor(Function.prototype.toString, 'name'); // We call `from.toString()` early (not lazily) to ensure `from` can be garbage collected. +// We use `bind()` instead of a closure for the same reason. +// Calling `from.toString()` early also allows caching it in case `to.toString()` is called several times. -function breakTies(tiesToBreak, text, options) { - const tieCount = tiesToBreak.length; +const changeToString = (to, from, name) => { + const withName = name === '' ? '' : `with ${name.trim()}() `; + const newToString = wrappedToString.bind(null, withName, from.toString()); // Ensure `to.toString.toString` is non-enumerable and has the same `same` - if (tieCount === 0) { - return; - } + Object.defineProperty(newToString, 'name', toStringName); + Object.defineProperty(to, 'toString', Object.assign({}, toStringDescriptor, { + value: newToString + })); +}; +const mimicFn = (to, from, { + ignoreNonConfigurable = false +} = {}) => { const { - precedingNode, - followingNode, - enclosingNode - } = tiesToBreak[0]; - const gapRegExp = options.printer.getGapRegex && options.printer.getGapRegex(enclosingNode) || /^[\s(]*$/; - let gapEndPos = options.locStart(followingNode); // Iterate backwards through tiesToBreak, examining the gaps - // between the tied comments. In order to qualify as leading, a - // comment must be separated from followingNode by an unbroken series of - // gaps (or other comments). Gaps should only contain whitespace or open - // parentheses. + name + } = to; - let indexOfFirstLeadingComment; + for (const property of Reflect.ownKeys(from)) { + copyProperty(to, from, property, ignoreNonConfigurable); + } - for (indexOfFirstLeadingComment = tieCount; indexOfFirstLeadingComment > 0; --indexOfFirstLeadingComment) { - const comment = tiesToBreak[indexOfFirstLeadingComment - 1]; - assert$1.strictEqual(comment.precedingNode, precedingNode); - assert$1.strictEqual(comment.followingNode, followingNode); - const gap = text.slice(options.locEnd(comment), gapEndPos); + changePrototype(to, from); + changeToString(to, from, name); + return to; +}; - if (gapRegExp.test(gap)) { - gapEndPos = options.locStart(comment); - } else { - // The gap string contained something other than whitespace or open - // parentheses. - break; - } - } +var mimicFn_1 = mimicFn; - tiesToBreak.forEach((comment, i) => { - if (i < indexOfFirstLeadingComment) { - addTrailingComment$2(precedingNode, comment); - } else { - addLeadingComment$2(followingNode, comment); - } +var pDefer = () => { + const ret = {}; + ret.promise = new Promise((resolve, reject) => { + ret.resolve = resolve; + ret.reject = reject; }); - tiesToBreak.length = 0; -} - -function printComment(commentPath, options) { - const comment = commentPath.getValue(); - comment.printed = true; - return options.printer.printComment(commentPath, options); -} + return ret; +}; -function findExpressionIndexForComment(quasis, comment, options) { - const startPos = options.locStart(comment) - 1; +var dist = createCommonjsModule(function (module, exports) { - for (let i = 1; i < quasis.length; ++i) { - if (startPos < getQuasiRange(quasis[i]).start) { - return i - 1; - } - } // We haven't found it, it probably means that some of the locations are off. - // Let's just return the first one. + var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } - /* istanbul ignore next */ + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : new P(function (resolve) { + resolve(result.value); + }).then(fulfilled, rejected); + } - return 0; -} + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; -function getQuasiRange(expr) { - if (expr.start !== undefined) { - // Babel - return { - start: expr.start, - end: expr.end + var __importDefault = this && this.__importDefault || function (mod) { + return mod && mod.__esModule ? mod : { + "default": mod }; - } // Flow + }; + Object.defineProperty(exports, "__esModule", { + value: true + }); - return { - start: expr.range[0], - end: expr.range[1] - }; -} + const p_defer_1 = __importDefault(pDefer); -function printLeadingComment(commentPath, print, options) { - const comment = commentPath.getValue(); - const contents = printComment(commentPath, options); + function mapAgeCleaner(map, property = 'maxAge') { + let processingKey; + let processingTimer; + let processingDeferred; - if (!contents) { - return ""; - } + const cleanup = () => __awaiter(this, void 0, void 0, function* () { + if (processingKey !== undefined) { + // If we are already processing an item, we can safely exit + return; + } - const isBlock = options.printer.isBlockComment && options.printer.isBlockComment(comment); // Leading block comments should see if they need to stay on the - // same line or not. + const setupTimer = item => __awaiter(this, void 0, void 0, function* () { + processingDeferred = p_defer_1.default(); + const delay = item[1][property] - Date.now(); - if (isBlock) { - const lineBreak = hasNewline$2(options.originalText, options.locEnd(comment)) ? hasNewline$2(options.originalText, options.locStart(comment), { - backwards: true - }) ? hardline$1 : line$1 : " "; - return concat$2([contents, lineBreak]); - } + if (delay <= 0) { + // Remove the item immediately if the delay is equal to or below 0 + map.delete(item[0]); + processingDeferred.resolve(); + return; + } // Keep track of the current processed key - return concat$2([contents, hardline$1]); -} -function printTrailingComment(commentPath, print, options) { - const comment = commentPath.getValue(); - const contents = printComment(commentPath, options); + processingKey = item[0]; + processingTimer = setTimeout(() => { + // Remove the item when the timeout fires + map.delete(item[0]); - if (!contents) { - return ""; - } + if (processingDeferred) { + processingDeferred.resolve(); + } + }, delay); // tslint:disable-next-line:strict-type-predicates - const isBlock = options.printer.isBlockComment && options.printer.isBlockComment(comment); // We don't want the line to break - // when the parentParentNode is a ClassDeclaration/-Expression - // And the parentNode is in the superClass property + if (typeof processingTimer.unref === 'function') { + // Don't hold up the process from exiting + processingTimer.unref(); + } - const parentNode = commentPath.getNode(1); - const parentParentNode = commentPath.getNode(2); - const isParentSuperClass = parentParentNode && (parentParentNode.type === "ClassDeclaration" || parentParentNode.type === "ClassExpression") && parentParentNode.superClass === parentNode; + return processingDeferred.promise; + }); - if (hasNewline$2(options.originalText, options.locStart(comment), { - backwards: true - })) { - // This allows comments at the end of nested structures: - // { - // x: 1, - // y: 2 - // // A comment - // } - // Those kinds of comments are almost always leading comments, but - // here it doesn't go "outside" the block and turns it into a - // trailing comment for `2`. We can simulate the above by checking - // if this a comment on its own line; normal trailing comments are - // always at the end of another expression. - const isLineBeforeEmpty = isPreviousLineEmpty$2(options.originalText, comment, options.locStart); - return lineSuffix$1(concat$2([hardline$1, isLineBeforeEmpty ? hardline$1 : "", contents])); - } else if (isBlock || isParentSuperClass) { - // Trailing block comments never need a newline - return concat$2([" ", contents]); - } + try { + for (const entry of map) { + yield setupTimer(entry); + } + } catch (_a) {// Do nothing if an error occurs, this means the timer was cleaned up and we should stop processing + } - return concat$2([lineSuffix$1(concat$2([" ", contents])), !isBlock ? breakParent$1 : ""]); -} + processingKey = undefined; + }); -function printDanglingComments(path, options, sameIndent, filter) { - const parts = []; - const node = path.getValue(); + const reset = () => { + processingKey = undefined; - if (!node || !node.comments) { - return ""; - } + if (processingTimer !== undefined) { + clearTimeout(processingTimer); + processingTimer = undefined; + } - path.each(commentPath => { - const comment = commentPath.getValue(); + if (processingDeferred !== undefined) { + // tslint:disable-line:early-exit + processingDeferred.reject(undefined); + processingDeferred = undefined; + } + }; - if (comment && !comment.leading && !comment.trailing && (!filter || filter(comment))) { - parts.push(printComment(commentPath, options)); - } - }, "comments"); + const originalSet = map.set.bind(map); - if (parts.length === 0) { - return ""; - } + map.set = (key, value) => { + if (map.has(key)) { + // If the key already exist, remove it so we can add it back at the end of the map. + map.delete(key); + } // Call the original `map.set` - if (sameIndent) { - return join$1(hardline$1, parts); - } - return indent$1(concat$2([hardline$1, join$1(hardline$1, parts)])); -} + const result = originalSet(key, value); // If we are already processing a key and the key added is the current processed key, stop processing it -function prependCursorPlaceholder(path, options, printed) { - if (path.getNode() === options.cursorNode && path.getValue()) { - return concat$2([cursor$2, printed, cursor$2]); - } + if (processingKey && processingKey === key) { + reset(); + } // Always run the cleanup method in case it wasn't started yet - return printed; -} -function printComments(path, print, options, needsSemi) { - const value = path.getValue(); - const printed = print(path); - const comments = value && value.comments; + cleanup(); // tslint:disable-line:no-floating-promises - if (!comments || comments.length === 0) { - return prependCursorPlaceholder(path, options, printed); + return result; + }; + + cleanup(); // tslint:disable-line:no-floating-promises + + return map; } - const leadingParts = []; - const trailingParts = [needsSemi ? ";" : "", printed]; - path.each(commentPath => { - const comment = commentPath.getValue(); - const { - leading, - trailing - } = comment; + exports.default = mapAgeCleaner; // Add support for CJS - if (leading) { - const contents = printLeadingComment(commentPath, print, options); + module.exports = mapAgeCleaner; + module.exports.default = mapAgeCleaner; +}); - if (!contents) { - return; - } +const cacheStore = new WeakMap(); +/** +[Memoize](https://en.wikipedia.org/wiki/Memoization) functions - An optimization used to speed up consecutive function calls by caching the result of calls with identical input. - leadingParts.push(contents); - const text = options.originalText; - const index = skipNewline$2(text, options.locEnd(comment)); +@param fn - Function to be memoized. - if (index !== false && hasNewline$2(text, index)) { - leadingParts.push(hardline$1); - } - } else if (trailing) { - trailingParts.push(printTrailingComment(commentPath, print, options)); - } - }, "comments"); - return prependCursorPlaceholder(path, options, concat$2(leadingParts.concat(trailingParts))); -} +@example +``` +import mem = require('mem'); -var comments = { - attach, - printComments, - printDanglingComments, - getSortedChildNodes -}; +let i = 0; +const counter = () => ++i; +const memoized = mem(counter); -function getNodeHelper(path, count) { - const stackIndex = getNodeStackIndexHelper(path.stack, count); - return stackIndex === -1 ? null : path.stack[stackIndex]; -} +memoized('foo'); +//=> 1 -function getNodeStackIndexHelper(stack, count) { - for (let i = stack.length - 1; i >= 0; i -= 2) { - const value = stack[i]; +// Cached as it's the same arguments +memoized('foo'); +//=> 1 - if (value && !Array.isArray(value) && --count < 0) { - return i; - } - } +// Not cached anymore as the arguments changed +memoized('bar'); +//=> 2 - return -1; -} +memoized('bar'); +//=> 2 +``` +*/ -class FastPath { - constructor(value) { - this.stack = [value]; - } // The name of the current property is always the penultimate element of - // this.stack, and always a String. +const mem = (fn, { + cacheKey, + cache = new Map(), + maxAge +} = {}) => { + if (typeof maxAge === 'number') { + // TODO: Drop after https://github.com/SamVerschueren/map-age-cleaner/issues/5 + // @ts-expect-error + dist(cache); + } + + const memoized = function (...arguments_) { + const key = cacheKey ? cacheKey(arguments_) : arguments_[0]; + const cacheItem = cache.get(key); + if (cacheItem) { + return cacheItem.data; + } - getName() { - const { - stack - } = this; - const { - length - } = stack; + const result = fn.apply(this, arguments_); + cache.set(key, { + data: result, + maxAge: maxAge ? Date.now() + maxAge : Infinity + }); + return result; + }; - if (length > 1) { - return stack[length - 2]; - } // Since the name is always a string, null is a safe sentinel value to - // return if we do not know the name of the (root) value. + try { + // The below call will throw in some host environments + // See https://github.com/sindresorhus/mimic-fn/issues/10 + mimicFn_1(memoized, fn); + } catch (_a) {} - /* istanbul ignore next */ + cacheStore.set(memoized, cache); + return memoized; +}; +/** +Clear all cached data of a memoized function. +@param fn - Memoized function. +*/ - return null; - } // The value of the current property is always the final element of - // this.stack. +mem.clear = fn => { + const cache = cacheStore.get(fn); - getValue() { - return getLast(this.stack); + if (!cache) { + throw new TypeError('Can\'t clear a function that was not memoized!'); } - getNode(count = 0) { - return getNodeHelper(this, count); + if (typeof cache.clear !== 'function') { + throw new TypeError('The cache Map can\'t be cleared!'); } - getParentNode(count = 0) { - return getNodeHelper(this, count + 1); - } // Temporarily push properties named by string arguments given after the - // callback function onto this.stack, then call the callback with a - // reference to this (modified) FastPath object. Note that the stack will - // be restored to its original state after the callback is finished, so it - // is probably a mistake to retain a reference to the path. + cache.clear(); +}; +var dist$1 = mem; - call(callback, ...names) { - const { - stack - } = this; - const { - length - } = stack; - let value = getLast(stack); +var thirdParty = require("./third-party"); - for (const name of names) { - value = value[name]; - stack.push(name, value); - } +const ParserEND = 0x110000; - const result = callback(this); - stack.length = length; - return result; +class ParserError extends Error { + /* istanbul ignore next */ + constructor(msg, filename, linenumber) { + super('[ParserError] ' + msg, filename, linenumber); + this.name = 'ParserError'; + this.code = 'ParserError'; + if (Error.captureStackTrace) Error.captureStackTrace(this, ParserError); } - callParent(callback, count = 0) { - const stackIndex = getNodeStackIndexHelper(this.stack, count + 1); - const parentValues = this.stack.splice(stackIndex + 1); - const result = callback(this); - this.stack.push(...parentValues); - return result; - } // Similar to FastPath.prototype.call, except that the value obtained by - // accessing this.getValue()[name1][name2]... should be array-like. The - // callback will be called with a reference to this path object for each - // element of the array. +} +class State { + constructor(parser) { + this.parser = parser; + this.buf = ''; + this.returned = null; + this.result = null; + this.resultTable = null; + this.resultArr = null; + } - each(callback, ...names) { - const { - stack - } = this; - const { - length - } = stack; - let value = getLast(stack); +} - for (const name of names) { - value = value[name]; - stack.push(name, value); +class Parser { + constructor() { + this.pos = 0; + this.col = 0; + this.line = 0; + this.obj = {}; + this.ctx = this.obj; + this.stack = []; + this._buf = ''; + this.char = null; + this.ii = 0; + this.state = new State(this.parseStart); + } + + parse(str) { + /* istanbul ignore next */ + if (str.length === 0 || str.length == null) return; + this._buf = String(str); + this.ii = -1; + this.char = -1; + let getNext; + + while (getNext === false || this.nextChar()) { + getNext = this.runOne(); } - for (let i = 0; i < value.length; ++i) { - if (i in value) { - stack.push(i, value[i]); // If the callback needs to know the value of i, call - // path.getName(), assuming path is the parameter name. + this._buf = null; + } - callback(this); - stack.length -= 2; - } + nextChar() { + if (this.char === 0x0A) { + ++this.line; + this.col = -1; } - stack.length = length; - } // Similar to FastPath.prototype.each, except that the results of the - // callback function invocations are stored in an array and returned at - // the end of the iteration. + ++this.ii; + this.char = this._buf.codePointAt(this.ii); + ++this.pos; + ++this.col; + return this.haveBuffer(); + } + haveBuffer() { + return this.ii < this._buf.length; + } - map(callback, ...names) { - const { - stack - } = this; - const { - length - } = stack; - let value = getLast(stack); + runOne() { + return this.state.parser.call(this, this.state.returned); + } - for (const name of names) { - value = value[name]; - stack.push(name, value); - } + finish() { + this.char = ParserEND; + let last; - const result = new Array(value.length); + do { + last = this.state.parser; + this.runOne(); + } while (this.state.parser !== last); - for (let i = 0; i < value.length; ++i) { - if (i in value) { - stack.push(i, value[i]); - result[i] = callback(this, i); - stack.length -= 2; - } - } + this.ctx = null; + this.state = null; + this._buf = null; + return this.obj; + } - stack.length = length; - return result; + next(fn) { + /* istanbul ignore next */ + if (typeof fn !== 'function') throw new ParserError('Tried to set state to non-existent state: ' + JSON.stringify(fn)); + this.state.parser = fn; } - /** - * @param {...( - * | ((node: any, name: string | null, number: number | null) => boolean) - * | undefined - * )} predicates - */ + goto(fn) { + this.next(fn); + return this.runOne(); + } - match(...predicates) { - let stackPointer = this.stack.length - 1; - let name = null; - let node = this.stack[stackPointer--]; + call(fn, returnWith) { + if (returnWith) this.next(returnWith); + this.stack.push(this.state); + this.state = new State(fn); + } - for (const predicate of predicates) { - if (node === undefined) { - return false; - } // skip index/array + callNow(fn, returnWith) { + this.call(fn, returnWith); + return this.runOne(); + } + return(value) { + /* istanbul ignore next */ + if (this.stack.length === 0) throw this.error(new ParserError('Stack underflow')); + if (value === undefined) value = this.state.buf; + this.state = this.stack.pop(); + this.state.returned = value; + } - let number = null; + returnNow(value) { + this.return(value); + return this.runOne(); + } - if (typeof name === "number") { - number = name; - name = this.stack[stackPointer--]; - node = this.stack[stackPointer--]; - } + consume() { + /* istanbul ignore next */ + if (this.char === ParserEND) throw this.error(new ParserError('Unexpected end-of-buffer')); + this.state.buf += this._buf[this.ii]; + } - if (predicate && !predicate(node, name, number)) { - return false; - } + error(err) { + err.line = this.line; + err.col = this.col; + err.pos = this.pos; + return err; + } + /* istanbul ignore next */ - name = this.stack[stackPointer--]; - node = this.stack[stackPointer--]; - } - return true; + parseStart() { + throw new ParserError('Must declare a parseStart method'); } } -var fastPath = FastPath; +Parser.END = ParserEND; +Parser.Error = ParserError; +var parser$1 = Parser; -const { - normalize: normalize$2 -} = options$1; +var createDatetime = value => { + const date = new Date(value); + /* istanbul ignore if */ -function printSubtree(path, print, options, printAstToDoc) { - if (options.printer.embed) { - return options.printer.embed(path, print, (text, partialNextOptions) => textToDoc(text, partialNextOptions, options, printAstToDoc), options); + if (isNaN(date)) { + throw new TypeError('Invalid Datetime'); + } else { + return date; } -} +}; -function textToDoc(text, partialNextOptions, parentOptions, printAstToDoc) { - const nextOptions = normalize$2(Object.assign({}, parentOptions, {}, partialNextOptions, { - parentParser: parentOptions.parser, - embeddedInHtml: !!(parentOptions.embeddedInHtml || parentOptions.parser === "html" || parentOptions.parser === "vue" || parentOptions.parser === "angular" || parentOptions.parser === "lwc"), - originalText: text - }), { - passThrough: true - }); - const result = parser.parse(text, nextOptions); - const { - ast - } = result; - text = result.text; - const astComments = ast.comments; - delete ast.comments; - comments.attach(astComments, ast, text, nextOptions); - return printAstToDoc(ast, nextOptions); -} +var formatNum = (d, num) => { + num = String(num); -var multiparser = { - printSubtree -}; + while (num.length < d) num = '0' + num; -const doc = document; -const docBuilders$1 = doc.builders; -const { - concat: concat$3, - hardline: hardline$2, - addAlignmentToDoc: addAlignmentToDoc$1 -} = docBuilders$1; -const docUtils$1 = doc.utils; -/** - * Takes an abstract syntax tree (AST) and recursively converts it to a - * document (series of printing primitives). - * - * This is done by descending down the AST recursively. The recursion - * involves two functions that call each other: - * - * 1. printGenerically(), which is defined as an inner function here. - * It basically takes care of node caching. - * 2. callPluginPrintFunction(), which checks for some options, and - * ultimately calls the print() function provided by the plugin. - * - * The plugin function will call printGenerically() again for child nodes - * of the current node, which will do its housekeeping, then call the - * plugin function again, and so on. - * - * All the while, these functions pass a "path" variable around, which - * is a stack-like data structure (FastPath) that maintains the current - * state of the recursion. It is called "path", because it represents - * the path to the current node through the Abstract Syntax Tree. - */ + return num; +}; -function printAstToDoc(ast, options, alignmentSize = 0) { - const { - printer - } = options; +class FloatingDateTime extends Date { + constructor(value) { + super(value + 'Z'); + this.isFloating = true; + } - if (printer.preprocess) { - ast = printer.preprocess(ast, options); + toISOString() { + const date = `${this.getUTCFullYear()}-${formatNum(2, this.getUTCMonth() + 1)}-${formatNum(2, this.getUTCDate())}`; + const time = `${formatNum(2, this.getUTCHours())}:${formatNum(2, this.getUTCMinutes())}:${formatNum(2, this.getUTCSeconds())}.${formatNum(3, this.getUTCMilliseconds())}`; + return `${date}T${time}`; } - const cache = new Map(); +} - function printGenerically(path, args) { - const node = path.getValue(); - const shouldCache = node && typeof node === "object" && args === undefined; +var createDatetimeFloat = value => { + const date = new FloatingDateTime(value); + /* istanbul ignore if */ - if (shouldCache && cache.has(node)) { - return cache.get(node); - } // We let JSXElement print its comments itself because it adds () around - // UnionTypeAnnotation has to align the child without the comments + if (isNaN(date)) { + throw new TypeError('Invalid Datetime'); + } else { + return date; + } +}; +const DateTime = global.Date; - let res; +class Date$1 extends DateTime { + constructor(value) { + super(value); + this.isDate = true; + } - if (printer.willPrintOwnComments && printer.willPrintOwnComments(path, options)) { - res = callPluginPrintFunction(path, options, printGenerically, args); - } else { - // printComments will call the plugin print function and check for - // comments to print - res = comments.printComments(path, p => callPluginPrintFunction(p, options, printGenerically, args), options, args && args.needsSemi); - } + toISOString() { + return `${this.getUTCFullYear()}-${formatNum(2, this.getUTCMonth() + 1)}-${formatNum(2, this.getUTCDate())}`; + } - if (shouldCache) { - cache.set(node, res); - } +} - return res; +var createDate = value => { + const date = new Date$1(value); + /* istanbul ignore if */ + + if (isNaN(date)) { + throw new TypeError('Invalid Datetime'); + } else { + return date; } +}; - let doc = printGenerically(new fastPath(ast)); +class Time extends Date { + constructor(value) { + super(`0000-01-01T${value}Z`); + this.isTime = true; + } - if (alignmentSize > 0) { - // Add a hardline to make the indents take effect - // It should be removed in index.js format() - doc = addAlignmentToDoc$1(concat$3([hardline$2, doc]), alignmentSize, options.tabWidth); + toISOString() { + return `${formatNum(2, this.getUTCHours())}:${formatNum(2, this.getUTCMinutes())}:${formatNum(2, this.getUTCSeconds())}.${formatNum(3, this.getUTCMilliseconds())}`; } - docUtils$1.propagateBreaks(doc); - return doc; } -function callPluginPrintFunction(path, options, printPath, args) { - assert$1.ok(path instanceof fastPath); - const node = path.getValue(); - const { - printer - } = options; // Escape hatch +var createTime = value => { + const date = new Time(value); + /* istanbul ignore if */ - if (printer.hasPrettierIgnore && printer.hasPrettierIgnore(path)) { - return options.originalText.slice(options.locStart(node), options.locEnd(node)); + if (isNaN(date)) { + throw new TypeError('Invalid Datetime'); + } else { + return date; } +}; - if (node) { - try { - // Potentially switch to a different parser - const sub = multiparser.printSubtree(path, printPath, options, printAstToDoc); +/* eslint-disable no-new-wrappers, no-eval, camelcase, operator-linebreak */ - if (sub) { - return sub; - } - } catch (error) { - /* istanbul ignore if */ - if (process.env.PRETTIER_DEBUG) { - throw error; - } // Continue with current parser - } - } +var tomlParser = makeParserClass(parser$1); +var makeParserClass_1 = makeParserClass; - return printer.print(path, options, printPath, args); -} +class TomlError extends Error { + constructor(msg) { + super(msg); + this.name = 'TomlError'; + /* istanbul ignore next */ -var astToDoc = printAstToDoc; + if (Error.captureStackTrace) Error.captureStackTrace(this, TomlError); + this.fromTOML = true; + this.wrapped = null; + } -function findSiblingAncestors(startNodeAndParents, endNodeAndParents, opts) { - let resultStartNode = startNodeAndParents.node; - let resultEndNode = endNodeAndParents.node; +} - if (resultStartNode === resultEndNode) { - return { - startNode: resultStartNode, - endNode: resultEndNode - }; - } +TomlError.wrap = err => { + const terr = new TomlError(err.message); + terr.code = err.code; + terr.wrapped = err; + return terr; +}; - for (const endParent of endNodeAndParents.parentNodes) { - if (endParent.type !== "Program" && endParent.type !== "File" && opts.locStart(endParent) >= opts.locStart(startNodeAndParents.node)) { - resultEndNode = endParent; - } else { - break; - } - } +var TomlError_1 = TomlError; +const CTRL_I = 0x09; +const CTRL_J = 0x0A; +const CTRL_M = 0x0D; +const CTRL_CHAR_BOUNDARY = 0x1F; // the last non-character in the latin1 region of unicode, except DEL - for (const startParent of startNodeAndParents.parentNodes) { - if (startParent.type !== "Program" && startParent.type !== "File" && opts.locEnd(startParent) <= opts.locEnd(endNodeAndParents.node)) { - resultStartNode = startParent; - } else { - break; - } - } +const CHAR_SP = 0x20; +const CHAR_QUOT = 0x22; +const CHAR_NUM = 0x23; +const CHAR_APOS = 0x27; +const CHAR_PLUS = 0x2B; +const CHAR_COMMA = 0x2C; +const CHAR_HYPHEN = 0x2D; +const CHAR_PERIOD = 0x2E; +const CHAR_0 = 0x30; +const CHAR_1 = 0x31; +const CHAR_7 = 0x37; +const CHAR_9 = 0x39; +const CHAR_COLON = 0x3A; +const CHAR_EQUALS = 0x3D; +const CHAR_A = 0x41; +const CHAR_E = 0x45; +const CHAR_F = 0x46; +const CHAR_T = 0x54; +const CHAR_U = 0x55; +const CHAR_Z = 0x5A; +const CHAR_LOWBAR = 0x5F; +const CHAR_a = 0x61; +const CHAR_b = 0x62; +const CHAR_e = 0x65; +const CHAR_f = 0x66; +const CHAR_i = 0x69; +const CHAR_l = 0x6C; +const CHAR_n = 0x6E; +const CHAR_o = 0x6F; +const CHAR_r = 0x72; +const CHAR_s = 0x73; +const CHAR_t = 0x74; +const CHAR_u = 0x75; +const CHAR_x = 0x78; +const CHAR_z = 0x7A; +const CHAR_LCUB = 0x7B; +const CHAR_RCUB = 0x7D; +const CHAR_LSQB = 0x5B; +const CHAR_BSOL = 0x5C; +const CHAR_RSQB = 0x5D; +const CHAR_DEL = 0x7F; +const SURROGATE_FIRST = 0xD800; +const SURROGATE_LAST = 0xDFFF; +const escapes = { + [CHAR_b]: '\u0008', + [CHAR_t]: '\u0009', + [CHAR_n]: '\u000A', + [CHAR_f]: '\u000C', + [CHAR_r]: '\u000D', + [CHAR_QUOT]: '\u0022', + [CHAR_BSOL]: '\u005C' +}; - return { - startNode: resultStartNode, - endNode: resultEndNode - }; +function isDigit(cp) { + return cp >= CHAR_0 && cp <= CHAR_9; } -function findNodeAtOffset(node, offset, options, predicate, parentNodes) { - predicate = predicate || (() => true); - - parentNodes = parentNodes || []; - const start = options.locStart(node, options.locStart); - const end = options.locEnd(node, options.locEnd); - - if (start <= offset && offset <= end) { - for (const childNode of comments.getSortedChildNodes(node, options)) { - const childResult = findNodeAtOffset(childNode, offset, options, predicate, [node].concat(parentNodes)); - - if (childResult) { - return childResult; - } - } +function isHexit(cp) { + return cp >= CHAR_A && cp <= CHAR_F || cp >= CHAR_a && cp <= CHAR_f || cp >= CHAR_0 && cp <= CHAR_9; +} - if (predicate(node)) { - return { - node, - parentNodes - }; - } - } -} // See https://www.ecma-international.org/ecma-262/5.1/#sec-A.5 +function isBit(cp) { + return cp === CHAR_1 || cp === CHAR_0; +} +function isOctit(cp) { + return cp >= CHAR_0 && cp <= CHAR_7; +} -function isSourceElement(opts, node) { - if (node == null) { - return false; - } // JS and JS like to avoid repetitions - - - const jsSourceElements = ["FunctionDeclaration", "BlockStatement", "BreakStatement", "ContinueStatement", "DebuggerStatement", "DoWhileStatement", "EmptyStatement", "ExpressionStatement", "ForInStatement", "ForStatement", "IfStatement", "LabeledStatement", "ReturnStatement", "SwitchStatement", "ThrowStatement", "TryStatement", "VariableDeclaration", "WhileStatement", "WithStatement", "ClassDeclaration", // ES 2015 - "ImportDeclaration", // Module - "ExportDefaultDeclaration", // Module - "ExportNamedDeclaration", // Module - "ExportAllDeclaration", // Module - "TypeAlias", // Flow - "InterfaceDeclaration", // Flow, TypeScript - "TypeAliasDeclaration", // TypeScript - "ExportAssignment", // TypeScript - "ExportDeclaration" // TypeScript - ]; - const jsonSourceElements = ["ObjectExpression", "ArrayExpression", "StringLiteral", "NumericLiteral", "BooleanLiteral", "NullLiteral"]; - const graphqlSourceElements = ["OperationDefinition", "FragmentDefinition", "VariableDefinition", "TypeExtensionDefinition", "ObjectTypeDefinition", "FieldDefinition", "DirectiveDefinition", "EnumTypeDefinition", "EnumValueDefinition", "InputValueDefinition", "InputObjectTypeDefinition", "SchemaDefinition", "OperationTypeDefinition", "InterfaceTypeDefinition", "UnionTypeDefinition", "ScalarTypeDefinition"]; +function isAlphaNumQuoteHyphen(cp) { + return cp >= CHAR_A && cp <= CHAR_Z || cp >= CHAR_a && cp <= CHAR_z || cp >= CHAR_0 && cp <= CHAR_9 || cp === CHAR_APOS || cp === CHAR_QUOT || cp === CHAR_LOWBAR || cp === CHAR_HYPHEN; +} - switch (opts.parser) { - case "flow": - case "babel": - case "babel-flow": - case "babel-ts": - case "typescript": - return jsSourceElements.includes(node.type); +function isAlphaNumHyphen(cp) { + return cp >= CHAR_A && cp <= CHAR_Z || cp >= CHAR_a && cp <= CHAR_z || cp >= CHAR_0 && cp <= CHAR_9 || cp === CHAR_LOWBAR || cp === CHAR_HYPHEN; +} - case "json": - return jsonSourceElements.includes(node.type); +const _type = Symbol('type'); - case "graphql": - return graphqlSourceElements.includes(node.kind); +const _declared = Symbol('declared'); - case "vue": - return node.tag !== "root"; - } +const hasOwnProperty$2 = Object.prototype.hasOwnProperty; +const defineProperty = Object.defineProperty; +const descriptor = { + configurable: true, + enumerable: true, + writable: true, + value: undefined +}; +function hasKey(obj, key) { + if (hasOwnProperty$2.call(obj, key)) return true; + if (key === '__proto__') defineProperty(obj, '__proto__', descriptor); return false; } -function calculateRange(text, opts, ast) { - // Contract the range so that it has non-whitespace characters at its endpoints. - // This ensures we can format a range that doesn't end on a node. - const rangeStringOrig = text.slice(opts.rangeStart, opts.rangeEnd); - const startNonWhitespace = Math.max(opts.rangeStart + rangeStringOrig.search(/\S/), opts.rangeStart); - let endNonWhitespace; +const INLINE_TABLE = Symbol('inline-table'); - for (endNonWhitespace = opts.rangeEnd; endNonWhitespace > opts.rangeStart; --endNonWhitespace) { - if (text[endNonWhitespace - 1].match(/\S/)) { - break; +function InlineTable() { + return Object.defineProperties({}, { + [_type]: { + value: INLINE_TABLE } - } + }); +} - const startNodeAndParents = findNodeAtOffset(ast, startNonWhitespace, opts, node => isSourceElement(opts, node)); - const endNodeAndParents = findNodeAtOffset(ast, endNonWhitespace, opts, node => isSourceElement(opts, node)); +function isInlineTable(obj) { + if (obj === null || typeof obj !== 'object') return false; + return obj[_type] === INLINE_TABLE; +} - if (!startNodeAndParents || !endNodeAndParents) { - return { - rangeStart: 0, - rangeEnd: 0 - }; - } +const TABLE = Symbol('table'); - const siblingAncestors = findSiblingAncestors(startNodeAndParents, endNodeAndParents, opts); - const { - startNode, - endNode - } = siblingAncestors; - const rangeStart = Math.min(opts.locStart(startNode, opts.locStart), opts.locStart(endNode, opts.locStart)); - const rangeEnd = Math.max(opts.locEnd(startNode, opts.locEnd), opts.locEnd(endNode, opts.locEnd)); - return { - rangeStart, - rangeEnd - }; +function Table() { + return Object.defineProperties({}, { + [_type]: { + value: TABLE + }, + [_declared]: { + value: false, + writable: true + } + }); } -var rangeUtil = { - calculateRange, - findNodeAtOffset -}; +function isTable(obj) { + if (obj === null || typeof obj !== 'object') return false; + return obj[_type] === TABLE; +} -const normalizeOptions$1 = options$1.normalize; -const { - guessEndOfLine: guessEndOfLine$1, - convertEndOfLineToChars: convertEndOfLineToChars$2 -} = endOfLine; -const { - printer: { - printDocToString: printDocToString$1 - }, - debug: { - printDocToDebug - } -} = document; -const BOM = "\uFEFF"; -const CURSOR = Symbol("cursor"); -const PLACEHOLDERS = { - cursorOffset: "<<>>", - rangeStart: "<<>>", - rangeEnd: "<<>>" -}; +const _contentType = Symbol('content-type'); -function ensureAllCommentsPrinted(astComments) { - if (!astComments) { - return; - } +const INLINE_LIST = Symbol('inline-list'); - for (let i = 0; i < astComments.length; ++i) { - if (util$1.isNodeIgnoreComment(astComments[i])) { - // If there's a prettier-ignore, we're not printing that sub-tree so we - // don't know if the comments was printed or not. - return; +function InlineList(type) { + return Object.defineProperties([], { + [_type]: { + value: INLINE_LIST + }, + [_contentType]: { + value: type } - } + }); +} - astComments.forEach(comment => { - if (!comment.printed) { - throw new Error('Comment "' + comment.value.trim() + '" was not printed. Please report this error!'); - } +function isInlineList(obj) { + if (obj === null || typeof obj !== 'object') return false; + return obj[_type] === INLINE_LIST; +} - delete comment.printed; +const LIST = Symbol('list'); + +function List() { + return Object.defineProperties([], { + [_type]: { + value: LIST + } }); } -function attachComments(text, ast, opts) { - const astComments = ast.comments; +function isList(obj) { + if (obj === null || typeof obj !== 'object') return false; + return obj[_type] === LIST; +} // in an eval, to let bundlers not slurp in a util proxy - if (astComments) { - delete ast.comments; - comments.attach(astComments, ast, text, opts); - } - ast.tokens = []; - opts.originalText = opts.parser === "yaml" ? text : text.trimEnd(); - return astComments; -} +let _custom; -function coreFormat(text, opts, addAlignmentSize) { - if (!text || !text.trim().length) { - return { - formatted: "", - cursorOffset: 0 - }; - } +try { + const utilInspect = util__default['default'].inspect; + _custom = utilInspect.custom; +} catch (_) { + /* eval require not available in transpiled bundle */ +} +/* istanbul ignore next */ - addAlignmentSize = addAlignmentSize || 0; - const parsed = parser.parse(text, opts); - const { - ast - } = parsed; - text = parsed.text; - if (opts.cursorOffset >= 0) { - const nodeResult = rangeUtil.findNodeAtOffset(ast, opts.cursorOffset, opts); +const _inspect = _custom || 'inspect'; - if (nodeResult && nodeResult.node) { - opts.cursorNode = nodeResult.node; +class BoxedBigInt { + constructor(value) { + try { + this.value = global.BigInt.asIntN(64, value); + } catch (_) { + /* istanbul ignore next */ + this.value = null; } + + Object.defineProperty(this, _type, { + value: INTEGER + }); } - const astComments = attachComments(text, ast, opts); - const doc = astToDoc(ast, opts, addAlignmentSize); - const result = printDocToString$1(doc, opts); - ensureAllCommentsPrinted(astComments); // Remove extra leading indentation as well as the added indentation after last newline + isNaN() { + return this.value === null; + } + /* istanbul ignore next */ - if (addAlignmentSize > 0) { - const trimmed = result.formatted.trim(); - if (result.cursorNodeStart !== undefined) { - result.cursorNodeStart -= result.formatted.indexOf(trimmed); - } + toString() { + return String(this.value); + } + /* istanbul ignore next */ - result.formatted = trimmed + convertEndOfLineToChars$2(opts.endOfLine); + + [_inspect]() { + return `[BigInt: ${this.toString()}]}`; } - if (opts.cursorOffset >= 0) { - let oldCursorNodeStart; - let oldCursorNodeText; - let cursorOffsetRelativeToOldCursorNode; - let newCursorNodeStart; - let newCursorNodeText; + valueOf() { + return this.value; + } - if (opts.cursorNode && result.cursorNodeText) { - oldCursorNodeStart = opts.locStart(opts.cursorNode); - oldCursorNodeText = text.slice(oldCursorNodeStart, opts.locEnd(opts.cursorNode)); - cursorOffsetRelativeToOldCursorNode = opts.cursorOffset - oldCursorNodeStart; - newCursorNodeStart = result.cursorNodeStart; - newCursorNodeText = result.cursorNodeText; - } else { - oldCursorNodeStart = 0; - oldCursorNodeText = text; - cursorOffsetRelativeToOldCursorNode = opts.cursorOffset; - newCursorNodeStart = 0; - newCursorNodeText = result.formatted; - } +} - if (oldCursorNodeText === newCursorNodeText) { - return { - formatted: result.formatted, - cursorOffset: newCursorNodeStart + cursorOffsetRelativeToOldCursorNode - }; - } // diff old and new cursor node texts, with a special cursor - // symbol inserted to find out where it moves to +const INTEGER = Symbol('integer'); +function Integer(value) { + let num = Number(value); // -0 is a float thing, not an int thing - const oldCursorNodeCharArray = oldCursorNodeText.split(""); - oldCursorNodeCharArray.splice(cursorOffsetRelativeToOldCursorNode, 0, CURSOR); - const newCursorNodeCharArray = newCursorNodeText.split(""); - const cursorNodeDiff = index_es6.diffArrays(oldCursorNodeCharArray, newCursorNodeCharArray); - let cursorOffset = newCursorNodeStart; + if (Object.is(num, -0)) num = 0; + /* istanbul ignore else */ - for (const entry of cursorNodeDiff) { - if (entry.removed) { - if (entry.value.includes(CURSOR)) { - break; + if (global.BigInt && !Number.isSafeInteger(num)) { + return new BoxedBigInt(value); + } else { + /* istanbul ignore next */ + return Object.defineProperties(new Number(num), { + isNaN: { + value: function () { + return isNaN(this); } - } else { - cursorOffset += entry.count; + }, + [_type]: { + value: INTEGER + }, + [_inspect]: { + value: () => `[Integer: ${value}]` } - } - - return { - formatted: result.formatted, - cursorOffset - }; + }); } +} - return { - formatted: result.formatted - }; +function isInteger(obj) { + if (obj === null || typeof obj !== 'object') return false; + return obj[_type] === INTEGER; } -function formatRange(text, opts) { - const parsed = parser.parse(text, opts); - const { - ast - } = parsed; - text = parsed.text; - const range = rangeUtil.calculateRange(text, opts, ast); - const { - rangeStart, - rangeEnd - } = range; - const rangeString = text.slice(rangeStart, rangeEnd); // Try to extend the range backwards to the beginning of the line. - // This is so we can detect indentation correctly and restore it. - // Use `Math.min` since `lastIndexOf` returns 0 when `rangeStart` is 0 +const FLOAT = Symbol('float'); - const rangeStart2 = Math.min(rangeStart, text.lastIndexOf("\n", rangeStart) + 1); - const indentString = text.slice(rangeStart2, rangeStart); - const alignmentSize = util$1.getAlignmentSize(indentString, opts.tabWidth); - const rangeResult = coreFormat(rangeString, Object.assign({}, opts, { - rangeStart: 0, - rangeEnd: Infinity, - // track the cursor offset only if it's within our range - cursorOffset: opts.cursorOffset >= rangeStart && opts.cursorOffset < rangeEnd ? opts.cursorOffset - rangeStart : -1 - }), alignmentSize); // Since the range contracts to avoid trailing whitespace, - // we need to remove the newline that was inserted by the `format` call. +function Float(value) { + /* istanbul ignore next */ + return Object.defineProperties(new Number(value), { + [_type]: { + value: FLOAT + }, + [_inspect]: { + value: () => `[Float: ${value}]` + } + }); +} - const rangeTrimmed = rangeResult.formatted.trimEnd(); - const rangeLeft = text.slice(0, rangeStart); - const rangeRight = text.slice(rangeEnd); - let { - cursorOffset - } = opts; +function isFloat(obj) { + if (obj === null || typeof obj !== 'object') return false; + return obj[_type] === FLOAT; +} - if (opts.cursorOffset >= rangeEnd) { - // handle the case where the cursor was past the end of the range - cursorOffset = opts.cursorOffset - rangeEnd + (rangeStart + rangeTrimmed.length); - } else if (rangeResult.cursorOffset !== undefined) { - // handle the case where the cursor was in the range - cursorOffset = rangeResult.cursorOffset + rangeStart; - } // keep the cursor as it was if it was before the start of the range +function tomlType(value) { + const type = typeof value; + if (type === 'object') { + /* istanbul ignore if */ + if (value === null) return 'null'; + if (value instanceof Date) return 'datetime'; + /* istanbul ignore else */ - let formatted; + if (_type in value) { + switch (value[_type]) { + case INLINE_TABLE: + return 'inline-table'; - if (opts.endOfLine === "lf") { - formatted = rangeLeft + rangeTrimmed + rangeRight; - } else { - const eol = convertEndOfLineToChars$2(opts.endOfLine); + case INLINE_LIST: + return 'inline-list'; - if (cursorOffset >= 0) { - const parts = [rangeLeft, rangeTrimmed, rangeRight]; - let partIndex = 0; - let partOffset = cursorOffset; + /* istanbul ignore next */ - while (partIndex < parts.length) { - const part = parts[partIndex]; + case TABLE: + return 'table'; - if (partOffset < part.length) { - parts[partIndex] = parts[partIndex].slice(0, partOffset) + PLACEHOLDERS.cursorOffset + parts[partIndex].slice(partOffset); - break; - } + /* istanbul ignore next */ - partIndex++; - partOffset -= part.length; - } + case LIST: + return 'list'; - const [newRangeLeft, newRangeTrimmed, newRangeRight] = parts; - formatted = (newRangeLeft.replace(/\n/g, eol) + newRangeTrimmed + newRangeRight.replace(/\n/g, eol)).replace(PLACEHOLDERS.cursorOffset, (_, index) => { - cursorOffset = index; - return ""; - }); - } else { - formatted = rangeLeft.replace(/\n/g, eol) + rangeTrimmed + rangeRight.replace(/\n/g, eol); + case FLOAT: + return 'float'; + + case INTEGER: + return 'integer'; + } } } - return { - formatted, - cursorOffset - }; + return type; } -function format(text, opts) { - const selectedParser = parser.resolveParser(opts); - const hasPragma = !selectedParser.hasPragma || selectedParser.hasPragma(text); - - if (opts.requirePragma && !hasPragma) { - return { - formatted: text - }; - } - - if (opts.endOfLine === "auto") { - opts.endOfLine = guessEndOfLine$1(text); - } - - const hasCursor = opts.cursorOffset >= 0; - const hasRangeStart = opts.rangeStart > 0; - const hasRangeEnd = opts.rangeEnd < text.length; // get rid of CR/CRLF parsing +function makeParserClass(Parser) { + class TOMLParser extends Parser { + constructor() { + super(); + this.ctx = this.obj = Table(); + } + /* MATCH HELPER */ - if (text.includes("\r")) { - const offsetKeys = [hasCursor && "cursorOffset", hasRangeStart && "rangeStart", hasRangeEnd && "rangeEnd"].filter(Boolean).sort((aKey, bKey) => opts[aKey] - opts[bKey]); - for (let i = offsetKeys.length - 1; i >= 0; i--) { - const key = offsetKeys[i]; - text = text.slice(0, opts[key]) + PLACEHOLDERS[key] + text.slice(opts[key]); + atEndOfWord() { + return this.char === CHAR_NUM || this.char === CTRL_I || this.char === CHAR_SP || this.atEndOfLine(); } - text = text.replace(/\r\n?/g, "\n"); - - for (let i = 0; i < offsetKeys.length; i++) { - const key = offsetKeys[i]; - text = text.replace(PLACEHOLDERS[key], (_, index) => { - opts[key] = index; - return ""; - }); + atEndOfLine() { + return this.char === Parser.END || this.char === CTRL_J || this.char === CTRL_M; } - } - const hasUnicodeBOM = text.charAt(0) === BOM; + parseStart() { + if (this.char === Parser.END) { + return null; + } else if (this.char === CHAR_LSQB) { + return this.call(this.parseTableOrList); + } else if (this.char === CHAR_NUM) { + return this.call(this.parseComment); + } else if (this.char === CTRL_J || this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M) { + return null; + } else if (isAlphaNumQuoteHyphen(this.char)) { + return this.callNow(this.parseAssignStatement); + } else { + throw this.error(new TomlError(`Unknown character "${this.char}"`)); + } + } // HELPER, this strips any whitespace and comments to the end of the line + // then RETURNS. Last state in a production. - if (hasUnicodeBOM) { - text = text.slice(1); - if (hasCursor) { - opts.cursorOffset++; + parseWhitespaceToEOL() { + if (this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M) { + return null; + } else if (this.char === CHAR_NUM) { + return this.goto(this.parseComment); + } else if (this.char === Parser.END || this.char === CTRL_J) { + return this.return(); + } else { + throw this.error(new TomlError('Unexpected character, expected only whitespace or comments till end of line')); + } } + /* ASSIGNMENT: key = value */ - if (hasRangeStart) { - opts.rangeStart++; - } - if (hasRangeEnd) { - opts.rangeEnd++; + parseAssignStatement() { + return this.callNow(this.parseAssign, this.recordAssignStatement); } - } - if (!hasCursor) { - opts.cursorOffset = -1; - } + recordAssignStatement(kv) { + let target = this.ctx; + let finalKey = kv.key.pop(); - if (opts.rangeStart < 0) { - opts.rangeStart = 0; - } + for (let kw of kv.key) { + if (hasKey(target, kw) && (!isTable(target[kw]) || target[kw][_declared])) { + throw this.error(new TomlError("Can't redefine existing key")); + } - if (opts.rangeEnd > text.length) { - opts.rangeEnd = text.length; - } + target = target[kw] = target[kw] || Table(); + } - const result = hasRangeStart || hasRangeEnd ? formatRange(text, opts) : coreFormat(opts.insertPragma && opts.printer.insertPragma && !hasPragma ? opts.printer.insertPragma(text) : text, opts); + if (hasKey(target, finalKey)) { + throw this.error(new TomlError("Can't redefine existing key")); + } // unbox our numbers - if (hasUnicodeBOM) { - result.formatted = BOM + result.formatted; - if (hasCursor) { - result.cursorOffset++; + if (isInteger(kv.value) || isFloat(kv.value)) { + target[finalKey] = kv.value.valueOf(); + } else { + target[finalKey] = kv.value; + } + + return this.goto(this.parseWhitespaceToEOL); } - } + /* ASSSIGNMENT expression, key = value possibly inside an inline table */ - return result; -} -var core = { - formatWithCursor(text, opts) { - opts = normalizeOptions$1(opts); - return format(text, opts); - }, + parseAssign() { + return this.callNow(this.parseKeyword, this.recordAssignKeyword); + } - parse(text, opts, massage) { - opts = normalizeOptions$1(opts); + recordAssignKeyword(key) { + if (this.state.resultTable) { + this.state.resultTable.push(key); + } else { + this.state.resultTable = [key]; + } - if (text.includes("\r")) { - text = text.replace(/\r\n?/g, "\n"); + return this.goto(this.parseAssignKeywordPreDot); } - const parsed = parser.parse(text, opts); - - if (massage) { - parsed.ast = massageAst(parsed.ast, opts); + parseAssignKeywordPreDot() { + if (this.char === CHAR_PERIOD) { + return this.next(this.parseAssignKeywordPostDot); + } else if (this.char !== CHAR_SP && this.char !== CTRL_I) { + return this.goto(this.parseAssignEqual); + } } - return parsed; - }, + parseAssignKeywordPostDot() { + if (this.char !== CHAR_SP && this.char !== CTRL_I) { + return this.callNow(this.parseKeyword, this.recordAssignKeyword); + } + } - formatAST(ast, opts) { - opts = normalizeOptions$1(opts); - const doc = astToDoc(ast, opts); - return printDocToString$1(doc, opts); - }, + parseAssignEqual() { + if (this.char === CHAR_EQUALS) { + return this.next(this.parseAssignPreValue); + } else { + throw this.error(new TomlError('Invalid character, expected "="')); + } + } - // Doesn't handle shebang for now - formatDoc(doc, opts) { - const debug = printDocToDebug(doc); - opts = normalizeOptions$1(Object.assign({}, opts, { - parser: "babel" - })); - return format(debug, opts).formatted; - }, + parseAssignPreValue() { + if (this.char === CHAR_SP || this.char === CTRL_I) { + return null; + } else { + return this.callNow(this.parseValue, this.recordAssignValue); + } + } - printToDoc(text, opts) { - opts = normalizeOptions$1(opts); - const parsed = parser.parse(text, opts); - const { - ast - } = parsed; - text = parsed.text; - attachComments(text, ast, opts); - return astToDoc(ast, opts); - }, + recordAssignValue(value) { + return this.returnNow({ + key: this.state.resultTable, + value: value + }); + } + /* COMMENTS: #...eol */ - printDocToString(doc, opts) { - return printDocToString$1(doc, normalizeOptions$1(opts)); - } -}; + parseComment() { + do { + if (this.char === Parser.END || this.char === CTRL_J) { + return this.return(); + } + } while (this.nextChar()); + } + /* TABLES AND LISTS, [foo] and [[foo]] */ -// A simple implementation of make-array -function make_array(subject) { - return Array.isArray(subject) ? subject : [subject]; -} -const REGEX_BLANK_LINE = /^\s+$/; -const REGEX_LEADING_EXCAPED_EXCLAMATION = /^\\!/; -const REGEX_LEADING_EXCAPED_HASH = /^\\#/; -const SLASH = '/'; -const KEY_IGNORE = typeof Symbol !== 'undefined' ? Symbol.for('node-ignore') -/* istanbul ignore next */ -: 'node-ignore'; + parseTableOrList() { + if (this.char === CHAR_LSQB) { + this.next(this.parseList); + } else { + return this.goto(this.parseTable); + } + } + /* TABLE [foo.bar.baz] */ -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 + parseTable() { + this.ctx = this.obj; + return this.goto(this.parseTableNext); + } -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. -: ''); // > 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 '`..`' + parseTableNext() { + if (this.char === CHAR_SP || this.char === CTRL_I) { + return null; + } else { + return this.callNow(this.parseKeyword, this.parseTableMore); + } + } + parseTableMore(keyword) { + if (this.char === CHAR_SP || this.char === CTRL_I) { + return null; + } else if (this.char === CHAR_RSQB) { + if (hasKey(this.ctx, keyword) && (!isTable(this.ctx[keyword]) || this.ctx[keyword][_declared])) { + throw this.error(new TomlError("Can't redefine existing key")); + } else { + this.ctx = this.ctx[keyword] = this.ctx[keyword] || Table(); + this.ctx[_declared] = true; + } -const DEFAULT_REPLACER_PREFIX = [// > Trailing spaces are ignored unless they are quoted with backslash ("\") -[// (a\ ) -> (a ) -// (a ) -> (a) -// (a \ ) -> (a ) -/\\?\s+$/, match => match.indexOf('\\') === 0 ? ' ' : ''], // replace (\ ) with ' ' -[/\\\s/g, () => ' '], // 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}`], [// > [abc] matches any character inside the brackets -// > (in this case a, b, or c); -/\[([^\]/]*)($|\])/g, (match, p1, p2) => p2 === ']' ? `[${sanitizeRange(p1)}]` : `\\${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' -() => '^(?:.*\\/)?']]; -const DEFAULT_REPLACER_SUFFIX = [// 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() { - return !/\/(?!$)/.test(this) // > 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 - ? '(?:^|\\/)' // > 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 `'/**'` -(match, 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' -(match, p1) => `${p1}[^\\/]*`], // trailing wildcard -[/(\^|\\\/)?\\\*$/, (match, p1) => { - const prefix = p1 // '\^': - // '/*' does not match '' - // '/*' does not match everything - // '\\\/': - // 'abc/*' does not match 'abc/' - ? `${p1}[^/]+` // 'a*' matches 'a' - // 'a*' matches 'aa' - : '[^/]*'; - return `${prefix}(?=$|\\/$)`; -}], [// unescape -/\\\\\\/g, () => '\\']]; -const POSITIVE_REPLACERS = [...DEFAULT_REPLACER_PREFIX, // 'f' -// matches -// - /f(end) -// - /f/ -// - (start)f(end) -// - (start)f/ -// doesn't match -// - oof -// - foo -// pseudo: -// -> (^|/)f(/|$) -// ending -[// 'js' will not match 'js.' -// 'ab' will not match 'abc' -/(?:[^*/])$/, // 'js*' will not match 'a.js' -// 'js/' will not match 'a.js' -// 'js' will match 'a.js' and 'a.js/' -match => `${match}(?=$|\\/)`], ...DEFAULT_REPLACER_SUFFIX]; -const NEGATIVE_REPLACERS = [...DEFAULT_REPLACER_PREFIX, // #24, #38 -// The MISSING rule of [gitignore docs](https://git-scm.com/docs/gitignore) -// A negative pattern without a trailing wildcard should not -// re-include the things inside that directory. -// eg: -// ['node_modules/*', '!node_modules'] -// should ignore `node_modules/a.js` -[/(?:[^*])$/, match => `${match}(?=$|\\/$)`], ...DEFAULT_REPLACER_SUFFIX]; // A simple cache, because an ignore rule only has only one certain meaning + return this.next(this.parseWhitespaceToEOL); + } else if (this.char === CHAR_PERIOD) { + if (!hasKey(this.ctx, keyword)) { + this.ctx = this.ctx[keyword] = Table(); + } else if (isTable(this.ctx[keyword])) { + this.ctx = this.ctx[keyword]; + } else if (isList(this.ctx[keyword])) { + this.ctx = this.ctx[keyword][this.ctx[keyword].length - 1]; + } else { + throw this.error(new TomlError("Can't redefine existing key")); + } -const cache = Object.create(null); // @param {pattern} + return this.next(this.parseTableNext); + } else { + throw this.error(new TomlError('Unexpected character, expected whitespace, . or ]')); + } + } + /* LIST [[a.b.c]] */ -const make_regex = (pattern, negative, ignorecase) => { - const r = cache[pattern]; - if (r) { - return r; - } + parseList() { + this.ctx = this.obj; + return this.goto(this.parseListNext); + } - const replacers = negative ? NEGATIVE_REPLACERS : POSITIVE_REPLACERS; - const source = replacers.reduce((prev, current) => prev.replace(current[0], current[1].bind(pattern)), pattern); - return cache[pattern] = ignorecase ? new RegExp(source, 'i') : new RegExp(source); -}; // > A blank line matches no files, so it can serve as a separator for readability. + parseListNext() { + if (this.char === CHAR_SP || this.char === CTRL_I) { + return null; + } else { + return this.callNow(this.parseKeyword, this.parseListMore); + } + } + parseListMore(keyword) { + if (this.char === CHAR_SP || this.char === CTRL_I) { + return null; + } else if (this.char === CHAR_RSQB) { + if (!hasKey(this.ctx, keyword)) { + this.ctx[keyword] = List(); + } -const checkPattern = pattern => pattern && typeof pattern === 'string' && !REGEX_BLANK_LINE.test(pattern) // > A line starting with # serves as a comment. -&& pattern.indexOf('#') !== 0; + if (isInlineList(this.ctx[keyword])) { + throw this.error(new TomlError("Can't extend an inline array")); + } else if (isList(this.ctx[keyword])) { + const next = Table(); + this.ctx[keyword].push(next); + this.ctx = next; + } else { + throw this.error(new TomlError("Can't redefine an existing key")); + } -const createRule = (pattern, ignorecase) => { - const origin = pattern; - let negative = false; // > An optional prefix "!" which negates the pattern; + return this.next(this.parseListEnd); + } else if (this.char === CHAR_PERIOD) { + if (!hasKey(this.ctx, keyword)) { + this.ctx = this.ctx[keyword] = Table(); + } else if (isInlineList(this.ctx[keyword])) { + throw this.error(new TomlError("Can't extend an inline array")); + } else if (isInlineTable(this.ctx[keyword])) { + throw this.error(new TomlError("Can't extend an inline table")); + } else if (isList(this.ctx[keyword])) { + this.ctx = this.ctx[keyword][this.ctx[keyword].length - 1]; + } else if (isTable(this.ctx[keyword])) { + this.ctx = this.ctx[keyword]; + } else { + throw this.error(new TomlError("Can't redefine an existing key")); + } - if (pattern.indexOf('!') === 0) { - negative = true; - pattern = pattern.substr(1); - } + return this.next(this.parseListNext); + } else { + throw this.error(new TomlError('Unexpected character, expected whitespace, . or ]')); + } + } - pattern = pattern // > Put a backslash ("\") in front of the first "!" for patterns that - // > begin with a literal "!", for example, `"\!important!.txt"`. - .replace(REGEX_LEADING_EXCAPED_EXCLAMATION, '!') // > Put a backslash ("\") in front of the first hash for patterns that - // > begin with a hash. - .replace(REGEX_LEADING_EXCAPED_HASH, '#'); - const regex = make_regex(pattern, negative, ignorecase); - return { - origin, - pattern, - negative, - regex - }; -}; + parseListEnd(keyword) { + if (this.char === CHAR_RSQB) { + return this.next(this.parseWhitespaceToEOL); + } else { + throw this.error(new TomlError('Unexpected character, expected whitespace, . or ]')); + } + } + /* VALUE string, number, boolean, inline list, inline object */ -class IgnoreBase { - constructor({ - ignorecase = true - } = {}) { - this._rules = []; - this._ignorecase = ignorecase; - define(this, KEY_IGNORE, true); - this._initCache(); - } + parseValue() { + if (this.char === Parser.END) { + throw this.error(new TomlError('Key without value')); + } else if (this.char === CHAR_QUOT) { + return this.next(this.parseDoubleString); + } - _initCache() { - this._cache = Object.create(null); - } // @param {Array.|string|Ignore} pattern + if (this.char === CHAR_APOS) { + return this.next(this.parseSingleString); + } else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) { + return this.goto(this.parseNumberSign); + } else if (this.char === CHAR_i) { + return this.next(this.parseInf); + } else if (this.char === CHAR_n) { + return this.next(this.parseNan); + } else if (isDigit(this.char)) { + return this.goto(this.parseNumberOrDateTime); + } else if (this.char === CHAR_t || this.char === CHAR_f) { + return this.goto(this.parseBoolean); + } else if (this.char === CHAR_LSQB) { + return this.call(this.parseInlineList, this.recordValue); + } else if (this.char === CHAR_LCUB) { + return this.call(this.parseInlineTable, this.recordValue); + } else { + throw this.error(new TomlError('Unexpected character, expecting string, number, datetime, boolean, inline array or inline table')); + } + } + recordValue(value) { + return this.returnNow(value); + } - add(pattern) { - this._added = false; + parseInf() { + if (this.char === CHAR_n) { + return this.next(this.parseInf2); + } else { + throw this.error(new TomlError('Unexpected character, expected "inf", "+inf" or "-inf"')); + } + } - if (typeof pattern === 'string') { - pattern = pattern.split(/\r?\n/g); + parseInf2() { + if (this.char === CHAR_f) { + if (this.state.buf === '-') { + return this.return(-Infinity); + } else { + return this.return(Infinity); + } + } else { + throw this.error(new TomlError('Unexpected character, expected "inf", "+inf" or "-inf"')); + } } - make_array(pattern).forEach(this._addPattern, this); // Some rules have just added to the ignore, - // making the behavior changed. + parseNan() { + if (this.char === CHAR_a) { + return this.next(this.parseNan2); + } else { + throw this.error(new TomlError('Unexpected character, expected "nan"')); + } + } - if (this._added) { - this._initCache(); + parseNan2() { + if (this.char === CHAR_n) { + return this.return(NaN); + } else { + throw this.error(new TomlError('Unexpected character, expected "nan"')); + } } + /* KEYS, barewords or basic, literal, or dotted */ - return this; - } // legacy + parseKeyword() { + if (this.char === CHAR_QUOT) { + return this.next(this.parseBasicString); + } else if (this.char === CHAR_APOS) { + return this.next(this.parseLiteralString); + } else { + return this.goto(this.parseBareKey); + } + } + /* KEYS: barewords */ - addPattern(pattern) { - return this.add(pattern); - } - _addPattern(pattern) { - // #32 - if (pattern && pattern[KEY_IGNORE]) { - this._rules = this._rules.concat(pattern._rules); - this._added = true; - return; + parseBareKey() { + do { + if (this.char === Parser.END) { + throw this.error(new TomlError('Key ended without value')); + } else if (isAlphaNumHyphen(this.char)) { + this.consume(); + } else if (this.state.buf.length === 0) { + throw this.error(new TomlError('Empty bare keys are not allowed')); + } else { + return this.returnNow(); + } + } while (this.nextChar()); } + /* STRINGS, single quoted (literal) */ - if (checkPattern(pattern)) { - const rule = createRule(pattern, this._ignorecase); - this._added = true; - this._rules.push(rule); + parseSingleString() { + if (this.char === CHAR_APOS) { + return this.next(this.parseLiteralMultiStringMaybe); + } else { + return this.goto(this.parseLiteralString); + } } - } - - filter(paths) { - return make_array(paths).filter(path => this._filter(path)); - } - createFilter() { - return path => this._filter(path); - } + parseLiteralString() { + do { + if (this.char === CHAR_APOS) { + return this.return(); + } else if (this.atEndOfLine()) { + throw this.error(new TomlError('Unterminated string')); + } else if (this.char === CHAR_DEL || this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I) { + throw this.errorControlCharInString(); + } else { + this.consume(); + } + } while (this.nextChar()); + } - ignores(path) { - return !this._filter(path); - } // @returns `Boolean` true if the `path` is NOT ignored + parseLiteralMultiStringMaybe() { + if (this.char === CHAR_APOS) { + return this.next(this.parseLiteralMultiString); + } else { + return this.returnNow(); + } + } + parseLiteralMultiString() { + if (this.char === CTRL_M) { + return null; + } else if (this.char === CTRL_J) { + return this.next(this.parseLiteralMultiStringContent); + } else { + return this.goto(this.parseLiteralMultiStringContent); + } + } - _filter(path, slices) { - if (!path) { - return false; + parseLiteralMultiStringContent() { + do { + if (this.char === CHAR_APOS) { + return this.next(this.parseLiteralMultiEnd); + } else if (this.char === Parser.END) { + throw this.error(new TomlError('Unterminated multi-line string')); + } else if (this.char === CHAR_DEL || this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I && this.char !== CTRL_J && this.char !== CTRL_M) { + throw this.errorControlCharInString(); + } else { + this.consume(); + } + } while (this.nextChar()); } - if (path in this._cache) { - return this._cache[path]; + parseLiteralMultiEnd() { + if (this.char === CHAR_APOS) { + return this.next(this.parseLiteralMultiEnd2); + } else { + this.state.buf += "'"; + return this.goto(this.parseLiteralMultiStringContent); + } } - if (!slices) { - // path/to/a.js - // ['path', 'to', 'a.js'] - slices = path.split(SLASH); + parseLiteralMultiEnd2() { + if (this.char === CHAR_APOS) { + return this.return(); + } else { + this.state.buf += "''"; + return this.goto(this.parseLiteralMultiStringContent); + } } + /* STRINGS double quoted */ - slices.pop(); - return this._cache[path] = slices.length // > It is not possible to re-include a file if a parent directory of - // > that file is excluded. - // If the path contains a parent directory, check the parent first - ? this._filter(slices.join(SLASH) + SLASH, slices) && this._test(path) // Or only test the path - : this._test(path); - } // @returns {Boolean} true if a file is NOT ignored + parseDoubleString() { + if (this.char === CHAR_QUOT) { + return this.next(this.parseMultiStringMaybe); + } else { + return this.goto(this.parseBasicString); + } + } + + parseBasicString() { + do { + if (this.char === CHAR_BSOL) { + return this.call(this.parseEscape, this.recordEscapeReplacement); + } else if (this.char === CHAR_QUOT) { + return this.return(); + } else if (this.atEndOfLine()) { + throw this.error(new TomlError('Unterminated string')); + } else if (this.char === CHAR_DEL || this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I) { + throw this.errorControlCharInString(); + } else { + this.consume(); + } + } while (this.nextChar()); + } - _test(path) { - // Explicitly define variable type by setting matched to `0` - let matched = 0; + recordEscapeReplacement(replacement) { + this.state.buf += replacement; + return this.goto(this.parseBasicString); + } - this._rules.forEach(rule => { - // if matched = true, then we only test negative rules - // if matched = false, then we test non-negative rules - if (!(matched ^ rule.negative)) { - matched = rule.negative ^ rule.regex.test(path); + parseMultiStringMaybe() { + if (this.char === CHAR_QUOT) { + return this.next(this.parseMultiString); + } else { + return this.returnNow(); } - }); - - return !matched; - } - -} // 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')) { - const filter = IgnoreBase.prototype._filter; - /* eslint no-control-regex: "off" */ + parseMultiString() { + if (this.char === CTRL_M) { + return null; + } else if (this.char === CTRL_J) { + return this.next(this.parseMultiStringContent); + } else { + return this.goto(this.parseMultiStringContent); + } + } - const make_posix = str => /^\\\\\?\\/.test(str) || /[^\x00-\x80]+/.test(str) ? str : str.replace(/\\/g, '/'); + parseMultiStringContent() { + do { + if (this.char === CHAR_BSOL) { + return this.call(this.parseMultiEscape, this.recordMultiEscapeReplacement); + } else if (this.char === CHAR_QUOT) { + return this.next(this.parseMultiEnd); + } else if (this.char === Parser.END) { + throw this.error(new TomlError('Unterminated multi-line string')); + } else if (this.char === CHAR_DEL || this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I && this.char !== CTRL_J && this.char !== CTRL_M) { + throw this.errorControlCharInString(); + } else { + this.consume(); + } + } while (this.nextChar()); + } - IgnoreBase.prototype._filter = function filterWin32(path, slices) { - path = make_posix(path); - return filter.call(this, path, slices); - }; -} + errorControlCharInString() { + let displayCode = '\\u00'; -var ignore = options => new IgnoreBase(options); + if (this.char < 16) { + displayCode += '0'; + } -/** - * @param {string} filename - * @returns {Promise} - */ + displayCode += this.char.toString(16); + return this.error(new TomlError(`Control characters (codes < 0x1f and 0x7f) are not allowed in strings, use ${displayCode} instead`)); + } + recordMultiEscapeReplacement(replacement) { + this.state.buf += replacement; + return this.goto(this.parseMultiStringContent); + } -function getFileContentOrNull(filename) { - return new Promise((resolve, reject) => { - fs$3.readFile(filename, "utf8", (error, data) => { - if (error && error.code !== "ENOENT") { - reject(createError(filename, error)); + parseMultiEnd() { + if (this.char === CHAR_QUOT) { + return this.next(this.parseMultiEnd2); } else { - resolve(error ? null : data); + this.state.buf += '"'; + return this.goto(this.parseMultiStringContent); } - }); - }); -} -/** - * @param {string} filename - * @returns {null | string} - */ + } + parseMultiEnd2() { + if (this.char === CHAR_QUOT) { + return this.return(); + } else { + this.state.buf += '""'; + return this.goto(this.parseMultiStringContent); + } + } -getFileContentOrNull.sync = function (filename) { - try { - return fs$3.readFileSync(filename, "utf8"); - } catch (error) { - if (error && error.code === "ENOENT") { - return null; + parseMultiEscape() { + if (this.char === CTRL_M || this.char === CTRL_J) { + return this.next(this.parseMultiTrim); + } else if (this.char === CHAR_SP || this.char === CTRL_I) { + return this.next(this.parsePreMultiTrim); + } else { + return this.goto(this.parseEscape); + } } - throw createError(filename, error); - } -}; + parsePreMultiTrim() { + if (this.char === CHAR_SP || this.char === CTRL_I) { + return null; + } else if (this.char === CTRL_M || this.char === CTRL_J) { + return this.next(this.parseMultiTrim); + } else { + throw this.error(new TomlError("Can't escape whitespace")); + } + } -function createError(filename, error) { - return new Error(`Unable to read ${filename}: ${error.message}`); -} + parseMultiTrim() { + // explicitly whitespace here, END should follow the same path as chars + if (this.char === CTRL_J || this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M) { + return null; + } else { + return this.returnNow(); + } + } -var getFileContentOrNull_1 = getFileContentOrNull; + parseEscape() { + if (this.char in escapes) { + return this.return(escapes[this.char]); + } else if (this.char === CHAR_u) { + return this.call(this.parseSmallUnicode, this.parseUnicodeReturn); + } else if (this.char === CHAR_U) { + return this.call(this.parseLargeUnicode, this.parseUnicodeReturn); + } else { + throw this.error(new TomlError('Unknown escape character: ' + this.char)); + } + } -/** - * @param {undefined | string} ignorePath - * @param {undefined | boolean} withNodeModules - */ + parseUnicodeReturn(char) { + try { + const codePoint = parseInt(char, 16); + if (codePoint >= SURROGATE_FIRST && codePoint <= SURROGATE_LAST) { + throw this.error(new TomlError('Invalid unicode, character in range 0xD800 - 0xDFFF is reserved')); + } -async function createIgnorer(ignorePath, withNodeModules) { - const ignoreContent = ignorePath ? await getFileContentOrNull_1(path$2.resolve(ignorePath)) : null; - return _createIgnorer(ignoreContent, withNodeModules); -} -/** - * @param {undefined | string} ignorePath - * @param {undefined | boolean} withNodeModules - */ + return this.returnNow(String.fromCodePoint(codePoint)); + } catch (err) { + throw this.error(TomlError.wrap(err)); + } + } + parseSmallUnicode() { + if (!isHexit(this.char)) { + throw this.error(new TomlError('Invalid character in unicode sequence, expected hex')); + } else { + this.consume(); + if (this.state.buf.length >= 4) return this.return(); + } + } -createIgnorer.sync = function (ignorePath, withNodeModules) { - const ignoreContent = !ignorePath ? null : getFileContentOrNull_1.sync(path$2.resolve(ignorePath)); - return _createIgnorer(ignoreContent, withNodeModules); -}; -/** - * @param {null | string} ignoreContent - * @param {undefined | boolean} withNodeModules - */ + parseLargeUnicode() { + if (!isHexit(this.char)) { + throw this.error(new TomlError('Invalid character in unicode sequence, expected hex')); + } else { + this.consume(); + if (this.state.buf.length >= 8) return this.return(); + } + } + /* NUMBERS */ -function _createIgnorer(ignoreContent, withNodeModules) { - const ignorer = ignore().add(ignoreContent || ""); + parseNumberSign() { + this.consume(); + return this.next(this.parseMaybeSignedInfOrNan); + } - if (!withNodeModules) { - ignorer.add("node_modules"); - } + parseMaybeSignedInfOrNan() { + if (this.char === CHAR_i) { + return this.next(this.parseInf); + } else if (this.char === CHAR_n) { + return this.next(this.parseNan); + } else { + return this.callNow(this.parseNoUnder, this.parseNumberIntegerStart); + } + } - return ignorer; -} + parseNumberIntegerStart() { + if (this.char === CHAR_0) { + this.consume(); + return this.next(this.parseNumberIntegerExponentOrDecimal); + } else { + return this.goto(this.parseNumberInteger); + } + } -var createIgnorer_1 = createIgnorer; + parseNumberIntegerExponentOrDecimal() { + if (this.char === CHAR_PERIOD) { + this.consume(); + return this.call(this.parseNoUnder, this.parseNumberFloat); + } else if (this.char === CHAR_E || this.char === CHAR_e) { + this.consume(); + return this.next(this.parseNumberExponentSign); + } else { + return this.returnNow(Integer(this.state.buf)); + } + } -var thirdParty = require("./third-party"); + parseNumberInteger() { + if (isDigit(this.char)) { + this.consume(); + } else if (this.char === CHAR_LOWBAR) { + return this.call(this.parseNoUnder); + } else if (this.char === CHAR_E || this.char === CHAR_e) { + this.consume(); + return this.next(this.parseNumberExponentSign); + } else if (this.char === CHAR_PERIOD) { + this.consume(); + return this.call(this.parseNoUnder, this.parseNumberFloat); + } else { + const result = Integer(this.state.buf); + /* istanbul ignore if */ -var concatMap = function (xs, fn) { - var res = []; + if (result.isNaN()) { + throw this.error(new TomlError('Invalid number')); + } else { + return this.returnNow(result); + } + } + } - for (var i = 0; i < xs.length; i++) { - var x = fn(xs[i], i); - if (isArray(x)) res.push.apply(res, x);else res.push(x); - } + parseNoUnder() { + if (this.char === CHAR_LOWBAR || this.char === CHAR_PERIOD || this.char === CHAR_E || this.char === CHAR_e) { + throw this.error(new TomlError('Unexpected character, expected digit')); + } else if (this.atEndOfWord()) { + throw this.error(new TomlError('Incomplete number')); + } - return res; -}; + return this.returnNow(); + } -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; + parseNoUnderHexOctBinLiteral() { + if (this.char === CHAR_LOWBAR || this.char === CHAR_PERIOD) { + throw this.error(new TomlError('Unexpected character, expected digit')); + } else if (this.atEndOfWord()) { + throw this.error(new TomlError('Incomplete number')); + } -var balancedMatch = balanced; + return this.returnNow(); + } -function balanced(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) - }; -} + parseNumberFloat() { + if (this.char === CHAR_LOWBAR) { + return this.call(this.parseNoUnder, this.parseNumberFloat); + } else if (isDigit(this.char)) { + this.consume(); + } else if (this.char === CHAR_E || this.char === CHAR_e) { + this.consume(); + return this.next(this.parseNumberExponentSign); + } else { + return this.returnNow(Float(this.state.buf)); + } + } -function maybeMatch(reg, str) { - var m = str.match(reg); - return m ? m[0] : null; -} + parseNumberExponentSign() { + if (isDigit(this.char)) { + return this.goto(this.parseNumberExponent); + } else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) { + this.consume(); + this.call(this.parseNoUnder, this.parseNumberExponent); + } else { + throw this.error(new TomlError('Unexpected character, expected -, + or digit')); + } + } -balanced.range = range; + parseNumberExponent() { + if (isDigit(this.char)) { + this.consume(); + } else if (this.char === CHAR_LOWBAR) { + return this.call(this.parseNoUnder); + } else { + return this.returnNow(Float(this.state.buf)); + } + } + /* NUMBERS or DATETIMES */ -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) { - begs = []; - left = str.length; + parseNumberOrDateTime() { + if (this.char === CHAR_0) { + this.consume(); + return this.next(this.parseNumberBaseOrDateTime); + } else { + return this.goto(this.parseNumberOrDateTimeOnly); + } + } - 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]; + parseNumberOrDateTimeOnly() { + // note, if two zeros are in a row then it MUST be a date + if (this.char === CHAR_LOWBAR) { + return this.call(this.parseNoUnder, this.parseNumberInteger); + } else if (isDigit(this.char)) { + this.consume(); + if (this.state.buf.length > 4) this.next(this.parseNumberInteger); + } else if (this.char === CHAR_E || this.char === CHAR_e) { + this.consume(); + return this.next(this.parseNumberExponentSign); + } else if (this.char === CHAR_PERIOD) { + this.consume(); + return this.call(this.parseNoUnder, this.parseNumberFloat); + } else if (this.char === CHAR_HYPHEN) { + return this.goto(this.parseDateTime); + } else if (this.char === CHAR_COLON) { + return this.goto(this.parseOnlyTimeHour); } else { - beg = begs.pop(); + return this.returnNow(Integer(this.state.buf)); + } + } - if (beg < left) { - left = beg; - right = bi; + parseDateTimeOnly() { + if (this.state.buf.length < 4) { + if (isDigit(this.char)) { + return this.consume(); + } else if (this.char === CHAR_COLON) { + return this.goto(this.parseOnlyTimeHour); + } else { + throw this.error(new TomlError('Expected digit while parsing year part of a date')); + } + } else { + if (this.char === CHAR_HYPHEN) { + return this.goto(this.parseDateTime); + } else { + throw this.error(new TomlError('Expected hyphen (-) while parsing year part of date')); } - - bi = str.indexOf(b, i + 1); } - - i = ai < bi && ai >= 0 ? ai : bi; } - if (begs.length) { - result = [left, right]; + parseNumberBaseOrDateTime() { + if (this.char === CHAR_b) { + this.consume(); + return this.call(this.parseNoUnderHexOctBinLiteral, this.parseIntegerBin); + } else if (this.char === CHAR_o) { + this.consume(); + return this.call(this.parseNoUnderHexOctBinLiteral, this.parseIntegerOct); + } else if (this.char === CHAR_x) { + this.consume(); + return this.call(this.parseNoUnderHexOctBinLiteral, this.parseIntegerHex); + } else if (this.char === CHAR_PERIOD) { + return this.goto(this.parseNumberInteger); + } else if (isDigit(this.char)) { + return this.goto(this.parseDateTimeOnly); + } else { + return this.returnNow(Integer(this.state.buf)); + } } - } - - return result; -} -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'; + parseIntegerHex() { + if (isHexit(this.char)) { + this.consume(); + } else if (this.char === CHAR_LOWBAR) { + return this.call(this.parseNoUnderHexOctBinLiteral); + } else { + const result = Integer(this.state.buf); + /* istanbul ignore if */ -function numeric$1(str) { - return parseInt(str, 10) == str ? parseInt(str, 10) : str.charCodeAt(0); -} + if (result.isNaN()) { + throw this.error(new TomlError('Invalid number')); + } else { + return this.returnNow(result); + } + } + } -function escapeBraces(str) { - return str.split('\\\\').join(escSlash).split('\\{').join(escOpen).split('\\}').join(escClose).split('\\,').join(escComma).split('\\.').join(escPeriod); -} + parseIntegerOct() { + if (isOctit(this.char)) { + this.consume(); + } else if (this.char === CHAR_LOWBAR) { + return this.call(this.parseNoUnderHexOctBinLiteral); + } else { + const result = Integer(this.state.buf); + /* istanbul ignore if */ -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} + if (result.isNaN()) { + throw this.error(new TomlError('Invalid number')); + } else { + return this.returnNow(result); + } + } + } + parseIntegerBin() { + if (isBit(this.char)) { + this.consume(); + } else if (this.char === CHAR_LOWBAR) { + return this.call(this.parseNoUnderHexOctBinLiteral); + } else { + const result = Integer(this.state.buf); + /* istanbul ignore if */ -function parseCommaParts(str) { - if (!str) return ['']; - var parts = []; - var m = balancedMatch('{', '}', 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 (result.isNaN()) { + throw this.error(new TomlError('Invalid number')); + } else { + return this.returnNow(result); + } + } + } + /* DATETIME */ - if (post.length) { - p[p.length - 1] += postParts.shift(); - p.push.apply(p, postParts); - } - parts.push.apply(parts, p); - return parts; -} + parseDateTime() { + // we enter here having just consumed the year and about to consume the hyphen + if (this.state.buf.length < 4) { + throw this.error(new TomlError('Years less than 1000 must be zero padded to four characters')); + } -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 {} + this.state.result = this.state.buf; + this.state.buf = ''; + return this.next(this.parseDateMonth); + } - if (str.substr(0, 2) === '{}') { - str = '\\{\\}' + str.substr(2); - } + parseDateMonth() { + if (this.char === CHAR_HYPHEN) { + if (this.state.buf.length < 2) { + throw this.error(new TomlError('Months less than 10 must be zero padded to two characters')); + } - return expand(escapeBraces(str), true).map(unescapeBraces); -} + this.state.result += '-' + this.state.buf; + this.state.buf = ''; + return this.next(this.parseDateDay); + } else if (isDigit(this.char)) { + this.consume(); + } else { + throw this.error(new TomlError('Incomplete datetime')); + } + } -function embrace(str) { - return '{' + str + '}'; -} + parseDateDay() { + if (this.char === CHAR_T || this.char === CHAR_SP) { + if (this.state.buf.length < 2) { + throw this.error(new TomlError('Days less than 10 must be zero padded to two characters')); + } -function isPadded(el) { - return /^-?0\d/.test(el); -} + this.state.result += '-' + this.state.buf; + this.state.buf = ''; + return this.next(this.parseStartTimeHour); + } else if (this.atEndOfWord()) { + return this.returnNow(createDate(this.state.result + '-' + this.state.buf)); + } else if (isDigit(this.char)) { + this.consume(); + } else { + throw this.error(new TomlError('Incomplete datetime')); + } + } -function lte(i, y) { - return i <= y; -} + parseStartTimeHour() { + if (this.atEndOfWord()) { + return this.returnNow(createDate(this.state.result)); + } else { + return this.goto(this.parseTimeHour); + } + } -function gte$1(i, y) { - return i >= y; -} + parseTimeHour() { + if (this.char === CHAR_COLON) { + if (this.state.buf.length < 2) { + throw this.error(new TomlError('Hours less than 10 must be zero padded to two characters')); + } -function expand(str, isTop) { - var expansions = []; - var m = balancedMatch('{', '}', 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; + this.state.result += 'T' + this.state.buf; + this.state.buf = ''; + return this.next(this.parseTimeMin); + } else if (isDigit(this.char)) { + this.consume(); + } else { + throw this.error(new TomlError('Incomplete datetime')); + } + } - if (!isSequence && !isOptions) { - // {a},b} - if (m.post.match(/,.*\}/)) { - str = m.pre + '{' + m.body + escClose + m.post; - return expand(str); + parseTimeMin() { + if (this.state.buf.length < 2 && isDigit(this.char)) { + this.consume(); + } else if (this.state.buf.length === 2 && this.char === CHAR_COLON) { + this.state.result += ':' + this.state.buf; + this.state.buf = ''; + return this.next(this.parseTimeSec); + } else { + throw this.error(new TomlError('Incomplete datetime')); + } } - return [str]; - } + parseTimeSec() { + if (isDigit(this.char)) { + this.consume(); - var n; + if (this.state.buf.length === 2) { + this.state.result += ':' + this.state.buf; + this.state.buf = ''; + return this.next(this.parseTimeZoneOrFraction); + } + } else { + throw this.error(new TomlError('Incomplete datetime')); + } + } - if (isSequence) { - n = m.body.split(/\.\./); - } else { - n = parseCommaParts(m.body); + parseOnlyTimeHour() { + /* istanbul ignore else */ + if (this.char === CHAR_COLON) { + if (this.state.buf.length < 2) { + throw this.error(new TomlError('Hours less than 10 must be zero padded to two characters')); + } - if (n.length === 1) { - // x{{a,b}}y ==> x{a}y x{b}y - n = expand(n[0], false).map(embrace); + this.state.result = this.state.buf; + this.state.buf = ''; + return this.next(this.parseOnlyTimeMin); + } else { + throw this.error(new TomlError('Incomplete time')); + } + } - if (n.length === 1) { - var post = m.post.length ? expand(m.post, false) : ['']; - return post.map(function (p) { - return m.pre + n[0] + p; - }); + parseOnlyTimeMin() { + if (this.state.buf.length < 2 && isDigit(this.char)) { + this.consume(); + } else if (this.state.buf.length === 2 && this.char === CHAR_COLON) { + this.state.result += ':' + this.state.buf; + this.state.buf = ''; + return this.next(this.parseOnlyTimeSec); + } else { + throw this.error(new TomlError('Incomplete time')); } } - } // 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 + parseOnlyTimeSec() { + if (isDigit(this.char)) { + this.consume(); - var pre = m.pre; - var post = m.post.length ? expand(m.post, false) : ['']; - var N; + if (this.state.buf.length === 2) { + return this.next(this.parseOnlyTimeFractionMaybe); + } + } else { + throw this.error(new TomlError('Incomplete time')); + } + } - if (isSequence) { - var x = numeric$1(n[0]); - var y = numeric$1(n[1]); - var width = Math.max(n[0].length, n[1].length); - var incr = n.length == 3 ? Math.abs(numeric$1(n[2])) : 1; - var test = lte; - var reverse = y < x; + parseOnlyTimeFractionMaybe() { + this.state.result += ':' + this.state.buf; - if (reverse) { - incr *= -1; - test = gte$1; + if (this.char === CHAR_PERIOD) { + this.state.buf = ''; + this.next(this.parseOnlyTimeFraction); + } else { + return this.return(createTime(this.state.result)); + } } - var pad = n.some(isPadded); - N = []; + parseOnlyTimeFraction() { + if (isDigit(this.char)) { + this.consume(); + } else if (this.atEndOfWord()) { + if (this.state.buf.length === 0) throw this.error(new TomlError('Expected digit in milliseconds')); + return this.returnNow(createTime(this.state.result + '.' + this.state.buf)); + } else { + throw this.error(new TomlError('Unexpected character in datetime, expected period (.), minus (-), plus (+) or Z')); + } + } - for (var i = x; test(i, y); i += incr) { - var c; + parseTimeZoneOrFraction() { + if (this.char === CHAR_PERIOD) { + this.consume(); + this.next(this.parseDateTimeFraction); + } else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) { + this.consume(); + this.next(this.parseTimeZoneHour); + } else if (this.char === CHAR_Z) { + this.consume(); + return this.return(createDatetime(this.state.result + this.state.buf)); + } else if (this.atEndOfWord()) { + return this.returnNow(createDatetimeFloat(this.state.result + this.state.buf)); + } else { + throw this.error(new TomlError('Unexpected character in datetime, expected period (.), minus (-), plus (+) or Z')); + } + } - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') c = ''; + parseDateTimeFraction() { + if (isDigit(this.char)) { + this.consume(); + } else if (this.state.buf.length === 1) { + throw this.error(new TomlError('Expected digit in milliseconds')); + } else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) { + this.consume(); + this.next(this.parseTimeZoneHour); + } else if (this.char === CHAR_Z) { + this.consume(); + return this.return(createDatetime(this.state.result + this.state.buf)); + } else if (this.atEndOfWord()) { + return this.returnNow(createDatetimeFloat(this.state.result + this.state.buf)); } else { - c = String(i); + throw this.error(new TomlError('Unexpected character in datetime, expected period (.), minus (-), plus (+) or Z')); + } + } - if (pad) { - var need = width - c.length; + parseTimeZoneHour() { + if (isDigit(this.char)) { + this.consume(); // FIXME: No more regexps - if (need > 0) { - var z = new Array(need + 1).join('0'); - if (i < 0) c = '-' + z + c.slice(1);else c = z + c; - } - } + if (/\d\d$/.test(this.state.buf)) return this.next(this.parseTimeZoneSep); + } else { + throw this.error(new TomlError('Unexpected character in datetime, expected digit')); } - - N.push(c); } - } else { - N = concatMap(n, function (el) { - return expand(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); + parseTimeZoneSep() { + if (this.char === CHAR_COLON) { + this.consume(); + this.next(this.parseTimeZoneMin); + } else { + throw this.error(new TomlError('Unexpected character in datetime, expected colon')); + } } - } - - return expansions; -} -var minimatch_1 = minimatch; -minimatch.Minimatch = Minimatch; -var path = { - sep: '/' -}; + parseTimeZoneMin() { + if (isDigit(this.char)) { + this.consume(); + if (/\d\d$/.test(this.state.buf)) return this.return(createDatetime(this.state.result + this.state.buf)); + } else { + throw this.error(new TomlError('Unexpected character in datetime, expected digit')); + } + } + /* BOOLEAN */ -try { - path = path$2; -} catch (er) {} -var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}; -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() + parseBoolean() { + /* istanbul ignore else */ + if (this.char === CHAR_t) { + this.consume(); + return this.next(this.parseTrue_r); + } else if (this.char === CHAR_f) { + this.consume(); + return this.next(this.parseFalse_a); + } + } -var qmark = '[^/]'; // * => any number of characters + parseTrue_r() { + if (this.char === CHAR_r) { + this.consume(); + return this.next(this.parseTrue_u); + } else { + throw this.error(new TomlError('Invalid boolean, expected true or false')); + } + } -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. + parseTrue_u() { + if (this.char === CHAR_u) { + this.consume(); + return this.next(this.parseTrue_e); + } else { + throw this.error(new TomlError('Invalid boolean, expected true or false')); + } + } -var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'; // not a ^ or / followed by a dot, -// followed by anything, any number of times. + parseTrue_e() { + if (this.char === CHAR_e) { + return this.return(true); + } else { + throw this.error(new TomlError('Invalid boolean, expected true or false')); + } + } -var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'; // characters that need to be escaped in RegExp. + parseFalse_a() { + if (this.char === CHAR_a) { + this.consume(); + return this.next(this.parseFalse_l); + } else { + throw this.error(new TomlError('Invalid boolean, expected true or false')); + } + } -var reSpecials = charSet('().*{}+?[]^$\\!'); // "abc" -> { a:true, b:true, c:true } + parseFalse_l() { + if (this.char === CHAR_l) { + this.consume(); + return this.next(this.parseFalse_s); + } else { + throw this.error(new TomlError('Invalid boolean, expected true or false')); + } + } -function charSet(s) { - return s.split('').reduce(function (set, c) { - set[c] = true; - return set; - }, {}); -} // normalizes slashes. + parseFalse_s() { + if (this.char === CHAR_s) { + this.consume(); + return this.next(this.parseFalse_e); + } else { + throw this.error(new TomlError('Invalid boolean, expected true or false')); + } + } + parseFalse_e() { + if (this.char === CHAR_e) { + return this.return(false); + } else { + throw this.error(new TomlError('Invalid boolean, expected true or false')); + } + } + /* INLINE LISTS */ -var slashSplit = /\/+/; -minimatch.filter = filter; -function filter(pattern, options) { - options = options || {}; - return function (p, i, list) { - return minimatch(p, pattern, options); - }; -} + parseInlineList() { + if (this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M || this.char === CTRL_J) { + return null; + } else if (this.char === Parser.END) { + throw this.error(new TomlError('Unterminated inline array')); + } else if (this.char === CHAR_NUM) { + return this.call(this.parseComment); + } else if (this.char === CHAR_RSQB) { + return this.return(this.state.resultArr || InlineList()); + } else { + return this.callNow(this.parseValue, this.recordInlineListValue); + } + } -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; -} + recordInlineListValue(value) { + if (this.state.resultArr) { + const listType = this.state.resultArr[_contentType]; + const valueType = tomlType(value); -minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return minimatch; - var orig = minimatch; + if (listType !== valueType) { + throw this.error(new TomlError(`Inline lists must be a single type, not a mix of ${listType} and ${valueType}`)); + } + } else { + this.state.resultArr = InlineList(tomlType(value)); + } - var m = function minimatch(p, pattern, options) { - return orig.minimatch(p, pattern, ext(def, options)); - }; + if (isFloat(value) || isInteger(value)) { + // unbox now that we've verified they're ok + this.state.resultArr.push(value.valueOf()); + } else { + this.state.resultArr.push(value); + } - m.Minimatch = function Minimatch(pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)); - }; + return this.goto(this.parseInlineListNext); + } - return m; -}; + parseInlineListNext() { + if (this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M || this.char === CTRL_J) { + return null; + } else if (this.char === CHAR_NUM) { + return this.call(this.parseComment); + } else if (this.char === CHAR_COMMA) { + return this.next(this.parseInlineList); + } else if (this.char === CHAR_RSQB) { + return this.goto(this.parseInlineList); + } else { + throw this.error(new TomlError('Invalid character, expected whitespace, comma (,) or close bracket (])')); + } + } + /* INLINE TABLE */ -Minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return Minimatch; - return minimatch.defaults(def).Minimatch; -}; -function minimatch(p, pattern, options) { - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required'); - } + parseInlineTable() { + if (this.char === CHAR_SP || this.char === CTRL_I) { + return null; + } else if (this.char === Parser.END || this.char === CHAR_NUM || this.char === CTRL_J || this.char === CTRL_M) { + throw this.error(new TomlError('Unterminated inline array')); + } else if (this.char === CHAR_RCUB) { + return this.return(this.state.resultTable || InlineTable()); + } else { + if (!this.state.resultTable) this.state.resultTable = InlineTable(); + return this.callNow(this.parseAssign, this.recordInlineTableValue); + } + } - if (!options) options = {}; // shortcut: comments match nothing. + recordInlineTableValue(kv) { + let target = this.state.resultTable; + let finalKey = kv.key.pop(); - if (!options.nocomment && pattern.charAt(0) === '#') { - return false; - } // "" only matches "" + for (let kw of kv.key) { + if (hasKey(target, kw) && (!isTable(target[kw]) || target[kw][_declared])) { + throw this.error(new TomlError("Can't redefine existing key")); + } + target = target[kw] = target[kw] || Table(); + } - if (pattern.trim() === '') return p === ''; - return new Minimatch(pattern, options).match(p); -} + if (hasKey(target, finalKey)) { + throw this.error(new TomlError("Can't redefine existing key")); + } -function Minimatch(pattern, options) { - if (!(this instanceof Minimatch)) { - return new Minimatch(pattern, options); - } + if (isInteger(kv.value) || isFloat(kv.value)) { + target[finalKey] = kv.value.valueOf(); + } else { + target[finalKey] = kv.value; + } - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required'); - } + return this.goto(this.parseInlineTableNext); + } - if (!options) options = {}; - pattern = pattern.trim(); // windows support: need to use /, not \ + parseInlineTableNext() { + if (this.char === CHAR_SP || this.char === CTRL_I) { + return null; + } else if (this.char === Parser.END || this.char === CHAR_NUM || this.char === CTRL_J || this.char === CTRL_M) { + throw this.error(new TomlError('Unterminated inline array')); + } else if (this.char === CHAR_COMMA) { + return this.next(this.parseInlineTable); + } else if (this.char === CHAR_RCUB) { + return this.goto(this.parseInlineTable); + } else { + throw this.error(new TomlError('Invalid character, expected whitespace, comma (,) or close bracket (])')); + } + } - if (path.sep !== '/') { - pattern = pattern.split(path.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(); + return TOMLParser; } +tomlParser.makeParserClass = makeParserClass_1; +tomlParser.TomlError = TomlError_1; -Minimatch.prototype.debug = function () {}; - -Minimatch.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. +var parsePrettyError = prettyError; - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true; - return; - } +function prettyError(err, buf) { + /* istanbul ignore if */ + if (err.pos == null || err.line == null) return err; + let msg = err.message; + msg += ` at row ${err.line + 1}, col ${err.col + 1}, pos ${err.pos}:\n`; + /* istanbul ignore else */ - if (!pattern) { - this.empty = true; - return; - } // step 1: figure out negation, etc. + if (buf && buf.split) { + const lines = buf.split(/\n/); + const lineNumWidth = String(Math.min(lines.length, err.line + 3)).length; + let linePadding = ' '; + while (linePadding.length < lineNumWidth) linePadding += ' '; - this.parseNegate(); // step 2: expand braces + for (let ii = Math.max(0, err.line - 1); ii < Math.min(lines.length, err.line + 2); ++ii) { + let lineNum = String(ii + 1); + if (lineNum.length < lineNumWidth) lineNum = ' ' + lineNum; - 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 + if (err.line === ii) { + msg += lineNum + '> ' + lines[ii] + '\n'; + msg += linePadding + ' '; - set = this.globParts = set.map(function (s) { - return s.split(slashSplit); - }); - this.debug(this.pattern, set); // glob --> regexps + for (let hh = 0; hh < err.col; ++hh) { + msg += ' '; + } - 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. + msg += '^\n'; + } else { + msg += lineNum + ': ' + lines[ii] + '\n'; + } + } + } - set = set.filter(function (s) { - return s.indexOf(false) === -1; - }); - this.debug(this.pattern, set); - this.set = set; + err.message = msg + '\n'; + return err; } -Minimatch.prototype.parseNegate = parseNegate; - -function parseNegate() { - var pattern = this.pattern; - var negate = false; - var options = this.options; - var negateOffset = 0; - if (options.nonegate) return; +var parseString_1 = parseString; - for (var i = 0, l = pattern.length; i < l && pattern.charAt(i) === '!'; i++) { - negate = !negate; - negateOffset++; +function parseString(str) { + if (global.Buffer && global.Buffer.isBuffer(str)) { + str = str.toString('utf8'); } - 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 + const parser = new tomlParser(); + try { + parser.parse(str); + return parser.finish(); + } catch (err) { + throw parsePrettyError(err, str); + } +} -minimatch.braceExpand = function (pattern, options) { - return braceExpand(pattern, options); +var loadToml = function (filePath, content) { + try { + return parseString_1(content); + } catch (error) { + error.message = `TOML Error in ${filePath}:\n${error.message}`; + throw error; + } }; -Minimatch.prototype.braceExpand = braceExpand; +// 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$2 = { + isSpaceSeparator(c) { + return typeof c === 'string' && unicode.Space_Separator.test(c); + }, -function braceExpand(pattern, options) { - if (!options) { - if (this instanceof Minimatch) { - options = this.options; - } else { - options = {}; - } - } + isIdStartChar(c) { + return typeof c === 'string' && (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c === '$' || c === '_' || unicode.ID_Start.test(c)); + }, - pattern = typeof pattern === 'undefined' ? this.pattern : pattern; + 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)); + }, - if (typeof pattern === 'undefined') { - throw new TypeError('undefined pattern'); - } + isDigit(c) { + return typeof c === 'string' && /[0-9]/.test(c); + }, - if (options.nobrace || !pattern.match(/\{.*\}/)) { - // shortcut. no need to expand. - return [pattern]; + isHexDigit(c) { + return typeof c === 'string' && /[0-9A-Fa-f]/.test(c); } - return braceExpansion(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.prototype.parse = parse$1; -var SUBPARSE = {}; +}; +let source$1; +let parseState; +let stack; +let pos; +let line$2; +let column; +let token; +let key; +let root$1; -function parse$1(pattern, isSub) { - if (pattern.length > 1024 * 64) { - throw new TypeError('pattern is too long'); - } +var parse$2 = function parse(text, reviver) { + source$1 = String(text); + parseState = 'start'; + stack = []; + pos = 0; + line$2 = 1; + column = 0; + token = undefined; + key = undefined; + root$1 = undefined; - var options = this.options; // shortcuts + do { + token = lex(); // This code is unreachable. + // if (!parseStates[parseState]) { + // throw invalidParseState() + // } - if (!options.noglobstar && pattern === '**') return GLOBSTAR; - if (pattern === '') return ''; - var re = ''; - var hasMagic = !!options.nocase; - var escaping = false; // ? => one single character + parseStates[parseState](); + } while (token.type !== 'eof'); - 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. + if (typeof reviver === 'function') { + return internalize({ + '': root$1 + }, '', reviver); + } - var patternStart = pattern.charAt(0) === '.' ? '' // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' : '(?!\\.)'; - var self = this; + return root$1; +}; - 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; +function internalize(holder, name, reviver) { + const value = holder[name]; - case '?': - re += qmark; - hasMagic = true; - break; + if (value != null && typeof value === 'object') { + for (const key in value) { + const replacement = internalize(value, key, reviver); - default: - re += '\\' + stateChar; - break; + if (replacement === undefined) { + delete value[key]; + } else { + value[key] = replacement; } - - 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; - } + return reviver.call(holder, name, value); +} - switch (c) { - case '/': - // completely not allowed, even escaped. - // Should already be path-split by now. - return false; +let lexState; +let buffer; +let doubleQuote; +let sign; +let c; - case '\\': - clearStateChar(); - escaping = true; - continue; - // the various stateChar values - // for the "extglob" stuff. +function lex() { + lexState = 'default'; + buffer = ''; + doubleQuote = false; + sign = 1; - 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 + for (;;) { + c = peek(); // This code is unreachable. + // if (!lexStates[lexState]) { + // throw invalidLexState(lexState) + // } - 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. + const token = lexStates[lexState](); + if (token) { + return token; + } + } +} - 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. +function peek() { + if (source$1[pos]) { + return String.fromCodePoint(source$1.codePointAt(pos)); + } +} - if (options.noext) clearStateChar(); - continue; +function read() { + const c = peek(); - case '(': - if (inClass) { - re += '('; - continue; - } + if (c === '\n') { + line$2++; + column = 0; + } else if (c) { + column += c.length; + } else { + column++; + } - if (!stateChar) { - re += '\\('; - continue; - } + if (c) { + pos += c.length; + } - patternListStack.push({ - type: stateChar, - start: i - 1, - reStart: re.length, - open: plTypes[stateChar].open, - close: plTypes[stateChar].close - }); // negation is (?:(?!js)[^/]*) + return c; +} - re += stateChar === '!' ? '(?:(?!(?:' : '(?:'; - this.debug('plType %j %j', stateChar, re); - stateChar = false; - continue; +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 ')': - if (inClass || !patternListStack.length) { - re += '\\)'; - continue; - } + case '/': + read(); + lexState = 'comment'; + return; - clearStateChar(); - hasMagic = true; - var pl = patternListStack.pop(); // negation is (?:(?!js)[^/]*) - // The others are (?:) + case undefined: + read(); + return newToken('eof'); + } - re += pl.close; + if (util$2.isSpaceSeparator(c)) { + read(); + return; + } // This code is unreachable. + // if (!lexStates[parseState]) { + // throw invalidLexState(parseState) + // } - if (pl.type === '!') { - negativeLists.push(pl); - } - pl.reEnd = re.length; - continue; + return lexStates[parseState](); + }, - case '|': - if (inClass || !patternListStack.length || escaping) { - re += '\\|'; - escaping = false; - continue; - } + comment() { + switch (c) { + case '*': + read(); + lexState = 'multiLineComment'; + return; - clearStateChar(); - re += '|'; - continue; - // these are mostly the same in regexp and glob + case '/': + read(); + lexState = 'singleLineComment'; + return; + } - case '[': - // swallow any state-tracking char before the [ - clearStateChar(); + throw invalidChar(read()); + }, - if (inClass) { - re += '\\' + c; - continue; - } + multiLineComment() { + switch (c) { + case '*': + read(); + lexState = 'multiLineCommentAsterisk'; + return; - inClass = true; - classStart = i; - reClassStart = re.length; - re += c; - continue; + case undefined: + throw invalidChar(read()); + } - 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\]" + read(); + }, + multiLineCommentAsterisk() { + switch (c) { + case '*': + read(); + return; - 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); + case '/': + read(); + lexState = 'default'; + return; - 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. + case undefined: + throw invalidChar(read()); + } + read(); + lexState = 'multiLineComment'; + }, - hasMagic = true; - inClass = false; - re += c; - continue; + singleLineComment() { + switch (c) { + case '\n': + case '\r': + case '\u2028': + case '\u2029': + read(); + lexState = 'default'; + return; - default: - // swallow any state char that wasn't consumed - clearStateChar(); + case undefined: + read(); + return newToken('eof'); + } - if (escaping) { - // no need - escaping = false; - } else if (reSpecials[c] && !(c === '^' && inClass)) { - re += '\\'; - } + read(); + }, - re += c; - } // switch + value() { + switch (c) { + case '{': + case '[': + return newToken('punctuator', read()); - } // for - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" + case 'n': + read(); + literal('ull'); + return newToken('null', null); + case 't': + read(); + literal('rue'); + return newToken('boolean', true); - 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. + case 'f': + read(); + literal('alse'); + return newToken('boolean', false); + case '-': + case '+': + if (read() === '-') { + sign = -1; + } - 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 | + lexState = 'sign'; + return; - 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. + case '.': + buffer = read(); + lexState = 'decimalPointLeading'; + return; + case '0': + buffer = read(); + lexState = 'zero'; + return; - 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. + 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; + } - clearStateChar(); + throw invalidChar(read()); + }, - if (escaping) { - // trailing \\ - re += '\\\\'; - } // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot + identifierNameStartEscape() { + if (c !== 'u') { + throw invalidChar(read()); + } + read(); + const u = unicodeEscape(); - var addPatternStart = false; + switch (u) { + case '$': + case '_': + break; - 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. + default: + if (!util$2.isIdStartChar(u)) { + throw invalidIdentifier(); + } + break; + } - 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. + buffer += u; + lexState = 'identifierName'; + }, - var openParensBefore = nlBefore.split('(').length - 1; - var cleanAfter = nlAfter; + identifierName() { + switch (c) { + case '$': + case '_': + case '\u200C': + case '\u200D': + buffer += read(); + return; - for (i = 0; i < openParensBefore; i++) { - cleanAfter = cleanAfter.replace(/\)[+*?]?/, ''); + case '\\': + read(); + lexState = 'identifierNameEscape'; + return; } - nlAfter = cleanAfter; - var dollar = ''; - - if (nlAfter === '' && isSub !== SUBPARSE) { - dollar = '$'; + if (util$2.isIdContinueChar(c)) { + buffer += read(); + return; } - 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. + return newToken('identifier', buffer); + }, + identifierNameEscape() { + if (c !== 'u') { + throw invalidChar(read()); + } - if (re !== '' && hasMagic) { - re = '(?=.)' + re; - } + read(); + const u = unicodeEscape(); - if (addPatternStart) { - re = patternStart + re; - } // parsing just a piece of a larger pattern. + switch (u) { + case '$': + case '_': + case '\u200C': + case '\u200D': + break; + default: + if (!util$2.isIdContinueChar(u)) { + throw invalidIdentifier(); + } - 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. + break; + } + buffer += u; + lexState = 'identifierName'; + }, - if (!hasMagic) { - return globUnescape(pattern); - } + sign() { + switch (c) { + case '.': + buffer = read(); + lexState = 'decimalPointLeading'; + return; - var flags = options.nocase ? 'i' : ''; + case '0': + buffer = read(); + lexState = 'zero'; + return; - 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('$.'); - } + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + buffer = read(); + lexState = 'decimalInteger'; + return; - regExp._glob = pattern; - regExp._src = re; - return regExp; -} + case 'I': + read(); + literal('nfinity'); + return newToken('numeric', sign * Infinity); -minimatch.makeRe = function (pattern, options) { - return new Minimatch(pattern, options || {}).makeRe(); -}; + case 'N': + read(); + literal('aN'); + return newToken('numeric', NaN); + } -Minimatch.prototype.makeRe = makeRe; + throw invalidChar(read()); + }, -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. + zero() { + switch (c) { + case '.': + buffer += read(); + lexState = 'decimalPoint'; + return; - var set = this.set; + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return; - if (!set.length) { - this.regexp = false; - return this.regexp; - } + case 'x': + case 'X': + buffer += read(); + lexState = 'hexadecimal'; + return; + } - 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. + return newToken('numeric', sign * 0); + }, - re = '^(?:' + re + ')$'; // can match anything, as long as it's not this. + decimalInteger() { + switch (c) { + case '.': + buffer += read(); + lexState = 'decimalPoint'; + return; - if (this.negate) re = '^(?!' + re + ').*$'; + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return; + } - try { - this.regexp = new RegExp(re, flags); - } catch (ex) { - this.regexp = false; - } + if (util$2.isDigit(c)) { + buffer += read(); + return; + } - return this.regexp; -} + return newToken('numeric', sign * Number(buffer)); + }, -minimatch.match = function (list, pattern, options) { - options = options || {}; - var mm = new Minimatch(pattern, options); - list = list.filter(function (f) { - return mm.match(f); - }); + decimalPointLeading() { + if (util$2.isDigit(c)) { + buffer += read(); + lexState = 'decimalFraction'; + return; + } - if (mm.options.nonull && !list.length) { - list.push(pattern); - } + throw invalidChar(read()); + }, - return list; -}; + decimalPoint() { + switch (c) { + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return; + } -Minimatch.prototype.match = match; + if (util$2.isDigit(c)) { + buffer += read(); + lexState = 'decimalFraction'; + return; + } -function match(f, partial) { - this.debug('match', f, this.pattern); // short-circuit in the case of busted things. - // comments, etc. + return newToken('numeric', sign * Number(buffer)); + }, - if (this.comment) return false; - if (this.empty) return f === ''; - if (f === '/' && partial) return true; - var options = this.options; // windows: need to use /, not \ + decimalFraction() { + switch (c) { + case 'e': + case 'E': + buffer += read(); + lexState = 'decimalExponent'; + return; + } - if (path.sep !== '/') { - f = f.split(path.sep).join('/'); - } // treat the test path as a set of pathparts. + if (util$2.isDigit(c)) { + buffer += read(); + return; + } + return newToken('numeric', sign * Number(buffer)); + }, - 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. + decimalExponent() { + switch (c) { + case '+': + case '-': + buffer += read(); + lexState = 'decimalExponentSign'; + return; + } - var set = this.set; - this.debug(this.pattern, 'set', set); // Find the basename of the path by looking for the last non-empty segment + if (util$2.isDigit(c)) { + buffer += read(); + lexState = 'decimalExponentInteger'; + return; + } - var filename; - var i; + throw invalidChar(read()); + }, - for (i = f.length - 1; i >= 0; i--) { - filename = f[i]; - if (filename) break; - } + decimalExponentSign() { + if (util$2.isDigit(c)) { + buffer += read(); + lexState = 'decimalExponentInteger'; + return; + } - for (i = 0; i < set.length; i++) { - var pattern = set[i]; - var file = f; + throw invalidChar(read()); + }, - if (options.matchBase && pattern.length === 1) { - file = [filename]; + decimalExponentInteger() { + if (util$2.isDigit(c)) { + buffer += read(); + return; } - var hit = this.matchOne(file, pattern, partial); + return newToken('numeric', sign * Number(buffer)); + }, - if (hit) { - if (options.flipNegate) return true; - return !this.negate; + hexadecimal() { + if (util$2.isHexDigit(c)) { + buffer += read(); + lexState = 'hexadecimalInteger'; + return; } - } // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. + throw invalidChar(read()); + }, - 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. + hexadecimalInteger() { + if (util$2.isHexDigit(c)) { + buffer += read(); + return; + } + return newToken('numeric', sign * Number(buffer)); + }, -Minimatch.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); + string() { + switch (c) { + case '\\': + read(); + buffer += escape(); + return; - 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. + case '"': + if (doubleQuote) { + read(); + return newToken('string', buffer); + } - if (p === false) return false; + buffer += read(); + return; - 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 + case "'": + if (!doubleQuote) { + read(); + return newToken('string', buffer); + } - var fr = fi; - var pr = pi + 1; + buffer += read(); + return; - 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. + case '\n': + case '\r': + throw invalidChar(read()); - for (; fi < fl; fi++) { - if (file[fi] === '.' || file[fi] === '..' || !options.dot && file[fi].charAt(0) === '.') return false; - } + case '\u2028': + case '\u2029': + separatorChar(c); + break; - return true; - } // ok, let's see if we can swallow whatever we can. + case undefined: + throw invalidChar(read()); + } + buffer += read(); + }, - 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. + start() { + switch (c) { + case '{': + case '[': + return newToken('punctuator', read()); + // This code is unreachable since the default lexState handles eof. + // case undefined: + // return newToken('eof') + } - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee); // found a match. + lexState = 'value'; + }, - 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. + beforePropertyName() { + switch (c) { + case '$': + case '_': + buffer = read(); + lexState = 'identifierName'; + return; + case '\\': + read(); + lexState = 'identifierNameStartEscape'; + return; - 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 + case '}': + return newToken('punctuator', read()); + case '"': + case "'": + doubleQuote = read() === '"'; + lexState = 'string'; + return; + } - if (partial) { - // ran out of file - this.debug('\n>>> no match, partial?', file, fr, pattern, pr); - if (fr === fl) return true; - } + if (util$2.isIdStartChar(c)) { + buffer += read(); + lexState = 'identifierName'; + return; + } - return false; - } // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. + throw invalidChar(read()); + }, + afterPropertyName() { + if (c === ':') { + return newToken('punctuator', read()); + } - var hit; + throw invalidChar(read()); + }, - if (typeof p === 'string') { - if (options.nocase) { - hit = f.toLowerCase() === p.toLowerCase(); - } else { - hit = f === p; - } + beforePropertyValue() { + lexState = 'value'; + }, - this.debug('string match', p, f, hit); - } else { - hit = f.match(p); - this.debug('pattern match', p, f, hit); + afterPropertyValue() { + switch (c) { + case ',': + case '}': + return newToken('punctuator', read()); } - 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. + throw invalidChar(read()); + }, + beforeArrayValue() { + if (c === ']') { + return newToken('punctuator', read()); + } - 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. + lexState = 'value'; + }, + afterArrayValue() { + switch (c) { + case ',': + case ']': + return newToken('punctuator', read()); + } - throw new Error('wtf?'); -}; // replace stuff like \* with * + 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 globUnescape(s) { - return s.replace(/\\(.)/g, '$1'); -} +}; -function regExpEscape(s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); +function newToken(type, value) { + return { + type, + value, + line: line$2, + column + }; } -const copyProperty = (to, from, property, ignoreNonConfigurable) => { - // `Function#length` should reflect the parameters of `to` not `from` since we keep its body. - // `Function#prototype` is non-writable and non-configurable so can never be modified. - if (property === 'length' || property === 'prototype') { - return; - } +function literal(s) { + for (const c of s) { + const p = peek(); - const toDescriptor = Object.getOwnPropertyDescriptor(to, property); - const fromDescriptor = Object.getOwnPropertyDescriptor(from, property); + if (p !== c) { + throw invalidChar(read()); + } - if (!canCopyProperty(toDescriptor, fromDescriptor) && ignoreNonConfigurable) { - return; + read(); } +} - Object.defineProperty(to, property, fromDescriptor); -}; // `Object.defineProperty()` throws if the property exists, is not configurable and either: -// - one its descriptors is changed -// - it is non-writable and its value is changed +function escape() { + const c = peek(); + switch (c) { + case 'b': + read(); + return '\b'; -const canCopyProperty = function (toDescriptor, fromDescriptor) { - return toDescriptor === undefined || toDescriptor.configurable || toDescriptor.writable === fromDescriptor.writable && toDescriptor.enumerable === fromDescriptor.enumerable && toDescriptor.configurable === fromDescriptor.configurable && (toDescriptor.writable || toDescriptor.value === fromDescriptor.value); -}; + case 'f': + read(); + return '\f'; -const changePrototype = (to, from) => { - const fromPrototype = Object.getPrototypeOf(from); + case 'n': + read(); + return '\n'; - if (fromPrototype === Object.getPrototypeOf(to)) { - return; - } + case 'r': + read(); + return '\r'; - Object.setPrototypeOf(to, fromPrototype); -}; + case 't': + read(); + return '\t'; -const wrappedToString = (withName, fromBody) => `/* Wrapped ${withName}*/\n${fromBody}`; + case 'v': + read(); + return '\v'; -const toStringDescriptor = Object.getOwnPropertyDescriptor(Function.prototype, 'toString'); -const toStringName = Object.getOwnPropertyDescriptor(Function.prototype.toString, 'name'); // We call `from.toString()` early (not lazily) to ensure `from` can be garbage collected. -// We use `bind()` instead of a closure for the same reason. -// Calling `from.toString()` early also allows caching it in case `to.toString()` is called several times. + case '0': + read(); -const changeToString = (to, from, name) => { - const withName = name === '' ? '' : `with ${name.trim()}() `; - const newToString = wrappedToString.bind(null, withName, from.toString()); // Ensure `to.toString.toString` is non-enumerable and has the same `same` + if (util$2.isDigit(peek())) { + throw invalidChar(read()); + } - Object.defineProperty(newToString, 'name', toStringName); - Object.defineProperty(to, 'toString', Object.assign({}, toStringDescriptor, { - value: newToString - })); -}; + return '\0'; -const mimicFn = (to, from, { - ignoreNonConfigurable = false -} = {}) => { - const { - name - } = to; + case 'x': + read(); + return hexEscape(); - for (const property of Reflect.ownKeys(from)) { - copyProperty(to, from, property, ignoreNonConfigurable); - } + case 'u': + read(); + return unicodeEscape(); - changePrototype(to, from); - changeToString(to, from, name); - return to; -}; + case '\n': + case '\u2028': + case '\u2029': + read(); + return ''; -var mimicFn_1 = mimicFn; + case '\r': + read(); -var pDefer = () => { - const ret = {}; - ret.promise = new Promise((resolve, reject) => { - ret.resolve = resolve; - ret.reject = reject; - }); - return ret; -}; + if (peek() === '\n') { + read(); + } -var dist = createCommonjsModule(function (module, exports) { + return ''; - var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) { - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { - try { - step(generator.next(value)); - } catch (e) { - reject(e); - } - } + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + throw invalidChar(read()); - function rejected(value) { - try { - step(generator["throw"](value)); - } catch (e) { - reject(e); - } - } + case undefined: + throw invalidChar(read()); + } - function step(result) { - result.done ? resolve(result.value) : new P(function (resolve) { - resolve(result.value); - }).then(fulfilled, rejected); - } + return read(); +} - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); - }; +function hexEscape() { + let buffer = ''; + let c = peek(); - var __importDefault = this && this.__importDefault || function (mod) { - return mod && mod.__esModule ? mod : { - "default": mod - }; - }; + if (!util$2.isHexDigit(c)) { + throw invalidChar(read()); + } - Object.defineProperty(exports, "__esModule", { - value: true - }); + buffer += read(); + c = peek(); - const p_defer_1 = __importDefault(pDefer); + if (!util$2.isHexDigit(c)) { + throw invalidChar(read()); + } - function mapAgeCleaner(map, property = 'maxAge') { - let processingKey; - let processingTimer; - let processingDeferred; + buffer += read(); + return String.fromCodePoint(parseInt(buffer, 16)); +} - const cleanup = () => __awaiter(this, void 0, void 0, function* () { - if (processingKey !== undefined) { - // If we are already processing an item, we can safely exit - return; - } +function unicodeEscape() { + let buffer = ''; + let count = 4; - const setupTimer = item => __awaiter(this, void 0, void 0, function* () { - processingDeferred = p_defer_1.default(); - const delay = item[1][property] - Date.now(); + while (count-- > 0) { + const c = peek(); - if (delay <= 0) { - // Remove the item immediately if the delay is equal to or below 0 - map.delete(item[0]); - processingDeferred.resolve(); - return; - } // Keep track of the current processed key + if (!util$2.isHexDigit(c)) { + throw invalidChar(read()); + } + buffer += read(); + } - processingKey = item[0]; - processingTimer = setTimeout(() => { - // Remove the item when the timeout fires - map.delete(item[0]); + return String.fromCodePoint(parseInt(buffer, 16)); +} - if (processingDeferred) { - processingDeferred.resolve(); - } - }, delay); // tslint:disable-next-line:strict-type-predicates +const parseStates = { + start() { + if (token.type === 'eof') { + throw invalidEOF(); + } - if (typeof processingTimer.unref === 'function') { - // Don't hold up the process from exiting - processingTimer.unref(); - } + push(); + }, - return processingDeferred.promise; - }); + beforePropertyName() { + switch (token.type) { + case 'identifier': + case 'string': + key = token.value; + parseState = 'afterPropertyName'; + return; - try { - for (const entry of map) { - yield setupTimer(entry); - } - } catch (_a) {// Do nothing if an error occurs, this means the timer was cleaned up and we should stop processing - } + case 'punctuator': + // This code is unreachable since it's handled by the lexState. + // if (token.value !== '}') { + // throw invalidToken() + // } + pop(); + return; - processingKey = undefined; - }); + case 'eof': + throw invalidEOF(); + } // This code is unreachable since it's handled by the lexState. + // throw invalidToken() - const reset = () => { - processingKey = undefined; + }, - if (processingTimer !== undefined) { - clearTimeout(processingTimer); - processingTimer = undefined; - } + 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(); + } - if (processingDeferred !== undefined) { - // tslint:disable-line:early-exit - processingDeferred.reject(undefined); - processingDeferred = undefined; - } - }; + parseState = 'beforePropertyValue'; + }, - const originalSet = map.set.bind(map); + beforePropertyValue() { + if (token.type === 'eof') { + throw invalidEOF(); + } - map.set = (key, value) => { - if (map.has(key)) { - // If the key already exist, remove it so we can add it back at the end of the map. - map.delete(key); - } // Call the original `map.set` + push(); + }, + beforeArrayValue() { + if (token.type === 'eof') { + throw invalidEOF(); + } - const result = originalSet(key, value); // If we are already processing a key and the key added is the current processed key, stop processing it + if (token.type === 'punctuator' && token.value === ']') { + pop(); + return; + } - if (processingKey && processingKey === key) { - reset(); - } // Always run the cleanup method in case it wasn't started yet + push(); + }, + afterPropertyValue() { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator') { + // throw invalidToken() + // } + if (token.type === 'eof') { + throw invalidEOF(); + } - cleanup(); // tslint:disable-line:no-floating-promises + switch (token.value) { + case ',': + parseState = 'beforePropertyName'; + return; - return result; - }; + case '}': + pop(); + } // This code is unreachable since it's handled by the lexState. + // throw invalidToken() - cleanup(); // tslint:disable-line:no-floating-promises + }, - return map; - } + afterArrayValue() { + // This code is unreachable since it's handled by the lexState. + // if (token.type !== 'punctuator') { + // throw invalidToken() + // } + if (token.type === 'eof') { + throw invalidEOF(); + } - exports.default = mapAgeCleaner; // Add support for CJS + switch (token.value) { + case ',': + parseState = 'beforeArrayValue'; + return; - module.exports = mapAgeCleaner; - module.exports.default = mapAgeCleaner; -}); -unwrapExports(dist); + case ']': + pop(); + } // This code is unreachable since it's handled by the lexState. + // throw invalidToken() -const cacheStore = new WeakMap(); + }, -const mem = (fn, { - cacheKey = ([firstArgument]) => firstArgument, - cache = new Map(), - maxAge -} = {}) => { - if (typeof maxAge === 'number') { - dist(cache); + end() {// This code is unreachable since it's handled by the lexState. + // if (token.type !== 'eof') { + // throw invalidToken() + // } } - const memoized = function (...arguments_) { - const key = cacheKey(arguments_); - - if (cache.has(key)) { - return cache.get(key).data; - } +}; - const cacheItem = fn.apply(this, arguments_); - cache.set(key, { - data: cacheItem, - maxAge: maxAge ? Date.now() + maxAge : Infinity - }); - return cacheItem; - }; +function push() { + let value; - try { - // The below call will throw in some host environments - // See https://github.com/sindresorhus/mimic-fn/issues/10 - mimicFn_1(memoized, fn); - } catch (_) {} + switch (token.type) { + case 'punctuator': + switch (token.value) { + case '{': + value = {}; + break; - cacheStore.set(memoized, cache); - return memoized; -}; + case '[': + value = []; + break; + } -var mem_1 = mem; + break; -var clear = fn => { - if (!cacheStore.has(fn)) { - throw new Error('Can\'t clear a function that was not memoized!'); + case 'null': + case 'boolean': + case 'numeric': + case 'string': + value = token.value; + break; + // This code is unreachable. + // default: + // throw invalidToken() } - const cache = cacheStore.get(fn); + if (root$1 === undefined) { + root$1 = value; + } else { + const parent = stack[stack.length - 1]; - if (typeof cache.clear === 'function') { - cache.clear(); + if (Array.isArray(parent)) { + parent.push(value); + } else { + parent[key] = value; + } } -}; -mem_1.clear = clear; -var semver$2 = createCommonjsModule(function (module, exports) { - exports = module.exports = SemVer; - var debug; - /* istanbul ignore next */ + if (value !== null && typeof value === 'object') { + stack.push(value); - if (typeof process === 'object' && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG)) { - debug = function () { - var args = Array.prototype.slice.call(arguments, 0); - args.unshift('SEMVER'); - console.log.apply(console, args); - }; + if (Array.isArray(value)) { + parseState = 'beforeArrayValue'; + } else { + parseState = 'beforePropertyName'; + } } else { - debug = function () {}; - } // Note: this is the semver.org version of the spec that it implements - // Not necessarily the package version of this code. + const current = stack[stack.length - 1]; + if (current == null) { + parseState = 'end'; + } else if (Array.isArray(current)) { + parseState = 'afterArrayValue'; + } else { + parseState = 'afterPropertyValue'; + } + } +} - exports.SEMVER_SPEC_VERSION = '2.0.0'; - var MAX_LENGTH = 256; - var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || - /* istanbul ignore next */ - 9007199254740991; // Max safe segment length for coercion. - - var MAX_SAFE_COMPONENT_LENGTH = 16; // The actual regexps go on exports.re +function pop() { + stack.pop(); + const current = stack[stack.length - 1]; - var re = exports.re = []; - var src = exports.src = []; - var R = 0; // 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. + 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}'`) +// } - var NUMERICIDENTIFIER = R++; - src[NUMERICIDENTIFIER] = '0|[1-9]\\d*'; - var NUMERICIDENTIFIERLOOSE = R++; - src[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. - var NONNUMERICIDENTIFIER = R++; - src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*'; // ## Main Version - // Three dot-separated numeric identifiers. +function invalidChar(c) { + if (c === undefined) { + return syntaxError(`JSON5: invalid end of input at ${line$2}:${column}`); + } - var MAINVERSION = R++; - src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + '(' + src[NUMERICIDENTIFIER] + ')\\.' + '(' + src[NUMERICIDENTIFIER] + ')'; - var MAINVERSIONLOOSE = R++; - src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + '(' + src[NUMERICIDENTIFIERLOOSE] + ')'; // ## Pre-release Version Identifier - // A numeric identifier, or a non-numeric identifier. + return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line$2}:${column}`); +} - var PRERELEASEIDENTIFIER = R++; - src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + '|' + src[NONNUMERICIDENTIFIER] + ')'; - var PRERELEASEIDENTIFIERLOOSE = R++; - src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + '|' + src[NONNUMERICIDENTIFIER] + ')'; // ## Pre-release Version - // Hyphen, followed by one or more dot-separated pre-release version - // identifiers. +function invalidEOF() { + return syntaxError(`JSON5: invalid end of input at ${line$2}:${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}`) +// } - var PRERELEASE = R++; - src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))'; - var PRERELEASELOOSE = R++; - src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))'; // ## Build Metadata Identifier - // Any combination of digits, letters, or hyphens. - var BUILDIDENTIFIER = R++; - src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+'; // ## Build Metadata - // Plus sign, followed by one or more period-separated build metadata - // identifiers. +function invalidIdentifier() { + column -= 5; + return syntaxError(`JSON5: invalid identifier character at ${line$2}:${column}`); +} - var BUILD = R++; - src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + '(?:\\.' + src[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. +function separatorChar(c) { + console.warn(`JSON5: '${formatChar(c)}' in strings is not valid ECMAScript; consider escaping`); +} - var FULL = R++; - var FULLPLAIN = 'v?' + src[MAINVERSION] + src[PRERELEASE] + '?' + src[BUILD] + '?'; - src[FULL] = '^' + 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. +function formatChar(c) { + const replacements = { + "'": "\\'", + '"': '\\"', + '\\': '\\\\', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', + '\v': '\\v', + '\0': '\\0', + '\u2028': '\\u2028', + '\u2029': '\\u2029' + }; - var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + src[PRERELEASELOOSE] + '?' + src[BUILD] + '?'; - var LOOSE = R++; - src[LOOSE] = '^' + LOOSEPLAIN + '$'; - var GTLT = R++; - src[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. + if (replacements[c]) { + return replacements[c]; + } - var XRANGEIDENTIFIERLOOSE = R++; - src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*'; - var XRANGEIDENTIFIER = R++; - src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*'; - var XRANGEPLAIN = R++; - src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + '(?:' + src[PRERELEASE] + ')?' + src[BUILD] + '?' + ')?)?'; - var XRANGEPLAINLOOSE = R++; - src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:' + src[PRERELEASELOOSE] + ')?' + src[BUILD] + '?' + ')?)?'; - var XRANGE = R++; - src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$'; - var XRANGELOOSE = R++; - src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$'; // Coercion. - // Extract anything that could conceivably be a part of a valid semver + if (c < ' ') { + const hexString = c.charCodeAt(0).toString(16); + return '\\x' + ('00' + hexString).substring(hexString.length); + } - var COERCE = R++; - src[COERCE] = '(?:^|[^\\d])' + '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + '(?:$|[^\\d])'; // Tilde ranges. - // Meaning is "reasonably at or greater than" + return c; +} - var LONETILDE = R++; - src[LONETILDE] = '(?:~>?)'; - var TILDETRIM = R++; - src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+'; - re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g'); - var tildeTrimReplace = '$1~'; - var TILDE = R++; - src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$'; - var TILDELOOSE = R++; - src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$'; // Caret ranges. - // Meaning is "at least and backwards compatible with" +function syntaxError(message) { + const err = new SyntaxError(message); + err.lineNumber = line$2; + err.columnNumber = column; + return err; +} - var LONECARET = R++; - src[LONECARET] = '(?:\\^)'; - var CARETTRIM = R++; - src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+'; - re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g'); - var caretTrimReplace = '$1^'; - var CARET = R++; - src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$'; - var CARETLOOSE = R++; - src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$'; // A simple gt/lt/eq thing, or just "" to indicate "any version" +var stringify = function stringify(value, replacer, space) { + const stack = []; + let indent = ''; + let propertyList; + let replacerFunc; + let gap = ''; + let quote; - var COMPARATORLOOSE = R++; - src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$'; - var COMPARATOR = R++; - src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$'; // An expression to strip any whitespace between the gtlt and the thing - // it modifies, so that `> 1.2.3` ==> `>1.2.3` + if (replacer != null && typeof replacer === 'object' && !Array.isArray(replacer)) { + space = replacer.space; + quote = replacer.quote; + replacer = replacer.replacer; + } - var COMPARATORTRIM = R++; - src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')'; // this one has to use the /g flag + if (typeof replacer === 'function') { + replacerFunc = replacer; + } else if (Array.isArray(replacer)) { + propertyList = []; - re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g'); - var 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. + for (const v of replacer) { + let item; - var HYPHENRANGE = R++; - src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + '\\s+-\\s+' + '(' + src[XRANGEPLAIN] + ')' + '\\s*$'; - var HYPHENRANGELOOSE = R++; - src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + '\\s+-\\s+' + '(' + src[XRANGEPLAINLOOSE] + ')' + '\\s*$'; // Star ranges basically just allow anything at all. + if (typeof v === 'string') { + item = v; + } else if (typeof v === 'number' || v instanceof String || v instanceof Number) { + item = String(v); + } - var STAR = R++; - src[STAR] = '(<|>)?=?\\s*\\*'; // Compile to actual regexp objects. - // All are flag-free, unless they were created above with a flag. + if (item !== undefined && propertyList.indexOf(item) < 0) { + propertyList.push(item); + } + } + } - for (var i = 0; i < R; i++) { - debug(i, src[i]); + if (space instanceof Number) { + space = Number(space); + } else if (space instanceof String) { + space = String(space); + } - if (!re[i]) { - re[i] = new RegExp(src[i]); + 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); } - exports.parse = parse; + return serializeProperty('', { + '': value + }); - function parse(version, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - }; + 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 (version instanceof SemVer) { - return version; + if (replacerFunc) { + value = replacerFunc.call(holder, key, value); } - if (typeof version !== 'string') { - return null; + if (value instanceof Number) { + value = Number(value); + } else if (value instanceof String) { + value = String(value); + } else if (value instanceof Boolean) { + value = value.valueOf(); } - if (version.length > MAX_LENGTH) { - return null; + switch (value) { + case null: + return 'null'; + + case true: + return 'true'; + + case false: + return 'false'; } - var r = options.loose ? re[LOOSE] : re[FULL]; + if (typeof value === 'string') { + return quoteString(value); + } - if (!r.test(version)) { - return null; + if (typeof value === 'number') { + return String(value); } - try { - return new SemVer(version, options); - } catch (er) { - return null; + if (typeof value === 'object') { + return Array.isArray(value) ? serializeArray(value) : serializeObject(value); } + + return undefined; } - exports.valid = valid; + 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 = ''; - function valid(version, options) { - var v = parse(version, options); - return v ? v.version : null; - } + for (let i = 0; i < value.length; i++) { + const c = value[i]; - exports.clean = clean; + switch (c) { + case "'": + case '"': + quotes[c]++; + product += c; + continue; - function clean(version, options) { - var s = parse(version.trim().replace(/^[=v]+/, ''), options); - return s ? s.version : null; + case '\0': + if (util$2.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; } - exports.SemVer = SemVer; + function serializeObject(value) { + if (stack.indexOf(value) >= 0) { + throw TypeError('Converting circular structure to JSON5'); + } - function SemVer(version, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - }; + 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); + } } - if (version instanceof SemVer) { - if (version.loose === options.loose) { - return version; + let final; + + if (partial.length === 0) { + final = '{}'; + } else { + let properties; + + if (gap === '') { + properties = partial.join(','); + final = '{' + properties + '}'; } else { - version = version.version; + let separator = ',\n' + indent; + properties = partial.join(separator); + final = '{\n' + indent + properties + ',\n' + stepback + '}'; } - } else if (typeof version !== 'string') { - throw new TypeError('Invalid Version: ' + version); } - if (version.length > MAX_LENGTH) { - throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters'); - } + stack.pop(); + indent = stepback; + return final; + } - if (!(this instanceof SemVer)) { - return new SemVer(version, options); + function serializeKey(key) { + if (key.length === 0) { + return quoteString(key); } - debug('SemVer', version, options); - this.options = options; - this.loose = !!options.loose; - var m = version.trim().match(options.loose ? re[LOOSE] : re[FULL]); + const firstChar = String.fromCodePoint(key.codePointAt(0)); - if (!m) { - throw new TypeError('Invalid Version: ' + version); + if (!util$2.isIdStartChar(firstChar)) { + return quoteString(key); } - this.raw = version; // these are actually numbers + for (let i = firstChar.length; i < key.length; i++) { + if (!util$2.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) { + return quoteString(key); + } + } - this.major = +m[1]; - this.minor = +m[2]; - this.patch = +m[3]; + return key; + } - if (this.major > MAX_SAFE_INTEGER || this.major < 0) { - throw new TypeError('Invalid major version'); + function serializeArray(value) { + if (stack.indexOf(value) >= 0) { + throw TypeError('Converting circular structure to JSON5'); } - if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { - throw new TypeError('Invalid minor version'); - } + stack.push(value); + let stepback = indent; + indent = indent + gap; + let partial = []; - if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { - throw new TypeError('Invalid patch version'); - } // numberify any prerelease numeric ids + for (let i = 0; i < value.length; i++) { + const propertyString = serializeProperty(String(i), value); + partial.push(propertyString !== undefined ? propertyString : 'null'); + } + let final; - if (!m[4]) { - this.prerelease = []; + if (partial.length === 0) { + final = '[]'; } else { - this.prerelease = m[4].split('.').map(function (id) { - if (/^[0-9]+$/.test(id)) { - var num = +id; + if (gap === '') { + let properties = partial.join(','); + final = '[' + properties + ']'; + } else { + let separator = ',\n' + indent; + let properties = partial.join(separator); + final = '[\n' + indent + properties + ',\n' + stepback + ']'; + } + } - if (num >= 0 && num < MAX_SAFE_INTEGER) { - return num; - } - } + stack.pop(); + indent = stepback; + return final; + } +}; - return id; - }); - } +const JSON5 = { + parse: parse$2, + stringify +}; +var lib$5 = JSON5; - this.build = m[5] ? m[5].split('.') : []; - this.format(); +var dist$2 = /*#__PURE__*/Object.freeze({ + __proto__: null, + 'default': lib$5 +}); + +var require$$0$1 = /*@__PURE__*/getDefaultExportFromNamespaceIfPresent(dist$2); + +const { + parse: parse$3 +} = require$$0$1; + +var loadJson5 = function (filePath, content) { + try { + return parse$3(content); + } catch (error) { + error.message = `JSON5 Error in ${filePath}:\n${error.message}`; + throw error; } +}; - SemVer.prototype.format = function () { - this.version = this.major + '.' + this.minor + '.' + this.patch; +var caller = function () { + // see https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi + var origPrepareStackTrace = Error.prepareStackTrace; - if (this.prerelease.length) { - this.version += '-' + this.prerelease.join('.'); + Error.prepareStackTrace = function (_, stack) { + return stack; + }; + + var stack = new Error().stack; + Error.prepareStackTrace = origPrepareStackTrace; + return stack[2].getFileName(); +}; + +var pathParse = createCommonjsModule(function (module) { + + var isWindows = process.platform === 'win32'; // Regex to split a windows path into three parts: [*, device, slash, + // tail] windows-only + + var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; // Regex to split the tail part of the above into [*, dir, basename, ext] + + var splitTailRe = /^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/; + var win32 = {}; // Function to split a filename into [root, dir, basename, ext] + + function win32SplitPath(filename) { + // Separate device+slash from tail + var result = splitDeviceRe.exec(filename), + device = (result[1] || '') + (result[2] || ''), + tail = result[3] || ''; // Split the tail into dir, basename and extension + + var result2 = splitTailRe.exec(tail), + dir = result2[1], + basename = result2[2], + ext = result2[3]; + return [device, dir, basename, ext]; + } + + win32.parse = function (pathString) { + if (typeof pathString !== 'string') { + throw new TypeError("Parameter 'pathString' must be a string, not " + typeof pathString); } - return this.version; - }; + var allParts = win32SplitPath(pathString); - SemVer.prototype.toString = function () { - return this.version; - }; + if (!allParts || allParts.length !== 4) { + throw new TypeError("Invalid path '" + pathString + "'"); + } - SemVer.prototype.compare = function (other) { - debug('SemVer.compare', this.version, this.options, other); + return { + root: allParts[0], + dir: allParts[0] + allParts[1].slice(0, -1), + base: allParts[2], + ext: allParts[3], + name: allParts[2].slice(0, allParts[2].length - allParts[3].length) + }; + }; // Split a filename into [root, dir, basename, ext], unix version + // 'root' is just a slash, or nothing. - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options); + + var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; + var posix = {}; + + function posixSplitPath(filename) { + return splitPathRe.exec(filename).slice(1); + } + + posix.parse = function (pathString) { + if (typeof pathString !== 'string') { + throw new TypeError("Parameter 'pathString' must be a string, not " + typeof pathString); } - return this.compareMain(other) || this.comparePre(other); - }; + var allParts = posixSplitPath(pathString); - SemVer.prototype.compareMain = function (other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options); + if (!allParts || allParts.length !== 4) { + throw new TypeError("Invalid path '" + pathString + "'"); } - return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch); + allParts[1] = allParts[1] || ''; + allParts[2] = allParts[2] || ''; + allParts[3] = allParts[3] || ''; + return { + root: allParts[0], + dir: allParts[0] + allParts[1].slice(0, -1), + base: allParts[2], + ext: allParts[3], + name: allParts[2].slice(0, allParts[2].length - allParts[3].length) + }; }; - SemVer.prototype.comparePre = function (other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options); - } // NOT having a prerelease is > having one + if (isWindows) module.exports = win32.parse;else + /* posix */ + module.exports = posix.parse; + module.exports.posix = posix.parse; + module.exports.win32 = win32.parse; +}); +var parse$4 = path__default['default'].parse || pathParse; - 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; - } +var getNodeModulesDirs = function getNodeModulesDirs(absoluteStart, modules) { + var prefix = '/'; + + if (/^([A-Za-z]:)/.test(absoluteStart)) { + prefix = ''; + } else if (/^\\\\/.test(absoluteStart)) { + prefix = '\\\\'; + } + + var paths = [absoluteStart]; + var parsed = parse$4(absoluteStart); + + while (parsed.dir !== paths[paths.length - 1]) { + paths.push(parsed.dir); + parsed = parse$4(parsed.dir); + } + + return paths.reduce(function (dirs, aPath) { + return dirs.concat(modules.map(function (moduleDir) { + return path__default['default'].resolve(prefix, aPath, moduleDir); + })); + }, []); +}; + +var nodeModulesPaths = function nodeModulesPaths(start, opts, request) { + var modules = opts && opts.moduleDirectory ? [].concat(opts.moduleDirectory) : ['node_modules']; + + if (opts && typeof opts.paths === 'function') { + return opts.paths(request, start, function () { + return getNodeModulesDirs(start, modules); + }, opts); + } + + var dirs = getNodeModulesDirs(start, modules); + return opts && opts.paths ? dirs.concat(opts.paths) : dirs; +}; + +var normalizeOptions$2 = function (x, opts) { + /** + * This file is purposefully a passthrough. It's expected that third-party + * environments will override it at runtime in order to inject special logic + * into `resolve` (by manipulating the options). One such example is the PnP + * code path in Yarn. + */ + return opts || {}; +}; - var i = 0; +/* eslint no-invalid-this: 1 */ - do { - var a = this.prerelease[i]; - var b = other.prerelease[i]; - debug('prerelease compare', i, a, b); +var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible '; +var slice = Array.prototype.slice; +var toStr = Object.prototype.toString; +var funcType = '[object Function]'; - 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. +var implementation = function bind(that) { + var target = this; + if (typeof target !== 'function' || toStr.call(target) !== funcType) { + throw new TypeError(ERROR_MESSAGE + target); + } - SemVer.prototype.inc = function (release, identifier) { - switch (release) { - case 'premajor': - this.prerelease.length = 0; - this.patch = 0; - this.minor = 0; - this.major++; - this.inc('pre', identifier); - break; + var args = slice.call(arguments, 1); + var bound; - case 'preminor': - this.prerelease.length = 0; - this.patch = 0; - this.minor++; - this.inc('pre', identifier); - break; + var binder = function () { + if (this instanceof bound) { + var result = target.apply(this, args.concat(slice.call(arguments))); - 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. + if (Object(result) === result) { + return result; + } - case 'prerelease': - if (this.prerelease.length === 0) { - this.inc('patch', identifier); - } + return this; + } else { + return target.apply(that, args.concat(slice.call(arguments))); + } + }; - this.inc('pre', identifier); - break; + var boundLength = Math.max(0, target.length - args.length); + var boundArgs = []; - 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++; - } + for (var i = 0; i < boundLength; i++) { + boundArgs.push('$' + i); + } - this.minor = 0; - this.patch = 0; - this.prerelease = []; - break; + bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this,arguments); }')(binder); - 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++; - } + if (target.prototype) { + var Empty = function Empty() {}; - this.patch = 0; - this.prerelease = []; - break; + Empty.prototype = target.prototype; + bound.prototype = new Empty(); + Empty.prototype = null; + } - 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++; - } + return bound; +}; - 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. +var functionBind = Function.prototype.bind || implementation; - case 'pre': - if (this.prerelease.length === 0) { - this.prerelease = [0]; - } else { - var i = this.prerelease.length; +var src = functionBind.call(Function.call, Object.prototype.hasOwnProperty); - while (--i >= 0) { - if (typeof this.prerelease[i] === 'number') { - this.prerelease[i]++; - i = -2; - } - } +var assert = true; +var async_hooks = ">= 8"; +var buffer_ieee754 = "< 0.9.7"; +var buffer$1 = true; +var child_process = true; +var cluster = true; +var console$1 = true; +var constants$1 = true; +var crypto = true; +var _debug_agent = ">= 1 && < 8"; +var _debugger = "< 8"; +var dgram = true; +var diagnostics_channel = ">= 15.1"; +var dns = true; +var domain = ">= 0.7.12"; +var events = true; +var freelist = "< 6"; +var fs = true; +var _http_agent = ">= 0.11.1"; +var _http_client = ">= 0.11.1"; +var _http_common = ">= 0.11.1"; +var _http_incoming = ">= 0.11.1"; +var _http_outgoing = ">= 0.11.1"; +var _http_server = ">= 0.11.1"; +var http = true; +var http2 = ">= 8.8"; +var https = true; +var inspector = ">= 8.0.0"; +var _linklist = "< 8"; +var module$1 = true; +var net = true; +var os = true; +var path$1 = true; +var perf_hooks = ">= 8.5"; +var process$1 = ">= 1"; +var punycode = true; +var querystring = true; +var readline = true; +var repl = true; +var smalloc = ">= 0.11.5 && < 3"; +var _stream_duplex = ">= 0.9.4"; +var _stream_transform = ">= 0.9.4"; +var _stream_wrap = ">= 1.4.1"; +var _stream_passthrough = ">= 0.9.4"; +var _stream_readable = ">= 0.9.4"; +var _stream_writable = ">= 0.9.4"; +var stream = true; +var string_decoder = true; +var sys = [ + ">= 0.6 && < 0.7", + ">= 0.8" +]; +var timers = true; +var _tls_common = ">= 0.11.13"; +var _tls_legacy = ">= 0.11.3 && < 10"; +var _tls_wrap = ">= 0.11.3"; +var tls = true; +var trace_events = ">= 10"; +var tty = true; +var url = true; +var util$3 = true; +var v8 = ">= 1"; +var vm = true; +var wasi = ">= 13.4 && < 13.5"; +var worker_threads = ">= 11.7"; +var zlib = true; +var data = { + assert: assert, + "assert/strict": ">= 15", + async_hooks: async_hooks, + buffer_ieee754: buffer_ieee754, + buffer: buffer$1, + child_process: child_process, + cluster: cluster, + console: console$1, + constants: constants$1, + crypto: crypto, + _debug_agent: _debug_agent, + _debugger: _debugger, + dgram: dgram, + diagnostics_channel: diagnostics_channel, + dns: dns, + "dns/promises": ">= 15", + domain: domain, + events: events, + freelist: freelist, + fs: fs, + "fs/promises": [ + ">= 10 && < 10.1", + ">= 14" +], + _http_agent: _http_agent, + _http_client: _http_client, + _http_common: _http_common, + _http_incoming: _http_incoming, + _http_outgoing: _http_outgoing, + _http_server: _http_server, + http: http, + http2: http2, + https: https, + inspector: inspector, + _linklist: _linklist, + module: module$1, + net: net, + "node-inspect/lib/_inspect": ">= 7.6.0 && < 12", + "node-inspect/lib/internal/inspect_client": ">= 7.6.0 && < 12", + "node-inspect/lib/internal/inspect_repl": ">= 7.6.0 && < 12", + os: os, + path: path$1, + perf_hooks: perf_hooks, + process: process$1, + punycode: punycode, + querystring: querystring, + readline: readline, + repl: repl, + smalloc: smalloc, + _stream_duplex: _stream_duplex, + _stream_transform: _stream_transform, + _stream_wrap: _stream_wrap, + _stream_passthrough: _stream_passthrough, + _stream_readable: _stream_readable, + _stream_writable: _stream_writable, + stream: stream, + "stream/promises": ">= 15", + string_decoder: string_decoder, + sys: sys, + timers: timers, + "timers/promises": ">= 15", + _tls_common: _tls_common, + _tls_legacy: _tls_legacy, + _tls_wrap: _tls_wrap, + tls: tls, + trace_events: trace_events, + tty: tty, + url: url, + util: util$3, + "v8/tools/arguments": ">= 10 && < 12", + "v8/tools/codemap": [ + ">= 4.4.0 && < 5", + ">= 5.2.0 && < 12" +], + "v8/tools/consarray": [ + ">= 4.4.0 && < 5", + ">= 5.2.0 && < 12" +], + "v8/tools/csvparser": [ + ">= 4.4.0 && < 5", + ">= 5.2.0 && < 12" +], + "v8/tools/logreader": [ + ">= 4.4.0 && < 5", + ">= 5.2.0 && < 12" +], + "v8/tools/profile_view": [ + ">= 4.4.0 && < 5", + ">= 5.2.0 && < 12" +], + "v8/tools/splaytree": [ + ">= 4.4.0 && < 5", + ">= 5.2.0 && < 12" +], + v8: v8, + vm: vm, + wasi: wasi, + worker_threads: worker_threads, + zlib: zlib +}; - if (i === -1) { - // didn't increment anything - this.prerelease.push(0); - } - } +function specifierIncluded(current, specifier) { + var nodeParts = current.split('.'); + var parts = specifier.split(' '); + var op = parts.length > 1 ? parts[0] : '='; + var versionParts = (parts.length > 1 ? parts[1] : parts[0]).split('.'); - 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]; - } - } + for (var i = 0; i < 3; ++i) { + var cur = parseInt(nodeParts[i] || 0, 10); + var ver = parseInt(versionParts[i] || 0, 10); - break; + if (cur === ver) { + continue; // eslint-disable-line no-restricted-syntax, no-continue + } - default: - throw new Error('invalid increment argument: ' + release); + if (op === '<') { + return cur < ver; } - this.format(); - this.raw = this.version; - return this; - }; + if (op === '>=') { + return cur >= ver; + } - exports.inc = inc; + return false; + } - function inc(version, release, loose, identifier) { - if (typeof loose === 'string') { - identifier = loose; - loose = undefined; - } + return op === '>='; +} - try { - return new SemVer(version, loose).inc(release, identifier).version; - } catch (er) { - return null; +function matchesRange(current, range) { + var specifiers = range.split(/ ?&& ?/); + + if (specifiers.length === 0) { + return false; + } + + for (var i = 0; i < specifiers.length; ++i) { + if (!specifierIncluded(current, specifiers[i])) { + return false; } } - exports.diff = diff; + return true; +} - function diff(version1, version2) { - if (eq(version1, version2)) { - return null; - } else { - var v1 = parse(version1); - var v2 = parse(version2); - var prefix = ''; +function versionIncluded(nodeVersion, specifierValue) { + if (typeof specifierValue === 'boolean') { + return specifierValue; + } - if (v1.prerelease.length || v2.prerelease.length) { - prefix = 'pre'; - var defaultResult = 'prerelease'; - } + var current = typeof nodeVersion === 'undefined' ? process.versions && process.versions.node && process.versions.node : nodeVersion; - for (var key in v1) { - if (key === 'major' || key === 'minor' || key === 'patch') { - if (v1[key] !== v2[key]) { - return prefix + key; - } - } - } + if (typeof current !== 'string') { + throw new TypeError(typeof nodeVersion === 'undefined' ? 'Unable to determine current node version' : 'If provided, a valid node version is required'); + } - return defaultResult; // may be undefined + if (specifierValue && typeof specifierValue === 'object') { + for (var i = 0; i < specifierValue.length; ++i) { + if (matchesRange(current, specifierValue[i])) { + return true; + } } + + return false; } - exports.compareIdentifiers = compareIdentifiers; - var numeric = /^[0-9]+$/; + return matchesRange(current, specifierValue); +} - function compareIdentifiers(a, b) { - var anum = numeric.test(a); - var bnum = numeric.test(b); +var isCoreModule = function isCore(x, nodeVersion) { + return src(data, x) && versionIncluded(nodeVersion, data[x]); +}; - if (anum && bnum) { - a = +a; - b = +b; +var realpathFS = fs__default['default'].realpath && typeof fs__default['default'].realpath.native === 'function' ? fs__default['default'].realpath.native : fs__default['default'].realpath; + +var defaultIsFile = function isFile(file, cb) { + fs__default['default'].stat(file, function (err, stat) { + if (!err) { + return cb(null, stat.isFile() || stat.isFIFO()); } - return a === b ? 0 : anum && !bnum ? -1 : bnum && !anum ? 1 : a < b ? -1 : 1; - } + if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false); + return cb(err); + }); +}; - exports.rcompareIdentifiers = rcompareIdentifiers; +var defaultIsDir = function isDirectory(dir, cb) { + fs__default['default'].stat(dir, function (err, stat) { + if (!err) { + return cb(null, stat.isDirectory()); + } - function rcompareIdentifiers(a, b) { - return compareIdentifiers(b, a); - } + if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false); + return cb(err); + }); +}; - exports.major = major; +var defaultRealpath = function realpath(x, cb) { + realpathFS(x, function (realpathErr, realPath) { + if (realpathErr && realpathErr.code !== 'ENOENT') cb(realpathErr);else cb(null, realpathErr ? x : realPath); + }); +}; - function major(a, loose) { - return new SemVer(a, loose).major; +var maybeRealpath = function maybeRealpath(realpath, x, opts, cb) { + if (opts && opts.preserveSymlinks === false) { + realpath(x, cb); + } else { + cb(null, x); } +}; - exports.minor = minor; +var getPackageCandidates = function getPackageCandidates(x, start, opts) { + var dirs = nodeModulesPaths(start, opts, x); - function minor(a, loose) { - return new SemVer(a, loose).minor; + for (var i = 0; i < dirs.length; i++) { + dirs[i] = path__default['default'].join(dirs[i], x); } - exports.patch = patch; - - function patch(a, loose) { - return new SemVer(a, loose).patch; - } + return dirs; +}; - exports.compare = compare; +var async = function resolve(x, options, callback) { + var cb = callback; + var opts = options; - function compare(a, b, loose) { - return new SemVer(a, loose).compare(new SemVer(b, loose)); + if (typeof options === 'function') { + cb = opts; + opts = {}; } - exports.compareLoose = compareLoose; - - function compareLoose(a, b) { - return compare(a, b, true); + if (typeof x !== 'string') { + var err = new TypeError('Path must be a string.'); + return process.nextTick(function () { + cb(err); + }); } - exports.rcompare = rcompare; + opts = normalizeOptions$2(x, opts); + var isFile = opts.isFile || defaultIsFile; + var isDirectory = opts.isDirectory || defaultIsDir; + var readFile = opts.readFile || fs__default['default'].readFile; + var realpath = opts.realpath || defaultRealpath; + var packageIterator = opts.packageIterator; + var extensions = opts.extensions || ['.js']; + var includeCoreModules = opts.includeCoreModules !== false; + var basedir = opts.basedir || path__default['default'].dirname(caller()); + var parent = opts.filename || basedir; + opts.paths = opts.paths || []; // ensure that `basedir` is an absolute path at this point, resolving against the process' current working directory - function rcompare(a, b, loose) { - return compare(b, a, loose); - } + var absoluteStart = path__default['default'].resolve(basedir); + maybeRealpath(realpath, absoluteStart, opts, function (err, realStart) { + if (err) cb(err);else init(realStart); + }); + var res; - exports.sort = sort; + function init(basedir) { + if (/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/.test(x)) { + res = path__default['default'].resolve(basedir, x); + if (x === '.' || x === '..' || x.slice(-1) === '/') res += '/'; - function sort(list, loose) { - return list.sort(function (a, b) { - return exports.compare(a, b, loose); + if (/\/$/.test(x) && res === basedir) { + loadAsDirectory(res, opts.package, onfile); + } else loadAsFile(res, opts.package, onfile); + } else if (includeCoreModules && isCoreModule(x)) { + return cb(null, x); + } else loadNodeModules(x, basedir, function (err, n, pkg) { + if (err) cb(err);else if (n) { + return maybeRealpath(realpath, n, opts, function (err, realN) { + if (err) { + cb(err); + } else { + cb(null, realN, pkg); + } + }); + } else { + var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'"); + moduleError.code = 'MODULE_NOT_FOUND'; + cb(moduleError); + } }); } - exports.rsort = rsort; - - function rsort(list, loose) { - return list.sort(function (a, b) { - return exports.rcompare(a, b, loose); + function onfile(err, m, pkg) { + if (err) cb(err);else if (m) cb(null, m, pkg);else loadAsDirectory(res, function (err, d, pkg) { + if (err) cb(err);else if (d) { + maybeRealpath(realpath, d, opts, function (err, realD) { + if (err) { + cb(err); + } else { + cb(null, realD, pkg); + } + }); + } else { + var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'"); + moduleError.code = 'MODULE_NOT_FOUND'; + cb(moduleError); + } }); } - exports.gt = gt; + function loadAsFile(x, thePackage, callback) { + var loadAsFilePackage = thePackage; + var cb = callback; - function gt(a, b, loose) { - return compare(a, b, loose) > 0; - } + if (typeof loadAsFilePackage === 'function') { + cb = loadAsFilePackage; + loadAsFilePackage = undefined; + } - exports.lt = lt; + var exts = [''].concat(extensions); + load(exts, x, loadAsFilePackage); - function lt(a, b, loose) { - return compare(a, b, loose) < 0; - } + function load(exts, x, loadPackage) { + if (exts.length === 0) return cb(null, undefined, loadPackage); + var file = x + exts[0]; + var pkg = loadPackage; + if (pkg) onpkg(null, pkg);else loadpkg(path__default['default'].dirname(file), onpkg); - exports.eq = eq; + function onpkg(err, pkg_, dir) { + pkg = pkg_; + if (err) return cb(err); - function eq(a, b, loose) { - return compare(a, b, loose) === 0; + if (dir && pkg && opts.pathFilter) { + var rfile = path__default['default'].relative(dir, file); + var rel = rfile.slice(0, rfile.length - exts[0].length); + var r = opts.pathFilter(pkg, x, rel); + if (r) return load([''].concat(extensions.slice()), path__default['default'].resolve(dir, r), pkg); + } + + isFile(file, onex); + } + + function onex(err, ex) { + if (err) return cb(err); + if (ex) return cb(null, file, pkg); + load(exts.slice(1), x, pkg); + } + } } - exports.neq = neq; + function loadpkg(dir, cb) { + if (dir === '' || dir === '/') return cb(null); - function neq(a, b, loose) { - return compare(a, b, loose) !== 0; - } + if (process.platform === 'win32' && /^\w:[/\\]*$/.test(dir)) { + return cb(null); + } - exports.gte = gte; + if (/[/\\]node_modules[/\\]*$/.test(dir)) return cb(null); + maybeRealpath(realpath, dir, opts, function (unwrapErr, pkgdir) { + if (unwrapErr) return loadpkg(path__default['default'].dirname(dir), cb); + var pkgfile = path__default['default'].join(pkgdir, 'package.json'); + isFile(pkgfile, function (err, ex) { + // on err, ex is false + if (!ex) return loadpkg(path__default['default'].dirname(dir), cb); + readFile(pkgfile, function (err, body) { + if (err) cb(err); - function gte(a, b, loose) { - return compare(a, b, loose) >= 0; - } + try { + var pkg = JSON.parse(body); + } catch (jsonErr) {} - exports.lte = lte; + if (pkg && opts.packageFilter) { + pkg = opts.packageFilter(pkg, pkgfile); + } - function lte(a, b, loose) { - return compare(a, b, loose) <= 0; + cb(null, pkg, dir); + }); + }); + }); } - exports.cmp = cmp; - - function cmp(a, op, b, loose) { - switch (op) { - case '===': - if (typeof a === 'object') a = a.version; - if (typeof b === 'object') b = b.version; - return a === b; + function loadAsDirectory(x, loadAsDirectoryPackage, callback) { + var cb = callback; + var fpkg = loadAsDirectoryPackage; - case '!==': - if (typeof a === 'object') a = a.version; - if (typeof b === 'object') b = b.version; - return a !== b; + if (typeof fpkg === 'function') { + cb = fpkg; + fpkg = opts.package; + } - case '': - case '=': - case '==': - return eq(a, b, loose); + maybeRealpath(realpath, x, opts, function (unwrapErr, pkgdir) { + if (unwrapErr) return cb(unwrapErr); + var pkgfile = path__default['default'].join(pkgdir, 'package.json'); + isFile(pkgfile, function (err, ex) { + if (err) return cb(err); + if (!ex) return loadAsFile(path__default['default'].join(x, 'index'), fpkg, cb); + readFile(pkgfile, function (err, body) { + if (err) return cb(err); - case '!=': - return neq(a, b, loose); + try { + var pkg = JSON.parse(body); + } catch (jsonErr) {} - case '>': - return gt(a, b, loose); + if (pkg && opts.packageFilter) { + pkg = opts.packageFilter(pkg, pkgfile); + } - case '>=': - return gte(a, b, loose); + if (pkg && pkg.main) { + if (typeof pkg.main !== 'string') { + var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string'); + mainError.code = 'INVALID_PACKAGE_MAIN'; + return cb(mainError); + } - case '<': - return lt(a, b, loose); + if (pkg.main === '.' || pkg.main === './') { + pkg.main = 'index'; + } - case '<=': - return lte(a, b, loose); + loadAsFile(path__default['default'].resolve(x, pkg.main), pkg, function (err, m, pkg) { + if (err) return cb(err); + if (m) return cb(null, m, pkg); + if (!pkg) return loadAsFile(path__default['default'].join(x, 'index'), pkg, cb); + var dir = path__default['default'].resolve(x, pkg.main); + loadAsDirectory(dir, pkg, function (err, n, pkg) { + if (err) return cb(err); + if (n) return cb(null, n, pkg); + loadAsFile(path__default['default'].join(x, 'index'), pkg, cb); + }); + }); + return; + } - default: - throw new TypeError('Invalid operator: ' + op); - } + loadAsFile(path__default['default'].join(x, '/index'), pkg, cb); + }); + }); + }); } - exports.Comparator = Comparator; + function processDirs(cb, dirs) { + if (dirs.length === 0) return cb(null, undefined); + var dir = dirs[0]; + isDirectory(path__default['default'].dirname(dir), isdir); - function Comparator(comp, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - }; + function isdir(err, isdir) { + if (err) return cb(err); + if (!isdir) return processDirs(cb, dirs.slice(1)); + loadAsFile(dir, opts.package, onfile); } - if (comp instanceof Comparator) { - if (comp.loose === !!options.loose) { - return comp; - } else { - comp = comp.value; - } + function onfile(err, m, pkg) { + if (err) return cb(err); + if (m) return cb(null, m, pkg); + loadAsDirectory(dir, opts.package, ondir); } - if (!(this instanceof Comparator)) { - return new Comparator(comp, options); + function ondir(err, n, pkg) { + if (err) return cb(err); + if (n) return cb(null, n, pkg); + processDirs(cb, dirs.slice(1)); } + } - debug('comparator', comp, options); - this.options = options; - this.loose = !!options.loose; - this.parse(comp); - - if (this.semver === ANY) { - this.value = ''; - } else { - this.value = this.operator + this.semver.version; - } + function loadNodeModules(x, start, cb) { + var thunk = function () { + return getPackageCandidates(x, start, opts); + }; - debug('comp', this); + processDirs(cb, packageIterator ? packageIterator(x, start, thunk, opts) : thunk()); } +}; - var ANY = {}; - - Comparator.prototype.parse = function (comp) { - var r = this.options.loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; - var m = comp.match(r); +var assert$1 = true; +var async_hooks$1 = ">= 8"; +var buffer_ieee754$1 = "< 0.9.7"; +var buffer$2 = true; +var child_process$1 = true; +var cluster$1 = true; +var console$2 = true; +var constants$2 = true; +var crypto$1 = true; +var _debug_agent$1 = ">= 1 && < 8"; +var _debugger$1 = "< 8"; +var dgram$1 = true; +var diagnostics_channel$1 = ">= 15.1"; +var dns$1 = true; +var domain$1 = ">= 0.7.12"; +var events$1 = true; +var freelist$1 = "< 6"; +var fs$1 = true; +var _http_agent$1 = ">= 0.11.1"; +var _http_client$1 = ">= 0.11.1"; +var _http_common$1 = ">= 0.11.1"; +var _http_incoming$1 = ">= 0.11.1"; +var _http_outgoing$1 = ">= 0.11.1"; +var _http_server$1 = ">= 0.11.1"; +var http$1 = true; +var http2$1 = ">= 8.8"; +var https$1 = true; +var inspector$1 = ">= 8.0.0"; +var _linklist$1 = "< 8"; +var module$2 = true; +var net$1 = true; +var os$1 = true; +var path$2 = true; +var perf_hooks$1 = ">= 8.5"; +var process$2 = ">= 1"; +var punycode$1 = true; +var querystring$1 = true; +var readline$1 = true; +var repl$1 = true; +var smalloc$1 = ">= 0.11.5 && < 3"; +var _stream_duplex$1 = ">= 0.9.4"; +var _stream_transform$1 = ">= 0.9.4"; +var _stream_wrap$1 = ">= 1.4.1"; +var _stream_passthrough$1 = ">= 0.9.4"; +var _stream_readable$1 = ">= 0.9.4"; +var _stream_writable$1 = ">= 0.9.4"; +var stream$1 = true; +var string_decoder$1 = true; +var sys$1 = [ + ">= 0.6 && < 0.7", + ">= 0.8" +]; +var timers$1 = true; +var _tls_common$1 = ">= 0.11.13"; +var _tls_legacy$1 = ">= 0.11.3 && < 10"; +var _tls_wrap$1 = ">= 0.11.3"; +var tls$1 = true; +var trace_events$1 = ">= 10"; +var tty$1 = true; +var url$1 = true; +var util$4 = true; +var v8$1 = ">= 1"; +var vm$1 = true; +var wasi$1 = ">= 13.4 && < 13.5"; +var worker_threads$1 = ">= 11.7"; +var zlib$1 = true; +var data$1 = { + assert: assert$1, + "assert/strict": ">= 15", + async_hooks: async_hooks$1, + buffer_ieee754: buffer_ieee754$1, + buffer: buffer$2, + child_process: child_process$1, + cluster: cluster$1, + console: console$2, + constants: constants$2, + crypto: crypto$1, + _debug_agent: _debug_agent$1, + _debugger: _debugger$1, + dgram: dgram$1, + diagnostics_channel: diagnostics_channel$1, + dns: dns$1, + "dns/promises": ">= 15", + domain: domain$1, + events: events$1, + freelist: freelist$1, + fs: fs$1, + "fs/promises": [ + ">= 10 && < 10.1", + ">= 14" +], + _http_agent: _http_agent$1, + _http_client: _http_client$1, + _http_common: _http_common$1, + _http_incoming: _http_incoming$1, + _http_outgoing: _http_outgoing$1, + _http_server: _http_server$1, + http: http$1, + http2: http2$1, + https: https$1, + inspector: inspector$1, + _linklist: _linklist$1, + module: module$2, + net: net$1, + "node-inspect/lib/_inspect": ">= 7.6.0 && < 12", + "node-inspect/lib/internal/inspect_client": ">= 7.6.0 && < 12", + "node-inspect/lib/internal/inspect_repl": ">= 7.6.0 && < 12", + os: os$1, + path: path$2, + perf_hooks: perf_hooks$1, + process: process$2, + punycode: punycode$1, + querystring: querystring$1, + readline: readline$1, + repl: repl$1, + smalloc: smalloc$1, + _stream_duplex: _stream_duplex$1, + _stream_transform: _stream_transform$1, + _stream_wrap: _stream_wrap$1, + _stream_passthrough: _stream_passthrough$1, + _stream_readable: _stream_readable$1, + _stream_writable: _stream_writable$1, + stream: stream$1, + "stream/promises": ">= 15", + string_decoder: string_decoder$1, + sys: sys$1, + timers: timers$1, + "timers/promises": ">= 15", + _tls_common: _tls_common$1, + _tls_legacy: _tls_legacy$1, + _tls_wrap: _tls_wrap$1, + tls: tls$1, + trace_events: trace_events$1, + tty: tty$1, + url: url$1, + util: util$4, + "v8/tools/arguments": ">= 10 && < 12", + "v8/tools/codemap": [ + ">= 4.4.0 && < 5", + ">= 5.2.0 && < 12" +], + "v8/tools/consarray": [ + ">= 4.4.0 && < 5", + ">= 5.2.0 && < 12" +], + "v8/tools/csvparser": [ + ">= 4.4.0 && < 5", + ">= 5.2.0 && < 12" +], + "v8/tools/logreader": [ + ">= 4.4.0 && < 5", + ">= 5.2.0 && < 12" +], + "v8/tools/profile_view": [ + ">= 4.4.0 && < 5", + ">= 5.2.0 && < 12" +], + "v8/tools/splaytree": [ + ">= 4.4.0 && < 5", + ">= 5.2.0 && < 12" +], + v8: v8$1, + vm: vm$1, + wasi: wasi$1, + worker_threads: worker_threads$1, + zlib: zlib$1 +}; - if (!m) { - throw new TypeError('Invalid comparator: ' + comp); - } +var current = process.versions && process.versions.node && process.versions.node.split('.') || []; - this.operator = m[1]; +function specifierIncluded$1(specifier) { + var parts = specifier.split(' '); + var op = parts.length > 1 ? parts[0] : '='; + var versionParts = (parts.length > 1 ? parts[1] : parts[0]).split('.'); - if (this.operator === '=') { - this.operator = ''; - } // if it literally is just '>' or '' then allow anything. + for (var i = 0; i < 3; ++i) { + var cur = parseInt(current[i] || 0, 10); + var ver = parseInt(versionParts[i] || 0, 10); + if (cur === ver) { + continue; // eslint-disable-line no-restricted-syntax, no-continue + } - if (!m[2]) { - this.semver = ANY; + if (op === '<') { + return cur < ver; + } else if (op === '>=') { + return cur >= ver; } else { - this.semver = new SemVer(m[2], this.options.loose); + return false; } - }; + } - Comparator.prototype.toString = function () { - return this.value; - }; + return op === '>='; +} - Comparator.prototype.test = function (version) { - debug('Comparator.test', version, this.options.loose); +function matchesRange$1(range) { + var specifiers = range.split(/ ?&& ?/); - if (this.semver === ANY) { - return true; - } + if (specifiers.length === 0) { + return false; + } - if (typeof version === 'string') { - version = new SemVer(version, this.options); + for (var i = 0; i < specifiers.length; ++i) { + if (!specifierIncluded$1(specifiers[i])) { + return false; } + } - return cmp(version, this.operator, this.semver, this.options); - }; + return true; +} - Comparator.prototype.intersects = function (comp, options) { - if (!(comp instanceof Comparator)) { - throw new TypeError('a Comparator is required'); - } +function versionIncluded$1(specifierValue) { + if (typeof specifierValue === 'boolean') { + return specifierValue; + } - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - }; + if (specifierValue && typeof specifierValue === 'object') { + for (var i = 0; i < specifierValue.length; ++i) { + if (matchesRange$1(specifierValue[i])) { + return true; + } } - var rangeTmp; + return false; + } - if (this.operator === '') { - rangeTmp = new Range(comp.value, options); - return satisfies(this.value, rangeTmp, options); - } else if (comp.operator === '') { - rangeTmp = new Range(this.value, options); - return satisfies(comp.semver, rangeTmp, options); - } + return matchesRange$1(specifierValue); +} - var sameDirectionIncreasing = (this.operator === '>=' || this.operator === '>') && (comp.operator === '>=' || comp.operator === '>'); - var sameDirectionDecreasing = (this.operator === '<=' || this.operator === '<') && (comp.operator === '<=' || comp.operator === '<'); - var sameSemVer = this.semver.version === comp.semver.version; - var differentDirectionsInclusive = (this.operator === '>=' || this.operator === '<=') && (comp.operator === '>=' || comp.operator === '<='); - var oppositeDirectionsLessThan = cmp(this.semver, '<', comp.semver, options) && (this.operator === '>=' || this.operator === '>') && (comp.operator === '<=' || comp.operator === '<'); - var oppositeDirectionsGreaterThan = cmp(this.semver, '>', comp.semver, options) && (this.operator === '<=' || this.operator === '<') && (comp.operator === '>=' || comp.operator === '>'); - return sameDirectionIncreasing || sameDirectionDecreasing || sameSemVer && differentDirectionsInclusive || oppositeDirectionsLessThan || oppositeDirectionsGreaterThan; - }; +var core$1 = {}; - exports.Range = Range; +for (var mod in data$1) { + // eslint-disable-line no-restricted-syntax + if (Object.prototype.hasOwnProperty.call(data$1, mod)) { + core$1[mod] = versionIncluded$1(data$1[mod]); + } +} - function Range(range, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - }; - } +var core_1 = core$1; - if (range instanceof Range) { - if (range.loose === !!options.loose && range.includePrerelease === !!options.includePrerelease) { - return range; - } else { - return new Range(range.raw, options); - } - } +var isCore = function isCore(x) { + return isCoreModule(x); +}; - if (range instanceof Comparator) { - return new Range(range.value, options); - } +var realpathFS$1 = fs__default['default'].realpathSync && typeof fs__default['default'].realpathSync.native === 'function' ? fs__default['default'].realpathSync.native : fs__default['default'].realpathSync; - if (!(this instanceof Range)) { - return new Range(range, options); - } +var defaultIsFile$1 = function isFile(file) { + try { + var stat = fs__default['default'].statSync(file); + } catch (e) { + if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false; + throw e; + } - this.options = options; - this.loose = !!options.loose; - this.includePrerelease = !!options.includePrerelease; // First, split based on boolean or || + return stat.isFile() || stat.isFIFO(); +}; - this.raw = range; - this.set = range.split(/\s*\|\|\s*/).map(function (range) { - return this.parseRange(range.trim()); - }, this).filter(function (c) { - // throw out any that are not relevant for whatever reason - return c.length; - }); +var defaultIsDir$1 = function isDirectory(dir) { + try { + var stat = fs__default['default'].statSync(dir); + } catch (e) { + if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false; + throw e; + } - if (!this.set.length) { - throw new TypeError('Invalid SemVer Range: ' + range); + return stat.isDirectory(); +}; + +var defaultRealpathSync = function realpathSync(x) { + try { + return realpathFS$1(x); + } catch (realpathErr) { + if (realpathErr.code !== 'ENOENT') { + throw realpathErr; } + } - this.format(); + return x; +}; + +var maybeRealpathSync = function maybeRealpathSync(realpathSync, x, opts) { + if (opts && opts.preserveSymlinks === false) { + return realpathSync(x); } - Range.prototype.format = function () { - this.range = this.set.map(function (comps) { - return comps.join(' ').trim(); - }).join('||').trim(); - return this.range; - }; + return x; +}; - Range.prototype.toString = function () { - return this.range; - }; +var getPackageCandidates$1 = function getPackageCandidates(x, start, opts) { + var dirs = nodeModulesPaths(start, opts, x); - Range.prototype.parseRange = function (range) { - var loose = this.options.loose; - range = range.trim(); // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` + for (var i = 0; i < dirs.length; i++) { + dirs[i] = path__default['default'].join(dirs[i], x); + } - var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE]; - range = range.replace(hr, hyphenReplace); - debug('hyphen replace', range); // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` + return dirs; +}; - range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace); - debug('comparator trim', range, re[COMPARATORTRIM]); // `~ 1.2.3` => `~1.2.3` +var sync = function resolveSync(x, options) { + if (typeof x !== 'string') { + throw new TypeError('Path must be a string.'); + } - range = range.replace(re[TILDETRIM], tildeTrimReplace); // `^ 1.2.3` => `^1.2.3` + var opts = normalizeOptions$2(x, options); + var isFile = opts.isFile || defaultIsFile$1; + var readFileSync = opts.readFileSync || fs__default['default'].readFileSync; + var isDirectory = opts.isDirectory || defaultIsDir$1; + var realpathSync = opts.realpathSync || defaultRealpathSync; + var packageIterator = opts.packageIterator; + var extensions = opts.extensions || ['.js']; + var includeCoreModules = opts.includeCoreModules !== false; + var basedir = opts.basedir || path__default['default'].dirname(caller()); + var parent = opts.filename || basedir; + opts.paths = opts.paths || []; // ensure that `basedir` is an absolute path at this point, resolving against the process' current working directory - range = range.replace(re[CARETTRIM], caretTrimReplace); // normalize spaces + var absoluteStart = maybeRealpathSync(realpathSync, path__default['default'].resolve(basedir), opts); - range = range.split(/\s+/).join(' '); // At this point, the range is completely trimmed and - // ready to be split into comparators. + if (/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/.test(x)) { + var res = path__default['default'].resolve(absoluteStart, x); + if (x === '.' || x === '..' || x.slice(-1) === '/') res += '/'; + var m = loadAsFileSync(res) || loadAsDirectorySync(res); + if (m) return maybeRealpathSync(realpathSync, m, opts); + } else if (includeCoreModules && isCoreModule(x)) { + return x; + } else { + var n = loadNodeModulesSync(x, absoluteStart); + if (n) return maybeRealpathSync(realpathSync, n, opts); + } - var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; - var set = range.split(' ').map(function (comp) { - return parseComparator(comp, this.options); - }, this).join(' ').split(/\s+/); + var err = new Error("Cannot find module '" + x + "' from '" + parent + "'"); + err.code = 'MODULE_NOT_FOUND'; + throw err; - if (this.options.loose) { - // in loose mode, throw out any that are not valid comparators - set = set.filter(function (comp) { - return !!comp.match(compRe); - }); - } + function loadAsFileSync(x) { + var pkg = loadpkg(path__default['default'].dirname(x)); - set = set.map(function (comp) { - return new Comparator(comp, this.options); - }, this); - return set; - }; + if (pkg && pkg.dir && pkg.pkg && opts.pathFilter) { + var rfile = path__default['default'].relative(pkg.dir, x); + var r = opts.pathFilter(pkg.pkg, x, rfile); - Range.prototype.intersects = function (range, options) { - if (!(range instanceof Range)) { - throw new TypeError('a Range is required'); + if (r) { + x = path__default['default'].resolve(pkg.dir, r); // eslint-disable-line no-param-reassign + } } - return this.set.some(function (thisComparators) { - return thisComparators.every(function (thisComparator) { - return range.set.some(function (rangeComparators) { - return rangeComparators.every(function (rangeComparator) { - return thisComparator.intersects(rangeComparator, options); - }); - }); - }); - }); - }; // Mostly just for testing and legacy API reasons - + if (isFile(x)) { + return x; + } - exports.toComparators = toComparators; + for (var i = 0; i < extensions.length; i++) { + var file = x + extensions[i]; - function toComparators(range, options) { - return new Range(range, options).set.map(function (comp) { - return comp.map(function (c) { - return c.value; - }).join(' ').trim().split(' '); - }); - } // comprised of xranges, tildes, stars, and gtlt's at this point. - // already replaced the hyphen ranges - // turn into a set of JUST comparators. + if (isFile(file)) { + return file; + } + } + } + function loadpkg(dir) { + if (dir === '' || dir === '/') return; - function parseComparator(comp, options) { - debug('comp', comp, options); - comp = replaceCarets(comp, options); - debug('caret', comp); - comp = replaceTildes(comp, options); - debug('tildes', comp); - comp = replaceXRanges(comp, options); - debug('xrange', comp); - comp = replaceStars(comp, options); - debug('stars', comp); - return comp; - } + if (process.platform === 'win32' && /^\w:[/\\]*$/.test(dir)) { + return; + } - function isX(id) { - return !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 - // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 - // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 - // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 - // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 + if (/[/\\]node_modules[/\\]*$/.test(dir)) return; + var pkgfile = path__default['default'].join(maybeRealpathSync(realpathSync, dir, opts), 'package.json'); + if (!isFile(pkgfile)) { + return loadpkg(path__default['default'].dirname(dir)); + } - function replaceTildes(comp, options) { - return comp.trim().split(/\s+/).map(function (comp) { - return replaceTilde(comp, options); - }).join(' '); - } + var body = readFileSync(pkgfile); - function replaceTilde(comp, options) { - var r = options.loose ? re[TILDELOOSE] : re[TILDE]; - return comp.replace(r, function (_, M, m, p, pr) { - debug('tilde', comp, _, M, m, p, pr); - var ret; + try { + var pkg = JSON.parse(body); + } catch (jsonErr) {} - if (isX(M)) { - ret = ''; - } else if (isX(m)) { - ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; - } else if (isX(p)) { - // ~1.2 == >=1.2.0 <1.3.0 - ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; - } else if (pr) { - debug('replaceTilde pr', pr); - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + ' <' + M + '.' + (+m + 1) + '.0'; - } else { - // ~1.2.3 == >=1.2.3 <1.3.0 - ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + (+m + 1) + '.0'; - } + if (pkg && opts.packageFilter) { + // v2 will pass pkgfile + pkg = opts.packageFilter(pkg, + /*pkgfile,*/ + dir); // eslint-disable-line spaced-comment + } - debug('tilde return', ret); - return ret; - }); - } // ^ --> * (any, kinda silly) - // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 - // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 - // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 - // ^1.2.3 --> >=1.2.3 <2.0.0 - // ^1.2.0 --> >=1.2.0 <2.0.0 + return { + pkg: pkg, + dir: dir + }; + } + function loadAsDirectorySync(x) { + var pkgfile = path__default['default'].join(maybeRealpathSync(realpathSync, x, opts), '/package.json'); - function replaceCarets(comp, options) { - return comp.trim().split(/\s+/).map(function (comp) { - return replaceCaret(comp, options); - }).join(' '); - } + if (isFile(pkgfile)) { + try { + var body = readFileSync(pkgfile, 'UTF8'); + var pkg = JSON.parse(body); + } catch (e) {} - function replaceCaret(comp, options) { - debug('caret', comp, options); - var r = options.loose ? re[CARETLOOSE] : re[CARET]; - return comp.replace(r, function (_, M, m, p, pr) { - debug('caret', comp, _, M, m, p, pr); - var ret; + if (pkg && opts.packageFilter) { + // v2 will pass pkgfile + pkg = opts.packageFilter(pkg, + /*pkgfile,*/ + x); // eslint-disable-line spaced-comment + } - if (isX(M)) { - ret = ''; - } else if (isX(m)) { - ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; - } else if (isX(p)) { - if (M === '0') { - ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; - } else { - ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0'; + if (pkg && pkg.main) { + if (typeof pkg.main !== 'string') { + var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string'); + mainError.code = 'INVALID_PACKAGE_MAIN'; + throw mainError; } - } else if (pr) { - debug('replaceCaret pr', pr); - if (M === '0') { - if (m === '0') { - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + ' <' + M + '.' + m + '.' + (+p + 1); - } else { - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + ' <' + M + '.' + (+m + 1) + '.0'; - } - } else { - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + ' <' + (+M + 1) + '.0.0'; + if (pkg.main === '.' || pkg.main === './') { + pkg.main = 'index'; } - } else { - debug('no pr'); - if (M === '0') { - if (m === '0') { - ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + m + '.' + (+p + 1); - } else { - ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + (+m + 1) + '.0'; - } - } else { - ret = '>=' + M + '.' + m + '.' + p + ' <' + (+M + 1) + '.0.0'; - } + try { + var m = loadAsFileSync(path__default['default'].resolve(x, pkg.main)); + if (m) return m; + var n = loadAsDirectorySync(path__default['default'].resolve(x, pkg.main)); + if (n) return n; + } catch (e) {} } + } - debug('caret return', ret); - return ret; - }); + return loadAsFileSync(path__default['default'].join(x, '/index')); } - function replaceXRanges(comp, options) { - debug('replaceXRanges', comp, options); - return comp.split(/\s+/).map(function (comp) { - return replaceXRange(comp, options); - }).join(' '); - } + function loadNodeModulesSync(x, start) { + var thunk = function () { + return getPackageCandidates$1(x, start, opts); + }; - function replaceXRange(comp, options) { - comp = comp.trim(); - var r = options.loose ? re[XRANGELOOSE] : re[XRANGE]; - return comp.replace(r, function (ret, gtlt, M, m, p, pr) { - debug('xRange', comp, ret, gtlt, M, m, p, pr); - var xM = isX(M); - var xm = xM || isX(m); - var xp = xm || isX(p); - var anyX = xp; + var dirs = packageIterator ? packageIterator(x, start, thunk, opts) : thunk(); - if (gtlt === '=' && anyX) { - gtlt = ''; + for (var i = 0; i < dirs.length; i++) { + var dir = dirs[i]; + + if (isDirectory(path__default['default'].dirname(dir))) { + var m = loadAsFileSync(dir); + if (m) return m; + var n = loadAsDirectorySync(dir); + if (n) return n; } + } + } +}; - if (xM) { - if (gtlt === '>' || gtlt === '<') { - // nothing is allowed - ret = '<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; - } +async.core = core_1; +async.isCore = isCore; +async.sync = sync; +var resolve = async; - p = 0; +let { + resolve: resolve$1 +} = require; // In the VS Code and Atom extensions `require` is overridden and `require.resolve` doesn't support the 2nd argument. - if (gtlt === '>') { - // >1 => >=2.0.0 - // >1.2 => >=1.3.0 - // >1.2.3 => >= 1.2.4 - gtlt = '>='; +if (resolve$1.length === 1 || process.env.PRETTIER_FALLBACK_RESOLVE) { + resolve$1 = (id, options) => { + let basedir; - 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 (options && options.paths && options.paths.length === 1) { + basedir = options.paths[0]; + } - if (xm) { - M = +M + 1; - } else { - m = +m + 1; - } - } + return resolve.sync(id, { + basedir + }); + }; +} - ret = gtlt + M + '.' + m + '.' + p; - } else if (xm) { - ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; - } else if (xp) { - ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; - } +var resolve_1 = resolve$1; - debug('xRange return', ret); - return ret; - }); - } // Because * is AND-ed with everything else in the comparator, - // and '' means "any version", just remove the *s entirely. +var semver$2 = createCommonjsModule(function (module, exports) { + exports = module.exports = SemVer; + var debug; + /* istanbul ignore next */ + if (typeof process === 'object' && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG)) { + debug = function () { + var args = Array.prototype.slice.call(arguments, 0); + args.unshift('SEMVER'); + console.log.apply(console, args); + }; + } else { + debug = function () {}; + } // Note: this is the semver.org version of the spec that it implements + // Not necessarily the package version of this code. - function replaceStars(comp, options) { - debug('replaceStars', comp, options); // Looseness is ignored here. star is always as loose as it gets! - return comp.trim().replace(re[STAR], ''); - } // This function is passed to string.replace(re[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 Any 3.4.x will do - // 1.2 - 3.4 => >=1.2.0 <3.5.0 + exports.SEMVER_SPEC_VERSION = '2.0.0'; + var MAX_LENGTH = 256; + var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || + /* istanbul ignore next */ + 9007199254740991; // Max safe segment length for coercion. + var MAX_SAFE_COMPONENT_LENGTH = 16; // The actual regexps go on exports.re - function hyphenReplace($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'; - } else if (isX(fp)) { - from = '>=' + fM + '.' + fm + '.0'; - } else { - from = '>=' + from; - } + var re = exports.re = []; + var src = exports.src = []; + var R = 0; // 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. - if (isX(tM)) { - to = ''; - } else if (isX(tm)) { - to = '<' + (+tM + 1) + '.0.0'; - } else if (isX(tp)) { - to = '<' + tM + '.' + (+tm + 1) + '.0'; - } else if (tpr) { - to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr; - } else { - to = '<=' + to; - } + var NUMERICIDENTIFIER = R++; + src[NUMERICIDENTIFIER] = '0|[1-9]\\d*'; + var NUMERICIDENTIFIERLOOSE = R++; + src[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. - return (from + ' ' + to).trim(); - } // if ANY of the sets match ALL of its comparators, then pass + var NONNUMERICIDENTIFIER = R++; + src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*'; // ## Main Version + // Three dot-separated numeric identifiers. + var MAINVERSION = R++; + src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + '(' + src[NUMERICIDENTIFIER] + ')\\.' + '(' + src[NUMERICIDENTIFIER] + ')'; + var MAINVERSIONLOOSE = R++; + src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + '(' + src[NUMERICIDENTIFIERLOOSE] + ')'; // ## Pre-release Version Identifier + // A numeric identifier, or a non-numeric identifier. - Range.prototype.test = function (version) { - if (!version) { - return false; - } + var PRERELEASEIDENTIFIER = R++; + src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + '|' + src[NONNUMERICIDENTIFIER] + ')'; + var PRERELEASEIDENTIFIERLOOSE = R++; + src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + '|' + src[NONNUMERICIDENTIFIER] + ')'; // ## Pre-release Version + // Hyphen, followed by one or more dot-separated pre-release version + // identifiers. - if (typeof version === 'string') { - version = new SemVer(version, this.options); - } + var PRERELEASE = R++; + src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))'; + var PRERELEASELOOSE = R++; + src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))'; // ## Build Metadata Identifier + // Any combination of digits, letters, or hyphens. - for (var i = 0; i < this.set.length; i++) { - if (testSet(this.set[i], version, this.options)) { - return true; - } - } + var BUILDIDENTIFIER = R++; + src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+'; // ## Build Metadata + // Plus sign, followed by one or more period-separated build metadata + // identifiers. - return false; - }; + var BUILD = R++; + src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + '(?:\\.' + src[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. - function testSet(set, version, options) { - for (var i = 0; i < set.length; i++) { - if (!set[i].test(version)) { - return false; - } - } + var FULL = R++; + var FULLPLAIN = 'v?' + src[MAINVERSION] + src[PRERELEASE] + '?' + src[BUILD] + '?'; + src[FULL] = '^' + 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. - 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 (i = 0; i < set.length; i++) { - debug(set[i].semver); + var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + src[PRERELEASELOOSE] + '?' + src[BUILD] + '?'; + var LOOSE = R++; + src[LOOSE] = '^' + LOOSEPLAIN + '$'; + var GTLT = R++; + src[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. - if (set[i].semver === ANY) { - continue; - } + var XRANGEIDENTIFIERLOOSE = R++; + src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*'; + var XRANGEIDENTIFIER = R++; + src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*'; + var XRANGEPLAIN = R++; + src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + '(?:' + src[PRERELEASE] + ')?' + src[BUILD] + '?' + ')?)?'; + var XRANGEPLAINLOOSE = R++; + src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:' + src[PRERELEASELOOSE] + ')?' + src[BUILD] + '?' + ')?)?'; + var XRANGE = R++; + src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$'; + var XRANGELOOSE = R++; + src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$'; // Coercion. + // Extract anything that could conceivably be a part of a valid semver - if (set[i].semver.prerelease.length > 0) { - var allowed = set[i].semver; + var COERCE = R++; + src[COERCE] = '(?:^|[^\\d])' + '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + '(?:$|[^\\d])'; // Tilde ranges. + // Meaning is "reasonably at or greater than" - 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. + var LONETILDE = R++; + src[LONETILDE] = '(?:~>?)'; + var TILDETRIM = R++; + src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+'; + re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g'); + var tildeTrimReplace = '$1~'; + var TILDE = R++; + src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$'; + var TILDELOOSE = R++; + src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$'; // Caret ranges. + // Meaning is "at least and backwards compatible with" + var LONECARET = R++; + src[LONECARET] = '(?:\\^)'; + var CARETTRIM = R++; + src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+'; + re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g'); + var caretTrimReplace = '$1^'; + var CARET = R++; + src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$'; + var CARETLOOSE = R++; + src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$'; // A simple gt/lt/eq thing, or just "" to indicate "any version" - return false; - } + var COMPARATORLOOSE = R++; + src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$'; + var COMPARATOR = R++; + src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$'; // An expression to strip any whitespace between the gtlt and the thing + // it modifies, so that `> 1.2.3` ==> `>1.2.3` - return true; - } + var COMPARATORTRIM = R++; + src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')'; // this one has to use the /g flag - exports.satisfies = satisfies; + re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g'); + var 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. - function satisfies(version, range, options) { - try { - range = new Range(range, options); - } catch (er) { - return false; - } + var HYPHENRANGE = R++; + src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + '\\s+-\\s+' + '(' + src[XRANGEPLAIN] + ')' + '\\s*$'; + var HYPHENRANGELOOSE = R++; + src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + '\\s+-\\s+' + '(' + src[XRANGEPLAINLOOSE] + ')' + '\\s*$'; // Star ranges basically just allow anything at all. - return range.test(version); + var STAR = R++; + src[STAR] = '(<|>)?=?\\s*\\*'; // Compile to actual regexp objects. + // All are flag-free, unless they were created above with a flag. + + for (var i = 0; i < R; i++) { + debug(i, src[i]); + + if (!re[i]) { + re[i] = new RegExp(src[i]); + } } - exports.maxSatisfying = maxSatisfying; + exports.parse = parse; - function maxSatisfying(versions, range, options) { - var max = null; - var maxSV = null; + function parse(version, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + }; + } - try { - var rangeObj = new Range(range, options); - } catch (er) { + if (version instanceof SemVer) { + return version; + } + + if (typeof version !== 'string') { return null; } - versions.forEach(function (v) { - if (rangeObj.test(v)) { - // satisfies(v, range, options) - if (!max || maxSV.compare(v) === -1) { - // compare(max, v, true) - max = v; - maxSV = new SemVer(max, options); - } - } - }); - return max; - } + if (version.length > MAX_LENGTH) { + return null; + } - exports.minSatisfying = minSatisfying; + var r = options.loose ? re[LOOSE] : re[FULL]; - function minSatisfying(versions, range, options) { - var min = null; - var minSV = null; + if (!r.test(version)) { + return null; + } try { - var rangeObj = new Range(range, options); + return new SemVer(version, options); } catch (er) { return null; } + } - versions.forEach(function (v) { - if (rangeObj.test(v)) { - // satisfies(v, range, options) - if (!min || minSV.compare(v) === 1) { - // compare(min, v, true) - min = v; - minSV = new SemVer(min, options); - } - } - }); - return min; + exports.valid = valid; + + function valid(version, options) { + var v = parse(version, options); + return v ? v.version : null; } - exports.minVersion = minVersion; + exports.clean = clean; - function minVersion(range, loose) { - range = new Range(range, loose); - var minver = new SemVer('0.0.0'); + function clean(version, options) { + var s = parse(version.trim().replace(/^[=v]+/, ''), options); + return s ? s.version : null; + } - if (range.test(minver)) { - return minver; + exports.SemVer = SemVer; + + function SemVer(version, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + }; } - minver = new SemVer('0.0.0-0'); + if (version instanceof SemVer) { + if (version.loose === options.loose) { + return version; + } else { + version = version.version; + } + } else if (typeof version !== 'string') { + throw new TypeError('Invalid Version: ' + version); + } - if (range.test(minver)) { - return minver; + if (version.length > MAX_LENGTH) { + throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters'); } - minver = null; + if (!(this instanceof SemVer)) { + return new SemVer(version, options); + } - for (var i = 0; i < range.set.length; ++i) { - var comparators = range.set[i]; - comparators.forEach(function (comparator) { - // Clone to avoid manipulating the comparator's semver object. - var compver = new SemVer(comparator.semver.version); + debug('SemVer', version, options); + this.options = options; + this.loose = !!options.loose; + var m = version.trim().match(options.loose ? re[LOOSE] : re[FULL]); - switch (comparator.operator) { - case '>': - if (compver.prerelease.length === 0) { - compver.patch++; - } else { - compver.prerelease.push(0); - } + if (!m) { + throw new TypeError('Invalid Version: ' + version); + } - compver.raw = compver.format(); + this.raw = version; // these are actually numbers + + this.major = +m[1]; + this.minor = +m[2]; + this.patch = +m[3]; - /* fallthrough */ + if (this.major > MAX_SAFE_INTEGER || this.major < 0) { + throw new TypeError('Invalid major version'); + } - case '': - case '>=': - if (!minver || gt(minver, compver)) { - minver = compver; - } + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { + throw new TypeError('Invalid minor version'); + } - break; + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { + throw new TypeError('Invalid patch version'); + } // numberify any prerelease numeric ids - case '<': - case '<=': - /* Ignore maximum versions */ - break; - /* istanbul ignore next */ + if (!m[4]) { + this.prerelease = []; + } else { + this.prerelease = m[4].split('.').map(function (id) { + if (/^[0-9]+$/.test(id)) { + var num = +id; - default: - throw new Error('Unexpected operation: ' + comparator.operator); + if (num >= 0 && num < MAX_SAFE_INTEGER) { + return num; + } } + + return id; }); } - if (minver && range.test(minver)) { - return minver; + this.build = m[5] ? m[5].split('.') : []; + this.format(); + } + + SemVer.prototype.format = function () { + this.version = this.major + '.' + this.minor + '.' + this.patch; + + if (this.prerelease.length) { + this.version += '-' + this.prerelease.join('.'); } - return null; - } + return this.version; + }; - exports.validRange = validRange; + SemVer.prototype.toString = function () { + return this.version; + }; - function validRange(range, options) { - try { - // Return '*' instead of '' so that truthiness works. - // This will throw if it's invalid anyway - return new Range(range, options).range || '*'; - } catch (er) { - return null; + SemVer.prototype.compare = function (other) { + debug('SemVer.compare', this.version, this.options, other); + + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options); } - } // Determine if version is less than all the versions possible in the range + return this.compareMain(other) || this.comparePre(other); + }; - exports.ltr = ltr; + SemVer.prototype.compareMain = function (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options); + } - function ltr(version, range, options) { - return outside(version, range, '<', options); - } // Determine if version is greater than all the versions possible in the range. + return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch); + }; + SemVer.prototype.comparePre = function (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options); + } // NOT having a prerelease is > having one - exports.gtr = gtr; - function gtr(version, range, options) { - return outside(version, range, '>', options); - } + 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; + } - exports.outside = outside; + var i = 0; - function outside(version, range, hilo, options) { - version = new SemVer(version, options); - range = new Range(range, options); - var gtfn, ltefn, ltfn, comp, ecomp; + do { + var a = this.prerelease[i]; + var b = other.prerelease[i]; + debug('prerelease compare', i, a, b); - switch (hilo) { - case '>': - gtfn = gt; - ltefn = lte; - ltfn = lt; - comp = '>'; - ecomp = '>='; + 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. + + + SemVer.prototype.inc = function (release, identifier) { + switch (release) { + case 'premajor': + this.prerelease.length = 0; + this.patch = 0; + this.minor = 0; + this.major++; + this.inc('pre', identifier); break; - case '<': - gtfn = lt; - ltefn = gte; - ltfn = gt; - comp = '<'; - ecomp = '<='; + case 'preminor': + this.prerelease.length = 0; + this.patch = 0; + this.minor++; + this.inc('pre', identifier); break; - default: - throw new TypeError('Must provide a hilo val of "<" or ">"'); - } // If it satisifes the range it is not outside + 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; - if (satisfies(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. + 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; - for (var i = 0; i < range.set.length; ++i) { - var comparators = range.set[i]; - var high = null; - var low = null; - comparators.forEach(function (comparator) { - if (comparator.semver === ANY) { - comparator = new Comparator('>=0.0.0'); + 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++; } - high = high || comparator; - low = low || comparator; + this.patch = 0; + this.prerelease = []; + break; - if (gtfn(comparator.semver, high.semver, options)) { - high = comparator; - } else if (ltfn(comparator.semver, low.semver, options)) { - low = comparator; + 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++; } - }); // 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 + 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 { + var i = this.prerelease.length; - if ((!low.operator || low.operator === comp) && ltefn(version, low.semver)) { - return false; - } else if (low.operator === ecomp && ltfn(version, low.semver)) { - return false; - } - } + while (--i >= 0) { + if (typeof this.prerelease[i] === 'number') { + this.prerelease[i]++; + i = -2; + } + } - return true; - } + if (i === -1) { + // didn't increment anything + this.prerelease.push(0); + } + } - exports.prerelease = prerelease; + 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]; + } + } - function prerelease(version, options) { - var parsed = parse(version, options); - return parsed && parsed.prerelease.length ? parsed.prerelease : null; - } + break; - exports.intersects = intersects; + default: + throw new Error('invalid increment argument: ' + release); + } - function intersects(r1, r2, options) { - r1 = new Range(r1, options); - r2 = new Range(r2, options); - return r1.intersects(r2); - } + this.format(); + this.raw = this.version; + return this; + }; - exports.coerce = coerce; + exports.inc = inc; - function coerce(version) { - if (version instanceof SemVer) { - return version; + function inc(version, release, loose, identifier) { + if (typeof loose === 'string') { + identifier = loose; + loose = undefined; } - if (typeof version !== 'string') { + try { + return new SemVer(version, loose).inc(release, identifier).version; + } catch (er) { return null; } + } - var match = version.match(re[COERCE]); + exports.diff = diff; - if (match == null) { + function diff(version1, version2) { + if (eq(version1, version2)) { return null; + } else { + var v1 = parse(version1); + var v2 = parse(version2); + var prefix = ''; + + if (v1.prerelease.length || v2.prerelease.length) { + prefix = 'pre'; + var defaultResult = 'prerelease'; + } + + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return prefix + key; + } + } + } + + return defaultResult; // may be undefined } + } - return parse(match[1] + '.' + (match[2] || '0') + '.' + (match[3] || '0')); + exports.compareIdentifiers = compareIdentifiers; + var numeric = /^[0-9]+$/; + + function compareIdentifiers(a, b) { + var anum = numeric.test(a); + var bnum = numeric.test(b); + + if (anum && bnum) { + a = +a; + b = +b; + } + + return a === b ? 0 : anum && !bnum ? -1 : bnum && !anum ? 1 : a < b ? -1 : 1; } -}); -var semver_1 = semver$2.SEMVER_SPEC_VERSION; -var semver_2 = semver$2.re; -var semver_3 = semver$2.src; -var semver_4 = semver$2.parse; -var semver_5 = semver$2.valid; -var semver_6 = semver$2.clean; -var semver_7 = semver$2.SemVer; -var semver_8 = semver$2.inc; -var semver_9 = semver$2.diff; -var semver_10 = semver$2.compareIdentifiers; -var semver_11 = semver$2.rcompareIdentifiers; -var semver_12 = semver$2.major; -var semver_13 = semver$2.minor; -var semver_14 = semver$2.patch; -var semver_15 = semver$2.compare; -var semver_16 = semver$2.compareLoose; -var semver_17 = semver$2.rcompare; -var semver_18 = semver$2.sort; -var semver_19 = semver$2.rsort; -var semver_20 = semver$2.gt; -var semver_21 = semver$2.lt; -var semver_22 = semver$2.eq; -var semver_23 = semver$2.neq; -var semver_24 = semver$2.gte; -var semver_25 = semver$2.lte; -var semver_26 = semver$2.cmp; -var semver_27 = semver$2.Comparator; -var semver_28 = semver$2.Range; -var semver_29 = semver$2.toComparators; -var semver_30 = semver$2.satisfies; -var semver_31 = semver$2.maxSatisfying; -var semver_32 = semver$2.minSatisfying; -var semver_33 = semver$2.minVersion; -var semver_34 = semver$2.validRange; -var semver_35 = semver$2.ltr; -var semver_36 = semver$2.gtr; -var semver_37 = semver$2.outside; -var semver_38 = semver$2.prerelease; -var semver_39 = semver$2.intersects; -var semver_40 = semver$2.coerce; - -var hasOwnProperty = Object.prototype.hasOwnProperty; -var pseudomap = PseudoMap; -function PseudoMap(set) { - if (!(this instanceof PseudoMap)) // whyyyyyyy - throw new TypeError("Constructor PseudoMap requires 'new'"); - this.clear(); + exports.rcompareIdentifiers = rcompareIdentifiers; - if (set) { - if (set instanceof PseudoMap || typeof Map === 'function' && set instanceof Map) set.forEach(function (value, key) { - this.set(key, value); - }, this);else if (Array.isArray(set)) set.forEach(function (kv) { - this.set(kv[0], kv[1]); - }, this);else throw new TypeError('invalid argument'); + function rcompareIdentifiers(a, b) { + return compareIdentifiers(b, a); } -} -PseudoMap.prototype.forEach = function (fn, thisp) { - thisp = thisp || this; - Object.keys(this._data).forEach(function (k) { - if (k !== 'size') fn.call(thisp, this._data[k].value, this._data[k].key); - }, this); -}; + exports.major = major; -PseudoMap.prototype.has = function (k) { - return !!find(this._data, k); -}; + function major(a, loose) { + return new SemVer(a, loose).major; + } -PseudoMap.prototype.get = function (k) { - var res = find(this._data, k); - return res && res.value; -}; + exports.minor = minor; -PseudoMap.prototype.set = function (k, v) { - set(this._data, k, v); -}; + function minor(a, loose) { + return new SemVer(a, loose).minor; + } -PseudoMap.prototype.delete = function (k) { - var res = find(this._data, k); + exports.patch = patch; - if (res) { - delete this._data[res._index]; - this._data.size--; + function patch(a, loose) { + return new SemVer(a, loose).patch; } -}; -PseudoMap.prototype.clear = function () { - var data = Object.create(null); - data.size = 0; - Object.defineProperty(this, '_data', { - value: data, - enumerable: false, - configurable: true, - writable: false - }); -}; + exports.compare = compare; -Object.defineProperty(PseudoMap.prototype, 'size', { - get: function () { - return this._data.size; - }, - set: function (n) {}, - enumerable: true, - configurable: true -}); + function compare(a, b, loose) { + return new SemVer(a, loose).compare(new SemVer(b, loose)); + } -PseudoMap.prototype.values = PseudoMap.prototype.keys = PseudoMap.prototype.entries = function () { - throw new Error('iterators are not implemented in this version'); -}; // Either identical, or both NaN + exports.compareLoose = compareLoose; + function compareLoose(a, b) { + return compare(a, b, true); + } -function same(a, b) { - return a === b || a !== a && b !== b; -} + exports.rcompare = rcompare; -function Entry(k, v, i) { - this.key = k; - this.value = v; - this._index = i; -} + function rcompare(a, b, loose) { + return compare(b, a, loose); + } -function find(data, k) { - for (var i = 0, s = '_' + k, key = s; hasOwnProperty.call(data, key); key = s + i++) { - if (same(data[key].key, k)) return data[key]; + exports.sort = sort; + + function sort(list, loose) { + return list.sort(function (a, b) { + return exports.compare(a, b, loose); + }); } -} -function set(data, k, v) { - for (var i = 0, s = '_' + k, key = s; hasOwnProperty.call(data, key); key = s + i++) { - if (same(data[key].key, k)) { - data[key].value = v; - return; - } + exports.rsort = rsort; + + function rsort(list, loose) { + return list.sort(function (a, b) { + return exports.rcompare(a, b, loose); + }); } - data.size++; - data[key] = new Entry(k, v, key); -} + exports.gt = gt; -var map = createCommonjsModule(function (module) { - if (process.env.npm_package_name === 'pseudomap' && process.env.npm_lifecycle_script === 'test') process.env.TEST_PSEUDOMAP = 'true'; + function gt(a, b, loose) { + return compare(a, b, loose) > 0; + } - if (typeof Map === 'function' && !process.env.TEST_PSEUDOMAP) { - module.exports = Map; - } else { - module.exports = pseudomap; + exports.lt = lt; + + function lt(a, b, loose) { + return compare(a, b, loose) < 0; } -}); -var yallist = Yallist; -Yallist.Node = Node; -Yallist.create = Yallist; + exports.eq = eq; -function Yallist(list) { - var self = this; + function eq(a, b, loose) { + return compare(a, b, loose) === 0; + } - if (!(self instanceof Yallist)) { - self = new Yallist(); + exports.neq = neq; + + function neq(a, b, loose) { + return compare(a, b, loose) !== 0; } - self.tail = null; - self.head = null; - self.length = 0; + exports.gte = gte; - 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]); - } + function gte(a, b, loose) { + return compare(a, b, loose) >= 0; } - return self; -} + exports.lte = lte; -Yallist.prototype.removeNode = function (node) { - if (node.list !== this) { - throw new Error('removing node which does not belong to this list'); + function lte(a, b, loose) { + return compare(a, b, loose) <= 0; } - var next = node.next; - var prev = node.prev; + exports.cmp = cmp; + + function cmp(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); - if (next) { - next.prev = prev; - } + case '!=': + return neq(a, b, loose); - if (prev) { - prev.next = next; - } + case '>': + return gt(a, b, loose); - if (node === this.head) { - this.head = next; - } + case '>=': + return gte(a, b, loose); - if (node === this.tail) { - this.tail = prev; - } + case '<': + return lt(a, b, loose); - node.list.length--; - node.next = null; - node.prev = null; - node.list = null; -}; + case '<=': + return lte(a, b, loose); -Yallist.prototype.unshiftNode = function (node) { - if (node === this.head) { - return; + default: + throw new TypeError('Invalid operator: ' + op); + } } - if (node.list) { - node.list.removeNode(node); - } + exports.Comparator = Comparator; - var head = this.head; - node.list = this; - node.next = head; + function Comparator(comp, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + }; + } - if (head) { - head.prev = node; - } + if (comp instanceof Comparator) { + if (comp.loose === !!options.loose) { + return comp; + } else { + comp = comp.value; + } + } - this.head = node; + if (!(this instanceof Comparator)) { + return new Comparator(comp, options); + } - if (!this.tail) { - this.tail = node; - } + debug('comparator', comp, options); + this.options = options; + this.loose = !!options.loose; + this.parse(comp); - this.length++; -}; + if (this.semver === ANY) { + this.value = ''; + } else { + this.value = this.operator + this.semver.version; + } -Yallist.prototype.pushNode = function (node) { - if (node === this.tail) { - return; + debug('comp', this); } - if (node.list) { - node.list.removeNode(node); - } + var ANY = {}; - var tail = this.tail; - node.list = this; - node.prev = tail; + Comparator.prototype.parse = function (comp) { + var r = this.options.loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; + var m = comp.match(r); - if (tail) { - tail.next = node; - } + if (!m) { + throw new TypeError('Invalid comparator: ' + comp); + } - this.tail = node; + this.operator = m[1]; - if (!this.head) { - this.head = node; - } + if (this.operator === '=') { + this.operator = ''; + } // if it literally is just '>' or '' then allow anything. - this.length++; -}; -Yallist.prototype.push = function () { - for (var i = 0, l = arguments.length; i < l; i++) { - push(this, arguments[i]); - } + if (!m[2]) { + this.semver = ANY; + } else { + this.semver = new SemVer(m[2], this.options.loose); + } + }; - return this.length; -}; + Comparator.prototype.toString = function () { + return this.value; + }; -Yallist.prototype.unshift = function () { - for (var i = 0, l = arguments.length; i < l; i++) { - unshift(this, arguments[i]); - } + Comparator.prototype.test = function (version) { + debug('Comparator.test', version, this.options.loose); - return this.length; -}; + if (this.semver === ANY) { + return true; + } -Yallist.prototype.pop = function () { - if (!this.tail) { - return undefined; - } + if (typeof version === 'string') { + version = new SemVer(version, this.options); + } - var res = this.tail.value; - this.tail = this.tail.prev; + return cmp(version, this.operator, this.semver, this.options); + }; - if (this.tail) { - this.tail.next = null; - } else { - this.head = null; - } + Comparator.prototype.intersects = function (comp, options) { + if (!(comp instanceof Comparator)) { + throw new TypeError('a Comparator is required'); + } - this.length--; - return res; -}; + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + }; + } -Yallist.prototype.shift = function () { - if (!this.head) { - return undefined; - } + var rangeTmp; - var res = this.head.value; - this.head = this.head.next; + if (this.operator === '') { + rangeTmp = new Range(comp.value, options); + return satisfies(this.value, rangeTmp, options); + } else if (comp.operator === '') { + rangeTmp = new Range(this.value, options); + return satisfies(comp.semver, rangeTmp, options); + } - if (this.head) { - this.head.prev = null; - } else { - this.tail = null; - } + var sameDirectionIncreasing = (this.operator === '>=' || this.operator === '>') && (comp.operator === '>=' || comp.operator === '>'); + var sameDirectionDecreasing = (this.operator === '<=' || this.operator === '<') && (comp.operator === '<=' || comp.operator === '<'); + var sameSemVer = this.semver.version === comp.semver.version; + var differentDirectionsInclusive = (this.operator === '>=' || this.operator === '<=') && (comp.operator === '>=' || comp.operator === '<='); + var oppositeDirectionsLessThan = cmp(this.semver, '<', comp.semver, options) && (this.operator === '>=' || this.operator === '>') && (comp.operator === '<=' || comp.operator === '<'); + var oppositeDirectionsGreaterThan = cmp(this.semver, '>', comp.semver, options) && (this.operator === '<=' || this.operator === '<') && (comp.operator === '>=' || comp.operator === '>'); + return sameDirectionIncreasing || sameDirectionDecreasing || sameSemVer && differentDirectionsInclusive || oppositeDirectionsLessThan || oppositeDirectionsGreaterThan; + }; - this.length--; - return res; -}; + exports.Range = Range; -Yallist.prototype.forEach = function (fn, thisp) { - thisp = thisp || this; + function Range(range, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + }; + } - for (var walker = this.head, i = 0; walker !== null; i++) { - fn.call(thisp, walker.value, i, this); - walker = walker.next; - } -}; + if (range instanceof Range) { + if (range.loose === !!options.loose && range.includePrerelease === !!options.includePrerelease) { + return range; + } else { + return new Range(range.raw, options); + } + } -Yallist.prototype.forEachReverse = function (fn, thisp) { - thisp = thisp || this; + if (range instanceof Comparator) { + return new Range(range.value, options); + } - for (var walker = this.tail, i = this.length - 1; walker !== null; i--) { - fn.call(thisp, walker.value, i, this); - walker = walker.prev; - } -}; + if (!(this instanceof Range)) { + return new Range(range, options); + } -Yallist.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; - } + this.options = options; + this.loose = !!options.loose; + this.includePrerelease = !!options.includePrerelease; // First, split based on boolean or || - if (i === n && walker !== null) { - return walker.value; - } -}; + this.raw = range; + this.set = range.split(/\s*\|\|\s*/).map(function (range) { + return this.parseRange(range.trim()); + }, this).filter(function (c) { + // throw out any that are not relevant for whatever reason + return c.length; + }); -Yallist.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 (!this.set.length) { + throw new TypeError('Invalid SemVer Range: ' + range); + } - if (i === n && walker !== null) { - return walker.value; + this.format(); } -}; -Yallist.prototype.map = function (fn, thisp) { - thisp = thisp || this; - var res = new Yallist(); - - for (var walker = this.head; walker !== null;) { - res.push(fn.call(thisp, walker.value, this)); - walker = walker.next; - } + Range.prototype.format = function () { + this.range = this.set.map(function (comps) { + return comps.join(' ').trim(); + }).join('||').trim(); + return this.range; + }; - return res; -}; + Range.prototype.toString = function () { + return this.range; + }; -Yallist.prototype.mapReverse = function (fn, thisp) { - thisp = thisp || this; - var res = new Yallist(); + Range.prototype.parseRange = function (range) { + var loose = this.options.loose; + range = range.trim(); // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` - for (var walker = this.tail; walker !== null;) { - res.push(fn.call(thisp, walker.value, this)); - walker = walker.prev; - } + var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE]; + range = range.replace(hr, hyphenReplace); + debug('hyphen replace', range); // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` - return res; -}; + range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace); + debug('comparator trim', range, re[COMPARATORTRIM]); // `~ 1.2.3` => `~1.2.3` -Yallist.prototype.reduce = function (fn, initial) { - var acc; - var walker = this.head; + range = range.replace(re[TILDETRIM], tildeTrimReplace); // `^ 1.2.3` => `^1.2.3` - 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'); - } + range = range.replace(re[CARETTRIM], caretTrimReplace); // normalize spaces - for (var i = 0; walker !== null; i++) { - acc = fn(acc, walker.value, i); - walker = walker.next; - } + range = range.split(/\s+/).join(' '); // At this point, the range is completely trimmed and + // ready to be split into comparators. - return acc; -}; + var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; + var set = range.split(' ').map(function (comp) { + return parseComparator(comp, this.options); + }, this).join(' ').split(/\s+/); -Yallist.prototype.reduceReverse = function (fn, initial) { - var acc; - var walker = this.tail; + if (this.options.loose) { + // in loose mode, throw out any that are not valid comparators + set = set.filter(function (comp) { + return !!comp.match(compRe); + }); + } - 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'); - } + set = set.map(function (comp) { + return new Comparator(comp, this.options); + }, this); + return set; + }; - for (var i = this.length - 1; walker !== null; i--) { - acc = fn(acc, walker.value, i); - walker = walker.prev; - } + Range.prototype.intersects = function (range, options) { + if (!(range instanceof Range)) { + throw new TypeError('a Range is required'); + } - return acc; -}; + return this.set.some(function (thisComparators) { + return thisComparators.every(function (thisComparator) { + return range.set.some(function (rangeComparators) { + return rangeComparators.every(function (rangeComparator) { + return thisComparator.intersects(rangeComparator, options); + }); + }); + }); + }); + }; // Mostly just for testing and legacy API reasons -Yallist.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; - } + exports.toComparators = toComparators; - return arr; -}; + function toComparators(range, options) { + return new Range(range, options).set.map(function (comp) { + return comp.map(function (c) { + return c.value; + }).join(' ').trim().split(' '); + }); + } // comprised of xranges, tildes, stars, and gtlt's at this point. + // already replaced the hyphen ranges + // turn into a set of JUST comparators. -Yallist.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; + function parseComparator(comp, options) { + debug('comp', comp, options); + comp = replaceCarets(comp, options); + debug('caret', comp); + comp = replaceTildes(comp, options); + debug('tildes', comp); + comp = replaceXRanges(comp, options); + debug('xrange', comp); + comp = replaceStars(comp, options); + debug('stars', comp); + return comp; } - return arr; -}; + function isX(id) { + return !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 + // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 + // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 + // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 + // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 -Yallist.prototype.slice = function (from, to) { - to = to || this.length; - if (to < 0) { - to += this.length; + function replaceTildes(comp, options) { + return comp.trim().split(/\s+/).map(function (comp) { + return replaceTilde(comp, options); + }).join(' '); } - from = from || 0; - - if (from < 0) { - from += this.length; - } + function replaceTilde(comp, options) { + var r = options.loose ? re[TILDELOOSE] : re[TILDE]; + return comp.replace(r, function (_, M, m, p, pr) { + debug('tilde', comp, _, M, m, p, pr); + var ret; - var ret = new Yallist(); + if (isX(M)) { + ret = ''; + } else if (isX(m)) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; + } else if (isX(p)) { + // ~1.2 == >=1.2.0 <1.3.0 + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; + } else if (pr) { + debug('replaceTilde pr', pr); + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + ' <' + M + '.' + (+m + 1) + '.0'; + } else { + // ~1.2.3 == >=1.2.3 <1.3.0 + ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + (+m + 1) + '.0'; + } - if (to < from || to < 0) { - return ret; - } + debug('tilde return', ret); + return ret; + }); + } // ^ --> * (any, kinda silly) + // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 + // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 + // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 + // ^1.2.3 --> >=1.2.3 <2.0.0 + // ^1.2.0 --> >=1.2.0 <2.0.0 - if (from < 0) { - from = 0; - } - if (to > this.length) { - to = this.length; + function replaceCarets(comp, options) { + return comp.trim().split(/\s+/).map(function (comp) { + return replaceCaret(comp, options); + }).join(' '); } - for (var i = 0, walker = this.head; walker !== null && i < from; i++) { - walker = walker.next; - } + function replaceCaret(comp, options) { + debug('caret', comp, options); + var r = options.loose ? re[CARETLOOSE] : re[CARET]; + return comp.replace(r, function (_, M, m, p, pr) { + debug('caret', comp, _, M, m, p, pr); + var ret; - for (; walker !== null && i < to; i++, walker = walker.next) { - ret.push(walker.value); - } + if (isX(M)) { + ret = ''; + } else if (isX(m)) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; + } else if (isX(p)) { + if (M === '0') { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; + } else { + ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0'; + } + } else if (pr) { + debug('replaceCaret pr', pr); - return ret; -}; + if (M === '0') { + if (m === '0') { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + ' <' + M + '.' + m + '.' + (+p + 1); + } else { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + ' <' + M + '.' + (+m + 1) + '.0'; + } + } else { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + ' <' + (+M + 1) + '.0.0'; + } + } else { + debug('no pr'); -Yallist.prototype.sliceReverse = function (from, to) { - to = to || this.length; + if (M === '0') { + if (m === '0') { + ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + m + '.' + (+p + 1); + } else { + ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + (+m + 1) + '.0'; + } + } else { + ret = '>=' + M + '.' + m + '.' + p + ' <' + (+M + 1) + '.0.0'; + } + } - if (to < 0) { - to += this.length; + debug('caret return', ret); + return ret; + }); + } + + function replaceXRanges(comp, options) { + debug('replaceXRanges', comp, options); + return comp.split(/\s+/).map(function (comp) { + return replaceXRange(comp, options); + }).join(' '); } - from = from || 0; + function replaceXRange(comp, options) { + comp = comp.trim(); + var r = options.loose ? re[XRANGELOOSE] : re[XRANGE]; + return comp.replace(r, function (ret, gtlt, M, m, p, pr) { + debug('xRange', comp, ret, gtlt, M, m, p, pr); + var xM = isX(M); + var xm = xM || isX(m); + var xp = xm || isX(p); + var anyX = xp; - if (from < 0) { - from += this.length; - } + if (gtlt === '=' && anyX) { + gtlt = ''; + } - var ret = new Yallist(); + if (xM) { + if (gtlt === '>' || gtlt === '<') { + // nothing is allowed + ret = '<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; + } - if (to < from || to < 0) { - return ret; - } + p = 0; - if (from < 0) { - from = 0; - } + if (gtlt === '>') { + // >1 => >=2.0.0 + // >1.2 => >=1.3.0 + // >1.2.3 => >= 1.2.4 + gtlt = '>='; - if (to > this.length) { - to = this.length; - } + 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 = '<'; - for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) { - walker = walker.prev; - } + if (xm) { + M = +M + 1; + } else { + m = +m + 1; + } + } - for (; walker !== null && i > from; i--, walker = walker.prev) { - ret.push(walker.value); - } + ret = gtlt + M + '.' + m + '.' + p; + } else if (xm) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; + } else if (xp) { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; + } - return ret; -}; + debug('xRange return', ret); + return ret; + }); + } // Because * is AND-ed with everything else in the comparator, + // and '' means "any version", just remove the *s entirely. -Yallist.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; - } + function replaceStars(comp, options) { + debug('replaceStars', comp, options); // Looseness is ignored here. star is always as loose as it gets! - this.head = tail; - this.tail = head; - return this; -}; + return comp.trim().replace(re[STAR], ''); + } // This function is passed to string.replace(re[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 Any 3.4.x will do + // 1.2 - 3.4 => >=1.2.0 <3.5.0 -function push(self, item) { - self.tail = new Node(item, self.tail, null, self); - if (!self.head) { - self.head = self.tail; - } + function hyphenReplace($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'; + } else if (isX(fp)) { + from = '>=' + fM + '.' + fm + '.0'; + } else { + from = '>=' + from; + } - self.length++; -} + if (isX(tM)) { + to = ''; + } else if (isX(tm)) { + to = '<' + (+tM + 1) + '.0.0'; + } else if (isX(tp)) { + to = '<' + tM + '.' + (+tm + 1) + '.0'; + } else if (tpr) { + to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr; + } else { + to = '<=' + to; + } -function unshift(self, item) { - self.head = new Node(item, null, self.head, self); + return (from + ' ' + to).trim(); + } // if ANY of the sets match ALL of its comparators, then pass - if (!self.tail) { - self.tail = self.head; - } - self.length++; -} + Range.prototype.test = function (version) { + if (!version) { + return false; + } -function Node(value, prev, next, list) { - if (!(this instanceof Node)) { - return new Node(value, prev, next, list); - } + if (typeof version === 'string') { + version = new SemVer(version, this.options); + } - this.list = list; - this.value = value; + for (var i = 0; i < this.set.length; i++) { + if (testSet(this.set[i], version, this.options)) { + return true; + } + } - if (prev) { - prev.next = this; - this.prev = prev; - } else { - this.prev = null; - } + return false; + }; - if (next) { - next.prev = this; - this.next = next; - } else { - this.next = null; - } -} + function testSet(set, version, options) { + for (var i = 0; i < set.length; i++) { + if (!set[i].test(version)) { + return false; + } + } -var lruCache = LRUCache; // This will be a proper iterable 'Map' in engines that support it, -// or a fakey-fake PseudoMap in older versions. -// A linked list to keep track of recently-used-ness -// use symbols if possible, otherwise just _props + 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 (i = 0; i < set.length; i++) { + debug(set[i].semver); -var hasSymbol = typeof Symbol === 'function' && process.env._nodeLRUCacheForceNoSymbol !== '1'; -var makeSymbol; + if (set[i].semver === ANY) { + continue; + } -if (hasSymbol) { - makeSymbol = function (key) { - return Symbol(key); - }; -} else { - makeSymbol = function (key) { - return '_' + key; - }; -} + if (set[i].semver.prerelease.length > 0) { + var allowed = set[i].semver; -var MAX = makeSymbol('max'); -var LENGTH = makeSymbol('length'); -var LENGTH_CALCULATOR = makeSymbol('lengthCalculator'); -var ALLOW_STALE = makeSymbol('allowStale'); -var MAX_AGE = makeSymbol('maxAge'); -var DISPOSE = makeSymbol('dispose'); -var NO_DISPOSE_ON_SET = makeSymbol('noDisposeOnSet'); -var LRU_LIST = makeSymbol('lruList'); -var CACHE = makeSymbol('cache'); + 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. -function naiveLength() { - return 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. + return false; + } -function LRUCache(options) { - if (!(this instanceof LRUCache)) { - return new LRUCache(options); + return true; } - if (typeof options === 'number') { - options = { - max: options - }; - } + exports.satisfies = satisfies; - if (!options) { - options = {}; + function satisfies(version, range, options) { + try { + range = new Range(range, options); + } catch (er) { + return false; + } + + return range.test(version); } - var max = this[MAX] = options.max; // Kind of weird to have a default max of Infinity, but oh well. + exports.maxSatisfying = maxSatisfying; - if (!max || !(typeof max === 'number') || max <= 0) { - this[MAX] = Infinity; - } + function maxSatisfying(versions, range, options) { + var max = null; + var maxSV = null; - var lc = options.length || naiveLength; + try { + var rangeObj = new Range(range, options); + } catch (er) { + return null; + } - if (typeof lc !== 'function') { - lc = naiveLength; + versions.forEach(function (v) { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!max || maxSV.compare(v) === -1) { + // compare(max, v, true) + max = v; + maxSV = new SemVer(max, options); + } + } + }); + return max; } - this[LENGTH_CALCULATOR] = lc; - this[ALLOW_STALE] = options.stale || false; - this[MAX_AGE] = options.maxAge || 0; - this[DISPOSE] = options.dispose; - this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false; - this.reset(); -} // resize the cache when the max changes. + exports.minSatisfying = minSatisfying; + function minSatisfying(versions, range, options) { + var min = null; + var minSV = null; -Object.defineProperty(LRUCache.prototype, 'max', { - set: function (mL) { - if (!mL || !(typeof mL === 'number') || mL <= 0) { - mL = Infinity; + try { + var rangeObj = new Range(range, options); + } catch (er) { + return null; } - this[MAX] = mL; - trim$2(this); - }, - get: function () { - return this[MAX]; - }, - enumerable: true -}); -Object.defineProperty(LRUCache.prototype, 'allowStale', { - set: function (allowStale) { - this[ALLOW_STALE] = !!allowStale; - }, - get: function () { - return this[ALLOW_STALE]; - }, - enumerable: true -}); -Object.defineProperty(LRUCache.prototype, 'maxAge', { - set: function (mA) { - if (!mA || !(typeof mA === 'number') || mA < 0) { - mA = 0; - } + versions.forEach(function (v) { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!min || minSV.compare(v) === 1) { + // compare(min, v, true) + min = v; + minSV = new SemVer(min, options); + } + } + }); + return min; + } - this[MAX_AGE] = mA; - trim$2(this); - }, - get: function () { - return this[MAX_AGE]; - }, - enumerable: true -}); // resize the cache when the lengthCalculator changes. + exports.minVersion = minVersion; -Object.defineProperty(LRUCache.prototype, 'lengthCalculator', { - set: function (lC) { - if (typeof lC !== 'function') { - lC = naiveLength; + function minVersion(range, loose) { + range = new Range(range, loose); + var minver = new SemVer('0.0.0'); + + if (range.test(minver)) { + return minver; } - if (lC !== this[LENGTH_CALCULATOR]) { - this[LENGTH_CALCULATOR] = lC; - this[LENGTH] = 0; - this[LRU_LIST].forEach(function (hit) { - hit.length = this[LENGTH_CALCULATOR](hit.value, hit.key); - this[LENGTH] += hit.length; - }, this); + minver = new SemVer('0.0.0-0'); + + if (range.test(minver)) { + return minver; } - trim$2(this); - }, - get: function () { - return this[LENGTH_CALCULATOR]; - }, - enumerable: true -}); -Object.defineProperty(LRUCache.prototype, 'length', { - get: function () { - return this[LENGTH]; - }, - enumerable: true -}); -Object.defineProperty(LRUCache.prototype, 'itemCount', { - get: function () { - return this[LRU_LIST].length; - }, - enumerable: true -}); + minver = null; -LRUCache.prototype.rforEach = function (fn, thisp) { - thisp = thisp || this; + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i]; + comparators.forEach(function (comparator) { + // Clone to avoid manipulating the comparator's semver object. + var compver = new SemVer(comparator.semver.version); - for (var walker = this[LRU_LIST].tail; walker !== null;) { - var prev = walker.prev; - forEachStep(this, fn, walker, thisp); - walker = prev; - } -}; + switch (comparator.operator) { + case '>': + if (compver.prerelease.length === 0) { + compver.patch++; + } else { + compver.prerelease.push(0); + } -function forEachStep(self, fn, node, thisp) { - var hit = node.value; + compver.raw = compver.format(); - if (isStale(self, hit)) { - del(self, node); + /* fallthrough */ - if (!self[ALLOW_STALE]) { - hit = undefined; - } - } + case '': + case '>=': + if (!minver || gt(minver, compver)) { + minver = compver; + } - if (hit) { - fn.call(thisp, hit.value, hit.key, self); - } -} + break; -LRUCache.prototype.forEach = function (fn, thisp) { - thisp = thisp || this; + case '<': + case '<=': + /* Ignore maximum versions */ + break; - for (var walker = this[LRU_LIST].head; walker !== null;) { - var next = walker.next; - forEachStep(this, fn, walker, thisp); - walker = next; - } -}; + /* istanbul ignore next */ -LRUCache.prototype.keys = function () { - return this[LRU_LIST].toArray().map(function (k) { - return k.key; - }, this); -}; + default: + throw new Error('Unexpected operation: ' + comparator.operator); + } + }); + } -LRUCache.prototype.values = function () { - return this[LRU_LIST].toArray().map(function (k) { - return k.value; - }, this); -}; + if (minver && range.test(minver)) { + return minver; + } -LRUCache.prototype.reset = function () { - if (this[DISPOSE] && this[LRU_LIST] && this[LRU_LIST].length) { - this[LRU_LIST].forEach(function (hit) { - this[DISPOSE](hit.key, hit.value); - }, this); + return null; } - this[CACHE] = new map(); // hash of items by key + exports.validRange = validRange; - this[LRU_LIST] = new yallist(); // list of items in order of use recency + function validRange(range, options) { + try { + // Return '*' instead of '' so that truthiness works. + // This will throw if it's invalid anyway + return new Range(range, options).range || '*'; + } catch (er) { + return null; + } + } // Determine if version is less than all the versions possible in the range - this[LENGTH] = 0; // length of items in the list -}; -LRUCache.prototype.dump = function () { - return this[LRU_LIST].map(function (hit) { - if (!isStale(this, hit)) { - return { - k: hit.key, - v: hit.value, - e: hit.now + (hit.maxAge || 0) - }; - } - }, this).toArray().filter(function (h) { - return h; - }); -}; + exports.ltr = ltr; -LRUCache.prototype.dumpLru = function () { - return this[LRU_LIST]; -}; -/* istanbul ignore next */ + function ltr(version, range, options) { + return outside(version, range, '<', options); + } // Determine if version is greater than all the versions possible in the range. -LRUCache.prototype.inspect = function (n, opts) { - var str = 'LRUCache {'; - var extras = false; - var as = this[ALLOW_STALE]; + exports.gtr = gtr; - if (as) { - str += '\n allowStale: true'; - extras = true; + function gtr(version, range, options) { + return outside(version, range, '>', options); } - var max = this[MAX]; + exports.outside = outside; - if (max && max !== Infinity) { - if (extras) { - str += ','; - } + function outside(version, range, hilo, options) { + version = new SemVer(version, options); + range = new Range(range, options); + var gtfn, ltefn, ltfn, comp, ecomp; - str += '\n max: ' + util$3.inspect(max, opts); - extras = true; - } + switch (hilo) { + case '>': + gtfn = gt; + ltefn = lte; + ltfn = lt; + comp = '>'; + ecomp = '>='; + break; - var maxAge = this[MAX_AGE]; + case '<': + gtfn = lt; + ltefn = gte; + ltfn = gt; + comp = '<'; + ecomp = '<='; + break; - if (maxAge) { - if (extras) { - str += ','; - } + default: + throw new TypeError('Must provide a hilo val of "<" or ">"'); + } // If it satisifes the range it is not outside - str += '\n maxAge: ' + util$3.inspect(maxAge, opts); - extras = true; - } - var lc = this[LENGTH_CALCULATOR]; + if (satisfies(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. - if (lc && lc !== naiveLength) { - if (extras) { - str += ','; - } - str += '\n length: ' + util$3.inspect(this[LENGTH], opts); - extras = true; - } + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i]; + var high = null; + var low = null; + comparators.forEach(function (comparator) { + if (comparator.semver === ANY) { + comparator = new Comparator('>=0.0.0'); + } - var didFirst = false; - this[LRU_LIST].forEach(function (item) { - if (didFirst) { - str += ',\n '; - } else { - if (extras) { - str += ',\n'; - } + high = high || comparator; + low = low || comparator; - didFirst = true; - str += '\n '; - } + 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 - var key = util$3.inspect(item.key).split('\n').join('\n '); - var val = { - value: item.value - }; + 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 (item.maxAge !== maxAge) { - val.maxAge = item.maxAge; - } - if (lc !== naiveLength) { - val.length = item.length; + if ((!low.operator || low.operator === comp) && ltefn(version, low.semver)) { + return false; + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false; + } } - if (isStale(this, item)) { - val.stale = true; - } + return true; + } - val = util$3.inspect(val, opts).split('\n').join('\n '); - str += key + ' => ' + val; - }); + exports.prerelease = prerelease; - if (didFirst || extras) { - str += '\n'; + function prerelease(version, options) { + var parsed = parse(version, options); + return parsed && parsed.prerelease.length ? parsed.prerelease : null; } - str += '}'; - return str; -}; - -LRUCache.prototype.set = function (key, value, maxAge) { - maxAge = maxAge || this[MAX_AGE]; - var now = maxAge ? Date.now() : 0; - var len = this[LENGTH_CALCULATOR](value, key); + exports.intersects = intersects; - if (this[CACHE].has(key)) { - if (len > this[MAX]) { - del(this, this[CACHE].get(key)); - return false; - } + function intersects(r1, r2, options) { + r1 = new Range(r1, options); + r2 = new Range(r2, options); + return r1.intersects(r2); + } - var node = this[CACHE].get(key); - var item = node.value; // dispose of the old one before overwriting - // split out into 2 ifs for better coverage tracking + exports.coerce = coerce; - if (this[DISPOSE]) { - if (!this[NO_DISPOSE_ON_SET]) { - this[DISPOSE](key, item.value); - } + function coerce(version) { + if (version instanceof SemVer) { + return version; } - item.now = now; - item.maxAge = maxAge; - item.value = value; - this[LENGTH] += len - item.length; - item.length = len; - this.get(key); - trim$2(this); - return true; - } + if (typeof version !== 'string') { + return null; + } - var hit = new Entry$1(key, value, len, now, maxAge); // oversized objects fall out of cache automatically. + var match = version.match(re[COERCE]); - if (hit.length > this[MAX]) { - if (this[DISPOSE]) { - this[DISPOSE](key, value); + if (match == null) { + return null; } - return false; + return parse(match[1] + '.' + (match[2] || '0') + '.' + (match[3] || '0')); } +}); - this[LENGTH] += hit.length; - this[LRU_LIST].unshift(hit); - this[CACHE].set(key, this[LRU_LIST].head); - trim$2(this); - return true; -}; +var hasOwnProperty$3 = Object.prototype.hasOwnProperty; +var pseudomap = PseudoMap; -LRUCache.prototype.has = function (key) { - if (!this[CACHE].has(key)) return false; - var hit = this[CACHE].get(key).value; +function PseudoMap(set) { + if (!(this instanceof PseudoMap)) // whyyyyyyy + throw new TypeError("Constructor PseudoMap requires 'new'"); + this.clear(); - if (isStale(this, hit)) { - return false; + if (set) { + if (set instanceof PseudoMap || typeof Map === 'function' && set instanceof Map) set.forEach(function (value, key) { + this.set(key, value); + }, this);else if (Array.isArray(set)) set.forEach(function (kv) { + this.set(kv[0], kv[1]); + }, this);else throw new TypeError('invalid argument'); } +} - return true; -}; - -LRUCache.prototype.get = function (key) { - return get(this, key, true); +PseudoMap.prototype.forEach = function (fn, thisp) { + thisp = thisp || this; + Object.keys(this._data).forEach(function (k) { + if (k !== 'size') fn.call(thisp, this._data[k].value, this._data[k].key); + }, this); }; -LRUCache.prototype.peek = function (key) { - return get(this, key, false); +PseudoMap.prototype.has = function (k) { + return !!find(this._data, k); }; -LRUCache.prototype.pop = function () { - var node = this[LRU_LIST].tail; - if (!node) return null; - del(this, node); - return node.value; +PseudoMap.prototype.get = function (k) { + var res = find(this._data, k); + return res && res.value; }; -LRUCache.prototype.del = function (key) { - del(this, this[CACHE].get(key)); +PseudoMap.prototype.set = function (k, v) { + set(this._data, k, v); }; -LRUCache.prototype.load = function (arr) { - // reset the cache - this.reset(); - var now = Date.now(); // A previous serialized cache has the most recent items first - - for (var l = arr.length - 1; l >= 0; l--) { - var hit = arr[l]; - var 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 { - var maxAge = expiresAt - now; // dont add already expired items +PseudoMap.prototype.delete = function (k) { + var res = find(this._data, k); - if (maxAge > 0) { - this.set(hit.k, hit.v, maxAge); - } - } + if (res) { + delete this._data[res._index]; + this._data.size--; } }; -LRUCache.prototype.prune = function () { - var self = this; - this[CACHE].forEach(function (value, key) { - get(self, key, false); +PseudoMap.prototype.clear = function () { + var data = Object.create(null); + data.size = 0; + Object.defineProperty(this, '_data', { + value: data, + enumerable: false, + configurable: true, + writable: false }); }; -function get(self, key, doUse) { - var node = self[CACHE].get(key); +Object.defineProperty(PseudoMap.prototype, 'size', { + get: function () { + return this._data.size; + }, + set: function (n) {}, + enumerable: true, + configurable: true +}); - if (node) { - var hit = node.value; +PseudoMap.prototype.values = PseudoMap.prototype.keys = PseudoMap.prototype.entries = function () { + throw new Error('iterators are not implemented in this version'); +}; // Either identical, or both NaN - if (isStale(self, hit)) { - del(self, node); - if (!self[ALLOW_STALE]) hit = undefined; - } else { - if (doUse) { - self[LRU_LIST].unshiftNode(node); - } - } - if (hit) hit = hit.value; - } +function same(a, b) { + return a === b || a !== a && b !== b; +} - return hit; +function Entry(k, v, i) { + this.key = k; + this.value = v; + this._index = i; } -function isStale(self, hit) { - if (!hit || !hit.maxAge && !self[MAX_AGE]) { - return false; +function find(data, k) { + for (var i = 0, s = '_' + k, key = s; hasOwnProperty$3.call(data, key); key = s + i++) { + if (same(data[key].key, k)) return data[key]; } +} - var stale = false; - var diff = Date.now() - hit.now; +function set(data, k, v) { + for (var i = 0, s = '_' + k, key = s; hasOwnProperty$3.call(data, key); key = s + i++) { + if (same(data[key].key, k)) { + data[key].value = v; + return; + } + } - if (hit.maxAge) { - stale = diff > hit.maxAge; + data.size++; + data[key] = new Entry(k, v, key); +} + +var map = createCommonjsModule(function (module) { + if (process.env.npm_package_name === 'pseudomap' && process.env.npm_lifecycle_script === 'test') process.env.TEST_PSEUDOMAP = 'true'; + + if (typeof Map === 'function' && !process.env.TEST_PSEUDOMAP) { + module.exports = Map; } else { - stale = self[MAX_AGE] && diff > self[MAX_AGE]; + module.exports = pseudomap; } +}); - return stale; -} +var yallist = Yallist; +Yallist.Node = Node; +Yallist.create = Yallist; -function trim$2(self) { - if (self[LENGTH] > self[MAX]) { - for (var 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. - var prev = walker.prev; - del(self, walker); - walker = prev; +function Yallist(list) { + var self = this; + + if (!(self instanceof Yallist)) { + self = new Yallist(); + } + + 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; } -function del(self, node) { - if (node) { - var hit = node.value; +Yallist.prototype.removeNode = function (node) { + if (node.list !== this) { + throw new Error('removing node which does not belong to this list'); + } - if (self[DISPOSE]) { - self[DISPOSE](hit.key, hit.value); - } + var next = node.next; + var prev = node.prev; - self[LENGTH] -= hit.length; - self[CACHE].delete(hit.key); - self[LRU_LIST].removeNode(node); + if (next) { + next.prev = prev; } -} // classy, since V8 prefers predictable objects. + if (prev) { + prev.next = next; + } -function Entry$1(key, value, length, now, maxAge) { - this.key = key; - this.value = value; - this.length = length; - this.now = now; - this.maxAge = maxAge || 0; -} + if (node === this.head) { + this.head = next; + } -var sigmund_1 = sigmund; + if (node === this.tail) { + this.tail = prev; + } -function sigmund(subject, maxSessions) { - maxSessions = maxSessions || 10; - var notes = []; - var analysis = ''; - var RE = RegExp; + node.list.length--; + node.next = null; + node.prev = null; + node.list = null; +}; - function psychoAnalyze(subject, session) { - if (session > maxSessions) return; +Yallist.prototype.unshiftNode = function (node) { + if (node === this.head) { + return; + } - if (typeof subject === 'function' || typeof subject === 'undefined') { - return; - } + if (node.list) { + node.list.removeNode(node); + } - if (typeof subject !== 'object' || !subject || subject instanceof RE) { - analysis += subject; - return; - } + var head = this.head; + node.list = this; + node.next = head; - if (notes.indexOf(subject) !== -1 || session === maxSessions) return; - notes.push(subject); - analysis += '{'; - Object.keys(subject).forEach(function (issue, _, __) { - // pseudo-private values. skip those. - if (issue.charAt(0) === '_') return; - var to = typeof subject[issue]; - if (to === 'function' || to === 'undefined') return; - analysis += issue; - psychoAnalyze(subject[issue], session + 1); - }); + if (head) { + head.prev = node; } - psychoAnalyze(subject, 0); - return analysis; -} // vim: set softtabstop=4 shiftwidth=4: + this.head = node; -var fnmatch = createCommonjsModule(function (module, exports) { - // Based on minimatch.js by isaacs - var platform = typeof process === "object" ? process.platform : "win32"; - if (module) module.exports = minimatch;else exports.minimatch = minimatch; - minimatch.Minimatch = Minimatch; - var cache = minimatch.cache = new lruCache({ - max: 100 - }), - GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}; - var qmark = "[^/]" // * => any number of characters - , - 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. - , - twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?" // not a ^ or / followed by a dot, - // followed by anything, any number of times. - , - twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?" // characters that need to be escaped in RegExp. - , - reSpecials = charSet("().*{}+?[]^$\\!"); // "abc" -> { a:true, b:true, c:true } + if (!this.tail) { + this.tail = node; + } - function charSet(s) { - return s.split("").reduce(function (set, c) { - set[c] = true; - return set; - }, {}); - } // normalizes slashes. + this.length++; +}; +Yallist.prototype.pushNode = function (node) { + if (node === this.tail) { + return; + } - var slashSplit = /\/+/; - minimatch.monkeyPatch = monkeyPatch; + if (node.list) { + node.list.removeNode(node); + } - function monkeyPatch() { - var desc = Object.getOwnPropertyDescriptor(String.prototype, "match"); - var orig = desc.value; + var tail = this.tail; + node.list = this; + node.prev = tail; - desc.value = function (p) { - if (p instanceof Minimatch) return p.match(this); - return orig.call(this, p); - }; + if (tail) { + tail.next = node; + } - Object.defineProperty(String.prototype, desc); + this.tail = node; + + if (!this.head) { + this.head = node; } - minimatch.filter = filter; + this.length++; +}; - function filter(pattern, options) { - options = options || {}; - return function (p, i, list) { - return minimatch(p, pattern, options); - }; +Yallist.prototype.push = function () { + for (var i = 0, l = arguments.length; i < l; i++) { + push$1(this, arguments[i]); } - 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; + return this.length; +}; + +Yallist.prototype.unshift = function () { + for (var i = 0, l = arguments.length; i < l; i++) { + unshift(this, arguments[i]); } - minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return minimatch; - var orig = minimatch; + return this.length; +}; + +Yallist.prototype.pop = function () { + if (!this.tail) { + return undefined; + } - var m = function minimatch(p, pattern, options) { - return orig.minimatch(p, pattern, ext(def, options)); - }; + var res = this.tail.value; + this.tail = this.tail.prev; - m.Minimatch = function Minimatch(pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)); - }; + if (this.tail) { + this.tail.next = null; + } else { + this.head = null; + } - return m; - }; + this.length--; + return res; +}; - Minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return Minimatch; - return minimatch.defaults(def).Minimatch; - }; +Yallist.prototype.shift = function () { + if (!this.head) { + return undefined; + } - function minimatch(p, pattern, options) { - if (typeof pattern !== "string") { - throw new TypeError("glob pattern string required"); - } + var res = this.head.value; + this.head = this.head.next; - if (!options) options = {}; // shortcut: comments match nothing. + if (this.head) { + this.head.prev = null; + } else { + this.tail = null; + } - if (!options.nocomment && pattern.charAt(0) === "#") { - return false; - } // "" only matches "" + this.length--; + return res; +}; +Yallist.prototype.forEach = function (fn, thisp) { + thisp = thisp || this; - if (pattern.trim() === "") return p === ""; - return new Minimatch(pattern, options).match(p); + for (var walker = this.head, i = 0; walker !== null; i++) { + fn.call(thisp, walker.value, i, this); + walker = walker.next; } +}; - function Minimatch(pattern, options) { - if (!(this instanceof Minimatch)) { - return new Minimatch(pattern, options, cache); - } +Yallist.prototype.forEachReverse = function (fn, thisp) { + thisp = thisp || this; - if (typeof pattern !== "string") { - throw new TypeError("glob pattern string required"); - } + for (var walker = this.tail, i = this.length - 1; walker !== null; i--) { + fn.call(thisp, walker.value, i, this); + walker = walker.prev; + } +}; - if (!options) options = {}; // windows: need to use /, not \ - // On other platforms, \ is a valid (albeit bad) filename char. +Yallist.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 (platform === "win32") { - pattern = pattern.split("\\").join("/"); - } // lru storage. - // these things aren't particularly big, but walking down the string - // and turning it into a regexp can get pretty costly. + if (i === n && walker !== null) { + return walker.value; + } +}; +Yallist.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; + } - var cacheKey = pattern + "\n" + sigmund_1(options); - var cached = minimatch.cache.get(cacheKey); - if (cached) return cached; - minimatch.cache.set(cacheKey, this); - 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. + if (i === n && walker !== null) { + return walker.value; + } +}; - this.make(); +Yallist.prototype.map = function (fn, thisp) { + thisp = thisp || this; + var res = new Yallist(); + + for (var walker = this.head; walker !== null;) { + res.push(fn.call(thisp, walker.value, this)); + walker = walker.next; } - Minimatch.prototype.make = make; + return res; +}; - 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. +Yallist.prototype.mapReverse = function (fn, thisp) { + thisp = thisp || this; + var res = new Yallist(); - if (!options.nocomment && pattern.charAt(0) === "#") { - this.comment = true; - return; - } + for (var walker = this.tail; walker !== null;) { + res.push(fn.call(thisp, walker.value, this)); + walker = walker.prev; + } - if (!pattern) { - this.empty = true; - return; - } // step 1: figure out negation, etc. + return res; +}; +Yallist.prototype.reduce = function (fn, initial) { + var acc; + var walker = this.head; - this.parseNegate(); // step 2: expand braces + 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'); + } - var set = this.globSet = this.braceExpand(); - if (options.debug) console.error(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 + for (var i = 0; walker !== null; i++) { + acc = fn(acc, walker.value, i); + walker = walker.next; + } - set = this.globParts = set.map(function (s) { - return s.split(slashSplit); - }); - if (options.debug) console.error(this.pattern, set); // glob --> regexps + return acc; +}; - set = set.map(function (s, si, set) { - return s.map(this.parse, this); - }, this); - if (options.debug) console.error(this.pattern, set); // filter out everything that didn't compile properly. +Yallist.prototype.reduceReverse = function (fn, initial) { + var acc; + var walker = this.tail; - set = set.filter(function (s) { - return -1 === s.indexOf(false); - }); - if (options.debug) console.error(this.pattern, set); - this.set = set; + 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'); } - Minimatch.prototype.parseNegate = parseNegate; + for (var i = this.length - 1; walker !== null; i--) { + acc = fn(acc, walker.value, i); + walker = walker.prev; + } - function parseNegate() { - var pattern = this.pattern, - negate = false, - options = this.options, - negateOffset = 0; - if (options.nonegate) return; + return acc; +}; - for (var i = 0, l = pattern.length; i < l && pattern.charAt(i) === "!"; i++) { - negate = !negate; - negateOffset++; - } +Yallist.prototype.toArray = function () { + var arr = new Array(this.length); - 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 + for (var i = 0, walker = this.head; walker !== null; i++) { + arr[i] = walker.value; + walker = walker.next; + } + return arr; +}; - minimatch.braceExpand = function (pattern, options) { - return new Minimatch(pattern, options).braceExpand(); - }; +Yallist.prototype.toArrayReverse = function () { + var arr = new Array(this.length); - Minimatch.prototype.braceExpand = braceExpand; + for (var i = 0, walker = this.tail; walker !== null; i++) { + arr[i] = walker.value; + walker = walker.prev; + } - function braceExpand(pattern, options) { - options = options || this.options; - pattern = typeof pattern === "undefined" ? this.pattern : pattern; + return arr; +}; - if (typeof pattern === "undefined") { - throw new Error("undefined pattern"); - } +Yallist.prototype.slice = function (from, to) { + to = to || this.length; - if (options.nobrace || !pattern.match(/\{.*\}/)) { - // shortcut. no need to expand. - return [pattern]; - } + if (to < 0) { + to += this.length; + } - var escaping = false; // examples and comments refer to this crazy pattern: - // a{b,c{d,e},{f,g}h}x{y,z} - // expected: - // abxy - // abxz - // acdxy - // acdxz - // acexy - // acexz - // afhxy - // afhxz - // aghxy - // aghxz - // everything before the first \{ is just a prefix. - // So, we pluck that off, and work with the rest, - // and then prepend it to everything we find. + from = from || 0; - if (pattern.charAt(0) !== "{") { - // console.error(pattern) - var prefix = null; + if (from < 0) { + from += this.length; + } - for (var i = 0, l = pattern.length; i < l; i++) { - var c = pattern.charAt(i); // console.error(i, c) + var ret = new Yallist(); - if (c === "\\") { - escaping = !escaping; - } else if (c === "{" && !escaping) { - prefix = pattern.substr(0, i); - break; - } - } // actually no sets, all { were escaped. + if (to < from || to < 0) { + return ret; + } + if (from < 0) { + from = 0; + } - if (prefix === null) { - // console.error("no sets") - return [pattern]; - } + if (to > this.length) { + to = this.length; + } - var tail = braceExpand(pattern.substr(i), options); - return tail.map(function (t) { - return prefix + t; - }); - } // now we have something like: - // {b,c{d,e},{f,g}h}x{y,z} - // walk through the set, expanding each part, until - // the set ends. then, we'll expand the suffix. - // If the set only has a single member, then'll put the {} back - // first, handle numeric sets, since they're easier + 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); + } - var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/); + return ret; +}; - if (numset) { - // console.error("numset", numset[1], numset[2]) - var suf = braceExpand(pattern.substr(numset[0].length), options), - start = +numset[1], - end = +numset[2], - inc = start > end ? -1 : 1, - set = []; +Yallist.prototype.sliceReverse = function (from, to) { + to = to || this.length; - for (var i = start; i != end + inc; i += inc) { - // append all the suffixes - for (var ii = 0, ll = suf.length; ii < ll; ii++) { - set.push(i + suf[ii]); - } - } + if (to < 0) { + to += this.length; + } - return set; - } // ok, walk through the set - // We hope, somewhat optimistically, that there - // will be a } at the end. - // If the closing brace isn't found, then the pattern is - // interpreted as braceExpand("\\" + pattern) so that - // the leading \{ will be interpreted literally. + from = from || 0; + if (from < 0) { + from += this.length; + } - var i = 1 // skip the \{ - , - depth = 1, - set = [], - member = "", - escaping = false; + var ret = new Yallist(); - function addMember() { - set.push(member); - member = ""; - } // console.error("Entering for") + if (to < from || to < 0) { + return ret; + } + if (from < 0) { + from = 0; + } - FOR: for (i = 1, l = pattern.length; i < l; i++) { - var c = pattern.charAt(i); // console.error("", i, c) + if (to > this.length) { + to = this.length; + } - if (escaping) { - escaping = false; - member += "\\" + c; - } else { - switch (c) { - case "\\": - escaping = true; - continue; + for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) { + walker = walker.prev; + } - case "{": - depth++; - member += "{"; - continue; + for (; walker !== null && i > from; i--, walker = walker.prev) { + ret.push(walker.value); + } - case "}": - depth--; // if this closes the actual set, then we're done + return ret; +}; - if (depth === 0) { - addMember(); // pluck off the close-brace +Yallist.prototype.reverse = function () { + var head = this.head; + var tail = this.tail; - i++; - break FOR; - } else { - member += c; - continue; - } + for (var walker = head; walker !== null; walker = walker.prev) { + var p = walker.prev; + walker.prev = walker.next; + walker.next = p; + } - case ",": - if (depth === 1) { - addMember(); - } else { - member += c; - } + this.head = tail; + this.tail = head; + return this; +}; - continue; +function push$1(self, item) { + self.tail = new Node(item, self.tail, null, self); - default: - member += c; - continue; - } // switch + if (!self.head) { + self.head = self.tail; + } - } // else + self.length++; +} - } // for - // now we've either finished the set, and the suffix is - // pattern.substr(i), or we have *not* closed the set, - // and need to escape the leading brace +function unshift(self, item) { + self.head = new Node(item, null, self.head, self); + if (!self.tail) { + self.tail = self.head; + } - if (depth !== 0) { - // console.error("didn't close", pattern) - return braceExpand("\\" + pattern, options); - } // x{y,z} -> ["xy", "xz"] - // console.error("set", set) - // console.error("suffix", pattern.substr(i)) + self.length++; +} +function Node(value, prev, next, list) { + if (!(this instanceof Node)) { + return new Node(value, prev, next, list); + } - var suf = braceExpand(pattern.substr(i), options); // ["b", "c{d,e}","{f,g}h"] -> - // [["b"], ["cd", "ce"], ["fh", "gh"]] + this.list = list; + this.value = value; - var addBraces = set.length === 1; // console.error("set pre-expanded", set) + if (prev) { + prev.next = this; + this.prev = prev; + } else { + this.prev = null; + } - set = set.map(function (p) { - return braceExpand(p, options); - }); // console.error("set expanded", set) - // [["b"], ["cd", "ce"], ["fh", "gh"]] -> - // ["b", "cd", "ce", "fh", "gh"] + if (next) { + next.prev = this; + this.next = next; + } else { + this.next = null; + } +} - set = set.reduce(function (l, r) { - return l.concat(r); - }); +var lruCache = LRUCache; // This will be a proper iterable 'Map' in engines that support it, +// or a fakey-fake PseudoMap in older versions. +// A linked list to keep track of recently-used-ness +// use symbols if possible, otherwise just _props - if (addBraces) { - set = set.map(function (s) { - return "{" + s + "}"; - }); - } // now attach the suffixes. +var hasSymbol = typeof Symbol === 'function' && process.env._nodeLRUCacheForceNoSymbol !== '1'; +var makeSymbol; +if (hasSymbol) { + makeSymbol = function (key) { + return Symbol(key); + }; +} else { + makeSymbol = function (key) { + return '_' + key; + }; +} - var ret = []; +var MAX = makeSymbol('max'); +var LENGTH = makeSymbol('length'); +var LENGTH_CALCULATOR = makeSymbol('lengthCalculator'); +var ALLOW_STALE = makeSymbol('allowStale'); +var MAX_AGE = makeSymbol('maxAge'); +var DISPOSE = makeSymbol('dispose'); +var NO_DISPOSE_ON_SET = makeSymbol('noDisposeOnSet'); +var LRU_LIST = makeSymbol('lruList'); +var CACHE = makeSymbol('cache'); - for (var i = 0, l = set.length; i < l; i++) { - for (var ii = 0, ll = suf.length; ii < ll; ii++) { - ret.push(set[i] + suf[ii]); - } - } +function naiveLength() { + return 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. - return ret; - } // 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. +function LRUCache(options) { + if (!(this instanceof LRUCache)) { + return new LRUCache(options); + } - Minimatch.prototype.parse = parse; - var SUBPARSE = {}; + if (typeof options === 'number') { + options = { + max: options + }; + } - function parse(pattern, isSub) { - var options = this.options; // shortcuts + if (!options) { + options = {}; + } - if (!options.noglobstar && pattern === "**") return GLOBSTAR; - if (pattern === "") return ""; - var re = "", - hasMagic = !!options.nocase, - escaping = false // ? => one single character - , - patternListStack = [], - plType, - stateChar, - inClass = false, - reClassStart = -1, - classStart = -1 // . and .. never match anything that doesn't start with ., - // even when options.dot is set. - , - patternStart = pattern.charAt(0) === "." ? "" // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))" : "(?!\\.)"; + var max = this[MAX] = options.max; // Kind of weird to have a default max of Infinity, but oh well. - 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; + if (!max || !(typeof max === 'number') || max <= 0) { + this[MAX] = Infinity; + } - case "?": - re += qmark; - hasMagic = true; - break; + var lc = options.length || naiveLength; - default: - re += "\\" + stateChar; - break; - } + if (typeof lc !== 'function') { + lc = naiveLength; + } - stateChar = false; - } + this[LENGTH_CALCULATOR] = lc; + this[ALLOW_STALE] = options.stale || false; + this[MAX_AGE] = options.maxAge || 0; + this[DISPOSE] = options.dispose; + this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false; + this.reset(); +} // resize the cache when the max changes. + + +Object.defineProperty(LRUCache.prototype, 'max', { + set: function (mL) { + if (!mL || !(typeof mL === 'number') || mL <= 0) { + mL = Infinity; } - for (var i = 0, len = pattern.length, c; i < len && (c = pattern.charAt(i)); i++) { - if (options.debug) { - console.error("%s\t%s %s %j", pattern, i, re, c); - } // skip over any that are escaped. + this[MAX] = mL; + trim$2(this); + }, + get: function () { + return this[MAX]; + }, + enumerable: true +}); +Object.defineProperty(LRUCache.prototype, 'allowStale', { + set: function (allowStale) { + this[ALLOW_STALE] = !!allowStale; + }, + get: function () { + return this[ALLOW_STALE]; + }, + enumerable: true +}); +Object.defineProperty(LRUCache.prototype, 'maxAge', { + set: function (mA) { + if (!mA || !(typeof mA === 'number') || mA < 0) { + mA = 0; + } + this[MAX_AGE] = mA; + trim$2(this); + }, + get: function () { + return this[MAX_AGE]; + }, + enumerable: true +}); // resize the cache when the lengthCalculator changes. - if (escaping && reSpecials[c]) { - re += "\\" + c; - escaping = false; - continue; - } +Object.defineProperty(LRUCache.prototype, 'lengthCalculator', { + set: function (lC) { + if (typeof lC !== 'function') { + lC = naiveLength; + } - switch (c) { - case "/": - // completely not allowed, even escaped. - // Should already be path-split by now. - return false; + if (lC !== this[LENGTH_CALCULATOR]) { + this[LENGTH_CALCULATOR] = lC; + this[LENGTH] = 0; + this[LRU_LIST].forEach(function (hit) { + hit.length = this[LENGTH_CALCULATOR](hit.value, hit.key); + this[LENGTH] += hit.length; + }, this); + } - case "\\": - clearStateChar(); - escaping = true; - continue; - // the various stateChar values - // for the "extglob" stuff. + trim$2(this); + }, + get: function () { + return this[LENGTH_CALCULATOR]; + }, + enumerable: true +}); +Object.defineProperty(LRUCache.prototype, 'length', { + get: function () { + return this[LENGTH]; + }, + enumerable: true +}); +Object.defineProperty(LRUCache.prototype, 'itemCount', { + get: function () { + return this[LRU_LIST].length; + }, + enumerable: true +}); - case "?": - case "*": - case "+": - case "@": - case "!": - if (options.debug) { - console.error("%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 +LRUCache.prototype.rforEach = function (fn, thisp) { + thisp = thisp || this; + for (var walker = this[LRU_LIST].tail; walker !== null;) { + var prev = walker.prev; + forEachStep(this, fn, walker, thisp); + walker = prev; + } +}; - if (inClass) { - 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. +function forEachStep(self, fn, node, thisp) { + var hit = node.value; + if (isStale(self, hit)) { + del(self, node); - 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 (!self[ALLOW_STALE]) { + hit = undefined; + } + } - if (options.noext) clearStateChar(); - continue; + if (hit) { + fn.call(thisp, hit.value, hit.key, self); + } +} - case "(": - if (inClass) { - re += "("; - continue; - } +LRUCache.prototype.forEach = function (fn, thisp) { + thisp = thisp || this; - if (!stateChar) { - re += "\\("; - continue; - } + for (var walker = this[LRU_LIST].head; walker !== null;) { + var next = walker.next; + forEachStep(this, fn, walker, thisp); + walker = next; + } +}; - plType = stateChar; - patternListStack.push({ - type: plType, - start: i - 1, - reStart: re.length - }); // negation is (?:(?!js)[^/]*) +LRUCache.prototype.keys = function () { + return this[LRU_LIST].toArray().map(function (k) { + return k.key; + }, this); +}; - re += stateChar === "!" ? "(?:(?!" : "(?:"; - stateChar = false; - continue; +LRUCache.prototype.values = function () { + return this[LRU_LIST].toArray().map(function (k) { + return k.value; + }, this); +}; - case ")": - if (inClass || !patternListStack.length) { - re += "\\)"; - continue; - } +LRUCache.prototype.reset = function () { + if (this[DISPOSE] && this[LRU_LIST] && this[LRU_LIST].length) { + this[LRU_LIST].forEach(function (hit) { + this[DISPOSE](hit.key, hit.value); + }, this); + } - hasMagic = true; - re += ")"; - plType = patternListStack.pop().type; // negation is (?:(?!js)[^/]*) - // The others are (?:) + this[CACHE] = new map(); // hash of items by key - switch (plType) { - case "!": - re += "[^/]*?)"; - break; + this[LRU_LIST] = new yallist(); // list of items in order of use recency - case "?": - case "+": - case "*": - re += plType; - // the default anyway - } + this[LENGTH] = 0; // length of items in the list +}; - continue; +LRUCache.prototype.dump = function () { + return this[LRU_LIST].map(function (hit) { + if (!isStale(this, hit)) { + return { + k: hit.key, + v: hit.value, + e: hit.now + (hit.maxAge || 0) + }; + } + }, this).toArray().filter(function (h) { + return h; + }); +}; - case "|": - if (inClass || !patternListStack.length || escaping) { - re += "\\|"; - escaping = false; - continue; - } +LRUCache.prototype.dumpLru = function () { + return this[LRU_LIST]; +}; +/* istanbul ignore next */ - re += "|"; - continue; - // these are mostly the same in regexp and glob - case "[": - // swallow any state-tracking char before the [ - clearStateChar(); +LRUCache.prototype.inspect = function (n, opts) { + var str = 'LRUCache {'; + var extras = false; + var as = this[ALLOW_STALE]; - if (inClass) { - re += "\\" + c; - continue; - } + if (as) { + str += '\n allowStale: true'; + extras = true; + } - inClass = true; - classStart = i; - reClassStart = re.length; - re += c; - continue; + var max = this[MAX]; - 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; - } // finish up the class. + if (max && max !== Infinity) { + if (extras) { + str += ','; + } + str += '\n max: ' + util__default['default'].inspect(max, opts); + extras = true; + } - hasMagic = true; - inClass = false; - re += c; - continue; + var maxAge = this[MAX_AGE]; - default: - // swallow any state char that wasn't consumed - clearStateChar(); + if (maxAge) { + if (extras) { + str += ','; + } - if (escaping) { - // no need - escaping = false; - } else if (reSpecials[c] && !(c === "^" && inClass)) { - re += "\\"; - } + str += '\n maxAge: ' + util__default['default'].inspect(maxAge, opts); + extras = true; + } - re += c; - } // switch + var lc = this[LENGTH_CALCULATOR]; - } // for - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" + if (lc && lc !== naiveLength) { + if (extras) { + str += ','; + } + str += '\n length: ' + util__default['default'].inspect(this[LENGTH], opts); + extras = true; + } - 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 - var 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. + var didFirst = false; + this[LRU_LIST].forEach(function (item) { + if (didFirst) { + str += ',\n '; + } else { + if (extras) { + str += ',\n'; + } + didFirst = true; + str += '\n '; + } - var pl; + var key = util__default['default'].inspect(item.key).split('\n').join('\n '); + var val = { + value: item.value + }; - while (pl = patternListStack.pop()) { - var tail = re.slice(pl.reStart + 3); // maybe some even number of \, then maybe 1 \, followed by a | + if (item.maxAge !== maxAge) { + val.maxAge = item.maxAge; + } - tail = tail.replace(/((?:\\{2})*)(\\?)\|/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. + if (lc !== naiveLength) { + val.length = item.length; + } + if (isStale(this, item)) { + val.stale = true; + } - return $1 + $1 + $2 + "|"; - }); // console.error("tail=%j\n %s", tail, tail) + val = util__default['default'].inspect(val, opts).split('\n').join('\n '); + str += key + ' => ' + val; + }); - 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. + if (didFirst || extras) { + str += '\n'; + } + str += '}'; + return str; +}; - clearStateChar(); +LRUCache.prototype.set = function (key, value, maxAge) { + maxAge = maxAge || this[MAX_AGE]; + var now = maxAge ? Date.now() : 0; + var len = this[LENGTH_CALCULATOR](value, key); - if (escaping) { - // trailing \\ - re += "\\\\"; - } // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot + if (this[CACHE].has(key)) { + if (len > this[MAX]) { + del(this, this[CACHE].get(key)); + return false; + } + var node = this[CACHE].get(key); + var item = node.value; // dispose of the old one before overwriting + // split out into 2 ifs for better coverage tracking - var addPatternStart = false; + if (this[DISPOSE]) { + if (!this[NO_DISPOSE_ON_SET]) { + this[DISPOSE](key, item.value); + } + } - switch (re.charAt(0)) { - case ".": - case "[": - case "(": - addPatternStart = true; - } // 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. + item.now = now; + item.maxAge = maxAge; + item.value = value; + this[LENGTH] += len - item.length; + item.length = len; + this.get(key); + trim$2(this); + return true; + } + var hit = new Entry$1(key, value, len, now, maxAge); // oversized objects fall out of cache automatically. - if (re !== "" && hasMagic) re = "(?=.)" + re; - if (addPatternStart) re = patternStart + re; // parsing just a piece of a larger pattern. + if (hit.length > this[MAX]) { + if (this[DISPOSE]) { + this[DISPOSE](key, value); + } - 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. + return false; + } + this[LENGTH] += hit.length; + this[LRU_LIST].unshift(hit); + this[CACHE].set(key, this[LRU_LIST].head); + trim$2(this); + return true; +}; - if (!hasMagic) { - return globUnescape(pattern); - } +LRUCache.prototype.has = function (key) { + if (!this[CACHE].has(key)) return false; + var hit = this[CACHE].get(key).value; - var flags = options.nocase ? "i" : "", - regExp = new RegExp("^" + re + "$", flags); - regExp._glob = pattern; - regExp._src = re; - return regExp; + if (isStale(this, hit)) { + return false; } - minimatch.makeRe = function (pattern, options) { - return new Minimatch(pattern, options || {}).makeRe(); - }; + return true; +}; + +LRUCache.prototype.get = function (key) { + return get(this, key, true); +}; - Minimatch.prototype.makeRe = makeRe; +LRUCache.prototype.peek = function (key) { + return get(this, key, false); +}; - 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. +LRUCache.prototype.pop = function () { + var node = this[LRU_LIST].tail; + if (!node) return null; + del(this, node); + return node.value; +}; - var set = this.set; - if (!set.length) return this.regexp = false; - var options = this.options; - var twoStar = options.noglobstar ? star : options.dot ? twoStarDot : twoStarNoDot, - 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. +LRUCache.prototype.del = function (key) { + del(this, this[CACHE].get(key)); +}; - re = "^(?:" + re + ")$"; // can match anything, as long as it's not this. +LRUCache.prototype.load = function (arr) { + // reset the cache + this.reset(); + var now = Date.now(); // A previous serialized cache has the most recent items first - if (this.negate) re = "^(?!" + re + ").*$"; + for (var l = arr.length - 1; l >= 0; l--) { + var hit = arr[l]; + var expiresAt = hit.e || 0; - try { - return this.regexp = new RegExp(re, flags); - } catch (ex) { - return this.regexp = false; + if (expiresAt === 0) { + // the item was created without expiration in a non aged cache + this.set(hit.k, hit.v); + } else { + var maxAge = expiresAt - now; // dont add already expired items + + if (maxAge > 0) { + this.set(hit.k, hit.v, maxAge); + } } } +}; - minimatch.match = function (list, pattern, options) { - var mm = new Minimatch(pattern, options); - list = list.filter(function (f) { - return mm.match(f); - }); +LRUCache.prototype.prune = function () { + var self = this; + this[CACHE].forEach(function (value, key) { + get(self, key, false); + }); +}; - if (options.nonull && !list.length) { - list.push(pattern); +function get(self, key, doUse) { + var node = self[CACHE].get(key); + + if (node) { + var hit = node.value; + + if (isStale(self, hit)) { + del(self, node); + if (!self[ALLOW_STALE]) hit = undefined; + } else { + if (doUse) { + self[LRU_LIST].unshiftNode(node); + } } - return list; - }; + if (hit) hit = hit.value; + } - Minimatch.prototype.match = match; + return hit; +} - function match(f, partial) { - // console.error("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 \ - // On other platforms, \ is a valid (albeit bad) filename char. +function isStale(self, hit) { + if (!hit || !hit.maxAge && !self[MAX_AGE]) { + return false; + } - if (platform === "win32") { - f = f.split("\\").join("/"); - } // treat the test path as a set of pathparts. + var stale = false; + var diff = Date.now() - hit.now; + if (hit.maxAge) { + stale = diff > hit.maxAge; + } else { + stale = self[MAX_AGE] && diff > self[MAX_AGE]; + } - f = f.split(slashSplit); + return stale; +} - if (options.debug) { - console.error(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. +function trim$2(self) { + if (self[LENGTH] > self[MAX]) { + for (var 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. + var prev = walker.prev; + del(self, walker); + walker = prev; + } + } +} +function del(self, node) { + if (node) { + var hit = node.value; - var set = this.set; // console.error(this.pattern, "set", set) + if (self[DISPOSE]) { + self[DISPOSE](hit.key, hit.value); + } - for (var i = 0, l = set.length; i < l; i++) { - var pattern = set[i]; - var hit = this.matchOne(f, pattern, partial); + self[LENGTH] -= hit.length; + self[CACHE].delete(hit.key); + self[LRU_LIST].removeNode(node); + } +} // classy, since V8 prefers predictable objects. - 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. +function Entry$1(key, value, length, now, maxAge) { + this.key = key; + this.value = value; + this.length = length; + this.now = now; + this.maxAge = maxAge || 0; +} - 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. +var sigmund_1 = sigmund; +function sigmund(subject, maxSessions) { + maxSessions = maxSessions || 10; + var notes = []; + var analysis = ''; + var RE = RegExp; - Minimatch.prototype.matchOne = function (file, pattern, partial) { - var options = this.options; + function psychoAnalyze(subject, session) { + if (session > maxSessions) return; - if (options.debug) { - console.error("matchOne", { - "this": this, - file: file, - pattern: pattern - }); + if (typeof subject === 'function' || typeof subject === 'undefined') { + return; } - if (options.matchBase && pattern.length === 1) { - file = path$2.basename(file.join("/")).split("/"); + if (typeof subject !== 'object' || !subject || subject instanceof RE) { + analysis += subject; + return; } - if (options.debug) { - console.error("matchOne", file.length, pattern.length); - } + if (notes.indexOf(subject) !== -1 || session === maxSessions) return; + notes.push(subject); + analysis += '{'; + Object.keys(subject).forEach(function (issue, _, __) { + // pseudo-private values. skip those. + if (issue.charAt(0) === '_') return; + var to = typeof subject[issue]; + if (to === 'function' || to === 'undefined') return; + analysis += issue; + psychoAnalyze(subject[issue], session + 1); + }); + } - for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) { - if (options.debug) { - console.error("matchOne loop"); - } + psychoAnalyze(subject, 0); + return analysis; +} // vim: set softtabstop=4 shiftwidth=4: - var p = pattern[pi], - f = file[fi]; +var fnmatch = createCommonjsModule(function (module, exports) { + // Based on minimatch.js by isaacs + var platform = typeof process === "object" ? process.platform : "win32"; + if (module) module.exports = minimatch;else exports.minimatch = minimatch; + minimatch.Minimatch = Minimatch; + var cache = minimatch.cache = new lruCache({ + max: 100 + }), + GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}; + var qmark = "[^/]" // * => any number of characters + , + 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. + , + twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?" // not a ^ or / followed by a dot, + // followed by anything, any number of times. + , + twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?" // characters that need to be escaped in RegExp. + , + reSpecials = charSet("().*{}+?[]^$\\!"); // "abc" -> { a:true, b:true, c:true } - if (options.debug) { - console.error(pattern, p, f); - } // should be impossible. - // some invalid regexp stuff in the set. + function charSet(s) { + return s.split("").reduce(function (set, c) { + set[c] = true; + return set; + }, {}); + } // normalizes slashes. - if (p === false) return false; + var slashSplit = /\/+/; + minimatch.monkeyPatch = monkeyPatch; - if (p === GLOBSTAR) { - if (options.debug) console.error('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 + function monkeyPatch() { + var desc = Object.getOwnPropertyDescriptor(String.prototype, "match"); + var orig = desc.value; - var fr = fi, - pr = pi + 1; + desc.value = function (p) { + if (p instanceof Minimatch) return p.match(this); + return orig.call(this, p); + }; - if (pr === pl) { - if (options.debug) console.error('** 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. + Object.defineProperty(String.prototype, desc); + } - for (; fi < fl; fi++) { - if (file[fi] === "." || file[fi] === ".." || !options.dot && file[fi].charAt(0) === ".") return false; - } + minimatch.filter = filter; - return true; - } // ok, let's see if we can swallow whatever we can. + function filter(pattern, options) { + options = options || {}; + return function (p, i, list) { + return minimatch(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; + } - WHILE: while (fr < fl) { - var swallowee = file[fr]; + minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return minimatch; + var orig = minimatch; - if (options.debug) { - console.error('\nglobstar while', file, fr, pattern, pr, swallowee); - } // XXX remove this slice. Just pass the start index. + 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)); + }; - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - if (options.debug) console.error('globstar found match!', fr, fl, swallowee); // found a match. + return m; + }; - return true; - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === "." || swallowee === ".." || !options.dot && swallowee.charAt(0) === ".") { - if (options.debug) console.error("dot detected!", file, fr, pattern, pr); - break WHILE; - } // ** swallows a segment, and continue. + Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch; + return minimatch.defaults(def).Minimatch; + }; + function minimatch(p, pattern, options) { + if (typeof pattern !== "string") { + throw new TypeError("glob pattern string required"); + } - if (options.debug) console.error('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 (!options) options = {}; // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === "#") { + return false; + } // "" only matches "" - if (partial) { - // ran out of file - // console.error("\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. + if (pattern.trim() === "") return p === ""; + return new Minimatch(pattern, options).match(p); + } + function Minimatch(pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options, cache); + } - var hit; + if (typeof pattern !== "string") { + throw new TypeError("glob pattern string required"); + } - if (typeof p === "string") { - if (options.nocase) { - hit = f.toLowerCase() === p.toLowerCase(); - } else { - hit = f === p; - } + if (!options) options = {}; // windows: need to use /, not \ + // On other platforms, \ is a valid (albeit bad) filename char. - if (options.debug) { - console.error("string match", p, f, hit); - } - } else { - hit = f.match(p); + if (platform === "win32") { + pattern = pattern.split("\\").join("/"); + } // lru storage. + // these things aren't particularly big, but walking down the string + // and turning it into a regexp can get pretty costly. - if (options.debug) { - console.error("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. + var cacheKey = pattern + "\n" + sigmund_1(options); + var cached = minimatch.cache.get(cacheKey); + if (cached) return cached; + minimatch.cache.set(cacheKey, this); + 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(); + } - 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. + Minimatch.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. - throw new Error("wtf?"); - }; // replace stuff like \* with * + if (!options.nocomment && pattern.charAt(0) === "#") { + this.comment = true; + return; + } + if (!pattern) { + this.empty = true; + return; + } // step 1: figure out negation, etc. - function globUnescape(s) { - return s.replace(/\\(.)/g, "$1"); - } - function regExpEscape(s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); - } -}); -var fnmatch_1 = fnmatch.minimatch; + this.parseNegate(); // step 2: expand braces -var ini = createCommonjsModule(function (module, exports) { + var set = this.globSet = this.braceExpand(); + if (options.debug) console.error(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 - var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) { - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { - try { - step(generator.next(value)); - } catch (e) { - reject(e); - } - } + set = this.globParts = set.map(function (s) { + return s.split(slashSplit); + }); + if (options.debug) console.error(this.pattern, set); // glob --> regexps - function rejected(value) { - try { - step(generator["throw"](value)); - } catch (e) { - reject(e); - } - } + set = set.map(function (s, si, set) { + return s.map(this.parse, this); + }, this); + if (options.debug) console.error(this.pattern, set); // filter out everything that didn't compile properly. - function step(result) { - result.done ? resolve(result.value) : new P(function (resolve) { - resolve(result.value); - }).then(fulfilled, rejected); - } + set = set.filter(function (s) { + return -1 === s.indexOf(false); + }); + if (options.debug) console.error(this.pattern, set); + this.set = set; + } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); - }; + Minimatch.prototype.parseNegate = parseNegate; - var __generator = this && this.__generator || function (thisArg, body) { - var _ = { - label: 0, - sent: function () { - if (t[0] & 1) throw t[1]; - return t[1]; - }, - trys: [], - ops: [] - }, - f, - y, - t, - g; - return g = { - next: verb(0), - "throw": verb(1), - "return": verb(2) - }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { - return this; - }), g; + function parseNegate() { + var pattern = this.pattern, + negate = false, + options = this.options, + negateOffset = 0; + if (options.nonegate) return; - function verb(n) { - return function (v) { - return step([n, v]); - }; + for (var i = 0, l = pattern.length; i < l && pattern.charAt(i) === "!"; i++) { + negate = !negate; + negateOffset++; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); + 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 - while (_) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: - case 1: - t = op; - break; + minimatch.braceExpand = function (pattern, options) { + return new Minimatch(pattern, options).braceExpand(); + }; - case 4: - _.label++; - return { - value: op[1], - done: false - }; + Minimatch.prototype.braceExpand = braceExpand; - case 5: - _.label++; - y = op[1]; - op = [0]; - continue; + function braceExpand(pattern, options) { + options = options || this.options; + pattern = typeof pattern === "undefined" ? this.pattern : pattern; - case 7: - op = _.ops.pop(); + if (typeof pattern === "undefined") { + throw new Error("undefined pattern"); + } - _.trys.pop(); + if (options.nobrace || !pattern.match(/\{.*\}/)) { + // shortcut. no need to expand. + return [pattern]; + } - continue; + var escaping = false; // examples and comments refer to this crazy pattern: + // a{b,c{d,e},{f,g}h}x{y,z} + // expected: + // abxy + // abxz + // acdxy + // acdxz + // acexy + // acexz + // afhxy + // afhxz + // aghxy + // aghxz + // everything before the first \{ is just a prefix. + // So, we pluck that off, and work with the rest, + // and then prepend it to everything we find. - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { - _ = 0; - continue; - } + if (pattern.charAt(0) !== "{") { + // console.error(pattern) + var prefix = null; - if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { - _.label = op[1]; - break; - } + for (var i = 0, l = pattern.length; i < l; i++) { + var c = pattern.charAt(i); // console.error(i, c) - if (op[0] === 6 && _.label < t[1]) { - _.label = t[1]; - t = op; - break; - } + if (c === "\\") { + escaping = !escaping; + } else if (c === "{" && !escaping) { + prefix = pattern.substr(0, i); + break; + } + } // actually no sets, all { were escaped. - if (t && _.label < t[2]) { - _.label = t[2]; - _.ops.push(op); + if (prefix === null) { + // console.error("no sets") + return [pattern]; + } - break; - } + var tail = braceExpand(pattern.substr(i), options); + return tail.map(function (t) { + return prefix + t; + }); + } // now we have something like: + // {b,c{d,e},{f,g}h}x{y,z} + // walk through the set, expanding each part, until + // the set ends. then, we'll expand the suffix. + // If the set only has a single member, then'll put the {} back + // first, handle numeric sets, since they're easier - if (t[2]) _.ops.pop(); - _.trys.pop(); + var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/); - continue; - } + if (numset) { + // console.error("numset", numset[1], numset[2]) + var suf = braceExpand(pattern.substr(numset[0].length), options), + start = +numset[1], + end = +numset[2], + inc = start > end ? -1 : 1, + set = []; - op = body.call(thisArg, _); - } catch (e) { - op = [6, e]; - y = 0; - } finally { - f = t = 0; + for (var i = start; i != end + inc; i += inc) { + // append all the suffixes + for (var ii = 0, ll = suf.length; ii < ll; ii++) { + set.push(i + suf[ii]); + } } - if (op[0] & 5) throw op[1]; - return { - value: op[0] ? op[1] : void 0, - done: true - }; - } - }; + return set; + } // ok, walk through the set + // We hope, somewhat optimistically, that there + // will be a } at the end. + // If the closing brace isn't found, then the pattern is + // interpreted as braceExpand("\\" + pattern) so that + // the leading \{ will be interpreted literally. - var __importStar = this && this.__importStar || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result["default"] = mod; - return result; - }; - Object.defineProperty(exports, "__esModule", { - value: true - }); + var i = 1 // skip the \{ + , + depth = 1, + set = [], + member = "", + escaping = false; - var fs = __importStar(fs$3); - /** - * define the possible values: - * section: [section] - * param: key=value - * comment: ;this is a comment - */ + function addMember() { + set.push(member); + member = ""; + } // console.error("Entering for") - var regex = { - section: /^\s*\[(([^#;]|\\#|\\;)+)\]\s*([#;].*)?$/, - param: /^\s*([\w\.\-\_]+)\s*[=:]\s*(.*?)\s*([#;].*)?$/, - comment: /^\s*[#;].*$/ - }; - /** - * Parses an .ini file - * @param file The location of the .ini file - */ + FOR: for (i = 1, l = pattern.length; i < l; i++) { + var c = pattern.charAt(i); // console.error("", i, c) - function parse(file) { - return __awaiter(this, void 0, void 0, function () { - return __generator(this, function (_a) { - return [2 - /*return*/ - , new Promise(function (resolve, reject) { - fs.readFile(file, 'utf8', function (err, data) { - if (err) { - reject(err); - return; - } + if (escaping) { + escaping = false; + member += "\\" + c; + } else { + switch (c) { + case "\\": + escaping = true; + continue; - resolve(parseString(data)); - }); - })]; - }); - }); - } + case "{": + depth++; + member += "{"; + continue; - exports.parse = parse; + case "}": + depth--; // if this closes the actual set, then we're done - function parseSync(file) { - return parseString(fs.readFileSync(file, 'utf8')); - } + if (depth === 0) { + addMember(); // pluck off the close-brace - exports.parseSync = parseSync; + i++; + break FOR; + } else { + member += c; + continue; + } - function parseString(data) { - var sectionBody = {}; - var sectionName = null; - var value = [[sectionName, sectionBody]]; - var lines = data.split(/\r\n|\r|\n/); - lines.forEach(function (line) { - var match; + case ",": + if (depth === 1) { + addMember(); + } else { + member += c; + } - if (regex.comment.test(line)) { - return; - } + continue; - if (regex.param.test(line)) { - match = line.match(regex.param); - sectionBody[match[1]] = match[2]; - } else if (regex.section.test(line)) { - match = line.match(regex.section); - sectionName = match[1]; - sectionBody = {}; - value.push([sectionName, sectionBody]); - } - }); - return value; - } + default: + member += c; + continue; + } // switch - exports.parseString = parseString; -}); -unwrapExports(ini); -var ini_1 = ini.parse; -var ini_2 = ini.parseSync; -var ini_3 = ini.parseString; + } // else -var name$1 = "editorconfig"; -var version$1 = "0.15.3"; -var description$1 = "EditorConfig File Locator and Interpreter for Node.js"; -var keywords = [ - "editorconfig", - "core" -]; -var main$1 = "src/index.js"; -var contributors = [ - "Hong Xu (topbug.net)", - "Jed Mao (https://github.com/jedmao/)", - "Trey Hunner (http://treyhunner.com)" -]; -var directories = { - bin: "./bin", - lib: "./lib" -}; -var scripts$1 = { - clean: "rimraf dist", - prebuild: "npm run clean", - build: "tsc", - pretest: "npm run lint && npm run build && npm run copy && cmake .", - test: "ctest .", - "pretest:ci": "npm run pretest", - "test:ci": "ctest -VV --output-on-failure .", - lint: "npm run eclint && npm run tslint", - eclint: "eclint check --indent_size ignore \"src/**\"", - tslint: "tslint --project tsconfig.json --exclude package.json", - copy: "cpy .npmignore LICENSE README.md CHANGELOG.md dist && cpy bin/* dist/bin && cpy src/lib/fnmatch*.* dist/src/lib", - prepub: "npm run lint && npm run build && npm run copy", - pub: "npm publish ./dist" -}; -var repository$1 = { - type: "git", - url: "git://github.com/editorconfig/editorconfig-core-js.git" -}; -var bugs = "https://github.com/editorconfig/editorconfig-core-js/issues"; -var author$1 = "EditorConfig Team"; -var license$1 = "MIT"; -var dependencies$1 = { - commander: "^2.19.0", - "lru-cache": "^4.1.5", - semver: "^5.6.0", - sigmund: "^1.0.1" -}; -var devDependencies$1 = { - "@types/mocha": "^5.2.6", - "@types/node": "^10.12.29", - "@types/semver": "^5.5.0", - "cpy-cli": "^2.0.0", - eclint: "^2.8.1", - mocha: "^5.2.0", - rimraf: "^2.6.3", - should: "^13.2.3", - tslint: "^5.13.1", - typescript: "^3.3.3333" -}; -var _package$2 = { - name: name$1, - version: version$1, - description: description$1, - keywords: keywords, - main: main$1, - contributors: contributors, - directories: directories, - scripts: scripts$1, - repository: repository$1, - bugs: bugs, - author: author$1, - license: license$1, - dependencies: dependencies$1, - devDependencies: devDependencies$1 -}; + } // for + // now we've either finished the set, and the suffix is + // pattern.substr(i), or we have *not* closed the set, + // and need to escape the leading brace -var _package$3 = /*#__PURE__*/Object.freeze({ - __proto__: null, - name: name$1, - version: version$1, - description: description$1, - keywords: keywords, - main: main$1, - contributors: contributors, - directories: directories, - scripts: scripts$1, - repository: repository$1, - bugs: bugs, - author: author$1, - license: license$1, - dependencies: dependencies$1, - devDependencies: devDependencies$1, - 'default': _package$2 -}); -var require$$4 = getCjsExportFromNamespace(_package$3); + if (depth !== 0) { + // console.error("didn't close", pattern) + return braceExpand("\\" + pattern, options); + } // x{y,z} -> ["xy", "xz"] + // console.error("set", set) + // console.error("suffix", pattern.substr(i)) -var src = createCommonjsModule(function (module, exports) { - var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) { - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { - try { - step(generator.next(value)); - } catch (e) { - reject(e); - } - } + var suf = braceExpand(pattern.substr(i), options); // ["b", "c{d,e}","{f,g}h"] -> + // [["b"], ["cd", "ce"], ["fh", "gh"]] - function rejected(value) { - try { - step(generator["throw"](value)); - } catch (e) { - reject(e); - } - } + var addBraces = set.length === 1; // console.error("set pre-expanded", set) - function step(result) { - result.done ? resolve(result.value) : new P(function (resolve) { - resolve(result.value); - }).then(fulfilled, rejected); - } + set = set.map(function (p) { + return braceExpand(p, options); + }); // console.error("set expanded", set) + // [["b"], ["cd", "ce"], ["fh", "gh"]] -> + // ["b", "cd", "ce", "fh", "gh"] - step((generator = generator.apply(thisArg, _arguments || [])).next()); + set = set.reduce(function (l, r) { + return l.concat(r); }); - }; - var __generator = this && this.__generator || function (thisArg, body) { - var _ = { - label: 0, - sent: function () { - if (t[0] & 1) throw t[1]; - return t[1]; - }, - trys: [], - ops: [] - }, - f, - y, - t, - g; - return g = { - next: verb(0), - "throw": verb(1), - "return": verb(2) - }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { - return this; - }), g; + if (addBraces) { + set = set.map(function (s) { + return "{" + s + "}"; + }); + } // now attach the suffixes. - function verb(n) { - return function (v) { - return step([n, v]); - }; - } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); + var ret = []; - while (_) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; + for (var i = 0, l = set.length; i < l; i++) { + for (var ii = 0, ll = suf.length; ii < ll; ii++) { + ret.push(set[i] + suf[ii]); + } + } - switch (op[0]) { - case 0: - case 1: - t = op; - break; + return ret; + } // 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. - case 4: - _.label++; - return { - value: op[1], - done: false - }; - case 5: - _.label++; - y = op[1]; - op = [0]; - continue; + Minimatch.prototype.parse = parse; + var SUBPARSE = {}; - case 7: - op = _.ops.pop(); + function parse(pattern, isSub) { + var options = this.options; // shortcuts + + if (!options.noglobstar && pattern === "**") return GLOBSTAR; + if (pattern === "") return ""; + var re = "", + hasMagic = !!options.nocase, + escaping = false // ? => one single character + , + patternListStack = [], + plType, + stateChar, + inClass = false, + reClassStart = -1, + classStart = -1 // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + , + patternStart = pattern.charAt(0) === "." ? "" // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))" : "(?!\\.)"; - _.trys.pop(); + 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; - continue; + case "?": + re += qmark; + hasMagic = true; + break; default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { - _ = 0; - continue; - } + re += "\\" + stateChar; + break; + } - if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { - _.label = op[1]; - break; - } + stateChar = false; + } + } - if (op[0] === 6 && _.label < t[1]) { - _.label = t[1]; - t = op; - break; - } + for (var i = 0, len = pattern.length, c; i < len && (c = pattern.charAt(i)); i++) { + if (options.debug) { + console.error("%s\t%s %s %j", pattern, i, re, c); + } // skip over any that are escaped. - if (t && _.label < t[2]) { - _.label = t[2]; - _.ops.push(op); + if (escaping && reSpecials[c]) { + re += "\\" + c; + escaping = false; + continue; + } - break; - } + switch (c) { + case "/": + // completely not allowed, even escaped. + // Should already be path-split by now. + return false; - if (t[2]) _.ops.pop(); + case "\\": + clearStateChar(); + escaping = true; + continue; + // the various stateChar values + // for the "extglob" stuff. - _.trys.pop(); + case "?": + case "*": + case "+": + case "@": + case "!": + if (options.debug) { + console.error("%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) { + 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. - op = body.call(thisArg, _); - } catch (e) { - op = [6, e]; - y = 0; - } finally { - f = t = 0; - } - if (op[0] & 5) throw op[1]; - return { - value: op[0] ? op[1] : void 0, - done: true - }; - } - }; + 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. - var __importStar = this && this.__importStar || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result["default"] = mod; - return result; - }; + if (options.noext) clearStateChar(); + continue; - var __importDefault = this && this.__importDefault || function (mod) { - return mod && mod.__esModule ? mod : { - "default": mod - }; - }; + case "(": + if (inClass) { + re += "("; + continue; + } - Object.defineProperty(exports, "__esModule", { - value: true - }); + if (!stateChar) { + re += "\\("; + continue; + } - var fs = __importStar(fs$3); + plType = stateChar; + patternListStack.push({ + type: plType, + start: i - 1, + reStart: re.length + }); // negation is (?:(?!js)[^/]*) - var path = __importStar(path$2); + re += stateChar === "!" ? "(?:(?!" : "(?:"; + stateChar = false; + continue; - var semver = __importStar(semver$2); + case ")": + if (inClass || !patternListStack.length) { + re += "\\)"; + continue; + } - var fnmatch_1 = __importDefault(fnmatch); + hasMagic = true; + re += ")"; + plType = patternListStack.pop().type; // negation is (?:(?!js)[^/]*) + // The others are (?:) - exports.parseString = ini.parseString; + switch (plType) { + case "!": + re += "[^/]*?)"; + break; - var package_json_1 = __importDefault(require$$4); + case "?": + case "+": + case "*": + re += plType; + // the default anyway + } - var knownProps = { - end_of_line: true, - indent_style: true, - indent_size: true, - insert_final_newline: true, - trim_trailing_whitespace: true, - charset: true - }; + continue; - function fnmatch$1(filepath, glob) { - var matchOptions = { - matchBase: true, - dot: true, - noext: true - }; - glob = glob.replace(/\*\*/g, '{*,**/**/**}'); - return fnmatch_1.default(filepath, glob, matchOptions); - } + case "|": + if (inClass || !patternListStack.length || escaping) { + re += "\\|"; + escaping = false; + continue; + } - function getConfigFileNames(filepath, options) { - var paths = []; + re += "|"; + continue; + // these are mostly the same in regexp and glob - do { - filepath = path.dirname(filepath); - paths.push(path.join(filepath, options.config)); - } while (filepath !== options.root); + case "[": + // swallow any state-tracking char before the [ + clearStateChar(); - return paths; - } + if (inClass) { + re += "\\" + c; + continue; + } - function processMatches(matches, version) { - // Set indent_size to 'tab' if indent_size is unspecified and - // indent_style is set to 'tab'. - if ('indent_style' in matches && matches.indent_style === 'tab' && !('indent_size' in matches) && semver.gte(version, '0.10.0')) { - matches.indent_size = 'tab'; - } // Set tab_width to indent_size if indent_size is specified and - // tab_width is unspecified + 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; + } // finish up the class. - if ('indent_size' in matches && !('tab_width' in matches) && matches.indent_size !== 'tab') { - matches.tab_width = matches.indent_size; - } // Set indent_size to tab_width if indent_size is 'tab' + hasMagic = true; + inClass = false; + re += c; + continue; - if ('indent_size' in matches && 'tab_width' in matches && matches.indent_size === 'tab') { - matches.indent_size = matches.tab_width; - } + default: + // swallow any state char that wasn't consumed + clearStateChar(); - return matches; - } + if (escaping) { + // no need + escaping = false; + } else if (reSpecials[c] && !(c === "^" && inClass)) { + re += "\\"; + } - function processOptions(options, filepath) { - if (options === void 0) { - options = {}; - } + re += c; + } // switch - return { - config: options.config || '.editorconfig', - version: options.version || package_json_1.default.version, - root: path.resolve(options.root || path.parse(filepath).root) - }; - } + } // for + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" - function buildFullGlob(pathPrefix, glob) { - switch (glob.indexOf('/')) { - case -1: - glob = '**/' + glob; - break; - case 0: - glob = glob.substring(1); - break; - } + 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 + var 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. - return path.join(pathPrefix, glob); - } - function extendProps(props, options) { - if (props === void 0) { - props = {}; - } + var pl; - if (options === void 0) { - options = {}; - } + while (pl = patternListStack.pop()) { + var tail = re.slice(pl.reStart + 3); // maybe some even number of \, then maybe 1 \, followed by a | - for (var key in options) { - if (options.hasOwnProperty(key)) { - var value = options[key]; - var key2 = key.toLowerCase(); - var value2 = value; + tail = tail.replace(/((?:\\{2})*)(\\?)\|/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. - if (knownProps[key2]) { - value2 = value.toLowerCase(); - } - try { - value2 = JSON.parse(value); - } catch (e) {} + return $1 + $1 + $2 + "|"; + }); // console.error("tail=%j\n %s", tail, tail) - if (typeof value === 'undefined' || value === null) { - // null and undefined are values specific to JSON (no special meaning - // in editorconfig) & should just be returned as regular strings. - value2 = String(value); - } + 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. - props[key2] = value2; - } - } - return props; - } + clearStateChar(); - function parseFromConfigs(configs, filepath, options) { - return processMatches(configs.reverse().reduce(function (matches, file) { - var pathPrefix = path.dirname(file.name); - file.contents.forEach(function (section) { - var glob = section[0]; - var options2 = section[1]; + if (escaping) { + // trailing \\ + re += "\\\\"; + } // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot - if (!glob) { - return; - } - var fullGlob = buildFullGlob(pathPrefix, glob); + var addPatternStart = false; - if (!fnmatch$1(filepath, fullGlob)) { - return; - } + switch (re.charAt(0)) { + case ".": + case "[": + case "(": + addPatternStart = true; + } // 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. - matches = extendProps(matches, options2); - }); - return matches; - }, {}), options.version); - } - function getConfigsForFiles(files) { - var configs = []; + if (re !== "" && hasMagic) re = "(?=.)" + re; + if (addPatternStart) re = patternStart + re; // parsing just a piece of a larger pattern. - for (var i in files) { - if (files.hasOwnProperty(i)) { - var file = files[i]; - var contents = ini.parseString(file.contents); - configs.push({ - name: file.name, - contents: contents - }); + 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 ((contents[0][1].root || '').toLowerCase() === 'true') { - break; - } - } - } - return configs; - } + if (!hasMagic) { + return globUnescape(pattern); + } - function readConfigFiles(filepaths) { - return __awaiter(this, void 0, void 0, function () { - return __generator(this, function (_a) { - return [2 - /*return*/ - , Promise.all(filepaths.map(function (name) { - return new Promise(function (resolve) { - fs.readFile(name, 'utf8', function (err, data) { - resolve({ - name: name, - contents: err ? '' : data - }); - }); - }); - }))]; - }); - }); + var flags = options.nocase ? "i" : "", + regExp = new RegExp("^" + re + "$", flags); + regExp._glob = pattern; + regExp._src = re; + return regExp; } - function readConfigFilesSync(filepaths) { - var files = []; - var file; - filepaths.forEach(function (filepath) { - try { - file = fs.readFileSync(filepath, 'utf8'); - } catch (e) { - file = ''; - } + minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe(); + }; - files.push({ - name: filepath, - contents: file - }); - }); - return files; - } + Minimatch.prototype.makeRe = makeRe; - function opts(filepath, options) { - if (options === void 0) { - options = {}; - } + 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 resolvedFilePath = path.resolve(filepath); - return [resolvedFilePath, processOptions(options, resolvedFilePath)]; - } + var set = this.set; + if (!set.length) return this.regexp = false; + var options = this.options; + var twoStar = options.noglobstar ? star : options.dot ? twoStarDot : twoStarNoDot, + 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. - function parseFromFiles(filepath, files, options) { - if (options === void 0) { - options = {}; - } + re = "^(?:" + re + ")$"; // can match anything, as long as it's not this. - return __awaiter(this, void 0, void 0, function () { - var _a, resolvedFilePath, processedOptions; + if (this.negate) re = "^(?!" + re + ").*$"; - return __generator(this, function (_b) { - _a = opts(filepath, options), resolvedFilePath = _a[0], processedOptions = _a[1]; - return [2 - /*return*/ - , files.then(getConfigsForFiles).then(function (configs) { - return parseFromConfigs(configs, resolvedFilePath, processedOptions); - })]; - }); - }); + try { + return this.regexp = new RegExp(re, flags); + } catch (ex) { + return this.regexp = false; + } } - exports.parseFromFiles = parseFromFiles; + minimatch.match = function (list, pattern, options) { + var mm = new Minimatch(pattern, options); + list = list.filter(function (f) { + return mm.match(f); + }); - function parseFromFilesSync(filepath, files, options) { - if (options === void 0) { - options = {}; + if (options.nonull && !list.length) { + list.push(pattern); } - var _a = opts(filepath, options), - resolvedFilePath = _a[0], - processedOptions = _a[1]; + return list; + }; - return parseFromConfigs(getConfigsForFiles(files), resolvedFilePath, processedOptions); - } + Minimatch.prototype.match = match; - exports.parseFromFilesSync = parseFromFilesSync; + function match(f, partial) { + // console.error("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 \ + // On other platforms, \ is a valid (albeit bad) filename char. + + if (platform === "win32") { + f = f.split("\\").join("/"); + } // treat the test path as a set of pathparts. - function parse(_filepath, _options) { - if (_options === void 0) { - _options = {}; - } - return __awaiter(this, void 0, void 0, function () { - var _a, resolvedFilePath, processedOptions, filepaths; + f = f.split(slashSplit); - return __generator(this, function (_b) { - _a = opts(_filepath, _options), resolvedFilePath = _a[0], processedOptions = _a[1]; - filepaths = getConfigFileNames(resolvedFilePath, processedOptions); - return [2 - /*return*/ - , readConfigFiles(filepaths).then(getConfigsForFiles).then(function (configs) { - return parseFromConfigs(configs, resolvedFilePath, processedOptions); - })]; - }); - }); - } + if (options.debug) { + console.error(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. - exports.parse = parse; - function parseSync(_filepath, _options) { - if (_options === void 0) { - _options = {}; - } + var set = this.set; // console.error(this.pattern, "set", set) - var _a = opts(_filepath, _options), - resolvedFilePath = _a[0], - processedOptions = _a[1]; + for (var i = 0, l = set.length; i < l; i++) { + var pattern = set[i]; + var hit = this.matchOne(f, pattern, partial); - var filepaths = getConfigFileNames(resolvedFilePath, processedOptions); - var files = readConfigFilesSync(filepaths); - return parseFromConfigs(getConfigsForFiles(files), resolvedFilePath, processedOptions); - } + 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. - exports.parseSync = parseSync; -}); -unwrapExports(src); -var src_1 = src.parseString; -var src_2 = src.parseFromFiles; -var src_3 = src.parseFromFilesSync; -var src_4 = src.parse; -var src_5 = src.parseSync; -var editorconfigToPrettier = editorConfigToPrettier; + 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. -function removeUnset(editorConfig) { - const result = {}; - const keys = Object.keys(editorConfig); - for (let i = 0; i < keys.length; i++) { - const key = keys[i]; + Minimatch.prototype.matchOne = function (file, pattern, partial) { + var options = this.options; - if (editorConfig[key] === "unset") { - continue; + if (options.debug) { + console.error("matchOne", { + "this": this, + file: file, + pattern: pattern + }); } - result[key] = editorConfig[key]; - } + if (options.matchBase && pattern.length === 1) { + file = path__default['default'].basename(file.join("/")).split("/"); + } - return result; -} + if (options.debug) { + console.error("matchOne", file.length, pattern.length); + } -function editorConfigToPrettier(editorConfig) { - if (!editorConfig) { - return null; - } + for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) { + if (options.debug) { + console.error("matchOne loop"); + } - editorConfig = removeUnset(editorConfig); + var p = pattern[pi], + f = file[fi]; - if (Object.keys(editorConfig).length === 0) { - return null; - } + if (options.debug) { + console.error(pattern, p, f); + } // should be impossible. + // some invalid regexp stuff in the set. - const result = {}; - if (editorConfig.indent_style) { - result.useTabs = editorConfig.indent_style === "tab"; - } + if (p === false) return false; - if (editorConfig.indent_size === "tab") { - result.useTabs = true; - } + if (p === GLOBSTAR) { + if (options.debug) console.error('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 - if (result.useTabs && editorConfig.tab_width) { - result.tabWidth = editorConfig.tab_width; - } else if (editorConfig.indent_style === "space" && editorConfig.indent_size && editorConfig.indent_size !== "tab") { - result.tabWidth = editorConfig.indent_size; - } else if (editorConfig.tab_width !== undefined) { - result.tabWidth = editorConfig.tab_width; - } + var fr = fi, + pr = pi + 1; - if (editorConfig.max_line_length && editorConfig.max_line_length !== "off") { - result.printWidth = editorConfig.max_line_length; - } + if (pr === pl) { + if (options.debug) console.error('** 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. - if (editorConfig.quote_type === "single") { - result.singleQuote = true; - } else if (editorConfig.quote_type === "double") { - result.singleQuote = false; - } + for (; fi < fl; fi++) { + if (file[fi] === "." || file[fi] === ".." || !options.dot && file[fi].charAt(0) === ".") return false; + } - if (["cr", "crlf", "lf"].indexOf(editorConfig.end_of_line) !== -1) { - result.endOfLine = editorConfig.end_of_line; - } + return true; + } // ok, let's see if we can swallow whatever we can. - return result; -} -function markerExists(files, markers) { - return markers.some(function (marker) { - return files.some(function (file) { - return file === marker; - }); - }); -} + WHILE: while (fr < fl) { + var swallowee = file[fr]; -function traverseFolder(directory, levels, markers) { - var files = fs$3.readdirSync(directory); + if (options.debug) { + console.error('\nglobstar while', file, fr, pattern, pr, swallowee); + } // XXX remove this slice. Just pass the start index. - if (levels === 0) { - return null; - } else if (markerExists(files, markers)) { - return directory; - } else { - return traverseFolder(path$2.resolve(directory, '..'), levels - 1, markers); - } -} -var findProjectRoot = function findRoot(dir, opts) { - if (!dir) throw new Error("Directory not defined"); - opts = opts || {}; - var levels = opts.maxDepth || findRoot.MAX_DEPTH; - var markers = opts.markers || findRoot.MARKERS; - return traverseFolder(dir, levels, markers); -}; + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + if (options.debug) console.error('globstar found match!', fr, fl, swallowee); // found a match. -var MAX_DEPTH = 9; -var MARKERS = ['.git', '.hg']; -findProjectRoot.MAX_DEPTH = MAX_DEPTH; -findProjectRoot.MARKERS = MARKERS; + return true; + } else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === "." || swallowee === ".." || !options.dot && swallowee.charAt(0) === ".") { + if (options.debug) console.error("dot detected!", file, fr, pattern, pr); + break WHILE; + } // ** swallows a segment, and continue. -const jsonStringifyMem = fn => mem_1(fn, { - cacheKey: JSON.stringify -}); -const maybeParse = (filePath, parse) => { - // findProjectRoot will throw an error if we pass a nonexistent directory to - // it, which is possible, for example, when the path is given via - // --stdin-filepath. So, first, traverse up until we find an existing - // directory. - let dirPath = path$2.dirname(path$2.resolve(filePath)); - const fsRoot = path$2.parse(dirPath).root; + if (options.debug) console.error('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 - while (dirPath !== fsRoot && !fs$3.existsSync(dirPath)) { - dirPath = path$2.dirname(dirPath); - } - const root = findProjectRoot(dirPath); - return filePath && parse(filePath, { - root - }); -}; + if (partial) { + // ran out of file + // console.error("\n>>> no match, partial?", file, fr, pattern, pr) + if (fr === fl) return true; + } -const editorconfigAsyncNoCache = async filePath => { - const editorConfig = await maybeParse(filePath, src.parse); - return editorconfigToPrettier(editorConfig); -}; + return false; + } // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. -const editorconfigAsyncWithCache = jsonStringifyMem(editorconfigAsyncNoCache); -const editorconfigSyncNoCache = filePath => { - return editorconfigToPrettier(maybeParse(filePath, src.parseSync)); -}; + var hit; -const editorconfigSyncWithCache = jsonStringifyMem(editorconfigSyncNoCache); + if (typeof p === "string") { + if (options.nocase) { + hit = f.toLowerCase() === p.toLowerCase(); + } else { + hit = f === p; + } -function getLoadFunction(opts) { - if (!opts.editorconfig) { - return () => null; - } + if (options.debug) { + console.error("string match", p, f, hit); + } + } else { + hit = f.match(p); - if (opts.sync) { - return opts.cache ? editorconfigSyncWithCache : editorconfigSyncNoCache; - } + if (options.debug) { + console.error("pattern match", p, f, hit); + } + } - return opts.cache ? editorconfigAsyncWithCache : editorconfigAsyncNoCache; -} + 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. -function clearCache() { - mem_1.clear(editorconfigSyncWithCache); - mem_1.clear(editorconfigAsyncWithCache); -} -var resolveConfigEditorconfig = { - getLoadFunction, - clearCache -}; + 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. -const ParserEND = 0x110000; -class ParserError extends Error { - /* istanbul ignore next */ - constructor(msg, filename, linenumber) { - super('[ParserError] ' + msg, filename, linenumber); - this.name = 'ParserError'; - this.code = 'ParserError'; - if (Error.captureStackTrace) Error.captureStackTrace(this, ParserError); - } + throw new Error("wtf?"); + }; // replace stuff like \* with * -} -class State { - constructor(parser) { - this.parser = parser; - this.buf = ''; - this.returned = null; - this.result = null; - this.resultTable = null; - this.resultArr = null; + function globUnescape(s) { + return s.replace(/\\(.)/g, "$1"); } -} - -class Parser { - constructor() { - this.pos = 0; - this.col = 0; - this.line = 0; - this.obj = {}; - this.ctx = this.obj; - this.stack = []; - this._buf = ''; - this.char = null; - this.ii = 0; - this.state = new State(this.parseStart); + function regExpEscape(s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); } +}); - parse(str) { - /* istanbul ignore next */ - if (str.length === 0 || str.length == null) return; - this._buf = String(str); - this.ii = -1; - this.char = -1; - let getNext; +var ini = createCommonjsModule(function (module, exports) { - while (getNext === false || this.nextChar()) { - getNext = this.runOne(); - } + var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } - this._buf = null; - } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } - nextChar() { - if (this.char === 0x0A) { - ++this.line; - this.col = -1; - } + function step(result) { + result.done ? resolve(result.value) : new P(function (resolve) { + resolve(result.value); + }).then(fulfilled, rejected); + } - ++this.ii; - this.char = this._buf.codePointAt(this.ii); - ++this.pos; - ++this.col; - return this.haveBuffer(); - } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; - haveBuffer() { - return this.ii < this._buf.length; - } + var __generator = this && this.__generator || function (thisArg, body) { + var _ = { + label: 0, + sent: function () { + if (t[0] & 1) throw t[1]; + return t[1]; + }, + trys: [], + ops: [] + }, + f, + y, + t, + g; + return g = { + next: verb(0), + "throw": verb(1), + "return": verb(2) + }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { + return this; + }), g; - runOne() { - return this.state.parser.call(this, this.state.returned); - } + function verb(n) { + return function (v) { + return step([n, v]); + }; + } - finish() { - this.char = ParserEND; - let last; + function step(op) { + if (f) throw new TypeError("Generator is already executing."); - do { - last = this.state.parser; - this.runOne(); - } while (this.state.parser !== last); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; - this.ctx = null; - this.state = null; - this._buf = null; - return this.obj; - } + switch (op[0]) { + case 0: + case 1: + t = op; + break; - next(fn) { - /* istanbul ignore next */ - if (typeof fn !== 'function') throw new ParserError('Tried to set state to non-existent state: ' + JSON.stringify(fn)); - this.state.parser = fn; - } + case 4: + _.label++; + return { + value: op[1], + done: false + }; - goto(fn) { - this.next(fn); - return this.runOne(); - } + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; - call(fn, returnWith) { - if (returnWith) this.next(returnWith); - this.stack.push(this.state); - this.state = new State(fn); - } + case 7: + op = _.ops.pop(); - callNow(fn, returnWith) { - this.call(fn, returnWith); - return this.runOne(); - } + _.trys.pop(); - return(value) { - /* istanbul ignore next */ - if (this.stack.length === 0) throw this.error(new ParserError('Stack underflow')); - if (value === undefined) value = this.state.buf; - this.state = this.stack.pop(); - this.state.returned = value; - } + continue; - returnNow(value) { - this.return(value); - return this.runOne(); - } + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } - consume() { - /* istanbul ignore next */ - if (this.char === ParserEND) throw this.error(new ParserError('Unexpected end-of-buffer')); - this.state.buf += this._buf[this.ii]; - } + if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { + _.label = op[1]; + break; + } - error(err) { - err.line = this.line; - err.col = this.col; - err.pos = this.pos; - return err; - } - /* istanbul ignore next */ + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + if (t && _.label < t[2]) { + _.label = t[2]; - parseStart() { - throw new ParserError('Must declare a parseStart method'); - } + _.ops.push(op); -} + break; + } -Parser.END = ParserEND; -Parser.Error = ParserError; -var parser$1 = Parser; + if (t[2]) _.ops.pop(); -var createDatetime = value => { - const date = new Date(value); - /* istanbul ignore if */ + _.trys.pop(); - if (isNaN(date)) { - throw new TypeError('Invalid Datetime'); - } else { - return date; - } -}; + continue; + } + + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } -var formatNum = (d, num) => { - num = String(num); + if (op[0] & 5) throw op[1]; + return { + value: op[0] ? op[1] : void 0, + done: true + }; + } + }; - while (num.length < d) num = '0' + num; + var __importStar = this && this.__importStar || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; + }; - return num; -}; + Object.defineProperty(exports, "__esModule", { + value: true + }); -class FloatingDateTime extends Date { - constructor(value) { - super(value + 'Z'); - this.isFloating = true; - } + var fs = __importStar(fs__default['default']); + /** + * define the possible values: + * section: [section] + * param: key=value + * comment: ;this is a comment + */ - toISOString() { - const date = `${this.getUTCFullYear()}-${formatNum(2, this.getUTCMonth() + 1)}-${formatNum(2, this.getUTCDate())}`; - const time = `${formatNum(2, this.getUTCHours())}:${formatNum(2, this.getUTCMinutes())}:${formatNum(2, this.getUTCSeconds())}.${formatNum(3, this.getUTCMilliseconds())}`; - return `${date}T${time}`; - } -} + var regex = { + section: /^\s*\[(([^#;]|\\#|\\;)+)\]\s*([#;].*)?$/, + param: /^\s*([\w\.\-\_]+)\s*[=:]\s*(.*?)\s*([#;].*)?$/, + comment: /^\s*[#;].*$/ + }; + /** + * Parses an .ini file + * @param file The location of the .ini file + */ -var createDatetimeFloat = value => { - const date = new FloatingDateTime(value); - /* istanbul ignore if */ + function parse(file) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 + /*return*/ + , new Promise(function (resolve, reject) { + fs.readFile(file, 'utf8', function (err, data) { + if (err) { + reject(err); + return; + } - if (isNaN(date)) { - throw new TypeError('Invalid Datetime'); - } else { - return date; + resolve(parseString(data)); + }); + })]; + }); + }); } -}; -const DateTime = global.Date; + exports.parse = parse; -class Date$1 extends DateTime { - constructor(value) { - super(value); - this.isDate = true; + function parseSync(file) { + return parseString(fs.readFileSync(file, 'utf8')); } - toISOString() { - return `${this.getUTCFullYear()}-${formatNum(2, this.getUTCMonth() + 1)}-${formatNum(2, this.getUTCDate())}`; - } + exports.parseSync = parseSync; -} + function parseString(data) { + var sectionBody = {}; + var sectionName = null; + var value = [[sectionName, sectionBody]]; + var lines = data.split(/\r\n|\r|\n/); + lines.forEach(function (line) { + var match; -var createDate = value => { - const date = new Date$1(value); - /* istanbul ignore if */ + if (regex.comment.test(line)) { + return; + } - if (isNaN(date)) { - throw new TypeError('Invalid Datetime'); - } else { - return date; + if (regex.param.test(line)) { + match = line.match(regex.param); + sectionBody[match[1]] = match[2]; + } else if (regex.section.test(line)) { + match = line.match(regex.section); + sectionName = match[1]; + sectionBody = {}; + value.push([sectionName, sectionBody]); + } + }); + return value; } + + exports.parseString = parseString; +}); + +var name$1 = "editorconfig"; +var version$1 = "0.15.3"; +var description$1 = "EditorConfig File Locator and Interpreter for Node.js"; +var keywords = [ + "editorconfig", + "core" +]; +var main$1 = "src/index.js"; +var contributors = [ + "Hong Xu (topbug.net)", + "Jed Mao (https://github.com/jedmao/)", + "Trey Hunner (http://treyhunner.com)" +]; +var directories = { + bin: "./bin", + lib: "./lib" +}; +var scripts$1 = { + clean: "rimraf dist", + prebuild: "npm run clean", + build: "tsc", + pretest: "npm run lint && npm run build && npm run copy && cmake .", + test: "ctest .", + "pretest:ci": "npm run pretest", + "test:ci": "ctest -VV --output-on-failure .", + lint: "npm run eclint && npm run tslint", + eclint: "eclint check --indent_size ignore \"src/**\"", + tslint: "tslint --project tsconfig.json --exclude package.json", + copy: "cpy .npmignore LICENSE README.md CHANGELOG.md dist && cpy bin/* dist/bin && cpy src/lib/fnmatch*.* dist/src/lib", + prepub: "npm run lint && npm run build && npm run copy", + pub: "npm publish ./dist" +}; +var repository$1 = { + type: "git", + url: "git://github.com/editorconfig/editorconfig-core-js.git" +}; +var bugs = "https://github.com/editorconfig/editorconfig-core-js/issues"; +var author$1 = "EditorConfig Team"; +var license$1 = "MIT"; +var dependencies$1 = { + commander: "^2.19.0", + "lru-cache": "^4.1.5", + semver: "^5.6.0", + sigmund: "^1.0.1" +}; +var devDependencies$1 = { + "@types/mocha": "^5.2.6", + "@types/node": "^10.12.29", + "@types/semver": "^5.5.0", + "cpy-cli": "^2.0.0", + eclint: "^2.8.1", + mocha: "^5.2.0", + rimraf: "^2.6.3", + should: "^13.2.3", + tslint: "^5.13.1", + typescript: "^3.3.3333" +}; +var require$$4 = { + name: name$1, + version: version$1, + description: description$1, + keywords: keywords, + main: main$1, + contributors: contributors, + directories: directories, + scripts: scripts$1, + repository: repository$1, + bugs: bugs, + author: author$1, + license: license$1, + dependencies: dependencies$1, + devDependencies: devDependencies$1 }; -class Time extends Date { - constructor(value) { - super(`0000-01-01T${value}Z`); - this.isTime = true; - } +var src$1 = createCommonjsModule(function (module, exports) { - toISOString() { - return `${formatNum(2, this.getUTCHours())}:${formatNum(2, this.getUTCMinutes())}:${formatNum(2, this.getUTCSeconds())}.${formatNum(3, this.getUTCMilliseconds())}`; - } + var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } -} + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } -var createTime = value => { - const date = new Time(value); - /* istanbul ignore if */ + function step(result) { + result.done ? resolve(result.value) : new P(function (resolve) { + resolve(result.value); + }).then(fulfilled, rejected); + } - if (isNaN(date)) { - throw new TypeError('Invalid Datetime'); - } else { - return date; - } -}; + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; -/* eslint-disable no-new-wrappers, no-eval, camelcase, operator-linebreak */ + var __generator = this && this.__generator || function (thisArg, body) { + var _ = { + label: 0, + sent: function () { + if (t[0] & 1) throw t[1]; + return t[1]; + }, + trys: [], + ops: [] + }, + f, + y, + t, + g; + return g = { + next: verb(0), + "throw": verb(1), + "return": verb(2) + }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { + return this; + }), g; + function verb(n) { + return function (v) { + return step([n, v]); + }; + } -var tomlParser = makeParserClass(parser$1); -var makeParserClass_1 = makeParserClass; + function step(op) { + if (f) throw new TypeError("Generator is already executing."); -class TomlError extends Error { - constructor(msg) { - super(msg); - this.name = 'TomlError'; - /* istanbul ignore next */ + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; - if (Error.captureStackTrace) Error.captureStackTrace(this, TomlError); - this.fromTOML = true; - this.wrapped = null; - } + switch (op[0]) { + case 0: + case 1: + t = op; + break; -} + case 4: + _.label++; + return { + value: op[1], + done: false + }; -TomlError.wrap = err => { - const terr = new TomlError(err.message); - terr.code = err.code; - terr.wrapped = err; - return terr; -}; + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; -var TomlError_1 = TomlError; -const CTRL_I = 0x09; -const CTRL_J = 0x0A; -const CTRL_M = 0x0D; -const CTRL_CHAR_BOUNDARY = 0x1F; // the last non-character in the latin1 region of unicode, except DEL + case 7: + op = _.ops.pop(); -const CHAR_SP = 0x20; -const CHAR_QUOT = 0x22; -const CHAR_NUM = 0x23; -const CHAR_APOS = 0x27; -const CHAR_PLUS = 0x2B; -const CHAR_COMMA = 0x2C; -const CHAR_HYPHEN = 0x2D; -const CHAR_PERIOD = 0x2E; -const CHAR_0 = 0x30; -const CHAR_1 = 0x31; -const CHAR_7 = 0x37; -const CHAR_9 = 0x39; -const CHAR_COLON = 0x3A; -const CHAR_EQUALS = 0x3D; -const CHAR_A = 0x41; -const CHAR_E = 0x45; -const CHAR_F = 0x46; -const CHAR_T = 0x54; -const CHAR_U = 0x55; -const CHAR_Z = 0x5A; -const CHAR_LOWBAR = 0x5F; -const CHAR_a = 0x61; -const CHAR_b = 0x62; -const CHAR_e = 0x65; -const CHAR_f = 0x66; -const CHAR_i = 0x69; -const CHAR_l = 0x6C; -const CHAR_n = 0x6E; -const CHAR_o = 0x6F; -const CHAR_r = 0x72; -const CHAR_s = 0x73; -const CHAR_t = 0x74; -const CHAR_u = 0x75; -const CHAR_x = 0x78; -const CHAR_z = 0x7A; -const CHAR_LCUB = 0x7B; -const CHAR_RCUB = 0x7D; -const CHAR_LSQB = 0x5B; -const CHAR_BSOL = 0x5C; -const CHAR_RSQB = 0x5D; -const CHAR_DEL = 0x7F; -const SURROGATE_FIRST = 0xD800; -const SURROGATE_LAST = 0xDFFF; -const escapes = { - [CHAR_b]: '\u0008', - [CHAR_t]: '\u0009', - [CHAR_n]: '\u000A', - [CHAR_f]: '\u000C', - [CHAR_r]: '\u000D', - [CHAR_QUOT]: '\u0022', - [CHAR_BSOL]: '\u005C' -}; + _.trys.pop(); -function isDigit(cp) { - return cp >= CHAR_0 && cp <= CHAR_9; -} + continue; -function isHexit(cp) { - return cp >= CHAR_A && cp <= CHAR_F || cp >= CHAR_a && cp <= CHAR_f || cp >= CHAR_0 && cp <= CHAR_9; -} + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } -function isBit(cp) { - return cp === CHAR_1 || cp === CHAR_0; -} + if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { + _.label = op[1]; + break; + } -function isOctit(cp) { - return cp >= CHAR_0 && cp <= CHAR_7; -} + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } -function isAlphaNumQuoteHyphen(cp) { - return cp >= CHAR_A && cp <= CHAR_Z || cp >= CHAR_a && cp <= CHAR_z || cp >= CHAR_0 && cp <= CHAR_9 || cp === CHAR_APOS || cp === CHAR_QUOT || cp === CHAR_LOWBAR || cp === CHAR_HYPHEN; -} + if (t && _.label < t[2]) { + _.label = t[2]; -function isAlphaNumHyphen(cp) { - return cp >= CHAR_A && cp <= CHAR_Z || cp >= CHAR_a && cp <= CHAR_z || cp >= CHAR_0 && cp <= CHAR_9 || cp === CHAR_LOWBAR || cp === CHAR_HYPHEN; -} + _.ops.push(op); -const _type = Symbol('type'); + break; + } -const _declared = Symbol('declared'); + if (t[2]) _.ops.pop(); -const hasOwnProperty$1 = Object.prototype.hasOwnProperty; -const defineProperty = Object.defineProperty; -const descriptor = { - configurable: true, - enumerable: true, - writable: true, - value: undefined -}; + _.trys.pop(); -function hasKey(obj, key) { - if (hasOwnProperty$1.call(obj, key)) return true; - if (key === '__proto__') defineProperty(obj, '__proto__', descriptor); - return false; -} + continue; + } -const INLINE_TABLE = Symbol('inline-table'); + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } -function InlineTable() { - return Object.defineProperties({}, { - [_type]: { - value: INLINE_TABLE + if (op[0] & 5) throw op[1]; + return { + value: op[0] ? op[1] : void 0, + done: true + }; } - }); -} + }; -function isInlineTable(obj) { - if (obj === null || typeof obj !== 'object') return false; - return obj[_type] === INLINE_TABLE; -} + var __importStar = this && this.__importStar || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; + }; -const TABLE = Symbol('table'); + var __importDefault = this && this.__importDefault || function (mod) { + return mod && mod.__esModule ? mod : { + "default": mod + }; + }; -function Table() { - return Object.defineProperties({}, { - [_type]: { - value: TABLE - }, - [_declared]: { - value: false, - writable: true - } + Object.defineProperty(exports, "__esModule", { + value: true }); -} -function isTable(obj) { - if (obj === null || typeof obj !== 'object') return false; - return obj[_type] === TABLE; -} + var fs = __importStar(fs__default['default']); -const _contentType = Symbol('content-type'); + var path = __importStar(path__default['default']); -const INLINE_LIST = Symbol('inline-list'); + var semver = __importStar(semver$2); -function InlineList(type) { - return Object.defineProperties([], { - [_type]: { - value: INLINE_LIST - }, - [_contentType]: { - value: type - } - }); -} + var fnmatch_1 = __importDefault(fnmatch); -function isInlineList(obj) { - if (obj === null || typeof obj !== 'object') return false; - return obj[_type] === INLINE_LIST; -} + exports.parseString = ini.parseString; -const LIST = Symbol('list'); + var package_json_1 = __importDefault(require$$4); -function List() { - return Object.defineProperties([], { - [_type]: { - value: LIST - } - }); -} + var knownProps = { + end_of_line: true, + indent_style: true, + indent_size: true, + insert_final_newline: true, + trim_trailing_whitespace: true, + charset: true + }; + + function fnmatch$1(filepath, glob) { + var matchOptions = { + matchBase: true, + dot: true, + noext: true + }; + glob = glob.replace(/\*\*/g, '{*,**/**/**}'); + return fnmatch_1.default(filepath, glob, matchOptions); + } -function isList(obj) { - if (obj === null || typeof obj !== 'object') return false; - return obj[_type] === LIST; -} // in an eval, to let bundlers not slurp in a util proxy + function getConfigFileNames(filepath, options) { + var paths = []; + do { + filepath = path.dirname(filepath); + paths.push(path.join(filepath, options.config)); + } while (filepath !== options.root); -let _custom; + return paths; + } -try { - const utilInspect = util$3.inspect; - _custom = utilInspect.custom; -} catch (_) {} -/* eval require not available in transpiled bundle */ + function processMatches(matches, version) { + // Set indent_size to 'tab' if indent_size is unspecified and + // indent_style is set to 'tab'. + if ('indent_style' in matches && matches.indent_style === 'tab' && !('indent_size' in matches) && semver.gte(version, '0.10.0')) { + matches.indent_size = 'tab'; + } // Set tab_width to indent_size if indent_size is specified and + // tab_width is unspecified -/* istanbul ignore next */ + if ('indent_size' in matches && !('tab_width' in matches) && matches.indent_size !== 'tab') { + matches.tab_width = matches.indent_size; + } // Set indent_size to tab_width if indent_size is 'tab' -const _inspect = _custom || 'inspect'; -class BoxedBigInt { - constructor(value) { - try { - this.value = global.BigInt.asIntN(64, value); - } catch (_) { - /* istanbul ignore next */ - this.value = null; + if ('indent_size' in matches && 'tab_width' in matches && matches.indent_size === 'tab') { + matches.indent_size = matches.tab_width; } - Object.defineProperty(this, _type, { - value: INTEGER - }); - } - - isNaN() { - return this.value === null; + return matches; } - /* istanbul ignore next */ + function processOptions(options, filepath) { + if (options === void 0) { + options = {}; + } - toString() { - return String(this.value); + return { + config: options.config || '.editorconfig', + version: options.version || package_json_1.default.version, + root: path.resolve(options.root || path.parse(filepath).root) + }; } - /* istanbul ignore next */ + function buildFullGlob(pathPrefix, glob) { + switch (glob.indexOf('/')) { + case -1: + glob = '**/' + glob; + break; - [_inspect]() { - return `[BigInt: ${this.toString()}]}`; - } + case 0: + glob = glob.substring(1); + break; + } - valueOf() { - return this.value; + return path.join(pathPrefix, glob); } -} - -const INTEGER = Symbol('integer'); + function extendProps(props, options) { + if (props === void 0) { + props = {}; + } -function Integer(value) { - let num = Number(value); // -0 is a float thing, not an int thing + if (options === void 0) { + options = {}; + } - if (Object.is(num, -0)) num = 0; - /* istanbul ignore else */ + for (var key in options) { + if (options.hasOwnProperty(key)) { + var value = options[key]; + var key2 = key.toLowerCase(); + var value2 = value; - if (global.BigInt && !Number.isSafeInteger(num)) { - return new BoxedBigInt(value); - } else { - /* istanbul ignore next */ - return Object.defineProperties(new Number(num), { - isNaN: { - value: function () { - return isNaN(this); + if (knownProps[key2]) { + value2 = value.toLowerCase(); } - }, - [_type]: { - value: INTEGER - }, - [_inspect]: { - value: () => `[Integer: ${value}]` - } - }); - } -} -function isInteger(obj) { - if (obj === null || typeof obj !== 'object') return false; - return obj[_type] === INTEGER; -} + try { + value2 = JSON.parse(value); + } catch (e) {} -const FLOAT = Symbol('float'); + if (typeof value === 'undefined' || value === null) { + // null and undefined are values specific to JSON (no special meaning + // in editorconfig) & should just be returned as regular strings. + value2 = String(value); + } -function Float(value) { - /* istanbul ignore next */ - return Object.defineProperties(new Number(value), { - [_type]: { - value: FLOAT - }, - [_inspect]: { - value: () => `[Float: ${value}]` + props[key2] = value2; + } } - }); -} - -function isFloat(obj) { - if (obj === null || typeof obj !== 'object') return false; - return obj[_type] === FLOAT; -} - -function tomlType(value) { - const type = typeof value; - if (type === 'object') { - /* istanbul ignore if */ - if (value === null) return 'null'; - if (value instanceof Date) return 'datetime'; - /* istanbul ignore else */ + return props; + } - if (_type in value) { - switch (value[_type]) { - case INLINE_TABLE: - return 'inline-table'; + function parseFromConfigs(configs, filepath, options) { + return processMatches(configs.reverse().reduce(function (matches, file) { + var pathPrefix = path.dirname(file.name); + file.contents.forEach(function (section) { + var glob = section[0]; + var options2 = section[1]; - case INLINE_LIST: - return 'inline-list'; + if (!glob) { + return; + } - /* istanbul ignore next */ + var fullGlob = buildFullGlob(pathPrefix, glob); - case TABLE: - return 'table'; + if (!fnmatch$1(filepath, fullGlob)) { + return; + } - /* istanbul ignore next */ + matches = extendProps(matches, options2); + }); + return matches; + }, {}), options.version); + } - case LIST: - return 'list'; + function getConfigsForFiles(files) { + var configs = []; - case FLOAT: - return 'float'; + for (var i in files) { + if (files.hasOwnProperty(i)) { + var file = files[i]; + var contents = ini.parseString(file.contents); + configs.push({ + name: file.name, + contents: contents + }); - case INTEGER: - return 'integer'; + if ((contents[0][1].root || '').toLowerCase() === 'true') { + break; + } } } + + return configs; } - return type; -} + function readConfigFiles(filepaths) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2 + /*return*/ + , Promise.all(filepaths.map(function (name) { + return new Promise(function (resolve) { + fs.readFile(name, 'utf8', function (err, data) { + resolve({ + name: name, + contents: err ? '' : data + }); + }); + }); + }))]; + }); + }); + } -function makeParserClass(Parser) { - class TOMLParser extends Parser { - constructor() { - super(); - this.ctx = this.obj = Table(); + function readConfigFilesSync(filepaths) { + var files = []; + var file; + filepaths.forEach(function (filepath) { + try { + file = fs.readFileSync(filepath, 'utf8'); + } catch (e) { + file = ''; + } + + files.push({ + name: filepath, + contents: file + }); + }); + return files; + } + + function opts(filepath, options) { + if (options === void 0) { + options = {}; } - /* MATCH HELPER */ + var resolvedFilePath = path.resolve(filepath); + return [resolvedFilePath, processOptions(options, resolvedFilePath)]; + } - atEndOfWord() { - return this.char === CHAR_NUM || this.char === CTRL_I || this.char === CHAR_SP || this.atEndOfLine(); + function parseFromFiles(filepath, files, options) { + if (options === void 0) { + options = {}; } - atEndOfLine() { - return this.char === Parser.END || this.char === CTRL_J || this.char === CTRL_M; + return __awaiter(this, void 0, void 0, function () { + var _a, resolvedFilePath, processedOptions; + + return __generator(this, function (_b) { + _a = opts(filepath, options), resolvedFilePath = _a[0], processedOptions = _a[1]; + return [2 + /*return*/ + , files.then(getConfigsForFiles).then(function (configs) { + return parseFromConfigs(configs, resolvedFilePath, processedOptions); + })]; + }); + }); + } + + exports.parseFromFiles = parseFromFiles; + + function parseFromFilesSync(filepath, files, options) { + if (options === void 0) { + options = {}; } - parseStart() { - if (this.char === Parser.END) { - return null; - } else if (this.char === CHAR_LSQB) { - return this.call(this.parseTableOrList); - } else if (this.char === CHAR_NUM) { - return this.call(this.parseComment); - } else if (this.char === CTRL_J || this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M) { - return null; - } else if (isAlphaNumQuoteHyphen(this.char)) { - return this.callNow(this.parseAssignStatement); - } else { - throw this.error(new TomlError(`Unknown character "${this.char}"`)); - } - } // HELPER, this strips any whitespace and comments to the end of the line - // then RETURNS. Last state in a production. + var _a = opts(filepath, options), + resolvedFilePath = _a[0], + processedOptions = _a[1]; + return parseFromConfigs(getConfigsForFiles(files), resolvedFilePath, processedOptions); + } - parseWhitespaceToEOL() { - if (this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M) { - return null; - } else if (this.char === CHAR_NUM) { - return this.goto(this.parseComment); - } else if (this.char === Parser.END || this.char === CTRL_J) { - return this.return(); - } else { - throw this.error(new TomlError('Unexpected character, expected only whitespace or comments till end of line')); - } + exports.parseFromFilesSync = parseFromFilesSync; + + function parse(_filepath, _options) { + if (_options === void 0) { + _options = {}; } - /* ASSIGNMENT: key = value */ + return __awaiter(this, void 0, void 0, function () { + var _a, resolvedFilePath, processedOptions, filepaths; - parseAssignStatement() { - return this.callNow(this.parseAssign, this.recordAssignStatement); + return __generator(this, function (_b) { + _a = opts(_filepath, _options), resolvedFilePath = _a[0], processedOptions = _a[1]; + filepaths = getConfigFileNames(resolvedFilePath, processedOptions); + return [2 + /*return*/ + , readConfigFiles(filepaths).then(getConfigsForFiles).then(function (configs) { + return parseFromConfigs(configs, resolvedFilePath, processedOptions); + })]; + }); + }); + } + + exports.parse = parse; + + function parseSync(_filepath, _options) { + if (_options === void 0) { + _options = {}; } - recordAssignStatement(kv) { - let target = this.ctx; - let finalKey = kv.key.pop(); + var _a = opts(_filepath, _options), + resolvedFilePath = _a[0], + processedOptions = _a[1]; - for (let kw of kv.key) { - if (hasKey(target, kw) && (!isTable(target[kw]) || target[kw][_declared])) { - throw this.error(new TomlError("Can't redefine existing key")); - } + var filepaths = getConfigFileNames(resolvedFilePath, processedOptions); + var files = readConfigFilesSync(filepaths); + return parseFromConfigs(getConfigsForFiles(files), resolvedFilePath, processedOptions); + } - target = target[kw] = target[kw] || Table(); - } + exports.parseSync = parseSync; +}); - if (hasKey(target, finalKey)) { - throw this.error(new TomlError("Can't redefine existing key")); - } // unbox our numbers +var editorconfigToPrettier = editorConfigToPrettier; +function removeUnset(editorConfig) { + const result = {}; + const keys = Object.keys(editorConfig); - if (isInteger(kv.value) || isFloat(kv.value)) { - target[finalKey] = kv.value.valueOf(); - } else { - target[finalKey] = kv.value; - } + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; - return this.goto(this.parseWhitespaceToEOL); + if (editorConfig[key] === "unset") { + continue; } - /* ASSSIGNMENT expression, key = value possibly inside an inline table */ + result[key] = editorConfig[key]; + } - parseAssign() { - return this.callNow(this.parseKeyword, this.recordAssignKeyword); - } + return result; +} - recordAssignKeyword(key) { - if (this.state.resultTable) { - this.state.resultTable.push(key); - } else { - this.state.resultTable = [key]; - } +function editorConfigToPrettier(editorConfig) { + if (!editorConfig) { + return null; + } - return this.goto(this.parseAssignKeywordPreDot); - } + editorConfig = removeUnset(editorConfig); - parseAssignKeywordPreDot() { - if (this.char === CHAR_PERIOD) { - return this.next(this.parseAssignKeywordPostDot); - } else if (this.char !== CHAR_SP && this.char !== CTRL_I) { - return this.goto(this.parseAssignEqual); - } - } + if (Object.keys(editorConfig).length === 0) { + return null; + } - parseAssignKeywordPostDot() { - if (this.char !== CHAR_SP && this.char !== CTRL_I) { - return this.callNow(this.parseKeyword, this.recordAssignKeyword); - } - } + const result = {}; - parseAssignEqual() { - if (this.char === CHAR_EQUALS) { - return this.next(this.parseAssignPreValue); - } else { - throw this.error(new TomlError('Invalid character, expected "="')); - } - } + if (editorConfig.indent_style) { + result.useTabs = editorConfig.indent_style === "tab"; + } - parseAssignPreValue() { - if (this.char === CHAR_SP || this.char === CTRL_I) { - return null; - } else { - return this.callNow(this.parseValue, this.recordAssignValue); - } - } + if (editorConfig.indent_size === "tab") { + result.useTabs = true; + } - recordAssignValue(value) { - return this.returnNow({ - key: this.state.resultTable, - value: value - }); - } - /* COMMENTS: #...eol */ + if (result.useTabs && editorConfig.tab_width) { + result.tabWidth = editorConfig.tab_width; + } else if (editorConfig.indent_style === "space" && editorConfig.indent_size && editorConfig.indent_size !== "tab") { + result.tabWidth = editorConfig.indent_size; + } else if (editorConfig.tab_width !== undefined) { + result.tabWidth = editorConfig.tab_width; + } + if (editorConfig.max_line_length && editorConfig.max_line_length !== "off") { + result.printWidth = editorConfig.max_line_length; + } - parseComment() { - do { - if (this.char === Parser.END || this.char === CTRL_J) { - return this.return(); - } - } while (this.nextChar()); - } - /* TABLES AND LISTS, [foo] and [[foo]] */ + if (editorConfig.quote_type === "single") { + result.singleQuote = true; + } else if (editorConfig.quote_type === "double") { + result.singleQuote = false; + } + if (["cr", "crlf", "lf"].indexOf(editorConfig.end_of_line) !== -1) { + result.endOfLine = editorConfig.end_of_line; + } - parseTableOrList() { - if (this.char === CHAR_LSQB) { - this.next(this.parseList); - } else { - return this.goto(this.parseTable); - } - } - /* TABLE [foo.bar.baz] */ + if (editorConfig.insert_final_newline === false || editorConfig.insert_final_newline === true) { + result.insertFinalNewline = editorConfig.insert_final_newline; + } + return result; +} - parseTable() { - this.ctx = this.obj; - return this.goto(this.parseTableNext); - } +// https://github.com/kirstein/find-project-root/blob/master/index.js - parseTableNext() { - if (this.char === CHAR_SP || this.char === CTRL_I) { - return null; - } else { - return this.callNow(this.parseKeyword, this.parseTableMore); - } - } - parseTableMore(keyword) { - if (this.char === CHAR_SP || this.char === CTRL_I) { - return null; - } else if (this.char === CHAR_RSQB) { - if (hasKey(this.ctx, keyword) && (!isTable(this.ctx[keyword]) || this.ctx[keyword][_declared])) { - throw this.error(new TomlError("Can't redefine existing key")); - } else { - this.ctx = this.ctx[keyword] = this.ctx[keyword] || Table(); - this.ctx[_declared] = true; - } +const MARKERS = [".git", ".hg"]; - return this.next(this.parseWhitespaceToEOL); - } else if (this.char === CHAR_PERIOD) { - if (!hasKey(this.ctx, keyword)) { - this.ctx = this.ctx[keyword] = Table(); - } else if (isTable(this.ctx[keyword])) { - this.ctx = this.ctx[keyword]; - } else if (isList(this.ctx[keyword])) { - this.ctx = this.ctx[keyword][this.ctx[keyword].length - 1]; - } else { - throw this.error(new TomlError("Can't redefine existing key")); - } +const markerExists = directory => MARKERS.some(mark => fs__default['default'].existsSync(path__default['default'].join(directory, mark))); - return this.next(this.parseTableNext); - } else { - throw this.error(new TomlError('Unexpected character, expected whitespace, . or ]')); - } +function findProjectRoot(directory) { + while (!markerExists(directory)) { + const parentDirectory = path__default['default'].resolve(directory, ".."); + + if (parentDirectory === directory) { + break; } - /* LIST [[a.b.c]] */ + directory = parentDirectory; + } + + return directory; +} - parseList() { - this.ctx = this.obj; - return this.goto(this.parseListNext); - } +var findProjectRoot_1 = findProjectRoot; - parseListNext() { - if (this.char === CHAR_SP || this.char === CTRL_I) { - return null; - } else { - return this.callNow(this.parseKeyword, this.parseListMore); - } - } +const jsonStringifyMem = fn => dist$1(fn, { + cacheKey: JSON.stringify +}); - parseListMore(keyword) { - if (this.char === CHAR_SP || this.char === CTRL_I) { - return null; - } else if (this.char === CHAR_RSQB) { - if (!hasKey(this.ctx, keyword)) { - this.ctx[keyword] = List(); - } +const maybeParse = (filePath, parse) => filePath && parse(filePath, { + root: findProjectRoot_1(path__default['default'].dirname(path__default['default'].resolve(filePath))) +}); - if (isInlineList(this.ctx[keyword])) { - throw this.error(new TomlError("Can't extend an inline array")); - } else if (isList(this.ctx[keyword])) { - const next = Table(); - this.ctx[keyword].push(next); - this.ctx = next; - } else { - throw this.error(new TomlError("Can't redefine an existing key")); - } +const editorconfigAsyncNoCache = async (filePath) => editorconfigToPrettier(await maybeParse(filePath, src$1.parse)); - return this.next(this.parseListEnd); - } else if (this.char === CHAR_PERIOD) { - if (!hasKey(this.ctx, keyword)) { - this.ctx = this.ctx[keyword] = Table(); - } else if (isInlineList(this.ctx[keyword])) { - throw this.error(new TomlError("Can't extend an inline array")); - } else if (isInlineTable(this.ctx[keyword])) { - throw this.error(new TomlError("Can't extend an inline table")); - } else if (isList(this.ctx[keyword])) { - this.ctx = this.ctx[keyword][this.ctx[keyword].length - 1]; - } else if (isTable(this.ctx[keyword])) { - this.ctx = this.ctx[keyword]; - } else { - throw this.error(new TomlError("Can't redefine an existing key")); - } +const editorconfigAsyncWithCache = jsonStringifyMem(editorconfigAsyncNoCache); - return this.next(this.parseListNext); - } else { - throw this.error(new TomlError('Unexpected character, expected whitespace, . or ]')); - } - } +const editorconfigSyncNoCache = filePath => editorconfigToPrettier(maybeParse(filePath, src$1.parseSync)); - parseListEnd(keyword) { - if (this.char === CHAR_RSQB) { - return this.next(this.parseWhitespaceToEOL); - } else { - throw this.error(new TomlError('Unexpected character, expected whitespace, . or ]')); - } - } - /* VALUE string, number, boolean, inline list, inline object */ +const editorconfigSyncWithCache = jsonStringifyMem(editorconfigSyncNoCache); +function getLoadFunction(opts) { + if (!opts.editorconfig) { + return () => null; + } - parseValue() { - if (this.char === Parser.END) { - throw this.error(new TomlError('Key without value')); - } else if (this.char === CHAR_QUOT) { - return this.next(this.parseDoubleString); - } + if (opts.sync) { + return opts.cache ? editorconfigSyncWithCache : editorconfigSyncNoCache; + } - if (this.char === CHAR_APOS) { - return this.next(this.parseSingleString); - } else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) { - return this.goto(this.parseNumberSign); - } else if (this.char === CHAR_i) { - return this.next(this.parseInf); - } else if (this.char === CHAR_n) { - return this.next(this.parseNan); - } else if (isDigit(this.char)) { - return this.goto(this.parseNumberOrDateTime); - } else if (this.char === CHAR_t || this.char === CHAR_f) { - return this.goto(this.parseBoolean); - } else if (this.char === CHAR_LSQB) { - return this.call(this.parseInlineList, this.recordValue); - } else if (this.char === CHAR_LCUB) { - return this.call(this.parseInlineTable, this.recordValue); - } else { - throw this.error(new TomlError('Unexpected character, expecting string, number, datetime, boolean, inline array or inline table')); - } - } + return opts.cache ? editorconfigAsyncWithCache : editorconfigAsyncNoCache; +} - recordValue(value) { - return this.returnNow(value); - } +function clearCache() { + dist$1.clear(editorconfigSyncWithCache); + dist$1.clear(editorconfigAsyncWithCache); +} - parseInf() { - if (this.char === CHAR_n) { - return this.next(this.parseInf2); - } else { - throw this.error(new TomlError('Unexpected character, expected "inf", "+inf" or "-inf"')); - } - } +var resolveConfigEditorconfig = { + getLoadFunction, + clearCache +}; - parseInf2() { - if (this.char === CHAR_f) { - if (this.state.buf === '-') { - return this.return(-Infinity); - } else { - return this.return(Infinity); +const getExplorerMemoized = dist$1(opts => { + const cosmiconfig = thirdParty["cosmiconfig" + (opts.sync ? "Sync" : "")]; + const explorer = cosmiconfig("prettier", { + cache: opts.cache, + transform: result => { + if (result && result.config) { + if (typeof result.config === "string") { + const dir = path__default['default'].dirname(result.filepath); + const modulePath = resolve_1(result.config, { + paths: [dir] + }); + result.config = require(modulePath); } - } else { - throw this.error(new TomlError('Unexpected character, expected "inf", "+inf" or "-inf"')); - } - } - parseNan() { - if (this.char === CHAR_a) { - return this.next(this.parseNan2); - } else { - throw this.error(new TomlError('Unexpected character, expected "nan"')); - } - } + if (typeof result.config !== "object") { + throw new Error("Config is only allowed to be an object, " + `but received ${typeof result.config} in "${result.filepath}"`); + } - parseNan2() { - if (this.char === CHAR_n) { - return this.return(NaN); - } else { - throw this.error(new TomlError('Unexpected character, expected "nan"')); + delete result.config.$schema; } + + return result; + }, + searchPlaces: ["package.json", ".prettierrc", ".prettierrc.json", ".prettierrc.yaml", ".prettierrc.yml", ".prettierrc.json5", ".prettierrc.js", ".prettierrc.cjs", "prettier.config.js", "prettier.config.cjs", ".prettierrc.toml"], + loaders: { + ".toml": loadToml, + ".json5": loadJson5 } - /* KEYS, barewords or basic, literal, or dotted */ + }); + return explorer; +}, { + cacheKey: JSON.stringify +}); +/** @param {{ cache: boolean, sync: boolean }} opts */ + +function getExplorer(opts) { + // Normalize opts before passing to a memoized function + opts = Object.assign({ + sync: false, + cache: false + }, opts); + return getExplorerMemoized(opts); +} +function _resolveConfig(filePath, opts, sync) { + opts = Object.assign({ + useCache: true + }, opts); + const loadOpts = { + cache: !!opts.useCache, + sync: !!sync, + editorconfig: !!opts.editorconfig + }; + const { + load, + search + } = getExplorer(loadOpts); + const loadEditorConfig = resolveConfigEditorconfig.getLoadFunction(loadOpts); + const arr = [opts.config ? load(opts.config) : search(filePath), loadEditorConfig(filePath)]; - parseKeyword() { - if (this.char === CHAR_QUOT) { - return this.next(this.parseBasicString); - } else if (this.char === CHAR_APOS) { - return this.next(this.parseLiteralString); - } else { - return this.goto(this.parseBareKey); + const unwrapAndMerge = ([result, editorConfigured]) => { + const merged = Object.assign({}, editorConfigured, mergeOverrides(result, filePath)); + ["plugins", "pluginSearchDirs"].forEach(optionName => { + if (Array.isArray(merged[optionName])) { + merged[optionName] = merged[optionName].map(value => typeof value === "string" && value.startsWith(".") // relative path + ? path__default['default'].resolve(path__default['default'].dirname(result.filepath), value) : value); } - } - /* KEYS: barewords */ + }); + if (!result && !editorConfigured) { + return null; + } // We are not using this option - parseBareKey() { - do { - if (this.char === Parser.END) { - throw this.error(new TomlError('Key ended without value')); - } else if (isAlphaNumHyphen(this.char)) { - this.consume(); - } else if (this.state.buf.length === 0) { - throw this.error(new TomlError('Empty bare keys are not allowed')); - } else { - return this.returnNow(); - } - } while (this.nextChar()); - } - /* STRINGS, single quoted (literal) */ + delete merged.insertFinalNewline; + return merged; + }; - parseSingleString() { - if (this.char === CHAR_APOS) { - return this.next(this.parseLiteralMultiStringMaybe); - } else { - return this.goto(this.parseLiteralString); - } - } + if (loadOpts.sync) { + return unwrapAndMerge(arr); + } - parseLiteralString() { - do { - if (this.char === CHAR_APOS) { - return this.return(); - } else if (this.atEndOfLine()) { - throw this.error(new TomlError('Unterminated string')); - } else if (this.char === CHAR_DEL || this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I) { - throw this.errorControlCharInString(); - } else { - this.consume(); - } - } while (this.nextChar()); - } + return Promise.all(arr).then(unwrapAndMerge); +} - parseLiteralMultiStringMaybe() { - if (this.char === CHAR_APOS) { - return this.next(this.parseLiteralMultiString); - } else { - return this.returnNow(); - } - } +const resolveConfig = (filePath, opts) => _resolveConfig(filePath, opts, false); - parseLiteralMultiString() { - if (this.char === CTRL_M) { - return null; - } else if (this.char === CTRL_J) { - return this.next(this.parseLiteralMultiStringContent); - } else { - return this.goto(this.parseLiteralMultiStringContent); - } - } +resolveConfig.sync = (filePath, opts) => _resolveConfig(filePath, opts, true); - parseLiteralMultiStringContent() { - do { - if (this.char === CHAR_APOS) { - return this.next(this.parseLiteralMultiEnd); - } else if (this.char === Parser.END) { - throw this.error(new TomlError('Unterminated multi-line string')); - } else if (this.char === CHAR_DEL || this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I && this.char !== CTRL_J && this.char !== CTRL_M) { - throw this.errorControlCharInString(); - } else { - this.consume(); - } - } while (this.nextChar()); - } +function clearCache$1() { + dist$1.clear(getExplorerMemoized); + resolveConfigEditorconfig.clearCache(); +} - parseLiteralMultiEnd() { - if (this.char === CHAR_APOS) { - return this.next(this.parseLiteralMultiEnd2); - } else { - this.state.buf += "'"; - return this.goto(this.parseLiteralMultiStringContent); - } - } +async function resolveConfigFile(filePath) { + const { + search + } = getExplorer({ + sync: false + }); + const result = await search(filePath); + return result ? result.filepath : null; +} - parseLiteralMultiEnd2() { - if (this.char === CHAR_APOS) { - return this.return(); - } else { - this.state.buf += "''"; - return this.goto(this.parseLiteralMultiStringContent); - } - } - /* STRINGS double quoted */ +resolveConfigFile.sync = filePath => { + const { + search + } = getExplorer({ + sync: true + }); + const result = search(filePath); + return result ? result.filepath : null; +}; +function mergeOverrides(configResult, filePath) { + const { + config, + filepath: configPath + } = configResult || {}; - parseDoubleString() { - if (this.char === CHAR_QUOT) { - return this.next(this.parseMultiStringMaybe); - } else { - return this.goto(this.parseBasicString); + const _ref = config || {}, + { + overrides + } = _ref, + options = _objectWithoutPropertiesLoose(_ref, ["overrides"]); + + if (filePath && overrides) { + const relativeFilePath = path__default['default'].relative(path__default['default'].dirname(configPath), filePath); + + for (const override of overrides) { + if (pathMatchesGlobs(relativeFilePath, override.files, override.excludeFiles)) { + Object.assign(options, override.options); } } + } - parseBasicString() { - do { - if (this.char === CHAR_BSOL) { - return this.call(this.parseEscape, this.recordEscapeReplacement); - } else if (this.char === CHAR_QUOT) { - return this.return(); - } else if (this.atEndOfLine()) { - throw this.error(new TomlError('Unterminated string')); - } else if (this.char === CHAR_DEL || this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I) { - throw this.errorControlCharInString(); - } else { - this.consume(); - } - } while (this.nextChar()); - } + return options; +} // Based on eslint: https://github.com/eslint/eslint/blob/master/lib/config/config-ops.js - recordEscapeReplacement(replacement) { - this.state.buf += replacement; - return this.goto(this.parseBasicString); - } - parseMultiStringMaybe() { - if (this.char === CHAR_QUOT) { - return this.next(this.parseMultiString); - } else { - return this.returnNow(); - } - } +function pathMatchesGlobs(filePath, patterns, excludedPatterns) { + const patternList = [].concat(patterns); + const excludedPatternList = [].concat(excludedPatterns || []); + const opts = { + matchBase: true, + dot: true + }; + return patternList.some(pattern => minimatch_1(filePath, pattern, opts)) && !excludedPatternList.some(excludedPattern => minimatch_1(filePath, excludedPattern, opts)); +} - parseMultiString() { - if (this.char === CTRL_M) { - return null; - } else if (this.char === CTRL_J) { - return this.next(this.parseMultiStringContent); - } else { - return this.goto(this.parseMultiStringContent); - } - } +var resolveConfig_1 = { + resolveConfig, + resolveConfigFile, + clearCache: clearCache$1 +}; - parseMultiStringContent() { - do { - if (this.char === CHAR_BSOL) { - return this.call(this.parseMultiEscape, this.recordMultiEscapeReplacement); - } else if (this.char === CHAR_QUOT) { - return this.next(this.parseMultiEnd); - } else if (this.char === Parser.END) { - throw this.error(new TomlError('Unterminated multi-line string')); - } else if (this.char === CHAR_DEL || this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I && this.char !== CTRL_J && this.char !== CTRL_M) { - throw this.errorControlCharInString(); - } else { - this.consume(); - } - } while (this.nextChar()); - } +// A simple implementation of make-array +function make_array(subject) { + return Array.isArray(subject) ? subject : [subject]; +} - errorControlCharInString() { - let displayCode = '\\u00'; +const REGEX_BLANK_LINE = /^\s+$/; +const REGEX_LEADING_EXCAPED_EXCLAMATION = /^\\!/; +const REGEX_LEADING_EXCAPED_HASH = /^\\#/; +const SLASH = '/'; +const KEY_IGNORE = typeof Symbol !== 'undefined' ? Symbol.for('node-ignore') +/* istanbul ignore next */ +: 'node-ignore'; - if (this.char < 16) { - displayCode += '0'; - } +const define = (object, key, value) => Object.defineProperty(object, key, { + value +}); - displayCode += this.char.toString(16); - return this.error(new TomlError(`Control characters (codes < 0x1f and 0x7f) are not allowed in strings, use ${displayCode} instead`)); - } +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. +: ''); // > 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 DEFAULT_REPLACER_PREFIX = [// > Trailing spaces are ignored unless they are quoted with backslash ("\") +[// (a\ ) -> (a ) +// (a ) -> (a) +// (a \ ) -> (a ) +/\\?\s+$/, match => match.indexOf('\\') === 0 ? ' ' : ''], // replace (\ ) with ' ' +[/\\\s/g, () => ' '], // 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}`], [// > [abc] matches any character inside the brackets +// > (in this case a, b, or c); +/\[([^\]/]*)($|\])/g, (match, p1, p2) => p2 === ']' ? `[${sanitizeRange(p1)}]` : `\\${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' +() => '^(?:.*\\/)?']]; +const DEFAULT_REPLACER_SUFFIX = [// 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() { + return !/\/(?!$)/.test(this) // > 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 + ? '(?:^|\\/)' // > 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 `'/**'` +(match, 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' +(match, p1) => `${p1}[^\\/]*`], // trailing wildcard +[/(\^|\\\/)?\\\*$/, (match, p1) => { + const prefix = p1 // '\^': + // '/*' does not match '' + // '/*' does not match everything + // '\\\/': + // 'abc/*' does not match 'abc/' + ? `${p1}[^/]+` // 'a*' matches 'a' + // 'a*' matches 'aa' + : '[^/]*'; + return `${prefix}(?=$|\\/$)`; +}], [// unescape +/\\\\\\/g, () => '\\']]; +const POSITIVE_REPLACERS = [...DEFAULT_REPLACER_PREFIX, // 'f' +// matches +// - /f(end) +// - /f/ +// - (start)f(end) +// - (start)f/ +// doesn't match +// - oof +// - foo +// pseudo: +// -> (^|/)f(/|$) +// ending +[// 'js' will not match 'js.' +// 'ab' will not match 'abc' +/(?:[^*/])$/, // 'js*' will not match 'a.js' +// 'js/' will not match 'a.js' +// 'js' will match 'a.js' and 'a.js/' +match => `${match}(?=$|\\/)`], ...DEFAULT_REPLACER_SUFFIX]; +const NEGATIVE_REPLACERS = [...DEFAULT_REPLACER_PREFIX, // #24, #38 +// The MISSING rule of [gitignore docs](https://git-scm.com/docs/gitignore) +// A negative pattern without a trailing wildcard should not +// re-include the things inside that directory. +// eg: +// ['node_modules/*', '!node_modules'] +// should ignore `node_modules/a.js` +[/(?:[^*])$/, match => `${match}(?=$|\\/$)`], ...DEFAULT_REPLACER_SUFFIX]; // A simple cache, because an ignore rule only has only one certain meaning - recordMultiEscapeReplacement(replacement) { - this.state.buf += replacement; - return this.goto(this.parseMultiStringContent); - } +const cache = Object.create(null); // @param {pattern} - parseMultiEnd() { - if (this.char === CHAR_QUOT) { - return this.next(this.parseMultiEnd2); - } else { - this.state.buf += '"'; - return this.goto(this.parseMultiStringContent); - } - } +const make_regex = (pattern, negative, ignorecase) => { + const r = cache[pattern]; - parseMultiEnd2() { - if (this.char === CHAR_QUOT) { - return this.return(); - } else { - this.state.buf += '""'; - return this.goto(this.parseMultiStringContent); - } - } + if (r) { + return r; + } - parseMultiEscape() { - if (this.char === CTRL_M || this.char === CTRL_J) { - return this.next(this.parseMultiTrim); - } else if (this.char === CHAR_SP || this.char === CTRL_I) { - return this.next(this.parsePreMultiTrim); - } else { - return this.goto(this.parseEscape); - } - } + const replacers = negative ? NEGATIVE_REPLACERS : POSITIVE_REPLACERS; + const source = replacers.reduce((prev, current) => prev.replace(current[0], current[1].bind(pattern)), pattern); + return cache[pattern] = ignorecase ? new RegExp(source, 'i') : new RegExp(source); +}; // > A blank line matches no files, so it can serve as a separator for readability. - parsePreMultiTrim() { - if (this.char === CHAR_SP || this.char === CTRL_I) { - return null; - } else if (this.char === CTRL_M || this.char === CTRL_J) { - return this.next(this.parseMultiTrim); - } else { - throw this.error(new TomlError("Can't escape whitespace")); - } - } - parseMultiTrim() { - // explicitly whitespace here, END should follow the same path as chars - if (this.char === CTRL_J || this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M) { - return null; - } else { - return this.returnNow(); - } - } +const checkPattern = pattern => pattern && typeof pattern === 'string' && !REGEX_BLANK_LINE.test(pattern) // > A line starting with # serves as a comment. +&& pattern.indexOf('#') !== 0; - parseEscape() { - if (this.char in escapes) { - return this.return(escapes[this.char]); - } else if (this.char === CHAR_u) { - return this.call(this.parseSmallUnicode, this.parseUnicodeReturn); - } else if (this.char === CHAR_U) { - return this.call(this.parseLargeUnicode, this.parseUnicodeReturn); - } else { - throw this.error(new TomlError('Unknown escape character: ' + this.char)); - } - } +const createRule = (pattern, ignorecase) => { + const origin = pattern; + let negative = false; // > An optional prefix "!" which negates the pattern; - parseUnicodeReturn(char) { - try { - const codePoint = parseInt(char, 16); + if (pattern.indexOf('!') === 0) { + negative = true; + pattern = pattern.substr(1); + } - if (codePoint >= SURROGATE_FIRST && codePoint <= SURROGATE_LAST) { - throw this.error(new TomlError('Invalid unicode, character in range 0xD800 - 0xDFFF is reserved')); - } + pattern = pattern // > Put a backslash ("\") in front of the first "!" for patterns that + // > begin with a literal "!", for example, `"\!important!.txt"`. + .replace(REGEX_LEADING_EXCAPED_EXCLAMATION, '!') // > Put a backslash ("\") in front of the first hash for patterns that + // > begin with a hash. + .replace(REGEX_LEADING_EXCAPED_HASH, '#'); + const regex = make_regex(pattern, negative, ignorecase); + return { + origin, + pattern, + negative, + regex + }; +}; - return this.returnNow(String.fromCodePoint(codePoint)); - } catch (err) { - throw this.error(TomlError.wrap(err)); - } - } +class IgnoreBase { + constructor({ + ignorecase = true + } = {}) { + this._rules = []; + this._ignorecase = ignorecase; + define(this, KEY_IGNORE, true); - parseSmallUnicode() { - if (!isHexit(this.char)) { - throw this.error(new TomlError('Invalid character in unicode sequence, expected hex')); - } else { - this.consume(); - if (this.state.buf.length >= 4) return this.return(); - } - } + this._initCache(); + } - parseLargeUnicode() { - if (!isHexit(this.char)) { - throw this.error(new TomlError('Invalid character in unicode sequence, expected hex')); - } else { - this.consume(); - if (this.state.buf.length >= 8) return this.return(); - } - } - /* NUMBERS */ + _initCache() { + this._cache = Object.create(null); + } // @param {Array.|string|Ignore} pattern - parseNumberSign() { - this.consume(); - return this.next(this.parseMaybeSignedInfOrNan); - } + add(pattern) { + this._added = false; - parseMaybeSignedInfOrNan() { - if (this.char === CHAR_i) { - return this.next(this.parseInf); - } else if (this.char === CHAR_n) { - return this.next(this.parseNan); - } else { - return this.callNow(this.parseNoUnder, this.parseNumberIntegerStart); - } + if (typeof pattern === 'string') { + pattern = pattern.split(/\r?\n/g); } - parseNumberIntegerStart() { - if (this.char === CHAR_0) { - this.consume(); - return this.next(this.parseNumberIntegerExponentOrDecimal); - } else { - return this.goto(this.parseNumberInteger); - } - } + make_array(pattern).forEach(this._addPattern, this); // Some rules have just added to the ignore, + // making the behavior changed. - parseNumberIntegerExponentOrDecimal() { - if (this.char === CHAR_PERIOD) { - this.consume(); - return this.call(this.parseNoUnder, this.parseNumberFloat); - } else if (this.char === CHAR_E || this.char === CHAR_e) { - this.consume(); - return this.next(this.parseNumberExponentSign); - } else { - return this.returnNow(Integer(this.state.buf)); - } + if (this._added) { + this._initCache(); } - parseNumberInteger() { - if (isDigit(this.char)) { - this.consume(); - } else if (this.char === CHAR_LOWBAR) { - return this.call(this.parseNoUnder); - } else if (this.char === CHAR_E || this.char === CHAR_e) { - this.consume(); - return this.next(this.parseNumberExponentSign); - } else if (this.char === CHAR_PERIOD) { - this.consume(); - return this.call(this.parseNoUnder, this.parseNumberFloat); - } else { - const result = Integer(this.state.buf); - /* istanbul ignore if */ - - if (result.isNaN()) { - throw this.error(new TomlError('Invalid number')); - } else { - return this.returnNow(result); - } - } - } + return this; + } // legacy - parseNoUnder() { - if (this.char === CHAR_LOWBAR || this.char === CHAR_PERIOD || this.char === CHAR_E || this.char === CHAR_e) { - throw this.error(new TomlError('Unexpected character, expected digit')); - } else if (this.atEndOfWord()) { - throw this.error(new TomlError('Incomplete number')); - } - return this.returnNow(); - } + addPattern(pattern) { + return this.add(pattern); + } - parseNumberFloat() { - if (this.char === CHAR_LOWBAR) { - return this.call(this.parseNoUnder, this.parseNumberFloat); - } else if (isDigit(this.char)) { - this.consume(); - } else if (this.char === CHAR_E || this.char === CHAR_e) { - this.consume(); - return this.next(this.parseNumberExponentSign); - } else { - return this.returnNow(Float(this.state.buf)); - } + _addPattern(pattern) { + // #32 + if (pattern && pattern[KEY_IGNORE]) { + this._rules = this._rules.concat(pattern._rules); + this._added = true; + return; } - parseNumberExponentSign() { - if (isDigit(this.char)) { - return this.goto(this.parseNumberExponent); - } else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) { - this.consume(); - this.call(this.parseNoUnder, this.parseNumberExponent); - } else { - throw this.error(new TomlError('Unexpected character, expected -, + or digit')); - } - } + if (checkPattern(pattern)) { + const rule = createRule(pattern, this._ignorecase); + this._added = true; - parseNumberExponent() { - if (isDigit(this.char)) { - this.consume(); - } else if (this.char === CHAR_LOWBAR) { - return this.call(this.parseNoUnder); - } else { - return this.returnNow(Float(this.state.buf)); - } + this._rules.push(rule); } - /* NUMBERS or DATETIMES */ + } + filter(paths) { + return make_array(paths).filter(path => this._filter(path)); + } - parseNumberOrDateTime() { - if (this.char === CHAR_0) { - this.consume(); - return this.next(this.parseNumberBaseOrDateTime); - } else { - return this.goto(this.parseNumberOrDateTimeOnly); - } - } + createFilter() { + return path => this._filter(path); + } - parseNumberOrDateTimeOnly() { - // note, if two zeros are in a row then it MUST be a date - if (this.char === CHAR_LOWBAR) { - return this.call(this.parseNoUnder, this.parseNumberInteger); - } else if (isDigit(this.char)) { - this.consume(); - if (this.state.buf.length > 4) this.next(this.parseNumberInteger); - } else if (this.char === CHAR_E || this.char === CHAR_e) { - this.consume(); - return this.next(this.parseNumberExponentSign); - } else if (this.char === CHAR_PERIOD) { - this.consume(); - return this.call(this.parseNoUnder, this.parseNumberFloat); - } else if (this.char === CHAR_HYPHEN) { - return this.goto(this.parseDateTime); - } else if (this.char === CHAR_COLON) { - return this.goto(this.parseOnlyTimeHour); - } else { - return this.returnNow(Integer(this.state.buf)); - } - } + ignores(path) { + return !this._filter(path); + } // @returns `Boolean` true if the `path` is NOT ignored - parseDateTimeOnly() { - if (this.state.buf.length < 4) { - if (isDigit(this.char)) { - return this.consume(); - } else if (this.char === CHAR_COLON) { - return this.goto(this.parseOnlyTimeHour); - } else { - throw this.error(new TomlError('Expected digit while parsing year part of a date')); - } - } else { - if (this.char === CHAR_HYPHEN) { - return this.goto(this.parseDateTime); - } else { - throw this.error(new TomlError('Expected hyphen (-) while parsing year part of date')); - } - } - } - parseNumberBaseOrDateTime() { - if (this.char === CHAR_b) { - this.consume(); - return this.call(this.parseNoUnder, this.parseIntegerBin); - } else if (this.char === CHAR_o) { - this.consume(); - return this.call(this.parseNoUnder, this.parseIntegerOct); - } else if (this.char === CHAR_x) { - this.consume(); - return this.call(this.parseNoUnder, this.parseIntegerHex); - } else if (this.char === CHAR_PERIOD) { - return this.goto(this.parseNumberInteger); - } else if (isDigit(this.char)) { - return this.goto(this.parseDateTimeOnly); - } else { - return this.returnNow(Integer(this.state.buf)); - } + _filter(path, slices) { + if (!path) { + return false; } - parseIntegerHex() { - if (isHexit(this.char)) { - this.consume(); - } else if (this.char === CHAR_LOWBAR) { - return this.call(this.parseNoUnder); - } else { - const result = Integer(this.state.buf); - /* istanbul ignore if */ - - if (result.isNaN()) { - throw this.error(new TomlError('Invalid number')); - } else { - return this.returnNow(result); - } - } + if (path in this._cache) { + return this._cache[path]; } - parseIntegerOct() { - if (isOctit(this.char)) { - this.consume(); - } else if (this.char === CHAR_LOWBAR) { - return this.call(this.parseNoUnder); - } else { - const result = Integer(this.state.buf); - /* istanbul ignore if */ - - if (result.isNaN()) { - throw this.error(new TomlError('Invalid number')); - } else { - return this.returnNow(result); - } - } + if (!slices) { + // path/to/a.js + // ['path', 'to', 'a.js'] + slices = path.split(SLASH); } - parseIntegerBin() { - if (isBit(this.char)) { - this.consume(); - } else if (this.char === CHAR_LOWBAR) { - return this.call(this.parseNoUnder); - } else { - const result = Integer(this.state.buf); - /* istanbul ignore if */ + slices.pop(); + return this._cache[path] = slices.length // > It is not possible to re-include a file if a parent directory of + // > that file is excluded. + // If the path contains a parent directory, check the parent first + ? this._filter(slices.join(SLASH) + SLASH, slices) && this._test(path) // Or only test the path + : this._test(path); + } // @returns {Boolean} true if a file is NOT ignored - if (result.isNaN()) { - throw this.error(new TomlError('Invalid number')); - } else { - return this.returnNow(result); - } - } - } - /* DATETIME */ + _test(path) { + // Explicitly define variable type by setting matched to `0` + let matched = 0; - parseDateTime() { - // we enter here having just consumed the year and about to consume the hyphen - if (this.state.buf.length < 4) { - throw this.error(new TomlError('Years less than 1000 must be zero padded to four characters')); + this._rules.forEach(rule => { + // if matched = true, then we only test negative rules + // if matched = false, then we test non-negative rules + if (!(matched ^ rule.negative)) { + matched = rule.negative ^ rule.regex.test(path); } + }); - this.state.result = this.state.buf; - this.state.buf = ''; - return this.next(this.parseDateMonth); - } - - parseDateMonth() { - if (this.char === CHAR_HYPHEN) { - if (this.state.buf.length < 2) { - throw this.error(new TomlError('Months less than 10 must be zero padded to two characters')); - } - - this.state.result += '-' + this.state.buf; - this.state.buf = ''; - return this.next(this.parseDateDay); - } else if (isDigit(this.char)) { - this.consume(); - } else { - throw this.error(new TomlError('Incomplete datetime')); - } - } + return !matched; + } - parseDateDay() { - if (this.char === CHAR_T || this.char === CHAR_SP) { - if (this.state.buf.length < 2) { - throw this.error(new TomlError('Days less than 10 must be zero padded to two characters')); - } +} // Windows +// -------------------------------------------------------------- - this.state.result += '-' + this.state.buf; - this.state.buf = ''; - return this.next(this.parseStartTimeHour); - } else if (this.atEndOfWord()) { - return this.return(createDate(this.state.result + '-' + this.state.buf)); - } else if (isDigit(this.char)) { - this.consume(); - } else { - throw this.error(new TomlError('Incomplete datetime')); - } - } +/* istanbul ignore if */ - parseStartTimeHour() { - if (this.atEndOfWord()) { - return this.returnNow(createDate(this.state.result)); - } else { - return this.goto(this.parseTimeHour); - } - } - parseTimeHour() { - if (this.char === CHAR_COLON) { - if (this.state.buf.length < 2) { - throw this.error(new TomlError('Hours less than 10 must be zero padded to two characters')); - } +if ( // Detect `process` so that it can run in browsers. +typeof process !== 'undefined' && (process.env && process.env.IGNORE_TEST_WIN32 || process.platform === 'win32')) { + const filter = IgnoreBase.prototype._filter; + /* eslint no-control-regex: "off" */ - this.state.result += 'T' + this.state.buf; - this.state.buf = ''; - return this.next(this.parseTimeMin); - } else if (isDigit(this.char)) { - this.consume(); - } else { - throw this.error(new TomlError('Incomplete datetime')); - } - } + const make_posix = str => /^\\\\\?\\/.test(str) || /[^\x00-\x80]+/.test(str) ? str : str.replace(/\\/g, '/'); - parseTimeMin() { - if (this.state.buf.length < 2 && isDigit(this.char)) { - this.consume(); - } else if (this.state.buf.length === 2 && this.char === CHAR_COLON) { - this.state.result += ':' + this.state.buf; - this.state.buf = ''; - return this.next(this.parseTimeSec); - } else { - throw this.error(new TomlError('Incomplete datetime')); - } - } + IgnoreBase.prototype._filter = function filterWin32(path, slices) { + path = make_posix(path); + return filter.call(this, path, slices); + }; +} - parseTimeSec() { - if (isDigit(this.char)) { - this.consume(); +var ignore = options => new IgnoreBase(options); - if (this.state.buf.length === 2) { - this.state.result += ':' + this.state.buf; - this.state.buf = ''; - return this.next(this.parseTimeZoneOrFraction); - } - } else { - throw this.error(new TomlError('Incomplete datetime')); - } - } +/** + * @param {string} filename + * @returns {Promise} + */ - parseOnlyTimeHour() { - /* istanbul ignore else */ - if (this.char === CHAR_COLON) { - if (this.state.buf.length < 2) { - throw this.error(new TomlError('Hours less than 10 must be zero padded to two characters')); - } - this.state.result = this.state.buf; - this.state.buf = ''; - return this.next(this.parseOnlyTimeMin); +function getFileContentOrNull(filename) { + return new Promise((resolve, reject) => { + fs__default['default'].readFile(filename, "utf8", (error, data) => { + if (error && error.code !== "ENOENT") { + reject(createError(filename, error)); } else { - throw this.error(new TomlError('Incomplete time')); + resolve(error ? null : data); } - } + }); + }); +} +/** + * @param {string} filename + * @returns {null | string} + */ - parseOnlyTimeMin() { - if (this.state.buf.length < 2 && isDigit(this.char)) { - this.consume(); - } else if (this.state.buf.length === 2 && this.char === CHAR_COLON) { - this.state.result += ':' + this.state.buf; - this.state.buf = ''; - return this.next(this.parseOnlyTimeSec); - } else { - throw this.error(new TomlError('Incomplete time')); - } + +getFileContentOrNull.sync = function (filename) { + try { + return fs__default['default'].readFileSync(filename, "utf8"); + } catch (error) { + if (error && error.code === "ENOENT") { + return null; } - parseOnlyTimeSec() { - if (isDigit(this.char)) { - this.consume(); + throw createError(filename, error); + } +}; - if (this.state.buf.length === 2) { - return this.next(this.parseOnlyTimeFractionMaybe); - } - } else { - throw this.error(new TomlError('Incomplete time')); - } - } +function createError(filename, error) { + return new Error(`Unable to read ${filename}: ${error.message}`); +} - parseOnlyTimeFractionMaybe() { - this.state.result += ':' + this.state.buf; +var getFileContentOrNull_1 = getFileContentOrNull; - if (this.char === CHAR_PERIOD) { - this.state.buf = ''; - this.next(this.parseOnlyTimeFraction); - } else { - return this.return(createTime(this.state.result)); - } - } +/** + * @param {string?} ignorePath + * @param {boolean?} withNodeModules + */ - parseOnlyTimeFraction() { - if (isDigit(this.char)) { - this.consume(); - } else if (this.atEndOfWord()) { - if (this.state.buf.length === 0) throw this.error(new TomlError('Expected digit in milliseconds')); - return this.returnNow(createTime(this.state.result + '.' + this.state.buf)); - } else { - throw this.error(new TomlError('Unexpected character in datetime, expected period (.), minus (-), plus (+) or Z')); - } - } - parseTimeZoneOrFraction() { - if (this.char === CHAR_PERIOD) { - this.consume(); - this.next(this.parseDateTimeFraction); - } else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) { - this.consume(); - this.next(this.parseTimeZoneHour); - } else if (this.char === CHAR_Z) { - this.consume(); - return this.return(createDatetime(this.state.result + this.state.buf)); - } else if (this.atEndOfWord()) { - return this.returnNow(createDatetimeFloat(this.state.result + this.state.buf)); - } else { - throw this.error(new TomlError('Unexpected character in datetime, expected period (.), minus (-), plus (+) or Z')); - } - } +async function createIgnorer(ignorePath, withNodeModules) { + const ignoreContent = ignorePath ? await getFileContentOrNull_1(path__default['default'].resolve(ignorePath)) : null; + return _createIgnorer(ignoreContent, withNodeModules); +} +/** + * @param {string?} ignorePath + * @param {boolean?} withNodeModules + */ - parseDateTimeFraction() { - if (isDigit(this.char)) { - this.consume(); - } else if (this.state.buf.length === 1) { - throw this.error(new TomlError('Expected digit in milliseconds')); - } else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) { - this.consume(); - this.next(this.parseTimeZoneHour); - } else if (this.char === CHAR_Z) { - this.consume(); - return this.return(createDatetime(this.state.result + this.state.buf)); - } else if (this.atEndOfWord()) { - return this.returnNow(createDatetimeFloat(this.state.result + this.state.buf)); - } else { - throw this.error(new TomlError('Unexpected character in datetime, expected period (.), minus (-), plus (+) or Z')); - } - } - parseTimeZoneHour() { - if (isDigit(this.char)) { - this.consume(); // FIXME: No more regexps +createIgnorer.sync = function (ignorePath, withNodeModules) { + const ignoreContent = !ignorePath ? null : getFileContentOrNull_1.sync(path__default['default'].resolve(ignorePath)); + return _createIgnorer(ignoreContent, withNodeModules); +}; +/** + * @param {null | string} ignoreContent + * @param {boolean?} withNodeModules + */ - if (/\d\d$/.test(this.state.buf)) return this.next(this.parseTimeZoneSep); - } else { - throw this.error(new TomlError('Unexpected character in datetime, expected digit')); - } - } - parseTimeZoneSep() { - if (this.char === CHAR_COLON) { - this.consume(); - this.next(this.parseTimeZoneMin); - } else { - throw this.error(new TomlError('Unexpected character in datetime, expected colon')); - } - } +function _createIgnorer(ignoreContent, withNodeModules) { + const ignorer = ignore().add(ignoreContent || ""); - parseTimeZoneMin() { - if (isDigit(this.char)) { - this.consume(); - if (/\d\d$/.test(this.state.buf)) return this.return(createDatetime(this.state.result + this.state.buf)); - } else { - throw this.error(new TomlError('Unexpected character in datetime, expected digit')); - } - } - /* BOOLEAN */ + if (!withNodeModules) { + ignorer.add("node_modules"); + } + return ignorer; +} - parseBoolean() { - /* istanbul ignore else */ - if (this.char === CHAR_t) { - this.consume(); - return this.next(this.parseTrue_r); - } else if (this.char === CHAR_f) { - this.consume(); - return this.next(this.parseFalse_a); - } - } +var createIgnorer_1 = createIgnorer; - parseTrue_r() { - if (this.char === CHAR_r) { - this.consume(); - return this.next(this.parseTrue_u); - } else { - throw this.error(new TomlError('Invalid boolean, expected true or false')); - } - } +/** + * @typedef {{ ignorePath?: string, withNodeModules?: boolean, plugins: object }} FileInfoOptions + * @typedef {{ ignored: boolean, inferredParser: string | null }} FileInfoResult + */ - parseTrue_u() { - if (this.char === CHAR_u) { - this.consume(); - return this.next(this.parseTrue_e); - } else { - throw this.error(new TomlError('Invalid boolean, expected true or false')); - } - } +/** + * @param {string} filePath + * @param {FileInfoOptions} opts + * @returns {Promise} + * + * Please note that prettier.getFileInfo() expects opts.plugins to be an array of paths, + * not an object. A transformation from this array to an object is automatically done + * internally by the method wrapper. See withPlugins() in index.js. + */ - parseTrue_e() { - if (this.char === CHAR_e) { - return this.return(true); - } else { - throw this.error(new TomlError('Invalid boolean, expected true or false')); - } - } - parseFalse_a() { - if (this.char === CHAR_a) { - this.consume(); - return this.next(this.parseFalse_l); - } else { - throw this.error(new TomlError('Invalid boolean, expected true or false')); - } - } +async function getFileInfo(filePath, opts) { + if (typeof filePath !== "string") { + throw new TypeError(`expect \`filePath\` to be a string, got \`${typeof filePath}\``); + } - parseFalse_l() { - if (this.char === CHAR_l) { - this.consume(); - return this.next(this.parseFalse_s); - } else { - throw this.error(new TomlError('Invalid boolean, expected true or false')); - } - } + const ignorer = await createIgnorer_1(opts.ignorePath, opts.withNodeModules); + return _getFileInfo({ + ignorer, + filePath, + plugins: opts.plugins, + resolveConfig: opts.resolveConfig, + ignorePath: opts.ignorePath, + sync: false + }); +} +/** + * @param {string} filePath + * @param {FileInfoOptions} opts + * @returns {FileInfoResult} + */ - parseFalse_s() { - if (this.char === CHAR_s) { - this.consume(); - return this.next(this.parseFalse_e); - } else { - throw this.error(new TomlError('Invalid boolean, expected true or false')); - } - } - parseFalse_e() { - if (this.char === CHAR_e) { - return this.return(false); - } else { - throw this.error(new TomlError('Invalid boolean, expected true or false')); - } - } - /* INLINE LISTS */ +getFileInfo.sync = function (filePath, opts) { + if (typeof filePath !== "string") { + throw new TypeError(`expect \`filePath\` to be a string, got \`${typeof filePath}\``); + } + const ignorer = createIgnorer_1.sync(opts.ignorePath, opts.withNodeModules); + return _getFileInfo({ + ignorer, + filePath, + plugins: opts.plugins, + resolveConfig: opts.resolveConfig, + ignorePath: opts.ignorePath, + sync: true + }); +}; - parseInlineList() { - if (this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M || this.char === CTRL_J) { - return null; - } else if (this.char === Parser.END) { - throw this.error(new TomlError('Unterminated inline array')); - } else if (this.char === CHAR_NUM) { - return this.call(this.parseComment); - } else if (this.char === CHAR_RSQB) { - return this.return(this.state.resultArr || InlineList()); - } else { - return this.callNow(this.parseValue, this.recordInlineListValue); - } - } +function getFileParser(resolvedConfig, filePath, plugins) { + if (resolvedConfig && resolvedConfig.parser) { + return resolvedConfig.parser; + } - recordInlineListValue(value) { - if (this.state.resultArr) { - const listType = this.state.resultArr[_contentType]; - const valueType = tomlType(value); + const inferredParser = options$1.inferParser(filePath, plugins); - if (listType !== valueType) { - throw this.error(new TomlError(`Inline lists must be a single type, not a mix of ${listType} and ${valueType}`)); - } - } else { - this.state.resultArr = InlineList(tomlType(value)); - } + if (inferredParser) { + return inferredParser; + } - if (isFloat(value) || isInteger(value)) { - // unbox now that we've verified they're ok - this.state.resultArr.push(value.valueOf()); - } else { - this.state.resultArr.push(value); - } + return null; +} - return this.goto(this.parseInlineListNext); - } +function _getFileInfo({ + ignorer, + filePath, + plugins, + resolveConfig = false, + ignorePath, + sync = false +}) { + const normalizedFilePath = normalizeFilePath(filePath, ignorePath); + const fileInfo = { + ignored: ignorer.ignores(normalizedFilePath), + inferredParser: null + }; - parseInlineListNext() { - if (this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M || this.char === CTRL_J) { - return null; - } else if (this.char === CHAR_NUM) { - return this.call(this.parseComment); - } else if (this.char === CHAR_COMMA) { - return this.next(this.parseInlineList); - } else if (this.char === CHAR_RSQB) { - return this.goto(this.parseInlineList); - } else { - throw this.error(new TomlError('Invalid character, expected whitespace, comma (,) or close bracket (])')); - } - } - /* INLINE TABLE */ + if (fileInfo.ignored) { + return fileInfo; + } + let resolvedConfig; - parseInlineTable() { - if (this.char === CHAR_SP || this.char === CTRL_I) { - return null; - } else if (this.char === Parser.END || this.char === CHAR_NUM || this.char === CTRL_J || this.char === CTRL_M) { - throw this.error(new TomlError('Unterminated inline array')); - } else if (this.char === CHAR_RCUB) { - return this.return(this.state.resultTable || InlineTable()); - } else { - if (!this.state.resultTable) this.state.resultTable = InlineTable(); - return this.callNow(this.parseAssign, this.recordInlineTableValue); - } + if (resolveConfig) { + if (sync) { + resolvedConfig = resolveConfig_1.resolveConfig.sync(filePath); + } else { + return resolveConfig_1.resolveConfig(filePath).then(resolvedConfig => { + fileInfo.inferredParser = getFileParser(resolvedConfig, filePath, plugins); + return fileInfo; + }); } + } - recordInlineTableValue(kv) { - let target = this.state.resultTable; - let finalKey = kv.key.pop(); + fileInfo.inferredParser = getFileParser(resolvedConfig, filePath, plugins); + return fileInfo; +} - for (let kw of kv.key) { - if (hasKey(target, kw) && (!isTable(target[kw]) || target[kw][_declared])) { - throw this.error(new TomlError("Can't redefine existing key")); - } +function normalizeFilePath(filePath, ignorePath) { + return ignorePath ? path__default['default'].relative(path__default['default'].dirname(ignorePath), filePath) : filePath; +} - target = target[kw] = target[kw] || Table(); - } +var getFileInfo_1 = getFileInfo; - if (hasKey(target, finalKey)) { - throw this.error(new TomlError("Can't redefine existing key")); - } +const { + getMaxContinuousCount: getMaxContinuousCount$1, + getStringWidth: getStringWidth$2, + getAlignmentSize: getAlignmentSize$2, + getIndentSize: getIndentSize$1, + skip: skip$1, + skipWhitespace: skipWhitespace$1, + skipSpaces: skipSpaces$2, + skipNewline: skipNewline$2, + skipToLineEnd: skipToLineEnd$1, + skipEverythingButNewLine: skipEverythingButNewLine$1, + skipInlineComment: skipInlineComment$1, + skipTrailingComment: skipTrailingComment$1, + hasNewline: hasNewline$2, + hasNewlineInRange: hasNewlineInRange$1, + hasSpaces: hasSpaces$1, + isNextLineEmpty: isNextLineEmpty$1, + isNextLineEmptyAfterIndex: isNextLineEmptyAfterIndex$1, + isPreviousLineEmpty: isPreviousLineEmpty$2, + getNextNonSpaceNonCommentCharacterIndex: getNextNonSpaceNonCommentCharacterIndex$1, + makeString: makeString$1, + addLeadingComment: addLeadingComment$2, + addDanglingComment: addDanglingComment$2, + addTrailingComment: addTrailingComment$2 +} = util; +var utilShared = { + getMaxContinuousCount: getMaxContinuousCount$1, + getStringWidth: getStringWidth$2, + getAlignmentSize: getAlignmentSize$2, + getIndentSize: getIndentSize$1, + skip: skip$1, + skipWhitespace: skipWhitespace$1, + skipSpaces: skipSpaces$2, + skipNewline: skipNewline$2, + skipToLineEnd: skipToLineEnd$1, + skipEverythingButNewLine: skipEverythingButNewLine$1, + skipInlineComment: skipInlineComment$1, + skipTrailingComment: skipTrailingComment$1, + hasNewline: hasNewline$2, + hasNewlineInRange: hasNewlineInRange$1, + hasSpaces: hasSpaces$1, + isNextLineEmpty: isNextLineEmpty$1, + isNextLineEmptyAfterIndex: isNextLineEmptyAfterIndex$1, + isPreviousLineEmpty: isPreviousLineEmpty$2, + getNextNonSpaceNonCommentCharacterIndex: getNextNonSpaceNonCommentCharacterIndex$1, + makeString: makeString$1, + addLeadingComment: addLeadingComment$2, + addDanglingComment: addDanglingComment$2, + addTrailingComment: addTrailingComment$2 +}; - if (isInteger(kv.value) || isFloat(kv.value)) { - target[finalKey] = kv.value.valueOf(); - } else { - target[finalKey] = kv.value; - } +/** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ +function listCacheClear() { + this.__data__ = []; + this.size = 0; +} - return this.goto(this.parseInlineTableNext); - } +var _listCacheClear = listCacheClear; - parseInlineTableNext() { - if (this.char === CHAR_SP || this.char === CTRL_I) { - return null; - } else if (this.char === Parser.END || this.char === CHAR_NUM || this.char === CTRL_J || this.char === CTRL_M) { - throw this.error(new TomlError('Unterminated inline array')); - } else if (this.char === CHAR_COMMA) { - return this.next(this.parseInlineTable); - } else if (this.char === CHAR_RCUB) { - return this.goto(this.parseInlineTable); - } else { - throw this.error(new TomlError('Invalid character, expected whitespace, comma (,) or close bracket (])')); - } - } +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || value !== value && other !== other; +} + +var eq_1 = eq; + +/** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function assocIndexOf(array, key) { + var length = array.length; + + while (length--) { + if (eq_1(array[length][0], key)) { + return length; + } } - return TOMLParser; + return -1; } -tomlParser.makeParserClass = makeParserClass_1; -tomlParser.TomlError = TomlError_1; -var parsePrettyError = prettyError; +var _assocIndexOf = assocIndexOf; -function prettyError(err, buf) { - /* istanbul ignore if */ - if (err.pos == null || err.line == null) return err; - let msg = err.message; - msg += ` at row ${err.line + 1}, col ${err.col + 1}, pos ${err.pos}:\n`; - /* istanbul ignore else */ +/** Used for built-in method references. */ - if (buf && buf.split) { - const lines = buf.split(/\n/); - const lineNumWidth = String(Math.min(lines.length, err.line + 3)).length; - let linePadding = ' '; +var arrayProto = Array.prototype; +/** Built-in value references. */ - while (linePadding.length < lineNumWidth) linePadding += ' '; +var splice = arrayProto.splice; +/** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ - for (let ii = Math.max(0, err.line - 1); ii < Math.min(lines.length, err.line + 2); ++ii) { - let lineNum = String(ii + 1); - if (lineNum.length < lineNumWidth) lineNum = ' ' + lineNum; +function listCacheDelete(key) { + var data = this.__data__, + index = _assocIndexOf(data, key); - if (err.line === ii) { - msg += lineNum + '> ' + lines[ii] + '\n'; - msg += linePadding + ' '; + if (index < 0) { + return false; + } - for (let hh = 0; hh < err.col; ++hh) { - msg += ' '; - } + var lastIndex = data.length - 1; - msg += '^\n'; - } else { - msg += lineNum + ': ' + lines[ii] + '\n'; - } - } + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); } - err.message = msg + '\n'; - return err; + --this.size; + return true; } -var parseString_1 = parseString; - -function parseString(str) { - if (global.Buffer && global.Buffer.isBuffer(str)) { - str = str.toString('utf8'); - } +var _listCacheDelete = listCacheDelete; - const parser = new tomlParser(); +/** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ - try { - parser.parse(str); - return parser.finish(); - } catch (err) { - throw parsePrettyError(err, str); - } +function listCacheGet(key) { + var data = this.__data__, + index = _assocIndexOf(data, key); + return index < 0 ? undefined : data[index][1]; } -var loadToml = function (filePath, content) { - try { - return parseString_1(content); - } catch (error) { - error.message = `TOML Error in ${filePath}:\n${error.message}`; - throw error; - } -}; +var _listCacheGet = listCacheGet; -var caller = function () { - // see https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi - var origPrepareStackTrace = Error.prepareStackTrace; +/** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ - Error.prepareStackTrace = function (_, stack) { - return stack; - }; +function listCacheHas(key) { + return _assocIndexOf(this.__data__, key) > -1; +} - var stack = new Error().stack; - Error.prepareStackTrace = origPrepareStackTrace; - return stack[2].getFileName(); -}; +var _listCacheHas = listCacheHas; -var pathParse = createCommonjsModule(function (module) { +/** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ - var isWindows = process.platform === 'win32'; // Regex to split a windows path into three parts: [*, device, slash, - // tail] windows-only +function listCacheSet(key, value) { + var data = this.__data__, + index = _assocIndexOf(data, key); - var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; // Regex to split the tail part of the above into [*, dir, basename, ext] + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } - var splitTailRe = /^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/; - var win32 = {}; // Function to split a filename into [root, dir, basename, ext] + return this; +} - function win32SplitPath(filename) { - // Separate device+slash from tail - var result = splitDeviceRe.exec(filename), - device = (result[1] || '') + (result[2] || ''), - tail = result[3] || ''; // Split the tail into dir, basename and extension +var _listCacheSet = listCacheSet; - var result2 = splitTailRe.exec(tail), - dir = result2[1], - basename = result2[2], - ext = result2[3]; - return [device, dir, basename, ext]; +/** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + +function ListCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + this.clear(); + + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); } +} // Add methods to `ListCache`. - win32.parse = function (pathString) { - if (typeof pathString !== 'string') { - throw new TypeError("Parameter 'pathString' must be a string, not " + typeof pathString); - } - var allParts = win32SplitPath(pathString); +ListCache.prototype.clear = _listCacheClear; +ListCache.prototype['delete'] = _listCacheDelete; +ListCache.prototype.get = _listCacheGet; +ListCache.prototype.has = _listCacheHas; +ListCache.prototype.set = _listCacheSet; +var _ListCache = ListCache; - if (!allParts || allParts.length !== 4) { - throw new TypeError("Invalid path '" + pathString + "'"); - } +/** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ - return { - root: allParts[0], - dir: allParts[0] + allParts[1].slice(0, -1), - base: allParts[2], - ext: allParts[3], - name: allParts[2].slice(0, allParts[2].length - allParts[3].length) - }; - }; // Split a filename into [root, dir, basename, ext], unix version - // 'root' is just a slash, or nothing. +function stackClear() { + this.__data__ = new _ListCache(); + this.size = 0; +} +var _stackClear = stackClear; - var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; - var posix = {}; +/** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function stackDelete(key) { + var data = this.__data__, + result = data['delete'](key); + this.size = data.size; + return result; +} - function posixSplitPath(filename) { - return splitPathRe.exec(filename).slice(1); - } +var _stackDelete = stackDelete; - posix.parse = function (pathString) { - if (typeof pathString !== 'string') { - throw new TypeError("Parameter 'pathString' must be a string, not " + typeof pathString); - } +/** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function stackGet(key) { + return this.__data__.get(key); +} - var allParts = posixSplitPath(pathString); +var _stackGet = stackGet; - if (!allParts || allParts.length !== 4) { - throw new TypeError("Invalid path '" + pathString + "'"); - } +/** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function stackHas(key) { + return this.__data__.has(key); +} - allParts[1] = allParts[1] || ''; - allParts[2] = allParts[2] || ''; - allParts[3] = allParts[3] || ''; - return { - root: allParts[0], - dir: allParts[0] + allParts[1].slice(0, -1), - base: allParts[2], - ext: allParts[3], - name: allParts[2].slice(0, allParts[2].length - allParts[3].length) - }; - }; +var _stackHas = stackHas; - if (isWindows) module.exports = win32.parse;else - /* posix */ - module.exports = posix.parse; - module.exports.posix = posix.parse; - module.exports.win32 = win32.parse; -}); -var pathParse_1 = pathParse.posix; -var pathParse_2 = pathParse.win32; +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); +} -var parse$2 = path$2.parse || pathParse; +var isObject_1 = isObject; -var getNodeModulesDirs = function getNodeModulesDirs(absoluteStart, modules) { - var prefix = '/'; +/** `Object#toString` result references. */ - if (/^([A-Za-z]:)/.test(absoluteStart)) { - prefix = ''; - } else if (/^\\\\/.test(absoluteStart)) { - prefix = '\\\\'; - } +var asyncTag = '[object AsyncFunction]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + proxyTag = '[object Proxy]'; +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ - var paths = [absoluteStart]; - var parsed = parse$2(absoluteStart); +function isFunction(value) { + if (!isObject_1(value)) { + return false; + } // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. - while (parsed.dir !== paths[paths.length - 1]) { - paths.push(parsed.dir); - parsed = parse$2(parsed.dir); - } - return paths.reduce(function (dirs, aPath) { - return dirs.concat(modules.map(function (moduleDir) { - return path$2.resolve(prefix, aPath, moduleDir); - })); - }, []); -}; + var tag = _baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; +} -var nodeModulesPaths = function nodeModulesPaths(start, opts, request) { - var modules = opts && opts.moduleDirectory ? [].concat(opts.moduleDirectory) : ['node_modules']; +var isFunction_1 = isFunction; - if (opts && typeof opts.paths === 'function') { - return opts.paths(request, start, function () { - return getNodeModulesDirs(start, modules); - }, opts); - } +/** Used to detect overreaching core-js shims. */ - var dirs = getNodeModulesDirs(start, modules); - return opts && opts.paths ? dirs.concat(opts.paths) : dirs; -}; +var coreJsData = _root['__core-js_shared__']; +var _coreJsData = coreJsData; -var normalizeOptions$2 = function (x, opts) { - /** - * This file is purposefully a passthrough. It's expected that third-party - * environments will override it at runtime in order to inject special logic - * into `resolve` (by manipulating the options). One such example is the PnP - * code path in Yarn. - */ - return opts || {}; -}; +/** Used to detect methods masquerading as native. */ -var assert = true; -var async_hooks = ">= 8"; -var buffer_ieee754 = "< 0.9.7"; -var buffer = true; -var child_process = true; -var cluster = true; -var console$1 = true; -var constants$1 = true; -var crypto = true; -var _debug_agent = ">= 1 && < 8"; -var _debugger = "< 8"; -var dgram = true; -var dns = true; -var domain = true; -var events = true; -var freelist = "< 6"; -var fs = true; -var _http_agent = ">= 0.11.1"; -var _http_client = ">= 0.11.1"; -var _http_common = ">= 0.11.1"; -var _http_incoming = ">= 0.11.1"; -var _http_outgoing = ">= 0.11.1"; -var _http_server = ">= 0.11.1"; -var http = true; -var http2 = ">= 8.8"; -var https = true; -var inspector = ">= 8.0.0"; -var _linklist = "< 8"; -var module$1 = true; -var net = true; -var os = true; -var path$1 = true; -var perf_hooks = ">= 8.5"; -var process$1 = ">= 1"; -var punycode = true; -var querystring = true; -var readline = true; -var repl = true; -var smalloc = ">= 0.11.5 && < 3"; -var _stream_duplex = ">= 0.9.4"; -var _stream_transform = ">= 0.9.4"; -var _stream_wrap = ">= 1.4.1"; -var _stream_passthrough = ">= 0.9.4"; -var _stream_readable = ">= 0.9.4"; -var _stream_writable = ">= 0.9.4"; -var stream = true; -var string_decoder = true; -var sys = true; -var timers = true; -var _tls_common = ">= 0.11.13"; -var _tls_legacy = ">= 0.11.3 && < 10"; -var _tls_wrap = ">= 0.11.3"; -var tls = true; -var trace_events = ">= 10"; -var tty = true; -var url = true; -var util$2 = true; -var v8 = ">= 1"; -var vm = true; -var wasi = ">= 13.4 && < 13.5"; -var worker_threads = ">= 11.7"; -var zlib = true; -var core$1 = { - assert: assert, - async_hooks: async_hooks, - buffer_ieee754: buffer_ieee754, - buffer: buffer, - child_process: child_process, - cluster: cluster, - console: console$1, - constants: constants$1, - crypto: crypto, - _debug_agent: _debug_agent, - _debugger: _debugger, - dgram: dgram, - dns: dns, - domain: domain, - events: events, - freelist: freelist, - fs: fs, - "fs/promises": [ - ">= 10 && < 10.1", - ">= 14" -], - _http_agent: _http_agent, - _http_client: _http_client, - _http_common: _http_common, - _http_incoming: _http_incoming, - _http_outgoing: _http_outgoing, - _http_server: _http_server, - http: http, - http2: http2, - https: https, - inspector: inspector, - _linklist: _linklist, - module: module$1, - net: net, - "node-inspect/lib/_inspect": ">= 7.6.0 && < 12", - "node-inspect/lib/internal/inspect_client": ">= 7.6.0 && < 12", - "node-inspect/lib/internal/inspect_repl": ">= 7.6.0 && < 12", - os: os, - path: path$1, - perf_hooks: perf_hooks, - process: process$1, - punycode: punycode, - querystring: querystring, - readline: readline, - repl: repl, - smalloc: smalloc, - _stream_duplex: _stream_duplex, - _stream_transform: _stream_transform, - _stream_wrap: _stream_wrap, - _stream_passthrough: _stream_passthrough, - _stream_readable: _stream_readable, - _stream_writable: _stream_writable, - stream: stream, - string_decoder: string_decoder, - sys: sys, - timers: timers, - _tls_common: _tls_common, - _tls_legacy: _tls_legacy, - _tls_wrap: _tls_wrap, - tls: tls, - trace_events: trace_events, - tty: tty, - url: url, - util: util$2, - "v8/tools/arguments": ">= 10 && < 12", - "v8/tools/codemap": [ - ">= 4.4.0 && < 5", - ">= 5.2.0 && < 12" -], - "v8/tools/consarray": [ - ">= 4.4.0 && < 5", - ">= 5.2.0 && < 12" -], - "v8/tools/csvparser": [ - ">= 4.4.0 && < 5", - ">= 5.2.0 && < 12" -], - "v8/tools/logreader": [ - ">= 4.4.0 && < 5", - ">= 5.2.0 && < 12" -], - "v8/tools/profile_view": [ - ">= 4.4.0 && < 5", - ">= 5.2.0 && < 12" -], - "v8/tools/splaytree": [ - ">= 4.4.0 && < 5", - ">= 5.2.0 && < 12" -], - v8: v8, - vm: vm, - wasi: wasi, - worker_threads: worker_threads, - zlib: zlib -}; +var maskSrcKey = function () { + var uid = /[^.]+$/.exec(_coreJsData && _coreJsData.keys && _coreJsData.keys.IE_PROTO || ''); + return uid ? 'Symbol(src)_1.' + uid : ''; +}(); +/** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ -var core$2 = /*#__PURE__*/Object.freeze({ - __proto__: null, - assert: assert, - async_hooks: async_hooks, - buffer_ieee754: buffer_ieee754, - buffer: buffer, - child_process: child_process, - cluster: cluster, - console: console$1, - constants: constants$1, - crypto: crypto, - _debug_agent: _debug_agent, - _debugger: _debugger, - dgram: dgram, - dns: dns, - domain: domain, - events: events, - freelist: freelist, - fs: fs, - _http_agent: _http_agent, - _http_client: _http_client, - _http_common: _http_common, - _http_incoming: _http_incoming, - _http_outgoing: _http_outgoing, - _http_server: _http_server, - http: http, - http2: http2, - https: https, - inspector: inspector, - _linklist: _linklist, - module: module$1, - net: net, - os: os, - path: path$1, - perf_hooks: perf_hooks, - process: process$1, - punycode: punycode, - querystring: querystring, - readline: readline, - repl: repl, - smalloc: smalloc, - _stream_duplex: _stream_duplex, - _stream_transform: _stream_transform, - _stream_wrap: _stream_wrap, - _stream_passthrough: _stream_passthrough, - _stream_readable: _stream_readable, - _stream_writable: _stream_writable, - stream: stream, - string_decoder: string_decoder, - sys: sys, - timers: timers, - _tls_common: _tls_common, - _tls_legacy: _tls_legacy, - _tls_wrap: _tls_wrap, - tls: tls, - trace_events: trace_events, - tty: tty, - url: url, - util: util$2, - v8: v8, - vm: vm, - wasi: wasi, - worker_threads: worker_threads, - zlib: zlib, - 'default': core$1 -}); -var data = getCjsExportFromNamespace(core$2); +function isMasked(func) { + return !!maskSrcKey && maskSrcKey in func; +} -var current = process.versions && process.versions.node && process.versions.node.split('.') || []; +var _isMasked = isMasked; -function specifierIncluded(specifier) { - var parts = specifier.split(' '); - var op = parts.length > 1 ? parts[0] : '='; - var versionParts = (parts.length > 1 ? parts[1] : parts[0]).split('.'); +/** Used for built-in method references. */ +var funcProto = Function.prototype; +/** Used to resolve the decompiled source of functions. */ - for (var i = 0; i < 3; ++i) { - var cur = Number(current[i] || 0); - var ver = Number(versionParts[i] || 0); +var funcToString = funcProto.toString; +/** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ - if (cur === ver) { - continue; // eslint-disable-line no-restricted-syntax, no-continue - } +function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} - if (op === '<') { - return cur < ver; - } else if (op === '>=') { - return cur >= ver; - } else { - return false; - } + try { + return func + ''; + } catch (e) {} } - return op === '>='; + return ''; } -function matchesRange(range) { - var specifiers = range.split(/ ?&& ?/); +var _toSource = toSource; - if (specifiers.length === 0) { - return false; - } +/** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ - for (var i = 0; i < specifiers.length; ++i) { - if (!specifierIncluded(specifiers[i])) { - return false; - } - } +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; +/** Used to detect host constructors (Safari). */ - return true; -} +var reIsHostCtor = /^\[object .+?Constructor\]$/; +/** Used for built-in method references. */ -function versionIncluded(specifierValue) { - if (typeof specifierValue === 'boolean') { - return specifierValue; - } +var funcProto$1 = Function.prototype, + objectProto$3 = Object.prototype; +/** Used to resolve the decompiled source of functions. */ - if (specifierValue && typeof specifierValue === 'object') { - for (var i = 0; i < specifierValue.length; ++i) { - if (matchesRange(specifierValue[i])) { - return true; - } - } +var funcToString$1 = funcProto$1.toString; +/** Used to check objects for own properties. */ + +var hasOwnProperty$4 = objectProto$3.hasOwnProperty; +/** Used to detect if a method is native. */ + +var reIsNative = RegExp('^' + funcToString$1.call(hasOwnProperty$4).replace(reRegExpChar, '\\$&').replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'); +/** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ +function baseIsNative(value) { + if (!isObject_1(value) || _isMasked(value)) { return false; } - return matchesRange(specifierValue); + var pattern = isFunction_1(value) ? reIsNative : reIsHostCtor; + return pattern.test(_toSource(value)); } -var core$3 = {}; +var _baseIsNative = baseIsNative; -for (var mod in data) { - // eslint-disable-line no-restricted-syntax - if (Object.prototype.hasOwnProperty.call(data, mod)) { - core$3[mod] = versionIncluded(data[mod]); - } +/** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ +function getValue(object, key) { + return object == null ? undefined : object[key]; } -var core_1 = core$3; +var _getValue = getValue; -var isCore = function isCore(x) { - return Object.prototype.hasOwnProperty.call(core_1, x); -}; +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ -var realpath = fs$3.realpath && typeof fs$3.realpath.native === 'function' ? fs$3.realpath.native : fs$3.realpath; +function getNative(object, key) { + var value = _getValue(object, key); + return _baseIsNative(value) ? value : undefined; +} -var defaultIsFile = function isFile(file, cb) { - fs$3.stat(file, function (err, stat) { - if (!err) { - return cb(null, stat.isFile() || stat.isFIFO()); - } +var _getNative = getNative; - if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false); - return cb(err); - }); -}; +/* Built-in method references that are verified to be native. */ -var defaultIsDir = function isDirectory(dir, cb) { - fs$3.stat(dir, function (err, stat) { - if (!err) { - return cb(null, stat.isDirectory()); - } +var Map$1 = _getNative(_root, 'Map'); +var _Map = Map$1; - if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false); - return cb(err); - }); -}; +/* Built-in method references that are verified to be native. */ -var maybeUnwrapSymlink = function maybeUnwrapSymlink(x, opts, cb) { - if (opts && opts.preserveSymlinks === false) { - realpath(x, function (realPathErr, realPath) { - if (realPathErr && realPathErr.code !== 'ENOENT') cb(realPathErr);else cb(null, realPathErr ? x : realPath); - }); - } else { - cb(null, x); - } -}; +var nativeCreate = _getNative(Object, 'create'); +var _nativeCreate = nativeCreate; -var getPackageCandidates = function getPackageCandidates(x, start, opts) { - var dirs = nodeModulesPaths(start, opts, x); +/** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ - for (var i = 0; i < dirs.length; i++) { - dirs[i] = path$2.join(dirs[i], x); - } +function hashClear() { + this.__data__ = _nativeCreate ? _nativeCreate(null) : {}; + this.size = 0; +} - return dirs; -}; +var _hashClear = hashClear; -var async = function resolve(x, options, callback) { - var cb = callback; - var opts = options; +/** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; +} - if (typeof options === 'function') { - cb = opts; - opts = {}; - } +var _hashDelete = hashDelete; - if (typeof x !== 'string') { - var err = new TypeError('Path must be a string.'); - return process.nextTick(function () { - cb(err); - }); - } +/** Used to stand-in for `undefined` hash values. */ - opts = normalizeOptions$2(x, opts); - var isFile = opts.isFile || defaultIsFile; - var isDirectory = opts.isDirectory || defaultIsDir; - var readFile = opts.readFile || fs$3.readFile; - var packageIterator = opts.packageIterator; - var extensions = opts.extensions || ['.js']; - var basedir = opts.basedir || path$2.dirname(caller()); - var parent = opts.filename || basedir; - opts.paths = opts.paths || []; // ensure that `basedir` is an absolute path at this point, resolving against the process' current working directory +var HASH_UNDEFINED = '__lodash_hash_undefined__'; +/** Used for built-in method references. */ - var absoluteStart = path$2.resolve(basedir); - maybeUnwrapSymlink(absoluteStart, opts, function (err, realStart) { - if (err) cb(err);else init(realStart); - }); - var res; +var objectProto$4 = Object.prototype; +/** Used to check objects for own properties. */ - function init(basedir) { - if (/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/.test(x)) { - res = path$2.resolve(basedir, x); - if (x === '.' || x === '..' || x.slice(-1) === '/') res += '/'; +var hasOwnProperty$5 = objectProto$4.hasOwnProperty; +/** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ - if (/\/$/.test(x) && res === basedir) { - loadAsDirectory(res, opts.package, onfile); - } else loadAsFile(res, opts.package, onfile); - } else if (isCore(x)) { - return cb(null, x); - } else loadNodeModules(x, basedir, function (err, n, pkg) { - if (err) cb(err);else if (n) { - return maybeUnwrapSymlink(n, opts, function (err, realN) { - if (err) { - cb(err); - } else { - cb(null, realN, pkg); - } - }); - } else { - var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'"); - moduleError.code = 'MODULE_NOT_FOUND'; - cb(moduleError); - } - }); - } +function hashGet(key) { + var data = this.__data__; - function onfile(err, m, pkg) { - if (err) cb(err);else if (m) cb(null, m, pkg);else loadAsDirectory(res, function (err, d, pkg) { - if (err) cb(err);else if (d) { - maybeUnwrapSymlink(d, opts, function (err, realD) { - if (err) { - cb(err); - } else { - cb(null, realD, pkg); - } - }); - } else { - var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'"); - moduleError.code = 'MODULE_NOT_FOUND'; - cb(moduleError); - } - }); + if (_nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; } - function loadAsFile(x, thePackage, callback) { - var loadAsFilePackage = thePackage; - var cb = callback; + return hasOwnProperty$5.call(data, key) ? data[key] : undefined; +} - if (typeof loadAsFilePackage === 'function') { - cb = loadAsFilePackage; - loadAsFilePackage = undefined; - } +var _hashGet = hashGet; - var exts = [''].concat(extensions); - load(exts, x, loadAsFilePackage); +/** Used for built-in method references. */ - function load(exts, x, loadPackage) { - if (exts.length === 0) return cb(null, undefined, loadPackage); - var file = x + exts[0]; - var pkg = loadPackage; - if (pkg) onpkg(null, pkg);else loadpkg(path$2.dirname(file), onpkg); +var objectProto$5 = Object.prototype; +/** Used to check objects for own properties. */ - function onpkg(err, pkg_, dir) { - pkg = pkg_; - if (err) return cb(err); +var hasOwnProperty$6 = objectProto$5.hasOwnProperty; +/** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ - if (dir && pkg && opts.pathFilter) { - var rfile = path$2.relative(dir, file); - var rel = rfile.slice(0, rfile.length - exts[0].length); - var r = opts.pathFilter(pkg, x, rel); - if (r) return load([''].concat(extensions.slice()), path$2.resolve(dir, r), pkg); - } +function hashHas(key) { + var data = this.__data__; + return _nativeCreate ? data[key] !== undefined : hasOwnProperty$6.call(data, key); +} - isFile(file, onex); - } +var _hashHas = hashHas; - function onex(err, ex) { - if (err) return cb(err); - if (ex) return cb(null, file, pkg); - load(exts.slice(1), x, pkg); - } - } - } +/** Used to stand-in for `undefined` hash values. */ - function loadpkg(dir, cb) { - if (dir === '' || dir === '/') return cb(null); +var HASH_UNDEFINED$1 = '__lodash_hash_undefined__'; +/** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ - if (process.platform === 'win32' && /^\w:[/\\]*$/.test(dir)) { - return cb(null); - } +function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = _nativeCreate && value === undefined ? HASH_UNDEFINED$1 : value; + return this; +} - if (/[/\\]node_modules[/\\]*$/.test(dir)) return cb(null); - maybeUnwrapSymlink(dir, opts, function (unwrapErr, pkgdir) { - if (unwrapErr) return loadpkg(path$2.dirname(dir), cb); - var pkgfile = path$2.join(pkgdir, 'package.json'); - isFile(pkgfile, function (err, ex) { - // on err, ex is false - if (!ex) return loadpkg(path$2.dirname(dir), cb); - readFile(pkgfile, function (err, body) { - if (err) cb(err); +var _hashSet = hashSet; - try { - var pkg = JSON.parse(body); - } catch (jsonErr) {} +/** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ - if (pkg && opts.packageFilter) { - pkg = opts.packageFilter(pkg, pkgfile); - } +function Hash(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + this.clear(); - cb(null, pkg, dir); - }); - }); - }); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); } +} // Add methods to `Hash`. - function loadAsDirectory(x, loadAsDirectoryPackage, callback) { - var cb = callback; - var fpkg = loadAsDirectoryPackage; - if (typeof fpkg === 'function') { - cb = fpkg; - fpkg = opts.package; - } +Hash.prototype.clear = _hashClear; +Hash.prototype['delete'] = _hashDelete; +Hash.prototype.get = _hashGet; +Hash.prototype.has = _hashHas; +Hash.prototype.set = _hashSet; +var _Hash = Hash; - maybeUnwrapSymlink(x, opts, function (unwrapErr, pkgdir) { - if (unwrapErr) return cb(unwrapErr); - var pkgfile = path$2.join(pkgdir, 'package.json'); - isFile(pkgfile, function (err, ex) { - if (err) return cb(err); - if (!ex) return loadAsFile(path$2.join(x, 'index'), fpkg, cb); - readFile(pkgfile, function (err, body) { - if (err) return cb(err); +/** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ - try { - var pkg = JSON.parse(body); - } catch (jsonErr) {} +function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new _Hash(), + 'map': new (_Map || _ListCache)(), + 'string': new _Hash() + }; +} - if (pkg && opts.packageFilter) { - pkg = opts.packageFilter(pkg, pkgfile); - } +var _mapCacheClear = mapCacheClear; - if (pkg && pkg.main) { - if (typeof pkg.main !== 'string') { - var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string'); - mainError.code = 'INVALID_PACKAGE_MAIN'; - return cb(mainError); - } +/** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ +function isKeyable(value) { + var type = typeof value; + return type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean' ? value !== '__proto__' : value === null; +} - if (pkg.main === '.' || pkg.main === './') { - pkg.main = 'index'; - } +var _isKeyable = isKeyable; - loadAsFile(path$2.resolve(x, pkg.main), pkg, function (err, m, pkg) { - if (err) return cb(err); - if (m) return cb(null, m, pkg); - if (!pkg) return loadAsFile(path$2.join(x, 'index'), pkg, cb); - var dir = path$2.resolve(x, pkg.main); - loadAsDirectory(dir, pkg, function (err, n, pkg) { - if (err) return cb(err); - if (n) return cb(null, n, pkg); - loadAsFile(path$2.join(x, 'index'), pkg, cb); - }); - }); - return; - } +/** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + +function getMapData(map, key) { + var data = map.__data__; + return _isKeyable(key) ? data[typeof key == 'string' ? 'string' : 'hash'] : data.map; +} + +var _getMapData = getMapData; + +/** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + +function mapCacheDelete(key) { + var result = _getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; +} + +var _mapCacheDelete = mapCacheDelete; + +/** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + +function mapCacheGet(key) { + return _getMapData(this, key).get(key); +} + +var _mapCacheGet = mapCacheGet; + +/** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + +function mapCacheHas(key) { + return _getMapData(this, key).has(key); +} + +var _mapCacheHas = mapCacheHas; + +/** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ - loadAsFile(path$2.join(x, '/index'), pkg, cb); - }); - }); - }); - } +function mapCacheSet(key, value) { + var data = _getMapData(this, key), + size = data.size; + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; +} - function processDirs(cb, dirs) { - if (dirs.length === 0) return cb(null, undefined); - var dir = dirs[0]; - isDirectory(path$2.dirname(dir), isdir); +var _mapCacheSet = mapCacheSet; - function isdir(err, isdir) { - if (err) return cb(err); - if (!isdir) return processDirs(cb, dirs.slice(1)); - loadAsFile(dir, opts.package, onfile); - } +/** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ - function onfile(err, m, pkg) { - if (err) return cb(err); - if (m) return cb(null, m, pkg); - loadAsDirectory(dir, opts.package, ondir); - } +function MapCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + this.clear(); - function ondir(err, n, pkg) { - if (err) return cb(err); - if (n) return cb(null, n, pkg); - processDirs(cb, dirs.slice(1)); - } + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); } +} // Add methods to `MapCache`. - function loadNodeModules(x, start, cb) { - var thunk = function () { - return getPackageCandidates(x, start, opts); - }; - - processDirs(cb, packageIterator ? packageIterator(x, start, thunk, opts) : thunk()); - } -}; -var realpath$1 = fs$3.realpathSync && typeof fs$3.realpathSync.native === 'function' ? fs$3.realpathSync.native : fs$3.realpathSync; +MapCache.prototype.clear = _mapCacheClear; +MapCache.prototype['delete'] = _mapCacheDelete; +MapCache.prototype.get = _mapCacheGet; +MapCache.prototype.has = _mapCacheHas; +MapCache.prototype.set = _mapCacheSet; +var _MapCache = MapCache; -var defaultIsFile$1 = function isFile(file) { - try { - var stat = fs$3.statSync(file); - } catch (e) { - if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false; - throw e; - } +/** Used as the size to enable large array optimizations. */ - return stat.isFile() || stat.isFIFO(); -}; +var LARGE_ARRAY_SIZE = 200; +/** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ -var defaultIsDir$1 = function isDirectory(dir) { - try { - var stat = fs$3.statSync(dir); - } catch (e) { - if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false; - throw e; - } +function stackSet(key, value) { + var data = this.__data__; - return stat.isDirectory(); -}; + if (data instanceof _ListCache) { + var pairs = data.__data__; -var maybeUnwrapSymlink$1 = function maybeUnwrapSymlink(x, opts) { - if (opts && opts.preserveSymlinks === false) { - try { - return realpath$1(x); - } catch (realPathErr) { - if (realPathErr.code !== 'ENOENT') { - throw realPathErr; - } + if (!_Map || pairs.length < LARGE_ARRAY_SIZE - 1) { + pairs.push([key, value]); + this.size = ++data.size; + return this; } + + data = this.__data__ = new _MapCache(pairs); } - return x; -}; + data.set(key, value); + this.size = data.size; + return this; +} -var getPackageCandidates$1 = function getPackageCandidates(x, start, opts) { - var dirs = nodeModulesPaths(start, opts, x); +var _stackSet = stackSet; - for (var i = 0; i < dirs.length; i++) { - dirs[i] = path$2.join(dirs[i], x); - } +/** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ - return dirs; -}; +function Stack(entries) { + var data = this.__data__ = new _ListCache(entries); + this.size = data.size; +} // Add methods to `Stack`. -var sync = function resolveSync(x, options) { - if (typeof x !== 'string') { - throw new TypeError('Path must be a string.'); - } - var opts = normalizeOptions$2(x, options); - var isFile = opts.isFile || defaultIsFile$1; - var readFileSync = opts.readFileSync || fs$3.readFileSync; - var isDirectory = opts.isDirectory || defaultIsDir$1; - var packageIterator = opts.packageIterator; - var extensions = opts.extensions || ['.js']; - var basedir = opts.basedir || path$2.dirname(caller()); - var parent = opts.filename || basedir; - opts.paths = opts.paths || []; // ensure that `basedir` is an absolute path at this point, resolving against the process' current working directory +Stack.prototype.clear = _stackClear; +Stack.prototype['delete'] = _stackDelete; +Stack.prototype.get = _stackGet; +Stack.prototype.has = _stackHas; +Stack.prototype.set = _stackSet; +var _Stack = Stack; - var absoluteStart = maybeUnwrapSymlink$1(path$2.resolve(basedir), opts); +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED$2 = '__lodash_hash_undefined__'; +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ - if (/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/.test(x)) { - var res = path$2.resolve(absoluteStart, x); - if (x === '.' || x === '..' || x.slice(-1) === '/') res += '/'; - var m = loadAsFileSync(res) || loadAsDirectorySync(res); - if (m) return maybeUnwrapSymlink$1(m, opts); - } else if (isCore(x)) { - return x; - } else { - var n = loadNodeModulesSync(x, absoluteStart); - if (n) return maybeUnwrapSymlink$1(n, opts); - } +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED$2); - var err = new Error("Cannot find module '" + x + "' from '" + parent + "'"); - err.code = 'MODULE_NOT_FOUND'; - throw err; + return this; +} - function loadAsFileSync(x) { - var pkg = loadpkg(path$2.dirname(x)); +var _setCacheAdd = setCacheAdd; - if (pkg && pkg.dir && pkg.pkg && opts.pathFilter) { - var rfile = path$2.relative(pkg.dir, x); - var r = opts.pathFilter(pkg.pkg, x, rfile); +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} - if (r) { - x = path$2.resolve(pkg.dir, r); // eslint-disable-line no-param-reassign - } - } +var _setCacheHas = setCacheHas; - if (isFile(x)) { - return x; - } +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ - for (var i = 0; i < extensions.length; i++) { - var file = x + extensions[i]; +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + this.__data__ = new _MapCache(); - if (isFile(file)) { - return file; - } - } + while (++index < length) { + this.add(values[index]); } +} // Add methods to `SetCache`. - function loadpkg(dir) { - if (dir === '' || dir === '/') return; - if (process.platform === 'win32' && /^\w:[/\\]*$/.test(dir)) { - return; - } +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; +var _SetCache = SetCache; - if (/[/\\]node_modules[/\\]*$/.test(dir)) return; - var pkgfile = path$2.join(maybeUnwrapSymlink$1(dir, opts), 'package.json'); +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; - if (!isFile(pkgfile)) { - return loadpkg(path$2.dirname(dir)); + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; } + } - var body = readFileSync(pkgfile); + return false; +} - try { - var pkg = JSON.parse(body); - } catch (jsonErr) {} +var _arraySome = arraySome; - if (pkg && opts.packageFilter) { - // v2 will pass pkgfile - pkg = opts.packageFilter(pkg, - /*pkgfile,*/ - dir); // eslint-disable-line spaced-comment - } +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} - return { - pkg: pkg, - dir: dir - }; - } +var _cacheHas = cacheHas; - function loadAsDirectorySync(x) { - var pkgfile = path$2.join(maybeUnwrapSymlink$1(x, opts), '/package.json'); +/** Used to compose bitmasks for value comparisons. */ - if (isFile(pkgfile)) { - try { - var body = readFileSync(pkgfile, 'UTF8'); - var pkg = JSON.parse(body); - } catch (e) {} +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ - if (pkg && opts.packageFilter) { - // v2 will pass pkgfile - pkg = opts.packageFilter(pkg, - /*pkgfile,*/ - x); // eslint-disable-line spaced-comment - } +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; - if (pkg && pkg.main) { - if (typeof pkg.main !== 'string') { - var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string'); - mainError.code = 'INVALID_PACKAGE_MAIN'; - throw mainError; - } + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } // Check that cyclic values are equal. - if (pkg.main === '.' || pkg.main === './') { - pkg.main = 'index'; - } - try { - var m = loadAsFileSync(path$2.resolve(x, pkg.main)); - if (m) return m; - var n = loadAsDirectorySync(path$2.resolve(x, pkg.main)); - if (n) return n; - } catch (e) {} - } - } + var arrStacked = stack.get(array); + var othStacked = stack.get(other); - return loadAsFileSync(path$2.join(x, '/index')); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; } - function loadNodeModulesSync(x, start) { - var thunk = function () { - return getPackageCandidates$1(x, start, opts); - }; + var index = -1, + result = true, + seen = bitmask & COMPARE_UNORDERED_FLAG ? new _SetCache() : undefined; + stack.set(array, other); + stack.set(other, array); // Ignore non-index properties. - var dirs = packageIterator ? packageIterator(x, start, thunk, opts) : thunk(); + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; - for (var i = 0; i < dirs.length; i++) { - var dir = dirs[i]; + if (customizer) { + var compared = isPartial ? customizer(othValue, arrValue, index, other, array, stack) : customizer(arrValue, othValue, index, array, other, stack); + } - if (isDirectory(path$2.dirname(dir))) { - var m = loadAsFileSync(dir); - if (m) return m; - var n = loadAsDirectorySync(dir); - if (n) return n; + if (compared !== undefined) { + if (compared) { + continue; } - } - } -}; -async.core = core_1; -async.isCore = isCore; -async.sync = sync; -var resolve = async; + result = false; + break; + } // Recursively compare arrays (susceptible to call stack limits). -// eslint-disable-next-line prefer-destructuring + if (seen) { + if (!_arraySome(other, function (othValue, othIndex) { + if (!_cacheHas(seen, othIndex) && (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + result = false; + break; + } + } -let resolve$1 = require.resolve; // In the VS Code and Atom extensions `require` is overridden and `require.resolve` doesn't support the 2nd argument. + stack['delete'](array); + stack['delete'](other); + return result; +} -if (resolve$1.length === 1 || process.env.PRETTIER_FALLBACK_RESOLVE) { - resolve$1 = (id, options) => { - let basedir; +var _equalArrays = equalArrays; - if (options && options.paths && options.paths.length === 1) { - basedir = options.paths[0]; - } +/** Built-in value references. */ - return resolve.sync(id, { - basedir - }); - }; +var Uint8Array = _root.Uint8Array; +var _Uint8Array = Uint8Array; + +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + map.forEach(function (value, key) { + result[++index] = [key, value]; + }); + return result; } -var resolve_1 = resolve$1; +var _mapToArray = mapToArray; -const getExplorerMemoized = mem_1(opts => { - const cosmiconfig = thirdParty["cosmiconfig" + (opts.sync ? "Sync" : "")]; - const explorer = cosmiconfig("prettier", { - cache: opts.cache, - transform: result => { - if (result && result.config) { - if (typeof result.config === "string") { - const dir = path$2.dirname(result.filepath); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + set.forEach(function (value) { + result[++index] = value; + }); + return result; +} - try { - const modulePath = resolve_1(result.config, { - paths: [dir] - }); - result.config = require(modulePath); - } catch (error) { - // Original message contains `__filename`, can't pass tests - error.message = `Cannot find module '${result.config}' from '${dir}'`; - throw error; - } - } +var _setToArray = setToArray; - if (typeof result.config !== "object") { - throw new Error("Config is only allowed to be an object, " + `but received ${typeof result.config} in "${result.filepath}"`); - } +/** Used to compose bitmasks for value comparisons. */ - delete result.config.$schema; - } +var COMPARE_PARTIAL_FLAG$1 = 1, + COMPARE_UNORDERED_FLAG$1 = 2; +/** `Object#toString` result references. */ - return result; - }, - searchPlaces: ["package.json", ".prettierrc", ".prettierrc.json", ".prettierrc.yaml", ".prettierrc.yml", ".prettierrc.js", "prettier.config.js", ".prettierrc.toml"], - loaders: { - ".toml": loadToml - } - }); - return explorer; -}, { - cacheKey: JSON.stringify -}); -/** @param {{ cache: boolean, sync: boolean }} opts */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; +/** Used to convert symbols to primitives and strings. */ -function getExplorer(opts) { - // Normalize opts before passing to a memoized function - opts = Object.assign({ - sync: false, - cache: false - }, opts); - return getExplorerMemoized(opts); -} +var symbolProto = _Symbol ? _Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ -function _resolveConfig(filePath, opts, sync) { - opts = Object.assign({ - useCache: true - }, opts); - const loadOpts = { - cache: !!opts.useCache, - sync: !!sync, - editorconfig: !!opts.editorconfig - }; - const { - load, - search - } = getExplorer(loadOpts); - const loadEditorConfig = resolveConfigEditorconfig.getLoadFunction(loadOpts); - const arr = [opts.config ? load(opts.config) : search(filePath), loadEditorConfig(filePath)]; +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if (object.byteLength != other.byteLength || object.byteOffset != other.byteOffset) { + return false; + } - const unwrapAndMerge = ([result, editorConfigured]) => { - const merged = Object.assign({}, editorConfigured, {}, mergeOverrides(result, filePath)); - ["plugins", "pluginSearchDirs"].forEach(optionName => { - if (Array.isArray(merged[optionName])) { - merged[optionName] = merged[optionName].map(value => typeof value === "string" && value.startsWith(".") // relative path - ? path$2.resolve(path$2.dirname(result.filepath), value) : value); + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if (object.byteLength != other.byteLength || !equalFunc(new _Uint8Array(object), new _Uint8Array(other))) { + return false; } - }); - if (!result && !editorConfigured) { - return null; - } + return true; - return merged; - }; + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return eq_1(+object, +other); - if (loadOpts.sync) { - return unwrapAndMerge(arr); - } + case errorTag: + return object.name == other.name && object.message == other.message; - return Promise.all(arr).then(unwrapAndMerge); -} + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == other + ''; -const resolveConfig = (filePath, opts) => _resolveConfig(filePath, opts, false); + case mapTag: + var convert = _mapToArray; -resolveConfig.sync = (filePath, opts) => _resolveConfig(filePath, opts, true); + case setTag: + var isPartial = bitmask & COMPARE_PARTIAL_FLAG$1; + convert || (convert = _setToArray); -function clearCache$1() { - mem_1.clear(getExplorerMemoized); - resolveConfigEditorconfig.clearCache(); -} + if (object.size != other.size && !isPartial) { + return false; + } // Assume cyclic values are equal. -async function resolveConfigFile(filePath) { - const { - search - } = getExplorer({ - sync: false - }); - const result = await search(filePath); - return result ? result.filepath : null; -} -resolveConfigFile.sync = filePath => { - const { - search - } = getExplorer({ - sync: true - }); - const result = search(filePath); - return result ? result.filepath : null; -}; + var stacked = stack.get(object); -function mergeOverrides(configResult, filePath) { - const { - config, - filepath: configPath - } = configResult || {}; + if (stacked) { + return stacked == other; + } - const _ref = config || {}, - { - overrides - } = _ref, - options = _objectWithoutPropertiesLoose(_ref, ["overrides"]); + bitmask |= COMPARE_UNORDERED_FLAG$1; // Recursively compare objects (susceptible to call stack limits). - if (filePath && overrides) { - const relativeFilePath = path$2.relative(path$2.dirname(configPath), filePath); + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; - for (const override of overrides) { - if (pathMatchesGlobs(relativeFilePath, override.files, override.excludeFiles)) { - Object.assign(options, override.options); + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); } - } - } - - return options; -} // Based on eslint: https://github.com/eslint/eslint/blob/master/lib/config/config-ops.js + } -function pathMatchesGlobs(filePath, patterns, excludedPatterns) { - const patternList = [].concat(patterns); - const excludedPatternList = [].concat(excludedPatterns || []); - const opts = { - matchBase: true, - dot: true - }; - return patternList.some(pattern => minimatch_1(filePath, pattern, opts)) && !excludedPatternList.some(excludedPattern => minimatch_1(filePath, excludedPattern, opts)); + return false; } -var resolveConfig_1 = { - resolveConfig, - resolveConfigFile, - clearCache: clearCache$1 -}; - -/** - * @typedef {{ ignorePath?: string, withNodeModules?: boolean, plugins: object }} FileInfoOptions - * @typedef {{ ignored: boolean, inferredParser: string | null }} FileInfoResult - */ +var _equalByTag = equalByTag; /** - * @param {string} filePath - * @param {FileInfoOptions} opts - * @returns {Promise} + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. * - * Please note that prettier.getFileInfo() expects opts.plugins to be an array of paths, - * not an object. A transformation from this array to an object is automatically done - * internally by the method wrapper. See withPlugins() in index.js. + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray_1(object) ? result : _arrayPush(result, symbolsFunc(object)); +} -async function getFileInfo(filePath, opts) { - if (typeof filePath !== "string") { - throw new TypeError(`expect \`filePath\` to be a string, got \`${typeof filePath}\``); - } +var _baseGetAllKeys = baseGetAllKeys; - const ignorer = await createIgnorer_1(opts.ignorePath, opts.withNodeModules); - return _getFileInfo({ - ignorer, - filePath: normalizeFilePath(filePath, opts.ignorePath), - plugins: opts.plugins, - resolveConfig: opts.resolveConfig, - sync: false - }); -} /** - * @param {string} filePath - * @param {FileInfoOptions} opts - * @returns {FileInfoResult} + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + while (++index < length) { + var value = array[index]; -getFileInfo.sync = function (filePath, opts) { - if (typeof filePath !== "string") { - throw new TypeError(`expect \`filePath\` to be a string, got \`${typeof filePath}\``); - } - - const ignorer = createIgnorer_1.sync(opts.ignorePath, opts.withNodeModules); - return _getFileInfo({ - ignorer, - filePath: normalizeFilePath(filePath, opts.ignorePath), - plugins: opts.plugins, - resolveConfig: opts.resolveConfig, - sync: true - }); -}; - -function _getFileInfo({ - ignorer, - filePath, - plugins, - resolveConfig = false, - sync = false -}) { - const fileInfo = { - ignored: ignorer.ignores(filePath), - inferredParser: options$1.inferParser(filePath, plugins) || null - }; - - if (!fileInfo.inferredParser && resolveConfig) { - if (!sync) { - return resolveConfig_1.resolveConfig(filePath).then(resolvedConfig => { - if (resolvedConfig && resolvedConfig.parser) { - fileInfo.inferredParser = resolvedConfig.parser; - } - - return fileInfo; - }); - } - - const resolvedConfig = resolveConfig_1.resolveConfig.sync(filePath); - - if (resolvedConfig && resolvedConfig.parser) { - fileInfo.inferredParser = resolvedConfig.parser; + if (predicate(value, index, array)) { + result[resIndex++] = value; } } - return fileInfo; -} - -function normalizeFilePath(filePath, ignorePath) { - return ignorePath ? path$2.relative(path$2.dirname(ignorePath), filePath) : filePath; -} - -var getFileInfo_1 = getFileInfo; - -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; + return result; } -var _listCacheClear = listCacheClear; +var _arrayFilter = arrayFilter; /** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. + * This method returns a new empty array. * * @static * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. * @example * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false + * var arrays = _.times(2, _.stubArray); * - * _.eq('a', 'a'); - * // => true + * console.log(arrays); + * // => [[], []] * - * _.eq('a', Object('a')); + * console.log(arrays[0] === arrays[1]); * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || value !== value && other !== other; -} - -var eq_1 = eq; - -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. */ - -function assocIndexOf(array, key) { - var length = array.length; - - while (length--) { - if (eq_1(array[length][0], key)) { - return length; - } - } - - return -1; +function stubArray() { + return []; } -var _assocIndexOf = assocIndexOf; +var stubArray_1 = stubArray; /** Used for built-in method references. */ -var arrayProto = Array.prototype; +var objectProto$6 = Object.prototype; /** Built-in value references. */ -var splice = arrayProto.splice; +var propertyIsEnumerable$1 = objectProto$6.propertyIsEnumerable; +/* Built-in method references for those with the same name as other `lodash` methods. */ + +var nativeGetSymbols = Object.getOwnPropertySymbols; /** - * Removes `key` and its value from the list cache. + * Creates an array of the own enumerable symbols of `object`. * * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. */ -function listCacheDelete(key) { - var data = this.__data__, - index = _assocIndexOf(data, key); - - if (index < 0) { - return false; - } - - var lastIndex = data.length - 1; - - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); +var getSymbols = !nativeGetSymbols ? stubArray_1 : function (object) { + if (object == null) { + return []; } - --this.size; - return true; -} - -var _listCacheDelete = listCacheDelete; + object = Object(object); + return _arrayFilter(nativeGetSymbols(object), function (symbol) { + return propertyIsEnumerable$1.call(object, symbol); + }); +}; +var _getSymbols = getSymbols; /** - * Gets the list cache value for `key`. + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. * * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. */ +function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); -function listCacheGet(key) { - var data = this.__data__, - index = _assocIndexOf(data, key); - return index < 0 ? undefined : data[index][1]; + while (++index < n) { + result[index] = iteratee(index); + } + + return result; } -var _listCacheGet = listCacheGet; +var _baseTimes = baseTimes; /** - * Checks if a list cache value for `key` exists. + * This method returns `false`. * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] */ - -function listCacheHas(key) { - return _assocIndexOf(this.__data__, key) > -1; +function stubFalse() { + return false; } -var _listCacheHas = listCacheHas; +var stubFalse_1 = stubFalse; -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ +var isBuffer_1 = createCommonjsModule(function (module, exports) { + /** Detect free variable `exports`. */ + var freeExports = exports && !exports.nodeType && exports; + /** Detect free variable `module`. */ -function listCacheSet(key, value) { - var data = this.__data__, - index = _assocIndexOf(data, key); + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + /** Detect the popular CommonJS extension `module.exports`. */ - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } + var moduleExports = freeModule && freeModule.exports === freeExports; + /** Built-in value references. */ - return this; -} + var Buffer = moduleExports ? _root.Buffer : undefined; + /* Built-in method references for those with the same name as other `lodash` methods. */ -var _listCacheSet = listCacheSet; + var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + + var isBuffer = nativeIsBuffer || stubFalse_1; + module.exports = isBuffer; +}); + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER$2 = 9007199254740991; +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; /** - * Creates an list cache object. + * Checks if `value` is a valid array-like index. * * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - this.clear(); - - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} // Add methods to `ListCache`. - +function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER$2 : length; + return !!length && (type == 'number' || type != 'symbol' && reIsUint.test(value)) && value > -1 && value % 1 == 0 && value < length; +} -ListCache.prototype.clear = _listCacheClear; -ListCache.prototype['delete'] = _listCacheDelete; -ListCache.prototype.get = _listCacheGet; -ListCache.prototype.has = _listCacheHas; -ListCache.prototype.set = _listCacheSet; -var _ListCache = ListCache; +var _isIndex = isIndex; +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER$3 = 9007199254740991; /** - * Removes all key-value entries from the stack. + * Checks if `value` is a valid array-like length. * - * @private - * @name clear - * @memberOf Stack + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false */ -function stackClear() { - this.__data__ = new _ListCache(); - this.size = 0; +function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$3; } -var _stackClear = stackClear; +var isLength_1 = isLength; + +/** `Object#toString` result references. */ + +var argsTag$1 = '[object Arguments]', + arrayTag = '[object Array]', + boolTag$1 = '[object Boolean]', + dateTag$1 = '[object Date]', + errorTag$1 = '[object Error]', + funcTag$1 = '[object Function]', + mapTag$1 = '[object Map]', + numberTag$1 = '[object Number]', + objectTag = '[object Object]', + regexpTag$1 = '[object RegExp]', + setTag$1 = '[object Set]', + stringTag$1 = '[object String]', + weakMapTag = '[object WeakMap]'; +var arrayBufferTag$1 = '[object ArrayBuffer]', + dataViewTag$1 = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; +/** Used to identify `toStringTag` values of typed arrays. */ +var typedArrayTags = {}; +typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true; +typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag$1] = typedArrayTags[boolTag$1] = typedArrayTags[dataViewTag$1] = typedArrayTags[dateTag$1] = typedArrayTags[errorTag$1] = typedArrayTags[funcTag$1] = typedArrayTags[mapTag$1] = typedArrayTags[numberTag$1] = typedArrayTags[objectTag] = typedArrayTags[regexpTag$1] = typedArrayTags[setTag$1] = typedArrayTags[stringTag$1] = typedArrayTags[weakMapTag] = false; /** - * Removes `key` and its value from the stack. + * The base implementation of `_.isTypedArray` without Node.js optimizations. * * @private - * @name delete - * @memberOf Stack - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. */ -function stackDelete(key) { - var data = this.__data__, - result = data['delete'](key); - this.size = data.size; - return result; -} - -var _stackDelete = stackDelete; -/** - * Gets the stack value for `key`. - * - * @private - * @name get - * @memberOf Stack - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function stackGet(key) { - return this.__data__.get(key); +function baseIsTypedArray(value) { + return isObjectLike_1(value) && isLength_1(value.length) && !!typedArrayTags[_baseGetTag(value)]; } -var _stackGet = stackGet; +var _baseIsTypedArray = baseIsTypedArray; /** - * Checks if a stack value for `key` exists. + * The base implementation of `_.unary` without support for storing metadata. * * @private - * @name has - * @memberOf Stack - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. */ -function stackHas(key) { - return this.__data__.has(key); +function baseUnary(func) { + return function (value) { + return func(value); + }; } -var _stackHas = stackHas; +var _baseUnary = baseUnary; -/** Detect free variable `global` from Node.js. */ +var _nodeUtil = createCommonjsModule(function (module, exports) { + /** Detect free variable `exports`. */ + var freeExports = exports && !exports.nodeType && exports; + /** Detect free variable `module`. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; -var _freeGlobal = freeGlobal; + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + /** Detect the popular CommonJS extension `module.exports`. */ -/** Detect free variable `self`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + /** Detect free variable `process` from Node.js. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; -/** Used as a reference to the global object. */ + var freeProcess = moduleExports && _freeGlobal.process; + /** Used to access faster Node.js helpers. */ -var root = _freeGlobal || freeSelf || Function('return this')(); -var _root = root; + var nodeUtil = function () { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule && freeModule.require && freeModule.require('util').types; -/** Built-in value references. */ + if (types) { + return types; + } // Legacy `process.binding('util')` for Node.js < 10. -var Symbol$1 = _root.Symbol; -var _Symbol = Symbol$1; -/** Used for built-in method references. */ + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} + }(); -var objectProto = Object.prototype; -/** Used to check objects for own properties. */ + module.exports = nodeUtil; +}); -var hasOwnProperty$2 = objectProto.hasOwnProperty; +/* Node.js helper references. */ + +var nodeIsTypedArray = _nodeUtil && _nodeUtil.isTypedArray; /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false */ -var nativeObjectToString = objectProto.toString; -/** Built-in value references. */ +var isTypedArray = nodeIsTypedArray ? _baseUnary(nodeIsTypedArray) : _baseIsTypedArray; +var isTypedArray_1 = isTypedArray; -var symToStringTag = _Symbol ? _Symbol.toStringTag : undefined; +/** Used for built-in method references. */ + +var objectProto$7 = Object.prototype; +/** Used to check objects for own properties. */ + +var hasOwnProperty$7 = objectProto$7.hasOwnProperty; /** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * Creates an array of the enumerable property names of the array-like `value`. * * @private * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. */ -function getRawTag(value) { - var isOwn = hasOwnProperty$2.call(value, symToStringTag), - tag = value[symToStringTag]; - - try { - value[symToStringTag] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString.call(value); +function arrayLikeKeys(value, inherited) { + var isArr = isArray_1(value), + isArg = !isArr && isArguments_1(value), + isBuff = !isArr && !isArg && isBuffer_1(value), + isType = !isArr && !isArg && !isBuff && isTypedArray_1(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? _baseTimes(value.length, String) : [], + length = result.length; - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; + for (var key in value) { + if ((inherited || hasOwnProperty$7.call(value, key)) && !(skipIndexes && ( // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || // Node.js 0.10 has enumerable non-index properties on buffers. + isBuff && (key == 'offset' || key == 'parent') || // PhantomJS 2 has enumerable non-index properties on typed arrays. + isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset') || // Skip index properties. + _isIndex(key, length)))) { + result.push(key); } } return result; } -var _getRawTag = getRawTag; +var _arrayLikeKeys = arrayLikeKeys; /** Used for built-in method references. */ -var objectProto$1 = Object.prototype; +var objectProto$8 = Object.prototype; /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. */ -var nativeObjectToString$1 = objectProto$1.toString; +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = typeof Ctor == 'function' && Ctor.prototype || objectProto$8; + return value === proto; +} + +var _isPrototype = isPrototype; + /** - * Converts `value` to a string using `Object.prototype.toString`. + * Creates a unary function that invokes `func` with its argument transformed. * * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. */ - -function objectToString(value) { - return nativeObjectToString$1.call(value); +function overArg(func, transform) { + return function (arg) { + return func(transform(arg)); + }; } -var _objectToString = objectToString; +var _overArg = overArg; -/** `Object#toString` result references. */ +/* Built-in method references for those with the same name as other `lodash` methods. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; -/** Built-in value references. */ +var nativeKeys = _overArg(Object.keys, Object); +var _nativeKeys = nativeKeys; -var symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined; +/** Used for built-in method references. */ + +var objectProto$9 = Object.prototype; +/** Used to check objects for own properties. */ + +var hasOwnProperty$8 = objectProto$9.hasOwnProperty; /** - * The base implementation of `getTag` without fallbacks for buggy environments. + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. * * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; +function baseKeys(object) { + if (!_isPrototype(object)) { + return _nativeKeys(object); } - return symToStringTag$1 && symToStringTag$1 in Object(value) ? _getRawTag(value) : _objectToString(value); + var result = []; + + for (var key in Object(object)) { + if (hasOwnProperty$8.call(object, key) && key != 'constructor') { + result.push(key); + } + } + + return result; } -var _baseGetTag = baseGetTag; +var _baseKeys = baseKeys; /** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. * * @static * @memberOf _ - * @since 0.1.0 + * @since 4.0.0 * @category Lang * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. * @example * - * _.isObject({}); + * _.isArrayLike([1, 2, 3]); * // => true * - * _.isObject([1, 2, 3]); + * _.isArrayLike(document.body.children); * // => true * - * _.isObject(_.noop); + * _.isArrayLike('abc'); * // => true * - * _.isObject(null); + * _.isArrayLike(_.noop); * // => false */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); -} -var isObject_1 = isObject; +function isArrayLike(value) { + return value != null && isLength_1(value.length) && !isFunction_1(value); +} -/** `Object#toString` result references. */ +var isArrayLike_1 = isArrayLike; -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; /** - * Checks if `value` is classified as a `Function` object. + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. * * @static - * @memberOf _ * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. * @example * - * _.isFunction(_); - * // => true + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * _.isFunction(/abc/); - * // => false + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] */ -function isFunction(value) { - if (!isObject_1(value)) { - return false; - } // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - - - var tag = _baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; +function keys(object) { + return isArrayLike_1(object) ? _arrayLikeKeys(object) : _baseKeys(object); } -var isFunction_1 = isFunction; - -/** Used to detect overreaching core-js shims. */ - -var coreJsData = _root['__core-js_shared__']; -var _coreJsData = coreJsData; - -/** Used to detect methods masquerading as native. */ +var keys_1 = keys; -var maskSrcKey = function () { - var uid = /[^.]+$/.exec(_coreJsData && _coreJsData.keys && _coreJsData.keys.IE_PROTO || ''); - return uid ? 'Symbol(src)_1.' + uid : ''; -}(); /** - * Checks if `func` has its source masked. + * Creates an array of own enumerable property names and symbols of `object`. * * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. */ - -function isMasked(func) { - return !!maskSrcKey && maskSrcKey in func; +function getAllKeys(object) { + return _baseGetAllKeys(object, keys_1, _getSymbols); } -var _isMasked = isMasked; +var _getAllKeys = getAllKeys; + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG$2 = 1; /** Used for built-in method references. */ -var funcProto = Function.prototype; -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; +var objectProto$a = Object.prototype; +/** Used to check objects for own properties. */ + +var hasOwnProperty$9 = objectProto$a.hasOwnProperty; /** - * Converts `func` to its source code. + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. * * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2, + objProps = _getAllKeys(object), + objLength = objProps.length, + othProps = _getAllKeys(other), + othLength = othProps.length; - try { - return func + ''; - } catch (e) {} + if (objLength != othLength && !isPartial) { + return false; } - return ''; -} + var index = objLength; -var _toSource = toSource; + while (index--) { + var key = objProps[index]; -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ + if (!(isPartial ? key in other : hasOwnProperty$9.call(other, key))) { + return false; + } + } // Check that cyclic values are equal. -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; -/** Used for built-in method references. */ + var objStacked = stack.get(object); + var othStacked = stack.get(other); -var funcProto$1 = Function.prototype, - objectProto$2 = Object.prototype; -/** Used to resolve the decompiled source of functions. */ + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } -var funcToString$1 = funcProto$1.toString; -/** Used to check objects for own properties. */ + var result = true; + stack.set(object, other); + stack.set(other, object); + var skipCtor = isPartial; -var hasOwnProperty$3 = objectProto$2.hasOwnProperty; -/** Used to detect if a method is native. */ + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; -var reIsNative = RegExp('^' + funcToString$1.call(hasOwnProperty$3).replace(reRegExpChar, '\\$&').replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'); -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ + if (customizer) { + var compared = isPartial ? customizer(othValue, objValue, key, other, object, stack) : customizer(objValue, othValue, key, object, other, stack); + } // Recursively compare objects (susceptible to call stack limits). -function baseIsNative(value) { - if (!isObject_1(value) || _isMasked(value)) { - return false; + + if (!(compared === undefined ? objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack) : compared)) { + result = false; + break; + } + + skipCtor || (skipCtor = key == 'constructor'); } - var pattern = isFunction_1(value) ? reIsNative : reIsHostCtor; - return pattern.test(_toSource(value)); -} + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; // Non `Object` object instances with different constructors are not equal. -var _baseIsNative = baseIsNative; + if (objCtor != othCtor && 'constructor' in object && 'constructor' in other && !(typeof objCtor == 'function' && objCtor instanceof objCtor && typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; + stack['delete'](object); + stack['delete'](other); + return result; } -var _getValue = getValue; +var _equalObjects = equalObjects; -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ +/* Built-in method references that are verified to be native. */ -function getNative(object, key) { - var value = _getValue(object, key); - return _baseIsNative(value) ? value : undefined; -} +var DataView = _getNative(_root, 'DataView'); +var _DataView = DataView; -var _getNative = getNative; +/* Built-in method references that are verified to be native. */ + +var Promise$1 = _getNative(_root, 'Promise'); +var _Promise = Promise$1; /* Built-in method references that are verified to be native. */ -var Map$1 = _getNative(_root, 'Map'); -var _Map = Map$1; +var Set$1 = _getNative(_root, 'Set'); +var _Set = Set$1; /* Built-in method references that are verified to be native. */ -var nativeCreate = _getNative(Object, 'create'); -var _nativeCreate = nativeCreate; +var WeakMap$1 = _getNative(_root, 'WeakMap'); +var _WeakMap = WeakMap$1; + +/** `Object#toString` result references. */ + +var mapTag$2 = '[object Map]', + objectTag$1 = '[object Object]', + promiseTag = '[object Promise]', + setTag$2 = '[object Set]', + weakMapTag$1 = '[object WeakMap]'; +var dataViewTag$2 = '[object DataView]'; +/** Used to detect maps, sets, and weakmaps. */ +var dataViewCtorString = _toSource(_DataView), + mapCtorString = _toSource(_Map), + promiseCtorString = _toSource(_Promise), + setCtorString = _toSource(_Set), + weakMapCtorString = _toSource(_WeakMap); /** - * Removes all key-value entries from the hash. + * Gets the `toStringTag` of `value`. * * @private - * @name clear - * @memberOf Hash + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. */ -function hashClear() { - this.__data__ = _nativeCreate ? _nativeCreate(null) : {}; - this.size = 0; -} +var getTag = _baseGetTag; // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. + +if (_DataView && getTag(new _DataView(new ArrayBuffer(1))) != dataViewTag$2 || _Map && getTag(new _Map()) != mapTag$2 || _Promise && getTag(_Promise.resolve()) != promiseTag || _Set && getTag(new _Set()) != setTag$2 || _WeakMap && getTag(new _WeakMap()) != weakMapTag$1) { + getTag = function (value) { + var result = _baseGetTag(value), + Ctor = result == objectTag$1 ? value.constructor : undefined, + ctorString = Ctor ? _toSource(Ctor) : ''; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: + return dataViewTag$2; + + case mapCtorString: + return mapTag$2; + + case promiseCtorString: + return promiseTag; -var _hashClear = hashClear; + case setCtorString: + return setTag$2; -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; + case weakMapCtorString: + return weakMapTag$1; + } + } + + return result; + }; } -var _hashDelete = hashDelete; +var _getTag = getTag; -/** Used to stand-in for `undefined` hash values. */ +/** Used to compose bitmasks for value comparisons. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; +var COMPARE_PARTIAL_FLAG$3 = 1; +/** `Object#toString` result references. */ + +var argsTag$2 = '[object Arguments]', + arrayTag$1 = '[object Array]', + objectTag$2 = '[object Object]'; /** Used for built-in method references. */ -var objectProto$3 = Object.prototype; +var objectProto$b = Object.prototype; /** Used to check objects for own properties. */ -var hasOwnProperty$4 = objectProto$3.hasOwnProperty; +var hasOwnProperty$a = objectProto$b.hasOwnProperty; /** - * Gets the hash value for `key`. + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. * * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ -function hashGet(key) { - var data = this.__data__; +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray_1(object), + othIsArr = isArray_1(other), + objTag = objIsArr ? arrayTag$1 : _getTag(object), + othTag = othIsArr ? arrayTag$1 : _getTag(other); + objTag = objTag == argsTag$2 ? objectTag$2 : objTag; + othTag = othTag == argsTag$2 ? objectTag$2 : othTag; + var objIsObj = objTag == objectTag$2, + othIsObj = othTag == objectTag$2, + isSameTag = objTag == othTag; - if (_nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; + if (isSameTag && isBuffer_1(object)) { + if (!isBuffer_1(other)) { + return false; + } + + objIsArr = true; + objIsObj = false; } - return hasOwnProperty$4.call(data, key) ? data[key] : undefined; -} + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack()); + return objIsArr || isTypedArray_1(object) ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } -var _hashGet = hashGet; + if (!(bitmask & COMPARE_PARTIAL_FLAG$3)) { + var objIsWrapped = objIsObj && hasOwnProperty$a.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty$a.call(other, '__wrapped__'); -/** Used for built-in method references. */ + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + stack || (stack = new _Stack()); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } -var objectProto$4 = Object.prototype; -/** Used to check objects for own properties. */ + if (!isSameTag) { + return false; + } + + stack || (stack = new _Stack()); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +var _baseIsEqualDeep = baseIsEqualDeep; -var hasOwnProperty$5 = objectProto$4.hasOwnProperty; /** - * Checks if a hash value for `key` exists. + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. * * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. */ -function hashHas(key) { - var data = this.__data__; - return _nativeCreate ? data[key] !== undefined : hasOwnProperty$5.call(data, key); +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + + if (value == null || other == null || !isObjectLike_1(value) && !isObjectLike_1(other)) { + return value !== value && other !== other; + } + + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); } -var _hashHas = hashHas; +var _baseIsEqual = baseIsEqual; -/** Used to stand-in for `undefined` hash values. */ +/** Used to compose bitmasks for value comparisons. */ -var HASH_UNDEFINED$1 = '__lodash_hash_undefined__'; +var COMPARE_PARTIAL_FLAG$4 = 1, + COMPARE_UNORDERED_FLAG$2 = 2; /** - * Sets the hash `key` to `value`. + * The base implementation of `_.isMatch` without support for iteratee shorthands. * * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = _nativeCreate && value === undefined ? HASH_UNDEFINED$1 : value; - return this; -} +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; -var _hashSet = hashSet; + if (object == null) { + return !length; + } -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ + object = Object(object); -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - this.clear(); + while (index--) { + var data = matchData[index]; - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); + if (noCustomizer && data[2] ? data[1] !== object[data[0]] : !(data[0] in object)) { + return false; + } } -} // Add methods to `Hash`. + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack(); -Hash.prototype.clear = _hashClear; -Hash.prototype['delete'] = _hashDelete; -Hash.prototype.get = _hashGet; -Hash.prototype.has = _hashHas; -Hash.prototype.set = _hashSet; -var _Hash = Hash; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } -/** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ + if (!(result === undefined ? _baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$4 | COMPARE_UNORDERED_FLAG$2, customizer, stack) : result)) { + return false; + } + } + } -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new _Hash(), - 'map': new (_Map || _ListCache)(), - 'string': new _Hash() - }; + return true; } -var _mapCacheClear = mapCacheClear; +var _baseIsMatch = baseIsMatch; /** - * Checks if `value` is suitable for use as unique object key. + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. * * @private * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. */ -function isKeyable(value) { - var type = typeof value; - return type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean' ? value !== '__proto__' : value === null; + +function isStrictComparable(value) { + return value === value && !isObject_1(value); } -var _isKeyable = isKeyable; +var _isStrictComparable = isStrictComparable; /** - * Gets the data for `map`. + * Gets the property names, values, and compare flags of `object`. * * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. */ -function getMapData(map, key) { - var data = map.__data__; - return _isKeyable(key) ? data[typeof key == 'string' ? 'string' : 'hash'] : data.map; -} - -var _getMapData = getMapData; +function getMatchData(object) { + var result = keys_1(object), + length = result.length; -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ + while (length--) { + var key = result[length], + value = object[key]; + result[length] = [key, value, _isStrictComparable(value)]; + } -function mapCacheDelete(key) { - var result = _getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; return result; } -var _mapCacheDelete = mapCacheDelete; +var _getMatchData = getMatchData; /** - * Gets the map value for `key`. + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. * * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. */ +function matchesStrictComparable(key, srcValue) { + return function (object) { + if (object == null) { + return false; + } -function mapCacheGet(key) { - return _getMapData(this, key).get(key); + return object[key] === srcValue && (srcValue !== undefined || key in Object(object)); + }; } -var _mapCacheGet = mapCacheGet; +var _matchesStrictComparable = matchesStrictComparable; /** - * Checks if a map value for `key` exists. + * The base implementation of `_.matches` which doesn't clone `source`. * * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. */ -function mapCacheHas(key) { - return _getMapData(this, key).has(key); -} - -var _mapCacheHas = mapCacheHas; +function baseMatches(source) { + var matchData = _getMatchData(source); -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } -function mapCacheSet(key, value) { - var data = _getMapData(this, key), - size = data.size; - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; + return function (object) { + return object === source || _baseIsMatch(object, source, matchData); + }; } -var _mapCacheSet = mapCacheSet; +var _baseMatches = baseMatches; + +/** `Object#toString` result references. */ +var symbolTag$1 = '[object Symbol]'; /** - * Creates a map cache object to store key-value pairs. + * Checks if `value` is classified as a `Symbol` primitive or object. * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - this.clear(); - - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} // Add methods to `MapCache`. - +function isSymbol(value) { + return typeof value == 'symbol' || isObjectLike_1(value) && _baseGetTag(value) == symbolTag$1; +} -MapCache.prototype.clear = _mapCacheClear; -MapCache.prototype['delete'] = _mapCacheDelete; -MapCache.prototype.get = _mapCacheGet; -MapCache.prototype.has = _mapCacheHas; -MapCache.prototype.set = _mapCacheSet; -var _MapCache = MapCache; +var isSymbol_1 = isSymbol; -/** Used as the size to enable large array optimizations. */ +/** Used to match property names within property paths. */ -var LARGE_ARRAY_SIZE = 200; +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; /** - * Sets the stack `key` to `value`. + * Checks if `value` is a property name and not a property path. * * @private - * @name set - * @memberOf Stack - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the stack cache instance. + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. */ -function stackSet(key, value) { - var data = this.__data__; - - if (data instanceof _ListCache) { - var pairs = data.__data__; +function isKey(value, object) { + if (isArray_1(value)) { + return false; + } - if (!_Map || pairs.length < LARGE_ARRAY_SIZE - 1) { - pairs.push([key, value]); - this.size = ++data.size; - return this; - } + var type = typeof value; - data = this.__data__ = new _MapCache(pairs); + if (type == 'number' || type == 'symbol' || type == 'boolean' || value == null || isSymbol_1(value)) { + return true; } - data.set(key, value); - this.size = data.size; - return this; + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || object != null && value in Object(object); } -var _stackSet = stackSet; +var _isKey = isKey; + +/** Error message constants. */ +var FUNC_ERROR_TEXT = 'Expected a function'; /** - * Creates a stack cache object to store key-value pairs. + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `clear`, `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; */ -function Stack(entries) { - var data = this.__data__ = new _ListCache(entries); - this.size = data.size; -} // Add methods to `Stack`. +function memoize(func, resolver) { + if (typeof func != 'function' || resolver != null && typeof resolver != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + + var memoized = function () { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + if (cache.has(key)) { + return cache.get(key); + } -Stack.prototype.clear = _stackClear; -Stack.prototype['delete'] = _stackDelete; -Stack.prototype.get = _stackGet; -Stack.prototype.has = _stackHas; -Stack.prototype.set = _stackSet; -var _Stack = Stack; + var result = func.apply(this, args); + memoized.cache = cache.set(key, result) || cache; + return result; + }; -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED$2 = '__lodash_hash_undefined__'; -/** - * Adds `value` to the array cache. - * - * @private - * @name add - * @memberOf SetCache - * @alias push - * @param {*} value The value to cache. - * @returns {Object} Returns the cache instance. - */ + memoized.cache = new (memoize.Cache || _MapCache)(); + return memoized; +} // Expose `MapCache`. -function setCacheAdd(value) { - this.__data__.set(value, HASH_UNDEFINED$2); - return this; -} +memoize.Cache = _MapCache; +var memoize_1 = memoize; -var _setCacheAdd = setCacheAdd; +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; /** - * Checks if `value` is in the array cache. + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. * * @private - * @name has - * @memberOf SetCache - * @param {*} value The value to search for. - * @returns {number} Returns `true` if `value` is found, else `false`. + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. */ -function setCacheHas(value) { - return this.__data__.has(value); + +function memoizeCapped(func) { + var result = memoize_1(func, function (key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + + return key; + }); + var cache = result.cache; + return result; } -var _setCacheHas = setCacheHas; +var _memoizeCapped = memoizeCapped; + +/** Used to match property names within property paths. */ + +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; /** - * - * Creates an array cache object to store unique values. + * Converts `string` to a property path array. * * @private - * @constructor - * @param {Array} [values] The values to cache. + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. */ -function SetCache(values) { - var index = -1, - length = values == null ? 0 : values.length; - this.__data__ = new _MapCache(); - - while (++index < length) { - this.add(values[index]); - } -} // Add methods to `SetCache`. +var stringToPath = _memoizeCapped(function (string) { + var result = []; + if (string.charCodeAt(0) === 46 + /* . */ + ) { + result.push(''); + } -SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; -SetCache.prototype.has = _setCacheHas; -var _SetCache = SetCache; + string.replace(rePropName, function (match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : number || match); + }); + return result; +}); +var _stringToPath = stringToPath; /** - * A specialized version of `_.some` for arrays without support for iteratee + * A specialized version of `_.map` for arrays without support for iteratee * shorthands. * * @private * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. */ -function arraySome(array, predicate) { +function arrayMap(array, iteratee) { var index = -1, - length = array == null ? 0 : array.length; + length = array == null ? 0 : array.length, + result = Array(length); while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } + result[index] = iteratee(array[index], index, array); } - return false; + return result; } -var _arraySome = arraySome; - -/** - * Checks if a `cache` value for `key` exists. - * - * @private - * @param {Object} cache The cache to query. - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function cacheHas(cache, key) { - return cache.has(key); -} +var _arrayMap = arrayMap; -var _cacheHas = cacheHas; +/** Used as references for various `Number` constants. */ -/** Used to compose bitmasks for value comparisons. */ +var INFINITY = 1 / 0; +/** Used to convert symbols to primitives and strings. */ -var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; +var symbolProto$1 = _Symbol ? _Symbol.prototype : undefined, + symbolToString = symbolProto$1 ? symbolProto$1.toString : undefined; /** - * A specialized version of `baseIsEqualDeep` for arrays with support for - * partial deep comparisons. + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. * * @private - * @param {Array} array The array to compare. - * @param {Array} other The other array to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `array` and `other` objects. - * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + * @param {*} value The value to process. + * @returns {string} Returns the string. */ -function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, - arrLength = array.length, - othLength = other.length; - - if (arrLength != othLength && !(isPartial && othLength > arrLength)) { - return false; - } // Assume cyclic values are equal. - - - var stacked = stack.get(array); - - if (stacked && stack.get(other)) { - return stacked == other; +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; } - var index = -1, - result = true, - seen = bitmask & COMPARE_UNORDERED_FLAG ? new _SetCache() : undefined; - stack.set(array, other); - stack.set(other, array); // Ignore non-index properties. - - while (++index < arrLength) { - var arrValue = array[index], - othValue = other[index]; - - if (customizer) { - var compared = isPartial ? customizer(othValue, arrValue, index, other, array, stack) : customizer(arrValue, othValue, index, array, other, stack); - } - - if (compared !== undefined) { - if (compared) { - continue; - } - - result = false; - break; - } // Recursively compare arrays (susceptible to call stack limits). - + if (isArray_1(value)) { + // Recursively convert values (susceptible to call stack limits). + return _arrayMap(value, baseToString) + ''; + } - if (seen) { - if (!_arraySome(other, function (othValue, othIndex) { - if (!_cacheHas(seen, othIndex) && (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { - return seen.push(othIndex); - } - })) { - result = false; - break; - } - } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { - result = false; - break; - } + if (isSymbol_1(value)) { + return symbolToString ? symbolToString.call(value) : ''; } - stack['delete'](array); - stack['delete'](other); - return result; + var result = value + ''; + return result == '0' && 1 / value == -INFINITY ? '-0' : result; } -var _equalArrays = equalArrays; - -/** Built-in value references. */ - -var Uint8Array = _root.Uint8Array; -var _Uint8Array = Uint8Array; +var _baseToString = baseToString; /** - * Converts `map` to its key-value pairs. + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. * - * @private - * @param {Object} map The map to convert. - * @returns {Array} Returns the key-value pairs. + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' */ -function mapToArray(map) { - var index = -1, - result = Array(map.size); - map.forEach(function (value, key) { - result[++index] = [key, value]; - }); - return result; + +function toString(value) { + return value == null ? '' : _baseToString(value); } -var _mapToArray = mapToArray; +var toString_1 = toString; /** - * Converts `set` to an array of its values. + * Casts `value` to a path array if it's not one. * * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the values. + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. */ -function setToArray(set) { - var index = -1, - result = Array(set.size); - set.forEach(function (value) { - result[++index] = value; - }); - return result; -} -var _setToArray = setToArray; +function castPath(value, object) { + if (isArray_1(value)) { + return value; + } -/** Used to compose bitmasks for value comparisons. */ + return _isKey(value, object) ? [value] : _stringToPath(toString_1(value)); +} -var COMPARE_PARTIAL_FLAG$1 = 1, - COMPARE_UNORDERED_FLAG$1 = 2; -/** `Object#toString` result references. */ +var _castPath = castPath; -var boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - mapTag = '[object Map]', - numberTag = '[object Number]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - symbolTag = '[object Symbol]'; -var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]'; -/** Used to convert symbols to primitives and strings. */ +/** Used as references for various `Number` constants. */ -var symbolProto = _Symbol ? _Symbol.prototype : undefined, - symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; +var INFINITY$1 = 1 / 0; /** - * A specialized version of `baseIsEqualDeep` for comparing objects of - * the same `toStringTag`. - * - * **Note:** This function only supports comparing values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * Converts `value` to a string key if it's not a string or symbol. * * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {string} tag The `toStringTag` of the objects to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. */ -function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { - switch (tag) { - case dataViewTag: - if (object.byteLength != other.byteLength || object.byteOffset != other.byteOffset) { - return false; - } - - object = object.buffer; - other = other.buffer; - - case arrayBufferTag: - if (object.byteLength != other.byteLength || !equalFunc(new _Uint8Array(object), new _Uint8Array(other))) { - return false; - } - - return true; - - case boolTag: - case dateTag: - case numberTag: - // Coerce booleans to `1` or `0` and dates to milliseconds. - // Invalid dates are coerced to `NaN`. - return eq_1(+object, +other); - - case errorTag: - return object.name == other.name && object.message == other.message; - - case regexpTag: - case stringTag: - // Coerce regexes to strings and treat strings, primitives and objects, - // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring - // for more details. - return object == other + ''; +function toKey(value) { + if (typeof value == 'string' || isSymbol_1(value)) { + return value; + } - case mapTag: - var convert = _mapToArray; + var result = value + ''; + return result == '0' && 1 / value == -INFINITY$1 ? '-0' : result; +} - case setTag: - var isPartial = bitmask & COMPARE_PARTIAL_FLAG$1; - convert || (convert = _setToArray); +var _toKey = toKey; - if (object.size != other.size && !isPartial) { - return false; - } // Assume cyclic values are equal. +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = _castPath(path, object); + var index = 0, + length = path.length; - var stacked = stack.get(object); + while (object != null && index < length) { + object = object[_toKey(path[index++])]; + } - if (stacked) { - return stacked == other; - } + return index && index == length ? object : undefined; +} - bitmask |= COMPARE_UNORDERED_FLAG$1; // Recursively compare objects (susceptible to call stack limits). +var _baseGet = baseGet; - stack.set(object, other); - var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); - stack['delete'](object); - return result; +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ - case symbolTag: - if (symbolValueOf) { - return symbolValueOf.call(object) == symbolValueOf.call(other); - } +function get$1(object, path, defaultValue) { + var result = object == null ? undefined : _baseGet(object, path); + return result === undefined ? defaultValue : result; +} - } +var get_1 = get$1; - return false; +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); } -var _equalByTag = equalByTag; +var _baseHasIn = baseHasIn; /** - * Appends the elements of `values` to `array`. + * Checks if `path` exists on `object`. * * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. */ -function arrayPush(array, values) { + +function hasPath(object, path, hasFunc) { + path = _castPath(path, object); var index = -1, - length = values.length, - offset = array.length; + length = path.length, + result = false; while (++index < length) { - array[offset + index] = values[index]; + var key = _toKey(path[index]); + + if (!(result = object != null && hasFunc(object, key))) { + break; + } + + object = object[key]; } - return array; + if (result || ++index != length) { + return result; + } + + length = object == null ? 0 : object.length; + return !!length && isLength_1(length) && _isIndex(key, length) && (isArray_1(object) || isArguments_1(object)); } -var _arrayPush = arrayPush; +var _hasPath = hasPath; /** - * Checks if `value` is classified as an `Array` object. + * Checks if `path` is a direct or inherited property of `object`. * * @static * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. * @example * - * _.isArray([1, 2, 3]); + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); * // => true * - * _.isArray(document.body.children); - * // => false + * _.hasIn(object, 'a.b'); + * // => true * - * _.isArray('abc'); - * // => false + * _.hasIn(object, ['a', 'b']); + * // => true * - * _.isArray(_.noop); + * _.hasIn(object, 'b'); * // => false */ -var isArray$1 = Array.isArray; -var isArray_1 = isArray$1; - -/** - * The base implementation of `getAllKeys` and `getAllKeysIn` which uses - * `keysFunc` and `symbolsFunc` to get the enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Function} keysFunc The function to get the keys of `object`. - * @param {Function} symbolsFunc The function to get the symbols of `object`. - * @returns {Array} Returns the array of property names and symbols. - */ -function baseGetAllKeys(object, keysFunc, symbolsFunc) { - var result = keysFunc(object); - return isArray_1(object) ? result : _arrayPush(result, symbolsFunc(object)); +function hasIn(object, path) { + return object != null && _hasPath(object, path, _baseHasIn); } -var _baseGetAllKeys = baseGetAllKeys; +var hasIn_1 = hasIn; + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG$5 = 1, + COMPARE_UNORDERED_FLAG$3 = 2; /** - * A specialized version of `_.filter` for arrays without support for - * iteratee shorthands. + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. * * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ -function arrayFilter(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ - if (predicate(value, index, array)) { - result[resIndex++] = value; - } +function baseMatchesProperty(path, srcValue) { + if (_isKey(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable(_toKey(path), srcValue); } - return result; + return function (object) { + var objValue = get_1(object, path); + return objValue === undefined && objValue === srcValue ? hasIn_1(object, path) : _baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$5 | COMPARE_UNORDERED_FLAG$3); + }; } -var _arrayFilter = arrayFilter; +var _baseMatchesProperty = baseMatchesProperty; /** - * This method returns a new empty array. + * This method returns the first argument it receives. * * @static + * @since 0.1.0 * @memberOf _ - * @since 4.13.0 * @category Util - * @returns {Array} Returns the new empty array. + * @param {*} value Any value. + * @returns {*} Returns `value`. * @example * - * var arrays = _.times(2, _.stubArray); - * - * console.log(arrays); - * // => [[], []] + * var object = { 'a': 1 }; * - * console.log(arrays[0] === arrays[1]); - * // => false + * console.log(_.identity(object) === object); + * // => true */ -function stubArray() { - return []; +function identity(value) { + return value; } -var stubArray_1 = stubArray; - -/** Used for built-in method references. */ - -var objectProto$5 = Object.prototype; -/** Built-in value references. */ - -var propertyIsEnumerable = objectProto$5.propertyIsEnumerable; -/* Built-in method references for those with the same name as other `lodash` methods. */ +var identity_1 = identity; -var nativeGetSymbols = Object.getOwnPropertySymbols; /** - * Creates an array of the own enumerable symbols of `object`. + * The base implementation of `_.property` without support for deep paths. * * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. */ +function baseProperty(key) { + return function (object) { + return object == null ? undefined : object[key]; + }; +} -var getSymbols = !nativeGetSymbols ? stubArray_1 : function (object) { - if (object == null) { - return []; - } - - object = Object(object); - return _arrayFilter(nativeGetSymbols(object), function (symbol) { - return propertyIsEnumerable.call(object, symbol); - }); -}; -var _getSymbols = getSymbols; +var _baseProperty = baseProperty; /** - * The base implementation of `_.times` without support for iteratee shorthands - * or max array length checks. + * A specialized version of `baseProperty` which supports deep paths. * * @private - * @param {number} n The number of times to invoke `iteratee`. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the array of results. + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. */ -function baseTimes(n, iteratee) { - var index = -1, - result = Array(n); - - while (++index < n) { - result[index] = iteratee(index); - } - return result; +function basePropertyDeep(path) { + return function (object) { + return _baseGet(object, path); + }; } -var _baseTimes = baseTimes; +var _basePropertyDeep = basePropertyDeep; /** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". + * Creates a function that returns the value at `path` of a given object. * * @static * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. * @example * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; * - * _.isObjectLike(_.noop); - * // => false + * _.map(objects, _.property('a.b')); + * // => [2, 1] * - * _.isObjectLike(null); - * // => false + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; -} -var isObjectLike_1 = isObjectLike; +function property(path) { + return _isKey(path) ? _baseProperty(_toKey(path)) : _basePropertyDeep(path); +} -/** `Object#toString` result references. */ +var property_1 = property; -var argsTag = '[object Arguments]'; /** - * The base implementation of `_.isArguments`. + * The base implementation of `_.iteratee`. * * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. */ -function baseIsArguments(value) { - return isObjectLike_1(value) && _baseGetTag(value) == argsTag; -} +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } -var _baseIsArguments = baseIsArguments; + if (value == null) { + return identity_1; + } -/** Used for built-in method references. */ + if (typeof value == 'object') { + return isArray_1(value) ? _baseMatchesProperty(value[0], value[1]) : _baseMatches(value); + } -var objectProto$6 = Object.prototype; -/** Used to check objects for own properties. */ + return property_1(value); +} -var hasOwnProperty$6 = objectProto$6.hasOwnProperty; -/** Built-in value references. */ +var _baseIteratee = baseIteratee; -var propertyIsEnumerable$1 = objectProto$6.propertyIsEnumerable; /** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. * - * _.isArguments([1, 2, 3]); - * // => false + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); -var isArguments = _baseIsArguments(function () { - return arguments; -}()) ? _baseIsArguments : function (value) { - return isObjectLike_1(value) && hasOwnProperty$6.call(value, 'callee') && !propertyIsEnumerable$1.call(value, 'callee'); -}; -var isArguments_1 = isArguments; + while (fromRight ? index-- : ++index < length) { + if (predicate(array[index], index, array)) { + return index; + } + } + + return -1; +} + +var _baseFindIndex = baseFindIndex; /** - * This method returns `false`. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {boolean} Returns `false`. - * @example + * The base implementation of `_.isNaN` without support for number objects. * - * _.times(2, _.stubFalse); - * // => [false, false] + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. */ -function stubFalse() { - return false; +function baseIsNaN(value) { + return value !== value; } -var stubFalse_1 = stubFalse; +var _baseIsNaN = baseIsNaN; -var isBuffer_1 = createCommonjsModule(function (module, exports) { - /** Detect free variable `exports`. */ - var freeExports = exports && !exports.nodeType && exports; - /** Detect free variable `module`. */ +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; - var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; - /** Detect the popular CommonJS extension `module.exports`. */ + while (++index < length) { + if (array[index] === value) { + return index; + } + } - var moduleExports = freeModule && freeModule.exports === freeExports; - /** Built-in value references. */ + return -1; +} - var Buffer = moduleExports ? _root.Buffer : undefined; - /* Built-in method references for those with the same name as other `lodash` methods. */ +var _strictIndexOf = strictIndexOf; - var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; - /** - * Checks if `value` is a buffer. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. - * @example - * - * _.isBuffer(new Buffer(2)); - * // => true - * - * _.isBuffer(new Uint8Array(2)); - * // => false - */ +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ - var isBuffer = nativeIsBuffer || stubFalse_1; - module.exports = isBuffer; -}); +function baseIndexOf(array, value, fromIndex) { + return value === value ? _strictIndexOf(array, value, fromIndex) : _baseFindIndex(array, _baseIsNaN, fromIndex); +} -/** Used as references for various `Number` constants. */ -var MAX_SAFE_INTEGER$2 = 9007199254740991; -/** Used to detect unsigned integer values. */ +var _baseIndexOf = baseIndexOf; -var reIsUint = /^(?:0|[1-9]\d*)$/; /** - * Checks if `value` is a valid array-like index. + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. * * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. */ -function isIndex(value, length) { - var type = typeof value; - length = length == null ? MAX_SAFE_INTEGER$2 : length; - return !!length && (type == 'number' || type != 'symbol' && reIsUint.test(value)) && value > -1 && value % 1 == 0 && value < length; +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; } -var _isIndex = isIndex; +var _arrayIncludes = arrayIncludes; -/** Used as references for various `Number` constants. */ -var MAX_SAFE_INTEGER$3 = 9007199254740991; /** - * Checks if `value` is a valid array-like length. + * This function is like `arrayIncludes` except that it accepts a comparator. * - * **Note:** This method is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + + return false; +} + +var _arrayIncludesWith = arrayIncludesWith; + +/** + * This method returns `undefined`. * * @static * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @since 2.3.0 + * @category Util * @example * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false + * _.times(2, _.noop); + * // => [undefined, undefined] */ - -function isLength(value) { - return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$3; +function noop() {// No operation performed. } -var isLength_1 = isLength; - -/** `Object#toString` result references. */ +var noop_1 = noop; -var argsTag$1 = '[object Arguments]', - arrayTag = '[object Array]', - boolTag$1 = '[object Boolean]', - dateTag$1 = '[object Date]', - errorTag$1 = '[object Error]', - funcTag$1 = '[object Function]', - mapTag$1 = '[object Map]', - numberTag$1 = '[object Number]', - objectTag = '[object Object]', - regexpTag$1 = '[object RegExp]', - setTag$1 = '[object Set]', - stringTag$1 = '[object String]', - weakMapTag = '[object WeakMap]'; -var arrayBufferTag$1 = '[object ArrayBuffer]', - dataViewTag$1 = '[object DataView]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; -/** Used to identify `toStringTag` values of typed arrays. */ +/** Used as references for various `Number` constants. */ -var typedArrayTags = {}; -typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true; -typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag$1] = typedArrayTags[boolTag$1] = typedArrayTags[dataViewTag$1] = typedArrayTags[dateTag$1] = typedArrayTags[errorTag$1] = typedArrayTags[funcTag$1] = typedArrayTags[mapTag$1] = typedArrayTags[numberTag$1] = typedArrayTags[objectTag] = typedArrayTags[regexpTag$1] = typedArrayTags[setTag$1] = typedArrayTags[stringTag$1] = typedArrayTags[weakMapTag] = false; +var INFINITY$2 = 1 / 0; /** - * The base implementation of `_.isTypedArray` without Node.js optimizations. + * Creates a set object of `values`. * * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. */ -function baseIsTypedArray(value) { - return isObjectLike_1(value) && isLength_1(value.length) && !!typedArrayTags[_baseGetTag(value)]; -} +var createSet = !(_Set && 1 / _setToArray(new _Set([, -0]))[1] == INFINITY$2) ? noop_1 : function (values) { + return new _Set(values); +}; +var _createSet = createSet; -var _baseIsTypedArray = baseIsTypedArray; +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE$1 = 200; /** - * The base implementation of `_.unary` without support for storing metadata. + * The base implementation of `_.uniqBy` without support for iteratee shorthands. * * @private - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. */ -function baseUnary(func) { - return function (value) { - return func(value); - }; -} -var _baseUnary = baseUnary; +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; -var _nodeUtil = createCommonjsModule(function (module, exports) { - /** Detect free variable `exports`. */ - var freeExports = exports && !exports.nodeType && exports; - /** Detect free variable `module`. */ + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } else if (length >= LARGE_ARRAY_SIZE$1) { + var set = iteratee ? null : _createSet(array); - var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; - /** Detect the popular CommonJS extension `module.exports`. */ + if (set) { + return _setToArray(set); + } - var moduleExports = freeModule && freeModule.exports === freeExports; - /** Detect free variable `process` from Node.js. */ + isCommon = false; + includes = _cacheHas; + seen = new _SetCache(); + } else { + seen = iteratee ? [] : result; + } - var freeProcess = moduleExports && _freeGlobal.process; - /** Used to access faster Node.js helpers. */ + outer: while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + value = comparator || value !== 0 ? value : 0; - var nodeUtil = function () { - try { - // Use `util.types` for Node.js 10+. - var types = freeModule && freeModule.require && freeModule.require('util').types; + if (isCommon && computed === computed) { + var seenIndex = seen.length; - if (types) { - return types; - } // Legacy `process.binding('util')` for Node.js < 10. + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } - return freeProcess && freeProcess.binding && freeProcess.binding('util'); - } catch (e) {} - }(); + result.push(value); + } else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } - module.exports = nodeUtil; -}); + result.push(value); + } + } -/* Node.js helper references. */ + return result; +} + +var _baseUniq = baseUniq; -var nodeIsTypedArray = _nodeUtil && _nodeUtil.isTypedArray; /** - * Checks if `value` is classified as a typed array. + * This method is like `_.uniq` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * uniqueness is computed. The order of result values is determined by the + * order they occur in the array. The iteratee is invoked with one argument: + * (value). * * @static * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @since 4.0.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. * @example * - * _.isTypedArray(new Uint8Array); - * // => true + * _.uniqBy([2.1, 1.2, 2.3], Math.floor); + * // => [2.1, 1.2] * - * _.isTypedArray([]); - * // => false + * // The `_.property` iteratee shorthand. + * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] */ -var isTypedArray = nodeIsTypedArray ? _baseUnary(nodeIsTypedArray) : _baseIsTypedArray; -var isTypedArray_1 = isTypedArray; - -/** Used for built-in method references. */ +function uniqBy(array, iteratee) { + return array && array.length ? _baseUniq(array, _baseIteratee(iteratee)) : []; +} -var objectProto$7 = Object.prototype; -/** Used to check objects for own properties. */ +var uniqBy_1 = uniqBy; -var hasOwnProperty$7 = objectProto$7.hasOwnProperty; /** - * Creates an array of the enumerable property names of the array-like `value`. + * A specialized version of `baseAggregator` for arrays. * * @private - * @param {*} value The value to query. - * @param {boolean} inherited Specify returning inherited property names. - * @returns {Array} Returns the array of property names. + * @param {Array} [array] The array to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. */ +function arrayAggregator(array, setter, iteratee, accumulator) { + var index = -1, + length = array == null ? 0 : array.length; -function arrayLikeKeys(value, inherited) { - var isArr = isArray_1(value), - isArg = !isArr && isArguments_1(value), - isBuff = !isArr && !isArg && isBuffer_1(value), - isType = !isArr && !isArg && !isBuff && isTypedArray_1(value), - skipIndexes = isArr || isArg || isBuff || isType, - result = skipIndexes ? _baseTimes(value.length, String) : [], - length = result.length; - - for (var key in value) { - if ((inherited || hasOwnProperty$7.call(value, key)) && !(skipIndexes && ( // Safari 9 has enumerable `arguments.length` in strict mode. - key == 'length' || // Node.js 0.10 has enumerable non-index properties on buffers. - isBuff && (key == 'offset' || key == 'parent') || // PhantomJS 2 has enumerable non-index properties on typed arrays. - isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset') || // Skip index properties. - _isIndex(key, length)))) { - result.push(key); - } + while (++index < length) { + var value = array[index]; + setter(accumulator, value, iteratee(value), array); } - return result; + return accumulator; } -var _arrayLikeKeys = arrayLikeKeys; +var _arrayAggregator = arrayAggregator; -/** Used for built-in method references. */ -var objectProto$8 = Object.prototype; /** - * Checks if `value` is likely a prototype object. + * Creates a base function for methods like `_.forIn` and `_.forOwn`. * * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. */ +function createBaseFor(fromRight) { + return function (object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; -function isPrototype(value) { - var Ctor = value && value.constructor, - proto = typeof Ctor == 'function' && Ctor.prototype || objectProto$8; - return value === proto; + while (length--) { + var key = props[fromRight ? length : ++index]; + + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + + return object; + }; } -var _isPrototype = isPrototype; +var _createBaseFor = createBaseFor; /** - * Creates a unary function that invokes `func` with its argument transformed. + * The base implementation of `baseForOwn` which iterates over `object` + * properties returned by `keysFunc` and invokes `iteratee` for each property. + * Iteratee functions may exit iteration early by explicitly returning `false`. * * @private - * @param {Function} func The function to wrap. - * @param {Function} transform The argument transform. - * @returns {Function} Returns the new function. + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. */ -function overArg(func, transform) { - return function (arg) { - return func(transform(arg)); - }; -} - -var _overArg = overArg; -/* Built-in method references for those with the same name as other `lodash` methods. */ +var baseFor = _createBaseFor(); +var _baseFor = baseFor; -var nativeKeys = _overArg(Object.keys, Object); -var _nativeKeys = nativeKeys; +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ -/** Used for built-in method references. */ +function baseForOwn(object, iteratee) { + return object && _baseFor(object, iteratee, keys_1); +} -var objectProto$9 = Object.prototype; -/** Used to check objects for own properties. */ +var _baseForOwn = baseForOwn; -var hasOwnProperty$8 = objectProto$9.hasOwnProperty; /** - * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * Creates a `baseEach` or `baseEachRight` function. * * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. */ -function baseKeys(object) { - if (!_isPrototype(object)) { - return _nativeKeys(object); - } +function createBaseEach(eachFunc, fromRight) { + return function (collection, iteratee) { + if (collection == null) { + return collection; + } - var result = []; + if (!isArrayLike_1(collection)) { + return eachFunc(collection, iteratee); + } - for (var key in Object(object)) { - if (hasOwnProperty$8.call(object, key) && key != 'constructor') { - result.push(key); + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while (fromRight ? index-- : ++index < length) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } } - } - return result; + return collection; + }; } -var _baseKeys = baseKeys; +var _createBaseEach = createBaseEach; /** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true + * The base implementation of `_.forEach` without support for iteratee shorthands. * - * _.isArrayLike('abc'); - * // => true + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ + +var baseEach = _createBaseEach(_baseForOwn); +var _baseEach = baseEach; + +/** + * Aggregates elements of `collection` on `accumulator` with keys transformed + * by `iteratee` and values set by `setter`. * - * _.isArrayLike(_.noop); - * // => false + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. */ -function isArrayLike(value) { - return value != null && isLength_1(value.length) && !isFunction_1(value); +function baseAggregator(collection, setter, iteratee, accumulator) { + _baseEach(collection, function (value, key, collection) { + setter(accumulator, value, iteratee(value), collection); + }); + return accumulator; } -var isArrayLike_1 = isArrayLike; +var _baseAggregator = baseAggregator; /** - * Creates an array of the own enumerable property names of `object`. + * Creates a function like `_.groupBy`. * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * for more details. + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} [initializer] The accumulator object initializer. + * @returns {Function} Returns the new aggregator function. + */ + +function createAggregator(setter, initializer) { + return function (collection, iteratee) { + var func = isArray_1(collection) ? _arrayAggregator : _baseAggregator, + accumulator = initializer ? initializer() : {}; + return func(collection, setter, _baseIteratee(iteratee), accumulator); + }; +} + +var _createAggregator = createAggregator; + +/** + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, the second of which + * contains elements `predicate` returns falsey for. The predicate is + * invoked with one argument: (value). * * @static - * @since 0.1.0 * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. + * @since 3.0.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the array of grouped elements. * @example * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; * - * Foo.prototype.c = 3; + * _.partition(users, function(o) { return o.active; }); + * // => objects for [['fred'], ['barney', 'pebbles']] * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) + * // The `_.matches` iteratee shorthand. + * _.partition(users, { 'age': 1, 'active': false }); + * // => objects for [['pebbles'], ['barney', 'fred']] * - * _.keys('hi'); - * // => ['0', '1'] + * // The `_.matchesProperty` iteratee shorthand. + * _.partition(users, ['active', false]); + * // => objects for [['barney', 'pebbles'], ['fred']] + * + * // The `_.property` iteratee shorthand. + * _.partition(users, 'active'); + * // => objects for [['fred'], ['barney', 'pebbles']] */ -function keys(object) { - return isArrayLike_1(object) ? _arrayLikeKeys(object) : _baseKeys(object); -} +var partition = _createAggregator(function (result, value, key) { + result[key ? 0 : 1].push(value); +}, function () { + return [[], []]; +}); +var partition_1 = partition; -var keys_1 = keys; +var arrayUnion = (...arguments_) => { + return [...new Set([].concat(...arguments_))]; +}; -/** - * Creates an array of own enumerable property names and symbols of `object`. +/* + * merge2 + * https://github.com/teambition/merge2 * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. + * Copyright (c) 2014-2020 Teambition + * Licensed under the MIT license. */ -function getAllKeys(object) { - return _baseGetAllKeys(object, keys_1, _getSymbols); -} -var _getAllKeys = getAllKeys; +const PassThrough = stream_1__default['default'].PassThrough; +const slice$1 = Array.prototype.slice; +var merge2_1 = merge2; -/** Used to compose bitmasks for value comparisons. */ +function merge2() { + const streamsQueue = []; + const args = slice$1.call(arguments); + let merging = false; + let options = args[args.length - 1]; -var COMPARE_PARTIAL_FLAG$2 = 1; -/** Used for built-in method references. */ + if (options && !Array.isArray(options) && options.pipe == null) { + args.pop(); + } else { + options = {}; + } -var objectProto$a = Object.prototype; -/** Used to check objects for own properties. */ + const doEnd = options.end !== false; + const doPipeError = options.pipeError === true; -var hasOwnProperty$9 = objectProto$a.hasOwnProperty; -/** - * A specialized version of `baseIsEqualDeep` for objects with support for - * partial deep comparisons. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ + if (options.objectMode == null) { + options.objectMode = true; + } -function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2, - objProps = _getAllKeys(object), - objLength = objProps.length, - othProps = _getAllKeys(other), - othLength = othProps.length; + if (options.highWaterMark == null) { + options.highWaterMark = 64 * 1024; + } - if (objLength != othLength && !isPartial) { - return false; + const mergedStream = PassThrough(options); + + function addStream() { + for (let i = 0, len = arguments.length; i < len; i++) { + streamsQueue.push(pauseStreams(arguments[i], options)); + } + + mergeStream(); + return this; } - var index = objLength; + function mergeStream() { + if (merging) { + return; + } - while (index--) { - var key = objProps[index]; + merging = true; + let streams = streamsQueue.shift(); - if (!(isPartial ? key in other : hasOwnProperty$9.call(other, key))) { - return false; + if (!streams) { + process.nextTick(endStream); + return; } - } // Assume cyclic values are equal. + if (!Array.isArray(streams)) { + streams = [streams]; + } - var stacked = stack.get(object); + let pipesCount = streams.length + 1; - if (stacked && stack.get(other)) { - return stacked == other; - } + function next() { + if (--pipesCount > 0) { + return; + } - var result = true; - stack.set(object, other); - stack.set(other, object); - var skipCtor = isPartial; + merging = false; + mergeStream(); + } - while (++index < objLength) { - key = objProps[index]; - var objValue = object[key], - othValue = other[key]; + function pipe(stream) { + function onend() { + stream.removeListener('merge2UnpipeEnd', onend); + stream.removeListener('end', onend); - if (customizer) { - var compared = isPartial ? customizer(othValue, objValue, key, other, object, stack) : customizer(objValue, othValue, key, object, other, stack); - } // Recursively compare objects (susceptible to call stack limits). + if (doPipeError) { + stream.removeListener('error', onerror); + } + next(); + } - if (!(compared === undefined ? objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack) : compared)) { - result = false; - break; + function onerror(err) { + mergedStream.emit('error', err); + } // skip ended stream + + + if (stream._readableState.endEmitted) { + return next(); + } + + stream.on('merge2UnpipeEnd', onend); + stream.on('end', onend); + + if (doPipeError) { + stream.on('error', onerror); + } + + stream.pipe(mergedStream, { + end: false + }); // compatible for old stream + + stream.resume(); } - skipCtor || (skipCtor = key == 'constructor'); + for (let i = 0; i < streams.length; i++) { + pipe(streams[i]); + } + + next(); } - if (result && !skipCtor) { - var objCtor = object.constructor, - othCtor = other.constructor; // Non `Object` object instances with different constructors are not equal. + function endStream() { + merging = false; // emit 'queueDrain' when all streams merged. - if (objCtor != othCtor && 'constructor' in object && 'constructor' in other && !(typeof objCtor == 'function' && objCtor instanceof objCtor && typeof othCtor == 'function' && othCtor instanceof othCtor)) { - result = false; + mergedStream.emit('queueDrain'); + + if (doEnd) { + mergedStream.end(); } } - stack['delete'](object); - stack['delete'](other); - return result; -} + mergedStream.setMaxListeners(0); + mergedStream.add = addStream; + mergedStream.on('unpipe', function (stream) { + stream.emit('merge2UnpipeEnd'); + }); -var _equalObjects = equalObjects; + if (args.length) { + addStream.apply(null, args); + } -/* Built-in method references that are verified to be native. */ + return mergedStream; +} // check and pause streams for pipe. -var DataView = _getNative(_root, 'DataView'); -var _DataView = DataView; -/* Built-in method references that are verified to be native. */ +function pauseStreams(streams, options) { + if (!Array.isArray(streams)) { + // Backwards-compat with old-style streams + if (!streams._readableState && streams.pipe) { + streams = streams.pipe(PassThrough(options)); + } -var Promise$1 = _getNative(_root, 'Promise'); -var _Promise = Promise$1; + if (!streams._readableState || !streams.pause || !streams.pipe) { + throw new Error('Only readable stream can be merged.'); + } -/* Built-in method references that are verified to be native. */ + streams.pause(); + } else { + for (let i = 0, len = streams.length; i < len; i++) { + streams[i] = pauseStreams(streams[i], options); + } + } -var Set$1 = _getNative(_root, 'Set'); -var _Set = Set$1; + return streams; +} -/* Built-in method references that are verified to be native. */ +var array$2 = createCommonjsModule(function (module, exports) { -var WeakMap$1 = _getNative(_root, 'WeakMap'); -var _WeakMap = WeakMap$1; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.splitWhen = exports.flatten = void 0; -/** `Object#toString` result references. */ + function flatten(items) { + return items.reduce((collection, item) => [].concat(collection, item), []); + } -var mapTag$2 = '[object Map]', - objectTag$1 = '[object Object]', - promiseTag = '[object Promise]', - setTag$2 = '[object Set]', - weakMapTag$1 = '[object WeakMap]'; -var dataViewTag$2 = '[object DataView]'; -/** Used to detect maps, sets, and weakmaps. */ + exports.flatten = flatten; -var dataViewCtorString = _toSource(_DataView), - mapCtorString = _toSource(_Map), - promiseCtorString = _toSource(_Promise), - setCtorString = _toSource(_Set), - weakMapCtorString = _toSource(_WeakMap); -/** - * Gets the `toStringTag` of `value`. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ + function splitWhen(items, predicate) { + const result = [[]]; + let groupIndex = 0; -var getTag = _baseGetTag; // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. + for (const item of items) { + if (predicate(item)) { + groupIndex++; + result[groupIndex] = []; + } else { + result[groupIndex].push(item); + } + } -if (_DataView && getTag(new _DataView(new ArrayBuffer(1))) != dataViewTag$2 || _Map && getTag(new _Map()) != mapTag$2 || _Promise && getTag(_Promise.resolve()) != promiseTag || _Set && getTag(new _Set()) != setTag$2 || _WeakMap && getTag(new _WeakMap()) != weakMapTag$1) { - getTag = function (value) { - var result = _baseGetTag(value), - Ctor = result == objectTag$1 ? value.constructor : undefined, - ctorString = Ctor ? _toSource(Ctor) : ''; + return result; + } - if (ctorString) { - switch (ctorString) { - case dataViewCtorString: - return dataViewTag$2; + exports.splitWhen = splitWhen; +}); + +var errno = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.isEnoentCodeError = void 0; + + function isEnoentCodeError(error) { + return error.code === 'ENOENT'; + } - case mapCtorString: - return mapTag$2; + exports.isEnoentCodeError = isEnoentCodeError; +}); - case promiseCtorString: - return promiseTag; +var fs$2 = createCommonjsModule(function (module, exports) { - case setCtorString: - return setTag$2; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.createDirentFromStats = void 0; - case weakMapCtorString: - return weakMapTag$1; - } + class DirentFromStats { + constructor(name, stats) { + this.name = name; + this.isBlockDevice = stats.isBlockDevice.bind(stats); + this.isCharacterDevice = stats.isCharacterDevice.bind(stats); + this.isDirectory = stats.isDirectory.bind(stats); + this.isFIFO = stats.isFIFO.bind(stats); + this.isFile = stats.isFile.bind(stats); + this.isSocket = stats.isSocket.bind(stats); + this.isSymbolicLink = stats.isSymbolicLink.bind(stats); } - return result; - }; -} - -var _getTag = getTag; + } -/** Used to compose bitmasks for value comparisons. */ + function createDirentFromStats(name, stats) { + return new DirentFromStats(name, stats); + } -var COMPARE_PARTIAL_FLAG$3 = 1; -/** `Object#toString` result references. */ + exports.createDirentFromStats = createDirentFromStats; +}); -var argsTag$2 = '[object Arguments]', - arrayTag$1 = '[object Array]', - objectTag$2 = '[object Object]'; -/** Used for built-in method references. */ +var path_1 = createCommonjsModule(function (module, exports) { -var objectProto$b = Object.prototype; -/** Used to check objects for own properties. */ + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.removeLeadingDotSegment = exports.escape = exports.makeAbsolute = exports.unixify = void 0; + const LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2; // ./ or .\\ -var hasOwnProperty$a = objectProto$b.hasOwnProperty; -/** - * A specialized version of `baseIsEqual` for arrays and objects which performs - * deep comparisons and tracks traversed objects enabling objects with circular - * references to be compared. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} [stack] Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ + const UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()*?[\]{|}]|^!|[!+@](?=\())/g; + /** + * Designed to work only with simple paths: `dir\\file`. + */ -function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { - var objIsArr = isArray_1(object), - othIsArr = isArray_1(other), - objTag = objIsArr ? arrayTag$1 : _getTag(object), - othTag = othIsArr ? arrayTag$1 : _getTag(other); - objTag = objTag == argsTag$2 ? objectTag$2 : objTag; - othTag = othTag == argsTag$2 ? objectTag$2 : othTag; - var objIsObj = objTag == objectTag$2, - othIsObj = othTag == objectTag$2, - isSameTag = objTag == othTag; + function unixify(filepath) { + return filepath.replace(/\\/g, '/'); + } - if (isSameTag && isBuffer_1(object)) { - if (!isBuffer_1(other)) { - return false; - } + exports.unixify = unixify; - objIsArr = true; - objIsObj = false; + function makeAbsolute(cwd, filepath) { + return path__default['default'].resolve(cwd, filepath); } - if (isSameTag && !objIsObj) { - stack || (stack = new _Stack()); - return objIsArr || isTypedArray_1(object) ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + exports.makeAbsolute = makeAbsolute; + + function escape(pattern) { + return pattern.replace(UNESCAPED_GLOB_SYMBOLS_RE, '\\$2'); } - if (!(bitmask & COMPARE_PARTIAL_FLAG$3)) { - var objIsWrapped = objIsObj && hasOwnProperty$a.call(object, '__wrapped__'), - othIsWrapped = othIsObj && hasOwnProperty$a.call(other, '__wrapped__'); + exports.escape = escape; - if (objIsWrapped || othIsWrapped) { - var objUnwrapped = objIsWrapped ? object.value() : object, - othUnwrapped = othIsWrapped ? other.value() : other; - stack || (stack = new _Stack()); - return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + function removeLeadingDotSegment(entry) { + // We do not use `startsWith` because this is 10x slower than current implementation for some cases. + // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with + if (entry.charAt(0) === '.') { + const secondCharactery = entry.charAt(1); + + if (secondCharactery === '/' || secondCharactery === '\\') { + return entry.slice(LEADING_DOT_SEGMENT_CHARACTERS_COUNT); + } } - } - if (!isSameTag) { - return false; + return entry; } - stack || (stack = new _Stack()); - return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); -} - -var _baseIsEqualDeep = baseIsEqualDeep; + exports.removeLeadingDotSegment = removeLeadingDotSegment; +}); -/** - * The base implementation of `_.isEqual` which supports partial comparisons - * and tracks traversed objects. +/*! + * is-extglob * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {boolean} bitmask The bitmask flags. - * 1 - Unordered comparison - * 2 - Partial comparison - * @param {Function} [customizer] The function to customize comparisons. - * @param {Object} [stack] Tracks traversed `value` and `other` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * Copyright (c) 2014-2016, Jon Schlinkert. + * Licensed under the MIT License. */ - -function baseIsEqual(value, other, bitmask, customizer, stack) { - if (value === other) { - return true; - } - - if (value == null || other == null || !isObjectLike_1(value) && !isObjectLike_1(other)) { - return value !== value && other !== other; +var isExtglob = function isExtglob(str) { + if (typeof str !== 'string' || str === '') { + return false; } - return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); -} + var match; -var _baseIsEqual = baseIsEqual; + while (match = /(\\).|([@?!+*]\(.*\))/g.exec(str)) { + if (match[2]) return true; + str = str.slice(match.index + match[0].length); + } -/** Used to compose bitmasks for value comparisons. */ + return false; +}; -var COMPARE_PARTIAL_FLAG$4 = 1, - COMPARE_UNORDERED_FLAG$2 = 2; -/** - * The base implementation of `_.isMatch` without support for iteratee shorthands. +/*! + * is-glob * - * @private - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Array} matchData The property names, values, and compare flags to match. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. */ -function baseIsMatch(object, source, matchData, customizer) { - var index = matchData.length, - length = index, - noCustomizer = !customizer; +var chars = { + '{': '}', + '(': ')', + '[': ']' +}; +var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; +var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; - if (object == null) { - return !length; +var isGlob = function isGlob(str, options) { + if (typeof str !== 'string' || str === '') { + return false; } - object = Object(object); + if (isExtglob(str)) { + return true; + } - while (index--) { - var data = matchData[index]; + var regex = strictRegex; + var match; // optionally relax regex - if (noCustomizer && data[2] ? data[1] !== object[data[0]] : !(data[0] in object)) { - return false; - } + if (options && options.strict === false) { + regex = relaxedRegex; } - while (++index < length) { - data = matchData[index]; - var key = data[0], - objValue = object[key], - srcValue = data[1]; + 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 - if (noCustomizer && data[2]) { - if (objValue === undefined && !(key in object)) { - return false; - } - } else { - var stack = new _Stack(); + var open = match[1]; + var close = open ? chars[open] : null; - if (customizer) { - var result = customizer(objValue, srcValue, key, object, source, stack); - } + if (open && close) { + var n = str.indexOf(close, idx); - if (!(result === undefined ? _baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$4 | COMPARE_UNORDERED_FLAG$2, customizer, stack) : result)) { - return false; + if (n !== -1) { + idx = n + 1; } } - } - return true; -} + str = str.slice(idx); + } -var _baseIsMatch = baseIsMatch; + return false; +}; +var pathPosixDirname = path__default['default'].posix.dirname; +var isWin32 = os__default['default'].platform() === 'win32'; +var slash = '/'; +var backslash = /\\/g; +var enclosure = /[\{\[].*[\/]*.*[\}\]]$/; +var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/; +var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g; /** - * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` if suitable for strict - * equality comparisons, else `false`. + * @param {string} str + * @param {Object} opts + * @param {boolean} [opts.flipBackslashes=true] */ -function isStrictComparable(value) { - return value === value && !isObject_1(value); -} +var globParent = function globParent(str, opts) { + var options = Object.assign({ + flipBackslashes: true + }, opts); // flip windows path separators -var _isStrictComparable = isStrictComparable; + if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) { + str = str.replace(backslash, slash); + } // special case for strings ending in enclosure containing path separator -/** - * Gets the property names, values, and compare flags of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the match data of `object`. - */ -function getMatchData(object) { - var result = keys_1(object), - length = result.length; + if (enclosure.test(str)) { + str += slash; + } // preserves full path in case of trailing path separator - while (length--) { - var key = result[length], - value = object[key]; - result[length] = [key, value, _isStrictComparable(value)]; - } - return result; -} + str += 'a'; // remove path parts that are globby -var _getMatchData = getMatchData; + do { + str = pathPosixDirname(str); + } while (isGlob(str) || globby.test(str)); // remove escape chars and return result -/** - * A specialized version of `matchesProperty` for source values suitable - * for strict equality comparisons, i.e. `===`. - * - * @private - * @param {string} key The key of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ -function matchesStrictComparable(key, srcValue) { - return function (object) { - if (object == null) { - return false; + + return str.replace(escaped, '$1'); +}; + +var utils$1 = createCommonjsModule(function (module, exports) { + + exports.isInteger = num => { + if (typeof num === 'number') { + return Number.isInteger(num); } - return object[key] === srcValue && (srcValue !== undefined || key in Object(object)); + if (typeof num === 'string' && num.trim() !== '') { + return Number.isInteger(Number(num)); + } + + return false; }; -} + /** + * Find a node of the given type + */ -var _matchesStrictComparable = matchesStrictComparable; -/** - * The base implementation of `_.matches` which doesn't clone `source`. - * - * @private - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new spec function. - */ + exports.find = (node, type) => node.nodes.find(node => node.type === type); + /** + * Find a node of the given type + */ -function baseMatches(source) { - var matchData = _getMatchData(source); - if (matchData.length == 1 && matchData[0][2]) { - return _matchesStrictComparable(matchData[0][0], matchData[0][1]); - } + 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 + */ - return function (object) { - return object === source || _baseIsMatch(object, source, matchData); + + 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 + */ -var _baseMatches = baseMatches; -/** `Object#toString` result references. */ + exports.encloseBrace = node => { + if (node.type !== 'brace') return false; -var symbolTag$1 = '[object Symbol]'; -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ + if (node.commas >> 0 + node.ranges >> 0 === 0) { + node.invalid = true; + return true; + } -function isSymbol(value) { - return typeof value == 'symbol' || isObjectLike_1(value) && _baseGetTag(value) == symbolTag$1; -} + return false; + }; + /** + * Returns true if a brace node is invalid. + */ -var isSymbol_1 = isSymbol; -/** Used to match property names within property paths. */ + exports.isInvalidBrace = block => { + if (block.type !== 'brace') return false; + if (block.invalid === true || block.dollar) return true; -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; -/** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ + 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; + } -function isKey(value, object) { - if (isArray_1(value)) { return false; - } + }; + /** + * Returns true if a node is an open or close node + */ - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || value == null || isSymbol_1(value)) { - return true; - } + exports.isOpenOrClose = node => { + if (node.type === 'open' || node.type === 'close') { + return true; + } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || object != null && value in Object(object); -} + return node.open === true || node.close === true; + }; + /** + * Reduce an array of text nodes. + */ -var _isKey = isKey; -/** Error message constants. */ + 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 + */ -var FUNC_ERROR_TEXT = 'Expected a function'; -/** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] - * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; - */ -function memoize(func, resolver) { - if (typeof func != 'function' || resolver != null && typeof resolver != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } + exports.flatten = (...args) => { + const result = []; - var memoized = function () { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; + 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); + } - if (cache.has(key)) { - return cache.get(key); - } + return result; + }; - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; + flat(args); return result; }; +}); - memoized.cache = new (memoize.Cache || _MapCache)(); - return memoized; -} // Expose `MapCache`. +var stringify$1 = (ast, options = {}) => { + let stringify = (node, parent = {}) => { + let invalidBlock = options.escapeInvalid && utils$1.isInvalidBrace(parent); + let invalidNode = node.invalid === true && options.escapeInvalid === true; + let output = ''; + if (node.value) { + if ((invalidBlock || invalidNode) && utils$1.isOpenOrClose(node)) { + return '\\' + node.value; + } -memoize.Cache = _MapCache; -var memoize_1 = memoize; + return node.value; + } -/** Used as the maximum memoize cache size. */ + if (node.value) { + return node.value; + } -var MAX_MEMOIZE_SIZE = 500; -/** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. + if (node.nodes) { + for (let child of node.nodes) { + output += stringify(child); + } + } + + return output; + }; + + return stringify(ast); +}; + +/*! + * is-number * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. + * Copyright (c) 2014-present, Jon Schlinkert. + * Released under the MIT License. */ -function memoizeCapped(func) { - var result = memoize_1(func, function (key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - - return key; - }); - var cache = result.cache; - return result; -} +var isNumber = function (num) { + if (typeof num === 'number') { + return num - num === 0; + } -var _memoizeCapped = memoizeCapped; + if (typeof num === 'string' && num.trim() !== '') { + return Number.isFinite ? Number.isFinite(+num) : isFinite(+num); + } -/** Used to match property names within property paths. */ + return false; +}; -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; -/** Used to match backslashes in property paths. */ +const toRegexRange = (min, max, options) => { + if (isNumber(min) === false) { + throw new TypeError('toRegexRange: expected the first argument to be a number'); + } -var reEscapeChar = /\\(\\)?/g; -/** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ + if (max === void 0 || min === max) { + return String(min); + } -var stringToPath = _memoizeCapped(function (string) { - var result = []; + if (isNumber(max) === false) { + throw new TypeError('toRegexRange: expected the second argument to be a number.'); + } - if (string.charCodeAt(0) === 46 - /* . */ - ) { - result.push(''); - } + let opts = Object.assign({ + relaxZeros: true + }, options); - string.replace(rePropName, function (match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : number || match); - }); - return result; -}); -var _stringToPath = stringToPath; + if (typeof opts.strictZeros === 'boolean') { + opts.relaxZeros = opts.strictZeros === false; + } -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); + 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; - while (++index < length) { - result[index] = iteratee(array[index], index, array); + if (toRegexRange.cache.hasOwnProperty(cacheKey)) { + return toRegexRange.cache[cacheKey].result; } - return result; -} + let a = Math.min(min, max); + let b = Math.max(min, max); -var _arrayMap = arrayMap; + if (Math.abs(a - b) === 1) { + let result = min + '|' + max; -/** Used as references for various `Number` constants. */ + if (opts.capture) { + return `(${result})`; + } -var INFINITY = 1 / 0; -/** Used to convert symbols to primitives and strings. */ + if (opts.wrap === false) { + return result; + } -var symbolProto$1 = _Symbol ? _Symbol.prototype : undefined, - symbolToString = symbolProto$1 ? symbolProto$1.toString : undefined; -/** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ + return `(?:${result})`; + } -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; + 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 (isArray_1(value)) { - // Recursively convert values (susceptible to call stack limits). - return _arrayMap(value, baseToString) + ''; + if (a < 0) { + let newMin = b < 0 ? Math.abs(b) : 1; + negatives = splitToPatterns(newMin, Math.abs(a), state, opts); + a = state.a = 0; } - if (isSymbol_1(value)) { - return symbolToString ? symbolToString.call(value) : ''; + if (b >= 0) { + positives = splitToPatterns(a, b, state, opts); } - var result = value + ''; - return result == '0' && 1 / value == -INFINITY ? '-0' : result; -} + state.negatives = negatives; + state.positives = positives; + state.result = collatePatterns(negatives, positives); -var _baseToString = baseToString; + if (opts.capture === true) { + state.result = `(${state.result})`; + } else if (opts.wrap !== false && positives.length + negatives.length > 1) { + state.result = `(?:${state.result})`; + } -/** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ + toRegexRange.cache[cacheKey] = state; + return state.result; +}; -function toString(value) { - return value == null ? '' : _baseToString(value); +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('|'); } -var toString_1 = toString; +function splitToRanges(min, max) { + let nines = 1; + let zeros = 1; + let stop = countNines(min, nines); + let stops = new Set([max]); -/** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ + while (min <= stop && stop <= max) { + stops.add(stop); + nines += 1; + stop = countNines(min, nines); + } -function castPath(value, object) { - if (isArray_1(value)) { - return value; + stop = countZeros(max + 1, zeros) - 1; + + while (min < stop && stop <= max) { + stops.add(stop); + zeros += 1; + stop = countZeros(max + 1, zeros) - 1; } - return _isKey(value, object) ? [value] : _stringToPath(toString_1(value)); + stops = [...stops]; + stops.sort(compare$1); + return stops; } +/** + * Convert a range to a regex pattern + * @param {Number} `start` + * @param {Number} `stop` + * @return {String} + */ -var _castPath = castPath; -/** Used as references for various `Number` constants. */ +function rangeToPattern(start, stop, options) { + if (start === stop) { + return { + pattern: start, + count: [], + digits: 0 + }; + } -var INFINITY$1 = 1 / 0; -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ + let zipped = zip(start, stop); + let digits = zipped.length; + let pattern = ''; + let count = 0; -function toKey(value) { - if (typeof value == 'string' || isSymbol_1(value)) { - return value; + 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++; + } } - var result = value + ''; - return result == '0' && 1 / value == -INFINITY$1 ? '-0' : result; + if (count) { + pattern += options.shorthand === true ? '\\d' : '[0-9]'; + } + + return { + pattern, + count: [count], + digits + }; } -var _toKey = toKey; +function splitToPatterns(min, max, tok, options) { + let ranges = splitToRanges(min, max); + let tokens = []; + let start = min; + let prev; -/** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ + for (let i = 0; i < ranges.length; i++) { + let max = ranges[i]; + let obj = rangeToPattern(String(start), String(max), options); + let zeros = ''; -function baseGet(object, path) { - path = _castPath(path, object); - var index = 0, - length = path.length; + if (!tok.isPadded && prev && prev.pattern === obj.pattern) { + if (prev.count.length > 1) { + prev.count.pop(); + } - while (object != null && index < length) { - object = object[_toKey(path[index++])]; + 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 index && index == length ? object : undefined; + return tokens; } -var _baseGet = baseGet; +function filterPatterns(arr, comparison, prefix, intersection, options) { + let result = []; -/** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ + for (let ele of arr) { + let { + string + } = ele; // only push if _both_ are negative... -function get$1(object, path, defaultValue) { - var result = object == null ? undefined : _baseGet(object, path); - return result === undefined ? defaultValue : result; -} + if (!intersection && !contains(comparison, 'string', string)) { + result.push(prefix + string); + } // or _both_ are positive -var get_1 = get$1; + if (intersection && contains(comparison, 'string', string)) { + result.push(prefix + string); + } + } + + return result; +} /** - * The base implementation of `_.hasIn` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. + * Zip strings */ -function baseHasIn(object, key) { - return object != null && key in Object(object); + + +function zip(a, b) { + let arr = []; + + for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]); + + return arr; } -var _baseHasIn = baseHasIn; +function compare$1(a, b) { + return a > b ? 1 : b > a ? -1 : 0; +} -/** - * Checks if `path` exists on `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @param {Function} hasFunc The function to check properties. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - */ +function contains(arr, key, val) { + return arr.some(ele => ele[key] === val); +} -function hasPath(object, path, hasFunc) { - path = _castPath(path, object); - var index = -1, - length = path.length, - result = false; +function countNines(min, len) { + return Number(String(min).slice(0, -len) + '9'.repeat(len)); +} - while (++index < length) { - var key = _toKey(path[index]); +function countZeros(integer, zeros) { + return integer - integer % Math.pow(10, zeros); +} - if (!(result = object != null && hasFunc(object, key))) { - break; - } +function toQuantifier(digits) { + let [start = 0, stop = ''] = digits; - object = object[key]; + if (stop || start > 1) { + return `{${start + (stop ? ',' + stop : '')}}`; } - if (result || ++index != length) { - return result; - } + return ''; +} - length = object == null ? 0 : object.length; - return !!length && isLength_1(length) && _isIndex(key, length) && (isArray_1(object) || isArguments_1(object)); +function toCharacterClass(a, b, options) { + return `[${a}${b - a === 1 ? '' : '-'}${b}]`; } -var _hasPath = hasPath; +function hasPadding(str) { + return /^-?(0+)\d/.test(str); +} -/** - * Checks if `path` is a direct or inherited property of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.hasIn(object, 'a'); - * // => true - * - * _.hasIn(object, 'a.b'); - * // => true - * - * _.hasIn(object, ['a', 'b']); - * // => true - * - * _.hasIn(object, 'b'); - * // => false - */ +function padZeros(value, tok, options) { + if (!tok.isPadded) { + return value; + } -function hasIn(object, path) { - return object != null && _hasPath(object, path, _baseHasIn); -} + let diff = Math.abs(tok.maxLen - String(value).length); + let relax = options.relaxZeros !== false; + + switch (diff) { + case 0: + return ''; -var hasIn_1 = hasIn; + case 1: + return relax ? '0?' : '0'; -/** Used to compose bitmasks for value comparisons. */ + case 2: + return relax ? '0{0,2}' : '00'; -var COMPARE_PARTIAL_FLAG$5 = 1, - COMPARE_UNORDERED_FLAG$3 = 2; + default: + { + return relax ? `0{0,${diff}}` : `0{${diff}}`; + } + } +} /** - * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. - * - * @private - * @param {string} path The path of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. + * Cache */ -function baseMatchesProperty(path, srcValue) { - if (_isKey(path) && _isStrictComparable(srcValue)) { - return _matchesStrictComparable(_toKey(path), srcValue); - } - - return function (object) { - var objValue = get_1(object, path); - return objValue === undefined && objValue === srcValue ? hasIn_1(object, path) : _baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$5 | COMPARE_UNORDERED_FLAG$3); - }; -} -var _baseMatchesProperty = baseMatchesProperty; +toRegexRange.cache = {}; +toRegexRange.clearCache = () => toRegexRange.cache = {}; /** - * This method returns the first argument it receives. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {*} value Any value. - * @returns {*} Returns `value`. - * @example - * - * var object = { 'a': 1 }; - * - * console.log(_.identity(object) === object); - * // => true + * Expose `toRegexRange` */ -function identity(value) { - return value; -} -var identity_1 = identity; -/** - * The base implementation of `_.property` without support for deep paths. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new accessor function. - */ -function baseProperty(key) { - return function (object) { - return object == null ? undefined : object[key]; - }; -} +var toRegexRange_1 = toRegexRange; -var _baseProperty = baseProperty; +const isObject$1 = val => val !== null && typeof val === 'object' && !Array.isArray(val); -/** - * A specialized version of `baseProperty` which supports deep paths. - * - * @private - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - */ +const transform = toNumber => { + return value => toNumber === true ? Number(value) : String(value); +}; -function basePropertyDeep(path) { - return function (object) { - return _baseGet(object, path); - }; -} +const isValidValue = value => { + return typeof value === 'number' || typeof value === 'string' && value !== ''; +}; -var _basePropertyDeep = basePropertyDeep; +const isNumber$1 = num => Number.isInteger(+num); -/** - * Creates a function that returns the value at `path` of a given object. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Util - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - * @example - * - * var objects = [ - * { 'a': { 'b': 2 } }, - * { 'a': { 'b': 1 } } - * ]; - * - * _.map(objects, _.property('a.b')); - * // => [2, 1] - * - * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); - * // => [1, 2] - */ +const zeros = input => { + let value = `${input}`; + let index = -1; + if (value[0] === '-') value = value.slice(1); + if (value === '0') return false; -function property(path) { - return _isKey(path) ? _baseProperty(_toKey(path)) : _basePropertyDeep(path); -} + while (value[++index] === '0'); -var property_1 = property; + return index > 0; +}; -/** - * The base implementation of `_.iteratee`. - * - * @private - * @param {*} [value=_.identity] The value to convert to an iteratee. - * @returns {Function} Returns the iteratee. - */ +const stringify$2 = (start, end, options) => { + if (typeof start === 'string' || typeof end === 'string') { + return true; + } -function baseIteratee(value) { - // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. - // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. - if (typeof value == 'function') { - return value; + 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 (value == null) { - return identity_1; + if (toNumber === false) { + return String(input); } - if (typeof value == 'object') { - return isArray_1(value) ? _baseMatchesProperty(value[0], value[1]) : _baseMatches(value); + return input; +}; + +const toMaxLen = (input, maxLength) => { + let negative = input[0] === '-' ? '-' : ''; + + if (negative) { + input = input.slice(1); + maxLength--; } - return property_1(value); -} + while (input.length < maxLength) input = '0' + input; -var _baseIteratee = baseIteratee; + return negative ? '-' + input : input; +}; -/** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {number} fromIndex The index to search from. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function baseFindIndex(array, predicate, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 1 : -1); +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; - while (fromRight ? index-- : ++index < length) { - if (predicate(array[index], index, array)) { - return index; - } + if (parts.positives.length) { + positives = parts.positives.join('|'); } - return -1; -} + if (parts.negatives.length) { + negatives = `-(${prefix}${parts.negatives.join('|')})`; + } -var _baseFindIndex = baseFindIndex; + if (positives && negatives) { + result = `${positives}|${negatives}`; + } else { + result = positives || negatives; + } -/** - * The base implementation of `_.isNaN` without support for number objects. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - */ -function baseIsNaN(value) { - return value !== value; -} + if (options.wrap) { + return `(${prefix}${result})`; + } -var _baseIsNaN = baseIsNaN; + return result; +}; -/** - * A specialized version of `_.indexOf` which performs strict equality - * comparisons of values, i.e. `===`. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function strictIndexOf(array, value, fromIndex) { - var index = fromIndex - 1, - length = array.length; +const toRange = (a, b, isNumbers, options) => { + if (isNumbers) { + return toRegexRange_1(a, b, Object.assign({ + wrap: false + }, options)); + } - while (++index < length) { - if (array[index] === value) { - return index; - } + 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 -1; -} + return toRegexRange_1(start, end, options); +}; -var _strictIndexOf = strictIndexOf; +const rangeError = (...args) => { + return new RangeError('Invalid range arguments: ' + util__default['default'].inspect(...args)); +}; -/** - * The base implementation of `_.indexOf` without `fromIndex` bounds checks. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ +const invalidRange = (start, end, options) => { + if (options.strictRanges === true) throw rangeError([start, end]); + return []; +}; -function baseIndexOf(array, value, fromIndex) { - return value === value ? _strictIndexOf(array, value, fromIndex) : _baseFindIndex(array, _baseIsNaN, fromIndex); -} +const invalidStep = (step, options) => { + if (options.strictRanges === true) { + throw new TypeError(`Expected step "${step}" to be a number`); + } -var _baseIndexOf = baseIndexOf; + return []; +}; -/** - * A specialized version of `_.includes` for arrays without support for - * specifying an index to search from. - * - * @private - * @param {Array} [array] The array to inspect. - * @param {*} target The value to search for. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ +const fillNumbers = (start, end, step = 1, options = {}) => { + let a = Number(start); + let b = Number(end); -function arrayIncludes(array, value) { - var length = array == null ? 0 : array.length; - return !!length && _baseIndexOf(array, value, 0) > -1; -} + if (!Number.isInteger(a) || !Number.isInteger(b)) { + if (options.strictRanges === true) throw rangeError([start, end]); + return []; + } // fix negative zero -var _arrayIncludes = arrayIncludes; -/** - * This function is like `arrayIncludes` except that it accepts a comparator. - * - * @private - * @param {Array} [array] The array to inspect. - * @param {*} target The value to search for. - * @param {Function} comparator The comparator invoked per element. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ -function arrayIncludesWith(array, value, comparator) { - var index = -1, - length = array == null ? 0 : array.length; + 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$2(start, end, options) === false; + let format = options.transform || transform(toNumber); - while (++index < length) { - if (comparator(value, array[index])) { - return true; - } + if (options.toRegex && step === 1) { + return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options); } - return false; -} + let parts = { + negatives: [], + positives: [] + }; -var _arrayIncludesWith = arrayIncludesWith; + let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num)); -/** - * This method returns `undefined`. - * - * @static - * @memberOf _ - * @since 2.3.0 - * @category Util - * @example - * - * _.times(2, _.noop); - * // => [undefined, undefined] - */ -function noop() {// No operation performed. -} + let range = []; + let index = 0; -var noop_1 = noop; + while (descending ? a >= b : a <= b) { + if (options.toRegex === true && step > 1) { + push(a); + } else { + range.push(pad(format(a, index), maxLen, toNumber)); + } -/** Used as references for various `Number` constants. */ + a = descending ? a - step : a + step; + index++; + } -var INFINITY$2 = 1 / 0; -/** - * Creates a set object of `values`. - * - * @private - * @param {Array} values The values to add to the set. - * @returns {Object} Returns the new set. - */ + if (options.toRegex === true) { + return step > 1 ? toSequence(parts, options) : toRegex(range, null, Object.assign({ + wrap: false + }, options)); + } -var createSet = !(_Set && 1 / _setToArray(new _Set([, -0]))[1] == INFINITY$2) ? noop_1 : function (values) { - return new _Set(values); + return range; }; -var _createSet = createSet; -/** Used as the size to enable large array optimizations. */ +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); + } -var LARGE_ARRAY_SIZE$1 = 200; -/** - * The base implementation of `_.uniqBy` without support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new duplicate free array. - */ + let format = options.transform || (val => String.fromCharCode(val)); -function baseUniq(array, iteratee, comparator) { - var index = -1, - includes = _arrayIncludes, - length = array.length, - isCommon = true, - result = [], - seen = result; + 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 (comparator) { - isCommon = false; - includes = _arrayIncludesWith; - } else if (length >= LARGE_ARRAY_SIZE$1) { - var set = iteratee ? null : _createSet(array); + if (options.toRegex && step === 1) { + return toRange(min, max, false, options); + } - if (set) { - return _setToArray(set); - } + let range = []; + let index = 0; - isCommon = false; - includes = _cacheHas; - seen = new _SetCache(); - } else { - seen = iteratee ? [] : result; + while (descending ? a >= b : a <= b) { + range.push(format(a, index)); + a = descending ? a - step : a + step; + index++; } - outer: while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - value = comparator || value !== 0 ? value : 0; - - if (isCommon && computed === computed) { - var seenIndex = seen.length; + if (options.toRegex === true) { + return toRegex(range, null, { + wrap: false, + options + }); + } - while (seenIndex--) { - if (seen[seenIndex] === computed) { - continue outer; - } - } + return range; +}; - if (iteratee) { - seen.push(computed); - } +const fill$2 = (start, end, step, options = {}) => { + if (end == null && isValidValue(start)) { + return [start]; + } - result.push(value); - } else if (!includes(seen, computed, comparator)) { - if (seen !== result) { - seen.push(computed); - } + if (!isValidValue(start) || !isValidValue(end)) { + return invalidRange(start, end, options); + } - result.push(value); - } + if (typeof step === 'function') { + return fill$2(start, end, 1, { + transform: step + }); } - return result; -} + if (isObject$1(step)) { + return fill$2(start, end, 0, step); + } -var _baseUniq = baseUniq; + let opts = Object.assign({}, options); + if (opts.capture === true) opts.wrap = true; + step = step || opts.step || 1; -/** - * This method is like `_.uniq` except that it accepts `iteratee` which is - * invoked for each element in `array` to generate the criterion by which - * uniqueness is computed. The order of result values is determined by the - * order they occur in the array. The iteratee is invoked with one argument: - * (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.uniqBy([2.1, 1.2, 2.3], Math.floor); - * // => [2.1, 1.2] - * - * // The `_.property` iteratee shorthand. - * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ + if (!isNumber$1(step)) { + if (step != null && !isObject$1(step)) return invalidStep(step, opts); + return fill$2(start, end, 1, step); + } -function uniqBy(array, iteratee) { - return array && array.length ? _baseUniq(array, _baseIteratee(iteratee)) : []; -} + if (isNumber$1(start) && isNumber$1(end)) { + return fillNumbers(start, end, step, opts); + } -var uniqBy_1 = uniqBy; + return fillLetters(start, end, Math.max(Math.abs(step), 1), opts); +}; -/** - * A specialized version of `baseAggregator` for arrays. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform keys. - * @param {Object} accumulator The initial aggregated object. - * @returns {Function} Returns `accumulator`. - */ -function arrayAggregator(array, setter, iteratee, accumulator) { - var index = -1, - length = array == null ? 0 : array.length; +var fillRange = fill$2; - while (++index < length) { - var value = array[index]; - setter(accumulator, value, iteratee(value), array); - } +const compile = (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 = ''; - return accumulator; -} + if (node.isOpen === true) { + return prefix + node.value; + } -var _arrayAggregator = arrayAggregator; + if (node.isClose === true) { + return prefix + node.value; + } -/** - * Creates a base function for methods like `_.forIn` and `_.forOwn`. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ -function createBaseFor(fromRight) { - return function (object, iteratee, keysFunc) { - var index = -1, - iterable = Object(object), - props = keysFunc(object), - length = props.length; + if (node.type === 'open') { + return invalid ? prefix + node.value : '('; + } - while (length--) { - var key = props[fromRight ? length : ++index]; + if (node.type === 'close') { + return invalid ? prefix + node.value : ')'; + } - if (iteratee(iterable[key], key, iterable) === false) { - break; + 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 = fillRange(...args, Object.assign({}, options, { + wrap: false, + toRegex: true + })); + + if (range.length !== 0) { + return args.length > 1 && range.length > 1 ? `(${range})` : range; } } - return object; + if (node.nodes) { + for (let child of node.nodes) { + output += walk(child, node); + } + } + + return output; }; -} -var _createBaseFor = createBaseFor; + return walk(ast); +}; -/** - * The base implementation of `baseForOwn` which iterates over `object` - * properties returned by `keysFunc` and invokes `iteratee` for each property. - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ +var compile_1 = compile; -var baseFor = _createBaseFor(); -var _baseFor = baseFor; +const append = (queue = '', stash = '', enclose = false) => { + let result = []; + queue = [].concat(queue); + stash = [].concat(stash); + if (!stash.length) return queue; -/** - * The base implementation of `_.forOwn` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ + if (!queue.length) { + return enclose ? utils$1.flatten(stash).map(ele => `{${ele}}`) : stash; + } -function baseForOwn(object, iteratee) { - return object && _baseFor(object, iteratee, keys_1); -} + 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); + } + } + } -var _baseForOwn = baseForOwn; + return utils$1.flatten(result); +}; -/** - * Creates a `baseEach` or `baseEachRight` function. - * - * @private - * @param {Function} eachFunc The function to iterate over a collection. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ +const expand$1 = (ast, options = {}) => { + let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit; -function createBaseEach(eachFunc, fromRight) { - return function (collection, iteratee) { - if (collection == null) { - return collection; + 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 (!isArrayLike_1(collection)) { - return eachFunc(collection, iteratee); + if (node.invalid || node.dollar) { + q.push(append(q.pop(), stringify$1(node, options))); + return; } - var length = collection.length, - index = fromRight ? length : -1, - iterable = Object(collection); + if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) { + q.push(append(q.pop(), ['{}'])); + return; + } - while (fromRight ? index-- : ++index < length) { - if (iteratee(iterable[index], index, iterable) === false) { - break; + if (node.nodes && node.ranges > 0) { + let args = utils$1.reduce(node.nodes); + + if (utils$1.exceedsLimit(...args, options.step, rangeLimit)) { + throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); } - } - return collection; - }; -} + let range = fillRange(...args, options); -var _createBaseEach = createBaseEach; + if (range.length === 0) { + range = stringify$1(node, options); + } -/** - * The base implementation of `_.forEach` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - */ + q.push(append(q.pop(), range)); + node.nodes = []; + return; + } -var baseEach = _createBaseEach(_baseForOwn); -var _baseEach = baseEach; + let enclose = utils$1.encloseBrace(node); + let queue = node.queue; + let block = node; -/** - * Aggregates elements of `collection` on `accumulator` with keys transformed - * by `iteratee` and values set by `setter`. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform keys. - * @param {Object} accumulator The initial aggregated object. - * @returns {Function} Returns `accumulator`. - */ + while (block.type !== 'brace' && block.type !== 'root' && block.parent) { + block = block.parent; + queue = block.queue; + } -function baseAggregator(collection, setter, iteratee, accumulator) { - _baseEach(collection, function (value, key, collection) { - setter(accumulator, value, iteratee(value), collection); - }); - return accumulator; -} + for (let i = 0; i < node.nodes.length; i++) { + let child = node.nodes[i]; -var _baseAggregator = baseAggregator; + if (child.type === 'comma' && node.type === 'brace') { + if (i === 1) queue.push(''); + queue.push(''); + continue; + } -/** - * Creates a function like `_.groupBy`. - * - * @private - * @param {Function} setter The function to set accumulator values. - * @param {Function} [initializer] The accumulator object initializer. - * @returns {Function} Returns the new aggregator function. - */ + if (child.type === 'close') { + q.push(append(q.pop(), queue, enclose)); + continue; + } -function createAggregator(setter, initializer) { - return function (collection, iteratee) { - var func = isArray_1(collection) ? _arrayAggregator : _baseAggregator, - accumulator = initializer ? initializer() : {}; - return func(collection, setter, _baseIteratee(iteratee), accumulator); + if (child.value && child.type !== 'open') { + queue.push(append(queue.pop(), child.value)); + continue; + } + + if (child.nodes) { + walk(child, node); + } + } + + return queue; }; -} -var _createAggregator = createAggregator; + return utils$1.flatten(walk(ast)); +}; -/** - * Creates an array of elements split into two groups, the first of which - * contains elements `predicate` returns truthy for, the second of which - * contains elements `predicate` returns falsey for. The predicate is - * invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the array of grouped elements. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true }, - * { 'user': 'pebbles', 'age': 1, 'active': false } - * ]; - * - * _.partition(users, function(o) { return o.active; }); - * // => objects for [['fred'], ['barney', 'pebbles']] - * - * // The `_.matches` iteratee shorthand. - * _.partition(users, { 'age': 1, 'active': false }); - * // => objects for [['pebbles'], ['barney', 'fred']] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.partition(users, ['active', false]); - * // => objects for [['barney', 'pebbles'], ['fred']] - * - * // The `_.property` iteratee shorthand. - * _.partition(users, 'active'); - * // => objects for [['fred'], ['barney', 'pebbles']] - */ +var expand_1 = expand$1; -var partition = _createAggregator(function (result, value, key) { - result[key ? 0 : 1].push(value); -}, function () { - return [[], []]; -}); -var partition_1 = partition; +var constants$3 = { + MAX_LENGTH: 1024 * 64, + // Digits + CHAR_0: '0', -var arrayUnion = (...arguments_) => { - return [...new Set([].concat(...arguments_))]; -}; + /* 0 */ + CHAR_9: '9', -/* - * merge2 - * https://github.com/teambition/merge2 - * - * Copyright (c) 2014-2016 Teambition - * Licensed under the MIT license. - */ + /* 9 */ + // Alphabet chars. + CHAR_UPPERCASE_A: 'A', + /* A */ + CHAR_LOWERCASE_A: 'a', -const PassThrough = stream$6.PassThrough; -const slice = Array.prototype.slice; -var merge2_1 = merge2; + /* a */ + CHAR_UPPERCASE_Z: 'Z', -function merge2() { - const streamsQueue = []; - let merging = false; - const args = slice.call(arguments); - let options = args[args.length - 1]; - if (options && !Array.isArray(options) && options.pipe == null) args.pop();else options = {}; - const doEnd = options.end !== false; - if (options.objectMode == null) options.objectMode = true; - if (options.highWaterMark == null) options.highWaterMark = 64 * 1024; - const mergedStream = PassThrough(options); + /* Z */ + CHAR_LOWERCASE_Z: 'z', - function addStream() { - for (let i = 0, len = arguments.length; i < len; i++) { - streamsQueue.push(pauseStreams(arguments[i], options)); - } + /* z */ + CHAR_LEFT_PARENTHESES: '(', - mergeStream(); - return this; - } + /* ( */ + CHAR_RIGHT_PARENTHESES: ')', - function mergeStream() { - if (merging) return; - merging = true; - let streams = streamsQueue.shift(); + /* ) */ + CHAR_ASTERISK: '*', - if (!streams) { - process.nextTick(endStream); - return; - } + /* * */ + // Non-alphabetic chars. + CHAR_AMPERSAND: '&', - if (!Array.isArray(streams)) streams = [streams]; - let pipesCount = streams.length + 1; + /* & */ + CHAR_AT: '@', - function next() { - if (--pipesCount > 0) return; - merging = false; - mergeStream(); - } + /* @ */ + CHAR_BACKSLASH: '\\', - function pipe(stream) { - function onend() { - stream.removeListener('merge2UnpipeEnd', onend); - stream.removeListener('end', onend); - next(); - } // skip ended stream + /* \ */ + CHAR_BACKTICK: '`', + /* ` */ + CHAR_CARRIAGE_RETURN: '\r', - if (stream._readableState.endEmitted) return next(); - stream.on('merge2UnpipeEnd', onend); - stream.on('end', onend); - stream.pipe(mergedStream, { - end: false - }); // compatible for old stream + /* \r */ + CHAR_CIRCUMFLEX_ACCENT: '^', - stream.resume(); - } + /* ^ */ + CHAR_COLON: ':', - for (let i = 0; i < streams.length; i++) pipe(streams[i]); + /* : */ + CHAR_COMMA: ',', - next(); - } + /* , */ + CHAR_DOLLAR: '$', - function endStream() { - merging = false; // emit 'queueDrain' when all streams merged. + /* . */ + CHAR_DOT: '.', - mergedStream.emit('queueDrain'); - return doEnd && mergedStream.end(); - } + /* . */ + CHAR_DOUBLE_QUOTE: '"', - mergedStream.setMaxListeners(0); - mergedStream.add = addStream; - mergedStream.on('unpipe', function (stream) { - stream.emit('merge2UnpipeEnd'); - }); - if (args.length) addStream.apply(null, args); - return mergedStream; -} // check and pause streams for pipe. + /* " */ + CHAR_EQUAL: '=', + /* = */ + CHAR_EXCLAMATION_MARK: '!', -function pauseStreams(streams, options) { - if (!Array.isArray(streams)) { - // Backwards-compat with old-style streams - if (!streams._readableState && streams.pipe) streams = streams.pipe(PassThrough(options)); + /* ! */ + CHAR_FORM_FEED: '\f', - if (!streams._readableState || !streams.pause || !streams.pipe) { - throw new Error('Only readable stream can be merged.'); - } + /* \f */ + CHAR_FORWARD_SLASH: '/', - streams.pause(); - } else { - for (let i = 0, len = streams.length; i < len; i++) streams[i] = pauseStreams(streams[i], options); - } + /* / */ + CHAR_HASH: '#', - return streams; -} + /* # */ + CHAR_HYPHEN_MINUS: '-', -var array$2 = createCommonjsModule(function (module, exports) { + /* - */ + CHAR_LEFT_ANGLE_BRACKET: '<', - Object.defineProperty(exports, "__esModule", { - value: true - }); + /* < */ + CHAR_LEFT_CURLY_BRACE: '{', - function flatten(items) { - return items.reduce((collection, item) => [].concat(collection, item), []); - } + /* { */ + CHAR_LEFT_SQUARE_BRACKET: '[', - exports.flatten = flatten; + /* [ */ + CHAR_LINE_FEED: '\n', - function splitWhen(items, predicate) { - const result = [[]]; - let groupIndex = 0; + /* \n */ + CHAR_NO_BREAK_SPACE: '\u00A0', - for (const item of items) { - if (predicate(item)) { - groupIndex++; - result[groupIndex] = []; - } else { - result[groupIndex].push(item); - } - } + /* \u00A0 */ + CHAR_PERCENT: '%', - return result; - } + /* % */ + CHAR_PLUS: '+', - exports.splitWhen = splitWhen; -}); -unwrapExports(array$2); -var array_1$1 = array$2.flatten; -var array_2 = array$2.splitWhen; + /* + */ + CHAR_QUESTION_MARK: '?', -var errno = createCommonjsModule(function (module, exports) { + /* ? */ + CHAR_RIGHT_ANGLE_BRACKET: '>', - Object.defineProperty(exports, "__esModule", { - value: true - }); + /* > */ + CHAR_RIGHT_CURLY_BRACE: '}', - function isEnoentCodeError(error) { - return error.code === 'ENOENT'; - } + /* } */ + CHAR_RIGHT_SQUARE_BRACKET: ']', - exports.isEnoentCodeError = isEnoentCodeError; -}); -unwrapExports(errno); -var errno_1 = errno.isEnoentCodeError; + /* ] */ + CHAR_SEMICOLON: ';', -var fs$1 = createCommonjsModule(function (module, exports) { + /* ; */ + CHAR_SINGLE_QUOTE: '\'', - Object.defineProperty(exports, "__esModule", { - value: true - }); + /* ' */ + CHAR_SPACE: ' ', - class DirentFromStats { - constructor(name, stats) { - this.name = name; - this.isBlockDevice = stats.isBlockDevice.bind(stats); - this.isCharacterDevice = stats.isCharacterDevice.bind(stats); - this.isDirectory = stats.isDirectory.bind(stats); - this.isFIFO = stats.isFIFO.bind(stats); - this.isFile = stats.isFile.bind(stats); - this.isSocket = stats.isSocket.bind(stats); - this.isSymbolicLink = stats.isSymbolicLink.bind(stats); - } + /* */ + CHAR_TAB: '\t', - } + /* \t */ + CHAR_UNDERSCORE: '_', - function createDirentFromStats(name, stats) { - return new DirentFromStats(name, stats); - } + /* _ */ + CHAR_VERTICAL_LINE: '|', - exports.createDirentFromStats = createDirentFromStats; -}); -unwrapExports(fs$1); -var fs_1 = fs$1.createDirentFromStats; + /* | */ + CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' + /* \uFEFF */ -var path_1 = createCommonjsModule(function (module, exports) { +}; - Object.defineProperty(exports, "__esModule", { - value: true - }); - const LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2; // ./ or .\\ +/** + * Constants + */ - const UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()*?[\]{|}]|^!|[!+@](?=\())/g; - /** - * Designed to work only with simple paths: `dir\\file`. - */ - function unixify(filepath) { - return filepath.replace(/\\/g, '/'); - } +const { + MAX_LENGTH: MAX_LENGTH$2, + CHAR_BACKSLASH, - exports.unixify = unixify; + /* \ */ + CHAR_BACKTICK, - function makeAbsolute(cwd, filepath) { - return path$2.resolve(cwd, filepath); - } + /* ` */ + CHAR_COMMA: CHAR_COMMA$1, - exports.makeAbsolute = makeAbsolute; + /* , */ + CHAR_DOT, - function escape(pattern) { - return pattern.replace(UNESCAPED_GLOB_SYMBOLS_RE, '\\$2'); - } + /* . */ + CHAR_LEFT_PARENTHESES, - exports.escape = escape; + /* ( */ + CHAR_RIGHT_PARENTHESES, - function removeLeadingDotSegment(entry) { - // We do not use `startsWith` because this is 10x slower than current implementation for some cases. - // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with - if (entry.charAt(0) === '.') { - const secondCharactery = entry.charAt(1); + /* ) */ + CHAR_LEFT_CURLY_BRACE, - if (secondCharactery === '/' || secondCharactery === '\\') { - return entry.slice(LEADING_DOT_SEGMENT_CHARACTERS_COUNT); - } - } + /* { */ + CHAR_RIGHT_CURLY_BRACE, - return entry; - } + /* } */ + CHAR_LEFT_SQUARE_BRACKET, - exports.removeLeadingDotSegment = removeLeadingDotSegment; -}); -unwrapExports(path_1); -var path_2 = path_1.unixify; -var path_3 = path_1.makeAbsolute; -var path_4 = path_1.escape; -var path_5 = path_1.removeLeadingDotSegment; + /* [ */ + CHAR_RIGHT_SQUARE_BRACKET, -/*! - * is-extglob - * - * Copyright (c) 2014-2016, Jon Schlinkert. - * Licensed under the MIT License. + /* ] */ + CHAR_DOUBLE_QUOTE, + + /* " */ + CHAR_SINGLE_QUOTE, + + /* ' */ + CHAR_NO_BREAK_SPACE, + CHAR_ZERO_WIDTH_NOBREAK_SPACE +} = constants$3; +/** + * parse */ -var isExtglob = function isExtglob(str) { - if (typeof str !== 'string' || str === '') { - return false; + +const parse$5 = (input, options = {}) => { + if (typeof input !== 'string') { + throw new TypeError('Expected a string'); } - var match; + let opts = options || {}; + let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH$2, opts.maxLength) : MAX_LENGTH$2; - while (match = /(\\).|([@?!+*]\(.*\))/g.exec(str)) { - if (match[2]) return true; - str = str.slice(match.index + match[0].length); + if (input.length > max) { + throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`); } - return false; -}; - -/*! - * is-glob - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ + 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 + */ -var chars = { - '{': '}', - '(': ')', - '[': ']' -}; -var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; -var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; + const advance = () => input[index++]; -var isGlob = function isGlob(str, options) { - if (typeof str !== 'string' || str === '') { - return false; - } + const push = node => { + if (node.type === 'text' && prev.type === 'dot') { + prev.type = 'text'; + } - if (isExtglob(str)) { - return true; - } + if (prev && prev.type === 'text' && node.type === 'text') { + prev.value += node.value; + return; + } - var regex = strictRegex; - var match; // optionally relax regex + block.nodes.push(node); + node.parent = block; + node.prev = prev; + prev = node; + return node; + }; - if (options && options.strict === false) { - regex = relaxedRegex; - } + push({ + type: 'bos' + }); - 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 + while (index < length) { + block = stack[stack.length - 1]; + value = advance(); + /** + * Invalid chars + */ - var open = match[1]; - var close = open ? chars[open] : null; + if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) { + continue; + } + /** + * Escaped chars + */ - if (open && close) { - var n = str.indexOf(close, idx); - if (n !== -1) { - idx = n + 1; - } + if (value === CHAR_BACKSLASH) { + push({ + type: 'text', + value: (options.keepEscaping ? value : '') + advance() + }); + continue; } + /** + * Right square bracket (literal): ']' + */ - str = str.slice(idx); - } - return false; -}; + if (value === CHAR_RIGHT_SQUARE_BRACKET) { + push({ + type: 'text', + value: '\\' + value + }); + continue; + } + /** + * Left square bracket: '[' + */ -var pathPosixDirname = path$2.posix.dirname; -var isWin32 = os$1.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] - */ -var globParent = function globParent(str, opts) { - var options = Object.assign({ - flipBackslashes: true - }, opts); // flip windows path separators + if (value === CHAR_LEFT_SQUARE_BRACKET) { + brackets++; + let next; - if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) { - str = str.replace(backslash, slash); - } // special case for strings ending in enclosure containing path separator + while (index < length && (next = advance())) { + value += next; + if (next === CHAR_LEFT_SQUARE_BRACKET) { + brackets++; + continue; + } - if (enclosure.test(str)) { - str += slash; - } // preserves full path in case of trailing path separator + if (next === CHAR_BACKSLASH) { + value += advance(); + continue; + } + if (next === CHAR_RIGHT_SQUARE_BRACKET) { + brackets--; - str += 'a'; // remove path parts that are globby + if (brackets === 0) { + break; + } + } + } - do { - str = pathPosixDirname(str); - } while (isGlob(str) || globby.test(str)); // remove escape chars and return result + push({ + type: 'text', + value + }); + continue; + } + /** + * Parentheses + */ - return str.replace(escaped, '$1'); -}; + if (value === CHAR_LEFT_PARENTHESES) { + block = push({ + type: 'paren', + nodes: [] + }); + stack.push(block); + push({ + type: 'text', + value + }); + continue; + } -var utils$2 = createCommonjsModule(function (module, exports) { + if (value === CHAR_RIGHT_PARENTHESES) { + if (block.type !== 'paren') { + push({ + type: 'text', + value + }); + continue; + } - exports.isInteger = num => { - if (typeof num === 'number') { - return Number.isInteger(num); + block = stack.pop(); + push({ + type: 'text', + value + }); + block = stack[stack.length - 1]; + continue; } + /** + * Quotes: '|"|` + */ - if (typeof num === 'string' && num.trim() !== '') { - return Number.isInteger(Number(num)); - } - return false; - }; - /** - * Find a node of the given type - */ + if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) { + let open = value; + let next; + if (options.keepQuotes !== true) { + value = ''; + } - exports.find = (node, type) => node.nodes.find(node => node.type === type); - /** - * Find a node of the given type - */ + while (index < length && (next = advance())) { + if (next === CHAR_BACKSLASH) { + value += next + advance(); + continue; + } + if (next === open) { + if (options.keepQuotes === true) value += next; + break; + } - 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 - */ + value += next; + } + push({ + type: 'text', + value + }); + continue; + } + /** + * Left curly brace: '{' + */ - 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; + 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; } - }; - /** - * Returns true if the given brace node should be enclosed in literal braces - */ + /** + * Comma: ',' + */ - exports.encloseBrace = node => { - if (node.type !== 'brace') return false; + 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$1(block) + }]; + } - if (node.commas >> 0 + node.ranges >> 0 === 0) { - node.invalid = true; - return true; + push({ + type: 'comma', + value + }); + block.commas++; + continue; } + /** + * Dot: '.' + */ - return false; - }; - /** - * Returns true if a brace node is invalid. - */ + if (value === CHAR_DOT && depth > 0 && block.commas === 0) { + let siblings = block.nodes; - exports.isInvalidBrace = block => { - if (block.type !== 'brace') return false; - if (block.invalid === true || block.dollar) return true; + if (depth === 0 || siblings.length === 0) { + push({ + type: 'text', + value + }); + continue; + } - if (block.commas >> 0 + block.ranges >> 0 === 0) { - block.invalid = true; - return true; - } + if (prev.type === 'dot') { + block.range = []; + prev.value += value; + prev.type = 'range'; - if (block.open !== true || block.close !== true) { - block.invalid = true; - return true; - } + if (block.nodes.length !== 3 && block.nodes.length !== 5) { + block.invalid = true; + block.ranges = 0; + prev.type = 'text'; + continue; + } - return false; - }; - /** - * Returns true if a node is an open or close node - */ + 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; + } - exports.isOpenOrClose = node => { - if (node.type === 'open' || node.type === 'close') { - return true; + push({ + type: 'dot', + value + }); + continue; } + /** + * Text + */ - return node.open === true || node.close === true; - }; - /** - * Reduce an array of text nodes. - */ + + push({ + type: 'text', + value + }); + } // Mark imbalanced braces and brackets as invalid - 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 - */ + 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 - exports.flatten = (...args) => { - const result = []; + parent.nodes.splice(index, 1, ...block.nodes); + } + } while (stack.length > 0); - 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); - } + push({ + type: 'eos' + }); + return ast; +}; - return result; - }; +var parse_1 = parse$5; - flat(args); - return result; - }; -}); -var utils_1$2 = utils$2.isInteger; -var utils_2$2 = utils$2.find; -var utils_3$2 = utils$2.exceedsLimit; -var utils_4$1 = utils$2.escapeNode; -var utils_5$1 = utils$2.encloseBrace; -var utils_6$1 = utils$2.isInvalidBrace; -var utils_7$1 = utils$2.isOpenOrClose; -var utils_8$1 = utils$2.reduce; -var utils_9$1 = utils$2.flatten; - -var stringify = (ast, options = {}) => { - let stringify = (node, parent = {}) => { - let invalidBlock = options.escapeInvalid && utils$2.isInvalidBrace(parent); - let invalidNode = node.invalid === true && options.escapeInvalid === true; - let output = ''; +/** + * 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 + */ - if (node.value) { - if ((invalidBlock || invalidNode) && utils$2.isOpenOrClose(node)) { - return '\\' + node.value; - } - return node.value; - } +const braces = (input, options = {}) => { + let output = []; - if (node.value) { - return node.value; - } + if (Array.isArray(input)) { + for (let pattern of input) { + let result = braces.create(pattern, options); - if (node.nodes) { - for (let child of node.nodes) { - output += stringify(child); + if (Array.isArray(result)) { + output.push(...result); + } else { + output.push(result); } } + } else { + output = [].concat(braces.create(input, options)); + } - return output; - }; + if (options && options.expand === true && options.nodupes === true) { + output = [...new Set(output)]; + } - return stringify(ast); + 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 + */ -/*! - * is-number + +braces.parse = (input, options = {}) => parse_1(input, options); +/** + * Creates a braces string from an AST, or an AST node. * - * Copyright (c) 2014-present, Jon Schlinkert. - * Released under the MIT License. + * ```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 */ -var isNumber = function (num) { - if (typeof num === 'number') { - return num - num === 0; - } - if (typeof num === 'string' && num.trim() !== '') { - return Number.isFinite ? Number.isFinite(+num) : isFinite(+num); +braces.stringify = (input, options = {}) => { + if (typeof input === 'string') { + return stringify$1(braces.parse(input, options), options); } - return false; + return stringify$1(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 + */ -const toRegexRange = (min, max, options) => { - if (isNumber(min) === false) { - throw new TypeError('toRegexRange: expected the first argument to be a number'); - } - if (max === void 0 || min === max) { - return String(min); +braces.compile = (input, options = {}) => { + if (typeof input === 'string') { + input = braces.parse(input, options); } - if (isNumber(max) === false) { - throw new TypeError('toRegexRange: expected the second argument to be a number.'); - } + return compile_1(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 + */ - let opts = Object.assign({ - relaxZeros: true - }, options); - if (typeof opts.strictZeros === 'boolean') { - opts.relaxZeros = opts.strictZeros === false; +braces.expand = (input, options = {}) => { + if (typeof input === 'string') { + input = braces.parse(input, options); } - 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; + let result = expand_1(input, options); // filter out empty strings if specified - if (toRegexRange.cache.hasOwnProperty(cacheKey)) { - return toRegexRange.cache[cacheKey].result; - } + if (options.noempty === true) { + result = result.filter(Boolean); + } // filter out duplicates if specified - let a = Math.min(min, max); - let b = Math.max(min, max); - if (Math.abs(a - b) === 1) { - let result = min + '|' + max; + if (options.nodupes === true) { + result = [...new Set(result)]; + } - if (opts.capture) { - return `(${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 + */ - if (opts.wrap === false) { - return result; - } - return `(?:${result})`; +braces.create = (input, options = {}) => { + if (input === '' || input.length < 3) { + return [input]; } - let isPadded = hasPadding(min) || hasPadding(max); - let state = { - min, - max, - a, - b - }; - let positives = []; - let negatives = []; + return options.expand !== true ? braces.compile(input, options) : braces.expand(input, options); +}; +/** + * Expose "braces" + */ - 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; - } +var braces_1 = braces; - if (b >= 0) { - positives = splitToPatterns(a, b, state, opts); - } +const WIN_SLASH = '\\\\/'; +const WIN_NO_SLASH = `[^${WIN_SLASH}]`; +/** + * Posix glob regex + */ - state.negatives = negatives; - state.positives = positives; - state.result = collatePatterns(negatives, positives); +const DOT_LITERAL = '\\.'; +const PLUS_LITERAL = '\\+'; +const QMARK_LITERAL = '\\?'; +const SLASH_LITERAL = '\\/'; +const ONE_CHAR = '(?=.)'; +const QMARK = '[^/]'; +const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; +const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; +const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; +const NO_DOT = `(?!${DOT_LITERAL})`; +const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; +const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; +const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; +const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; +const STAR = `${QMARK}*?`; +const POSIX_CHARS = { + DOT_LITERAL, + PLUS_LITERAL, + QMARK_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + QMARK, + END_ANCHOR, + DOTS_SLASH, + NO_DOT, + NO_DOTS, + NO_DOT_SLASH, + NO_DOTS_SLASH, + QMARK_NO_DOT, + STAR, + START_ANCHOR +}; +/** + * Windows glob regex + */ - if (opts.capture === true) { - state.result = `(${state.result})`; - } else if (opts.wrap !== false && positives.length + negatives.length > 1) { - state.result = `(?:${state.result})`; - } +const WINDOWS_CHARS = Object.assign({}, 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 + */ - toRegexRange.cache[cacheKey] = state; - return state.result; +const POSIX_REGEX_SOURCE = { + alnum: 'a-zA-Z0-9', + alpha: 'a-zA-Z', + ascii: '\\x00-\\x7F', + blank: ' \\t', + cntrl: '\\x00-\\x1F\\x7F', + digit: '0-9', + graph: '\\x21-\\x7E', + lower: 'a-z', + print: '\\x20-\\x7E ', + punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', + space: ' \\t\\r\\n\\v\\f', + upper: 'A-Z', + word: 'A-Za-z0-9_', + xdigit: 'A-Fa-f0-9' }; +var constants$4 = { + MAX_LENGTH: 1024 * 64, + POSIX_REGEX_SOURCE, + // regular expressions + REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, + REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, + REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, + REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, + REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, + REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, + // Replace globs with equivalent patterns to reduce parsing time. + REPLACEMENTS: { + '***': '*', + '**/**': '**', + '**/**/**': '**' + }, + // Digits + CHAR_0: 48, -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('|'); -} + /* 0 */ + CHAR_9: 57, -function splitToRanges(min, max) { - let nines = 1; - let zeros = 1; - let stop = countNines(min, nines); - let stops = new Set([max]); + /* 9 */ + // Alphabet chars. + CHAR_UPPERCASE_A: 65, - while (min <= stop && stop <= max) { - stops.add(stop); - nines += 1; - stop = countNines(min, nines); - } + /* A */ + CHAR_LOWERCASE_A: 97, - stop = countZeros(max + 1, zeros) - 1; + /* a */ + CHAR_UPPERCASE_Z: 90, - while (min < stop && stop <= max) { - stops.add(stop); - zeros += 1; - stop = countZeros(max + 1, zeros) - 1; - } + /* Z */ + CHAR_LOWERCASE_Z: 122, - stops = [...stops]; - stops.sort(compare$1); - return stops; -} -/** - * Convert a range to a regex pattern - * @param {Number} `start` - * @param {Number} `stop` - * @return {String} - */ + /* z */ + CHAR_LEFT_PARENTHESES: 40, + + /* ( */ + CHAR_RIGHT_PARENTHESES: 41, + /* ) */ + CHAR_ASTERISK: 42, -function rangeToPattern(start, stop, options) { - if (start === stop) { - return { - pattern: start, - count: [], - digits: 0 - }; - } + /* * */ + // Non-alphabetic chars. + CHAR_AMPERSAND: 38, - let zipped = zip(start, stop); - let digits = zipped.length; - let pattern = ''; - let count = 0; + /* & */ + CHAR_AT: 64, - for (let i = 0; i < digits; i++) { - let [startDigit, stopDigit] = zipped[i]; + /* @ */ + CHAR_BACKWARD_SLASH: 92, - if (startDigit === stopDigit) { - pattern += startDigit; - } else if (startDigit !== '0' || stopDigit !== '9') { - pattern += toCharacterClass(startDigit, stopDigit); - } else { - count++; - } - } + /* \ */ + CHAR_CARRIAGE_RETURN: 13, - if (count) { - pattern += options.shorthand === true ? '\\d' : '[0-9]'; - } + /* \r */ + CHAR_CIRCUMFLEX_ACCENT: 94, - return { - pattern, - count: [count], - digits - }; -} + /* ^ */ + CHAR_COLON: 58, -function splitToPatterns(min, max, tok, options) { - let ranges = splitToRanges(min, max); - let tokens = []; - let start = min; - let prev; + /* : */ + CHAR_COMMA: 44, - for (let i = 0; i < ranges.length; i++) { - let max = ranges[i]; - let obj = rangeToPattern(String(start), String(max), options); - let zeros = ''; + /* , */ + CHAR_DOT: 46, - if (!tok.isPadded && prev && prev.pattern === obj.pattern) { - if (prev.count.length > 1) { - prev.count.pop(); - } + /* . */ + CHAR_DOUBLE_QUOTE: 34, - prev.count.push(obj.count[0]); - prev.string = prev.pattern + toQuantifier(prev.count); - start = max + 1; - continue; - } + /* " */ + CHAR_EQUAL: 61, - if (tok.isPadded) { - zeros = padZeros(max, tok, options); - } + /* = */ + CHAR_EXCLAMATION_MARK: 33, - obj.string = zeros + obj.pattern + toQuantifier(obj.count); - tokens.push(obj); - start = max + 1; - prev = obj; - } + /* ! */ + CHAR_FORM_FEED: 12, - return tokens; -} + /* \f */ + CHAR_FORWARD_SLASH: 47, -function filterPatterns(arr, comparison, prefix, intersection, options) { - let result = []; + /* / */ + CHAR_GRAVE_ACCENT: 96, - for (let ele of arr) { - let { - string - } = ele; // only push if _both_ are negative... + /* ` */ + CHAR_HASH: 35, - if (!intersection && !contains(comparison, 'string', string)) { - result.push(prefix + string); - } // or _both_ are positive + /* # */ + 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, - if (intersection && contains(comparison, 'string', string)) { - result.push(prefix + string); - } - } + /* > */ + CHAR_RIGHT_CURLY_BRACE: 125, - return result; -} -/** - * Zip strings - */ + /* } */ + CHAR_RIGHT_SQUARE_BRACKET: 93, + /* ] */ + CHAR_SEMICOLON: 59, -function zip(a, b) { - let arr = []; + /* ; */ + CHAR_SINGLE_QUOTE: 39, - for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]); + /* ' */ + CHAR_SPACE: 32, - return arr; -} + /* */ + CHAR_TAB: 9, -function compare$1(a, b) { - return a > b ? 1 : b > a ? -1 : 0; -} + /* \t */ + CHAR_UNDERSCORE: 95, -function contains(arr, key, val) { - return arr.some(ele => ele[key] === val); -} + /* _ */ + CHAR_VERTICAL_LINE: 124, -function countNines(min, len) { - return Number(String(min).slice(0, -len) + '9'.repeat(len)); -} + /* | */ + CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, -function countZeros(integer, zeros) { - return integer - integer % Math.pow(10, zeros); -} + /* \uFEFF */ + SEP: path__default['default'].sep, -function toQuantifier(digits) { - let [start = 0, stop = ''] = digits; + /** + * 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: ')' + } + }; + }, - if (stop || start > 1) { - return `{${start + (stop ? ',' + stop : '')}}`; + /** + * Create GLOB_CHARS + */ + globChars(win32) { + return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; } - return ''; -} +}; -function toCharacterClass(a, b, options) { - return `[${a}${b - a === 1 ? '' : '-'}${b}]`; -} +var utils$2 = createCommonjsModule(function (module, exports) { -function hasPadding(str) { - return /^-?(0+)\d/.test(str); -} + const win32 = process.platform === 'win32'; + const { + REGEX_BACKSLASH, + REGEX_REMOVE_BACKSLASH, + REGEX_SPECIAL_CHARS, + REGEX_SPECIAL_CHARS_GLOBAL + } = constants$4; -function padZeros(value, tok, options) { - if (!tok.isPadded) { - return value; - } + exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); - let diff = Math.abs(tok.maxLen - String(value).length); - let relax = options.relaxZeros !== false; + exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); - switch (diff) { - case 0: - return ''; + exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); - case 1: - return relax ? '0?' : '0'; + exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); - case 2: - return relax ? '0{0,2}' : '00'; + exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); - default: - { - return relax ? `0{0,${diff}}` : `0{${diff}}`; - } - } -} -/** - * Cache - */ + exports.removeBackslashes = str => { + return str.replace(REGEX_REMOVE_BACKSLASH, match => { + return match === '\\' ? '' : match; + }); + }; + exports.supportsLookbehinds = () => { + const segs = process.version.slice(1).split('.').map(Number); -toRegexRange.cache = {}; + if (segs.length === 3 && segs[0] >= 9 || segs[0] === 8 && segs[1] >= 10) { + return true; + } -toRegexRange.clearCache = () => toRegexRange.cache = {}; -/** - * Expose `toRegexRange` - */ + return false; + }; + exports.isWindows = options => { + if (options && typeof options.windows === 'boolean') { + return options.windows; + } -var toRegexRange_1 = toRegexRange; + return win32 === true || path__default['default'].sep === '\\'; + }; -const isObject$1 = val => val !== null && typeof val === 'object' && !Array.isArray(val); + 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)}`; + }; -const transform = toNumber => { - return value => toNumber === true ? Number(value) : String(value); -}; + exports.removePrefix = (input, state = {}) => { + let output = input; -const isValidValue = value => { - return typeof value === 'number' || typeof value === 'string' && value !== ''; -}; + if (output.startsWith('./')) { + output = output.slice(2); + state.prefix = './'; + } -const isNumber$1 = num => Number.isInteger(+num); + return output; + }; -const zeros = input => { - let value = `${input}`; - let index = -1; - if (value[0] === '-') value = value.slice(1); - if (value === '0') return false; + exports.wrapOutput = (input, state = {}, options = {}) => { + const prepend = options.contains ? '' : '^'; + const append = options.contains ? '' : '$'; + let output = `${prepend}(?:${input})${append}`; - while (value[++index] === '0'); + if (state.negated === true) { + output = `(?:^(?!${output}).*$)`; + } - return index > 0; -}; + return output; + }; +}); -const stringify$1 = (start, end, options) => { - if (typeof start === 'string' || typeof end === 'string') { - return true; - } +const { + CHAR_ASTERISK, - return options.stringify === true; -}; + /* * */ + CHAR_AT, -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'); - } + /* @ */ + CHAR_BACKWARD_SLASH, - if (toNumber === false) { - return String(input); - } + /* \ */ + CHAR_COMMA: CHAR_COMMA$2, - return input; -}; + /* , */ + CHAR_DOT: CHAR_DOT$1, -const toMaxLen = (input, maxLength) => { - let negative = input[0] === '-' ? '-' : ''; + /* . */ + CHAR_EXCLAMATION_MARK, - if (negative) { - input = input.slice(1); - maxLength--; - } + /* ! */ + CHAR_FORWARD_SLASH, - while (input.length < maxLength) input = '0' + input; + /* / */ + CHAR_LEFT_CURLY_BRACE: CHAR_LEFT_CURLY_BRACE$1, - return negative ? '-' + input : input; -}; + /* { */ + CHAR_LEFT_PARENTHESES: CHAR_LEFT_PARENTHESES$1, -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; + /* ( */ + CHAR_LEFT_SQUARE_BRACKET: CHAR_LEFT_SQUARE_BRACKET$1, - if (parts.positives.length) { - positives = parts.positives.join('|'); - } + /* [ */ + CHAR_PLUS: CHAR_PLUS$1, - if (parts.negatives.length) { - negatives = `-(${prefix}${parts.negatives.join('|')})`; - } + /* + */ + CHAR_QUESTION_MARK, - if (positives && negatives) { - result = `${positives}|${negatives}`; - } else { - result = positives || negatives; - } + /* ? */ + CHAR_RIGHT_CURLY_BRACE: CHAR_RIGHT_CURLY_BRACE$1, - if (options.wrap) { - return `(${prefix}${result})`; - } + /* } */ + CHAR_RIGHT_PARENTHESES: CHAR_RIGHT_PARENTHESES$1, - return result; -}; + /* ) */ + CHAR_RIGHT_SQUARE_BRACKET: CHAR_RIGHT_SQUARE_BRACKET$1 + /* ] */ -const toRange = (a, b, isNumbers, options) => { - if (isNumbers) { - return toRegexRange_1(a, b, Object.assign({ - wrap: false - }, options)); - } +} = constants$4; - let start = String.fromCharCode(a); - if (a === b) return start; - let stop = String.fromCharCode(b); - return `[${start}-${stop}]`; +const isPathSeparator = code => { + return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; }; -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('|'); +const depth = token => { + if (token.isPrefix !== true) { + token.depth = token.isGlobstar ? Infinity : 1; } - - return toRegexRange_1(start, end, options); }; +/** + * 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), and `negated` (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 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 scan = (input, options) => { + const opts = options || {}; + const length = input.length - 1; + const scanToEnd = opts.parts === true || opts.scanToEnd === true; + const slashes = []; + const tokens = []; + const parts = []; + let str = input; + let index = -1; + let start = 0; + let lastIndex = 0; + let isBrace = false; + let isBracket = false; + let isGlob = false; + let isExtglob = false; + let isGlobstar = false; + let braceEscaped = false; + let backslashes = false; + let negated = false; + let finished = false; + let braces = 0; + let prev; + let code; + let token = { + value: '', + depth: 0, + isGlob: false + }; -const invalidStep = (step, options) => { - if (options.strictRanges === true) { - throw new TypeError(`Expected step "${step}" to be a number`); - } + const eos = () => index >= length; - return []; -}; + const peek = () => str.charCodeAt(index + 1); -const fillNumbers = (start, end, step = 1, options = {}) => { - let a = Number(start); - let b = Number(end); + const advance = () => { + prev = code; + return str.charCodeAt(++index); + }; - if (!Number.isInteger(a) || !Number.isInteger(b)) { - if (options.strictRanges === true) throw rangeError([start, end]); - return []; - } // fix negative zero + while (index < length) { + code = advance(); + let next; + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + code = advance(); - 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$1(start, end, options) === false; - let format = options.transform || transform(toNumber); + if (code === CHAR_LEFT_CURLY_BRACE$1) { + braceEscaped = true; + } - if (options.toRegex && step === 1) { - return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options); - } + continue; + } - let parts = { - negatives: [], - positives: [] - }; + if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE$1) { + braces++; - let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num)); + while (eos() !== true && (code = advance())) { + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + advance(); + continue; + } - let range = []; - let index = 0; + if (code === CHAR_LEFT_CURLY_BRACE$1) { + braces++; + continue; + } - while (descending ? a >= b : a <= b) { - if (options.toRegex === true && step > 1) { - push(a); - } else { - range.push(pad(format(a, index), maxLen, toNumber)); - } + if (braceEscaped !== true && code === CHAR_DOT$1 && (code = advance()) === CHAR_DOT$1) { + isBrace = token.isBrace = true; + isGlob = token.isGlob = true; + finished = true; - a = descending ? a - step : a + step; - index++; - } + if (scanToEnd === true) { + continue; + } - if (options.toRegex === true) { - return step > 1 ? toSequence(parts, options) : toRegex(range, null, Object.assign({ - wrap: false - }, options)); - } + break; + } - return range; -}; + if (braceEscaped !== true && code === CHAR_COMMA$2) { + isBrace = token.isBrace = true; + isGlob = token.isGlob = true; + finished = true; -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); - } + if (scanToEnd === true) { + continue; + } - let format = options.transform || (val => String.fromCharCode(val)); + break; + } - 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 (code === CHAR_RIGHT_CURLY_BRACE$1) { + braces--; - if (options.toRegex && step === 1) { - return toRange(min, max, false, options); - } + if (braces === 0) { + braceEscaped = false; + isBrace = token.isBrace = true; + finished = true; + break; + } + } + } - let range = []; - let index = 0; + if (scanToEnd === true) { + continue; + } - while (descending ? a >= b : a <= b) { - range.push(format(a, index)); - a = descending ? a - step : a + step; - index++; - } + break; + } - if (options.toRegex === true) { - return toRegex(range, null, { - wrap: false, - options - }); - } + if (code === CHAR_FORWARD_SLASH) { + slashes.push(index); + tokens.push(token); + token = { + value: '', + depth: 0, + isGlob: false + }; + if (finished === true) continue; - return range; -}; + if (prev === CHAR_DOT$1 && index === start + 1) { + start += 2; + continue; + } -const fill$2 = (start, end, step, options = {}) => { - if (end == null && isValidValue(start)) { - return [start]; - } + lastIndex = index + 1; + continue; + } + + if (opts.noext !== true) { + const isExtglobChar = code === CHAR_PLUS$1 || code === CHAR_AT || code === CHAR_ASTERISK || 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 (!isValidValue(start) || !isValidValue(end)) { - return invalidRange(start, end, options); - } + if (scanToEnd === true) { + while (eos() !== true && (code = advance())) { + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + code = advance(); + continue; + } - if (typeof step === 'function') { - return fill$2(start, end, 1, { - transform: step - }); - } + if (code === CHAR_RIGHT_PARENTHESES$1) { + isGlob = token.isGlob = true; + finished = true; + break; + } + } - if (isObject$1(step)) { - return fill$2(start, end, 0, step); - } + continue; + } - let opts = Object.assign({}, options); - if (opts.capture === true) opts.wrap = true; - step = step || opts.step || 1; + break; + } + } - if (!isNumber$1(step)) { - if (step != null && !isObject$1(step)) return invalidStep(step, opts); - return fill$2(start, end, 1, step); - } + if (code === CHAR_ASTERISK) { + if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; + isGlob = token.isGlob = true; + finished = true; - if (isNumber$1(start) && isNumber$1(end)) { - return fillNumbers(start, end, step, opts); - } + if (scanToEnd === true) { + continue; + } - return fillLetters(start, end, Math.max(Math.abs(step), 1), opts); -}; + break; + } -var fillRange = fill$2; + if (code === CHAR_QUESTION_MARK) { + isGlob = token.isGlob = true; + finished = true; -const compile = (ast, options = {}) => { - let walk = (node, parent = {}) => { - let invalidBlock = utils$2.isInvalidBrace(parent); - let invalidNode = node.invalid === true && options.escapeInvalid === true; - let invalid = invalidBlock === true || invalidNode === true; - let prefix = options.escapeInvalid === true ? '\\' : ''; - let output = ''; + if (scanToEnd === true) { + continue; + } - if (node.isOpen === true) { - return prefix + node.value; + break; } - if (node.isClose === true) { - return prefix + node.value; - } + if (code === CHAR_LEFT_SQUARE_BRACKET$1) { + while (eos() !== true && (next = advance())) { + if (next === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + advance(); + continue; + } - if (node.type === 'open') { - return invalid ? prefix + node.value : '('; - } + if (next === CHAR_RIGHT_SQUARE_BRACKET$1) { + isBracket = token.isBracket = true; + isGlob = token.isGlob = true; + finished = true; - if (node.type === 'close') { - return invalid ? prefix + node.value : ')'; - } + if (scanToEnd === true) { + continue; + } - if (node.type === 'comma') { - return node.prev.type === 'comma' ? '' : invalid ? node.value : '|'; + break; + } + } } - if (node.value) { - return node.value; + if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { + negated = token.negated = true; + start++; + continue; } - if (node.nodes && node.ranges > 0) { - let args = utils$2.reduce(node.nodes); - let range = fillRange(...args, Object.assign({}, options, { - wrap: false, - toRegex: true - })); + if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES$1) { + isGlob = token.isGlob = true; - if (range.length !== 0) { - return args.length > 1 && range.length > 1 ? `(${range})` : range; + 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 (node.nodes) { - for (let child of node.nodes) { - output += walk(child, node); + if (isGlob === true) { + finished = true; + + if (scanToEnd === true) { + continue; } - } - return output; - }; + break; + } + } - return walk(ast); -}; + if (opts.noext === true) { + isExtglob = false; + isGlob = false; + } -var compile_1 = compile; + let base = str; + let prefix = ''; + let glob = ''; -const append = (queue = '', stash = '', enclose = false) => { - let result = []; - queue = [].concat(queue); - stash = [].concat(stash); - if (!stash.length) return queue; + if (start > 0) { + prefix = str.slice(0, start); + str = str.slice(start); + lastIndex -= start; + } - if (!queue.length) { - return enclose ? utils$2.flatten(stash).map(ele => `{${ele}}`) : stash; + 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; } - 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); - } + if (base && base !== '' && base !== '/' && base !== str) { + if (isPathSeparator(base.charCodeAt(base.length - 1))) { + base = base.slice(0, -1); } } - return utils$2.flatten(result); -}; + if (opts.unescape === true) { + if (glob) glob = utils$2.removeBackslashes(glob); -const expand$1 = (ast, options = {}) => { - let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit; + if (base && backslashes === true) { + base = utils$2.removeBackslashes(base); + } + } - let walk = (node, parent = {}) => { - node.queue = []; - let p = parent; - let q = parent.queue; + const state = { + prefix, + input, + start, + base, + glob, + isBrace, + isBracket, + isGlob, + isExtglob, + isGlobstar, + negated + }; - while (p.type !== 'brace' && p.type !== 'root' && p.parent) { - p = p.parent; - q = p.queue; - } + if (opts.tokens === true) { + state.maxDepth = 0; - if (node.invalid || node.dollar) { - q.push(append(q.pop(), stringify(node, options))); - return; + if (!isPathSeparator(code)) { + tokens.push(token); } - if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) { - q.push(append(q.pop(), ['{}'])); - return; - } + state.tokens = tokens; + } - if (node.nodes && node.ranges > 0) { - let args = utils$2.reduce(node.nodes); + if (opts.parts === true || opts.tokens === true) { + let prevIndex; - if (utils$2.exceedsLimit(...args, options.step, rangeLimit)) { - throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); - } + for (let idx = 0; idx < slashes.length; idx++) { + const n = prevIndex ? prevIndex + 1 : start; + const i = slashes[idx]; + const value = input.slice(n, i); - let range = fillRange(...args, options); + if (opts.tokens) { + if (idx === 0 && start !== 0) { + tokens[idx].isPrefix = true; + tokens[idx].value = prefix; + } else { + tokens[idx].value = value; + } - if (range.length === 0) { - range = stringify(node, options); + depth(tokens[idx]); + state.maxDepth += tokens[idx].depth; } - q.push(append(q.pop(), range)); - node.nodes = []; - return; + if (idx !== 0 || value !== '') { + parts.push(value); + } + + prevIndex = i; } - let enclose = utils$2.encloseBrace(node); - let queue = node.queue; - let block = node; + if (prevIndex && prevIndex + 1 < input.length) { + const value = input.slice(prevIndex + 1); + parts.push(value); - while (block.type !== 'brace' && block.type !== 'root' && block.parent) { - block = block.parent; - queue = block.queue; + if (opts.tokens) { + tokens[tokens.length - 1].value = value; + depth(tokens[tokens.length - 1]); + state.maxDepth += tokens[tokens.length - 1].depth; + } } - for (let i = 0; i < node.nodes.length; i++) { - let child = node.nodes[i]; + state.slashes = slashes; + state.parts = parts; + } - if (child.type === 'comma' && node.type === 'brace') { - if (i === 1) queue.push(''); - queue.push(''); - continue; - } + return state; +}; - if (child.type === 'close') { - q.push(append(q.pop(), queue, enclose)); - continue; - } +var scan_1 = scan; - if (child.value && child.type !== 'open') { - queue.push(append(queue.pop(), child.value)); - continue; - } +/** + * Constants + */ - if (child.nodes) { - walk(child, node); - } - } - return queue; - }; +const { + MAX_LENGTH: MAX_LENGTH$3, + POSIX_REGEX_SOURCE: POSIX_REGEX_SOURCE$1, + 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$2.escapeRegex(v)).join('..'); + } - return utils$2.flatten(walk(ast)); + return value; }; +/** + * Create the message for a syntax error + */ -var expand_1 = expand$1; -var constants$2 = { - MAX_LENGTH: 1024 * 64, - // Digits - CHAR_0: '0', +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} + */ - /* 0 */ - CHAR_9: '9', - /* 9 */ - // Alphabet chars. - CHAR_UPPERCASE_A: 'A', +const parse$6 = (input, options) => { + if (typeof input !== 'string') { + throw new TypeError('Expected a string'); + } - /* A */ - CHAR_LOWERCASE_A: 'a', + input = REPLACEMENTS[input] || input; + const opts = Object.assign({}, options); + const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH$3, opts.maxLength) : MAX_LENGTH$3; + let len = input.length; - /* a */ - CHAR_UPPERCASE_Z: 'Z', + if (len > max) { + throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); + } - /* Z */ - CHAR_LOWERCASE_Z: 'z', + const bos = { + type: 'bos', + value: '', + output: opts.prepend || '' + }; + const tokens = [bos]; + const capture = opts.capture ? '' : '?:'; + const win32 = utils$2.isWindows(options); // create constants based on platform, for windows or posix - /* z */ - CHAR_LEFT_PARENTHESES: '(', + 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; - /* ( */ - CHAR_RIGHT_PARENTHESES: ')', + const globstar = opts => { + return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; + }; - /* ) */ - CHAR_ASTERISK: '*', + const nodot = opts.dot ? '' : NO_DOT; + const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; + let star = opts.bash === true ? globstar(opts) : STAR; - /* * */ - // Non-alphabetic chars. - CHAR_AMPERSAND: '&', + if (opts.capture) { + star = `(${star})`; + } // minimatch options support - /* & */ - CHAR_AT: '@', - /* @ */ - CHAR_BACKSLASH: '\\', + if (typeof opts.noext === 'boolean') { + opts.noextglob = opts.noext; + } - /* \ */ - CHAR_BACKTICK: '`', + 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$2.removePrefix(input, state); + len = input.length; + const extglobs = []; + const braces = []; + const stack = []; + let prev = bos; + let value; + /** + * Tokenizing helpers + */ - /* ` */ - CHAR_CARRIAGE_RETURN: '\r', + const eos = () => state.index === len - 1; - /* \r */ - CHAR_CIRCUMFLEX_ACCENT: '^', + const peek = state.peek = (n = 1) => input[state.index + n]; - /* ^ */ - CHAR_COLON: ':', + const advance = state.advance = () => input[++state.index]; - /* : */ - CHAR_COMMA: ',', + const remaining = () => input.slice(state.index + 1); - /* , */ - CHAR_DOLLAR: '$', + const consume = (value = '', num = 0) => { + state.consumed += value; + state.index += num; + }; - /* . */ - CHAR_DOT: '.', + const append = token => { + state.output += token.output != null ? token.output : token.value; + consume(token.value); + }; - /* . */ - CHAR_DOUBLE_QUOTE: '"', + const negate = () => { + let count = 1; - /* " */ - CHAR_EQUAL: '=', + while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { + advance(); + state.start++; + count++; + } - /* = */ - CHAR_EXCLAMATION_MARK: '!', + if (count % 2 === 0) { + return false; + } - /* ! */ - CHAR_FORM_FEED: '\f', + state.negated = true; + state.start++; + return true; + }; - /* \f */ - CHAR_FORWARD_SLASH: '/', + const increment = type => { + state[type]++; + stack.push(type); + }; - /* / */ - CHAR_HASH: '#', + 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. + */ - /* # */ - CHAR_HYPHEN_MINUS: '-', - /* - */ - CHAR_LEFT_ANGLE_BRACKET: '<', + 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' && !EXTGLOB_CHARS[tok.value]) { + 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; + }; - /* < */ - CHAR_LEFT_CURLY_BRACE: '{', + const extglobOpen = (type, value) => { + const token = Object.assign({}, 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); + }; - /* { */ - CHAR_LEFT_SQUARE_BRACKET: '[', + const extglobClose = token => { + let output = token.close + (opts.capture ? ')' : ''); - /* [ */ - CHAR_LINE_FEED: '\n', + if (token.type === 'negate') { + let extglobStar = star; - /* \n */ - CHAR_NO_BREAK_SPACE: '\u00A0', + if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { + extglobStar = globstar(opts); + } - /* \u00A0 */ - CHAR_PERCENT: '%', + if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { + output = token.close = `)$))${extglobStar}`; + } - /* % */ - CHAR_PLUS: '+', + if (token.prev.type === 'bos' && eos()) { + state.negatedExtglob = true; + } + } - /* + */ - CHAR_QUESTION_MARK: '?', + push({ + type: 'paren', + extglob: true, + value, + output + }); + decrement('parens'); + }; + /** + * Fast paths + */ - /* ? */ - CHAR_RIGHT_ANGLE_BRACKET: '>', - /* > */ - CHAR_RIGHT_CURLY_BRACE: '}', + 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; + } - /* } */ - CHAR_RIGHT_SQUARE_BRACKET: ']', + if (first === '?') { + if (esc) { + return esc + first + (rest ? QMARK.repeat(rest.length) : ''); + } - /* ] */ - CHAR_SEMICOLON: ';', + if (index === 0) { + return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); + } - /* ; */ - CHAR_SINGLE_QUOTE: '\'', + return QMARK.repeat(chars.length); + } - /* ' */ - CHAR_SPACE: ' ', + if (first === '.') { + return DOT_LITERAL.repeat(chars.length); + } - /* */ - CHAR_TAB: '\t', + if (first === '*') { + if (esc) { + return esc + first + (rest ? star : ''); + } - /* \t */ - CHAR_UNDERSCORE: '_', + return star; + } - /* _ */ - CHAR_VERTICAL_LINE: '|', + return esc ? m : `\\${m}`; + }); - /* | */ - CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' - /* \uFEFF */ + 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; + } -/** - * Constants - */ + state.output = utils$2.wrapOutput(output, state, options); + return state; + } + /** + * Tokenize input until we reach end-of-string + */ -const { - MAX_LENGTH: MAX_LENGTH$2, - CHAR_BACKSLASH, + while (!eos()) { + value = advance(); - /* \ */ - CHAR_BACKTICK, + if (value === '\u0000') { + continue; + } + /** + * Escaped characters + */ - /* ` */ - CHAR_COMMA: CHAR_COMMA$1, - /* , */ - CHAR_DOT, + if (value === '\\') { + const next = peek(); - /* . */ - CHAR_LEFT_PARENTHESES, + if (next === '/' && opts.bash !== true) { + continue; + } - /* ( */ - CHAR_RIGHT_PARENTHESES, + if (next === '.' || next === ';') { + continue; + } - /* ) */ - CHAR_LEFT_CURLY_BRACE, + if (!next) { + value += '\\'; + push({ + type: 'text', + value + }); + continue; + } // collapse slashes to reduce potential for exploits - /* { */ - CHAR_RIGHT_CURLY_BRACE, - /* } */ - CHAR_LEFT_SQUARE_BRACKET, + const match = /^\\+/.exec(remaining()); + let slashes = 0; - /* [ */ - CHAR_RIGHT_SQUARE_BRACKET, + if (match && match[0].length > 2) { + slashes = match[0].length; + state.index += slashes; - /* ] */ - CHAR_DOUBLE_QUOTE, + if (slashes % 2 !== 0) { + value += '\\'; + } + } - /* " */ - CHAR_SINGLE_QUOTE, + if (opts.unescape === true) { + value = advance() || ''; + } else { + value += advance() || ''; + } - /* ' */ - CHAR_NO_BREAK_SPACE, - CHAR_ZERO_WIDTH_NOBREAK_SPACE -} = constants$2; -/** - * parse - */ + if (state.brackets === 0) { + push({ + type: 'text', + value + }); + continue; + } + } + /** + * If we're inside a regex character class, continue + * until we reach the closing bracket. + */ -const parse$3 = (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$2, opts.maxLength) : MAX_LENGTH$2; + if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { + if (opts.posix !== false && value === ':') { + const inner = prev.value.slice(1); - if (input.length > max) { - throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`); - } + if (inner.includes('[')) { + prev.posix = true; - 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 - */ + 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$1[rest]; - const advance = () => input[index++]; + if (posix) { + prev.value = pre + posix; + state.backtrack = true; + advance(); - const push = node => { - if (node.type === 'text' && prev.type === 'dot') { - prev.type = 'text'; - } + if (!bos.output && tokens.indexOf(prev) === 1) { + bos.output = ONE_CHAR; + } - if (prev && prev.type === 'text' && node.type === 'text') { - prev.value += node.value; - return; - } + continue; + } + } + } + } - block.nodes.push(node); - node.parent = block; - node.prev = prev; - prev = node; - return node; - }; + if (value === '[' && peek() !== ':' || value === '-' && peek() === ']') { + value = `\\${value}`; + } - push({ - type: 'bos' - }); + if (value === ']' && (prev.value === '[' || prev.value === '[^')) { + value = `\\${value}`; + } - while (index < length) { - block = stack[stack.length - 1]; - value = advance(); - /** - * Invalid chars - */ + if (opts.posix === true && value === '!' && prev.value === '[') { + value = '^'; + } - if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) { + prev.value += value; + append({ + value + }); continue; } /** - * Escaped chars + * If we're inside a quoted string, continue + * until we reach the closing double quote. */ - if (value === CHAR_BACKSLASH) { - push({ - type: 'text', - value: (options.keepEscaping ? value : '') + advance() + if (state.quotes === 1 && value !== '"') { + value = utils$2.escapeRegex(value); + prev.value += value; + append({ + value }); continue; } /** - * Right square bracket (literal): ']' + * Double quotes */ - if (value === CHAR_RIGHT_SQUARE_BRACKET) { - push({ - type: 'text', - value: '\\' + value - }); + if (value === '"') { + state.quotes = state.quotes === 1 ? 0 : 1; + + if (opts.keepQuotes === true) { + push({ + type: 'text', + value + }); + } + continue; } /** - * Left square bracket: '[' + * Parentheses */ - if (value === CHAR_LEFT_SQUARE_BRACKET) { - brackets++; - let next; - - while (index < length && (next = advance())) { - value += next; - - if (next === CHAR_LEFT_SQUARE_BRACKET) { - brackets++; - continue; - } + if (value === '(') { + increment('parens'); + push({ + type: 'paren', + value + }); + continue; + } - if (next === CHAR_BACKSLASH) { - value += advance(); - continue; - } + if (value === ')') { + if (state.parens === 0 && opts.strictBrackets === true) { + throw new SyntaxError(syntaxError$1('opening', '(')); + } - if (next === CHAR_RIGHT_SQUARE_BRACKET) { - brackets--; + const extglob = extglobs[extglobs.length - 1]; - if (brackets === 0) { - break; - } - } + if (extglob && state.parens === extglob.parens + 1) { + extglobClose(extglobs.pop()); + continue; } push({ - type: 'text', - value + type: 'paren', + value, + output: state.parens ? ')' : '\\)' }); + decrement('parens'); continue; } /** - * Parentheses + * Square brackets */ - if (value === CHAR_LEFT_PARENTHESES) { - block = push({ - type: 'paren', - nodes: [] - }); - stack.push(block); + 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: 'text', + type: 'bracket', value }); continue; } - if (value === CHAR_RIGHT_PARENTHESES) { - if (block.type !== 'paren') { + if (value === ']') { + if (opts.nobracket === true || prev && prev.type === 'bracket' && prev.value.length === 1) { push({ type: 'text', - value + value, + output: `\\${value}` }); continue; } - block = stack.pop(); - push({ - type: 'text', + 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 - }); - block = stack[stack.length - 1]; + }); // when literal brackets are explicitly disabled + // assume we should match with a regex character class + + if (opts.literalBrackets === false || utils$2.hasRegexChars(prevValue)) { + continue; + } + + const escaped = utils$2.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; } /** - * Quotes: '|"|` + * Braces */ - if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) { - let open = value; - let next; + 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 (options.keepQuotes !== true) { - value = ''; + if (value === '}') { + const brace = braces[braces.length - 1]; + + if (opts.nobrace === true || !brace) { + push({ + type: 'text', + value, + output: value + }); + continue; } - while (index < length && (next = advance())) { - if (next === CHAR_BACKSLASH) { - value += next + advance(); - 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; } + } - if (next === open) { - if (options.keepQuotes === true) value += next; - break; - } + push({ + type: 'brace', + value, + output + }); + decrement('braces'); + braces.pop(); + continue; + } + /** + * Pipes + */ - value += next; + + if (value === '|') { + if (extglobs.length > 0) { + extglobs[extglobs.length - 1].conditions++; } push({ @@ -29511,6447 +32851,6490 @@ const parse$3 = (input, options = {}) => { continue; } /** - * Left curly brace: '{' + * Commas */ - 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); + if (value === ',') { + let output = value; + const brace = braces[braces.length - 1]; + + if (brace && stack[stack.length - 1] === 'braces') { + brace.comma = true; + output = '|'; + } + push({ - type: 'open', - value + type: 'comma', + value, + output }); continue; } /** - * Right curly brace: '}' + * Slashes */ - if (value === CHAR_RIGHT_CURLY_BRACE) { - if (block.type !== 'brace') { - push({ - type: 'text', - value - }); + 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; } - let type = 'close'; - block = stack.pop(); - block.close = true; push({ - type, - value + type: 'slash', + value, + output: SLASH_LITERAL }); - depth--; - block = stack[stack.length - 1]; continue; } /** - * Comma: ',' + * Dots */ - if (value === CHAR_COMMA$1 && depth > 0) { - if (block.ranges > 0) { - block.ranges = 0; - let open = block.nodes.shift(); - block.nodes = [open, { + 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: stringify(block) - }]; + value, + output: DOT_LITERAL + }); + continue; } push({ - type: 'comma', - value + type: 'dot', + value, + output: DOT_LITERAL }); - block.commas++; continue; } /** - * Dot: '.' + * Question marks */ - if (value === CHAR_DOT && depth > 0 && block.commas === 0) { - let siblings = block.nodes; + if (value === '?') { + const isGroup = prev && prev.value === '('; - if (depth === 0 || siblings.length === 0) { - push({ - type: 'text', - value - }); + if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('qmark', value); continue; } - if (prev.type === 'dot') { - block.range = []; - prev.value += value; - prev.type = 'range'; + if (prev && prev.type === 'paren') { + const next = peek(); + let output = value; - if (block.nodes.length !== 3 && block.nodes.length !== 5) { - block.invalid = true; - block.ranges = 0; - prev.type = 'text'; - continue; + if (next === '<' && !utils$2.supportsLookbehinds()) { + throw new Error('Node.js v10 or higher is required for regex lookbehinds'); } - block.ranges++; - block.args = []; + if (prev.value === '(' && !/[!=<:]/.test(next) || next === '<' && !/<([!=]|\w+>)/.test(remaining())) { + output = `\\${value}`; + } + + push({ + type: 'text', + value, + output + }); continue; } - if (prev.type === 'range') { - siblings.pop(); - let before = siblings[siblings.length - 1]; - before.value += prev.value + value; - prev = before; - block.ranges--; + if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { + push({ + type: 'qmark', + value, + output: QMARK_NO_DOT + }); continue; } push({ - type: 'dot', - value + type: 'qmark', + value, + output: QMARK }); continue; } /** - * Text + * Exclamation */ - 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; + if (value === '!') { + if (opts.noextglob !== true && peek() === '(') { + if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { + extglobOpen('negate', value); + continue; } - }); // 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 = parse$3; - -/** - * 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 = (input, options = {}) => { - let output = []; - - if (Array.isArray(input)) { - for (let pattern of input) { - let result = braces.create(pattern, options); + } - if (Array.isArray(result)) { - output.push(...result); - } else { - output.push(result); + if (opts.nonegate !== true && state.index === 0) { + negate(); + continue; } } - } else { - output = [].concat(braces.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.parse = (input, options = {}) => parse_1(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.stringify = (input, options = {}) => { - if (typeof input === 'string') { - return stringify(braces.parse(input, options), options); - } - - return stringify(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.compile = (input, options = {}) => { - if (typeof input === 'string') { - input = braces.parse(input, options); - } - - return compile_1(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.expand = (input, options = {}) => { - if (typeof input === 'string') { - input = braces.parse(input, options); - } - - let result = expand_1(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.create = (input, options = {}) => { - if (input === '' || input.length < 3) { - return [input]; - } - - return options.expand !== true ? braces.compile(input, options) : braces.expand(input, options); -}; -/** - * Expose "braces" - */ + /** + * Plus + */ -var braces_1 = braces; + if (value === '+') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('plus', value); + continue; + } -const WIN_SLASH = '\\\\/'; -const WIN_NO_SLASH = `[^${WIN_SLASH}]`; -/** - * Posix glob regex - */ + if (prev && prev.value === '(' || opts.regex === false) { + push({ + type: 'plus', + value, + output: PLUS_LITERAL + }); + continue; + } -const DOT_LITERAL = '\\.'; -const PLUS_LITERAL = '\\+'; -const QMARK_LITERAL = '\\?'; -const SLASH_LITERAL = '\\/'; -const ONE_CHAR = '(?=.)'; -const QMARK = '[^/]'; -const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; -const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; -const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; -const NO_DOT = `(?!${DOT_LITERAL})`; -const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; -const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; -const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; -const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; -const STAR = `${QMARK}*?`; -const POSIX_CHARS = { - DOT_LITERAL, - PLUS_LITERAL, - QMARK_LITERAL, - SLASH_LITERAL, - ONE_CHAR, - QMARK, - END_ANCHOR, - DOTS_SLASH, - NO_DOT, - NO_DOTS, - NO_DOT_SLASH, - NO_DOTS_SLASH, - QMARK_NO_DOT, - STAR, - START_ANCHOR -}; -/** - * Windows glob regex - */ + if (prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace') || state.parens > 0) { + push({ + type: 'plus', + value + }); + continue; + } -const WINDOWS_CHARS = Object.assign({}, 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 - */ + push({ + type: 'plus', + value: PLUS_LITERAL + }); + continue; + } + /** + * Plain text + */ -const POSIX_REGEX_SOURCE = { - alnum: 'a-zA-Z0-9', - alpha: 'a-zA-Z', - ascii: '\\x00-\\x7F', - blank: ' \\t', - cntrl: '\\x00-\\x1F\\x7F', - digit: '0-9', - graph: '\\x21-\\x7E', - lower: 'a-z', - print: '\\x20-\\x7E ', - punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', - space: ' \\t\\r\\n\\v\\f', - upper: 'A-Z', - word: 'A-Za-z0-9_', - xdigit: 'A-Fa-f0-9' -}; -var constants$3 = { - MAX_LENGTH: 1024 * 64, - POSIX_REGEX_SOURCE, - // regular expressions - REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, - REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, - REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, - REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, - REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, - REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, - // Replace globs with equivalent patterns to reduce parsing time. - REPLACEMENTS: { - '***': '*', - '**/**': '**', - '**/**/**': '**' - }, - // Digits - CHAR_0: 48, - /* 0 */ - CHAR_9: 57, + if (value === '@') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + push({ + type: 'at', + extglob: true, + value, + output: '' + }); + continue; + } - /* 9 */ - // Alphabet chars. - CHAR_UPPERCASE_A: 65, + push({ + type: 'text', + value + }); + continue; + } + /** + * Plain text + */ - /* A */ - CHAR_LOWERCASE_A: 97, - /* a */ - CHAR_UPPERCASE_Z: 90, + if (value !== '*') { + if (value === '$' || value === '^') { + value = `\\${value}`; + } - /* Z */ - CHAR_LOWERCASE_Z: 122, + const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); - /* z */ - CHAR_LEFT_PARENTHESES: 40, + if (match) { + value += match[0]; + state.index += match[0].length; + } - /* ( */ - CHAR_RIGHT_PARENTHESES: 41, + push({ + type: 'text', + value + }); + continue; + } + /** + * Stars + */ - /* ) */ - CHAR_ASTERISK: 42, - /* * */ - // Non-alphabetic chars. - CHAR_AMPERSAND: 38, + 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; + } - /* & */ - CHAR_AT: 64, + let rest = remaining(); - /* @ */ - CHAR_BACKWARD_SLASH: 92, + if (opts.noextglob !== true && /^\([^?]/.test(rest)) { + extglobOpen('star', value); + continue; + } - /* \ */ - CHAR_CARRIAGE_RETURN: 13, + if (prev.type === 'star') { + if (opts.noglobstar === true) { + consume(value); + continue; + } - /* \r */ - CHAR_CIRCUMFLEX_ACCENT: 94, + 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'); - /* ^ */ - CHAR_COLON: 58, + if (opts.bash === true && (!isStart || rest[0] && rest[0] !== '/')) { + push({ + type: 'star', + value, + output: '' + }); + continue; + } - /* : */ - CHAR_COMMA: 44, + const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); + const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); - /* , */ - CHAR_DOT: 46, + if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { + push({ + type: 'star', + value, + output: '' + }); + continue; + } // strip consecutive `/**/` - /* . */ - CHAR_DOUBLE_QUOTE: 34, - /* " */ - CHAR_EQUAL: 61, + while (rest.slice(0, 3) === '/**') { + const after = input[state.index + 4]; - /* = */ - CHAR_EXCLAMATION_MARK: 33, + if (after && after !== '/') { + break; + } - /* ! */ - CHAR_FORM_FEED: 12, + rest = rest.slice(3); + consume('/**', 3); + } - /* \f */ - CHAR_FORWARD_SLASH: 47, + 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; + } - /* / */ - CHAR_GRAVE_ACCENT: 96, + 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; + } - /* ` */ - CHAR_HASH: 35, + 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; + } - /* # */ - CHAR_HYPHEN_MINUS: 45, + 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 - /* - */ - CHAR_LEFT_ANGLE_BRACKET: 60, - /* < */ - CHAR_LEFT_CURLY_BRACE: 123, + state.output = state.output.slice(0, -prev.output.length); // reset previous token to globstar - /* { */ - CHAR_LEFT_SQUARE_BRACKET: 91, + prev.type = 'globstar'; + prev.output = globstar(opts); + prev.value += value; // reset output with globstar - /* [ */ - CHAR_LINE_FEED: 10, + state.output += prev.output; + state.globstar = true; + consume(value); + continue; + } - /* \n */ - CHAR_NO_BREAK_SPACE: 160, + const token = { + type: 'star', + value, + output: star + }; - /* \u00A0 */ - CHAR_PERCENT: 37, + if (opts.bash === true) { + token.output = '.*?'; - /* % */ - CHAR_PLUS: 43, + if (prev.type === 'bos' || prev.type === 'slash') { + token.output = nodot + token.output; + } - /* + */ - CHAR_QUESTION_MARK: 63, + push(token); + continue; + } - /* ? */ - CHAR_RIGHT_ANGLE_BRACKET: 62, + if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { + token.output = value; + push(token); + continue; + } - /* > */ - CHAR_RIGHT_CURLY_BRACE: 125, + 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; + } - /* } */ - CHAR_RIGHT_SQUARE_BRACKET: 93, + if (peek() !== '*') { + state.output += ONE_CHAR; + prev.output += ONE_CHAR; + } + } - /* ] */ - CHAR_SEMICOLON: 59, + push(token); + } - /* ; */ - CHAR_SINGLE_QUOTE: 39, + while (state.brackets > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError$1('closing', ']')); + state.output = utils$2.escapeLast(state.output, '['); + decrement('brackets'); + } - /* ' */ - CHAR_SPACE: 32, + while (state.parens > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError$1('closing', ')')); + state.output = utils$2.escapeLast(state.output, '('); + decrement('parens'); + } - /* */ - CHAR_TAB: 9, + while (state.braces > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError$1('closing', '}')); + state.output = utils$2.escapeLast(state.output, '{'); + decrement('braces'); + } - /* \t */ - CHAR_UNDERSCORE: 95, + 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 - /* _ */ - CHAR_VERTICAL_LINE: 124, - /* | */ - CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, + if (state.backtrack === true) { + state.output = ''; - /* \uFEFF */ - SEP: path$2.sep, + for (const token of state.tokens) { + state.output += token.output != null ? token.output : token.value; - /** - * 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: ')' + if (token.suffix) { + state.output += token.suffix; } - }; - }, - - /** - * Create GLOB_CHARS - */ - globChars(win32) { - return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; + } } + 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. + */ -var utils$3 = createCommonjsModule(function (module, exports) { - const win32 = process.platform === 'win32'; +parse$6.fastpaths = (input, options) => { + const opts = Object.assign({}, options); + const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH$3, opts.maxLength) : MAX_LENGTH$3; + 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$2.isWindows(options); // create constants based on platform, for windows or posix + const { - REGEX_BACKSLASH, - REGEX_REMOVE_BACKSLASH, - REGEX_SPECIAL_CHARS, - REGEX_SPECIAL_CHARS_GLOBAL - } = constants$3; + 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; - exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); + if (opts.capture) { + star = `(${star})`; + } - exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); + const globstar = opts => { + if (opts.noglobstar === true) return star; + return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; + }; - exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); + const create = str => { + switch (str) { + case '*': + return `${nodot}${ONE_CHAR}${star}`; - exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); + case '.*': + return `${DOT_LITERAL}${ONE_CHAR}${star}`; - exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); + case '*.*': + return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; - exports.removeBackslashes = str => { - return str.replace(REGEX_REMOVE_BACKSLASH, match => { - return match === '\\' ? '' : match; - }); - }; + case '*/*': + return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; - exports.supportsLookbehinds = () => { - const segs = process.version.slice(1).split('.').map(Number); + case '**': + return nodot + globstar(opts); - if (segs.length === 3 && segs[0] >= 9 || segs[0] === 8 && segs[1] >= 10) { - return true; - } + case '**/*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; - return false; - }; + case '**/*.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; - exports.isWindows = options => { - if (options && typeof options.windows === 'boolean') { - return options.windows; - } + case '**/.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; - return win32 === true || path$2.sep === '\\'; + default: + { + const match = /^(.*?)\.(\w+)$/.exec(str); + if (!match) return; + const source = create(match[1]); + if (!source) return; + return source + DOT_LITERAL + match[2]; + } + } }; - 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)}`; - }; + const output = utils$2.removePrefix(input, state); + let source = create(output); - exports.removePrefix = (input, state = {}) => { - let output = input; + if (source && opts.strictSlashes !== true) { + source += `${SLASH_LITERAL}?`; + } - if (output.startsWith('./')) { - output = output.slice(2); - state.prefix = './'; - } + return source; +}; - return output; - }; +var parse_1$1 = parse$6; - exports.wrapOutput = (input, state = {}, options = {}) => { - const prepend = options.contains ? '' : '^'; - const append = options.contains ? '' : '$'; - let output = `${prepend}(?:${input})${append}`; +const isObject$2 = 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 = (glob, options, returnState = false) => { + if (Array.isArray(glob)) { + const fns = glob.map(input => picomatch(input, options, returnState)); + + const arrayMatcher = str => { + for (const isMatch of fns) { + const state = isMatch(str); + if (state) return state; + } + + return false; + }; + + return arrayMatcher; + } + + const isState = isObject$2(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$2.isWindows(options); + const regex = isState ? picomatch.compileRe(glob, options) : picomatch.makeRe(glob, options, false, true); + const state = regex.state; + delete regex.state; + + let isIgnored = () => false; + + if (opts.ignore) { + const ignoreOpts = Object.assign({}, options, { + ignore: null, + onMatch: null, + onResult: null + }); + isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); + } + + const matcher = (input, returnObject = false) => { + const { + isMatch, + match, + output + } = picomatch.test(input, regex, options, { + glob, + posix + }); + const result = { + glob, + state, + regex, + posix, + input, + output, + match, + isMatch + }; + + if (typeof opts.onResult === 'function') { + opts.onResult(result); + } - if (state.negated === true) { - output = `(?:^(?!${output}).*$)`; + if (isMatch === false) { + result.isMatch = false; + return returnObject ? result : false; } - return output; - }; -}); -var utils_1$3 = utils$3.isObject; -var utils_2$3 = utils$3.hasRegexChars; -var utils_3$3 = utils$3.isRegexChar; -var utils_4$2 = utils$3.escapeRegex; -var utils_5$2 = utils$3.toPosixSlashes; -var utils_6$2 = utils$3.removeBackslashes; -var utils_7$2 = utils$3.supportsLookbehinds; -var utils_8$2 = utils$3.isWindows; -var utils_9$2 = utils$3.escapeLast; -var utils_10$1 = utils$3.removePrefix; -var utils_11$1 = utils$3.wrapOutput; + if (isIgnored(input)) { + if (typeof opts.onIgnore === 'function') { + opts.onIgnore(result); + } -const { - CHAR_ASTERISK, + result.isMatch = false; + return returnObject ? result : false; + } - /* * */ - CHAR_AT, + if (typeof opts.onMatch === 'function') { + opts.onMatch(result); + } - /* @ */ - CHAR_BACKWARD_SLASH, + return returnObject ? result : true; + }; - /* \ */ - CHAR_COMMA: CHAR_COMMA$2, + if (returnState) { + matcher.state = state; + } - /* , */ - CHAR_DOT: CHAR_DOT$1, + 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 + */ - /* . */ - CHAR_EXCLAMATION_MARK, - /* ! */ - CHAR_FORWARD_SLASH, +picomatch.test = (input, regex, options, { + glob, + posix +} = {}) => { + if (typeof input !== 'string') { + throw new TypeError('Expected input to be a string'); + } - /* / */ - CHAR_LEFT_CURLY_BRACE: CHAR_LEFT_CURLY_BRACE$1, + if (input === '') { + return { + isMatch: false, + output: '' + }; + } - /* { */ - CHAR_LEFT_PARENTHESES: CHAR_LEFT_PARENTHESES$1, + const opts = options || {}; + const format = opts.format || (posix ? utils$2.toPosixSlashes : null); + let match = input === glob; + let output = match && format ? format(input) : input; - /* ( */ - CHAR_LEFT_SQUARE_BRACKET: CHAR_LEFT_SQUARE_BRACKET$1, + if (match === false) { + output = format ? format(input) : input; + match = output === glob; + } - /* [ */ - CHAR_PLUS: CHAR_PLUS$1, + if (match === false || opts.capture === true) { + if (opts.matchBase === true || opts.basename === true) { + match = picomatch.matchBase(input, regex, options, posix); + } else { + match = regex.exec(output); + } + } - /* + */ - CHAR_QUESTION_MARK, + 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 + */ - /* ? */ - CHAR_RIGHT_CURLY_BRACE: CHAR_RIGHT_CURLY_BRACE$1, - /* } */ - CHAR_RIGHT_PARENTHESES: CHAR_RIGHT_PARENTHESES$1, +picomatch.matchBase = (input, glob, options, posix = utils$2.isWindows(options)) => { + const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); + return regex.test(path__default['default'].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 + */ - /* ) */ - CHAR_RIGHT_SQUARE_BRACKET: CHAR_RIGHT_SQUARE_BRACKET$1 - /* ] */ -} = constants$3; +picomatch.isMatch = (str, patterns, options) => picomatch(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 + */ -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; - } +picomatch.parse = (pattern, options) => { + if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); + return parse_1$1(pattern, Object.assign({}, options, { + fastpaths: false + })); }; /** - * 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), and `negated` (true if the path starts with `!`). + * Scan a glob pattern to separate the pattern into segments. * * ```js - * const pm = require('picomatch'); - * console.log(pm.scan('foo/bar/*.js')); - * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.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} `str` + * @param {String} `input` Glob pattern to scan. * @param {Object} `options` - * @return {Object} Returns an object with tokens and regex source string. + * @return {Object} Returns an object with * @api public */ -const scan = (input, options) => { - const opts = options || {}; - const length = input.length - 1; - const scanToEnd = opts.parts === true || opts.scanToEnd === true; - const slashes = []; - const tokens = []; - const parts = []; - let str = input; - let index = -1; - let start = 0; - let lastIndex = 0; - let isBrace = false; - let isBracket = false; - let isGlob = false; - let isExtglob = false; - let isGlobstar = false; - let braceEscaped = false; - let backslashes = false; - let negated = false; - let 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); +picomatch.scan = (input, options) => scan_1(input, options); +/** + * 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` + * @return {RegExp} Returns a regex created from the given pattern. + * @api public + */ - const advance = () => { - prev = code; - return str.charCodeAt(++index); - }; - while (index < length) { - code = advance(); - let next; +picomatch.compileRe = (parsed, options, returnOutput = false, returnState = false) => { + if (returnOutput === true) { + return parsed.output; + } - if (code === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - code = advance(); + const opts = options || {}; + const prepend = opts.contains ? '' : '^'; + const append = opts.contains ? '' : '$'; + let source = `${prepend}(?:${parsed.output})${append}`; - if (code === CHAR_LEFT_CURLY_BRACE$1) { - braceEscaped = true; - } + if (parsed && parsed.negated === true) { + source = `^(?!${source}).*$`; + } - continue; - } + const regex = picomatch.toRegex(source, options); - if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE$1) { - braces++; + if (returnState === true) { + regex.state = parsed; + } - while (eos() !== true && (code = advance())) { - if (code === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - advance(); - continue; - } + return regex; +}; - if (code === CHAR_LEFT_CURLY_BRACE$1) { - braces++; - continue; - } +picomatch.makeRe = (input, options, returnOutput = false, returnState = false) => { + if (!input || typeof input !== 'string') { + throw new TypeError('Expected a non-empty string'); + } - if (braceEscaped !== true && code === CHAR_DOT$1 && (code = advance()) === CHAR_DOT$1) { - isBrace = token.isBrace = true; - isGlob = token.isGlob = true; - finished = true; + const opts = options || {}; + let parsed = { + negated: false, + fastpaths: true + }; + let prefix = ''; + let output; - if (scanToEnd === true) { - continue; - } + if (input.startsWith('./')) { + input = input.slice(2); + prefix = parsed.prefix = './'; + } - break; - } + if (opts.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { + output = parse_1$1.fastpaths(input, options); + } - if (braceEscaped !== true && code === CHAR_COMMA$2) { - isBrace = token.isBrace = true; - isGlob = token.isGlob = true; - finished = true; + if (output === undefined) { + parsed = parse_1$1(input, options); + parsed.prefix = prefix + (parsed.prefix || ''); + } else { + parsed.output = output; + } - if (scanToEnd === true) { - continue; - } + return picomatch.compileRe(parsed, options, returnOutput, returnState); +}; +/** + * Create a regular expression from the given regex source string. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch.toRegex(source[, options]); + * + * const { output } = picomatch.parse('*.js'); + * console.log(picomatch.toRegex(output)); + * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ + * ``` + * @param {String} `source` Regular expression source string. + * @param {Object} `options` + * @return {RegExp} + * @api public + */ - break; - } - if (code === CHAR_RIGHT_CURLY_BRACE$1) { - braces--; +picomatch.toRegex = (source, options) => { + try { + const opts = options || {}; + return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); + } catch (err) { + if (options && options.debug === true) throw err; + return /$^/; + } +}; +/** + * Picomatch constants. + * @return {Object} + */ - if (braces === 0) { - braceEscaped = false; - isBrace = token.isBrace = true; - finished = true; - break; - } - } - } - if (scanToEnd === true) { - continue; - } +picomatch.constants = constants$4; +/** + * Expose "picomatch" + */ - break; - } +var picomatch_1 = picomatch; - if (code === CHAR_FORWARD_SLASH) { - slashes.push(index); - tokens.push(token); - token = { - value: '', - depth: 0, - isGlob: false - }; - if (finished === true) continue; +var picomatch$1 = picomatch_1; - if (prev === CHAR_DOT$1 && index === start + 1) { - start += 2; - continue; - } +const isEmptyString = val => typeof val === 'string' && (val === '' || val === './'); +/** + * Returns an array of strings that match one or more glob patterns. + * + * ```js + * const mm = require('micromatch'); + * // mm(list, patterns[, options]); + * + * console.log(mm(['a.js', 'a.txt'], ['*.js'])); + * //=> [ 'a.js' ] + * ``` + * @param {String|Array} list List of strings to match. + * @param {String|Array} patterns One or more glob patterns to use for matching. + * @param {Object} options See available [options](#options) + * @return {Array} Returns an array of matches + * @summary false + * @api public + */ - lastIndex = index + 1; - continue; - } - if (opts.noext !== true) { - const isExtglobChar = code === CHAR_PLUS$1 || code === CHAR_AT || code === CHAR_ASTERISK || code === CHAR_QUESTION_MARK || code === CHAR_EXCLAMATION_MARK; +const micromatch = (list, patterns, options) => { + patterns = [].concat(patterns); + list = [].concat(list); + let omit = new Set(); + let keep = new Set(); + let items = new Set(); + let negatives = 0; - if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES$1) { - isGlob = token.isGlob = true; - isExtglob = token.isExtglob = true; - finished = true; + let onResult = state => { + items.add(state.output); - if (scanToEnd === true) { - while (eos() !== true && (code = advance())) { - if (code === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - code = advance(); - continue; - } + if (options && options.onResult) { + options.onResult(state); + } + }; - if (code === CHAR_RIGHT_PARENTHESES$1) { - isGlob = token.isGlob = true; - finished = true; - break; - } - } + for (let i = 0; i < patterns.length; i++) { + let isMatch = picomatch$1(String(patterns[i]), Object.assign({}, options, { + onResult + }), true); + let negated = isMatch.state.negated || isMatch.state.negatedExtglob; + if (negated) negatives++; - continue; - } + for (let item of list) { + let matched = isMatch(item, true); + let match = negated ? !matched.isMatch : matched.isMatch; + if (!match) continue; - break; + if (negated) { + omit.add(matched.output); + } else { + omit.delete(matched.output); + keep.add(matched.output); } } + } - if (code === CHAR_ASTERISK) { - if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; - isGlob = token.isGlob = true; - finished = true; - - if (scanToEnd === true) { - continue; - } + let result = negatives === patterns.length ? [...items] : [...keep]; + let matches = result.filter(item => !omit.has(item)); - break; + if (options && matches.length === 0) { + if (options.failglob === true) { + throw new Error(`No matches found for "${patterns.join(', ')}"`); } - if (code === CHAR_QUESTION_MARK) { - isGlob = token.isGlob = true; - finished = true; - - if (scanToEnd === true) { - continue; - } - - break; + if (options.nonull === true || options.nullglob === true) { + return options.unescape ? patterns.map(p => p.replace(/\\/g, '')) : patterns; } + } - if (code === CHAR_LEFT_SQUARE_BRACKET$1) { - while (eos() !== true && (next = advance())) { - if (next === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - advance(); - continue; - } + return matches; +}; +/** + * Backwards compatibility + */ - if (next === CHAR_RIGHT_SQUARE_BRACKET$1) { - isBracket = token.isBracket = true; - isGlob = token.isGlob = true; - finished = true; - if (scanToEnd === true) { - continue; - } +micromatch.match = micromatch; +/** + * Returns a matcher function from the given glob `pattern` and `options`. + * The returned function takes a string to match as its only argument and returns + * true if the string is a match. + * + * ```js + * const mm = require('micromatch'); + * // mm.matcher(pattern[, options]); + * + * const isMatch = mm.matcher('*.!(*a)'); + * console.log(isMatch('a.a')); //=> false + * console.log(isMatch('a.b')); //=> true + * ``` + * @param {String} `pattern` Glob pattern + * @param {Object} `options` + * @return {Function} Returns a matcher function. + * @api public + */ - break; - } - } - } +micromatch.matcher = (pattern, options) => picomatch$1(pattern, options); +/** + * Returns true if **any** of the given glob `patterns` match the specified `string`. + * + * ```js + * const mm = require('micromatch'); + * // mm.isMatch(string, patterns[, options]); + * + * console.log(mm.isMatch('a.a', ['b.*', '*.a'])); //=> true + * console.log(mm.isMatch('a.a', 'b.*')); //=> false + * ``` + * @param {String} str The string to test. + * @param {String|Array} patterns One or more glob patterns to use for matching. + * @param {Object} [options] See available [options](#options). + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ - 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) { - while (eos() !== true && (code = advance())) { - if (code === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - code = advance(); - continue; - } +micromatch.isMatch = (str, patterns, options) => picomatch$1(patterns, options)(str); +/** + * Backwards compatibility + */ - if (code === CHAR_RIGHT_PARENTHESES$1) { - isGlob = token.isGlob = true; - finished = true; - if (scanToEnd === true) { - continue; - } +micromatch.any = micromatch.isMatch; +/** + * Returns a list of strings that _**do not match any**_ of the given `patterns`. + * + * ```js + * const mm = require('micromatch'); + * // mm.not(list, patterns[, options]); + * + * console.log(mm.not(['a.a', 'b.b', 'c.c'], '*.a')); + * //=> ['b.b', 'c.c'] + * ``` + * @param {Array} `list` Array of strings to match. + * @param {String|Array} `patterns` One or more glob pattern to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Array} Returns an array of strings that **do not match** the given patterns. + * @api public + */ - break; - } - } - } +micromatch.not = (list, patterns, options = {}) => { + patterns = [].concat(patterns).map(String); + let result = new Set(); + let items = []; - if (isGlob === true) { - finished = true; + let onResult = state => { + if (options.onResult) options.onResult(state); + items.push(state.output); + }; - if (scanToEnd === true) { - continue; - } + let matches = micromatch(list, patterns, Object.assign({}, options, { + onResult + })); - break; + for (let item of items) { + if (!matches.includes(item)) { + result.add(item); } } - if (opts.noext === true) { - isExtglob = false; - isGlob = false; - } + return [...result]; +}; +/** + * Returns true if the given `string` contains the given pattern. Similar + * to [.isMatch](#isMatch) but the pattern can match any part of the string. + * + * ```js + * var mm = require('micromatch'); + * // mm.contains(string, pattern[, options]); + * + * console.log(mm.contains('aa/bb/cc', '*b')); + * //=> true + * console.log(mm.contains('aa/bb/cc', '*d')); + * //=> false + * ``` + * @param {String} `str` The string to match. + * @param {String|Array} `patterns` Glob pattern to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if the patter matches any part of `str`. + * @api public + */ - let base = str; - let prefix = ''; - let glob = ''; - if (start > 0) { - prefix = str.slice(0, start); - str = str.slice(start); - lastIndex -= start; +micromatch.contains = (str, pattern, options) => { + if (typeof str !== 'string') { + throw new TypeError(`Expected a string: "${util__default['default'].inspect(str)}"`); } - 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 (Array.isArray(pattern)) { + return pattern.some(p => micromatch.contains(str, p, options)); } - if (base && base !== '' && base !== '/' && base !== str) { - if (isPathSeparator(base.charCodeAt(base.length - 1))) { - base = base.slice(0, -1); + if (typeof pattern === 'string') { + if (isEmptyString(str) || isEmptyString(pattern)) { + return false; } - } - - if (opts.unescape === true) { - if (glob) glob = utils$3.removeBackslashes(glob); - if (base && backslashes === true) { - base = utils$3.removeBackslashes(base); + if (str.includes(pattern) || str.startsWith('./') && str.slice(2).includes(pattern)) { + return true; } } - const state = { - prefix, - input, - start, - base, - glob, - isBrace, - isBracket, - isGlob, - isExtglob, - isGlobstar, - negated - }; - - if (opts.tokens === true) { - state.maxDepth = 0; + return micromatch.isMatch(str, pattern, Object.assign({}, options, { + contains: true + })); +}; +/** + * Filter the keys of the given object with the given `glob` pattern + * and `options`. Does not attempt to match nested keys. If you need this feature, + * use [glob-object][] instead. + * + * ```js + * const mm = require('micromatch'); + * // mm.matchKeys(object, patterns[, options]); + * + * const obj = { aa: 'a', ab: 'b', ac: 'c' }; + * console.log(mm.matchKeys(obj, '*b')); + * //=> { ab: 'b' } + * ``` + * @param {Object} `object` The object with keys to filter. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Object} Returns an object with only keys that match the given patterns. + * @api public + */ - if (!isPathSeparator(code)) { - tokens.push(token); - } - state.tokens = tokens; +micromatch.matchKeys = (obj, patterns, options) => { + if (!utils$2.isObject(obj)) { + throw new TypeError('Expected the first argument to be an object'); } - 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); + let keys = micromatch(Object.keys(obj), patterns, options); + let res = {}; - if (opts.tokens) { - if (idx === 0 && start !== 0) { - tokens[idx].isPrefix = true; - tokens[idx].value = prefix; - } else { - tokens[idx].value = value; - } + for (let key of keys) res[key] = obj[key]; - depth(tokens[idx]); - state.maxDepth += tokens[idx].depth; - } + return res; +}; +/** + * Returns true if some of the strings in the given `list` match any of the given glob `patterns`. + * + * ```js + * const mm = require('micromatch'); + * // mm.some(list, patterns[, options]); + * + * console.log(mm.some(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); + * // true + * console.log(mm.some(['foo.js'], ['*.js', '!foo.js'])); + * // false + * ``` + * @param {String|Array} `list` The string or array of strings to test. Returns as soon as the first match is found. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ - if (idx !== 0 || value !== '') { - parts.push(value); - } - prevIndex = i; - } +micromatch.some = (list, patterns, options) => { + let items = [].concat(list); - if (prevIndex && prevIndex + 1 < input.length) { - const value = input.slice(prevIndex + 1); - parts.push(value); + for (let pattern of [].concat(patterns)) { + let isMatch = picomatch$1(String(pattern), options); - if (opts.tokens) { - tokens[tokens.length - 1].value = value; - depth(tokens[tokens.length - 1]); - state.maxDepth += tokens[tokens.length - 1].depth; - } + if (items.some(item => isMatch(item))) { + return true; } - - state.slashes = slashes; - state.parts = parts; } - return state; + return false; }; - -var scan_1 = scan; - /** - * Constants + * Returns true if every string in the given `list` matches + * any of the given glob `patterns`. + * + * ```js + * const mm = require('micromatch'); + * // mm.every(list, patterns[, options]); + * + * console.log(mm.every('foo.js', ['foo.js'])); + * // true + * console.log(mm.every(['foo.js', 'bar.js'], ['*.js'])); + * // true + * console.log(mm.every(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); + * // false + * console.log(mm.every(['foo.js'], ['*.js', '!foo.js'])); + * // false + * ``` + * @param {String|Array} `list` The string or array of strings to test. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if any patterns match `str` + * @api public */ -const { - MAX_LENGTH: MAX_LENGTH$3, - POSIX_REGEX_SOURCE: POSIX_REGEX_SOURCE$1, - REGEX_NON_SPECIAL_CHARS, - REGEX_SPECIAL_CHARS_BACKREF, - REPLACEMENTS -} = constants$3; -/** - * Helpers - */ +micromatch.every = (list, patterns, options) => { + let items = [].concat(list); -const expandRange = (args, options) => { - if (typeof options.expandRange === 'function') { - return options.expandRange(...args, options); + for (let pattern of [].concat(patterns)) { + let isMatch = picomatch$1(String(pattern), options); + + if (!items.every(item => isMatch(item))) { + return false; + } } - args.sort(); - const value = `[${args.join('-')}]`; + return true; +}; +/** + * Returns true if **all** of the given `patterns` match + * the specified string. + * + * ```js + * const mm = require('micromatch'); + * // mm.all(string, patterns[, options]); + * + * console.log(mm.all('foo.js', ['foo.js'])); + * // true + * + * console.log(mm.all('foo.js', ['*.js', '!foo.js'])); + * // false + * + * console.log(mm.all('foo.js', ['*.js', 'foo.js'])); + * // true + * + * console.log(mm.all('foo.js', ['*.js', 'f*', '*o*', '*o.js'])); + * // true + * ``` + * @param {String|Array} `str` The string to test. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ - try { - /* eslint-disable-next-line no-new */ - new RegExp(value); - } catch (ex) { - return args.map(v => utils$3.escapeRegex(v)).join('..'); + +micromatch.all = (str, patterns, options) => { + if (typeof str !== 'string') { + throw new TypeError(`Expected a string: "${util__default['default'].inspect(str)}"`); } - return value; + return [].concat(patterns).every(p => picomatch$1(p, options)(str)); }; /** - * Create the message for a syntax error + * Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match. + * + * ```js + * const mm = require('micromatch'); + * // mm.capture(pattern, string[, options]); + * + * console.log(mm.capture('test/*.js', 'test/foo.js')); + * //=> ['foo'] + * console.log(mm.capture('test/*.js', 'foo/bar.css')); + * //=> null + * ``` + * @param {String} `glob` Glob pattern to use for matching. + * @param {String} `input` String to match + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns an array of captures if the input matches the glob pattern, otherwise `null`. + * @api public */ -const syntaxError = (type, char) => { - return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; +micromatch.capture = (glob, input, options) => { + let posix = utils$2.isWindows(options); + let regex = picomatch$1.makeRe(String(glob), Object.assign({}, options, { + capture: true + })); + let match = regex.exec(posix ? utils$2.toPosixSlashes(input) : input); + + if (match) { + return match.slice(1).map(v => v === void 0 ? '' : v); + } }; /** - * Parse the given input string. - * @param {String} input - * @param {Object} options - * @return {Object} + * Create a regular expression from the given glob `pattern`. + * + * ```js + * const mm = require('micromatch'); + * // mm.makeRe(pattern[, options]); + * + * console.log(mm.makeRe('*.js')); + * //=> /^(?:(\.[\\\/])?(?!\.)(?=.)[^\/]*?\.js)$/ + * ``` + * @param {String} `pattern` A glob pattern to convert to regex. + * @param {Object} `options` + * @return {RegExp} Returns a regex created from the given pattern. + * @api public */ -const parse$4 = (input, options) => { - if (typeof input !== 'string') { - throw new TypeError('Expected a string'); - } +micromatch.makeRe = (...args) => picomatch$1.makeRe(...args); +/** + * Scan a glob pattern to separate the pattern into segments. Used + * by the [split](#split) method. + * + * ```js + * const mm = require('micromatch'); + * const state = mm.scan(pattern[, options]); + * ``` + * @param {String} `pattern` + * @param {Object} `options` + * @return {Object} Returns an object with + * @api public + */ - input = REPLACEMENTS[input] || input; - const opts = Object.assign({}, options); - const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH$3, opts.maxLength) : MAX_LENGTH$3; - let len = input.length; - if (len > max) { - throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); - } +micromatch.scan = (...args) => picomatch$1.scan(...args); +/** + * Parse a glob pattern to create the source string for a regular + * expression. + * + * ```js + * const mm = require('micromatch'); + * const state = mm(pattern[, options]); + * ``` + * @param {String} `glob` + * @param {Object} `options` + * @return {Object} Returns an object with useful properties and output to be used as regex source string. + * @api public + */ - const bos = { - type: 'bos', - value: '', - output: opts.prepend || '' - }; - const tokens = [bos]; - const capture = opts.capture ? '' : '?:'; - const win32 = utils$3.isWindows(options); // create constants based on platform, for windows or posix - const PLATFORM_CHARS = constants$3.globChars(win32); - const EXTGLOB_CHARS = constants$3.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; +micromatch.parse = (patterns, options) => { + let res = []; - const globstar = opts => { - return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; - }; + for (let pattern of [].concat(patterns || [])) { + for (let str of braces_1(String(pattern), options)) { + res.push(picomatch$1.parse(str, options)); + } + } - const nodot = opts.dot ? '' : NO_DOT; - const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; - let star = opts.bash === true ? globstar(opts) : STAR; + return res; +}; +/** + * Process the given brace `pattern`. + * + * ```js + * const { braces } = require('micromatch'); + * console.log(braces('foo/{a,b,c}/bar')); + * //=> [ 'foo/(a|b|c)/bar' ] + * + * console.log(braces('foo/{a,b,c}/bar', { expand: true })); + * //=> [ 'foo/a/bar', 'foo/b/bar', 'foo/c/bar' ] + * ``` + * @param {String} `pattern` String with brace pattern to process. + * @param {Object} `options` Any [options](#options) to change how expansion is performed. See the [braces][] library for all available options. + * @return {Array} + * @api public + */ - if (opts.capture) { - star = `(${star})`; - } // minimatch options support +micromatch.braces = (pattern, options) => { + if (typeof pattern !== 'string') throw new TypeError('Expected a string'); - if (typeof opts.noext === 'boolean') { - opts.noextglob = opts.noext; + if (options && options.nobrace === true || !/\{.*\}/.test(pattern)) { + return [pattern]; } - 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$3.removePrefix(input, state); - len = input.length; - const extglobs = []; - const braces = []; - const stack = []; - let prev = bos; - let value; - /** - * Tokenizing helpers - */ + return braces_1(pattern, options); +}; +/** + * Expand braces + */ - const eos = () => state.index === len - 1; - const peek = state.peek = (n = 1) => input[state.index + n]; +micromatch.braceExpand = (pattern, options) => { + if (typeof pattern !== 'string') throw new TypeError('Expected a string'); + return micromatch.braces(pattern, Object.assign({}, options, { + expand: true + })); +}; +/** + * Expose micromatch + */ - const advance = state.advance = () => input[++state.index]; - const remaining = () => input.slice(state.index + 1); +var micromatch_1 = micromatch; - const consume = (value = '', num = 0) => { - state.consumed += value; - state.index += num; - }; +var pattern = createCommonjsModule(function (module, exports) { - const append = token => { - state.output += token.output != null ? token.output : token.value; - consume(token.value); - }; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.matchAny = exports.convertPatternsToRe = exports.makeRe = exports.getPatternParts = exports.expandBraceExpansion = exports.expandPatternsWithBraceExpansion = exports.isAffectDepthOfReadingPattern = exports.endsWithSlashGlobStar = exports.hasGlobStar = exports.getBaseDirectory = exports.getPositivePatterns = exports.getNegativePatterns = exports.isPositivePattern = exports.isNegativePattern = exports.convertToNegativePattern = exports.convertToPositivePattern = exports.isDynamicPattern = exports.isStaticPattern = void 0; + const GLOBSTAR = '**'; + const ESCAPE_SYMBOL = '\\'; + const COMMON_GLOB_SYMBOLS_RE = /[*?]|^!/; + const REGEX_CHARACTER_CLASS_SYMBOLS_RE = /\[.*]/; + const REGEX_GROUP_SYMBOLS_RE = /(?:^|[^!*+?@])\(.*\|.*\)/; + const GLOB_EXTENSION_SYMBOLS_RE = /[!*+?@]\(.*\)/; + const BRACE_EXPANSIONS_SYMBOLS_RE = /{.*(?:,|\.\.).*}/; - const negate = () => { - let count = 1; + function isStaticPattern(pattern, options = {}) { + return !isDynamicPattern(pattern, options); + } - while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { - advance(); - state.start++; - count++; - } + exports.isStaticPattern = isStaticPattern; - if (count % 2 === 0) { + function isDynamicPattern(pattern, options = {}) { + /** + * A special case with an empty string is necessary for matching patterns that start with a forward slash. + * An empty string cannot be a dynamic pattern. + * For example, the pattern `/lib/*` will be spread into parts: '', 'lib', '*'. + */ + if (pattern === '') { return false; } + /** + * When the `caseSensitiveMatch` option is disabled, all patterns must be marked as dynamic, because we cannot check + * filepath directly (without read directory). + */ - 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 (options.caseSensitiveMatch === false || pattern.includes(ESCAPE_SYMBOL)) { + return true; } - if (extglobs.length && tok.type !== 'paren' && !EXTGLOB_CHARS[tok.value]) { - extglobs[extglobs.length - 1].inner += tok.value; + if (COMMON_GLOB_SYMBOLS_RE.test(pattern) || REGEX_CHARACTER_CLASS_SYMBOLS_RE.test(pattern) || REGEX_GROUP_SYMBOLS_RE.test(pattern)) { + return true; } - 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; + if (options.extglob !== false && GLOB_EXTENSION_SYMBOLS_RE.test(pattern)) { + return true; } - tok.prev = prev; - tokens.push(tok); - prev = tok; - }; - - const extglobOpen = (type, value) => { - const token = Object.assign({}, 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); - }; + if (options.braceExpansion !== false && BRACE_EXPANSIONS_SYMBOLS_RE.test(pattern)) { + return true; + } - const extglobClose = token => { - let output = token.close + (opts.capture ? ')' : ''); + return false; + } - if (token.type === 'negate') { - let extglobStar = star; + exports.isDynamicPattern = isDynamicPattern; - if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { - extglobStar = globstar(opts); - } + function convertToPositivePattern(pattern) { + return isNegativePattern(pattern) ? pattern.slice(1) : pattern; + } - if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { - output = token.close = `)$))${extglobStar}`; - } + exports.convertToPositivePattern = convertToPositivePattern; - if (token.prev.type === 'bos' && eos()) { - state.negatedExtglob = true; - } - } + function convertToNegativePattern(pattern) { + return '!' + pattern; + } - push({ - type: 'paren', - extglob: true, - value, - output - }); - decrement('parens'); - }; - /** - * Fast paths - */ + exports.convertToNegativePattern = convertToNegativePattern; + function isNegativePattern(pattern) { + return pattern.startsWith('!') && pattern[1] !== '('; + } - 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; - } + exports.isNegativePattern = isNegativePattern; - if (first === '?') { - if (esc) { - return esc + first + (rest ? QMARK.repeat(rest.length) : ''); - } + function isPositivePattern(pattern) { + return !isNegativePattern(pattern); + } - if (index === 0) { - return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); - } + exports.isPositivePattern = isPositivePattern; - return QMARK.repeat(chars.length); - } + function getNegativePatterns(patterns) { + return patterns.filter(isNegativePattern); + } - if (first === '.') { - return DOT_LITERAL.repeat(chars.length); - } + exports.getNegativePatterns = getNegativePatterns; - if (first === '*') { - if (esc) { - return esc + first + (rest ? star : ''); - } + function getPositivePatterns(patterns) { + return patterns.filter(isPositivePattern); + } - return star; - } + exports.getPositivePatterns = getPositivePatterns; - return esc ? m : `\\${m}`; + function getBaseDirectory(pattern) { + return globParent(pattern, { + flipBackslashes: false }); + } - 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; - } + exports.getBaseDirectory = getBaseDirectory; - state.output = utils$3.wrapOutput(output, state, options); - return state; + function hasGlobStar(pattern) { + return pattern.includes(GLOBSTAR); } - /** - * Tokenize input until we reach end-of-string - */ - - while (!eos()) { - value = advance(); + exports.hasGlobStar = hasGlobStar; - if (value === '\u0000') { - continue; - } - /** - * Escaped characters - */ + function endsWithSlashGlobStar(pattern) { + return pattern.endsWith('/' + GLOBSTAR); + } + exports.endsWithSlashGlobStar = endsWithSlashGlobStar; - if (value === '\\') { - const next = peek(); + function isAffectDepthOfReadingPattern(pattern) { + const basename = path__default['default'].basename(pattern); + return endsWithSlashGlobStar(pattern) || isStaticPattern(basename); + } - if (next === '/' && opts.bash !== true) { - continue; - } + exports.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern; - if (next === '.' || next === ';') { - continue; - } + function expandPatternsWithBraceExpansion(patterns) { + return patterns.reduce((collection, pattern) => { + return collection.concat(expandBraceExpansion(pattern)); + }, []); + } - if (!next) { - value += '\\'; - push({ - type: 'text', - value - }); - continue; - } // collapse slashes to reduce potential for exploits + exports.expandPatternsWithBraceExpansion = expandPatternsWithBraceExpansion; + function expandBraceExpansion(pattern) { + return micromatch_1.braces(pattern, { + expand: true, + nodupes: true + }); + } - const match = /^\\+/.exec(remaining()); - let slashes = 0; + exports.expandBraceExpansion = expandBraceExpansion; - if (match && match[0].length > 2) { - slashes = match[0].length; - state.index += slashes; + function getPatternParts(pattern, options) { + let { + parts + } = picomatch$1.scan(pattern, Object.assign(Object.assign({}, options), { + parts: true + })); + /** + * The scan method returns an empty array in some cases. + * See micromatch/picomatch#58 for more details. + */ - if (slashes % 2 !== 0) { - value += '\\'; - } - } + if (parts.length === 0) { + parts = [pattern]; + } + /** + * The scan method does not return an empty part for the pattern with a forward slash. + * This is another part of micromatch/picomatch#58. + */ - if (opts.unescape === true) { - value = advance() || ''; - } else { - value += advance() || ''; - } - if (state.brackets === 0) { - push({ - type: 'text', - value - }); - continue; - } + if (parts[0].startsWith('/')) { + parts[0] = parts[0].slice(1); + parts.unshift(''); } - /** - * If we're inside a regex character class, continue - * until we reach the closing bracket. - */ + return parts; + } - if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { - if (opts.posix !== false && value === ':') { - const inner = prev.value.slice(1); + exports.getPatternParts = getPatternParts; - if (inner.includes('[')) { - prev.posix = true; + function makeRe(pattern, options) { + return micromatch_1.makeRe(pattern, options); + } - 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$1[rest]; + exports.makeRe = makeRe; - if (posix) { - prev.value = pre + posix; - state.backtrack = true; - advance(); + function convertPatternsToRe(patterns, options) { + return patterns.map(pattern => makeRe(pattern, options)); + } - if (!bos.output && tokens.indexOf(prev) === 1) { - bos.output = ONE_CHAR; - } + exports.convertPatternsToRe = convertPatternsToRe; - continue; - } - } - } - } + function matchAny(entry, patternsRe) { + return patternsRe.some(patternRe => patternRe.test(entry)); + } - if (value === '[' && peek() !== ':' || value === '-' && peek() === ']') { - value = `\\${value}`; - } + exports.matchAny = matchAny; +}); - if (value === ']' && (prev.value === '[' || prev.value === '[^')) { - value = `\\${value}`; - } +var stream$2 = createCommonjsModule(function (module, exports) { - if (opts.posix === true && value === '!' && prev.value === '[') { - value = '^'; - } + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.merge = void 0; - prev.value += value; - append({ - value - }); - continue; - } - /** - * If we're inside a quoted string, continue - * until we reach the closing double quote. - */ + function merge(streams) { + const mergedStream = merge2_1(streams); + streams.forEach(stream => { + stream.once('error', error => mergedStream.emit('error', error)); + }); + mergedStream.once('close', () => propagateCloseEventToSources(streams)); + mergedStream.once('end', () => propagateCloseEventToSources(streams)); + return mergedStream; + } + exports.merge = merge; - if (state.quotes === 1 && value !== '"') { - value = utils$3.escapeRegex(value); - prev.value += value; - append({ - value - }); - continue; - } - /** - * Double quotes - */ + function propagateCloseEventToSources(streams) { + streams.forEach(stream => stream.emit('close')); + } +}); +var string$1 = createCommonjsModule(function (module, exports) { - if (value === '"') { - state.quotes = state.quotes === 1 ? 0 : 1; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.isEmpty = exports.isString = void 0; - if (opts.keepQuotes === true) { - push({ - type: 'text', - value - }); - } + function isString(input) { + return typeof input === 'string'; + } - continue; - } - /** - * Parentheses - */ + exports.isString = isString; + function isEmpty(input) { + return input === ''; + } - if (value === '(') { - increment('parens'); - push({ - type: 'paren', - value - }); - continue; - } + exports.isEmpty = isEmpty; +}); - if (value === ')') { - if (state.parens === 0 && opts.strictBrackets === true) { - throw new SyntaxError(syntaxError('opening', '(')); - } +var utils$3 = createCommonjsModule(function (module, exports) { - const extglob = extglobs[extglobs.length - 1]; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.string = exports.stream = exports.pattern = exports.path = exports.fs = exports.errno = exports.array = void 0; + exports.array = array$2; + exports.errno = errno; + exports.fs = fs$2; + exports.path = path_1; + exports.pattern = pattern; + exports.stream = stream$2; + exports.string = string$1; +}); - if (extglob && state.parens === extglob.parens + 1) { - extglobClose(extglobs.pop()); - continue; - } +var tasks = createCommonjsModule(function (module, exports) { - push({ - type: 'paren', - value, - output: state.parens ? ')' : '\\)' - }); - decrement('parens'); - continue; - } - /** - * Square brackets - */ + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.convertPatternGroupToTask = exports.convertPatternGroupsToTasks = exports.groupPatternsByBaseDirectory = exports.getNegativePatternsAsPositive = exports.getPositivePatterns = exports.convertPatternsToTasks = exports.generate = void 0; + function generate(patterns, settings) { + const positivePatterns = getPositivePatterns(patterns); + const negativePatterns = getNegativePatternsAsPositive(patterns, settings.ignore); + const staticPatterns = positivePatterns.filter(pattern => utils$3.pattern.isStaticPattern(pattern, settings)); + const dynamicPatterns = positivePatterns.filter(pattern => utils$3.pattern.isDynamicPattern(pattern, settings)); + const staticTasks = convertPatternsToTasks(staticPatterns, negativePatterns, + /* dynamic */ + false); + const dynamicTasks = convertPatternsToTasks(dynamicPatterns, negativePatterns, + /* dynamic */ + true); + return staticTasks.concat(dynamicTasks); + } - if (value === '[') { - if (opts.nobracket === true || !remaining().includes(']')) { - if (opts.nobracket !== true && opts.strictBrackets === true) { - throw new SyntaxError(syntaxError('closing', ']')); - } + exports.generate = generate; - value = `\\${value}`; - } else { - increment('brackets'); - } + function convertPatternsToTasks(positive, negative, dynamic) { + const positivePatternsGroup = groupPatternsByBaseDirectory(positive); // When we have a global group – there is no reason to divide the patterns into independent tasks. + // In this case, the global task covers the rest. - push({ - type: 'bracket', - value - }); - continue; + if ('.' in positivePatternsGroup) { + const task = convertPatternGroupToTask('.', positive, negative, dynamic); + return [task]; } - if (value === ']') { - if (opts.nobracket === true || prev && prev.type === 'bracket' && prev.value.length === 1) { - push({ - type: 'text', - value, - output: `\\${value}` - }); - continue; - } - - if (state.brackets === 0) { - if (opts.strictBrackets === true) { - throw new SyntaxError(syntaxError('opening', '[')); - } + return convertPatternGroupsToTasks(positivePatternsGroup, negative, dynamic); + } - push({ - type: 'text', - value, - output: `\\${value}` - }); - continue; - } + exports.convertPatternsToTasks = convertPatternsToTasks; - decrement('brackets'); - const prevValue = prev.value.slice(1); + function getPositivePatterns(patterns) { + return utils$3.pattern.getPositivePatterns(patterns); + } - if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { - value = `/${value}`; - } + exports.getPositivePatterns = getPositivePatterns; - prev.value += value; - append({ - value - }); // when literal brackets are explicitly disabled - // assume we should match with a regex character class + function getNegativePatternsAsPositive(patterns, ignore) { + const negative = utils$3.pattern.getNegativePatterns(patterns).concat(ignore); + const positive = negative.map(utils$3.pattern.convertToPositivePattern); + return positive; + } - if (opts.literalBrackets === false || utils$3.hasRegexChars(prevValue)) { - continue; - } + exports.getNegativePatternsAsPositive = getNegativePatternsAsPositive; - const escaped = utils$3.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 + function groupPatternsByBaseDirectory(patterns) { + const group = {}; + return patterns.reduce((collection, pattern) => { + const base = utils$3.pattern.getBaseDirectory(pattern); - if (opts.literalBrackets === true) { - state.output += escaped; - prev.value = escaped; - continue; - } // when the user specifies nothing, try to match both + if (base in collection) { + collection[base].push(pattern); + } else { + collection[base] = [pattern]; + } + return collection; + }, group); + } - prev.value = `(${capture}${escaped}|${prev.value})`; - state.output += prev.value; - continue; - } - /** - * Braces - */ + exports.groupPatternsByBaseDirectory = groupPatternsByBaseDirectory; + function convertPatternGroupsToTasks(positive, negative, dynamic) { + return Object.keys(positive).map(base => { + return convertPatternGroupToTask(base, positive[base], negative, dynamic); + }); + } - 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; - } + exports.convertPatternGroupsToTasks = convertPatternGroupsToTasks; - if (value === '}') { - const brace = braces[braces.length - 1]; + function convertPatternGroupToTask(base, positive, negative, dynamic) { + return { + dynamic, + positive, + negative, + base, + patterns: [].concat(positive, negative.map(utils$3.pattern.convertToNegativePattern)) + }; + } - if (opts.nobrace === true || !brace) { - push({ - type: 'text', - value, - output: value - }); - continue; - } + exports.convertPatternGroupToTask = convertPatternGroupToTask; +}); - let output = ')'; +var async$1 = createCommonjsModule(function (module, exports) { - if (brace.dots === true) { - const arr = tokens.slice(); - const range = []; + Object.defineProperty(exports, "__esModule", { + value: true + }); - for (let i = arr.length - 1; i >= 0; i--) { - tokens.pop(); + function read(path, settings, callback) { + settings.fs.lstat(path, (lstatError, lstat) => { + if (lstatError !== null) { + return callFailureCallback(callback, lstatError); + } - if (arr[i].type === 'brace') { - break; - } + if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { + return callSuccessCallback(callback, lstat); + } - if (arr[i].type !== 'dots') { - range.unshift(arr[i].value); + settings.fs.stat(path, (statError, stat) => { + if (statError !== null) { + if (settings.throwErrorOnBrokenSymbolicLink) { + return callFailureCallback(callback, statError); } - } - - 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; + return callSuccessCallback(callback, lstat); + } - for (const t of toks) { - state.output += t.output || t.value; + if (settings.markSymbolicLink) { + stat.isSymbolicLink = () => true; } - } - push({ - type: 'brace', - value, - output + callSuccessCallback(callback, stat); }); - decrement('braces'); - braces.pop(); - continue; - } - /** - * Pipes - */ + }); + } + exports.read = read; - if (value === '|') { - if (extglobs.length > 0) { - extglobs[extglobs.length - 1].conditions++; - } + function callFailureCallback(callback, error) { + callback(error); + } - push({ - type: 'text', - value - }); - continue; - } - /** - * Commas - */ + function callSuccessCallback(callback, result) { + callback(null, result); + } +}); +var sync$1 = createCommonjsModule(function (module, exports) { - if (value === ',') { - let output = value; - const brace = braces[braces.length - 1]; + Object.defineProperty(exports, "__esModule", { + value: true + }); - if (brace && stack[stack.length - 1] === 'braces') { - brace.comma = true; - output = '|'; - } + function read(path, settings) { + const lstat = settings.fs.lstatSync(path); - push({ - type: 'comma', - value, - output - }); - continue; + if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { + return lstat; } - /** - * Slashes - */ + try { + const stat = settings.fs.statSync(path); - 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 + if (settings.markSymbolicLink) { + stat.isSymbolicLink = () => true; + } - continue; + return stat; + } catch (error) { + if (!settings.throwErrorOnBrokenSymbolicLink) { + return lstat; } - push({ - type: 'slash', - value, - output: SLASH_LITERAL - }); - continue; + throw error; } - /** - * Dots - */ + } + exports.read = read; +}); - 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; - } +var fs_1 = createCommonjsModule(function (module, exports) { - if (state.braces + state.parens === 0 && prev.type !== 'bos' && prev.type !== 'slash') { - push({ - type: 'text', - value, - output: DOT_LITERAL - }); - continue; - } + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.FILE_SYSTEM_ADAPTER = { + lstat: fs__default['default'].lstat, + stat: fs__default['default'].stat, + lstatSync: fs__default['default'].lstatSync, + statSync: fs__default['default'].statSync + }; - push({ - type: 'dot', - value, - output: DOT_LITERAL - }); - continue; + function createFileSystemAdapter(fsMethods) { + if (fsMethods === undefined) { + return exports.FILE_SYSTEM_ADAPTER; } - /** - * Question marks - */ + return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods); + } - if (value === '?') { - const isGroup = prev && prev.value === '('; + exports.createFileSystemAdapter = createFileSystemAdapter; +}); - if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - extglobOpen('qmark', value); - continue; - } +var settings = createCommonjsModule(function (module, exports) { - if (prev && prev.type === 'paren') { - const next = peek(); - let output = value; + Object.defineProperty(exports, "__esModule", { + value: true + }); - if (next === '<' && !utils$3.supportsLookbehinds()) { - throw new Error('Node.js v10 or higher is required for regex lookbehinds'); - } + class Settings { + constructor(_options = {}) { + this._options = _options; + this.followSymbolicLink = this._getValue(this._options.followSymbolicLink, true); + this.fs = fs_1.createFileSystemAdapter(this._options.fs); + this.markSymbolicLink = this._getValue(this._options.markSymbolicLink, false); + this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); + } - if (prev.value === '(' && !/[!=<:]/.test(next) || next === '<' && !/<([!=]|\w+>)/.test(remaining())) { - output = `\\${value}`; - } + _getValue(option, value) { + return option === undefined ? value : option; + } - 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; - } + exports.default = Settings; +}); - push({ - type: 'qmark', - value, - output: QMARK - }); - continue; +var out = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.Settings = settings.default; + + function stat(path, optionsOrSettingsOrCallback, callback) { + if (typeof optionsOrSettingsOrCallback === 'function') { + return async$1.read(path, getSettings(), optionsOrSettingsOrCallback); } - /** - * Exclamation - */ + async$1.read(path, getSettings(optionsOrSettingsOrCallback), callback); + } - if (value === '!') { - if (opts.noextglob !== true && peek() === '(') { - if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { - extglobOpen('negate', value); - continue; - } - } + exports.stat = stat; - if (opts.nonegate !== true && state.index === 0) { - negate(); - continue; - } + function statSync(path, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + return sync$1.read(path, settings); + } + + exports.statSync = statSync; + + function getSettings(settingsOrOptions = {}) { + if (settingsOrOptions instanceof settings.default) { + return settingsOrOptions; } - /** - * Plus - */ + return new settings.default(settingsOrOptions); + } +}); - if (value === '+') { - if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - extglobOpen('plus', value); - continue; - } +var runParallel_1 = runParallel; - if (prev && prev.value === '(' || opts.regex === false) { - push({ - type: 'plus', - value, - output: PLUS_LITERAL - }); - continue; - } +function runParallel(tasks, cb) { + var results, pending, keys; + var isSync = true; - if (prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace') || state.parens > 0) { - push({ - type: 'plus', - value - }); - continue; - } + if (Array.isArray(tasks)) { + results = []; + pending = tasks.length; + } else { + keys = Object.keys(tasks); + results = {}; + pending = keys.length; + } - push({ - type: 'plus', - value: PLUS_LITERAL - }); - continue; + function done(err) { + function end() { + if (cb) cb(err, results); + cb = null; } - /** - * Plain text - */ + if (isSync) process.nextTick(end);else end(); + } - if (value === '@') { - if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - push({ - type: 'at', - extglob: true, - value, - output: '' - }); - continue; - } + function each(i, err, result) { + results[i] = result; - push({ - type: 'text', - value - }); - continue; + if (--pending === 0 || err) { + done(err); } - /** - * Plain text - */ + } + + if (!pending) { + // empty + done(null); + } else if (keys) { + // object + keys.forEach(function (key) { + tasks[key](function (err, result) { + each(key, err, result); + }); + }); + } else { + // array + tasks.forEach(function (task, i) { + task(function (err, result) { + each(i, err, result); + }); + }); + } + isSync = false; +} - if (value !== '*') { - if (value === '$' || value === '^') { - value = `\\${value}`; - } +var constants$5 = createCommonjsModule(function (module, exports) { - const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); + Object.defineProperty(exports, "__esModule", { + value: true + }); + const NODE_PROCESS_VERSION_PARTS = process.versions.node.split('.'); + const MAJOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[0], 10); + const MINOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[1], 10); + const SUPPORTED_MAJOR_VERSION = 10; + const SUPPORTED_MINOR_VERSION = 10; + const IS_MATCHED_BY_MAJOR = MAJOR_VERSION > SUPPORTED_MAJOR_VERSION; + const IS_MATCHED_BY_MAJOR_AND_MINOR = MAJOR_VERSION === SUPPORTED_MAJOR_VERSION && MINOR_VERSION >= SUPPORTED_MINOR_VERSION; + /** + * IS `true` for Node.js 10.10 and greater. + */ - if (match) { - value += match[0]; - state.index += match[0].length; - } + exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = IS_MATCHED_BY_MAJOR || IS_MATCHED_BY_MAJOR_AND_MINOR; +}); - push({ - type: 'text', - value - }); - continue; - } - /** - * Stars - */ +var fs$3 = createCommonjsModule(function (module, exports) { + Object.defineProperty(exports, "__esModule", { + value: true + }); - 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; + class DirentFromStats { + constructor(name, stats) { + this.name = name; + this.isBlockDevice = stats.isBlockDevice.bind(stats); + this.isCharacterDevice = stats.isCharacterDevice.bind(stats); + this.isDirectory = stats.isDirectory.bind(stats); + this.isFIFO = stats.isFIFO.bind(stats); + this.isFile = stats.isFile.bind(stats); + this.isSocket = stats.isSocket.bind(stats); + this.isSymbolicLink = stats.isSymbolicLink.bind(stats); } - let rest = remaining(); + } - if (opts.noextglob !== true && /^\([^?]/.test(rest)) { - extglobOpen('star', value); - continue; - } + function createDirentFromStats(name, stats) { + return new DirentFromStats(name, stats); + } - if (prev.type === 'star') { - if (opts.noglobstar === true) { - consume(value); - continue; - } + exports.createDirentFromStats = createDirentFromStats; +}); - 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'); +var utils$4 = createCommonjsModule(function (module, exports) { - if (opts.bash === true && (!isStart || rest[0] && rest[0] !== '/')) { - push({ - type: 'star', - value, - output: '' - }); - continue; - } + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.fs = fs$3; +}); - const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); - const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); +var async$2 = createCommonjsModule(function (module, exports) { - if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { - push({ - type: 'star', - value, - output: '' - }); - continue; - } // strip consecutive `/**/` + Object.defineProperty(exports, "__esModule", { + value: true + }); + function read(directory, settings, callback) { + if (!settings.stats && constants$5.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { + return readdirWithFileTypes(directory, settings, callback); + } - while (rest.slice(0, 3) === '/**') { - const after = input[state.index + 4]; + return readdir(directory, settings, callback); + } - if (after && after !== '/') { - break; - } + exports.read = read; - rest = rest.slice(3); - consume('/**', 3); + function readdirWithFileTypes(directory, settings, callback) { + settings.fs.readdir(directory, { + withFileTypes: true + }, (readdirError, dirents) => { + if (readdirError !== null) { + return callFailureCallback(callback, readdirError); } - 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; - } + const entries = dirents.map(dirent => ({ + dirent, + name: dirent.name, + path: `${directory}${settings.pathSegmentSeparator}${dirent.name}` + })); - 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 (!settings.followSymbolicLinks) { + return callSuccessCallback(callback, entries); } - 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; - } + const tasks = entries.map(entry => makeRplTaskEntry(entry, settings)); + runParallel_1(tasks, (rplError, rplEntries) => { + if (rplError !== null) { + return callFailureCallback(callback, rplError); + } - 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 + callSuccessCallback(callback, rplEntries); + }); + }); + } + exports.readdirWithFileTypes = readdirWithFileTypes; - state.output = state.output.slice(0, -prev.output.length); // reset previous token to globstar + function makeRplTaskEntry(entry, settings) { + return done => { + if (!entry.dirent.isSymbolicLink()) { + return done(null, entry); + } - prev.type = 'globstar'; - prev.output = globstar(opts); - prev.value += value; // reset output with globstar + settings.fs.stat(entry.path, (statError, stats) => { + if (statError !== null) { + if (settings.throwErrorOnBrokenSymbolicLink) { + return done(statError); + } - state.output += prev.output; - state.globstar = true; - consume(value); - continue; - } + return done(null, entry); + } - const token = { - type: 'star', - value, - output: star + entry.dirent = utils$4.fs.createDirentFromStats(entry.name, stats); + return done(null, entry); + }); }; + } - if (opts.bash === true) { - token.output = '.*?'; - - if (prev.type === 'bos' || prev.type === 'slash') { - token.output = nodot + token.output; + function readdir(directory, settings, callback) { + settings.fs.readdir(directory, (readdirError, names) => { + if (readdirError !== null) { + return callFailureCallback(callback, readdirError); } - push(token); - continue; - } - - if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { - token.output = value; - push(token); - continue; - } + const filepaths = names.map(name => `${directory}${settings.pathSegmentSeparator}${name}`); + const tasks = filepaths.map(filepath => { + return done => out.stat(filepath, settings.fsStatSettings, done); + }); + runParallel_1(tasks, (rplError, results) => { + if (rplError !== null) { + return callFailureCallback(callback, rplError); + } - 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; - } + const entries = []; + names.forEach((name, index) => { + const stats = results[index]; + const entry = { + name, + path: filepaths[index], + dirent: utils$4.fs.createDirentFromStats(name, stats) + }; - if (peek() !== '*') { - state.output += ONE_CHAR; - prev.output += ONE_CHAR; - } - } + if (settings.stats) { + entry.stats = stats; + } - push(token); + entries.push(entry); + }); + callSuccessCallback(callback, entries); + }); + }); } - while (state.brackets > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); - state.output = utils$3.escapeLast(state.output, '['); - decrement('brackets'); - } + exports.readdir = readdir; - while (state.parens > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); - state.output = utils$3.escapeLast(state.output, '('); - decrement('parens'); + function callFailureCallback(callback, error) { + callback(error); } - while (state.braces > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); - state.output = utils$3.escapeLast(state.output, '{'); - decrement('braces'); + function callSuccessCallback(callback, result) { + callback(null, result); } +}); - 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 +var sync$2 = createCommonjsModule(function (module, exports) { + Object.defineProperty(exports, "__esModule", { + value: true + }); - if (state.backtrack === true) { - state.output = ''; + function read(directory, settings) { + if (!settings.stats && constants$5.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { + return readdirWithFileTypes(directory, settings); + } - for (const token of state.tokens) { - state.output += token.output != null ? token.output : token.value; + return readdir(directory, settings); + } - if (token.suffix) { - state.output += token.suffix; + exports.read = read; + + function readdirWithFileTypes(directory, settings) { + const dirents = settings.fs.readdirSync(directory, { + withFileTypes: true + }); + return dirents.map(dirent => { + const entry = { + dirent, + name: dirent.name, + path: `${directory}${settings.pathSegmentSeparator}${dirent.name}` + }; + + if (entry.dirent.isSymbolicLink() && settings.followSymbolicLinks) { + try { + const stats = settings.fs.statSync(entry.path); + entry.dirent = utils$4.fs.createDirentFromStats(entry.name, stats); + } catch (error) { + if (settings.throwErrorOnBrokenSymbolicLink) { + throw error; + } + } } - } + + return entry; + }); } - 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. - */ + exports.readdirWithFileTypes = readdirWithFileTypes; + function readdir(directory, settings) { + const names = settings.fs.readdirSync(directory); + return names.map(name => { + const entryPath = `${directory}${settings.pathSegmentSeparator}${name}`; + const stats = out.statSync(entryPath, settings.fsStatSettings); + const entry = { + name, + path: entryPath, + dirent: utils$4.fs.createDirentFromStats(name, stats) + }; -parse$4.fastpaths = (input, options) => { - const opts = Object.assign({}, options); - const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH$3, opts.maxLength) : MAX_LENGTH$3; - const len = input.length; + if (settings.stats) { + entry.stats = stats; + } - if (len > max) { - throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); + return entry; + }); } - input = REPLACEMENTS[input] || input; - const win32 = utils$3.isWindows(options); // create constants based on platform, for windows or posix + exports.readdir = readdir; +}); - const { - DOT_LITERAL, - SLASH_LITERAL, - ONE_CHAR, - DOTS_SLASH, - NO_DOT, - NO_DOTS, - NO_DOTS_SLASH, - STAR, - START_ANCHOR - } = constants$3.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: '' +var fs_1$1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.FILE_SYSTEM_ADAPTER = { + lstat: fs__default['default'].lstat, + stat: fs__default['default'].stat, + lstatSync: fs__default['default'].lstatSync, + statSync: fs__default['default'].statSync, + readdir: fs__default['default'].readdir, + readdirSync: fs__default['default'].readdirSync }; - let star = opts.bash === true ? '.*?' : STAR; - if (opts.capture) { - star = `(${star})`; + function createFileSystemAdapter(fsMethods) { + if (fsMethods === undefined) { + return exports.FILE_SYSTEM_ADAPTER; + } + + return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods); } - const globstar = opts => { - if (opts.noglobstar === true) return star; - return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; - }; + exports.createFileSystemAdapter = createFileSystemAdapter; +}); - const create = str => { - switch (str) { - case '*': - return `${nodot}${ONE_CHAR}${star}`; +var settings$1 = createCommonjsModule(function (module, exports) { - case '.*': - return `${DOT_LITERAL}${ONE_CHAR}${star}`; + Object.defineProperty(exports, "__esModule", { + value: true + }); - case '*.*': - return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; + class Settings { + constructor(_options = {}) { + this._options = _options; + this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false); + this.fs = fs_1$1.createFileSystemAdapter(this._options.fs); + this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path__default['default'].sep); + this.stats = this._getValue(this._options.stats, false); + this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); + this.fsStatSettings = new out.Settings({ + followSymbolicLink: this.followSymbolicLinks, + fs: this.fs, + throwErrorOnBrokenSymbolicLink: this.throwErrorOnBrokenSymbolicLink + }); + } - case '*/*': - return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; + _getValue(option, value) { + return option === undefined ? value : option; + } - case '**': - return nodot + globstar(opts); + } - case '**/*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; + exports.default = Settings; +}); - case '**/*.*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; +var out$1 = createCommonjsModule(function (module, exports) { - case '**/.*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.Settings = settings$1.default; - default: - { - const match = /^(.*?)\.(\w+)$/.exec(str); - if (!match) return; - const source = create(match[1]); - if (!source) return; - return source + DOT_LITERAL + match[2]; - } + function scandir(path, optionsOrSettingsOrCallback, callback) { + if (typeof optionsOrSettingsOrCallback === 'function') { + return async$2.read(path, getSettings(), optionsOrSettingsOrCallback); } - }; - const output = utils$3.removePrefix(input, state); - let source = create(output); + async$2.read(path, getSettings(optionsOrSettingsOrCallback), callback); + } - if (source && opts.strictSlashes !== true) { - source += `${SLASH_LITERAL}?`; + exports.scandir = scandir; + + function scandirSync(path, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + return sync$2.read(path, settings); } - return source; -}; + exports.scandirSync = scandirSync; -var parse_1$1 = parse$4; + function getSettings(settingsOrOptions = {}) { + if (settingsOrOptions instanceof settings$1.default) { + return settingsOrOptions; + } -const isObject$2 = 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 - */ + return new settings$1.default(settingsOrOptions); + } +}); + +function reusify(Constructor) { + var head = new Constructor(); + var tail = head; + function get() { + var current = head; -const picomatch = (glob, options, returnState = false) => { - if (Array.isArray(glob)) { - const fns = glob.map(input => picomatch(input, options, returnState)); + if (current.next) { + head = current.next; + } else { + head = new Constructor(); + tail = head; + } - const arrayMatcher = str => { - for (const isMatch of fns) { - const state = isMatch(str); - if (state) return state; - } + current.next = null; + return current; + } - return false; - }; + function release(obj) { + tail.next = obj; + tail = obj; + } + + return { + get: get, + release: release + }; +} + +var reusify_1 = reusify; + +function fastqueue(context, worker, concurrency) { + if (typeof context === 'function') { + concurrency = worker; + worker = context; + context = null; + } + + var cache = reusify_1(Task); + var queueHead = null; + var queueTail = null; + var _running = 0; + var self = { + push: push, + drain: noop$1, + saturated: noop$1, + pause: pause, + paused: false, + concurrency: concurrency, + running: running, + resume: resume, + idle: idle, + length: length, + getQueue: getQueue, + unshift: unshift, + empty: noop$1, + kill: kill, + killAndDrain: killAndDrain + }; + return self; - return arrayMatcher; + function running() { + return _running; } - const isState = isObject$2(glob) && glob.tokens && glob.input; - - if (glob === '' || typeof glob !== 'string' && !isState) { - throw new TypeError('Expected pattern to be a non-empty string'); + function pause() { + self.paused = true; } - const opts = options || {}; - const posix = utils$3.isWindows(options); - const regex = isState ? picomatch.compileRe(glob, options) : picomatch.makeRe(glob, options, false, true); - const state = regex.state; - delete regex.state; + function length() { + var current = queueHead; + var counter = 0; - let isIgnored = () => false; + while (current) { + current = current.next; + counter++; + } - if (opts.ignore) { - const ignoreOpts = Object.assign({}, options, { - ignore: null, - onMatch: null, - onResult: null - }); - isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); + return counter; } - const matcher = (input, returnObject = false) => { - const { - isMatch, - match, - output - } = picomatch.test(input, regex, options, { - glob, - posix - }); - const result = { - glob, - state, - regex, - posix, - input, - output, - match, - isMatch - }; + function getQueue() { + var current = queueHead; + var tasks = []; - if (typeof opts.onResult === 'function') { - opts.onResult(result); + while (current) { + tasks.push(current.value); + current = current.next; } - if (isMatch === false) { - result.isMatch = false; - return returnObject ? result : false; - } + return tasks; + } - if (isIgnored(input)) { - if (typeof opts.onIgnore === 'function') { - opts.onIgnore(result); - } + function resume() { + if (!self.paused) return; + self.paused = false; - result.isMatch = false; - return returnObject ? result : false; + for (var i = 0; i < self.concurrency; i++) { + _running++; + release(); } + } - if (typeof opts.onMatch === 'function') { - opts.onMatch(result); - } + function idle() { + return _running === 0 && self.length() === 0; + } - return returnObject ? result : true; - }; + function push(value, done) { + var current = cache.get(); + current.context = context; + current.release = release; + current.value = value; + current.callback = done || noop$1; - if (returnState) { - matcher.state = state; + if (_running === self.concurrency || self.paused) { + if (queueTail) { + queueTail.next = current; + queueTail = current; + } else { + queueHead = current; + queueTail = current; + self.saturated(); + } + } else { + _running++; + worker.call(context, current.value, current.worked); + } } - 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 - */ - + function unshift(value, done) { + var current = cache.get(); + current.context = context; + current.release = release; + current.value = value; + current.callback = done || noop$1; -picomatch.test = (input, regex, options, { - glob, - posix -} = {}) => { - if (typeof input !== 'string') { - throw new TypeError('Expected input to be a string'); + if (_running === self.concurrency || self.paused) { + if (queueHead) { + current.next = queueHead; + queueHead = current; + } else { + queueHead = current; + queueTail = current; + self.saturated(); + } + } else { + _running++; + worker.call(context, current.value, current.worked); + } } - if (input === '') { - return { - isMatch: false, - output: '' - }; - } + function release(holder) { + if (holder) { + cache.release(holder); + } - const opts = options || {}; - const format = opts.format || (posix ? utils$3.toPosixSlashes : null); - let match = input === glob; - let output = match && format ? format(input) : input; + var next = queueHead; - if (match === false) { - output = format ? format(input) : input; - match = output === glob; - } + if (next) { + if (!self.paused) { + if (queueTail === queueHead) { + queueTail = null; + } - if (match === false || opts.capture === true) { - if (opts.matchBase === true || opts.basename === true) { - match = picomatch.matchBase(input, regex, options, posix); - } else { - match = regex.exec(output); + queueHead = next.next; + next.next = null; + worker.call(context, next.value, next.worked); + + if (queueTail === null) { + self.empty(); + } + } else { + _running--; + } + } else if (--_running === 0) { + self.drain(); } } - 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 - */ - + function kill() { + queueHead = null; + queueTail = null; + self.drain = noop$1; + } -picomatch.matchBase = (input, glob, options, posix = utils$3.isWindows(options)) => { - const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); - return regex.test(path$2.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 - */ + function killAndDrain() { + queueHead = null; + queueTail = null; + self.drain(); + self.drain = noop$1; + } +} +function noop$1() {} -picomatch.isMatch = (str, patterns, options) => picomatch(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 - */ +function Task() { + this.value = null; + this.callback = noop$1; + this.next = null; + this.release = noop$1; + this.context = null; + var self = this; + this.worked = function worked(err, result) { + var callback = self.callback; + self.value = null; + self.callback = noop$1; + callback.call(self.context, err, result); + self.release(self); + }; +} -picomatch.parse = (pattern, options) => { - if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); - return parse_1$1(pattern, Object.assign({}, 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 - */ +var queue = fastqueue; +var common$2 = createCommonjsModule(function (module, exports) { -picomatch.scan = (input, options) => scan_1(input, options); -/** - * Create a regular expression from a glob pattern. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.makeRe(input[, options]); - * - * console.log(picomatch.makeRe('*.js')); - * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ - * ``` - * @param {String} `input` A glob pattern to convert to regex. - * @param {Object} `options` - * @return {RegExp} Returns a regex created from the given pattern. - * @api public - */ + Object.defineProperty(exports, "__esModule", { + value: true + }); + function isFatalError(settings, error) { + if (settings.errorFilter === null) { + return true; + } -picomatch.compileRe = (parsed, options, returnOutput = false, returnState = false) => { - if (returnOutput === true) { - return parsed.output; + return !settings.errorFilter(error); } - const opts = options || {}; - const prepend = opts.contains ? '' : '^'; - const append = opts.contains ? '' : '$'; - let source = `${prepend}(?:${parsed.output})${append}`; + exports.isFatalError = isFatalError; - if (parsed && parsed.negated === true) { - source = `^(?!${source}).*$`; + function isAppliedFilter(filter, value) { + return filter === null || filter(value); } - const regex = picomatch.toRegex(source, options); + exports.isAppliedFilter = isAppliedFilter; - if (returnState === true) { - regex.state = parsed; + function replacePathSegmentSeparator(filepath, separator) { + return filepath.split(/[\\/]/).join(separator); } - return regex; -}; - -picomatch.makeRe = (input, options, returnOutput = false, returnState = false) => { - if (!input || typeof input !== 'string') { - throw new TypeError('Expected a non-empty string'); - } + exports.replacePathSegmentSeparator = replacePathSegmentSeparator; - const opts = options || {}; - let parsed = { - negated: false, - fastpaths: true - }; - let prefix = ''; - let output; + function joinPathSegments(a, b, separator) { + if (a === '') { + return b; + } - if (input.startsWith('./')) { - input = input.slice(2); - prefix = parsed.prefix = './'; + return a + separator + b; } - if (opts.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { - output = parse_1$1.fastpaths(input, options); - } + exports.joinPathSegments = joinPathSegments; +}); - if (output === undefined) { - parsed = parse_1$1(input, options); - parsed.prefix = prefix + (parsed.prefix || ''); - } else { - parsed.output = output; - } +var reader = createCommonjsModule(function (module, exports) { - return picomatch.compileRe(parsed, options, returnOutput, returnState); -}; -/** - * Create a regular expression from the given regex source string. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.toRegex(source[, options]); - * - * const { output } = picomatch.parse('*.js'); - * console.log(picomatch.toRegex(output)); - * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ - * ``` - * @param {String} `source` Regular expression source string. - * @param {Object} `options` - * @return {RegExp} - * @api public - */ + Object.defineProperty(exports, "__esModule", { + value: true + }); + class Reader { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._root = common$2.replacePathSegmentSeparator(_root, _settings.pathSegmentSeparator); + } -picomatch.toRegex = (source, options) => { - try { - const opts = options || {}; - return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); - } catch (err) { - if (options && options.debug === true) throw err; - return /$^/; } -}; -/** - * Picomatch constants. - * @return {Object} - */ + exports.default = Reader; +}); -picomatch.constants = constants$3; -/** - * Expose "picomatch" - */ +var async$3 = createCommonjsModule(function (module, exports) { -var picomatch_1 = picomatch; + Object.defineProperty(exports, "__esModule", { + value: true + }); -var picomatch$1 = picomatch_1; + class AsyncReader extends reader.default { + constructor(_root, _settings) { + super(_root, _settings); + this._settings = _settings; + this._scandir = out$1.scandir; + this._emitter = new events_1__default['default'].EventEmitter(); + this._queue = queue(this._worker.bind(this), this._settings.concurrency); + this._isFatalError = false; + this._isDestroyed = false; -const isEmptyString = val => typeof val === 'string' && (val === '' || val === './'); -/** - * Returns an array of strings that match one or more glob patterns. - * - * ```js - * const mm = require('micromatch'); - * // mm(list, patterns[, options]); - * - * console.log(mm(['a.js', 'a.txt'], ['*.js'])); - * //=> [ 'a.js' ] - * ``` - * @param {String|Array} list List of strings to match. - * @param {String|Array} patterns One or more glob patterns to use for matching. - * @param {Object} options See available [options](#options) - * @return {Array} Returns an array of matches - * @summary false - * @api public - */ + this._queue.drain = () => { + if (!this._isFatalError) { + this._emitter.emit('end'); + } + }; + } + read() { + this._isFatalError = false; + this._isDestroyed = false; + setImmediate(() => { + this._pushToQueue(this._root, this._settings.basePath); + }); + return this._emitter; + } -const micromatch = (list, patterns, options) => { - patterns = [].concat(patterns); - list = [].concat(list); - let omit = new Set(); - let keep = new Set(); - let items = new Set(); - let negatives = 0; + destroy() { + if (this._isDestroyed) { + throw new Error('The reader is already destroyed'); + } - let onResult = state => { - items.add(state.output); + this._isDestroyed = true; - if (options && options.onResult) { - options.onResult(state); + this._queue.killAndDrain(); } - }; - for (let i = 0; i < patterns.length; i++) { - let isMatch = picomatch$1(String(patterns[i]), Object.assign({}, options, { - onResult - }), true); - let negated = isMatch.state.negated || isMatch.state.negatedExtglob; - if (negated) negatives++; - - for (let item of list) { - let matched = isMatch(item, true); - let match = negated ? !matched.isMatch : matched.isMatch; - if (!match) continue; - - if (negated) { - omit.add(matched.output); - } else { - omit.delete(matched.output); - keep.add(matched.output); - } + onEntry(callback) { + this._emitter.on('entry', callback); } - } - let result = negatives === patterns.length ? [...items] : [...keep]; - let matches = result.filter(item => !omit.has(item)); + onError(callback) { + this._emitter.once('error', callback); + } - if (options && matches.length === 0) { - if (options.failglob === true) { - throw new Error(`No matches found for "${patterns.join(', ')}"`); + onEnd(callback) { + this._emitter.once('end', callback); } - if (options.nonull === true || options.nullglob === true) { - return options.unescape ? patterns.map(p => p.replace(/\\/g, '')) : patterns; + _pushToQueue(directory, base) { + const queueItem = { + directory, + base + }; + + this._queue.push(queueItem, error => { + if (error !== null) { + this._handleError(error); + } + }); } - } - return matches; -}; -/** - * Backwards compatibility - */ + _worker(item, done) { + this._scandir(item.directory, this._settings.fsScandirSettings, (error, entries) => { + if (error !== null) { + return done(error, undefined); + } + for (const entry of entries) { + this._handleEntry(entry, item.base); + } -micromatch.match = micromatch; -/** - * Returns a matcher function from the given glob `pattern` and `options`. - * The returned function takes a string to match as its only argument and returns - * true if the string is a match. - * - * ```js - * const mm = require('micromatch'); - * // mm.matcher(pattern[, options]); - * - * const isMatch = mm.matcher('*.!(*a)'); - * console.log(isMatch('a.a')); //=> false - * console.log(isMatch('a.b')); //=> true - * ``` - * @param {String} `pattern` Glob pattern - * @param {Object} `options` - * @return {Function} Returns a matcher function. - * @api public - */ + done(null, undefined); + }); + } -micromatch.matcher = (pattern, options) => picomatch$1(pattern, options); -/** - * Returns true if **any** of the given glob `patterns` match the specified `string`. - * - * ```js - * const mm = require('micromatch'); - * // mm.isMatch(string, patterns[, options]); - * - * console.log(mm.isMatch('a.a', ['b.*', '*.a'])); //=> true - * console.log(mm.isMatch('a.a', 'b.*')); //=> false - * ``` - * @param {String} str The string to test. - * @param {String|Array} patterns One or more glob patterns to use for matching. - * @param {Object} [options] See available [options](#options). - * @return {Boolean} Returns true if any patterns match `str` - * @api public - */ + _handleError(error) { + if (!common$2.isFatalError(this._settings, error)) { + return; + } + this._isFatalError = true; + this._isDestroyed = true; -micromatch.isMatch = (str, patterns, options) => picomatch$1(patterns, options)(str); -/** - * Backwards compatibility - */ + this._emitter.emit('error', error); + } + _handleEntry(entry, base) { + if (this._isDestroyed || this._isFatalError) { + return; + } -micromatch.any = micromatch.isMatch; -/** - * Returns a list of strings that _**do not match any**_ of the given `patterns`. - * - * ```js - * const mm = require('micromatch'); - * // mm.not(list, patterns[, options]); - * - * console.log(mm.not(['a.a', 'b.b', 'c.c'], '*.a')); - * //=> ['b.b', 'c.c'] - * ``` - * @param {Array} `list` Array of strings to match. - * @param {String|Array} `patterns` One or more glob pattern to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Array} Returns an array of strings that **do not match** the given patterns. - * @api public - */ + const fullpath = entry.path; -micromatch.not = (list, patterns, options = {}) => { - patterns = [].concat(patterns).map(String); - let result = new Set(); - let items = []; + if (base !== undefined) { + entry.path = common$2.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); + } - let onResult = state => { - if (options.onResult) options.onResult(state); - items.push(state.output); - }; + if (common$2.isAppliedFilter(this._settings.entryFilter, entry)) { + this._emitEntry(entry); + } - let matches = micromatch(list, patterns, Object.assign({}, options, { - onResult - })); + if (entry.dirent.isDirectory() && common$2.isAppliedFilter(this._settings.deepFilter, entry)) { + this._pushToQueue(fullpath, entry.path); + } + } - for (let item of items) { - if (!matches.includes(item)) { - result.add(item); + _emitEntry(entry) { + this._emitter.emit('entry', entry); } - } - return [...result]; -}; -/** - * Returns true if the given `string` contains the given pattern. Similar - * to [.isMatch](#isMatch) but the pattern can match any part of the string. - * - * ```js - * var mm = require('micromatch'); - * // mm.contains(string, pattern[, options]); - * - * console.log(mm.contains('aa/bb/cc', '*b')); - * //=> true - * console.log(mm.contains('aa/bb/cc', '*d')); - * //=> false - * ``` - * @param {String} `str` The string to match. - * @param {String|Array} `patterns` Glob pattern to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Boolean} Returns true if the patter matches any part of `str`. - * @api public - */ + } + exports.default = AsyncReader; +}); -micromatch.contains = (str, pattern, options) => { - if (typeof str !== 'string') { - throw new TypeError(`Expected a string: "${util$3.inspect(str)}"`); - } +var async$4 = createCommonjsModule(function (module, exports) { - if (Array.isArray(pattern)) { - return pattern.some(p => micromatch.contains(str, p, options)); - } + Object.defineProperty(exports, "__esModule", { + value: true + }); - if (typeof pattern === 'string') { - if (isEmptyString(str) || isEmptyString(pattern)) { - return false; + class AsyncProvider { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._reader = new async$3.default(this._root, this._settings); + this._storage = new Set(); } - if (str.includes(pattern) || str.startsWith('./') && str.slice(2).includes(pattern)) { - return true; - } - } + read(callback) { + this._reader.onError(error => { + callFailureCallback(callback, error); + }); - return micromatch.isMatch(str, pattern, Object.assign({}, options, { - contains: true - })); -}; -/** - * Filter the keys of the given object with the given `glob` pattern - * and `options`. Does not attempt to match nested keys. If you need this feature, - * use [glob-object][] instead. - * - * ```js - * const mm = require('micromatch'); - * // mm.matchKeys(object, patterns[, options]); - * - * const obj = { aa: 'a', ab: 'b', ac: 'c' }; - * console.log(mm.matchKeys(obj, '*b')); - * //=> { ab: 'b' } - * ``` - * @param {Object} `object` The object with keys to filter. - * @param {String|Array} `patterns` One or more glob patterns to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Object} Returns an object with only keys that match the given patterns. - * @api public - */ + this._reader.onEntry(entry => { + this._storage.add(entry); + }); + this._reader.onEnd(() => { + callSuccessCallback(callback, [...this._storage]); + }); -micromatch.matchKeys = (obj, patterns, options) => { - if (!utils$3.isObject(obj)) { - throw new TypeError('Expected the first argument to be an object'); - } + this._reader.read(); + } - let keys = micromatch(Object.keys(obj), patterns, options); - let res = {}; + } - for (let key of keys) res[key] = obj[key]; + exports.default = AsyncProvider; - return res; -}; -/** - * Returns true if some of the strings in the given `list` match any of the given glob `patterns`. - * - * ```js - * const mm = require('micromatch'); - * // mm.some(list, patterns[, options]); - * - * console.log(mm.some(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); - * // true - * console.log(mm.some(['foo.js'], ['*.js', '!foo.js'])); - * // false - * ``` - * @param {String|Array} `list` The string or array of strings to test. Returns as soon as the first match is found. - * @param {String|Array} `patterns` One or more glob patterns to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Boolean} Returns true if any patterns match `str` - * @api public - */ + function callFailureCallback(callback, error) { + callback(error); + } + function callSuccessCallback(callback, entries) { + callback(null, entries); + } +}); -micromatch.some = (list, patterns, options) => { - let items = [].concat(list); +var stream$3 = createCommonjsModule(function (module, exports) { - for (let pattern of [].concat(patterns)) { - let isMatch = picomatch$1(String(pattern), options); + Object.defineProperty(exports, "__esModule", { + value: true + }); - if (items.some(item => isMatch(item))) { - return true; + class StreamProvider { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._reader = new async$3.default(this._root, this._settings); + this._stream = new stream_1__default['default'].Readable({ + objectMode: true, + read: () => {}, + destroy: this._reader.destroy.bind(this._reader) + }); } - } - return false; -}; -/** - * Returns true if every string in the given `list` matches - * any of the given glob `patterns`. - * - * ```js - * const mm = require('micromatch'); - * // mm.every(list, patterns[, options]); - * - * console.log(mm.every('foo.js', ['foo.js'])); - * // true - * console.log(mm.every(['foo.js', 'bar.js'], ['*.js'])); - * // true - * console.log(mm.every(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); - * // false - * console.log(mm.every(['foo.js'], ['*.js', '!foo.js'])); - * // false - * ``` - * @param {String|Array} `list` The string or array of strings to test. - * @param {String|Array} `patterns` One or more glob patterns to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Boolean} Returns true if any patterns match `str` - * @api public - */ + read() { + this._reader.onError(error => { + this._stream.emit('error', error); + }); + this._reader.onEntry(entry => { + this._stream.push(entry); + }); -micromatch.every = (list, patterns, options) => { - let items = [].concat(list); + this._reader.onEnd(() => { + this._stream.push(null); + }); - for (let pattern of [].concat(patterns)) { - let isMatch = picomatch$1(String(pattern), options); + this._reader.read(); - if (!items.every(item => isMatch(item))) { - return false; + return this._stream; } - } - - return true; -}; -/** - * Returns true if **all** of the given `patterns` match - * the specified string. - * - * ```js - * const mm = require('micromatch'); - * // mm.all(string, patterns[, options]); - * - * console.log(mm.all('foo.js', ['foo.js'])); - * // true - * - * console.log(mm.all('foo.js', ['*.js', '!foo.js'])); - * // false - * - * console.log(mm.all('foo.js', ['*.js', 'foo.js'])); - * // true - * - * console.log(mm.all('foo.js', ['*.js', 'f*', '*o*', '*o.js'])); - * // true - * ``` - * @param {String|Array} `str` The string to test. - * @param {String|Array} `patterns` One or more glob patterns to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Boolean} Returns true if any patterns match `str` - * @api public - */ - -micromatch.all = (str, patterns, options) => { - if (typeof str !== 'string') { - throw new TypeError(`Expected a string: "${util$3.inspect(str)}"`); } - return [].concat(patterns).every(p => picomatch$1(p, options)(str)); -}; -/** - * Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match. - * - * ```js - * const mm = require('micromatch'); - * // mm.capture(pattern, string[, options]); - * - * console.log(mm.capture('test/*.js', 'test/foo.js')); - * //=> ['foo'] - * console.log(mm.capture('test/*.js', 'foo/bar.css')); - * //=> null - * ``` - * @param {String} `glob` Glob pattern to use for matching. - * @param {String} `input` String to match - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Boolean} Returns an array of captures if the input matches the glob pattern, otherwise `null`. - * @api public - */ + exports.default = StreamProvider; +}); +var sync$3 = createCommonjsModule(function (module, exports) { -micromatch.capture = (glob, input, options) => { - let posix = utils$3.isWindows(options); - let regex = picomatch$1.makeRe(String(glob), Object.assign({}, options, { - capture: true - })); - let match = regex.exec(posix ? utils$3.toPosixSlashes(input) : input); + Object.defineProperty(exports, "__esModule", { + value: true + }); - if (match) { - return match.slice(1).map(v => v === void 0 ? '' : v); - } -}; -/** - * Create a regular expression from the given glob `pattern`. - * - * ```js - * const mm = require('micromatch'); - * // mm.makeRe(pattern[, options]); - * - * console.log(mm.makeRe('*.js')); - * //=> /^(?:(\.[\\\/])?(?!\.)(?=.)[^\/]*?\.js)$/ - * ``` - * @param {String} `pattern` A glob pattern to convert to regex. - * @param {Object} `options` - * @return {RegExp} Returns a regex created from the given pattern. - * @api public - */ + class SyncReader extends reader.default { + constructor() { + super(...arguments); + this._scandir = out$1.scandirSync; + this._storage = new Set(); + this._queue = new Set(); + } + read() { + this._pushToQueue(this._root, this._settings.basePath); -micromatch.makeRe = (...args) => picomatch$1.makeRe(...args); -/** - * Scan a glob pattern to separate the pattern into segments. Used - * by the [split](#split) method. - * - * ```js - * const mm = require('micromatch'); - * const state = mm.scan(pattern[, options]); - * ``` - * @param {String} `pattern` - * @param {Object} `options` - * @return {Object} Returns an object with - * @api public - */ + this._handleQueue(); + return [...this._storage]; + } -micromatch.scan = (...args) => picomatch$1.scan(...args); -/** - * Parse a glob pattern to create the source string for a regular - * expression. - * - * ```js - * const mm = require('micromatch'); - * const state = mm(pattern[, options]); - * ``` - * @param {String} `glob` - * @param {Object} `options` - * @return {Object} Returns an object with useful properties and output to be used as regex source string. - * @api public - */ + _pushToQueue(directory, base) { + this._queue.add({ + directory, + base + }); + } + _handleQueue() { + for (const item of this._queue.values()) { + this._handleDirectory(item.directory, item.base); + } + } -micromatch.parse = (patterns, options) => { - let res = []; + _handleDirectory(directory, base) { + try { + const entries = this._scandir(directory, this._settings.fsScandirSettings); - for (let pattern of [].concat(patterns || [])) { - for (let str of braces_1(String(pattern), options)) { - res.push(picomatch$1.parse(str, options)); + for (const entry of entries) { + this._handleEntry(entry, base); + } + } catch (error) { + this._handleError(error); + } } - } - return res; -}; -/** - * Process the given brace `pattern`. - * - * ```js - * const { braces } = require('micromatch'); - * console.log(braces('foo/{a,b,c}/bar')); - * //=> [ 'foo/(a|b|c)/bar' ] - * - * console.log(braces('foo/{a,b,c}/bar', { expand: true })); - * //=> [ 'foo/a/bar', 'foo/b/bar', 'foo/c/bar' ] - * ``` - * @param {String} `pattern` String with brace pattern to process. - * @param {Object} `options` Any [options](#options) to change how expansion is performed. See the [braces][] library for all available options. - * @return {Array} - * @api public - */ + _handleError(error) { + if (!common$2.isFatalError(this._settings, error)) { + return; + } + throw error; + } -micromatch.braces = (pattern, options) => { - if (typeof pattern !== 'string') throw new TypeError('Expected a string'); + _handleEntry(entry, base) { + const fullpath = entry.path; - if (options && options.nobrace === true || !/\{.*\}/.test(pattern)) { - return [pattern]; - } + if (base !== undefined) { + entry.path = common$2.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); + } - return braces_1(pattern, options); -}; -/** - * Expand braces - */ + if (common$2.isAppliedFilter(this._settings.entryFilter, entry)) { + this._pushToStorage(entry); + } + if (entry.dirent.isDirectory() && common$2.isAppliedFilter(this._settings.deepFilter, entry)) { + this._pushToQueue(fullpath, entry.path); + } + } -micromatch.braceExpand = (pattern, options) => { - if (typeof pattern !== 'string') throw new TypeError('Expected a string'); - return micromatch.braces(pattern, Object.assign({}, options, { - expand: true - })); -}; -/** - * Expose micromatch - */ + _pushToStorage(entry) { + this._storage.add(entry); + } + } -var micromatch_1 = micromatch; + exports.default = SyncReader; +}); -var pattern = createCommonjsModule(function (module, exports) { +var sync$4 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); - const GLOBSTAR = '**'; - const ESCAPE_SYMBOL = '\\'; - const COMMON_GLOB_SYMBOLS_RE = /[*?]|^!/; - const REGEX_CHARACTER_CLASS_SYMBOLS_RE = /\[.*]/; - const REGEX_GROUP_SYMBOLS_RE = /(?:^|[^!*+?@])\(.*\|.*\)/; - const GLOB_EXTENSION_SYMBOLS_RE = /[!*+?@]\(.*\)/; - const BRACE_EXPANSIONS_SYMBOLS_RE = /{.*(?:,|\.\.).*}/; - function isStaticPattern(pattern, options = {}) { - return !isDynamicPattern(pattern, options); + class SyncProvider { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._reader = new sync$3.default(this._root, this._settings); + } + + read() { + return this._reader.read(); + } + } - exports.isStaticPattern = isStaticPattern; + exports.default = SyncProvider; +}); - function isDynamicPattern(pattern, options = {}) { - /** - * When the `caseSensitiveMatch` option is disabled, all patterns must be marked as dynamic, because we cannot check - * filepath directly (without read directory). - */ - if (options.caseSensitiveMatch === false || pattern.includes(ESCAPE_SYMBOL)) { - return true; - } +var settings$2 = createCommonjsModule(function (module, exports) { - if (COMMON_GLOB_SYMBOLS_RE.test(pattern) || REGEX_CHARACTER_CLASS_SYMBOLS_RE.test(pattern) || REGEX_GROUP_SYMBOLS_RE.test(pattern)) { - return true; - } + Object.defineProperty(exports, "__esModule", { + value: true + }); - if (options.extglob !== false && GLOB_EXTENSION_SYMBOLS_RE.test(pattern)) { - return true; + class Settings { + constructor(_options = {}) { + this._options = _options; + this.basePath = this._getValue(this._options.basePath, undefined); + this.concurrency = this._getValue(this._options.concurrency, Infinity); + this.deepFilter = this._getValue(this._options.deepFilter, null); + this.entryFilter = this._getValue(this._options.entryFilter, null); + this.errorFilter = this._getValue(this._options.errorFilter, null); + this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path__default['default'].sep); + this.fsScandirSettings = new out$1.Settings({ + followSymbolicLinks: this._options.followSymbolicLinks, + fs: this._options.fs, + pathSegmentSeparator: this._options.pathSegmentSeparator, + stats: this._options.stats, + throwErrorOnBrokenSymbolicLink: this._options.throwErrorOnBrokenSymbolicLink + }); } - if (options.braceExpansion !== false && BRACE_EXPANSIONS_SYMBOLS_RE.test(pattern)) { - return true; + _getValue(option, value) { + return option === undefined ? value : option; } - return false; } - exports.isDynamicPattern = isDynamicPattern; - - function convertToPositivePattern(pattern) { - return isNegativePattern(pattern) ? pattern.slice(1) : pattern; - } + exports.default = Settings; +}); - exports.convertToPositivePattern = convertToPositivePattern; +var out$2 = createCommonjsModule(function (module, exports) { - function convertToNegativePattern(pattern) { - return '!' + pattern; - } + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.Settings = settings$2.default; - exports.convertToNegativePattern = convertToNegativePattern; + function walk(directory, optionsOrSettingsOrCallback, callback) { + if (typeof optionsOrSettingsOrCallback === 'function') { + return new async$4.default(directory, getSettings()).read(optionsOrSettingsOrCallback); + } - function isNegativePattern(pattern) { - return pattern.startsWith('!') && pattern[1] !== '('; + new async$4.default(directory, getSettings(optionsOrSettingsOrCallback)).read(callback); } - exports.isNegativePattern = isNegativePattern; + exports.walk = walk; - function isPositivePattern(pattern) { - return !isNegativePattern(pattern); + function walkSync(directory, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + const provider = new sync$4.default(directory, settings); + return provider.read(); } - exports.isPositivePattern = isPositivePattern; + exports.walkSync = walkSync; - function getNegativePatterns(patterns) { - return patterns.filter(isNegativePattern); + function walkStream(directory, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + const provider = new stream$3.default(directory, settings); + return provider.read(); } - exports.getNegativePatterns = getNegativePatterns; - - function getPositivePatterns(patterns) { - return patterns.filter(isPositivePattern); - } + exports.walkStream = walkStream; - exports.getPositivePatterns = getPositivePatterns; + function getSettings(settingsOrOptions = {}) { + if (settingsOrOptions instanceof settings$2.default) { + return settingsOrOptions; + } - function getBaseDirectory(pattern) { - return globParent(pattern, { - flipBackslashes: false - }); + return new settings$2.default(settingsOrOptions); } +}); - exports.getBaseDirectory = getBaseDirectory; +var reader$1 = createCommonjsModule(function (module, exports) { - function hasGlobStar(pattern) { - return pattern.includes(GLOBSTAR); - } + Object.defineProperty(exports, "__esModule", { + value: true + }); - exports.hasGlobStar = hasGlobStar; + class Reader { + constructor(_settings) { + this._settings = _settings; + this._fsStatSettings = new out.Settings({ + followSymbolicLink: this._settings.followSymbolicLinks, + fs: this._settings.fs, + throwErrorOnBrokenSymbolicLink: this._settings.followSymbolicLinks + }); + } - function endsWithSlashGlobStar(pattern) { - return pattern.endsWith('/' + GLOBSTAR); - } + _getFullEntryPath(filepath) { + return path__default['default'].resolve(this._settings.cwd, filepath); + } - exports.endsWithSlashGlobStar = endsWithSlashGlobStar; + _makeEntry(stats, pattern) { + const entry = { + name: pattern, + path: pattern, + dirent: utils$3.fs.createDirentFromStats(pattern, stats) + }; - function isAffectDepthOfReadingPattern(pattern) { - const basename = path$2.basename(pattern); - return endsWithSlashGlobStar(pattern) || isStaticPattern(basename); - } + if (this._settings.stats) { + entry.stats = stats; + } - exports.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern; + return entry; + } + + _isFatalError(error) { + return !utils$3.errno.isEnoentCodeError(error) && !this._settings.suppressErrors; + } - function expandPatternsWithBraceExpansion(patterns) { - return patterns.reduce((collection, pattern) => { - return collection.concat(expandBraceExpansion(pattern)); - }, []); } - exports.expandPatternsWithBraceExpansion = expandPatternsWithBraceExpansion; + exports.default = Reader; +}); - function expandBraceExpansion(pattern) { - return micromatch_1.braces(pattern, { - expand: true, - nodupes: true - }); - } +var stream$4 = createCommonjsModule(function (module, exports) { - exports.expandBraceExpansion = expandBraceExpansion; + Object.defineProperty(exports, "__esModule", { + value: true + }); - function getPatternParts(pattern, options) { - const info = picomatch$1.scan(pattern, Object.assign(Object.assign({}, options), { - parts: true - })); // See micromatch/picomatch#58 for more details + class ReaderStream extends reader$1.default { + constructor() { + super(...arguments); + this._walkStream = out$2.walkStream; + this._stat = out.stat; + } - if (info.parts.length === 0) { - return [pattern]; + dynamic(root, options) { + return this._walkStream(root, options); } - return info.parts; - } + static(patterns, options) { + const filepaths = patterns.map(this._getFullEntryPath, this); + const stream = new stream_1__default['default'].PassThrough({ + objectMode: true + }); - exports.getPatternParts = getPatternParts; + stream._write = (index, _enc, done) => { + return this._getEntry(filepaths[index], patterns[index], options).then(entry => { + if (entry !== null && options.entryFilter(entry)) { + stream.push(entry); + } - function makeRe(pattern, options) { - return micromatch_1.makeRe(pattern, options); - } + if (index === filepaths.length - 1) { + stream.end(); + } - exports.makeRe = makeRe; + done(); + }).catch(done); + }; - function convertPatternsToRe(patterns, options) { - return patterns.map(pattern => makeRe(pattern, options)); - } + for (let i = 0; i < filepaths.length; i++) { + stream.write(i); + } - exports.convertPatternsToRe = convertPatternsToRe; + return stream; + } + + _getEntry(filepath, pattern, options) { + return this._getStat(filepath).then(stats => this._makeEntry(stats, pattern)).catch(error => { + if (options.errorFilter(error)) { + return null; + } + + throw error; + }); + } + + _getStat(filepath) { + return new Promise((resolve, reject) => { + this._stat(filepath, this._fsStatSettings, (error, stats) => { + return error === null ? resolve(stats) : reject(error); + }); + }); + } - function matchAny(entry, patternsRe) { - return patternsRe.some(patternRe => patternRe.test(entry)); } - exports.matchAny = matchAny; + exports.default = ReaderStream; }); -unwrapExports(pattern); -var pattern_1 = pattern.isStaticPattern; -var pattern_2 = pattern.isDynamicPattern; -var pattern_3 = pattern.convertToPositivePattern; -var pattern_4 = pattern.convertToNegativePattern; -var pattern_5 = pattern.isNegativePattern; -var pattern_6 = pattern.isPositivePattern; -var pattern_7 = pattern.getNegativePatterns; -var pattern_8 = pattern.getPositivePatterns; -var pattern_9 = pattern.getBaseDirectory; -var pattern_10 = pattern.hasGlobStar; -var pattern_11 = pattern.endsWithSlashGlobStar; -var pattern_12 = pattern.isAffectDepthOfReadingPattern; -var pattern_13 = pattern.expandPatternsWithBraceExpansion; -var pattern_14 = pattern.expandBraceExpansion; -var pattern_15 = pattern.getPatternParts; -var pattern_16 = pattern.makeRe; -var pattern_17 = pattern.convertPatternsToRe; -var pattern_18 = pattern.matchAny; - -var stream$1 = createCommonjsModule(function (module, exports) { + +var matcher = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); - function merge(streams) { - const mergedStream = merge2_1(streams); - streams.forEach(stream => { - stream.once('error', error => mergedStream.emit('error', error)); - }); - mergedStream.once('close', () => propagateCloseEventToSources(streams)); - mergedStream.once('end', () => propagateCloseEventToSources(streams)); - return mergedStream; - } + class Matcher { + constructor(_patterns, _settings, _micromatchOptions) { + this._patterns = _patterns; + this._settings = _settings; + this._micromatchOptions = _micromatchOptions; + this._storage = []; - exports.merge = merge; + this._fillStorage(); + } + + _fillStorage() { + /** + * The original pattern may include `{,*,**,a/*}`, which will lead to problems with matching (unresolved level). + * So, before expand patterns with brace expansion into separated patterns. + */ + const patterns = utils$3.pattern.expandPatternsWithBraceExpansion(this._patterns); + + for (const pattern of patterns) { + const segments = this._getPatternSegments(pattern); + + const sections = this._splitSegmentsIntoSections(segments); + + this._storage.push({ + complete: sections.length <= 1, + pattern, + segments, + sections + }); + } + } + + _getPatternSegments(pattern) { + const parts = utils$3.pattern.getPatternParts(pattern, this._micromatchOptions); + return parts.map(part => { + const dynamic = utils$3.pattern.isDynamicPattern(part, this._settings); + + if (!dynamic) { + return { + dynamic: false, + pattern: part + }; + } + + return { + dynamic: true, + pattern: part, + patternRe: utils$3.pattern.makeRe(part, this._micromatchOptions) + }; + }); + } + + _splitSegmentsIntoSections(segments) { + return utils$3.array.splitWhen(segments, segment => segment.dynamic && utils$3.pattern.hasGlobStar(segment.pattern)); + } - function propagateCloseEventToSources(streams) { - streams.forEach(stream => stream.emit('close')); } + + exports.default = Matcher; }); -unwrapExports(stream$1); -var stream_1 = stream$1.merge; -var string$1 = createCommonjsModule(function (module, exports) { +var partial = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); - function isString(input) { - return typeof input === 'string'; - } + class PartialMatcher extends matcher.default { + match(filepath) { + const parts = filepath.split('/'); + const levels = parts.length; - exports.isString = isString; + const patterns = this._storage.filter(info => !info.complete || info.segments.length > levels); + + for (const pattern of patterns) { + const section = pattern.sections[0]; + /** + * In this case, the pattern has a globstar and we must read all directories unconditionally, + * but only if the level has reached the end of the first group. + * + * fixtures/{a,b}/** + * ^ true/false ^ always true + */ + + if (!pattern.complete && levels > section.length) { + return true; + } + + const match = parts.every((part, index) => { + const segment = pattern.segments[index]; + + if (segment.dynamic && segment.patternRe.test(part)) { + return true; + } + + if (!segment.dynamic && segment.pattern === part) { + return true; + } + + return false; + }); + + if (match) { + return true; + } + } + + return false; + } - function isEmpty(input) { - return input === ''; } - exports.isEmpty = isEmpty; + exports.default = PartialMatcher; }); -unwrapExports(string$1); -var string_1$1 = string$1.isString; -var string_2 = string$1.isEmpty; -var utils$4 = createCommonjsModule(function (module, exports) { +var deep = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); - exports.array = array$2; - exports.errno = errno; - exports.fs = fs$1; - exports.path = path_1; - exports.pattern = pattern; - exports.stream = stream$1; - exports.string = string$1; -}); -unwrapExports(utils$4); -var utils_1$4 = utils$4.array; -var utils_2$4 = utils$4.errno; -var utils_3$4 = utils$4.fs; -var utils_4$3 = utils$4.path; -var utils_5$3 = utils$4.pattern; -var utils_6$3 = utils$4.stream; -var utils_7$3 = utils$4.string; -var tasks = createCommonjsModule(function (module, exports) { + class DeepFilter { + constructor(_settings, _micromatchOptions) { + this._settings = _settings; + this._micromatchOptions = _micromatchOptions; + } - Object.defineProperty(exports, "__esModule", { - value: true - }); + getFilter(basePath, positive, negative) { + const matcher = this._getMatcher(positive); - function generate(patterns, settings) { - const positivePatterns = getPositivePatterns(patterns); - const negativePatterns = getNegativePatternsAsPositive(patterns, settings.ignore); - const staticPatterns = positivePatterns.filter(pattern => utils$4.pattern.isStaticPattern(pattern, settings)); - const dynamicPatterns = positivePatterns.filter(pattern => utils$4.pattern.isDynamicPattern(pattern, settings)); - const staticTasks = convertPatternsToTasks(staticPatterns, negativePatterns, - /* dynamic */ - false); - const dynamicTasks = convertPatternsToTasks(dynamicPatterns, negativePatterns, - /* dynamic */ - true); - return staticTasks.concat(dynamicTasks); - } + const negativeRe = this._getNegativePatternsRe(negative); - exports.generate = generate; + return entry => this._filter(basePath, entry, matcher, negativeRe); + } - function convertPatternsToTasks(positive, negative, dynamic) { - const positivePatternsGroup = groupPatternsByBaseDirectory(positive); // When we have a global group – there is no reason to divide the patterns into independent tasks. - // In this case, the global task covers the rest. + _getMatcher(patterns) { + return new partial.default(patterns, this._settings, this._micromatchOptions); + } - if ('.' in positivePatternsGroup) { - const task = convertPatternGroupToTask('.', positive, negative, dynamic); - return [task]; + _getNegativePatternsRe(patterns) { + const affectDepthOfReadingPatterns = patterns.filter(utils$3.pattern.isAffectDepthOfReadingPattern); + return utils$3.pattern.convertPatternsToRe(affectDepthOfReadingPatterns, this._micromatchOptions); } - return convertPatternGroupsToTasks(positivePatternsGroup, negative, dynamic); - } + _filter(basePath, entry, matcher, negativeRe) { + if (this._isSkippedByDeep(basePath, entry.path)) { + return false; + } - exports.convertPatternsToTasks = convertPatternsToTasks; + if (this._isSkippedSymbolicLink(entry)) { + return false; + } - function getPositivePatterns(patterns) { - return utils$4.pattern.getPositivePatterns(patterns); - } + const filepath = utils$3.path.removeLeadingDotSegment(entry.path); - exports.getPositivePatterns = getPositivePatterns; + if (this._isSkippedByPositivePatterns(filepath, matcher)) { + return false; + } - function getNegativePatternsAsPositive(patterns, ignore) { - const negative = utils$4.pattern.getNegativePatterns(patterns).concat(ignore); - const positive = negative.map(utils$4.pattern.convertToPositivePattern); - return positive; - } + return this._isSkippedByNegativePatterns(filepath, negativeRe); + } - exports.getNegativePatternsAsPositive = getNegativePatternsAsPositive; + _isSkippedByDeep(basePath, entryPath) { + /** + * Avoid unnecessary depth calculations when it doesn't matter. + */ + if (this._settings.deep === Infinity) { + return false; + } - function groupPatternsByBaseDirectory(patterns) { - const group = {}; - return patterns.reduce((collection, pattern) => { - const base = utils$4.pattern.getBaseDirectory(pattern); + return this._getEntryLevel(basePath, entryPath) >= this._settings.deep; + } - if (base in collection) { - collection[base].push(pattern); - } else { - collection[base] = [pattern]; + _getEntryLevel(basePath, entryPath) { + const entryPathDepth = entryPath.split('/').length; + + if (basePath === '') { + return entryPathDepth; } - return collection; - }, group); - } + const basePathDepth = basePath.split('/').length; + return entryPathDepth - basePathDepth; + } - exports.groupPatternsByBaseDirectory = groupPatternsByBaseDirectory; + _isSkippedSymbolicLink(entry) { + return !this._settings.followSymbolicLinks && entry.dirent.isSymbolicLink(); + } - function convertPatternGroupsToTasks(positive, negative, dynamic) { - return Object.keys(positive).map(base => { - return convertPatternGroupToTask(base, positive[base], negative, dynamic); - }); - } + _isSkippedByPositivePatterns(entryPath, matcher) { + return !this._settings.baseNameMatch && !matcher.match(entryPath); + } - exports.convertPatternGroupsToTasks = convertPatternGroupsToTasks; + _isSkippedByNegativePatterns(entryPath, patternsRe) { + return !utils$3.pattern.matchAny(entryPath, patternsRe); + } - function convertPatternGroupToTask(base, positive, negative, dynamic) { - return { - dynamic, - positive, - negative, - base, - patterns: [].concat(positive, negative.map(utils$4.pattern.convertToNegativePattern)) - }; } - exports.convertPatternGroupToTask = convertPatternGroupToTask; + exports.default = DeepFilter; }); -unwrapExports(tasks); -var tasks_1 = tasks.generate; -var tasks_2 = tasks.convertPatternsToTasks; -var tasks_3 = tasks.getPositivePatterns; -var tasks_4 = tasks.getNegativePatternsAsPositive; -var tasks_5 = tasks.groupPatternsByBaseDirectory; -var tasks_6 = tasks.convertPatternGroupsToTasks; -var tasks_7 = tasks.convertPatternGroupToTask; -var async$1 = createCommonjsModule(function (module, exports) { +var entry = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); - function read(path, settings, callback) { - settings.fs.lstat(path, (lstatError, lstat) => { - if (lstatError !== null) { - return callFailureCallback(callback, lstatError); - } - - if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { - return callSuccessCallback(callback, lstat); - } - - settings.fs.stat(path, (statError, stat) => { - if (statError !== null) { - if (settings.throwErrorOnBrokenSymbolicLink) { - return callFailureCallback(callback, statError); - } - - return callSuccessCallback(callback, lstat); - } - - if (settings.markSymbolicLink) { - stat.isSymbolicLink = () => true; - } - - callSuccessCallback(callback, stat); - }); - }); - } + class EntryFilter { + constructor(_settings, _micromatchOptions) { + this._settings = _settings; + this._micromatchOptions = _micromatchOptions; + this.index = new Map(); + } - exports.read = read; + getFilter(positive, negative) { + const positiveRe = utils$3.pattern.convertPatternsToRe(positive, this._micromatchOptions); + const negativeRe = utils$3.pattern.convertPatternsToRe(negative, this._micromatchOptions); + return entry => this._filter(entry, positiveRe, negativeRe); + } - function callFailureCallback(callback, error) { - callback(error); - } + _filter(entry, positiveRe, negativeRe) { + if (this._settings.unique && this._isDuplicateEntry(entry)) { + return false; + } - function callSuccessCallback(callback, result) { - callback(null, result); - } -}); -unwrapExports(async$1); -var async_1 = async$1.read; + if (this._onlyFileFilter(entry) || this._onlyDirectoryFilter(entry)) { + return false; + } -var sync$1 = createCommonjsModule(function (module, exports) { + if (this._isSkippedByAbsoluteNegativePatterns(entry.path, negativeRe)) { + return false; + } - Object.defineProperty(exports, "__esModule", { - value: true - }); + const filepath = this._settings.baseNameMatch ? entry.name : entry.path; + const isMatched = this._isMatchToPatterns(filepath, positiveRe) && !this._isMatchToPatterns(entry.path, negativeRe); - function read(path, settings) { - const lstat = settings.fs.lstatSync(path); + if (this._settings.unique && isMatched) { + this._createIndexRecord(entry); + } - if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { - return lstat; + return isMatched; } - try { - const stat = settings.fs.statSync(path); - - if (settings.markSymbolicLink) { - stat.isSymbolicLink = () => true; - } + _isDuplicateEntry(entry) { + return this.index.has(entry.path); + } - return stat; - } catch (error) { - if (!settings.throwErrorOnBrokenSymbolicLink) { - return lstat; - } + _createIndexRecord(entry) { + this.index.set(entry.path, undefined); + } - throw error; + _onlyFileFilter(entry) { + return this._settings.onlyFiles && !entry.dirent.isFile(); } - } - exports.read = read; -}); -unwrapExports(sync$1); -var sync_1 = sync$1.read; + _onlyDirectoryFilter(entry) { + return this._settings.onlyDirectories && !entry.dirent.isDirectory(); + } -var fs_1$1 = createCommonjsModule(function (module, exports) { + _isSkippedByAbsoluteNegativePatterns(entryPath, patternsRe) { + if (!this._settings.absolute) { + return false; + } - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.FILE_SYSTEM_ADAPTER = { - lstat: fs$3.lstat, - stat: fs$3.stat, - lstatSync: fs$3.lstatSync, - statSync: fs$3.statSync - }; + const fullpath = utils$3.path.makeAbsolute(this._settings.cwd, entryPath); + return utils$3.pattern.matchAny(fullpath, patternsRe); + } - function createFileSystemAdapter(fsMethods) { - if (fsMethods === undefined) { - return exports.FILE_SYSTEM_ADAPTER; + _isMatchToPatterns(entryPath, patternsRe) { + const filepath = utils$3.path.removeLeadingDotSegment(entryPath); + return utils$3.pattern.matchAny(filepath, patternsRe); } - return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods); } - exports.createFileSystemAdapter = createFileSystemAdapter; + exports.default = EntryFilter; }); -unwrapExports(fs_1$1); -var fs_2 = fs_1$1.FILE_SYSTEM_ADAPTER; -var fs_3 = fs_1$1.createFileSystemAdapter; -var settings = createCommonjsModule(function (module, exports) { +var error = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); - class Settings { - constructor(_options = {}) { - this._options = _options; - this.followSymbolicLink = this._getValue(this._options.followSymbolicLink, true); - this.fs = fs_1$1.createFileSystemAdapter(this._options.fs); - this.markSymbolicLink = this._getValue(this._options.markSymbolicLink, false); - this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); + class ErrorFilter { + constructor(_settings) { + this._settings = _settings; } - _getValue(option, value) { - return option === undefined ? value : option; + getFilter() { + return error => this._isNonFatalError(error); + } + + _isNonFatalError(error) { + return utils$3.errno.isEnoentCodeError(error) || this._settings.suppressErrors; } } - exports.default = Settings; + exports.default = ErrorFilter; }); -unwrapExports(settings); -var out = createCommonjsModule(function (module, exports) { +var entry$1 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); - exports.Settings = settings.default; - function stat(path, optionsOrSettingsOrCallback, callback) { - if (typeof optionsOrSettingsOrCallback === 'function') { - return async$1.read(path, getSettings(), optionsOrSettingsOrCallback); + class EntryTransformer { + constructor(_settings) { + this._settings = _settings; } - async$1.read(path, getSettings(optionsOrSettingsOrCallback), callback); - } + getTransformer() { + return entry => this._transform(entry); + } - exports.stat = stat; + _transform(entry) { + let filepath = entry.path; - function statSync(path, optionsOrSettings) { - const settings = getSettings(optionsOrSettings); - return sync$1.read(path, settings); - } + if (this._settings.absolute) { + filepath = utils$3.path.makeAbsolute(this._settings.cwd, filepath); + filepath = utils$3.path.unixify(filepath); + } - exports.statSync = statSync; + if (this._settings.markDirectories && entry.dirent.isDirectory()) { + filepath += '/'; + } - function getSettings(settingsOrOptions = {}) { - if (settingsOrOptions instanceof settings.default) { - return settingsOrOptions; + if (!this._settings.objectMode) { + return filepath; + } + + return Object.assign(Object.assign({}, entry), { + path: filepath + }); } - return new settings.default(settingsOrOptions); } -}); -unwrapExports(out); -var out_1 = out.Settings; -var out_2 = out.stat; -var out_3 = out.statSync; -var runParallel_1 = runParallel; + exports.default = EntryTransformer; +}); -function runParallel(tasks, cb) { - var results, pending, keys; - var isSync = true; +var provider = createCommonjsModule(function (module, exports) { - if (Array.isArray(tasks)) { - results = []; - pending = tasks.length; - } else { - keys = Object.keys(tasks); - results = {}; - pending = keys.length; - } + Object.defineProperty(exports, "__esModule", { + value: true + }); - function done(err) { - function end() { - if (cb) cb(err, results); - cb = null; + class Provider { + constructor(_settings) { + this._settings = _settings; + this.errorFilter = new error.default(this._settings); + this.entryFilter = new entry.default(this._settings, this._getMicromatchOptions()); + this.deepFilter = new deep.default(this._settings, this._getMicromatchOptions()); + this.entryTransformer = new entry$1.default(this._settings); } - if (isSync) process.nextTick(end);else end(); - } + _getRootDirectory(task) { + return path__default['default'].resolve(this._settings.cwd, task.base); + } - function each(i, err, result) { - results[i] = result; + _getReaderOptions(task) { + const basePath = task.base === '.' ? '' : task.base; + return { + basePath, + pathSegmentSeparator: '/', + concurrency: this._settings.concurrency, + deepFilter: this.deepFilter.getFilter(basePath, task.positive, task.negative), + entryFilter: this.entryFilter.getFilter(task.positive, task.negative), + errorFilter: this.errorFilter.getFilter(), + followSymbolicLinks: this._settings.followSymbolicLinks, + fs: this._settings.fs, + stats: this._settings.stats, + throwErrorOnBrokenSymbolicLink: this._settings.throwErrorOnBrokenSymbolicLink, + transform: this.entryTransformer.getTransformer() + }; + } - if (--pending === 0 || err) { - done(err); + _getMicromatchOptions() { + return { + dot: this._settings.dot, + matchBase: this._settings.baseNameMatch, + nobrace: !this._settings.braceExpansion, + nocase: !this._settings.caseSensitiveMatch, + noext: !this._settings.extglob, + noglobstar: !this._settings.globstar, + posix: true, + strictSlashes: false + }; } - } - if (!pending) { - // empty - done(null); - } else if (keys) { - // object - keys.forEach(function (key) { - tasks[key](function (err, result) { - each(key, err, result); - }); - }); - } else { - // array - tasks.forEach(function (task, i) { - task(function (err, result) { - each(i, err, result); - }); - }); } - isSync = false; -} + exports.default = Provider; +}); -var constants$4 = createCommonjsModule(function (module, exports) { +var async$5 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); - const NODE_PROCESS_VERSION_PARTS = process.versions.node.split('.'); - const MAJOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[0], 10); - const MINOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[1], 10); - const SUPPORTED_MAJOR_VERSION = 10; - const SUPPORTED_MINOR_VERSION = 10; - const IS_MATCHED_BY_MAJOR = MAJOR_VERSION > SUPPORTED_MAJOR_VERSION; - const IS_MATCHED_BY_MAJOR_AND_MINOR = MAJOR_VERSION === SUPPORTED_MAJOR_VERSION && MINOR_VERSION >= SUPPORTED_MINOR_VERSION; - /** - * IS `true` for Node.js 10.10 and greater. - */ - exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = IS_MATCHED_BY_MAJOR || IS_MATCHED_BY_MAJOR_AND_MINOR; -}); -unwrapExports(constants$4); -var constants_1 = constants$4.IS_SUPPORT_READDIR_WITH_FILE_TYPES; + class ProviderAsync extends provider.default { + constructor() { + super(...arguments); + this._reader = new stream$4.default(this._settings); + } -var fs$2 = createCommonjsModule(function (module, exports) { + read(task) { + const root = this._getRootDirectory(task); - Object.defineProperty(exports, "__esModule", { - value: true - }); + const options = this._getReaderOptions(task); - class DirentFromStats { - constructor(name, stats) { - this.name = name; - this.isBlockDevice = stats.isBlockDevice.bind(stats); - this.isCharacterDevice = stats.isCharacterDevice.bind(stats); - this.isDirectory = stats.isDirectory.bind(stats); - this.isFIFO = stats.isFIFO.bind(stats); - this.isFile = stats.isFile.bind(stats); - this.isSocket = stats.isSocket.bind(stats); - this.isSymbolicLink = stats.isSymbolicLink.bind(stats); + const entries = []; + return new Promise((resolve, reject) => { + const stream = this.api(root, task, options); + stream.once('error', reject); + stream.on('data', entry => entries.push(options.transform(entry))); + stream.once('end', () => resolve(entries)); + }); } - } + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); + } + + return this._reader.static(task.patterns, options); + } - function createDirentFromStats(name, stats) { - return new DirentFromStats(name, stats); } - exports.createDirentFromStats = createDirentFromStats; + exports.default = ProviderAsync; }); -unwrapExports(fs$2); -var fs_1$2 = fs$2.createDirentFromStats; -var utils$5 = createCommonjsModule(function (module, exports) { +var stream$5 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); - exports.fs = fs$2; -}); -unwrapExports(utils$5); -var utils_1$5 = utils$5.fs; -var async$2 = createCommonjsModule(function (module, exports) { + class ProviderStream extends provider.default { + constructor() { + super(...arguments); + this._reader = new stream$4.default(this._settings); + } - Object.defineProperty(exports, "__esModule", { - value: true - }); + read(task) { + const root = this._getRootDirectory(task); - function read(directory, settings, callback) { - if (!settings.stats && constants$4.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { - return readdirWithFileTypes(directory, settings, callback); + const options = this._getReaderOptions(task); + + const source = this.api(root, task, options); + const destination = new stream_1__default['default'].Readable({ + objectMode: true, + read: () => {} + }); + source.once('error', error => destination.emit('error', error)).on('data', entry => destination.emit('data', options.transform(entry))).once('end', () => destination.emit('end')); + destination.once('close', () => source.destroy()); + return destination; } - return readdir(directory, settings, callback); - } + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); + } - exports.read = read; + return this._reader.static(task.patterns, options); + } - function readdirWithFileTypes(directory, settings, callback) { - settings.fs.readdir(directory, { - withFileTypes: true - }, (readdirError, dirents) => { - if (readdirError !== null) { - return callFailureCallback(callback, readdirError); - } + } - const entries = dirents.map(dirent => ({ - dirent, - name: dirent.name, - path: `${directory}${settings.pathSegmentSeparator}${dirent.name}` - })); + exports.default = ProviderStream; +}); - if (!settings.followSymbolicLinks) { - return callSuccessCallback(callback, entries); - } +var sync$5 = createCommonjsModule(function (module, exports) { - const tasks = entries.map(entry => makeRplTaskEntry(entry, settings)); - runParallel_1(tasks, (rplError, rplEntries) => { - if (rplError !== null) { - return callFailureCallback(callback, rplError); - } + Object.defineProperty(exports, "__esModule", { + value: true + }); - callSuccessCallback(callback, rplEntries); - }); - }); - } + class ReaderSync extends reader$1.default { + constructor() { + super(...arguments); + this._walkSync = out$2.walkSync; + this._statSync = out.statSync; + } - exports.readdirWithFileTypes = readdirWithFileTypes; + dynamic(root, options) { + return this._walkSync(root, options); + } - function makeRplTaskEntry(entry, settings) { - return done => { - if (!entry.dirent.isSymbolicLink()) { - return done(null, entry); - } + static(patterns, options) { + const entries = []; - settings.fs.stat(entry.path, (statError, stats) => { - if (statError !== null) { - if (settings.throwErrorOnBrokenSymbolicLink) { - return done(statError); - } + for (const pattern of patterns) { + const filepath = this._getFullEntryPath(pattern); - return done(null, entry); - } + const entry = this._getEntry(filepath, pattern, options); - entry.dirent = utils$5.fs.createDirentFromStats(entry.name, stats); - return done(null, entry); - }); - }; - } + if (entry === null || !options.entryFilter(entry)) { + continue; + } - function readdir(directory, settings, callback) { - settings.fs.readdir(directory, (readdirError, names) => { - if (readdirError !== null) { - return callFailureCallback(callback, readdirError); + entries.push(entry); } - const filepaths = names.map(name => `${directory}${settings.pathSegmentSeparator}${name}`); - const tasks = filepaths.map(filepath => { - return done => out.stat(filepath, settings.fsStatSettings, done); - }); - runParallel_1(tasks, (rplError, results) => { - if (rplError !== null) { - return callFailureCallback(callback, rplError); - } + return entries; + } - const entries = []; - names.forEach((name, index) => { - const stats = results[index]; - const entry = { - name, - path: filepaths[index], - dirent: utils$5.fs.createDirentFromStats(name, stats) - }; + _getEntry(filepath, pattern, options) { + try { + const stats = this._getStat(filepath); - if (settings.stats) { - entry.stats = stats; - } + return this._makeEntry(stats, pattern); + } catch (error) { + if (options.errorFilter(error)) { + return null; + } - entries.push(entry); - }); - callSuccessCallback(callback, entries); - }); - }); - } + throw error; + } + } - exports.readdir = readdir; + _getStat(filepath) { + return this._statSync(filepath, this._fsStatSettings); + } - function callFailureCallback(callback, error) { - callback(error); } - function callSuccessCallback(callback, result) { - callback(null, result); - } + exports.default = ReaderSync; }); -unwrapExports(async$2); -var async_1$1 = async$2.read; -var async_2 = async$2.readdirWithFileTypes; -var async_3 = async$2.readdir; -var sync$2 = createCommonjsModule(function (module, exports) { +var sync$6 = createCommonjsModule(function (module, exports) { Object.defineProperty(exports, "__esModule", { value: true }); - function read(directory, settings) { - if (!settings.stats && constants$4.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { - return readdirWithFileTypes(directory, settings); + class ProviderSync extends provider.default { + constructor() { + super(...arguments); + this._reader = new sync$5.default(this._settings); } - return readdir(directory, settings); - } + read(task) { + const root = this._getRootDirectory(task); - exports.read = read; + const options = this._getReaderOptions(task); - function readdirWithFileTypes(directory, settings) { - const dirents = settings.fs.readdirSync(directory, { - withFileTypes: true - }); - return dirents.map(dirent => { - const entry = { - dirent, - name: dirent.name, - path: `${directory}${settings.pathSegmentSeparator}${dirent.name}` - }; + const entries = this.api(root, task, options); + return entries.map(options.transform); + } - if (entry.dirent.isSymbolicLink() && settings.followSymbolicLinks) { - try { - const stats = settings.fs.statSync(entry.path); - entry.dirent = utils$5.fs.createDirentFromStats(entry.name, stats); - } catch (error) { - if (settings.throwErrorOnBrokenSymbolicLink) { - throw error; - } - } + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); } - return entry; - }); + return this._reader.static(task.patterns, options); + } + } - exports.readdirWithFileTypes = readdirWithFileTypes; + exports.default = ProviderSync; +}); - function readdir(directory, settings) { - const names = settings.fs.readdirSync(directory); - return names.map(name => { - const entryPath = `${directory}${settings.pathSegmentSeparator}${name}`; - const stats = out.statSync(entryPath, settings.fsStatSettings); - const entry = { - name, - path: entryPath, - dirent: utils$5.fs.createDirentFromStats(name, stats) - }; +var settings$3 = createCommonjsModule(function (module, exports) { - if (settings.stats) { - entry.stats = stats; - } + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.DEFAULT_FILE_SYSTEM_ADAPTER = void 0; + const CPU_COUNT = os__default['default'].cpus().length; + exports.DEFAULT_FILE_SYSTEM_ADAPTER = { + lstat: fs__default['default'].lstat, + lstatSync: fs__default['default'].lstatSync, + stat: fs__default['default'].stat, + statSync: fs__default['default'].statSync, + readdir: fs__default['default'].readdir, + readdirSync: fs__default['default'].readdirSync + }; - return entry; - }); - } + class Settings { + constructor(_options = {}) { + this._options = _options; + this.absolute = this._getValue(this._options.absolute, false); + this.baseNameMatch = this._getValue(this._options.baseNameMatch, false); + this.braceExpansion = this._getValue(this._options.braceExpansion, true); + this.caseSensitiveMatch = this._getValue(this._options.caseSensitiveMatch, true); + this.concurrency = this._getValue(this._options.concurrency, CPU_COUNT); + this.cwd = this._getValue(this._options.cwd, process.cwd()); + this.deep = this._getValue(this._options.deep, Infinity); + this.dot = this._getValue(this._options.dot, false); + this.extglob = this._getValue(this._options.extglob, true); + this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, true); + this.fs = this._getFileSystemMethods(this._options.fs); + this.globstar = this._getValue(this._options.globstar, true); + this.ignore = this._getValue(this._options.ignore, []); + this.markDirectories = this._getValue(this._options.markDirectories, false); + this.objectMode = this._getValue(this._options.objectMode, false); + this.onlyDirectories = this._getValue(this._options.onlyDirectories, false); + this.onlyFiles = this._getValue(this._options.onlyFiles, true); + this.stats = this._getValue(this._options.stats, false); + this.suppressErrors = this._getValue(this._options.suppressErrors, false); + this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, false); + this.unique = this._getValue(this._options.unique, true); - exports.readdir = readdir; -}); -unwrapExports(sync$2); -var sync_1$1 = sync$2.read; -var sync_2 = sync$2.readdirWithFileTypes; -var sync_3 = sync$2.readdir; + if (this.onlyDirectories) { + this.onlyFiles = false; + } -var fs_1$3 = createCommonjsModule(function (module, exports) { + if (this.stats) { + this.objectMode = true; + } + } - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.FILE_SYSTEM_ADAPTER = { - lstat: fs$3.lstat, - stat: fs$3.stat, - lstatSync: fs$3.lstatSync, - statSync: fs$3.statSync, - readdir: fs$3.readdir, - readdirSync: fs$3.readdirSync - }; + _getValue(option, value) { + return option === undefined ? value : option; + } - function createFileSystemAdapter(fsMethods) { - if (fsMethods === undefined) { - return exports.FILE_SYSTEM_ADAPTER; + _getFileSystemMethods(methods = {}) { + return Object.assign(Object.assign({}, exports.DEFAULT_FILE_SYSTEM_ADAPTER), methods); } - return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods); } - exports.createFileSystemAdapter = createFileSystemAdapter; + exports.default = Settings; }); -unwrapExports(fs_1$3); -var fs_2$1 = fs_1$3.FILE_SYSTEM_ADAPTER; -var fs_3$1 = fs_1$3.createFileSystemAdapter; -var settings$1 = createCommonjsModule(function (module, exports) { +async function FastGlob(source, options) { + assertPatternsInput(source); + const works = getWorks(source, async$5.default, options); + const result = await Promise.all(works); + return utils$3.array.flatten(result); +} // https://github.com/typescript-eslint/typescript-eslint/issues/60 +// eslint-disable-next-line no-redeclare - Object.defineProperty(exports, "__esModule", { - value: true - }); - class Settings { - constructor(_options = {}) { - this._options = _options; - this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false); - this.fs = fs_1$3.createFileSystemAdapter(this._options.fs); - this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path$2.sep); - this.stats = this._getValue(this._options.stats, false); - this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); - this.fsStatSettings = new out.Settings({ - followSymbolicLink: this.followSymbolicLinks, - fs: this.fs, - throwErrorOnBrokenSymbolicLink: this.throwErrorOnBrokenSymbolicLink - }); - } +(function (FastGlob) { + function sync(source, options) { + assertPatternsInput(source); + const works = getWorks(source, sync$6.default, options); + return utils$3.array.flatten(works); + } - _getValue(option, value) { - return option === undefined ? value : option; - } + FastGlob.sync = sync; - } + function stream(source, options) { + assertPatternsInput(source); + const works = getWorks(source, stream$5.default, options); + /** + * The stream returned by the provider cannot work with an asynchronous iterator. + * To support asynchronous iterators, regardless of the number of tasks, we always multiplex streams. + * This affects performance (+25%). I don't see best solution right now. + */ - exports.default = Settings; -}); -unwrapExports(settings$1); + return utils$3.stream.merge(works); + } -var out$1 = createCommonjsModule(function (module, exports) { + FastGlob.stream = stream; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.Settings = settings$1.default; + function generateTasks(source, options) { + assertPatternsInput(source); + const patterns = [].concat(source); + const settings = new settings$3.default(options); + return tasks.generate(patterns, settings); + } - function scandir(path, optionsOrSettingsOrCallback, callback) { - if (typeof optionsOrSettingsOrCallback === 'function') { - return async$2.read(path, getSettings(), optionsOrSettingsOrCallback); - } + FastGlob.generateTasks = generateTasks; - async$2.read(path, getSettings(optionsOrSettingsOrCallback), callback); + function isDynamicPattern(source, options) { + assertPatternsInput(source); + const settings = new settings$3.default(options); + return utils$3.pattern.isDynamicPattern(source, settings); } - exports.scandir = scandir; + FastGlob.isDynamicPattern = isDynamicPattern; - function scandirSync(path, optionsOrSettings) { - const settings = getSettings(optionsOrSettings); - return sync$2.read(path, settings); + function escapePath(source) { + assertPatternsInput(source); + return utils$3.path.escape(source); } - exports.scandirSync = scandirSync; + FastGlob.escapePath = escapePath; +})(FastGlob || (FastGlob = {})); - function getSettings(settingsOrOptions = {}) { - if (settingsOrOptions instanceof settings$1.default) { - return settingsOrOptions; - } +function getWorks(source, _Provider, options) { + const patterns = [].concat(source); + const settings = new settings$3.default(options); + const tasks$1 = tasks.generate(patterns, settings); + const provider = new _Provider(settings); + return tasks$1.map(provider.read, provider); +} - return new settings$1.default(settingsOrOptions); +function assertPatternsInput(input) { + const source = [].concat(input); + const isValidSource = source.every(item => utils$3.string.isString(item) && !utils$3.string.isEmpty(item)); + + if (!isValidSource) { + throw new TypeError('Patterns must be a string (non empty) or an array of strings'); } -}); -unwrapExports(out$1); -var out_1$1 = out$1.Settings; -var out_2$1 = out$1.scandir; -var out_3$1 = out$1.scandirSync; +} -function reusify(Constructor) { - var head = new Constructor(); - var tail = head; +var out$3 = FastGlob; - function get() { - var current = head; +const { + promisify +} = util__default['default']; - if (current.next) { - head = current.next; - } else { - head = new Constructor(); - tail = head; +async function isType(fsStatType, statsMethodName, filePath) { + if (typeof filePath !== 'string') { + throw new TypeError(`Expected a string, got ${typeof filePath}`); + } + + try { + const stats = await promisify(fs__default['default'][fsStatType])(filePath); + return stats[statsMethodName](); + } catch (error) { + if (error.code === 'ENOENT') { + return false; } - current.next = null; - return current; + throw error; } +} - function release(obj) { - tail.next = obj; - tail = obj; +function isTypeSync(fsStatType, statsMethodName, filePath) { + if (typeof filePath !== 'string') { + throw new TypeError(`Expected a string, got ${typeof filePath}`); } - return { - get: get, - release: release - }; + try { + return fs__default['default'][fsStatType](filePath)[statsMethodName](); + } catch (error) { + if (error.code === 'ENOENT') { + return false; + } + + throw error; + } } -var reusify_1 = reusify; +var isFile = isType.bind(null, 'stat', 'isFile'); +var isDirectory = isType.bind(null, 'stat', 'isDirectory'); +var isSymlink = isType.bind(null, 'lstat', 'isSymbolicLink'); +var isFileSync = isTypeSync.bind(null, 'statSync', 'isFile'); +var isDirectorySync = isTypeSync.bind(null, 'statSync', 'isDirectory'); +var isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink'); +var pathType = { + isFile: isFile, + isDirectory: isDirectory, + isSymlink: isSymlink, + isFileSync: isFileSync, + isDirectorySync: isDirectorySync, + isSymlinkSync: isSymlinkSync +}; -function fastqueue(context, worker, concurrency) { - if (typeof context === 'function') { - concurrency = worker; - worker = context; - context = null; +const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; + +const getPath = (filepath, cwd) => { + const pth = filepath[0] === '!' ? filepath.slice(1) : filepath; + return path__default['default'].isAbsolute(pth) ? pth : path__default['default'].join(cwd, pth); +}; + +const addExtensions = (file, extensions) => { + if (path__default['default'].extname(file)) { + return `**/${file}`; } - var cache = reusify_1(Task); - var queueHead = null; - var queueTail = null; - var _running = 0; - var self = { - push: push, - drain: noop$1, - saturated: noop$1, - pause: pause, - paused: false, - concurrency: concurrency, - running: running, - resume: resume, - idle: idle, - length: length, - unshift: unshift, - empty: noop$1, - kill: kill, - killAndDrain: killAndDrain - }; - return self; + return `**/${file}.${getExtensions(extensions)}`; +}; - function running() { - return _running; +const getGlob = (directory, options) => { + if (options.files && !Array.isArray(options.files)) { + throw new TypeError(`Expected \`files\` to be of type \`Array\` but received type \`${typeof options.files}\``); } - function pause() { - self.paused = true; + if (options.extensions && !Array.isArray(options.extensions)) { + throw new TypeError(`Expected \`extensions\` to be of type \`Array\` but received type \`${typeof options.extensions}\``); } - function length() { - var current = queueHead; - var counter = 0; + if (options.files && options.extensions) { + return options.files.map(x => path__default['default'].posix.join(directory, addExtensions(x, options.extensions))); + } - while (current) { - current = current.next; - counter++; - } + if (options.files) { + return options.files.map(x => path__default['default'].posix.join(directory, `**/${x}`)); + } - return counter; + if (options.extensions) { + return [path__default['default'].posix.join(directory, `**/*.${getExtensions(options.extensions)}`)]; } - function resume() { - if (!self.paused) return; - self.paused = false; + return [path__default['default'].posix.join(directory, '**')]; +}; - for (var i = 0; i < self.concurrency; i++) { - _running++; - release(); - } - } +var dirGlob = async (input, options) => { + options = Object.assign({ + cwd: process.cwd() + }, options); - function idle() { - return _running === 0 && self.length() === 0; + if (typeof options.cwd !== 'string') { + throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); } - function push(value, done) { - var current = cache.get(); - current.context = context; - current.release = release; - current.value = value; - current.callback = done || noop$1; + const globs = await Promise.all([].concat(input).map(async x => { + const isDirectory = await pathType.isDirectory(getPath(x, options.cwd)); + return isDirectory ? getGlob(x, options) : x; + })); + return [].concat.apply([], globs); // eslint-disable-line prefer-spread +}; - if (_running === self.concurrency || self.paused) { - if (queueTail) { - queueTail.next = current; - queueTail = current; - } else { - queueHead = current; - queueTail = current; - self.saturated(); - } - } else { - _running++; - worker.call(context, current.value, current.worked); - } +var sync$7 = (input, options) => { + options = Object.assign({ + cwd: process.cwd() + }, options); + + if (typeof options.cwd !== 'string') { + throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); } - function unshift(value, done) { - var current = cache.get(); - current.context = context; - current.release = release; - current.value = value; - current.callback = done || noop$1; + const globs = [].concat(input).map(x => pathType.isDirectorySync(getPath(x, options.cwd)) ? getGlob(x, options) : x); + return [].concat.apply([], globs); // eslint-disable-line prefer-spread +}; +dirGlob.sync = sync$7; - if (_running === self.concurrency || self.paused) { - if (queueHead) { - current.next = queueHead; - queueHead = current; - } else { - queueHead = current; - queueTail = current; - self.saturated(); - } - } else { - _running++; - worker.call(context, current.value, current.worked); - } - } +// A simple implementation of make-array +function makeArray(subject) { + return Array.isArray(subject) ? subject : [subject]; +} - function release(holder) { - if (holder) { - cache.release(holder); - } +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, +// . +// .. - var next = queueHead; +const REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/; +const SLASH$1 = '/'; +const KEY_IGNORE$1 = typeof Symbol !== 'undefined' ? Symbol.for('node-ignore') +/* istanbul ignore next */ +: 'node-ignore'; - if (next) { - if (!self.paused) { - if (queueTail === queueHead) { - queueTail = null; - } +const define$1 = (object, key, value) => Object.defineProperty(object, key, { + value +}); - queueHead = next.next; - next.next = null; - worker.call(context, next.value, next.worked); +const REGEX_REGEXP_RANGE$1 = /([0-z])-([0-z])/g; // Sanitize the range of a regular expression +// The cases are complicated, see test cases for details - if (queueTail === null) { - self.empty(); - } - } else { - _running--; - } - } else if (--_running === 0) { - self.drain(); - } - } +const sanitizeRange$1 = range => range.replace(REGEX_REGEXP_RANGE$1, (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 - function kill() { - queueHead = null; - queueTail = null; - self.drain = noop$1; - } - function killAndDrain() { - queueHead = null; - queueTail = null; - self.drain(); - self.drain = noop$1; +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$1(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$1 = 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; } + } -function noop$1() {} +const createRule$1 = (pattern, ignorecase) => { + const origin = pattern; + let negative = false; // > An optional prefix "!" which negates the pattern; -function Task() { - this.value = null; - this.callback = noop$1; - this.next = null; - this.release = noop$1; - this.context = null; - var self = this; + 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); +}; - this.worked = function worked(err, result) { - var callback = self.callback; - self.value = null; - self.callback = noop$1; - callback.call(self.context, err, result); - self.release(self); - }; -} +const throwError = (message, Ctor) => { + throw new Ctor(message); +}; -var queue = fastqueue; +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 -var common$2 = createCommonjsModule(function (module, exports) { - Object.defineProperty(exports, "__esModule", { - value: true - }); + if (!path) { + return doThrow(`path must not be empty`, TypeError); + } // Check if it is a relative path - function isFatalError(settings, error) { - if (settings.errorFilter === null) { - return true; - } - return !settings.errorFilter(error); + if (checkPath.isNotRelative(path)) { + const r = '`path.relative()`d'; + return doThrow(`path should be a ${r} string, but got "${originalPath}"`, RangeError); } - exports.isFatalError = isFatalError; + return true; +}; - function isAppliedFilter(filter, value) { - return filter === null || filter(value); - } +const isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path); - exports.isAppliedFilter = isAppliedFilter; +checkPath.isNotRelative = isNotRelative; - function replacePathSegmentSeparator(filepath, separator) { - return filepath.split(/[\\/]/).join(separator); +checkPath.convert = p => p; + +class Ignore { + constructor({ + ignorecase = true + } = {}) { + this._rules = []; + this._ignorecase = ignorecase; + define$1(this, KEY_IGNORE$1, true); + + this._initCache(); } - exports.replacePathSegmentSeparator = replacePathSegmentSeparator; + _initCache() { + this._ignoreCache = Object.create(null); + this._testCache = Object.create(null); + } - function joinPathSegments(a, b, separator) { - if (a === '') { - return b; + _addPattern(pattern) { + // #32 + if (pattern && pattern[KEY_IGNORE$1]) { + this._rules = this._rules.concat(pattern._rules); + this._added = true; + return; } - return a + separator + b; - } + if (checkPattern$1(pattern)) { + const rule = createRule$1(pattern, this._ignorecase); + this._added = true; - exports.joinPathSegments = joinPathSegments; -}); -unwrapExports(common$2); -var common_1$2 = common$2.isFatalError; -var common_2 = common$2.isAppliedFilter; -var common_3 = common$2.replacePathSegmentSeparator; -var common_4 = common$2.joinPathSegments; + this._rules.push(rule); + } + } // @param {Array | string | Ignore} pattern -var reader = createCommonjsModule(function (module, exports) { - Object.defineProperty(exports, "__esModule", { - value: true - }); + 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. - class Reader { - constructor(_root, _settings) { - this._root = _root; - this._settings = _settings; - this._root = common$2.replacePathSegmentSeparator(_root, _settings.pathSegmentSeparator); + if (this._added) { + this._initCache(); } - } + return this; + } // legacy - exports.default = Reader; -}); -unwrapExports(reader); -var async$3 = createCommonjsModule(function (module, exports) { + 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 - Object.defineProperty(exports, "__esModule", { - value: true - }); - class AsyncReader extends reader.default { - constructor(_root, _settings) { - super(_root, _settings); - this._settings = _settings; - this._scandir = out$1.scandir; - this._emitter = new events$1.EventEmitter(); - this._queue = queue(this._worker.bind(this), this._settings.concurrency); - this._isFatalError = false; - this._isDestroyed = false; + _testOne(path, checkUnignored) { + let ignored = false; + let unignored = false; - this._queue.drain = () => { - if (!this._isFatalError) { - this._emitter.emit('end'); - } - }; - } + this._rules.forEach(rule => { + const { + negative + } = rule; - read() { - this._isFatalError = false; - this._isDestroyed = false; - setImmediate(() => { - this._pushToQueue(this._root, this._settings.basePath); - }); - return this._emitter; - } + if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) { + return; + } - destroy() { - if (this._isDestroyed) { - throw new Error('The reader is already destroyed'); + const matched = rule.regex.test(path); + + if (matched) { + ignored = !negative; + unignored = negative; } + }); - this._isDestroyed = true; + return { + ignored, + unignored + }; + } // @returns {TestResult} - this._queue.killAndDrain(); - } - onEntry(callback) { - this._emitter.on('entry', callback); - } + _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); + } - onError(callback) { - this._emitter.once('error', callback); + _t(path, cache, checkUnignored, slices) { + if (path in cache) { + return cache[path]; } - onEnd(callback) { - this._emitter.once('end', callback); + if (!slices) { + // path/to/a.js + // ['path', 'to', 'a.js'] + slices = path.split(SLASH$1); } - _pushToQueue(directory, base) { - const queueItem = { - directory, - base - }; + slices.pop(); // If the path has no parent directory, just test it - this._queue.push(queueItem, error => { - if (error !== null) { - this._handleError(error); - } - }); + if (!slices.length) { + return cache[path] = this._testOne(path, checkUnignored); } - _worker(item, done) { - this._scandir(item.directory, this._settings.fsScandirSettings, (error, entries) => { - if (error !== null) { - return done(error, undefined); - } - - for (const entry of entries) { - this._handleEntry(entry, item.base); - } + const parent = this._t(slices.join(SLASH$1) + SLASH$1, cache, checkUnignored, slices); // If the path contains a parent directory, check the parent first - done(null, undefined); - }); - } - _handleError(error) { - if (!common$2.isFatalError(this._settings, error)) { - return; - } + 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); + } - this._isFatalError = true; - this._isDestroyed = true; + ignores(path) { + return this._test(path, this._ignoreCache, false).ignored; + } - this._emitter.emit('error', error); - } + createFilter() { + return path => !this.ignores(path); + } - _handleEntry(entry, base) { - if (this._isDestroyed || this._isFatalError) { - return; - } + filter(paths) { + return makeArray(paths).filter(this.createFilter()); + } // @returns {TestResult} - const fullpath = entry.path; - if (base !== undefined) { - entry.path = common$2.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); - } + test(path) { + return this._test(path, this._testCache, true); + } - if (common$2.isAppliedFilter(this._settings.entryFilter, entry)) { - this._emitEntry(entry); - } +} - if (entry.dirent.isDirectory() && common$2.isAppliedFilter(this._settings.deepFilter, entry)) { - this._pushToQueue(fullpath, entry.path); - } - } +const factory = options => new Ignore(options); - _emitEntry(entry) { - this._emitter.emit('entry', entry); - } +const returnFalse = () => false; - } +const isPathValid = path => checkPath(path && checkPath.convert(path), path, returnFalse); - exports.default = AsyncReader; -}); -unwrapExports(async$3); +factory.isPathValid = isPathValid; // Fixes typescript -var async$4 = createCommonjsModule(function (module, exports) { +factory.default = factory; +var ignore$1 = factory; // Windows +// -------------------------------------------------------------- - Object.defineProperty(exports, "__esModule", { - value: true - }); +/* istanbul ignore if */ - class AsyncProvider { - constructor(_root, _settings) { - this._root = _root; - this._settings = _settings; - this._reader = new async$3.default(this._root, this._settings); - this._storage = new Set(); - } +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, '/'); - read(callback) { - this._reader.onError(error => { - callFailureCallback(callback, error); - }); + checkPath.convert = makePosix; // 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/' + // 'd:\\foo' - this._reader.onEntry(entry => { - this._storage.add(entry); - }); + const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i; - this._reader.onEnd(() => { - callSuccessCallback(callback, [...this._storage]); - }); + checkPath.isNotRelative = path => REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path) || isNotRelative(path); +} - this._reader.read(); - } +var slash$1 = path => { + const isExtendedLengthPath = /^\\\\\?\\/.test(path); + const hasNonAscii = /[^\u0000-\u0080]+/.test(path); // eslint-disable-line no-control-regex + if (isExtendedLengthPath || hasNonAscii) { + return path; } - exports.default = AsyncProvider; + return path.replace(/\\/g, '/'); +}; - function callFailureCallback(callback, error) { - callback(error); - } +const { + promisify: promisify$1 +} = util__default['default']; +const DEFAULT_IGNORE = ['**/node_modules/**', '**/flow-typed/**', '**/coverage/**', '**/.git']; +const readFileP = promisify$1(fs__default['default'].readFile); - function callSuccessCallback(callback, entries) { - callback(null, entries); +const mapGitIgnorePatternTo = base => ignore => { + if (ignore.startsWith('!')) { + return '!' + path__default['default'].posix.join(base, ignore.slice(1)); } -}); -unwrapExports(async$4); -var stream$2 = createCommonjsModule(function (module, exports) { + return path__default['default'].posix.join(base, ignore); +}; - Object.defineProperty(exports, "__esModule", { - value: true - }); +const parseGitIgnore = (content, options) => { + const base = slash$1(path__default['default'].relative(options.cwd, path__default['default'].dirname(options.fileName))); + return content.split(/\r?\n/).filter(Boolean).filter(line => !line.startsWith('#')).map(mapGitIgnorePatternTo(base)); +}; - class StreamProvider { - constructor(_root, _settings) { - this._root = _root; - this._settings = _settings; - this._reader = new async$3.default(this._root, this._settings); - this._stream = new stream$6.Readable({ - objectMode: true, - read: () => {}, - destroy: this._reader.destroy.bind(this._reader) - }); - } +const reduceIgnore = files => { + return files.reduce((ignores, file) => { + ignores.add(parseGitIgnore(file.content, { + cwd: file.cwd, + fileName: file.filePath + })); + return ignores; + }, ignore$1()); +}; - read() { - this._reader.onError(error => { - this._stream.emit('error', error); - }); +const ensureAbsolutePathForCwd = (cwd, p) => { + cwd = slash$1(cwd); - this._reader.onEntry(entry => { - this._stream.push(entry); - }); + if (path__default['default'].isAbsolute(p)) { + if (p.startsWith(cwd)) { + return p; + } - this._reader.onEnd(() => { - this._stream.push(null); - }); + throw new Error(`Path ${p} is not in cwd ${cwd}`); + } - this._reader.read(); + return path__default['default'].join(cwd, p); +}; - return this._stream; - } +const getIsIgnoredPredecate = (ignores, cwd) => { + return p => ignores.ignores(slash$1(path__default['default'].relative(cwd, ensureAbsolutePathForCwd(cwd, p)))); +}; - } +const getFile = async (file, cwd) => { + const filePath = path__default['default'].join(cwd, file); + const content = await readFileP(filePath, 'utf8'); + return { + cwd, + filePath, + content + }; +}; - exports.default = StreamProvider; -}); -unwrapExports(stream$2); +const getFileSync = (file, cwd) => { + const filePath = path__default['default'].join(cwd, file); + const content = fs__default['default'].readFileSync(filePath, 'utf8'); + return { + cwd, + filePath, + content + }; +}; -var sync$3 = createCommonjsModule(function (module, exports) { +const normalizeOptions$3 = ({ + ignore = [], + cwd = slash$1(process.cwd()) +} = {}) => { + return { + ignore, + cwd + }; +}; - Object.defineProperty(exports, "__esModule", { - value: true +var gitignore = async options => { + options = normalizeOptions$3(options); + const paths = await out$3('**/.gitignore', { + ignore: DEFAULT_IGNORE.concat(options.ignore), + cwd: options.cwd }); + const files = await Promise.all(paths.map(file => getFile(file, options.cwd))); + const ignores = reduceIgnore(files); + return getIsIgnoredPredecate(ignores, options.cwd); +}; - class SyncReader extends reader.default { - constructor() { - super(...arguments); - this._scandir = out$1.scandirSync; - this._storage = new Set(); - this._queue = new Set(); - } +var sync$8 = options => { + options = normalizeOptions$3(options); + const paths = out$3.sync('**/.gitignore', { + ignore: DEFAULT_IGNORE.concat(options.ignore), + cwd: options.cwd + }); + const files = paths.map(file => getFileSync(file, options.cwd)); + const ignores = reduceIgnore(files); + return getIsIgnoredPredecate(ignores, options.cwd); +}; +gitignore.sync = sync$8; - read() { - this._pushToQueue(this._root, this._settings.basePath); +const { + Transform +} = stream_1__default['default']; - this._handleQueue(); +class ObjectTransform extends Transform { + constructor() { + super({ + objectMode: true + }); + } - return [...this._storage]; - } +} - _pushToQueue(directory, base) { - this._queue.add({ - directory, - base - }); - } +class FilterStream extends ObjectTransform { + constructor(filter) { + super(); + this._filter = filter; + } - _handleQueue() { - for (const item of this._queue.values()) { - this._handleDirectory(item.directory, item.base); - } + _transform(data, encoding, callback) { + if (this._filter(data)) { + this.push(data); } - _handleDirectory(directory, base) { - try { - const entries = this._scandir(directory, this._settings.fsScandirSettings); + callback(); + } - for (const entry of entries) { - this._handleEntry(entry, base); - } - } catch (error) { - this._handleError(error); - } - } +} - _handleError(error) { - if (!common$2.isFatalError(this._settings, error)) { - return; - } +class UniqueStream extends ObjectTransform { + constructor() { + super(); + this._pushed = new Set(); + } - throw error; + _transform(data, encoding, callback) { + if (!this._pushed.has(data)) { + this.push(data); + + this._pushed.add(data); } - _handleEntry(entry, base) { - const fullpath = entry.path; + callback(); + } - if (base !== undefined) { - entry.path = common$2.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); - } +} - if (common$2.isAppliedFilter(this._settings.entryFilter, entry)) { - this._pushToStorage(entry); - } +var streamUtils = { + FilterStream, + UniqueStream +}; - if (entry.dirent.isDirectory() && common$2.isAppliedFilter(this._settings.deepFilter, entry)) { - this._pushToQueue(fullpath, entry.path); - } - } +const { + FilterStream: FilterStream$1, + UniqueStream: UniqueStream$1 +} = streamUtils; + +const DEFAULT_FILTER = () => false; + +const isNegative = pattern => pattern[0] === '!'; - _pushToStorage(entry) { - this._storage.add(entry); - } +const assertPatternsInput$1 = patterns => { + if (!patterns.every(pattern => typeof pattern === 'string')) { + throw new TypeError('Patterns must be a string or an array of strings'); + } +}; +const checkCwdOption = (options = {}) => { + if (!options.cwd) { + return; } - exports.default = SyncReader; -}); -unwrapExports(sync$3); + let stat; -var sync$4 = createCommonjsModule(function (module, exports) { + try { + stat = fs__default['default'].statSync(options.cwd); + } catch (_) { + return; + } - Object.defineProperty(exports, "__esModule", { - value: true - }); + if (!stat.isDirectory()) { + throw new Error('The `cwd` option must be a path to a directory'); + } +}; - class SyncProvider { - constructor(_root, _settings) { - this._root = _root; - this._settings = _settings; - this._reader = new sync$3.default(this._root, this._settings); - } +const getPathString = p => p.stats instanceof fs__default['default'].Stats ? p.path : p; - read() { - return this._reader.read(); +const generateGlobTasks = (patterns, taskOptions) => { + patterns = arrayUnion([].concat(patterns)); + assertPatternsInput$1(patterns); + checkCwdOption(taskOptions); + const globTasks = []; + taskOptions = Object.assign({ + ignore: [], + expandDirectories: true + }, taskOptions); + + for (const [index, pattern] of patterns.entries()) { + if (isNegative(pattern)) { + continue; } + const ignore = patterns.slice(index).filter(isNegative).map(pattern => pattern.slice(1)); + const options = Object.assign({}, taskOptions, { + ignore: taskOptions.ignore.concat(ignore) + }); + globTasks.push({ + pattern, + options + }); } - exports.default = SyncProvider; -}); -unwrapExports(sync$4); - -var settings$2 = createCommonjsModule(function (module, exports) { - - Object.defineProperty(exports, "__esModule", { - value: true - }); + return globTasks; +}; - class Settings { - constructor(_options = {}) { - this._options = _options; - this.basePath = this._getValue(this._options.basePath, undefined); - this.concurrency = this._getValue(this._options.concurrency, Infinity); - this.deepFilter = this._getValue(this._options.deepFilter, null); - this.entryFilter = this._getValue(this._options.entryFilter, null); - this.errorFilter = this._getValue(this._options.errorFilter, null); - this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path$2.sep); - this.fsScandirSettings = new out$1.Settings({ - followSymbolicLinks: this._options.followSymbolicLinks, - fs: this._options.fs, - pathSegmentSeparator: this._options.pathSegmentSeparator, - stats: this._options.stats, - throwErrorOnBrokenSymbolicLink: this._options.throwErrorOnBrokenSymbolicLink - }); - } +const globDirs = (task, fn) => { + let options = {}; - _getValue(option, value) { - return option === undefined ? value : option; - } + if (task.options.cwd) { + options.cwd = task.options.cwd; + } + if (Array.isArray(task.options.expandDirectories)) { + options = Object.assign({}, options, { + files: task.options.expandDirectories + }); + } else if (typeof task.options.expandDirectories === 'object') { + options = Object.assign({}, options, task.options.expandDirectories); } - exports.default = Settings; -}); -unwrapExports(settings$2); + return fn(task.pattern, options); +}; -var out$2 = createCommonjsModule(function (module, exports) { +const getPattern = (task, fn) => task.options.expandDirectories ? globDirs(task, fn) : [task.pattern]; - Object.defineProperty(exports, "__esModule", { - value: true - }); - exports.Settings = settings$2.default; +const getFilterSync = options => { + return options && options.gitignore ? gitignore.sync({ + cwd: options.cwd, + ignore: options.ignore + }) : DEFAULT_FILTER; +}; - function walk(directory, optionsOrSettingsOrCallback, callback) { - if (typeof optionsOrSettingsOrCallback === 'function') { - return new async$4.default(directory, getSettings()).read(optionsOrSettingsOrCallback); - } +const globToTask = task => glob => { + const { + options + } = task; - new async$4.default(directory, getSettings(optionsOrSettingsOrCallback)).read(callback); + if (options.ignore && Array.isArray(options.ignore) && options.expandDirectories) { + options.ignore = dirGlob.sync(options.ignore); } - exports.walk = walk; + return { + pattern: glob, + options + }; +}; - function walkSync(directory, optionsOrSettings) { - const settings = getSettings(optionsOrSettings); - const provider = new sync$4.default(directory, settings); - return provider.read(); - } +var globby$1 = async (patterns, options) => { + const globTasks = generateGlobTasks(patterns, options); - exports.walkSync = walkSync; + const getFilter = async () => { + return options && options.gitignore ? gitignore({ + cwd: options.cwd, + ignore: options.ignore + }) : DEFAULT_FILTER; + }; - function walkStream(directory, optionsOrSettings) { - const settings = getSettings(optionsOrSettings); - const provider = new stream$2.default(directory, settings); - return provider.read(); - } + const getTasks = async () => { + const tasks = await Promise.all(globTasks.map(async task => { + const globs = await getPattern(task, dirGlob); + return Promise.all(globs.map(globToTask(task))); + })); + return arrayUnion(...tasks); + }; - exports.walkStream = walkStream; + const [filter, tasks] = await Promise.all([getFilter(), getTasks()]); + const paths = await Promise.all(tasks.map(task => out$3(task.pattern, task.options))); + return arrayUnion(...paths).filter(path_ => !filter(getPathString(path_))); +}; - function getSettings(settingsOrOptions = {}) { - if (settingsOrOptions instanceof settings$2.default) { - return settingsOrOptions; - } +var sync$9 = (patterns, options) => { + const globTasks = generateGlobTasks(patterns, options); + const tasks = globTasks.reduce((tasks, task) => { + const newTask = getPattern(task, dirGlob.sync).map(globToTask(task)); + return tasks.concat(newTask); + }, []); + const filter = getFilterSync(options); + return tasks.reduce((matches, task) => arrayUnion(matches, out$3.sync(task.pattern, task.options)), []).filter(path_ => !filter(path_)); +}; - return new settings$2.default(settingsOrOptions); - } -}); -unwrapExports(out$2); -var out_1$2 = out$2.Settings; -var out_2$2 = out$2.walk; -var out_3$2 = out$2.walkSync; -var out_4 = out$2.walkStream; +var stream$6 = (patterns, options) => { + const globTasks = generateGlobTasks(patterns, options); + const tasks = globTasks.reduce((tasks, task) => { + const newTask = getPattern(task, dirGlob.sync).map(globToTask(task)); + return tasks.concat(newTask); + }, []); + const filter = getFilterSync(options); + const filterStream = new FilterStream$1(p => !filter(p)); + const uniqueStream = new UniqueStream$1(); + return merge2_1(tasks.map(task => out$3.stream(task.pattern, task.options))).pipe(filterStream).pipe(uniqueStream); +}; -var reader$1 = createCommonjsModule(function (module, exports) { +var generateGlobTasks_1 = generateGlobTasks; - Object.defineProperty(exports, "__esModule", { - value: true - }); +var hasMagic = (patterns, options) => [].concat(patterns).some(pattern => out$3.isDynamicPattern(pattern, options)); - class Reader { - constructor(_settings) { - this._settings = _settings; - this._fsStatSettings = new out.Settings({ - followSymbolicLink: this._settings.followSymbolicLinks, - fs: this._settings.fs, - throwErrorOnBrokenSymbolicLink: this._settings.followSymbolicLinks - }); - } +var gitignore_1 = gitignore; +globby$1.sync = sync$9; +globby$1.stream = stream$6; +globby$1.generateGlobTasks = generateGlobTasks_1; +globby$1.hasMagic = hasMagic; +globby$1.gitignore = gitignore_1; - _getFullEntryPath(filepath) { - return path$2.resolve(this._settings.cwd, filepath); - } +var createLanguage = function (linguistData, override) { + const { + languageId + } = linguistData, + rest = _objectWithoutPropertiesLoose(linguistData, ["languageId"]); - _makeEntry(stats, pattern) { - const entry = { - name: pattern, - path: pattern, - dirent: utils$4.fs.createDirentFromStats(pattern, stats) - }; + return Object.assign({ + linguistLanguageId: languageId + }, rest, override(linguistData)); +}; - if (this._settings.stats) { - entry.stats = stats; +var ast = createCommonjsModule(function (module) { + /* + Copyright (C) 2013 Yusuke Suzuki + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + (function () { + + function isExpression(node) { + if (node == null) { + return false; } - return entry; - } + switch (node.type) { + case 'ArrayExpression': + case 'AssignmentExpression': + case 'BinaryExpression': + case 'CallExpression': + case 'ConditionalExpression': + case 'FunctionExpression': + case 'Identifier': + case 'Literal': + case 'LogicalExpression': + case 'MemberExpression': + case 'NewExpression': + case 'ObjectExpression': + case 'SequenceExpression': + case 'ThisExpression': + case 'UnaryExpression': + case 'UpdateExpression': + return true; + } - _isFatalError(error) { - return !utils$4.errno.isEnoentCodeError(error) && !this._settings.suppressErrors; + return false; } - } + function isIterationStatement(node) { + if (node == null) { + return false; + } - exports.default = Reader; -}); -unwrapExports(reader$1); + switch (node.type) { + case 'DoWhileStatement': + case 'ForInStatement': + case 'ForStatement': + case 'WhileStatement': + return true; + } -var stream$3 = createCommonjsModule(function (module, exports) { + return false; + } - Object.defineProperty(exports, "__esModule", { - value: true - }); + function isStatement(node) { + if (node == null) { + return false; + } - class ReaderStream extends reader$1.default { - constructor() { - super(...arguments); - this._walkStream = out$2.walkStream; - this._stat = out.stat; - } + switch (node.type) { + case 'BlockStatement': + case 'BreakStatement': + case 'ContinueStatement': + case 'DebuggerStatement': + case 'DoWhileStatement': + case 'EmptyStatement': + case 'ExpressionStatement': + case 'ForInStatement': + case 'ForStatement': + case 'IfStatement': + case 'LabeledStatement': + case 'ReturnStatement': + case 'SwitchStatement': + case 'ThrowStatement': + case 'TryStatement': + case 'VariableDeclaration': + case 'WhileStatement': + case 'WithStatement': + return true; + } - dynamic(root, options) { - return this._walkStream(root, options); + return false; } - static(patterns, options) { - const filepaths = patterns.map(this._getFullEntryPath, this); - const stream = new stream$6.PassThrough({ - objectMode: true - }); - - stream._write = (index, _enc, done) => { - return this._getEntry(filepaths[index], patterns[index], options).then(entry => { - if (entry !== null && options.entryFilter(entry)) { - stream.push(entry); - } + function isSourceElement(node) { + return isStatement(node) || node != null && node.type === 'FunctionDeclaration'; + } - if (index === filepaths.length - 1) { - stream.end(); + function trailingStatement(node) { + switch (node.type) { + case 'IfStatement': + if (node.alternate != null) { + return node.alternate; } - done(); - }).catch(done); - }; + return node.consequent; - for (let i = 0; i < filepaths.length; i++) { - stream.write(i); + case 'LabeledStatement': + case 'ForStatement': + case 'ForInStatement': + case 'WhileStatement': + case 'WithStatement': + return node.body; } - return stream; + return null; } - _getEntry(filepath, pattern, options) { - return this._getStat(filepath).then(stats => this._makeEntry(stats, pattern)).catch(error => { - if (options.errorFilter(error)) { - return null; + function isProblematicIfStatement(node) { + var current; + + if (node.type !== 'IfStatement') { + return false; + } + + if (node.alternate == null) { + return false; + } + + current = node.consequent; + + do { + if (current.type === 'IfStatement') { + if (current.alternate == null) { + return true; + } } - throw error; - }); - } + current = trailingStatement(current); + } while (current); - _getStat(filepath) { - return new Promise((resolve, reject) => { - this._stat(filepath, this._fsStatSettings, (error, stats) => { - return error === null ? resolve(stats) : reject(error); - }); - }); + return false; } - } + module.exports = { + isExpression: isExpression, + isStatement: isStatement, + isIterationStatement: isIterationStatement, + isSourceElement: isSourceElement, + isProblematicIfStatement: isProblematicIfStatement, + trailingStatement: trailingStatement + }; + })(); + /* vim: set sw=4 ts=4 et tw=80 : */ - exports.default = ReaderStream; }); -unwrapExports(stream$3); -var matcher = createCommonjsModule(function (module, exports) { +var code = createCommonjsModule(function (module) { + /* + Copyright (C) 2013-2014 Yusuke Suzuki + Copyright (C) 2014 Ivan Nikulin + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + (function () { - Object.defineProperty(exports, "__esModule", { - value: true - }); + var ES6Regex, ES5Regex, NON_ASCII_WHITESPACES, IDENTIFIER_START, IDENTIFIER_PART, ch; // See `tools/generate-identifier-regex.js`. - class Matcher { - constructor(_patterns, _settings, _micromatchOptions) { - this._patterns = _patterns; - this._settings = _settings; - this._micromatchOptions = _micromatchOptions; - this._storage = []; + ES5Regex = { + // ECMAScript 5.1/Unicode v9.0.0 NonAsciiIdentifierStart: + NonAsciiIdentifierStart: /[\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\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\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-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\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]/, + // ECMAScript 5.1/Unicode v9.0.0 NonAsciiIdentifierPart: + NonAsciiIdentifierPart: /[\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\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\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\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\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\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-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\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\u200C\u200D\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-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\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]/ + }; + ES6Regex = { + // ECMAScript 6/Unicode v9.0.0 NonAsciiIdentifierStart: + NonAsciiIdentifierStart: /[\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\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\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-\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\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-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\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\uDF30-\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\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\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]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00\uDC01]|\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]|\uD87E[\uDC00-\uDE1D]/, + // ECMAScript 6/Unicode v9.0.0 NonAsciiIdentifierPart: + NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\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\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\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\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\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\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\u1369-\u1371\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-\u19DA\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-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\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\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\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-\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\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\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\uDF30-\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\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\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]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00\uDC01]|\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]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/ + }; - this._fillStorage(); + function isDecimalDigit(ch) { + return 0x30 <= ch && ch <= 0x39; // 0..9 } - _fillStorage() { - /** - * The original pattern may include `{,*,**,a/*}`, which will lead to problems with matching (unresolved level). - * So, before expand patterns with brace expansion into separated patterns. - */ - const patterns = utils$4.pattern.expandPatternsWithBraceExpansion(this._patterns); + function isHexDigit(ch) { + return 0x30 <= ch && ch <= 0x39 || // 0..9 + 0x61 <= ch && ch <= 0x66 || // a..f + 0x41 <= ch && ch <= 0x46; // A..F + } - for (const pattern of patterns) { - const segments = this._getPatternSegments(pattern); + function isOctalDigit(ch) { + return ch >= 0x30 && ch <= 0x37; // 0..7 + } // 7.2 White Space - const sections = this._splitSegmentsIntoSections(segments); - this._storage.push({ - complete: sections.length <= 1, - pattern, - segments, - sections - }); - } - } + NON_ASCII_WHITESPACES = [0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF]; - _getPatternSegments(pattern) { - const parts = utils$4.pattern.getPatternParts(pattern, this._micromatchOptions); - return parts.map(part => { - const dynamic = utils$4.pattern.isDynamicPattern(part, this._settings); + function isWhiteSpace(ch) { + return ch === 0x20 || ch === 0x09 || ch === 0x0B || ch === 0x0C || ch === 0xA0 || ch >= 0x1680 && NON_ASCII_WHITESPACES.indexOf(ch) >= 0; + } // 7.3 Line Terminators - if (!dynamic) { - return { - dynamic: false, - pattern: part - }; - } - return { - dynamic: true, - pattern: part, - patternRe: utils$4.pattern.makeRe(part, this._micromatchOptions) - }; - }); + function isLineTerminator(ch) { + return ch === 0x0A || ch === 0x0D || ch === 0x2028 || ch === 0x2029; + } // 7.6 Identifier Names and Identifiers + + + function fromCodePoint(cp) { + if (cp <= 0xFFFF) { + return String.fromCharCode(cp); + } + + var cu1 = String.fromCharCode(Math.floor((cp - 0x10000) / 0x400) + 0xD800); + var cu2 = String.fromCharCode((cp - 0x10000) % 0x400 + 0xDC00); + return cu1 + cu2; } - _splitSegmentsIntoSections(segments) { - return utils$4.array.splitWhen(segments, segment => segment.dynamic && utils$4.pattern.hasGlobStar(segment.pattern)); + IDENTIFIER_START = new Array(0x80); + + for (ch = 0; ch < 0x80; ++ch) { + IDENTIFIER_START[ch] = ch >= 0x61 && ch <= 0x7A || // a..z + ch >= 0x41 && ch <= 0x5A || // A..Z + ch === 0x24 || ch === 0x5F; // $ (dollar) and _ (underscore) } - } + IDENTIFIER_PART = new Array(0x80); - exports.default = Matcher; -}); -unwrapExports(matcher); + for (ch = 0; ch < 0x80; ++ch) { + IDENTIFIER_PART[ch] = ch >= 0x61 && ch <= 0x7A || // a..z + ch >= 0x41 && ch <= 0x5A || // A..Z + ch >= 0x30 && ch <= 0x39 || // 0..9 + ch === 0x24 || ch === 0x5F; // $ (dollar) and _ (underscore) + } -var partial = createCommonjsModule(function (module, exports) { + function isIdentifierStartES5(ch) { + return ch < 0x80 ? IDENTIFIER_START[ch] : ES5Regex.NonAsciiIdentifierStart.test(fromCodePoint(ch)); + } - Object.defineProperty(exports, "__esModule", { - value: true - }); + function isIdentifierPartES5(ch) { + return ch < 0x80 ? IDENTIFIER_PART[ch] : ES5Regex.NonAsciiIdentifierPart.test(fromCodePoint(ch)); + } - class PartialMatcher extends matcher.default { - match(filepath) { - const parts = filepath.split('/'); - const levels = parts.length; + function isIdentifierStartES6(ch) { + return ch < 0x80 ? IDENTIFIER_START[ch] : ES6Regex.NonAsciiIdentifierStart.test(fromCodePoint(ch)); + } - const patterns = this._storage.filter(info => !info.complete || info.segments.length > levels); + function isIdentifierPartES6(ch) { + return ch < 0x80 ? IDENTIFIER_PART[ch] : ES6Regex.NonAsciiIdentifierPart.test(fromCodePoint(ch)); + } - for (const pattern of patterns) { - const section = pattern.sections[0]; - /** - * In this case, the pattern has a globstar and we must read all directories unconditionally, - * but only if the level has reached the end of the first group. - * - * fixtures/{a,b}/** - * ^ true/false ^ always true - */ + module.exports = { + isDecimalDigit: isDecimalDigit, + isHexDigit: isHexDigit, + isOctalDigit: isOctalDigit, + isWhiteSpace: isWhiteSpace, + isLineTerminator: isLineTerminator, + isIdentifierStartES5: isIdentifierStartES5, + isIdentifierPartES5: isIdentifierPartES5, + isIdentifierStartES6: isIdentifierStartES6, + isIdentifierPartES6: isIdentifierPartES6 + }; + })(); + /* vim: set sw=4 ts=4 et tw=80 : */ - if (!pattern.complete && levels > section.length) { - return true; - } +}); - const match = parts.every((part, index) => { - const segment = pattern.segments[index]; +var keyword$1 = createCommonjsModule(function (module) { + /* + Copyright (C) 2013 Yusuke Suzuki + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + (function () { - if (segment.dynamic && segment.patternRe.test(part)) { - return true; - } + var code$1 = code; - if (!segment.dynamic && segment.pattern === part) { - return true; - } + function isStrictModeReservedWordES6(id) { + switch (id) { + case 'implements': + case 'interface': + case 'package': + case 'private': + case 'protected': + case 'public': + case 'static': + case 'let': + return true; + default: return false; - }); + } + } - if (match) { - return true; - } + function isKeywordES5(id, strict) { + // yield should not be treated as keyword under non-strict mode. + if (!strict && id === 'yield') { + return false; } - return false; + return isKeywordES6(id, strict); } - } + function isKeywordES6(id, strict) { + if (strict && isStrictModeReservedWordES6(id)) { + return true; + } - exports.default = PartialMatcher; -}); -unwrapExports(partial); + switch (id.length) { + case 2: + return id === 'if' || id === 'in' || id === 'do'; -var deep = createCommonjsModule(function (module, exports) { + case 3: + return id === 'var' || id === 'for' || id === 'new' || id === 'try'; - Object.defineProperty(exports, "__esModule", { - value: true - }); + case 4: + return id === 'this' || id === 'else' || id === 'case' || id === 'void' || id === 'with' || id === 'enum'; - class DeepFilter { - constructor(_settings, _micromatchOptions) { - this._settings = _settings; - this._micromatchOptions = _micromatchOptions; - } + case 5: + return id === 'while' || id === 'break' || id === 'catch' || id === 'throw' || id === 'const' || id === 'yield' || id === 'class' || id === 'super'; - getFilter(basePath, positive, negative) { - const matcher = this._getMatcher(positive); + case 6: + return id === 'return' || id === 'typeof' || id === 'delete' || id === 'switch' || id === 'export' || id === 'import'; - const negativeRe = this._getNegativePatternsRe(negative); + case 7: + return id === 'default' || id === 'finally' || id === 'extends'; - return entry => this._filter(basePath, entry, matcher, negativeRe); + case 8: + return id === 'function' || id === 'continue' || id === 'debugger'; + + case 10: + return id === 'instanceof'; + + default: + return false; + } } - _getMatcher(patterns) { - return new partial.default(patterns, this._settings, this._micromatchOptions); + function isReservedWordES5(id, strict) { + return id === 'null' || id === 'true' || id === 'false' || isKeywordES5(id, strict); } - _getNegativePatternsRe(patterns) { - const affectDepthOfReadingPatterns = patterns.filter(utils$4.pattern.isAffectDepthOfReadingPattern); - return utils$4.pattern.convertPatternsToRe(affectDepthOfReadingPatterns, this._micromatchOptions); + function isReservedWordES6(id, strict) { + return id === 'null' || id === 'true' || id === 'false' || isKeywordES6(id, strict); } - _filter(basePath, entry, matcher, negativeRe) { - const depth = this._getEntryLevel(basePath, entry.path); + function isRestrictedWord(id) { + return id === 'eval' || id === 'arguments'; + } - if (this._isSkippedByDeep(depth)) { - return false; - } + function isIdentifierNameES5(id) { + var i, iz, ch; - if (this._isSkippedSymbolicLink(entry)) { + if (id.length === 0) { return false; } - const filepath = utils$4.path.removeLeadingDotSegment(entry.path); + ch = id.charCodeAt(0); - if (this._isSkippedByPositivePatterns(filepath, matcher)) { + if (!code$1.isIdentifierStartES5(ch)) { return false; } - return this._isSkippedByNegativePatterns(filepath, negativeRe); - } + for (i = 1, iz = id.length; i < iz; ++i) { + ch = id.charCodeAt(i); - _isSkippedByDeep(entryDepth) { - return entryDepth >= this._settings.deep; - } + if (!code$1.isIdentifierPartES5(ch)) { + return false; + } + } - _isSkippedSymbolicLink(entry) { - return !this._settings.followSymbolicLinks && entry.dirent.isSymbolicLink(); + return true; } - _getEntryLevel(basePath, entryPath) { - const basePathDepth = basePath.split('/').length; - const entryPathDepth = entryPath.split('/').length; - return entryPathDepth - (basePath === '' ? 0 : basePathDepth); + function decodeUtf16(lead, trail) { + return (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000; } - _isSkippedByPositivePatterns(entryPath, matcher) { - return !this._settings.baseNameMatch && !matcher.match(entryPath); - } + function isIdentifierNameES6(id) { + var i, iz, ch, lowCh, check; - _isSkippedByNegativePatterns(entryPath, negativeRe) { - return !utils$4.pattern.matchAny(entryPath, negativeRe); - } + if (id.length === 0) { + return false; + } - } + check = code$1.isIdentifierStartES6; - exports.default = DeepFilter; -}); -unwrapExports(deep); + for (i = 0, iz = id.length; i < iz; ++i) { + ch = id.charCodeAt(i); -var entry = createCommonjsModule(function (module, exports) { + if (0xD800 <= ch && ch <= 0xDBFF) { + ++i; - Object.defineProperty(exports, "__esModule", { - value: true - }); + if (i >= iz) { + return false; + } - class EntryFilter { - constructor(_settings, _micromatchOptions) { - this._settings = _settings; - this._micromatchOptions = _micromatchOptions; - this.index = new Map(); - } + lowCh = id.charCodeAt(i); - getFilter(positive, negative) { - const positiveRe = utils$4.pattern.convertPatternsToRe(positive, this._micromatchOptions); - const negativeRe = utils$4.pattern.convertPatternsToRe(negative, this._micromatchOptions); - return entry => this._filter(entry, positiveRe, negativeRe); - } + if (!(0xDC00 <= lowCh && lowCh <= 0xDFFF)) { + return false; + } - _filter(entry, positiveRe, negativeRe) { - if (this._settings.unique) { - if (this._isDuplicateEntry(entry)) { - return false; + ch = decodeUtf16(ch, lowCh); } - this._createIndexRecord(entry); - } - - if (this._onlyFileFilter(entry) || this._onlyDirectoryFilter(entry)) { - return false; - } + if (!check(ch)) { + return false; + } - if (this._isSkippedByAbsoluteNegativePatterns(entry, negativeRe)) { - return false; + check = code$1.isIdentifierPartES6; } - const filepath = this._settings.baseNameMatch ? entry.name : entry.path; - return this._isMatchToPatterns(filepath, positiveRe) && !this._isMatchToPatterns(entry.path, negativeRe); + return true; } - _isDuplicateEntry(entry) { - return this.index.has(entry.path); + function isIdentifierES5(id, strict) { + return isIdentifierNameES5(id) && !isReservedWordES5(id, strict); } - _createIndexRecord(entry) { - this.index.set(entry.path, undefined); + function isIdentifierES6(id, strict) { + return isIdentifierNameES6(id) && !isReservedWordES6(id, strict); } - _onlyFileFilter(entry) { - return this._settings.onlyFiles && !entry.dirent.isFile(); - } + module.exports = { + isKeywordES5: isKeywordES5, + isKeywordES6: isKeywordES6, + isReservedWordES5: isReservedWordES5, + isReservedWordES6: isReservedWordES6, + isRestrictedWord: isRestrictedWord, + isIdentifierNameES5: isIdentifierNameES5, + isIdentifierNameES6: isIdentifierNameES6, + isIdentifierES5: isIdentifierES5, + isIdentifierES6: isIdentifierES6 + }; + })(); + /* vim: set sw=4 ts=4 et tw=80 : */ - _onlyDirectoryFilter(entry) { - return this._settings.onlyDirectories && !entry.dirent.isDirectory(); - } +}); - _isSkippedByAbsoluteNegativePatterns(entry, negativeRe) { - if (!this._settings.absolute) { - return false; - } +var utils$5 = createCommonjsModule(function (module, exports) { + /* + Copyright (C) 2013 Yusuke Suzuki + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + (function () { - const fullpath = utils$4.path.makeAbsolute(this._settings.cwd, entry.path); - return this._isMatchToPatterns(fullpath, negativeRe); - } + exports.ast = ast; + exports.code = code; + exports.keyword = keyword$1; + })(); + /* vim: set sw=4 ts=4 et tw=80 : */ - _isMatchToPatterns(entryPath, patternsRe) { - const filepath = utils$4.path.removeLeadingDotSegment(entryPath); - return utils$4.pattern.matchAny(filepath, patternsRe); - } +}); - } +const isIdentifierName = utils$5.keyword.isIdentifierNameES5; +const { + getLast: getLast$1, + hasNewline: hasNewline$3, + hasNewlineInRange: hasNewlineInRange$2, + skipWhitespace: skipWhitespace$2 +} = util; +const { + locStart: locStart$2, + locEnd: locEnd$2, + hasSameLocStart: hasSameLocStart$1 +} = loc; +/** + * @typedef {import("./types/estree").Node} Node + * @typedef {import("./types/estree").TemplateLiteral} TemplateLiteral + * @typedef {import("./types/estree").Comment} Comment + * @typedef {import("./types/estree").MemberExpression} MemberExpression + * @typedef {import("./types/estree").OptionalMemberExpression} OptionalMemberExpression + * @typedef {import("./types/estree").CallExpression} CallExpression + * @typedef {import("./types/estree").OptionalCallExpression} OptionalCallExpression + * @typedef {import("./types/estree").Expression} Expression + * @typedef {import("./types/estree").Property} Property + * @typedef {import("./types/estree").ObjectTypeProperty} ObjectTypeProperty + * @typedef {import("./types/estree").JSXElement} JSXElement + * @typedef {import("./types/estree").TaggedTemplateExpression} TaggedTemplateExpression + * @typedef {import("./types/estree").Literal} Literal + * + * @typedef {import("../common/fast-path")} FastPath + */ +// We match any whitespace except line terminators because +// Flow annotation comments cannot be split across lines. For example: +// +// (this /* +// : any */).foo = 5; +// +// is not picked up by Flow (see https://github.com/facebook/flow/issues/7050), so +// removing the newline would create a type annotation that the user did not intend +// to create. - exports.default = EntryFilter; -}); -unwrapExports(entry); +const NON_LINE_TERMINATING_WHITE_SPACE = "(?:(?=.)\\s)"; +const FLOW_SHORTHAND_ANNOTATION = new RegExp(`^${NON_LINE_TERMINATING_WHITE_SPACE}*:`); +const FLOW_ANNOTATION = new RegExp(`^${NON_LINE_TERMINATING_WHITE_SPACE}*::`); +/** + * @param {Node} node + * @returns {boolean} + */ -var error = createCommonjsModule(function (module, exports) { +function hasFlowShorthandAnnotationComment(node) { + // https://flow.org/en/docs/types/comments/ + // Syntax example: const r = new (window.Request /*: Class */)(""); + return node.extra && node.extra.parenthesized && node.trailingComments && isBlockComment(node.trailingComments[0]) && FLOW_SHORTHAND_ANNOTATION.test(node.trailingComments[0].value); +} +/** + * @param {Comment[]} comments + * @returns {boolean} + */ - Object.defineProperty(exports, "__esModule", { - value: true - }); - class ErrorFilter { - constructor(_settings) { - this._settings = _settings; - } +function hasFlowAnnotationComment(comments) { + return comments && isBlockComment(comments[0]) && FLOW_ANNOTATION.test(comments[0].value); +} +/** + * @param {Node} node + * @param {(Node) => boolean} fn + * @returns {boolean} + */ - getFilter() { - return error => this._isNonFatalError(error); - } - _isNonFatalError(error) { - return utils$4.errno.isEnoentCodeError(error) || this._settings.suppressErrors; - } +function hasNode(node, fn) { + if (!node || typeof node !== "object") { + return false; + } + if (Array.isArray(node)) { + return node.some(value => hasNode(value, fn)); } - exports.default = ErrorFilter; -}); -unwrapExports(error); + const result = fn(node); + return typeof result === "boolean" ? result : Object.keys(node).some(key => hasNode(node[key], fn)); +} +/** + * @param {Node} node + * @returns {boolean} + */ -var entry$1 = createCommonjsModule(function (module, exports) { - Object.defineProperty(exports, "__esModule", { - value: true - }); +function hasNakedLeftSide(node) { + return node.type === "AssignmentExpression" || node.type === "BinaryExpression" || node.type === "LogicalExpression" || node.type === "NGPipeExpression" || node.type === "ConditionalExpression" || node.type === "CallExpression" || node.type === "OptionalCallExpression" || node.type === "MemberExpression" || node.type === "OptionalMemberExpression" || node.type === "SequenceExpression" || node.type === "TaggedTemplateExpression" || node.type === "BindExpression" || node.type === "UpdateExpression" && !node.prefix || node.type === "TSAsExpression" || node.type === "TSNonNullExpression"; +} - class EntryTransformer { - constructor(_settings) { - this._settings = _settings; - } +function getLeftSide(node) { + if (node.expressions) { + return node.expressions[0]; + } - getTransformer() { - return entry => this._transform(entry); - } + return node.left || node.test || node.callee || node.object || node.tag || node.argument || node.expression; +} - _transform(entry) { - let filepath = entry.path; +function getLeftSidePathName(path, node) { + if (node.expressions) { + return ["expressions", 0]; + } - if (this._settings.absolute) { - filepath = utils$4.path.makeAbsolute(this._settings.cwd, filepath); - filepath = utils$4.path.unixify(filepath); - } + if (node.left) { + return ["left"]; + } - if (this._settings.markDirectories && entry.dirent.isDirectory()) { - filepath += '/'; - } + if (node.test) { + return ["test"]; + } - if (!this._settings.objectMode) { - return filepath; - } + if (node.object) { + return ["object"]; + } - return Object.assign(Object.assign({}, entry), { - path: filepath - }); - } + if (node.callee) { + return ["callee"]; + } + if (node.tag) { + return ["tag"]; } - exports.default = EntryTransformer; -}); -unwrapExports(entry$1); + if (node.argument) { + return ["argument"]; + } -var provider = createCommonjsModule(function (module, exports) { + if (node.expression) { + return ["expression"]; + } - Object.defineProperty(exports, "__esModule", { - value: true - }); + throw new Error("Unexpected node has no left side."); +} +/** + * @param {Comment} comment + * @returns {boolean} + */ - class Provider { - constructor(_settings) { - this._settings = _settings; - this.errorFilter = new error.default(this._settings); - this.entryFilter = new entry.default(this._settings, this._getMicromatchOptions()); - this.deepFilter = new deep.default(this._settings, this._getMicromatchOptions()); - this.entryTransformer = new entry$1.default(this._settings); - } - _getRootDirectory(task) { - return path$2.resolve(this._settings.cwd, task.base); - } +function isBlockComment(comment) { + return comment.type === "Block" || comment.type === "CommentBlock" || // `meriyah` + comment.type === "MultiLine"; +} +/** + * @param {Comment} comment + * @returns {boolean} + */ - _getReaderOptions(task) { - const basePath = task.base === '.' ? '' : task.base; - return { - basePath, - pathSegmentSeparator: '/', - concurrency: this._settings.concurrency, - deepFilter: this.deepFilter.getFilter(basePath, task.positive, task.negative), - entryFilter: this.entryFilter.getFilter(task.positive, task.negative), - errorFilter: this.errorFilter.getFilter(), - followSymbolicLinks: this._settings.followSymbolicLinks, - fs: this._settings.fs, - stats: this._settings.stats, - throwErrorOnBrokenSymbolicLink: this._settings.throwErrorOnBrokenSymbolicLink, - transform: this.entryTransformer.getTransformer() - }; - } - _getMicromatchOptions() { - return { - dot: this._settings.dot, - matchBase: this._settings.baseNameMatch, - nobrace: !this._settings.braceExpansion, - nocase: !this._settings.caseSensitiveMatch, - noext: !this._settings.extglob, - noglobstar: !this._settings.globstar, - posix: true, - strictSlashes: false - }; - } +function isLineComment(comment) { + return comment.type === "Line" || comment.type === "CommentLine" || // `meriyah` has `SingleLine`, `HashbangComment`, `HTMLOpen`, and `HTMLClose` + comment.type === "SingleLine" || comment.type === "HashbangComment" || comment.type === "HTMLOpen" || comment.type === "HTMLClose"; +} + +const exportDeclarationTypes = new Set(["ExportDefaultDeclaration", "ExportDefaultSpecifier", "DeclareExportDeclaration", "ExportNamedDeclaration", "ExportAllDeclaration"]); +/** + * @param {Node} node + * @returns {boolean} + */ + +function isExportDeclaration(node) { + return node && exportDeclarationTypes.has(node.type); +} +/** + * @param {FastPath} path + * @returns {Node | null} + */ + + +function getParentExportDeclaration(path) { + const parentNode = path.getParentNode(); + + if (path.getName() === "declaration" && isExportDeclaration(parentNode)) { + return parentNode; + } + + return null; +} +/** + * @param {Node} node + * @returns {boolean} + */ + + +function isLiteral(node) { + return node.type === "BooleanLiteral" || node.type === "DirectiveLiteral" || node.type === "Literal" || node.type === "NullLiteral" || node.type === "NumericLiteral" || node.type === "BigIntLiteral" || node.type === "DecimalLiteral" || node.type === "RegExpLiteral" || node.type === "StringLiteral" || node.type === "TemplateLiteral" || node.type === "TSTypeLiteral" || node.type === "JSXText"; +} +/** + * @param {Node} node + * @returns {boolean} + */ + - } +function isNumericLiteral(node) { + return node.type === "NumericLiteral" || node.type === "Literal" && typeof node.value === "number"; +} +/** + * @param {Node} node + * @returns {boolean} + */ - exports.default = Provider; -}); -unwrapExports(provider); -var async$5 = createCommonjsModule(function (module, exports) { +function isStringLiteral(node) { + return node.type === "StringLiteral" || node.type === "Literal" && typeof node.value === "string"; +} +/** + * @param {Node} node + * @returns {boolean} + */ - Object.defineProperty(exports, "__esModule", { - value: true - }); - class ProviderAsync extends provider.default { - constructor() { - super(...arguments); - this._reader = new stream$3.default(this._settings); - } +function isObjectType(node) { + return node.type === "ObjectTypeAnnotation" || node.type === "TSTypeLiteral"; +} +/** + * @param {Node} node + * @returns {boolean} + */ - read(task) { - const root = this._getRootDirectory(task); - const options = this._getReaderOptions(task); +function isFunctionOrArrowExpression(node) { + return node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression"; +} +/** + * @param {Node} node + * @returns {boolean} + */ - const entries = []; - return new Promise((resolve, reject) => { - const stream = this.api(root, task, options); - stream.once('error', reject); - stream.on('data', entry => entries.push(options.transform(entry))); - stream.once('end', () => resolve(entries)); - }); - } - api(root, task, options) { - if (task.dynamic) { - return this._reader.dynamic(root, options); - } +function isFunctionOrArrowExpressionWithBody(node) { + return node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression" && node.body.type === "BlockStatement"; +} +/** + * @param {Node} node + * @returns {boolean} + */ - return this._reader.static(task.patterns, options); - } - } +function isTemplateLiteral(node) { + return node.type === "TemplateLiteral"; +} +/** + * Note: `inject` is used in AngularJS 1.x, `async` in Angular 2+ + * example: https://docs.angularjs.org/guide/unit-testing#using-beforeall- + * + * @param {Node} node + * @returns {boolean} + */ - exports.default = ProviderAsync; -}); -unwrapExports(async$5); -var stream$4 = createCommonjsModule(function (module, exports) { +function isAngularTestWrapper(node) { + return (node.type === "CallExpression" || node.type === "OptionalCallExpression") && node.callee.type === "Identifier" && (node.callee.name === "async" || node.callee.name === "inject" || node.callee.name === "fakeAsync"); +} +/** + * @param {Node} node + * @returns {boolean} + */ - Object.defineProperty(exports, "__esModule", { - value: true - }); - class ProviderStream extends provider.default { - constructor() { - super(...arguments); - this._reader = new stream$3.default(this._settings); - } +function isJSXNode(node) { + return node.type === "JSXElement" || node.type === "JSXFragment"; +} - read(task) { - const root = this._getRootDirectory(task); +function isTheOnlyJSXElementInMarkdown(options, path) { + if (options.parentParser !== "markdown" && options.parentParser !== "mdx") { + return false; + } - const options = this._getReaderOptions(task); + const node = path.getNode(); - const source = this.api(root, task, options); - const destination = new stream$6.Readable({ - objectMode: true, - read: () => {} - }); - source.once('error', error => destination.emit('error', error)).on('data', entry => destination.emit('data', options.transform(entry))).once('end', () => destination.emit('end')); - destination.once('close', () => source.destroy()); - return destination; - } + if (!node.expression || !isJSXNode(node.expression)) { + return false; + } - api(root, task, options) { - if (task.dynamic) { - return this._reader.dynamic(root, options); - } + const parent = path.getParentNode(); + return parent.type === "Program" && parent.body.length === 1; +} // Detect an expression node representing `{" "}` + + +function isJSXWhitespaceExpression(node) { + return node.type === "JSXExpressionContainer" && isLiteral(node.expression) && node.expression.value === " " && !node.expression.comments; +} +/** + * @param {Node} node + * @returns {boolean} + */ - return this._reader.static(task.patterns, options); - } +function isMemberExpressionChain(node) { + if (node.type !== "MemberExpression" && node.type !== "OptionalMemberExpression") { + return false; } - exports.default = ProviderStream; -}); -unwrapExports(stream$4); + if (node.object.type === "Identifier") { + return true; + } -var sync$5 = createCommonjsModule(function (module, exports) { + return isMemberExpressionChain(node.object); +} - Object.defineProperty(exports, "__esModule", { - value: true - }); +function isGetterOrSetter(node) { + return node.kind === "get" || node.kind === "set"; +} // TODO: This is a bad hack and we need a better way to distinguish between +// arrow functions and otherwise - class ReaderSync extends reader$1.default { - constructor() { - super(...arguments); - this._walkSync = out$2.walkSync; - this._statSync = out.statSync; - } - dynamic(root, options) { - return this._walkSync(root, options); - } +function isFunctionNotation(node) { + return isGetterOrSetter(node) || hasSameLocStart$1(node, node.value); +} // Hack to differentiate between the following two which have the same ast +// type T = { method: () => void }; +// type T = { method(): void }; - static(patterns, options) { - const entries = []; +/** + * @param {Node} node + * @returns {boolean} + */ - for (const pattern of patterns) { - const filepath = this._getFullEntryPath(pattern); - const entry = this._getEntry(filepath, pattern, options); +function isObjectTypePropertyAFunction(node) { + return (node.type === "ObjectTypeProperty" || node.type === "ObjectTypeInternalSlot") && node.value.type === "FunctionTypeAnnotation" && !node.static && !isFunctionNotation(node); +} // Hack to differentiate between the following two which have the same ast +// declare function f(a): void; +// var f: (a) => void; - if (entry === null || !options.entryFilter(entry)) { - continue; - } - entries.push(entry); - } +function isTypeAnnotationAFunction(node) { + return (node.type === "TypeAnnotation" || node.type === "TSTypeAnnotation") && node.typeAnnotation.type === "FunctionTypeAnnotation" && !node.static && !hasSameLocStart$1(node, node.typeAnnotation); +} - return entries; - } +const binaryishNodeTypes = new Set(["BinaryExpression", "LogicalExpression", "NGPipeExpression"]); +/** + * @param {Node} node + * @returns {boolean} + */ - _getEntry(filepath, pattern, options) { - try { - const stats = this._getStat(filepath); +function isBinaryish(node) { + return binaryishNodeTypes.has(node.type); +} +/** + * @param {Node} node + * @returns {boolean} + */ - return this._makeEntry(stats, pattern); - } catch (error) { - if (options.errorFilter(error)) { - return null; - } - throw error; - } - } +function isMemberish(node) { + return node.type === "MemberExpression" || node.type === "OptionalMemberExpression" || node.type === "BindExpression" && Boolean(node.object); +} + +const simpleTypeAnnotations = new Set([// `any` +"AnyTypeAnnotation", "TSAnyKeyword", // `null` +"NullLiteralTypeAnnotation", "TSNullKeyword", // `this` +"ThisTypeAnnotation", "TSThisType", // `number` +"NumberTypeAnnotation", "TSNumberKeyword", // `void` +"VoidTypeAnnotation", "TSVoidKeyword", // `boolean` +"BooleanTypeAnnotation", "TSBooleanKeyword", // `bigint` +"BigIntTypeAnnotation", "TSBigIntKeyword", // `symbol` +"SymbolTypeAnnotation", "TSSymbolKeyword", // `string` +"StringTypeAnnotation", "TSStringKeyword", // literals +"BooleanLiteralTypeAnnotation", "StringLiteralTypeAnnotation", "BigIntLiteralTypeAnnotation", "NumberLiteralTypeAnnotation", "TSLiteralType", "TSTemplateLiteralType", // flow only, `empty`, `mixed` +"EmptyTypeAnnotation", "MixedTypeAnnotation", // typescript only, `never`, `object`, `undefined`, `unknown` +"TSNeverKeyword", "TSObjectKeyword", "TSUndefinedKeyword", "TSUnknownKeyword"]); +/** + * @param {Node} node + * @returns {boolean} + */ - _getStat(filepath) { - return this._statSync(filepath, this._fsStatSettings); - } +function isSimpleType(node) { + if (!node) { + return false; + } + if ((node.type === "GenericTypeAnnotation" || node.type === "TSTypeReference") && !node.typeParameters) { + return true; } - exports.default = ReaderSync; -}); -unwrapExports(sync$5); + if (simpleTypeAnnotations.has(node.type)) { + return true; + } -var sync$6 = createCommonjsModule(function (module, exports) { + return false; +} - Object.defineProperty(exports, "__esModule", { - value: true - }); +const unitTestRe = /^(skip|[fx]?(it|describe|test))$/; +/** + * @param {CallExpression} node + * @returns {boolean} + */ - class ProviderSync extends provider.default { - constructor() { - super(...arguments); - this._reader = new sync$5.default(this._settings); - } +function isSkipOrOnlyBlock(node) { + return (node.callee.type === "MemberExpression" || node.callee.type === "OptionalMemberExpression") && node.callee.object.type === "Identifier" && node.callee.property.type === "Identifier" && unitTestRe.test(node.callee.object.name) && (node.callee.property.name === "only" || node.callee.property.name === "skip"); +} +/** + * @param {CallExpression} node + * @returns {boolean} + */ - read(task) { - const root = this._getRootDirectory(task); - const options = this._getReaderOptions(task); +function isUnitTestSetUp(node) { + const unitTestSetUpRe = /^(before|after)(Each|All)$/; + return node.callee.type === "Identifier" && unitTestSetUpRe.test(node.callee.name) && node.arguments.length === 1; +} // eg; `describe("some string", (done) => {})` - const entries = this.api(root, task, options); - return entries.map(options.transform); + +function isTestCall(n, parent) { + if (n.type !== "CallExpression") { + return false; + } + + if (n.arguments.length === 1) { + if (isAngularTestWrapper(n) && parent && isTestCall(parent)) { + return isFunctionOrArrowExpression(n.arguments[0]); } - api(root, task, options) { - if (task.dynamic) { - return this._reader.dynamic(root, options); + if (isUnitTestSetUp(n)) { + return isAngularTestWrapper(n.arguments[0]); + } + } else if (n.arguments.length === 2 || n.arguments.length === 3) { + if ((n.callee.type === "Identifier" && unitTestRe.test(n.callee.name) || isSkipOrOnlyBlock(n)) && (isTemplateLiteral(n.arguments[0]) || isStringLiteral(n.arguments[0]))) { + // it("name", () => { ... }, 2500) + if (n.arguments[2] && !isNumericLiteral(n.arguments[2])) { + return false; } - return this._reader.static(task.patterns, options); + return (n.arguments.length === 2 ? isFunctionOrArrowExpression(n.arguments[1]) : isFunctionOrArrowExpressionWithBody(n.arguments[1]) && getFunctionParameters(n.arguments[1]).length <= 1) || isAngularTestWrapper(n.arguments[1]); } - } - exports.default = ProviderSync; -}); -unwrapExports(sync$6); + return false; +} +/** + * @param {Node} node + * @returns {boolean} + */ -var settings$3 = createCommonjsModule(function (module, exports) { - Object.defineProperty(exports, "__esModule", { - value: true - }); - const CPU_COUNT = os$1.cpus().length; - exports.DEFAULT_FILE_SYSTEM_ADAPTER = { - lstat: fs$3.lstat, - lstatSync: fs$3.lstatSync, - stat: fs$3.stat, - statSync: fs$3.statSync, - readdir: fs$3.readdir, - readdirSync: fs$3.readdirSync - }; +function hasLeadingComment(node) { + return node.comments && node.comments.some(comment => comment.leading); +} +/** + * @param {Node} node + * @returns {boolean} + */ - class Settings { - constructor(_options = {}) { - this._options = _options; - this.absolute = this._getValue(this._options.absolute, false); - this.baseNameMatch = this._getValue(this._options.baseNameMatch, false); - this.braceExpansion = this._getValue(this._options.braceExpansion, true); - this.caseSensitiveMatch = this._getValue(this._options.caseSensitiveMatch, true); - this.concurrency = this._getValue(this._options.concurrency, CPU_COUNT); - this.cwd = this._getValue(this._options.cwd, process.cwd()); - this.deep = this._getValue(this._options.deep, Infinity); - this.dot = this._getValue(this._options.dot, false); - this.extglob = this._getValue(this._options.extglob, true); - this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, true); - this.fs = this._getFileSystemMethods(this._options.fs); - this.globstar = this._getValue(this._options.globstar, true); - this.ignore = this._getValue(this._options.ignore, []); - this.markDirectories = this._getValue(this._options.markDirectories, false); - this.objectMode = this._getValue(this._options.objectMode, false); - this.onlyDirectories = this._getValue(this._options.onlyDirectories, false); - this.onlyFiles = this._getValue(this._options.onlyFiles, true); - this.stats = this._getValue(this._options.stats, false); - this.suppressErrors = this._getValue(this._options.suppressErrors, false); - this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, false); - this.unique = this._getValue(this._options.unique, true); - if (this.onlyDirectories) { - this.onlyFiles = false; - } +function hasTrailingComment(node) { + return node.comments && node.comments.some(comment => comment.trailing); +} +/** + * @param {Node} node + * @returns {boolean} + */ - if (this.stats) { - this.objectMode = true; - } - } - _getValue(option, value) { - return option === undefined ? value : option; - } +function hasTrailingLineComment(node) { + return node.comments && node.comments.some(comment => comment.trailing && !isBlockComment(comment)); +} +/** + * @param {CallExpression | OptionalCallExpression} node + * @returns {boolean} + */ - _getFileSystemMethods(methods = {}) { - return Object.assign(Object.assign({}, exports.DEFAULT_FILE_SYSTEM_ADAPTER), methods); - } - } +function isCallOrOptionalCallExpression(node) { + return node.type === "CallExpression" || node.type === "OptionalCallExpression"; +} +/** + * @param {Node} node + * @returns {boolean} + */ - exports.default = Settings; -}); -unwrapExports(settings$3); -var settings_1 = settings$3.DEFAULT_FILE_SYSTEM_ADAPTER; -async function FastGlob(source, options) { - assertPatternsInput(source); - const works = getWorks(source, async$5.default, options); - const result = await Promise.all(works); - return utils$4.array.flatten(result); -} // https://github.com/typescript-eslint/typescript-eslint/issues/60 -// eslint-disable-next-line no-redeclare +function hasDanglingComments(node) { + return node.comments && node.comments.some(comment => !comment.leading && !comment.trailing); +} +/** identify if an angular expression seems to have side effects */ +/** + * @param {FastPath} path + * @returns {boolean} + */ -(function (FastGlob) { - function sync(source, options) { - assertPatternsInput(source); - const works = getWorks(source, sync$6.default, options); - return utils$4.array.flatten(works); - } - FastGlob.sync = sync; +function hasNgSideEffect(path) { + return hasNode(path.getValue(), node => { + switch (node.type) { + case undefined: + return false; - function stream(source, options) { - assertPatternsInput(source); - const works = getWorks(source, stream$4.default, options); - /** - * The stream returned by the provider cannot work with an asynchronous iterator. - * To support asynchronous iterators, regardless of the number of tasks, we always multiplex streams. - * This affects performance (+25%). I don't see best solution right now. - */ + case "CallExpression": + case "OptionalCallExpression": + case "AssignmentExpression": + return true; + } + }); +} - return utils$4.stream.merge(works); - } +function isNgForOf(node, index, parentNode) { + return node.type === "NGMicrosyntaxKeyedExpression" && node.key.name === "of" && index === 1 && parentNode.body[0].type === "NGMicrosyntaxLet" && parentNode.body[0].value === null; +} +/** + * + * @param {any} node + * @returns {boolean} + */ - FastGlob.stream = stream; - function generateTasks(source, options) { - assertPatternsInput(source); - const patterns = [].concat(source); - const settings = new settings$3.default(options); - return tasks.generate(patterns, settings); +function isSimpleTemplateLiteral(node) { + let expressionsKey = "expressions"; + + if (node.type === "TSTemplateLiteralType") { + expressionsKey = "types"; } - FastGlob.generateTasks = generateTasks; + const expressions = node[expressionsKey]; - function isDynamicPattern(source, options) { - assertPatternsInput(source); - const settings = new settings$3.default(options); - return utils$4.pattern.isDynamicPattern(source, settings); + if (expressions.length === 0) { + return false; } - FastGlob.isDynamicPattern = isDynamicPattern; + return expressions.every(expr => { + // Disallow comments since printDocToString can't print them here + if (expr.comments) { + return false; + } // Allow `x` and `this` - function escapePath(source) { - assertPatternsInput(source); - return utils$4.path.escape(source); - } - FastGlob.escapePath = escapePath; -})(FastGlob || (FastGlob = {})); + if (expr.type === "Identifier" || expr.type === "ThisExpression") { + return true; + } // Allow `a.b.c`, `a.b[c]`, and `this.x.y` -function getWorks(source, _Provider, options) { - const patterns = [].concat(source); - const settings = new settings$3.default(options); - const tasks$1 = tasks.generate(patterns, settings); - const provider = new _Provider(settings); - return tasks$1.map(provider.read, provider); -} -function assertPatternsInput(input) { - const source = [].concat(input); - const isValidSource = source.every(item => utils$4.string.isString(item) && !utils$4.string.isEmpty(item)); + if (expr.type === "MemberExpression" || expr.type === "OptionalMemberExpression") { + let head = expr; - if (!isValidSource) { - throw new TypeError('Patterns must be a string (non empty) or an array of strings'); - } -} + while (head.type === "MemberExpression" || head.type === "OptionalMemberExpression") { + if (head.property.type !== "Identifier" && head.property.type !== "Literal" && head.property.type !== "StringLiteral" && head.property.type !== "NumericLiteral") { + return false; + } -var out$3 = FastGlob; + head = head.object; -const { - promisify -} = util$3; + if (head.comments) { + return false; + } + } -async function isType(fsStatType, statsMethodName, filePath) { - if (typeof filePath !== 'string') { - throw new TypeError(`Expected a string, got ${typeof filePath}`); - } + if (head.type === "Identifier" || head.type === "ThisExpression") { + return true; + } - try { - const stats = await promisify(fs$3[fsStatType])(filePath); - return stats[statsMethodName](); - } catch (error) { - if (error.code === 'ENOENT') { return false; } - throw error; + return false; + }); +} +/** + * @param {FastPath} path + * @returns {boolean} + */ + + +function classPropMayCauseASIProblems(path) { + const node = path.getNode(); + + if (node.type !== "ClassProperty" && node.type !== "FieldDefinition") { + return false; + } + + const name = node.key && node.key.name; // this isn't actually possible yet with most parsers available today + // so isn't properly tested yet. + + if ((name === "static" || name === "get" || name === "set") && !node.value && !node.typeAnnotation) { + return true; } } -function isTypeSync(fsStatType, statsMethodName, filePath) { - if (typeof filePath !== 'string') { - throw new TypeError(`Expected a string, got ${typeof filePath}`); +function classChildNeedsASIProtection(node) { + if (!node) { + return; } - try { - return fs$3[fsStatType](filePath)[statsMethodName](); - } catch (error) { - if (error.code === 'ENOENT') { + if (node.static || node.accessibility // TypeScript + ) { return false; } - throw error; + if (!node.computed) { + const name = node.key && node.key.name; + + if (name === "in" || name === "instanceof") { + return true; + } } -} -var isFile = isType.bind(null, 'stat', 'isFile'); -var isDirectory = isType.bind(null, 'stat', 'isDirectory'); -var isSymlink = isType.bind(null, 'lstat', 'isSymbolicLink'); -var isFileSync = isTypeSync.bind(null, 'statSync', 'isFile'); -var isDirectorySync = isTypeSync.bind(null, 'statSync', 'isDirectory'); -var isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink'); -var pathType = { - isFile: isFile, - isDirectory: isDirectory, - isSymlink: isSymlink, - isFileSync: isFileSync, - isDirectorySync: isDirectorySync, - isSymlinkSync: isSymlinkSync -}; + switch (node.type) { + case "ClassProperty": + case "FieldDefinition": + case "TSAbstractClassProperty": + return node.computed; + + case "MethodDefinition": // Flow -const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; + case "TSAbstractMethodDefinition": // TypeScript -const getPath = (filepath, cwd) => { - const pth = filepath[0] === '!' ? filepath.slice(1) : filepath; - return path$2.isAbsolute(pth) ? pth : path$2.join(cwd, pth); -}; + case "ClassMethod": + case "ClassPrivateMethod": + { + // Babel + const isAsync = node.value ? node.value.async : node.async; + const isGenerator = node.value ? node.value.generator : node.generator; -const addExtensions = (file, extensions) => { - if (path$2.extname(file)) { - return `**/${file}`; - } + if (isAsync || node.kind === "get" || node.kind === "set") { + return false; + } - return `**/${file}.${getExtensions(extensions)}`; -}; + if (node.computed || isGenerator) { + return true; + } -const getGlob = (directory, options) => { - if (options.files && !Array.isArray(options.files)) { - throw new TypeError(`Expected \`files\` to be of type \`Array\` but received type \`${typeof options.files}\``); - } + return false; + } - if (options.extensions && !Array.isArray(options.extensions)) { - throw new TypeError(`Expected \`extensions\` to be of type \`Array\` but received type \`${typeof options.extensions}\``); - } + case "TSIndexSignature": + return true; - if (options.files && options.extensions) { - return options.files.map(x => path$2.posix.join(directory, addExtensions(x, options.extensions))); + default: + /* istanbul ignore next */ + return false; } +} +/** + * @param {string} tokenNode + * @param {string} keyword + * @returns {string} + */ - if (options.files) { - return options.files.map(x => path$2.posix.join(directory, `**/${x}`)); - } - if (options.extensions) { - return [path$2.posix.join(directory, `**/*.${getExtensions(options.extensions)}`)]; +function getTypeScriptMappedTypeModifier(tokenNode, keyword) { + if (tokenNode === "+") { + return "+" + keyword; + } else if (tokenNode === "-") { + return "-" + keyword; } - return [path$2.posix.join(directory, '**')]; -}; + return keyword; +} -var dirGlob = async (input, options) => { - options = Object.assign({ - cwd: process.cwd() - }, options); +function hasNewlineBetweenOrAfterDecorators(node, options) { + return hasNewlineInRange$2(options.originalText, locStart$2(node.decorators[0]), locEnd$2(getLast$1(node.decorators))) || hasNewline$3(options.originalText, locEnd$2(getLast$1(node.decorators))); +} // Only space, newline, carriage return, and tab are treated as whitespace +// inside JSX. - if (typeof options.cwd !== 'string') { - throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); - } - const globs = await Promise.all([].concat(input).map(async x => { - const isDirectory = await pathType.isDirectory(getPath(x, options.cwd)); - return isDirectory ? getGlob(x, options) : x; - })); - return [].concat.apply([], globs); // eslint-disable-line prefer-spread -}; +const jsxWhitespaceChars = " \n\r\t"; +const matchJsxWhitespaceRegex = new RegExp("([" + jsxWhitespaceChars + "]+)"); +const containsNonJsxWhitespaceRegex = new RegExp("[^" + jsxWhitespaceChars + "]"); // Meaningful if it contains non-whitespace characters, +// or it contains whitespace without a new line. -var sync$7 = (input, options) => { - options = Object.assign({ - cwd: process.cwd() - }, options); +/** + * @param {Node} node + * @returns {boolean} + */ - if (typeof options.cwd !== 'string') { - throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); - } +function isMeaningfulJSXText(node) { + return isLiteral(node) && (containsNonJsxWhitespaceRegex.test(rawText(node)) || !/\n/.test(rawText(node))); +} +/** + * @param {FastPath} path + * @returns {boolean} + */ - const globs = [].concat(input).map(x => pathType.isDirectorySync(getPath(x, options.cwd)) ? getGlob(x, options) : x); - return [].concat.apply([], globs); // eslint-disable-line prefer-spread -}; -dirGlob.sync = sync$7; -// A simple implementation of make-array -function makeArray(subject) { - return Array.isArray(subject) ? subject : [subject]; -} +function hasJsxIgnoreComment(path) { + const node = path.getValue(); + const parent = path.getParentNode(); -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, -// . -// .. + if (!parent || !node || !isJSXNode(node) || !isJSXNode(parent)) { + return false; + } // Lookup the previous sibling, ignoring any empty JSXText elements -const REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/; -const SLASH$1 = '/'; -const KEY_IGNORE$1 = typeof Symbol !== 'undefined' ? Symbol.for('node-ignore') -/* istanbul ignore next */ -: 'node-ignore'; -const define$1 = (object, key, value) => Object.defineProperty(object, key, { - value -}); + const index = parent.children.indexOf(node); + let prevSibling = null; -const REGEX_REGEXP_RANGE$1 = /([0-z])-([0-z])/g; // Sanitize the range of a regular expression -// The cases are complicated, see test cases for details + for (let i = index; i > 0; i--) { + const candidate = parent.children[i - 1]; -const sanitizeRange$1 = range => range.replace(REGEX_REGEXP_RANGE$1, (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. -: ''); // > 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 '`..`' + if (candidate.type === "JSXText" && !isMeaningfulJSXText(candidate)) { + continue; + } + prevSibling = candidate; + break; + } -const REPLACERS = [// > Trailing spaces are ignored unless they are quoted with backslash ("\") -[// (a\ ) -> (a ) -// (a ) -> (a) -// (a \ ) -> (a ) -/\\?\s+$/, match => match.indexOf('\\') === 0 ? ' ' : ''], // replace (\ ) with ' ' -[/\\\s/g, () => ' '], // 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}`], [// > [abc] matches any character inside the brackets -// > (in this case a, b, or c); -/\[([^\]/]*)($|\])/g, (match, p1, p2) => p2 === ']' ? `[${sanitizeRange$1(p1)}]` : `\\${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' -() => '^(?:.*\\/)?'], // 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}(?=$|\\/$)`], // 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}[^\\/]*`], // trailing wildcard -[/(\^|\\\/)?\\\*$/, (_, p1) => { - const prefix = p1 // '\^': - // '/*' does not match '' - // '/*' does not match everything - // '\\\/': - // 'abc/*' does not match 'abc/' - ? `${p1}[^/]+` // 'a*' matches 'a' - // 'a*' matches 'aa' - : '[^/]*'; - return `${prefix}(?=$|\\/$)`; -}], [// unescape -/\\\\\\/g, () => '\\']]; // A simple cache, because an ignore rule only has only one certain meaning + return prevSibling && prevSibling.type === "JSXExpressionContainer" && prevSibling.expression.type === "JSXEmptyExpression" && prevSibling.expression.comments && prevSibling.expression.comments.some(comment => isPrettierIgnoreComment(comment)); +} +/** + * @param {JSXElement} node + * @returns {boolean} + */ -const regexCache = Object.create(null); // @param {pattern} -const makeRegex = (pattern, negative, ignorecase) => { - const r = regexCache[pattern]; +function isEmptyJSXElement(node) { + if (node.children.length === 0) { + return true; + } - if (r) { - return r; - } // const replacers = negative - // ? NEGATIVE_REPLACERS - // : POSITIVE_REPLACERS + if (node.children.length > 1) { + return false; + } // if there is one text child and does not contain any meaningful text + // we can treat the element as empty. - 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 child = node.children[0]; + return isLiteral(child) && !isMeaningfulJSXText(child); +} +/** + * @param {FastPath} path + * @returns {boolean} + */ -const isString = subject => typeof subject === 'string'; // > A blank line matches no files, so it can serve as a separator for readability. +function hasPrettierIgnore(path) { + return hasIgnoreComment(path) || hasJsxIgnoreComment(path); +} +/** + * @param {FastPath} path + * @returns {boolean} + */ -const checkPattern$1 = 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); +function isLastStatement(path) { + const parent = path.getParentNode(); -class IgnoreRule { - constructor(origin, pattern, negative, regex) { - this.origin = origin; - this.pattern = pattern; - this.negative = negative; - this.regex = regex; + if (!parent) { + return true; } + const node = path.getValue(); + const body = (parent.body || parent.consequent).filter(stmt => stmt.type !== "EmptyStatement"); + return body[body.length - 1] === node; } +/** + * @param {string} text + * @param {Node} typeAnnotation + * @returns {boolean} + */ -const createRule$1 = (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); - } +function isFlowAnnotationComment(text, typeAnnotation) { + const start = locStart$2(typeAnnotation); + const end = skipWhitespace$2(text, locEnd$2(typeAnnotation)); + return end !== false && text.slice(start, start + 2) === "/*" && text.slice(end, end + 2) === "*/"; +} +/** + * @param {string} text + * @param {Node} node + * @returns {boolean} + */ - 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); -}; +function hasLeadingOwnLineComment(text, node) { + if (isJSXNode(node)) { + return hasNodeIgnoreComment(node); + } -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 '', so throw + const res = node.comments && node.comments.some(comment => comment.leading && hasNewline$3(text, locEnd$2(comment))); + return res; +} // This recurses the return argument, looking for the first token +// (the leftmost leaf node) and, if it (or its parents) has any +// leadingComments, returns true (so it can be wrapped in parens). - if (!path) { - return doThrow(`path must not be empty`, TypeError); - } // Check if it is a relative path +function returnArgumentHasLeadingComment(options, argument) { + if (hasLeadingOwnLineComment(options.originalText, argument)) { + return true; + } + + if (hasNakedLeftSide(argument)) { + let leftMost = argument; + let newLeftMost; + while (newLeftMost = getLeftSide(leftMost)) { + leftMost = newLeftMost; - if (checkPath.isNotRelative(path)) { - const r = '`path.relative()`d'; - return doThrow(`path should be a ${r} string, but got "${originalPath}"`, RangeError); + if (hasLeadingOwnLineComment(options.originalText, leftMost)) { + return true; + } + } } - return true; -}; - -const isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path); + return false; +} // Note: Quoting/unquoting numbers in TypeScript is not safe. +// +// let a = { 1: 1, 2: 2 } +// let b = { '1': 1, '2': 2 } +// +// declare let aa: keyof typeof a; +// declare let bb: keyof typeof b; +// +// aa = bb; +// ^^ +// Type '"1" | "2"' is not assignable to type '1 | 2'. +// Type '"1"' is not assignable to type '1 | 2'.(2322) +// +// And in Flow, you get: +// +// const x = { +// 0: 1 +// ^ Non-string literal property keys not supported. [unsupported-syntax] +// } +// +// Angular does not support unquoted numbers in expressions. +// +// So we play it safe and only unquote numbers for the JavaScript parsers. +// (Vue supports unquoted numbers in expressions, but let’s keep it simple.) +// +// Identifiers can be unquoted in more circumstances, though. -checkPath.isNotRelative = isNotRelative; -checkPath.convert = p => p; +function isStringPropSafeToUnquote(node, options) { + return options.parser !== "json" && isStringLiteral(node.key) && rawText(node.key).slice(1, -1) === node.key.value && (isIdentifierName(node.key.value) && // With `--strictPropertyInitialization`, TS treats properties with quoted names differently than unquoted ones. + // See https://github.com/microsoft/TypeScript/pull/20075 + !((options.parser === "typescript" || options.parser === "babel-ts") && node.type === "ClassProperty") || isSimpleNumber(node.key.value) && String(Number(node.key.value)) === node.key.value && (options.parser === "babel" || options.parser === "espree" || options.parser === "meriyah")); +} // Matches “simple” numbers like `123` and `2.5` but not `1_000`, `1e+100` or `0b10`. -class Ignore { - constructor({ - ignorecase = true - } = {}) { - this._rules = []; - this._ignorecase = ignorecase; - define$1(this, KEY_IGNORE$1, true); - this._initCache(); - } +function isSimpleNumber(numberString) { + return /^(\d+|\d+\.\d+)$/.test(numberString); +} +/** + * @param {Node} node + * @param {Node} parentNode + * @returns {boolean} + */ - _initCache() { - this._ignoreCache = Object.create(null); - this._testCache = Object.create(null); - } - _addPattern(pattern) { - // #32 - if (pattern && pattern[KEY_IGNORE$1]) { - this._rules = this._rules.concat(pattern._rules); - this._added = true; - return; - } +function isJestEachTemplateLiteral(node, parentNode) { + /** + * describe.each`table`(name, fn) + * describe.only.each`table`(name, fn) + * describe.skip.each`table`(name, fn) + * test.each`table`(name, fn) + * test.only.each`table`(name, fn) + * test.skip.each`table`(name, fn) + * + * Ref: https://github.com/facebook/jest/pull/6102 + */ + const jestEachTriggerRegex = /^[fx]?(describe|it|test)$/; + return parentNode.type === "TaggedTemplateExpression" && parentNode.quasi === node && parentNode.tag.type === "MemberExpression" && parentNode.tag.property.type === "Identifier" && parentNode.tag.property.name === "each" && (parentNode.tag.object.type === "Identifier" && jestEachTriggerRegex.test(parentNode.tag.object.name) || parentNode.tag.object.type === "MemberExpression" && parentNode.tag.object.property.type === "Identifier" && (parentNode.tag.object.property.name === "only" || parentNode.tag.object.property.name === "skip") && parentNode.tag.object.object.type === "Identifier" && jestEachTriggerRegex.test(parentNode.tag.object.object.name)); +} +/** + * @param {TemplateLiteral} template + * @returns {boolean} + */ - if (checkPattern$1(pattern)) { - const rule = createRule$1(pattern, this._ignorecase); - this._added = true; - this._rules.push(rule); - } - } // @param {Array | string | Ignore} pattern +function templateLiteralHasNewLines(template) { + return template.quasis.some(quasi => quasi.value.raw.includes("\n")); +} +/** + * @param {TemplateLiteral | TaggedTemplateExpression} n + * @param {string} text + * @returns {boolean} + */ - 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. +function isTemplateOnItsOwnLine(n, text) { + return (n.type === "TemplateLiteral" && templateLiteralHasNewLines(n) || n.type === "TaggedTemplateExpression" && templateLiteralHasNewLines(n.quasi)) && !hasNewline$3(text, locStart$2(n), { + backwards: true + }); +} +/** + * @param {Node} node + * @returns {boolean} + */ - if (this._added) { - this._initCache(); - } - return this; - } // legacy +function needsHardlineAfterDanglingComment(node) { + if (!node.comments) { + return false; + } + const lastDanglingComment = getLast$1(node.comments.filter(comment => !comment.leading && !comment.trailing)); + return lastDanglingComment && !isBlockComment(lastDanglingComment); +} // Logic to check for args with multiple anonymous functions. For instance, +// the following call should be split on multiple lines for readability: +// source.pipe(map((x) => x + x), filter((x) => x % 2 === 0)) - 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 +function isFunctionCompositionArgs(args) { + if (args.length <= 1) { + return false; + } - _testOne(path, checkUnignored) { - let ignored = false; - let unignored = false; + let count = 0; - this._rules.forEach(rule => { - const { - negative - } = rule; + for (const arg of args) { + if (isFunctionOrArrowExpression(arg)) { + count += 1; - if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) { - return; + if (count > 1) { + return true; + } + } else if (isCallOrOptionalCallExpression(arg)) { + for (const childArg of arg.arguments) { + if (isFunctionOrArrowExpression(childArg)) { + return true; + } } + } + } - const matched = rule.regex.test(path); + return false; +} // Logic to determine if a call is a “long curried function call”. +// See https://github.com/prettier/prettier/issues/1420. +// +// `connect(a, b, c)(d)` +// In the above call expression, the second call is the parent node and the +// first call is the current node. - if (matched) { - ignored = !negative; - unignored = negative; - } - }); +/** + * @param {FastPath} path + * @returns {boolean} + */ - return { - ignored, - unignored - }; - } // @returns {TestResult} + +function isLongCurriedCallExpression(path) { + const node = path.getValue(); + const parent = path.getParentNode(); + return isCallOrOptionalCallExpression(node) && isCallOrOptionalCallExpression(parent) && parent.callee === node && node.arguments.length > parent.arguments.length && parent.arguments.length > 0; +} +/** + * @param {any} node + * @param {number} depth + * @returns {boolean} + */ - _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); +function isSimpleCallArgument(node, depth) { + if (depth >= 2) { + return false; } - _t(path, cache, checkUnignored, slices) { - if (path in cache) { - return cache[path]; - } + const isChildSimple = child => isSimpleCallArgument(child, depth + 1); - if (!slices) { - // path/to/a.js - // ['path', 'to', 'a.js'] - slices = path.split(SLASH$1); - } + const regexpPattern = node.type === "Literal" && "regex" in node && node.regex.pattern || node.type === "RegExpLiteral" && node.pattern; - slices.pop(); // If the path has no parent directory, just test it + if (regexpPattern && regexpPattern.length > 5) { + return false; + } - if (!slices.length) { - return cache[path] = this._testOne(path, checkUnignored); - } + if (node.type === "Literal" || node.type === "BigIntLiteral" || node.type === "DecimalLiteral" || node.type === "BooleanLiteral" || node.type === "NullLiteral" || node.type === "NumericLiteral" || node.type === "RegExpLiteral" || node.type === "StringLiteral" || node.type === "Identifier" || node.type === "ThisExpression" || node.type === "Super" || node.type === "PrivateName" || node.type === "ArgumentPlaceholder" || node.type === "Import") { + return true; + } - const parent = this._t(slices.join(SLASH$1) + SLASH$1, cache, checkUnignored, slices); // If the path contains a parent directory, check the parent first + if (node.type === "TemplateLiteral") { + return node.expressions.every(isChildSimple); + } + if (node.type === "ObjectExpression") { + return node.properties.every(p => !p.computed && (p.shorthand || p.value && isChildSimple(p.value))); + } - 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); + if (node.type === "ArrayExpression") { + return node.elements.every(x => x === null || isChildSimple(x)); } - ignores(path) { - return this._test(path, this._ignoreCache, false).ignored; + if (node.type === "ImportExpression") { + return isChildSimple(node.source); } - createFilter() { - return path => !this.ignores(path); + if (node.type === "CallExpression" || node.type === "OptionalCallExpression" || node.type === "NewExpression") { + return isSimpleCallArgument(node.callee, depth) && node.arguments.every(isChildSimple); } - filter(paths) { - return makeArray(paths).filter(this.createFilter()); - } // @returns {TestResult} + if (node.type === "MemberExpression" || node.type === "OptionalMemberExpression") { + return isSimpleCallArgument(node.object, depth) && isSimpleCallArgument(node.property, depth); + } + if (node.type === "UnaryExpression" && (node.operator === "!" || node.operator === "-")) { + return isSimpleCallArgument(node.argument, depth); + } - test(path) { - return this._test(path, this._testCache, true); + if (node.type === "TSNonNullExpression") { + return isSimpleCallArgument(node.expression, depth); } + return false; } -const factory = options => new Ignore(options); +function rawText(node) { + return node.extra ? node.extra.raw : node.raw; +} -const returnFalse = () => false; +function identity$1(x) { + return x; +} -const isPathValid = path => checkPath(path && checkPath.convert(path), path, returnFalse); +function isTSXFile(options) { + return options.filepath && /\.tsx$/i.test(options.filepath); +} +/** + * @param {any} options + * @param {("es5" | "all")} [level] + * @returns {boolean} + */ -factory.isPathValid = isPathValid; // Fixes typescript -factory.default = factory; -var ignore$1 = factory; // Windows -// -------------------------------------------------------------- +function shouldPrintComma(options, level = "es5") { + return options.trailingComma === "es5" && level === "es5" || options.trailingComma === "all" && (level === "all" || level === "es5"); +} +/** + * Tests if an expression starts with `{`, or (if forbidFunctionClassAndDoExpr + * holds) `function`, `class`, or `do {}`. Will be overzealous if there's + * already necessary grouping parentheses. + * + * @param {Node} node + * @param {boolean} forbidFunctionClassAndDoExpr + * @returns {boolean} + */ -/* 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, '/'); +function startsWithNoLookaheadToken(node, forbidFunctionClassAndDoExpr) { + node = getLeftMost(node); - checkPath.convert = makePosix; // 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/' - // 'd:\\foo' + switch (node.type) { + case "FunctionExpression": + case "ClassExpression": + case "DoExpression": + return forbidFunctionClassAndDoExpr; - const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i; + case "ObjectExpression": + return true; - checkPath.isNotRelative = path => REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path) || isNotRelative(path); -} + case "MemberExpression": + case "OptionalMemberExpression": + return startsWithNoLookaheadToken(node.object, forbidFunctionClassAndDoExpr); -var slash$1 = path => { - const isExtendedLengthPath = /^\\\\\?\\/.test(path); - const hasNonAscii = /[^\u0000-\u0080]+/.test(path); // eslint-disable-line no-control-regex + case "TaggedTemplateExpression": + if (node.tag.type === "FunctionExpression") { + // IIFEs are always already parenthesized + return false; + } - if (isExtendedLengthPath || hasNonAscii) { - return path; - } + return startsWithNoLookaheadToken(node.tag, forbidFunctionClassAndDoExpr); - return path.replace(/\\/g, '/'); -}; + case "CallExpression": + case "OptionalCallExpression": + if (node.callee.type === "FunctionExpression") { + // IIFEs are always already parenthesized + return false; + } -const { - promisify: promisify$1 -} = util$3; -const DEFAULT_IGNORE = ['**/node_modules/**', '**/flow-typed/**', '**/coverage/**', '**/.git']; -const readFileP = promisify$1(fs$3.readFile); + return startsWithNoLookaheadToken(node.callee, forbidFunctionClassAndDoExpr); -const mapGitIgnorePatternTo = base => ignore => { - if (ignore.startsWith('!')) { - return '!' + path$2.posix.join(base, ignore.slice(1)); - } + case "ConditionalExpression": + return startsWithNoLookaheadToken(node.test, forbidFunctionClassAndDoExpr); - return path$2.posix.join(base, ignore); -}; + case "UpdateExpression": + return !node.prefix && startsWithNoLookaheadToken(node.argument, forbidFunctionClassAndDoExpr); -const parseGitIgnore = (content, options) => { - const base = slash$1(path$2.relative(options.cwd, path$2.dirname(options.fileName))); - return content.split(/\r?\n/).filter(Boolean).filter(line => !line.startsWith('#')).map(mapGitIgnorePatternTo(base)); -}; + case "BindExpression": + return node.object && startsWithNoLookaheadToken(node.object, forbidFunctionClassAndDoExpr); -const reduceIgnore = files => { - return files.reduce((ignores, file) => { - ignores.add(parseGitIgnore(file.content, { - cwd: file.cwd, - fileName: file.filePath - })); - return ignores; - }, ignore$1()); -}; + case "SequenceExpression": + return startsWithNoLookaheadToken(node.expressions[0], forbidFunctionClassAndDoExpr); -const ensureAbsolutePathForCwd = (cwd, p) => { - if (path$2.isAbsolute(p)) { - if (p.startsWith(cwd)) { - return p; - } + case "TSAsExpression": + return startsWithNoLookaheadToken(node.expression, forbidFunctionClassAndDoExpr); - throw new Error(`Path ${p} is not in cwd ${cwd}`); + default: + return false; } +} - return path$2.join(cwd, p); +const equalityOperators = { + "==": true, + "!=": true, + "===": true, + "!==": true }; - -const getIsIgnoredPredecate = (ignores, cwd) => { - return p => ignores.ignores(slash$1(path$2.relative(cwd, ensureAbsolutePathForCwd(cwd, p)))); +const multiplicativeOperators = { + "*": true, + "/": true, + "%": true }; - -const getFile = async (file, cwd) => { - const filePath = path$2.join(cwd, file); - const content = await readFileP(filePath, 'utf8'); - return { - cwd, - filePath, - content - }; +const bitshiftOperators = { + ">>": true, + ">>>": true, + "<<": true }; -const getFileSync = (file, cwd) => { - const filePath = path$2.join(cwd, file); - const content = fs$3.readFileSync(filePath, 'utf8'); - return { - cwd, - filePath, - content - }; -}; +function shouldFlatten(parentOp, nodeOp) { + if (getPrecedence(nodeOp) !== getPrecedence(parentOp)) { + return false; + } // ** is right-associative + // x ** y ** z --> x ** (y ** z) -const normalizeOptions$3 = ({ - ignore = [], - cwd = slash$1(process.cwd()) -} = {}) => { - return { - ignore, - cwd - }; -}; -var gitignore = async options => { - options = normalizeOptions$3(options); - const paths = await out$3('**/.gitignore', { - ignore: DEFAULT_IGNORE.concat(options.ignore), - cwd: options.cwd - }); - const files = await Promise.all(paths.map(file => getFile(file, options.cwd))); - const ignores = reduceIgnore(files); - return getIsIgnoredPredecate(ignores, options.cwd); -}; + if (parentOp === "**") { + return false; + } // x == y == z --> (x == y) == z -var sync$8 = options => { - options = normalizeOptions$3(options); - const paths = out$3.sync('**/.gitignore', { - ignore: DEFAULT_IGNORE.concat(options.ignore), - cwd: options.cwd - }); - const files = paths.map(file => getFileSync(file, options.cwd)); - const ignores = reduceIgnore(files); - return getIsIgnoredPredecate(ignores, options.cwd); -}; -gitignore.sync = sync$8; -const { - Transform -} = stream$6; + if (equalityOperators[parentOp] && equalityOperators[nodeOp]) { + return false; + } // x * y % z --> (x * y) % z -class ObjectTransform extends Transform { - constructor() { - super({ - objectMode: true - }); - } -} + if (nodeOp === "%" && multiplicativeOperators[parentOp] || parentOp === "%" && multiplicativeOperators[nodeOp]) { + return false; + } // x * y / z --> (x * y) / z + // x / y * z --> (x / y) * z -class FilterStream extends ObjectTransform { - constructor(filter) { - super(); - this._filter = filter; - } - _transform(data, encoding, callback) { - if (this._filter(data)) { - this.push(data); - } + if (nodeOp !== parentOp && multiplicativeOperators[nodeOp] && multiplicativeOperators[parentOp]) { + return false; + } // x << y << z --> (x << y) << z - callback(); + + if (bitshiftOperators[parentOp] && bitshiftOperators[nodeOp]) { + return false; } + return true; } -class UniqueStream extends ObjectTransform { - constructor() { - super(); - this._pushed = new Set(); - } - - _transform(data, encoding, callback) { - if (!this._pushed.has(data)) { - this.push(data); +const PRECEDENCE = {}; +[["|>"], ["??"], ["||"], ["&&"], ["|"], ["^"], ["&"], ["==", "===", "!=", "!=="], ["<", ">", "<=", ">=", "in", "instanceof"], [">>", "<<", ">>>"], ["+", "-"], ["*", "/", "%"], ["**"]].forEach((tier, i) => { + tier.forEach(op => { + PRECEDENCE[op] = i; + }); +}); - this._pushed.add(data); - } +function getPrecedence(op) { + return PRECEDENCE[op]; +} - callback(); +function getLeftMost(node) { + while (node.left) { + node = node.left; } + return node; } -var streamUtils = { - FilterStream, - UniqueStream -}; +function isBitwiseOperator(operator) { + return !!bitshiftOperators[operator] || operator === "|" || operator === "^" || operator === "&"; +} -const { - FilterStream: FilterStream$1, - UniqueStream: UniqueStream$1 -} = streamUtils; +function hasRestParameter(node) { + if (node.rest) { + return true; + } -const DEFAULT_FILTER = () => false; + const parameters = getFunctionParameters(node); + return parameters.length > 0 && getLast$1(parameters).type === "RestElement"; +} -const isNegative = pattern => pattern[0] === '!'; +const functionParametersCache = new WeakMap(); -const assertPatternsInput$1 = patterns => { - if (!patterns.every(pattern => typeof pattern === 'string')) { - throw new TypeError('Patterns must be a string or an array of strings'); +function getFunctionParameters(node) { + if (functionParametersCache.has(node)) { + return functionParametersCache.get(node); } -}; -const checkCwdOption = (options = {}) => { - if (!options.cwd) { - return; - } + const parameters = []; - let stat; + if (node.this) { + parameters.push(node.this); + } // `params` vs `parameters` - see https://github.com/babel/babel/issues/9231 - try { - stat = fs$3.statSync(options.cwd); - } catch (_) { - return; + + if (Array.isArray(node.parameters)) { + parameters.push(...node.parameters); + } else if (Array.isArray(node.params)) { + parameters.push(...node.params); } - if (!stat.isDirectory()) { - throw new Error('The `cwd` option must be a path to a directory'); + if (node.rest) { + parameters.push(node.rest); } -}; -const getPathString = p => p.stats instanceof fs$3.Stats ? p.path : p; + functionParametersCache.set(node, parameters); + return parameters; +} -const generateGlobTasks = (patterns, taskOptions) => { - patterns = arrayUnion([].concat(patterns)); - assertPatternsInput$1(patterns); - checkCwdOption(taskOptions); - const globTasks = []; - taskOptions = Object.assign({ - ignore: [], - expandDirectories: true - }, taskOptions); +function iterateFunctionParametersPath(path, iteratee) { + const node = path.getValue(); + let index = 0; - for (const [index, pattern] of patterns.entries()) { - if (isNegative(pattern)) { - continue; - } + const callback = childPath => iteratee(childPath, index++); - const ignore = patterns.slice(index).filter(isNegative).map(pattern => pattern.slice(1)); - const options = Object.assign({}, taskOptions, { - ignore: taskOptions.ignore.concat(ignore) - }); - globTasks.push({ - pattern, - options - }); + if (node.this) { + path.call(callback, "this"); } - return globTasks; -}; - -const globDirs = (task, fn) => { - let options = {}; - - if (task.options.cwd) { - options.cwd = task.options.cwd; + if (Array.isArray(node.parameters)) { + path.each(callback, "parameters"); + } else if (Array.isArray(node.params)) { + path.each(callback, "params"); } - if (Array.isArray(task.options.expandDirectories)) { - options = Object.assign({}, options, { - files: task.options.expandDirectories - }); - } else if (typeof task.options.expandDirectories === 'object') { - options = Object.assign({}, options, {}, task.options.expandDirectories); + if (node.rest) { + path.call(callback, "rest"); } +} - return fn(task.pattern, options); -}; - -const getPattern = (task, fn) => task.options.expandDirectories ? globDirs(task, fn) : [task.pattern]; - -const getFilterSync = options => { - return options && options.gitignore ? gitignore.sync({ - cwd: options.cwd, - ignore: options.ignore - }) : DEFAULT_FILTER; -}; - -const globToTask = task => glob => { - const { - options - } = task; +const callArgumentsCache = new WeakMap(); - if (options.ignore && Array.isArray(options.ignore) && options.expandDirectories) { - options.ignore = dirGlob.sync(options.ignore); +function getCallArguments(node) { + if (callArgumentsCache.has(node)) { + return callArgumentsCache.get(node); } - return { - pattern: glob, - options - }; -}; + const args = node.type === "ImportExpression" ? // No parser except `babel` supports `import("./foo.json", { assert: { type: "json" } })` yet, + // And `babel` parser it as `CallExpression` + // We need add the second argument here + [node.source] : node.arguments; + callArgumentsCache.set(node, args); + return args; +} -var globby$1 = async (patterns, options) => { - const globTasks = generateGlobTasks(patterns, options); +function iterateCallArgumentsPath(path, iteratee) { + const node = path.getValue(); // See comment in `getCallArguments` - const getFilter = async () => { - return options && options.gitignore ? gitignore({ - cwd: options.cwd, - ignore: options.ignore - }) : DEFAULT_FILTER; - }; + if (node.type === "ImportExpression") { + path.call(sourcePath => iteratee(sourcePath, 0), "source"); + } else { + path.each(iteratee, "arguments"); + } +} - const getTasks = async () => { - const tasks = await Promise.all(globTasks.map(async task => { - const globs = await getPattern(task, dirGlob); - return Promise.all(globs.map(globToTask(task))); - })); - return arrayUnion(...tasks); - }; +function isPrettierIgnoreComment(comment) { + return comment.value.trim() === "prettier-ignore"; +} - const [filter, tasks] = await Promise.all([getFilter(), getTasks()]); - const paths = await Promise.all(tasks.map(task => out$3(task.pattern, task.options))); - return arrayUnion(...paths).filter(path_ => !filter(getPathString(path_))); -}; +function hasNodeIgnoreComment(node) { + return node && (node.comments && node.comments.length > 0 && node.comments.some(comment => isPrettierIgnoreComment(comment) && !comment.unignore) || node.prettierIgnore); +} -var sync$9 = (patterns, options) => { - const globTasks = generateGlobTasks(patterns, options); - const tasks = globTasks.reduce((tasks, task) => { - const newTask = getPattern(task, dirGlob.sync).map(globToTask(task)); - return tasks.concat(newTask); - }, []); - const filter = getFilterSync(options); - return tasks.reduce((matches, task) => arrayUnion(matches, out$3.sync(task.pattern, task.options)), []).filter(path_ => !filter(path_)); -}; +function hasIgnoreComment(path) { + const node = path.getValue(); + return hasNodeIgnoreComment(node); +} -var stream$5 = (patterns, options) => { - const globTasks = generateGlobTasks(patterns, options); - const tasks = globTasks.reduce((tasks, task) => { - const newTask = getPattern(task, dirGlob.sync).map(globToTask(task)); - return tasks.concat(newTask); - }, []); - const filter = getFilterSync(options); - const filterStream = new FilterStream$1(p => !filter(p)); - const uniqueStream = new UniqueStream$1(); - return merge2_1(tasks.map(task => out$3.stream(task.pattern, task.options))).pipe(filterStream).pipe(uniqueStream); +var utils$6 = { + classChildNeedsASIProtection, + classPropMayCauseASIProblems, + getFunctionParameters, + iterateFunctionParametersPath, + getCallArguments, + iterateCallArgumentsPath, + hasRestParameter, + getLeftSidePathName, + getParentExportDeclaration, + getTypeScriptMappedTypeModifier, + hasDanglingComments, + hasFlowAnnotationComment, + hasFlowShorthandAnnotationComment, + hasLeadingComment, + hasLeadingOwnLineComment, + hasNakedLeftSide, + hasNewlineBetweenOrAfterDecorators, + hasNgSideEffect, + hasNode, + hasPrettierIgnore, + hasTrailingComment, + hasTrailingLineComment, + hasIgnoreComment, + hasNodeIgnoreComment, + identity: identity$1, + isBinaryish, + isBlockComment, + isLineComment, + isPrettierIgnoreComment, + isCallOrOptionalCallExpression, + isEmptyJSXElement, + isExportDeclaration, + isFlowAnnotationComment, + isFunctionCompositionArgs, + isFunctionNotation, + isFunctionOrArrowExpression, + isGetterOrSetter, + isJestEachTemplateLiteral, + isJSXNode, + isJSXWhitespaceExpression, + isLastStatement, + isLiteral, + isLongCurriedCallExpression, + isSimpleCallArgument, + isMeaningfulJSXText, + isMemberExpressionChain, + isMemberish, + isNgForOf, + isNumericLiteral, + isObjectType, + isObjectTypePropertyAFunction, + isSimpleType, + isSimpleNumber, + isSimpleTemplateLiteral, + isStringLiteral, + isStringPropSafeToUnquote, + isTemplateOnItsOwnLine, + isTestCall, + isTheOnlyJSXElementInMarkdown, + isTSXFile, + isTypeAnnotationAFunction, + matchJsxWhitespaceRegex, + needsHardlineAfterDanglingComment, + rawText, + returnArgumentHasLeadingComment, + shouldPrintComma, + isBitwiseOperator, + shouldFlatten, + startsWithNoLookaheadToken, + getPrecedence }; -var generateGlobTasks_1 = generateGlobTasks; - -var hasMagic = (patterns, options) => [].concat(patterns).some(pattern => out$3.isDynamicPattern(pattern, options)); - -var gitignore_1 = gitignore; -globby$1.sync = sync$9; -globby$1.stream = stream$5; -globby$1.generateGlobTasks = generateGlobTasks_1; -globby$1.hasMagic = hasMagic; -globby$1.gitignore = gitignore_1; - const { + getLast: getLast$2, + hasNewline: hasNewline$4, + getNextNonSpaceNonCommentCharacterIndexWithStartIndex: getNextNonSpaceNonCommentCharacterIndexWithStartIndex$1, + getNextNonSpaceNonCommentCharacter: getNextNonSpaceNonCommentCharacter$1, + hasNewlineInRange: hasNewlineInRange$3, addLeadingComment: addLeadingComment$3, addTrailingComment: addTrailingComment$3, addDanglingComment: addDanglingComment$3, getNextNonSpaceNonCommentCharacterIndex: getNextNonSpaceNonCommentCharacterIndex$2 -} = utilShared; +} = util; +const { + isBlockComment: isBlockComment$1, + getFunctionParameters: getFunctionParameters$1, + isPrettierIgnoreComment: isPrettierIgnoreComment$1, + isJSXNode: isJSXNode$1, + hasFlowShorthandAnnotationComment: hasFlowShorthandAnnotationComment$1, + hasFlowAnnotationComment: hasFlowAnnotationComment$1, + hasIgnoreComment: hasIgnoreComment$1 +} = utils$6; +const { + locStart: locStart$3, + locEnd: locEnd$3 +} = loc; -function handleOwnLineComment(comment, text, options, ast, isLastComment) { - const { - precedingNode, - enclosingNode, - followingNode - } = comment; - return handleLastFunctionArgComments(text, precedingNode, enclosingNode, followingNode, comment, options) || handleMemberExpressionComments(enclosingNode, followingNode, comment) || handleIfStatementComments(text, precedingNode, enclosingNode, followingNode, comment, options) || handleWhileComments(text, precedingNode, enclosingNode, followingNode, comment, options) || handleTryStatementComments(enclosingNode, precedingNode, followingNode, comment) || handleClassComments(enclosingNode, precedingNode, followingNode, comment) || handleImportSpecifierComments(enclosingNode, comment) || handleForComments(enclosingNode, precedingNode, comment) || handleUnionTypeComments(precedingNode, enclosingNode, followingNode, comment) || handleOnlyComments(enclosingNode, ast, comment, isLastComment) || handleImportDeclarationComments(text, enclosingNode, precedingNode, comment, options) || handleAssignmentPatternComments(enclosingNode, comment) || handleMethodNameComments(text, enclosingNode, precedingNode, comment, options) || handleLabeledStatementComments(enclosingNode, comment); +function handleOwnLineComment(comment, text, options, ast, isLastComment) { + return handleIgnoreComments(comment) || handleLastFunctionArgComments(comment, text) || handleMemberExpressionComments(comment) || handleIfStatementComments(comment, text) || handleWhileComments(comment, text) || handleTryStatementComments(comment) || handleClassComments(comment) || handleImportSpecifierComments(comment) || handleForComments(comment) || handleUnionTypeComments(comment) || handleOnlyComments(comment, ast, isLastComment) || handleImportDeclarationComments(comment, text) || handleAssignmentPatternComments(comment) || handleMethodNameComments(comment, text) || handleLabeledStatementComments(comment); } function handleEndOfLineComment(comment, text, options, ast, isLastComment) { - const { - precedingNode, - enclosingNode, - followingNode - } = comment; - return handleClosureTypeCastComments(followingNode, comment) || handleLastFunctionArgComments(text, precedingNode, enclosingNode, followingNode, comment, options) || handleConditionalExpressionComments(enclosingNode, precedingNode, followingNode, comment, text, options) || handleImportSpecifierComments(enclosingNode, comment) || handleIfStatementComments(text, precedingNode, enclosingNode, followingNode, comment, options) || handleWhileComments(text, precedingNode, enclosingNode, followingNode, comment, options) || handleTryStatementComments(enclosingNode, precedingNode, followingNode, comment) || handleClassComments(enclosingNode, precedingNode, followingNode, comment) || handleLabeledStatementComments(enclosingNode, comment) || handleCallExpressionComments(precedingNode, enclosingNode, comment) || handlePropertyComments(enclosingNode, comment) || handleOnlyComments(enclosingNode, ast, comment, isLastComment) || handleTypeAliasComments(enclosingNode, followingNode, comment) || handleVariableDeclaratorComments(enclosingNode, followingNode, comment); + return handleClosureTypeCastComments(comment) || handleLastFunctionArgComments(comment, text) || handleConditionalExpressionComments(comment, text) || handleImportSpecifierComments(comment) || handleIfStatementComments(comment, text) || handleWhileComments(comment, text) || handleTryStatementComments(comment) || handleClassComments(comment) || handleLabeledStatementComments(comment) || handleCallExpressionComments(comment) || handlePropertyComments(comment) || handleOnlyComments(comment, ast, isLastComment) || handleTypeAliasComments(comment) || handleVariableDeclaratorComments(comment); } function handleRemainingComment(comment, text, options, ast, isLastComment) { - const { - precedingNode, - enclosingNode, - followingNode - } = comment; - - if (handleIfStatementComments(text, precedingNode, enclosingNode, followingNode, comment, options) || handleWhileComments(text, precedingNode, enclosingNode, followingNode, comment, options) || handleObjectPropertyAssignment(enclosingNode, precedingNode, comment) || handleCommentInEmptyParens(text, enclosingNode, comment, options) || handleMethodNameComments(text, enclosingNode, precedingNode, comment, options) || handleOnlyComments(enclosingNode, ast, comment, isLastComment) || handleCommentAfterArrowParams(text, enclosingNode, comment, options) || handleFunctionNameComments(text, enclosingNode, precedingNode, comment, options) || handleTSMappedTypeComments(text, enclosingNode, precedingNode, followingNode, comment) || handleBreakAndContinueStatementComments(enclosingNode, comment) || handleTSFunctionTrailingComments(text, enclosingNode, followingNode, comment, options)) { + if (handleIgnoreComments(comment) || handleIfStatementComments(comment, text) || handleWhileComments(comment, text) || handleObjectPropertyAssignment(comment) || handleCommentInEmptyParens(comment, text) || handleMethodNameComments(comment, text) || handleOnlyComments(comment, ast, isLastComment) || handleCommentAfterArrowParams(comment, text) || handleFunctionNameComments(comment, text) || handleTSMappedTypeComments(comment) || handleBreakAndContinueStatementComments(comment) || handleTSFunctionTrailingComments(comment, text)) { return true; } @@ -35959,12 +39342,14 @@ function handleRemainingComment(comment, text, options, ast, isLastComment) { } function addBlockStatementFirstComment(node, comment) { - const body = node.body.filter(n => n.type !== "EmptyStatement"); + const firstNonEmptyNode = (node.body || node.properties).find(({ + type + }) => type !== "EmptyStatement"); - if (body.length === 0) { - addDanglingComment$3(node, comment); + if (firstNonEmptyNode) { + addLeadingComment$3(firstNonEmptyNode, comment); } else { - addLeadingComment$3(body[0], comment); + addDanglingComment$3(node, comment); } } @@ -35976,7 +39361,11 @@ function addBlockOrNotComment(node, comment) { } } -function handleClosureTypeCastComments(followingNode, comment) { +function handleClosureTypeCastComments(comment) { + const { + followingNode + } = comment; + if (followingNode && isTypeCastComment(comment)) { addLeadingComment$3(followingNode, comment); return true; @@ -36001,7 +39390,13 @@ function handleClosureTypeCastComments(followingNode, comment) { // } -function handleIfStatementComments(text, precedingNode, enclosingNode, followingNode, comment, options) { +function handleIfStatementComments(comment, text) { + const { + precedingNode, + enclosingNode, + followingNode + } = comment; + if (!enclosingNode || enclosingNode.type !== "IfStatement" || !followingNode) { return false; } // We unfortunately have no way using the AST or location of nodes to know @@ -36011,7 +39406,7 @@ function handleIfStatementComments(text, precedingNode, enclosingNode, following // it is a ). - const nextCharacter = util$1.getNextNonSpaceNonCommentCharacter(text, comment, options.locEnd); + const nextCharacter = getNextNonSpaceNonCommentCharacter$1(text, comment, locEnd$3); if (nextCharacter === ")") { addTrailingComment$3(precedingNode, comment); @@ -36054,7 +39449,13 @@ function handleIfStatementComments(text, precedingNode, enclosingNode, following return false; } -function handleWhileComments(text, precedingNode, enclosingNode, followingNode, comment, options) { +function handleWhileComments(comment, text) { + const { + precedingNode, + enclosingNode, + followingNode + } = comment; + if (!enclosingNode || enclosingNode.type !== "WhileStatement" || !followingNode) { return false; } // We unfortunately have no way using the AST or location of nodes to know @@ -36064,7 +39465,7 @@ function handleWhileComments(text, precedingNode, enclosingNode, followingNode, // it is a ). - const nextCharacter = util$1.getNextNonSpaceNonCommentCharacter(text, comment, options.locEnd); + const nextCharacter = getNextNonSpaceNonCommentCharacter$1(text, comment, locEnd$3); if (nextCharacter === ")") { addTrailingComment$3(precedingNode, comment); @@ -36076,11 +39477,22 @@ function handleWhileComments(text, precedingNode, enclosingNode, followingNode, return true; } + if (enclosingNode.body === followingNode) { + addLeadingComment$3(followingNode, comment); + return true; + } + return false; } // Same as IfStatement but for TryStatement -function handleTryStatementComments(enclosingNode, precedingNode, followingNode, comment) { +function handleTryStatementComments(comment) { + const { + precedingNode, + enclosingNode, + followingNode + } = comment; + if (!enclosingNode || enclosingNode.type !== "TryStatement" && enclosingNode.type !== "CatchClause" || !followingNode) { return false; } @@ -36108,7 +39520,12 @@ function handleTryStatementComments(enclosingNode, precedingNode, followingNode, return false; } -function handleMemberExpressionComments(enclosingNode, followingNode, comment) { +function handleMemberExpressionComments(comment) { + const { + enclosingNode, + followingNode + } = comment; + if (enclosingNode && (enclosingNode.type === "MemberExpression" || enclosingNode.type === "OptionalMemberExpression") && followingNode && followingNode.type === "Identifier") { addLeadingComment$3(enclosingNode, comment); return true; @@ -36117,10 +39534,15 @@ function handleMemberExpressionComments(enclosingNode, followingNode, comment) { return false; } -function handleConditionalExpressionComments(enclosingNode, precedingNode, followingNode, comment, text, options) { - const isSameLineAsPrecedingNode = precedingNode && !util$1.hasNewlineInRange(text, options.locEnd(precedingNode), options.locStart(comment)); +function handleConditionalExpressionComments(comment, text) { + const { + precedingNode, + enclosingNode, + followingNode + } = comment; + const isSameLineAsPrecedingNode = precedingNode && !hasNewlineInRange$3(text, locEnd$3(precedingNode), locStart$3(comment)); - if ((!precedingNode || !isSameLineAsPrecedingNode) && enclosingNode && enclosingNode.type === "ConditionalExpression" && followingNode) { + if ((!precedingNode || !isSameLineAsPrecedingNode) && enclosingNode && (enclosingNode.type === "ConditionalExpression" || enclosingNode.type === "TSConditionalType") && followingNode) { addLeadingComment$3(followingNode, comment); return true; } @@ -36128,7 +39550,12 @@ function handleConditionalExpressionComments(enclosingNode, precedingNode, follo return false; } -function handleObjectPropertyAssignment(enclosingNode, precedingNode, comment) { +function handleObjectPropertyAssignment(comment) { + const { + precedingNode, + enclosingNode + } = comment; + if (enclosingNode && (enclosingNode.type === "ObjectProperty" || enclosingNode.type === "Property") && enclosingNode.shorthand && enclosingNode.key === precedingNode && enclosingNode.value.type === "AssignmentPattern") { addTrailingComment$3(enclosingNode.value.left, comment); return true; @@ -36137,1998 +39564,1602 @@ function handleObjectPropertyAssignment(enclosingNode, precedingNode, comment) { return false; } -function handleClassComments(enclosingNode, precedingNode, followingNode, comment) { - if (enclosingNode && (enclosingNode.type === "ClassDeclaration" || enclosingNode.type === "ClassExpression") && enclosingNode.decorators && enclosingNode.decorators.length > 0 && !(followingNode && followingNode.type === "Decorator")) { - if (!enclosingNode.decorators || enclosingNode.decorators.length === 0) { - addLeadingComment$3(enclosingNode, comment); - } else { - addTrailingComment$3(enclosingNode.decorators[enclosingNode.decorators.length - 1], comment); - } - - return true; - } - - return false; -} - -function handleMethodNameComments(text, enclosingNode, precedingNode, comment, options) { - // This is only needed for estree parsers (flow, typescript) to attach - // after a method name: - // obj = { fn /*comment*/() {} }; - if (enclosingNode && precedingNode && ( // "MethodDefinition" is handled in getCommentChildNodes - enclosingNode.type === "Property" || enclosingNode.type === "TSDeclareMethod" || enclosingNode.type === "TSAbstractMethodDefinition") && precedingNode.type === "Identifier" && enclosingNode.key === precedingNode && // special Property case: { key: /*comment*/(value) }; - // comment should be attached to value instead of key - util$1.getNextNonSpaceNonCommentCharacter(text, precedingNode, options.locEnd) !== ":") { - addTrailingComment$3(precedingNode, comment); - return true; - } // Print comments between decorators and class methods as a trailing comment - // on the decorator node instead of the method node - - - if (precedingNode && enclosingNode && precedingNode.type === "Decorator" && (enclosingNode.type === "ClassMethod" || enclosingNode.type === "ClassProperty" || enclosingNode.type === "TSAbstractClassProperty" || enclosingNode.type === "TSAbstractMethodDefinition" || enclosingNode.type === "TSDeclareMethod" || enclosingNode.type === "MethodDefinition")) { - addTrailingComment$3(precedingNode, comment); - return true; - } - - return false; -} - -function handleFunctionNameComments(text, enclosingNode, precedingNode, comment, options) { - if (util$1.getNextNonSpaceNonCommentCharacter(text, comment, options.locEnd) !== "(") { - return false; - } - - if (precedingNode && enclosingNode && (enclosingNode.type === "FunctionDeclaration" || enclosingNode.type === "FunctionExpression" || enclosingNode.type === "ClassMethod" || enclosingNode.type === "MethodDefinition" || enclosingNode.type === "ObjectMethod")) { - addTrailingComment$3(precedingNode, comment); - return true; - } - - return false; -} - -function handleCommentAfterArrowParams(text, enclosingNode, comment, options) { - if (!(enclosingNode && enclosingNode.type === "ArrowFunctionExpression")) { - return false; - } - - const index = getNextNonSpaceNonCommentCharacterIndex$2(text, comment, options.locEnd); - - if (text.slice(index, index + 2) === "=>") { - addDanglingComment$3(enclosingNode, comment); - return true; - } - - return false; -} - -function handleCommentInEmptyParens(text, enclosingNode, comment, options) { - if (util$1.getNextNonSpaceNonCommentCharacter(text, comment, options.locEnd) !== ")") { - return false; - } // Only add dangling comments to fix the case when no params are present, - // i.e. a function without any argument. - - - if (enclosingNode && (isRealFunctionLikeNode(enclosingNode) && // `params` vs `parameters` - see https://github.com/babel/babel/issues/9231 - (enclosingNode.params || enclosingNode.parameters).length === 0 || (enclosingNode.type === "CallExpression" || enclosingNode.type === "OptionalCallExpression" || enclosingNode.type === "NewExpression") && enclosingNode.arguments.length === 0)) { - addDanglingComment$3(enclosingNode, comment); - return true; - } - - if (enclosingNode && enclosingNode.type === "MethodDefinition" && enclosingNode.value.params.length === 0) { - addDanglingComment$3(enclosingNode.value, comment); - return true; - } - - return false; -} - -function handleLastFunctionArgComments(text, precedingNode, enclosingNode, followingNode, comment, options) { - // Flow function type definitions - if (precedingNode && precedingNode.type === "FunctionTypeParam" && enclosingNode && enclosingNode.type === "FunctionTypeAnnotation" && followingNode && followingNode.type !== "FunctionTypeParam") { - addTrailingComment$3(precedingNode, comment); - return true; - } // Real functions and TypeScript function type definitions - - - if (precedingNode && (precedingNode.type === "Identifier" || precedingNode.type === "AssignmentPattern") && enclosingNode && isRealFunctionLikeNode(enclosingNode) && util$1.getNextNonSpaceNonCommentCharacter(text, comment, options.locEnd) === ")") { - addTrailingComment$3(precedingNode, comment); - return true; - } - - if (enclosingNode && enclosingNode.type === "FunctionDeclaration" && followingNode && followingNode.type === "BlockStatement") { - const functionParamRightParenIndex = (() => { - if ((enclosingNode.params || enclosingNode.parameters).length !== 0) { - return util$1.getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, options.locEnd(util$1.getLast(enclosingNode.params || enclosingNode.parameters))); - } - - const functionParamLeftParenIndex = util$1.getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, options.locEnd(enclosingNode.id)); - return util$1.getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, functionParamLeftParenIndex + 1); - })(); - - if (options.locStart(comment) > functionParamRightParenIndex) { - addBlockStatementFirstComment(followingNode, comment); - return true; - } - } - - return false; -} - -function handleImportSpecifierComments(enclosingNode, comment) { - if (enclosingNode && enclosingNode.type === "ImportSpecifier") { - addLeadingComment$3(enclosingNode, comment); - return true; - } - - return false; -} - -function handleLabeledStatementComments(enclosingNode, comment) { - if (enclosingNode && enclosingNode.type === "LabeledStatement") { - addLeadingComment$3(enclosingNode, comment); - return true; - } - - return false; -} - -function handleBreakAndContinueStatementComments(enclosingNode, comment) { - if (enclosingNode && (enclosingNode.type === "ContinueStatement" || enclosingNode.type === "BreakStatement") && !enclosingNode.label) { - addTrailingComment$3(enclosingNode, comment); - return true; - } - - return false; -} - -function handleCallExpressionComments(precedingNode, enclosingNode, comment) { - if (enclosingNode && (enclosingNode.type === "CallExpression" || enclosingNode.type === "OptionalCallExpression") && precedingNode && enclosingNode.callee === precedingNode && enclosingNode.arguments.length > 0) { - addLeadingComment$3(enclosingNode.arguments[0], comment); - return true; - } - - return false; -} - -function handleUnionTypeComments(precedingNode, enclosingNode, followingNode, comment) { - if (enclosingNode && (enclosingNode.type === "UnionTypeAnnotation" || enclosingNode.type === "TSUnionType")) { - if (util$1.isNodeIgnoreComment(comment)) { - followingNode.prettierIgnore = true; - comment.unignore = true; - } - - if (precedingNode) { - addTrailingComment$3(precedingNode, comment); - return true; - } - - return false; - } - - if (followingNode && (followingNode.type === "UnionTypeAnnotation" || followingNode.type === "TSUnionType") && util$1.isNodeIgnoreComment(comment)) { - followingNode.types[0].prettierIgnore = true; - comment.unignore = true; - } - - return false; -} - -function handlePropertyComments(enclosingNode, comment) { - if (enclosingNode && (enclosingNode.type === "Property" || enclosingNode.type === "ObjectProperty")) { - addLeadingComment$3(enclosingNode, comment); - return true; - } - - return false; -} - -function handleOnlyComments(enclosingNode, ast, comment, isLastComment) { - // With Flow the enclosingNode is undefined so use the AST instead. - if (ast && ast.body && ast.body.length === 0) { - if (isLastComment) { - addDanglingComment$3(ast, comment); - } else { - addLeadingComment$3(ast, comment); - } - - return true; - } else if (enclosingNode && enclosingNode.type === "Program" && enclosingNode.body.length === 0 && enclosingNode.directives && enclosingNode.directives.length === 0) { - if (isLastComment) { - addDanglingComment$3(enclosingNode, comment); - } else { - addLeadingComment$3(enclosingNode, comment); - } - - return true; - } - - return false; -} - -function handleForComments(enclosingNode, precedingNode, comment) { - if (enclosingNode && (enclosingNode.type === "ForInStatement" || enclosingNode.type === "ForOfStatement")) { - addLeadingComment$3(enclosingNode, comment); - return true; - } - - return false; -} - -function handleImportDeclarationComments(text, enclosingNode, precedingNode, comment, options) { - if (precedingNode && precedingNode.type === "ImportSpecifier" && enclosingNode && enclosingNode.type === "ImportDeclaration" && util$1.hasNewline(text, options.locEnd(comment))) { - addTrailingComment$3(precedingNode, comment); - return true; - } - - return false; -} - -function handleAssignmentPatternComments(enclosingNode, comment) { - if (enclosingNode && enclosingNode.type === "AssignmentPattern") { - addLeadingComment$3(enclosingNode, comment); - return true; - } - - return false; -} - -function handleTypeAliasComments(enclosingNode, followingNode, comment) { - if (enclosingNode && enclosingNode.type === "TypeAlias") { - addLeadingComment$3(enclosingNode, comment); - return true; - } - - return false; -} - -function handleVariableDeclaratorComments(enclosingNode, followingNode, comment) { - if (enclosingNode && (enclosingNode.type === "VariableDeclarator" || enclosingNode.type === "AssignmentExpression") && followingNode && (followingNode.type === "ObjectExpression" || followingNode.type === "ArrayExpression" || followingNode.type === "TemplateLiteral" || followingNode.type === "TaggedTemplateExpression" || isBlockComment(comment))) { - addLeadingComment$3(followingNode, comment); - return true; - } - - return false; -} - -function handleTSFunctionTrailingComments(text, enclosingNode, followingNode, comment, options) { - if (!followingNode && enclosingNode && (enclosingNode.type === "TSMethodSignature" || enclosingNode.type === "TSDeclareFunction" || enclosingNode.type === "TSAbstractMethodDefinition") && util$1.getNextNonSpaceNonCommentCharacter(text, comment, options.locEnd) === ";") { - addTrailingComment$3(enclosingNode, comment); - return true; - } - - return false; -} - -function handleTSMappedTypeComments(text, enclosingNode, precedingNode, followingNode, comment) { - if (!enclosingNode || enclosingNode.type !== "TSMappedType") { - return false; - } - - if (followingNode && followingNode.type === "TSTypeParameter" && followingNode.name) { - addLeadingComment$3(followingNode.name, comment); - return true; - } - - if (precedingNode && precedingNode.type === "TSTypeParameter" && precedingNode.constraint) { - addTrailingComment$3(precedingNode.constraint, comment); - return true; - } - - return false; -} - -function isBlockComment(comment) { - return comment.type === "Block" || comment.type === "CommentBlock"; -} - -function hasLeadingComment(node, fn = () => true) { - if (node.leadingComments) { - return node.leadingComments.some(fn); - } - - if (node.comments) { - return node.comments.some(comment => comment.leading && fn(comment)); - } - - return false; -} - -function isRealFunctionLikeNode(node) { - return node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression" || node.type === "FunctionDeclaration" || node.type === "ObjectMethod" || node.type === "ClassMethod" || node.type === "TSDeclareFunction" || node.type === "TSCallSignatureDeclaration" || node.type === "TSConstructSignatureDeclaration" || node.type === "TSConstructSignatureDeclaration" || node.type === "TSMethodSignature" || node.type === "TSConstructorType" || node.type === "TSFunctionType" || node.type === "TSDeclareMethod"; -} - -function getGapRegex(enclosingNode) { - if (enclosingNode && enclosingNode.type !== "BinaryExpression" && enclosingNode.type !== "LogicalExpression") { - // Support degenerate single-element unions and intersections. - // E.g.: `type A = /* 1 */ & B` - return /^[\s(&|]*$/; - } -} - -function getCommentChildNodes(node, options) { - // Prevent attaching comments to FunctionExpression in this case: - // class Foo { - // bar() // comment - // { - // baz(); - // } - // } - if ((options.parser === "typescript" || options.parser === "flow") && node.type === "MethodDefinition" && node.value && node.value.type === "FunctionExpression" && node.value.params.length === 0 && !node.value.returnType && (!node.value.typeParameters || node.value.typeParameters.length === 0) && node.value.body) { - return [...(node.decorators || []), node.key, node.value.body]; - } -} - -function isTypeCastComment(comment) { - return isBlockComment(comment) && comment.value[0] === "*" && // TypeScript expects the type to be enclosed in curly brackets, however - // Closure Compiler accepts types in parens and even without any delimiters at all. - // That's why we just search for "@type". - /@type\b/.test(comment.value); -} - -var comments$1 = { - handleOwnLineComment, - handleEndOfLineComment, - handleRemainingComment, - hasLeadingComment, - isBlockComment, - isTypeCastComment, - getGapRegex, - getCommentChildNodes -}; - -const { - isBlockComment: isBlockComment$1, - hasLeadingComment: hasLeadingComment$1 -} = comments$1; -const { - builders: { - indent: indent$2, - join: join$2, - line: line$2, - hardline: hardline$3, - softline: softline$1, - literalline: literalline$1, - concat: concat$4, - group: group$1, - dedentToRoot: dedentToRoot$1 - }, - utils: { - mapDoc: mapDoc$1, - stripTrailingHardline: stripTrailingHardline$1 - } -} = document; - -function embed(path, print, textToDoc, options) { - const node = path.getValue(); - const parent = path.getParentNode(); - const parentParent = path.getParentNode(1); - - switch (node.type) { - case "TemplateLiteral": - { - const isCss = [isStyledJsx, isStyledComponents, isCssProp, isAngularComponentStyles].some(isIt => isIt(path)); - - if (isCss) { - // Get full template literal with expressions replaced by placeholders - const rawQuasis = node.quasis.map(q => q.value.raw); - let placeholderID = 0; - const text = rawQuasis.reduce((prevVal, currVal, idx) => { - return idx === 0 ? currVal : prevVal + "@prettier-placeholder-" + placeholderID++ + "-id" + currVal; - }, ""); - const doc = textToDoc(text, { - parser: "scss" - }); - return transformCssDoc(doc, path, print); - } - /* - * react-relay and graphql-tag - * graphql`...` - * graphql.experimental`...` - * gql`...` - * - * This intentionally excludes Relay Classic tags, as Prettier does not - * support Relay Classic formatting. - */ - - - if (isGraphQL(path)) { - const expressionDocs = node.expressions ? path.map(print, "expressions") : []; - const numQuasis = node.quasis.length; - - if (numQuasis === 1 && node.quasis[0].value.raw.trim() === "") { - return "``"; - } - - const parts = []; - - for (let i = 0; i < numQuasis; i++) { - const templateElement = node.quasis[i]; - const isFirst = i === 0; - const isLast = i === numQuasis - 1; - const text = templateElement.value.cooked; // Bail out if any of the quasis have an invalid escape sequence - // (which would make the `cooked` value be `null` or `undefined`) - - if (typeof text !== "string") { - return null; - } - - const lines = text.split("\n"); - const numLines = lines.length; - const expressionDoc = expressionDocs[i]; - const startsWithBlankLine = numLines > 2 && lines[0].trim() === "" && lines[1].trim() === ""; - const endsWithBlankLine = numLines > 2 && lines[numLines - 1].trim() === "" && lines[numLines - 2].trim() === ""; - const commentsAndWhitespaceOnly = lines.every(line => /^\s*(?:#[^\r\n]*)?$/.test(line)); // Bail out if an interpolation occurs within a comment. - - if (!isLast && /#[^\r\n]*$/.test(lines[numLines - 1])) { - return null; - } - - let doc = null; - - if (commentsAndWhitespaceOnly) { - doc = printGraphqlComments(lines); - } else { - doc = stripTrailingHardline$1(textToDoc(text, { - parser: "graphql" - })); - } - - if (doc) { - doc = escapeTemplateCharacters(doc, false); - - if (!isFirst && startsWithBlankLine) { - parts.push(""); - } - - parts.push(doc); - - if (!isLast && endsWithBlankLine) { - parts.push(""); - } - } else if (!isFirst && !isLast && startsWithBlankLine) { - parts.push(""); - } - - if (expressionDoc) { - parts.push(concat$4(["${", expressionDoc, "}"])); - } - } - - return concat$4(["`", indent$2(concat$4([hardline$3, join$2(hardline$3, parts)])), hardline$3, "`"]); - } - - const htmlParser = isHtml(path) ? "html" : isAngularComponentTemplate(path) ? "angular" : undefined; - - if (htmlParser) { - return printHtmlTemplateLiteral(path, print, textToDoc, htmlParser, options); - } - - break; - } - - case "TemplateElement": - { - /** - * md`...` - * markdown`...` - */ - if (parentParent && parentParent.type === "TaggedTemplateExpression" && parent.quasis.length === 1 && parentParent.tag.type === "Identifier" && (parentParent.tag.name === "md" || parentParent.tag.name === "markdown")) { - const text = parent.quasis[0].value.raw.replace(/((?:\\\\)*)\\`/g, (_, backslashes) => "\\".repeat(backslashes.length / 2) + "`"); - const indentation = getIndentation(text); - const hasIndent = indentation !== ""; - return concat$4([hasIndent ? indent$2(concat$4([softline$1, printMarkdown(text.replace(new RegExp(`^${indentation}`, "gm"), ""))])) : concat$4([literalline$1, dedentToRoot$1(printMarkdown(text))]), softline$1]); - } - - break; - } - } - - function printMarkdown(text) { - const doc = textToDoc(text, { - parser: "markdown", - __inJsTemplate: true - }); - return stripTrailingHardline$1(escapeTemplateCharacters(doc, true)); - } -} - -function getIndentation(str) { - const firstMatchedIndent = str.match(/^([^\S\n]*)\S/m); - return firstMatchedIndent === null ? "" : firstMatchedIndent[1]; -} - -function uncook(cookedValue) { - return cookedValue.replace(/([\\`]|\$\{)/g, "\\$1"); -} - -function escapeTemplateCharacters(doc, raw) { - return mapDoc$1(doc, currentDoc => { - if (!currentDoc.parts) { - return currentDoc; - } - - const parts = []; - currentDoc.parts.forEach(part => { - if (typeof part === "string") { - parts.push(raw ? part.replace(/(\\*)`/g, "$1$1\\`") : uncook(part)); - } else { - parts.push(part); - } - }); - return Object.assign({}, currentDoc, { - parts - }); - }); -} - -function transformCssDoc(quasisDoc, path, print) { - const parentNode = path.getValue(); - const isEmpty = parentNode.quasis.length === 1 && !parentNode.quasis[0].value.raw.trim(); - - if (isEmpty) { - return "``"; - } - - const expressionDocs = parentNode.expressions ? path.map(print, "expressions") : []; - const newDoc = replacePlaceholders(quasisDoc, expressionDocs); - /* istanbul ignore if */ - - if (!newDoc) { - throw new Error("Couldn't insert all the expressions"); - } - - return concat$4(["`", indent$2(concat$4([hardline$3, stripTrailingHardline$1(newDoc)])), softline$1, "`"]); -} // Search all the placeholders in the quasisDoc tree -// and replace them with the expression docs one by one -// returns a new doc with all the placeholders replaced, -// or null if it couldn't replace any expression - - -function replacePlaceholders(quasisDoc, expressionDocs) { - if (!expressionDocs || !expressionDocs.length) { - return quasisDoc; - } - - const expressions = expressionDocs.slice(); - let replaceCounter = 0; - const newDoc = mapDoc$1(quasisDoc, doc => { - if (!doc || !doc.parts || !doc.parts.length) { - return doc; - } - - let { - parts - } = doc; - const atIndex = parts.indexOf("@"); - const placeholderIndex = atIndex + 1; - - if (atIndex > -1 && typeof parts[placeholderIndex] === "string" && parts[placeholderIndex].startsWith("prettier-placeholder")) { - // If placeholder is split, join it - const at = parts[atIndex]; - const placeholder = parts[placeholderIndex]; - const rest = parts.slice(placeholderIndex + 1); - parts = parts.slice(0, atIndex).concat([at + placeholder]).concat(rest); - } - - const atPlaceholderIndex = parts.findIndex(part => typeof part === "string" && part.startsWith("@prettier-placeholder")); - - if (atPlaceholderIndex > -1) { - const placeholder = parts[atPlaceholderIndex]; - const rest = parts.slice(atPlaceholderIndex + 1); - const placeholderMatch = placeholder.match(/@prettier-placeholder-(.+)-id([\s\S]*)/); - const placeholderID = placeholderMatch[1]; // When the expression has a suffix appended, like: - // animation: linear ${time}s ease-out; - - const suffix = placeholderMatch[2]; - const expression = expressions[placeholderID]; - replaceCounter++; - parts = parts.slice(0, atPlaceholderIndex).concat(["${", expression, "}" + suffix]).concat(rest); - } - - return Object.assign({}, doc, { - parts - }); - }); - return expressions.length === replaceCounter ? newDoc : null; -} - -function printGraphqlComments(lines) { - const parts = []; - let seenComment = false; - lines.map(textLine => textLine.trim()).forEach((textLine, i, array) => { - // Lines are either whitespace only, or a comment (with potential whitespace - // around it). Drop whitespace-only lines. - if (textLine === "") { - return; - } +function handleClassComments(comment) { + const { + precedingNode, + enclosingNode, + followingNode + } = comment; - if (array[i - 1] === "" && seenComment) { - // If a non-first comment is preceded by a blank (whitespace only) line, - // add in a blank line. - parts.push(concat$4([hardline$3, textLine])); - } else { - parts.push(textLine); + if (enclosingNode && (enclosingNode.type === "ClassDeclaration" || enclosingNode.type === "ClassExpression" || enclosingNode.type === "DeclareClass" || enclosingNode.type === "DeclareInterface" || enclosingNode.type === "InterfaceDeclaration" || enclosingNode.type === "TSInterfaceDeclaration")) { + if (enclosingNode.decorators && enclosingNode.decorators.length > 0 && !(followingNode && followingNode.type === "Decorator")) { + addTrailingComment$3(enclosingNode.decorators[enclosingNode.decorators.length - 1], comment); + return true; } - seenComment = true; - }); // If `lines` was whitespace only, return `null`. + if (enclosingNode.body && followingNode === enclosingNode.body) { + addBlockStatementFirstComment(enclosingNode.body, comment); + return true; + } // Don't add leading comments to `implements`, `extends`, `mixins` to + // avoid printing the comment after the keyword. - return parts.length === 0 ? null : join$2(hardline$3, parts); -} -/** - * Template literal in these contexts: - * - * css`` - * css.global`` - * css.resolve`` - */ + if (followingNode) { + for (const prop of ["implements", "extends", "mixins"]) { + if (enclosingNode[prop] && followingNode === enclosingNode[prop][0]) { + if (precedingNode && (precedingNode === enclosingNode.id || precedingNode === enclosingNode.typeParameters || precedingNode === enclosingNode.superClass)) { + addTrailingComment$3(precedingNode, comment); + } else { + addDanglingComment$3(enclosingNode, comment, prop); + } -function isStyledJsx(path) { - const node = path.getValue(); - const parent = path.getParentNode(); - const parentParent = path.getParentNode(1); - return parentParent && node.quasis && parent.type === "JSXExpressionContainer" && parentParent.type === "JSXElement" && parentParent.openingElement.name.name === "style" && parentParent.openingElement.attributes.some(attribute => attribute.name.name === "jsx") || parent && parent.type === "TaggedTemplateExpression" && parent.tag.type === "Identifier" && parent.tag.name === "css" || parent && parent.type === "TaggedTemplateExpression" && parent.tag.type === "MemberExpression" && parent.tag.object.name === "css" && (parent.tag.property.name === "global" || parent.tag.property.name === "resolve"); + return true; + } + } + } + } + + return false; } -/** - * Angular Components can have: - * - Inline HTML template - * - Inline CSS styles - * - * ...which are both within template literals somewhere - * inside of the Component decorator factory. - * - * E.g. - * @Component({ - * template: `
...
`, - * styles: [`h1 { color: blue; }`] - * }) - */ +function handleMethodNameComments(comment, text) { + const { + precedingNode, + enclosingNode + } = comment; // This is only needed for estree parsers (flow, typescript) to attach + // after a method name: + // obj = { fn /*comment*/() {} }; -function isAngularComponentStyles(path) { - return path.match(node => node.type === "TemplateLiteral", (node, name) => node.type === "ArrayExpression" && name === "elements", (node, name) => (node.type === "Property" || node.type === "ObjectProperty") && node.key.type === "Identifier" && node.key.name === "styles" && name === "value", ...angularComponentObjectExpressionPredicates); -} + if (enclosingNode && precedingNode && ( // "MethodDefinition" is handled in getCommentChildNodes + enclosingNode.type === "Property" || enclosingNode.type === "TSDeclareMethod" || enclosingNode.type === "TSAbstractMethodDefinition") && precedingNode.type === "Identifier" && enclosingNode.key === precedingNode && // special Property case: { key: /*comment*/(value) }; + // comment should be attached to value instead of key + getNextNonSpaceNonCommentCharacter$1(text, precedingNode, locEnd$3) !== ":") { + addTrailingComment$3(precedingNode, comment); + return true; + } // Print comments between decorators and class methods as a trailing comment + // on the decorator node instead of the method node -function isAngularComponentTemplate(path) { - return path.match(node => node.type === "TemplateLiteral", (node, name) => (node.type === "Property" || node.type === "ObjectProperty") && node.key.type === "Identifier" && node.key.name === "template" && name === "value", ...angularComponentObjectExpressionPredicates); -} -const angularComponentObjectExpressionPredicates = [(node, name) => node.type === "ObjectExpression" && name === "properties", (node, name) => node.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === "Component" && name === "arguments", (node, name) => node.type === "Decorator" && name === "expression"]; -/** - * styled-components template literals - */ + if (precedingNode && enclosingNode && precedingNode.type === "Decorator" && (enclosingNode.type === "ClassMethod" || enclosingNode.type === "ClassProperty" || enclosingNode.type === "FieldDefinition" || enclosingNode.type === "TSAbstractClassProperty" || enclosingNode.type === "TSAbstractMethodDefinition" || enclosingNode.type === "TSDeclareMethod" || enclosingNode.type === "MethodDefinition")) { + addTrailingComment$3(precedingNode, comment); + return true; + } -function isStyledComponents(path) { - const parent = path.getParentNode(); + return false; +} - if (!parent || parent.type !== "TaggedTemplateExpression") { +function handleFunctionNameComments(comment, text) { + if (getNextNonSpaceNonCommentCharacter$1(text, comment, locEnd$3) !== "(") { return false; } const { - tag - } = parent; + precedingNode, + enclosingNode + } = comment; - switch (tag.type) { - case "MemberExpression": - return (// styled.foo`` - isStyledIdentifier(tag.object) || // Component.extend`` - isStyledExtend(tag) - ); + if (precedingNode && enclosingNode && (enclosingNode.type === "FunctionDeclaration" || enclosingNode.type === "FunctionExpression" || enclosingNode.type === "ClassMethod" || enclosingNode.type === "MethodDefinition" || enclosingNode.type === "ObjectMethod")) { + addTrailingComment$3(precedingNode, comment); + return true; + } - case "CallExpression": - return (// styled(Component)`` - isStyledIdentifier(tag.callee) || tag.callee.type === "MemberExpression" && (tag.callee.object.type === "MemberExpression" && ( // styled.foo.attrs({})`` - isStyledIdentifier(tag.callee.object.object) || // Component.extend.attrs({})`` - isStyledExtend(tag.callee.object)) || // styled(Component).attrs({})`` - tag.callee.object.type === "CallExpression" && isStyledIdentifier(tag.callee.object.callee)) - ); + return false; +} - case "Identifier": - // css`` - return tag.name === "css"; +function handleCommentAfterArrowParams(comment, text) { + const { + enclosingNode + } = comment; - default: - return false; + if (!(enclosingNode && enclosingNode.type === "ArrowFunctionExpression")) { + return false; } -} -/** - * JSX element with CSS prop - */ + const index = getNextNonSpaceNonCommentCharacterIndex$2(text, comment, locEnd$3); -function isCssProp(path) { - const parent = path.getParentNode(); - const parentParent = path.getParentNode(1); - return parentParent && parent.type === "JSXExpressionContainer" && parentParent.type === "JSXAttribute" && parentParent.name.type === "JSXIdentifier" && parentParent.name.name === "css"; -} + if (index !== false && text.slice(index, index + 2) === "=>") { + addDanglingComment$3(enclosingNode, comment); + return true; + } -function isStyledIdentifier(node) { - return node.type === "Identifier" && node.name === "styled"; + return false; } -function isStyledExtend(node) { - return /^[A-Z]/.test(node.object.name) && node.property.name === "extend"; -} -/* - * react-relay and graphql-tag - * graphql`...` - * graphql.experimental`...` - * gql`...` - * GraphQL comment block - * - * This intentionally excludes Relay Classic tags, as Prettier does not - * support Relay Classic formatting. - */ +function handleCommentInEmptyParens(comment, text) { + if (getNextNonSpaceNonCommentCharacter$1(text, comment, locEnd$3) !== ")") { + return false; + } + const { + enclosingNode + } = comment; // Only add dangling comments to fix the case when no params are present, + // i.e. a function without any argument. -function isGraphQL(path) { - const node = path.getValue(); - const parent = path.getParentNode(); - return hasLanguageComment(node, "GraphQL") || parent && (parent.type === "TaggedTemplateExpression" && (parent.tag.type === "MemberExpression" && parent.tag.object.name === "graphql" && parent.tag.property.name === "experimental" || parent.tag.type === "Identifier" && (parent.tag.name === "gql" || parent.tag.name === "graphql")) || parent.type === "CallExpression" && parent.callee.type === "Identifier" && parent.callee.name === "graphql"); -} + if (enclosingNode && (isRealFunctionLikeNode(enclosingNode) && getFunctionParameters$1(enclosingNode).length === 0 || (enclosingNode.type === "CallExpression" || enclosingNode.type === "OptionalCallExpression" || enclosingNode.type === "NewExpression") && enclosingNode.arguments.length === 0)) { + addDanglingComment$3(enclosingNode, comment); + return true; + } -function hasLanguageComment(node, languageName) { - // This checks for a leading comment that is exactly `/* GraphQL */` - // In order to be in line with other implementations of this comment tag - // we will not trim the comment value and we will expect exactly one space on - // either side of the GraphQL string - // Also see ./clean.js - return hasLeadingComment$1(node, comment => isBlockComment$1(comment) && comment.value === ` ${languageName} `); + if (enclosingNode && enclosingNode.type === "MethodDefinition" && getFunctionParameters$1(enclosingNode.value).length === 0) { + addDanglingComment$3(enclosingNode.value, comment); + return true; + } + + return false; } -/** - * - html`...` - * - HTML comment block - */ +function handleLastFunctionArgComments(comment, text) { + const { + precedingNode, + enclosingNode, + followingNode + } = comment; // Flow function type definitions -function isHtml(path) { - return hasLanguageComment(path.getValue(), "HTML") || path.match(node => node.type === "TemplateLiteral", (node, name) => node.type === "TaggedTemplateExpression" && node.tag.type === "Identifier" && node.tag.name === "html" && name === "quasi"); -} // The counter is needed to distinguish nested embeds. + if (precedingNode && precedingNode.type === "FunctionTypeParam" && enclosingNode && enclosingNode.type === "FunctionTypeAnnotation" && followingNode && followingNode.type !== "FunctionTypeParam") { + addTrailingComment$3(precedingNode, comment); + return true; + } // Real functions and TypeScript function type definitions -let htmlTemplateLiteralCounter = 0; + if (precedingNode && (precedingNode.type === "Identifier" || precedingNode.type === "AssignmentPattern") && enclosingNode && isRealFunctionLikeNode(enclosingNode) && getNextNonSpaceNonCommentCharacter$1(text, comment, locEnd$3) === ")") { + addTrailingComment$3(precedingNode, comment); + return true; + } -function printHtmlTemplateLiteral(path, print, textToDoc, parser, options) { - const node = path.getValue(); - const counter = htmlTemplateLiteralCounter; - htmlTemplateLiteralCounter = htmlTemplateLiteralCounter + 1 >>> 0; + if (enclosingNode && enclosingNode.type === "FunctionDeclaration" && followingNode && followingNode.type === "BlockStatement") { + const functionParamRightParenIndex = (() => { + const parameters = getFunctionParameters$1(enclosingNode); - const composePlaceholder = index => `PRETTIER_HTML_PLACEHOLDER_${index}_${counter}_IN_JS`; + if (parameters.length !== 0) { + return getNextNonSpaceNonCommentCharacterIndexWithStartIndex$1(text, locEnd$3(getLast$2(parameters))); + } - const text = node.quasis.map((quasi, index, quasis) => index === quasis.length - 1 ? quasi.value.cooked : quasi.value.cooked + composePlaceholder(index)).join(""); - const expressionDocs = path.map(print, "expressions"); + const functionParamLeftParenIndex = getNextNonSpaceNonCommentCharacterIndexWithStartIndex$1(text, locEnd$3(enclosingNode.id)); + return functionParamLeftParenIndex !== false && getNextNonSpaceNonCommentCharacterIndexWithStartIndex$1(text, functionParamLeftParenIndex + 1); + })(); - if (expressionDocs.length === 0 && text.trim().length === 0) { - return "``"; + if (locStart$3(comment) > functionParamRightParenIndex) { + addBlockStatementFirstComment(followingNode, comment); + return true; + } } - const placeholderRegex = new RegExp(composePlaceholder("(\\d+)"), "g"); - let topLevelCount = 0; - const contentDoc = mapDoc$1(stripTrailingHardline$1(textToDoc(text, { - parser, + return false; +} - __onHtmlRoot(root) { - topLevelCount = root.children.length; - } +function handleImportSpecifierComments(comment) { + const { + enclosingNode + } = comment; - })), doc => { - if (typeof doc !== "string") { - return doc; - } + if (enclosingNode && enclosingNode.type === "ImportSpecifier") { + addLeadingComment$3(enclosingNode, comment); + return true; + } - const parts = []; - const components = doc.split(placeholderRegex); + return false; +} - for (let i = 0; i < components.length; i++) { - let component = components[i]; +function handleLabeledStatementComments(comment) { + const { + enclosingNode + } = comment; - if (i % 2 === 0) { - if (component) { - component = uncook(component); + if (enclosingNode && enclosingNode.type === "LabeledStatement") { + addLeadingComment$3(enclosingNode, comment); + return true; + } - if (options.embeddedInHtml) { - component = component.replace(/<\/(script)\b/gi, "<\\/$1"); - } + return false; +} - parts.push(component); - } +function handleBreakAndContinueStatementComments(comment) { + const { + enclosingNode + } = comment; - continue; - } + if (enclosingNode && (enclosingNode.type === "ContinueStatement" || enclosingNode.type === "BreakStatement") && !enclosingNode.label) { + addTrailingComment$3(enclosingNode, comment); + return true; + } - const placeholderIndex = +component; - parts.push(concat$4(["${", group$1(expressionDocs[placeholderIndex]), "}"])); - } + return false; +} - return concat$4(parts); - }); - const leadingWhitespace = /^\s/.test(text) ? " " : ""; - const trailingWhitespace = /\s$/.test(text) ? " " : ""; - const linebreak = options.htmlWhitespaceSensitivity === "ignore" ? hardline$3 : leadingWhitespace && trailingWhitespace ? line$2 : null; +function handleCallExpressionComments(comment) { + const { + precedingNode, + enclosingNode + } = comment; - if (linebreak) { - return group$1(concat$4(["`", indent$2(concat$4([linebreak, group$1(contentDoc)])), linebreak, "`"])); + if (enclosingNode && (enclosingNode.type === "CallExpression" || enclosingNode.type === "OptionalCallExpression") && precedingNode && enclosingNode.callee === precedingNode && enclosingNode.arguments.length > 0) { + addLeadingComment$3(enclosingNode.arguments[0], comment); + return true; } - return group$1(concat$4(["`", leadingWhitespace, topLevelCount > 1 ? indent$2(group$1(contentDoc)) : group$1(contentDoc), trailingWhitespace, "`"])); + return false; } -var embed_1 = embed; +function handleUnionTypeComments(comment) { + const { + precedingNode, + enclosingNode, + followingNode + } = comment; -function clean(ast, newObj, parent) { - ["range", "raw", "comments", "leadingComments", "trailingComments", "innerComments", "extra", "start", "end", "flags", "errors"].forEach(name => { - delete newObj[name]; - }); + if (enclosingNode && (enclosingNode.type === "UnionTypeAnnotation" || enclosingNode.type === "TSUnionType")) { + if (isPrettierIgnoreComment$1(comment)) { + followingNode.prettierIgnore = true; + comment.unignore = true; + } - if (ast.loc && ast.loc.source === null) { - delete newObj.loc.source; - } + if (precedingNode) { + addTrailingComment$3(precedingNode, comment); + return true; + } - if (ast.type === "BigIntLiteral") { - newObj.value = newObj.value.toLowerCase(); - } // We remove extra `;` and add them when needed + return false; + } + if (followingNode && (followingNode.type === "UnionTypeAnnotation" || followingNode.type === "TSUnionType") && isPrettierIgnoreComment$1(comment)) { + followingNode.types[0].prettierIgnore = true; + comment.unignore = true; + } - if (ast.type === "EmptyStatement") { - return null; - } // We move text around, including whitespaces and add {" "} + return false; +} +function handlePropertyComments(comment) { + const { + enclosingNode + } = comment; - if (ast.type === "JSXText") { - return null; + if (enclosingNode && (enclosingNode.type === "Property" || enclosingNode.type === "ObjectProperty")) { + addLeadingComment$3(enclosingNode, comment); + return true; } - if (ast.type === "JSXExpressionContainer" && ast.expression.type === "Literal" && ast.expression.value === " ") { - return null; - } // (TypeScript) Ignore `static` in `constructor(static p) {}` - // and `export` in `constructor(export p) {}` - - - if (ast.type === "TSParameterProperty" && ast.accessibility === null && !ast.readonly) { - return { - type: "Identifier", - name: ast.parameter.name, - typeAnnotation: newObj.parameter.typeAnnotation, - decorators: newObj.decorators - }; - } // (TypeScript) ignore empty `specifiers` array + return false; +} +function handleOnlyComments(comment, ast, isLastComment) { + const { + enclosingNode + } = comment; // With Flow the enclosingNode is undefined so use the AST instead. - if (ast.type === "TSNamespaceExportDeclaration" && ast.specifiers && ast.specifiers.length === 0) { - delete newObj.specifiers; - } // We convert
to
+ if (ast && ast.body && ast.body.length === 0) { + if (isLastComment) { + addDanglingComment$3(ast, comment); + } else { + addLeadingComment$3(ast, comment); + } + return true; + } else if (enclosingNode && enclosingNode.type === "Program" && enclosingNode.body.length === 0 && enclosingNode.directives && enclosingNode.directives.length === 0) { + if (isLastComment) { + addDanglingComment$3(enclosingNode, comment); + } else { + addLeadingComment$3(enclosingNode, comment); + } - if (ast.type === "JSXOpeningElement") { - delete newObj.selfClosing; + return true; } - if (ast.type === "JSXElement") { - delete newObj.closingElement; - } // We change {'key': value} into {key: value} + return false; +} +function handleForComments(comment) { + const { + enclosingNode + } = comment; - if ((ast.type === "Property" || ast.type === "ObjectProperty" || ast.type === "MethodDefinition" || ast.type === "ClassProperty" || ast.type === "TSPropertySignature" || ast.type === "ObjectTypeProperty") && typeof ast.key === "object" && ast.key && (ast.key.type === "Literal" || ast.key.type === "StringLiteral" || ast.key.type === "Identifier")) { - delete newObj.key; + if (enclosingNode && (enclosingNode.type === "ForInStatement" || enclosingNode.type === "ForOfStatement")) { + addLeadingComment$3(enclosingNode, comment); + return true; } - if (ast.type === "OptionalMemberExpression" && ast.optional === false) { - newObj.type = "MemberExpression"; - delete newObj.optional; - } // Remove raw and cooked values from TemplateElement when it's CSS - // styled-jsx + return false; +} +function handleImportDeclarationComments(comment, text) { + const { + precedingNode, + enclosingNode + } = comment; - if (ast.type === "JSXElement" && ast.openingElement.name.name === "style" && ast.openingElement.attributes.some(attr => attr.name.name === "jsx")) { - const templateLiterals = newObj.children.filter(child => child.type === "JSXExpressionContainer" && child.expression.type === "TemplateLiteral").map(container => container.expression); - const quasis = templateLiterals.reduce((quasis, templateLiteral) => quasis.concat(templateLiteral.quasis), []); - quasis.forEach(q => delete q.value); - } // CSS template literals in css prop + if (precedingNode && precedingNode.type === "ImportSpecifier" && enclosingNode && enclosingNode.type === "ImportDeclaration" && hasNewline$4(text, locEnd$3(comment))) { + addTrailingComment$3(precedingNode, comment); + return true; + } + return false; +} - if (ast.type === "JSXAttribute" && ast.name.name === "css" && ast.value.type === "JSXExpressionContainer" && ast.value.expression.type === "TemplateLiteral") { - newObj.value.expression.quasis.forEach(q => delete q.value); - } // Angular Components: Inline HTML template and Inline CSS styles +function handleAssignmentPatternComments(comment) { + const { + enclosingNode + } = comment; + if (enclosingNode && enclosingNode.type === "AssignmentPattern") { + addLeadingComment$3(enclosingNode, comment); + return true; + } - const expression = ast.expression || ast.callee; + return false; +} - if (ast.type === "Decorator" && expression.type === "CallExpression" && expression.callee.name === "Component" && expression.arguments.length === 1) { - const astProps = ast.expression.arguments[0].properties; - newObj.expression.arguments[0].properties.forEach((prop, index) => { - let templateLiteral = null; +function handleTypeAliasComments(comment) { + const { + enclosingNode + } = comment; - switch (astProps[index].key.name) { - case "styles": - if (prop.value.type === "ArrayExpression") { - templateLiteral = prop.value.elements[0]; - } + if (enclosingNode && enclosingNode.type === "TypeAlias") { + addLeadingComment$3(enclosingNode, comment); + return true; + } - break; + return false; +} - case "template": - if (prop.value.type === "TemplateLiteral") { - templateLiteral = prop.value; - } +function handleVariableDeclaratorComments(comment) { + const { + enclosingNode, + followingNode + } = comment; - break; - } + if (enclosingNode && (enclosingNode.type === "VariableDeclarator" || enclosingNode.type === "AssignmentExpression") && followingNode && (followingNode.type === "ObjectExpression" || followingNode.type === "ArrayExpression" || followingNode.type === "TemplateLiteral" || followingNode.type === "TaggedTemplateExpression" || isBlockComment$1(comment))) { + addLeadingComment$3(followingNode, comment); + return true; + } - if (templateLiteral) { - templateLiteral.quasis.forEach(q => delete q.value); - } - }); - } // styled-components, graphql, markdown + return false; +} +function handleTSFunctionTrailingComments(comment, text) { + const { + enclosingNode, + followingNode + } = comment; - if (ast.type === "TaggedTemplateExpression" && (ast.tag.type === "MemberExpression" || ast.tag.type === "Identifier" && (ast.tag.name === "gql" || ast.tag.name === "graphql" || ast.tag.name === "css" || ast.tag.name === "md" || ast.tag.name === "markdown" || ast.tag.name === "html") || ast.tag.type === "CallExpression")) { - newObj.quasi.quasis.forEach(quasi => delete quasi.value); + if (!followingNode && enclosingNode && (enclosingNode.type === "TSMethodSignature" || enclosingNode.type === "TSDeclareFunction" || enclosingNode.type === "TSAbstractMethodDefinition") && getNextNonSpaceNonCommentCharacter$1(text, comment, locEnd$3) === ";") { + addTrailingComment$3(enclosingNode, comment); + return true; } - if (ast.type === "TemplateLiteral") { - // This checks for a leading comment that is exactly `/* GraphQL */` - // In order to be in line with other implementations of this comment tag - // we will not trim the comment value and we will expect exactly one space on - // either side of the GraphQL string - // Also see ./embed.js - const hasLanguageComment = ast.leadingComments && ast.leadingComments.some(comment => comment.type === "CommentBlock" && ["GraphQL", "HTML"].some(languageName => comment.value === ` ${languageName} `)); + return false; +} - if (hasLanguageComment || parent.type === "CallExpression" && parent.callee.name === "graphql") { - newObj.quasis.forEach(quasi => delete quasi.value); - } +function handleIgnoreComments(comment) { + const { + enclosingNode, + followingNode + } = comment; + + if (isPrettierIgnoreComment$1(comment) && enclosingNode && enclosingNode.type === "TSMappedType" && followingNode && followingNode.type === "TSTypeParameter" && followingNode.constraint) { + enclosingNode.prettierIgnore = true; + comment.unignore = true; + return true; } } -var clean_1 = clean; +function handleTSMappedTypeComments(comment) { + const { + precedingNode, + enclosingNode, + followingNode + } = comment; -const detectNewline = string => { - if (typeof string !== 'string') { - throw new TypeError('Expected a string'); + if (!enclosingNode || enclosingNode.type !== "TSMappedType") { + return false; } - const newlines = string.match(/(?:\r?\n)/g) || []; + if (followingNode && followingNode.type === "TSTypeParameter" && followingNode.name) { + addLeadingComment$3(followingNode.name, comment); + return true; + } - if (newlines.length === 0) { - return; + if (precedingNode && precedingNode.type === "TSTypeParameter" && precedingNode.constraint) { + addTrailingComment$3(precedingNode.constraint, comment); + return true; } - const crlf = newlines.filter(newline => newline === '\r\n').length; - const lf = newlines.length - crlf; - return crlf > lf ? '\r\n' : '\n'; -}; + return false; +} +/** + * @param {any} node + * @param {(comment: any) => boolean} fn + * @returns boolean + */ -var detectNewline_1 = detectNewline; -var graceful = string => typeof string === 'string' && detectNewline(string) || '\n'; -detectNewline_1.graceful = graceful; +function hasLeadingComment$1(node, fn = () => true) { + if (node.leadingComments) { + return node.leadingComments.some(fn); + } -var build = createCommonjsModule(function (module, exports) { + if (node.comments) { + return node.comments.some(comment => comment.leading && fn(comment)); + } - Object.defineProperty(exports, '__esModule', { - value: true - }); - exports.extract = extract; - exports.strip = strip; - exports.parse = parse; - exports.parseWithComments = parseWithComments; - exports.print = print; + return false; +} - function _os() { - const data = os$1; +function isRealFunctionLikeNode(node) { + return node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression" || node.type === "FunctionDeclaration" || node.type === "ObjectMethod" || node.type === "ClassMethod" || node.type === "TSDeclareFunction" || node.type === "TSCallSignatureDeclaration" || node.type === "TSConstructSignatureDeclaration" || node.type === "TSMethodSignature" || node.type === "TSConstructorType" || node.type === "TSFunctionType" || node.type === "TSDeclareMethod"; +} - _os = function () { - return data; - }; +function getGapRegex(enclosingNode) { + if (enclosingNode && enclosingNode.type !== "BinaryExpression" && enclosingNode.type !== "LogicalExpression") { + // Support degenerate single-element unions and intersections. + // E.g.: `type A = /* 1 */ & B` + return /^[\s&(|]*$/; + } +} - return data; +function getCommentChildNodes(node, options) { + // Prevent attaching comments to FunctionExpression in this case: + // class Foo { + // bar() // comment + // { + // baz(); + // } + // } + if ((options.parser === "typescript" || options.parser === "flow" || options.parser === "espree" || options.parser === "meriyah") && node.type === "MethodDefinition" && node.value && node.value.type === "FunctionExpression" && getFunctionParameters$1(node.value).length === 0 && !node.value.returnType && (!node.value.typeParameters || node.value.typeParameters.length === 0) && node.value.body) { + return [...(node.decorators || []), node.key, node.value.body]; } +} - function _detectNewline() { - const data = _interopRequireDefault(detectNewline_1); +function isTypeCastComment(comment) { + return isBlockComment$1(comment) && comment.value[0] === "*" && // TypeScript expects the type to be enclosed in curly brackets, however + // Closure Compiler accepts types in parens and even without any delimiters at all. + // That's why we just search for "@type". + /@type\b/.test(comment.value); +} - _detectNewline = function () { - return data; - }; +function willPrintOwnComments(path +/*, options */ +) { + const node = path.getValue(); + const parent = path.getParentNode(); + return (node && (isJSXNode$1(node) || hasFlowShorthandAnnotationComment$1(node) || parent && (parent.type === "CallExpression" || parent.type === "OptionalCallExpression") && (hasFlowAnnotationComment$1(node.leadingComments) || hasFlowAnnotationComment$1(node.trailingComments))) || parent && (parent.type === "JSXSpreadAttribute" || parent.type === "JSXSpreadChild" || parent.type === "UnionTypeAnnotation" || parent.type === "TSUnionType" || (parent.type === "ClassDeclaration" || parent.type === "ClassExpression") && parent.superClass === node)) && (!hasIgnoreComment$1(path) || parent.type === "UnionTypeAnnotation" || parent.type === "TSUnionType"); +} - return data; - } +var comments$1 = { + handleOwnLineComment, + handleEndOfLineComment, + handleRemainingComment, + hasLeadingComment: hasLeadingComment$1, + isTypeCastComment, + getGapRegex, + getCommentChildNodes, + willPrintOwnComments +}; - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { - default: obj - }; +const { + getStringWidth: getStringWidth$3, + getIndentSize: getIndentSize$2 +} = util; +const { + builders: { + concat: concat$5, + join: join$2, + hardline: hardline$3, + softline: softline$1, + group: group$1, + indent: indent$2, + align: align$1, + lineSuffixBoundary: lineSuffixBoundary$1, + addAlignmentToDoc: addAlignmentToDoc$2 + }, + printer: { + printDocToString: printDocToString$2 + }, + utils: { + mapDoc: mapDoc$1 } - /** - * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ +} = document; +const { + isBinaryish: isBinaryish$1, + isJestEachTemplateLiteral: isJestEachTemplateLiteral$1, + isSimpleTemplateLiteral: isSimpleTemplateLiteral$1 +} = utils$6; +function printTemplateLiteral(path, print, options) { + const node = path.getValue(); + const isTemplateLiteral = node.type === "TemplateLiteral"; - const commentEndRe = /\*\/$/; - const commentStartRe = /^\/\*\*/; - const docblockRe = /^\s*(\/\*\*?(.|\r?\n)*?\*\/)/; - const lineCommentRe = /(^|\s+)\/\/([^\r\n]*)/g; - const ltrimNewlineRe = /^(\r?\n)+/; - const multilineRe = /(?:^|\r?\n) *(@[^\r\n]*?) *\r?\n *(?![^@\r\n]*\/\/[^]*)([^@\r\n\s][^@\r\n]+?) *\r?\n/g; - const propertyRe = /(?:^|\r?\n) *@(\S+) *([^\r\n]*)/g; - const stringStartRe = /(\r?\n|^) *\* ?/g; + if (isTemplateLiteral && isJestEachTemplateLiteral$1(node, path.getParentNode())) { + const printed = printJestEachTemplateLiteral(path, options, print); - function extract(contents) { - const match = contents.match(docblockRe); - return match ? match[0].trimLeft() : ''; + if (printed) { + return printed; + } } - function strip(contents) { - const match = contents.match(docblockRe); - return match && match[0] ? contents.substring(match[0].length) : contents; - } + let expressionsKey = "expressions"; - function parse(docblock) { - return parseWithComments(docblock).pragmas; + if (node.type === "TSTemplateLiteralType") { + expressionsKey = "types"; } - function parseWithComments(docblock) { - const line = (0, _detectNewline().default)(docblock) || _os().EOL; - - docblock = docblock.replace(commentStartRe, '').replace(commentEndRe, '').replace(stringStartRe, '$1'); // Normalize multi-line directives - - let prev = ''; + const parts = []; + let expressions = path.map(print, expressionsKey); + const isSimple = isSimpleTemplateLiteral$1(node); - while (prev !== docblock) { - prev = docblock; - docblock = docblock.replace(multilineRe, `${line}$1 $2${line}`); - } + if (isSimple) { + expressions = expressions.map(doc => printDocToString$2(doc, Object.assign({}, options, { + printWidth: Infinity + })).formatted); + } - docblock = docblock.replace(ltrimNewlineRe, '').trimRight(); - const result = Object.create(null); - const comments = docblock.replace(propertyRe, '').replace(ltrimNewlineRe, '').trimRight(); - let match; + parts.push(lineSuffixBoundary$1, "`"); + path.each(childPath => { + const i = childPath.getName(); + parts.push(print(childPath)); + + if (i < expressions.length) { + // For a template literal of the following form: + // `someQuery { + // ${call({ + // a, + // b, + // })} + // }` + // the expression is on its own line (there is a \n in the previous + // quasi literal), therefore we want to indent the JavaScript + // expression inside at the beginning of ${ instead of the beginning + // of the `. + const { + tabWidth + } = options; + const quasi = childPath.getValue(); + const indentSize = getIndentSize$2(quasi.value.raw, tabWidth); + let printed = expressions[i]; - while (match = propertyRe.exec(docblock)) { - // strip linecomments from pragmas - const nextPragma = match[2].replace(lineCommentRe, ''); + if (!isSimple) { + const expression = node[expressionsKey][i]; // Breaks at the template element boundaries (${ and }) are preferred to breaking + // in the middle of a MemberExpression - if (typeof result[match[1]] === 'string' || Array.isArray(result[match[1]])) { - result[match[1]] = [].concat(result[match[1]], nextPragma); - } else { - result[match[1]] = nextPragma; + if (expression.comments && expression.comments.length || expression.type === "MemberExpression" || expression.type === "OptionalMemberExpression" || expression.type === "ConditionalExpression" || expression.type === "SequenceExpression" || expression.type === "TSAsExpression" || isBinaryish$1(expression)) { + printed = concat$5([indent$2(concat$5([softline$1, printed])), softline$1]); + } } + + const aligned = indentSize === 0 && quasi.value.raw.endsWith("\n") ? align$1(-Infinity, printed) : addAlignmentToDoc$2(printed, indentSize, tabWidth); + parts.push(group$1(concat$5(["${", aligned, lineSuffixBoundary$1, "}"]))); } + }, "quasis"); + parts.push("`"); + return concat$5(parts); +} - return { - comments, - pragmas: result - }; - } +function printJestEachTemplateLiteral(path, options, print) { + /** + * a | b | expected + * ${1} | ${1} | ${2} + * ${1} | ${2} | ${3} + * ${2} | ${1} | ${3} + */ + const node = path.getNode(); + const headerNames = node.quasis[0].value.raw.trim().split(/\s*\|\s*/); - function print({ - comments = '', - pragmas = {} - }) { - const line = (0, _detectNewline().default)(comments) || _os().EOL; + if (headerNames.length > 1 || headerNames.some(headerName => headerName.length !== 0)) { + options.__inJestEach = true; + const expressions = path.map(print, "expressions"); + options.__inJestEach = false; + const parts = []; + const stringifiedExpressions = expressions.map(doc => "${" + printDocToString$2(doc, Object.assign({}, options, { + printWidth: Infinity, + endOfLine: "lf" + })).formatted + "}"); + const tableBody = [{ + hasLineBreak: false, + cells: [] + }]; - const head = '/**'; - const start = ' *'; - const tail = ' */'; - const keys = Object.keys(pragmas); - const printedObject = keys.map(key => printKeyValues(key, pragmas[key])).reduce((arr, next) => arr.concat(next), []).map(keyValue => start + ' ' + keyValue + line).join(''); + for (let i = 1; i < node.quasis.length; i++) { + const row = tableBody[tableBody.length - 1]; + const correspondingExpression = stringifiedExpressions[i - 1]; + row.cells.push(correspondingExpression); - if (!comments) { - if (keys.length === 0) { - return ''; + if (correspondingExpression.includes("\n")) { + row.hasLineBreak = true; } - if (keys.length === 1 && !Array.isArray(pragmas[keys[0]])) { - const value = pragmas[keys[0]]; - return `${head} ${printKeyValues(keys[0], value)[0]}${tail}`; + if (node.quasis[i].value.raw.includes("\n")) { + tableBody.push({ + hasLineBreak: false, + cells: [] + }); } } - const printedComments = comments.split(line).map(textLine => `${start} ${textLine}`).join(line) + line; - return head + line + (comments ? printedComments : '') + (comments && keys.length ? start + line : '') + printedObject + tail; - } + const maxColumnCount = Math.max(headerNames.length, ...tableBody.map(row => row.cells.length)); + const maxColumnWidths = Array.from({ + length: maxColumnCount + }).fill(0); + const table = [{ + cells: headerNames + }, ...tableBody.filter(row => row.cells.length !== 0)]; - function printKeyValues(key, valueOrArray) { - return [].concat(valueOrArray).map(value => `@${key} ${value}`.trim()); - } -}); -unwrapExports(build); -var build_1 = build.extract; -var build_2 = build.strip; -var build_3 = build.parse; -var build_4 = build.parseWithComments; -var build_5 = build.print; + for (const { + cells + } of table.filter(row => !row.hasLineBreak)) { + cells.forEach((cell, index) => { + maxColumnWidths[index] = Math.max(maxColumnWidths[index], getStringWidth$3(cell)); + }); + } -function hasPragma(text) { - const pragmas = Object.keys(build.parse(build.extract(text))); - return pragmas.includes("prettier") || pragmas.includes("format"); + parts.push(lineSuffixBoundary$1, "`", indent$2(concat$5([hardline$3, join$2(hardline$3, table.map(row => join$2(" | ", row.cells.map((cell, index) => row.hasLineBreak ? cell : cell + " ".repeat(maxColumnWidths[index] - getStringWidth$3(cell))))))])), hardline$3, "`"); + return concat$5(parts); + } } -function insertPragma(text) { - const parsedDocblock = build.parseWithComments(build.extract(text)); - const pragmas = Object.assign({ - format: "" - }, parsedDocblock.pragmas); - const newDocblock = build.print({ - pragmas, - comments: parsedDocblock.comments.replace(/^(\s+?\r?\n)+/, "") // remove leading newlines +function printTemplateExpression(path, print) { + const node = path.getValue(); + let printed = print(path); - }).replace(/(\r\n|\r)/g, "\n"); // normalise newlines (mitigate use of os.EOL by jest-docblock) + if (node.comments && node.comments.length) { + printed = group$1(concat$5([indent$2(concat$5([softline$1, printed])), softline$1])); + } - const strippedText = build.strip(text); - const separatingNewlines = strippedText.startsWith("\n") ? "\n" : "\n\n"; - return newDocblock + separatingNewlines + strippedText; + return concat$5(["${", printed, lineSuffixBoundary$1, "}"]); } -var pragma = { - hasPragma, - insertPragma -}; +function printTemplateExpressions(path, print) { + return path.map(path => printTemplateExpression(path, print), "expressions"); +} -const { - getLast: getLast$1, - hasNewline: hasNewline$3, - hasNewlineInRange: hasNewlineInRange$2, - hasIgnoreComment: hasIgnoreComment$1, - hasNodeIgnoreComment: hasNodeIgnoreComment$1, - skipWhitespace: skipWhitespace$2 -} = util$1; -const isIdentifierName = utils$1.keyword.isIdentifierNameES5; // We match any whitespace except line terminators because -// Flow annotation comments cannot be split across lines. For example: -// -// (this /* -// : any */).foo = 5; -// -// is not picked up by Flow (see https://github.com/facebook/flow/issues/7050), so -// removing the newline would create a type annotation that the user did not intend -// to create. +function escapeTemplateCharacters(doc, raw) { + return mapDoc$1(doc, currentDoc => { + if (!currentDoc.parts) { + return currentDoc; + } -const NON_LINE_TERMINATING_WHITE_SPACE = "(?:(?=.)\\s)"; -const FLOW_SHORTHAND_ANNOTATION = new RegExp(`^${NON_LINE_TERMINATING_WHITE_SPACE}*:`); -const FLOW_ANNOTATION = new RegExp(`^${NON_LINE_TERMINATING_WHITE_SPACE}*::`); + const parts = currentDoc.parts.map(part => { + if (typeof part === "string") { + return raw ? part.replace(/(\\*)`/g, "$1$1\\`") : uncookTemplateElementValue(part); + } -function hasFlowShorthandAnnotationComment(node) { - // https://flow.org/en/docs/types/comments/ - // Syntax example: const r = new (window.Request /*: Class */)(""); - return node.extra && node.extra.parenthesized && node.trailingComments && node.trailingComments[0].value.match(FLOW_SHORTHAND_ANNOTATION); + return part; + }); + return Object.assign({}, currentDoc, { + parts + }); + }); } -function hasFlowAnnotationComment(comments) { - return comments && comments[0].value.match(FLOW_ANNOTATION); +function uncookTemplateElementValue(cookedValue) { + return cookedValue.replace(/([\\`]|\${)/g, "\\$1"); } -function hasNode(node, fn) { - if (!node || typeof node !== "object") { - return false; +var templateLiteral = { + printTemplateLiteral, + printTemplateExpressions, + escapeTemplateCharacters, + uncookTemplateElementValue +}; + +const { + builders: { + indent: indent$3, + softline: softline$2, + literalline: literalline$2, + concat: concat$6, + dedentToRoot: dedentToRoot$1 } +} = document; +const { + escapeTemplateCharacters: escapeTemplateCharacters$1 +} = templateLiteral; - if (Array.isArray(node)) { - return node.some(value => hasNode(value, fn)); +function format$1(path, print, textToDoc) { + const node = path.getValue(); + let text = node.quasis[0].value.raw.replace(/((?:\\\\)*)\\`/g, (_, backslashes) => "\\".repeat(backslashes.length / 2) + "`"); + const indentation = getIndentation(text); + const hasIndent = indentation !== ""; + + if (hasIndent) { + text = text.replace(new RegExp(`^${indentation}`, "gm"), ""); } - const result = fn(node); - return typeof result === "boolean" ? result : Object.keys(node).some(key => hasNode(node[key], fn)); + const doc = escapeTemplateCharacters$1(textToDoc(text, { + parser: "markdown", + __inJsTemplate: true + }, { + stripTrailingHardline: true + }), true); + return concat$6(["`", hasIndent ? indent$3(concat$6([softline$2, doc])) : concat$6([literalline$2, dedentToRoot$1(doc)]), softline$2, "`"]); } -function hasNakedLeftSide(node) { - return node.type === "AssignmentExpression" || node.type === "BinaryExpression" || node.type === "LogicalExpression" || node.type === "NGPipeExpression" || node.type === "ConditionalExpression" || node.type === "CallExpression" || node.type === "OptionalCallExpression" || node.type === "MemberExpression" || node.type === "OptionalMemberExpression" || node.type === "SequenceExpression" || node.type === "TaggedTemplateExpression" || node.type === "BindExpression" || node.type === "UpdateExpression" && !node.prefix || node.type === "TSAsExpression" || node.type === "TSNonNullExpression"; +function getIndentation(str) { + const firstMatchedIndent = str.match(/^([^\S\n]*)\S/m); + return firstMatchedIndent === null ? "" : firstMatchedIndent[1]; } -function getLeftSide(node) { - if (node.expressions) { - return node.expressions[0]; - } +var markdown = format$1; - return node.left || node.test || node.callee || node.object || node.tag || node.argument || node.expression; +const { + builders: { + indent: indent$4, + hardline: hardline$4, + softline: softline$3, + concat: concat$7 + }, + utils: { + mapDoc: mapDoc$2, + replaceNewlinesWithLiterallines: replaceNewlinesWithLiterallines$1 + } +} = document; +const { + printTemplateExpressions: printTemplateExpressions$1 +} = templateLiteral; + +function format$2(path, print, textToDoc) { + const node = path.getValue(); // Get full template literal with expressions replaced by placeholders + + const rawQuasis = node.quasis.map(q => q.value.raw); + let placeholderID = 0; + const text = rawQuasis.reduce((prevVal, currVal, idx) => { + return idx === 0 ? currVal : prevVal + "@prettier-placeholder-" + placeholderID++ + "-id" + currVal; + }, ""); + const doc = textToDoc(text, { + parser: "scss" + }, { + stripTrailingHardline: true + }); + const expressionDocs = printTemplateExpressions$1(path, print); + return transformCssDoc(doc, node, expressionDocs); } -function getLeftSidePathName(path, node) { - if (node.expressions) { - return ["expressions", 0]; - } +function transformCssDoc(quasisDoc, parentNode, expressionDocs) { + const isEmpty = parentNode.quasis.length === 1 && !parentNode.quasis[0].value.raw.trim(); - if (node.left) { - return ["left"]; + if (isEmpty) { + return "``"; } - if (node.test) { - return ["test"]; - } + const newDoc = replacePlaceholders(quasisDoc, expressionDocs); + /* istanbul ignore if */ - if (node.object) { - return ["object"]; + if (!newDoc) { + throw new Error("Couldn't insert all the expressions"); } - if (node.callee) { - return ["callee"]; - } + return concat$7(["`", indent$4(concat$7([hardline$4, newDoc])), softline$3, "`"]); +} // Search all the placeholders in the quasisDoc tree +// and replace them with the expression docs one by one +// returns a new doc with all the placeholders replaced, +// or null if it couldn't replace any expression - if (node.tag) { - return ["tag"]; - } - if (node.argument) { - return ["argument"]; +function replacePlaceholders(quasisDoc, expressionDocs) { + if (!expressionDocs || !expressionDocs.length) { + return quasisDoc; } - if (node.expression) { - return ["expression"]; - } + let replaceCounter = 0; + const newDoc = mapDoc$2(quasisDoc, doc => { + if (!doc || !doc.parts || !doc.parts.length) { + return doc; + } - throw new Error("Unexpected node has no left side", node); -} + let { + parts + } = doc; + const atIndex = parts.indexOf("@"); + const placeholderIndex = atIndex + 1; -const exportDeclarationTypes = new Set(["ExportDefaultDeclaration", "ExportDefaultSpecifier", "DeclareExportDeclaration", "ExportNamedDeclaration", "ExportAllDeclaration"]); + if (atIndex > -1 && typeof parts[placeholderIndex] === "string" && parts[placeholderIndex].startsWith("prettier-placeholder")) { + // If placeholder is split, join it + const at = parts[atIndex]; + const placeholder = parts[placeholderIndex]; + const rest = parts.slice(placeholderIndex + 1); + parts = parts.slice(0, atIndex).concat([at + placeholder]).concat(rest); + } -function isExportDeclaration(node) { - return node && exportDeclarationTypes.has(node.type); -} + const replacedParts = []; + parts.forEach(part => { + if (typeof part !== "string" || !part.includes("@prettier-placeholder")) { + replacedParts.push(part); + return; + } // When we have multiple placeholders in one line, like: + // ${Child}${Child2}:not(:first-child) -function getParentExportDeclaration(path) { - const parentNode = path.getParentNode(); - if (path.getName() === "declaration" && isExportDeclaration(parentNode)) { - return parentNode; - } + part.split(/@prettier-placeholder-(\d+)-id/).forEach((component, idx) => { + // The placeholder is always at odd indices + if (idx % 2 === 0) { + replacedParts.push(replaceNewlinesWithLiterallines$1(component)); + return; + } // The component will always be a number at odd index - return null; -} -function isLiteral(node) { - return node.type === "BooleanLiteral" || node.type === "DirectiveLiteral" || node.type === "Literal" || node.type === "NullLiteral" || node.type === "NumericLiteral" || node.type === "RegExpLiteral" || node.type === "StringLiteral" || node.type === "TemplateLiteral" || node.type === "TSTypeLiteral" || node.type === "JSXText"; + replacedParts.push(expressionDocs[component]); + replaceCounter++; + }); + }); + return Object.assign({}, doc, { + parts: replacedParts + }); + }); + return expressionDocs.length === replaceCounter ? newDoc : null; } -function isNumericLiteral(node) { - return node.type === "NumericLiteral" || node.type === "Literal" && typeof node.value === "number"; -} +var css = format$2; -function isStringLiteral(node) { - return node.type === "StringLiteral" || node.type === "Literal" && typeof node.value === "string"; -} +const { + builders: { + indent: indent$5, + join: join$3, + hardline: hardline$5, + concat: concat$8 + } +} = document; +const { + escapeTemplateCharacters: escapeTemplateCharacters$2, + printTemplateExpressions: printTemplateExpressions$2 +} = templateLiteral; -function isObjectType(n) { - return n.type === "ObjectTypeAnnotation" || n.type === "TSTypeLiteral"; -} +function format$3(path, print, textToDoc) { + const node = path.getValue(); + const numQuasis = node.quasis.length; -function isFunctionOrArrowExpression(node) { - return node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression"; -} + if (numQuasis === 1 && node.quasis[0].value.raw.trim() === "") { + return "``"; + } -function isFunctionOrArrowExpressionWithBody(node) { - return node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression" && node.body.type === "BlockStatement"; -} + const expressionDocs = printTemplateExpressions$2(path, print); + const parts = []; -function isTemplateLiteral(node) { - return node.type === "TemplateLiteral"; -} // `inject` is used in AngularJS 1.x, `async` in Angular 2+ -// example: https://docs.angularjs.org/guide/unit-testing#using-beforeall- + for (let i = 0; i < numQuasis; i++) { + const templateElement = node.quasis[i]; + const isFirst = i === 0; + const isLast = i === numQuasis - 1; + const text = templateElement.value.cooked; + const lines = text.split("\n"); + const numLines = lines.length; + const expressionDoc = expressionDocs[i]; + const startsWithBlankLine = numLines > 2 && lines[0].trim() === "" && lines[1].trim() === ""; + const endsWithBlankLine = numLines > 2 && lines[numLines - 1].trim() === "" && lines[numLines - 2].trim() === ""; + const commentsAndWhitespaceOnly = lines.every(line => /^\s*(?:#[^\n\r]*)?$/.test(line)); // Bail out if an interpolation occurs within a comment. + + if (!isLast && /#[^\n\r]*$/.test(lines[numLines - 1])) { + return null; + } + let doc = null; -function isAngularTestWrapper(node) { - return (node.type === "CallExpression" || node.type === "OptionalCallExpression") && node.callee.type === "Identifier" && (node.callee.name === "async" || node.callee.name === "inject" || node.callee.name === "fakeAsync"); -} + if (commentsAndWhitespaceOnly) { + doc = printGraphqlComments(lines); + } else { + doc = textToDoc(text, { + parser: "graphql" + }, { + stripTrailingHardline: true + }); + } -function isJSXNode(node) { - return node.type === "JSXElement" || node.type === "JSXFragment"; -} + if (doc) { + doc = escapeTemplateCharacters$2(doc, false); -function isTheOnlyJSXElementInMarkdown(options, path) { - if (options.parentParser !== "markdown" && options.parentParser !== "mdx") { - return false; - } + if (!isFirst && startsWithBlankLine) { + parts.push(""); + } - const node = path.getNode(); + parts.push(doc); - if (!node.expression || !isJSXNode(node.expression)) { - return false; + if (!isLast && endsWithBlankLine) { + parts.push(""); + } + } else if (!isFirst && !isLast && startsWithBlankLine) { + parts.push(""); + } + + if (expressionDoc) { + parts.push(expressionDoc); + } } - const parent = path.getParentNode(); - return parent.type === "Program" && parent.body.length === 1; -} // Detect an expression node representing `{" "}` + return concat$8(["`", indent$5(concat$8([hardline$5, join$3(hardline$5, parts)])), hardline$5, "`"]); +} +function printGraphqlComments(lines) { + const parts = []; + let seenComment = false; + lines.map(textLine => textLine.trim()).forEach((textLine, i, array) => { + // Lines are either whitespace only, or a comment (with potential whitespace + // around it). Drop whitespace-only lines. + if (textLine === "") { + return; + } -function isJSXWhitespaceExpression(node) { - return node.type === "JSXExpressionContainer" && isLiteral(node.expression) && node.expression.value === " " && !node.expression.comments; + if (array[i - 1] === "" && seenComment) { + // If a non-first comment is preceded by a blank (whitespace only) line, + // add in a blank line. + parts.push(concat$8([hardline$5, textLine])); + } else { + parts.push(textLine); + } + + seenComment = true; + }); // If `lines` was whitespace only, return `null`. + + return parts.length === 0 ? null : join$3(hardline$5, parts); } -function isMemberExpressionChain(node) { - if (node.type !== "MemberExpression" && node.type !== "OptionalMemberExpression") { - return false; +var graphql = format$3; + +const { + builders: { + indent: indent$6, + line: line$3, + hardline: hardline$6, + concat: concat$9, + group: group$2 + }, + utils: { + mapDoc: mapDoc$3 } +} = document; +const { + printTemplateExpressions: printTemplateExpressions$3, + uncookTemplateElementValue: uncookTemplateElementValue$1 +} = templateLiteral; // The counter is needed to distinguish nested embeds. - if (node.object.type === "Identifier") { - return true; +let htmlTemplateLiteralCounter = 0; + +function format$4(path, print, textToDoc, options, { + parser +}) { + const node = path.getValue(); + const counter = htmlTemplateLiteralCounter; + htmlTemplateLiteralCounter = htmlTemplateLiteralCounter + 1 >>> 0; + + const composePlaceholder = index => `PRETTIER_HTML_PLACEHOLDER_${index}_${counter}_IN_JS`; + + const text = node.quasis.map((quasi, index, quasis) => index === quasis.length - 1 ? quasi.value.cooked : quasi.value.cooked + composePlaceholder(index)).join(""); + const expressionDocs = printTemplateExpressions$3(path, print); + + if (expressionDocs.length === 0 && text.trim().length === 0) { + return "``"; } - return isMemberExpressionChain(node.object); -} + const placeholderRegex = new RegExp(composePlaceholder("(\\d+)"), "g"); + let topLevelCount = 0; + const doc = textToDoc(text, { + parser, -function isGetterOrSetter(node) { - return node.kind === "get" || node.kind === "set"; -} + __onHtmlRoot(root) { + topLevelCount = root.children.length; + } -function sameLocStart(nodeA, nodeB, options) { - return options.locStart(nodeA) === options.locStart(nodeB); -} // TODO: This is a bad hack and we need a better way to distinguish between -// arrow functions and otherwise + }, { + stripTrailingHardline: true + }); + const contentDoc = mapDoc$3(doc, doc => { + if (typeof doc !== "string") { + return doc; + } + const parts = []; + const components = doc.split(placeholderRegex); -function isFunctionNotation(node, options) { - return isGetterOrSetter(node) || sameLocStart(node, node.value, options); -} // Hack to differentiate between the following two which have the same ast -// type T = { method: () => void }; -// type T = { method(): void }; + for (let i = 0; i < components.length; i++) { + let component = components[i]; + if (i % 2 === 0) { + if (component) { + component = uncookTemplateElementValue$1(component); -function isObjectTypePropertyAFunction(node, options) { - return (node.type === "ObjectTypeProperty" || node.type === "ObjectTypeInternalSlot") && node.value.type === "FunctionTypeAnnotation" && !node.static && !isFunctionNotation(node, options); -} // Hack to differentiate between the following two which have the same ast -// declare function f(a): void; -// var f: (a) => void; + if (options.embeddedInHtml) { + component = component.replace(/<\/(script)\b/gi, "<\\/$1"); + } + parts.push(component); + } -function isTypeAnnotationAFunction(node, options) { - return (node.type === "TypeAnnotation" || node.type === "TSTypeAnnotation") && node.typeAnnotation.type === "FunctionTypeAnnotation" && !node.static && !sameLocStart(node, node.typeAnnotation, options); -} + continue; + } -const binaryishNodeTypes = new Set(["BinaryExpression", "LogicalExpression", "NGPipeExpression"]); + const placeholderIndex = +component; + parts.push(expressionDocs[placeholderIndex]); + } -function isBinaryish(node) { - return binaryishNodeTypes.has(node.type); -} + return concat$9(parts); + }); + const leadingWhitespace = /^\s/.test(text) ? " " : ""; + const trailingWhitespace = /\s$/.test(text) ? " " : ""; + const linebreak = options.htmlWhitespaceSensitivity === "ignore" ? hardline$6 : leadingWhitespace && trailingWhitespace ? line$3 : null; -function isMemberish(node) { - return node.type === "MemberExpression" || node.type === "OptionalMemberExpression" || node.type === "BindExpression" && node.object; -} + if (linebreak) { + return group$2(concat$9(["`", indent$6(concat$9([linebreak, group$2(contentDoc)])), linebreak, "`"])); + } -function isSimpleFlowType(node) { - const flowTypeAnnotations = ["AnyTypeAnnotation", "NullLiteralTypeAnnotation", "GenericTypeAnnotation", "ThisTypeAnnotation", "NumberTypeAnnotation", "VoidTypeAnnotation", "EmptyTypeAnnotation", "MixedTypeAnnotation", "BooleanTypeAnnotation", "BooleanLiteralTypeAnnotation", "StringTypeAnnotation"]; - return node && flowTypeAnnotations.includes(node.type) && !(node.type === "GenericTypeAnnotation" && node.typeParameters); + return group$2(concat$9(["`", leadingWhitespace, topLevelCount > 1 ? indent$6(group$2(contentDoc)) : group$2(contentDoc), trailingWhitespace, "`"])); } -const unitTestRe = /^(skip|[fx]?(it|describe|test))$/; +var html = format$4; -function isSkipOrOnlyBlock(node) { - return (node.callee.type === "MemberExpression" || node.callee.type === "OptionalMemberExpression") && node.callee.object.type === "Identifier" && node.callee.property.type === "Identifier" && unitTestRe.test(node.callee.object.name) && (node.callee.property.name === "only" || node.callee.property.name === "skip"); +const { + isBlockComment: isBlockComment$2 +} = utils$6; +const { + hasLeadingComment: hasLeadingComment$2 +} = comments$1; + +function getLanguage(path) { + if (isStyledJsx(path) || isStyledComponents(path) || isCssProp(path) || isAngularComponentStyles(path)) { + return "css"; + } + + if (isGraphQL(path)) { + return "graphql"; + } + + if (isHtml(path)) { + return "html"; + } + + if (isAngularComponentTemplate(path)) { + return "angular"; + } + + if (isMarkdown(path)) { + return "markdown"; + } } -function isUnitTestSetUp(n) { - const unitTestSetUpRe = /^(before|after)(Each|All)$/; - return n.callee.type === "Identifier" && unitTestSetUpRe.test(n.callee.name) && n.arguments.length === 1; -} // eg; `describe("some string", (done) => {})` +function embed(path, print, textToDoc, options) { + const node = path.getValue(); + if (node.type !== "TemplateLiteral" || // Bail out if any of the quasis have an invalid escape sequence + // (which would make the `cooked` value be `null`) + hasInvalidCookedValue(node)) { + return; + } -function isTestCall(n, parent) { - if (n.type !== "CallExpression") { - return false; + const language = getLanguage(path); + + if (!language) { + return; } - if (n.arguments.length === 1) { - if (isAngularTestWrapper(n) && parent && isTestCall(parent)) { - return isFunctionOrArrowExpression(n.arguments[0]); - } + if (language === "markdown") { + return markdown(path, print, textToDoc); + } - if (isUnitTestSetUp(n)) { - return isAngularTestWrapper(n.arguments[0]); - } - } else if (n.arguments.length === 2 || n.arguments.length === 3) { - if ((n.callee.type === "Identifier" && unitTestRe.test(n.callee.name) || isSkipOrOnlyBlock(n)) && (isTemplateLiteral(n.arguments[0]) || isStringLiteral(n.arguments[0]))) { - // it("name", () => { ... }, 2500) - if (n.arguments[2] && !isNumericLiteral(n.arguments[2])) { - return false; - } + if (language === "css") { + return css(path, print, textToDoc); + } - return (n.arguments.length === 2 ? isFunctionOrArrowExpression(n.arguments[1]) : isFunctionOrArrowExpressionWithBody(n.arguments[1]) && n.arguments[1].params.length <= 1) || isAngularTestWrapper(n.arguments[1]); - } + if (language === "graphql") { + return graphql(path, print, textToDoc); } - return false; + if (language === "html" || language === "angular") { + return html(path, print, textToDoc, options, { + parser: language + }); + } } +/** + * md`...` + * markdown`...` + */ -function hasLeadingComment$2(node) { - return node.comments && node.comments.some(comment => comment.leading); -} -function hasTrailingComment(node) { - return node.comments && node.comments.some(comment => comment.trailing); +function isMarkdown(path) { + const node = path.getValue(); + const parent = path.getParentNode(); + return parent && parent.type === "TaggedTemplateExpression" && node.quasis.length === 1 && parent.tag.type === "Identifier" && (parent.tag.name === "md" || parent.tag.name === "markdown"); } +/** + * Template literal in these contexts: + * + * css`` + * css.global`` + * css.resolve`` + */ -function isCallOrOptionalCallExpression(node) { - return node.type === "CallExpression" || node.type === "OptionalCallExpression"; -} -function hasDanglingComments(node) { - return node.comments && node.comments.some(comment => !comment.leading && !comment.trailing); +function isStyledJsx(path) { + const node = path.getValue(); + const parent = path.getParentNode(); + const parentParent = path.getParentNode(1); + return parentParent && node.quasis && parent.type === "JSXExpressionContainer" && parentParent.type === "JSXElement" && parentParent.openingElement.name.name === "style" && parentParent.openingElement.attributes.some(attribute => attribute.name.name === "jsx") || parent && parent.type === "TaggedTemplateExpression" && parent.tag.type === "Identifier" && parent.tag.name === "css" || parent && parent.type === "TaggedTemplateExpression" && parent.tag.type === "MemberExpression" && parent.tag.object.name === "css" && (parent.tag.property.name === "global" || parent.tag.property.name === "resolve"); } -/** identify if an angular expression seems to have side effects */ - +/** + * Angular Components can have: + * - Inline HTML template + * - Inline CSS styles + * + * ...which are both within template literals somewhere + * inside of the Component decorator factory. + * + * E.g. + * @Component({ + * template: `
...
`, + * styles: [`h1 { color: blue; }`] + * }) + */ -function hasNgSideEffect(path) { - return hasNode(path.getValue(), node => { - switch (node.type) { - case undefined: - return false; - case "CallExpression": - case "OptionalCallExpression": - case "AssignmentExpression": - return true; - } - }); +function isAngularComponentStyles(path) { + return path.match(node => node.type === "TemplateLiteral", (node, name) => node.type === "ArrayExpression" && name === "elements", (node, name) => (node.type === "Property" || node.type === "ObjectProperty") && node.key.type === "Identifier" && node.key.name === "styles" && name === "value", ...angularComponentObjectExpressionPredicates); } -function isNgForOf(node, index, parentNode) { - return node.type === "NGMicrosyntaxKeyedExpression" && node.key.name === "of" && index === 1 && parentNode.body[0].type === "NGMicrosyntaxLet" && parentNode.body[0].value === null; +function isAngularComponentTemplate(path) { + return path.match(node => node.type === "TemplateLiteral", (node, name) => (node.type === "Property" || node.type === "ObjectProperty") && node.key.type === "Identifier" && node.key.name === "template" && name === "value", ...angularComponentObjectExpressionPredicates); } -/** @param node {import("estree").TemplateLiteral} */ +const angularComponentObjectExpressionPredicates = [(node, name) => node.type === "ObjectExpression" && name === "properties", (node, name) => node.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === "Component" && name === "arguments", (node, name) => node.type === "Decorator" && name === "expression"]; +/** + * styled-components template literals + */ + +function isStyledComponents(path) { + const parent = path.getParentNode(); -function isSimpleTemplateLiteral(node) { - if (node.expressions.length === 0) { + if (!parent || parent.type !== "TaggedTemplateExpression") { return false; } - return node.expressions.every(expr => { - // Disallow comments since printDocToString can't print them here - if (expr.comments) { - return false; - } // Allow `x` and `this` - - - if (expr.type === "Identifier" || expr.type === "ThisExpression") { - return true; - } // Allow `a.b.c`, `a.b[c]`, and `this.x.y` - - - if (expr.type === "MemberExpression" || expr.type === "OptionalMemberExpression") { - let head = expr; - - while (head.type === "MemberExpression" || head.type === "OptionalMemberExpression") { - if (head.property.type !== "Identifier" && head.property.type !== "Literal" && head.property.type !== "StringLiteral" && head.property.type !== "NumericLiteral") { - return false; - } + const { + tag + } = parent; - head = head.object; + switch (tag.type) { + case "MemberExpression": + return (// styled.foo`` + isStyledIdentifier(tag.object) || // Component.extend`` + isStyledExtend(tag) + ); - if (head.comments) { - return false; - } - } + case "CallExpression": + return (// styled(Component)`` + isStyledIdentifier(tag.callee) || tag.callee.type === "MemberExpression" && (tag.callee.object.type === "MemberExpression" && ( // styled.foo.attrs({})`` + isStyledIdentifier(tag.callee.object.object) || // Component.extend.attrs({})`` + isStyledExtend(tag.callee.object)) || // styled(Component).attrs({})`` + tag.callee.object.type === "CallExpression" && isStyledIdentifier(tag.callee.object.callee)) + ); - if (head.type === "Identifier" || head.type === "ThisExpression") { - return true; - } + case "Identifier": + // css`` + return tag.name === "css"; + default: return false; - } - - return false; - }); + } } +/** + * JSX element with CSS prop + */ -function getFlowVariance(path) { - if (!path.variance) { - return null; - } // Babel 7.0 currently uses variance node type, and flow should - // follow suit soon: - // https://github.com/babel/babel/issues/4722 +function isCssProp(path) { + const parent = path.getParentNode(); + const parentParent = path.getParentNode(1); + return parentParent && parent.type === "JSXExpressionContainer" && parentParent.type === "JSXAttribute" && parentParent.name.type === "JSXIdentifier" && parentParent.name.name === "css"; +} - const variance = path.variance.kind || path.variance; +function isStyledIdentifier(node) { + return node.type === "Identifier" && node.name === "styled"; +} - switch (variance) { - case "plus": - return "+"; +function isStyledExtend(node) { + return /^[A-Z]/.test(node.object.name) && node.property.name === "extend"; +} +/* + * react-relay and graphql-tag + * graphql`...` + * graphql.experimental`...` + * gql`...` + * GraphQL comment block + * + * This intentionally excludes Relay Classic tags, as Prettier does not + * support Relay Classic formatting. + */ - case "minus": - return "-"; - default: - /* istanbul ignore next */ - return variance; - } +function isGraphQL(path) { + const node = path.getValue(); + const parent = path.getParentNode(); + return hasLanguageComment(node, "GraphQL") || parent && (parent.type === "TaggedTemplateExpression" && (parent.tag.type === "MemberExpression" && parent.tag.object.name === "graphql" && parent.tag.property.name === "experimental" || parent.tag.type === "Identifier" && (parent.tag.name === "gql" || parent.tag.name === "graphql")) || parent.type === "CallExpression" && parent.callee.type === "Identifier" && parent.callee.name === "graphql"); } -function classPropMayCauseASIProblems(path) { - const node = path.getNode(); +function hasLanguageComment(node, languageName) { + // This checks for a leading comment that is exactly `/* GraphQL */` + // In order to be in line with other implementations of this comment tag + // we will not trim the comment value and we will expect exactly one space on + // either side of the GraphQL string + // Also see ./clean.js + return hasLeadingComment$2(node, comment => isBlockComment$2(comment) && comment.value === ` ${languageName} `); +} +/** + * - html`...` + * - HTML comment block + */ - if (node.type !== "ClassProperty") { - return false; - } - const name = node.key && node.key.name; // this isn't actually possible yet with most parsers available today - // so isn't properly tested yet. +function isHtml(path) { + return hasLanguageComment(path.getValue(), "HTML") || path.match(node => node.type === "TemplateLiteral", (node, name) => node.type === "TaggedTemplateExpression" && node.tag.type === "Identifier" && node.tag.name === "html" && name === "quasi"); +} - if ((name === "static" || name === "get" || name === "set") && !node.value && !node.typeAnnotation) { - return true; - } +function hasInvalidCookedValue({ + quasis +}) { + return quasis.some(({ + value: { + cooked + } + }) => cooked === null); } -function classChildNeedsASIProtection(node) { - if (!node) { - return; - } +var embed_1 = embed; - if (node.static || node.accessibility // TypeScript - ) { - return false; - } +const { + isBlockComment: isBlockComment$3 +} = utils$6; +const ignoredProperties = new Set(["range", "raw", "comments", "leadingComments", "trailingComments", "innerComments", "extra", "start", "end", "loc", "flags", "errors", "tokens"]); - if (!node.computed) { - const name = node.key && node.key.name; +function clean(ast, newObj, parent) { + if (ast.type === "Program") { + delete newObj.sourceType; + } - if (name === "in" || name === "instanceof") { - return true; + if (ast.type === "BigIntLiteral" || ast.type === "BigIntLiteralTypeAnnotation") { + if (newObj.value) { + newObj.value = newObj.value.toLowerCase(); } } - switch (node.type) { - case "ClassProperty": - case "TSAbstractClassProperty": - return node.computed; + if (ast.type === "BigIntLiteral" || ast.type === "Literal") { + if (newObj.bigint) { + newObj.bigint = newObj.bigint.toLowerCase(); + } + } - case "MethodDefinition": // Flow + if (ast.type === "DecimalLiteral") { + newObj.value = Number(newObj.value); + } // We remove extra `;` and add them when needed - case "TSAbstractMethodDefinition": // TypeScript - case "ClassMethod": - case "ClassPrivateMethod": - { - // Babel - const isAsync = node.value ? node.value.async : node.async; - const isGenerator = node.value ? node.value.generator : node.generator; + if (ast.type === "EmptyStatement") { + return null; + } // We move text around, including whitespaces and add {" "} - if (isAsync || node.kind === "get" || node.kind === "set") { - return false; - } - if (node.computed || isGenerator) { - return true; - } + if (ast.type === "JSXText") { + return null; + } - return false; - } + if (ast.type === "JSXExpressionContainer" && (ast.expression.type === "Literal" || ast.expression.type === "StringLiteral") && ast.expression.value === " ") { + return null; + } // We change {'key': value} into {key: value}. + // And {key: value} into {'key': value}. + // Also for (some) number keys. - case "TSIndexSignature": - return true; - default: - /* istanbul ignore next */ - return false; + if ((ast.type === "Property" || ast.type === "ObjectProperty" || ast.type === "MethodDefinition" || ast.type === "ClassProperty" || ast.type === "ClassMethod" || ast.type === "FieldDefinition" || ast.type === "TSDeclareMethod" || ast.type === "TSPropertySignature" || ast.type === "ObjectTypeProperty") && typeof ast.key === "object" && ast.key && (ast.key.type === "Literal" || ast.key.type === "NumericLiteral" || ast.key.type === "StringLiteral" || ast.key.type === "Identifier")) { + delete newObj.key; } -} -function getTypeScriptMappedTypeModifier(tokenNode, keyword) { - if (tokenNode === "+") { - return "+" + keyword; - } else if (tokenNode === "-") { - return "-" + keyword; - } + if (ast.type === "OptionalMemberExpression" && ast.optional === false) { + newObj.type = "MemberExpression"; + delete newObj.optional; + } // Remove raw and cooked values from TemplateElement when it's CSS + // styled-jsx - return keyword; -} -function hasNewlineBetweenOrAfterDecorators(node, options) { - return hasNewlineInRange$2(options.originalText, options.locStart(node.decorators[0]), options.locEnd(getLast$1(node.decorators))) || hasNewline$3(options.originalText, options.locEnd(getLast$1(node.decorators))); -} // Only space, newline, carriage return, and tab are treated as whitespace -// inside JSX. + if (ast.type === "JSXElement" && ast.openingElement.name.name === "style" && ast.openingElement.attributes.some(attr => attr.name.name === "jsx")) { + const templateLiterals = newObj.children.filter(child => child.type === "JSXExpressionContainer" && child.expression.type === "TemplateLiteral").map(container => container.expression); + const quasis = templateLiterals.reduce((quasis, templateLiteral) => quasis.concat(templateLiteral.quasis), []); + quasis.forEach(q => delete q.value); + } // CSS template literals in css prop -const jsxWhitespaceChars = " \n\r\t"; -const matchJsxWhitespaceRegex = new RegExp("([" + jsxWhitespaceChars + "]+)"); -const containsNonJsxWhitespaceRegex = new RegExp("[^" + jsxWhitespaceChars + "]"); // Meaningful if it contains non-whitespace characters, -// or it contains whitespace without a new line. + if (ast.type === "JSXAttribute" && ast.name.name === "css" && ast.value.type === "JSXExpressionContainer" && ast.value.expression.type === "TemplateLiteral") { + newObj.value.expression.quasis.forEach(q => delete q.value); + } // We change quotes -function isMeaningfulJSXText(node) { - return isLiteral(node) && (containsNonJsxWhitespaceRegex.test(rawText(node)) || !/\n/.test(rawText(node))); -} -function hasJsxIgnoreComment(path) { - const node = path.getValue(); - const parent = path.getParentNode(); + if (ast.type === "JSXAttribute" && ast.value && ast.value.type === "Literal" && /["']|"|'/.test(ast.value.value)) { + newObj.value.value = newObj.value.value.replace(/["']|"|'/g, '"'); + } // Angular Components: Inline HTML template and Inline CSS styles - if (!parent || !node || !isJSXNode(node) || !isJSXNode(parent)) { - return false; - } // Lookup the previous sibling, ignoring any empty JSXText elements + const expression = ast.expression || ast.callee; - const index = parent.children.indexOf(node); - let prevSibling = null; + if (ast.type === "Decorator" && expression.type === "CallExpression" && expression.callee.name === "Component" && expression.arguments.length === 1) { + const astProps = ast.expression.arguments[0].properties; + newObj.expression.arguments[0].properties.forEach((prop, index) => { + let templateLiteral = null; - for (let i = index; i > 0; i--) { - const candidate = parent.children[i - 1]; + switch (astProps[index].key.name) { + case "styles": + if (prop.value.type === "ArrayExpression") { + templateLiteral = prop.value.elements[0]; + } - if (candidate.type === "JSXText" && !isMeaningfulJSXText(candidate)) { - continue; - } + break; - prevSibling = candidate; - break; - } + case "template": + if (prop.value.type === "TemplateLiteral") { + templateLiteral = prop.value; + } - return prevSibling && prevSibling.type === "JSXExpressionContainer" && prevSibling.expression.type === "JSXEmptyExpression" && prevSibling.expression.comments && prevSibling.expression.comments.find(comment => comment.value.trim() === "prettier-ignore"); -} + break; + } -function isEmptyJSXElement(node) { - if (node.children.length === 0) { - return true; - } + if (templateLiteral) { + templateLiteral.quasis.forEach(q => delete q.value); + } + }); + } // styled-components, graphql, markdown - if (node.children.length > 1) { - return false; - } // if there is one text child and does not contain any meaningful text - // we can treat the element as empty. + if (ast.type === "TaggedTemplateExpression" && (ast.tag.type === "MemberExpression" || ast.tag.type === "Identifier" && (ast.tag.name === "gql" || ast.tag.name === "graphql" || ast.tag.name === "css" || ast.tag.name === "md" || ast.tag.name === "markdown" || ast.tag.name === "html") || ast.tag.type === "CallExpression")) { + newObj.quasi.quasis.forEach(quasi => delete quasi.value); + } - const child = node.children[0]; - return isLiteral(child) && !isMeaningfulJSXText(child); -} + if (ast.type === "TemplateLiteral") { + // This checks for a leading comment that is exactly `/* GraphQL */` + // In order to be in line with other implementations of this comment tag + // we will not trim the comment value and we will expect exactly one space on + // either side of the GraphQL string + // Also see ./embed.js + const hasLanguageComment = ast.leadingComments && ast.leadingComments.some(comment => isBlockComment$3(comment) && ["GraphQL", "HTML"].some(languageName => comment.value === ` ${languageName} `)); -function hasPrettierIgnore(path) { - return hasIgnoreComment$1(path) || hasJsxIgnoreComment(path); -} + if (hasLanguageComment || parent.type === "CallExpression" && parent.callee.name === "graphql") { + newObj.quasis.forEach(quasi => delete quasi.value); + } // TODO: check parser + // `flow` and `typescript` don't have `leadingComments` -function isLastStatement(path) { - const parent = path.getParentNode(); - if (!parent) { - return true; + if (!ast.leadingComments) { + newObj.quasis.forEach(quasi => { + if (quasi.value) { + delete quasi.value.cooked; + } + }); + } } - const node = path.getValue(); - const body = (parent.body || parent.consequent).filter(stmt => stmt.type !== "EmptyStatement"); - return body && body[body.length - 1] === node; + if (ast.type === "InterpreterDirective") { + newObj.value = newObj.value.trimEnd(); + } } -function isFlowAnnotationComment(text, typeAnnotation, options) { - const start = options.locStart(typeAnnotation); - const end = skipWhitespace$2(text, options.locEnd(typeAnnotation)); - return text.slice(start, start + 2) === "/*" && text.slice(end, end + 2) === "*/"; -} +clean.ignoredProperties = ignoredProperties; +var clean_1 = clean; -function hasLeadingOwnLineComment(text, node, options) { - if (isJSXNode(node)) { - return hasNodeIgnoreComment$1(node); +const detectNewline = string => { + if (typeof string !== 'string') { + throw new TypeError('Expected a string'); } - const res = node.comments && node.comments.some(comment => comment.leading && hasNewline$3(text, options.locEnd(comment))); - return res; -} // This recurses the return argument, looking for the first token -// (the leftmost leaf node) and, if it (or its parents) has any -// leadingComments, returns true (so it can be wrapped in parens). - + const newlines = string.match(/(?:\r?\n)/g) || []; -function returnArgumentHasLeadingComment(options, argument) { - if (hasLeadingOwnLineComment(options.originalText, argument, options)) { - return true; + if (newlines.length === 0) { + return; } - if (hasNakedLeftSide(argument)) { - let leftMost = argument; - let newLeftMost; - - while (newLeftMost = getLeftSide(leftMost)) { - leftMost = newLeftMost; + const crlf = newlines.filter(newline => newline === '\r\n').length; + const lf = newlines.length - crlf; + return crlf > lf ? '\r\n' : '\n'; +}; - if (hasLeadingOwnLineComment(options.originalText, leftMost, options)) { - return true; - } - } - } +var detectNewline_1 = detectNewline; - return false; -} +var graceful = string => typeof string === 'string' && detectNewline(string) || '\n'; +detectNewline_1.graceful = graceful; -function isStringPropSafeToCoerceToIdentifier(node, options) { - return isStringLiteral(node.key) && isIdentifierName(node.key.value) && options.parser !== "json" && // With `--strictPropertyInitialization`, TS treats properties with quoted names differently than unquoted ones. - // See https://github.com/microsoft/TypeScript/pull/20075 - !((options.parser === "typescript" || options.parser === "babel-ts") && node.type === "ClassProperty"); -} +var build = createCommonjsModule(function (module, exports) { -function isJestEachTemplateLiteral(node, parentNode) { - /** - * describe.each`table`(name, fn) - * describe.only.each`table`(name, fn) - * describe.skip.each`table`(name, fn) - * test.each`table`(name, fn) - * test.only.each`table`(name, fn) - * test.skip.each`table`(name, fn) - * - * Ref: https://github.com/facebook/jest/pull/6102 - */ - const jestEachTriggerRegex = /^[xf]?(describe|it|test)$/; - return parentNode.type === "TaggedTemplateExpression" && parentNode.quasi === node && parentNode.tag.type === "MemberExpression" && parentNode.tag.property.type === "Identifier" && parentNode.tag.property.name === "each" && (parentNode.tag.object.type === "Identifier" && jestEachTriggerRegex.test(parentNode.tag.object.name) || parentNode.tag.object.type === "MemberExpression" && parentNode.tag.object.property.type === "Identifier" && (parentNode.tag.object.property.name === "only" || parentNode.tag.object.property.name === "skip") && parentNode.tag.object.object.type === "Identifier" && jestEachTriggerRegex.test(parentNode.tag.object.object.name)); -} + Object.defineProperty(exports, '__esModule', { + value: true + }); + exports.extract = extract; + exports.strip = strip; + exports.parse = parse; + exports.parseWithComments = parseWithComments; + exports.print = print; -function templateLiteralHasNewLines(template) { - return template.quasis.some(quasi => quasi.value.raw.includes("\n")); -} + function _os() { + const data = os__default['default']; -function isTemplateOnItsOwnLine(n, text, options) { - return (n.type === "TemplateLiteral" && templateLiteralHasNewLines(n) || n.type === "TaggedTemplateExpression" && templateLiteralHasNewLines(n.quasi)) && !hasNewline$3(text, options.locStart(n), { - backwards: true - }); -} + _os = function () { + return data; + }; -function needsHardlineAfterDanglingComment(node) { - if (!node.comments) { - return false; + return data; } - const lastDanglingComment = getLast$1(node.comments.filter(comment => !comment.leading && !comment.trailing)); - return lastDanglingComment && !comments$1.isBlockComment(lastDanglingComment); -} // If we have nested conditional expressions, we want to print them in JSX mode -// if there's at least one JSXElement somewhere in the tree. -// -// A conditional expression chain like this should be printed in normal mode, -// because there aren't JSXElements anywhere in it: -// -// isA ? "A" : isB ? "B" : isC ? "C" : "Unknown"; -// -// But a conditional expression chain like this should be printed in JSX mode, -// because there is a JSXElement in the last ConditionalExpression: -// -// isA ? "A" : isB ? "B" : isC ? "C" : Unknown; -// -// This type of ConditionalExpression chain is structured like this in the AST: -// -// ConditionalExpression { -// test: ..., -// consequent: ..., -// alternate: ConditionalExpression { -// test: ..., -// consequent: ..., -// alternate: ConditionalExpression { -// test: ..., -// consequent: ..., -// alternate: ..., -// } -// } -// } -// -// We want to traverse over that shape and convert it into a flat structure so -// that we can find if there's a JSXElement somewhere inside. - + function _detectNewline() { + const data = _interopRequireDefault(detectNewline_1); -function getConditionalChainContents(node) { - // Given this code: - // - // // Using a ConditionalExpression as the consequent is uncommon, but should - // // be handled. - // A ? B : C ? D : E ? F ? G : H : I - // - // which has this AST: - // - // ConditionalExpression { - // test: Identifier(A), - // consequent: Identifier(B), - // alternate: ConditionalExpression { - // test: Identifier(C), - // consequent: Identifier(D), - // alternate: ConditionalExpression { - // test: Identifier(E), - // consequent: ConditionalExpression { - // test: Identifier(F), - // consequent: Identifier(G), - // alternate: Identifier(H), - // }, - // alternate: Identifier(I), - // } - // } - // } - // - // we should return this Array: - // - // [ - // Identifier(A), - // Identifier(B), - // Identifier(C), - // Identifier(D), - // Identifier(E), - // Identifier(F), - // Identifier(G), - // Identifier(H), - // Identifier(I) - // ]; - // - // This loses the information about whether each node was the test, - // consequent, or alternate, but we don't care about that here- we are only - // flattening this structure to find if there's any JSXElements inside. - const nonConditionalExpressions = []; + _detectNewline = function () { + return data; + }; - function recurse(node) { - if (node.type === "ConditionalExpression") { - recurse(node.test); - recurse(node.consequent); - recurse(node.alternate); - } else { - nonConditionalExpressions.push(node); - } + return data; } - recurse(node); - return nonConditionalExpressions; -} + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { + default: obj + }; + } + /** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ -function conditionalExpressionChainContainsJSX(node) { - return Boolean(getConditionalChainContents(node).find(isJSXNode)); -} // Logic to check for args with multiple anonymous functions. For instance, -// the following call should be split on multiple lines for readability: -// source.pipe(map((x) => x + x), filter((x) => x % 2 === 0)) + const commentEndRe = /\*\/$/; + const commentStartRe = /^\/\*\*/; + const docblockRe = /^\s*(\/\*\*?(.|\r?\n)*?\*\/)/; + const lineCommentRe = /(^|\s+)\/\/([^\r\n]*)/g; + const ltrimNewlineRe = /^(\r?\n)+/; + const multilineRe = /(?:^|\r?\n) *(@[^\r\n]*?) *\r?\n *(?![^@\r\n]*\/\/[^]*)([^@\r\n\s][^@\r\n]+?) *\r?\n/g; + const propertyRe = /(?:^|\r?\n) *@(\S+) *([^\r\n]*)/g; + const stringStartRe = /(\r?\n|^) *\* ?/g; + const STRING_ARRAY = []; -function isFunctionCompositionArgs(args) { - if (args.length <= 1) { - return false; + function extract(contents) { + const match = contents.match(docblockRe); + return match ? match[0].trimLeft() : ''; } - let count = 0; - - for (const arg of args) { - if (isFunctionOrArrowExpression(arg)) { - count += 1; + function strip(contents) { + const match = contents.match(docblockRe); + return match && match[0] ? contents.substring(match[0].length) : contents; + } - if (count > 1) { - return true; - } - } else if (isCallOrOptionalCallExpression(arg)) { - for (const childArg of arg.arguments) { - if (isFunctionOrArrowExpression(childArg)) { - return true; - } - } - } + function parse(docblock) { + return parseWithComments(docblock).pragmas; } - return false; -} // Logic to determine if a call is a “long curried function call”. -// See https://github.com/prettier/prettier/issues/1420. -// -// `connect(a, b, c)(d)` -// In the above call expression, the second call is the parent node and the -// first call is the current node. + function parseWithComments(docblock) { + const line = (0, _detectNewline().default)(docblock) || _os().EOL; + docblock = docblock.replace(commentStartRe, '').replace(commentEndRe, '').replace(stringStartRe, '$1'); // Normalize multi-line directives -function isLongCurriedCallExpression(path) { - const node = path.getValue(); - const parent = path.getParentNode(); - return isCallOrOptionalCallExpression(node) && isCallOrOptionalCallExpression(parent) && parent.callee === node && node.arguments.length > parent.arguments.length && parent.arguments.length > 0; -} -/** - * @param {import('estree').Node} node - * @param {number} depth - * @returns {boolean} - */ + let prev = ''; + while (prev !== docblock) { + prev = docblock; + docblock = docblock.replace(multilineRe, `${line}$1 $2${line}`); + } -function isSimpleCallArgument(node, depth) { - if (depth >= 2) { - return false; - } + docblock = docblock.replace(ltrimNewlineRe, '').trimRight(); + const result = Object.create(null); + const comments = docblock.replace(propertyRe, '').replace(ltrimNewlineRe, '').trimRight(); + let match; - const isChildSimple = child => isSimpleCallArgument(child, depth + 1); + while (match = propertyRe.exec(docblock)) { + // strip linecomments from pragmas + const nextPragma = match[2].replace(lineCommentRe, ''); - const regexpPattern = node.type === "Literal" && node.regex && node.regex.pattern || node.type === "RegExpLiteral" && node.pattern; + if (typeof result[match[1]] === 'string' || Array.isArray(result[match[1]])) { + result[match[1]] = STRING_ARRAY.concat(result[match[1]], nextPragma); + } else { + result[match[1]] = nextPragma; + } + } - if (regexpPattern && regexpPattern.length > 5) { - return false; + return { + comments, + pragmas: result + }; } - if (node.type === "Literal" || node.type === "BooleanLiteral" || node.type === "NullLiteral" || node.type === "NumericLiteral" || node.type === "StringLiteral" || node.type === "Identifier" || node.type === "ThisExpression" || node.type === "Super" || node.type === "BigIntLiteral" || node.type === "PrivateName" || node.type === "ArgumentPlaceholder" || node.type === "RegExpLiteral" || node.type === "Import") { - return true; - } + function print({ + comments = '', + pragmas = {} + }) { + const line = (0, _detectNewline().default)(comments) || _os().EOL; - if (node.type === "TemplateLiteral") { - return node.expressions.every(isChildSimple); - } + const head = '/**'; + const start = ' *'; + const tail = ' */'; + const keys = Object.keys(pragmas); + const printedObject = keys.map(key => printKeyValues(key, pragmas[key])).reduce((arr, next) => arr.concat(next), []).map(keyValue => start + ' ' + keyValue + line).join(''); - if (node.type === "ObjectExpression") { - return node.properties.every(p => !p.computed && (p.shorthand || p.value && isChildSimple(p.value))); - } + if (!comments) { + if (keys.length === 0) { + return ''; + } - if (node.type === "ArrayExpression") { - return node.elements.every(x => x == null || isChildSimple(x)); - } + if (keys.length === 1 && !Array.isArray(pragmas[keys[0]])) { + const value = pragmas[keys[0]]; + return `${head} ${printKeyValues(keys[0], value)[0]}${tail}`; + } + } - if (node.type === "CallExpression" || node.type === "OptionalCallExpression" || node.type === "NewExpression") { - return isSimpleCallArgument(node.callee, depth) && node.arguments.every(isChildSimple); + const printedComments = comments.split(line).map(textLine => `${start} ${textLine}`).join(line) + line; + return head + line + (comments ? printedComments : '') + (comments && keys.length ? start + line : '') + printedObject + tail; } - if (node.type === "MemberExpression" || node.type === "OptionalMemberExpression") { - return isSimpleCallArgument(node.object, depth) && isSimpleCallArgument(node.property, depth); + function printKeyValues(key, valueOrArray) { + return STRING_ARRAY.concat(valueOrArray).map(value => `@${key} ${value}`.trim()); } +}); - if (node.type === "UnaryExpression" && (node.operator === "!" || node.operator === "-")) { - return isSimpleCallArgument(node.argument, depth); - } +const { + parseWithComments, + strip, + extract, + print +} = build; +const { + getShebang: getShebang$1 +} = util; +const { + normalizeEndOfLine: normalizeEndOfLine$2 +} = endOfLine; - if (node.type === "TSNonNullExpression") { - return isSimpleCallArgument(node.expression, depth); - } +function parseDocBlock(text) { + const shebang = getShebang$1(text); - return false; -} + if (shebang) { + text = text.slice(shebang.length + 1); + } -function rawText(node) { - return node.extra ? node.extra.raw : node.raw; + const docBlock = extract(text); + const { + pragmas, + comments + } = parseWithComments(docBlock); + return { + shebang, + text, + pragmas, + comments + }; } -function identity$1(x) { - return x; +function hasPragma(text) { + const pragmas = Object.keys(parseDocBlock(text).pragmas); + return pragmas.includes("prettier") || pragmas.includes("format"); } -function isTSXFile(options) { - return options.filepath && /\.tsx$/i.test(options.filepath); +function insertPragma(originalText) { + const { + shebang, + text, + pragmas, + comments + } = parseDocBlock(originalText); + const strippedText = strip(text); + const docBlock = print({ + pragmas: Object.assign({ + format: "" + }, pragmas), + comments: comments.trimStart() + }); + return (shebang ? `${shebang}\n` : "") + // normalise newlines (mitigate use of os.EOL by jest-docblock) + normalizeEndOfLine$2(docBlock) + (strippedText.startsWith("\n") ? "\n" : "\n\n") + strippedText; } -var utils$6 = { - classChildNeedsASIProtection, - classPropMayCauseASIProblems, - conditionalExpressionChainContainsJSX, - getFlowVariance, - getLeftSidePathName, - getParentExportDeclaration, - getTypeScriptMappedTypeModifier, - hasDanglingComments, - hasFlowAnnotationComment, - hasFlowShorthandAnnotationComment, - hasLeadingComment: hasLeadingComment$2, - hasLeadingOwnLineComment, - hasNakedLeftSide, - hasNewlineBetweenOrAfterDecorators, - hasNgSideEffect, - hasNode, - hasPrettierIgnore, - hasTrailingComment, - identity: identity$1, - isBinaryish, - isCallOrOptionalCallExpression, - isEmptyJSXElement, - isExportDeclaration, - isFlowAnnotationComment, - isFunctionCompositionArgs, - isFunctionNotation, - isFunctionOrArrowExpression, - isGetterOrSetter, - isJestEachTemplateLiteral, - isJSXNode, - isJSXWhitespaceExpression, - isLastStatement, - isLiteral, - isLongCurriedCallExpression, - isSimpleCallArgument, - isMeaningfulJSXText, - isMemberExpressionChain, - isMemberish, - isNgForOf, - isNumericLiteral, - isObjectType, - isObjectTypePropertyAFunction, - isSimpleFlowType, - isSimpleTemplateLiteral, - isStringLiteral, - isStringPropSafeToCoerceToIdentifier, - isTemplateOnItsOwnLine, - isTestCall, - isTheOnlyJSXElementInMarkdown, - isTSXFile, - isTypeAnnotationAFunction, - matchJsxWhitespaceRegex, - needsHardlineAfterDanglingComment, - rawText, - returnArgumentHasLeadingComment +var pragma = { + hasPragma, + insertPragma }; const { + getFunctionParameters: getFunctionParameters$2, getLeftSidePathName: getLeftSidePathName$1, - hasFlowShorthandAnnotationComment: hasFlowShorthandAnnotationComment$1, + hasFlowShorthandAnnotationComment: hasFlowShorthandAnnotationComment$2, hasNakedLeftSide: hasNakedLeftSide$1, - hasNode: hasNode$1 + hasNode: hasNode$1, + isBitwiseOperator: isBitwiseOperator$1, + startsWithNoLookaheadToken: startsWithNoLookaheadToken$1, + shouldFlatten: shouldFlatten$1, + getPrecedence: getPrecedence$1 } = utils$6; function needsParens(path, options) { @@ -38139,14 +41170,7 @@ function needsParens(path, options) { } const name = path.getName(); - const node = path.getNode(); // If the value of this path is some child of a Node and not a Node - // itself, then it doesn't need parentheses. Only Node objects (in - // fact, only Expression nodes) need parentheses. - - if (path.getValue() !== node) { - return false; - } // to avoid unexpected `}}` in HTML interpolations - + const node = path.getNode(); // to avoid unexpected `}}` in HTML interpolations if (options.__isInHtmlInterpolation && !options.bracketSpacing && endsWithRightBracket(node) && isFollowedByRightBracket(path)) { return true; @@ -38160,7 +41184,7 @@ function needsParens(path, options) { if ( // Preserve parens if we have a Flow annotation comment, unless we're using the Flow // parser. The Flow parser turns Flow comments into type annotation nodes in its // AST, which we handle separately. - options.parser !== "flow" && hasFlowShorthandAnnotationComment$1(path.getValue())) { + options.parser !== "flow" && hasFlowShorthandAnnotationComment$2(path.getValue())) { return true; } // Identifiers never need parentheses. @@ -38178,74 +41202,101 @@ function needsParens(path, options) { return false; } - if (parent.type === "ParenthesizedExpression") { - return false; - } // Add parens around the extends clause of a class. It is needed for almost - // all expressions. + switch (parent.type) { + case "ParenthesizedExpression": + return false; + + case "ClassDeclaration": + case "ClassExpression": + { + // Add parens around the extends clause of a class. It is needed for almost + // all expressions. + if (name === "superClass" && (node.type === "ArrowFunctionExpression" || node.type === "AssignmentExpression" || node.type === "AwaitExpression" || node.type === "BinaryExpression" || node.type === "ConditionalExpression" || node.type === "LogicalExpression" || node.type === "NewExpression" || node.type === "ObjectExpression" || node.type === "ParenthesizedExpression" || node.type === "SequenceExpression" || node.type === "TaggedTemplateExpression" || node.type === "UnaryExpression" || node.type === "UpdateExpression" || node.type === "YieldExpression")) { + return true; + } + break; + } - if ((parent.type === "ClassDeclaration" || parent.type === "ClassExpression") && parent.superClass === node && (node.type === "ArrowFunctionExpression" || node.type === "AssignmentExpression" || node.type === "AwaitExpression" || node.type === "BinaryExpression" || node.type === "ConditionalExpression" || node.type === "LogicalExpression" || node.type === "NewExpression" || node.type === "ObjectExpression" || node.type === "ParenthesizedExpression" || node.type === "SequenceExpression" || node.type === "TaggedTemplateExpression" || node.type === "UnaryExpression" || node.type === "UpdateExpression" || node.type === "YieldExpression")) { - return true; - } + case "ExportDefaultDeclaration": + { + return (// `export default function` or `export default class` can't be followed by + // anything after. So an expression like `export default (function(){}).toString()` + // needs to be followed by a parentheses + shouldWrapFunctionForExportDefault(path, options) || // `export default (foo, bar)` also needs parentheses + node.type === "SequenceExpression" + ); + } - if (parent.type === "ExportDefaultDeclaration") { - return (// `export default function` or `export default class` can't be followed by - // anything after. So an expression like `export default (function(){}).toString()` - // needs to be followed by a parentheses - shouldWrapFunctionForExportDefault(path, options) || // `export default (foo, bar)` also needs parentheses - node.type === "SequenceExpression" - ); - } + case "Decorator": + { + if (name === "expression") { + let hasCallExpression = false; + let hasMemberExpression = false; + let current = node; + + while (current) { + switch (current.type) { + case "MemberExpression": + hasMemberExpression = true; + current = current.object; + break; - if (parent.type === "Decorator" && parent.expression === node) { - let hasCallExpression = false; - let hasMemberExpression = false; - let current = node; + case "CallExpression": + if ( + /** @(x().y) */ + hasMemberExpression || + /** @(x().y()) */ + hasCallExpression) { + return true; + } - while (current) { - switch (current.type) { - case "MemberExpression": - hasMemberExpression = true; - current = current.object; - break; + hasCallExpression = true; + current = current.callee; + break; - case "CallExpression": - if ( - /** @(x().y) */ - hasMemberExpression || - /** @(x().y()) */ - hasCallExpression) { - return true; + case "Identifier": + return false; + + default: + return true; + } } - hasCallExpression = true; - current = current.callee; - break; + return true; + } - case "Identifier": - return false; + break; + } - default: + case "ExpressionStatement": + { + if (startsWithNoLookaheadToken$1(node, + /* forbidFunctionClassAndDoExpr */ + true)) { return true; + } + + break; } - } - return true; - } + case "ArrowFunctionExpression": + { + if (name === "body" && node.type !== "SequenceExpression" && // these have parens added anyway + startsWithNoLookaheadToken$1(node, + /* forbidFunctionClassAndDoExpr */ + false)) { + return true; + } - if (parent.type === "ArrowFunctionExpression" && parent.body === node && node.type !== "SequenceExpression" && // these have parens added anyway - util$1.startsWithNoLookaheadToken(node, - /* forbidFunctionClassAndDoExpr */ - false) || parent.type === "ExpressionStatement" && util$1.startsWithNoLookaheadToken(node, - /* forbidFunctionClassAndDoExpr */ - true)) { - return true; + break; + } } switch (node.type) { case "SpreadElement": case "SpreadProperty": - return parent.type === "MemberExpression" && name === "object" && parent.object === node; + return name === "object" && parent.type === "MemberExpression"; case "UpdateExpression": if (parent.type === "UnaryExpression") { @@ -38275,7 +41326,7 @@ function needsParens(path, options) { return name === "callee"; case "BinaryExpression": - return parent.operator === "**" && name === "left"; + return name === "left" && parent.operator === "**"; case "TSNonNullExpression": return true; @@ -38286,32 +41337,22 @@ function needsParens(path, options) { case "BinaryExpression": { - if (parent.type === "UpdateExpression") { + if (parent.type === "UpdateExpression" || parent.type === "PipelineTopicExpression" && node.operator === "|>") { return true; - } - - const isLeftOfAForStatement = node => { - let i = 0; + } // We add parentheses to any `a in b` inside `ForStatement` initializer + // https://github.com/prettier/prettier/issues/907#issuecomment-284304321 - while (node) { - const parent = path.getParentNode(i++); - if (!parent) { - return false; - } + if (node.operator === "in" && isPathInForStatementInitializer(path)) { + return true; + } - if (parent.type === "ForStatement" && parent.init === node) { - return true; - } + if (node.operator === "|>" && node.extra && node.extra.parenthesized) { + const grandParent = path.getParentNode(1); - node = parent; + if (grandParent.type === "BinaryExpression" && grandParent.operator === "|>") { + return true; } - - return false; - }; - - if (node.operator === "in" && isLeftOfAForStatement(node)) { - return true; } } // fallthrough @@ -38330,7 +41371,7 @@ function needsParens(path, options) { case "ClassExpression": case "ClassDeclaration": - return name === "superClass" && parent.superClass === node; + return name === "superClass"; case "TSTypeAssertion": case "TaggedTemplateExpression": @@ -38350,7 +41391,7 @@ function needsParens(path, options) { return name === "object"; case "AssignmentExpression": - return parent.left === node && (node.type === "TSTypeAssertion" || node.type === "TSAsExpression"); + return name === "left" && (node.type === "TSTypeAssertion" || node.type === "TSAsExpression"); case "LogicalExpression": if (node.type === "LogicalExpression") { @@ -38361,35 +41402,38 @@ function needsParens(path, options) { case "BinaryExpression": { - if (!node.operator && node.type !== "TSTypeAssertion") { + const { + operator, + type + } = node; + + if (!operator && type !== "TSTypeAssertion") { return true; } - const po = parent.operator; - const pp = util$1.getPrecedence(po); - const no = node.operator; - const np = util$1.getPrecedence(no); + const precedence = getPrecedence$1(operator); + const parentOperator = parent.operator; + const parentPrecedence = getPrecedence$1(parentOperator); - if (pp > np) { + if (parentPrecedence > precedence) { return true; } - if (pp === np && name === "right") { - assert$1.strictEqual(parent.right, node); + if (name === "right" && parentPrecedence === precedence) { return true; } - if (pp === np && !util$1.shouldFlatten(po, no)) { + if (parentPrecedence === precedence && !shouldFlatten$1(parentOperator, operator)) { return true; } - if (pp < np && no === "%") { - return po === "+" || po === "-"; + if (parentPrecedence < precedence && operator === "%") { + return parentOperator === "+" || parentOperator === "-"; } // Add parenthesis when working with bitwise operators // It's not strictly needed but helps with code understanding - if (util$1.isBitwiseOperator(po)) { + if (isBitwiseOperator$1(parentOperator)) { return true; } @@ -38437,7 +41481,6 @@ function needsParens(path, options) { switch (parent.type) { case "TaggedTemplateExpression": case "UnaryExpression": - case "BinaryExpression": case "LogicalExpression": case "SpreadElement": case "SpreadProperty": @@ -38456,7 +41499,16 @@ function needsParens(path, options) { return name === "callee"; case "ConditionalExpression": - return parent.test === node; + return name === "test"; + + case "BinaryExpression": + { + if (!node.argument && parent.operator === "|>") { + return false; + } + + return true; + } default: return false; @@ -38464,7 +41516,7 @@ function needsParens(path, options) { case "TSJSDocFunctionType": case "TSConditionalType": - if (parent.type === "TSConditionalType" && node === parent.extendsType) { + if (name === "extendsType" && parent.type === "TSConditionalType") { return true; } @@ -38472,7 +41524,7 @@ function needsParens(path, options) { case "TSFunctionType": case "TSConstructorType": - if (parent.type === "TSConditionalType" && node === parent.checkType) { + if (name === "checkType" && parent.type === "TSConditionalType") { return true; } @@ -38486,9 +41538,15 @@ function needsParens(path, options) { // fallthrough - case "TSTypeOperator": case "TSInferType": - return parent.type === "TSArrayType" || parent.type === "TSOptionalType" || parent.type === "TSRestType" || parent.type === "TSIndexedAccessType" && node === parent.objectType || parent.type === "TSTypeOperator" || parent.type === "TSTypeAnnotation" && /^TSJSDoc/.test(path.getParentNode(1).type); + if (node.type === "TSInferType" && parent.type === "TSRestType") { + return false; + } + + // fallthrough + + case "TSTypeOperator": + return parent.type === "TSArrayType" || parent.type === "TSOptionalType" || parent.type === "TSRestType" || name === "objectType" && parent.type === "TSIndexedAccessType" || parent.type === "TSTypeOperator" || parent.type === "TSTypeAnnotation" && /^TSJSDoc/.test(path.getParentNode(1).type); case "ArrayTypeAnnotation": return parent.type === "NullableTypeAnnotation"; @@ -38506,43 +41564,40 @@ function needsParens(path, options) { return ancestor.type === "UnionTypeAnnotation" || ancestor.type === "IntersectionTypeAnnotation" || ancestor.type === "ArrayTypeAnnotation" || // We should check ancestor's parent to know whether the parentheses // are really needed, but since ??T doesn't make sense this check // will almost never be true. - ancestor.type === "NullableTypeAnnotation"; + ancestor.type === "NullableTypeAnnotation" || // See #5283 + parent.type === "FunctionTypeParam" && parent.name === null && getFunctionParameters$2(node).some(param => param.typeAnnotation && param.typeAnnotation.type === "NullableTypeAnnotation"); } case "StringLiteral": case "NumericLiteral": case "Literal": - if (typeof node.value === "string" && parent.type === "ExpressionStatement" && ( // TypeScript workaround for https://github.com/JamesHenry/typescript-estree/issues/2 - // See corresponding workaround in printer.js case: "Literal" - options.parser !== "typescript" && !parent.directive || options.parser === "typescript" && options.originalText.charAt(options.locStart(node) - 1) === "(")) { + if (typeof node.value === "string" && parent.type === "ExpressionStatement" && !parent.directive) { // To avoid becoming a directive const grandParent = path.getParentNode(1); return grandParent.type === "Program" || grandParent.type === "BlockStatement"; } - return parent.type === "MemberExpression" && typeof node.value === "number" && name === "object" && parent.object === node; + return name === "object" && parent.type === "MemberExpression" && typeof node.value === "number"; case "AssignmentExpression": { const grandParent = path.getParentNode(1); - if (parent.type === "ArrowFunctionExpression" && parent.body === node) { + if (name === "body" && parent.type === "ArrowFunctionExpression") { return true; - } else if (parent.type === "ClassProperty" && parent.key === node && parent.computed) { - return false; - } else if (parent.type === "TSPropertySignature" && parent.name === node) { + } else if (name === "key" && (parent.type === "ClassProperty" || parent.type === "FieldDefinition") && parent.computed) { return false; - } else if (parent.type === "ForStatement" && (parent.init === node || parent.update === node)) { + } else if ((name === "init" || name === "update") && parent.type === "ForStatement") { return false; } else if (parent.type === "ExpressionStatement") { return node.left.type === "ObjectPattern"; - } else if (parent.type === "TSPropertySignature" && parent.key === node) { + } else if (name === "key" && parent.type === "TSPropertySignature") { return false; } else if (parent.type === "AssignmentExpression") { return false; } else if (parent.type === "SequenceExpression" && grandParent && grandParent.type === "ForStatement" && (grandParent.init === parent || grandParent.update === parent)) { return false; - } else if (parent.type === "Property" && parent.value === node) { + } else if (name === "value" && parent.type === "Property" && grandParent && grandParent.type === "ObjectPattern" && grandParent.properties.includes(parent)) { return false; } else if (parent.type === "NGChainedExpression") { return false; @@ -38575,7 +41630,7 @@ function needsParens(path, options) { return name === "callee"; case "ConditionalExpression": - return name === "test" && parent.test === node; + return name === "test"; case "MemberExpression": case "OptionalMemberExpression": @@ -38604,6 +41659,12 @@ function needsParens(path, options) { case "ArrowFunctionExpression": switch (parent.type) { + case "PipelineTopicExpression": + return !!(node.extra && node.extra.parenthesized); + + case "BinaryExpression": + return parent.operator !== "|>" || node.extra && node.extra.parenthesized; + case "NewExpression": case "CallExpression": case "OptionalCallExpression": @@ -38618,7 +41679,6 @@ function needsParens(path, options) { case "TaggedTemplateExpression": case "UnaryExpression": case "LogicalExpression": - case "BinaryExpression": case "AwaitExpression": case "TSTypeAssertion": return true; @@ -38633,7 +41693,7 @@ function needsParens(path, options) { case "ClassExpression": switch (parent.type) { case "NewExpression": - return name === "callee" && parent.callee === node; + return name === "callee"; default: return false; @@ -38641,17 +41701,20 @@ function needsParens(path, options) { case "OptionalMemberExpression": case "OptionalCallExpression": - if (parent.type === "MemberExpression" && name === "object" || (parent.type === "CallExpression" || parent.type === "NewExpression") && name === "callee") { - return true; - } + { + const parentParent = path.getParentNode(1); + if (name === "object" && parent.type === "MemberExpression" || name === "callee" && (parent.type === "CallExpression" || parent.type === "NewExpression") || parent.type === "TSNonNullExpression" && parentParent.type === "MemberExpression" && parentParent.object === parent) { + return true; + } + } // fallthrough case "CallExpression": case "MemberExpression": case "TaggedTemplateExpression": case "TSNonNullExpression": - if ((parent.type === "BindExpression" || parent.type === "NewExpression") && name === "callee") { + if (name === "callee" && (parent.type === "BindExpression" || parent.type === "NewExpression")) { let object = node; while (object) { @@ -38685,10 +41748,11 @@ function needsParens(path, options) { return false; case "BindExpression": - return (parent.type === "BindExpression" || parent.type === "NewExpression") && name === "callee" || (parent.type === "MemberExpression" || parent.type === "OptionalMemberExpression") && name === "object"; + return name === "callee" && (parent.type === "BindExpression" || parent.type === "NewExpression") || name === "object" && (parent.type === "MemberExpression" || parent.type === "OptionalMemberExpression"); case "NGPipeExpression": - if (parent.type === "NGRoot" || parent.type === "NGMicrosyntaxExpression" || parent.type === "ObjectProperty" || parent.type === "ArrayExpression" || (parent.type === "CallExpression" || parent.type === "OptionalCallExpression") && parent.arguments[name] === node || parent.type === "NGPipeExpression" && name === "right" || parent.type === "MemberExpression" && name === "property" || parent.type === "AssignmentExpression") { + if (parent.type === "NGRoot" || parent.type === "NGMicrosyntaxExpression" || parent.type === "ObjectProperty" && // Preserve parens for compatibility with AngularJS expressions + !(node.extra && node.extra.parenthesized) || parent.type === "ArrayExpression" || (parent.type === "CallExpression" || parent.type === "OptionalCallExpression") && parent.arguments[name] === node || name === "right" && parent.type === "NGPipeExpression" || name === "property" && parent.type === "MemberExpression" || parent.type === "AssignmentExpression") { return false; } @@ -38696,7 +41760,7 @@ function needsParens(path, options) { case "JSXFragment": case "JSXElement": - return name === "callee" || parent.type !== "ArrayExpression" && parent.type !== "ArrowFunctionExpression" && parent.type !== "AssignmentExpression" && parent.type !== "AssignmentPattern" && parent.type !== "BinaryExpression" && parent.type !== "CallExpression" && parent.type !== "NewExpression" && parent.type !== "ConditionalExpression" && parent.type !== "ExpressionStatement" && parent.type !== "JsExpressionRoot" && parent.type !== "JSXAttribute" && parent.type !== "JSXElement" && parent.type !== "JSXExpressionContainer" && parent.type !== "JSXFragment" && parent.type !== "LogicalExpression" && parent.type !== "ObjectProperty" && parent.type !== "OptionalCallExpression" && parent.type !== "Property" && parent.type !== "ReturnStatement" && parent.type !== "ThrowStatement" && parent.type !== "TypeCastExpression" && parent.type !== "VariableDeclarator" && parent.type !== "YieldExpression"; + return name === "callee" || name === "left" && parent.type === "BinaryExpression" && parent.operator === "<" || parent.type !== "ArrayExpression" && parent.type !== "ArrowFunctionExpression" && parent.type !== "AssignmentExpression" && parent.type !== "AssignmentPattern" && parent.type !== "BinaryExpression" && parent.type !== "CallExpression" && parent.type !== "NewExpression" && parent.type !== "ConditionalExpression" && parent.type !== "ExpressionStatement" && parent.type !== "JsExpressionRoot" && parent.type !== "JSXAttribute" && parent.type !== "JSXElement" && parent.type !== "JSXExpressionContainer" && parent.type !== "JSXFragment" && parent.type !== "LogicalExpression" && parent.type !== "ObjectProperty" && parent.type !== "OptionalCallExpression" && parent.type !== "Property" && parent.type !== "ReturnStatement" && parent.type !== "ThrowStatement" && parent.type !== "TypeCastExpression" && parent.type !== "VariableDeclarator" && parent.type !== "YieldExpression"; case "TypeAnnotation": return name === "returnType" && parent.type === "ArrowFunctionExpression" && includesFunctionTypeInObjectType(node); @@ -38706,7 +41770,24 @@ function needsParens(path, options) { } function isStatement(node) { - return node.type === "BlockStatement" || node.type === "BreakStatement" || node.type === "ClassBody" || node.type === "ClassDeclaration" || node.type === "ClassMethod" || node.type === "ClassProperty" || node.type === "ClassPrivateProperty" || node.type === "ContinueStatement" || node.type === "DebuggerStatement" || node.type === "DeclareClass" || node.type === "DeclareExportAllDeclaration" || node.type === "DeclareExportDeclaration" || node.type === "DeclareFunction" || node.type === "DeclareInterface" || node.type === "DeclareModule" || node.type === "DeclareModuleExports" || node.type === "DeclareVariable" || node.type === "DoWhileStatement" || node.type === "EnumDeclaration" || node.type === "ExportAllDeclaration" || node.type === "ExportDefaultDeclaration" || node.type === "ExportNamedDeclaration" || node.type === "ExpressionStatement" || node.type === "ForInStatement" || node.type === "ForOfStatement" || node.type === "ForStatement" || node.type === "FunctionDeclaration" || node.type === "IfStatement" || node.type === "ImportDeclaration" || node.type === "InterfaceDeclaration" || node.type === "LabeledStatement" || node.type === "MethodDefinition" || node.type === "ReturnStatement" || node.type === "SwitchStatement" || node.type === "ThrowStatement" || node.type === "TryStatement" || node.type === "TSDeclareFunction" || node.type === "TSEnumDeclaration" || node.type === "TSImportEqualsDeclaration" || node.type === "TSInterfaceDeclaration" || node.type === "TSModuleDeclaration" || node.type === "TSNamespaceExportDeclaration" || node.type === "TypeAlias" || node.type === "VariableDeclaration" || node.type === "WhileStatement" || node.type === "WithStatement"; + return node.type === "BlockStatement" || node.type === "BreakStatement" || node.type === "ClassBody" || node.type === "ClassDeclaration" || node.type === "ClassMethod" || node.type === "ClassProperty" || node.type === "FieldDefinition" || node.type === "ClassPrivateProperty" || node.type === "ContinueStatement" || node.type === "DebuggerStatement" || node.type === "DeclareClass" || node.type === "DeclareExportAllDeclaration" || node.type === "DeclareExportDeclaration" || node.type === "DeclareFunction" || node.type === "DeclareInterface" || node.type === "DeclareModule" || node.type === "DeclareModuleExports" || node.type === "DeclareVariable" || node.type === "DoWhileStatement" || node.type === "EnumDeclaration" || node.type === "ExportAllDeclaration" || node.type === "ExportDefaultDeclaration" || node.type === "ExportNamedDeclaration" || node.type === "ExpressionStatement" || node.type === "ForInStatement" || node.type === "ForOfStatement" || node.type === "ForStatement" || node.type === "FunctionDeclaration" || node.type === "IfStatement" || node.type === "ImportDeclaration" || node.type === "InterfaceDeclaration" || node.type === "LabeledStatement" || node.type === "MethodDefinition" || node.type === "ReturnStatement" || node.type === "SwitchStatement" || node.type === "ThrowStatement" || node.type === "TryStatement" || node.type === "TSDeclareFunction" || node.type === "TSEnumDeclaration" || node.type === "TSImportEqualsDeclaration" || node.type === "TSInterfaceDeclaration" || node.type === "TSModuleDeclaration" || node.type === "TSNamespaceExportDeclaration" || node.type === "TypeAlias" || node.type === "VariableDeclaration" || node.type === "WhileStatement" || node.type === "WithStatement"; +} + +function isPathInForStatementInitializer(path) { + let i = 0; + let node = path.getValue(); + + while (node) { + const parent = path.getParentNode(i++); + + if (parent && parent.type === "ForStatement" && parent.init === node) { + return true; + } + + node = parent; + } + + return false; } function includesFunctionTypeInObjectType(node) { @@ -38785,320 +41866,520 @@ function shouldWrapFunctionForExportDefault(path, options) { return false; } - return path.call(childPath => shouldWrapFunctionForExportDefault(childPath, options), ...getLeftSidePathName$1(path, node)); + return path.call(childPath => shouldWrapFunctionForExportDefault(childPath, options), ...getLeftSidePathName$1(path, node)); +} + +var needsParens_1 = needsParens; + +const { + builders: { + concat: concat$a, + join: join$4, + line: line$4, + group: group$3, + softline: softline$4, + indent: indent$7 + } +} = document; + +function printHtmlBinding(path, options, print) { + const node = path.getValue(); + + if (options.__onHtmlBindingRoot && path.getName() === null) { + options.__onHtmlBindingRoot(node, options); + } + + if (node.type !== "File") { + return; + } + + if (options.__isVueForBindingLeft) { + return path.call(functionDeclarationPath => { + const printed = join$4(concat$a([",", line$4]), functionDeclarationPath.map(print, "params")); + const { + params + } = functionDeclarationPath.getValue(); + + if (params.length === 1) { + return printed; + } + + return concat$a(["(", indent$7(concat$a([softline$4, group$3(printed)])), softline$4, ")"]); + }, "program", "body", 0); + } + + if (options.__isVueBindings) { + return path.call(functionDeclarationPath => join$4(concat$a([",", line$4]), functionDeclarationPath.map(print, "params")), "program", "body", 0); + } +} // based on https://github.com/prettier/prettier/blob/master/src/language-html/syntax-vue.js isVueEventBindingExpression() + + +function isVueEventBindingExpression(node) { + switch (node.type) { + case "MemberExpression": + switch (node.property.type) { + case "Identifier": + case "NumericLiteral": + case "StringLiteral": + return isVueEventBindingExpression(node.object); + } + + return false; + + case "Identifier": + return true; + + default: + return false; + } +} + +var htmlBinding = { + isVueEventBindingExpression, + printHtmlBinding +}; + +function preprocess(ast, options) { + switch (options.parser) { + case "json": + case "json5": + case "json-stringify": + case "__js_expression": + case "__vue_expression": + return Object.assign({}, ast, { + type: options.parser.startsWith("__") ? "JsExpressionRoot" : "JsonRoot", + node: ast, + comments: [], + rootMarker: options.rootMarker + }); + + default: + return ast; + } +} + +var printPreprocess = preprocess; + +/** @type {import("assert")} */ + + +const { + builders: { + concat: concat$b, + group: group$4, + indent: indent$8, + join: join$5, + line: line$5, + hardline: hardline$7 + } +} = document; +const { + hasNewlineBetweenOrAfterDecorators: hasNewlineBetweenOrAfterDecorators$1, + getParentExportDeclaration: getParentExportDeclaration$1 +} = utils$6; + +function printOptionalToken(path) { + const node = path.getValue(); + + if (!node.optional || // It's an optional computed method parsed by typescript-estree. + // "?" is printed in `printMethod`. + node.type === "Identifier" && node === path.getParentNode().key) { + return ""; + } + + if (node.type === "OptionalCallExpression" || node.type === "OptionalMemberExpression" && node.computed) { + return "?."; + } + + return "?"; +} + +function printFunctionTypeParameters(path, options, print) { + const fun = path.getValue(); + + if (fun.typeArguments) { + return path.call(print, "typeArguments"); + } + + if (fun.typeParameters) { + return path.call(print, "typeParameters"); + } + + return ""; +} + +function printBindExpressionCallee(path, options, print) { + return concat$b(["::", path.call(print, "callee")]); +} + +function printTypeScriptModifiers(path, options, print) { + const n = path.getValue(); + + if (!n.modifiers || !n.modifiers.length) { + return ""; + } + + return concat$b([join$5(" ", path.map(print, "modifiers")), " "]); +} + +function printDecorators(path, options, print) { + const node = path.getValue(); + return group$4(concat$b([join$5(line$5, path.map(print, "decorators")), hasNewlineBetweenOrAfterDecorators$1(node, options) ? hardline$7 : line$5])); +} + +function printFlowDeclaration(path, printed) { + const parentExportDecl = getParentExportDeclaration$1(path); + + if (parentExportDecl) { + assert__default['default'].strictEqual(parentExportDecl.type, "DeclareExportDeclaration"); + return printed; + } // If the parent node has type DeclareExportDeclaration, then it + // will be responsible for printing the "declare" token. Otherwise + // it needs to be printed with this non-exported declaration node. + + + return concat$b(["declare ", printed]); +} + +function adjustClause(node, clause, forceSpace) { + if (node.type === "EmptyStatement") { + return ";"; + } + + if (node.type === "BlockStatement" || forceSpace) { + return concat$b([" ", clause]); + } + + return indent$8(concat$b([line$5, clause])); +} + +var misc = { + printOptionalToken, + printFunctionTypeParameters, + printBindExpressionCallee, + printTypeScriptModifiers, + printDecorators, + printFlowDeclaration, + adjustClause +}; + +const { + builders: { + concat: concat$c, + softline: softline$5, + group: group$5, + indent: indent$9, + join: join$6, + line: line$6, + ifBreak: ifBreak$1, + hardline: hardline$8 + } +} = document; +const { + printDanglingComments: printDanglingComments$1 +} = comments; +const { + hasDanglingComments: hasDanglingComments$1, + shouldPrintComma: shouldPrintComma$1, + needsHardlineAfterDanglingComment: needsHardlineAfterDanglingComment$1 +} = utils$6; +const { + locStart: locStart$4, + hasSameLoc: hasSameLoc$1 +} = loc; +/** + * @typedef {import("../../document").Doc} Doc + */ + +function printImportDeclaration(path, options, print) { + const node = path.getValue(); + const semi = options.semi ? ";" : ""; + /** @type{Doc[]} */ + + const parts = []; + const { + importKind + } = node; + parts.push("import"); + + if (importKind && importKind !== "value") { + parts.push(" ", importKind); + } + + parts.push(printModuleSpecifiers(path, options, print), printModuleSource(path, options, print), printImportAssertions(path, options, print)); + parts.push(semi); + return concat$c(parts); } -var needsParens_1 = needsParens; +function printExportDeclaration(path, options, print) { + const node = path.getValue(); + /** @type{Doc[]} */ -const { - builders: { - concat: concat$5, - join: join$3, - line: line$3 + const parts = []; + const { + type, + exportKind, + declaration + } = node; + + if (type === "DeclareExportDeclaration") { + parts.push("declare "); } -} = document; -function printHtmlBinding(path, options, print) { - const node = path.getValue(); + parts.push("export"); + const isDefaultExport = node.default || type === "ExportDefaultDeclaration"; - if (options.__onHtmlBindingRoot && path.getName() === null) { - options.__onHtmlBindingRoot(node, options); + if (isDefaultExport) { + parts.push(" default"); } - if (node.type !== "File") { - return; + if (hasDanglingComments$1(node)) { + parts.push(" ", printDanglingComments$1(path, options, + /* sameIndent */ + true)); + + if (needsHardlineAfterDanglingComment$1(node)) { + parts.push(hardline$8); + } } - if (options.__isVueForBindingLeft) { - return path.call(functionDeclarationPath => { - const { - params - } = functionDeclarationPath.getValue(); - return concat$5([params.length > 1 ? "(" : "", join$3(concat$5([",", line$3]), functionDeclarationPath.map(print, "params")), params.length > 1 ? ")" : ""]); - }, "program", "body", 0); + if (declaration) { + parts.push(" ", path.call(print, "declaration")); + } else { + parts.push(exportKind === "type" ? " type" : "", printModuleSpecifiers(path, options, print), printModuleSource(path, options, print), printImportAssertions(path, options, print)); } - if (options.__isVueSlotScope) { - return path.call(functionDeclarationPath => join$3(concat$5([",", line$3]), functionDeclarationPath.map(print, "params")), "program", "body", 0); + if (shouldExportDeclarationPrintSemi(node, options)) { + parts.push(";"); } -} // based on https://github.com/prettier/prettier/blob/master/src/language-html/syntax-vue.js isVueEventBindingExpression() + return concat$c(parts); +} -function isVueEventBindingExpression(node) { - switch (node.type) { - case "MemberExpression": - switch (node.property.type) { - case "Identifier": - case "NumericLiteral": - case "StringLiteral": - return isVueEventBindingExpression(node.object); - } +function printExportAllDeclaration(path, options, print) { + const node = path.getValue(); + let semi = options.semi ? ";" : ""; + /** @type{Doc[]} */ - return false; + const parts = []; + const { + type, + exportKind, + exported + } = node; - case "Identifier": - return true; + if (type === "DeclareExportAllDeclaration") { + parts.push("declare "); + semi = ""; + } - default: - return false; + parts.push("export"); + + if (exportKind === "type") { + parts.push(" type"); + } + + parts.push(" *"); + + if (exported) { + parts.push(" as ", path.call(print, "exported")); } + + parts.push(printModuleSource(path, options, print), printImportAssertions(path, options, print), semi); + return concat$c(parts); } -var htmlBinding = { - isVueEventBindingExpression, - printHtmlBinding -}; +function shouldExportDeclarationPrintSemi(node, options) { + if (!options.semi) { + return false; + } -function preprocess(ast, options) { - switch (options.parser) { - case "json": - case "json5": - case "json-stringify": - case "__js_expression": - case "__vue_expression": - return Object.assign({}, ast, { - type: options.parser.startsWith("__") ? "JsExpressionRoot" : "JsonRoot", - node: ast, - comments: [], - rootMarker: options.rootMarker - }); + const { + type, + declaration + } = node; + const isDefaultExport = node.default || type === "ExportDefaultDeclaration"; - default: - return ast; + if (!declaration) { + return true; } -} -var preprocess_1 = preprocess; + const { + type: declarationType + } = declaration; -const { - shouldFlatten: shouldFlatten$1, - getNextNonSpaceNonCommentCharacter: getNextNonSpaceNonCommentCharacter$1, - hasNewline: hasNewline$4, - hasNewlineInRange: hasNewlineInRange$3, - getLast: getLast$2, - getStringWidth: getStringWidth$3, - printString: printString$1, - printNumber: printNumber$1, - hasIgnoreComment: hasIgnoreComment$2, - hasNodeIgnoreComment: hasNodeIgnoreComment$2, - getPenultimate: getPenultimate$1, - startsWithNoLookaheadToken: startsWithNoLookaheadToken$1, - getIndentSize: getIndentSize$2, - getPreferredQuote: getPreferredQuote$1 -} = util$1; -const { - isNextLineEmpty: isNextLineEmpty$2, - isNextLineEmptyAfterIndex: isNextLineEmptyAfterIndex$2, - getNextNonSpaceNonCommentCharacterIndex: getNextNonSpaceNonCommentCharacterIndex$3 -} = utilShared; -const { - insertPragma: insertPragma$1 -} = pragma; -const { - printHtmlBinding: printHtmlBinding$1, - isVueEventBindingExpression: isVueEventBindingExpression$1 -} = htmlBinding; -const { - classChildNeedsASIProtection: classChildNeedsASIProtection$1, - classPropMayCauseASIProblems: classPropMayCauseASIProblems$1, - conditionalExpressionChainContainsJSX: conditionalExpressionChainContainsJSX$1, - getFlowVariance: getFlowVariance$1, - getLeftSidePathName: getLeftSidePathName$2, - getParentExportDeclaration: getParentExportDeclaration$1, - getTypeScriptMappedTypeModifier: getTypeScriptMappedTypeModifier$1, - hasDanglingComments: hasDanglingComments$1, - hasFlowAnnotationComment: hasFlowAnnotationComment$1, - hasFlowShorthandAnnotationComment: hasFlowShorthandAnnotationComment$2, - hasLeadingComment: hasLeadingComment$3, - hasLeadingOwnLineComment: hasLeadingOwnLineComment$1, - hasNakedLeftSide: hasNakedLeftSide$2, - hasNewlineBetweenOrAfterDecorators: hasNewlineBetweenOrAfterDecorators$1, - hasNgSideEffect: hasNgSideEffect$1, - hasPrettierIgnore: hasPrettierIgnore$1, - hasTrailingComment: hasTrailingComment$1, - identity: identity$2, - isBinaryish: isBinaryish$1, - isCallOrOptionalCallExpression: isCallOrOptionalCallExpression$1, - isEmptyJSXElement: isEmptyJSXElement$1, - isExportDeclaration: isExportDeclaration$1, - isFlowAnnotationComment: isFlowAnnotationComment$1, - isFunctionCompositionArgs: isFunctionCompositionArgs$1, - isFunctionNotation: isFunctionNotation$1, - isFunctionOrArrowExpression: isFunctionOrArrowExpression$1, - isGetterOrSetter: isGetterOrSetter$1, - isJestEachTemplateLiteral: isJestEachTemplateLiteral$1, - isJSXNode: isJSXNode$1, - isJSXWhitespaceExpression: isJSXWhitespaceExpression$1, - isLastStatement: isLastStatement$1, - isLiteral: isLiteral$1, - isLongCurriedCallExpression: isLongCurriedCallExpression$1, - isMeaningfulJSXText: isMeaningfulJSXText$1, - isMemberExpressionChain: isMemberExpressionChain$1, - isMemberish: isMemberish$1, - isNgForOf: isNgForOf$1, - isNumericLiteral: isNumericLiteral$1, - isObjectType: isObjectType$1, - isObjectTypePropertyAFunction: isObjectTypePropertyAFunction$1, - isSimpleCallArgument: isSimpleCallArgument$1, - isSimpleFlowType: isSimpleFlowType$1, - isSimpleTemplateLiteral: isSimpleTemplateLiteral$1, - isStringLiteral: isStringLiteral$1, - isStringPropSafeToCoerceToIdentifier: isStringPropSafeToCoerceToIdentifier$1, - isTemplateOnItsOwnLine: isTemplateOnItsOwnLine$1, - isTestCall: isTestCall$1, - isTheOnlyJSXElementInMarkdown: isTheOnlyJSXElementInMarkdown$1, - isTSXFile: isTSXFile$1, - isTypeAnnotationAFunction: isTypeAnnotationAFunction$1, - matchJsxWhitespaceRegex: matchJsxWhitespaceRegex$1, - needsHardlineAfterDanglingComment: needsHardlineAfterDanglingComment$1, - rawText: rawText$1, - returnArgumentHasLeadingComment: returnArgumentHasLeadingComment$1 -} = utils$6; -const needsQuoteProps = new WeakMap(); -const { - builders: { - concat: concat$6, - join: join$4, - line: line$4, - hardline: hardline$4, - softline: softline$2, - literalline: literalline$2, - group: group$2, - indent: indent$3, - align: align$1, - conditionalGroup: conditionalGroup$1, - fill: fill$3, - ifBreak: ifBreak$1, - breakParent: breakParent$2, - lineSuffixBoundary: lineSuffixBoundary$1, - addAlignmentToDoc: addAlignmentToDoc$2, - dedent: dedent$1 - }, - utils: { - willBreak: willBreak$1, - isLineNext: isLineNext$1, - isEmpty: isEmpty$1, - removeLines: removeLines$1 - }, - printer: { - printDocToString: printDocToString$2 + if (isDefaultExport && declarationType !== "ClassDeclaration" && declarationType !== "FunctionDeclaration" && declarationType !== "TSInterfaceDeclaration" && declarationType !== "DeclareClass" && declarationType !== "DeclareFunction" && declarationType !== "TSDeclareFunction" && declarationType !== "EnumDeclaration") { + return true; } -} = document; -let uid = 0; -function shouldPrintComma(options, level) { - level = level || "es5"; + return false; +} - switch (options.trailingComma) { - case "all": - if (level === "all") { - return true; - } +function printModuleSource(path, options, print) { + const node = path.getValue(); - // fallthrough + if (!node.source) { + return ""; + } + /** @type{Doc[]} */ - case "es5": - if (level === "es5") { - return true; - } - // fallthrough + const parts = []; - case "none": - default: - return false; + if (!shouldNotPrintSpecifiers(node, options)) { + parts.push(" from"); } + + parts.push(" ", path.call(print, "source")); + return concat$c(parts); } -function genericPrint(path, options, printPath, args) { +function printModuleSpecifiers(path, options, print) { const node = path.getValue(); - let needsParens = false; - const linesWithoutParens = printPathNoParens(path, options, printPath, args); - if (!node || isEmpty$1(linesWithoutParens)) { - return linesWithoutParens; + if (shouldNotPrintSpecifiers(node, options)) { + return ""; } + /** @type{Doc[]} */ - const parentExportDecl = getParentExportDeclaration$1(path); - const decorators = []; - if (node.type === "ClassMethod" || node.type === "ClassPrivateMethod" || node.type === "ClassProperty" || node.type === "TSAbstractClassProperty" || node.type === "ClassPrivateProperty" || node.type === "MethodDefinition" || node.type === "TSAbstractMethodDefinition" || node.type === "TSDeclareMethod") ; else if (node.decorators && node.decorators.length > 0 && // If the parent node is an export declaration and the decorator - // was written before the export, the export will be responsible - // for printing the decorators. - !(parentExportDecl && options.locStart(parentExportDecl, { - ignoreDecorators: true - }) > options.locStart(node.decorators[0]))) { - const shouldBreak = node.type === "ClassExpression" || node.type === "ClassDeclaration" || hasNewlineBetweenOrAfterDecorators$1(node, options); - const separator = shouldBreak ? hardline$4 : line$4; - path.each(decoratorPath => { - let decorator = decoratorPath.getValue(); + const parts = [" "]; - if (decorator.expression) { - decorator = decorator.expression; + if (node.specifiers && node.specifiers.length > 0) { + const standaloneSpecifiers = []; + const groupedSpecifiers = []; + path.each(specifierPath => { + const specifierType = path.getValue().type; + + if (specifierType === "ExportNamespaceSpecifier" || specifierType === "ExportDefaultSpecifier" || specifierType === "ImportNamespaceSpecifier" || specifierType === "ImportDefaultSpecifier") { + standaloneSpecifiers.push(print(specifierPath)); + } else if (specifierType === "ExportSpecifier" || specifierType === "ImportSpecifier") { + groupedSpecifiers.push(print(specifierPath)); } else { - decorator = decorator.callee; + /* istanbul ignore next */ + throw new Error(`Unknown specifier type ${JSON.stringify(specifierType)}`); } + }, "specifiers"); + parts.push(join$6(", ", standaloneSpecifiers)); - decorators.push(printPath(decoratorPath), separator); - }, "decorators"); + if (groupedSpecifiers.length !== 0) { + if (standaloneSpecifiers.length !== 0) { + parts.push(", "); + } - if (parentExportDecl) { - decorators.unshift(hardline$4); + const canBreak = groupedSpecifiers.length > 1 || standaloneSpecifiers.length > 0 || node.specifiers.some(node => node.comments); + + if (canBreak) { + parts.push(group$5(concat$c(["{", indent$9(concat$c([options.bracketSpacing ? line$6 : softline$5, join$6(concat$c([",", line$6]), groupedSpecifiers)])), ifBreak$1(shouldPrintComma$1(options) ? "," : ""), options.bracketSpacing ? line$6 : softline$5, "}"]))); + } else { + parts.push(concat$c(["{", options.bracketSpacing ? " " : "", concat$c(groupedSpecifiers), options.bracketSpacing ? " " : "", "}"])); + } } - } else if (isExportDeclaration$1(node) && node.declaration && node.declaration.decorators && node.declaration.decorators.length > 0 && // Only print decorators here if they were written before the export, - // otherwise they are printed by the node.declaration - options.locStart(node, { - ignoreDecorators: true - }) > options.locStart(node.declaration.decorators[0])) { - // Export declarations are responsible for printing any decorators - // that logically apply to node.declaration. - path.each(decoratorPath => { - const decorator = decoratorPath.getValue(); - const prefix = decorator.type === "Decorator" ? "" : "@"; - decorators.push(prefix, printPath(decoratorPath), hardline$4); - }, "declaration", "decorators"); } else { - // Nodes with decorators can't have parentheses, so we can avoid - // computing pathNeedsParens() except in this case. - needsParens = needsParens_1(path, options); + parts.push("{}"); } - const parts = []; + return concat$c(parts); +} - if (needsParens) { - parts.unshift("("); +function shouldNotPrintSpecifiers(node, options) { + const { + type, + importKind, + source, + specifiers + } = node; + + if (type !== "ImportDeclaration" || Array.isArray(specifiers) && specifiers.length > 0 || importKind === "type") { + return false; + } // TODO: check tokens + + + return !/{\s*}/.test(options.originalText.slice(locStart$4(node), locStart$4(source))); +} + +function printImportAssertions(path, options, print) { + const node = path.getNode(); + + if (Array.isArray(node.assertions) && node.assertions.length !== 0) { + return concat$c([" assert {", options.bracketSpacing ? " " : "", join$6(", ", path.map(print, "assertions")), options.bracketSpacing ? " " : "", "}"]); } - parts.push(linesWithoutParens); + return ""; +} - if (needsParens) { - const node = path.getValue(); +function printModuleSpecifier(path, options, print) { + const node = path.getNode(); + const { + type, + importKind + } = node; + /** @type{Doc[]} */ - if (hasFlowShorthandAnnotationComment$2(node)) { - parts.push(" /*"); - parts.push(node.trailingComments[0].value.trimStart()); - parts.push("*/"); - node.trailingComments[0].printed = true; - } + const parts = []; - parts.push(")"); + if (type === "ImportSpecifier" && importKind) { + parts.push(importKind, " "); } - if (decorators.length > 0) { - return group$2(concat$6(decorators.concat(parts))); + const isImport = type.startsWith("Import"); + const leftSideProperty = isImport ? "imported" : "local"; + const rightSideProperty = isImport ? "local" : "exported"; + let left = ""; + let right = ""; + + if (type === "ExportNamespaceSpecifier" || type === "ImportNamespaceSpecifier") { + left = "*"; + } else if (node[leftSideProperty]) { + left = path.call(print, leftSideProperty); } - return concat$6(parts); -} + if (node[rightSideProperty] && (!node[leftSideProperty] || // import {a as a} from '.' + !hasSameLoc$1(node[leftSideProperty], node[rightSideProperty]))) { + right = path.call(print, rightSideProperty); + } -function printDecorators(path, options, print) { - const node = path.getValue(); - return group$2(concat$6([join$4(line$4, path.map(print, "decorators")), hasNewlineBetweenOrAfterDecorators$1(node, options) ? hardline$4 : line$4])); + parts.push(left, left && right ? " as " : "", right); + return concat$c(parts); } + +var module$3 = { + printImportDeclaration, + printExportDeclaration, + printExportAllDeclaration, + printModuleSpecifier +}; + +const { + hasNewlineInRange: hasNewlineInRange$4 +} = util; +const { + isJSXNode: isJSXNode$2, + isBlockComment: isBlockComment$4 +} = utils$6; +const { + locStart: locStart$5, + locEnd: locEnd$4 +} = loc; +const { + builders: { + concat: concat$d, + line: line$7, + softline: softline$6, + group: group$6, + indent: indent$a, + align: align$2, + ifBreak: ifBreak$2, + dedent: dedent$1, + breakParent: breakParent$2 + } +} = document; /** - * The following is the shared logic for - * ternary operators, namely ConditionalExpression - * and TSConditionalType + * @typedef {import("../../document").Doc} Doc + * @typedef {import("../../common/fast-path")} FastPath + * + * @typedef {any} Options - Prettier options (TBD ...) + * * @typedef {Object} OperatorOptions * @property {() => Array} beforeParts - Parts to print before the `?`. * @property {(breakClosingParen: boolean) => Array} afterParts - Parts to print after the conditional expression. @@ -39107,11 +42388,111 @@ function printDecorators(path, options, print) { * @property {string} consequentNodePropertyName - The property at which the consequent node can be found on the main node, eg "consequent". * @property {string} alternateNodePropertyName - The property at which the alternate node can be found on the main node, eg "alternate". * @property {string[]} testNodePropertyNames - The properties at which the test nodes can be found on the main node, eg "test". + */ +// If we have nested conditional expressions, we want to print them in JSX mode +// if there's at least one JSXElement somewhere in the tree. +// +// A conditional expression chain like this should be printed in normal mode, +// because there aren't JSXElements anywhere in it: +// +// isA ? "A" : isB ? "B" : isC ? "C" : "Unknown"; +// +// But a conditional expression chain like this should be printed in JSX mode, +// because there is a JSXElement in the last ConditionalExpression: +// +// isA ? "A" : isB ? "B" : isC ? "C" : Unknown; +// +// This type of ConditionalExpression chain is structured like this in the AST: +// +// ConditionalExpression { +// test: ..., +// consequent: ..., +// alternate: ConditionalExpression { +// test: ..., +// consequent: ..., +// alternate: ConditionalExpression { +// test: ..., +// consequent: ..., +// alternate: ..., +// } +// } +// } +// +// We want to traverse over that shape and convert it into a flat structure so +// that we can find if there's a JSXElement somewhere inside. + +function getConditionalChainContents(node) { + // Given this code: + // + // // Using a ConditionalExpression as the consequent is uncommon, but should + // // be handled. + // A ? B : C ? D : E ? F ? G : H : I + // + // which has this AST: + // + // ConditionalExpression { + // test: Identifier(A), + // consequent: Identifier(B), + // alternate: ConditionalExpression { + // test: Identifier(C), + // consequent: Identifier(D), + // alternate: ConditionalExpression { + // test: Identifier(E), + // consequent: ConditionalExpression { + // test: Identifier(F), + // consequent: Identifier(G), + // alternate: Identifier(H), + // }, + // alternate: Identifier(I), + // } + // } + // } + // + // we should return this Array: + // + // [ + // Identifier(A), + // Identifier(B), + // Identifier(C), + // Identifier(D), + // Identifier(E), + // Identifier(F), + // Identifier(G), + // Identifier(H), + // Identifier(I) + // ]; + // + // This loses the information about whether each node was the test, + // consequent, or alternate, but we don't care about that here- we are only + // flattening this structure to find if there's any JSXElements inside. + const nonConditionalExpressions = []; + + function recurse(node) { + if (node.type === "ConditionalExpression") { + recurse(node.test); + recurse(node.consequent); + recurse(node.alternate); + } else { + nonConditionalExpressions.push(node); + } + } + + recurse(node); + return nonConditionalExpressions; +} + +function conditionalExpressionChainContainsJSX(node) { + return getConditionalChainContents(node).some(isJSXNode$2); +} +/** + * The following is the shared logic for + * ternary operators, namely ConditionalExpression + * and TSConditionalType * @param {FastPath} path - The path to the ConditionalExpression/TSConditionalType node. * @param {Options} options - Prettier options * @param {Function} print - Print function to call recursively * @param {OperatorOptions} operatorOptions - * @returns Doc + * @returns {Doc} */ @@ -39142,13 +42523,13 @@ function printTernaryOperator(path, options, print, operatorOptions) { const firstNonConditionalParent = currentParent || parent; const lastConditionalParent = previousParent; - if (operatorOptions.shouldCheckJsx && (isJSXNode$1(node[operatorOptions.testNodePropertyNames[0]]) || isJSXNode$1(consequentNode) || isJSXNode$1(alternateNode) || conditionalExpressionChainContainsJSX$1(lastConditionalParent))) { + if (operatorOptions.shouldCheckJsx && (isJSXNode$2(node[operatorOptions.testNodePropertyNames[0]]) || isJSXNode$2(consequentNode) || isJSXNode$2(alternateNode) || conditionalExpressionChainContainsJSX(lastConditionalParent))) { jsxMode = true; forceNoIndent = true; // Even though they don't need parens, we wrap (almost) everything in // parens when using ?: within JSX, because the parens are analogous to // curly braces in an if statement. - const wrap = doc => concat$6([ifBreak$1("(", ""), indent$3(concat$6([softline$2, doc])), softline$2, ifBreak$1(")", "")]); // The only things we don't wrap are: + const wrap = doc => concat$d([ifBreak$2("(", ""), indent$a(concat$d([softline$6, doc])), softline$6, ifBreak$2(")", "")]); // The only things we don't wrap are: // * Nested conditional expressions in alternates // * null // * undefined @@ -39159,14 +42540,19 @@ function printTernaryOperator(path, options, print, operatorOptions) { parts.push(" ? ", isNil(consequentNode) ? path.call(print, operatorOptions.consequentNodePropertyName) : wrap(path.call(print, operatorOptions.consequentNodePropertyName)), " : ", alternateNode.type === operatorOptions.conditionalNodeType || isNil(alternateNode) ? path.call(print, operatorOptions.alternateNodePropertyName) : wrap(path.call(print, operatorOptions.alternateNodePropertyName))); } else { // normal mode - const part = concat$6([line$4, "? ", consequentNode.type === operatorOptions.conditionalNodeType ? ifBreak$1("", "(") : "", align$1(2, path.call(print, operatorOptions.consequentNodePropertyName)), consequentNode.type === operatorOptions.conditionalNodeType ? ifBreak$1("", ")") : "", line$4, ": ", alternateNode.type === operatorOptions.conditionalNodeType ? path.call(print, operatorOptions.alternateNodePropertyName) : align$1(2, path.call(print, operatorOptions.alternateNodePropertyName))]); - parts.push(parent.type !== operatorOptions.conditionalNodeType || parent[operatorOptions.alternateNodePropertyName] === node || isParentTest ? part : options.useTabs ? dedent$1(indent$3(part)) : align$1(Math.max(0, options.tabWidth - 2), part)); + const part = concat$d([line$7, "? ", consequentNode.type === operatorOptions.conditionalNodeType ? ifBreak$2("", "(") : "", align$2(2, path.call(print, operatorOptions.consequentNodePropertyName)), consequentNode.type === operatorOptions.conditionalNodeType ? ifBreak$2("", ")") : "", line$7, ": ", alternateNode.type === operatorOptions.conditionalNodeType ? path.call(print, operatorOptions.alternateNodePropertyName) : align$2(2, path.call(print, operatorOptions.alternateNodePropertyName))]); + parts.push(parent.type !== operatorOptions.conditionalNodeType || parent[operatorOptions.alternateNodePropertyName] === node || isParentTest ? part : options.useTabs ? dedent$1(indent$a(part)) : align$2(Math.max(0, options.tabWidth - 2), part)); } // We want a whole chain of ConditionalExpressions to all // break if any of them break. That means we should only group around the // outer-most ConditionalExpression. - const maybeGroup = doc => parent === firstNonConditionalParent ? group$2(doc) : doc; // Break the closing paren to keep the chain right after it: + const comments = flatten_1([...operatorOptions.testNodePropertyNames.map(propertyName => node[propertyName].comments), consequentNode.comments, alternateNode.comments]).filter(Boolean); + const shouldBreak = comments.some(comment => isBlockComment$4(comment) && hasNewlineInRange$4(options.originalText, locStart$5(comment), locEnd$4(comment))); + + const maybeGroup = doc => parent === firstNonConditionalParent ? group$6(doc, { + shouldBreak + }) : shouldBreak ? concat$d([doc, breakParent$2]) : doc; // Break the closing paren to keep the chain right after it: // (a // ? b // : c @@ -39174,7 +42560,7 @@ function printTernaryOperator(path, options, print, operatorOptions) { const breakClosingParen = !jsxMode && (parent.type === "MemberExpression" || parent.type === "OptionalMemberExpression" || parent.type === "NGPipeExpression" && parent.left === node) && !parent.computed; - const result = maybeGroup(concat$6([].concat((testDoc => + const result = maybeGroup(concat$d([].concat((testDoc => /** * a * ? b @@ -39185,3812 +42571,4574 @@ function printTernaryOperator(path, options, print, operatorOptions) { * ? d * : e */ - parent.type === operatorOptions.conditionalNodeType && parent[operatorOptions.alternateNodePropertyName] === node ? align$1(2, testDoc) : testDoc)(concat$6(operatorOptions.beforeParts())), forceNoIndent ? concat$6(parts) : indent$3(concat$6(parts)), operatorOptions.afterParts(breakClosingParen)))); - return isParentTest ? group$2(concat$6([indent$3(concat$6([softline$2, result])), softline$2])) : result; + parent.type === operatorOptions.conditionalNodeType && parent[operatorOptions.alternateNodePropertyName] === node ? align$2(2, testDoc) : testDoc)(concat$d(operatorOptions.beforeParts())), forceNoIndent ? concat$d(parts) : indent$a(concat$d(parts)), operatorOptions.afterParts(breakClosingParen)))); + return isParentTest ? group$6(concat$d([indent$a(concat$d([softline$6, result])), softline$6])) : result; } -function printPathNoParens(path, options, print, args) { - const n = path.getValue(); - const semi = options.semi ? ";" : ""; +var ternary = printTernaryOperator; - if (!n) { +const { + getNextNonSpaceNonCommentCharacter: getNextNonSpaceNonCommentCharacter$2, + isNextLineEmpty: isNextLineEmpty$2 +} = util; +const { + printDanglingComments: printDanglingComments$2 +} = comments; +const { + builders: { + concat: concat$e, + line: line$8, + hardline: hardline$9, + softline: softline$7, + group: group$7, + indent: indent$b, + ifBreak: ifBreak$3 + }, + utils: { + removeLines: removeLines$1 + } +} = document; +const { + getFunctionParameters: getFunctionParameters$3, + iterateFunctionParametersPath: iterateFunctionParametersPath$1, + isSimpleType: isSimpleType$1, + isTestCall: isTestCall$1, + isTypeAnnotationAFunction: isTypeAnnotationAFunction$1, + isObjectType: isObjectType$1, + isObjectTypePropertyAFunction: isObjectTypePropertyAFunction$1, + hasRestParameter: hasRestParameter$1, + shouldPrintComma: shouldPrintComma$2 +} = utils$6; +const { + locEnd: locEnd$5 +} = loc; +const { + printFunctionTypeParameters: printFunctionTypeParameters$1 +} = misc; + +function printFunctionParameters(path, print, options, expandArg, printTypeParams) { + const functionNode = path.getValue(); + const parameters = getFunctionParameters$3(functionNode); + const typeParams = printTypeParams ? printFunctionTypeParameters$1(path, options, print) : ""; + + if (parameters.length === 0) { + return concat$e([typeParams, "(", printDanglingComments$2(path, options, + /* sameIndent */ + true, comment => getNextNonSpaceNonCommentCharacter$2(options.originalText, comment, locEnd$5) === ")"), ")"]); + } + + const parent = path.getParentNode(); + const isParametersInTestCall = isTestCall$1(parent); + const shouldHugParameters = shouldHugFunctionParameters(functionNode); + const shouldExpandParameters = expandArg && !parameters.some(node => node.comments); + const printed = []; + iterateFunctionParametersPath$1(path, (parameterPath, index) => { + const isLastParameter = index === parameters.length - 1; + + if (isLastParameter && functionNode.rest) { + printed.push("..."); + } + + printed.push(parameterPath.call(print)); + + if (isLastParameter) { + return; + } + + printed.push(","); + + if (isParametersInTestCall || shouldHugParameters || shouldExpandParameters) { + printed.push(" "); + } else if (isNextLineEmpty$2(options.originalText, parameters[index], locEnd$5)) { + printed.push(hardline$9, hardline$9); + } else { + printed.push(line$8); + } + }); // If the parent is a call with the first/last argument expansion and this is the + // params of the first/last argument, we don't want the arguments to break and instead + // want the whole expression to be on a new line. + // + // Good: Bad: + // verylongcall( verylongcall(( + // (a, b) => { a, + // } b, + // }) ) => { + // }) + + if (shouldExpandParameters) { + return group$7(concat$e([removeLines$1(typeParams), "(", concat$e(printed.map(removeLines$1)), ")"])); + } // Single object destructuring should hug + // + // function({ + // a, + // b, + // c + // }) {} + + + const hasNotParameterDecorator = parameters.every(node => !node.decorators); + + if (shouldHugParameters && hasNotParameterDecorator) { + return concat$e([typeParams, "(", concat$e(printed), ")"]); + } // don't break in specs, eg; `it("should maintain parens around done even when long", (done) => {})` + + + if (isParametersInTestCall) { + return concat$e([typeParams, "(", concat$e(printed), ")"]); + } + + const isFlowShorthandWithOneArg = (isObjectTypePropertyAFunction$1(parent) || isTypeAnnotationAFunction$1(parent) || parent.type === "TypeAlias" || parent.type === "UnionTypeAnnotation" || parent.type === "TSUnionType" || parent.type === "IntersectionTypeAnnotation" || parent.type === "FunctionTypeAnnotation" && parent.returnType === functionNode) && parameters.length === 1 && parameters[0].name === null && // `type q = (this: string) => void;` + functionNode.this !== parameters[0] && parameters[0].typeAnnotation && functionNode.typeParameters === null && isSimpleType$1(parameters[0].typeAnnotation) && !functionNode.rest; + + if (isFlowShorthandWithOneArg) { + if (options.arrowParens === "always") { + return concat$e(["(", concat$e(printed), ")"]); + } + + return concat$e(printed); + } + + return concat$e([typeParams, "(", indent$b(concat$e([softline$7, concat$e(printed)])), ifBreak$3(!hasRestParameter$1(functionNode) && shouldPrintComma$2(options, "all") ? "," : ""), softline$7, ")"]); +} + +function shouldHugFunctionParameters(node) { + if (!node) { + return false; + } + + const parameters = getFunctionParameters$3(node); + + if (parameters.length !== 1) { + return false; + } + + const [parameter] = parameters; + return !parameter.comments && (parameter.type === "ObjectPattern" || parameter.type === "ArrayPattern" || parameter.type === "Identifier" && parameter.typeAnnotation && (parameter.typeAnnotation.type === "TypeAnnotation" || parameter.typeAnnotation.type === "TSTypeAnnotation") && isObjectType$1(parameter.typeAnnotation.typeAnnotation) || parameter.type === "FunctionTypeParam" && isObjectType$1(parameter.typeAnnotation) || parameter.type === "AssignmentPattern" && (parameter.left.type === "ObjectPattern" || parameter.left.type === "ArrayPattern") && (parameter.right.type === "Identifier" || parameter.right.type === "ObjectExpression" && parameter.right.properties.length === 0 || parameter.right.type === "ArrayExpression" && parameter.right.elements.length === 0)); +} + +var functionParameters = { + printFunctionParameters, + shouldHugFunctionParameters +}; + +const { + builders: { + concat: concat$f + } +} = document; +const { + isFlowAnnotationComment: isFlowAnnotationComment$1, + isSimpleType: isSimpleType$2, + isObjectType: isObjectType$2 +} = utils$6; + +function printTypeAnnotation(path, options, print) { + const node = path.getValue(); + + if (!node.typeAnnotation) { return ""; } - if (typeof n === "string") { - return n; + const parentNode = path.getParentNode(); + const isDefinite = node.definite || parentNode && parentNode.type === "VariableDeclarator" && parentNode.definite; + const isFunctionDeclarationIdentifier = parentNode.type === "DeclareFunction" && parentNode.id === node; + + if (isFlowAnnotationComment$1(options.originalText, node.typeAnnotation)) { + return concat$f([" /*: ", path.call(print, "typeAnnotation"), " */"]); } - const htmlBinding = printHtmlBinding$1(path, options, print); + return concat$f([isFunctionDeclarationIdentifier ? "" : isDefinite ? "!: " : ": ", path.call(print, "typeAnnotation")]); +} - if (htmlBinding) { - return htmlBinding; +function shouldHugType(node) { + if (isSimpleType$2(node) || isObjectType$2(node)) { + return true; } - let parts = []; + if (node.type === "UnionTypeAnnotation" || node.type === "TSUnionType") { + const voidCount = node.types.filter(n => n.type === "VoidTypeAnnotation" || n.type === "TSVoidKeyword" || n.type === "NullLiteralTypeAnnotation" || n.type === "TSNullKeyword").length; + const hasObject = node.types.some(n => n.type === "ObjectTypeAnnotation" || n.type === "TSTypeLiteral" || // This is a bit aggressive but captures Array<{x}> + n.type === "GenericTypeAnnotation" || n.type === "TSTypeReference"); - switch (n.type) { - case "JsExpressionRoot": - return path.call(print, "node"); + if (node.types.length - 1 === voidCount && hasObject) { + return true; + } + } + + return false; +} - case "JsonRoot": - return concat$6([path.call(print, "node"), hardline$4]); +var typeAnnotation = { + printTypeAnnotation, + shouldHugType +}; - case "File": - // Print @babel/parser's InterpreterDirective here so that - // leading comments on the `Program` node get printed after the hashbang. - if (n.program && n.program.interpreter) { - parts.push(path.call(programPath => programPath.call(print, "interpreter"), "program")); - } +const { + printDanglingComments: printDanglingComments$3 +} = comments; +const { + builders: { + concat: concat$g, + line: line$9, + softline: softline$8, + group: group$8, + indent: indent$c, + ifBreak: ifBreak$4 + } +} = document; +const { + getLast: getLast$3, + isNextLineEmpty: isNextLineEmpty$3 +} = util; +const { + hasDanglingComments: hasDanglingComments$2, + shouldPrintComma: shouldPrintComma$3 +} = utils$6; +const { + locEnd: locEnd$6 +} = loc; +const { + printOptionalToken: printOptionalToken$1 +} = misc; +const { + printTypeAnnotation: printTypeAnnotation$1 +} = typeAnnotation; +/** @typedef {import("../../document").Doc} Doc */ - parts.push(path.call(print, "program")); - return concat$6(parts); +function printArray(path, options, print) { + const n = path.getValue(); + /** @type{Doc[]} */ - case "Program": - // Babel 6 - if (n.directives) { - path.each(childPath => { - parts.push(print(childPath), semi, hardline$4); + const parts = []; + const openBracket = n.type === "TupleExpression" ? "#[" : "["; + const closeBracket = "]"; - if (isNextLineEmpty$2(options.originalText, childPath.getValue(), options.locEnd)) { - parts.push(hardline$4); - } - }, "directives"); - } + if (n.elements.length === 0) { + if (!hasDanglingComments$2(n)) { + parts.push(openBracket, closeBracket); + } else { + parts.push(group$8(concat$g([openBracket, printDanglingComments$3(path, options), softline$8, closeBracket]))); + } + } else { + const lastElem = getLast$3(n.elements); + const canHaveTrailingComma = !(lastElem && lastElem.type === "RestElement"); // JavaScript allows you to have empty elements in an array which + // changes its length based on the number of commas. The algorithm + // is that if the last argument is null, we need to force insert + // a comma to ensure JavaScript recognizes it. + // [,].length === 1 + // [1,].length === 1 + // [1,,].length === 2 + // + // Note that getLast returns null if the array is empty, but + // we already check for an empty array just above so we are safe - parts.push(path.call(bodyPath => { - return printStatementSequence(bodyPath, options, print); - }, "body")); - parts.push(comments.printDanglingComments(path, options, - /* sameIndent */ - true)); // Only force a trailing newline if there were any contents. + const needsForcedTrailingComma = canHaveTrailingComma && lastElem === null; + const shouldBreak = !options.__inJestEach && n.elements.length > 1 && n.elements.every((element, i, elements) => { + const elementType = element && element.type; - if (!n.body.every(({ - type - }) => type === "EmptyStatement") || n.comments) { - parts.push(hardline$4); + if (elementType !== "ArrayExpression" && elementType !== "ObjectExpression") { + return false; } - return concat$6(parts); - // Babel extension. - - case "EmptyStatement": - return ""; + const nextElement = elements[i + 1]; - case "ExpressionStatement": - // Detect Flow-parsed directives - if (n.directive) { - return concat$6([nodeStr(n.expression, options, true), semi]); + if (nextElement && elementType !== nextElement.type) { + return false; } - if (options.parser === "__vue_event_binding") { - const parent = path.getParentNode(); + const itemsKey = elementType === "ArrayExpression" ? "elements" : "properties"; + return element[itemsKey] && element[itemsKey].length > 1; + }); + parts.push(group$8(concat$g([openBracket, indent$c(concat$g([softline$8, printArrayItems(path, options, "elements", print)])), needsForcedTrailingComma ? "," : "", ifBreak$4(canHaveTrailingComma && !needsForcedTrailingComma && shouldPrintComma$3(options) ? "," : ""), printDanglingComments$3(path, options, + /* sameIndent */ + true), softline$8, closeBracket]), { + shouldBreak + })); + } - if (parent.type === "Program" && parent.body.length === 1 && parent.body[0] === n) { - return concat$6([path.call(print, "expression"), isVueEventBindingExpression$1(n.expression) ? ";" : ""]); - } - } // Do not append semicolon after the only JSX element in a program + parts.push(printOptionalToken$1(path), printTypeAnnotation$1(path, options, print)); + return concat$g(parts); +} +function printArrayItems(path, options, printPath, print) { + const printedElements = []; + let separatorParts = []; + path.each(childPath => { + printedElements.push(concat$g(separatorParts)); + printedElements.push(group$8(print(childPath))); + separatorParts = [",", line$9]; - return concat$6([path.call(print, "expression"), isTheOnlyJSXElementInMarkdown$1(options, path) ? "" : semi]); - // Babel non-standard node. Used for Closure-style type casts. See postprocess.js. + if (childPath.getValue() && isNextLineEmpty$3(options.originalText, childPath.getValue(), locEnd$6)) { + separatorParts.push(softline$8); + } + }, printPath); + return concat$g(printedElements); +} - case "ParenthesizedExpression": - { - const shouldHug = !n.expression.comments; +var array$3 = { + printArray, + printArrayItems +}; - if (shouldHug) { - return concat$6(["(", path.call(print, "expression"), ")"]); - } +const { + printDanglingComments: printDanglingComments$4 +} = comments; +const { + builders: { + concat: concat$h, + line: line$a, + softline: softline$9, + group: group$9, + indent: indent$d, + ifBreak: ifBreak$5, + hardline: hardline$a + } +} = document; +const { + getLast: getLast$4, + isNextLineEmpty: isNextLineEmpty$4, + hasNewlineInRange: hasNewlineInRange$5, + hasNewline: hasNewline$5 +} = util; +const { + hasDanglingComments: hasDanglingComments$3, + shouldPrintComma: shouldPrintComma$4, + hasNodeIgnoreComment: hasNodeIgnoreComment$1, + isBlockComment: isBlockComment$5 +} = utils$6; +const { + locStart: locStart$6, + locEnd: locEnd$7 +} = loc; +const { + printOptionalToken: printOptionalToken$2 +} = misc; +const { + shouldHugFunctionParameters: shouldHugFunctionParameters$1 +} = functionParameters; +const { + printTypeAnnotation: printTypeAnnotation$2, + shouldHugType: shouldHugType$1 +} = typeAnnotation; +/** @typedef {import("../../document").Doc} Doc */ - return group$2(concat$6(["(", indent$3(concat$6([softline$2, path.call(print, "expression")])), softline$2, ")"])); - } +function printObject(path, options, print) { + const semi = options.semi ? ";" : ""; + const n = path.getValue(); + let propertiesField; - case "AssignmentExpression": - return printAssignment(n.left, path.call(print, "left"), concat$6([" ", n.operator]), n.right, path.call(print, "right"), options); + if (n.type === "TSTypeLiteral") { + propertiesField = "members"; + } else if (n.type === "TSInterfaceBody") { + propertiesField = "body"; + } else { + propertiesField = "properties"; + } - case "BinaryExpression": - case "LogicalExpression": - case "NGPipeExpression": - { - const parent = path.getParentNode(); - const parentParent = path.getParentNode(1); - const isInsideParenthesis = n !== parent.body && (parent.type === "IfStatement" || parent.type === "WhileStatement" || parent.type === "SwitchStatement" || parent.type === "DoWhileStatement"); - const parts = printBinaryishExpressions(path, print, options, - /* isNested */ - false, isInsideParenthesis); // if ( - // this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft - // ) { - // - // looks super weird, we want to break the children if the parent breaks - // - // if ( - // this.hasPlugin("dynamicImports") && - // this.lookahead().type === tt.parenLeft - // ) { - - if (isInsideParenthesis) { - return concat$6(parts); - } // Break between the parens in - // unaries or in a member or specific call expression, i.e. - // - // ( - // a && - // b && - // c - // ).call() + const isTypeAnnotation = n.type === "ObjectTypeAnnotation"; + const fields = []; + if (isTypeAnnotation) { + fields.push("indexers", "callProperties", "internalSlots"); + } - if ((parent.type === "CallExpression" || parent.type === "OptionalCallExpression") && parent.callee === n || parent.type === "UnaryExpression" || (parent.type === "MemberExpression" || parent.type === "OptionalMemberExpression") && !parent.computed) { - return group$2(concat$6([indent$3(concat$6([softline$2, concat$6(parts)])), softline$2])); - } // Avoid indenting sub-expressions in some cases where the first sub-expression is already - // indented accordingly. We should indent sub-expressions where the first case isn't indented. + fields.push(propertiesField); + const firstProperty = fields.map(field => n[field][0]).sort((a, b) => locStart$6(a) - locStart$6(b))[0]; + const parent = path.getParentNode(0); + const isFlowInterfaceLikeBody = isTypeAnnotation && parent && (parent.type === "InterfaceDeclaration" || parent.type === "DeclareInterface" || parent.type === "DeclareClass") && path.getName() === "body"; + const shouldBreak = n.type === "TSInterfaceBody" || isFlowInterfaceLikeBody || n.type === "ObjectPattern" && parent.type !== "FunctionDeclaration" && parent.type !== "FunctionExpression" && parent.type !== "ArrowFunctionExpression" && parent.type !== "ObjectMethod" && parent.type !== "ClassMethod" && parent.type !== "ClassPrivateMethod" && parent.type !== "AssignmentPattern" && parent.type !== "CatchClause" && n.properties.some(property => property.value && (property.value.type === "ObjectPattern" || property.value.type === "ArrayPattern")) || n.type !== "ObjectPattern" && firstProperty && hasNewlineInRange$5(options.originalText, locStart$6(n), locStart$6(firstProperty)); + const separator = isFlowInterfaceLikeBody ? ";" : n.type === "TSInterfaceBody" || n.type === "TSTypeLiteral" ? ifBreak$5(semi, ";") : ","; + const leftBrace = n.type === "RecordExpression" ? "#{" : n.exact ? "{|" : "{"; + const rightBrace = n.exact ? "|}" : "}"; // Unfortunately, things are grouped together in the ast can be + // interleaved in the source code. So we need to reorder them before + // printing them. + const propsAndLoc = []; + fields.forEach(field => { + path.each(childPath => { + const node = childPath.getValue(); + propsAndLoc.push({ + node, + printed: print(childPath), + loc: locStart$6(node) + }); + }, field); + }); + let separatorParts = []; + const props = propsAndLoc.sort((a, b) => a.loc - b.loc).map(prop => { + const result = concat$h(separatorParts.concat(group$9(prop.printed))); + separatorParts = [separator, line$a]; - const shouldNotIndent = parent.type === "ReturnStatement" || parent.type === "ThrowStatement" || parent.type === "JSXExpressionContainer" && parentParent.type === "JSXAttribute" || n.operator !== "|" && parent.type === "JsExpressionRoot" || n.type !== "NGPipeExpression" && (parent.type === "NGRoot" && options.parser === "__ng_binding" || parent.type === "NGMicrosyntaxExpression" && parentParent.type === "NGMicrosyntax" && parentParent.body.length === 1) || n === parent.body && parent.type === "ArrowFunctionExpression" || n !== parent.body && parent.type === "ForStatement" || parent.type === "ConditionalExpression" && parentParent.type !== "ReturnStatement" && parentParent.type !== "ThrowStatement" && parentParent.type !== "CallExpression" && parentParent.type !== "OptionalCallExpression" || parent.type === "TemplateLiteral"; - const shouldIndentIfInlining = parent.type === "AssignmentExpression" || parent.type === "VariableDeclarator" || parent.type === "ClassProperty" || parent.type === "TSAbstractClassProperty" || parent.type === "ClassPrivateProperty" || parent.type === "ObjectProperty" || parent.type === "Property"; - const samePrecedenceSubExpression = isBinaryish$1(n.left) && shouldFlatten$1(n.operator, n.left.operator); + if ((prop.node.type === "TSPropertySignature" || prop.node.type === "TSMethodSignature" || prop.node.type === "TSConstructSignatureDeclaration") && hasNodeIgnoreComment$1(prop.node)) { + separatorParts.shift(); + } - if (shouldNotIndent || shouldInlineLogicalExpression(n) && !samePrecedenceSubExpression || !shouldInlineLogicalExpression(n) && shouldIndentIfInlining) { - return group$2(concat$6(parts)); - } + if (isNextLineEmpty$4(options.originalText, prop.node, locEnd$7)) { + separatorParts.push(hardline$a); + } - if (parts.length === 0) { - return ""; - } // If the right part is a JSX node, we include it in a separate group to - // prevent it breaking the whole chain, so we can print the expression like: - // - // foo && bar && ( - // - // - // - // ) - - - const hasJSX = isJSXNode$1(n.right); - const rest = concat$6(hasJSX ? parts.slice(1, -1) : parts.slice(1)); - const groupId = Symbol("logicalChain-" + ++uid); - const chain = group$2(concat$6([// Don't include the initial expression in the indentation - // level. The first item is guaranteed to be the first - // left-most expression. - parts.length > 0 ? parts[0] : "", indent$3(rest)]), { - id: groupId - }); + return result; + }); - if (!hasJSX) { - return chain; - } + if (n.inexact) { + let printed; - const jsxPart = getLast$2(parts); - return group$2(concat$6([chain, ifBreak$1(indent$3(jsxPart), jsxPart, { - groupId - })])); - } + if (hasDanglingComments$3(n)) { + const hasLineComments = !n.comments.every(comment => isBlockComment$5(comment)); + const printedDanglingComments = printDanglingComments$4(path, options, + /* sameIndent */ + true); + printed = concat$h([printedDanglingComments, hasLineComments || hasNewline$5(options.originalText, locEnd$7(n.comments[n.comments.length - 1])) ? hardline$a : line$a, "..."]); + } else { + printed = "..."; + } - case "AssignmentPattern": - return concat$6([path.call(print, "left"), " = ", path.call(print, "right")]); + props.push(concat$h(separatorParts.concat(printed))); + } - case "TSTypeAssertion": - { - const shouldBreakAfterCast = !(n.expression.type === "ArrayExpression" || n.expression.type === "ObjectExpression"); - const castGroup = group$2(concat$6(["<", indent$3(concat$6([softline$2, path.call(print, "typeAnnotation")])), softline$2, ">"])); - const exprContents = concat$6([ifBreak$1("("), indent$3(concat$6([softline$2, path.call(print, "expression")])), softline$2, ifBreak$1(")")]); + const lastElem = getLast$4(n[propertiesField]); + const canHaveTrailingSeparator = !(n.inexact || lastElem && lastElem.type === "RestElement" || lastElem && (lastElem.type === "TSPropertySignature" || lastElem.type === "TSCallSignatureDeclaration" || lastElem.type === "TSMethodSignature" || lastElem.type === "TSConstructSignatureDeclaration") && hasNodeIgnoreComment$1(lastElem)); + let content; - if (shouldBreakAfterCast) { - return conditionalGroup$1([concat$6([castGroup, path.call(print, "expression")]), concat$6([castGroup, group$2(exprContents, { - shouldBreak: true - })]), concat$6([castGroup, path.call(print, "expression")])]); - } + if (props.length === 0) { + if (!hasDanglingComments$3(n)) { + return concat$h([leftBrace, rightBrace, printTypeAnnotation$2(path, options, print)]); + } - return group$2(concat$6([castGroup, path.call(print, "expression")])); - } + content = group$9(concat$h([leftBrace, printDanglingComments$4(path, options), softline$9, rightBrace, printOptionalToken$2(path), printTypeAnnotation$2(path, options, print)])); + } else { + content = concat$h([leftBrace, indent$d(concat$h([options.bracketSpacing ? line$a : softline$9, concat$h(props)])), ifBreak$5(canHaveTrailingSeparator && (separator !== "," || shouldPrintComma$4(options)) ? separator : ""), concat$h([options.bracketSpacing ? line$a : softline$9, rightBrace]), printOptionalToken$2(path), printTypeAnnotation$2(path, options, print)]); + } // If we inline the object as first argument of the parent, we don't want + // to create another group so that the object breaks before the return + // type - case "OptionalMemberExpression": - case "MemberExpression": - { - const parent = path.getParentNode(); - let firstNonMemberParent; - let i = 0; - do { - firstNonMemberParent = path.getParentNode(i); - i++; - } while (firstNonMemberParent && (firstNonMemberParent.type === "MemberExpression" || firstNonMemberParent.type === "OptionalMemberExpression" || firstNonMemberParent.type === "TSNonNullExpression")); + if (path.match(node => node.type === "ObjectPattern" && !node.decorators, (node, name, number) => shouldHugFunctionParameters$1(node) && (name === "params" || name === "parameters" || name === "this" || name === "rest") && number === 0) || path.match(shouldHugType$1, (node, name) => name === "typeAnnotation", (node, name) => name === "typeAnnotation", (node, name, number) => shouldHugFunctionParameters$1(node) && (name === "params" || name === "parameters" || name === "this" || name === "rest") && number === 0)) { + return content; + } - const shouldInline = firstNonMemberParent && (firstNonMemberParent.type === "NewExpression" || firstNonMemberParent.type === "BindExpression" || firstNonMemberParent.type === "VariableDeclarator" && firstNonMemberParent.id.type !== "Identifier" || firstNonMemberParent.type === "AssignmentExpression" && firstNonMemberParent.left.type !== "Identifier") || n.computed || n.object.type === "Identifier" && n.property.type === "Identifier" && parent.type !== "MemberExpression" && parent.type !== "OptionalMemberExpression"; - return concat$6([path.call(print, "object"), shouldInline ? printMemberLookup(path, options, print) : group$2(indent$3(concat$6([softline$2, printMemberLookup(path, options, print)])))]); - } + return group$9(content, { + shouldBreak + }); +} - case "MetaProperty": - return concat$6([path.call(print, "meta"), ".", path.call(print, "property")]); +var object = { + printObject +}; - case "BindExpression": - if (n.object) { - parts.push(path.call(print, "object")); - } +const { + printComments: printComments$1, + printDanglingComments: printDanglingComments$5 +} = comments; +const { + builders: { + concat: concat$i, + line: line$b, + hardline: hardline$b, + softline: softline$a, + group: group$a, + indent: indent$e, + conditionalGroup: conditionalGroup$1, + fill: fill$3, + ifBreak: ifBreak$6, + lineSuffixBoundary: lineSuffixBoundary$2 + }, + utils: { + willBreak: willBreak$1, + isLineNext: isLineNext$1, + isEmpty: isEmpty$1 + } +} = document; +const { + getLast: getLast$5, + getPreferredQuote: getPreferredQuote$1 +} = util; +const { + hasTrailingComment: hasTrailingComment$1, + isEmptyJSXElement: isEmptyJSXElement$1, + isJSXWhitespaceExpression: isJSXWhitespaceExpression$1, + isJSXNode: isJSXNode$3, + isMeaningfulJSXText: isMeaningfulJSXText$1, + matchJsxWhitespaceRegex: matchJsxWhitespaceRegex$1, + rawText: rawText$1, + isLiteral: isLiteral$1, + isCallOrOptionalCallExpression: isCallOrOptionalCallExpression$1, + isStringLiteral: isStringLiteral$1, + isBinaryish: isBinaryish$2, + isBlockComment: isBlockComment$6 +} = utils$6; +const { + willPrintOwnComments: willPrintOwnComments$1 +} = comments$1; // JSX expands children from the inside-out, instead of the outside-in. +// This is both to break children before attributes, +// and to ensure that when children break, their parents do as well. +// +// Any element that is written without any newlines and fits on a single line +// is left that way. +// Not only that, any user-written-line containing multiple JSX siblings +// should also be kept on one line if possible, +// so each user-written-line is wrapped in its own group. +// +// Elements that contain newlines or don't fit on a single line (recursively) +// are fully-split, using hardline and shouldBreak: true. +// +// To support that case properly, all leading and trailing spaces +// are stripped from the list of children, and replaced with a single hardline. - parts.push(group$2(indent$3(concat$6([softline$2, printBindExpressionCallee(path, options, print)])))); - return concat$6(parts); +function printJsxElementInternal(path, options, print) { + const n = path.getValue(); - case "Identifier": - { - return concat$6([n.name, printOptionalToken(path), printTypeAnnotation(path, options, print)]); - } + if (n.type === "JSXElement" && isEmptyJSXElement$1(n)) { + return concat$i([path.call(print, "openingElement"), path.call(print, "closingElement")]); + } - case "V8IntrinsicIdentifier": - return concat$6(["%", n.name]); + const openingLines = n.type === "JSXElement" ? path.call(print, "openingElement") : path.call(print, "openingFragment"); + const closingLines = n.type === "JSXElement" ? path.call(print, "closingElement") : path.call(print, "closingFragment"); - case "SpreadElement": - case "SpreadElementPattern": - case "SpreadProperty": - case "SpreadPropertyPattern": - case "RestElement": - case "ObjectTypeSpreadProperty": - return concat$6(["...", path.call(print, "argument"), printTypeAnnotation(path, options, print)]); + if (n.children.length === 1 && n.children[0].type === "JSXExpressionContainer" && (n.children[0].expression.type === "TemplateLiteral" || n.children[0].expression.type === "TaggedTemplateExpression")) { + return concat$i([openingLines, concat$i(path.map(print, "children")), closingLines]); + } // Convert `{" "}` to text nodes containing a space. + // This makes it easy to turn them into `jsxWhitespace` which + // can then print as either a space or `{" "}` when breaking. - case "FunctionDeclaration": - case "FunctionExpression": - parts.push(printFunctionDeclaration(path, print, options)); - if (!n.body) { - parts.push(semi); - } + n.children = n.children.map(child => { + if (isJSXWhitespaceExpression$1(child)) { + return { + type: "JSXText", + value: " ", + raw: " " + }; + } - return concat$6(parts); + return child; + }); + const containsTag = n.children.filter(isJSXNode$3).length > 0; + const containsMultipleExpressions = n.children.filter(child => child.type === "JSXExpressionContainer").length > 1; + const containsMultipleAttributes = n.type === "JSXElement" && n.openingElement.attributes.length > 1; // Record any breaks. Should never go from true to false, only false to true. - case "ArrowFunctionExpression": - { - if (n.async) { - parts.push("async "); - } + let forcedBreak = willBreak$1(openingLines) || containsTag || containsMultipleAttributes || containsMultipleExpressions; + const isMdxBlock = path.getParentNode().rootMarker === "mdx"; + const rawJsxWhitespace = options.singleQuote ? "{' '}" : '{" "}'; + const jsxWhitespace = isMdxBlock ? concat$i([" "]) : ifBreak$6(concat$i([rawJsxWhitespace, softline$a]), " "); + const isFacebookTranslationTag = n.openingElement && n.openingElement.name && n.openingElement.name.name === "fbt"; + const children = printJSXChildren(path, options, print, jsxWhitespace, isFacebookTranslationTag); + const containsText = n.children.some(child => isMeaningfulJSXText$1(child)); // We can end up we multiple whitespace elements with empty string + // content between them. + // We need to remove empty whitespace and softlines before JSX whitespace + // to get the correct output. - if (shouldPrintParamsWithoutParens(path, options)) { - parts.push(path.call(print, "params", 0)); - } else { - parts.push(group$2(concat$6([printFunctionParams(path, print, options, - /* expandLast */ - args && (args.expandLastArg || args.expandFirstArg), - /* printTypeParams */ - true), printReturnType(path, print, options)]))); - } + for (let i = children.length - 2; i >= 0; i--) { + const isPairOfEmptyStrings = children[i] === "" && children[i + 1] === ""; + const isPairOfHardlines = children[i] === hardline$b && children[i + 1] === "" && children[i + 2] === hardline$b; + const isLineFollowedByJSXWhitespace = (children[i] === softline$a || children[i] === hardline$b) && children[i + 1] === "" && children[i + 2] === jsxWhitespace; + const isJSXWhitespaceFollowedByLine = children[i] === jsxWhitespace && children[i + 1] === "" && (children[i + 2] === softline$a || children[i + 2] === hardline$b); + const isDoubleJSXWhitespace = children[i] === jsxWhitespace && children[i + 1] === "" && children[i + 2] === jsxWhitespace; + const isPairOfHardOrSoftLines = children[i] === softline$a && children[i + 1] === "" && children[i + 2] === hardline$b || children[i] === hardline$b && children[i + 1] === "" && children[i + 2] === softline$a; - const dangling = comments.printDanglingComments(path, options, - /* sameIndent */ - true, comment => { - const nextCharacter = getNextNonSpaceNonCommentCharacterIndex$3(options.originalText, comment, options.locEnd); - return options.originalText.slice(nextCharacter, nextCharacter + 2) === "=>"; - }); + if (isPairOfHardlines && containsText || isPairOfEmptyStrings || isLineFollowedByJSXWhitespace || isDoubleJSXWhitespace || isPairOfHardOrSoftLines) { + children.splice(i, 2); + } else if (isJSXWhitespaceFollowedByLine) { + children.splice(i + 1, 2); + } + } // Trim trailing lines (or empty strings) - if (dangling) { - parts.push(" ", dangling); - } - parts.push(" =>"); - const body = path.call(bodyPath => print(bodyPath, args), "body"); // We want to always keep these types of nodes on the same line - // as the arrow. + while (children.length && (isLineNext$1(getLast$5(children)) || isEmpty$1(getLast$5(children)))) { + children.pop(); + } // Trim leading lines (or empty strings) - if (!hasLeadingOwnLineComment$1(options.originalText, n.body, options) && (n.body.type === "ArrayExpression" || n.body.type === "ObjectExpression" || n.body.type === "BlockStatement" || isJSXNode$1(n.body) || isTemplateOnItsOwnLine$1(n.body, options.originalText, options) || n.body.type === "ArrowFunctionExpression" || n.body.type === "DoExpression")) { - return group$2(concat$6([concat$6(parts), " ", body])); - } // We handle sequence expressions as the body of arrows specially, - // so that the required parentheses end up on their own lines. + while (children.length && (isLineNext$1(children[0]) || isEmpty$1(children[0])) && (isLineNext$1(children[1]) || isEmpty$1(children[1]))) { + children.shift(); + children.shift(); + } // Tweak how we format children if outputting this element over multiple lines. + // Also detect whether we will force this element to output over multiple lines. - if (n.body.type === "SequenceExpression") { - return group$2(concat$6([concat$6(parts), group$2(concat$6([" (", indent$3(concat$6([softline$2, body])), softline$2, ")"]))])); - } // if the arrow function is expanded as last argument, we are adding a - // level of indentation and need to add a softline to align the closing ) - // with the opening (, or if it's inside a JSXExpression (e.g. an attribute) - // we should align the expression's closing } with the line with the opening {. + const multilineChildren = []; + children.forEach((child, i) => { + // There are a number of situations where we need to ensure we display + // whitespace as `{" "}` when outputting this element over multiple lines. + if (child === jsxWhitespace) { + if (i === 1 && children[i - 1] === "") { + if (children.length === 2) { + // Solitary whitespace + multilineChildren.push(rawJsxWhitespace); + return; + } // Leading whitespace - const shouldAddSoftLine = (args && args.expandLastArg || path.getParentNode().type === "JSXExpressionContainer") && !(n.comments && n.comments.length); - const printTrailingComma = args && args.expandLastArg && shouldPrintComma(options, "all"); // In order to avoid confusion between - // a => a ? a : a - // a <= a ? a : a - const shouldAddParens = n.body.type === "ConditionalExpression" && !startsWithNoLookaheadToken$1(n.body, - /* forbidFunctionAndClass */ - false); - return group$2(concat$6([concat$6(parts), group$2(concat$6([indent$3(concat$6([line$4, shouldAddParens ? ifBreak$1("", "(") : "", body, shouldAddParens ? ifBreak$1("", ")") : ""])), shouldAddSoftLine ? concat$6([ifBreak$1(printTrailingComma ? "," : ""), softline$2]) : ""]))])); + multilineChildren.push(concat$i([rawJsxWhitespace, hardline$b])); + return; + } else if (i === children.length - 1) { + // Trailing whitespace + multilineChildren.push(rawJsxWhitespace); + return; + } else if (children[i - 1] === "" && children[i - 2] === hardline$b) { + // Whitespace after line break + multilineChildren.push(rawJsxWhitespace); + return; } + } - case "YieldExpression": - parts.push("yield"); + multilineChildren.push(child); - if (n.delegate) { - parts.push("*"); - } + if (willBreak$1(child)) { + forcedBreak = true; + } + }); // If there is text we use `fill` to fit as much onto each line as possible. + // When there is no text (just tags and expressions) we use `group` + // to output each on a separate line. - if (n.argument) { - parts.push(" ", path.call(print, "argument")); - } + const content = containsText ? fill$3(multilineChildren) : group$a(concat$i(multilineChildren), { + shouldBreak: true + }); - return concat$6(parts); + if (isMdxBlock) { + return content; + } - case "AwaitExpression": - { - parts.push("await ", path.call(print, "argument")); - const parent = path.getParentNode(); + const multiLineElem = group$a(concat$i([openingLines, indent$e(concat$i([hardline$b, content])), hardline$b, closingLines])); - if ((parent.type === "CallExpression" || parent.type === "OptionalCallExpression") && parent.callee === n || (parent.type === "MemberExpression" || parent.type === "OptionalMemberExpression") && parent.object === n) { - return group$2(concat$6([indent$3(concat$6([softline$2, concat$6(parts)])), softline$2])); - } + if (forcedBreak) { + return multiLineElem; + } - return concat$6(parts); - } + return conditionalGroup$1([group$a(concat$i([openingLines, concat$i(children), closingLines])), multiLineElem]); +} // JSX Children are strange, mostly for two reasons: +// 1. JSX reads newlines into string values, instead of skipping them like JS +// 2. up to one whitespace between elements within a line is significant, +// but not between lines. +// +// Leading, trailing, and lone whitespace all need to +// turn themselves into the rather ugly `{' '}` when breaking. +// +// We print JSX using the `fill` doc primitive. +// This requires that we give it an array of alternating +// content and whitespace elements. +// To ensure this we add dummy `""` content elements as needed. - case "ImportSpecifier": - if (n.importKind) { - parts.push(path.call(print, "importKind"), " "); - } - parts.push(path.call(print, "imported")); +function printJSXChildren(path, options, print, jsxWhitespace, isFacebookTranslationTag) { + const n = path.getValue(); + const children = []; + path.each((childPath, i) => { + const child = childPath.getValue(); - if (n.local && n.local.name !== n.imported.name) { - parts.push(" as ", path.call(print, "local")); - } + if (isLiteral$1(child)) { + const text = rawText$1(child); // Contains a non-whitespace character - return concat$6(parts); + if (isMeaningfulJSXText$1(child)) { + const words = text.split(matchJsxWhitespaceRegex$1); // Starts with whitespace - case "ExportSpecifier": - parts.push(path.call(print, "local")); + if (words[0] === "") { + children.push(""); + words.shift(); - if (n.exported && n.exported.name !== n.local.name) { - parts.push(" as ", path.call(print, "exported")); - } + if (/\n/.test(words[0])) { + const next = n.children[i + 1]; + children.push(separatorWithWhitespace(isFacebookTranslationTag, words[1], child, next)); + } else { + children.push(jsxWhitespace); + } - return concat$6(parts); + words.shift(); + } - case "ImportNamespaceSpecifier": - parts.push("* as "); - parts.push(path.call(print, "local")); - return concat$6(parts); + let endWhitespace; // Ends with whitespace - case "ImportDefaultSpecifier": - return path.call(print, "local"); + if (getLast$5(words) === "") { + words.pop(); + endWhitespace = words.pop(); + } // This was whitespace only without a new line. - case "TSExportAssignment": - return concat$6(["export = ", path.call(print, "expression"), semi]); - case "ExportDefaultDeclaration": - case "ExportNamedDeclaration": - return printExportDeclaration(path, options, print); + if (words.length === 0) { + return; + } - case "ExportAllDeclaration": - parts.push("export "); + words.forEach((word, i) => { + if (i % 2 === 1) { + children.push(line$b); + } else { + children.push(word); + } + }); - if (n.exportKind === "type") { - parts.push("type "); + if (endWhitespace !== undefined) { + if (/\n/.test(endWhitespace)) { + const next = n.children[i + 1]; + children.push(separatorWithWhitespace(isFacebookTranslationTag, getLast$5(children), child, next)); + } else { + children.push(jsxWhitespace); + } + } else { + const next = n.children[i + 1]; + children.push(separatorNoWhitespace(isFacebookTranslationTag, getLast$5(children), child, next)); + } + } else if (/\n/.test(text)) { + // Keep (up to one) blank line between tags/expressions/text. + // Note: We don't keep blank lines between text elements. + if (text.match(/\n/g).length > 1) { + children.push(""); + children.push(hardline$b); + } + } else { + children.push(""); + children.push(jsxWhitespace); } + } else { + const printedChild = print(childPath); + children.push(printedChild); + const next = n.children[i + 1]; + const directlyFollowedByMeaningfulText = next && isMeaningfulJSXText$1(next); - parts.push("* "); - - if (n.exported) { - parts.push("as ", path.call(print, "exported"), " "); + if (directlyFollowedByMeaningfulText) { + const firstWord = rawText$1(next).trim().split(matchJsxWhitespaceRegex$1)[0]; + children.push(separatorNoWhitespace(isFacebookTranslationTag, firstWord, child, next)); + } else { + children.push(hardline$b); } + } + }, "children"); + return children; +} - parts.push("from ", path.call(print, "source"), semi); - return concat$6(parts); - - case "ExportNamespaceSpecifier": - case "ExportDefaultSpecifier": - return path.call(print, "exported"); - - case "ImportDeclaration": - { - parts.push("import "); +function separatorNoWhitespace(isFacebookTranslationTag, child, childNode, nextNode) { + if (isFacebookTranslationTag) { + return ""; + } - if (n.importKind && n.importKind !== "value") { - parts.push(n.importKind + " "); - } + if (childNode.type === "JSXElement" && !childNode.closingElement || nextNode && nextNode.type === "JSXElement" && !nextNode.closingElement) { + return child.length === 1 ? softline$a : hardline$b; + } - const standalones = []; - const grouped = []; + return softline$a; +} - if (n.specifiers && n.specifiers.length > 0) { - path.each(specifierPath => { - const value = specifierPath.getValue(); +function separatorWithWhitespace(isFacebookTranslationTag, child, childNode, nextNode) { + if (isFacebookTranslationTag) { + return hardline$b; + } - if (value.type === "ImportDefaultSpecifier" || value.type === "ImportNamespaceSpecifier") { - standalones.push(print(specifierPath)); - } else { - grouped.push(print(specifierPath)); - } - }, "specifiers"); + if (child.length === 1) { + return childNode.type === "JSXElement" && !childNode.closingElement || nextNode && nextNode.type === "JSXElement" && !nextNode.closingElement ? hardline$b : softline$a; + } - if (standalones.length > 0) { - parts.push(join$4(", ", standalones)); - } + return hardline$b; +} - if (standalones.length > 0 && grouped.length > 0) { - parts.push(", "); - } +function maybeWrapJSXElementInParens(path, elem, options) { + const parent = path.getParentNode(); + /* istanbul ignore next */ - if (grouped.length === 1 && standalones.length === 0 && n.specifiers && !n.specifiers.some(node => node.comments)) { - parts.push(concat$6(["{", options.bracketSpacing ? " " : "", concat$6(grouped), options.bracketSpacing ? " " : "", "}"])); - } else if (grouped.length >= 1) { - parts.push(group$2(concat$6(["{", indent$3(concat$6([options.bracketSpacing ? line$4 : softline$2, join$4(concat$6([",", line$4]), grouped)])), ifBreak$1(shouldPrintComma(options) ? "," : ""), options.bracketSpacing ? line$4 : softline$2, "}"]))); - } + if (!parent) { + return elem; + } - parts.push(" from "); - } else if (n.importKind && n.importKind === "type" || // import {} from 'x' - /{\s*}/.test(options.originalText.slice(options.locStart(n), options.locStart(n.source)))) { - parts.push("{} from "); - } + const NO_WRAP_PARENTS = { + ArrayExpression: true, + JSXAttribute: true, + JSXElement: true, + JSXExpressionContainer: true, + JSXFragment: true, + ExpressionStatement: true, + CallExpression: true, + OptionalCallExpression: true, + ConditionalExpression: true, + JsExpressionRoot: true + }; - parts.push(path.call(print, "source"), semi); - return concat$6(parts); - } + if (NO_WRAP_PARENTS[parent.type]) { + return elem; + } - case "Import": - return "import"; + const shouldBreak = path.match(undefined, node => node.type === "ArrowFunctionExpression", isCallOrOptionalCallExpression$1, node => node.type === "JSXExpressionContainer"); + const needsParens = needsParens_1(path, options); + return group$a(concat$i([needsParens ? "" : ifBreak$6("("), indent$e(concat$i([softline$a, elem])), softline$a, needsParens ? "" : ifBreak$6(")")]), { + shouldBreak + }); +} - case "TSModuleBlock": - case "BlockStatement": - { - const naked = path.call(bodyPath => { - return printStatementSequence(bodyPath, options, print); - }, "body"); - const hasContent = n.body.find(node => node.type !== "EmptyStatement"); - const hasDirectives = n.directives && n.directives.length > 0; - const parent = path.getParentNode(); - const parentParent = path.getParentNode(1); +function printJsxAttribute(path, options, print) { + const n = path.getValue(); + const parts = []; + parts.push(path.call(print, "name")); - if (!hasContent && !hasDirectives && !hasDanglingComments$1(n) && (parent.type === "ArrowFunctionExpression" || parent.type === "FunctionExpression" || parent.type === "FunctionDeclaration" || parent.type === "ObjectMethod" || parent.type === "ClassMethod" || parent.type === "ClassPrivateMethod" || parent.type === "ForStatement" || parent.type === "WhileStatement" || parent.type === "DoWhileStatement" || parent.type === "DoExpression" || parent.type === "CatchClause" && !parentParent.finalizer || parent.type === "TSModuleDeclaration")) { - return "{}"; - } + if (n.value) { + let res; - parts.push("{"); // Babel 6 + if (isStringLiteral$1(n.value)) { + const raw = rawText$1(n.value); // Unescape all quotes so we get an accurate preferred quote - if (hasDirectives) { - path.each(childPath => { - parts.push(indent$3(concat$6([hardline$4, print(childPath), semi]))); + let final = raw.replace(/'/g, "'").replace(/"/g, '"'); + const quote = getPreferredQuote$1(final, options.jsxSingleQuote ? "'" : '"'); + const escape = quote === "'" ? "'" : """; + final = final.slice(1, -1).replace(new RegExp(quote, "g"), escape); + res = concat$i([quote, final, quote]); + } else { + res = path.call(print, "value"); + } - if (isNextLineEmpty$2(options.originalText, childPath.getValue(), options.locEnd)) { - parts.push(hardline$4); - } - }, "directives"); - } + parts.push("=", res); + } - if (hasContent) { - parts.push(indent$3(concat$6([hardline$4, naked]))); - } + return concat$i(parts); +} - parts.push(comments.printDanglingComments(path, options)); - parts.push(hardline$4, "}"); - return concat$6(parts); - } +function printJsxExpressionContainer(path, options, print) { + const n = path.getValue(); + const parent = path.getParentNode(0); + const hasComments = n.expression.comments && n.expression.comments.length > 0; + const shouldInline = n.expression.type === "JSXEmptyExpression" || !hasComments && (n.expression.type === "ArrayExpression" || n.expression.type === "ObjectExpression" || n.expression.type === "ArrowFunctionExpression" || n.expression.type === "CallExpression" || n.expression.type === "OptionalCallExpression" || n.expression.type === "FunctionExpression" || n.expression.type === "TemplateLiteral" || n.expression.type === "TaggedTemplateExpression" || n.expression.type === "DoExpression" || isJSXNode$3(parent) && (n.expression.type === "ConditionalExpression" || isBinaryish$2(n.expression))); - case "ReturnStatement": - return concat$6(["return", printReturnAndThrowArgument(path, options, print)]); + if (shouldInline) { + return group$a(concat$i(["{", path.call(print, "expression"), lineSuffixBoundary$2, "}"])); + } - case "NewExpression": - case "OptionalCallExpression": - case "CallExpression": - { - const isNew = n.type === "NewExpression"; - const optional = printOptionalToken(path); - - if ( // We want to keep CommonJS- and AMD-style require calls, and AMD-style - // define calls, as a unit. - // e.g. `define(["some/lib", (lib) => {` - !isNew && n.callee.type === "Identifier" && (n.callee.name === "require" || n.callee.name === "define") || // Template literals as single arguments - n.arguments.length === 1 && isTemplateOnItsOwnLine$1(n.arguments[0], options.originalText, options) || // Keep test declarations on a single line - // e.g. `it('long name', () => {` - !isNew && isTestCall$1(n, path.getParentNode())) { - return concat$6([isNew ? "new " : "", path.call(print, "callee"), optional, printFunctionTypeParameters(path, options, print), concat$6(["(", join$4(", ", path.map(print, "arguments")), ")"])]); - } // Inline Flow annotation comments following Identifiers in Call nodes need to - // stay with the Identifier. For example: - // - // foo /*:: */(bar); - // - // Here, we ensure that such comments stay between the Identifier and the Callee. + return group$a(concat$i(["{", indent$e(concat$i([softline$a, path.call(print, "expression")])), softline$a, lineSuffixBoundary$2, "}"])); +} +function printJsxOpeningElement(path, options, print) { + const n = path.getValue(); + const nameHasComments = n.name && n.name.comments && n.name.comments.length > 0 || n.typeParameters && n.typeParameters.comments && n.typeParameters.comments.length > 0; // Don't break self-closing elements with no attributes and no comments + + if (n.selfClosing && !n.attributes.length && !nameHasComments) { + return concat$i(["<", path.call(print, "name"), path.call(print, "typeParameters"), " />"]); + } // don't break up opening elements with a single long text attribute + + + if (n.attributes && n.attributes.length === 1 && n.attributes[0].value && isStringLiteral$1(n.attributes[0].value) && !n.attributes[0].value.value.includes("\n") && // We should break for the following cases: + //
+ //
+ !nameHasComments && (!n.attributes[0].comments || !n.attributes[0].comments.length)) { + return group$a(concat$i(["<", path.call(print, "name"), path.call(print, "typeParameters"), " ", concat$i(path.map(print, "attributes")), n.selfClosing ? " />" : ">"])); + } + + const lastAttrHasTrailingComments = n.attributes.length && hasTrailingComment$1(getLast$5(n.attributes)); + const bracketSameLine = // Simple tags (no attributes and no comment in tag name) should be + // kept unbroken regardless of `jsxBracketSameLine` + !n.attributes.length && !nameHasComments || options.jsxBracketSameLine && ( // We should print the bracket in a new line for the following cases: + //
+ //
+ !nameHasComments || n.attributes.length) && !lastAttrHasTrailingComments; // We should print the opening element expanded if any prop value is a + // string literal with newlines + + const shouldBreak = n.attributes && n.attributes.some(attr => attr.value && isStringLiteral$1(attr.value) && attr.value.value.includes("\n")); + return group$a(concat$i(["<", path.call(print, "name"), path.call(print, "typeParameters"), concat$i([indent$e(concat$i(path.map(attr => concat$i([line$b, print(attr)]), "attributes"))), n.selfClosing ? line$b : bracketSameLine ? ">" : softline$a]), n.selfClosing ? "/>" : bracketSameLine ? "" : ">"]), { + shouldBreak + }); +} - const isIdentifierWithFlowAnnotation = n.callee.type === "Identifier" && hasFlowAnnotationComment$1(n.callee.trailingComments); +function printJsxClosingElement(path, options, print) { + return concat$i([""]); +} - if (isIdentifierWithFlowAnnotation) { - n.callee.trailingComments[0].printed = true; - } // We detect calls on member lookups and possibly print them in a - // special chain format. See `printMemberChain` for more info. +function printJsxOpeningClosingFragment(path, options +/*, print*/ +) { + const n = path.getValue(); + const hasComment = n.comments && n.comments.length; + const hasOwnLineComment = hasComment && !n.comments.every(comment => isBlockComment$6(comment)); + const isOpeningFragment = n.type === "JSXOpeningFragment"; + return concat$i([isOpeningFragment ? "<" : ""]); +} +function printJsxElement(path, options, print) { + const elem = printComments$1(path, () => printJsxElementInternal(path, options, print), options); + return maybeWrapJSXElementInParens(path, elem, options); +} - if (!isNew && isMemberish$1(n.callee) && !path.call(path => needsParens_1(path, options), "callee")) { - return printMemberChain(path, options, print); - } +function printJsxEmptyExpression(path, options +/*, print*/ +) { + const n = path.getValue(); + const requiresHardline = n.comments && !n.comments.every(comment => isBlockComment$6(comment)); + return concat$i([printDanglingComments$5(path, options, + /* sameIndent */ + !requiresHardline), requiresHardline ? hardline$b : ""]); +} // `JSXSpreadAttribute` and `JSXSpreadChild` - const contents = concat$6([isNew ? "new " : "", path.call(print, "callee"), optional, isIdentifierWithFlowAnnotation ? `/*:: ${n.callee.trailingComments[0].value.slice(2).trim()} */` : "", printFunctionTypeParameters(path, options, print), printArgumentsList(path, options, print)]); // We group here when the callee is itself a call expression. - // See `isLongCurriedCallExpression` for more info. - if (isCallOrOptionalCallExpression$1(n.callee)) { - return group$2(contents); - } +function printJsxSpreadAttribute(path, options, print) { + const n = path.getValue(); + return concat$i(["{", path.call(p => { + const printed = concat$i(["...", print(p)]); + const n = p.getValue(); - return contents; - } + if (!n.comments || !n.comments.length || !willPrintOwnComments$1(p)) { + return printed; + } - case "TSInterfaceDeclaration": - if (n.declare) { - parts.push("declare "); - } + return concat$i([indent$e(concat$i([softline$a, printComments$1(p, () => printed, options)])), softline$a]); + }, n.type === "JSXSpreadAttribute" ? "argument" : "expression"), "}"]); +} - parts.push(n.abstract ? "abstract " : "", printTypeScriptModifiers(path, options, print), "interface ", path.call(print, "id"), n.typeParameters ? path.call(print, "typeParameters") : "", " "); +var jsx = { + printJsxElement, + printJsxAttribute, + printJsxOpeningElement, + printJsxClosingElement, + printJsxOpeningClosingFragment, + printJsxExpressionContainer, + printJsxEmptyExpression, + printJsxSpreadAttribute, + // Alias + printJsxSpreadChild: printJsxSpreadAttribute +}; - if (n.extends && n.extends.length) { - parts.push(group$2(indent$3(concat$6([softline$2, "extends ", (n.extends.length === 1 ? identity$2 : indent$3)(join$4(concat$6([",", line$4]), path.map(print, "extends"))), " "])))); - } +const { + printDanglingComments: printDanglingComments$6 +} = comments; +const { + builders: { + concat: concat$j, + join: join$7, + line: line$c, + hardline: hardline$c, + softline: softline$b, + group: group$b, + indent: indent$f, + ifBreak: ifBreak$7 + } +} = document; +const { + hasDanglingComments: hasDanglingComments$4, + isTestCall: isTestCall$2, + isBlockComment: isBlockComment$7, + shouldPrintComma: shouldPrintComma$5 +} = utils$6; +const { + shouldHugType: shouldHugType$2 +} = typeAnnotation; +const typeParametersGroupIds = new WeakMap(); - parts.push(path.call(print, "body")); - return concat$6(parts); +function getTypeParametersGroupId(node) { + if (!typeParametersGroupIds.has(node)) { + typeParametersGroupIds.set(node, Symbol("typeParameters")); + } - case "ObjectTypeInternalSlot": - return concat$6([n.static ? "static " : "", "[[", path.call(print, "id"), "]]", printOptionalToken(path), n.method ? "" : ": ", path.call(print, "value")]); + return typeParametersGroupIds.get(node); +} - case "ObjectExpression": - case "ObjectPattern": - case "ObjectTypeAnnotation": - case "TSInterfaceBody": - case "TSTypeLiteral": - { - let propertiesField; +function printTypeParameters(path, options, print, paramsKey) { + const n = path.getValue(); - if (n.type === "TSTypeLiteral") { - propertiesField = "members"; - } else if (n.type === "TSInterfaceBody") { - propertiesField = "body"; - } else { - propertiesField = "properties"; - } + if (!n[paramsKey]) { + return ""; + } // for TypeParameterDeclaration typeParameters is a single node - const isTypeAnnotation = n.type === "ObjectTypeAnnotation"; - const fields = []; - if (isTypeAnnotation) { - fields.push("indexers", "callProperties", "internalSlots"); - } + if (!Array.isArray(n[paramsKey])) { + return path.call(print, paramsKey); + } - fields.push(propertiesField); - const firstProperty = fields.map(field => n[field][0]).sort((a, b) => options.locStart(a) - options.locStart(b))[0]; - const parent = path.getParentNode(0); - const isFlowInterfaceLikeBody = isTypeAnnotation && parent && (parent.type === "InterfaceDeclaration" || parent.type === "DeclareInterface" || parent.type === "DeclareClass") && path.getName() === "body"; - const shouldBreak = n.type === "TSInterfaceBody" || isFlowInterfaceLikeBody || n.type === "ObjectPattern" && parent.type !== "FunctionDeclaration" && parent.type !== "FunctionExpression" && parent.type !== "ArrowFunctionExpression" && parent.type !== "ObjectMethod" && parent.type !== "ClassMethod" && parent.type !== "ClassPrivateMethod" && parent.type !== "AssignmentPattern" && parent.type !== "CatchClause" && n.properties.some(property => property.value && (property.value.type === "ObjectPattern" || property.value.type === "ArrayPattern")) || n.type !== "ObjectPattern" && firstProperty && hasNewlineInRange$3(options.originalText, options.locStart(n), options.locStart(firstProperty)); - const separator = isFlowInterfaceLikeBody ? ";" : n.type === "TSInterfaceBody" || n.type === "TSTypeLiteral" ? ifBreak$1(semi, ";") : ","; - const leftBrace = n.exact ? "{|" : "{"; - const rightBrace = n.exact ? "|}" : "}"; // Unfortunately, things are grouped together in the ast can be - // interleaved in the source code. So we need to reorder them before - // printing them. - - const propsAndLoc = []; - fields.forEach(field => { - path.each(childPath => { - const node = childPath.getValue(); - propsAndLoc.push({ - node, - printed: print(childPath), - loc: options.locStart(node) - }); - }, field); - }); - let separatorParts = []; - const props = propsAndLoc.sort((a, b) => a.loc - b.loc).map(prop => { - const result = concat$6(separatorParts.concat(group$2(prop.printed))); - separatorParts = [separator, line$4]; + const grandparent = path.getNode(2); + const isParameterInTestCall = grandparent != null && isTestCall$2(grandparent); + const shouldInline = isParameterInTestCall || n[paramsKey].length === 0 || n[paramsKey].length === 1 && (shouldHugType$2(n[paramsKey][0]) || n[paramsKey][0].type === "GenericTypeAnnotation" && shouldHugType$2(n[paramsKey][0].id) || n[paramsKey][0].type === "TSTypeReference" && shouldHugType$2(n[paramsKey][0].typeName) || n[paramsKey][0].type === "NullableTypeAnnotation"); - if ((prop.node.type === "TSPropertySignature" || prop.node.type === "TSMethodSignature" || prop.node.type === "TSConstructSignatureDeclaration") && hasNodeIgnoreComment$2(prop.node)) { - separatorParts.shift(); - } + if (shouldInline) { + return concat$j(["<", join$7(", ", path.map(print, paramsKey)), printDanglingCommentsForInline(path, options), ">"]); + } - if (isNextLineEmpty$2(options.originalText, prop.node, options.locEnd)) { - separatorParts.push(hardline$4); - } + return group$b(concat$j(["<", indent$f(concat$j([softline$b, join$7(concat$j([",", line$c]), path.map(print, paramsKey))])), ifBreak$7(options.parser !== "typescript" && options.parser !== "babel-ts" && shouldPrintComma$5(options, "all") ? "," : ""), softline$b, ">"]), { + id: getTypeParametersGroupId(n) + }); +} - return result; - }); +function printDanglingCommentsForInline(path, options) { + const n = path.getValue(); - if (n.inexact) { - let printed; + if (!hasDanglingComments$4(n)) { + return ""; + } - if (hasDanglingComments$1(n)) { - const hasLineComments = !n.comments.every(comments$1.isBlockComment); - const printedDanglingComments = comments.printDanglingComments(path, options, - /* sameIndent */ - true); - printed = concat$6([printedDanglingComments, hasLineComments || hasNewline$4(options.originalText, options.locEnd(n.comments[n.comments.length - 1])) ? hardline$4 : line$4, "..."]); - } else { - printed = "..."; - } + const hasOnlyBlockComments = n.comments.every(comment => isBlockComment$7(comment)); + const printed = printDanglingComments$6(path, options, + /* sameIndent */ + hasOnlyBlockComments); - props.push(concat$6(separatorParts.concat(printed))); - } + if (hasOnlyBlockComments) { + return printed; + } - const lastElem = getLast$2(n[propertiesField]); - const canHaveTrailingSeparator = !(n.inexact || lastElem && (lastElem.type === "RestElement" || hasNodeIgnoreComment$2(lastElem))); - let content; + return concat$j([printed, hardline$c]); +} - if (props.length === 0) { - if (!hasDanglingComments$1(n)) { - return concat$6([leftBrace, rightBrace, printTypeAnnotation(path, options, print)]); - } +var typeParameters = { + printTypeParameters, + getTypeParametersGroupId +}; - content = group$2(concat$6([leftBrace, comments.printDanglingComments(path, options), softline$2, rightBrace, printOptionalToken(path), printTypeAnnotation(path, options, print)])); - } else { - content = concat$6([leftBrace, indent$3(concat$6([options.bracketSpacing ? line$4 : softline$2, concat$6(props)])), ifBreak$1(canHaveTrailingSeparator && (separator !== "," || shouldPrintComma(options)) ? separator : ""), concat$6([options.bracketSpacing ? line$4 : softline$2, rightBrace]), printOptionalToken(path), printTypeAnnotation(path, options, print)]); - } // If we inline the object as first argument of the parent, we don't want - // to create another group so that the object breaks before the return - // type +const { + printComments: printComments$2 +} = comments; +const { + printString: printString$1, + printNumber: printNumber$1 +} = util; +const { + builders: { + concat: concat$k + } +} = document; +const { + isNumericLiteral: isNumericLiteral$1, + isSimpleNumber: isSimpleNumber$1, + isStringLiteral: isStringLiteral$2, + isStringPropSafeToUnquote: isStringPropSafeToUnquote$1, + rawText: rawText$2 +} = utils$6; +const needsQuoteProps = new WeakMap(); +function printPropertyKey(path, options, print) { + const node = path.getNode(); - if (path.match(node => node.type === "ObjectPattern" && !node.decorators, (node, name, number) => shouldHugArguments(node) && (name === "params" || name === "parameters") && number === 0) || path.match(shouldHugType, (node, name) => name === "typeAnnotation", (node, name) => name === "typeAnnotation", (node, name, number) => shouldHugArguments(node) && (name === "params" || name === "parameters") && number === 0)) { - return content; - } + if (node.computed) { + return concat$k(["[", path.call(print, "key"), "]"]); + } - return group$2(content, { - shouldBreak - }); - } - // Babel 6 + const parent = path.getParentNode(); + const { + key + } = node; - case "ObjectProperty": // Non-standard AST node type. + if (node.type === "ClassPrivateProperty" && // flow has `Identifier` key, and babel has `PrivateName` key + key.type === "Identifier") { + return concat$k(["#", path.call(print, "key")]); + } - case "Property": - if (n.method || n.kind === "get" || n.kind === "set") { - return printMethod(path, options, print); - } + if (options.quoteProps === "consistent" && !needsQuoteProps.has(parent)) { + const objectHasStringProp = (parent.properties || parent.body || parent.members).some(prop => !prop.computed && prop.key && isStringLiteral$2(prop.key) && !isStringPropSafeToUnquote$1(prop, options)); + needsQuoteProps.set(parent, objectHasStringProp); + } - if (n.shorthand) { - parts.push(path.call(print, "value")); - } else { - parts.push(printAssignment(n.key, printPropertyKey(path, options, print), ":", n.value, path.call(print, "value"), options)); - } + if ((key.type === "Identifier" || isNumericLiteral$1(key) && isSimpleNumber$1(printNumber$1(rawText$2(key))) && // Avoid converting 999999999999999999999 to 1e+21, 0.99999999999999999 to 1 and 1.0 to 1. + String(key.value) === printNumber$1(rawText$2(key)) && // Quoting number keys is safe in JS and Flow, but not in TypeScript (as + // mentioned in `isStringPropSafeToUnquote`). + !(options.parser === "typescript" || options.parser === "babel-ts")) && (options.parser === "json" || options.quoteProps === "consistent" && needsQuoteProps.get(parent))) { + // a -> "a" + // 1 -> "1" + // 1.5 -> "1.5" + const prop = printString$1(JSON.stringify(key.type === "Identifier" ? key.name : key.value.toString()), options); + return path.call(keyPath => printComments$2(keyPath, () => prop, options), "key"); + } - return concat$6(parts); - // Babel 6 + if (isStringPropSafeToUnquote$1(node, options) && (options.quoteProps === "as-needed" || options.quoteProps === "consistent" && !needsQuoteProps.get(parent))) { + // 'a' -> a + // '1' -> 1 + // '1.5' -> 1.5 + return path.call(keyPath => printComments$2(keyPath, () => /^\d/.test(key.value) ? printNumber$1(key.value) : key.value, options), "key"); + } - case "ClassMethod": - case "ClassPrivateMethod": - case "MethodDefinition": - case "TSAbstractMethodDefinition": - case "TSDeclareMethod": - if (n.decorators && n.decorators.length !== 0) { - parts.push(printDecorators(path, options, print)); - } + return path.call(print, "key"); +} - if (n.accessibility) { - parts.push(n.accessibility + " "); - } +var property$1 = { + printPropertyKey +}; - if (n.static) { - parts.push("static "); - } +/** @type {import("assert")} */ - if (n.type === "TSAbstractMethodDefinition" || n.abstract) { - parts.push("abstract "); - } - parts.push(printMethod(path, options, print)); - return concat$6(parts); +const { + printDanglingComments: printDanglingComments$7 +} = comments; +const { + getNextNonSpaceNonCommentCharacterIndex: getNextNonSpaceNonCommentCharacterIndex$3 +} = util; +const { + builders: { + concat: concat$l, + line: line$d, + softline: softline$c, + group: group$c, + indent: indent$g, + ifBreak: ifBreak$8, + hardline: hardline$d + } +} = document; +const { + getFunctionParameters: getFunctionParameters$4, + hasDanglingComments: hasDanglingComments$5, + hasLeadingOwnLineComment: hasLeadingOwnLineComment$1, + isFlowAnnotationComment: isFlowAnnotationComment$2, + isJSXNode: isJSXNode$4, + isTemplateOnItsOwnLine: isTemplateOnItsOwnLine$1, + shouldPrintComma: shouldPrintComma$6, + startsWithNoLookaheadToken: startsWithNoLookaheadToken$2, + returnArgumentHasLeadingComment: returnArgumentHasLeadingComment$1, + isBinaryish: isBinaryish$3, + isLineComment: isLineComment$1 +} = utils$6; +const { + locEnd: locEnd$8 +} = loc; +const { + printFunctionParameters: printFunctionParameters$1 +} = functionParameters; +const { + printPropertyKey: printPropertyKey$1 +} = property$1; +const { + printFunctionTypeParameters: printFunctionTypeParameters$2 +} = misc; - case "ObjectMethod": - return printMethod(path, options, print); +function printFunctionDeclaration(path, print, options, expandArg) { + const n = path.getValue(); + const parts = []; - case "Decorator": - return concat$6(["@", path.call(print, "expression"), path.call(print, "callee")]); + if (n.async) { + parts.push("async "); + } - case "ArrayExpression": - case "ArrayPattern": - if (n.elements.length === 0) { - if (!hasDanglingComments$1(n)) { - parts.push("[]"); - } else { - parts.push(group$2(concat$6(["[", comments.printDanglingComments(path, options), softline$2, "]"]))); - } - } else { - const lastElem = getLast$2(n.elements); - const canHaveTrailingComma = !(lastElem && lastElem.type === "RestElement"); // JavaScript allows you to have empty elements in an array which - // changes its length based on the number of commas. The algorithm - // is that if the last argument is null, we need to force insert - // a comma to ensure JavaScript recognizes it. - // [,].length === 1 - // [1,].length === 1 - // [1,,].length === 2 - // - // Note that getLast returns null if the array is empty, but - // we already check for an empty array just above so we are safe + if (n.generator) { + parts.push("function* "); + } else { + parts.push("function "); + } - const needsForcedTrailingComma = canHaveTrailingComma && lastElem === null; - const shouldBreak = n.elements.length > 1 && n.elements.every((element, i, elements) => { - const elementType = element && element.type; + if (n.id) { + parts.push(path.call(print, "id")); + } - if (elementType !== "ArrayExpression" && elementType !== "ObjectExpression") { - return false; - } + parts.push(printFunctionTypeParameters$2(path, options, print), group$c(concat$l([printFunctionParameters$1(path, print, options, expandArg), printReturnType(path, print, options)])), n.body ? " " : "", path.call(print, "body")); + return concat$l(parts); +} - const nextElement = elements[i + 1]; +function printMethod(path, options, print) { + const node = path.getNode(); + const { + kind + } = node; + const value = node.value || node; + const parts = []; - if (nextElement && elementType !== nextElement.type) { - return false; - } + if (!kind || kind === "init" || kind === "method" || kind === "constructor") { + if (value.async) { + parts.push("async "); + } + } else { + assert__default['default'].ok(kind === "get" || kind === "set"); + parts.push(kind, " "); + } // A `getter`/`setter` can't be a generator, but it's recoverable - const itemsKey = elementType === "ArrayExpression" ? "elements" : "properties"; - return element[itemsKey] && element[itemsKey].length > 1; - }); - parts.push(group$2(concat$6(["[", indent$3(concat$6([softline$2, printArrayItems(path, options, "elements", print)])), needsForcedTrailingComma ? "," : "", ifBreak$1(canHaveTrailingComma && !needsForcedTrailingComma && shouldPrintComma(options) ? "," : ""), comments.printDanglingComments(path, options, - /* sameIndent */ - true), softline$2, "]"]), { - shouldBreak - })); - } - parts.push(printOptionalToken(path), printTypeAnnotation(path, options, print)); - return concat$6(parts); + if (value.generator) { + parts.push("*"); + } - case "SequenceExpression": - { - const parent = path.getParentNode(0); + parts.push(printPropertyKey$1(path, options, print), node.optional || node.key.optional ? "?" : "", node === value ? printMethodInternal(path, options, print) : path.call(path => printMethodInternal(path, options, print), "value")); + return concat$l(parts); +} - if (parent.type === "ExpressionStatement" || parent.type === "ForStatement") { - // For ExpressionStatements and for-loop heads, which are among - // the few places a SequenceExpression appears unparenthesized, we want - // to indent expressions after the first. - const parts = []; - path.each(p => { - if (p.getName() === 0) { - parts.push(print(p)); - } else { - parts.push(",", indent$3(concat$6([line$4, print(p)]))); - } - }, "expressions"); - return group$2(concat$6(parts)); - } +function printMethodInternal(path, options, print) { + const parts = [printFunctionTypeParameters$2(path, options, print), group$c(concat$l([printFunctionParameters$1(path, print, options), printReturnType(path, print, options)]))]; - return group$2(concat$6([join$4(concat$6([",", line$4]), path.map(print, "expressions"))])); - } + if (path.getNode().body) { + parts.push(" ", path.call(print, "body")); + } else { + parts.push(options.semi ? ";" : ""); + } - case "ThisExpression": - return "this"; + return concat$l(parts); +} - case "Super": - return "super"; +function printArrowFunctionExpression(path, options, print, args) { + const n = path.getValue(); + const parts = []; - case "NullLiteral": - // Babel 6 Literal split - return "null"; + if (n.async) { + parts.push("async "); + } - case "RegExpLiteral": - // Babel 6 Literal split - return printRegex(n); + if (shouldPrintParamsWithoutParens(path, options)) { + parts.push(path.call(print, "params", 0)); + } else { + parts.push(group$c(concat$l([printFunctionParameters$1(path, print, options, + /* expandLast */ + args && (args.expandLastArg || args.expandFirstArg), + /* printTypeParams */ + true), printReturnType(path, print, options)]))); + } - case "NumericLiteral": - // Babel 6 Literal split - return printNumber$1(n.extra.raw); + const dangling = printDanglingComments$7(path, options, + /* sameIndent */ + true, comment => { + const nextCharacter = getNextNonSpaceNonCommentCharacterIndex$3(options.originalText, comment, locEnd$8); + return nextCharacter !== false && options.originalText.slice(nextCharacter, nextCharacter + 2) === "=>"; + }); - case "BigIntLiteral": - // babel: n.extra.raw, typescript: n.raw, flow: n.bigint - return (n.bigint || (n.extra ? n.extra.raw : n.raw)).toLowerCase(); + if (dangling) { + parts.push(" ", dangling); + } - case "BooleanLiteral": // Babel 6 Literal split + parts.push(" =>"); + const body = path.call(bodyPath => print(bodyPath, args), "body"); // We want to always keep these types of nodes on the same line + // as the arrow. - case "StringLiteral": // Babel 6 Literal split + if (!hasLeadingOwnLineComment$1(options.originalText, n.body) && (n.body.type === "ArrayExpression" || n.body.type === "ObjectExpression" || n.body.type === "BlockStatement" || isJSXNode$4(n.body) || isTemplateOnItsOwnLine$1(n.body, options.originalText) || n.body.type === "ArrowFunctionExpression" || n.body.type === "DoExpression")) { + return group$c(concat$l([concat$l(parts), " ", body])); + } // We handle sequence expressions as the body of arrows specially, + // so that the required parentheses end up on their own lines. - case "Literal": - { - if (n.regex) { - return printRegex(n.regex); - } - if (typeof n.value === "number") { - return printNumber$1(n.raw); - } + if (n.body.type === "SequenceExpression") { + return group$c(concat$l([concat$l(parts), group$c(concat$l([" (", indent$g(concat$l([softline$c, body])), softline$c, ")"]))])); + } // if the arrow function is expanded as last argument, we are adding a + // level of indentation and need to add a softline to align the closing ) + // with the opening (, or if it's inside a JSXExpression (e.g. an attribute) + // we should align the expression's closing } with the line with the opening {. - if (typeof n.value !== "string") { - return "" + n.value; - } // TypeScript workaround for https://github.com/JamesHenry/typescript-estree/issues/2 - // See corresponding workaround in needs-parens.js + const shouldAddSoftLine = (args && args.expandLastArg || path.getParentNode().type === "JSXExpressionContainer") && !(n.comments && n.comments.length); + const printTrailingComma = args && args.expandLastArg && shouldPrintComma$6(options, "all"); // In order to avoid confusion between + // a => a ? a : a + // a <= a ? a : a - const grandParent = path.getParentNode(1); - const isTypeScriptDirective = options.parser === "typescript" && typeof n.value === "string" && grandParent && (grandParent.type === "Program" || grandParent.type === "BlockStatement"); - return nodeStr(n, options, isTypeScriptDirective); - } + const shouldAddParens = n.body.type === "ConditionalExpression" && !startsWithNoLookaheadToken$2(n.body, + /* forbidFunctionAndClass */ + false); + return group$c(concat$l([concat$l(parts), group$c(concat$l([indent$g(concat$l([line$d, shouldAddParens ? ifBreak$8("", "(") : "", body, shouldAddParens ? ifBreak$8("", ")") : ""])), shouldAddSoftLine ? concat$l([ifBreak$8(printTrailingComma ? "," : ""), softline$c]) : ""]))])); +} - case "Directive": - return path.call(print, "value"); - // Babel 6 +function canPrintParamsWithoutParens(node) { + const parameters = getFunctionParameters$4(node); + return parameters.length === 1 && !node.typeParameters && !hasDanglingComments$5(node) && parameters[0].type === "Identifier" && !parameters[0].typeAnnotation && !parameters[0].comments && !parameters[0].optional && !node.predicate && !node.returnType; +} - case "DirectiveLiteral": - return nodeStr(n, options); +function shouldPrintParamsWithoutParens(path, options) { + if (options.arrowParens === "always") { + return false; + } - case "UnaryExpression": - parts.push(n.operator); + if (options.arrowParens === "avoid") { + const node = path.getValue(); + return canPrintParamsWithoutParens(node); + } // Fallback default; should be unreachable - if (/[a-z]$/.test(n.operator)) { - parts.push(" "); - } + /* istanbul ignore next */ - if (n.argument.comments && n.argument.comments.length > 0) { - parts.push(group$2(concat$6(["(", indent$3(concat$6([softline$2, path.call(print, "argument")])), softline$2, ")"]))); - } else { - parts.push(path.call(print, "argument")); - } - return concat$6(parts); + return false; +} - case "UpdateExpression": - parts.push(path.call(print, "argument"), n.operator); +function printReturnType(path, print, options) { + const n = path.getValue(); + const returnType = path.call(print, "returnType"); - if (n.prefix) { - parts.reverse(); - } + if (n.returnType && isFlowAnnotationComment$2(options.originalText, n.returnType)) { + return concat$l([" /*: ", returnType, " */"]); + } - return concat$6(parts); + const parts = [returnType]; // prepend colon to TypeScript type annotation - case "ConditionalExpression": - return printTernaryOperator(path, options, print, { - beforeParts: () => [path.call(print, "test")], - afterParts: breakClosingParen => [breakClosingParen ? softline$2 : ""], - shouldCheckJsx: true, - conditionalNodeType: "ConditionalExpression", - consequentNodePropertyName: "consequent", - alternateNodePropertyName: "alternate", - testNodePropertyNames: ["test"] - }); + if (n.returnType && n.returnType.typeAnnotation) { + parts.unshift(": "); + } - case "VariableDeclaration": - { - const printed = path.map(childPath => { - return print(childPath); - }, "declarations"); // We generally want to terminate all variable declarations with a - // semicolon, except when they in the () part of for loops. + if (n.predicate) { + // The return type will already add the colon, but otherwise we + // need to do it ourselves + parts.push(n.returnType ? " " : ": ", path.call(print, "predicate")); + } - const parentNode = path.getParentNode(); - const isParentForLoop = parentNode.type === "ForStatement" || parentNode.type === "ForInStatement" || parentNode.type === "ForOfStatement"; - const hasValue = n.declarations.some(decl => decl.init); - let firstVariable; + return concat$l(parts); +} // `ReturnStatement` and `ThrowStatement` - if (printed.length === 1 && !n.declarations[0].comments) { - firstVariable = printed[0]; - } else if (printed.length > 0) { - // Indent first var to comply with eslint one-var rule - firstVariable = indent$3(printed[0]); - } - parts = [n.declare ? "declare " : "", n.kind, firstVariable ? concat$6([" ", firstVariable]) : "", indent$3(concat$6(printed.slice(1).map(p => concat$6([",", hasValue && !isParentForLoop ? hardline$4 : line$4, p]))))]; +function printReturnAndThrowArgument(path, options, print) { + const node = path.getValue(); + const semi = options.semi ? ";" : ""; + const parts = []; - if (!(isParentForLoop && parentNode.body !== n)) { - parts.push(semi); - } + if (node.argument) { + if (returnArgumentHasLeadingComment$1(options, node.argument)) { + parts.push(concat$l([" (", indent$g(concat$l([hardline$d, path.call(print, "argument")])), hardline$d, ")"])); + } else if (isBinaryish$3(node.argument) || node.argument.type === "SequenceExpression") { + parts.push(group$c(concat$l([ifBreak$8(" (", " "), indent$g(concat$l([softline$c, path.call(print, "argument")])), softline$c, ifBreak$8(")")]))); + } else { + parts.push(" ", path.call(print, "argument")); + } + } - return group$2(concat$6(parts)); - } + const lastComment = Array.isArray(node.comments) && node.comments[node.comments.length - 1]; + const isLastCommentLine = lastComment && isLineComment$1(lastComment); - case "TSTypeAliasDeclaration": - { - if (n.declare) { - parts.push("declare "); - } + if (isLastCommentLine) { + parts.push(semi); + } - const printed = printAssignmentRight(n.id, n.typeAnnotation, n.typeAnnotation && path.call(print, "typeAnnotation"), options); - parts.push("type ", path.call(print, "id"), path.call(print, "typeParameters"), " =", printed, semi); - return group$2(concat$6(parts)); - } + if (hasDanglingComments$5(node)) { + parts.push(" ", printDanglingComments$7(path, options, + /* sameIndent */ + true)); + } - case "VariableDeclarator": - return printAssignment(n.id, path.call(print, "id"), " =", n.init, n.init && path.call(print, "init"), options); + if (!isLastCommentLine) { + parts.push(semi); + } - case "WithStatement": - return group$2(concat$6(["with (", path.call(print, "object"), ")", adjustClause(n.body, path.call(print, "body"))])); + return concat$l(parts); +} - case "IfStatement": - { - const con = adjustClause(n.consequent, path.call(print, "consequent")); - const opening = group$2(concat$6(["if (", group$2(concat$6([indent$3(concat$6([softline$2, path.call(print, "test")])), softline$2])), ")", con])); - parts.push(opening); +var _function = { + printFunctionDeclaration, + printArrowFunctionExpression, + printMethod, + printReturnAndThrowArgument, + shouldPrintParamsWithoutParens +}; - if (n.alternate) { - const commentOnOwnLine = hasTrailingComment$1(n.consequent) && n.consequent.comments.some(comment => comment.trailing && !comments$1.isBlockComment(comment)) || needsHardlineAfterDanglingComment$1(n); - const elseOnSameLine = n.consequent.type === "BlockStatement" && !commentOnOwnLine; - parts.push(elseOnSameLine ? " " : hardline$4); +const { + printComments: printComments$3, + printDanglingComments: printDanglingComments$8 +} = comments; +const { + builders: { + concat: concat$m, + join: join$8, + line: line$e, + hardline: hardline$e, + softline: softline$d, + group: group$d, + indent: indent$h, + ifBreak: ifBreak$9 + } +} = document; +const { + hasTrailingComment: hasTrailingComment$2, + hasTrailingLineComment: hasTrailingLineComment$1 +} = utils$6; +const { + getTypeParametersGroupId: getTypeParametersGroupId$1 +} = typeParameters; +const { + printMethod: printMethod$1 +} = _function; +const { + printDecorators: printDecorators$1 +} = misc; - if (hasDanglingComments$1(n)) { - parts.push(comments.printDanglingComments(path, options, true), commentOnOwnLine ? hardline$4 : " "); - } +function printClass(path, options, print) { + const n = path.getValue(); + const parts = []; - parts.push("else", group$2(adjustClause(n.alternate, path.call(print, "alternate"), n.alternate.type === "IfStatement"))); - } + if (n.abstract) { + parts.push("abstract "); + } - return concat$6(parts); - } + parts.push("class"); // Keep old behaviour of extends in same line + // If there is only on extends and there are not comments - case "ForStatement": - { - const body = adjustClause(n.body, path.call(print, "body")); // We want to keep dangling comments above the loop to stay consistent. - // Any comment positioned between the for statement and the parentheses - // is going to be printed before the statement. + const groupMode = n.id && hasTrailingComment$2(n.id) || n.superClass && n.superClass.comments && n.superClass.comments.length !== 0 || n.extends && n.extends.length !== 0 || // DeclareClass + n.mixins && n.mixins.length !== 0 || n.implements && n.implements.length !== 0; + const partsGroup = []; + const extendsParts = []; - const dangling = comments.printDanglingComments(path, options, - /* sameLine */ - true); - const printedComments = dangling ? concat$6([dangling, softline$2]) : ""; + if (n.id) { + partsGroup.push(" ", path.call(print, "id")); + } - if (!n.init && !n.test && !n.update) { - return concat$6([printedComments, group$2(concat$6(["for (;;)", body]))]); - } + partsGroup.push(path.call(print, "typeParameters")); - return concat$6([printedComments, group$2(concat$6(["for (", group$2(concat$6([indent$3(concat$6([softline$2, path.call(print, "init"), ";", line$4, path.call(print, "test"), ";", line$4, path.call(print, "update")])), softline$2])), ")", body]))]); - } + if (n.superClass) { + const printed = concat$m(["extends ", printSuperClass(path, options, print), path.call(print, "superTypeParameters")]); + const printedWithComments = path.call(superClass => printComments$3(superClass, () => printed, options), "superClass"); - case "WhileStatement": - return group$2(concat$6(["while (", group$2(concat$6([indent$3(concat$6([softline$2, path.call(print, "test")])), softline$2])), ")", adjustClause(n.body, path.call(print, "body"))])); + if (groupMode) { + extendsParts.push(line$e, group$d(printedWithComments)); + } else { + extendsParts.push(" ", printedWithComments); + } + } else { + extendsParts.push(printList(path, options, print, "extends")); + } - case "ForInStatement": - // Note: esprima can't actually parse "for each (". - return group$2(concat$6([n.each ? "for each (" : "for (", path.call(print, "left"), " in ", path.call(print, "right"), ")", adjustClause(n.body, path.call(print, "body"))])); + extendsParts.push(printList(path, options, print, "mixins")); + extendsParts.push(printList(path, options, print, "implements")); - case "ForOfStatement": - return group$2(concat$6(["for", n.await ? " await" : "", " (", path.call(print, "left"), " of ", path.call(print, "right"), ")", adjustClause(n.body, path.call(print, "body"))])); + if (groupMode) { + const printedExtends = concat$m(extendsParts); - case "DoWhileStatement": - { - const clause = adjustClause(n.body, path.call(print, "body")); - const doBody = group$2(concat$6(["do", clause])); - parts = [doBody]; + if (shouldIndentOnlyHeritageClauses(n)) { + parts.push(group$d(concat$m(partsGroup.concat(ifBreak$9(indent$h(printedExtends), printedExtends))))); + } else { + parts.push(group$d(indent$h(concat$m(partsGroup.concat(printedExtends))))); + } + } else { + parts.push(...partsGroup, ...extendsParts); + } - if (n.body.type === "BlockStatement") { - parts.push(" "); - } else { - parts.push(hardline$4); - } + parts.push(" ", path.call(print, "body")); + return concat$m(parts); +} - parts.push("while ("); - parts.push(group$2(concat$6([indent$3(concat$6([softline$2, path.call(print, "test")])), softline$2])), ")", semi); - return concat$6(parts); - } +function hasMultipleHeritage(node) { + return ["superClass", "extends", "mixins", "implements"].filter(key => !!node[key]).length > 1; +} - case "DoExpression": - return concat$6(["do ", path.call(print, "body")]); +function shouldIndentOnlyHeritageClauses(node) { + return node.typeParameters && !hasTrailingLineComment$1(node.typeParameters) && !hasMultipleHeritage(node); +} - case "BreakStatement": - parts.push("break"); +function printList(path, options, print, listName) { + const n = path.getValue(); - if (n.label) { - parts.push(" ", path.call(print, "label")); - } + if (!n[listName] || n[listName].length === 0) { + return ""; + } - parts.push(semi); - return concat$6(parts); + const printedLeadingComments = printDanglingComments$8(path, options, + /* sameIndent */ + true, ({ + marker + }) => marker === listName); + return concat$m([shouldIndentOnlyHeritageClauses(n) ? ifBreak$9(" ", line$e, { + groupId: getTypeParametersGroupId$1(n.typeParameters) + }) : line$e, printedLeadingComments, printedLeadingComments && hardline$e, listName, group$d(indent$h(concat$m([line$e, join$8(concat$m([",", line$e]), path.map(print, listName))])))]); +} - case "ContinueStatement": - parts.push("continue"); +function printSuperClass(path, options, print) { + const printed = path.call(print, "superClass"); + const parent = path.getParentNode(); - if (n.label) { - parts.push(" ", path.call(print, "label")); - } + if (parent.type === "AssignmentExpression") { + return group$d(ifBreak$9(concat$m(["(", indent$h(concat$m([softline$d, printed])), softline$d, ")"]), printed)); + } - parts.push(semi); - return concat$6(parts); + return printed; +} - case "LabeledStatement": - if (n.body.type === "EmptyStatement") { - return concat$6([path.call(print, "label"), ":;"]); - } +function printClassMethod(path, options, print) { + const n = path.getValue(); + const parts = []; - return concat$6([path.call(print, "label"), ": ", path.call(print, "body")]); + if (n.decorators && n.decorators.length !== 0) { + parts.push(printDecorators$1(path, options, print)); + } - case "TryStatement": - return concat$6(["try ", path.call(print, "block"), n.handler ? concat$6([" ", path.call(print, "handler")]) : "", n.finalizer ? concat$6([" finally ", path.call(print, "finalizer")]) : ""]); + if (n.accessibility) { + parts.push(n.accessibility + " "); + } - case "CatchClause": - if (n.param) { - const hasComments = n.param.comments && n.param.comments.some(comment => !comments$1.isBlockComment(comment) || comment.leading && hasNewline$4(options.originalText, options.locEnd(comment)) || comment.trailing && hasNewline$4(options.originalText, options.locStart(comment), { - backwards: true - })); - const param = path.call(print, "param"); - return concat$6(["catch ", hasComments ? concat$6(["(", indent$3(concat$6([softline$2, param])), softline$2, ") "]) : concat$6(["(", param, ") "]), path.call(print, "body")]); - } + if (n.static) { + parts.push("static "); + } - return concat$6(["catch ", path.call(print, "body")]); + if (n.type === "TSAbstractMethodDefinition" || n.abstract) { + parts.push("abstract "); + } - case "ThrowStatement": - return concat$6(["throw", printReturnAndThrowArgument(path, options, print)]); - // Note: ignoring n.lexical because it has no printing consequences. + parts.push(printMethod$1(path, options, print)); + return concat$m(parts); +} - case "SwitchStatement": - return concat$6([group$2(concat$6(["switch (", indent$3(concat$6([softline$2, path.call(print, "discriminant")])), softline$2, ")"])), " {", n.cases.length > 0 ? indent$3(concat$6([hardline$4, join$4(hardline$4, path.map(casePath => { - const caseNode = casePath.getValue(); - return concat$6([casePath.call(print), n.cases.indexOf(caseNode) !== n.cases.length - 1 && isNextLineEmpty$2(options.originalText, caseNode, options.locEnd) ? hardline$4 : ""]); - }, "cases"))])) : "", hardline$4, "}"]); +var _class = { + printClass, + printClassMethod +}; - case "SwitchCase": - { - if (n.test) { - parts.push("case ", path.call(print, "test"), ":"); - } else { - parts.push("default:"); - } +const { + getLast: getLast$6, + getPenultimate: getPenultimate$1, + isNextLineEmpty: isNextLineEmpty$5 +} = util; +const { + getFunctionParameters: getFunctionParameters$5, + iterateFunctionParametersPath: iterateFunctionParametersPath$2, + hasLeadingComment: hasLeadingComment$3, + hasTrailingComment: hasTrailingComment$3, + isFunctionCompositionArgs: isFunctionCompositionArgs$1, + isJSXNode: isJSXNode$5, + isLongCurriedCallExpression: isLongCurriedCallExpression$1, + shouldPrintComma: shouldPrintComma$7, + getCallArguments: getCallArguments$1, + iterateCallArgumentsPath: iterateCallArgumentsPath$1 +} = utils$6; +const { + locEnd: locEnd$9 +} = loc; +const { + builders: { + concat: concat$n, + line: line$f, + hardline: hardline$f, + softline: softline$e, + group: group$e, + indent: indent$i, + conditionalGroup: conditionalGroup$2, + ifBreak: ifBreak$a, + breakParent: breakParent$3 + }, + utils: { + willBreak: willBreak$2 + } +} = document; - const consequent = n.consequent.filter(node => node.type !== "EmptyStatement"); +function printCallArguments(path, options, print) { + const node = path.getValue(); + const isDynamicImport = node.type === "ImportExpression"; + const args = getCallArguments$1(node); - if (consequent.length > 0) { - const cons = path.call(consequentPath => { - return printStatementSequence(consequentPath, options, print); - }, "consequent"); - parts.push(consequent.length === 1 && consequent[0].type === "BlockStatement" ? concat$6([" ", cons]) : indent$3(concat$6([hardline$4, cons]))); - } + if (args.length === 0) { + return concat$n(["(", comments.printDanglingComments(path, options, + /* sameIndent */ + true), ")"]); + } // useEffect(() => { ... }, [foo, bar, baz]) - return concat$6(parts); - } - // JSX extensions below. - case "DebuggerStatement": - return concat$6(["debugger", semi]); + if (args.length === 2 && args[0].type === "ArrowFunctionExpression" && getFunctionParameters$5(args[0]).length === 0 && args[0].body.type === "BlockStatement" && args[1].type === "ArrayExpression" && !args.some(arg => arg.comments)) { + return concat$n(["(", path.call(print, "arguments", 0), ", ", path.call(print, "arguments", 1), ")"]); + } // func( + // ({ + // a, + // + // b + // }) => {} + // ); - case "JSXAttribute": - parts.push(path.call(print, "name")); - if (n.value) { - let res; + function shouldBreakForArrowFunctionInArguments(arg, argPath) { + if (!arg || arg.type !== "ArrowFunctionExpression" || !arg.body || arg.body.type !== "BlockStatement" || getFunctionParameters$5(arg).length === 0) { + return false; + } - if (isStringLiteral$1(n.value)) { - const raw = rawText$1(n.value); // Unescape all quotes so we get an accurate preferred quote + let shouldBreak = false; + iterateFunctionParametersPath$2(argPath, parameterPath => { + shouldBreak = shouldBreak || willBreak$2(concat$n([print(parameterPath)])); + }); + return shouldBreak; + } - let final = raw.replace(/'/g, "'").replace(/"/g, '"'); - const quote = getPreferredQuote$1(final, options.jsxSingleQuote ? "'" : '"'); - const escape = quote === "'" ? "'" : """; - final = final.slice(1, -1).replace(new RegExp(quote, "g"), escape); - res = concat$6([quote, final, quote]); - } else { - res = path.call(print, "value"); - } + let anyArgEmptyLine = false; + let shouldBreakForArrowFunction = false; + let hasEmptyLineFollowingFirstArg = false; + const lastArgIndex = args.length - 1; + const printedArguments = []; + iterateCallArgumentsPath$1(path, (argPath, index) => { + const arg = argPath.getNode(); + const parts = [print(argPath)]; - parts.push("=", res); + if (index === lastArgIndex) ; else if (isNextLineEmpty$5(options.originalText, arg, locEnd$9)) { + if (index === 0) { + hasEmptyLineFollowingFirstArg = true; } - return concat$6(parts); - - case "JSXIdentifier": - return "" + n.name; + anyArgEmptyLine = true; + parts.push(",", hardline$f, hardline$f); + } else { + parts.push(",", line$f); + } - case "JSXNamespacedName": - return join$4(":", [path.call(print, "namespace"), path.call(print, "name")]); + shouldBreakForArrowFunction = shouldBreakForArrowFunctionInArguments(arg, argPath); + printedArguments.push(concat$n(parts)); + }); + const maybeTrailingComma = // Dynamic imports cannot have trailing commas + !(isDynamicImport || node.callee && node.callee.type === "Import") && shouldPrintComma$7(options, "all") ? "," : ""; - case "JSXMemberExpression": - return join$4(".", [path.call(print, "object"), path.call(print, "property")]); + function allArgsBrokenOut() { + return group$e(concat$n(["(", indent$i(concat$n([line$f, concat$n(printedArguments)])), maybeTrailingComma, line$f, ")"]), { + shouldBreak: true + }); + } - case "TSQualifiedName": - return join$4(".", [path.call(print, "left"), path.call(print, "right")]); + if (path.getParentNode().type !== "Decorator" && isFunctionCompositionArgs$1(args)) { + return allArgsBrokenOut(); + } - case "JSXSpreadAttribute": - case "JSXSpreadChild": - { - return concat$6(["{", path.call(p => { - const printed = concat$6(["...", print(p)]); - const n = p.getValue(); + const shouldGroupFirst = shouldGroupFirstArg(args); + const shouldGroupLast = shouldGroupLastArg(args); - if (!n.comments || !n.comments.length) { - return printed; - } + if (shouldGroupFirst || shouldGroupLast) { + const shouldBreak = (shouldGroupFirst ? printedArguments.slice(1).some(willBreak$2) : printedArguments.slice(0, -1).some(willBreak$2)) || anyArgEmptyLine || shouldBreakForArrowFunction; // We want to print the last argument with a special flag - return concat$6([indent$3(concat$6([softline$2, comments.printComments(p, () => printed, options)])), softline$2]); - }, n.type === "JSXSpreadAttribute" ? "argument" : "expression"), "}"]); + let printedExpanded = []; + iterateCallArgumentsPath$1(path, (argPath, i) => { + if (shouldGroupFirst && i === 0) { + printedExpanded = [concat$n([argPath.call(p => print(p, { + expandFirstArg: true + })), printedArguments.length > 1 ? "," : "", hasEmptyLineFollowingFirstArg ? hardline$f : line$f, hasEmptyLineFollowingFirstArg ? hardline$f : ""])].concat(printedArguments.slice(1)); } - case "JSXExpressionContainer": - { - const parent = path.getParentNode(0); - const hasComments = n.expression.comments && n.expression.comments.length > 0; - const shouldInline = n.expression.type === "JSXEmptyExpression" || !hasComments && (n.expression.type === "ArrayExpression" || n.expression.type === "ObjectExpression" || n.expression.type === "ArrowFunctionExpression" || n.expression.type === "CallExpression" || n.expression.type === "OptionalCallExpression" || n.expression.type === "FunctionExpression" || n.expression.type === "TemplateLiteral" || n.expression.type === "TaggedTemplateExpression" || n.expression.type === "DoExpression" || isJSXNode$1(parent) && (n.expression.type === "ConditionalExpression" || isBinaryish$1(n.expression))); + if (shouldGroupLast && i === args.length - 1) { + printedExpanded = printedArguments.slice(0, -1).concat(argPath.call(p => print(p, { + expandLastArg: true + }))); + } + }); + const somePrintedArgumentsWillBreak = printedArguments.some(willBreak$2); + const simpleConcat = concat$n(["(", concat$n(printedExpanded), ")"]); + return concat$n([somePrintedArgumentsWillBreak ? breakParent$3 : "", conditionalGroup$2([!somePrintedArgumentsWillBreak && !node.typeArguments && !node.typeParameters ? simpleConcat : ifBreak$a(allArgsBrokenOut(), simpleConcat), shouldGroupFirst ? concat$n(["(", group$e(printedExpanded[0], { + shouldBreak: true + }), concat$n(printedExpanded.slice(1)), ")"]) : concat$n(["(", concat$n(printedArguments.slice(0, -1)), group$e(getLast$6(printedExpanded), { + shouldBreak: true + }), ")"]), allArgsBrokenOut()], { + shouldBreak + })]); + } - if (shouldInline) { - return group$2(concat$6(["{", path.call(print, "expression"), lineSuffixBoundary$1, "}"])); - } + const contents = concat$n(["(", indent$i(concat$n([softline$e, concat$n(printedArguments)])), ifBreak$a(maybeTrailingComma), softline$e, ")"]); - return group$2(concat$6(["{", indent$3(concat$6([softline$2, path.call(print, "expression")])), softline$2, lineSuffixBoundary$1, "}"])); - } + if (isLongCurriedCallExpression$1(path)) { + // By not wrapping the arguments in a group, the printer prioritizes + // breaking up these arguments rather than the args of the parent call. + return contents; + } - case "JSXFragment": - case "JSXElement": - { - const elem = comments.printComments(path, () => printJSXElement(path, options, print), options); - return maybeWrapJSXElementInParens(path, elem, options); - } + return group$e(contents, { + shouldBreak: printedArguments.some(willBreak$2) || anyArgEmptyLine + }); +} - case "JSXOpeningElement": - { - const n = path.getValue(); - const nameHasComments = n.name && n.name.comments && n.name.comments.length > 0 || n.typeParameters && n.typeParameters.comments && n.typeParameters.comments.length > 0; // Don't break self-closing elements with no attributes and no comments - - if (n.selfClosing && !n.attributes.length && !nameHasComments) { - return concat$6(["<", path.call(print, "name"), path.call(print, "typeParameters"), " />"]); - } // don't break up opening elements with a single long text attribute - - - if (n.attributes && n.attributes.length === 1 && n.attributes[0].value && isStringLiteral$1(n.attributes[0].value) && !n.attributes[0].value.value.includes("\n") && // We should break for the following cases: - //
- //
- !nameHasComments && (!n.attributes[0].comments || !n.attributes[0].comments.length)) { - return group$2(concat$6(["<", path.call(print, "name"), path.call(print, "typeParameters"), " ", concat$6(path.map(print, "attributes")), n.selfClosing ? " />" : ">"])); - } - - const lastAttrHasTrailingComments = n.attributes.length && hasTrailingComment$1(getLast$2(n.attributes)); - const bracketSameLine = // Simple tags (no attributes and no comment in tag name) should be - // kept unbroken regardless of `jsxBracketSameLine` - !n.attributes.length && !nameHasComments || options.jsxBracketSameLine && ( // We should print the bracket in a new line for the following cases: - //
- //
- !nameHasComments || n.attributes.length) && !lastAttrHasTrailingComments; // We should print the opening element expanded if any prop value is a - // string literal with newlines - - const shouldBreak = n.attributes && n.attributes.some(attr => attr.value && isStringLiteral$1(attr.value) && attr.value.value.includes("\n")); - return group$2(concat$6(["<", path.call(print, "name"), path.call(print, "typeParameters"), concat$6([indent$3(concat$6(path.map(attr => concat$6([line$4, print(attr)]), "attributes"))), n.selfClosing ? line$4 : bracketSameLine ? ">" : softline$2]), n.selfClosing ? "/>" : bracketSameLine ? "" : ">"]), { - shouldBreak - }); - } +function couldGroupArg(arg) { + return arg.type === "ObjectExpression" && (arg.properties.length > 0 || arg.comments) || arg.type === "ArrayExpression" && (arg.elements.length > 0 || arg.comments) || arg.type === "TSTypeAssertion" && couldGroupArg(arg.expression) || arg.type === "TSAsExpression" && couldGroupArg(arg.expression) || arg.type === "FunctionExpression" || arg.type === "ArrowFunctionExpression" && ( // we want to avoid breaking inside composite return types but not simple keywords + // https://github.com/prettier/prettier/issues/4070 + // export class Thing implements OtherThing { + // do: (type: Type) => Provider = memoize( + // (type: ObjectType): Provider => {} + // ); + // } + // https://github.com/prettier/prettier/issues/6099 + // app.get("/", (req, res): void => { + // res.send("Hello World!"); + // }); + !arg.returnType || !arg.returnType.typeAnnotation || arg.returnType.typeAnnotation.type !== "TSTypeReference") && (arg.body.type === "BlockStatement" || arg.body.type === "ArrowFunctionExpression" || arg.body.type === "ObjectExpression" || arg.body.type === "ArrayExpression" || arg.body.type === "CallExpression" || arg.body.type === "OptionalCallExpression" || arg.body.type === "ConditionalExpression" || isJSXNode$5(arg.body)); +} - case "JSXClosingElement": - return concat$6([""]); +function shouldGroupLastArg(args) { + const lastArg = getLast$6(args); + const penultimateArg = getPenultimate$1(args); + return !hasLeadingComment$3(lastArg) && !hasTrailingComment$3(lastArg) && couldGroupArg(lastArg) && ( // If the last two arguments are of the same type, + // disable last element expansion. + !penultimateArg || penultimateArg.type !== lastArg.type); +} - case "JSXOpeningFragment": - case "JSXClosingFragment": - { - const hasComment = n.comments && n.comments.length; - const hasOwnLineComment = hasComment && !n.comments.every(comments$1.isBlockComment); - const isOpeningFragment = n.type === "JSXOpeningFragment"; - return concat$6([isOpeningFragment ? "<" : ""]); - } +function shouldGroupFirstArg(args) { + if (args.length !== 2) { + return false; + } - case "JSXText": - /* istanbul ignore next */ - throw new Error("JSXTest should be handled by JSXElement"); + const [firstArg, secondArg] = args; + return (!firstArg.comments || !firstArg.comments.length) && (firstArg.type === "FunctionExpression" || firstArg.type === "ArrowFunctionExpression" && firstArg.body.type === "BlockStatement") && secondArg.type !== "FunctionExpression" && secondArg.type !== "ArrowFunctionExpression" && secondArg.type !== "ConditionalExpression" && !couldGroupArg(secondArg); +} - case "JSXEmptyExpression": - { - const requiresHardline = n.comments && !n.comments.every(comments$1.isBlockComment); - return concat$6([comments.printDanglingComments(path, options, - /* sameIndent */ - !requiresHardline), requiresHardline ? hardline$4 : ""]); - } +var callArguments = printCallArguments; - case "ClassBody": - if (!n.comments && n.body.length === 0) { - return "{}"; - } +const { + builders: { + concat: concat$o, + softline: softline$f, + group: group$f, + indent: indent$j + } +} = document; +const { + isNumericLiteral: isNumericLiteral$2 +} = utils$6; +const { + printOptionalToken: printOptionalToken$3 +} = misc; - return concat$6(["{", n.body.length > 0 ? indent$3(concat$6([hardline$4, path.call(bodyPath => { - return printStatementSequence(bodyPath, options, print); - }, "body")])) : comments.printDanglingComments(path, options), hardline$4, "}"]); +function printMemberExpression(path, options, print) { + const n = path.getValue(); + const parent = path.getParentNode(); + let firstNonMemberParent; + let i = 0; - case "ClassProperty": - case "TSAbstractClassProperty": - case "ClassPrivateProperty": - { - if (n.decorators && n.decorators.length !== 0) { - parts.push(printDecorators(path, options, print)); - } + do { + firstNonMemberParent = path.getParentNode(i); + i++; + } while (firstNonMemberParent && (firstNonMemberParent.type === "MemberExpression" || firstNonMemberParent.type === "OptionalMemberExpression" || firstNonMemberParent.type === "TSNonNullExpression")); - if (n.accessibility) { - parts.push(n.accessibility + " "); - } + const shouldInline = firstNonMemberParent && (firstNonMemberParent.type === "NewExpression" || firstNonMemberParent.type === "BindExpression" || firstNonMemberParent.type === "VariableDeclarator" && firstNonMemberParent.id.type !== "Identifier" || firstNonMemberParent.type === "AssignmentExpression" && firstNonMemberParent.left.type !== "Identifier") || n.computed || n.object.type === "Identifier" && n.property.type === "Identifier" && parent.type !== "MemberExpression" && parent.type !== "OptionalMemberExpression"; + return concat$o([path.call(print, "object"), shouldInline ? printMemberLookup(path, options, print) : group$f(indent$j(concat$o([softline$f, printMemberLookup(path, options, print)])))]); +} - if (n.declare) { - parts.push("declare "); - } +function printMemberLookup(path, options, print) { + const property = path.call(print, "property"); + const n = path.getValue(); + const optional = printOptionalToken$3(path); - if (n.static) { - parts.push("static "); - } + if (!n.computed) { + return concat$o([optional, ".", property]); + } - if (n.type === "TSAbstractClassProperty" || n.abstract) { - parts.push("abstract "); - } + if (!n.property || isNumericLiteral$2(n.property)) { + return concat$o([optional, "[", property, "]"]); + } - if (n.readonly) { - parts.push("readonly "); - } + return group$f(concat$o([optional, "[", indent$j(concat$o([softline$f, property])), softline$f, "]"])); +} - const variance = getFlowVariance$1(n); +var member = { + printMemberExpression, + printMemberLookup +}; - if (variance) { - parts.push(variance); - } +const { + getLast: getLast$7, + isNextLineEmpty: isNextLineEmpty$6, + isNextLineEmptyAfterIndex: isNextLineEmptyAfterIndex$2, + getNextNonSpaceNonCommentCharacterIndex: getNextNonSpaceNonCommentCharacterIndex$4 +} = util; +const { + hasLeadingComment: hasLeadingComment$4, + hasTrailingComment: hasTrailingComment$4, + isCallOrOptionalCallExpression: isCallOrOptionalCallExpression$2, + isFunctionOrArrowExpression: isFunctionOrArrowExpression$1, + isLongCurriedCallExpression: isLongCurriedCallExpression$2, + isMemberish: isMemberish$1, + isNumericLiteral: isNumericLiteral$3, + isSimpleCallArgument: isSimpleCallArgument$1 +} = utils$6; +const { + locEnd: locEnd$a +} = loc; +const { + builders: { + concat: concat$p, + join: join$9, + hardline: hardline$g, + group: group$g, + indent: indent$k, + conditionalGroup: conditionalGroup$3, + breakParent: breakParent$4 + }, + utils: { + willBreak: willBreak$3 + } +} = document; +const { + printMemberLookup: printMemberLookup$1 +} = member; +const { + printOptionalToken: printOptionalToken$4, + printFunctionTypeParameters: printFunctionTypeParameters$3, + printBindExpressionCallee: printBindExpressionCallee$1 +} = misc; // We detect calls on member expressions specially to format a +// common pattern better. The pattern we are looking for is this: +// +// arr +// .map(x => x + 1) +// .filter(x => x > 10) +// .some(x => x % 2) +// +// The way it is structured in the AST is via a nested sequence of +// MemberExpression and CallExpression. We need to traverse the AST +// and make groups out of it to print it in the desired way. - parts.push(printPropertyKey(path, options, print), printOptionalToken(path), printTypeAnnotation(path, options, print)); +function printMemberChain(path, options, print) { + const parent = path.getParentNode(); + const isExpressionStatement = !parent || parent.type === "ExpressionStatement"; // The first phase is to linearize the AST by traversing it down. + // + // a().b() + // has the following AST structure: + // CallExpression(MemberExpression(CallExpression(Identifier))) + // and we transform it into + // [Identifier, CallExpression, MemberExpression, CallExpression] - if (n.value) { - parts.push(" =", printAssignmentRight(n.key, n.value, path.call(print, "value"), options)); - } + const printedNodes = []; // Here we try to retain one typed empty line after each call expression or + // the first group whether it is in parentheses or not - parts.push(semi); - return group$2(concat$6(parts)); - } + function shouldInsertEmptyLineAfter(node) { + const { + originalText + } = options; + const nextCharIndex = getNextNonSpaceNonCommentCharacterIndex$4(originalText, node, locEnd$a); + const nextChar = originalText.charAt(nextCharIndex); // if it is cut off by a parenthesis, we only account for one typed empty + // line after that parenthesis - case "ClassDeclaration": - case "ClassExpression": - if (n.declare) { - parts.push("declare "); - } + if (nextChar === ")") { + return nextCharIndex !== false && isNextLineEmptyAfterIndex$2(originalText, nextCharIndex + 1); + } - parts.push(concat$6(printClass(path, options, print))); - return concat$6(parts); + return isNextLineEmpty$6(originalText, node, locEnd$a); + } - case "TSInterfaceHeritage": - case "TSExpressionWithTypeArguments": - // Babel AST - parts.push(path.call(print, "expression")); + function rec(path) { + const node = path.getValue(); - if (n.typeParameters) { - parts.push(path.call(print, "typeParameters")); - } + if (isCallOrOptionalCallExpression$2(node) && (isMemberish$1(node.callee) || isCallOrOptionalCallExpression$2(node.callee))) { + printedNodes.unshift({ + node, + printed: concat$p([comments.printComments(path, () => concat$p([printOptionalToken$4(path), printFunctionTypeParameters$3(path, options, print), callArguments(path, options, print)]), options), shouldInsertEmptyLineAfter(node) ? hardline$g : ""]) + }); + path.call(callee => rec(callee), "callee"); + } else if (isMemberish$1(node)) { + printedNodes.unshift({ + node, + needsParens: needsParens_1(path, options), + printed: comments.printComments(path, () => node.type === "OptionalMemberExpression" || node.type === "MemberExpression" ? printMemberLookup$1(path, options, print) : printBindExpressionCallee$1(path, options, print), options) + }); + path.call(object => rec(object), "object"); + } else if (node.type === "TSNonNullExpression") { + printedNodes.unshift({ + node, + printed: comments.printComments(path, () => "!", options) + }); + path.call(expression => rec(expression), "expression"); + } else { + printedNodes.unshift({ + node, + printed: path.call(print) + }); + } + } // Note: the comments of the root node have already been printed, so we + // need to extract this first call without printing them as they would + // if handled inside of the recursive call. - return concat$6(parts); - case "TemplateElement": - return join$4(literalline$2, n.value.raw.split(/\r?\n/g)); + const node = path.getValue(); + printedNodes.unshift({ + node, + printed: concat$p([printOptionalToken$4(path), printFunctionTypeParameters$3(path, options, print), callArguments(path, options, print)]) + }); - case "TemplateLiteral": - { - let expressions = path.map(print, "expressions"); - const parentNode = path.getParentNode(); + if (node.callee) { + path.call(callee => rec(callee), "callee"); + } // Once we have a linear list of printed nodes, we want to create groups out + // of it. + // + // a().b.c().d().e + // will be grouped as + // [ + // [Identifier, CallExpression], + // [MemberExpression, MemberExpression, CallExpression], + // [MemberExpression, CallExpression], + // [MemberExpression], + // ] + // so that we can print it as + // a() + // .b.c() + // .d() + // .e + // The first group is the first node followed by + // - as many CallExpression as possible + // < fn()()() >.something() + // - as many array accessors as possible + // < fn()[0][1][2] >.something() + // - then, as many MemberExpression as possible but the last one + // < this.items >.something() - if (isJestEachTemplateLiteral$1(n, parentNode)) { - const printed = printJestEachTemplateLiteral(n, expressions, options); - if (printed) { - return printed; - } - } + const groups = []; + let currentGroup = [printedNodes[0]]; + let i = 1; - const isSimple = isSimpleTemplateLiteral$1(n); + for (; i < printedNodes.length; ++i) { + if (printedNodes[i].node.type === "TSNonNullExpression" || isCallOrOptionalCallExpression$2(printedNodes[i].node) || (printedNodes[i].node.type === "MemberExpression" || printedNodes[i].node.type === "OptionalMemberExpression") && printedNodes[i].node.computed && isNumericLiteral$3(printedNodes[i].node.property)) { + currentGroup.push(printedNodes[i]); + } else { + break; + } + } - if (isSimple) { - expressions = expressions.map(doc => printDocToString$2(doc, Object.assign({}, options, { - printWidth: Infinity - })).formatted); - } + if (!isCallOrOptionalCallExpression$2(printedNodes[0].node)) { + for (; i + 1 < printedNodes.length; ++i) { + if (isMemberish$1(printedNodes[i].node) && isMemberish$1(printedNodes[i + 1].node)) { + currentGroup.push(printedNodes[i]); + } else { + break; + } + } + } - parts.push(lineSuffixBoundary$1, "`"); - path.each(childPath => { - const i = childPath.getName(); - parts.push(print(childPath)); - - if (i < expressions.length) { - // For a template literal of the following form: - // `someQuery { - // ${call({ - // a, - // b, - // })} - // }` - // the expression is on its own line (there is a \n in the previous - // quasi literal), therefore we want to indent the JavaScript - // expression inside at the beginning of ${ instead of the beginning - // of the `. - const { - tabWidth - } = options; - const quasi = childPath.getValue(); - const indentSize = getIndentSize$2(quasi.value.raw, tabWidth); - let printed = expressions[i]; - - if (!isSimple) { - // Breaks at the template element boundaries (${ and }) are preferred to breaking - // in the middle of a MemberExpression - if (n.expressions[i].comments && n.expressions[i].comments.length || n.expressions[i].type === "MemberExpression" || n.expressions[i].type === "OptionalMemberExpression" || n.expressions[i].type === "ConditionalExpression" || n.expressions[i].type === "SequenceExpression" || n.expressions[i].type === "TSAsExpression" || isBinaryish$1(n.expressions[i])) { - printed = concat$6([indent$3(concat$6([softline$2, printed])), softline$2]); - } - } + groups.push(currentGroup); + currentGroup = []; // Then, each following group is a sequence of MemberExpression followed by + // a sequence of CallExpression. To compute it, we keep adding things to the + // group until we has seen a CallExpression in the past and reach a + // MemberExpression - const aligned = indentSize === 0 && quasi.value.raw.endsWith("\n") ? align$1(-Infinity, printed) : addAlignmentToDoc$2(printed, indentSize, tabWidth); - parts.push(group$2(concat$6(["${", aligned, lineSuffixBoundary$1, "}"]))); - } - }, "quasis"); - parts.push("`"); - return concat$6(parts); + let hasSeenCallExpression = false; + + for (; i < printedNodes.length; ++i) { + if (hasSeenCallExpression && isMemberish$1(printedNodes[i].node)) { + // [0] should be appended at the end of the group instead of the + // beginning of the next one + if (printedNodes[i].node.computed && isNumericLiteral$3(printedNodes[i].node.property)) { + currentGroup.push(printedNodes[i]); + continue; } - // These types are unprintable because they serve as abstract - // supertypes for other (printable) types. - case "TaggedTemplateExpression": - return concat$6([path.call(print, "tag"), path.call(print, "typeParameters"), path.call(print, "quasi")]); + groups.push(currentGroup); + currentGroup = []; + hasSeenCallExpression = false; + } - case "Node": - case "Printable": - case "SourceLocation": - case "Position": - case "Statement": - case "Function": - case "Pattern": - case "Expression": - case "Declaration": - case "Specifier": - case "NamedSpecifier": - case "Comment": - case "MemberTypeAnnotation": // Flow + if (isCallOrOptionalCallExpression$2(printedNodes[i].node) || printedNodes[i].node.type === "ImportExpression") { + hasSeenCallExpression = true; + } - case "Type": - /* istanbul ignore next */ - throw new Error("unprintable type: " + JSON.stringify(n.type)); - // Type Annotations for Facebook Flow, typically stripped out or - // transformed away before printing. + currentGroup.push(printedNodes[i]); - case "TypeAnnotation": - case "TSTypeAnnotation": - if (n.typeAnnotation) { - return path.call(print, "typeAnnotation"); - } - /* istanbul ignore next */ + if (printedNodes[i].node.comments && printedNodes[i].node.comments.some(comment => comment.trailing)) { + groups.push(currentGroup); + currentGroup = []; + hasSeenCallExpression = false; + } + } + if (currentGroup.length > 0) { + groups.push(currentGroup); + } // There are cases like Object.keys(), Observable.of(), _.values() where + // they are the subject of all the chained calls and therefore should + // be kept on the same line: + // + // Object.keys(items) + // .filter(x => x) + // .map(x => x) + // + // In order to detect those cases, we use an heuristic: if the first + // node is an identifier with the name starting with a capital + // letter or just a sequence of _$. The rationale is that they are + // likely to be factories. - return ""; - case "TSTupleType": - case "TupleTypeAnnotation": - { - const typesField = n.type === "TSTupleType" ? "elementTypes" : "types"; - const hasRest = n[typesField].length > 0 && getLast$2(n[typesField]).type === "TSRestType"; - return group$2(concat$6(["[", indent$3(concat$6([softline$2, printArrayItems(path, options, typesField, print)])), ifBreak$1(shouldPrintComma(options, "all") && !hasRest ? "," : ""), comments.printDanglingComments(path, options, - /* sameIndent */ - true), softline$2, "]"])); - } + function isFactory(name) { + return /^[A-Z]|^[$_]+$/.test(name); + } // In case the Identifier is shorter than tab width, we can keep the + // first call in a single line, if it's an ExpressionStatement. + // + // d3.scaleLinear() + // .domain([0, 100]) + // .range([0, width]); + // - case "ExistsTypeAnnotation": - return "*"; - case "EmptyTypeAnnotation": - return "empty"; + function isShort(name) { + return name.length <= options.tabWidth; + } - case "AnyTypeAnnotation": - return "any"; + function shouldNotWrap(groups) { + const hasComputed = groups[1].length && groups[1][0].node.computed; - case "MixedTypeAnnotation": - return "mixed"; + if (groups[0].length === 1) { + const firstNode = groups[0][0].node; + return firstNode.type === "ThisExpression" || firstNode.type === "Identifier" && (isFactory(firstNode.name) || isExpressionStatement && isShort(firstNode.name) || hasComputed); + } - case "ArrayTypeAnnotation": - return concat$6([path.call(print, "elementType"), "[]"]); + const lastNode = getLast$7(groups[0]).node; + return (lastNode.type === "MemberExpression" || lastNode.type === "OptionalMemberExpression") && lastNode.property.type === "Identifier" && (isFactory(lastNode.property.name) || hasComputed); + } - case "BooleanTypeAnnotation": - return "boolean"; + const shouldMerge = groups.length >= 2 && !groups[1][0].node.comments && shouldNotWrap(groups); - case "BooleanLiteralTypeAnnotation": - return "" + n.value; + function printGroup(printedGroup) { + const printed = printedGroup.map(tuple => tuple.printed); // Checks if the last node (i.e. the parent node) needs parens and print + // accordingly - case "DeclareClass": - return printFlowDeclaration(path, printClass(path, options, print)); + if (printedGroup.length > 0 && printedGroup[printedGroup.length - 1].needsParens) { + return concat$p(["(", ...printed, ")"]); + } - case "TSDeclareFunction": - // For TypeScript the TSDeclareFunction node shares the AST - // structure with FunctionDeclaration - return concat$6([n.declare ? "declare " : "", printFunctionDeclaration(path, print, options), semi]); + return concat$p(printed); + } - case "DeclareFunction": - return printFlowDeclaration(path, ["function ", path.call(print, "id"), n.predicate ? " " : "", path.call(print, "predicate"), semi]); + function printIndentedGroup(groups) { + /* istanbul ignore next */ + if (groups.length === 0) { + return ""; + } - case "DeclareModule": - return printFlowDeclaration(path, ["module ", path.call(print, "id"), " ", path.call(print, "body")]); + return indent$k(group$g(concat$p([hardline$g, join$9(hardline$g, groups.map(printGroup))]))); + } - case "DeclareModuleExports": - return printFlowDeclaration(path, ["module.exports", ": ", path.call(print, "typeAnnotation"), semi]); + const printedGroups = groups.map(printGroup); + const oneLine = concat$p(printedGroups); + const cutoff = shouldMerge ? 3 : 2; + const flatGroups = flatten_1(groups); + const hasComment = flatGroups.slice(1, -1).some(node => hasLeadingComment$4(node.node)) || flatGroups.slice(0, -1).some(node => hasTrailingComment$4(node.node)) || groups[cutoff] && hasLeadingComment$4(groups[cutoff][0].node); // If we only have a single `.`, we shouldn't do anything fancy and just + // render everything concatenated together. - case "DeclareVariable": - return printFlowDeclaration(path, ["var ", path.call(print, "id"), semi]); + if (groups.length <= cutoff && !hasComment) { + if (isLongCurriedCallExpression$2(path)) { + return oneLine; + } - case "DeclareExportAllDeclaration": - return concat$6(["declare export * from ", path.call(print, "source")]); + return group$g(oneLine); + } // Find out the last node in the first group and check if it has an + // empty line after - case "DeclareExportDeclaration": - return concat$6(["declare ", printExportDeclaration(path, options, print)]); - case "DeclareOpaqueType": - case "OpaqueType": - { - parts.push("opaque type ", path.call(print, "id"), path.call(print, "typeParameters")); + const lastNodeBeforeIndent = getLast$7(groups[shouldMerge ? 1 : 0]).node; + const shouldHaveEmptyLineBeforeIndent = !isCallOrOptionalCallExpression$2(lastNodeBeforeIndent) && shouldInsertEmptyLineAfter(lastNodeBeforeIndent); + const expanded = concat$p([printGroup(groups[0]), shouldMerge ? concat$p(groups.slice(1, 2).map(printGroup)) : "", shouldHaveEmptyLineBeforeIndent ? hardline$g : "", printIndentedGroup(groups.slice(shouldMerge ? 2 : 1))]); + const callExpressions = printedNodes.map(({ + node + }) => node).filter(isCallOrOptionalCallExpression$2); - if (n.supertype) { - parts.push(": ", path.call(print, "supertype")); - } + function lastGroupWillBreakAndOtherCallsHaveFunctionArguments() { + const lastGroupNode = getLast$7(getLast$7(groups)).node; + const lastGroupDoc = getLast$7(printedGroups); + return isCallOrOptionalCallExpression$2(lastGroupNode) && willBreak$3(lastGroupDoc) && callExpressions.slice(0, -1).some(n => n.arguments.some(isFunctionOrArrowExpression$1)); + } // We don't want to print in one line if at least one of these conditions occurs: + // * the chain has comments, + // * the chain is an expression statement and all the arguments are literal-like ("fluent configuration" pattern), + // * the chain is longer than 2 calls and has non-trivial arguments or more than 2 arguments in any call but the first one, + // * any group but the last one has a hard line, + // * the last call's arguments have a hard line and other calls have non-trivial arguments. - if (n.impltype) { - parts.push(" = ", path.call(print, "impltype")); - } - parts.push(semi); + if (hasComment || callExpressions.length > 2 && callExpressions.some(expr => !expr.arguments.every(arg => isSimpleCallArgument$1(arg, 0))) || printedGroups.slice(0, -1).some(willBreak$3) || lastGroupWillBreakAndOtherCallsHaveFunctionArguments()) { + return group$g(expanded); + } - if (n.type === "DeclareOpaqueType") { - return printFlowDeclaration(path, parts); - } + return concat$p([// We only need to check `oneLine` because if `expanded` is chosen + // that means that the parent group has already been broken + // naturally + willBreak$3(oneLine) || shouldHaveEmptyLineBeforeIndent ? breakParent$4 : "", conditionalGroup$3([oneLine, expanded])]); +} - return concat$6(parts); - } +var memberChain = printMemberChain; - case "EnumDeclaration": - return concat$6(["enum ", path.call(print, "id"), " ", path.call(print, "body")]); +const { + builders: { + concat: concat$q, + join: join$a, + group: group$h + } +} = document; +const { + getCallArguments: getCallArguments$2, + hasFlowAnnotationComment: hasFlowAnnotationComment$2, + isCallOrOptionalCallExpression: isCallOrOptionalCallExpression$3, + isMemberish: isMemberish$2, + isTemplateOnItsOwnLine: isTemplateOnItsOwnLine$2, + isTestCall: isTestCall$3, + iterateCallArgumentsPath: iterateCallArgumentsPath$2 +} = utils$6; +const { + printOptionalToken: printOptionalToken$5, + printFunctionTypeParameters: printFunctionTypeParameters$4 +} = misc; - case "EnumBooleanBody": - case "EnumNumberBody": - case "EnumStringBody": - case "EnumSymbolBody": - { - if (n.type === "EnumSymbolBody" || n.explicitType) { - let type = null; +function printCallExpression(path, options, print) { + const n = path.getValue(); + const isNew = n.type === "NewExpression"; + const isDynamicImport = n.type === "ImportExpression"; + const optional = printOptionalToken$5(path); + const args = getCallArguments$2(n); + + if ( // Dangling comments not handled, all these special cases should has argument #9668 + args.length > 0 && ( // We want to keep CommonJS- and AMD-style require calls, and AMD-style + // define calls, as a unit. + // e.g. `define(["some/lib", (lib) => {` + !isDynamicImport && !isNew && n.callee.type === "Identifier" && (n.callee.name === "require" || n.callee.name === "define") || // Template literals as single arguments + args.length === 1 && isTemplateOnItsOwnLine$2(args[0], options.originalText) || // Keep test declarations on a single line + // e.g. `it('long name', () => {` + !isNew && isTestCall$3(n, path.getParentNode()))) { + const printed = []; + iterateCallArgumentsPath$2(path, argPath => { + printed.push(print(argPath)); + }); + return concat$q([isNew ? "new " : "", path.call(print, "callee"), optional, printFunctionTypeParameters$4(path, options, print), concat$q(["(", join$a(", ", printed), ")"])]); + } // Inline Flow annotation comments following Identifiers in Call nodes need to + // stay with the Identifier. For example: + // + // foo /*:: */(bar); + // + // Here, we ensure that such comments stay between the Identifier and the Callee. - switch (n.type) { - case "EnumBooleanBody": - type = "boolean"; - break; - case "EnumNumberBody": - type = "number"; - break; + const isIdentifierWithFlowAnnotation = (options.parser === "babel" || options.parser === "babel-flow") && n.callee && n.callee.type === "Identifier" && hasFlowAnnotationComment$2(n.callee.trailingComments); - case "EnumStringBody": - type = "string"; - break; + if (isIdentifierWithFlowAnnotation) { + n.callee.trailingComments[0].printed = true; + } // We detect calls on member lookups and possibly print them in a + // special chain format. See `printMemberChain` for more info. - case "EnumSymbolBody": - type = "symbol"; - break; - } - parts.push("of ", type, " "); - } + if (!isDynamicImport && !isNew && isMemberish$2(n.callee) && !path.call(path => needsParens_1(path, options), "callee")) { + return memberChain(path, options, print); + } - if (n.members.length === 0) { - parts.push(group$2(concat$6(["{", comments.printDanglingComments(path, options), softline$2, "}"]))); - } else { - parts.push(group$2(concat$6(["{", indent$3(concat$6([hardline$4, printArrayItems(path, options, "members", print), shouldPrintComma(options) ? "," : ""])), comments.printDanglingComments(path, options, - /* sameIndent */ - true), hardline$4, "}"]))); - } + const contents = concat$q([isNew ? "new " : "", isDynamicImport ? "import" : path.call(print, "callee"), optional, isIdentifierWithFlowAnnotation ? `/*:: ${n.callee.trailingComments[0].value.slice(2).trim()} */` : "", printFunctionTypeParameters$4(path, options, print), callArguments(path, options, print)]); // We group here when the callee is itself a call expression. + // See `isLongCurriedCallExpression` for more info. - return concat$6(parts); - } + if (isDynamicImport || isCallOrOptionalCallExpression$3(n.callee)) { + return group$h(contents); + } - case "EnumBooleanMember": - case "EnumNumberMember": - case "EnumStringMember": - return concat$6([path.call(print, "id"), " = ", typeof n.init === "object" ? path.call(print, "init") : String(n.init)]); + return contents; +} - case "EnumDefaultedMember": - return path.call(print, "id"); +var callExpression = { + printCallExpression +}; - case "FunctionTypeAnnotation": - case "TSFunctionType": - { - // FunctionTypeAnnotation is ambiguous: - // declare function foo(a: B): void; OR - // var A: (a: B) => void; - const parent = path.getParentNode(0); - const parentParent = path.getParentNode(1); - const parentParentParent = path.getParentNode(2); - let isArrowFunctionTypeAnnotation = n.type === "TSFunctionType" || !((parent.type === "ObjectTypeProperty" || parent.type === "ObjectTypeInternalSlot") && !getFlowVariance$1(parent) && !parent.optional && options.locStart(parent) === options.locStart(n) || parent.type === "ObjectTypeCallProperty" || parentParentParent && parentParentParent.type === "DeclareFunction"); - let needsColon = isArrowFunctionTypeAnnotation && (parent.type === "TypeAnnotation" || parent.type === "TSTypeAnnotation"); // Sadly we can't put it inside of FastPath::needsColon because we are - // printing ":" as part of the expression and it would put parenthesis - // around :( +const { + builders: { + concat: concat$r, + join: join$b, + line: line$g, + group: group$i, + indent: indent$l, + ifBreak: ifBreak$b + } +} = document; +const { + hasTrailingComment: hasTrailingComment$5, + hasTrailingLineComment: hasTrailingLineComment$2, + identity: identity$2 +} = utils$6; +const { + getTypeParametersGroupId: getTypeParametersGroupId$2 +} = typeParameters; +const { + printTypeScriptModifiers: printTypeScriptModifiers$1 +} = misc; - const needsParens = needsColon && isArrowFunctionTypeAnnotation && (parent.type === "TypeAnnotation" || parent.type === "TSTypeAnnotation") && parentParent.type === "ArrowFunctionExpression"; +function printInterface(path, options, print) { + const n = path.getValue(); + const parts = []; - if (isObjectTypePropertyAFunction$1(parent, options)) { - isArrowFunctionTypeAnnotation = true; - needsColon = true; - } + if (n.type === "DeclareInterface" || n.declare) { + parts.push("declare "); + } - if (needsParens) { - parts.push("("); - } + if (n.type === "TSInterfaceDeclaration") { + parts.push(n.abstract ? "abstract " : "", printTypeScriptModifiers$1(path, options, print)); + } - parts.push(printFunctionParams(path, print, options, - /* expandArg */ - false, - /* printTypeParams */ - true)); // The returnType is not wrapped in a TypeAnnotation, so the colon - // needs to be added separately. + parts.push("interface"); + const partsGroup = []; + const extendsParts = []; - if (n.returnType || n.predicate || n.typeAnnotation) { - parts.push(isArrowFunctionTypeAnnotation ? " => " : ": ", path.call(print, "returnType"), path.call(print, "predicate"), path.call(print, "typeAnnotation")); - } + if (n.type !== "InterfaceTypeAnnotation") { + partsGroup.push(" ", path.call(print, "id"), path.call(print, "typeParameters")); + } - if (needsParens) { - parts.push(")"); - } + const shouldIndentOnlyHeritageClauses = n.typeParameters && !hasTrailingLineComment$2(n.typeParameters); - return group$2(concat$6(parts)); - } + if (n.extends && n.extends.length !== 0) { + extendsParts.push(shouldIndentOnlyHeritageClauses ? ifBreak$b(" ", line$g, { + groupId: getTypeParametersGroupId$2(n.typeParameters) + }) : line$g, "extends ", (n.extends.length === 1 ? identity$2 : indent$l)(join$b(concat$r([",", line$g]), path.map(print, "extends")))); + } - case "TSRestType": - return concat$6(["...", path.call(print, "typeAnnotation")]); + if (n.id && hasTrailingComment$5(n.id) || n.extends && n.extends.length !== 0) { + const printedExtends = concat$r(extendsParts); - case "TSOptionalType": - return concat$6([path.call(print, "typeAnnotation"), "?"]); + if (shouldIndentOnlyHeritageClauses) { + parts.push(group$i(concat$r(partsGroup.concat(ifBreak$b(indent$l(printedExtends), printedExtends))))); + } else { + parts.push(group$i(indent$l(concat$r(partsGroup.concat(printedExtends))))); + } + } else { + parts.push(...partsGroup, ...extendsParts); + } - case "FunctionTypeParam": - return concat$6([path.call(print, "name"), printOptionalToken(path), n.name ? ": " : "", path.call(print, "typeAnnotation")]); + parts.push(" ", path.call(print, "body")); + return group$i(concat$r(parts)); +} - case "GenericTypeAnnotation": - return concat$6([path.call(print, "id"), path.call(print, "typeParameters")]); +var _interface = { + printInterface +}; - case "DeclareInterface": - case "InterfaceDeclaration": - case "InterfaceTypeAnnotation": - { - if (n.type === "DeclareInterface" || n.declare) { - parts.push("declare "); - } +const { + printComments: printComments$4 +} = comments; +const { + getLast: getLast$8 +} = util; +const { + builders: { + concat: concat$s, + join: join$c, + line: line$h, + softline: softline$g, + group: group$j, + indent: indent$m, + align: align$3, + ifBreak: ifBreak$c + }, + utils: { + normalizeParts: normalizeParts$1 + } +} = document; +const { + hasLeadingOwnLineComment: hasLeadingOwnLineComment$2, + hasTrailingLineComment: hasTrailingLineComment$3, + isBinaryish: isBinaryish$4, + isJSXNode: isJSXNode$6, + shouldFlatten: shouldFlatten$2 +} = utils$6; +/** @typedef {import("../../document").Doc} Doc */ - parts.push("interface"); +let uid = 0; - if (n.type === "DeclareInterface" || n.type === "InterfaceDeclaration") { - parts.push(" ", path.call(print, "id"), path.call(print, "typeParameters")); - } +function printBinaryishExpression(path, options, print) { + const n = path.getValue(); + const parent = path.getParentNode(); + const parentParent = path.getParentNode(1); + const isInsideParenthesis = n !== parent.body && (parent.type === "IfStatement" || parent.type === "WhileStatement" || parent.type === "SwitchStatement" || parent.type === "DoWhileStatement"); + const parts = printBinaryishExpressions(path, print, options, + /* isNested */ + false, isInsideParenthesis); // if ( + // this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft + // ) { + // + // looks super weird, we want to break the children if the parent breaks + // + // if ( + // this.hasPlugin("dynamicImports") && + // this.lookahead().type === tt.parenLeft + // ) { + + if (isInsideParenthesis) { + return concat$s(parts); + } // Break between the parens in + // unaries or in a member or specific call expression, i.e. + // + // ( + // a && + // b && + // c + // ).call() - if (n.extends.length > 0) { - parts.push(group$2(indent$3(concat$6([line$4, "extends ", (n.extends.length === 1 ? identity$2 : indent$3)(join$4(concat$6([",", line$4]), path.map(print, "extends")))])))); - } - parts.push(" ", path.call(print, "body")); - return group$2(concat$6(parts)); - } + if ((parent.type === "CallExpression" || parent.type === "OptionalCallExpression") && parent.callee === n || parent.type === "UnaryExpression" || (parent.type === "MemberExpression" || parent.type === "OptionalMemberExpression") && !parent.computed) { + return group$j(concat$s([indent$m(concat$s([softline$g, concat$s(parts)])), softline$g])); + } // Avoid indenting sub-expressions in some cases where the first sub-expression is already + // indented accordingly. We should indent sub-expressions where the first case isn't indented. - case "ClassImplements": - case "InterfaceExtends": - return concat$6([path.call(print, "id"), path.call(print, "typeParameters")]); - case "TSClassImplements": - return concat$6([path.call(print, "expression"), path.call(print, "typeParameters")]); + const shouldNotIndent = parent.type === "ReturnStatement" || parent.type === "ThrowStatement" || parent.type === "JSXExpressionContainer" && parentParent.type === "JSXAttribute" || n.operator !== "|" && parent.type === "JsExpressionRoot" || n.type !== "NGPipeExpression" && (parent.type === "NGRoot" && options.parser === "__ng_binding" || parent.type === "NGMicrosyntaxExpression" && parentParent.type === "NGMicrosyntax" && parentParent.body.length === 1) || n === parent.body && parent.type === "ArrowFunctionExpression" || n !== parent.body && parent.type === "ForStatement" || parent.type === "ConditionalExpression" && parentParent.type !== "ReturnStatement" && parentParent.type !== "ThrowStatement" && parentParent.type !== "CallExpression" && parentParent.type !== "OptionalCallExpression" || parent.type === "TemplateLiteral"; + const shouldIndentIfInlining = parent.type === "AssignmentExpression" || parent.type === "VariableDeclarator" || parent.type === "ClassProperty" || parent.type === "FieldDefinition" || parent.type === "TSAbstractClassProperty" || parent.type === "ClassPrivateProperty" || parent.type === "ObjectProperty" || parent.type === "Property"; + const samePrecedenceSubExpression = isBinaryish$4(n.left) && shouldFlatten$2(n.operator, n.left.operator); - case "TSIntersectionType": - case "IntersectionTypeAnnotation": - { - const types = path.map(print, "types"); - const result = []; - let wasIndented = false; + if (shouldNotIndent || shouldInlineLogicalExpression(n) && !samePrecedenceSubExpression || !shouldInlineLogicalExpression(n) && shouldIndentIfInlining) { + return group$j(concat$s(parts)); + } - for (let i = 0; i < types.length; ++i) { - if (i === 0) { - result.push(types[i]); - } else if (isObjectType$1(n.types[i - 1]) && isObjectType$1(n.types[i])) { - // If both are objects, don't indent - result.push(concat$6([" & ", wasIndented ? indent$3(types[i]) : types[i]])); - } else if (!isObjectType$1(n.types[i - 1]) && !isObjectType$1(n.types[i])) { - // If no object is involved, go to the next line if it breaks - result.push(indent$3(concat$6([" &", line$4, types[i]]))); - } else { - // If you go from object to non-object or vis-versa, then inline it - if (i > 1) { - wasIndented = true; - } + if (parts.length === 0) { + return ""; + } // If the right part is a JSX node, we include it in a separate group to + // prevent it breaking the whole chain, so we can print the expression like: + // + // foo && bar && ( + // + // + // + // ) + + + const hasJSX = isJSXNode$6(n.right); + const firstGroupIndex = parts.findIndex(part => typeof part !== "string" && part.type === "group"); // Separate the leftmost expression, possibly with its leading comments. + + const headParts = parts.slice(0, firstGroupIndex === -1 ? 1 : firstGroupIndex + 1); + const rest = concat$s(parts.slice(headParts.length, hasJSX ? -1 : undefined)); + const groupId = Symbol("logicalChain-" + ++uid); + const chain = group$j(concat$s([// Don't include the initial expression in the indentation + // level. The first item is guaranteed to be the first + // left-most expression. + ...headParts, indent$m(rest)]), { + id: groupId + }); - result.push(" & ", i > 1 ? indent$3(types[i]) : types[i]); - } - } + if (!hasJSX) { + return chain; + } - return group$2(concat$6(result)); - } + const jsxPart = getLast$8(parts); + return group$j(concat$s([chain, ifBreak$c(indent$m(jsxPart), jsxPart, { + groupId + })])); +} // For binary expressions to be consistent, we need to group +// subsequent operators with the same precedence level under a single +// group. Otherwise they will be nested such that some of them break +// onto new lines but not all. Operators with the same precedence +// level should either all break or not. Because we group them by +// precedence level and the AST is structured based on precedence +// level, things are naturally broken up correctly, i.e. `&&` is +// broken before `+`. - case "TSUnionType": - case "UnionTypeAnnotation": - { - // single-line variation - // A | B | C - // multi-line variation - // | A - // | B - // | C - const parent = path.getParentNode(); // If there's a leading comment, the parent is doing the indentation - const shouldIndent = parent.type !== "TypeParameterInstantiation" && parent.type !== "TSTypeParameterInstantiation" && parent.type !== "GenericTypeAnnotation" && parent.type !== "TSTypeReference" && parent.type !== "TSTypeAssertion" && parent.type !== "TupleTypeAnnotation" && parent.type !== "TSTupleType" && !(parent.type === "FunctionTypeParam" && !parent.name) && !((parent.type === "TypeAlias" || parent.type === "VariableDeclarator" || parent.type === "TSTypeAliasDeclaration") && hasLeadingOwnLineComment$1(options.originalText, n, options)); // { - // a: string - // } | null | void - // should be inlined and not be printed in the multi-line variant +function printBinaryishExpressions(path, print, options, isNested, isInsideParenthesis) { + /** @type{Doc[]} */ + let parts = []; + const node = path.getValue(); // We treat BinaryExpression and LogicalExpression nodes the same. - const shouldHug = shouldHugType(n); // We want to align the children but without its comment, so it looks like - // | child1 - // // comment - // | child2 + if (isBinaryish$4(node)) { + // Put all operators with the same precedence level in the same + // group. The reason we only need to do this with the `left` + // expression is because given an expression like `1 + 2 - 3`, it + // is always parsed like `((1 + 2) - 3)`, meaning the `left` side + // is where the rest of the expression will exist. Binary + // expressions on the right side mean they have a difference + // precedence level and should be treated as a separate group, so + // print them normally. (This doesn't hold for the `**` operator, + // which is unique in that it is right-associative.) + if (shouldFlatten$2(node.operator, node.left.operator)) { + // Flatten them out by recursively calling this function. + parts = parts.concat(path.call(left => printBinaryishExpressions(left, print, options, + /* isNested */ + true, isInsideParenthesis), "left")); + } else { + parts.push(group$j(path.call(print, "left"))); + } - const printed = path.map(typePath => { - let printedType = typePath.call(print); + const shouldInline = shouldInlineLogicalExpression(node); + const lineBeforeOperator = (node.operator === "|>" || node.type === "NGPipeExpression" || node.operator === "|" && options.parser === "__vue_expression") && !hasLeadingOwnLineComment$2(options.originalText, node.right); + const operator = node.type === "NGPipeExpression" ? "|" : node.operator; + const rightSuffix = node.type === "NGPipeExpression" && node.arguments.length !== 0 ? group$j(indent$m(concat$s([softline$g, ": ", join$c(concat$s([softline$g, ":", ifBreak$c(" ")]), path.map(print, "arguments").map(arg => align$3(2, group$j(arg))))]))) : ""; + const right = shouldInline ? concat$s([operator, " ", path.call(print, "right"), rightSuffix]) : concat$s([lineBeforeOperator ? line$h : "", operator, lineBeforeOperator ? " " : line$h, path.call(print, "right"), rightSuffix]); // If there's only a single binary expression, we want to create a group + // in order to avoid having a small right part like -1 be on its own line. - if (!shouldHug) { - printedType = align$1(2, printedType); - } + const parent = path.getParentNode(); + const shouldBreak = hasTrailingLineComment$3(node.left); + const shouldGroup = shouldBreak || !(isInsideParenthesis && node.type === "LogicalExpression") && parent.type !== node.type && node.left.type !== node.type && node.right.type !== node.type; + parts.push(lineBeforeOperator ? "" : " ", shouldGroup ? group$j(right, { + shouldBreak + }) : right); // The root comments are already printed, but we need to manually print + // the other ones since we don't call the normal print on BinaryExpression, + // only for the left and right parts - return comments.printComments(typePath, () => printedType, options); - }, "types"); + if (isNested && node.comments) { + parts = normalizeParts$1(printComments$4(path, () => concat$s(parts), options).parts); + } + } else { + // Our stopping case. Simply print the node normally. + parts.push(group$j(path.call(print))); + } - if (shouldHug) { - return join$4(" | ", printed); - } + return parts; +} - const shouldAddStartLine = shouldIndent && !hasLeadingOwnLineComment$1(options.originalText, n, options); - const code = concat$6([ifBreak$1(concat$6([shouldAddStartLine ? line$4 : "", "| "])), join$4(concat$6([line$4, "| "]), printed)]); +function shouldInlineLogicalExpression(node) { + if (node.type !== "LogicalExpression") { + return false; + } - if (needsParens_1(path, options)) { - return group$2(concat$6([indent$3(code), softline$2])); - } + if (node.right.type === "ObjectExpression" && node.right.properties.length !== 0) { + return true; + } - if (parent.type === "TupleTypeAnnotation" && parent.types.length > 1 || parent.type === "TSTupleType" && parent.elementTypes.length > 1) { - return group$2(concat$6([indent$3(concat$6([ifBreak$1(concat$6(["(", softline$2])), code])), softline$2, ifBreak$1(")")])); - } + if (node.right.type === "ArrayExpression" && node.right.elements.length !== 0) { + return true; + } - return group$2(shouldIndent ? indent$3(code) : code); - } + if (isJSXNode$6(node.right)) { + return true; + } - case "NullableTypeAnnotation": - return concat$6(["?", path.call(print, "typeAnnotation")]); + return false; +} - case "TSNullKeyword": - case "NullLiteralTypeAnnotation": - return "null"; +var binaryish = { + printBinaryishExpression, + shouldInlineLogicalExpression +}; - case "ThisTypeAnnotation": - return "this"; +const { + builders: { + concat: concat$t, + line: line$i, + group: group$k, + indent: indent$n + } +} = document; +const { + hasLeadingOwnLineComment: hasLeadingOwnLineComment$3, + isBinaryish: isBinaryish$5, + isMemberExpressionChain: isMemberExpressionChain$1, + isStringLiteral: isStringLiteral$3 +} = utils$6; +const { + shouldInlineLogicalExpression: shouldInlineLogicalExpression$1 +} = binaryish; - case "NumberTypeAnnotation": - return "number"; +function printAssignment(leftNode, printedLeft, operator, rightNode, printedRight, options) { + if (!rightNode) { + return printedLeft; + } - case "SymbolTypeAnnotation": - return "symbol"; + const printed = printAssignmentRight(leftNode, rightNode, printedRight, options); + return group$k(concat$t([printedLeft, operator, printed])); +} - case "ObjectTypeCallProperty": - if (n.static) { - parts.push("static "); - } +function printAssignmentExpression(path, options, print) { + const n = path.getValue(); + return printAssignment(n.left, path.call(print, "left"), concat$t([" ", n.operator]), n.right, path.call(print, "right"), options); +} - parts.push(path.call(print, "value")); - return concat$6(parts); +function printVariableDeclarator(path, options, print) { + const n = path.getValue(); + return printAssignment(n.id, path.call(print, "id"), " =", n.init, n.init && path.call(print, "init"), options); +} - case "ObjectTypeIndexer": - { - const variance = getFlowVariance$1(n); - return concat$6([variance || "", "[", path.call(print, "id"), n.id ? ": " : "", path.call(print, "key"), "]: ", path.call(print, "value")]); - } +function printAssignmentRight(leftNode, rightNode, printedRight, options) { + if (hasLeadingOwnLineComment$3(options.originalText, rightNode)) { + return indent$n(concat$t([line$i, printedRight])); + } - case "ObjectTypeProperty": - { - const variance = getFlowVariance$1(n); - let modifier = ""; + const canBreak = isBinaryish$5(rightNode) && !shouldInlineLogicalExpression$1(rightNode) || rightNode.type === "ConditionalExpression" && isBinaryish$5(rightNode.test) && !shouldInlineLogicalExpression$1(rightNode.test) || rightNode.type === "StringLiteralTypeAnnotation" || rightNode.type === "ClassExpression" && rightNode.decorators && rightNode.decorators.length || (leftNode.type === "Identifier" || isStringLiteral$3(leftNode) || leftNode.type === "MemberExpression") && (isStringLiteral$3(rightNode) || isMemberExpressionChain$1(rightNode)) && // do not put values on a separate line from the key in json + options.parser !== "json" && options.parser !== "json5" || rightNode.type === "SequenceExpression"; - if (n.proto) { - modifier = "proto "; - } else if (n.static) { - modifier = "static "; - } + if (canBreak) { + return group$k(indent$n(concat$t([line$i, printedRight]))); + } - return concat$6([modifier, isGetterOrSetter$1(n) ? n.kind + " " : "", variance || "", printPropertyKey(path, options, print), printOptionalToken(path), isFunctionNotation$1(n, options) ? "" : ": ", path.call(print, "value")]); - } + return concat$t([" ", printedRight]); +} - case "QualifiedTypeIdentifier": - return concat$6([path.call(print, "qualification"), ".", path.call(print, "id")]); +var assignment = { + printVariableDeclarator, + printAssignmentExpression, + printAssignment, + printAssignmentRight +}; - case "StringLiteralTypeAnnotation": - return nodeStr(n, options); +const { + isNextLineEmpty: isNextLineEmpty$7 +} = util; +const { + builders: { + concat: concat$u, + join: join$d, + hardline: hardline$h + } +} = document; +const { + classChildNeedsASIProtection: classChildNeedsASIProtection$1, + classPropMayCauseASIProblems: classPropMayCauseASIProblems$1, + getLeftSidePathName: getLeftSidePathName$2, + hasNakedLeftSide: hasNakedLeftSide$2, + isJSXNode: isJSXNode$7, + isLastStatement: isLastStatement$1, + isTheOnlyJSXElementInMarkdown: isTheOnlyJSXElementInMarkdown$1 +} = utils$6; +const { + locEnd: locEnd$b +} = loc; +const { + shouldPrintParamsWithoutParens: shouldPrintParamsWithoutParens$1 +} = _function; +/** @typedef {import("../../document").Doc} Doc */ + +function printStatement({ + path, + index, + bodyNode, + isClass +}, options, print) { + const node = path.getValue(); // Just in case the AST has been modified to contain falsy + // "statements," it's safer simply to skip them. - case "NumberLiteralTypeAnnotation": - assert$1.strictEqual(typeof n.value, "number"); + /* istanbul ignore if */ - if (n.extra != null) { - return printNumber$1(n.extra.raw); - } + if (!node) { + return; + } // Skip printing EmptyStatement nodes to avoid leaving stray + // semicolons lying around. - return printNumber$1(n.raw); - case "StringTypeAnnotation": - return "string"; + if (node.type === "EmptyStatement") { + return; + } - case "DeclareTypeAlias": - case "TypeAlias": - { - if (n.type === "DeclareTypeAlias" || n.declare) { - parts.push("declare "); - } + const printed = print(path); + const text = options.originalText; + const parts = []; // in no-semi mode, prepend statement with semicolon if it might break ASI + // don't prepend the only JSX element in a program with semicolon + + if (!options.semi && !isClass && !isTheOnlyJSXElementInMarkdown$1(options, path) && statementNeedsASIProtection(path, options)) { + if (node.comments && node.comments.some(comment => comment.leading)) { + parts.push(print(path, { + needsSemi: true + })); + } else { + parts.push(";", printed); + } + } else { + parts.push(printed); + } - const printed = printAssignmentRight(n.id, n.right, path.call(print, "right"), options); - parts.push("type ", path.call(print, "id"), path.call(print, "typeParameters"), " =", printed, semi); - return group$2(concat$6(parts)); - } + if (!options.semi && isClass) { + if (classPropMayCauseASIProblems$1(path)) { + parts.push(";"); + } else if (node.type === "ClassProperty" || node.type === "FieldDefinition") { + const nextChild = bodyNode.body[index + 1]; - case "TypeCastExpression": - { - return concat$6(["(", path.call(print, "expression"), printTypeAnnotation(path, options, print), ")"]); + if (classChildNeedsASIProtection$1(nextChild)) { + parts.push(";"); } + } + } - case "TypeParameterDeclaration": - case "TypeParameterInstantiation": - { - const value = path.getValue(); - const commentStart = value.range ? options.originalText.slice(0, value.range[0]).lastIndexOf("/*") : -1; // As noted in the TypeCastExpression comments above, we're able to use a normal whitespace regex here - // because we know for sure that this is a type definition. + if (isNextLineEmpty$7(text, node, locEnd$b) && !isLastStatement$1(path)) { + parts.push(hardline$h); + } - const commentSyntax = commentStart >= 0 && options.originalText.slice(commentStart).match(/^\/\*\s*::/); + return concat$u(parts); +} - if (commentSyntax) { - return concat$6(["/*:: ", printTypeParameters(path, options, print, "params"), " */"]); - } +function printStatementSequence(path, options, print) { + const bodyNode = path.getNode(); + const isClass = bodyNode.type === "ClassBody"; + const printed = path.map((statementPath, index) => printStatement({ + path, + index, + bodyNode, + isClass + }, options, print)).filter(Boolean); + return join$d(hardline$h, printed); +} - return printTypeParameters(path, options, print, "params"); - } +function statementNeedsASIProtection(path, options) { + const node = path.getNode(); - case "TSTypeParameterDeclaration": - case "TSTypeParameterInstantiation": - return printTypeParameters(path, options, print, "params"); + if (node.type !== "ExpressionStatement") { + return false; + } - case "TSTypeParameter": - case "TypeParameter": - { - const parent = path.getParentNode(); + return path.call(childPath => expressionNeedsASIProtection(childPath, options), "expression"); +} - if (parent.type === "TSMappedType") { - parts.push("[", path.call(print, "name")); +function expressionNeedsASIProtection(path, options) { + const node = path.getValue(); + const maybeASIProblem = needsParens_1(path, options) || node.type === "ParenthesizedExpression" || node.type === "TypeCastExpression" || node.type === "ArrowFunctionExpression" && !shouldPrintParamsWithoutParens$1(path, options) || node.type === "ArrayExpression" || node.type === "ArrayPattern" || node.type === "UnaryExpression" && node.prefix && (node.operator === "+" || node.operator === "-") || node.type === "TemplateLiteral" || node.type === "TemplateElement" || isJSXNode$7(node) || node.type === "BindExpression" && !node.object || node.type === "RegExpLiteral" || node.type === "Literal" && node.pattern || node.type === "Literal" && node.regex; - if (n.constraint) { - parts.push(" in ", path.call(print, "constraint")); - } + if (maybeASIProblem) { + return true; + } - parts.push("]"); - return concat$6(parts); - } + if (!hasNakedLeftSide$2(node)) { + return false; + } - const variance = getFlowVariance$1(n); + return path.call(childPath => expressionNeedsASIProtection(childPath, options), ...getLeftSidePathName$2(path, node)); +} - if (variance) { - parts.push(variance); - } +var statement = { + printStatementSequence +}; - parts.push(path.call(print, "name")); +const { + printDanglingComments: printDanglingComments$9 +} = comments; +const { + isNextLineEmpty: isNextLineEmpty$8 +} = util; +const { + builders: { + concat: concat$v, + hardline: hardline$i, + indent: indent$o + } +} = document; +const { + hasDanglingComments: hasDanglingComments$6 +} = utils$6; +const { + locEnd: locEnd$c +} = loc; +const { + printStatementSequence: printStatementSequence$1 +} = statement; +/** @typedef {import("../../document").Doc} Doc */ - if (n.bound) { - parts.push(": "); - parts.push(path.call(print, "bound")); - } +function printBlock(path, options, print) { + const n = path.getValue(); + const parts = []; + const semi = options.semi ? ";" : ""; + const naked = path.call(bodyPath => { + return printStatementSequence$1(bodyPath, options, print); + }, "body"); - if (n.constraint) { - parts.push(" extends ", path.call(print, "constraint")); - } + if (n.type === "StaticBlock") { + parts.push("static "); + } - if (n.default) { - parts.push(" = ", path.call(print, "default")); - } // Keep comma if the file extension is .tsx and - // has one type parameter that isn't extend with any types. - // Because, otherwise formatted result will be invalid as tsx. + const hasContent = n.body.some(node => node.type !== "EmptyStatement"); + const hasDirectives = n.directives && n.directives.length > 0; + const parent = path.getParentNode(); + const parentParent = path.getParentNode(1); + if (!hasContent && !hasDirectives && !hasDanglingComments$6(n) && (parent.type === "ArrowFunctionExpression" || parent.type === "FunctionExpression" || parent.type === "FunctionDeclaration" || parent.type === "ObjectMethod" || parent.type === "ClassMethod" || parent.type === "ClassPrivateMethod" || parent.type === "ForStatement" || parent.type === "WhileStatement" || parent.type === "DoWhileStatement" || parent.type === "DoExpression" || parent.type === "CatchClause" && !parentParent.finalizer || parent.type === "TSModuleDeclaration" || parent.type === "TSDeclareFunction" || n.type === "StaticBlock")) { + return concat$v([...parts, "{}"]); + } - const grandParent = path.getNode(2); + parts.push("{"); // Babel 6 - if (parent.params && parent.params.length === 1 && isTSXFile$1(options) && !n.constraint && grandParent.type === "ArrowFunctionExpression") { - parts.push(","); - } + if (hasDirectives) { + path.each(childPath => { + parts.push(indent$o(concat$v([hardline$i, print(childPath), semi]))); - return concat$6(parts); + if (isNextLineEmpty$8(options.originalText, childPath.getValue(), locEnd$c)) { + parts.push(hardline$i); } + }, "directives"); + } - case "TypeofTypeAnnotation": - return concat$6(["typeof ", path.call(print, "argument")]); + if (hasContent) { + parts.push(indent$o(concat$v([hardline$i, naked]))); + } - case "VoidTypeAnnotation": - return "void"; + parts.push(printDanglingComments$9(path, options)); + parts.push(hardline$i, "}"); + return concat$v(parts); +} - case "InferredPredicate": - return "%checks"; - // Unhandled types below. If encountered, nodes of these types should - // be either left alone or desugared into AST types that are fully - // supported by the pretty-printer. +var block = { + printBlock +}; - case "DeclaredPredicate": - return concat$6(["%checks(", path.call(print, "value"), ")"]); +const { + hasNewline: hasNewline$6 +} = util; +const { + builders: { + concat: concat$w, + join: join$e, + hardline: hardline$j + } +} = document; +const { + isLineComment: isLineComment$2, + isBlockComment: isBlockComment$8 +} = utils$6; +const { + locStart: locStart$7, + locEnd: locEnd$d +} = loc; - case "TSAbstractKeyword": - return "abstract"; +function printComment$1(commentPath, options) { + const comment = commentPath.getValue(); - case "TSAnyKeyword": - return "any"; + if (isLineComment$2(comment)) { + // Supports `//`, `#!`, `` + return options.originalText.slice(locStart$7(comment), locEnd$d(comment)).trimEnd(); + } - case "TSAsyncKeyword": - return "async"; + if (isBlockComment$8(comment)) { + if (isIndentableBlockComment(comment)) { + const printed = printIndentableBlockComment(comment); // We need to prevent an edge case of a previous trailing comment + // printed as a `lineSuffix` which causes the comments to be + // interleaved. See https://github.com/prettier/prettier/issues/4412 - case "TSBooleanKeyword": - return "boolean"; + if (comment.trailing && !hasNewline$6(options.originalText, locStart$7(comment), { + backwards: true + })) { + return concat$w([hardline$j, printed]); + } - case "TSBigIntKeyword": - return "bigint"; + return printed; + } - case "TSConstKeyword": - return "const"; + const commentEnd = locEnd$d(comment); + const isInsideFlowComment = options.originalText.slice(commentEnd - 3, commentEnd) === "*-/"; + return "/*" + comment.value + (isInsideFlowComment ? "*-/" : "*/"); + } + /* istanbul ignore next */ - case "TSDeclareKeyword": - return "declare"; - case "TSExportKeyword": - return "export"; + throw new Error("Not a comment: " + JSON.stringify(comment)); +} - case "TSNeverKeyword": - return "never"; +function isIndentableBlockComment(comment) { + // If the comment has multiple lines and every line starts with a star + // we can fix the indentation of each line. The stars in the `/*` and + // `*/` delimiters are not included in the comment value, so add them + // back first. + const lines = `*${comment.value}*`.split("\n"); + return lines.length > 1 && lines.every(line => line.trim()[0] === "*"); +} - case "TSNumberKeyword": - return "number"; +function printIndentableBlockComment(comment) { + const lines = comment.value.split("\n"); + return concat$w(["/*", join$e(hardline$j, lines.map((line, index) => index === 0 ? line.trimEnd() : " " + (index < lines.length - 1 ? line.trim() : line.trimStart()))), "*/"]); +} - case "TSObjectKeyword": - return "object"; +var comment = { + printComment: printComment$1 +}; - case "TSProtectedKeyword": - return "protected"; +/** @typedef {import("../document").Doc} Doc */ - case "TSPrivateKeyword": - return "private"; +/** @type {import("assert")} */ +// TODO(azz): anything that imports from main shouldn't be in a `language-*` dir. - case "TSPublicKeyword": - return "public"; - case "TSReadonlyKeyword": - return "readonly"; +const { + hasNewline: hasNewline$7, + hasNewlineInRange: hasNewlineInRange$6, + getLast: getLast$9, + printString: printString$2, + printNumber: printNumber$2, + isNextLineEmpty: isNextLineEmpty$9 +} = util; +const { + builders: { + concat: concat$x, + join: join$f, + line: line$j, + hardline: hardline$k, + softline: softline$h, + literalline: literalline$3, + group: group$l, + indent: indent$p, + align: align$4, + conditionalGroup: conditionalGroup$4, + ifBreak: ifBreak$d + }, + utils: { + isEmpty: isEmpty$2 + } +} = document; +const { + insertPragma: insertPragma$1 +} = pragma; +const { + printHtmlBinding: printHtmlBinding$1, + isVueEventBindingExpression: isVueEventBindingExpression$1 +} = htmlBinding; +const { + getFunctionParameters: getFunctionParameters$6, + getCallArguments: getCallArguments$3, + getParentExportDeclaration: getParentExportDeclaration$2, + getTypeScriptMappedTypeModifier: getTypeScriptMappedTypeModifier$1, + hasDanglingComments: hasDanglingComments$7, + hasFlowShorthandAnnotationComment: hasFlowShorthandAnnotationComment$3, + hasLeadingOwnLineComment: hasLeadingOwnLineComment$4, + hasNewlineBetweenOrAfterDecorators: hasNewlineBetweenOrAfterDecorators$2, + hasNgSideEffect: hasNgSideEffect$1, + hasPrettierIgnore: hasPrettierIgnore$1, + hasTrailingComment: hasTrailingComment$6, + isExportDeclaration: isExportDeclaration$1, + isFunctionNotation: isFunctionNotation$1, + isGetterOrSetter: isGetterOrSetter$1, + isLiteral: isLiteral$2, + isNgForOf: isNgForOf$1, + isObjectType: isObjectType$3, + isObjectTypePropertyAFunction: isObjectTypePropertyAFunction$2, + isTheOnlyJSXElementInMarkdown: isTheOnlyJSXElementInMarkdown$2, + isTSXFile: isTSXFile$1, + isBlockComment: isBlockComment$9, + needsHardlineAfterDanglingComment: needsHardlineAfterDanglingComment$2, + rawText: rawText$3, + shouldPrintComma: shouldPrintComma$8 +} = utils$6; +const { + locStart: locStart$8, + locEnd: locEnd$e +} = loc; +const { + printOptionalToken: printOptionalToken$6, + printBindExpressionCallee: printBindExpressionCallee$2, + printTypeScriptModifiers: printTypeScriptModifiers$2, + printDecorators: printDecorators$2, + printFlowDeclaration: printFlowDeclaration$1, + adjustClause: adjustClause$1 +} = misc; +const { + printImportDeclaration: printImportDeclaration$1, + printExportDeclaration: printExportDeclaration$1, + printExportAllDeclaration: printExportAllDeclaration$1, + printModuleSpecifier: printModuleSpecifier$1 +} = module$3; +const { + printFunctionParameters: printFunctionParameters$2 +} = functionParameters; +const { + printTemplateLiteral: printTemplateLiteral$1 +} = templateLiteral; +const { + printArray: printArray$1, + printArrayItems: printArrayItems$1 +} = array$3; +const { + printObject: printObject$1 +} = object; +const { + printTypeAnnotation: printTypeAnnotation$3, + shouldHugType: shouldHugType$3 +} = typeAnnotation; +const { + printJsxElement: printJsxElement$1, + printJsxAttribute: printJsxAttribute$1, + printJsxOpeningElement: printJsxOpeningElement$1, + printJsxClosingElement: printJsxClosingElement$1, + printJsxOpeningClosingFragment: printJsxOpeningClosingFragment$1, + printJsxExpressionContainer: printJsxExpressionContainer$1, + printJsxEmptyExpression: printJsxEmptyExpression$1, + printJsxSpreadAttribute: printJsxSpreadAttribute$1, + printJsxSpreadChild +} = jsx; +const { + printClass: printClass$1, + printClassMethod: printClassMethod$1 +} = _class; +const { + printTypeParameters: printTypeParameters$1 +} = typeParameters; +const { + printPropertyKey: printPropertyKey$2 +} = property$1; +const { + printFunctionDeclaration: printFunctionDeclaration$1, + printArrowFunctionExpression: printArrowFunctionExpression$1, + printMethod: printMethod$2, + printReturnAndThrowArgument: printReturnAndThrowArgument$1 +} = _function; +const { + printCallExpression: printCallExpression$1 +} = callExpression; +const { + printInterface: printInterface$1 +} = _interface; +const { + printVariableDeclarator: printVariableDeclarator$1, + printAssignmentExpression: printAssignmentExpression$1, + printAssignment: printAssignment$1, + printAssignmentRight: printAssignmentRight$1 +} = assignment; +const { + printBinaryishExpression: printBinaryishExpression$1 +} = binaryish; +const { + printStatementSequence: printStatementSequence$2 +} = statement; +const { + printMemberExpression: printMemberExpression$1 +} = member; +const { + printBlock: printBlock$1 +} = block; +const { + printComment: printComment$2 +} = comment; - case "TSSymbolKeyword": - return "symbol"; +function genericPrint(path, options, printPath, args) { + const node = path.getValue(); + let needsParens = false; + const linesWithoutParens = printPathNoParens(path, options, printPath, args); - case "TSStaticKeyword": - return "static"; + if (!node || isEmpty$2(linesWithoutParens)) { + return linesWithoutParens; + } - case "TSStringKeyword": - return "string"; + const parentExportDecl = getParentExportDeclaration$2(path); + const decorators = []; - case "TSUndefinedKeyword": - return "undefined"; + if (node.type === "ClassMethod" || node.type === "ClassPrivateMethod" || node.type === "ClassProperty" || node.type === "FieldDefinition" || node.type === "TSAbstractClassProperty" || node.type === "ClassPrivateProperty" || node.type === "MethodDefinition" || node.type === "TSAbstractMethodDefinition" || node.type === "TSDeclareMethod") ; else if (node.decorators && node.decorators.length > 0 && // If the parent node is an export declaration and the decorator + // was written before the export, the export will be responsible + // for printing the decorators. + !(parentExportDecl && locStart$8(parentExportDecl, { + ignoreDecorators: true + }) > locStart$8(node.decorators[0]))) { + const shouldBreak = node.type === "ClassExpression" || node.type === "ClassDeclaration" || hasNewlineBetweenOrAfterDecorators$2(node, options); + const separator = shouldBreak ? hardline$k : line$j; + path.each(decoratorPath => { + let decorator = decoratorPath.getValue(); - case "TSUnknownKeyword": - return "unknown"; + if (decorator.expression) { + decorator = decorator.expression; + } else { + decorator = decorator.callee; + } - case "TSVoidKeyword": - return "void"; + decorators.push(printPath(decoratorPath), separator); + }, "decorators"); + + if (parentExportDecl) { + decorators.unshift(hardline$k); + } + } else if (isExportDeclaration$1(node) && node.declaration && node.declaration.decorators && node.declaration.decorators.length > 0 && // Only print decorators here if they were written before the export, + // otherwise they are printed by the node.declaration + locStart$8(node, { + ignoreDecorators: true + }) > locStart$8(node.declaration.decorators[0])) { + // Export declarations are responsible for printing any decorators + // that logically apply to node.declaration. + path.each(decoratorPath => { + const decorator = decoratorPath.getValue(); + const prefix = decorator.type === "Decorator" ? "" : "@"; + decorators.push(prefix, printPath(decoratorPath), hardline$k); + }, "declaration", "decorators"); + } else { + // Nodes with decorators can't have parentheses, so we can avoid + // computing pathNeedsParens() except in this case. + needsParens = needsParens_1(path, options); + } + + const parts = []; + + if (needsParens) { + parts.unshift("("); + } + + parts.push(linesWithoutParens); + + if (needsParens) { + const node = path.getValue(); + + if (hasFlowShorthandAnnotationComment$3(node)) { + parts.push(" /*"); + parts.push(node.trailingComments[0].value.trimStart()); + parts.push("*/"); + node.trailingComments[0].printed = true; + } - case "TSAsExpression": - return concat$6([path.call(print, "expression"), " as ", path.call(print, "typeAnnotation")]); + parts.push(")"); + } - case "TSArrayType": - return concat$6([path.call(print, "elementType"), "[]"]); + if (decorators.length > 0) { + return group$l(concat$x(decorators.concat(parts))); + } - case "TSPropertySignature": - { - if (n.export) { - parts.push("export "); - } + return concat$x(parts); +} - if (n.accessibility) { - parts.push(n.accessibility + " "); - } +function printPathNoParens(path, options, print, args) { + const n = path.getValue(); + const semi = options.semi ? ";" : ""; - if (n.static) { - parts.push("static "); - } + if (!n) { + return ""; + } - if (n.readonly) { - parts.push("readonly "); - } + if (typeof n === "string") { + return n; + } - parts.push(printPropertyKey(path, options, print), printOptionalToken(path)); + const htmlBinding = printHtmlBinding$1(path, options, print); - if (n.typeAnnotation) { - parts.push(": "); - parts.push(path.call(print, "typeAnnotation")); - } // This isn't valid semantically, but it's in the AST so we can print it. + if (htmlBinding) { + return htmlBinding; + } + /** @type{Doc[]} */ - if (n.initializer) { - parts.push(" = ", path.call(print, "initializer")); - } + let parts = []; - return concat$6(parts); - } + switch (n.type) { + case "JsExpressionRoot": + return path.call(print, "node"); - case "TSParameterProperty": - if (n.accessibility) { - parts.push(n.accessibility + " "); - } + case "JsonRoot": + return concat$x([path.call(print, "node"), hardline$k]); - if (n.export) { - parts.push("export "); + case "File": + // Print @babel/parser's InterpreterDirective here so that + // leading comments on the `Program` node get printed after the hashbang. + if (n.program && n.program.interpreter) { + parts.push(path.call(programPath => programPath.call(print, "interpreter"), "program")); } - if (n.static) { - parts.push("static "); - } + parts.push(path.call(print, "program")); + return concat$x(parts); - if (n.readonly) { - parts.push("readonly "); - } + case "Program": + { + const hasContents = !n.body.every(({ + type + }) => type === "EmptyStatement") || n.comments; // Babel 6 - parts.push(path.call(print, "parameter")); - return concat$6(parts); + if (n.directives) { + const directivesCount = n.directives.length; + path.each((childPath, index) => { + parts.push(print(childPath), semi, hardline$k); - case "TSTypeReference": - return concat$6([path.call(print, "typeName"), printTypeParameters(path, options, print, "typeParameters")]); + if ((index < directivesCount - 1 || hasContents) && isNextLineEmpty$9(options.originalText, childPath.getValue(), locEnd$e)) { + parts.push(hardline$k); + } + }, "directives"); + } - case "TSTypeQuery": - return concat$6(["typeof ", path.call(print, "exprName")]); + parts.push(path.call(bodyPath => { + return printStatementSequence$2(bodyPath, options, print); + }, "body")); + parts.push(comments.printDanglingComments(path, options, + /* sameIndent */ + true)); // Only force a trailing newline if there were any contents. - case "TSIndexSignature": - { - const parent = path.getParentNode(); // The typescript parser accepts multiple parameters here. If you're - // using them, it makes sense to have a trailing comma. But if you - // aren't, this is more like a computed property name than an array. - // So we leave off the trailing comma when there's just one parameter. + if (hasContents) { + parts.push(hardline$k); + } - const trailingComma = n.parameters.length > 1 ? ifBreak$1(shouldPrintComma(options) ? "," : "") : ""; - const parametersGroup = group$2(concat$6([indent$3(concat$6([softline$2, join$4(concat$6([", ", softline$2]), path.map(print, "parameters"))])), trailingComma, softline$2])); - return concat$6([n.export ? "export " : "", n.accessibility ? concat$6([n.accessibility, " "]) : "", n.static ? "static " : "", n.readonly ? "readonly " : "", "[", n.parameters ? parametersGroup : "", n.typeAnnotation ? "]: " : "]", n.typeAnnotation ? path.call(print, "typeAnnotation") : "", parent.type === "ClassBody" ? semi : ""]); + return concat$x(parts); } + // Babel extension. - case "TSTypePredicate": - return concat$6([n.asserts ? "asserts " : "", path.call(print, "parameterName"), n.typeAnnotation ? concat$6([" is ", path.call(print, "typeAnnotation")]) : ""]); + case "EmptyStatement": + return ""; - case "TSNonNullExpression": - return concat$6([path.call(print, "expression"), "!"]); + case "ExpressionStatement": + // Detect Flow and TypeScript directives + if (n.directive) { + return concat$x([nodeStr(n.expression, options, true), semi]); + } - case "TSThisType": - return "this"; + if (options.parser === "__vue_event_binding") { + const parent = path.getParentNode(); - case "TSImportType": - return concat$6([!n.isTypeOf ? "" : "typeof ", "import(", path.call(print, n.parameter ? "parameter" : "argument"), ")", !n.qualifier ? "" : concat$6([".", path.call(print, "qualifier")]), printTypeParameters(path, options, print, "typeParameters")]); + if (parent.type === "Program" && parent.body.length === 1 && parent.body[0] === n) { + return concat$x([path.call(print, "expression"), isVueEventBindingExpression$1(n.expression) ? ";" : ""]); + } + } // Do not append semicolon after the only JSX element in a program - case "TSLiteralType": - return path.call(print, "literal"); - case "TSIndexedAccessType": - return concat$6([path.call(print, "objectType"), "[", path.call(print, "indexType"), "]"]); + return concat$x([path.call(print, "expression"), isTheOnlyJSXElementInMarkdown$2(options, path) ? "" : semi]); + // Babel non-standard node. Used for Closure-style type casts. See postprocess.js. - case "TSConstructSignatureDeclaration": - case "TSCallSignatureDeclaration": - case "TSConstructorType": + case "ParenthesizedExpression": { - if (n.type !== "TSCallSignatureDeclaration") { - parts.push("new "); - } - - parts.push(group$2(printFunctionParams(path, print, options, - /* expandArg */ - false, - /* printTypeParams */ - true))); + const shouldHug = !n.expression.comments; - if (n.returnType || n.typeAnnotation) { - const isType = n.type === "TSConstructorType"; - parts.push(isType ? " => " : ": ", path.call(print, "returnType"), path.call(print, "typeAnnotation")); + if (shouldHug) { + return concat$x(["(", path.call(print, "expression"), ")"]); } - return concat$6(parts); + return group$l(concat$x(["(", indent$p(concat$x([softline$h, path.call(print, "expression")])), softline$h, ")"])); } - case "TSTypeOperator": - return concat$6([n.operator, " ", path.call(print, "typeAnnotation")]); + case "AssignmentExpression": + return printAssignmentExpression$1(path, options, print); - case "TSMappedType": - { - const shouldBreak = hasNewlineInRange$3(options.originalText, options.locStart(n), options.locEnd(n)); - return group$2(concat$6(["{", indent$3(concat$6([options.bracketSpacing ? line$4 : softline$2, n.readonly ? concat$6([getTypeScriptMappedTypeModifier$1(n.readonly, "readonly"), " "]) : "", printTypeScriptModifiers(path, options, print), path.call(print, "typeParameter"), n.optional ? getTypeScriptMappedTypeModifier$1(n.optional, "?") : "", n.typeAnnotation ? ": " : "", path.call(print, "typeAnnotation"), ifBreak$1(semi, "")])), comments.printDanglingComments(path, options, - /* sameIndent */ - true), options.bracketSpacing ? line$4 : softline$2, "}"]), { - shouldBreak - }); - } + case "VariableDeclarator": + return printVariableDeclarator$1(path, options, print); - case "TSMethodSignature": - parts.push(n.accessibility ? concat$6([n.accessibility, " "]) : "", n.export ? "export " : "", n.static ? "static " : "", n.readonly ? "readonly " : "", n.computed ? "[" : "", path.call(print, "key"), n.computed ? "]" : "", printOptionalToken(path), printFunctionParams(path, print, options, - /* expandArg */ - false, - /* printTypeParams */ - true)); + case "BinaryExpression": + case "LogicalExpression": + case "NGPipeExpression": + return printBinaryishExpression$1(path, options, print); - if (n.returnType || n.typeAnnotation) { - parts.push(": ", path.call(print, "returnType"), path.call(print, "typeAnnotation")); - } + case "AssignmentPattern": + return concat$x([path.call(print, "left"), " = ", path.call(print, "right")]); - return group$2(concat$6(parts)); + case "TSTypeAssertion": + { + const shouldBreakAfterCast = !(n.expression.type === "ArrayExpression" || n.expression.type === "ObjectExpression"); + const castGroup = group$l(concat$x(["<", indent$p(concat$x([softline$h, path.call(print, "typeAnnotation")])), softline$h, ">"])); + const exprContents = concat$x([ifBreak$d("("), indent$p(concat$x([softline$h, path.call(print, "expression")])), softline$h, ifBreak$d(")")]); - case "TSNamespaceExportDeclaration": - parts.push("export as namespace ", path.call(print, "id")); + if (shouldBreakAfterCast) { + return conditionalGroup$4([concat$x([castGroup, path.call(print, "expression")]), concat$x([castGroup, group$l(exprContents, { + shouldBreak: true + })]), concat$x([castGroup, path.call(print, "expression")])]); + } - if (options.semi) { - parts.push(";"); + return group$l(concat$x([castGroup, path.call(print, "expression")])); } - return group$2(concat$6(parts)); - - case "TSEnumDeclaration": - if (n.declare) { - parts.push("declare "); + case "OptionalMemberExpression": + case "MemberExpression": + { + return printMemberExpression$1(path, options, print); } - if (n.modifiers) { - parts.push(printTypeScriptModifiers(path, options, print)); - } + case "MetaProperty": + return concat$x([path.call(print, "meta"), ".", path.call(print, "property")]); - if (n.const) { - parts.push("const "); + case "BindExpression": + if (n.object) { + parts.push(path.call(print, "object")); } - parts.push("enum ", path.call(print, "id"), " "); + parts.push(group$l(indent$p(concat$x([softline$h, printBindExpressionCallee$2(path, options, print)])))); + return concat$x(parts); - if (n.members.length === 0) { - parts.push(group$2(concat$6(["{", comments.printDanglingComments(path, options), softline$2, "}"]))); - } else { - parts.push(group$2(concat$6(["{", indent$3(concat$6([hardline$4, printArrayItems(path, options, "members", print), shouldPrintComma(options, "es5") ? "," : ""])), comments.printDanglingComments(path, options, - /* sameIndent */ - true), hardline$4, "}"]))); + case "Identifier": + { + return concat$x([n.name, printOptionalToken$6(path), printTypeAnnotation$3(path, options, print)]); } - return concat$6(parts); + case "V8IntrinsicIdentifier": + return concat$x(["%", n.name]); - case "TSEnumMember": - parts.push(path.call(print, "id")); + case "SpreadElement": + case "SpreadElementPattern": + case "SpreadProperty": + case "SpreadPropertyPattern": + case "RestElement": + case "ObjectTypeSpreadProperty": + return concat$x(["...", path.call(print, "argument"), printTypeAnnotation$3(path, options, print)]); - if (n.initializer) { - parts.push(" = ", path.call(print, "initializer")); + case "FunctionDeclaration": + case "FunctionExpression": + parts.push(printFunctionDeclaration$1(path, print, options, args && args.expandLastArg && getCallArguments$3(path.getParentNode()).length > 1)); + + if (!n.body) { + parts.push(semi); } - return concat$6(parts); + return concat$x(parts); - case "TSImportEqualsDeclaration": - if (n.isExport) { - parts.push("export "); - } + case "ArrowFunctionExpression": + return printArrowFunctionExpression$1(path, options, print, args); - parts.push("import ", path.call(print, "id"), " = ", path.call(print, "moduleReference")); + case "YieldExpression": + parts.push("yield"); - if (options.semi) { - parts.push(";"); + if (n.delegate) { + parts.push("*"); } - return group$2(concat$6(parts)); + if (n.argument) { + parts.push(" ", path.call(print, "argument")); + } - case "TSExternalModuleReference": - return concat$6(["require(", path.call(print, "expression"), ")"]); + return concat$x(parts); - case "TSModuleDeclaration": + case "AwaitExpression": { - const parent = path.getParentNode(); - const isExternalModule = isLiteral$1(n.id); - const parentIsDeclaration = parent.type === "TSModuleDeclaration"; - const bodyIsDeclaration = n.body && n.body.type === "TSModuleDeclaration"; - - if (parentIsDeclaration) { - parts.push("."); - } else { - if (n.declare) { - parts.push("declare "); - } - - parts.push(printTypeScriptModifiers(path, options, print)); - const textBetweenNodeAndItsId = options.originalText.slice(options.locStart(n), options.locStart(n.id)); // Global declaration looks like this: - // (declare)? global { ... } + parts.push("await"); - const isGlobalDeclaration = n.id.type === "Identifier" && n.id.name === "global" && !/namespace|module/.test(textBetweenNodeAndItsId); - - if (!isGlobalDeclaration) { - parts.push(isExternalModule || /(^|\s)module(\s|$)/.test(textBetweenNodeAndItsId) ? "module " : "namespace "); - } + if (n.argument) { + parts.push(" ", path.call(print, "argument")); } - parts.push(path.call(print, "id")); + const parent = path.getParentNode(); - if (bodyIsDeclaration) { - parts.push(path.call(print, "body")); - } else if (n.body) { - parts.push(" ", group$2(path.call(print, "body"))); - } else { - parts.push(semi); + if ((parent.type === "CallExpression" || parent.type === "OptionalCallExpression") && parent.callee === n || (parent.type === "MemberExpression" || parent.type === "OptionalMemberExpression") && parent.object === n) { + return group$l(concat$x([indent$p(concat$x([softline$h, concat$x(parts)])), softline$h])); } - return concat$6(parts); + return concat$x(parts); } - case "PrivateName": - return concat$6(["#", path.call(print, "id")]); - // TODO: Temporary auto-generated node type. To remove when typescript-estree has proper support for private fields. + case "TSExportAssignment": + return concat$x(["export = ", path.call(print, "expression"), semi]); - case "TSPrivateIdentifier": - return n.escapedText; + case "ExportDefaultDeclaration": + case "ExportNamedDeclaration": + case "DeclareExportDeclaration": + return printExportDeclaration$1(path, options, print); - case "TSConditionalType": - return printTernaryOperator(path, options, print, { - beforeParts: () => [path.call(print, "checkType"), " ", "extends", " ", path.call(print, "extendsType")], - afterParts: () => [], - shouldCheckJsx: false, - conditionalNodeType: "TSConditionalType", - consequentNodePropertyName: "trueType", - alternateNodePropertyName: "falseType", - testNodePropertyNames: ["checkType", "extendsType"] - }); + case "ExportAllDeclaration": + case "DeclareExportAllDeclaration": + return printExportAllDeclaration$1(path, options, print); - case "TSInferType": - return concat$6(["infer", " ", path.call(print, "typeParameter")]); + case "ImportDeclaration": + return printImportDeclaration$1(path, options, print); - case "InterpreterDirective": - parts.push("#!", n.value, hardline$4); + case "ImportSpecifier": + case "ExportSpecifier": + case "ImportNamespaceSpecifier": + case "ExportNamespaceSpecifier": + case "ImportDefaultSpecifier": + case "ExportDefaultSpecifier": + return printModuleSpecifier$1(path, options, print); - if (isNextLineEmpty$2(options.originalText, n, options.locEnd)) { - parts.push(hardline$4); - } + case "ImportAttribute": + return concat$x([path.call(print, "key"), ": ", path.call(print, "value")]); - return concat$6(parts); + case "Import": + return "import"; - case "NGRoot": - return concat$6([].concat(path.call(print, "node"), !n.node.comments || n.node.comments.length === 0 ? [] : concat$6([" //", n.node.comments[0].value.trimEnd()]))); + case "TSModuleBlock": + case "BlockStatement": + case "StaticBlock": + return printBlock$1(path, options, print); - case "NGChainedExpression": - return group$2(join$4(concat$6([";", line$4]), path.map(childPath => hasNgSideEffect$1(childPath) ? print(childPath) : concat$6(["(", print(childPath), ")"]), "expressions"))); + case "ThrowStatement": + case "ReturnStatement": + return concat$x([n.type === "ReturnStatement" ? "return" : "throw", printReturnAndThrowArgument$1(path, options, print)]); - case "NGEmptyExpression": - return ""; + case "NewExpression": + case "ImportExpression": + case "OptionalCallExpression": + case "CallExpression": + return printCallExpression$1(path, options, print); - case "NGQuotedExpression": - return concat$6([n.prefix, ": ", n.value.trim()]); + case "ObjectTypeInternalSlot": + return concat$x([n.static ? "static " : "", "[[", path.call(print, "id"), "]]", printOptionalToken$6(path), n.method ? "" : ": ", path.call(print, "value")]); - case "NGMicrosyntax": - return concat$6(path.map((childPath, index) => concat$6([index === 0 ? "" : isNgForOf$1(childPath.getValue(), index, n) ? " " : concat$6([";", line$4]), print(childPath)]), "body")); + case "ObjectExpression": + case "ObjectPattern": + case "ObjectTypeAnnotation": + case "TSInterfaceBody": + case "TSTypeLiteral": + case "RecordExpression": + return printObject$1(path, options, print); + // Babel 6 - case "NGMicrosyntaxKey": - return /^[a-z_$][a-z0-9_$]*(-[a-z_$][a-z0-9_$])*$/i.test(n.name) ? n.name : JSON.stringify(n.name); + case "ObjectProperty": // Non-standard AST node type. - case "NGMicrosyntaxExpression": - return concat$6([path.call(print, "expression"), n.alias === null ? "" : concat$6([" as ", path.call(print, "alias")])]); + case "Property": + if (n.method || n.kind === "get" || n.kind === "set") { + return printMethod$2(path, options, print); + } - case "NGMicrosyntaxKeyedExpression": - { - const index = path.getName(); - const parentNode = path.getParentNode(); - const shouldNotPrintColon = isNgForOf$1(n, index, parentNode) || (index === 1 && (n.key.name === "then" || n.key.name === "else") || index === 2 && n.key.name === "else" && parentNode.body[index - 1].type === "NGMicrosyntaxKeyedExpression" && parentNode.body[index - 1].key.name === "then") && parentNode.body[0].type === "NGMicrosyntaxExpression"; - return concat$6([path.call(print, "key"), shouldNotPrintColon ? " " : ": ", path.call(print, "expression")]); + if (n.shorthand) { + parts.push(path.call(print, "value")); + } else { + parts.push(printAssignment$1(n.key, printPropertyKey$2(path, options, print), ":", n.value, path.call(print, "value"), options)); } - case "NGMicrosyntaxLet": - return concat$6(["let ", path.call(print, "key"), n.value === null ? "" : concat$6([" = ", path.call(print, "value")])]); + return concat$x(parts); + // Babel 6 - case "NGMicrosyntaxAs": - return concat$6([path.call(print, "key"), " as ", path.call(print, "alias")]); + case "ClassMethod": + case "ClassPrivateMethod": + case "MethodDefinition": + case "TSAbstractMethodDefinition": + case "TSDeclareMethod": + return printClassMethod$1(path, options, print); - case "ArgumentPlaceholder": - return "?"; - // These are not valid TypeScript. Printing them just for the sake of error recovery. + case "ObjectMethod": + return printMethod$2(path, options, print); - case "TSJSDocAllType": - return "*"; + case "Decorator": + return concat$x(["@", path.call(print, "expression"), path.call(print, "callee")]); - case "TSJSDocUnknownType": - return "?"; + case "ArrayExpression": + case "ArrayPattern": + case "TupleExpression": + return printArray$1(path, options, print); - case "TSJSDocNullableType": - return concat$6(["?", path.call(print, "typeAnnotation")]); + case "SequenceExpression": + { + const parent = path.getParentNode(0); - case "TSJSDocNonNullableType": - return concat$6(["!", path.call(print, "typeAnnotation")]); + if (parent.type === "ExpressionStatement" || parent.type === "ForStatement") { + // For ExpressionStatements and for-loop heads, which are among + // the few places a SequenceExpression appears unparenthesized, we want + // to indent expressions after the first. + const parts = []; + path.each(p => { + if (p.getName() === 0) { + parts.push(print(p)); + } else { + parts.push(",", indent$p(concat$x([line$j, print(p)]))); + } + }, "expressions"); + return group$l(concat$x(parts)); + } - case "TSJSDocFunctionType": - return concat$6(["function(", // The parameters could be here, but typescript-estree doesn't convert them anyway (throws an error). - "): ", path.call(print, "typeAnnotation")]); + return group$l(concat$x([join$f(concat$x([",", line$j]), path.map(print, "expressions"))])); + } - default: - /* istanbul ignore next */ - throw new Error("unknown type: " + JSON.stringify(n.type)); - } -} + case "ThisExpression": + return "this"; -function printStatementSequence(path, options, print) { - const printed = []; - const bodyNode = path.getNode(); - const isClass = bodyNode.type === "ClassBody"; - path.map((stmtPath, i) => { - const stmt = stmtPath.getValue(); // Just in case the AST has been modified to contain falsy - // "statements," it's safer simply to skip them. + case "Super": + return "super"; - /* istanbul ignore if */ + case "NullLiteral": + // Babel 6 Literal split + return "null"; - if (!stmt) { - return; - } // Skip printing EmptyStatement nodes to avoid leaving stray - // semicolons lying around. + case "RegExpLiteral": + // Babel 6 Literal split + return printRegex(n); + case "NumericLiteral": + // Babel 6 Literal split + return printNumber$2(n.extra.raw); - if (stmt.type === "EmptyStatement") { - return; - } + case "DecimalLiteral": + return printNumber$2(n.value) + "m"; - const stmtPrinted = print(stmtPath); - const text = options.originalText; - const parts = []; // in no-semi mode, prepend statement with semicolon if it might break ASI - // don't prepend the only JSX element in a program with semicolon + case "BigIntLiteral": + // babel: n.extra.raw, flow: n.bigint + return (n.bigint || n.extra.raw).toLowerCase(); - if (!options.semi && !isClass && !isTheOnlyJSXElementInMarkdown$1(options, stmtPath) && stmtNeedsASIProtection(stmtPath, options)) { - if (stmt.comments && stmt.comments.some(comment => comment.leading)) { - parts.push(print(stmtPath, { - needsSemi: true - })); - } else { - parts.push(";", stmtPrinted); + case "BooleanLiteral": // Babel 6 Literal split + + case "StringLiteral": // Babel 6 Literal split + + case "Literal": + if (n.regex) { + return printRegex(n.regex); + } // typescript + + + if (n.bigint) { + return n.raw.toLowerCase(); } - } else { - parts.push(stmtPrinted); - } - if (!options.semi && isClass) { - if (classPropMayCauseASIProblems$1(stmtPath)) { - parts.push(";"); - } else if (stmt.type === "ClassProperty") { - const nextChild = bodyNode.body[i + 1]; + if (typeof n.value === "number") { + return printNumber$2(n.raw); + } - if (classChildNeedsASIProtection$1(nextChild)) { - parts.push(";"); - } + if (typeof n.value !== "string") { + return "" + n.value; } - } - if (isNextLineEmpty$2(text, stmt, options.locEnd) && !isLastStatement$1(stmtPath)) { - parts.push(hardline$4); - } + return nodeStr(n, options); - printed.push(concat$6(parts)); - }); - return join$4(hardline$4, printed); -} + case "Directive": + return path.call(print, "value"); + // Babel 6 -function printPropertyKey(path, options, print) { - const node = path.getNode(); + case "DirectiveLiteral": + return nodeStr(n, options); - if (node.computed) { - return concat$6(["[", path.call(print, "key"), "]"]); - } + case "UnaryExpression": + parts.push(n.operator); - const parent = path.getParentNode(); - const { - key - } = node; + if (/[a-z]$/.test(n.operator)) { + parts.push(" "); + } - if (node.type === "ClassPrivateProperty" && // flow has `Identifier` key, and babel has `PrivateName` key - key.type === "Identifier") { - return concat$6(["#", path.call(print, "key")]); - } + if (n.argument.comments && n.argument.comments.length > 0) { + parts.push(group$l(concat$x(["(", indent$p(concat$x([softline$h, path.call(print, "argument")])), softline$h, ")"]))); + } else { + parts.push(path.call(print, "argument")); + } - if (options.quoteProps === "consistent" && !needsQuoteProps.has(parent)) { - const objectHasStringProp = (parent.properties || parent.body || parent.members).some(prop => !prop.computed && prop.key && isStringLiteral$1(prop.key) && !isStringPropSafeToCoerceToIdentifier$1(prop, options)); - needsQuoteProps.set(parent, objectHasStringProp); - } + return concat$x(parts); - if (key.type === "Identifier" && (options.parser === "json" || options.quoteProps === "consistent" && needsQuoteProps.get(parent))) { - // a -> "a" - const prop = printString$1(JSON.stringify(key.name), options); - return path.call(keyPath => comments.printComments(keyPath, () => prop, options), "key"); - } + case "UpdateExpression": + parts.push(path.call(print, "argument"), n.operator); - if (isStringPropSafeToCoerceToIdentifier$1(node, options) && (options.quoteProps === "as-needed" || options.quoteProps === "consistent" && !needsQuoteProps.get(parent))) { - // 'a' -> a - return path.call(keyPath => comments.printComments(keyPath, () => key.value, options), "key"); - } + if (n.prefix) { + parts.reverse(); + } - return path.call(print, "key"); -} + return concat$x(parts); -function printMethod(path, options, print) { - const node = path.getNode(); - const { - kind - } = node; - const value = node.value || node; - const parts = []; + case "ConditionalExpression": + return ternary(path, options, print, { + beforeParts: () => [path.call(print, "test")], + afterParts: breakClosingParen => [breakClosingParen ? softline$h : ""], + shouldCheckJsx: true, + conditionalNodeType: "ConditionalExpression", + consequentNodePropertyName: "consequent", + alternateNodePropertyName: "alternate", + testNodePropertyNames: ["test"] + }); - if (!kind || kind === "init" || kind === "method" || kind === "constructor") { - if (value.async) { - parts.push("async "); - } + case "VariableDeclaration": + { + const printed = path.map(childPath => { + return print(childPath); + }, "declarations"); // We generally want to terminate all variable declarations with a + // semicolon, except when they in the () part of for loops. - if (value.generator) { - parts.push("*"); - } - } else { - assert$1.ok(kind === "get" || kind === "set"); - parts.push(kind, " "); - } + const parentNode = path.getParentNode(); + const isParentForLoop = parentNode.type === "ForStatement" || parentNode.type === "ForInStatement" || parentNode.type === "ForOfStatement"; + const hasValue = n.declarations.some(decl => decl.init); + let firstVariable; - parts.push(printPropertyKey(path, options, print), node.optional || node.key.optional ? "?" : "", node === value ? printMethodInternal(path, options, print) : path.call(path => printMethodInternal(path, options, print), "value")); - return concat$6(parts); -} + if (printed.length === 1 && !n.declarations[0].comments) { + firstVariable = printed[0]; + } else if (printed.length > 0) { + // Indent first var to comply with eslint one-var rule + firstVariable = indent$p(printed[0]); + } -function printMethodInternal(path, options, print) { - const parts = [printFunctionTypeParameters(path, options, print), group$2(concat$6([printFunctionParams(path, print, options), printReturnType(path, print, options)]))]; + parts = [n.declare ? "declare " : "", n.kind, firstVariable ? concat$x([" ", firstVariable]) : "", indent$p(concat$x(printed.slice(1).map(p => concat$x([",", hasValue && !isParentForLoop ? hardline$k : line$j, p]))))]; - if (path.getNode().body) { - parts.push(" ", path.call(print, "body")); - } else { - parts.push(options.semi ? ";" : ""); - } + if (!(isParentForLoop && parentNode.body !== n)) { + parts.push(semi); + } - return concat$6(parts); -} + return group$l(concat$x(parts)); + } -function couldGroupArg(arg) { - return arg.type === "ObjectExpression" && (arg.properties.length > 0 || arg.comments) || arg.type === "ArrayExpression" && (arg.elements.length > 0 || arg.comments) || arg.type === "TSTypeAssertion" && couldGroupArg(arg.expression) || arg.type === "TSAsExpression" && couldGroupArg(arg.expression) || arg.type === "FunctionExpression" || arg.type === "ArrowFunctionExpression" && ( // we want to avoid breaking inside composite return types but not simple keywords - // https://github.com/prettier/prettier/issues/4070 - // export class Thing implements OtherThing { - // do: (type: Type) => Provider = memoize( - // (type: ObjectType): Provider => {} - // ); - // } - // https://github.com/prettier/prettier/issues/6099 - // app.get("/", (req, res): void => { - // res.send("Hello World!"); - // }); - !arg.returnType || !arg.returnType.typeAnnotation || arg.returnType.typeAnnotation.type !== "TSTypeReference") && (arg.body.type === "BlockStatement" || arg.body.type === "ArrowFunctionExpression" || arg.body.type === "ObjectExpression" || arg.body.type === "ArrayExpression" || arg.body.type === "CallExpression" || arg.body.type === "OptionalCallExpression" || arg.body.type === "ConditionalExpression" || isJSXNode$1(arg.body)); -} + case "TSTypeAliasDeclaration": + { + if (n.declare) { + parts.push("declare "); + } -function shouldGroupLastArg(args) { - const lastArg = getLast$2(args); - const penultimateArg = getPenultimate$1(args); - return !hasLeadingComment$3(lastArg) && !hasTrailingComment$1(lastArg) && couldGroupArg(lastArg) && ( // If the last two arguments are of the same type, - // disable last element expansion. - !penultimateArg || penultimateArg.type !== lastArg.type); -} + const printed = printAssignmentRight$1(n.id, n.typeAnnotation, n.typeAnnotation && path.call(print, "typeAnnotation"), options); + parts.push("type ", path.call(print, "id"), path.call(print, "typeParameters"), " =", printed, semi); + return group$l(concat$x(parts)); + } -function shouldGroupFirstArg(args) { - if (args.length !== 2) { - return false; - } + case "WithStatement": + return group$l(concat$x(["with (", path.call(print, "object"), ")", adjustClause$1(n.body, path.call(print, "body"))])); - const [firstArg, secondArg] = args; - return (!firstArg.comments || !firstArg.comments.length) && (firstArg.type === "FunctionExpression" || firstArg.type === "ArrowFunctionExpression" && firstArg.body.type === "BlockStatement") && secondArg.type !== "FunctionExpression" && secondArg.type !== "ArrowFunctionExpression" && secondArg.type !== "ConditionalExpression" && !couldGroupArg(secondArg); -} + case "IfStatement": + { + const con = adjustClause$1(n.consequent, path.call(print, "consequent")); + const opening = group$l(concat$x(["if (", group$l(concat$x([indent$p(concat$x([softline$h, path.call(print, "test")])), softline$h])), ")", con])); + parts.push(opening); -function printJestEachTemplateLiteral(node, expressions, options) { - /** - * a | b | expected - * ${1} | ${1} | ${2} - * ${1} | ${2} | ${3} - * ${2} | ${1} | ${3} - */ - const headerNames = node.quasis[0].value.raw.trim().split(/\s*\|\s*/); + if (n.alternate) { + const commentOnOwnLine = hasTrailingComment$6(n.consequent) && n.consequent.comments.some(comment => comment.trailing && !isBlockComment$9(comment)) || needsHardlineAfterDanglingComment$2(n); + const elseOnSameLine = n.consequent.type === "BlockStatement" && !commentOnOwnLine; + parts.push(elseOnSameLine ? " " : hardline$k); - if (headerNames.length > 1 || headerNames.some(headerName => headerName.length !== 0)) { - const parts = []; - const stringifiedExpressions = expressions.map(doc => "${" + printDocToString$2(doc, Object.assign({}, options, { - printWidth: Infinity, - endOfLine: "lf" - })).formatted + "}"); - const tableBody = [{ - hasLineBreak: false, - cells: [] - }]; + if (hasDanglingComments$7(n)) { + parts.push(comments.printDanglingComments(path, options, true), commentOnOwnLine ? hardline$k : " "); + } - for (let i = 1; i < node.quasis.length; i++) { - const row = tableBody[tableBody.length - 1]; - const correspondingExpression = stringifiedExpressions[i - 1]; - row.cells.push(correspondingExpression); + parts.push("else", group$l(adjustClause$1(n.alternate, path.call(print, "alternate"), n.alternate.type === "IfStatement"))); + } - if (correspondingExpression.includes("\n")) { - row.hasLineBreak = true; + return concat$x(parts); } - if (node.quasis[i].value.raw.includes("\n")) { - tableBody.push({ - hasLineBreak: false, - cells: [] - }); - } - } + case "ForStatement": + { + const body = adjustClause$1(n.body, path.call(print, "body")); // We want to keep dangling comments above the loop to stay consistent. + // Any comment positioned between the for statement and the parentheses + // is going to be printed before the statement. - const maxColumnCount = Math.max(headerNames.length, ...tableBody.map(row => row.cells.length)); - const maxColumnWidths = Array.from({ - length: maxColumnCount - }).fill(0); - const table = [{ - cells: headerNames - }, ...tableBody.filter(row => row.cells.length !== 0)]; + const dangling = comments.printDanglingComments(path, options, + /* sameLine */ + true); + const printedComments = dangling ? concat$x([dangling, softline$h]) : ""; - for (const { - cells - } of table.filter(row => !row.hasLineBreak)) { - cells.forEach((cell, index) => { - maxColumnWidths[index] = Math.max(maxColumnWidths[index], getStringWidth$3(cell)); - }); - } + if (!n.init && !n.test && !n.update) { + return concat$x([printedComments, group$l(concat$x(["for (;;)", body]))]); + } - parts.push(lineSuffixBoundary$1, "`", indent$3(concat$6([hardline$4, join$4(hardline$4, table.map(row => join$4(" | ", row.cells.map((cell, index) => row.hasLineBreak ? cell : cell + " ".repeat(maxColumnWidths[index] - getStringWidth$3(cell))))))])), hardline$4, "`"); - return concat$6(parts); - } -} + return concat$x([printedComments, group$l(concat$x(["for (", group$l(concat$x([indent$p(concat$x([softline$h, path.call(print, "init"), ";", line$j, path.call(print, "test"), ";", line$j, path.call(print, "update")])), softline$h])), ")", body]))]); + } -function printArgumentsList(path, options, print) { - const node = path.getValue(); - const args = node.arguments; + case "WhileStatement": + return group$l(concat$x(["while (", group$l(concat$x([indent$p(concat$x([softline$h, path.call(print, "test")])), softline$h])), ")", adjustClause$1(n.body, path.call(print, "body"))])); - if (args.length === 0) { - return concat$6(["(", comments.printDanglingComments(path, options, - /* sameIndent */ - true), ")"]); - } // useEffect(() => { ... }, [foo, bar, baz]) + case "ForInStatement": + return group$l(concat$x(["for (", path.call(print, "left"), " in ", path.call(print, "right"), ")", adjustClause$1(n.body, path.call(print, "body"))])); + case "ForOfStatement": + return group$l(concat$x(["for", n.await ? " await" : "", " (", path.call(print, "left"), " of ", path.call(print, "right"), ")", adjustClause$1(n.body, path.call(print, "body"))])); - if (args.length === 2 && args[0].type === "ArrowFunctionExpression" && args[0].params.length === 0 && args[0].body.type === "BlockStatement" && args[1].type === "ArrayExpression" && !args.find(arg => arg.comments)) { - return concat$6(["(", path.call(print, "arguments", 0), ", ", path.call(print, "arguments", 1), ")"]); - } // func( - // ({ - // a, - // b - // }) => {} - // ); + case "DoWhileStatement": + { + const clause = adjustClause$1(n.body, path.call(print, "body")); + const doBody = group$l(concat$x(["do", clause])); + parts = [doBody]; + if (n.body.type === "BlockStatement") { + parts.push(" "); + } else { + parts.push(hardline$k); + } - function shouldBreakForArrowFunctionInArguments(arg, argPath) { - if (!arg || arg.type !== "ArrowFunctionExpression" || !arg.body || arg.body.type !== "BlockStatement" || !arg.params || arg.params.length < 1) { - return false; - } + parts.push("while ("); + parts.push(group$l(concat$x([indent$p(concat$x([softline$h, path.call(print, "test")])), softline$h])), ")", semi); + return concat$x(parts); + } - let shouldBreak = false; - argPath.each(paramPath => { - const printed = concat$6([print(paramPath)]); - shouldBreak = shouldBreak || willBreak$1(printed); - }, "params"); - return shouldBreak; - } + case "DoExpression": + return concat$x(["do ", path.call(print, "body")]); - let anyArgEmptyLine = false; - let shouldBreakForArrowFunction = false; - let hasEmptyLineFollowingFirstArg = false; - const lastArgIndex = args.length - 1; - const printedArguments = path.map((argPath, index) => { - const arg = argPath.getNode(); - const parts = [print(argPath)]; + case "BreakStatement": + parts.push("break"); - if (index === lastArgIndex) ; else if (isNextLineEmpty$2(options.originalText, arg, options.locEnd)) { - if (index === 0) { - hasEmptyLineFollowingFirstArg = true; + if (n.label) { + parts.push(" ", path.call(print, "label")); } - anyArgEmptyLine = true; - parts.push(",", hardline$4, hardline$4); - } else { - parts.push(",", line$4); - } + parts.push(semi); + return concat$x(parts); - shouldBreakForArrowFunction = shouldBreakForArrowFunctionInArguments(arg, argPath); - return concat$6(parts); - }, "arguments"); - const maybeTrailingComma = // Dynamic imports cannot have trailing commas - !(node.callee && node.callee.type === "Import") && shouldPrintComma(options, "all") ? "," : ""; + case "ContinueStatement": + parts.push("continue"); - function allArgsBrokenOut() { - return group$2(concat$6(["(", indent$3(concat$6([line$4, concat$6(printedArguments)])), maybeTrailingComma, line$4, ")"]), { - shouldBreak: true - }); - } + if (n.label) { + parts.push(" ", path.call(print, "label")); + } - if (path.getParentNode().type !== "Decorator" && isFunctionCompositionArgs$1(args)) { - return allArgsBrokenOut(); - } + parts.push(semi); + return concat$x(parts); - const shouldGroupFirst = shouldGroupFirstArg(args); - const shouldGroupLast = shouldGroupLastArg(args); + case "LabeledStatement": + if (n.body.type === "EmptyStatement") { + return concat$x([path.call(print, "label"), ":;"]); + } - if (shouldGroupFirst || shouldGroupLast) { - const shouldBreak = (shouldGroupFirst ? printedArguments.slice(1).some(willBreak$1) : printedArguments.slice(0, -1).some(willBreak$1)) || anyArgEmptyLine || shouldBreakForArrowFunction; // We want to print the last argument with a special flag + return concat$x([path.call(print, "label"), ": ", path.call(print, "body")]); - let printedExpanded; - let i = 0; - path.each(argPath => { - if (shouldGroupFirst && i === 0) { - printedExpanded = [concat$6([argPath.call(p => print(p, { - expandFirstArg: true - })), printedArguments.length > 1 ? "," : "", hasEmptyLineFollowingFirstArg ? hardline$4 : line$4, hasEmptyLineFollowingFirstArg ? hardline$4 : ""])].concat(printedArguments.slice(1)); + case "TryStatement": + return concat$x(["try ", path.call(print, "block"), n.handler ? concat$x([" ", path.call(print, "handler")]) : "", n.finalizer ? concat$x([" finally ", path.call(print, "finalizer")]) : ""]); + + case "CatchClause": + if (n.param) { + const hasComments = n.param.comments && n.param.comments.some(comment => !isBlockComment$9(comment) || comment.leading && hasNewline$7(options.originalText, locEnd$e(comment)) || comment.trailing && hasNewline$7(options.originalText, locStart$8(comment), { + backwards: true + })); + const param = path.call(print, "param"); + return concat$x(["catch ", hasComments ? concat$x(["(", indent$p(concat$x([softline$h, param])), softline$h, ") "]) : concat$x(["(", param, ") "]), path.call(print, "body")]); } - if (shouldGroupLast && i === args.length - 1) { - printedExpanded = printedArguments.slice(0, -1).concat(argPath.call(p => print(p, { - expandLastArg: true - }))); + return concat$x(["catch ", path.call(print, "body")]); + // Note: ignoring n.lexical because it has no printing consequences. + + case "SwitchStatement": + return concat$x([group$l(concat$x(["switch (", indent$p(concat$x([softline$h, path.call(print, "discriminant")])), softline$h, ")"])), " {", n.cases.length > 0 ? indent$p(concat$x([hardline$k, join$f(hardline$k, path.map(casePath => { + const caseNode = casePath.getValue(); + return concat$x([casePath.call(print), n.cases.indexOf(caseNode) !== n.cases.length - 1 && isNextLineEmpty$9(options.originalText, caseNode, locEnd$e) ? hardline$k : ""]); + }, "cases"))])) : "", hardline$k, "}"]); + + case "SwitchCase": + { + if (n.test) { + parts.push("case ", path.call(print, "test"), ":"); + } else { + parts.push("default:"); + } + + const consequent = n.consequent.filter(node => node.type !== "EmptyStatement"); + + if (consequent.length > 0) { + const cons = path.call(consequentPath => { + return printStatementSequence$2(consequentPath, options, print); + }, "consequent"); + parts.push(consequent.length === 1 && consequent[0].type === "BlockStatement" ? concat$x([" ", cons]) : indent$p(concat$x([hardline$k, cons]))); + } + + return concat$x(parts); } + // JSX extensions below. - i++; - }, "arguments"); - const somePrintedArgumentsWillBreak = printedArguments.some(willBreak$1); - const simpleConcat = concat$6(["(", concat$6(printedExpanded), ")"]); - return concat$6([somePrintedArgumentsWillBreak ? breakParent$2 : "", conditionalGroup$1([!somePrintedArgumentsWillBreak && !node.typeArguments && !node.typeParameters ? simpleConcat : ifBreak$1(allArgsBrokenOut(), simpleConcat), shouldGroupFirst ? concat$6(["(", group$2(printedExpanded[0], { - shouldBreak: true - }), concat$6(printedExpanded.slice(1)), ")"]) : concat$6(["(", concat$6(printedArguments.slice(0, -1)), group$2(getLast$2(printedExpanded), { - shouldBreak: true - }), ")"]), allArgsBrokenOut()], { - shouldBreak - })]); - } + case "DebuggerStatement": + return concat$x(["debugger", semi]); - const contents = concat$6(["(", indent$3(concat$6([softline$2, concat$6(printedArguments)])), ifBreak$1(maybeTrailingComma), softline$2, ")"]); + case "JSXAttribute": + return printJsxAttribute$1(path, options, print); - if (isLongCurriedCallExpression$1(path)) { - // By not wrapping the arguments in a group, the printer prioritizes - // breaking up these arguments rather than the args of the parent call. - return contents; - } + case "JSXIdentifier": + return "" + n.name; - return group$2(contents, { - shouldBreak: printedArguments.some(willBreak$1) || anyArgEmptyLine - }); -} + case "JSXNamespacedName": + return join$f(":", [path.call(print, "namespace"), path.call(print, "name")]); -function printTypeAnnotation(path, options, print) { - const node = path.getValue(); + case "JSXMemberExpression": + return join$f(".", [path.call(print, "object"), path.call(print, "property")]); - if (!node.typeAnnotation) { - return ""; - } + case "TSQualifiedName": + return join$f(".", [path.call(print, "left"), path.call(print, "right")]); - const parentNode = path.getParentNode(); - const isDefinite = node.definite || parentNode && parentNode.type === "VariableDeclarator" && parentNode.definite; - const isFunctionDeclarationIdentifier = parentNode.type === "DeclareFunction" && parentNode.id === node; + case "JSXSpreadAttribute": + return printJsxSpreadAttribute$1(path, options, print); - if (isFlowAnnotationComment$1(options.originalText, node.typeAnnotation, options)) { - return concat$6([" /*: ", path.call(print, "typeAnnotation"), " */"]); - } + case "JSXSpreadChild": + return printJsxSpreadChild(path, options, print); - return concat$6([isFunctionDeclarationIdentifier ? "" : isDefinite ? "!: " : ": ", path.call(print, "typeAnnotation")]); -} + case "JSXExpressionContainer": + return printJsxExpressionContainer$1(path, options, print); -function printFunctionTypeParameters(path, options, print) { - const fun = path.getValue(); + case "JSXFragment": + case "JSXElement": + return printJsxElement$1(path, options, print); - if (fun.typeArguments) { - return path.call(print, "typeArguments"); - } + case "JSXOpeningElement": + return printJsxOpeningElement$1(path, options, print); - if (fun.typeParameters) { - return path.call(print, "typeParameters"); - } + case "JSXClosingElement": + return printJsxClosingElement$1(path, options, print); - return ""; -} + case "JSXOpeningFragment": + case "JSXClosingFragment": + return printJsxOpeningClosingFragment$1(path, options + /*, print*/ + ); -function printFunctionParams(path, print, options, expandArg, printTypeParams) { - const fun = path.getValue(); - const parent = path.getParentNode(); - const paramsField = fun.parameters ? "parameters" : "params"; - const isParametersInTestCall = isTestCall$1(parent); - const shouldHugParameters = shouldHugArguments(fun); - const shouldExpandParameters = expandArg && !(fun[paramsField] && fun[paramsField].some(n => n.comments)); - const typeParams = printTypeParams ? printFunctionTypeParameters(path, options, print) : ""; - let printed = []; - - if (fun[paramsField]) { - const lastArgIndex = fun[paramsField].length - 1; - printed = path.map((childPath, index) => { - const parts = []; - const param = childPath.getValue(); - parts.push(print(childPath)); + case "JSXText": + /* istanbul ignore next */ + throw new Error("JSXTest should be handled by JSXElement"); - if (index === lastArgIndex) { - if (fun.rest) { - parts.push(",", line$4); - } - } else if (isParametersInTestCall || shouldHugParameters || shouldExpandParameters) { - parts.push(", "); - } else if (isNextLineEmpty$2(options.originalText, param, options.locEnd)) { - parts.push(",", hardline$4, hardline$4); - } else { - parts.push(",", line$4); + case "JSXEmptyExpression": + return printJsxEmptyExpression$1(path, options + /*, print*/ + ); + + case "ClassBody": + if (!n.comments && n.body.length === 0) { + return "{}"; } - return concat$6(parts); - }, paramsField); - } + return concat$x(["{", n.body.length > 0 ? indent$p(concat$x([hardline$k, path.call(bodyPath => { + return printStatementSequence$2(bodyPath, options, print); + }, "body")])) : comments.printDanglingComments(path, options), hardline$k, "}"]); - if (fun.rest) { - printed.push(concat$6(["...", path.call(print, "rest")])); - } + case "ClassProperty": + case "FieldDefinition": + case "TSAbstractClassProperty": + case "ClassPrivateProperty": + { + if (n.decorators && n.decorators.length !== 0) { + parts.push(printDecorators$2(path, options, print)); + } - if (printed.length === 0) { - return concat$6([typeParams, "(", comments.printDanglingComments(path, options, - /* sameIndent */ - true, comment => getNextNonSpaceNonCommentCharacter$1(options.originalText, comment, options.locEnd) === ")"), ")"]); - } + if (n.accessibility) { + parts.push(n.accessibility + " "); + } - const lastParam = getLast$2(fun[paramsField]); // If the parent is a call with the first/last argument expansion and this is the - // params of the first/last argument, we don't want the arguments to break and instead - // want the whole expression to be on a new line. - // - // Good: Bad: - // verylongcall( verylongcall(( - // (a, b) => { a, - // } b, - // }) ) => { - // }) + if (n.declare) { + parts.push("declare "); + } - if (shouldExpandParameters) { - return group$2(concat$6([removeLines$1(typeParams), "(", concat$6(printed.map(removeLines$1)), ")"])); - } // Single object destructuring should hug - // - // function({ - // a, - // b, - // c - // }) {} + if (n.static) { + parts.push("static "); + } + if (n.type === "TSAbstractClassProperty" || n.abstract) { + parts.push("abstract "); + } - const hasNotParameterDecorator = fun[paramsField].every(param => !param.decorators); + if (n.readonly) { + parts.push("readonly "); + } - if (shouldHugParameters && hasNotParameterDecorator) { - return concat$6([typeParams, "(", concat$6(printed), ")"]); - } // don't break in specs, eg; `it("should maintain parens around done even when long", (done) => {})` + if (n.variance) { + parts.push(path.call(print, "variance")); + } + parts.push(printPropertyKey$2(path, options, print), printOptionalToken$6(path), printTypeAnnotation$3(path, options, print)); - if (isParametersInTestCall) { - return concat$6([typeParams, "(", concat$6(printed), ")"]); - } + if (n.value) { + parts.push(" =", printAssignmentRight$1(n.key, n.value, path.call(print, "value"), options)); + } - const isFlowShorthandWithOneArg = (isObjectTypePropertyAFunction$1(parent, options) || isTypeAnnotationAFunction$1(parent, options) || parent.type === "TypeAlias" || parent.type === "UnionTypeAnnotation" || parent.type === "TSUnionType" || parent.type === "IntersectionTypeAnnotation" || parent.type === "FunctionTypeAnnotation" && parent.returnType === fun) && fun[paramsField].length === 1 && fun[paramsField][0].name === null && fun[paramsField][0].typeAnnotation && fun.typeParameters === null && isSimpleFlowType$1(fun[paramsField][0].typeAnnotation) && !fun.rest; + parts.push(semi); + return group$l(concat$x(parts)); + } - if (isFlowShorthandWithOneArg) { - if (options.arrowParens === "always") { - return concat$6(["(", concat$6(printed), ")"]); - } + case "ClassDeclaration": + case "ClassExpression": + if (n.declare) { + parts.push("declare "); + } - return concat$6(printed); - } + parts.push(printClass$1(path, options, print)); + return concat$x(parts); - const canHaveTrailingComma = !(lastParam && lastParam.type === "RestElement") && !fun.rest; - return concat$6([typeParams, "(", indent$3(concat$6([softline$2, concat$6(printed)])), ifBreak$1(canHaveTrailingComma && shouldPrintComma(options, "all") ? "," : ""), softline$2, ")"]); -} + case "TSInterfaceHeritage": + case "TSExpressionWithTypeArguments": + // Babel AST + parts.push(path.call(print, "expression")); -function shouldPrintParamsWithoutParens(path, options) { - if (options.arrowParens === "always") { - return false; - } + if (n.typeParameters) { + parts.push(path.call(print, "typeParameters")); + } - if (options.arrowParens === "avoid") { - const node = path.getValue(); - return canPrintParamsWithoutParens(node); - } // Fallback default; should be unreachable + return concat$x(parts); + case "TemplateElement": + return join$f(literalline$3, n.value.raw.split(/\r?\n/g)); - return false; -} + case "TSTemplateLiteralType": + case "TemplateLiteral": + { + return printTemplateLiteral$1(path, print, options); + } -function canPrintParamsWithoutParens(node) { - return node.params.length === 1 && !node.rest && !node.typeParameters && !hasDanglingComments$1(node) && node.params[0].type === "Identifier" && !node.params[0].typeAnnotation && !node.params[0].comments && !node.params[0].optional && !node.predicate && !node.returnType; -} + case "TaggedTemplateExpression": + return concat$x([path.call(print, "tag"), path.call(print, "typeParameters"), path.call(print, "quasi")]); + // These types are unprintable because they serve as abstract + // supertypes for other (printable) types. -function printFunctionDeclaration(path, print, options) { - const n = path.getValue(); - const parts = []; + case "Node": + case "Printable": + case "SourceLocation": + case "Position": + case "Statement": + case "Function": + case "Pattern": + case "Expression": + case "Declaration": + case "Specifier": + case "NamedSpecifier": + case "Comment": + case "MemberTypeAnnotation": // Flow - if (n.async) { - parts.push("async "); - } + case "Type": + /* istanbul ignore next */ + throw new Error("unprintable type: " + JSON.stringify(n.type)); + // Type Annotations for Facebook Flow, typically stripped out or + // transformed away before printing. - if (n.generator) { - parts.push("function* "); - } else { - parts.push("function "); - } + case "TypeAnnotation": + case "TSTypeAnnotation": + if (n.typeAnnotation) { + return path.call(print, "typeAnnotation"); + } + /* istanbul ignore next */ - if (n.id) { - parts.push(path.call(print, "id")); - } - parts.push(printFunctionTypeParameters(path, options, print), group$2(concat$6([printFunctionParams(path, print, options), printReturnType(path, print, options)])), n.body ? " " : "", path.call(print, "body")); - return concat$6(parts); -} + return ""; -function printReturnType(path, print, options) { - const n = path.getValue(); - const returnType = path.call(print, "returnType"); + case "TSNamedTupleMember": + return concat$x([path.call(print, "label"), n.optional ? "?" : "", ": ", path.call(print, "elementType")]); - if (n.returnType && isFlowAnnotationComment$1(options.originalText, n.returnType, options)) { - return concat$6([" /*: ", returnType, " */"]); - } + case "TSTupleType": + case "TupleTypeAnnotation": + { + const typesField = n.type === "TSTupleType" ? "elementTypes" : "types"; + const hasRest = n[typesField].length > 0 && getLast$9(n[typesField]).type === "TSRestType"; + return group$l(concat$x(["[", indent$p(concat$x([softline$h, printArrayItems$1(path, options, typesField, print)])), ifBreak$d(shouldPrintComma$8(options, "all") && !hasRest ? "," : ""), comments.printDanglingComments(path, options, + /* sameIndent */ + true), softline$h, "]"])); + } - const parts = [returnType]; // prepend colon to TypeScript type annotation + case "ExistsTypeAnnotation": + return "*"; - if (n.returnType && n.returnType.typeAnnotation) { - parts.unshift(": "); - } + case "EmptyTypeAnnotation": + return "empty"; - if (n.predicate) { - // The return type will already add the colon, but otherwise we - // need to do it ourselves - parts.push(n.returnType ? " " : ": ", path.call(print, "predicate")); - } + case "MixedTypeAnnotation": + return "mixed"; - return concat$6(parts); -} + case "ArrayTypeAnnotation": + return concat$x([path.call(print, "elementType"), "[]"]); -function printExportDeclaration(path, options, print) { - const decl = path.getValue(); - const semi = options.semi ? ";" : ""; - const parts = ["export "]; - const isDefault = decl.default || decl.type === "ExportDefaultDeclaration"; + case "BooleanLiteralTypeAnnotation": + return "" + n.value; - if (isDefault) { - parts.push("default "); - } + case "DeclareClass": + return printFlowDeclaration$1(path, printClass$1(path, options, print)); - parts.push(comments.printDanglingComments(path, options, - /* sameIndent */ - true)); + case "TSDeclareFunction": + // For TypeScript the TSDeclareFunction node shares the AST + // structure with FunctionDeclaration + return concat$x([n.declare ? "declare " : "", printFunctionDeclaration$1(path, print, options), semi]); - if (needsHardlineAfterDanglingComment$1(decl)) { - parts.push(hardline$4); - } + case "DeclareFunction": + return printFlowDeclaration$1(path, concat$x(["function ", path.call(print, "id"), n.predicate ? " " : "", path.call(print, "predicate"), semi])); - if (decl.declaration) { - parts.push(path.call(print, "declaration")); + case "DeclareModule": + return printFlowDeclaration$1(path, concat$x(["module ", path.call(print, "id"), " ", path.call(print, "body")])); - if (isDefault && decl.declaration.type !== "ClassDeclaration" && decl.declaration.type !== "FunctionDeclaration" && decl.declaration.type !== "TSInterfaceDeclaration" && decl.declaration.type !== "DeclareClass" && decl.declaration.type !== "DeclareFunction" && decl.declaration.type !== "TSDeclareFunction") { - parts.push(semi); - } - } else { - if (decl.specifiers && decl.specifiers.length > 0) { - const specifiers = []; - const defaultSpecifiers = []; - const namespaceSpecifiers = []; - path.each(specifierPath => { - const specifierType = path.getValue().type; - - if (specifierType === "ExportSpecifier") { - specifiers.push(print(specifierPath)); - } else if (specifierType === "ExportDefaultSpecifier") { - defaultSpecifiers.push(print(specifierPath)); - } else if (specifierType === "ExportNamespaceSpecifier") { - namespaceSpecifiers.push(concat$6(["* as ", print(specifierPath)])); - } - }, "specifiers"); - const isNamespaceFollowed = namespaceSpecifiers.length !== 0 && specifiers.length !== 0; - const isDefaultFollowed = defaultSpecifiers.length !== 0 && (namespaceSpecifiers.length !== 0 || specifiers.length !== 0); - const canBreak = specifiers.length > 1 || defaultSpecifiers.length > 0 || decl.specifiers && decl.specifiers.some(node => node.comments); - let printed = ""; - - if (specifiers.length !== 0) { - if (canBreak) { - printed = group$2(concat$6(["{", indent$3(concat$6([options.bracketSpacing ? line$4 : softline$2, join$4(concat$6([",", line$4]), specifiers)])), ifBreak$1(shouldPrintComma(options) ? "," : ""), options.bracketSpacing ? line$4 : softline$2, "}"])); - } else { - printed = concat$6(["{", options.bracketSpacing ? " " : "", concat$6(specifiers), options.bracketSpacing ? " " : "", "}"]); - } - } + case "DeclareModuleExports": + return printFlowDeclaration$1(path, concat$x(["module.exports", ": ", path.call(print, "typeAnnotation"), semi])); - parts.push(decl.exportKind === "type" ? "type " : "", concat$6(defaultSpecifiers), concat$6([isDefaultFollowed ? ", " : ""]), concat$6(namespaceSpecifiers), concat$6([isNamespaceFollowed ? ", " : ""]), printed); - } else { - parts.push("{}"); - } + case "DeclareVariable": + return printFlowDeclaration$1(path, concat$x(["var ", path.call(print, "id"), semi])); - if (decl.source) { - parts.push(" from ", path.call(print, "source")); - } + case "DeclareOpaqueType": + case "OpaqueType": + { + parts.push("opaque type ", path.call(print, "id"), path.call(print, "typeParameters")); - parts.push(semi); - } + if (n.supertype) { + parts.push(": ", path.call(print, "supertype")); + } - return concat$6(parts); -} + if (n.impltype) { + parts.push(" = ", path.call(print, "impltype")); + } -function printFlowDeclaration(path, parts) { - const parentExportDecl = getParentExportDeclaration$1(path); + parts.push(semi); - if (parentExportDecl) { - assert$1.strictEqual(parentExportDecl.type, "DeclareExportDeclaration"); - } else { - // If the parent node has type DeclareExportDeclaration, then it - // will be responsible for printing the "declare" token. Otherwise - // it needs to be printed with this non-exported declaration node. - parts.unshift("declare "); - } + if (n.type === "DeclareOpaqueType") { + return printFlowDeclaration$1(path, concat$x(parts)); + } - return concat$6(parts); -} + return concat$x(parts); + } -function printTypeScriptModifiers(path, options, print) { - const n = path.getValue(); + case "EnumDeclaration": + return concat$x(["enum ", path.call(print, "id"), " ", path.call(print, "body")]); - if (!n.modifiers || !n.modifiers.length) { - return ""; - } + case "EnumBooleanBody": + case "EnumNumberBody": + case "EnumStringBody": + case "EnumSymbolBody": + { + if (n.type === "EnumSymbolBody" || n.explicitType) { + let type = null; - return concat$6([join$4(" ", path.map(print, "modifiers")), " "]); -} + switch (n.type) { + case "EnumBooleanBody": + type = "boolean"; + break; -function printTypeParameters(path, options, print, paramsKey) { - const n = path.getValue(); + case "EnumNumberBody": + type = "number"; + break; - if (!n[paramsKey]) { - return ""; - } // for TypeParameterDeclaration typeParameters is a single node + case "EnumStringBody": + type = "string"; + break; + case "EnumSymbolBody": + type = "symbol"; + break; + } - if (!Array.isArray(n[paramsKey])) { - return path.call(print, paramsKey); - } + parts.push("of ", type, " "); + } - const grandparent = path.getNode(2); - const greatGrandParent = path.getNode(3); - const greatGreatGrandParent = path.getNode(4); - const isParameterInTestCall = grandparent != null && isTestCall$1(grandparent); - const shouldInline = isParameterInTestCall || n[paramsKey].length === 0 || n[paramsKey].length === 1 && (shouldHugType(n[paramsKey][0]) || n[paramsKey][0].type === "GenericTypeAnnotation" && shouldHugType(n[paramsKey][0].id) || n[paramsKey][0].type === "TSTypeReference" && shouldHugType(n[paramsKey][0].typeName) || n[paramsKey][0].type === "NullableTypeAnnotation" || // See https://github.com/prettier/prettier/pull/6467 for the context. - greatGreatGrandParent && greatGreatGrandParent.type === "VariableDeclarator" && grandparent.type === "TSTypeAnnotation" && greatGrandParent.type !== "ArrowFunctionExpression" && n[paramsKey][0].type !== "TSUnionType" && n[paramsKey][0].type !== "UnionTypeAnnotation" && n[paramsKey][0].type !== "TSIntersectionType" && n[paramsKey][0].type !== "IntersectionTypeAnnotation" && n[paramsKey][0].type !== "TSConditionalType" && n[paramsKey][0].type !== "TSMappedType" && n[paramsKey][0].type !== "TSTypeOperator" && n[paramsKey][0].type !== "TSIndexedAccessType" && n[paramsKey][0].type !== "TSArrayType"); - - function printDanglingCommentsForInline(n) { - if (!hasDanglingComments$1(n)) { - return ""; - } + if (n.members.length === 0 && !n.hasUnknownMembers) { + parts.push(group$l(concat$x(["{", comments.printDanglingComments(path, options), softline$h, "}"]))); + } else { + const members = n.members.length ? [hardline$k, printArrayItems$1(path, options, "members", print), n.hasUnknownMembers || shouldPrintComma$8(options) ? "," : ""] : []; + parts.push(group$l(concat$x(["{", indent$p(concat$x([...members, ...(n.hasUnknownMembers ? [hardline$k, "..."] : [])])), comments.printDanglingComments(path, options, + /* sameIndent */ + true), hardline$k, "}"]))); + } - const hasOnlyBlockComments = n.comments.every(comments$1.isBlockComment); - const printed = comments.printDanglingComments(path, options, - /* sameIndent */ - hasOnlyBlockComments); + return concat$x(parts); + } - if (hasOnlyBlockComments) { - return printed; - } + case "EnumBooleanMember": + case "EnumNumberMember": + case "EnumStringMember": + return concat$x([path.call(print, "id"), " = ", typeof n.init === "object" ? path.call(print, "init") : String(n.init)]); - return concat$6([printed, hardline$4]); - } + case "EnumDefaultedMember": + return path.call(print, "id"); - if (shouldInline) { - return concat$6(["<", join$4(", ", path.map(print, paramsKey)), printDanglingCommentsForInline(n), ">"]); - } + case "FunctionTypeAnnotation": + case "TSFunctionType": + { + // FunctionTypeAnnotation is ambiguous: + // declare function foo(a: B): void; OR + // var A: (a: B) => void; + const parent = path.getParentNode(0); + const parentParent = path.getParentNode(1); + const parentParentParent = path.getParentNode(2); + let isArrowFunctionTypeAnnotation = n.type === "TSFunctionType" || !((parent.type === "ObjectTypeProperty" || parent.type === "ObjectTypeInternalSlot") && !parent.variance && !parent.optional && locStart$8(parent) === locStart$8(n) || parent.type === "ObjectTypeCallProperty" || parentParentParent && parentParentParent.type === "DeclareFunction"); + let needsColon = isArrowFunctionTypeAnnotation && (parent.type === "TypeAnnotation" || parent.type === "TSTypeAnnotation"); // Sadly we can't put it inside of FastPath::needsColon because we are + // printing ":" as part of the expression and it would put parenthesis + // around :( - return group$2(concat$6(["<", indent$3(concat$6([softline$2, join$4(concat$6([",", line$4]), path.map(print, paramsKey))])), ifBreak$1(options.parser !== "typescript" && options.parser !== "babel-ts" && shouldPrintComma(options, "all") ? "," : ""), softline$2, ">"])); -} + const needsParens = needsColon && isArrowFunctionTypeAnnotation && (parent.type === "TypeAnnotation" || parent.type === "TSTypeAnnotation") && parentParent.type === "ArrowFunctionExpression"; -function printClass(path, options, print) { - const n = path.getValue(); - const parts = []; + if (isObjectTypePropertyAFunction$2(parent)) { + isArrowFunctionTypeAnnotation = true; + needsColon = true; + } - if (n.abstract) { - parts.push("abstract "); - } + if (needsParens) { + parts.push("("); + } + + parts.push(printFunctionParameters$2(path, print, options, + /* expandArg */ + false, + /* printTypeParams */ + true)); // The returnType is not wrapped in a TypeAnnotation, so the colon + // needs to be added separately. + + if (n.returnType || n.predicate || n.typeAnnotation) { + parts.push(isArrowFunctionTypeAnnotation ? " => " : ": ", path.call(print, "returnType"), path.call(print, "predicate"), path.call(print, "typeAnnotation")); + } - parts.push("class"); + if (needsParens) { + parts.push(")"); + } - if (n.id) { - parts.push(" ", path.call(print, "id")); - } + return group$l(concat$x(parts)); + } - parts.push(path.call(print, "typeParameters")); - const partsGroup = []; + case "TSRestType": + return concat$x(["...", path.call(print, "typeAnnotation")]); - if (n.superClass) { - const printed = concat$6(["extends ", path.call(print, "superClass"), path.call(print, "superTypeParameters")]); // Keep old behaviour of extends in same line - // If there is only on extends and there are not comments + case "TSOptionalType": + return concat$x([path.call(print, "typeAnnotation"), "?"]); - if ((!n.implements || n.implements.length === 0) && (!n.superClass.comments || n.superClass.comments.length === 0)) { - parts.push(concat$6([" ", path.call(superClass => comments.printComments(superClass, () => printed, options), "superClass")])); - } else { - partsGroup.push(group$2(concat$6([line$4, path.call(superClass => comments.printComments(superClass, () => printed, options), "superClass")]))); - } - } else if (n.extends && n.extends.length > 0) { - parts.push(" extends ", join$4(", ", path.map(print, "extends"))); - } + case "FunctionTypeParam": + { + const name = n.name ? path.call(print, "name") : path.getParentNode().this === n ? "this" : ""; + return concat$x([name, printOptionalToken$6(path), name ? ": " : "", path.call(print, "typeAnnotation")]); + } - if (n.mixins && n.mixins.length > 0) { - partsGroup.push(line$4, "mixins ", group$2(indent$3(join$4(concat$6([",", line$4]), path.map(print, "mixins"))))); - } + case "DeclareInterface": + case "InterfaceDeclaration": + case "InterfaceTypeAnnotation": + case "TSInterfaceDeclaration": + return printInterface$1(path, options, print); - if (n.implements && n.implements.length > 0) { - partsGroup.push(line$4, "implements", group$2(indent$3(concat$6([line$4, join$4(concat$6([",", line$4]), path.map(print, "implements"))])))); - } + case "ClassImplements": + case "InterfaceExtends": + return concat$x([path.call(print, "id"), path.call(print, "typeParameters")]); - if (partsGroup.length > 0) { - parts.push(group$2(indent$3(concat$6(partsGroup)))); - } + case "TSClassImplements": + return concat$x([path.call(print, "expression"), path.call(print, "typeParameters")]); - if (n.body && n.body.comments && hasLeadingOwnLineComment$1(options.originalText, n.body, options)) { - parts.push(hardline$4); - } else { - parts.push(" "); - } + case "TSIntersectionType": + case "IntersectionTypeAnnotation": + { + const types = path.map(print, "types"); + const result = []; + let wasIndented = false; - parts.push(path.call(print, "body")); - return parts; -} + for (let i = 0; i < types.length; ++i) { + if (i === 0) { + result.push(types[i]); + } else if (isObjectType$3(n.types[i - 1]) && isObjectType$3(n.types[i])) { + // If both are objects, don't indent + result.push(concat$x([" & ", wasIndented ? indent$p(types[i]) : types[i]])); + } else if (!isObjectType$3(n.types[i - 1]) && !isObjectType$3(n.types[i])) { + // If no object is involved, go to the next line if it breaks + result.push(indent$p(concat$x([" &", line$j, types[i]]))); + } else { + // If you go from object to non-object or vis-versa, then inline it + if (i > 1) { + wasIndented = true; + } -function printOptionalToken(path) { - const node = path.getValue(); + result.push(" & ", i > 1 ? indent$p(types[i]) : types[i]); + } + } - if (!node.optional || // It's an optional computed method parsed by typescript-estree. - // "?" is printed in `printMethod`. - node.type === "Identifier" && node === path.getParentNode().key) { - return ""; - } + return group$l(concat$x(result)); + } - if (node.type === "OptionalCallExpression" || node.type === "OptionalMemberExpression" && node.computed) { - return "?."; - } + case "TSUnionType": + case "UnionTypeAnnotation": + { + // single-line variation + // A | B | C + // multi-line variation + // | A + // | B + // | C + const parent = path.getParentNode(); // If there's a leading comment, the parent is doing the indentation - return "?"; -} + const shouldIndent = parent.type !== "TypeParameterInstantiation" && parent.type !== "TSTypeParameterInstantiation" && parent.type !== "GenericTypeAnnotation" && parent.type !== "TSTypeReference" && parent.type !== "TSTypeAssertion" && parent.type !== "TupleTypeAnnotation" && parent.type !== "TSTupleType" && !(parent.type === "FunctionTypeParam" && !parent.name && path.getParentNode(1).this !== parent) && !((parent.type === "TypeAlias" || parent.type === "VariableDeclarator" || parent.type === "TSTypeAliasDeclaration") && hasLeadingOwnLineComment$4(options.originalText, n)); // { + // a: string + // } | null | void + // should be inlined and not be printed in the multi-line variant -function printMemberLookup(path, options, print) { - const property = path.call(print, "property"); - const n = path.getValue(); - const optional = printOptionalToken(path); + const shouldHug = shouldHugType$3(n); // We want to align the children but without its comment, so it looks like + // | child1 + // // comment + // | child2 - if (!n.computed) { - return concat$6([optional, ".", property]); - } + const printed = path.map(typePath => { + let printedType = typePath.call(print); - if (!n.property || isNumericLiteral$1(n.property)) { - return concat$6([optional, "[", property, "]"]); - } + if (!shouldHug) { + printedType = align$4(2, printedType); + } - return group$2(concat$6([optional, "[", indent$3(concat$6([softline$2, property])), softline$2, "]"])); -} + return comments.printComments(typePath, () => printedType, options); + }, "types"); -function printBindExpressionCallee(path, options, print) { - return concat$6(["::", path.call(print, "callee")]); -} // We detect calls on member expressions specially to format a -// common pattern better. The pattern we are looking for is this: -// -// arr -// .map(x => x + 1) -// .filter(x => x > 10) -// .some(x => x % 2) -// -// The way it is structured in the AST is via a nested sequence of -// MemberExpression and CallExpression. We need to traverse the AST -// and make groups out of it to print it in the desired way. + if (shouldHug) { + return join$f(" | ", printed); + } + const shouldAddStartLine = shouldIndent && !hasLeadingOwnLineComment$4(options.originalText, n); + const code = concat$x([ifBreak$d(concat$x([shouldAddStartLine ? line$j : "", "| "])), join$f(concat$x([line$j, "| "]), printed)]); -function printMemberChain(path, options, print) { - // The first phase is to linearize the AST by traversing it down. - // - // a().b() - // has the following AST structure: - // CallExpression(MemberExpression(CallExpression(Identifier))) - // and we transform it into - // [Identifier, CallExpression, MemberExpression, CallExpression] - const printedNodes = []; // Here we try to retain one typed empty line after each call expression or - // the first group whether it is in parentheses or not + if (needsParens_1(path, options)) { + return group$l(concat$x([indent$p(code), softline$h])); + } - function shouldInsertEmptyLineAfter(node) { - const { - originalText - } = options; - const nextCharIndex = getNextNonSpaceNonCommentCharacterIndex$3(originalText, node, options.locEnd); - const nextChar = originalText.charAt(nextCharIndex); // if it is cut off by a parenthesis, we only account for one typed empty - // line after that parenthesis + if (parent.type === "TupleTypeAnnotation" && parent.types.length > 1 || parent.type === "TSTupleType" && parent.elementTypes.length > 1) { + return group$l(concat$x([indent$p(concat$x([ifBreak$d(concat$x(["(", softline$h])), code])), softline$h, ifBreak$d(")")])); + } - if (nextChar === ")") { - return isNextLineEmptyAfterIndex$2(originalText, nextCharIndex + 1, options.locEnd); - } + return group$l(shouldIndent ? indent$p(code) : code); + } - return isNextLineEmpty$2(originalText, node, options.locEnd); - } + case "NullableTypeAnnotation": + return concat$x(["?", path.call(print, "typeAnnotation")]); - function rec(path) { - const node = path.getValue(); + case "Variance": + { + const { + kind + } = n; + assert__default['default'].ok(kind === "plus" || kind === "minus"); + return kind === "plus" ? "+" : "-"; + } - if ((node.type === "CallExpression" || node.type === "OptionalCallExpression") && (isMemberish$1(node.callee) || node.callee.type === "CallExpression" || node.callee.type === "OptionalCallExpression")) { - printedNodes.unshift({ - node, - printed: concat$6([comments.printComments(path, () => concat$6([printOptionalToken(path), printFunctionTypeParameters(path, options, print), printArgumentsList(path, options, print)]), options), shouldInsertEmptyLineAfter(node) ? hardline$4 : ""]) - }); - path.call(callee => rec(callee), "callee"); - } else if (isMemberish$1(node)) { - printedNodes.unshift({ - node, - needsParens: needsParens_1(path, options), - printed: comments.printComments(path, () => node.type === "OptionalMemberExpression" || node.type === "MemberExpression" ? printMemberLookup(path, options, print) : printBindExpressionCallee(path, options, print), options) - }); - path.call(object => rec(object), "object"); - } else if (node.type === "TSNonNullExpression") { - printedNodes.unshift({ - node, - printed: comments.printComments(path, () => "!", options) - }); - path.call(expression => rec(expression), "expression"); - } else { - printedNodes.unshift({ - node, - printed: path.call(print) - }); - } - } // Note: the comments of the root node have already been printed, so we - // need to extract this first call without printing them as they would - // if handled inside of the recursive call. + case "ObjectTypeCallProperty": + if (n.static) { + parts.push("static "); + } + parts.push(path.call(print, "value")); + return concat$x(parts); - const node = path.getValue(); - printedNodes.unshift({ - node, - printed: concat$6([printOptionalToken(path), printFunctionTypeParameters(path, options, print), printArgumentsList(path, options, print)]) - }); - path.call(callee => rec(callee), "callee"); // Once we have a linear list of printed nodes, we want to create groups out - // of it. - // - // a().b.c().d().e - // will be grouped as - // [ - // [Identifier, CallExpression], - // [MemberExpression, MemberExpression, CallExpression], - // [MemberExpression, CallExpression], - // [MemberExpression], - // ] - // so that we can print it as - // a() - // .b.c() - // .d() - // .e - // The first group is the first node followed by - // - as many CallExpression as possible - // < fn()()() >.something() - // - as many array accessors as possible - // < fn()[0][1][2] >.something() - // - then, as many MemberExpression as possible but the last one - // < this.items >.something() + case "ObjectTypeIndexer": + { + return concat$x([n.variance ? path.call(print, "variance") : "", "[", path.call(print, "id"), n.id ? ": " : "", path.call(print, "key"), "]: ", path.call(print, "value")]); + } - const groups = []; - let currentGroup = [printedNodes[0]]; - let i = 1; + case "ObjectTypeProperty": + { + let modifier = ""; - for (; i < printedNodes.length; ++i) { - if (printedNodes[i].node.type === "TSNonNullExpression" || printedNodes[i].node.type === "OptionalCallExpression" || printedNodes[i].node.type === "CallExpression" || (printedNodes[i].node.type === "MemberExpression" || printedNodes[i].node.type === "OptionalMemberExpression") && printedNodes[i].node.computed && isNumericLiteral$1(printedNodes[i].node.property)) { - currentGroup.push(printedNodes[i]); - } else { - break; - } - } + if (n.proto) { + modifier = "proto "; + } else if (n.static) { + modifier = "static "; + } - if (printedNodes[0].node.type !== "CallExpression" && printedNodes[0].node.type !== "OptionalCallExpression") { - for (; i + 1 < printedNodes.length; ++i) { - if (isMemberish$1(printedNodes[i].node) && isMemberish$1(printedNodes[i + 1].node)) { - currentGroup.push(printedNodes[i]); - } else { - break; + return concat$x([modifier, isGetterOrSetter$1(n) ? n.kind + " " : "", n.variance ? path.call(print, "variance") : "", printPropertyKey$2(path, options, print), printOptionalToken$6(path), isFunctionNotation$1(n) ? "" : ": ", path.call(print, "value")]); } - } - } - groups.push(currentGroup); - currentGroup = []; // Then, each following group is a sequence of MemberExpression followed by - // a sequence of CallExpression. To compute it, we keep adding things to the - // group until we has seen a CallExpression in the past and reach a - // MemberExpression + case "QualifiedTypeIdentifier": + return concat$x([path.call(print, "qualification"), ".", path.call(print, "id")]); - let hasSeenCallExpression = false; + case "StringLiteralTypeAnnotation": + return nodeStr(n, options); - for (; i < printedNodes.length; ++i) { - if (hasSeenCallExpression && isMemberish$1(printedNodes[i].node)) { - // [0] should be appended at the end of the group instead of the - // beginning of the next one - if (printedNodes[i].node.computed && isNumericLiteral$1(printedNodes[i].node.property)) { - currentGroup.push(printedNodes[i]); - continue; - } + case "NumberLiteralTypeAnnotation": + assert__default['default'].strictEqual(typeof n.value, "number"); + // fall through - groups.push(currentGroup); - currentGroup = []; - hasSeenCallExpression = false; - } + case "BigIntLiteralTypeAnnotation": + if (n.extra != null) { + return printNumber$2(n.extra.raw); + } - if (printedNodes[i].node.type === "CallExpression" || printedNodes[i].node.type === "OptionalCallExpression") { - hasSeenCallExpression = true; - } + return printNumber$2(n.raw); - currentGroup.push(printedNodes[i]); + case "DeclareTypeAlias": + case "TypeAlias": + { + if (n.type === "DeclareTypeAlias" || n.declare) { + parts.push("declare "); + } - if (printedNodes[i].node.comments && printedNodes[i].node.comments.some(comment => comment.trailing)) { - groups.push(currentGroup); - currentGroup = []; - hasSeenCallExpression = false; - } - } + const printed = printAssignmentRight$1(n.id, n.right, path.call(print, "right"), options); + parts.push("type ", path.call(print, "id"), path.call(print, "typeParameters"), " =", printed, semi); + return group$l(concat$x(parts)); + } - if (currentGroup.length > 0) { - groups.push(currentGroup); - } // There are cases like Object.keys(), Observable.of(), _.values() where - // they are the subject of all the chained calls and therefore should - // be kept on the same line: - // - // Object.keys(items) - // .filter(x => x) - // .map(x => x) - // - // In order to detect those cases, we use an heuristic: if the first - // node is an identifier with the name starting with a capital - // letter or just a sequence of _$. The rationale is that they are - // likely to be factories. + case "TypeCastExpression": + { + return concat$x(["(", path.call(print, "expression"), printTypeAnnotation$3(path, options, print), ")"]); + } + case "TypeParameterDeclaration": + case "TypeParameterInstantiation": + { + const printed = printTypeParameters$1(path, options, print, "params"); - function isFactory(name) { - return /^[A-Z]|^[_$]+$/.test(name); - } // In case the Identifier is shorter than tab width, we can keep the - // first call in a single line, if it's an ExpressionStatement. - // - // d3.scaleLinear() - // .domain([0, 100]) - // .range([0, width]); - // + if (options.parser === "flow") { + const start = locStart$8(n); + const end = locEnd$e(n); + const commentStartIndex = options.originalText.lastIndexOf("/*", start); + const commentEndIndex = options.originalText.indexOf("*/", end); + if (commentStartIndex !== -1 && commentEndIndex !== -1) { + const comment = options.originalText.slice(commentStartIndex + 2, commentEndIndex).trim(); - function isShort(name) { - return name.length <= options.tabWidth; - } + if (comment.startsWith("::") && !comment.includes("/*") && !comment.includes("*/")) { + return concat$x(["/*:: ", printed, " */"]); + } + } + } - function shouldNotWrap(groups) { - const parent = path.getParentNode(); - const isExpression = parent && parent.type === "ExpressionStatement"; - const hasComputed = groups[1].length && groups[1][0].node.computed; + return printed; + } - if (groups[0].length === 1) { - const firstNode = groups[0][0].node; - return firstNode.type === "ThisExpression" || firstNode.type === "Identifier" && (isFactory(firstNode.name) || isExpression && isShort(firstNode.name) || hasComputed); - } + case "TSTypeParameterDeclaration": + case "TSTypeParameterInstantiation": + return printTypeParameters$1(path, options, print, "params"); - const lastNode = getLast$2(groups[0]).node; - return (lastNode.type === "MemberExpression" || lastNode.type === "OptionalMemberExpression") && lastNode.property.type === "Identifier" && (isFactory(lastNode.property.name) || hasComputed); - } + case "TSTypeParameter": + case "TypeParameter": + { + const parent = path.getParentNode(); - const shouldMerge = groups.length >= 2 && !groups[1][0].node.comments && shouldNotWrap(groups); + if (parent.type === "TSMappedType") { + parts.push("[", path.call(print, "name")); - function printGroup(printedGroup) { - const printed = printedGroup.map(tuple => tuple.printed); // Checks if the last node (i.e. the parent node) needs parens and print - // accordingly + if (n.constraint) { + parts.push(" in ", path.call(print, "constraint")); + } - if (printedGroup.length > 0 && printedGroup[printedGroup.length - 1].needsParens) { - return concat$6(["(", ...printed, ")"]); - } + if (parent.nameType) { + parts.push(" as ", path.callParent(path => { + return path.call(print, "nameType"); + })); + } - return concat$6(printed); - } + parts.push("]"); + return concat$x(parts); + } - function printIndentedGroup(groups) { - if (groups.length === 0) { - return ""; - } + if (n.variance) { + parts.push(path.call(print, "variance")); + } - return indent$3(group$2(concat$6([hardline$4, join$4(hardline$4, groups.map(printGroup))]))); - } + parts.push(path.call(print, "name")); - const printedGroups = groups.map(printGroup); - const oneLine = concat$6(printedGroups); - const cutoff = shouldMerge ? 3 : 2; - const flatGroups = groups.reduce((res, group) => res.concat(group), []); - const hasComment = flatGroups.slice(1, -1).some(node => hasLeadingComment$3(node.node)) || flatGroups.slice(0, -1).some(node => hasTrailingComment$1(node.node)) || groups[cutoff] && hasLeadingComment$3(groups[cutoff][0].node); // If we only have a single `.`, we shouldn't do anything fancy and just - // render everything concatenated together. + if (n.bound) { + parts.push(": "); + parts.push(path.call(print, "bound")); + } - if (groups.length <= cutoff && !hasComment) { - if (isLongCurriedCallExpression$1(path)) { - return oneLine; - } + if (n.constraint) { + parts.push(" extends ", path.call(print, "constraint")); + } - return group$2(oneLine); - } // Find out the last node in the first group and check if it has an - // empty line after + if (n.default) { + parts.push(" = ", path.call(print, "default")); + } // Keep comma if the file extension is .tsx and + // has one type parameter that isn't extend with any types. + // Because, otherwise formatted result will be invalid as tsx. - const lastNodeBeforeIndent = getLast$2(shouldMerge ? groups.slice(1, 2)[0] : groups[0]).node; - const shouldHaveEmptyLineBeforeIndent = lastNodeBeforeIndent.type !== "CallExpression" && lastNodeBeforeIndent.type !== "OptionalCallExpression" && shouldInsertEmptyLineAfter(lastNodeBeforeIndent); - const expanded = concat$6([printGroup(groups[0]), shouldMerge ? concat$6(groups.slice(1, 2).map(printGroup)) : "", shouldHaveEmptyLineBeforeIndent ? hardline$4 : "", printIndentedGroup(groups.slice(shouldMerge ? 2 : 1))]); - const callExpressions = printedNodes.map(({ - node - }) => node).filter(isCallOrOptionalCallExpression$1); // We don't want to print in one line if the chain has: - // * A comment. - // * Non-trivial arguments. - // * Any group but the last one has a hard line. - // If the last group is a function it's okay to inline if it fits. + const grandParent = path.getNode(2); - if (hasComment || callExpressions.length > 2 && callExpressions.some(expr => !expr.arguments.every(arg => isSimpleCallArgument$1(arg, 0))) || printedGroups.slice(0, -1).some(willBreak$1) || - /** - * scopes.filter(scope => scope.value !== '').map((scope, i) => { - * // multi line content - * }) - */ - ((lastGroupDoc, lastGroupNode) => isCallOrOptionalCallExpression$1(lastGroupNode) && willBreak$1(lastGroupDoc))(getLast$2(printedGroups), getLast$2(getLast$2(groups)).node) && callExpressions.slice(0, -1).some(n => n.arguments.some(isFunctionOrArrowExpression$1))) { - return group$2(expanded); - } + if (getFunctionParameters$6(parent).length === 1 && isTSXFile$1(options) && !n.constraint && grandParent.type === "ArrowFunctionExpression") { + parts.push(","); + } - return concat$6([// We only need to check `oneLine` because if `expanded` is chosen - // that means that the parent group has already been broken - // naturally - willBreak$1(oneLine) || shouldHaveEmptyLineBeforeIndent ? breakParent$2 : "", conditionalGroup$1([oneLine, expanded])]); -} + return concat$x(parts); + } -function separatorNoWhitespace(isFacebookTranslationTag, child, childNode, nextNode) { - if (isFacebookTranslationTag) { - return ""; - } + case "TypeofTypeAnnotation": + return concat$x(["typeof ", path.call(print, "argument")]); - if (childNode.type === "JSXElement" && !childNode.closingElement || nextNode && nextNode.type === "JSXElement" && !nextNode.closingElement) { - return child.length === 1 ? softline$2 : hardline$4; - } + case "InferredPredicate": + return "%checks"; + // Unhandled types below. If encountered, nodes of these types should + // be either left alone or desugared into AST types that are fully + // supported by the pretty-printer. - return softline$2; -} + case "DeclaredPredicate": + return concat$x(["%checks(", path.call(print, "value"), ")"]); -function separatorWithWhitespace(isFacebookTranslationTag, child, childNode, nextNode) { - if (isFacebookTranslationTag) { - return hardline$4; - } + case "TSAbstractKeyword": + return "abstract"; - if (child.length === 1) { - return childNode.type === "JSXElement" && !childNode.closingElement || nextNode && nextNode.type === "JSXElement" && !nextNode.closingElement ? hardline$4 : softline$2; - } + case "AnyTypeAnnotation": + case "TSAnyKeyword": + return "any"; - return hardline$4; -} // JSX Children are strange, mostly for two reasons: -// 1. JSX reads newlines into string values, instead of skipping them like JS -// 2. up to one whitespace between elements within a line is significant, -// but not between lines. -// -// Leading, trailing, and lone whitespace all need to -// turn themselves into the rather ugly `{' '}` when breaking. -// -// We print JSX using the `fill` doc primitive. -// This requires that we give it an array of alternating -// content and whitespace elements. -// To ensure this we add dummy `""` content elements as needed. + case "TSAsyncKeyword": + return "async"; + case "BooleanTypeAnnotation": + case "TSBooleanKeyword": + return "boolean"; -function printJSXChildren(path, options, print, jsxWhitespace, isFacebookTranslationTag) { - const n = path.getValue(); - const children = []; // using `map` instead of `each` because it provides `i` + case "BigIntTypeAnnotation": + case "TSBigIntKeyword": + return "bigint"; - path.map((childPath, i) => { - const child = childPath.getValue(); + case "TSConstKeyword": + return "const"; - if (isLiteral$1(child)) { - const text = rawText$1(child); // Contains a non-whitespace character + case "TSDeclareKeyword": + return "declare"; - if (isMeaningfulJSXText$1(child)) { - const words = text.split(matchJsxWhitespaceRegex$1); // Starts with whitespace + case "TSExportKeyword": + return "export"; - if (words[0] === "") { - children.push(""); - words.shift(); + case "NullLiteralTypeAnnotation": + case "TSNullKeyword": + return "null"; - if (/\n/.test(words[0])) { - const next = n.children[i + 1]; - children.push(separatorWithWhitespace(isFacebookTranslationTag, words[1], child, next)); - } else { - children.push(jsxWhitespace); - } + case "TSNeverKeyword": + return "never"; - words.shift(); - } + case "NumberTypeAnnotation": + case "TSNumberKeyword": + return "number"; - let endWhitespace; // Ends with whitespace + case "TSObjectKeyword": + return "object"; - if (getLast$2(words) === "") { - words.pop(); - endWhitespace = words.pop(); - } // This was whitespace only without a new line. + case "TSProtectedKeyword": + return "protected"; + case "TSPrivateKeyword": + return "private"; - if (words.length === 0) { - return; - } + case "TSPublicKeyword": + return "public"; - words.forEach((word, i) => { - if (i % 2 === 1) { - children.push(line$4); - } else { - children.push(word); - } - }); + case "TSReadonlyKeyword": + return "readonly"; - if (endWhitespace !== undefined) { - if (/\n/.test(endWhitespace)) { - const next = n.children[i + 1]; - children.push(separatorWithWhitespace(isFacebookTranslationTag, getLast$2(children), child, next)); - } else { - children.push(jsxWhitespace); - } - } else { - const next = n.children[i + 1]; - children.push(separatorNoWhitespace(isFacebookTranslationTag, getLast$2(children), child, next)); - } - } else if (/\n/.test(text)) { - // Keep (up to one) blank line between tags/expressions/text. - // Note: We don't keep blank lines between text elements. - if (text.match(/\n/g).length > 1) { - children.push(""); - children.push(hardline$4); - } - } else { - children.push(""); - children.push(jsxWhitespace); - } - } else { - const printedChild = print(childPath); - children.push(printedChild); - const next = n.children[i + 1]; - const directlyFollowedByMeaningfulText = next && isMeaningfulJSXText$1(next); + case "SymbolTypeAnnotation": + case "TSSymbolKeyword": + return "symbol"; - if (directlyFollowedByMeaningfulText) { - const firstWord = rawText$1(next).trim().split(matchJsxWhitespaceRegex$1)[0]; - children.push(separatorNoWhitespace(isFacebookTranslationTag, firstWord, child, next)); - } else { - children.push(hardline$4); - } - } - }, "children"); - return children; -} // JSX expands children from the inside-out, instead of the outside-in. -// This is both to break children before attributes, -// and to ensure that when children break, their parents do as well. -// -// Any element that is written without any newlines and fits on a single line -// is left that way. -// Not only that, any user-written-line containing multiple JSX siblings -// should also be kept on one line if possible, -// so each user-written-line is wrapped in its own group. -// -// Elements that contain newlines or don't fit on a single line (recursively) -// are fully-split, using hardline and shouldBreak: true. -// -// To support that case properly, all leading and trailing spaces -// are stripped from the list of children, and replaced with a single hardline. + case "TSStaticKeyword": + return "static"; + case "StringTypeAnnotation": + case "TSStringKeyword": + return "string"; -function printJSXElement(path, options, print) { - const n = path.getValue(); + case "TSUndefinedKeyword": + return "undefined"; - if (n.type === "JSXElement" && isEmptyJSXElement$1(n)) { - return concat$6([path.call(print, "openingElement"), path.call(print, "closingElement")]); - } + case "TSUnknownKeyword": + return "unknown"; - const openingLines = n.type === "JSXElement" ? path.call(print, "openingElement") : path.call(print, "openingFragment"); - const closingLines = n.type === "JSXElement" ? path.call(print, "closingElement") : path.call(print, "closingFragment"); + case "VoidTypeAnnotation": + case "TSVoidKeyword": + return "void"; - if (n.children.length === 1 && n.children[0].type === "JSXExpressionContainer" && (n.children[0].expression.type === "TemplateLiteral" || n.children[0].expression.type === "TaggedTemplateExpression")) { - return concat$6([openingLines, concat$6(path.map(print, "children")), closingLines]); - } // Convert `{" "}` to text nodes containing a space. - // This makes it easy to turn them into `jsxWhitespace` which - // can then print as either a space or `{" "}` when breaking. + case "TSAsExpression": + return concat$x([path.call(print, "expression"), " as ", path.call(print, "typeAnnotation")]); + case "TSArrayType": + return concat$x([path.call(print, "elementType"), "[]"]); - n.children = n.children.map(child => { - if (isJSXWhitespaceExpression$1(child)) { - return { - type: "JSXText", - value: " ", - raw: " " - }; - } + case "TSPropertySignature": + { + if (n.export) { + parts.push("export "); + } - return child; - }); - const containsTag = n.children.filter(isJSXNode$1).length > 0; - const containsMultipleExpressions = n.children.filter(child => child.type === "JSXExpressionContainer").length > 1; - const containsMultipleAttributes = n.type === "JSXElement" && n.openingElement.attributes.length > 1; // Record any breaks. Should never go from true to false, only false to true. + if (n.accessibility) { + parts.push(n.accessibility + " "); + } - let forcedBreak = willBreak$1(openingLines) || containsTag || containsMultipleAttributes || containsMultipleExpressions; - const isMdxBlock = path.getParentNode().rootMarker === "mdx"; - const rawJsxWhitespace = options.singleQuote ? "{' '}" : '{" "}'; - const jsxWhitespace = isMdxBlock ? concat$6([" "]) : ifBreak$1(concat$6([rawJsxWhitespace, softline$2]), " "); - const isFacebookTranslationTag = n.openingElement && n.openingElement.name && n.openingElement.name.name === "fbt"; - const children = printJSXChildren(path, options, print, jsxWhitespace, isFacebookTranslationTag); - const containsText = n.children.some(child => isMeaningfulJSXText$1(child)); // We can end up we multiple whitespace elements with empty string - // content between them. - // We need to remove empty whitespace and softlines before JSX whitespace - // to get the correct output. + if (n.static) { + parts.push("static "); + } - for (let i = children.length - 2; i >= 0; i--) { - const isPairOfEmptyStrings = children[i] === "" && children[i + 1] === ""; - const isPairOfHardlines = children[i] === hardline$4 && children[i + 1] === "" && children[i + 2] === hardline$4; - const isLineFollowedByJSXWhitespace = (children[i] === softline$2 || children[i] === hardline$4) && children[i + 1] === "" && children[i + 2] === jsxWhitespace; - const isJSXWhitespaceFollowedByLine = children[i] === jsxWhitespace && children[i + 1] === "" && (children[i + 2] === softline$2 || children[i + 2] === hardline$4); - const isDoubleJSXWhitespace = children[i] === jsxWhitespace && children[i + 1] === "" && children[i + 2] === jsxWhitespace; - const isPairOfHardOrSoftLines = children[i] === softline$2 && children[i + 1] === "" && children[i + 2] === hardline$4 || children[i] === hardline$4 && children[i + 1] === "" && children[i + 2] === softline$2; + if (n.readonly) { + parts.push("readonly "); + } - if (isPairOfHardlines && containsText || isPairOfEmptyStrings || isLineFollowedByJSXWhitespace || isDoubleJSXWhitespace || isPairOfHardOrSoftLines) { - children.splice(i, 2); - } else if (isJSXWhitespaceFollowedByLine) { - children.splice(i + 1, 2); - } - } // Trim trailing lines (or empty strings) + parts.push(printPropertyKey$2(path, options, print), printOptionalToken$6(path)); + if (n.typeAnnotation) { + parts.push(": "); + parts.push(path.call(print, "typeAnnotation")); + } // This isn't valid semantically, but it's in the AST so we can print it. - while (children.length && (isLineNext$1(getLast$2(children)) || isEmpty$1(getLast$2(children)))) { - children.pop(); - } // Trim leading lines (or empty strings) + if (n.initializer) { + parts.push(" = ", path.call(print, "initializer")); + } - while (children.length && (isLineNext$1(children[0]) || isEmpty$1(children[0])) && (isLineNext$1(children[1]) || isEmpty$1(children[1]))) { - children.shift(); - children.shift(); - } // Tweak how we format children if outputting this element over multiple lines. - // Also detect whether we will force this element to output over multiple lines. + return concat$x(parts); + } + case "TSParameterProperty": + if (n.accessibility) { + parts.push(n.accessibility + " "); + } - const multilineChildren = []; - children.forEach((child, i) => { - // There are a number of situations where we need to ensure we display - // whitespace as `{" "}` when outputting this element over multiple lines. - if (child === jsxWhitespace) { - if (i === 1 && children[i - 1] === "") { - if (children.length === 2) { - // Solitary whitespace - multilineChildren.push(rawJsxWhitespace); - return; - } // Leading whitespace + if (n.export) { + parts.push("export "); + } + if (n.static) { + parts.push("static "); + } - multilineChildren.push(concat$6([rawJsxWhitespace, hardline$4])); - return; - } else if (i === children.length - 1) { - // Trailing whitespace - multilineChildren.push(rawJsxWhitespace); - return; - } else if (children[i - 1] === "" && children[i - 2] === hardline$4) { - // Whitespace after line break - multilineChildren.push(rawJsxWhitespace); - return; + if (n.readonly) { + parts.push("readonly "); } - } - multilineChildren.push(child); + parts.push(path.call(print, "parameter")); + return concat$x(parts); - if (willBreak$1(child)) { - forcedBreak = true; - } - }); // If there is text we use `fill` to fit as much onto each line as possible. - // When there is no text (just tags and expressions) we use `group` - // to output each on a separate line. + case "GenericTypeAnnotation": + case "TSTypeReference": + return concat$x([path.call(print, n.type === "TSTypeReference" ? "typeName" : "id"), printTypeParameters$1(path, options, print, "typeParameters")]); - const content = containsText ? fill$3(multilineChildren) : group$2(concat$6(multilineChildren), { - shouldBreak: true - }); + case "TSTypeQuery": + return concat$x(["typeof ", path.call(print, "exprName")]); - if (isMdxBlock) { - return content; - } + case "TSIndexSignature": + { + const parent = path.getParentNode(); // The typescript parser accepts multiple parameters here. If you're + // using them, it makes sense to have a trailing comma. But if you + // aren't, this is more like a computed property name than an array. + // So we leave off the trailing comma when there's just one parameter. - const multiLineElem = group$2(concat$6([openingLines, indent$3(concat$6([hardline$4, content])), hardline$4, closingLines])); + const trailingComma = n.parameters.length > 1 ? ifBreak$d(shouldPrintComma$8(options) ? "," : "") : ""; + const parametersGroup = group$l(concat$x([indent$p(concat$x([softline$h, join$f(concat$x([", ", softline$h]), path.map(print, "parameters"))])), trailingComma, softline$h])); + return concat$x([n.export ? "export " : "", n.accessibility ? concat$x([n.accessibility, " "]) : "", n.static ? "static " : "", n.readonly ? "readonly " : "", n.declare ? "declare " : "", "[", n.parameters ? parametersGroup : "", n.typeAnnotation ? "]: " : "]", n.typeAnnotation ? path.call(print, "typeAnnotation") : "", parent.type === "ClassBody" ? semi : ""]); + } - if (forcedBreak) { - return multiLineElem; - } + case "TSTypePredicate": + return concat$x([n.asserts ? "asserts " : "", path.call(print, "parameterName"), n.typeAnnotation ? concat$x([" is ", path.call(print, "typeAnnotation")]) : ""]); - return conditionalGroup$1([group$2(concat$6([openingLines, concat$6(children), closingLines])), multiLineElem]); -} + case "TSNonNullExpression": + return concat$x([path.call(print, "expression"), "!"]); -function maybeWrapJSXElementInParens(path, elem, options) { - const parent = path.getParentNode(); + case "ThisTypeAnnotation": + case "TSThisType": + return "this"; - if (!parent) { - return elem; - } + case "TSImportType": + return concat$x([!n.isTypeOf ? "" : "typeof ", "import(", path.call(print, n.parameter ? "parameter" : "argument"), ")", !n.qualifier ? "" : concat$x([".", path.call(print, "qualifier")]), printTypeParameters$1(path, options, print, "typeParameters")]); - const NO_WRAP_PARENTS = { - ArrayExpression: true, - JSXAttribute: true, - JSXElement: true, - JSXExpressionContainer: true, - JSXFragment: true, - ExpressionStatement: true, - CallExpression: true, - OptionalCallExpression: true, - ConditionalExpression: true, - JsExpressionRoot: true - }; + case "TSLiteralType": + return path.call(print, "literal"); - if (NO_WRAP_PARENTS[parent.type]) { - return elem; - } + case "TSIndexedAccessType": + return concat$x([path.call(print, "objectType"), "[", path.call(print, "indexType"), "]"]); - const shouldBreak = path.match(undefined, node => node.type === "ArrowFunctionExpression", isCallOrOptionalCallExpression$1, node => node.type === "JSXExpressionContainer"); - const needsParens = needsParens_1(path, options); - return group$2(concat$6([needsParens ? "" : ifBreak$1("("), indent$3(concat$6([softline$2, elem])), softline$2, needsParens ? "" : ifBreak$1(")")]), { - shouldBreak - }); -} + case "TSConstructSignatureDeclaration": + case "TSCallSignatureDeclaration": + case "TSConstructorType": + { + if (n.type !== "TSCallSignatureDeclaration") { + parts.push("new "); + } -function shouldInlineLogicalExpression(node) { - if (node.type !== "LogicalExpression") { - return false; - } + parts.push(group$l(printFunctionParameters$2(path, print, options, + /* expandArg */ + false, + /* printTypeParams */ + true))); - if (node.right.type === "ObjectExpression" && node.right.properties.length !== 0) { - return true; - } + if (n.returnType || n.typeAnnotation) { + const isType = n.type === "TSConstructorType"; + parts.push(isType ? " => " : ": ", path.call(print, "returnType"), path.call(print, "typeAnnotation")); + } - if (node.right.type === "ArrayExpression" && node.right.elements.length !== 0) { - return true; - } + return concat$x(parts); + } - if (isJSXNode$1(node.right)) { - return true; - } + case "TSTypeOperator": + return concat$x([n.operator, " ", path.call(print, "typeAnnotation")]); - return false; -} // For binary expressions to be consistent, we need to group -// subsequent operators with the same precedence level under a single -// group. Otherwise they will be nested such that some of them break -// onto new lines but not all. Operators with the same precedence -// level should either all break or not. Because we group them by -// precedence level and the AST is structured based on precedence -// level, things are naturally broken up correctly, i.e. `&&` is -// broken before `+`. + case "TSMappedType": + { + const shouldBreak = hasNewlineInRange$6(options.originalText, locStart$8(n), locEnd$e(n)); + return group$l(concat$x(["{", indent$p(concat$x([options.bracketSpacing ? line$j : softline$h, n.readonly ? concat$x([getTypeScriptMappedTypeModifier$1(n.readonly, "readonly"), " "]) : "", printTypeScriptModifiers$2(path, options, print), path.call(print, "typeParameter"), n.optional ? getTypeScriptMappedTypeModifier$1(n.optional, "?") : "", n.typeAnnotation ? ": " : "", path.call(print, "typeAnnotation"), ifBreak$d(semi, "")])), comments.printDanglingComments(path, options, + /* sameIndent */ + true), options.bracketSpacing ? line$j : softline$h, "}"]), { + shouldBreak + }); + } + case "TSMethodSignature": + parts.push(n.accessibility ? concat$x([n.accessibility, " "]) : "", n.export ? "export " : "", n.static ? "static " : "", n.readonly ? "readonly " : "", n.computed ? "[" : "", path.call(print, "key"), n.computed ? "]" : "", printOptionalToken$6(path), printFunctionParameters$2(path, print, options, + /* expandArg */ + false, + /* printTypeParams */ + true)); -function printBinaryishExpressions(path, print, options, isNested, isInsideParenthesis) { - let parts = []; - const node = path.getValue(); // We treat BinaryExpression and LogicalExpression nodes the same. + if (n.returnType || n.typeAnnotation) { + parts.push(": ", path.call(print, "returnType"), path.call(print, "typeAnnotation")); + } - if (isBinaryish$1(node)) { - // Put all operators with the same precedence level in the same - // group. The reason we only need to do this with the `left` - // expression is because given an expression like `1 + 2 - 3`, it - // is always parsed like `((1 + 2) - 3)`, meaning the `left` side - // is where the rest of the expression will exist. Binary - // expressions on the right side mean they have a difference - // precedence level and should be treated as a separate group, so - // print them normally. (This doesn't hold for the `**` operator, - // which is unique in that it is right-associative.) - if (shouldFlatten$1(node.operator, node.left.operator)) { - // Flatten them out by recursively calling this function. - parts = parts.concat(path.call(left => printBinaryishExpressions(left, print, options, - /* isNested */ - true, isInsideParenthesis), "left")); - } else { - parts.push(path.call(print, "left")); - } + return group$l(concat$x(parts)); - const shouldInline = shouldInlineLogicalExpression(node); - const lineBeforeOperator = (node.operator === "|>" || node.type === "NGPipeExpression" || node.operator === "|" && options.parser === "__vue_expression") && !hasLeadingOwnLineComment$1(options.originalText, node.right, options); - const operator = node.type === "NGPipeExpression" ? "|" : node.operator; - const rightSuffix = node.type === "NGPipeExpression" && node.arguments.length !== 0 ? group$2(indent$3(concat$6([softline$2, ": ", join$4(concat$6([softline$2, ":", ifBreak$1(" ")]), path.map(print, "arguments").map(arg => align$1(2, group$2(arg))))]))) : ""; - const right = shouldInline ? concat$6([operator, " ", path.call(print, "right"), rightSuffix]) : concat$6([lineBeforeOperator ? softline$2 : "", operator, lineBeforeOperator ? " " : line$4, path.call(print, "right"), rightSuffix]); // If there's only a single binary expression, we want to create a group - // in order to avoid having a small right part like -1 be on its own line. + case "TSNamespaceExportDeclaration": + parts.push("export as namespace ", path.call(print, "id")); - const parent = path.getParentNode(); - const shouldGroup = !(isInsideParenthesis && node.type === "LogicalExpression") && parent.type !== node.type && node.left.type !== node.type && node.right.type !== node.type; - parts.push(" ", shouldGroup ? group$2(right) : right); // The root comments are already printed, but we need to manually print - // the other ones since we don't call the normal print on BinaryExpression, - // only for the left and right parts + if (options.semi) { + parts.push(";"); + } - if (isNested && node.comments) { - parts = comments.printComments(path, () => concat$6(parts), options); - } - } else { - // Our stopping case. Simply print the node normally. - parts.push(path.call(print)); - } + return group$l(concat$x(parts)); - return parts; -} + case "TSEnumDeclaration": + if (n.declare) { + parts.push("declare "); + } -function printAssignmentRight(leftNode, rightNode, printedRight, options) { - if (hasLeadingOwnLineComment$1(options.originalText, rightNode, options)) { - return indent$3(concat$6([line$4, printedRight])); - } + if (n.modifiers) { + parts.push(printTypeScriptModifiers$2(path, options, print)); + } - const canBreak = isBinaryish$1(rightNode) && !shouldInlineLogicalExpression(rightNode) || rightNode.type === "ConditionalExpression" && isBinaryish$1(rightNode.test) && !shouldInlineLogicalExpression(rightNode.test) || rightNode.type === "StringLiteralTypeAnnotation" || rightNode.type === "ClassExpression" && rightNode.decorators && rightNode.decorators.length || (leftNode.type === "Identifier" || isStringLiteral$1(leftNode) || leftNode.type === "MemberExpression") && (isStringLiteral$1(rightNode) || isMemberExpressionChain$1(rightNode)) && // do not put values on a separate line from the key in json - options.parser !== "json" && options.parser !== "json5" || rightNode.type === "SequenceExpression"; + if (n.const) { + parts.push("const "); + } - if (canBreak) { - return group$2(indent$3(concat$6([line$4, printedRight]))); - } + parts.push("enum ", path.call(print, "id"), " "); - return concat$6([" ", printedRight]); -} + if (n.members.length === 0) { + parts.push(group$l(concat$x(["{", comments.printDanglingComments(path, options), softline$h, "}"]))); + } else { + parts.push(group$l(concat$x(["{", indent$p(concat$x([hardline$k, printArrayItems$1(path, options, "members", print), shouldPrintComma$8(options, "es5") ? "," : ""])), comments.printDanglingComments(path, options, + /* sameIndent */ + true), hardline$k, "}"]))); + } -function printAssignment(leftNode, printedLeft, operator, rightNode, printedRight, options) { - if (!rightNode) { - return printedLeft; - } + return concat$x(parts); - const printed = printAssignmentRight(leftNode, rightNode, printedRight, options); - return group$2(concat$6([printedLeft, operator, printed])); -} + case "TSEnumMember": + parts.push(path.call(print, "id")); -function adjustClause(node, clause, forceSpace) { - if (node.type === "EmptyStatement") { - return ";"; - } + if (n.initializer) { + parts.push(" = ", path.call(print, "initializer")); + } - if (node.type === "BlockStatement" || forceSpace) { - return concat$6([" ", clause]); - } + return concat$x(parts); - return indent$3(concat$6([line$4, clause])); -} + case "TSImportEqualsDeclaration": + if (n.isExport) { + parts.push("export "); + } -function nodeStr(node, options, isFlowOrTypeScriptDirectiveLiteral) { - const raw = rawText$1(node); - const isDirectiveLiteral = isFlowOrTypeScriptDirectiveLiteral || node.type === "DirectiveLiteral"; - return printString$1(raw, options, isDirectiveLiteral); -} + parts.push("import ", path.call(print, "id"), " = ", path.call(print, "moduleReference")); -function printRegex(node) { - const flags = node.flags.split("").sort().join(""); - return `/${node.pattern}/${flags}`; -} + if (options.semi) { + parts.push(";"); + } -function exprNeedsASIProtection(path, options) { - const node = path.getValue(); - const maybeASIProblem = needsParens_1(path, options) || node.type === "ParenthesizedExpression" || node.type === "TypeCastExpression" || node.type === "ArrowFunctionExpression" && !shouldPrintParamsWithoutParens(path, options) || node.type === "ArrayExpression" || node.type === "ArrayPattern" || node.type === "UnaryExpression" && node.prefix && (node.operator === "+" || node.operator === "-") || node.type === "TemplateLiteral" || node.type === "TemplateElement" || isJSXNode$1(node) || node.type === "BindExpression" && !node.object || node.type === "RegExpLiteral" || node.type === "Literal" && node.pattern || node.type === "Literal" && node.regex; + return group$l(concat$x(parts)); - if (maybeASIProblem) { - return true; - } + case "TSExternalModuleReference": + return concat$x(["require(", path.call(print, "expression"), ")"]); - if (!hasNakedLeftSide$2(node)) { - return false; - } + case "TSModuleDeclaration": + { + const parent = path.getParentNode(); + const isExternalModule = isLiteral$2(n.id); + const parentIsDeclaration = parent.type === "TSModuleDeclaration"; + const bodyIsDeclaration = n.body && n.body.type === "TSModuleDeclaration"; - return path.call(childPath => exprNeedsASIProtection(childPath, options), ...getLeftSidePathName$2(path, node)); -} + if (parentIsDeclaration) { + parts.push("."); + } else { + if (n.declare) { + parts.push("declare "); + } -function stmtNeedsASIProtection(path, options) { - const node = path.getNode(); + parts.push(printTypeScriptModifiers$2(path, options, print)); + const textBetweenNodeAndItsId = options.originalText.slice(locStart$8(n), locStart$8(n.id)); // Global declaration looks like this: + // (declare)? global { ... } - if (node.type !== "ExpressionStatement") { - return false; - } + const isGlobalDeclaration = n.id.type === "Identifier" && n.id.name === "global" && !/namespace|module/.test(textBetweenNodeAndItsId); - return path.call(childPath => exprNeedsASIProtection(childPath, options), "expression"); -} + if (!isGlobalDeclaration) { + parts.push(isExternalModule || /(^|\s)module(\s|$)/.test(textBetweenNodeAndItsId) ? "module " : "namespace "); + } + } -function shouldHugType(node) { - if (isSimpleFlowType$1(node) || isObjectType$1(node)) { - return true; - } + parts.push(path.call(print, "id")); - if (node.type === "UnionTypeAnnotation" || node.type === "TSUnionType") { - const voidCount = node.types.filter(n => n.type === "VoidTypeAnnotation" || n.type === "TSVoidKeyword" || n.type === "NullLiteralTypeAnnotation" || n.type === "TSNullKeyword").length; - const hasObject = node.types.some(n => n.type === "ObjectTypeAnnotation" || n.type === "TSTypeLiteral" || // This is a bit aggressive but captures Array<{x}> - n.type === "GenericTypeAnnotation" || n.type === "TSTypeReference"); + if (bodyIsDeclaration) { + parts.push(path.call(print, "body")); + } else if (n.body) { + parts.push(" ", group$l(path.call(print, "body"))); + } else { + parts.push(semi); + } - if (node.types.length - 1 === voidCount && hasObject) { - return true; - } - } + return concat$x(parts); + } - return false; -} + case "PrivateName": + // babel use `id`, meriyah use `name` + return concat$x(["#", path.call(print, n.id ? "id" : "name")]); + // TODO: Temporary auto-generated node type. To remove when typescript-estree has proper support for private fields. -function shouldHugArguments(fun) { - if (!fun || fun.rest) { - return false; - } + case "TSPrivateIdentifier": + return n.escapedText; - const params = fun.params || fun.parameters; + case "TSConditionalType": + return ternary(path, options, print, { + beforeParts: () => [path.call(print, "checkType"), " ", "extends", " ", path.call(print, "extendsType")], + afterParts: () => [], + shouldCheckJsx: false, + conditionalNodeType: "TSConditionalType", + consequentNodePropertyName: "trueType", + alternateNodePropertyName: "falseType", + testNodePropertyNames: ["checkType", "extendsType"] + }); - if (!params || params.length !== 1) { - return false; - } + case "TSInferType": + return concat$x(["infer", " ", path.call(print, "typeParameter")]); - const param = params[0]; - return !param.comments && (param.type === "ObjectPattern" || param.type === "ArrayPattern" || param.type === "Identifier" && param.typeAnnotation && (param.typeAnnotation.type === "TypeAnnotation" || param.typeAnnotation.type === "TSTypeAnnotation") && isObjectType$1(param.typeAnnotation.typeAnnotation) || param.type === "FunctionTypeParam" && isObjectType$1(param.typeAnnotation) || param.type === "AssignmentPattern" && (param.left.type === "ObjectPattern" || param.left.type === "ArrayPattern") && (param.right.type === "Identifier" || param.right.type === "ObjectExpression" && param.right.properties.length === 0 || param.right.type === "ArrayExpression" && param.right.elements.length === 0)); -} + case "InterpreterDirective": + parts.push("#!", n.value, hardline$k); -function printArrayItems(path, options, printPath, print) { - const printedElements = []; - let separatorParts = []; - path.each(childPath => { - printedElements.push(concat$6(separatorParts)); - printedElements.push(group$2(print(childPath))); - separatorParts = [",", line$4]; + if (isNextLineEmpty$9(options.originalText, n, locEnd$e)) { + parts.push(hardline$k); + } - if (childPath.getValue() && isNextLineEmpty$2(options.originalText, childPath.getValue(), options.locEnd)) { - separatorParts.push(softline$2); - } - }, printPath); - return concat$6(printedElements); -} + return concat$x(parts); -function printReturnAndThrowArgument(path, options, print) { - const node = path.getValue(); - const semi = options.semi ? ";" : ""; - const parts = []; + case "NGRoot": + return concat$x([].concat(path.call(print, "node"), !n.node.comments || n.node.comments.length === 0 ? [] : concat$x([" //", n.node.comments[0].value.trimEnd()]))); - if (node.argument) { - if (returnArgumentHasLeadingComment$1(options, node.argument)) { - parts.push(concat$6([" (", indent$3(concat$6([hardline$4, path.call(print, "argument")])), hardline$4, ")"])); - } else if (isBinaryish$1(node.argument) || node.argument.type === "SequenceExpression") { - parts.push(group$2(concat$6([ifBreak$1(" (", " "), indent$3(concat$6([softline$2, path.call(print, "argument")])), softline$2, ifBreak$1(")")]))); - } else { - parts.push(" ", path.call(print, "argument")); - } - } + case "NGChainedExpression": + return group$l(join$f(concat$x([";", line$j]), path.map(childPath => hasNgSideEffect$1(childPath) ? print(childPath) : concat$x(["(", print(childPath), ")"]), "expressions"))); - const lastComment = Array.isArray(node.comments) && node.comments[node.comments.length - 1]; - const isLastCommentLine = lastComment && (lastComment.type === "CommentLine" || lastComment.type === "Line"); + case "NGEmptyExpression": + return ""; - if (isLastCommentLine) { - parts.push(semi); - } + case "NGQuotedExpression": + return concat$x([n.prefix, ": ", n.value.trim()]); - if (hasDanglingComments$1(node)) { - parts.push(" ", comments.printDanglingComments(path, options, - /* sameIndent */ - true)); - } + case "NGMicrosyntax": + return concat$x(path.map((childPath, index) => concat$x([index === 0 ? "" : isNgForOf$1(childPath.getValue(), index, n) ? " " : concat$x([";", line$j]), print(childPath)]), "body")); - if (!isLastCommentLine) { - parts.push(semi); - } + case "NGMicrosyntaxKey": + return /^[$_a-z][\w$]*(-[$_a-z][\w$])*$/i.test(n.name) ? n.name : JSON.stringify(n.name); - return concat$6(parts); -} + case "NGMicrosyntaxExpression": + return concat$x([path.call(print, "expression"), n.alias === null ? "" : concat$x([" as ", path.call(print, "alias")])]); -function willPrintOwnComments(path -/*, options */ -) { - const node = path.getValue(); - const parent = path.getParentNode(); - return (node && (isJSXNode$1(node) || hasFlowShorthandAnnotationComment$2(node) || parent && (parent.type === "CallExpression" || parent.type === "OptionalCallExpression") && (hasFlowAnnotationComment$1(node.leadingComments) || hasFlowAnnotationComment$1(node.trailingComments))) || parent && (parent.type === "JSXSpreadAttribute" || parent.type === "JSXSpreadChild" || parent.type === "UnionTypeAnnotation" || parent.type === "TSUnionType" || (parent.type === "ClassDeclaration" || parent.type === "ClassExpression") && parent.superClass === node)) && (!hasIgnoreComment$2(path) || parent.type === "UnionTypeAnnotation" || parent.type === "TSUnionType"); -} + case "NGMicrosyntaxKeyedExpression": + { + const index = path.getName(); + const parentNode = path.getParentNode(); + const shouldNotPrintColon = isNgForOf$1(n, index, parentNode) || (index === 1 && (n.key.name === "then" || n.key.name === "else") || index === 2 && n.key.name === "else" && parentNode.body[index - 1].type === "NGMicrosyntaxKeyedExpression" && parentNode.body[index - 1].key.name === "then") && parentNode.body[0].type === "NGMicrosyntaxExpression"; + return concat$x([path.call(print, "key"), shouldNotPrintColon ? " " : ": ", path.call(print, "expression")]); + } -function canAttachComment(node) { - return node.type && node.type !== "CommentBlock" && node.type !== "CommentLine" && node.type !== "Line" && node.type !== "Block" && node.type !== "EmptyStatement" && node.type !== "TemplateElement" && node.type !== "Import"; -} + case "NGMicrosyntaxLet": + return concat$x(["let ", path.call(print, "key"), n.value === null ? "" : concat$x([" = ", path.call(print, "value")])]); -function printComment$1(commentPath, options) { - const comment = commentPath.getValue(); + case "NGMicrosyntaxAs": + return concat$x([path.call(print, "key"), " as ", path.call(print, "alias")]); - switch (comment.type) { - case "CommentBlock": - case "Block": - { - if (isIndentableBlockComment(comment)) { - const printed = printIndentableBlockComment(comment); // We need to prevent an edge case of a previous trailing comment - // printed as a `lineSuffix` which causes the comments to be - // interleaved. See https://github.com/prettier/prettier/issues/4412 - - if (comment.trailing && !hasNewline$4(options.originalText, options.locStart(comment), { - backwards: true - })) { - return concat$6([hardline$4, printed]); - } + case "PipelineBareFunction": + return path.call(print, "callee"); - return printed; - } + case "PipelineTopicExpression": + return path.call(print, "expression"); - const commentEnd = options.locEnd(comment); - const isInsideFlowComment = options.originalText.slice(commentEnd - 3, commentEnd) === "*-/"; - return "/*" + comment.value + (isInsideFlowComment ? "*-/" : "*/"); + case "PipelinePrimaryTopicReference": + { + parts.push("#"); + return concat$x(parts); } - case "CommentLine": - case "Line": - // Print shebangs with the proper comment characters - if (options.originalText.slice(options.locStart(comment)).startsWith("#!")) { - return "#!" + comment.value.trimEnd(); - } + case "ArgumentPlaceholder": + return "?"; + // These are not valid TypeScript. Printing them just for the sake of error recovery. + + case "TSJSDocAllType": + return "*"; + + case "TSJSDocUnknownType": + return "?"; - return "//" + comment.value.trimEnd(); + case "TSJSDocNullableType": + return concat$x(["?", path.call(print, "typeAnnotation")]); + + case "TSJSDocNonNullableType": + return concat$x(["!", path.call(print, "typeAnnotation")]); + + case "TSJSDocFunctionType": + return concat$x(["function(", // The parameters could be here, but typescript-estree doesn't convert them anyway (throws an error). + "): ", path.call(print, "typeAnnotation")]); default: - throw new Error("Not a comment: " + JSON.stringify(comment)); + /* istanbul ignore next */ + throw new Error("unknown type: " + JSON.stringify(n.type)); } } -function isIndentableBlockComment(comment) { - // If the comment has multiple lines and every line starts with a star - // we can fix the indentation of each line. The stars in the `/*` and - // `*/` delimiters are not included in the comment value, so add them - // back first. - const lines = `*${comment.value}*`.split("\n"); - return lines.length > 1 && lines.every(line => line.trim()[0] === "*"); +function nodeStr(node, options, isFlowOrTypeScriptDirectiveLiteral) { + const raw = rawText$3(node); + const isDirectiveLiteral = isFlowOrTypeScriptDirectiveLiteral || node.type === "DirectiveLiteral"; + return printString$2(raw, options, isDirectiveLiteral); } -function printIndentableBlockComment(comment) { - const lines = comment.value.split("\n"); - return concat$6(["/*", join$4(hardline$4, lines.map((line, index) => index === 0 ? line.trimEnd() : " " + (index < lines.length - 1 ? line.trim() : line.trimStart()))), "*/"]); +function printRegex(node) { + const flags = node.flags.split("").sort().join(""); + return `/${node.pattern}/${flags}`; +} + +function canAttachComment(node) { + return node.type && node.type !== "CommentBlock" && node.type !== "CommentLine" && node.type !== "Line" && node.type !== "Block" && node.type !== "EmptyStatement" && node.type !== "TemplateElement" && node.type !== "Import"; } var printerEstree = { - preprocess: preprocess_1, + preprocess: printPreprocess, print: genericPrint, embed: embed_1, insertPragma: insertPragma$1, massageAstNode: clean_1, hasPrettierIgnore: hasPrettierIgnore$1, - willPrintOwnComments, + willPrintOwnComments: comments$1.willPrintOwnComments, canAttachComment, - printComment: printComment$1, - isBlockComment: comments$1.isBlockComment, + printComment: printComment$2, + isBlockComment: isBlockComment$9, handleComments: { ownLine: comments$1.handleOwnLineComment, endOfLine: comments$1.handleEndOfLineComment, @@ -43001,30 +47149,32 @@ var printerEstree = { }; const { - concat: concat$7, - hardline: hardline$5, - indent: indent$4, - join: join$5 -} = document.builders; + builders: { + concat: concat$y, + hardline: hardline$l, + indent: indent$q, + join: join$g + } +} = document; function genericPrint$1(path, options, print) { const node = path.getValue(); switch (node.type) { case "JsonRoot": - return concat$7([path.call(print, "node"), hardline$5]); + return concat$y([path.call(print, "node"), hardline$l]); case "ArrayExpression": - return node.elements.length === 0 ? "[]" : concat$7(["[", indent$4(concat$7([hardline$5, join$5(concat$7([",", hardline$5]), path.map(print, "elements"))])), hardline$5, "]"]); + return node.elements.length === 0 ? "[]" : concat$y(["[", indent$q(concat$y([hardline$l, join$g(concat$y([",", hardline$l]), path.map(print, "elements"))])), hardline$l, "]"]); case "ObjectExpression": - return node.properties.length === 0 ? "{}" : concat$7(["{", indent$4(concat$7([hardline$5, join$5(concat$7([",", hardline$5]), path.map(print, "properties"))])), hardline$5, "}"]); + return node.properties.length === 0 ? "{}" : concat$y(["{", indent$q(concat$y([hardline$l, join$g(concat$y([",", hardline$l]), path.map(print, "properties"))])), hardline$l, "}"]); case "ObjectProperty": - return concat$7([path.call(print, "key"), ": ", path.call(print, "value")]); + return concat$y([path.call(print, "key"), ": ", path.call(print, "value")]); case "UnaryExpression": - return concat$7([node.operator === "+" ? "" : node.operator, path.call(print, "argument")]); + return concat$y([node.operator === "+" ? "" : node.operator, path.call(print, "argument")]); case "NullLiteral": return "null"; @@ -43045,30 +47195,30 @@ function genericPrint$1(path, options, print) { } } +const ignoredProperties$1 = new Set(["start", "end", "extra", "loc", "comments", "errors", "range"]); + function clean$1(node, newNode /*, parent*/ ) { - delete newNode.start; - delete newNode.end; - delete newNode.extra; - delete newNode.loc; - delete newNode.comments; - delete newNode.errors; + const { + type + } = node; - if (node.type === "Identifier") { + if (type === "Identifier") { return { type: "StringLiteral", value: node.name }; } - if (node.type === "UnaryExpression" && node.operator === "+") { + if (type === "UnaryExpression" && node.operator === "+") { return newNode.argument; } } +clean$1.ignoredProperties = ignoredProperties$1; var printerEstreeJson = { - preprocess: preprocess_1, + preprocess: printPreprocess, print: genericPrint$1, massageAstNode: clean$1 }; @@ -43211,17 +47361,6 @@ var options$2 = { } }; -var createLanguage = function (linguistData, override) { - const { - languageId - } = linguistData, - rest = _objectWithoutPropertiesLoose(linguistData, ["languageId"]); - - return Object.assign({ - linguistLanguageId: languageId - }, rest, {}, override(linguistData)); -}; - var name$2 = "JavaScript"; var type = "programming"; var tmScope = "source.js"; @@ -43265,13 +47404,14 @@ var interpreters = [ "gjs", "js", "node", + "nodejs", "qjs", "rhino", "v8", "v8-shell" ]; var languageId = 183; -var JavaScript = { +var require$$0$2 = { name: name$2, type: type, tmScope: tmScope, @@ -43286,26 +47426,9 @@ var JavaScript = { languageId: languageId }; -var JavaScript$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - name: name$2, - type: type, - tmScope: tmScope, - aceMode: aceMode, - codemirrorMode: codemirrorMode, - codemirrorMimeType: codemirrorMimeType, - color: color, - aliases: aliases, - extensions: extensions, - filenames: filenames, - interpreters: interpreters, - languageId: languageId, - 'default': JavaScript -}); - var name$3 = "JSX"; var type$1 = "programming"; -var group$3 = "JavaScript"; +var group$m = "JavaScript"; var extensions$1 = [ ".jsx" ]; @@ -43314,10 +47437,10 @@ var aceMode$1 = "javascript"; var codemirrorMode$1 = "jsx"; var codemirrorMimeType$1 = "text/jsx"; var languageId$1 = 178; -var JSX = { +var require$$1 = { name: name$3, type: type$1, - group: group$3, + group: group$m, extensions: extensions$1, tmScope: tmScope$1, aceMode: aceMode$1, @@ -43326,20 +47449,6 @@ var JSX = { languageId: languageId$1 }; -var JSX$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - name: name$3, - type: type$1, - group: group$3, - extensions: extensions$1, - tmScope: tmScope$1, - aceMode: aceMode$1, - codemirrorMode: codemirrorMode$1, - codemirrorMimeType: codemirrorMimeType$1, - languageId: languageId$1, - 'default': JSX -}); - var name$4 = "TypeScript"; var type$2 = "programming"; var color$1 = "#2b7489"; @@ -43358,7 +47467,7 @@ var aceMode$2 = "typescript"; var codemirrorMode$2 = "javascript"; var codemirrorMimeType$2 = "application/typescript"; var languageId$2 = 378; -var TypeScript = { +var require$$2 = { name: name$4, type: type$2, color: color$1, @@ -43372,25 +47481,9 @@ var TypeScript = { languageId: languageId$2 }; -var TypeScript$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - name: name$4, - type: type$2, - color: color$1, - aliases: aliases$1, - interpreters: interpreters$1, - extensions: extensions$2, - tmScope: tmScope$2, - aceMode: aceMode$2, - codemirrorMode: codemirrorMode$2, - codemirrorMimeType: codemirrorMimeType$2, - languageId: languageId$2, - 'default': TypeScript -}); - var name$5 = "TSX"; var type$3 = "programming"; -var group$4 = "TypeScript"; +var group$n = "TypeScript"; var extensions$3 = [ ".tsx" ]; @@ -43399,10 +47492,10 @@ var aceMode$3 = "javascript"; var codemirrorMode$3 = "jsx"; var codemirrorMimeType$3 = "text/jsx"; var languageId$3 = 94901924; -var TSX = { +var require$$3 = { name: name$5, type: type$3, - group: group$4, + group: group$n, extensions: extensions$3, tmScope: tmScope$3, aceMode: aceMode$3, @@ -43411,20 +47504,6 @@ var TSX = { languageId: languageId$3 }; -var TSX$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - name: name$5, - type: type$3, - group: group$4, - extensions: extensions$3, - tmScope: tmScope$3, - aceMode: aceMode$3, - codemirrorMode: codemirrorMode$3, - codemirrorMimeType: codemirrorMimeType$3, - languageId: languageId$3, - 'default': TSX -}); - var name$6 = "JSON"; var type$4 = "data"; var tmScope$4 = "source.json"; @@ -43460,7 +47539,7 @@ var filenames$1 = [ "mcmod.info" ]; var languageId$4 = 174; -var _JSON = { +var require$$4$1 = { name: name$6, type: type$4, tmScope: tmScope$4, @@ -43473,24 +47552,9 @@ var _JSON = { languageId: languageId$4 }; -var _JSON$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - name: name$6, - type: type$4, - tmScope: tmScope$4, - aceMode: aceMode$4, - codemirrorMode: codemirrorMode$4, - codemirrorMimeType: codemirrorMimeType$4, - searchable: searchable, - extensions: extensions$4, - filenames: filenames$1, - languageId: languageId$4, - 'default': _JSON -}); - var name$7 = "JSON with Comments"; var type$5 = "data"; -var group$5 = "JSON"; +var group$o = "JSON"; var tmScope$5 = "source.js"; var aceMode$5 = "javascript"; var codemirrorMode$5 = "javascript"; @@ -43520,15 +47584,17 @@ var filenames$2 = [ ".jscsrc", ".jshintrc", ".jslintrc", + "devcontainer.json", "jsconfig.json", "language-configuration.json", - "tsconfig.json" + "tsconfig.json", + "tslint.json" ]; var languageId$5 = 423; -var JSON_with_Comments = { +var require$$5 = { name: name$7, type: type$5, - group: group$5, + group: group$o, tmScope: tmScope$5, aceMode: aceMode$5, codemirrorMode: codemirrorMode$5, @@ -43539,22 +47605,6 @@ var JSON_with_Comments = { languageId: languageId$5 }; -var JSON_with_Comments$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - name: name$7, - type: type$5, - group: group$5, - tmScope: tmScope$5, - aceMode: aceMode$5, - codemirrorMode: codemirrorMode$5, - codemirrorMimeType: codemirrorMimeType$5, - aliases: aliases$2, - extensions: extensions$5, - filenames: filenames$2, - languageId: languageId$5, - 'default': JSON_with_Comments -}); - var name$8 = "JSON5"; var type$6 = "data"; var extensions$6 = [ @@ -43565,7 +47615,7 @@ var aceMode$6 = "javascript"; var codemirrorMode$6 = "javascript"; var codemirrorMimeType$6 = "application/json"; var languageId$6 = 175; -var JSON5 = { +var require$$6 = { name: name$8, type: type$6, extensions: extensions$6, @@ -43576,49 +47626,24 @@ var JSON5 = { languageId: languageId$6 }; -var JSON5$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - name: name$8, - type: type$6, - extensions: extensions$6, - tmScope: tmScope$6, - aceMode: aceMode$6, - codemirrorMode: codemirrorMode$6, - codemirrorMimeType: codemirrorMimeType$6, - languageId: languageId$6, - 'default': JSON5 -}); - -var require$$0$1 = getCjsExportFromNamespace(JavaScript$1); - -var require$$1 = getCjsExportFromNamespace(JSX$1); - -var require$$2 = getCjsExportFromNamespace(TypeScript$1); - -var require$$3 = getCjsExportFromNamespace(TSX$1); - -var require$$4$1 = getCjsExportFromNamespace(_JSON$1); - -var require$$5 = getCjsExportFromNamespace(JSON_with_Comments$1); - -var require$$6 = getCjsExportFromNamespace(JSON5$1); - -const languages = [createLanguage(require$$0$1, data => ({ +const languages = [createLanguage(require$$0$2, data => ({ since: "0.0.0", - parsers: ["babel", "flow"], + parsers: ["babel", "espree", "meriyah", "babel-flow", "babel-ts", "flow", "typescript"], vscodeLanguageIds: ["javascript", "mongo"], - interpreters: data.interpreters.concat(["nodejs"]) -})), createLanguage(require$$0$1, () => ({ + extensions: [...data.extensions, // WeiXin Script (Weixin Mini Programs) + // https://developers.weixin.qq.com/miniprogram/en/dev/framework/view/wxs/ + ".wxs"] +})), createLanguage(require$$0$2, () => ({ name: "Flow", since: "0.0.0", - parsers: ["babel", "flow"], + parsers: ["flow", "babel-flow"], vscodeLanguageIds: ["javascript"], aliases: [], filenames: [], extensions: [".js.flow"] })), createLanguage(require$$1, () => ({ since: "0.0.0", - parsers: ["babel", "flow"], + parsers: ["babel", "babel-flow", "babel-ts", "flow", "typescript", "espree", "meriyah"], vscodeLanguageIds: ["javascriptreact"] })), createLanguage(require$$2, () => ({ since: "1.4.0", @@ -43640,12 +47665,13 @@ const languages = [createLanguage(require$$0$1, data => ({ since: "1.5.0", parsers: ["json"], vscodeLanguageIds: ["json"], - filenames: data.filenames.concat([".prettierrc"]) + filenames: [...data.filenames, ".prettierrc"], + extensions: data.extensions.filter(extension => extension !== ".jsonl") })), createLanguage(require$$5, data => ({ since: "1.5.0", parsers: ["json"], vscodeLanguageIds: ["jsonc"], - filenames: data.filenames.concat([".eslintrc"]) + filenames: [...data.filenames, ".eslintrc"] })), createLanguage(require$$6, () => ({ since: "1.13.0", parsers: ["json5"], @@ -43655,37 +47681,129 @@ const printers = { estree: printerEstree, "estree-json": printerEstreeJson }; +const parsers = { + // JS - Babel + get babel() { + return require("./parser-babel").parsers.babel; + }, + + get "babel-flow"() { + return require("./parser-babel").parsers["babel-flow"]; + }, + + get "babel-ts"() { + return require("./parser-babel").parsers["babel-ts"]; + }, + + get json() { + return require("./parser-babel").parsers.json; + }, + + get json5() { + return require("./parser-babel").parsers.json5; + }, + + get "json-stringify"() { + return require("./parser-babel").parsers["json-stringify"]; + }, + + get __js_expression() { + return require("./parser-babel").parsers.__js_expression; + }, + + get __vue_expression() { + return require("./parser-babel").parsers.__vue_expression; + }, + + get __vue_event_binding() { + return require("./parser-babel").parsers.__vue_event_binding; + }, + + // JS - Flow + get flow() { + return require("./parser-flow").parsers.flow; + }, + + // JS - TypeScript + get typescript() { + return require("./parser-typescript").parsers.typescript; + }, + + // JS - Angular Action + get __ng_action() { + return require("./parser-angular").parsers.__ng_action; + }, + + // JS - Angular Binding + get __ng_binding() { + return require("./parser-angular").parsers.__ng_binding; + }, + + // JS - Angular Interpolation + get __ng_interpolation() { + return require("./parser-angular").parsers.__ng_interpolation; + }, + + // JS - Angular Directive + get __ng_directive() { + return require("./parser-angular").parsers.__ng_directive; + }, + + // JS - espree + get espree() { + return require("./parser-espree").parsers.espree; + }, + + // JS - meriyah + get meriyah() { + return require("./parser-meriyah").parsers.meriyah; + } + +}; var languageJs = { languages, options: options$2, - printers + printers, + parsers }; -function clean$2(ast, newObj, parent) { - ["raw", // front-matter - "raws", "sourceIndex", "source", "before", "after", "trailingComma"].forEach(name => { - delete newObj[name]; - }); +const { + isFrontMatterNode: isFrontMatterNode$1 +} = util; +const ignoredProperties$2 = new Set(["raw", // front-matter +"raws", "sourceIndex", "source", "before", "after", "trailingComma"]); - if (ast.type === "yaml") { +function clean$2(ast, newObj, parent) { + if (isFrontMatterNode$1(ast) && ast.lang === "yaml") { delete newObj.value; - } // --insert-pragma + } + if (ast.type === "css-comment" && parent.type === "css-root" && parent.nodes.length !== 0) { + // --insert-pragma + // first non-front-matter comment + if (parent.nodes[0] === ast || isFrontMatterNode$1(parent.nodes[0]) && parent.nodes[1] === ast) { + /** + * something + * + * @format + */ + delete newObj.text; // standalone pragma + + if (/^\*\s*@(format|prettier)\s*$/.test(ast.text)) { + return null; + } + } // Last comment is not parsed, when omitting semicolon, #8675 - if (ast.type === "css-comment" && parent.type === "css-root" && parent.nodes.length !== 0 && ( // first non-front-matter comment - parent.nodes[0] === ast || (parent.nodes[0].type === "yaml" || parent.nodes[0].type === "toml") && parent.nodes[1] === ast)) { - /** - * something - * - * @format - */ - delete newObj.text; // standalone pragma - if (/^\*\s*@(format|prettier)\s*$/.test(ast.text)) { + if (parent.type === "css-root" && getLast(parent.nodes) === ast) { return null; } } + if (ast.type === "value-root") { + delete newObj.text; + } + if (ast.type === "media-query" || ast.type === "media-query-list" || ast.type === "media-feature-expression") { delete newObj.value; } @@ -43736,13 +47854,13 @@ function clean$2(ast, newObj, parent) { } if (newObj.value) { - newObj.value = newObj.value.trim().replace(/^['"]|['"]$/g, ""); + newObj.value = newObj.value.trim().replace(/^["']|["']$/g, ""); delete newObj.quoted; } } if ((ast.type === "media-value" || ast.type === "media-type" || ast.type === "value-number" || ast.type === "selector-root-invalid" || ast.type === "selector-class" || ast.type === "selector-combinator" || ast.type === "selector-tag") && newObj.value) { - newObj.value = newObj.value.replace(/([\d.eE+-]+)([a-zA-Z]*)/g, (match, numStr, unit) => { + newObj.value = newObj.value.replace(/([\d+.Ee-]+)([A-Za-z]*)/g, (match, numStr, unit) => { const num = Number(numStr); return isNaN(num) ? match : num + unit.toLowerCase(); }); @@ -43767,53 +47885,30 @@ function clean$2(ast, newObj, parent) { } } +clean$2.ignoredProperties = ignoredProperties$2; + function cleanCSSStrings(value) { - return value.replace(/'/g, '"').replace(/\\([^a-fA-F\d])/g, "$1"); + return value.replace(/'/g, '"').replace(/\\([^\dA-Fa-f])/g, "$1"); } var clean_1$1 = clean$2; const { builders: { - hardline: hardline$6, - literalline: literalline$3, - concat: concat$8, + hardline: hardline$m, + concat: concat$z, markAsRoot: markAsRoot$1 - }, - utils: { - mapDoc: mapDoc$2 } } = document; - -function embed$1(path, print, textToDoc -/*, options */ -) { - const node = path.getValue(); - - if (node.type === "yaml") { - return markAsRoot$1(concat$8(["---", hardline$6, node.value.trim() ? replaceNewlinesWithLiterallines(textToDoc(node.value, { - parser: "yaml" - })) : "", "---", hardline$6])); - } - - return null; - - function replaceNewlinesWithLiterallines(doc) { - return mapDoc$2(doc, currentDoc => typeof currentDoc === "string" && currentDoc.includes("\n") ? concat$8(currentDoc.split(/(\n)/g).map((v, i) => i % 2 === 0 ? v : literalline$3)) : currentDoc); - } -} - -var embed_1$1 = embed$1; - const DELIMITER_MAP = { "---": "yaml", "+++": "toml" }; -function parse$5(text) { - const delimiterRegex = Object.keys(DELIMITER_MAP).map(escapeStringRegexp$2).join("|"); +function parse$7(text) { + const delimiterRegex = Object.keys(DELIMITER_MAP).map(escapeStringRegexp).join("|"); const match = text.match( // trailing spaces after delimiters are allowed - new RegExp(`^(${delimiterRegex})[^\\n\\S]*\\n(?:([\\s\\S]*?)\\n)?\\1[^\\n\\S]*(\\n|$)`)); + new RegExp(`^(${delimiterRegex})([^\\n]*)\\n(?:([\\s\\S]*?)\\n)?\\1[^\\n\\S]*(\\n|$)`)); if (match === null) { return { @@ -43822,10 +47917,17 @@ function parse$5(text) { }; } - const [raw, delimiter, value] = match; + const [raw, delimiter, language, value] = match; + let lang = DELIMITER_MAP[delimiter]; + + if (lang !== "toml" && language && language.trim()) { + lang = language.trim(); + } + return { frontMatter: { - type: DELIMITER_MAP[delimiter], + type: "front-matter", + lang, value, raw: raw.replace(/\n$/, "") }, @@ -43833,230 +47935,68 @@ function parse$5(text) { }; } -var frontMatter = parse$5; - -function hasPragma$1(text) { - return pragma.hasPragma(frontMatter(text).content); -} - -function insertPragma$2(text) { - const { - frontMatter: frontMatter$1, - content - } = frontMatter(text); - return (frontMatter$1 ? frontMatter$1.raw + "\n\n" : "") + pragma.insertPragma(content); -} - -var pragma$1 = { - hasPragma: hasPragma$1, - insertPragma: insertPragma$2 -}; - -var lineColumnToIndex = function (lineColumn, text) { - let index = 0; - - for (let i = 0; i < lineColumn.line - 1; ++i) { - index = text.indexOf("\n", index) + 1; - - if (index === -1) { - return -1; - } +function print$1(node, textToDoc) { + if (node.lang === "yaml") { + const value = node.value.trim(); + const doc = value ? textToDoc(value, { + parser: "yaml" + }, { + stripTrailingHardline: true + }) : ""; + return markAsRoot$1(concat$z(["---", hardline$m, doc, doc ? hardline$m : "", "---"])); } +} - return index + lineColumn.column; +var frontMatter = { + parse: parse$7, + print: print$1 }; const { - getLast: getLast$3, - skipEverythingButNewLine: skipEverythingButNewLine$2 -} = util$1; - -function calculateLocStart(node, text) { - if (node.source) { - return lineColumnToIndex(node.source.start, text) - 1; - } - - return null; -} - -function calculateLocEnd(node, text) { - if (node.type === "css-comment" && node.inline) { - return skipEverythingButNewLine$2(text, node.source.startOffset); - } - - const endNode = node.nodes && getLast$3(node.nodes); - - if (endNode && node.source && !node.source.end) { - node = endNode; - } - - if (node.source && node.source.end) { - return lineColumnToIndex(node.source.end, text); + builders: { + hardline: hardline$n, + concat: concat$A } +} = document; +const { + print: printFrontMatter +} = frontMatter; - return null; -} - -function calculateLoc(node, text) { - if (node && typeof node === "object") { - if (node.source) { - node.source.startOffset = calculateLocStart(node, text); - node.source.endOffset = calculateLocEnd(node, text); - } +function embed$1(path, print, textToDoc +/*, options */ +) { + const node = path.getValue(); - for (const key in node) { - calculateLoc(node[key], text); - } + if (node.type === "front-matter") { + const doc = printFrontMatter(node, textToDoc); + return doc ? concat$A([doc, hardline$n]) : ""; } } -/** - * Workaround for a bug: quotes in inline comments corrupt loc data of subsequent nodes. - * This function replaces the quotes with U+FFFE and U+FFFF. Later, when the comments are printed, - * their content is extracted from the original text or restored by replacing the placeholder - * characters back with quotes. - * - https://github.com/prettier/prettier/issues/7780 - * - https://github.com/shellscape/postcss-less/issues/145 - * - About noncharacters (U+FFFE and U+FFFF): http://www.unicode.org/faq/private_use.html#nonchar1 - * @param text {string} - */ - -function replaceQuotesInInlineComments(text) { - /** @typedef { 'initial' | 'single-quotes' | 'double-quotes' | 'url' | 'comment-block' | 'comment-inline' } State */ - - /** @type {State} */ - let state = "initial"; - /** @type {State} */ - - let stateToReturnFromQuotes = "initial"; - let inlineCommentStartIndex; - let inlineCommentContainsQuotes = false; - const inlineCommentsToReplace = []; - - for (let i = 0; i < text.length; i++) { - const c = text[i]; - - switch (state) { - case "initial": - if (c === "'") { - state = "single-quotes"; - continue; - } - - if (c === '"') { - state = "double-quotes"; - continue; - } - - if ((c === "u" || c === "U") && text.slice(i, i + 4).toLowerCase() === "url(") { - state = "url"; - i += 3; - continue; - } - - if (c === "*" && text[i - 1] === "/") { - state = "comment-block"; - continue; - } - - if (c === "/" && text[i - 1] === "/") { - state = "comment-inline"; - inlineCommentStartIndex = i - 1; - continue; - } - - continue; - - case "single-quotes": - if (c === "'" && text[i - 1] !== "\\") { - state = stateToReturnFromQuotes; - stateToReturnFromQuotes = "initial"; - } - - if (c === "\n" || c === "\r") { - return text; // invalid input - } - - continue; - - case "double-quotes": - if (c === '"' && text[i - 1] !== "\\") { - state = stateToReturnFromQuotes; - stateToReturnFromQuotes = "initial"; - } - - if (c === "\n" || c === "\r") { - return text; // invalid input - } - - continue; - - case "url": - if (c === ")") { - state = "initial"; - } - - if (c === "\n" || c === "\r") { - return text; // invalid input - } - - if (c === "'") { - state = "single-quotes"; - stateToReturnFromQuotes = "url"; - continue; - } - - if (c === '"') { - state = "double-quotes"; - stateToReturnFromQuotes = "url"; - continue; - } - - continue; - - case "comment-block": - if (c === "/" && text[i - 1] === "*") { - state = "initial"; - } - - continue; - - case "comment-inline": - if (c === '"' || c === "'") { - inlineCommentContainsQuotes = true; - } - - if (c === "\n" || c === "\r") { - if (inlineCommentContainsQuotes) { - inlineCommentsToReplace.push([inlineCommentStartIndex, i]); - } - - state = "initial"; - inlineCommentContainsQuotes = false; - } - - continue; - } - } +var embed_1$1 = embed$1; - for (const [start, end] of inlineCommentsToReplace) { - text = text.slice(0, start) + text.slice(start, end).replace(/'/g, "\ufffe").replace(/"/g, "\uffff") + text.slice(end); - } +const { + parse: parseFrontMatter +} = frontMatter; - return text; +function hasPragma$1(text) { + return pragma.hasPragma(parseFrontMatter(text).content); } -function restoreQuotesInInlineComments(text) { - return text.replace(/\ufffe/g, "'").replace(/\uffff/g, '"'); +function insertPragma$2(text) { + const { + frontMatter, + content + } = parseFrontMatter(text); + return (frontMatter ? frontMatter.raw + "\n\n" : "") + pragma.insertPragma(content); } -var loc$1 = { - calculateLoc, - replaceQuotesInInlineComments, - restoreQuotesInInlineComments +var pragma$1 = { + hasPragma: hasPragma$1, + insertPragma: insertPragma$2 }; -const colorAdjusterFunctions = ["red", "green", "blue", "alpha", "a", "rgb", "hue", "h", "saturation", "s", "lightness", "l", "whiteness", "w", "blackness", "b", "tint", "shade", "blend", "blenda", "contrast", "hsl", "hsla", "hwb", "hwba"]; +const colorAdjusterFunctions = new Set(["red", "green", "blue", "alpha", "a", "rgb", "hue", "h", "saturation", "s", "lightness", "l", "whiteness", "w", "blackness", "b", "tint", "shade", "blend", "blenda", "contrast", "hsl", "hsla", "hwb", "hwba"]); function getAncestorCounter(path, typeOrTypes) { const types = [].concat(typeOrTypes); @@ -44082,12 +48022,41 @@ function getPropOfDeclNode(path) { return declAncestorNode && declAncestorNode.prop && declAncestorNode.prop.toLowerCase(); } +function hasSCSSInterpolation(groupList) { + if (groupList && groupList.length) { + for (let i = groupList.length - 1; i > 0; i--) { + // If we find `#{`, return true. + if (groupList[i].type === "word" && groupList[i].value === "{" && groupList[i - 1].type === "word" && groupList[i - 1].value.endsWith("#")) { + return true; + } + } + } + + return false; +} + +function hasStringOrFunction(groupList) { + if (groupList && groupList.length) { + for (let i = 0; i < groupList.length; i++) { + if (groupList[i].type === "string" || groupList[i].type === "func") { + return true; + } + } + } + + return false; +} + function isSCSS(parser, text) { const hasExplicitParserChoice = parser === "less" || parser === "scss"; - const IS_POSSIBLY_SCSS = /(\w\s*:\s*[^}:]+|#){|@import[^\n]+(?:url|,)/; + const IS_POSSIBLY_SCSS = /(\w\s*:\s*[^:}]+|#){|@import[^\n]+(?:url|,)/; return hasExplicitParserChoice ? parser === "scss" : IS_POSSIBLY_SCSS.test(text); } +function isSCSSVariable(node) { + return !!(node && node.type === "word" && node.value.startsWith("$")); +} + function isWideKeywords(value) { return ["initial", "inherit", "unset", "revert"].includes(value.toLowerCase()); } @@ -44129,6 +48098,7 @@ function isURLFunctionNode(node) { function isLastNode(path, node) { const parentNode = path.getParentNode(); + /* istanbul ignore next */ if (!parentNode) { return false; @@ -44144,6 +48114,8 @@ function isDetachedRulesetDeclarationNode(node) { // If a Less file ends up being parsed with the SCSS parser, Less // variable declarations will be parsed as atrules with names ending // with a colon, so keep the original case then. + + /* istanbul ignore next */ if (!node.selector) { return false; } @@ -44200,6 +48172,7 @@ function isSCSSControlDirectiveNode(node) { } function isSCSSNestedPropertyNode(node) { + /* istanbul ignore next */ if (!node.selector) { return false; } @@ -44308,7 +48281,7 @@ function isColorAdjusterFuncNode(node) { return false; } - return colorAdjusterFunctions.includes(node.value.toLowerCase()); + return colorAdjusterFunctions.has(node.value.toLowerCase()); } // TODO: only check `less` when we don't use `less` to parse `css` @@ -44317,13 +48290,39 @@ function isLessParser(options) { } function lastLineHasInlineComment(text) { - return /\/\//.test(text.split(/[\r\n]/).pop()); + return /\/\//.test(text.split(/[\n\r]/).pop()); +} + +function stringifyNode(node) { + if (node.groups) { + const open = node.open && node.open.value ? node.open.value : ""; + const groups = node.groups.reduce((previousValue, currentValue, index) => { + return previousValue + stringifyNode(currentValue) + (node.groups[0].type === "comma_group" && index !== node.groups.length - 1 ? "," : ""); + }, ""); + const close = node.close && node.close.value ? node.close.value : ""; + return open + groups + close; + } + + const before = node.raws && node.raws.before ? node.raws.before : ""; + const quote = node.raws && node.raws.quote ? node.raws.quote : ""; + const atword = node.type === "atword" ? "@" : ""; + const value = node.value ? node.value : ""; + const unit = node.unit ? node.unit : ""; + const group = node.group ? stringifyNode(node.group) : ""; + const after = node.raws && node.raws.after ? node.raws.after : ""; + return before + quote + atword + value + quote + unit + group + after; +} + +function isAtWordPlaceholderNode(node) { + return node && node.type === "value-atword" && node.value.startsWith("prettier-placeholder-"); } var utils$7 = { getAncestorCounter, getAncestorNode, getPropOfDeclNode, + hasSCSSInterpolation, + hasStringOrFunction, maybeToLowerCase, insideValueFunctionNode, insideICSSRuleNode, @@ -44332,6 +48331,7 @@ var utils$7 = { isKeyframeAtRuleKeywords, isWideKeywords, isSCSS, + isSCSSVariable, isLastNode, isLessParser, isSCSSControlDirectiveNode, @@ -44367,41 +48367,287 @@ var utils$7 = { isColonNode, isMediaAndSupportsKeywords, isColorAdjusterFuncNode, - lastLineHasInlineComment + lastLineHasInlineComment, + stringifyNode, + isAtWordPlaceholderNode +}; + +var lineColumnToIndex = function (lineColumn, text) { + let index = 0; + + for (let i = 0; i < lineColumn.line - 1; ++i) { + index = text.indexOf("\n", index) + 1; + } + + return index + lineColumn.column; }; const { - insertPragma: insertPragma$3 -} = pragma$1; -const { - printNumber: printNumber$2, - printString: printString$2, - hasIgnoreComment: hasIgnoreComment$3, - hasNewline: hasNewline$5 -} = util$1; -const { - isNextLineEmpty: isNextLineEmpty$3 -} = utilShared; + getLast: getLast$a, + skipEverythingButNewLine: skipEverythingButNewLine$2 +} = util; + +function calculateLocStart(node, text) { + // value-* nodes have this + if (typeof node.sourceIndex === "number") { + return node.sourceIndex; + } + + return node.source ? lineColumnToIndex(node.source.start, text) - 1 : null; +} + +function calculateLocEnd(node, text) { + if (node.type === "css-comment" && node.inline) { + return skipEverythingButNewLine$2(text, node.source.startOffset); + } + + const endNode = node.nodes && getLast$a(node.nodes); + + if (endNode && node.source && !node.source.end) { + node = endNode; + } + + if (node.source && node.source.end) { + return lineColumnToIndex(node.source.end, text); + } + + return null; +} + +function calculateLoc(node, text) { + if (node.source) { + node.source.startOffset = calculateLocStart(node, text); + node.source.endOffset = calculateLocEnd(node, text); + } + + for (const key in node) { + const child = node[key]; + + if (key === "source" || !child || typeof child !== "object") { + continue; + } + + if (child.type === "value-root" || child.type === "value-unknown") { + calculateValueNodeLoc(child, getValueRootOffset(node), child.text || child.value); + } else { + calculateLoc(child, text); + } + } +} + +function calculateValueNodeLoc(node, rootOffset, text) { + if (node.source) { + node.source.startOffset = calculateLocStart(node, text) + rootOffset; + node.source.endOffset = calculateLocEnd(node, text) + rootOffset; + } + + for (const key in node) { + const child = node[key]; + + if (key === "source" || !child || typeof child !== "object") { + continue; + } + + calculateValueNodeLoc(child, rootOffset, text); + } +} + +function getValueRootOffset(node) { + let result = node.source.startOffset; + + if (typeof node.prop === "string") { + result += node.prop.length; + } + + if (node.type === "css-atrule" && typeof node.name === "string") { + result += 1 + node.name.length + node.raws.afterName.match(/^\s*:?\s*/)[0].length; + } + + if (node.type !== "css-atrule" && node.raws && typeof node.raws.between === "string") { + result += node.raws.between.length; + } + + return result; +} +/** + * Workaround for a bug: quotes and asterisks in inline comments corrupt loc data of subsequent nodes. + * This function replaces the quotes and asterisks with spaces. Later, when the comments are printed, + * their content is extracted from the original text. + * - https://github.com/prettier/prettier/issues/7780 + * - https://github.com/shellscape/postcss-less/issues/145 + * - https://github.com/prettier/prettier/issues/8130 + * @param text {string} + */ + + +function replaceQuotesInInlineComments(text) { + /** @typedef { 'initial' | 'single-quotes' | 'double-quotes' | 'url' | 'comment-block' | 'comment-inline' } State */ + + /** @type {State} */ + let state = "initial"; + /** @type {State} */ + + let stateToReturnFromQuotes = "initial"; + let inlineCommentStartIndex; + let inlineCommentContainsQuotes = false; + const inlineCommentsToReplace = []; + + for (let i = 0; i < text.length; i++) { + const c = text[i]; + + switch (state) { + case "initial": + if (c === "'") { + state = "single-quotes"; + continue; + } + + if (c === '"') { + state = "double-quotes"; + continue; + } + + if ((c === "u" || c === "U") && text.slice(i, i + 4).toLowerCase() === "url(") { + state = "url"; + i += 3; + continue; + } + + if (c === "*" && text[i - 1] === "/") { + state = "comment-block"; + continue; + } + + if (c === "/" && text[i - 1] === "/") { + state = "comment-inline"; + inlineCommentStartIndex = i - 1; + continue; + } + + continue; + + case "single-quotes": + if (c === "'" && text[i - 1] !== "\\") { + state = stateToReturnFromQuotes; + stateToReturnFromQuotes = "initial"; + } + + if (c === "\n" || c === "\r") { + return text; // invalid input + } + + continue; + + case "double-quotes": + if (c === '"' && text[i - 1] !== "\\") { + state = stateToReturnFromQuotes; + stateToReturnFromQuotes = "initial"; + } + + if (c === "\n" || c === "\r") { + return text; // invalid input + } + + continue; + + case "url": + if (c === ")") { + state = "initial"; + } + + if (c === "\n" || c === "\r") { + return text; // invalid input + } + + if (c === "'") { + state = "single-quotes"; + stateToReturnFromQuotes = "url"; + continue; + } + + if (c === '"') { + state = "double-quotes"; + stateToReturnFromQuotes = "url"; + continue; + } + + continue; + + case "comment-block": + if (c === "/" && text[i - 1] === "*") { + state = "initial"; + } + + continue; + + case "comment-inline": + if (c === '"' || c === "'" || c === "*") { + inlineCommentContainsQuotes = true; + } + + if (c === "\n" || c === "\r") { + if (inlineCommentContainsQuotes) { + inlineCommentsToReplace.push([inlineCommentStartIndex, i]); + } + + state = "initial"; + inlineCommentContainsQuotes = false; + } + + continue; + } + } + + for (const [start, end] of inlineCommentsToReplace) { + text = text.slice(0, start) + text.slice(start, end).replace(/["'*]/g, " ") + text.slice(end); + } + + return text; +} + +function locStart$9(node) { + return node.source.startOffset; +} + +function locEnd$f(node) { + return node.source.endOffset; +} + +var loc$1 = { + locStart: locStart$9, + locEnd: locEnd$f, + calculateLoc, + replaceQuotesInInlineComments +}; + const { - restoreQuotesInInlineComments: restoreQuotesInInlineComments$1 -} = loc$1; + printNumber: printNumber$3, + printString: printString$3, + hasNewline: hasNewline$8, + isFrontMatterNode: isFrontMatterNode$2, + isNextLineEmpty: isNextLineEmpty$a +} = util; const { builders: { - concat: concat$9, - join: join$6, - line: line$5, - hardline: hardline$7, - softline: softline$3, - group: group$6, + concat: concat$B, + join: join$h, + line: line$k, + hardline: hardline$o, + softline: softline$i, + group: group$p, fill: fill$4, - indent: indent$5, + indent: indent$r, dedent: dedent$2, - ifBreak: ifBreak$2 + ifBreak: ifBreak$e, + breakParent: breakParent$5 }, utils: { removeLines: removeLines$2 } } = document; +const { + insertPragma: insertPragma$3 +} = pragma$1; const { getAncestorNode: getAncestorNode$1, getPropOfDeclNode: getPropOfDeclNode$1, @@ -44445,19 +48691,16 @@ const { isColonNode: isColonNode$1, isMediaAndSupportsKeywords: isMediaAndSupportsKeywords$1, isColorAdjusterFuncNode: isColorAdjusterFuncNode$1, - lastLineHasInlineComment: lastLineHasInlineComment$1 + lastLineHasInlineComment: lastLineHasInlineComment$1, + isAtWordPlaceholderNode: isAtWordPlaceholderNode$1 } = utils$7; +const { + locStart: locStart$a, + locEnd: locEnd$g +} = loc$1; -function shouldPrintComma$1(options) { - switch (options.trailingComma) { - case "all": - case "es5": - return true; - - case "none": - default: - return false; - } +function shouldPrintComma$9(options) { + return options.trailingComma === "es5" || options.trailingComma === "all"; } function genericPrint$2(path, options, print) { @@ -44473,62 +48716,68 @@ function genericPrint$2(path, options, print) { } switch (node.type) { - case "yaml": - case "toml": - return concat$9([node.raw, hardline$7]); + case "front-matter": + return concat$B([node.raw, hardline$o]); case "css-root": { const nodes = printNodeSequence(path, options, print); - - if (nodes.parts.length) { - return concat$9([nodes, options.__isHTMLStyleAttribute ? "" : hardline$7]); - } - - return nodes; + const after = node.raws.after.trim(); + return concat$B([nodes, after ? ` ${after}` : "", nodes.parts.length ? hardline$o : ""]); } case "css-comment": { const isInlineComment = node.inline || node.raws.inline; - const text = options.originalText.slice(options.locStart(node), options.locEnd(node)); + const text = options.originalText.slice(locStart$a(node), locEnd$g(node)); return isInlineComment ? text.trimEnd() : text; } case "css-rule": { - return concat$9([path.call(print, "selector"), node.important ? " !important" : "", node.nodes ? concat$9([node.selector && node.selector.type === "selector-unknown" && lastLineHasInlineComment$1(node.selector.value) ? line$5 : " ", "{", node.nodes.length > 0 ? indent$5(concat$9([hardline$7, printNodeSequence(path, options, print)])) : "", hardline$7, "}", isDetachedRulesetDeclarationNode$1(node) ? ";" : ""]) : ";"]); + return concat$B([path.call(print, "selector"), node.important ? " !important" : "", node.nodes ? concat$B([node.selector && node.selector.type === "selector-unknown" && lastLineHasInlineComment$1(node.selector.value) ? line$k : " ", "{", node.nodes.length > 0 ? indent$r(concat$B([hardline$o, printNodeSequence(path, options, print)])) : "", hardline$o, "}", isDetachedRulesetDeclarationNode$1(node) ? ";" : ""]) : ";"]); } case "css-decl": { const parentNode = path.getParentNode(); - return concat$9([node.raws.before.replace(/[\s;]/g, ""), insideICSSRuleNode$1(path) ? node.prop : maybeToLowerCase$1(node.prop), node.raws.between.trim() === ":" ? ":" : node.raws.between.trim(), node.extend ? "" : " ", hasComposesNode$1(node) ? removeLines$2(path.call(print, "value")) : path.call(print, "value"), node.raws.important ? node.raws.important.replace(/\s*!\s*important/i, " !important") : node.important ? " !important" : "", node.raws.scssDefault ? node.raws.scssDefault.replace(/\s*!default/i, " !default") : node.scssDefault ? " !default" : "", node.raws.scssGlobal ? node.raws.scssGlobal.replace(/\s*!global/i, " !global") : node.scssGlobal ? " !global" : "", node.nodes ? concat$9([" {", indent$5(concat$9([softline$3, printNodeSequence(path, options, print)])), softline$3, "}"]) : isTemplatePropNode$1(node) && !parentNode.raws.semicolon && options.originalText[options.locEnd(node) - 1] !== ";" ? "" : ";"]); + const { + between: rawBetween + } = node.raws; + const trimmedBetween = rawBetween.trim(); + const isColon = trimmedBetween === ":"; + let value = hasComposesNode$1(node) ? removeLines$2(path.call(print, "value")) : path.call(print, "value"); + + if (!isColon && lastLineHasInlineComment$1(trimmedBetween)) { + value = indent$r(concat$B([hardline$o, dedent$2(value)])); + } + + return concat$B([node.raws.before.replace(/[\s;]/g, ""), insideICSSRuleNode$1(path) ? node.prop : maybeToLowerCase$1(node.prop), trimmedBetween.startsWith("//") ? " " : "", trimmedBetween, node.extend ? "" : " ", isLessParser$1(options) && node.extend && node.selector ? concat$B(["extend(", path.call(print, "selector"), ")"]) : "", value, node.raws.important ? node.raws.important.replace(/\s*!\s*important/i, " !important") : node.important ? " !important" : "", node.raws.scssDefault ? node.raws.scssDefault.replace(/\s*!default/i, " !default") : node.scssDefault ? " !default" : "", node.raws.scssGlobal ? node.raws.scssGlobal.replace(/\s*!global/i, " !global") : node.scssGlobal ? " !global" : "", node.nodes ? concat$B([" {", indent$r(concat$B([softline$i, printNodeSequence(path, options, print)])), softline$i, "}"]) : isTemplatePropNode$1(node) && !parentNode.raws.semicolon && options.originalText[locEnd$g(node) - 1] !== ";" ? "" : options.__isHTMLStyleAttribute && isLastNode$1(path, node) ? ifBreak$e(";", "") : ";"]); } case "css-atrule": { const parentNode = path.getParentNode(); - const isTemplatePlaceholderNodeWithoutSemiColon = isTemplatePlaceholderNode$1(node) && !parentNode.raws.semicolon && options.originalText[options.locEnd(node) - 1] !== ";"; + const isTemplatePlaceholderNodeWithoutSemiColon = isTemplatePlaceholderNode$1(node) && !parentNode.raws.semicolon && options.originalText[locEnd$g(node) - 1] !== ";"; if (isLessParser$1(options)) { if (node.mixin) { - return concat$9([path.call(print, "selector"), node.important ? " !important" : "", isTemplatePlaceholderNodeWithoutSemiColon ? "" : ";"]); + return concat$B([path.call(print, "selector"), node.important ? " !important" : "", isTemplatePlaceholderNodeWithoutSemiColon ? "" : ";"]); } if (node.function) { - return concat$9([node.name, concat$9([path.call(print, "params")]), isTemplatePlaceholderNodeWithoutSemiColon ? "" : ";"]); + return concat$B([node.name, concat$B([path.call(print, "params")]), isTemplatePlaceholderNodeWithoutSemiColon ? "" : ";"]); } if (node.variable) { - return concat$9(["@", node.name, ": ", node.value ? concat$9([path.call(print, "value")]) : "", node.raws.between.trim() ? node.raws.between.trim() + " " : "", node.nodes ? concat$9(["{", indent$5(concat$9([node.nodes.length > 0 ? softline$3 : "", printNodeSequence(path, options, print)])), softline$3, "}"]) : "", isTemplatePlaceholderNodeWithoutSemiColon ? "" : ";"]); + return concat$B(["@", node.name, ": ", node.value ? concat$B([path.call(print, "value")]) : "", node.raws.between.trim() ? node.raws.between.trim() + " " : "", node.nodes ? concat$B(["{", indent$r(concat$B([node.nodes.length > 0 ? softline$i : "", printNodeSequence(path, options, print)])), softline$i, "}"]) : "", isTemplatePlaceholderNodeWithoutSemiColon ? "" : ";"]); } } - return concat$9(["@", // If a Less file ends up being parsed with the SCSS parser, Less + return concat$B(["@", // If a Less file ends up being parsed with the SCSS parser, Less // variable declarations will be parsed as at-rules with names ending // with a colon, so keep the original case then. - isDetachedRulesetCallNode$1(node) || node.name.endsWith(":") ? node.name : maybeToLowerCase$1(node.name), node.params ? concat$9([isDetachedRulesetCallNode$1(node) ? "" : isTemplatePlaceholderNode$1(node) ? node.raws.afterName === "" ? "" : node.name.endsWith(":") ? " " : /^\s*\n\s*\n/.test(node.raws.afterName) ? concat$9([hardline$7, hardline$7]) : /^\s*\n/.test(node.raws.afterName) ? hardline$7 : " " : " ", path.call(print, "params")]) : "", node.selector ? indent$5(concat$9([" ", path.call(print, "selector")])) : "", node.value ? group$6(concat$9([" ", path.call(print, "value"), isSCSSControlDirectiveNode$1(node) ? hasParensAroundNode$1(node) ? " " : line$5 : ""])) : node.name === "else" ? " " : "", node.nodes ? concat$9([isSCSSControlDirectiveNode$1(node) ? "" : " ", "{", indent$5(concat$9([node.nodes.length > 0 ? softline$3 : "", printNodeSequence(path, options, print)])), softline$3, "}"]) : isTemplatePlaceholderNodeWithoutSemiColon ? "" : ";"]); + isDetachedRulesetCallNode$1(node) || node.name.endsWith(":") ? node.name : maybeToLowerCase$1(node.name), node.params ? concat$B([isDetachedRulesetCallNode$1(node) ? "" : isTemplatePlaceholderNode$1(node) ? node.raws.afterName === "" ? "" : node.name.endsWith(":") ? " " : /^\s*\n\s*\n/.test(node.raws.afterName) ? concat$B([hardline$o, hardline$o]) : /^\s*\n/.test(node.raws.afterName) ? hardline$o : " " : " ", path.call(print, "params")]) : "", node.selector ? indent$r(concat$B([" ", path.call(print, "selector")])) : "", node.value ? group$p(concat$B([" ", path.call(print, "value"), isSCSSControlDirectiveNode$1(node) ? hasParensAroundNode$1(node) ? " " : line$k : ""])) : node.name === "else" ? " " : "", node.nodes ? concat$B([isSCSSControlDirectiveNode$1(node) ? "" : node.selector && !node.selector.nodes && typeof node.selector.value === "string" && lastLineHasInlineComment$1(node.selector.value) || !node.selector && typeof node.params === "string" && lastLineHasInlineComment$1(node.params) ? line$k : " ", "{", indent$r(concat$B([node.nodes.length > 0 ? softline$i : "", printNodeSequence(path, options, print)])), softline$i, "}"]) : isTemplatePlaceholderNodeWithoutSemiColon ? "" : ";"]); } // postcss-media-query-parser @@ -44544,12 +48793,12 @@ function genericPrint$2(path, options, print) { parts.push(childPath.call(print)); }, "nodes"); - return group$6(indent$5(join$6(line$5, parts))); + return group$p(indent$r(join$h(line$k, parts))); } case "media-query": { - return concat$9([join$6(" ", path.map(print, "nodes")), isLastNode$1(path, node) ? "" : ","]); + return concat$B([join$h(" ", path.map(print, "nodes")), isLastNode$1(path, node) ? "" : ","]); } case "media-type": @@ -44563,7 +48812,7 @@ function genericPrint$2(path, options, print) { return node.value; } - return concat$9(["(", concat$9(path.map(print, "nodes")), ")"]); + return concat$B(["(", concat$B(path.map(print, "nodes")), ")"]); } case "media-feature": @@ -44573,7 +48822,7 @@ function genericPrint$2(path, options, print) { case "media-colon": { - return concat$9([node.value, " "]); + return concat$B([node.value, " "]); } case "media-value": @@ -44599,12 +48848,12 @@ function genericPrint$2(path, options, print) { case "selector-root": { - return group$6(concat$9([insideAtRuleNode$1(path, "custom-selector") ? concat$9([getAncestorNode$1(path, "css-atrule").customSelector, line$5]) : "", join$6(concat$9([",", insideAtRuleNode$1(path, ["extend", "custom-selector", "nest"]) ? line$5 : hardline$7]), path.map(print, "nodes"))])); + return group$p(concat$B([insideAtRuleNode$1(path, "custom-selector") ? concat$B([getAncestorNode$1(path, "css-atrule").customSelector, line$k]) : "", join$h(concat$B([",", insideAtRuleNode$1(path, ["extend", "custom-selector", "nest"]) ? line$k : hardline$o]), path.map(print, "nodes"))])); } case "selector-selector": { - return group$6(indent$5(concat$9(path.map(print, "nodes")))); + return group$p(indent$r(concat$B(path.map(print, "nodes")))); } case "selector-comment": @@ -44622,45 +48871,45 @@ function genericPrint$2(path, options, print) { const parentNode = path.getParentNode(); const index = parentNode && parentNode.nodes.indexOf(node); const prevNode = index && parentNode.nodes[index - 1]; - return concat$9([node.namespace ? concat$9([node.namespace === true ? "" : node.namespace.trim(), "|"]) : "", prevNode.type === "selector-nesting" ? node.value : adjustNumbers(isKeyframeAtRuleKeywords$1(path, node.value) ? node.value.toLowerCase() : node.value)]); + return concat$B([node.namespace ? concat$B([node.namespace === true ? "" : node.namespace.trim(), "|"]) : "", prevNode.type === "selector-nesting" ? node.value : adjustNumbers(isKeyframeAtRuleKeywords$1(path, node.value) ? node.value.toLowerCase() : node.value)]); } case "selector-id": { - return concat$9(["#", node.value]); + return concat$B(["#", node.value]); } case "selector-class": { - return concat$9([".", adjustNumbers(adjustStrings(node.value, options))]); + return concat$B([".", adjustNumbers(adjustStrings(node.value, options))]); } case "selector-attribute": { - return concat$9(["[", node.namespace ? concat$9([node.namespace === true ? "" : node.namespace.trim(), "|"]) : "", node.attribute.trim(), node.operator ? node.operator : "", node.value ? quoteAttributeValue(adjustStrings(node.value.trim(), options), options) : "", node.insensitive ? " i" : "", "]"]); + return concat$B(["[", node.namespace ? concat$B([node.namespace === true ? "" : node.namespace.trim(), "|"]) : "", node.attribute.trim(), node.operator ? node.operator : "", node.value ? quoteAttributeValue(adjustStrings(node.value.trim(), options), options) : "", node.insensitive ? " i" : "", "]"]); } case "selector-combinator": { if (node.value === "+" || node.value === ">" || node.value === "~" || node.value === ">>>") { const parentNode = path.getParentNode(); - const leading = parentNode.type === "selector-selector" && parentNode.nodes[0] === node ? "" : line$5; - return concat$9([leading, node.value, isLastNode$1(path, node) ? "" : " "]); + const leading = parentNode.type === "selector-selector" && parentNode.nodes[0] === node ? "" : line$k; + return concat$B([leading, node.value, isLastNode$1(path, node) ? "" : " "]); } - const leading = node.value.trim().startsWith("(") ? line$5 : ""; - const value = adjustNumbers(adjustStrings(node.value.trim(), options)) || line$5; - return concat$9([leading, value]); + const leading = node.value.trim().startsWith("(") ? line$k : ""; + const value = adjustNumbers(adjustStrings(node.value.trim(), options)) || line$k; + return concat$B([leading, value]); } case "selector-universal": { - return concat$9([node.namespace ? concat$9([node.namespace === true ? "" : node.namespace.trim(), "|"]) : "", node.value]); + return concat$B([node.namespace ? concat$B([node.namespace === true ? "" : node.namespace.trim(), "|"]) : "", node.value]); } case "selector-pseudo": { - return concat$9([maybeToLowerCase$1(node.value), node.nodes && node.nodes.length > 0 ? concat$9(["(", join$6(", ", path.map(print, "nodes")), ")"]) : ""]); + return concat$B([maybeToLowerCase$1(node.value), node.nodes && node.nodes.length > 0 ? concat$B(["(", join$h(", ", path.map(print, "nodes")), ")"]) : ""]); } case "selector-nesting": @@ -44680,9 +48929,19 @@ function genericPrint$2(path, options, print) { const parentNode = path.getParentNode(); if (parentNode.raws && parentNode.raws.selector) { - const start = options.locStart(parentNode); + const start = locStart$a(parentNode); const end = start + parentNode.raws.selector.length; return options.originalText.slice(start, end).trim(); + } // Same reason above + + + const grandParent = path.getParentNode(1); + + if (parentNode.type === "value-paren_group" && grandParent && grandParent.type === "value-func" && grandParent.value === "selector") { + const start = locStart$a(parentNode.open) + 1; + const end = locEnd$g(parentNode.close) - 1; + const selector = options.originalText.slice(start, end).trim(); + return lastLineHasInlineComment$1(selector) ? concat$B([breakParent$5, selector]) : selector; } return node.value; @@ -44697,9 +48956,7 @@ function genericPrint$2(path, options, print) { case "value-comment": { - return concat$9([node.inline ? "//" : "/*", // see replaceQuotesInInlineComments in loc.js - // value-* nodes don't have correct location data, so we have to rely on placeholder characters. - restoreQuotesInInlineComments$1(node.value), node.inline ? "" : "*/"]); + return options.originalText.slice(locStart$a(node), locEnd$g(node)); } case "value-comma_group": @@ -44737,7 +48994,7 @@ function genericPrint$2(path, options, print) { } // styled.div` background: var(--${one}); ` - if (!iPrevNode && iNode.value === "--" && iNextNode.type === "value-atword") { + if (iNode.type === "value-word" && iNode.value.endsWith("-") && isAtWordPlaceholderNode$1(iNextNode)) { continue; } // Ignore spaces before/after string interpolation (i.e. `"#{my-fn("_")}"`) @@ -44828,7 +49085,12 @@ function genericPrint$2(path, options, print) { if (isInlineValueCommentNode$1(iNode)) { - parts.push(hardline$7); + if (parentNode.type === "value-paren_group") { + parts.push(dedent$2(hardline$o)); + continue; + } + + parts.push(hardline$o); continue; } // Handle keywords in SCSS control directive @@ -44847,7 +49109,7 @@ function genericPrint$2(path, options, print) { if (isGridValue) { if (iNode.source && iNextNode.source && iNode.source.start.line !== iNextNode.source.start.line) { - parts.push(hardline$7); + parts.push(hardline$o); didBreak = true; } else { parts.push(" "); @@ -44862,18 +49124,27 @@ function genericPrint$2(path, options, print) { if (isNextMathOperator) { parts.push(" "); continue; + } // allow function(returns-list($list)...) + + + if (iNextNode && iNextNode.value === "...") { + continue; + } + + if (isAtWordPlaceholderNode$1(iNode) && isAtWordPlaceholderNode$1(iNextNode) && locEnd$g(iNode) === locStart$a(iNextNode)) { + continue; } // Be default all values go through `line` - parts.push(line$5); + parts.push(line$k); } if (didBreak) { - parts.unshift(hardline$7); + parts.unshift(hardline$o); } if (isControlDirective) { - return group$6(indent$5(concat$9(parts))); + return group$p(indent$r(concat$B(parts))); } // Indent is not needed for import url when url is very long // and node has two groups // when type is value-comma_group @@ -44881,10 +49152,10 @@ function genericPrint$2(path, options, print) { if (insideURLFunctionInImportAtRuleNode$1(path)) { - return group$6(fill$4(parts)); + return group$p(fill$4(parts)); } - return group$6(indent$5(fill$4(parts))); + return group$p(indent$r(fill$4(parts))); } case "value-paren_group": @@ -44892,7 +49163,7 @@ function genericPrint$2(path, options, print) { const parentNode = path.getParentNode(); if (parentNode && isURLFunctionNode$1(parentNode) && (node.groups.length === 1 || node.groups.length > 0 && node.groups[0].type === "value-comma_group" && node.groups[0].groups.length > 0 && node.groups[0].groups[0].type === "value-word" && node.groups[0].groups[0].value.startsWith("data:"))) { - return concat$9([node.open ? path.call(print, "open") : "", join$6(",", path.map(print, "groups")), node.close ? path.call(print, "close") : ""]); + return concat$B([node.open ? path.call(print, "open") : "", join$h(",", path.map(print, "groups")), node.close ? path.call(print, "close") : ""]); } if (!node.open) { @@ -44901,36 +49172,36 @@ function genericPrint$2(path, options, print) { for (let i = 0; i < printed.length; i++) { if (i !== 0) { - res.push(concat$9([",", line$5])); + res.push(concat$B([",", line$k])); } res.push(printed[i]); } - return group$6(indent$5(fill$4(res))); + return group$p(indent$r(fill$4(res))); } const isSCSSMapItem = isSCSSMapItemNode$1(path); const lastItem = node.groups[node.groups.length - 1]; const isLastItemComment = lastItem && lastItem.type === "value-comment"; - return group$6(concat$9([node.open ? path.call(print, "open") : "", indent$5(concat$9([softline$3, join$6(concat$9([",", line$5]), path.map(childPath => { + return group$p(concat$B([node.open ? path.call(print, "open") : "", indent$r(concat$B([softline$i, join$h(concat$B([",", line$k]), path.map(childPath => { const node = childPath.getValue(); const printed = print(childPath); // Key/Value pair in open paren already indented if (isKeyValuePairNode$1(node) && node.type === "value-comma_group" && node.groups && node.groups[2] && node.groups[2].type === "value-paren_group") { - printed.contents.contents.parts[1] = group$6(printed.contents.contents.parts[1]); - return group$6(dedent$2(printed)); + printed.contents.contents.parts[1] = group$p(printed.contents.contents.parts[1]); + return group$p(dedent$2(printed)); } return printed; - }, "groups"))])), ifBreak$2(!isLastItemComment && isSCSS$1(options.parser, options.originalText) && isSCSSMapItem && shouldPrintComma$1(options) ? "," : ""), softline$3, node.close ? path.call(print, "close") : ""]), { + }, "groups"))])), ifBreak$e(!isLastItemComment && isSCSS$1(options.parser, options.originalText) && isSCSSMapItem && shouldPrintComma$9(options) ? "," : ""), softline$i, node.close ? path.call(print, "close") : ""]), { shouldBreak: isSCSSMapItem }); } case "value-func": { - return concat$9([node.value, insideAtRuleNode$1(path, "supports") && isMediaAndSupportsKeywords$1(node) ? " " : "", path.call(print, "group")]); + return concat$B([node.value, insideAtRuleNode$1(path, "supports") && isMediaAndSupportsKeywords$1(node) ? " " : "", path.call(print, "group")]); } case "value-paren": @@ -44940,7 +49211,7 @@ function genericPrint$2(path, options, print) { case "value-number": { - return concat$9([printCssNumber(node.value), maybeToLowerCase$1(node.unit)]); + return concat$B([printCssNumber(node.value), maybeToLowerCase$1(node.unit)]); } case "value-operator": @@ -44959,23 +49230,30 @@ function genericPrint$2(path, options, print) { case "value-colon": { - return concat$9([node.value, // Don't add spaces on `:` in `url` function (i.e. `url(fbglyph: cross-outline, fig-white)`) - insideValueFunctionNode$1(path, "url") ? "" : line$5]); + const parentNode = path.getParentNode(); + const index = parentNode && parentNode.groups.indexOf(node); + const prevNode = index && parentNode.groups[index - 1]; + return concat$B([node.value, // Don't add spaces on escaped colon `:`, e.g: grid-template-rows: [row-1-00\:00] auto; + prevNode && prevNode.value[prevNode.value.length - 1] === "\\" || // Don't add spaces on `:` in `url` function (i.e. `url(fbglyph: cross-outline, fig-white)`) + insideValueFunctionNode$1(path, "url") ? "" : line$k]); } + // TODO: confirm this code is dead + + /* istanbul ignore next */ case "value-comma": { - return concat$9([node.value, " "]); + return concat$B([node.value, " "]); } case "value-string": { - return printString$2(node.raws.quote + node.value + node.raws.quote, options); + return printString$3(node.raws.quote + node.value + node.raws.quote, options); } case "value-atword": { - return concat$9(["@", node.value]); + return concat$B(["@", node.value]); } case "value-unicode-range": @@ -44997,44 +49275,41 @@ function genericPrint$2(path, options, print) { function printNodeSequence(path, options, print) { const node = path.getValue(); const parts = []; - let i = 0; - path.map(pathChild => { + path.each((pathChild, i) => { const prevNode = node.nodes[i - 1]; if (prevNode && prevNode.type === "css-comment" && prevNode.text.trim() === "prettier-ignore") { const childNode = pathChild.getValue(); - parts.push(options.originalText.slice(options.locStart(childNode), options.locEnd(childNode))); + parts.push(options.originalText.slice(locStart$a(childNode), locEnd$g(childNode))); } else { parts.push(pathChild.call(print)); } if (i !== node.nodes.length - 1) { - if (node.nodes[i + 1].type === "css-comment" && !hasNewline$5(options.originalText, options.locStart(node.nodes[i + 1]), { + if (node.nodes[i + 1].type === "css-comment" && !hasNewline$8(options.originalText, locStart$a(node.nodes[i + 1]), { backwards: true - }) && node.nodes[i].type !== "yaml" && node.nodes[i].type !== "toml" || node.nodes[i + 1].type === "css-atrule" && node.nodes[i + 1].name === "else" && node.nodes[i].type !== "css-comment") { + }) && !isFrontMatterNode$2(node.nodes[i]) || node.nodes[i + 1].type === "css-atrule" && node.nodes[i + 1].name === "else" && node.nodes[i].type !== "css-comment") { parts.push(" "); } else { - parts.push(options.__isHTMLStyleAttribute ? line$5 : hardline$7); + parts.push(options.__isHTMLStyleAttribute ? line$k : hardline$o); - if (isNextLineEmpty$3(options.originalText, pathChild.getValue(), options.locEnd) && node.nodes[i].type !== "yaml" && node.nodes[i].type !== "toml") { - parts.push(hardline$7); + if (isNextLineEmpty$a(options.originalText, pathChild.getValue(), locEnd$g) && !isFrontMatterNode$2(node.nodes[i])) { + parts.push(hardline$o); } } } - - i++; }, "nodes"); - return concat$9(parts); + return concat$B(parts); } -const STRING_REGEX$3 = /(['"])(?:(?!\1)[^\\]|\\[\s\S])*\1/g; -const NUMBER_REGEX = /(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g; -const STANDARD_UNIT_REGEX = /[a-zA-Z]+/g; -const WORD_PART_REGEX = /[$@]?[a-zA-Z_\u0080-\uFFFF][\w\-\u0080-\uFFFF]*/g; +const STRING_REGEX$3 = /(["'])(?:(?!\1)[^\\]|\\[\S\s])*\1/g; +const NUMBER_REGEX = /(?:\d*\.\d+|\d+\.?)(?:[Ee][+-]?\d+)?/g; +const STANDARD_UNIT_REGEX = /[A-Za-z]+/g; +const WORD_PART_REGEX = /[$@]?[A-Z_a-z\u0080-\uFFFF][\w\u0080-\uFFFF-]*/g; const ADJUST_NUMBERS_REGEX = new RegExp(STRING_REGEX$3.source + "|" + `(${WORD_PART_REGEX.source})?` + `(${NUMBER_REGEX.source})` + `(${STANDARD_UNIT_REGEX.source})?`, "g"); function adjustStrings(value, options) { - return value.replace(STRING_REGEX$3, match => printString$2(match, options)); + return value.replace(STRING_REGEX$3, match => printString$3(match, options)); } function quoteAttributeValue(value, options) { @@ -45047,7 +49322,7 @@ function adjustNumbers(value) { } function printCssNumber(rawNumber) { - return printNumber$2(rawNumber) // Remove trailing `.0`. + return printNumber$3(rawNumber) // Remove trailing `.0`. .replace(/\.0(?=$|e)/, ""); } @@ -45055,7 +49330,6 @@ var printerPostcss = { print: genericPrint$2, embed: embed_1$1, insertPragma: insertPragma$3, - hasPrettierIgnore: hasIgnoreComment$3, massageAstNode: clean_1$1 }; @@ -45074,7 +49348,7 @@ var extensions$7 = [ ".css" ]; var languageId$7 = 50; -var CSS = { +var require$$0$3 = { name: name$9, type: type$7, tmScope: tmScope$7, @@ -45086,55 +49360,29 @@ var CSS = { languageId: languageId$7 }; -var CSS$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - name: name$9, - type: type$7, - tmScope: tmScope$7, - aceMode: aceMode$7, - codemirrorMode: codemirrorMode$7, - codemirrorMimeType: codemirrorMimeType$7, - color: color$2, - extensions: extensions$7, - languageId: languageId$7, - 'default': CSS -}); - var name$a = "PostCSS"; var type$8 = "markup"; var tmScope$8 = "source.postcss"; -var group$7 = "CSS"; +var group$q = "CSS"; var extensions$8 = [ ".pcss", ".postcss" ]; var aceMode$8 = "text"; var languageId$8 = 262764437; -var PostCSS = { +var require$$1$1 = { name: name$a, type: type$8, tmScope: tmScope$8, - group: group$7, + group: group$q, extensions: extensions$8, aceMode: aceMode$8, languageId: languageId$8 }; -var PostCSS$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - name: name$a, - type: type$8, - tmScope: tmScope$8, - group: group$7, - extensions: extensions$8, - aceMode: aceMode$8, - languageId: languageId$8, - 'default': PostCSS -}); - var name$b = "Less"; var type$9 = "markup"; -var group$8 = "CSS"; +var color$3 = "#1d365d"; var extensions$9 = [ ".less" ]; @@ -45143,10 +49391,10 @@ var aceMode$9 = "less"; var codemirrorMode$8 = "css"; var codemirrorMimeType$8 = "text/css"; var languageId$9 = 198; -var Less = { +var require$$2$1 = { name: name$b, type: type$9, - group: group$8, + color: color$3, extensions: extensions$9, tmScope: tmScope$9, aceMode: aceMode$9, @@ -45155,24 +49403,10 @@ var Less = { languageId: languageId$9 }; -var Less$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - name: name$b, - type: type$9, - group: group$8, - extensions: extensions$9, - tmScope: tmScope$9, - aceMode: aceMode$9, - codemirrorMode: codemirrorMode$8, - codemirrorMimeType: codemirrorMimeType$8, - languageId: languageId$9, - 'default': Less -}); - var name$c = "SCSS"; var type$a = "markup"; +var color$4 = "#c6538c"; var tmScope$a = "source.css.scss"; -var group$9 = "CSS"; var aceMode$a = "scss"; var codemirrorMode$9 = "css"; var codemirrorMimeType$9 = "text/x-scss"; @@ -45180,11 +49414,11 @@ var extensions$a = [ ".scss" ]; var languageId$a = 329; -var SCSS = { +var require$$3$1 = { name: name$c, type: type$a, + color: color$4, tmScope: tmScope$a, - group: group$9, aceMode: aceMode$a, codemirrorMode: codemirrorMode$9, codemirrorMimeType: codemirrorMimeType$9, @@ -45192,32 +49426,13 @@ var SCSS = { languageId: languageId$a }; -var SCSS$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - name: name$c, - type: type$a, - tmScope: tmScope$a, - group: group$9, - aceMode: aceMode$a, - codemirrorMode: codemirrorMode$9, - codemirrorMimeType: codemirrorMimeType$9, - extensions: extensions$a, - languageId: languageId$a, - 'default': SCSS -}); - -var require$$0$2 = getCjsExportFromNamespace(CSS$1); - -var require$$1$1 = getCjsExportFromNamespace(PostCSS$1); - -var require$$2$1 = getCjsExportFromNamespace(Less$1); - -var require$$3$1 = getCjsExportFromNamespace(SCSS$1); - -const languages$1 = [createLanguage(require$$0$2, () => ({ +const languages$1 = [createLanguage(require$$0$3, data => ({ since: "1.4.0", parsers: ["css"], - vscodeLanguageIds: ["css"] + vscodeLanguageIds: ["css"], + extensions: [...data.extensions, // `WeiXin Style Sheets`(Weixin Mini Programs) + // https://developers.weixin.qq.com/miniprogram/en/dev/framework/view/wxs/ + ".wxss"] })), createLanguage(require$$1$1, () => ({ since: "1.4.0", parsers: ["css"], @@ -45234,16 +49449,45 @@ const languages$1 = [createLanguage(require$$0$2, () => ({ const printers$1 = { postcss: printerPostcss }; +const parsers$1 = { + // TODO: switch these to just `postcss` and use `language` instead. + get css() { + return require("./parser-postcss").parsers.css; + }, + + get less() { + return require("./parser-postcss").parsers.less; + }, + + get scss() { + return require("./parser-postcss").parsers.scss; + } + +}; var languageCss = { languages: languages$1, options: options$3, - printers: printers$1 + printers: printers$1, + parsers: parsers$1 }; -var clean$3 = function (ast, newNode) { - delete newNode.loc; - delete newNode.selfClosing; // (Glimmer/HTML) ignore TextNode whitespace +function locStart$b(node) { + return node.loc.start.offset; +} + +function locEnd$h(node) { + return node.loc.end.offset; +} + +var loc$2 = { + locStart: locStart$b, + locEnd: locEnd$h +}; +function clean$3(ast, newNode +/*, parent*/ +) { + // (Glimmer/HTML) ignore TextNode whitespace if (ast.type === "TextNode") { const trimmed = ast.chars.trim(); @@ -45253,7 +49497,36 @@ var clean$3 = function (ast, newNode) { newNode.chars = trimmed; } -}; +} + +clean$3.ignoredProperties = new Set(["loc", "selfClosing"]); +var clean_1$2 = clean$3; + +var htmlVoidElements = [ + "area", + "base", + "basefont", + "bgsound", + "br", + "col", + "command", + "embed", + "frame", + "hr", + "image", + "img", + "input", + "isindex", + "keygen", + "link", + "menuitem", + "meta", + "nextid", + "param", + "source", + "track", + "wbr" +]; function isUppercase(string) { return string.toUpperCase() === string; @@ -45263,6 +49536,12 @@ function isGlimmerComponent(node) { return isNodeOfSomeType(node, ["ElementNode"]) && typeof node.tag === "string" && (isUppercase(node.tag[0]) || node.tag.includes(".")); } +const voidTags = new Set(htmlVoidElements); + +function isVoid(node) { + return isGlimmerComponent(node) && node.children.every(n => isWhitespaceNode(n)) || voidTags.has(node.tag); +} + function isWhitespaceNode(node) { return isNodeOfSomeType(node, ["TextNode"]) && !/\S/.test(node.chars); } @@ -45289,7 +49568,7 @@ function isNextNodeOfSomeType(path, types) { function getSiblingNode(path, offset) { const node = path.getValue(); const parentNode = path.getParentNode(0) || {}; - const children = parentNode.children || parentNode.body || []; + const children = parentNode.children || parentNode.body || parentNode.parts || []; const index = children.indexOf(node); return index !== -1 && children[index + offset]; } @@ -45316,39 +49595,44 @@ var utils$8 = { getNextNode, getPreviousNode, hasPrettierIgnore: hasPrettierIgnore$2, - isGlimmerComponent, isNextNodeOfSomeType, isNodeOfSomeType, isParentOfSomeType, isPreviousNodeOfSomeType, + isVoid, isWhitespaceNode }; const { - concat: concat$a, - join: join$7, - softline: softline$4, - hardline: hardline$8, - line: line$6, - group: group$a, - indent: indent$6, - ifBreak: ifBreak$3 -} = document.builders; + builders: { + concat: concat$C, + group: group$r, + hardline: hardline$p, + ifBreak: ifBreak$f, + indent: indent$s, + join: join$i, + line: line$l, + softline: softline$j + } +} = document; +const { + locStart: locStart$c, + locEnd: locEnd$i +} = loc$2; const { getNextNode: getNextNode$1, getPreviousNode: getPreviousNode$1, hasPrettierIgnore: hasPrettierIgnore$3, - isGlimmerComponent: isGlimmerComponent$1, isNextNodeOfSomeType: isNextNodeOfSomeType$1, + isNodeOfSomeType: isNodeOfSomeType$1, isParentOfSomeType: isParentOfSomeType$1, isPreviousNodeOfSomeType: isPreviousNodeOfSomeType$1, + isVoid: isVoid$1, isWhitespaceNode: isWhitespaceNode$1 -} = utils$8; // http://w3c.github.io/html/single-page.html#void-elements - -const voidTags = ["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"]; // Formatter based on @glimmerjs/syntax's built-in test formatter: +} = utils$8; // Formatter based on @glimmerjs/syntax's built-in test formatter: // https://github.com/glimmerjs/glimmer-vm/blob/master/packages/%40glimmer/syntax/lib/generation/print.ts -function print(path, options, print) { +function print$2(path, options, print) { const n = path.getValue(); /* istanbul ignore if*/ @@ -45357,10 +49641,7 @@ function print(path, options, print) { } if (hasPrettierIgnore$3(path)) { - const startOffset = locationToOffset(options.originalText, n.loc.start.line - 1, n.loc.start.column); - const endOffset = locationToOffset(options.originalText, n.loc.end.line - 1, n.loc.end.column); - const ignoredText = options.originalText.slice(startOffset, endOffset); - return ignoredText; + return options.originalText.slice(locStart$c(n), locEnd$i(n)); } switch (n.type) { @@ -45368,97 +49649,82 @@ function print(path, options, print) { case "Program": case "Template": { - return group$a(concat$a(path.map(print, "body"))); + return group$r(concat$C(path.map(print, "body"))); } case "ElementNode": { - const hasChildren = n.children.length > 0; - const hasNonWhitespaceChildren = n.children.some(n => !isWhitespaceNode$1(n)); - const isVoid = isGlimmerComponent$1(n) && (!hasChildren || !hasNonWhitespaceChildren) || voidTags.includes(n.tag); - const closeTagForNoBreak = isVoid ? concat$a([" />", softline$4]) : ">"; - const closeTagForBreak = isVoid ? "/>" : ">"; + // TODO: make it whitespace sensitive + const bim = isNextNodeOfSomeType$1(path, ["ElementNode"]) ? hardline$p : ""; - const printParams = (path, print) => indent$6(concat$a([n.attributes.length ? line$6 : "", join$7(line$6, path.map(print, "attributes")), n.modifiers.length ? line$6 : "", join$7(line$6, path.map(print, "modifiers")), n.comments.length ? line$6 : "", join$7(line$6, path.map(print, "comments"))])); + if (isVoid$1(n)) { + return concat$C([group$r(printStartingTag(path, print)), bim]); + } - const nextNode = getNextNode$1(path); - return concat$a([group$a(concat$a(["<", n.tag, printParams(path, print), n.blockParams.length ? ` as |${n.blockParams.join(" ")}|` : "", ifBreak$3(softline$4, ""), ifBreak$3(closeTagForBreak, closeTagForNoBreak)])), !isVoid ? group$a(concat$a([hasNonWhitespaceChildren ? indent$6(printChildren(path, options, print)) : "", ifBreak$3(hasChildren ? hardline$8 : "", ""), concat$a([""])])) : "", nextNode && nextNode.type === "ElementNode" ? hardline$8 : ""]); + const isWhitespaceOnly = n.children.every(n => isWhitespaceNode$1(n)); + return concat$C([group$r(printStartingTag(path, print)), group$r(concat$C([isWhitespaceOnly ? "" : indent$s(printChildren(path, options, print)), n.children.length ? hardline$p : "", concat$C([""])])), bim]); } case "BlockStatement": { const pp = path.getParentNode(1); const isElseIf = pp && pp.inverse && pp.inverse.body.length === 1 && pp.inverse.body[0] === n && pp.inverse.body[0].path.parts[0] === "if"; - const hasElseIf = n.inverse && n.inverse.body.length === 1 && n.inverse.body[0].type === "BlockStatement" && n.inverse.body[0].path.parts[0] === "if"; - const indentElse = hasElseIf ? a => a : indent$6; - const inverseElseStatement = (n.inverseStrip.open ? "{{~" : "{{") + "else" + (n.inverseStrip.close ? "~}}" : "}}"); - if (n.inverse) { - return concat$a([isElseIf ? concat$a([n.openStrip.open ? "{{~else " : "{{else ", printPathParams(path, print), n.openStrip.close ? "~}}" : "}}"]) : printOpenBlock(path, print, n.openStrip), indent$6(concat$a([hardline$8, path.call(print, "program")])), n.inverse && !hasElseIf ? concat$a([hardline$8, inverseElseStatement]) : "", n.inverse ? indentElse(concat$a([hardline$8, path.call(print, "inverse")])) : "", isElseIf ? "" : concat$a([hardline$8, printCloseBlock(path, print, n.closeStrip)])]); - } else if (isElseIf) { - return concat$a([concat$a([n.openStrip.open ? "{{~else" : "{{else ", printPathParams(path, print), n.openStrip.close ? "~}}" : "}}"]), indent$6(concat$a([hardline$8, path.call(print, "program")]))]); + if (isElseIf) { + return concat$C([printElseIfBlock(path, print), printProgram(path, print), printInverse(path, print)]); } - const hasNonWhitespaceChildren = n.program.body.some(n => !isWhitespaceNode$1(n)); - return concat$a([printOpenBlock(path, print, n.openStrip), group$a(concat$a([indent$6(concat$a([softline$4, path.call(print, "program")])), hasNonWhitespaceChildren ? hardline$8 : softline$4, printCloseBlock(path, print, n.closeStrip)]))]); + return concat$C([printOpenBlock(path, print), group$r(concat$C([printProgram(path, print), printInverse(path, print), printCloseBlock(path, print)]))]); } case "ElementModifierStatement": { - return group$a(concat$a(["{{", printPathParams(path, print), softline$4, "}}"])); + return group$r(concat$C(["{{", printPathAndParams(path, print), softline$j, "}}"])); } case "MustacheStatement": { - const isEscaped = n.escaped === false; - const { - open: openStrip, - close: closeStrip - } = n.strip; - const opening = (isEscaped ? "{{{" : "{{") + (openStrip ? "~" : ""); - const closing = (closeStrip ? "~" : "") + (isEscaped ? "}}}" : "}}"); - const leading = isParentOfSomeType$1(path, ["AttrNode", "ConcatStatement", "ElementNode"]) ? [opening, indent$6(softline$4)] : [opening]; - return group$a(concat$a([...leading, printPathParams(path, print), softline$4, closing])); + const isParentOfSpecifiedTypes = isParentOfSomeType$1(path, ["AttrNode", "ConcatStatement"]); + const isChildOfElementNodeAndDoesNotHaveParams = isParentOfSomeType$1(path, ["ElementNode"]) && doesNotHaveHashParams(n) && doesNotHavePositionalParams(n); + const shouldBreakOpeningMustache = isParentOfSpecifiedTypes || isChildOfElementNodeAndDoesNotHaveParams; + return group$r(concat$C([printOpeningMustache(n), shouldBreakOpeningMustache ? indent$s(softline$j) : "", printPathAndParams(path, print), softline$j, printClosingMustache(n)])); } case "SubExpression": { - const params = printParams(path, print); - const printedParams = params.length > 0 ? indent$6(concat$a([line$6, group$a(join$7(line$6, params))])) : ""; - return group$a(concat$a(["(", printPath(path, print), printedParams, softline$4, ")"])); + return group$r(concat$C(["(", printSubExpressionPathAndParams(path, print), softline$j, ")"])); } case "AttrNode": { const isText = n.value.type === "TextNode"; - const isEmptyText = isText && n.value.chars === ""; // If the text is empty and the value's loc start and end columns are the + const isEmptyText = isText && n.value.chars === ""; // If the text is empty and the value's loc start and end offsets are the // same, there is no value for this AttrNode and it should be printed // without the `=""`. Example: `` -> `` - const isEmptyValue = isEmptyText && n.value.loc.start.column === n.value.loc.end.column; - - if (isEmptyValue) { - return concat$a([n.name]); + if (isEmptyText && locStart$c(n.value) === locEnd$i(n.value)) { + return concat$C([n.name]); } const value = path.call(print, "value"); const quotedValue = isText ? printStringLiteral(value.parts.join(), options) : value; - return concat$a([n.name, "=", quotedValue]); + return concat$C([n.name, "=", quotedValue]); } case "ConcatStatement": { - return concat$a(['"', concat$a(path.map(partPath => print(partPath), "parts").filter(a => a !== "")), '"']); + const quote = options.singleQuote ? "'" : '"'; + return concat$C([quote, ...path.map(partPath => print(partPath), "parts"), quote]); } case "Hash": { - return concat$a([join$7(line$6, path.map(print, "pairs"))]); + return concat$C([join$i(line$l, path.map(print, "pairs"))]); } case "HashPair": { - return concat$a([n.key, "=", path.call(print, "value")]); + return concat$C([n.key, "=", path.call(print, "value")]); } case "TextNode": @@ -45468,13 +49734,10 @@ function print(path, options, print) { const isLastElement = !getNextNode$1(path); const isWhitespaceOnly = !/\S/.test(n.chars); const lineBreaksCount = countNewLines(n.chars); - const hasBlockParent = path.getParentNode(0).type === "Block"; - const hasElementParent = path.getParentNode(0).type === "ElementNode"; - const hasTemplateParent = path.getParentNode(0).type === "Template"; let leadingLineBreaksCount = countLeadingNewLines(n.chars); let trailingLineBreaksCount = countTrailingNewLines(n.chars); - if ((isFirstElement || isLastElement) && isWhitespaceOnly && (hasBlockParent || hasElementParent || hasTemplateParent)) { + if ((isFirstElement || isLastElement) && isWhitespaceOnly && isParentOfSomeType$1(path, ["Block", "ElementNode", "Template"])) { return ""; } @@ -45486,72 +49749,74 @@ function print(path, options, print) { trailingLineBreaksCount = Math.max(trailingLineBreaksCount, 1); } - if (isPreviousNodeOfSomeType$1(path, ["ElementNode"]) || isPreviousNodeOfSomeType$1(path, ["BlockStatement"])) { + if (isPreviousNodeOfSomeType$1(path, ["BlockStatement", "ElementNode"])) { leadingLineBreaksCount = Math.max(leadingLineBreaksCount, 1); } } - let leadingSpace = ""; - let trailingSpace = ""; // preserve a space inside of an attribute node where whitespace present, - // when next to mustache statement. - const inAttrNode = path.stack.includes("attributes"); if (inAttrNode) { - const parentNode = path.getParentNode(0); - const isConcat = parentNode.type === "ConcatStatement"; - - if (isConcat) { - const { - parts - } = parentNode; - const partIndex = parts.indexOf(n); + // TODO: format style and srcset attributes + // and cleanup concat that is not necessary + if (!isInAttributeOfName(path, "class")) { + return concat$C([n.chars]); + } - if (partIndex > 0) { - const partType = parts[partIndex - 1].type; - const isMustache = partType === "MustacheStatement"; + let leadingSpace = ""; + let trailingSpace = ""; - if (isMustache) { - leadingSpace = " "; - } + if (isParentOfSomeType$1(path, ["ConcatStatement"])) { + if (isPreviousNodeOfSomeType$1(path, ["MustacheStatement"])) { + leadingSpace = " "; } - if (partIndex < parts.length - 1) { - const partType = parts[partIndex + 1].type; - const isMustache = partType === "MustacheStatement"; - - if (isMustache) { - trailingSpace = " "; - } + if (isNextNodeOfSomeType$1(path, ["MustacheStatement"])) { + trailingSpace = " "; } } - } else { - if (trailingLineBreaksCount === 0 && isNextNodeOfSomeType$1(path, ["MustacheStatement"])) { - trailingSpace = " "; - } - if (leadingLineBreaksCount === 0 && isPreviousNodeOfSomeType$1(path, ["MustacheStatement"])) { - leadingSpace = " "; - } + return concat$C([...generateHardlines(leadingLineBreaksCount, maxLineBreaksToPreserve), n.chars.replace(/^\s+/g, leadingSpace).replace(/\s+$/, trailingSpace), ...generateHardlines(trailingLineBreaksCount, maxLineBreaksToPreserve)]); + } - if (isFirstElement) { - leadingLineBreaksCount = 0; - leadingSpace = ""; - } + let leadingSpace = ""; + let trailingSpace = ""; - if (isLastElement) { - trailingLineBreaksCount = 0; - trailingSpace = ""; - } + if (trailingLineBreaksCount === 0 && isNextNodeOfSomeType$1(path, ["MustacheStatement"])) { + trailingSpace = " "; + } + + if (leadingLineBreaksCount === 0 && isPreviousNodeOfSomeType$1(path, ["MustacheStatement"])) { + leadingSpace = " "; } - return concat$a([...generateHardlines(leadingLineBreaksCount, maxLineBreaksToPreserve), n.chars.replace(/^[\s ]+/g, leadingSpace).replace(/[\s ]+$/, trailingSpace), ...generateHardlines(trailingLineBreaksCount, maxLineBreaksToPreserve)].filter(Boolean)); + if (isFirstElement) { + leadingLineBreaksCount = 0; + leadingSpace = ""; + } + + if (isLastElement) { + trailingLineBreaksCount = 0; + trailingSpace = ""; + } + + let text = n.chars; + /* if `{{my-component}}` (or any text starting with a mustache) + * makes it to the TextNode, + * it means it was escaped, + * so let's print it escaped, ie.; `\{{my-component}}` */ + + if (text.startsWith("{{") && text.includes("}}")) { + text = "\\" + text; + } + + return concat$C([...generateHardlines(leadingLineBreaksCount, maxLineBreaksToPreserve), text.replace(/^\s+/g, leadingSpace).replace(/\s+$/, trailingSpace), ...generateHardlines(trailingLineBreaksCount, maxLineBreaksToPreserve)]); } case "MustacheCommentStatement": { const dashes = n.value.includes("}}") ? "--" : ""; - return concat$a(["{{!", dashes, n.value, dashes, "}}"]); + return concat$C(["{{!", dashes, n.value, dashes, "}}"]); } case "PathExpression": @@ -45566,7 +49831,7 @@ function print(path, options, print) { case "CommentStatement": { - return concat$a([""]); + return concat$C([""]); } case "StringLiteral": @@ -45595,24 +49860,178 @@ function print(path, options, print) { throw new Error("unknown glimmer type: " + JSON.stringify(n.type)); } } +/* ElementNode print helpers */ -function printChildren(path, options, print) { - return concat$a(path.map((childPath, childIndex) => { - const childNode = path.getValue(); - const isFirstNode = childIndex === 0; - const isLastNode = childIndex === path.getParentNode(0).children.length - 1; - const isLastNodeInMultiNodeList = isLastNode && !isFirstNode; - const isWhitespace = isWhitespaceNode$1(childNode); - if (isWhitespace && isLastNodeInMultiNodeList) { - return print(childPath, options, print); - } else if (isFirstNode) { - return concat$a([softline$4, print(childPath, options, print)]); +function printStartingTag(path, print) { + const node = path.getValue(); + return concat$C(["<", node.tag, printAttributesLike(path, print), printBlockParams(node), printStartingTagEndMarker(node)]); +} + +function printAttributesLike(path, print) { + const node = path.getValue(); + return indent$s(concat$C([node.attributes.length ? line$l : "", join$i(line$l, path.map(print, "attributes")), node.modifiers.length ? line$l : "", join$i(line$l, path.map(print, "modifiers")), node.comments.length ? line$l : "", join$i(line$l, path.map(print, "comments"))])); +} + +function printChildren(path, options, print) { + return concat$C(path.map((childPath, childIndex) => { + if (childIndex === 0) { + return concat$C([softline$j, print(childPath, options, print)]); } return print(childPath, options, print); }, "children")); } + +function printStartingTagEndMarker(node) { + if (isVoid$1(node)) { + return ifBreak$f(concat$C([softline$j, "/>"]), concat$C([" />", softline$j])); + } + + return ifBreak$f(concat$C([softline$j, ">"]), ">"); +} +/* MustacheStatement print helpers */ + + +function printOpeningMustache(node) { + const mustache = node.escaped === false ? "{{{" : "{{"; + const strip = node.strip && node.strip.open ? "~" : ""; + return concat$C([mustache, strip]); +} + +function printClosingMustache(node) { + const mustache = node.escaped === false ? "}}}" : "}}"; + const strip = node.strip && node.strip.close ? "~" : ""; + return concat$C([strip, mustache]); +} +/* BlockStatement print helpers */ + + +function printOpeningBlockOpeningMustache(node) { + const opening = printOpeningMustache(node); + const strip = node.openStrip.open ? "~" : ""; + return concat$C([opening, strip, "#"]); +} + +function printOpeningBlockClosingMustache(node) { + const closing = printClosingMustache(node); + const strip = node.openStrip.close ? "~" : ""; + return concat$C([strip, closing]); +} + +function printClosingBlockOpeningMustache(node) { + const opening = printOpeningMustache(node); + const strip = node.closeStrip.open ? "~" : ""; + return concat$C([opening, strip, "/"]); +} + +function printClosingBlockClosingMustache(node) { + const closing = printClosingMustache(node); + const strip = node.closeStrip.close ? "~" : ""; + return concat$C([strip, closing]); +} + +function printInverseBlockOpeningMustache(node) { + const opening = printOpeningMustache(node); + const strip = node.inverseStrip.open ? "~" : ""; + return concat$C([opening, strip]); +} + +function printInverseBlockClosingMustache(node) { + const closing = printClosingMustache(node); + const strip = node.inverseStrip.close ? "~" : ""; + return concat$C([strip, closing]); +} + +function printOpenBlock(path, print) { + const node = path.getValue(); + return group$r(concat$C([printOpeningBlockOpeningMustache(node), printPathAndParams(path, print), printBlockParams(node.program), softline$j, printOpeningBlockClosingMustache(node)])); +} + +function printElseBlock(node) { + return concat$C([hardline$p, printInverseBlockOpeningMustache(node), "else", printInverseBlockClosingMustache(node)]); +} + +function printElseIfBlock(path, print) { + const parentNode = path.getParentNode(1); + return concat$C([printInverseBlockOpeningMustache(parentNode), "else ", printPathAndParams(path, print), printInverseBlockClosingMustache(parentNode)]); +} + +function printCloseBlock(path, print) { + const node = path.getValue(); + return concat$C([blockStatementHasOnlyWhitespaceInProgram(node) ? softline$j : hardline$p, printClosingBlockOpeningMustache(node), path.call(print, "path"), printClosingBlockClosingMustache(node)]); +} + +function blockStatementHasOnlyWhitespaceInProgram(node) { + return isNodeOfSomeType$1(node, ["BlockStatement"]) && node.program.body.every(n => isWhitespaceNode$1(n)); +} + +function blockStatementHasElseIf(node) { + return blockStatementHasElse(node) && node.inverse.body.length === 1 && isNodeOfSomeType$1(node.inverse.body[0], ["BlockStatement"]) && node.inverse.body[0].path.parts[0] === "if"; +} + +function blockStatementHasElse(node) { + return isNodeOfSomeType$1(node, ["BlockStatement"]) && node.inverse; +} + +function printProgram(path, print) { + const node = path.getValue(); + + if (blockStatementHasOnlyWhitespaceInProgram(node)) { + return ""; + } + + const program = path.call(print, "program"); + return indent$s(concat$C([hardline$p, program])); +} + +function printInverse(path, print) { + const node = path.getValue(); + const inverse = path.call(print, "inverse"); + const parts = concat$C([hardline$p, inverse]); + + if (blockStatementHasElseIf(node)) { + return parts; + } + + if (blockStatementHasElse(node)) { + return concat$C([printElseBlock(node), indent$s(parts)]); + } + + return ""; +} +/* TextNode print helpers */ + + +function isInAttributeOfName(path, type) { + return isParentOfSomeType$1(path, ["AttrNode"]) && path.getParentNode().name.toLowerCase() === type || isParentOfSomeType$1(path, ["ConcatStatement"]) && path.getParentNode(1).name.toLowerCase() === type; +} + +function countNewLines(string) { + /* istanbul ignore next */ + string = typeof string === "string" ? string : ""; + return string.split("\n").length - 1; +} + +function countLeadingNewLines(string) { + /* istanbul ignore next */ + string = typeof string === "string" ? string : ""; + const newLines = (string.match(/^([^\S\n\r]*[\n\r])+/g) || [])[0] || ""; + return countNewLines(newLines); +} + +function countTrailingNewLines(string) { + /* istanbul ignore next */ + string = typeof string === "string" ? string : ""; + const newLines = (string.match(/([\n\r][^\S\n\r]*)+$/g) || [])[0] || ""; + return countNewLines(newLines); +} + +function generateHardlines(number = 0, max = 0) { + return new Array(Math.min(number, max)).fill(hardline$p); +} +/* StringLiteral print helpers */ + /** * Prints a string literal with the correct surrounding quotes based on * `options.singleQuote` and the number of escaped quotes contained in @@ -45647,125 +50066,84 @@ function printStringLiteral(stringLiteral, options) { const enclosingQuote = shouldUseAlternateQuote ? alternate : preferred; const escapedStringLiteral = stringLiteral.replace(enclosingQuote.regex, `\\${enclosingQuote.quote}`); - return concat$a([enclosingQuote.quote, escapedStringLiteral, enclosingQuote.quote]); + return concat$C([enclosingQuote.quote, escapedStringLiteral, enclosingQuote.quote]); } +/* SubExpression print helpers */ -function printPath(path, print) { - return path.call(print, "path"); -} -function printParams(path, print) { - const node = path.getValue(); - let parts = []; - - if (node.params.length > 0) { - parts = parts.concat(path.map(print, "params")); - } +function printSubExpressionPathAndParams(path, print) { + const p = printPath(path, print); + const params = printParams(path, print); - if (node.hash && node.hash.pairs.length > 0) { - parts.push(path.call(print, "hash")); + if (!params) { + return p; } - return parts; + return indent$s(concat$C([p, line$l, group$r(params)])); } +/* misc. print helpers */ -function printPathParams(path, print) { - const printedPath = printPath(path, print); - const printedParams = printParams(path, print); - const parts = [printedPath, ...printedParams]; - return indent$6(group$a(join$7(line$6, parts))); -} -function printBlockParams(path) { - const block = path.getValue(); +function printPathAndParams(path, print) { + const p = printPath(path, print); + const params = printParams(path, print); - if (!block.program || !block.program.blockParams.length) { - return ""; + if (!params) { + return p; } - return concat$a([" as |", block.program.blockParams.join(" "), "|"]); + return indent$s(group$r(concat$C([p, line$l, params]))); } -function printOpenBlock(path, print, { - open: isOpenStrip = false, - close: isCloseStrip = false -} = {}) { - return group$a(concat$a([isOpenStrip ? "{{~#" : "{{#", printPathParams(path, print), printBlockParams(path), softline$4, isCloseStrip ? "~}}" : "}}"])); +function printPath(path, print) { + return path.call(print, "path"); } -function printCloseBlock(path, print, { - open: isOpenStrip = false, - close: isCloseStrip = false -} = {}) { - return concat$a([isOpenStrip ? "{{~/" : "{{/", path.call(print, "path"), isCloseStrip ? "~}}" : "}}"]); -} +function printParams(path, print) { + const node = path.getValue(); + const parts = []; -function countNewLines(string) { - /* istanbul ignore next */ - string = typeof string === "string" ? string : ""; - return string.split("\n").length - 1; -} + if (node.params.length) { + const params = path.map(print, "params"); + parts.push(...params); + } -function countLeadingNewLines(string) { - /* istanbul ignore next */ - string = typeof string === "string" ? string : ""; - const newLines = (string.match(/^([^\S\r\n]*[\r\n])+/g) || [])[0] || ""; - return countNewLines(newLines); -} + if (node.hash && node.hash.pairs.length > 0) { + const hash = path.call(print, "hash"); + parts.push(hash); + } -function countTrailingNewLines(string) { - /* istanbul ignore next */ - string = typeof string === "string" ? string : ""; - const newLines = (string.match(/([\r\n][^\S\r\n]*)+$/g) || [])[0] || ""; - return countNewLines(newLines); -} + if (!parts.length) { + return ""; + } -function generateHardlines(number = 0, max = 0) { - return new Array(Math.min(number, max)).fill(hardline$8); + return join$i(line$l, parts); } -/* istanbul ignore next - https://github.com/glimmerjs/glimmer-vm/blob/master/packages/%40glimmer/compiler/lib/location.ts#L5-L29 -*/ - - -function locationToOffset(source, line, column) { - let seenLines = 0; - let seenChars = 0; // eslint-disable-next-line no-constant-condition - while (true) { - if (seenChars === source.length) { - return null; - } - - let nextLine = source.indexOf("\n", seenChars); - - if (nextLine === -1) { - nextLine = source.length; - } +function printBlockParams(node) { + if (!node || !node.blockParams.length) { + return ""; + } - if (seenLines === line) { - if (seenChars + column > nextLine) { - return null; - } + return concat$C([" as |", node.blockParams.join(" "), "|"]); +} - return seenChars + column; - } else if (nextLine === -1) { - return null; - } +function doesNotHaveHashParams(node) { + return node.hash.pairs.length === 0; +} - seenLines += 1; - seenChars = nextLine + 1; - } +function doesNotHavePositionalParams(node) { + return node.params.length === 0; } var printerGlimmer = { - print, - massageAstNode: clean$3 + print: print$2, + massageAstNode: clean_1$2 }; var name$d = "Handlebars"; var type$b = "markup"; -var group$b = "HTML"; +var color$5 = "#f7931e"; var aliases$3 = [ "hbs", "htmlbars" @@ -45777,10 +50155,10 @@ var extensions$b = [ var tmScope$b = "text.html.handlebars"; var aceMode$b = "handlebars"; var languageId$b = 155; -var Handlebars = { +var require$$0$4 = { name: name$d, type: type$b, - group: group$b, + color: color$5, aliases: aliases$3, extensions: extensions$b, tmScope: tmScope$b, @@ -45788,22 +50166,7 @@ var Handlebars = { languageId: languageId$b }; -var Handlebars$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - name: name$d, - type: type$b, - group: group$b, - aliases: aliases$3, - extensions: extensions$b, - tmScope: tmScope$b, - aceMode: aceMode$b, - languageId: languageId$b, - 'default': Handlebars -}); - -var require$$0$3 = getCjsExportFromNamespace(Handlebars$1); - -const languages$2 = [createLanguage(require$$0$3, () => ({ +const languages$2 = [createLanguage(require$$0$4, () => ({ since: null, // unreleased parsers: ["glimmer"], @@ -45812,13 +50175,20 @@ const languages$2 = [createLanguage(require$$0$3, () => ({ const printers$2 = { glimmer: printerGlimmer }; +const parsers$2 = { + get glimmer() { + return require("./parser-glimmer").parsers.glimmer; + } + +}; var languageHandlebars = { languages: languages$2, - printers: printers$2 + printers: printers$2, + parsers: parsers$2 }; function hasPragma$2(text) { - return /^\s*#[^\n\S]*@(format|prettier)\s*(\n|$)/.test(text); + return /^\s*#[^\S\n]*@(format|prettier)\s*(\n|$)/.test(text); } function insertPragma$4(text) { @@ -45830,25 +50200,49 @@ var pragma$2 = { insertPragma: insertPragma$4 }; +function locStart$d(node) { + if (typeof node.start === "number") { + return node.start; + } + + return node.loc && node.loc.start; +} + +function locEnd$j(node) { + if (typeof node.end === "number") { + return node.end; + } + + return node.loc && node.loc.end; +} + +var loc$3 = { + locStart: locStart$d, + locEnd: locEnd$j +}; + const { - concat: concat$b, - join: join$8, - hardline: hardline$9, - line: line$7, - softline: softline$5, - group: group$c, - indent: indent$7, - ifBreak: ifBreak$4 -} = document.builders; -const { - hasIgnoreComment: hasIgnoreComment$4 -} = util$1; + builders: { + concat: concat$D, + join: join$j, + hardline: hardline$q, + line: line$m, + softline: softline$k, + group: group$s, + indent: indent$t, + ifBreak: ifBreak$g + } +} = document; const { - isNextLineEmpty: isNextLineEmpty$4 -} = utilShared; + isNextLineEmpty: isNextLineEmpty$b +} = util; const { insertPragma: insertPragma$5 } = pragma$2; +const { + locStart: locStart$e, + locEnd: locEnd$k +} = loc$3; function genericPrint$3(path, options, print) { const n = path.getValue(); @@ -45865,40 +50259,40 @@ function genericPrint$3(path, options, print) { case "Document": { const parts = []; - path.map((pathChild, index) => { - parts.push(concat$b([pathChild.call(print)])); + path.each((pathChild, index) => { + parts.push(concat$D([pathChild.call(print)])); if (index !== n.definitions.length - 1) { - parts.push(hardline$9); + parts.push(hardline$q); - if (isNextLineEmpty$4(options.originalText, pathChild.getValue(), options.locEnd)) { - parts.push(hardline$9); + if (isNextLineEmpty$b(options.originalText, pathChild.getValue(), locEnd$k)) { + parts.push(hardline$q); } } }, "definitions"); - return concat$b([concat$b(parts), hardline$9]); + return concat$D([concat$D(parts), hardline$q]); } case "OperationDefinition": { - const hasOperation = options.originalText[options.locStart(n)] !== "{"; + const hasOperation = options.originalText[locStart$e(n)] !== "{"; const hasName = !!n.name; - return concat$b([hasOperation ? n.operation : "", hasOperation && hasName ? concat$b([" ", path.call(print, "name")]) : "", n.variableDefinitions && n.variableDefinitions.length ? group$c(concat$b(["(", indent$7(concat$b([softline$5, join$8(concat$b([ifBreak$4("", ", "), softline$5]), path.map(print, "variableDefinitions"))])), softline$5, ")"])) : "", printDirectives(path, print, n), n.selectionSet ? !hasOperation && !hasName ? "" : " " : "", path.call(print, "selectionSet")]); + return concat$D([hasOperation ? n.operation : "", hasOperation && hasName ? concat$D([" ", path.call(print, "name")]) : "", n.variableDefinitions && n.variableDefinitions.length ? group$s(concat$D(["(", indent$t(concat$D([softline$k, join$j(concat$D([ifBreak$g("", ", "), softline$k]), path.map(print, "variableDefinitions"))])), softline$k, ")"])) : "", printDirectives(path, print, n), n.selectionSet ? !hasOperation && !hasName ? "" : " " : "", path.call(print, "selectionSet")]); } case "FragmentDefinition": { - return concat$b(["fragment ", path.call(print, "name"), n.variableDefinitions && n.variableDefinitions.length ? group$c(concat$b(["(", indent$7(concat$b([softline$5, join$8(concat$b([ifBreak$4("", ", "), softline$5]), path.map(print, "variableDefinitions"))])), softline$5, ")"])) : "", " on ", path.call(print, "typeCondition"), printDirectives(path, print, n), " ", path.call(print, "selectionSet")]); + return concat$D(["fragment ", path.call(print, "name"), n.variableDefinitions && n.variableDefinitions.length ? group$s(concat$D(["(", indent$t(concat$D([softline$k, join$j(concat$D([ifBreak$g("", ", "), softline$k]), path.map(print, "variableDefinitions"))])), softline$k, ")"])) : "", " on ", path.call(print, "typeCondition"), printDirectives(path, print, n), " ", path.call(print, "selectionSet")]); } case "SelectionSet": { - return concat$b(["{", indent$7(concat$b([hardline$9, join$8(hardline$9, path.call(selectionsPath => printSequence(selectionsPath, options, print), "selections"))])), hardline$9, "}"]); + return concat$D(["{", indent$t(concat$D([hardline$q, join$j(hardline$q, path.call(selectionsPath => printSequence(selectionsPath, options, print), "selections"))])), hardline$q, "}"]); } case "Field": { - return group$c(concat$b([n.alias ? concat$b([path.call(print, "alias"), ": "]) : "", path.call(print, "name"), n.arguments.length > 0 ? group$c(concat$b(["(", indent$7(concat$b([softline$5, join$8(concat$b([ifBreak$4("", ", "), softline$5]), path.call(argsPath => printSequence(argsPath, options, print), "arguments"))])), softline$5, ")"])) : "", printDirectives(path, print, n), n.selectionSet ? " " : "", path.call(print, "selectionSet")])); + return group$s(concat$D([n.alias ? concat$D([path.call(print, "alias"), ": "]) : "", path.call(print, "name"), n.arguments.length > 0 ? group$s(concat$D(["(", indent$t(concat$D([softline$k, join$j(concat$D([ifBreak$g("", ", "), softline$k]), path.call(argsPath => printSequence(argsPath, options, print), "arguments"))])), softline$k, ")"])) : "", printDirectives(path, print, n), n.selectionSet ? " " : "", path.call(print, "selectionSet")])); } case "Name": @@ -45909,10 +50303,10 @@ function genericPrint$3(path, options, print) { case "StringValue": { if (n.block) { - return concat$b(['"""', hardline$9, join$8(hardline$9, n.value.replace(/"""/g, "\\$&").split("\n")), hardline$9, '"""']); + return concat$D(['"""', hardline$q, join$j(hardline$q, n.value.replace(/"""/g, "\\$&").split("\n")), hardline$q, '"""']); } - return concat$b(['"', n.value.replace(/["\\]/g, "\\$&").replace(/\n/g, "\\n"), '"']); + return concat$D(['"', n.value.replace(/["\\]/g, "\\$&").replace(/\n/g, "\\n"), '"']); } case "IntValue": @@ -45934,28 +50328,28 @@ function genericPrint$3(path, options, print) { case "Variable": { - return concat$b(["$", path.call(print, "name")]); + return concat$D(["$", path.call(print, "name")]); } case "ListValue": { - return group$c(concat$b(["[", indent$7(concat$b([softline$5, join$8(concat$b([ifBreak$4("", ", "), softline$5]), path.map(print, "values"))])), softline$5, "]"])); + return group$s(concat$D(["[", indent$t(concat$D([softline$k, join$j(concat$D([ifBreak$g("", ", "), softline$k]), path.map(print, "values"))])), softline$k, "]"])); } case "ObjectValue": { - return group$c(concat$b(["{", options.bracketSpacing && n.fields.length > 0 ? " " : "", indent$7(concat$b([softline$5, join$8(concat$b([ifBreak$4("", ", "), softline$5]), path.map(print, "fields"))])), softline$5, ifBreak$4("", options.bracketSpacing && n.fields.length > 0 ? " " : ""), "}"])); + return group$s(concat$D(["{", options.bracketSpacing && n.fields.length > 0 ? " " : "", indent$t(concat$D([softline$k, join$j(concat$D([ifBreak$g("", ", "), softline$k]), path.map(print, "fields"))])), softline$k, ifBreak$g("", options.bracketSpacing && n.fields.length > 0 ? " " : ""), "}"])); } case "ObjectField": case "Argument": { - return concat$b([path.call(print, "name"), ": ", path.call(print, "value")]); + return concat$D([path.call(print, "name"), ": ", path.call(print, "value")]); } case "Directive": { - return concat$b(["@", path.call(print, "name"), n.arguments.length > 0 ? group$c(concat$b(["(", indent$7(concat$b([softline$5, join$8(concat$b([ifBreak$4("", ", "), softline$5]), path.call(argsPath => printSequence(argsPath, options, print), "arguments"))])), softline$5, ")"])) : ""]); + return concat$D(["@", path.call(print, "name"), n.arguments.length > 0 ? group$s(concat$D(["(", indent$t(concat$D([softline$k, join$j(concat$D([ifBreak$g("", ", "), softline$k]), path.call(argsPath => printSequence(argsPath, options, print), "arguments"))])), softline$k, ")"])) : ""]); } case "NamedType": @@ -45965,98 +50359,93 @@ function genericPrint$3(path, options, print) { case "VariableDefinition": { - return concat$b([path.call(print, "variable"), ": ", path.call(print, "type"), n.defaultValue ? concat$b([" = ", path.call(print, "defaultValue")]) : "", printDirectives(path, print, n)]); - } - - case "TypeExtensionDefinition": - { - return concat$b(["extend ", path.call(print, "definition")]); + return concat$D([path.call(print, "variable"), ": ", path.call(print, "type"), n.defaultValue ? concat$D([" = ", path.call(print, "defaultValue")]) : "", printDirectives(path, print, n)]); } case "ObjectTypeExtension": case "ObjectTypeDefinition": { - return concat$b([path.call(print, "description"), n.description ? hardline$9 : "", n.kind === "ObjectTypeExtension" ? "extend " : "", "type ", path.call(print, "name"), n.interfaces.length > 0 ? concat$b([" implements ", concat$b(printInterfaces(path, options, print))]) : "", printDirectives(path, print, n), n.fields.length > 0 ? concat$b([" {", indent$7(concat$b([hardline$9, join$8(hardline$9, path.call(fieldsPath => printSequence(fieldsPath, options, print), "fields"))])), hardline$9, "}"]) : ""]); + return concat$D([path.call(print, "description"), n.description ? hardline$q : "", n.kind === "ObjectTypeExtension" ? "extend " : "", "type ", path.call(print, "name"), n.interfaces.length > 0 ? concat$D([" implements ", concat$D(printInterfaces(path, options, print))]) : "", printDirectives(path, print, n), n.fields.length > 0 ? concat$D([" {", indent$t(concat$D([hardline$q, join$j(hardline$q, path.call(fieldsPath => printSequence(fieldsPath, options, print), "fields"))])), hardline$q, "}"]) : ""]); } case "FieldDefinition": { - return concat$b([path.call(print, "description"), n.description ? hardline$9 : "", path.call(print, "name"), n.arguments.length > 0 ? group$c(concat$b(["(", indent$7(concat$b([softline$5, join$8(concat$b([ifBreak$4("", ", "), softline$5]), path.call(argsPath => printSequence(argsPath, options, print), "arguments"))])), softline$5, ")"])) : "", ": ", path.call(print, "type"), printDirectives(path, print, n)]); + return concat$D([path.call(print, "description"), n.description ? hardline$q : "", path.call(print, "name"), n.arguments.length > 0 ? group$s(concat$D(["(", indent$t(concat$D([softline$k, join$j(concat$D([ifBreak$g("", ", "), softline$k]), path.call(argsPath => printSequence(argsPath, options, print), "arguments"))])), softline$k, ")"])) : "", ": ", path.call(print, "type"), printDirectives(path, print, n)]); } case "DirectiveDefinition": { - return concat$b([path.call(print, "description"), n.description ? hardline$9 : "", "directive ", "@", path.call(print, "name"), n.arguments.length > 0 ? group$c(concat$b(["(", indent$7(concat$b([softline$5, join$8(concat$b([ifBreak$4("", ", "), softline$5]), path.call(argsPath => printSequence(argsPath, options, print), "arguments"))])), softline$5, ")"])) : "", n.repeatable ? " repeatable" : "", concat$b([" on ", join$8(" | ", path.map(print, "locations"))])]); + return concat$D([path.call(print, "description"), n.description ? hardline$q : "", "directive ", "@", path.call(print, "name"), n.arguments.length > 0 ? group$s(concat$D(["(", indent$t(concat$D([softline$k, join$j(concat$D([ifBreak$g("", ", "), softline$k]), path.call(argsPath => printSequence(argsPath, options, print), "arguments"))])), softline$k, ")"])) : "", n.repeatable ? " repeatable" : "", concat$D([" on ", join$j(" | ", path.map(print, "locations"))])]); } case "EnumTypeExtension": case "EnumTypeDefinition": { - return concat$b([path.call(print, "description"), n.description ? hardline$9 : "", n.kind === "EnumTypeExtension" ? "extend " : "", "enum ", path.call(print, "name"), printDirectives(path, print, n), n.values.length > 0 ? concat$b([" {", indent$7(concat$b([hardline$9, join$8(hardline$9, path.call(valuesPath => printSequence(valuesPath, options, print), "values"))])), hardline$9, "}"]) : ""]); + return concat$D([path.call(print, "description"), n.description ? hardline$q : "", n.kind === "EnumTypeExtension" ? "extend " : "", "enum ", path.call(print, "name"), printDirectives(path, print, n), n.values.length > 0 ? concat$D([" {", indent$t(concat$D([hardline$q, join$j(hardline$q, path.call(valuesPath => printSequence(valuesPath, options, print), "values"))])), hardline$q, "}"]) : ""]); } case "EnumValueDefinition": { - return concat$b([path.call(print, "description"), n.description ? hardline$9 : "", path.call(print, "name"), printDirectives(path, print, n)]); + return concat$D([path.call(print, "description"), n.description ? hardline$q : "", path.call(print, "name"), printDirectives(path, print, n)]); } case "InputValueDefinition": { - return concat$b([path.call(print, "description"), n.description ? n.description.block ? hardline$9 : line$7 : "", path.call(print, "name"), ": ", path.call(print, "type"), n.defaultValue ? concat$b([" = ", path.call(print, "defaultValue")]) : "", printDirectives(path, print, n)]); + return concat$D([path.call(print, "description"), n.description ? n.description.block ? hardline$q : line$m : "", path.call(print, "name"), ": ", path.call(print, "type"), n.defaultValue ? concat$D([" = ", path.call(print, "defaultValue")]) : "", printDirectives(path, print, n)]); } case "InputObjectTypeExtension": case "InputObjectTypeDefinition": { - return concat$b([path.call(print, "description"), n.description ? hardline$9 : "", n.kind === "InputObjectTypeExtension" ? "extend " : "", "input ", path.call(print, "name"), printDirectives(path, print, n), n.fields.length > 0 ? concat$b([" {", indent$7(concat$b([hardline$9, join$8(hardline$9, path.call(fieldsPath => printSequence(fieldsPath, options, print), "fields"))])), hardline$9, "}"]) : ""]); + return concat$D([path.call(print, "description"), n.description ? hardline$q : "", n.kind === "InputObjectTypeExtension" ? "extend " : "", "input ", path.call(print, "name"), printDirectives(path, print, n), n.fields.length > 0 ? concat$D([" {", indent$t(concat$D([hardline$q, join$j(hardline$q, path.call(fieldsPath => printSequence(fieldsPath, options, print), "fields"))])), hardline$q, "}"]) : ""]); } case "SchemaDefinition": { - return concat$b(["schema", printDirectives(path, print, n), " {", n.operationTypes.length > 0 ? indent$7(concat$b([hardline$9, join$8(hardline$9, path.call(opsPath => printSequence(opsPath, options, print), "operationTypes"))])) : "", hardline$9, "}"]); + return concat$D(["schema", printDirectives(path, print, n), " {", n.operationTypes.length > 0 ? indent$t(concat$D([hardline$q, join$j(hardline$q, path.call(opsPath => printSequence(opsPath, options, print), "operationTypes"))])) : "", hardline$q, "}"]); } case "OperationTypeDefinition": { - return concat$b([path.call(print, "operation"), ": ", path.call(print, "type")]); + return concat$D([path.call(print, "operation"), ": ", path.call(print, "type")]); } case "InterfaceTypeExtension": case "InterfaceTypeDefinition": { - return concat$b([path.call(print, "description"), n.description ? hardline$9 : "", n.kind === "InterfaceTypeExtension" ? "extend " : "", "interface ", path.call(print, "name"), printDirectives(path, print, n), n.fields.length > 0 ? concat$b([" {", indent$7(concat$b([hardline$9, join$8(hardline$9, path.call(fieldsPath => printSequence(fieldsPath, options, print), "fields"))])), hardline$9, "}"]) : ""]); + return concat$D([path.call(print, "description"), n.description ? hardline$q : "", n.kind === "InterfaceTypeExtension" ? "extend " : "", "interface ", path.call(print, "name"), n.interfaces.length > 0 ? concat$D([" implements ", concat$D(printInterfaces(path, options, print))]) : "", printDirectives(path, print, n), n.fields.length > 0 ? concat$D([" {", indent$t(concat$D([hardline$q, join$j(hardline$q, path.call(fieldsPath => printSequence(fieldsPath, options, print), "fields"))])), hardline$q, "}"]) : ""]); } case "FragmentSpread": { - return concat$b(["...", path.call(print, "name"), printDirectives(path, print, n)]); + return concat$D(["...", path.call(print, "name"), printDirectives(path, print, n)]); } case "InlineFragment": { - return concat$b(["...", n.typeCondition ? concat$b([" on ", path.call(print, "typeCondition")]) : "", printDirectives(path, print, n), " ", path.call(print, "selectionSet")]); + return concat$D(["...", n.typeCondition ? concat$D([" on ", path.call(print, "typeCondition")]) : "", printDirectives(path, print, n), " ", path.call(print, "selectionSet")]); } case "UnionTypeExtension": case "UnionTypeDefinition": { - return group$c(concat$b([path.call(print, "description"), n.description ? hardline$9 : "", group$c(concat$b([n.kind === "UnionTypeExtension" ? "extend " : "", "union ", path.call(print, "name"), printDirectives(path, print, n), n.types.length > 0 ? concat$b([" =", ifBreak$4("", " "), indent$7(concat$b([ifBreak$4(concat$b([line$7, " "])), join$8(concat$b([line$7, "| "]), path.map(print, "types"))]))]) : ""]))])); + return group$s(concat$D([path.call(print, "description"), n.description ? hardline$q : "", group$s(concat$D([n.kind === "UnionTypeExtension" ? "extend " : "", "union ", path.call(print, "name"), printDirectives(path, print, n), n.types.length > 0 ? concat$D([" =", ifBreak$g("", " "), indent$t(concat$D([ifBreak$g(concat$D([line$m, " "])), join$j(concat$D([line$m, "| "]), path.map(print, "types"))]))]) : ""]))])); } case "ScalarTypeExtension": case "ScalarTypeDefinition": { - return concat$b([path.call(print, "description"), n.description ? hardline$9 : "", n.kind === "ScalarTypeExtension" ? "extend " : "", "scalar ", path.call(print, "name"), printDirectives(path, print, n)]); + return concat$D([path.call(print, "description"), n.description ? hardline$q : "", n.kind === "ScalarTypeExtension" ? "extend " : "", "scalar ", path.call(print, "name"), printDirectives(path, print, n)]); } case "NonNullType": { - return concat$b([path.call(print, "type"), "!"]); + return concat$D([path.call(print, "type"), "!"]); } case "ListType": { - return concat$b(["[", path.call(print, "type"), "]"]); + return concat$D(["[", path.call(print, "type"), "]"]); } default: @@ -46070,7 +50459,13 @@ function printDirectives(path, print, n) { return ""; } - return concat$b([" ", group$c(indent$7(concat$b([softline$5, join$8(concat$b([ifBreak$4("", " "), softline$5]), path.map(print, "directives"))])))]); + const printed = join$j(line$m, path.map(print, "directives")); + + if (n.kind === "FragmentDefinition" || n.kind === "OperationDefinition") { + return group$s(concat$D([line$m, printed])); + } + + return concat$D([" ", group$s(indent$t(concat$D([softline$k, printed])))]); } function printSequence(sequencePath, options, print) { @@ -46078,8 +50473,8 @@ function printSequence(sequencePath, options, print) { return sequencePath.map((path, i) => { const printed = print(path); - if (isNextLineEmpty$4(options.originalText, path.getValue(), options.locEnd) && i < count - 1) { - return concat$b([printed, hardline$9]); + if (isNextLineEmpty$b(options.originalText, path.getValue(), locEnd$k) && i < count - 1) { + return concat$D([printed, hardline$q]); } return printed; @@ -46090,19 +50485,16 @@ function canAttachComment$1(node) { return node.kind && node.kind !== "Comment"; } -function printComment$2(commentPath) { +function printComment$3(commentPath) { const comment = commentPath.getValue(); if (comment.kind === "Comment") { return "#" + comment.value.trimEnd(); } + /* istanbul ignore next */ - throw new Error("Not a comment: " + JSON.stringify(comment)); -} -function determineInterfaceSeparatorBetween(first, second, options) { - const textBetween = options.originalText.slice(first.loc.end, second.loc.start).replace(/#.*/g, "").trim(); - return textBetween === "," ? ", " : " & "; + throw new Error("Not a comment: " + JSON.stringify(comment)); } function printInterfaces(path, options, print) { @@ -46115,30 +50507,38 @@ function printInterfaces(path, options, print) { for (let index = 0; index < interfaces.length; index++) { const interfaceNode = interfaces[index]; + parts.push(printed[index]); + const nextInterfaceNode = interfaces[index + 1]; - if (index > 0) { - parts.push(determineInterfaceSeparatorBetween(interfaces[index - 1], interfaceNode, options)); + if (nextInterfaceNode) { + const textBetween = options.originalText.slice(interfaceNode.loc.end, nextInterfaceNode.loc.start); + const hasComment = textBetween.includes("#"); + const separator = textBetween.replace(/#.*/g, "").trim(); + parts.push(separator === "," ? "," : " &"); + parts.push(hasComment ? line$m : " "); } - - parts.push(printed[index]); } return parts; } -function clean$4(node, newNode -/*, parent*/ -) { - delete newNode.loc; - delete newNode.comments; +function clean$4() +/*node, newNode , parent*/ +{} + +clean$4.ignoredProperties = new Set(["loc", "comments"]); + +function hasPrettierIgnore$4(path) { + const node = path.getValue(); + return node && Array.isArray(node.comments) && node.comments.some(comment => comment.value.trim() === "prettier-ignore"); } var printerGraphql = { print: genericPrint$3, massageAstNode: clean$4, - hasPrettierIgnore: hasIgnoreComment$4, + hasPrettierIgnore: hasPrettierIgnore$4, insertPragma: insertPragma$5, - printComment: printComment$2, + printComment: printComment$3, canAttachComment: canAttachComment$1 }; @@ -46148,6 +50548,7 @@ var options$4 = { var name$e = "GraphQL"; var type$c = "data"; +var color$6 = "#e10098"; var extensions$c = [ ".graphql", ".gql", @@ -46156,29 +50557,17 @@ var extensions$c = [ var tmScope$c = "source.graphql"; var aceMode$c = "text"; var languageId$c = 139; -var GraphQL = { +var require$$0$5 = { name: name$e, type: type$c, + color: color$6, extensions: extensions$c, tmScope: tmScope$c, aceMode: aceMode$c, languageId: languageId$c }; -var GraphQL$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - name: name$e, - type: type$c, - extensions: extensions$c, - tmScope: tmScope$c, - aceMode: aceMode$c, - languageId: languageId$c, - 'default': GraphQL -}); - -var require$$0$4 = getCjsExportFromNamespace(GraphQL$1); - -const languages$3 = [createLanguage(require$$0$4, () => ({ +const languages$3 = [createLanguage(require$$0$5, () => ({ since: "1.5.0", parsers: ["graphql"], vscodeLanguageIds: ["graphql"] @@ -46186,27 +50575,51 @@ const languages$3 = [createLanguage(require$$0$4, () => ({ const printers$3 = { graphql: printerGraphql }; +const parsers$3 = { + get graphql() { + return require("./parser-graphql").parsers.graphql; + } + +}; var languageGraphql = { languages: languages$3, options: options$4, - printers: printers$3 + printers: printers$3, + parsers: parsers$3 +}; + +function locStart$f(node) { + return node.position.start.offset; +} + +function locEnd$l(node) { + return node.position.end.offset; +} + +var loc$4 = { + locStart: locStart$f, + locEnd: locEnd$l }; var json = { - "cjkPattern": "[\\u02ea-\\u02eb\\u1100-\\u11ff\\u2e80-\\u2e99\\u2e9b-\\u2ef3\\u2f00-\\u2fd5\\u3000-\\u303f\\u3041-\\u3096\\u3099-\\u309f\\u30a1-\\u30fa\\u30fc-\\u30ff\\u3105-\\u312f\\u3131-\\u318e\\u3190-\\u3191\\u3196-\\u31ba\\u31c0-\\u31e3\\u31f0-\\u321e\\u322a-\\u3247\\u3260-\\u327e\\u328a-\\u32b0\\u32c0-\\u32cb\\u32d0-\\u3370\\u337b-\\u337f\\u33e0-\\u33fe\\u3400-\\u4db5\\u4e00-\\u9fef\\ua960-\\ua97c\\uac00-\\ud7a3\\ud7b0-\\ud7c6\\ud7cb-\\ud7fb\\uf900-\\ufa6d\\ufa70-\\ufad9\\ufe10-\\ufe1f\\ufe30-\\ufe6f\\uff00-\\uffef]|[\\ud840-\\ud868\\ud86a-\\ud86c\\ud86f-\\ud872\\ud874-\\ud879][\\udc00-\\udfff]|\\ud82c[\\udc00-\\udd1e\\udd50-\\udd52\\udd64-\\udd67]|\\ud83c[\\ude00\\ude50-\\ude51]|\\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]", + "cjkPattern": "(?:[\\u02ea-\\u02eb\\u1100-\\u11ff\\u2e80-\\u2e99\\u2e9b-\\u2ef3\\u2f00-\\u2fd5\\u3000-\\u303f\\u3041-\\u3096\\u3099-\\u309f\\u30a1-\\u30fa\\u30fc-\\u30ff\\u3105-\\u312f\\u3131-\\u318e\\u3190-\\u3191\\u3196-\\u31ba\\u31c0-\\u31e3\\u31f0-\\u321e\\u322a-\\u3247\\u3260-\\u327e\\u328a-\\u32b0\\u32c0-\\u32cb\\u32d0-\\u3370\\u337b-\\u337f\\u33e0-\\u33fe\\u3400-\\u4db5\\u4e00-\\u9fef\\ua960-\\ua97c\\uac00-\\ud7a3\\ud7b0-\\ud7c6\\ud7cb-\\ud7fb\\uf900-\\ufa6d\\ufa70-\\ufad9\\ufe10-\\ufe1f\\ufe30-\\ufe6f\\uff00-\\uffef]|[\\ud840-\\ud868\\ud86a-\\ud86c\\ud86f-\\ud872\\ud874-\\ud879][\\udc00-\\udfff]|\\ud82c[\\udc00-\\udd1e\\udd50-\\udd52\\udd64-\\udd67]|\\ud83c[\\ude00\\ude50-\\ude51]|\\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])(?:[\\ufe00-\\ufe0f]|\\udb40[\\udd00-\\uddef])?", "kPattern": "[\\u1100-\\u11ff\\u3001-\\u3003\\u3008-\\u3011\\u3013-\\u301f\\u302e-\\u3030\\u3037\\u30fb\\u3131-\\u318e\\u3200-\\u321e\\u3260-\\u327e\\ua960-\\ua97c\\uac00-\\ud7a3\\ud7b0-\\ud7c6\\ud7cb-\\ud7fb\\ufe45-\\ufe46\\uff61-\\uff65\\uffa0-\\uffbe\\uffc2-\\uffc7\\uffca-\\uffcf\\uffd2-\\uffd7\\uffda-\\uffdc]", "punctuationPattern": "[\\u0021-\\u002f\\u003a-\\u0040\\u005b-\\u0060\\u007b-\\u007e\\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\\u3001-\\u3003\\u3008-\\u3011\\u3014-\\u301f\\u3030\\u303d\\u30a0\\u30fb\\ua4fe-\\ua4ff\\ua60d-\\ua60f\\ua673\\ua67e\\ua6f2-\\ua6f7\\ua874-\\ua877\\ua8ce-\\ua8cf\\ua8f8-\\ua8fa\\ua8fc\\ua92e-\\ua92f\\ua95f\\ua9c1-\\ua9cd\\ua9de-\\ua9df\\uaa5c-\\uaa5f\\uaade-\\uaadf\\uaaf0-\\uaaf1\\uabeb\\ufd3e-\\ufd3f\\ufe10-\\ufe19\\ufe30-\\ufe52\\ufe54-\\ufe61\\ufe63\\ufe68\\ufe6a-\\ufe6b\\uff01-\\uff03\\uff05-\\uff0a\\uff0c-\\uff0f\\uff1a-\\uff1b\\uff1f-\\uff20\\uff3b-\\uff3d\\uff3f\\uff5b\\uff5d\\uff5f-\\uff65]|\\ud800[\\udd00-\\udd02\\udf9f\\udfd0]|\\ud801[\\udd6f]|\\ud802[\\udc57\\udd1f\\udd3f\\ude50-\\ude58\\ude7f\\udef0-\\udef6\\udf39-\\udf3f\\udf99-\\udf9c]|\\ud803[\\udf55-\\udf59]|\\ud804[\\udc47-\\udc4d\\udcbb-\\udcbc\\udcbe-\\udcc1\\udd40-\\udd43\\udd74-\\udd75\\uddc5-\\uddc8\\uddcd\\udddb\\udddd-\\udddf\\ude38-\\ude3d\\udea9]|\\ud805[\\udc4b-\\udc4f\\udc5b\\udc5d\\udcc6\\uddc1-\\uddd7\\ude41-\\ude43\\ude60-\\ude6c\\udf3c-\\udf3e]|\\ud806[\\udc3b\\udde2\\ude3f-\\ude46\\ude9a-\\ude9c\\ude9e-\\udea2]|\\ud807[\\udc41-\\udc45\\udc70-\\udc71\\udef7-\\udef8\\udfff]|\\ud809[\\udc70-\\udc74]|\\ud81a[\\ude6e-\\ude6f\\udef5\\udf37-\\udf3b\\udf44]|\\ud81b[\\ude97-\\ude9a\\udfe2]|\\ud82f[\\udc9f]|\\ud836[\\ude87-\\ude8b]|\\ud83a[\\udd5e-\\udd5f]" }; +const { + getLast: getLast$b +} = util; +const { + locStart: locStart$g, + locEnd: locEnd$m +} = loc$4; const { cjkPattern, kPattern, punctuationPattern } = json; -const { - getLast: getLast$4 -} = util$1; -const INLINE_NODE_TYPES = ["liquidNode", "inlineCode", "emphasis", "strong", "delete", "link", "linkReference", "image", "imageReference", "footnote", "footnoteReference", "sentence", "whitespace", "word", "break", "inlineMath"]; +const INLINE_NODE_TYPES = ["liquidNode", "inlineCode", "emphasis", "strong", "delete", "wikiLink", "link", "linkReference", "image", "imageReference", "footnote", "footnoteReference", "sentence", "whitespace", "word", "break", "inlineMath"]; const INLINE_NODE_WRAPPER_TYPES = INLINE_NODE_TYPES.concat(["tableCell", "paragraph", "heading"]); const kRegex = new RegExp(kPattern); const punctuationRegex = new RegExp(punctuationPattern); @@ -46222,7 +50635,7 @@ function splitText(text, options) { const KIND_K_LETTER = "k-letter"; const KIND_CJK_PUNCTUATION = "cjk-punctuation"; const nodes = []; - (options.proseWrap === "preserve" ? text : text.replace(new RegExp(`(${cjkPattern})\n(${cjkPattern})`, "g"), "$1$2")).split(/([ \t\n]+)/).forEach((token, index, tokens) => { + (options.proseWrap === "preserve" ? text : text.replace(new RegExp(`(${cjkPattern})\n(${cjkPattern})`, "g"), "$1$2")).split(/([\t\n ]+)/).forEach((token, index, tokens) => { // whitespace if (index % 2 === 1) { nodes.push({ @@ -46250,7 +50663,7 @@ function splitText(text, options) { value: innerToken, kind: KIND_NON_CJK, hasLeadingPunctuation: punctuationRegex.test(innerToken[0]), - hasTrailingPunctuation: punctuationRegex.test(getLast$4(innerToken)) + hasTrailingPunctuation: punctuationRegex.test(getLast$b(innerToken)) }); } @@ -46276,7 +50689,7 @@ function splitText(text, options) { return nodes; function appendNode(node) { - const lastNode = getLast$4(nodes); + const lastNode = getLast$b(nodes); if (lastNode && lastNode.type === "word") { if (lastNode.kind === KIND_NON_CJK && node.kind === KIND_CJ_LETTER && !lastNode.hasTrailingPunctuation || lastNode.kind === KIND_CJ_LETTER && node.kind === KIND_NON_CJK && !node.hasLeadingPunctuation) { @@ -46328,26 +50741,21 @@ function hasGitDiffFriendlyOrderedList(node, options) { } return secondNumber === 1; -} // workaround for https://github.com/remarkjs/remark/issues/351 -// leading and trailing newlines are stripped by remark +} // The final new line should not include in value +// https://github.com/remarkjs/remark/issues/512 function getFencedCodeBlockValue(node, originalText) { - const text = originalText.slice(node.position.start.offset, node.position.end.offset); - const leadingSpaceCount = text.match(/^\s*/)[0].length; - const replaceRegex = new RegExp(`^\\s{0,${leadingSpaceCount}}`); - const lineContents = text.split("\n"); - const markerStyle = text[leadingSpaceCount]; // ` or ~ - - const marker = text.slice(leadingSpaceCount).match(new RegExp(`^[${markerStyle}]+`))[0]; // https://spec.commonmark.org/0.28/#example-104: Closing fences may be indented by 0-3 spaces - // https://spec.commonmark.org/0.28/#example-93: The closing code fence must be at least as long as the opening fence - - const hasEndMarker = new RegExp(`^\\s{0,3}${marker}`).test(lineContents[lineContents.length - 1].slice(getIndent(lineContents.length - 1))); - return lineContents.slice(1, hasEndMarker ? -1 : undefined).map((x, i) => x.slice(getIndent(i + 1)).replace(replaceRegex, "")).join("\n"); + const { + value + } = node; - function getIndent(lineIndex) { - return node.position.indent[lineIndex - 1] - 1; + if (node.position.end.offset === originalText.length && value.endsWith("\n") && // Code block has no end mark + originalText.endsWith("\n")) { + return value.slice(0, -1); } + + return value; } function mapAst(ast, handler) { @@ -46365,6 +50773,15 @@ function mapAst(ast, handler) { }(ast, null, null); } +function isAutolink(node) { + if (!node || node.type !== "link" || node.children.length !== 1) { + return false; + } + + const child = node.children[0]; + return child && locStart$g(node) === locStart$g(child) && locEnd$m(node) === locEnd$m(child); +} + var utils$9 = { mapAst, splitText, @@ -46373,20 +50790,27 @@ var utils$9 = { getOrderedListItemInfo, hasGitDiffFriendlyOrderedList, INLINE_NODE_TYPES, - INLINE_NODE_WRAPPER_TYPES + INLINE_NODE_WRAPPER_TYPES, + isAutolink }; +const { + inferParserByLanguage: inferParserByLanguage$1, + getMaxContinuousCount: getMaxContinuousCount$2 +} = util; const { builders: { - hardline: hardline$a, - literalline: literalline$4, - concat: concat$c, + hardline: hardline$r, + concat: concat$E, markAsRoot: markAsRoot$2 }, utils: { - mapDoc: mapDoc$3 + replaceNewlinesWithLiterallines: replaceNewlinesWithLiterallines$2 } } = document; +const { + print: printFrontMatter$1 +} = frontMatter; const { getFencedCodeBlockValue: getFencedCodeBlockValue$1 } = utils$9; @@ -46395,63 +50819,49 @@ function embed$2(path, print, textToDoc, options) { const node = path.getValue(); if (node.type === "code" && node.lang !== null) { - // only look for the first string so as to support [markdown-preview-enhanced](https://shd101wyy.github.io/markdown-preview-enhanced/#/code-chunk) - const langMatch = node.lang.match(/^[A-Za-z0-9_-]+/); - const lang = langMatch ? langMatch[0] : ""; - const parser = getParserName(lang); + const parser = inferParserByLanguage$1(node.lang, options); if (parser) { const styleUnit = options.__inJsTemplate ? "~" : "`"; - const style = styleUnit.repeat(Math.max(3, util$1.getMaxContinuousCount(node.value, styleUnit) + 1)); + const style = styleUnit.repeat(Math.max(3, getMaxContinuousCount$2(node.value, styleUnit) + 1)); const doc = textToDoc(getFencedCodeBlockValue$1(node, options.originalText), { parser + }, { + stripTrailingHardline: true }); - return markAsRoot$2(concat$c([style, node.lang, hardline$a, replaceNewlinesWithLiterallines(doc), style])); + return markAsRoot$2(concat$E([style, node.lang, node.meta ? " " + node.meta : "", hardline$r, replaceNewlinesWithLiterallines$2(doc), hardline$r, style])); } } - if (node.type === "yaml") { - return markAsRoot$2(concat$c(["---", hardline$a, node.value && node.value.trim() ? replaceNewlinesWithLiterallines(textToDoc(node.value, { - parser: "yaml" - })) : "", "---"])); - } // MDX - - switch (node.type) { + case "front-matter": + return printFrontMatter$1(node, textToDoc); + // MDX + case "importExport": - return textToDoc(node.value, { + return concat$E([textToDoc(node.value, { parser: "babel" - }); + }, { + stripTrailingHardline: true + }), hardline$r]); case "jsx": return textToDoc(`<$>${node.value}`, { parser: "__js_expression", rootMarker: "mdx" + }, { + stripTrailingHardline: true }); } return null; - - function getParserName(lang) { - const supportInfo = support.getSupportInfo({ - plugins: options.plugins - }); - const language = supportInfo.languages.find(language => language.name.toLowerCase() === lang || language.aliases && language.aliases.includes(lang) || language.extensions && language.extensions.find(ext => ext === `.${lang}`)); - - if (language) { - return language.parsers[0]; - } - - return null; - } - - function replaceNewlinesWithLiterallines(doc) { - return mapDoc$3(doc, currentDoc => typeof currentDoc === "string" && currentDoc.includes("\n") ? concat$c(currentDoc.split(/(\n)/g).map((v, i) => i % 2 === 0 ? v : literalline$4)) : currentDoc); - } } var embed_1$2 = embed$2; +const { + parse: parseFrontMatter$1 +} = frontMatter; const pragmas = ["format", "prettier"]; function startWithPragma(text) { @@ -46463,9 +50873,9 @@ function startWithPragma(text) { var pragma$3 = { startWithPragma, - hasPragma: text => startWithPragma(frontMatter(text).content.trimStart()), + hasPragma: text => startWithPragma(parseFrontMatter$1(text).content.trimStart()), insertPragma: text => { - const extracted = frontMatter(text); + const extracted = parseFrontMatter$1(text); const pragma = ``; return extracted.frontMatter ? `${extracted.frontMatter.raw}\n\n${pragma}\n\n${extracted.content}` : `${pragma}\n\n${extracted.content}`; } @@ -46517,12 +50927,10 @@ function transformInlineCode(ast) { } function restoreUnescapedCharacter(ast, options) { - return mapAst$1(ast, node => { - return node.type !== "text" ? node : Object.assign({}, node, { - value: node.value !== "*" && node.value !== "_" && node.value !== "$" && // handle these cases in printer - isSingleCharRegex.test(node.value) && node.position.end.offset - node.position.start.offset !== node.value.length ? options.originalText.slice(node.position.start.offset, node.position.end.offset) : node.value - }); - }); + return mapAst$1(ast, node => node.type !== "text" || node.value === "*" || node.value === "_" || // handle these cases in printer + !isSingleCharRegex.test(node.value) || node.position.end.offset - node.position.start.offset === node.value.length ? node : Object.assign({}, node, { + value: options.originalText.slice(node.position.start.offset, node.position.end.offset) + })); } function mergeContinuousImportExport(ast) { @@ -46732,60 +51140,135 @@ function markAlignedList(ast, options) { } } -var preprocess_1$1 = preprocess$1; +var printPreprocess$1 = preprocess$1; + +const { + isFrontMatterNode: isFrontMatterNode$3 +} = util; +const { + startWithPragma: startWithPragma$1 +} = pragma$3; +const ignoredProperties$3 = new Set(["position", "raw" // front-matter +]); + +function clean$5(ast, newObj, parent) { + // for codeblock + if (ast.type === "front-matter" || ast.type === "code" || ast.type === "yaml" || ast.type === "import" || ast.type === "export" || ast.type === "jsx") { + delete newObj.value; + } + + if (ast.type === "list") { + delete newObj.isAligned; + } + + if (ast.type === "list" || ast.type === "listItem") { + delete newObj.spread; + delete newObj.loose; + } // texts can be splitted or merged + + + if (ast.type === "text") { + return null; + } + + if (ast.type === "inlineCode") { + newObj.value = ast.value.replace(/[\t\n ]+/g, " "); + } + + if (ast.type === "wikiLink") { + newObj.value = ast.value.trim().replace(/[\t\n]+/g, " "); + } + + if (ast.type === "definition" || ast.type === "linkReference") { + newObj.label = ast.label.trim().replace(/[\t\n ]+/g, " ").toLowerCase(); + } + + if ((ast.type === "definition" || ast.type === "link" || ast.type === "image") && ast.title) { + newObj.title = ast.title.replace(/\\(["')])/g, "$1"); + } // for insert pragma + + + if (parent && parent.type === "root" && parent.children.length > 0 && (parent.children[0] === ast || isFrontMatterNode$3(parent.children[0]) && parent.children[1] === ast) && ast.type === "html" && startWithPragma$1(ast.value)) { + return null; + } +} + +clean$5.ignoredProperties = ignoredProperties$3; +var clean_1$3 = clean$5; +const { + getLast: getLast$c, + getMinNotPresentContinuousCount: getMinNotPresentContinuousCount$1, + getMaxContinuousCount: getMaxContinuousCount$3, + getStringWidth: getStringWidth$4 +} = util; const { builders: { - breakParent: breakParent$3, - concat: concat$d, - join: join$9, - line: line$8, - literalline: literalline$5, + breakParent: breakParent$6, + concat: concat$F, + join: join$k, + line: line$n, + literalline: literalline$4, markAsRoot: markAsRoot$3, - hardline: hardline$b, - softline: softline$6, - ifBreak: ifBreak$5, + hardline: hardline$s, + softline: softline$l, + ifBreak: ifBreak$h, fill: fill$5, - align: align$2, - indent: indent$8, - group: group$d + align: align$5, + indent: indent$u, + group: group$t }, utils: { - mapDoc: mapDoc$4 + normalizeDoc: normalizeDoc$1 }, printer: { printDocToString: printDocToString$3 } } = document; +const { + replaceEndOfLineWith: replaceEndOfLineWith$1 +} = util; +const { + insertPragma: insertPragma$6 +} = pragma$3; +const { + locStart: locStart$h, + locEnd: locEnd$n +} = loc$4; const { getFencedCodeBlockValue: getFencedCodeBlockValue$2, hasGitDiffFriendlyOrderedList: hasGitDiffFriendlyOrderedList$1, splitText: splitText$2, punctuationPattern: punctuationPattern$1, INLINE_NODE_TYPES: INLINE_NODE_TYPES$1, - INLINE_NODE_WRAPPER_TYPES: INLINE_NODE_WRAPPER_TYPES$1 + INLINE_NODE_WRAPPER_TYPES: INLINE_NODE_WRAPPER_TYPES$1, + isAutolink: isAutolink$1 } = utils$9; -const { - replaceEndOfLineWith: replaceEndOfLineWith$1 -} = util$1; -const TRAILING_HARDLINE_NODES = ["importExport"]; -const SINGLE_LINE_NODE_TYPES = ["heading", "tableCell", "link"]; -const SIBLING_NODE_TYPES = ["listItem", "definition", "footnoteDefinition"]; +/** + * @typedef {import("../document").Doc} Doc + */ + +const TRAILING_HARDLINE_NODES = new Set(["importExport"]); +const SINGLE_LINE_NODE_TYPES = ["heading", "tableCell", "link", "wikiLink"]; +const SIBLING_NODE_TYPES = new Set(["listItem", "definition", "footnoteDefinition"]); function genericPrint$4(path, options, print) { const node = path.getValue(); if (shouldRemainTheSameContent(path)) { - return concat$d(splitText$2(options.originalText.slice(node.position.start.offset, node.position.end.offset), options).map(node => node.type === "word" ? node.value : node.value === "" ? "" : printLine(path, node.value, options))); + return concat$F(splitText$2(options.originalText.slice(node.position.start.offset, node.position.end.offset), options).map(node => node.type === "word" ? node.value : node.value === "" ? "" : printLine(path, node.value, options))); } switch (node.type) { + case "front-matter": + return options.originalText.slice(node.position.start.offset, node.position.end.offset); + case "root": if (node.children.length === 0) { return ""; } - return concat$d([normalizeDoc(printRoot(path, options, print)), !TRAILING_HARDLINE_NODES.includes(getLastDescendantNode(node).type) ? hardline$b : ""]); + return concat$F([normalizeDoc$1(printRoot(path, options, print)), !TRAILING_HARDLINE_NODES.has(getLastDescendantNode(node).type) ? hardline$s : ""]); case "paragraph": return printChildren$1(path, options, print, { @@ -46796,9 +51279,21 @@ function genericPrint$4(path, options, print) { return printChildren$1(path, options, print); case "word": - return node.value.replace(/[*$]/g, "\\$&") // escape all `*` and `$` (math) - .replace(new RegExp([`(^|${punctuationPattern$1})(_+)`, `(_+)(${punctuationPattern$1}|$)`].join("|"), "g"), (_, text1, underscore1, underscore2, text2) => (underscore1 ? `${text1}${underscore1}` : `${underscore2}${text2}`).replace(/_/g, "\\_")); - // escape all `_` except concating with non-punctuation, e.g. `1_2_3` is not considered emphasis + { + let escapedValue = node.value.replace(/\*/g, "\\$&") // escape all `*` + .replace(new RegExp([`(^|${punctuationPattern$1})(_+)`, `(_+)(${punctuationPattern$1}|$)`].join("|"), "g"), (_, text1, underscore1, underscore2, text2) => (underscore1 ? `${text1}${underscore1}` : `${underscore2}${text2}`).replace(/_/g, "\\_")); // escape all `_` except concating with non-punctuation, e.g. `1_2_3` is not considered emphasis + + const isFirstSentence = (node, name, index) => node.type === "sentence" && index === 0; + + const isLastChildAutolink = (node, name, index) => isAutolink$1(node.children[index - 1]); + + if (escapedValue !== node.value && (path.match(undefined, isFirstSentence, isLastChildAutolink) || path.match(undefined, isFirstSentence, (node, name, index) => node.type === "emphasis" && index === 0, isLastChildAutolink))) { + // backslash is parsed as part of autolinks, so we need to remove it + escapedValue = escapedValue.replace(/^(\\?[*_])+/, prefix => prefix.replace(/\\/g, "")); + } + + return escapedValue; + } case "whitespace": { @@ -46806,7 +51301,7 @@ function genericPrint$4(path, options, print) { const index = parentNode.children.indexOf(node); const nextNode = parentNode.children[index + 1]; const proseWrap = // leading char that may cause different syntax - nextNode && /^>|^([-+*]|#{1,6}|[0-9]+[.)])$/.test(nextNode.value) ? "never" : options.proseWrap; + nextNode && /^>|^([*+-]|#{1,6}|\d+[).])$/.test(nextNode.value) ? "never" : options.proseWrap; return printLine(path, node.value, { proseWrap }); @@ -46814,28 +51309,48 @@ function genericPrint$4(path, options, print) { case "emphasis": { - const parentNode = path.getParentNode(); - const index = parentNode.children.indexOf(node); - const prevNode = parentNode.children[index - 1]; - const nextNode = parentNode.children[index + 1]; - const hasPrevOrNextWord = // `1*2*3` is considered emphasis but `1_2_3` is not - prevNode && prevNode.type === "sentence" && prevNode.children.length > 0 && util$1.getLast(prevNode.children).type === "word" && !util$1.getLast(prevNode.children).hasTrailingPunctuation || nextNode && nextNode.type === "sentence" && nextNode.children.length > 0 && nextNode.children[0].type === "word" && !nextNode.children[0].hasLeadingPunctuation; - const style = hasPrevOrNextWord || getAncestorNode$2(path, "emphasis") ? "*" : "_"; - return concat$d([style, printChildren$1(path, options, print), style]); + let style; + + if (isAutolink$1(node.children[0])) { + style = options.originalText[node.position.start.offset]; + } else { + const parentNode = path.getParentNode(); + const index = parentNode.children.indexOf(node); + const prevNode = parentNode.children[index - 1]; + const nextNode = parentNode.children[index + 1]; + const hasPrevOrNextWord = // `1*2*3` is considered emphasis but `1_2_3` is not + prevNode && prevNode.type === "sentence" && prevNode.children.length > 0 && getLast$c(prevNode.children).type === "word" && !getLast$c(prevNode.children).hasTrailingPunctuation || nextNode && nextNode.type === "sentence" && nextNode.children.length > 0 && nextNode.children[0].type === "word" && !nextNode.children[0].hasLeadingPunctuation; + style = hasPrevOrNextWord || getAncestorNode$2(path, "emphasis") ? "*" : "_"; + } + + return concat$F([style, printChildren$1(path, options, print), style]); } case "strong": - return concat$d(["**", printChildren$1(path, options, print), "**"]); + return concat$F(["**", printChildren$1(path, options, print), "**"]); case "delete": - return concat$d(["~~", printChildren$1(path, options, print), "~~"]); + return concat$F(["~~", printChildren$1(path, options, print), "~~"]); case "inlineCode": { - const backtickCount = util$1.getMinNotPresentContinuousCount(node.value, "`"); + const backtickCount = getMinNotPresentContinuousCount$1(node.value, "`"); const style = "`".repeat(backtickCount || 1); - const gap = backtickCount ? " " : ""; - return concat$d([style, gap, node.value, gap, style]); + const gap = backtickCount && !/^\s/.test(node.value) ? " " : ""; + return concat$F([style, gap, node.value, gap, style]); + } + + case "wikiLink": + { + let contents = ""; + + if (options.proseWrap === "preserve") { + contents = node.value; + } else { + contents = node.value.replace(/[\t\n]+/g, " "); + } + + return concat$F(["[[", contents, "]]"]); } case "link": @@ -46845,49 +51360,45 @@ function genericPrint$4(path, options, print) { const mailto = "mailto:"; const url = // is parsed as { url: "mailto:hello@example.com" } node.url.startsWith(mailto) && options.originalText.slice(node.position.start.offset + 1, node.position.start.offset + 1 + mailto.length) !== mailto ? node.url.slice(mailto.length) : node.url; - return concat$d(["<", url, ">"]); + return concat$F(["<", url, ">"]); } case "[": - return concat$d(["[", printChildren$1(path, options, print), "](", printUrl(node.url, ")"), printTitle(node.title, options), ")"]); + return concat$F(["[", printChildren$1(path, options, print), "](", printUrl(node.url, ")"), printTitle(node.title, options), ")"]); default: return options.originalText.slice(node.position.start.offset, node.position.end.offset); } case "image": - return concat$d(["![", node.alt || "", "](", printUrl(node.url, ")"), printTitle(node.title, options), ")"]); + return concat$F(["![", node.alt || "", "](", printUrl(node.url, ")"), printTitle(node.title, options), ")"]); case "blockquote": - return concat$d(["> ", align$2("> ", printChildren$1(path, options, print))]); + return concat$F(["> ", align$5("> ", printChildren$1(path, options, print))]); case "heading": - return concat$d(["#".repeat(node.depth) + " ", printChildren$1(path, options, print)]); + return concat$F(["#".repeat(node.depth) + " ", printChildren$1(path, options, print)]); case "code": { if (node.isIndented) { // indented code block const alignment = " ".repeat(4); - return align$2(alignment, concat$d([alignment, concat$d(replaceEndOfLineWith$1(node.value, hardline$b))])); + return align$5(alignment, concat$F([alignment, concat$F(replaceEndOfLineWith$1(node.value, hardline$s))])); } // fenced code block const styleUnit = options.__inJsTemplate ? "~" : "`"; - const style = styleUnit.repeat(Math.max(3, util$1.getMaxContinuousCount(node.value, styleUnit) + 1)); - return concat$d([style, node.lang || "", hardline$b, concat$d(replaceEndOfLineWith$1(getFencedCodeBlockValue$2(node, options.originalText), hardline$b)), hardline$b, style]); + const style = styleUnit.repeat(Math.max(3, getMaxContinuousCount$3(node.value, styleUnit) + 1)); + return concat$F([style, node.lang || "", node.meta ? " " + node.meta : "", hardline$s, concat$F(replaceEndOfLineWith$1(getFencedCodeBlockValue$2(node, options.originalText), hardline$s)), hardline$s, style]); } - case "yaml": - case "toml": - return options.originalText.slice(node.position.start.offset, node.position.end.offset); - case "html": { const parentNode = path.getParentNode(); - const value = parentNode.type === "root" && util$1.getLast(parentNode.children) === node ? node.value.trimEnd() : node.value; - const isHtmlComment = /^$/.test(value); - return concat$d(replaceEndOfLineWith$1(value, isHtmlComment ? hardline$b : markAsRoot$3(literalline$5))); + const value = parentNode.type === "root" && getLast$c(parentNode.children) === node ? node.value.trimEnd() : node.value; + const isHtmlComment = /^$/.test(value); + return concat$F(replaceEndOfLineWith$1(value, isHtmlComment ? hardline$s : markAsRoot$3(literalline$4))); } case "list": @@ -46900,10 +51411,10 @@ function genericPrint$4(path, options, print) { const childNode = childPath.getValue(); if (childNode.children.length === 2 && childNode.children[1].type === "html" && childNode.children[0].position.start.column !== childNode.children[1].position.start.column) { - return concat$d([prefix, printListItem(childPath, options, print, prefix)]); + return concat$F([prefix, printListItem(childPath, options, print, prefix)]); } - return concat$d([prefix, align$2(" ".repeat(prefix.length), printListItem(childPath, options, print, prefix))]); + return concat$F([prefix, align$5(" ".repeat(prefix.length), printListItem(childPath, options, print, prefix))]); function getPrefix() { const rawPrefix = node.ordered ? (index === 0 ? node.start : isGitDiffFriendlyOrderedList ? 1 : node.start + index) + (nthSiblingIndex % 2 === 0 ? ". " : ") ") : nthSiblingIndex % 2 === 0 ? "- " : "* "; @@ -46928,38 +51439,42 @@ function genericPrint$4(path, options, print) { } case "linkReference": - return concat$d(["[", printChildren$1(path, options, print), "]", node.referenceType === "full" ? concat$d(["[", node.identifier, "]"]) : node.referenceType === "collapsed" ? "[]" : ""]); + return concat$F(["[", printChildren$1(path, options, print), "]", node.referenceType === "full" ? concat$F(["[", node.identifier, "]"]) : node.referenceType === "collapsed" ? "[]" : ""]); case "imageReference": switch (node.referenceType) { case "full": - return concat$d(["![", node.alt || "", "][", node.identifier, "]"]); + return concat$F(["![", node.alt || "", "][", node.identifier, "]"]); default: - return concat$d(["![", node.alt, "]", node.referenceType === "collapsed" ? "[]" : ""]); + return concat$F(["![", node.alt, "]", node.referenceType === "collapsed" ? "[]" : ""]); } case "definition": { - const lineOrSpace = options.proseWrap === "always" ? line$8 : " "; - return group$d(concat$d([concat$d(["[", node.identifier, "]:"]), indent$8(concat$d([lineOrSpace, printUrl(node.url), node.title === null ? "" : concat$d([lineOrSpace, printTitle(node.title, options, false)])]))])); + const lineOrSpace = options.proseWrap === "always" ? line$n : " "; + return group$t(concat$F([concat$F(["[", node.identifier, "]:"]), indent$u(concat$F([lineOrSpace, printUrl(node.url), node.title === null ? "" : concat$F([lineOrSpace, printTitle(node.title, options, false)])]))])); } + // `footnote` requires `.use(footnotes, {inlineNotes: true})`, we are not using this option + // https://github.com/remarkjs/remark-footnotes#optionsinlinenotes + + /* istanbul ignore next */ case "footnote": - return concat$d(["[^", printChildren$1(path, options, print), "]"]); + return concat$F(["[^", printChildren$1(path, options, print), "]"]); case "footnoteReference": - return concat$d(["[^", node.identifier, "]"]); + return concat$F(["[^", node.identifier, "]"]); case "footnoteDefinition": { const nextNode = path.getParentNode().children[path.getName() + 1]; const shouldInlineFootnote = node.children.length === 1 && node.children[0].type === "paragraph" && (options.proseWrap === "never" || options.proseWrap === "preserve" && node.children[0].position.start.line === node.children[0].position.end.line); - return concat$d(["[^", node.identifier, "]: ", shouldInlineFootnote ? printChildren$1(path, options, print) : group$d(concat$d([align$2(" ".repeat(options.tabWidth), printChildren$1(path, options, print, { + return concat$F(["[^", node.identifier, "]: ", shouldInlineFootnote ? printChildren$1(path, options, print) : group$t(concat$F([align$5(" ".repeat(4), printChildren$1(path, options, print, { processor: (childPath, index) => { - return index === 0 ? group$d(concat$d([softline$6, childPath.call(print)])) : childPath.call(print); + return index === 0 ? group$t(concat$F([softline$l, childPath.call(print)])) : childPath.call(print); } - })), nextNode && nextNode.type === "footnoteDefinition" ? softline$6 : ""]))]); + })), nextNode && nextNode.type === "footnoteDefinition" ? softline$l : ""]))]); } case "table": @@ -46969,25 +51484,28 @@ function genericPrint$4(path, options, print) { return printChildren$1(path, options, print); case "break": - return /\s/.test(options.originalText[node.position.start.offset]) ? concat$d([" ", markAsRoot$3(literalline$5)]) : concat$d(["\\", hardline$b]); + return /\s/.test(options.originalText[node.position.start.offset]) ? concat$F([" ", markAsRoot$3(literalline$4)]) : concat$F(["\\", hardline$s]); case "liquidNode": - return concat$d(replaceEndOfLineWith$1(node.value, hardline$b)); + return concat$F(replaceEndOfLineWith$1(node.value, hardline$s)); // MDX + // fallback to the original text if multiparser failed + // or `embeddedLanguageFormatting: "off"` case "importExport": + return concat$F([node.value, hardline$s]); + case "jsx": return node.value; - // fallback to the original text if multiparser failed case "math": - return concat$d(["$$", hardline$b, node.value ? concat$d([concat$d(replaceEndOfLineWith$1(node.value, hardline$b)), hardline$b]) : "", "$$"]); + return concat$F(["$$", hardline$s, node.value ? concat$F([concat$F(replaceEndOfLineWith$1(node.value, hardline$s)), hardline$s]) : "", "$$"]); case "inlineMath": { // remark-math trims content but we don't want to remove whitespaces // since it's very possible that it's recognized as math accidentally - return options.originalText.slice(options.locStart(node), options.locEnd(node)); + return options.originalText.slice(locStart$h(node), locEnd$n(node)); } case "tableRow": // handled in "table" @@ -46995,6 +51513,7 @@ function genericPrint$4(path, options, print) { case "listItem": // handled in "list" default: + /* istanbul ignore next */ throw new Error(`Unknown markdown type ${JSON.stringify(node.type)}`); } } @@ -47002,15 +51521,15 @@ function genericPrint$4(path, options, print) { function printListItem(path, options, print, listPrefix) { const node = path.getValue(); const prefix = node.checked === null ? "" : node.checked ? "[x] " : "[ ] "; - return concat$d([prefix, printChildren$1(path, options, print, { + return concat$F([prefix, printChildren$1(path, options, print, { processor: (childPath, index) => { if (index === 0 && childPath.getValue().type !== "list") { - return align$2(" ".repeat(prefix.length), childPath.call(print)); + return align$5(" ".repeat(prefix.length), childPath.call(print)); } const alignment = " ".repeat(clamp(options.tabWidth - listPrefix.length, 0, 3) // 4+ will cause indented code block ); - return concat$d([alignment, align$2(alignment, childPath.call(print))]); + return concat$F([alignment, align$5(alignment, childPath.call(print))]); } })]); } @@ -47069,94 +51588,87 @@ function getAncestorNode$2(path, typeOrTypes) { function printLine(path, value, options) { if (options.proseWrap === "preserve" && value === "\n") { - return hardline$b; + return hardline$s; } const isBreakable = options.proseWrap === "always" && !getAncestorNode$2(path, SINGLE_LINE_NODE_TYPES); - return value !== "" ? isBreakable ? line$8 : " " : isBreakable ? softline$6 : ""; + return value !== "" ? isBreakable ? line$n : " " : isBreakable ? softline$l : ""; } function printTable(path, options, print) { - const hardlineWithoutBreakParent = hardline$b.parts[0]; + const hardlineWithoutBreakParent = hardline$s.parts[0]; const node = path.getValue(); - const contents = []; // { [rowIndex: number]: { [columnIndex: number]: string } } - - path.map(rowPath => { - const rowContents = []; - rowPath.map(cellPath => { - rowContents.push(printDocToString$3(cellPath.call(print), options).formatted); - }, "children"); - contents.push(rowContents); - }, "children"); // Get the width of each column + const columnMaxWidths = []; // { [rowIndex: number]: { [columnIndex: number]: {text: string, width: number} } } - const columnMaxWidths = contents.reduce((currentWidths, rowContents) => currentWidths.map((width, columnIndex) => Math.max(width, util$1.getStringWidth(rowContents[columnIndex]))), contents[0].map(() => 3) // minimum width = 3 (---, :--, :-:, --:) - ); - const alignedTable = join$9(hardlineWithoutBreakParent, [printRow(contents[0]), printSeparator(), join$9(hardlineWithoutBreakParent, contents.slice(1).map(rowContents => printRow(rowContents)))]); + const contents = path.map(rowPath => rowPath.map((cellPath, columnIndex) => { + const text = printDocToString$3(cellPath.call(print), options).formatted; + const width = getStringWidth$4(text); + columnMaxWidths[columnIndex] = Math.max(columnMaxWidths[columnIndex] || 3, // minimum width = 3 (---, :--, :-:, --:) + width); + return { + text, + width + }; + }, "children"), "children"); + const alignedTable = printTableContents( + /* isCompact */ + false); if (options.proseWrap !== "never") { - return concat$d([breakParent$3, alignedTable]); + return concat$F([breakParent$6, alignedTable]); } // Only if the --prose-wrap never is set and it exceeds the print width. - const compactTable = join$9(hardlineWithoutBreakParent, [printRow(contents[0], - /* isCompact */ - true), printSeparator( + const compactTable = printTableContents( /* isCompact */ - true), join$9(hardlineWithoutBreakParent, contents.slice(1).map(rowContents => printRow(rowContents, - /* isCompact */ - true)))]); - return concat$d([breakParent$3, group$d(ifBreak$5(compactTable, alignedTable))]); - - function printSeparator(isCompact) { - return concat$d(["| ", join$9(" | ", columnMaxWidths.map((width, index) => { - const spaces = isCompact ? 3 : width; + true); + return concat$F([breakParent$6, group$t(ifBreak$h(compactTable, alignedTable))]); - switch (node.align[index]) { - case "left": - return ":" + "-".repeat(spaces - 1); + function printTableContents(isCompact) { + /** @type{Doc[]} */ + const parts = [printRow(contents[0], isCompact), printAlign(isCompact)]; - case "right": - return "-".repeat(spaces - 1) + ":"; + if (contents.length > 1) { + parts.push(join$k(hardlineWithoutBreakParent, contents.slice(1).map(rowContents => printRow(rowContents, isCompact)))); + } - case "center": - return ":" + "-".repeat(spaces - 2) + ":"; + return join$k(hardlineWithoutBreakParent, parts); + } - default: - return "-".repeat(spaces); - } - })), " |"]); + function printAlign(isCompact) { + const align = columnMaxWidths.map((width, index) => { + const align = node.align[index]; + const first = align === "center" || align === "left" ? ":" : "-"; + const last = align === "center" || align === "right" ? ":" : "-"; + const middle = isCompact ? "-" : "-".repeat(width - 2); + return `${first}${middle}${last}`; + }); + return `| ${align.join(" | ")} |`; } function printRow(rowContents, isCompact) { - return concat$d(["| ", join$9(" | ", isCompact ? rowContents : rowContents.map((rowContent, columnIndex) => { - switch (node.align[columnIndex]) { - case "right": - return alignRight(rowContent, columnMaxWidths[columnIndex]); - - case "center": - return alignCenter(rowContent, columnMaxWidths[columnIndex]); - - default: - return alignLeft(rowContent, columnMaxWidths[columnIndex]); + const columns = rowContents.map(({ + text, + width + }, columnIndex) => { + if (isCompact) { + return text; } - })), " |"]); - } - function alignLeft(text, width) { - const spaces = width - util$1.getStringWidth(text); - return concat$d([text, " ".repeat(spaces)]); - } + const spaces = columnMaxWidths[columnIndex] - width; + const align = node.align[columnIndex]; + let before = 0; - function alignRight(text, width) { - const spaces = width - util$1.getStringWidth(text); - return concat$d([" ".repeat(spaces), text]); - } + if (align === "right") { + before = spaces; + } else if (align === "center") { + before = Math.floor(spaces / 2); + } - function alignCenter(text, width) { - const spaces = width - util$1.getStringWidth(text); - const left = Math.floor(spaces / 2); - const right = spaces - left; - return concat$d([" ".repeat(left), text, " ".repeat(right)]); + const after = spaces - before; + return `${" ".repeat(before)}${text}${" ".repeat(after)}`; + }); + return `| ${columns.join(" | ")} |`; } } @@ -47204,7 +51716,7 @@ function printRoot(path, options, print) { const ignoreRange = ignoreRanges[0]; if (index === ignoreRange.start.index) { - return concat$d([children[ignoreRange.start.index].value, options.originalText.slice(ignoreRange.start.offset, ignoreRange.end.offset), children[ignoreRange.end.index].value]); + return concat$F([children[ignoreRange.start.index].value, options.originalText.slice(ignoreRange.start.offset, ignoreRange.end.offset), children[ignoreRange.end.index].value]); } if (ignoreRange.start.index < index && index < ignoreRange.end.index) { @@ -47224,14 +51736,14 @@ function printRoot(path, options, print) { function printChildren$1(path, options, print, events) { events = events || {}; - const postprocessor = events.postprocessor || concat$d; + const postprocessor = events.postprocessor || concat$F; const processor = events.processor || (childPath => childPath.call(print)); const node = path.getValue(); const parts = []; let lastChildNode; - path.map((childPath, index) => { + path.each((childPath, index) => { const childNode = childPath.getValue(); const result = processor(childPath, index); @@ -47244,19 +51756,21 @@ function printChildren$1(path, options, print, events) { }; if (!shouldNotPrePrintHardline(childNode, data)) { - parts.push(hardline$b); + parts.push(hardline$s); // Can't find a case to pass `shouldPrePrintTripleHardline` + + /* istanbul ignore next */ - if (lastChildNode && TRAILING_HARDLINE_NODES.includes(lastChildNode.type)) { + if (lastChildNode && TRAILING_HARDLINE_NODES.has(lastChildNode.type)) { if (shouldPrePrintTripleHardline(childNode, data)) { - parts.push(hardline$b); + parts.push(hardline$s); } } else { if (shouldPrePrintDoubleHardline(childNode, data) || shouldPrePrintTripleHardline(childNode, data)) { - parts.push(hardline$b); + parts.push(hardline$s); } if (shouldPrePrintTripleHardline(childNode, data)) { - parts.push(hardline$b); + parts.push(hardline$s); } } } @@ -47298,7 +51812,7 @@ function shouldNotPrePrintHardline(node, data) { function shouldPrePrintDoubleHardline(node, data) { const isSequence = (data.prevNode && data.prevNode.type) === node.type; - const isSiblingNode = isSequence && SIBLING_NODE_TYPES.includes(node.type); + const isSiblingNode = isSequence && SIBLING_NODE_TYPES.has(node.type); const isInTightListItem = data.parentNode.type === "listItem" && !data.parentNode.loose; const isPrevNodeLooseListItem = data.prevNode && data.prevNode.type === "listItem" && data.prevNode.loose; const isPrevNodePrettierIgnore = isPrettierIgnore(data.prevNode) === "next"; @@ -47318,31 +51832,6 @@ function shouldRemainTheSameContent(path) { return ancestorNode && (ancestorNode.type !== "linkReference" || ancestorNode.referenceType !== "full"); } -function normalizeDoc(doc) { - return mapDoc$4(doc, currentDoc => { - if (!currentDoc.parts) { - return currentDoc; - } - - if (currentDoc.type === "concat" && currentDoc.parts.length === 1) { - return currentDoc.parts[0]; - } - - const parts = currentDoc.parts.reduce((parts, part) => { - if (part.type === "concat") { - parts.push(...part.parts); - } else if (part !== "") { - parts.push(part); - } - - return parts; - }, []); - return Object.assign({}, currentDoc, { - parts: normalizeParts(parts) - }); - }); -} - function printUrl(url, dangerousCharOrChars) { const dangerousChars = [" "].concat(dangerousCharOrChars || []); return new RegExp(dangerousChars.map(x => `\\${x}`).join("|")).test(url) ? `<${url}>` : url; @@ -47359,7 +51848,10 @@ function printTitle(title, options, printSpace) { if (printSpace) { return " " + printTitle(title, options, false); - } + } // title is escaped after `remark-parse` v7 + + + title = title.replace(/\\(["')])/g, "$1"); if (title.includes('"') && title.includes("'") && !title.includes(")")) { return `(${title})`; // avoid escaped quotes @@ -47369,57 +51861,16 @@ function printTitle(title, options, printSpace) { const singleCount = title.split("'").length - 1; const doubleCount = title.split('"').length - 1; const quote = singleCount > doubleCount ? '"' : doubleCount > singleCount ? "'" : options.singleQuote ? "'" : '"'; + title = title.replace(/\\/, "\\\\"); title = title.replace(new RegExp(`(${quote})`, "g"), "\\$1"); return `${quote}${title}${quote}`; } -function normalizeParts(parts) { - return parts.reduce((current, part) => { - const lastPart = util$1.getLast(current); - - if (typeof lastPart === "string" && typeof part === "string") { - current.splice(-1, 1, lastPart + part); - } else { - current.push(part); - } - - return current; - }, []); -} - function clamp(value, min, max) { return value < min ? min : value > max ? max : value; } -function clean$5(ast, newObj, parent) { - delete newObj.position; - delete newObj.raw; // front-matter - // for codeblock - - if (ast.type === "code" || ast.type === "yaml" || ast.type === "import" || ast.type === "export" || ast.type === "jsx") { - delete newObj.value; - } - - if (ast.type === "list") { - delete newObj.isAligned; - } // texts can be splitted or merged - - - if (ast.type === "text") { - return null; - } - - if (ast.type === "inlineCode") { - newObj.value = ast.value.replace(/[ \t\n]+/g, " "); - } // for insert pragma - - - if (parent && parent.type === "root" && parent.children.length > 0 && (parent.children[0] === ast || (parent.children[0].type === "yaml" || parent.children[0].type === "toml") && parent.children[1] === ast) && ast.type === "html" && pragma$3.startWithPragma(ast.value)) { - return null; - } -} - -function hasPrettierIgnore$4(path) { +function hasPrettierIgnore$5(path) { const index = +path.getName(); if (index === 0) { @@ -47431,12 +51882,12 @@ function hasPrettierIgnore$4(path) { } var printerMarkdown = { - preprocess: preprocess_1$1, + preprocess: printPreprocess$1, print: genericPrint$4, embed: embed_1$2, - massageAstNode: clean$5, - hasPrettierIgnore: hasPrettierIgnore$4, - insertPragma: pragma$3.insertPragma + massageAstNode: clean_1$3, + hasPrettierIgnore: hasPrettierIgnore$5, + insertPragma: insertPragma$6 }; var options$5 = { @@ -47446,6 +51897,7 @@ var options$5 = { var name$f = "Markdown"; var type$d = "prose"; +var color$7 = "#083fa1"; var aliases$4 = [ "pandoc" ]; @@ -47470,9 +51922,10 @@ var filenames$3 = [ ]; var tmScope$d = "source.gfm"; var languageId$d = 222; -var Markdown = { +var require$$0$6 = { name: name$f, type: type$d, + color: color$7, aliases: aliases$4, aceMode: aceMode$d, codemirrorMode: codemirrorMode$a, @@ -47484,31 +51937,13 @@ var Markdown = { languageId: languageId$d }; -var Markdown$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - name: name$f, - type: type$d, - aliases: aliases$4, - aceMode: aceMode$d, - codemirrorMode: codemirrorMode$a, - codemirrorMimeType: codemirrorMimeType$a, - wrap: wrap, - extensions: extensions$d, - filenames: filenames$3, - tmScope: tmScope$d, - languageId: languageId$d, - 'default': Markdown -}); - -var require$$0$5 = getCjsExportFromNamespace(Markdown$1); - -const languages$4 = [createLanguage(require$$0$5, data => ({ +const languages$4 = [createLanguage(require$$0$6, data => ({ since: "1.8.0", parsers: ["markdown"], vscodeLanguageIds: ["markdown"], filenames: data.filenames.concat(["README"]), extensions: data.extensions.filter(extension => extension !== ".mdx") -})), createLanguage(require$$0$5, () => ({ +})), createLanguage(require$$0$6, () => ({ name: "MDX", since: "1.15.0", parsers: ["mdx"], @@ -47519,25 +51954,40 @@ const languages$4 = [createLanguage(require$$0$5, data => ({ const printers$4 = { mdast: printerMarkdown }; +const parsers$4 = { + /* istanbul ignore next */ + get remark() { + return require("./parser-markdown").parsers.remark; + }, + + get markdown() { + return require("./parser-markdown").parsers.remark; + }, + + get mdx() { + return require("./parser-markdown").parsers.mdx; + } + +}; var languageMarkdown = { languages: languages$4, options: options$5, - printers: printers$4 + printers: printers$4, + parsers: parsers$4 }; -var clean$6 = function (ast, newNode) { - delete newNode.sourceSpan; - delete newNode.startSourceSpan; - delete newNode.endSourceSpan; - delete newNode.nameSpan; - delete newNode.valueSpan; +const { + isFrontMatterNode: isFrontMatterNode$4 +} = util; +const ignoredProperties$4 = new Set(["sourceSpan", "startSourceSpan", "endSourceSpan", "nameSpan", "valueSpan"]); +function clean$6(ast, newNode) { if (ast.type === "text" || ast.type === "comment") { return null; } // may be formatted by multiparser - if (ast.type === "yaml" || ast.type === "toml") { + if (isFrontMatterNode$4(ast) || ast.type === "yaml" || ast.type === "toml") { return null; } @@ -47548,96 +51998,12 @@ var clean$6 = function (ast, newNode) { if (ast.type === "docType") { delete newNode.value; } -}; +} -var json$1 = { - "CSS_DISPLAY_TAGS": { - "area": "none", - "base": "none", - "basefont": "none", - "datalist": "none", - "head": "none", - "link": "none", - "meta": "none", - "noembed": "none", - "noframes": "none", - "param": "none", - "rp": "none", - "script": "block", - "source": "block", - "style": "none", - "template": "inline", - "track": "block", - "title": "none", - "html": "block", - "body": "block", - "address": "block", - "blockquote": "block", - "center": "block", - "div": "block", - "figure": "block", - "figcaption": "block", - "footer": "block", - "form": "block", - "header": "block", - "hr": "block", - "legend": "block", - "listing": "block", - "main": "block", - "p": "block", - "plaintext": "block", - "pre": "block", - "xmp": "block", - "slot": "contents", - "ruby": "ruby", - "rt": "ruby-text", - "article": "block", - "aside": "block", - "h1": "block", - "h2": "block", - "h3": "block", - "h4": "block", - "h5": "block", - "h6": "block", - "hgroup": "block", - "nav": "block", - "section": "block", - "dir": "block", - "dd": "block", - "dl": "block", - "dt": "block", - "ol": "block", - "ul": "block", - "li": "list-item", - "table": "table", - "caption": "table-caption", - "colgroup": "table-column-group", - "col": "table-column", - "thead": "table-header-group", - "tbody": "table-row-group", - "tfoot": "table-footer-group", - "tr": "table-row", - "td": "table-cell", - "th": "table-cell", - "fieldset": "block", - "button": "inline-block", - "video": "inline-block", - "audio": "inline-block" - }, - "CSS_DISPLAY_DEFAULT": "inline", - "CSS_WHITE_SPACE_TAGS": { - "listing": "pre", - "plaintext": "pre", - "pre": "pre", - "xmp": "pre", - "nobr": "nowrap", - "table": "initial", - "textarea": "pre-wrap" - }, - "CSS_WHITE_SPACE_DEFAULT": "normal" -}; +clean$6.ignoredProperties = ignoredProperties$4; +var clean_1$4 = clean$6; -var index = [ +var htmlTagNames = [ "a", "abbr", "acronym", @@ -47788,11 +52154,6 @@ var index = [ "xmp" ]; -var htmlTagNames = /*#__PURE__*/Object.freeze({ - __proto__: null, - 'default': index -}); - var a = [ "accesskey", "charset", @@ -47915,7 +52276,7 @@ var colgroup = [ "valign", "width" ]; -var data$1 = [ +var data$2 = [ "value" ]; var del$1 = [ @@ -48008,7 +52369,7 @@ var hr = [ "size", "width" ]; -var html = [ +var html$1 = [ "manifest", "version" ]; @@ -48020,6 +52381,7 @@ var iframe = [ "allowusermedia", "frameborder", "height", + "loading", "longdesc", "marginheight", "marginwidth", @@ -48040,6 +52402,7 @@ var img = [ "height", "hspace", "ismap", + "loading", "longdesc", "name", "referrerpolicy", @@ -48114,6 +52477,7 @@ var link$3 = [ "charset", "color", "crossorigin", + "disabled", "href", "hreflang", "imagesizes", @@ -48150,7 +52514,7 @@ var meter = [ "optimum", "value" ]; -var object = [ +var object$1 = [ "align", "archive", "border", @@ -48238,7 +52602,7 @@ var select = [ var slot = [ "name" ]; -var source$1 = [ +var source$2 = [ "media", "sizes", "src", @@ -48364,7 +52728,7 @@ var video = [ "src", "width" ]; -var index$1 = { +var htmlElementAttributes = { "*": [ "accesskey", "autocapitalize", @@ -48408,7 +52772,7 @@ var index$1 = { caption: caption, col: col, colgroup: colgroup, - data: data$1, + data: data$2, del: del$1, details: details, dfn: dfn, @@ -48430,7 +52794,7 @@ var index$1 = { h6: h6, head: head, hr: hr, - html: html, + html: html$1, iframe: iframe, img: img, input: input, @@ -48444,7 +52808,7 @@ var index$1 = { menu: menu, meta: meta, meter: meter, - object: object, + object: object$1, ol: ol, optgroup: optgroup, option: option, @@ -48457,7 +52821,7 @@ var index$1 = { script: script, select: select, slot: slot, - source: source$1, + source: source$2, style: style, table: table, tbody: tbody, @@ -48473,102 +52837,141 @@ var index$1 = { video: video }; -var htmlElementAttributes = /*#__PURE__*/Object.freeze({ - __proto__: null, - a: a, - abbr: abbr, - applet: applet, - area: area, - audio: audio, - base: base, - basefont: basefont, - bdo: bdo, - blockquote: blockquote, - body: body, - br: br, - button: button, - canvas: canvas, - caption: caption, - col: col, - colgroup: colgroup, - data: data$1, - del: del$1, - details: details, - dfn: dfn, - dialog: dialog, - dir: dir, - div: div, - dl: dl, - embed: embed$3, - fieldset: fieldset, - font: font, - form: form, - frame: frame, - frameset: frameset, - h1: h1, - h2: h2, - h3: h3, - h4: h4, - h5: h5, - h6: h6, - head: head, - hr: hr, - html: html, - iframe: iframe, - img: img, - input: input, - ins: ins, - isindex: isindex, - label: label, - legend: legend, - li: li, - link: link$3, - map: map$1, - menu: menu, - meta: meta, - meter: meter, - object: object, - ol: ol, - optgroup: optgroup, - option: option, - output: output, - p: p, - param: param, - pre: pre, - progress: progress, - q: q, - script: script, - select: select, - slot: slot, - source: source$1, - style: style, - table: table, - tbody: tbody, - td: td, - textarea: textarea, - tfoot: tfoot, - th: th, - thead: thead, - time: time, - tr: tr, - track: track, - ul: ul, - video: video, - 'default': index$1 -}); - -var htmlTagNames$1 = getCjsExportFromNamespace(htmlTagNames); - -var htmlElementAttributes$1 = getCjsExportFromNamespace(htmlElementAttributes); +var json$1 = { + "CSS_DISPLAY_TAGS": { + "area": "none", + "base": "none", + "basefont": "none", + "datalist": "none", + "head": "none", + "link": "none", + "meta": "none", + "noembed": "none", + "noframes": "none", + "param": "block", + "rp": "none", + "script": "block", + "source": "block", + "style": "none", + "template": "inline", + "track": "block", + "title": "none", + "html": "block", + "body": "block", + "address": "block", + "blockquote": "block", + "center": "block", + "div": "block", + "figure": "block", + "figcaption": "block", + "footer": "block", + "form": "block", + "header": "block", + "hr": "block", + "legend": "block", + "listing": "block", + "main": "block", + "p": "block", + "plaintext": "block", + "pre": "block", + "xmp": "block", + "slot": "contents", + "ruby": "ruby", + "rt": "ruby-text", + "article": "block", + "aside": "block", + "h1": "block", + "h2": "block", + "h3": "block", + "h4": "block", + "h5": "block", + "h6": "block", + "hgroup": "block", + "nav": "block", + "section": "block", + "dir": "block", + "dd": "block", + "dl": "block", + "dt": "block", + "ol": "block", + "ul": "block", + "li": "list-item", + "table": "table", + "caption": "table-caption", + "colgroup": "table-column-group", + "col": "table-column", + "thead": "table-header-group", + "tbody": "table-row-group", + "tfoot": "table-footer-group", + "tr": "table-row", + "td": "table-cell", + "th": "table-cell", + "fieldset": "block", + "button": "inline-block", + "details": "block", + "summary": "block", + "dialog": "block", + "meter": "inline-block", + "progress": "inline-block", + "object": "inline-block", + "video": "inline-block", + "audio": "inline-block", + "select": "inline-block", + "option": "block", + "optgroup": "block" + }, + "CSS_DISPLAY_DEFAULT": "inline", + "CSS_WHITE_SPACE_TAGS": { + "listing": "pre", + "plaintext": "pre", + "pre": "pre", + "xmp": "pre", + "nobr": "nowrap", + "table": "initial", + "textarea": "pre-wrap" + }, + "CSS_WHITE_SPACE_DEFAULT": "normal" +}; +const { + inferParserByLanguage: inferParserByLanguage$2, + isFrontMatterNode: isFrontMatterNode$5 +} = util; const { CSS_DISPLAY_TAGS, CSS_DISPLAY_DEFAULT, CSS_WHITE_SPACE_TAGS, CSS_WHITE_SPACE_DEFAULT } = json$1; -const HTML_TAGS = arrayToMap(htmlTagNames$1); -const HTML_ELEMENT_ATTRIBUTES = mapObject(htmlElementAttributes$1, arrayToMap); +const HTML_TAGS = arrayToMap(htmlTagNames); +const HTML_ELEMENT_ATTRIBUTES = mapObject(htmlElementAttributes, arrayToMap); // https://infra.spec.whatwg.org/#ascii-whitespace + +const HTML_WHITESPACE = new Set(["\t", "\n", "\f", "\r", " "]); + +const htmlTrimStart = string => string.replace(/^[\t\n\f\r ]+/, ""); + +const htmlTrimEnd = string => string.replace(/[\t\n\f\r ]+$/, ""); + +const htmlTrim = string => htmlTrimStart(htmlTrimEnd(string)); + +const htmlTrimLeadingBlankLines = string => string.replace(/^[\t\f\r ]*?\n/g, ""); + +const htmlTrimPreserveIndentation = string => htmlTrimLeadingBlankLines(htmlTrimEnd(string)); + +const splitByHtmlWhitespace = string => string.split(/[\t\n\f\r ]+/); + +const getLeadingHtmlWhitespace = string => string.match(/^[\t\n\f\r ]*/)[0]; + +const getLeadingAndTrailingHtmlWhitespace = string => { + const [, leadingWhitespace, text, trailingWhitespace] = string.match(/^([\t\n\f\r ]*)([\S\s]*?)([\t\n\f\r ]*)$/); + return { + leadingWhitespace, + trailingWhitespace, + text + }; +}; + +const hasHtmlWhitespace = string => /[\t\n\f\r ]/.test(string); function arrayToMap(array) { const map = Object.create(null); @@ -48591,16 +52994,8 @@ function mapObject(object, fn) { } function shouldPreserveContent(node, options) { - if (!node.endSourceSpan) { - return false; - } - - if (node.type === "element" && node.fullName === "template" && node.attrMap.lang && node.attrMap.lang !== "html") { - return true; - } // unterminated node in ie conditional comment + // unterminated node in ie conditional comment // e.g. - - if (node.type === "ieConditionalComment" && node.lastChild && !node.lastChild.isSelfClosing && !node.lastChild.endSourceSpan) { return true; } // incomplete html in ie conditional comment @@ -48609,13 +53004,6 @@ function shouldPreserveContent(node, options) { if (node.type === "ieConditionalComment" && !node.complete) { return true; - } // top-level elements (excluding