1 (function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3 typeof define === 'function' && define.amd ? define(factory) :
4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.doc = factory());
5 }(this, (function () { 'use strict';
13 function concat(parts) {
14 // access the internals of a document directly.
15 // if(parts.length === 1) {
16 // // If it's a single document, no need to concat it.
27 * @param {Doc} contents
32 function indent(contents) {
40 * @param {number | string} n
41 * @param {Doc} contents
46 function align(n, contents) {
55 * @param {Doc} contents
56 * @param {object} [opts] - TBD ???
61 function group(contents, opts) {
68 break: !!opts.shouldBreak,
69 expandedStates: opts.expandedStates
73 * @param {Doc} contents
78 function dedentToRoot(contents) {
79 return align(-Infinity, contents);
82 * @param {Doc} contents
87 function markAsRoot(contents) {
88 // @ts-ignore - TBD ???:
94 * @param {Doc} contents
99 function dedent(contents) {
100 return align(-1, contents);
103 * @param {Doc[]} states
104 * @param {object} [opts] - TBD ???
109 function conditionalGroup(states, opts) {
110 return group(states[0], Object.assign({}, opts, {
111 expandedStates: states
115 * @param {Doc[]} parts
120 function fill(parts) {
128 * @param {Doc} [breakContents]
129 * @param {Doc} [flatContents]
130 * @param {object} [opts] - TBD ???
135 function ifBreak(breakContents, flatContents, opts) {
142 groupId: opts.groupId
146 * @param {Doc} contents
151 function lineSuffix(contents) {
159 const lineSuffixBoundary = {
160 type: "line-suffix-boundary"
162 const breakParent = {
175 const hardline = concat([{
179 const literalline = concat([{
186 placeholder: Symbol("cursor")
194 function join(sep, arr) {
197 for (let i = 0; i < arr.length; i++) {
209 * @param {number} size
210 * @param {number} tabWidth
214 function addAlignmentToDoc(doc, size, tabWidth) {
218 // Use indent to add tabs for all the levels of tabs we need
219 for (let i = 0; i < Math.floor(size / tabWidth); ++i) {
220 aligned = indent(aligned);
221 } // Use align for all the spaces that are needed
224 aligned = align(size % tabWidth, aligned); // size is absolute from 0 and not relative to the current
225 // indentation, so we use -Infinity to reset the indentation to 0
227 aligned = align(-Infinity, aligned);
260 const pattern = ['[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))'].join('|');
261 return new RegExp(pattern, onlyFirst ? undefined : 'g');
264 var stripAnsi = string => typeof string === 'string' ? string.replace(ansiRegex(), '') : string;
266 /* eslint-disable yoda */
268 const isFullwidthCodePoint = codePoint => {
269 if (Number.isNaN(codePoint)) {
271 } // Code points are derived from:
272 // http://www.unix.org/Public/UNIDATA/EastAsianWidth.txt
275 if (codePoint >= 0x1100 && (codePoint <= 0x115F || // Hangul Jamo
276 codePoint === 0x2329 || // LEFT-POINTING ANGLE BRACKET
277 codePoint === 0x232A || // RIGHT-POINTING ANGLE BRACKET
278 // CJK Radicals Supplement .. Enclosed CJK Letters and Months
279 0x2E80 <= codePoint && codePoint <= 0x3247 && codePoint !== 0x303F || // Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A
280 0x3250 <= codePoint && codePoint <= 0x4DBF || // CJK Unified Ideographs .. Yi Radicals
281 0x4E00 <= codePoint && codePoint <= 0xA4C6 || // Hangul Jamo Extended-A
282 0xA960 <= codePoint && codePoint <= 0xA97C || // Hangul Syllables
283 0xAC00 <= codePoint && codePoint <= 0xD7A3 || // CJK Compatibility Ideographs
284 0xF900 <= codePoint && codePoint <= 0xFAFF || // Vertical Forms
285 0xFE10 <= codePoint && codePoint <= 0xFE19 || // CJK Compatibility Forms .. Small Form Variants
286 0xFE30 <= codePoint && codePoint <= 0xFE6B || // Halfwidth and Fullwidth Forms
287 0xFF01 <= codePoint && codePoint <= 0xFF60 || 0xFFE0 <= codePoint && codePoint <= 0xFFE6 || // Kana Supplement
288 0x1B000 <= codePoint && codePoint <= 0x1B001 || // Enclosed Ideographic Supplement
289 0x1F200 <= codePoint && codePoint <= 0x1F251 || // CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane
290 0x20000 <= codePoint && codePoint <= 0x3FFFD)) {
297 var isFullwidthCodePoint_1 = isFullwidthCodePoint;
298 var _default = isFullwidthCodePoint;
299 isFullwidthCodePoint_1.default = _default;
301 var emojiRegex = function () {
302 // https://mths.be/emoji
303 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;
306 const stringWidth = string => {
307 string = string.replace(emojiRegex(), ' ');
309 if (typeof string !== 'string' || string.length === 0) {
313 string = stripAnsi(string);
316 for (let i = 0; i < string.length; i++) {
317 const code = string.codePointAt(i); // Ignore control characters
319 if (code <= 0x1F || code >= 0x7F && code <= 0x9F) {
321 } // Ignore combining characters
324 if (code >= 0x300 && code <= 0x36F) {
333 width += isFullwidthCodePoint_1(code) ? 2 : 1;
339 var stringWidth_1 = stringWidth; // TODO: remove this in the next major version
341 var _default$1 = stringWidth;
342 stringWidth_1.default = _default$1;
344 var escapeStringRegexp = string => {
345 if (typeof string !== 'string') {
346 throw new TypeError('Expected a string');
347 } // Escape characters with special meaning either inside or outside character sets.
348 // 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.
351 return string.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d');
354 var getLast = arr => arr[arr.length - 1];
356 function _objectWithoutPropertiesLoose(source, excluded) {
357 if (source == null) return {};
359 var sourceKeys = Object.keys(source);
362 for (i = 0; i < sourceKeys.length; i++) {
364 if (excluded.indexOf(key) >= 0) continue;
365 target[key] = source[key];
371 function _taggedTemplateLiteral(strings, raw) {
373 raw = strings.slice(0);
376 return Object.freeze(Object.defineProperties(strings, {
378 value: Object.freeze(raw)
383 var global$1 = typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};
385 // based off https://github.com/defunctzombie/node-process/blob/master/browser.js
387 function defaultSetTimout() {
388 throw new Error('setTimeout has not been defined');
391 function defaultClearTimeout() {
392 throw new Error('clearTimeout has not been defined');
395 var cachedSetTimeout = defaultSetTimout;
396 var cachedClearTimeout = defaultClearTimeout;
398 if (typeof global$1.setTimeout === 'function') {
399 cachedSetTimeout = setTimeout;
402 if (typeof global$1.clearTimeout === 'function') {
403 cachedClearTimeout = clearTimeout;
406 function runTimeout(fun) {
407 if (cachedSetTimeout === setTimeout) {
408 //normal enviroments in sane situations
409 return setTimeout(fun, 0);
410 } // if setTimeout wasn't available but was latter defined
413 if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
414 cachedSetTimeout = setTimeout;
415 return setTimeout(fun, 0);
419 // when when somebody has screwed with setTimeout but no I.E. maddness
420 return cachedSetTimeout(fun, 0);
423 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
424 return cachedSetTimeout.call(null, fun, 0);
426 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
427 return cachedSetTimeout.call(this, fun, 0);
432 function runClearTimeout(marker) {
433 if (cachedClearTimeout === clearTimeout) {
434 //normal enviroments in sane situations
435 return clearTimeout(marker);
436 } // if clearTimeout wasn't available but was latter defined
439 if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
440 cachedClearTimeout = clearTimeout;
441 return clearTimeout(marker);
445 // when when somebody has screwed with setTimeout but no I.E. maddness
446 return cachedClearTimeout(marker);
449 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
450 return cachedClearTimeout.call(null, marker);
452 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
453 // Some versions of I.E. have different rules for clearTimeout vs setTimeout
454 return cachedClearTimeout.call(this, marker);
460 var draining = false;
464 function cleanUpNextTick() {
465 if (!draining || !currentQueue) {
471 if (currentQueue.length) {
472 queue = currentQueue.concat(queue);
482 function drainQueue() {
487 var timeout = runTimeout(cleanUpNextTick);
489 var len = queue.length;
492 currentQueue = queue;
495 while (++queueIndex < len) {
497 currentQueue[queueIndex].run();
507 runClearTimeout(timeout);
510 function nextTick(fun) {
511 var args = new Array(arguments.length - 1);
513 if (arguments.length > 1) {
514 for (var i = 1; i < arguments.length; i++) {
515 args[i - 1] = arguments[i];
519 queue.push(new Item(fun, args));
521 if (queue.length === 1 && !draining) {
522 runTimeout(drainQueue);
524 } // v8 likes predictible objects
526 function Item(fun, array) {
531 Item.prototype.run = function () {
532 this.fun.apply(null, this.array);
535 var title = 'browser';
536 var platform = 'browser';
540 var version = ''; // empty string to avoid regexp issues
549 var addListener = noop;
552 var removeListener = noop;
553 var removeAllListeners = noop;
555 function binding(name) {
556 throw new Error('process.binding is not supported');
561 function chdir(dir) {
562 throw new Error('process.chdir is not supported');
566 } // from https://github.com/kumavis/browser-process-hrtime/blob/master/index.js
568 var performance = global$1.performance || {};
570 var performanceNow = performance.now || performance.mozNow || performance.msNow || performance.oNow || performance.webkitNow || function () {
571 return new Date().getTime();
572 }; // generate timestamp or delta
573 // see http://nodejs.org/api/process.html#process_process_hrtime
576 function hrtime(previousTimestamp) {
577 var clocktime = performanceNow.call(performance) * 1e-3;
578 var seconds = Math.floor(clocktime);
579 var nanoseconds = Math.floor(clocktime % 1 * 1e9);
581 if (previousTimestamp) {
582 seconds = seconds - previousTimestamp[0];
583 nanoseconds = nanoseconds - previousTimestamp[1];
585 if (nanoseconds < 0) {
591 return [seconds, nanoseconds];
593 var startTime = new Date();
595 var currentTime = new Date();
596 var dif = currentTime - startTime;
608 addListener: addListener,
611 removeListener: removeListener,
612 removeAllListeners: removeAllListeners,
625 const debug = typeof process === 'object' && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG) ? (...args) => console.error('SEMVER', ...args) : () => {};
628 // Note: this is the semver.org version of the spec that it implements
629 // Not necessarily the package version of this code.
630 const SEMVER_SPEC_VERSION = '2.0.0';
631 const MAX_LENGTH = 256;
632 const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER ||
633 /* istanbul ignore next */
634 9007199254740991; // Max safe segment length for coercion.
636 const MAX_SAFE_COMPONENT_LENGTH = 16;
641 MAX_SAFE_COMPONENT_LENGTH
644 function createCommonjsModule(fn, basedir, module) {
648 require: function (path, base) {
649 return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
651 }, fn(module, module.exports), module.exports;
654 function commonjsRequire () {
655 throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
658 var re_1 = createCommonjsModule(function (module, exports) {
660 MAX_SAFE_COMPONENT_LENGTH
662 exports = module.exports = {}; // The actual regexps go on exports.re
664 const re = exports.re = [];
665 const src = exports.src = [];
666 const t = exports.t = {};
669 const createToken = (name, value, isGlobal) => {
671 debug_1(index, value);
674 re[index] = new RegExp(value, isGlobal ? 'g' : undefined);
675 }; // The following Regular Expressions can be used for tokenizing,
676 // validating, and parsing SemVer version strings.
677 // ## Numeric Identifier
678 // A single `0`, or a non-zero digit followed by zero or more digits.
681 createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*');
682 createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+'); // ## Non-numeric Identifier
683 // Zero or more digits, followed by a letter or hyphen, and then zero or
684 // more letters, digits, or hyphens.
686 createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*'); // ## Main Version
687 // Three dot-separated numeric identifiers.
689 createToken('MAINVERSION', "(".concat(src[t.NUMERICIDENTIFIER], ")\\.") + "(".concat(src[t.NUMERICIDENTIFIER], ")\\.") + "(".concat(src[t.NUMERICIDENTIFIER], ")"));
690 createToken('MAINVERSIONLOOSE', "(".concat(src[t.NUMERICIDENTIFIERLOOSE], ")\\.") + "(".concat(src[t.NUMERICIDENTIFIERLOOSE], ")\\.") + "(".concat(src[t.NUMERICIDENTIFIERLOOSE], ")")); // ## Pre-release Version Identifier
691 // A numeric identifier, or a non-numeric identifier.
693 createToken('PRERELEASEIDENTIFIER', "(?:".concat(src[t.NUMERICIDENTIFIER], "|").concat(src[t.NONNUMERICIDENTIFIER], ")"));
694 createToken('PRERELEASEIDENTIFIERLOOSE', "(?:".concat(src[t.NUMERICIDENTIFIERLOOSE], "|").concat(src[t.NONNUMERICIDENTIFIER], ")")); // ## Pre-release Version
695 // Hyphen, followed by one or more dot-separated pre-release version
698 createToken('PRERELEASE', "(?:-(".concat(src[t.PRERELEASEIDENTIFIER], "(?:\\.").concat(src[t.PRERELEASEIDENTIFIER], ")*))"));
699 createToken('PRERELEASELOOSE', "(?:-?(".concat(src[t.PRERELEASEIDENTIFIERLOOSE], "(?:\\.").concat(src[t.PRERELEASEIDENTIFIERLOOSE], ")*))")); // ## Build Metadata Identifier
700 // Any combination of digits, letters, or hyphens.
702 createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+'); // ## Build Metadata
703 // Plus sign, followed by one or more period-separated build metadata
706 createToken('BUILD', "(?:\\+(".concat(src[t.BUILDIDENTIFIER], "(?:\\.").concat(src[t.BUILDIDENTIFIER], ")*))")); // ## Full Version String
707 // A main version, followed optionally by a pre-release version and
709 // Note that the only major, minor, patch, and pre-release sections of
710 // the version string are capturing groups. The build metadata is not a
711 // capturing group, because it should not ever be used in version
714 createToken('FULLPLAIN', "v?".concat(src[t.MAINVERSION]).concat(src[t.PRERELEASE], "?").concat(src[t.BUILD], "?"));
715 createToken('FULL', "^".concat(src[t.FULLPLAIN], "$")); // like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
716 // also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
717 // common in the npm registry.
719 createToken('LOOSEPLAIN', "[v=\\s]*".concat(src[t.MAINVERSIONLOOSE]).concat(src[t.PRERELEASELOOSE], "?").concat(src[t.BUILD], "?"));
720 createToken('LOOSE', "^".concat(src[t.LOOSEPLAIN], "$"));
721 createToken('GTLT', '((?:<|>)?=?)'); // Something like "2.*" or "1.2.x".
722 // Note that "x.x" is a valid xRange identifer, meaning "any version"
723 // Only the first item is strictly required.
725 createToken('XRANGEIDENTIFIERLOOSE', "".concat(src[t.NUMERICIDENTIFIERLOOSE], "|x|X|\\*"));
726 createToken('XRANGEIDENTIFIER', "".concat(src[t.NUMERICIDENTIFIER], "|x|X|\\*"));
727 createToken('XRANGEPLAIN', "[v=\\s]*(".concat(src[t.XRANGEIDENTIFIER], ")") + "(?:\\.(".concat(src[t.XRANGEIDENTIFIER], ")") + "(?:\\.(".concat(src[t.XRANGEIDENTIFIER], ")") + "(?:".concat(src[t.PRERELEASE], ")?").concat(src[t.BUILD], "?") + ")?)?");
728 createToken('XRANGEPLAINLOOSE', "[v=\\s]*(".concat(src[t.XRANGEIDENTIFIERLOOSE], ")") + "(?:\\.(".concat(src[t.XRANGEIDENTIFIERLOOSE], ")") + "(?:\\.(".concat(src[t.XRANGEIDENTIFIERLOOSE], ")") + "(?:".concat(src[t.PRERELEASELOOSE], ")?").concat(src[t.BUILD], "?") + ")?)?");
729 createToken('XRANGE', "^".concat(src[t.GTLT], "\\s*").concat(src[t.XRANGEPLAIN], "$"));
730 createToken('XRANGELOOSE', "^".concat(src[t.GTLT], "\\s*").concat(src[t.XRANGEPLAINLOOSE], "$")); // Coercion.
731 // Extract anything that could conceivably be a part of a valid semver
733 createToken('COERCE', "".concat('(^|[^\\d])' + '(\\d{1,').concat(MAX_SAFE_COMPONENT_LENGTH, "})") + "(?:\\.(\\d{1,".concat(MAX_SAFE_COMPONENT_LENGTH, "}))?") + "(?:\\.(\\d{1,".concat(MAX_SAFE_COMPONENT_LENGTH, "}))?") + "(?:$|[^\\d])");
734 createToken('COERCERTL', src[t.COERCE], true); // Tilde ranges.
735 // Meaning is "reasonably at or greater than"
737 createToken('LONETILDE', '(?:~>?)');
738 createToken('TILDETRIM', "(\\s*)".concat(src[t.LONETILDE], "\\s+"), true);
739 exports.tildeTrimReplace = '$1~';
740 createToken('TILDE', "^".concat(src[t.LONETILDE]).concat(src[t.XRANGEPLAIN], "$"));
741 createToken('TILDELOOSE', "^".concat(src[t.LONETILDE]).concat(src[t.XRANGEPLAINLOOSE], "$")); // Caret ranges.
742 // Meaning is "at least and backwards compatible with"
744 createToken('LONECARET', '(?:\\^)');
745 createToken('CARETTRIM', "(\\s*)".concat(src[t.LONECARET], "\\s+"), true);
746 exports.caretTrimReplace = '$1^';
747 createToken('CARET', "^".concat(src[t.LONECARET]).concat(src[t.XRANGEPLAIN], "$"));
748 createToken('CARETLOOSE', "^".concat(src[t.LONECARET]).concat(src[t.XRANGEPLAINLOOSE], "$")); // A simple gt/lt/eq thing, or just "" to indicate "any version"
750 createToken('COMPARATORLOOSE', "^".concat(src[t.GTLT], "\\s*(").concat(src[t.LOOSEPLAIN], ")$|^$"));
751 createToken('COMPARATOR', "^".concat(src[t.GTLT], "\\s*(").concat(src[t.FULLPLAIN], ")$|^$")); // An expression to strip any whitespace between the gtlt and the thing
752 // it modifies, so that `> 1.2.3` ==> `>1.2.3`
754 createToken('COMPARATORTRIM', "(\\s*)".concat(src[t.GTLT], "\\s*(").concat(src[t.LOOSEPLAIN], "|").concat(src[t.XRANGEPLAIN], ")"), true);
755 exports.comparatorTrimReplace = '$1$2$3'; // Something like `1.2.3 - 1.2.4`
756 // Note that these all use the loose form, because they'll be
757 // checked against either the strict or loose comparator form
760 createToken('HYPHENRANGE', "^\\s*(".concat(src[t.XRANGEPLAIN], ")") + "\\s+-\\s+" + "(".concat(src[t.XRANGEPLAIN], ")") + "\\s*$");
761 createToken('HYPHENRANGELOOSE', "^\\s*(".concat(src[t.XRANGEPLAINLOOSE], ")") + "\\s+-\\s+" + "(".concat(src[t.XRANGEPLAINLOOSE], ")") + "\\s*$"); // Star ranges basically just allow anything at all.
763 createToken('STAR', '(<|>)?=?\\s*\\*'); // >=0.0.0 is like a star
765 createToken('GTE0', '^\\s*>=\\s*0\.0\.0\\s*$');
766 createToken('GTE0PRE', '^\\s*>=\\s*0\.0\.0-0\\s*$');
769 const numeric = /^[0-9]+$/;
771 const compareIdentifiers = (a, b) => {
772 const anum = numeric.test(a);
773 const bnum = numeric.test(b);
780 return a === b ? 0 : anum && !bnum ? -1 : bnum && !anum ? 1 : a < b ? -1 : 1;
783 const rcompareIdentifiers = (a, b) => compareIdentifiers(b, a);
791 MAX_LENGTH: MAX_LENGTH$1,
792 MAX_SAFE_INTEGER: MAX_SAFE_INTEGER$1
799 compareIdentifiers: compareIdentifiers$1
803 constructor(version, options) {
804 if (!options || typeof options !== 'object') {
807 includePrerelease: false
811 if (version instanceof SemVer) {
812 if (version.loose === !!options.loose && version.includePrerelease === !!options.includePrerelease) {
815 version = version.version;
817 } else if (typeof version !== 'string') {
818 throw new TypeError("Invalid Version: ".concat(version));
821 if (version.length > MAX_LENGTH$1) {
822 throw new TypeError("version is longer than ".concat(MAX_LENGTH$1, " characters"));
825 debug_1('SemVer', version, options);
826 this.options = options;
827 this.loose = !!options.loose; // this isn't actually relevant for versions, but keep it so that we
828 // don't run into trouble passing this.options around.
830 this.includePrerelease = !!options.includePrerelease;
831 const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]);
834 throw new TypeError("Invalid Version: ".concat(version));
837 this.raw = version; // these are actually numbers
843 if (this.major > MAX_SAFE_INTEGER$1 || this.major < 0) {
844 throw new TypeError('Invalid major version');
847 if (this.minor > MAX_SAFE_INTEGER$1 || this.minor < 0) {
848 throw new TypeError('Invalid minor version');
851 if (this.patch > MAX_SAFE_INTEGER$1 || this.patch < 0) {
852 throw new TypeError('Invalid patch version');
853 } // numberify any prerelease numeric ids
857 this.prerelease = [];
859 this.prerelease = m[4].split('.').map(id => {
860 if (/^[0-9]+$/.test(id)) {
863 if (num >= 0 && num < MAX_SAFE_INTEGER$1) {
872 this.build = m[5] ? m[5].split('.') : [];
877 this.version = "".concat(this.major, ".").concat(this.minor, ".").concat(this.patch);
879 if (this.prerelease.length) {
880 this.version += "-".concat(this.prerelease.join('.'));
891 debug_1('SemVer.compare', this.version, this.options, other);
893 if (!(other instanceof SemVer)) {
894 if (typeof other === 'string' && other === this.version) {
898 other = new SemVer(other, this.options);
901 if (other.version === this.version) {
905 return this.compareMain(other) || this.comparePre(other);
909 if (!(other instanceof SemVer)) {
910 other = new SemVer(other, this.options);
913 return compareIdentifiers$1(this.major, other.major) || compareIdentifiers$1(this.minor, other.minor) || compareIdentifiers$1(this.patch, other.patch);
917 if (!(other instanceof SemVer)) {
918 other = new SemVer(other, this.options);
919 } // NOT having a prerelease is > having one
922 if (this.prerelease.length && !other.prerelease.length) {
924 } else if (!this.prerelease.length && other.prerelease.length) {
926 } else if (!this.prerelease.length && !other.prerelease.length) {
933 const a = this.prerelease[i];
934 const b = other.prerelease[i];
935 debug_1('prerelease compare', i, a, b);
937 if (a === undefined && b === undefined) {
939 } else if (b === undefined) {
941 } else if (a === undefined) {
943 } else if (a === b) {
946 return compareIdentifiers$1(a, b);
951 compareBuild(other) {
952 if (!(other instanceof SemVer)) {
953 other = new SemVer(other, this.options);
959 const a = this.build[i];
960 const b = other.build[i];
961 debug_1('prerelease compare', i, a, b);
963 if (a === undefined && b === undefined) {
965 } else if (b === undefined) {
967 } else if (a === undefined) {
969 } else if (a === b) {
972 return compareIdentifiers$1(a, b);
975 } // preminor will bump the version up to the next minor release, and immediately
976 // down to pre-release. premajor and prepatch work the same way.
979 inc(release, identifier) {
982 this.prerelease.length = 0;
986 this.inc('pre', identifier);
990 this.prerelease.length = 0;
993 this.inc('pre', identifier);
997 // If this is already a prerelease, it will bump to the next version
998 // drop any prereleases that might already exist, since they are not
999 // relevant at this point.
1000 this.prerelease.length = 0;
1001 this.inc('patch', identifier);
1002 this.inc('pre', identifier);
1004 // If the input is a non-prerelease version, this acts the same as
1008 if (this.prerelease.length === 0) {
1009 this.inc('patch', identifier);
1012 this.inc('pre', identifier);
1016 // If this is a pre-major version, bump up to the same major version.
1017 // Otherwise increment major.
1018 // 1.0.0-5 bumps to 1.0.0
1019 // 1.1.0 bumps to 2.0.0
1020 if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) {
1026 this.prerelease = [];
1030 // If this is a pre-minor version, bump up to the same minor version.
1031 // Otherwise increment minor.
1032 // 1.2.0-5 bumps to 1.2.0
1033 // 1.2.1 bumps to 1.3.0
1034 if (this.patch !== 0 || this.prerelease.length === 0) {
1039 this.prerelease = [];
1043 // If this is not a pre-release version, it will increment the patch.
1044 // If it is a pre-release it will bump up to the same patch version.
1045 // 1.2.0-5 patches to 1.2.0
1046 // 1.2.0 patches to 1.2.1
1047 if (this.prerelease.length === 0) {
1051 this.prerelease = [];
1053 // This probably shouldn't be used publicly.
1054 // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction.
1057 if (this.prerelease.length === 0) {
1058 this.prerelease = [0];
1060 let i = this.prerelease.length;
1063 if (typeof this.prerelease[i] === 'number') {
1064 this.prerelease[i]++;
1070 // didn't increment anything
1071 this.prerelease.push(0);
1076 // 1.2.0-beta.1 bumps to 1.2.0-beta.2,
1077 // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
1078 if (this.prerelease[0] === identifier) {
1079 if (isNaN(this.prerelease[1])) {
1080 this.prerelease = [identifier, 0];
1083 this.prerelease = [identifier, 0];
1090 throw new Error("invalid increment argument: ".concat(release));
1094 this.raw = this.version;
1100 var semver = SemVer;
1102 const compare = (a, b, loose) => new semver(a, loose).compare(new semver(b, loose));
1104 var compare_1 = compare;
1106 const lt = (a, b, loose) => compare_1(a, b, loose) < 0;
1110 const gte = (a, b, loose) => compare_1(a, b, loose) >= 0;
1114 var arrayify = (object, keyName) => Object.entries(object).map(([key, value]) => Object.assign({
1118 var name = "prettier";
1119 var version$1 = "2.2.1";
1120 var description = "Prettier is an opinionated code formatter";
1121 var bin = "./bin/prettier.js";
1122 var repository = "prettier/prettier";
1123 var homepage = "https://prettier.io";
1124 var author = "James Long";
1125 var license = "MIT";
1126 var main = "./index.js";
1127 var browser$1 = "./standalone.js";
1128 var unpkg = "./standalone.js";
1138 var dependencies = {
1139 "@angular/compiler": "10.2.3",
1140 "@babel/code-frame": "7.10.4",
1141 "@babel/parser": "7.12.5",
1142 "@glimmer/syntax": "0.66.0",
1143 "@iarna/toml": "2.2.5",
1144 "@typescript-eslint/typescript-estree": "4.8.1",
1145 "angular-estree-parser": "2.2.1",
1146 "angular-html-parser": "1.7.1",
1149 "ci-info": "watson/ci-info#f43f6a1cefff47fb361c88cf4b943fdbcaafe540",
1150 "cjk-regex": "2.0.0",
1151 cosmiconfig: "7.0.0",
1154 editorconfig: "0.15.3",
1155 "editorconfig-to-prettier": "0.2.0",
1156 "escape-string-regexp": "4.0.0",
1159 "fast-glob": "3.2.4",
1160 "fast-json-stable-stringify": "2.1.0",
1161 "find-parent-dir": "0.3.0",
1162 "flow-parser": "0.138.0",
1163 "get-stdin": "8.0.0",
1166 "html-element-attributes": "2.3.0",
1167 "html-styles": "1.0.0",
1168 "html-tag-names": "1.1.5",
1169 "html-void-elements": "1.0.5",
1171 "jest-docblock": "26.0.0",
1174 "lines-and-columns": "1.1.6",
1175 "linguist-languages": "7.12.1",
1181 "n-readlines": "1.0.1",
1183 "parse-srcset": "ikatyang/parse-srcset#54eb9c1cb21db5c62b4d0e275d7249516df6f0ee",
1184 "please-upgrade-node": "3.2.0",
1185 "postcss-less": "3.1.4",
1186 "postcss-media-query-parser": "0.2.3",
1187 "postcss-scss": "2.1.1",
1188 "postcss-selector-parser": "2.2.3",
1189 "postcss-values-parser": "2.0.1",
1190 "regexp-util": "1.2.2",
1191 "remark-footnotes": "2.0.0",
1192 "remark-math": "3.0.1",
1193 "remark-parse": "8.0.3",
1196 "string-width": "4.2.0",
1197 typescript: "4.1.2",
1198 "unicode-regex": "3.0.0",
1201 "yaml-unist-parser": "1.3.1"
1203 var devDependencies = {
1204 "@babel/core": "7.12.3",
1205 "@babel/preset-env": "7.12.1",
1206 "@babel/types": "7.12.6",
1207 "@glimmer/reference": "0.66.0",
1208 "@rollup/plugin-alias": "3.1.1",
1209 "@rollup/plugin-babel": "5.2.1",
1210 "@rollup/plugin-commonjs": "16.0.0",
1211 "@rollup/plugin-json": "4.1.0",
1212 "@rollup/plugin-node-resolve": "10.0.0",
1213 "@rollup/plugin-replace": "2.3.4",
1214 "@types/estree": "0.0.45",
1215 "@types/node": "14.14.0",
1216 "@typescript-eslint/types": "4.8.1",
1217 "babel-jest": "26.6.3",
1218 "babel-loader": "8.2.1",
1220 "builtin-modules": "3.1.0",
1221 "cross-env": "7.0.2",
1224 "eslint-config-prettier": "6.15.0",
1225 "eslint-formatter-friendly": "7.0.0",
1226 "eslint-plugin-import": "2.22.1",
1227 "eslint-plugin-jest": "24.1.3",
1228 "eslint-plugin-prettier-internal-rules": "file:scripts/tools/eslint-plugin-prettier-internal-rules",
1229 "eslint-plugin-react": "7.21.5",
1230 "eslint-plugin-unicorn": "23.0.0",
1233 "jest-snapshot-serializer-ansi": "1.0.0",
1234 "jest-snapshot-serializer-raw": "1.1.0",
1235 "jest-watch-typeahead": "0.6.1",
1236 "npm-run-all": "4.1.5",
1237 "path-browserify": "1.0.1",
1241 "rollup-plugin-node-globals": "1.4.0",
1242 "rollup-plugin-terser": "7.0.2",
1244 "snapshot-diff": "0.8.1",
1245 "strip-ansi": "6.0.0",
1246 "synchronous-promise": "2.0.15",
1248 "terser-webpack-plugin": "5.0.3",
1252 prepublishOnly: "echo \"Error: must publish from dist/\" && exit 1",
1253 "prepare-release": "yarn && yarn build && yarn test:dist",
1255 "test:dev-package": "cross-env INSTALL_PACKAGE=1 jest",
1256 "test:dist": "cross-env NODE_ENV=production jest",
1257 "test:dist-standalone": "cross-env NODE_ENV=production TEST_STANDALONE=1 jest",
1258 "test:integration": "jest tests_integration",
1259 "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",
1260 "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",
1261 "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",
1262 lint: "run-p lint:*",
1263 "lint:typecheck": "tsc",
1264 "lint:eslint": "cross-env EFF_NO_LINK_RULES=true eslint . --format friendly",
1265 "lint:changelog": "node ./scripts/lint-changelog.js",
1266 "lint:prettier": "prettier . \"!test*\" --check",
1267 "lint:dist": "eslint --no-eslintrc --no-ignore --env=es6,browser --parser-options=ecmaVersion:2018 \"dist/!(bin-prettier|index|third-party).js\"",
1268 "lint:spellcheck": "cspell \"**/*\" \".github/**/*\"",
1269 "lint:deps": "node ./scripts/check-deps.js",
1270 fix: "run-s fix:eslint fix:prettier",
1271 "fix:eslint": "yarn lint:eslint --fix",
1272 "fix:prettier": "yarn lint:prettier --write",
1273 build: "node --max-old-space-size=3072 ./scripts/build/build.js",
1274 "build-docs": "node ./scripts/build-docs.js"
1279 description: description,
1281 repository: repository,
1290 dependencies: dependencies,
1291 devDependencies: devDependencies,
1295 var lib = createCommonjsModule(function (module, exports) {
1297 Object.defineProperty(exports, "__esModule", {
1299 }); // In the absence of a WeakSet or WeakMap implementation, don't break, but don't cache either.
1304 for (var _i = 0; _i < arguments.length; _i++) {
1305 args[_i] = arguments[_i];
1309 function createWeakMap() {
1310 if (typeof WeakMap !== 'undefined') {
1311 return new WeakMap();
1313 return fakeSetOrMap();
1317 * Creates and returns a no-op implementation of a WeakMap / WeakSet that never stores anything.
1321 function fakeSetOrMap() {
1331 } // Safe hasOwnProperty
1334 var hop = Object.prototype.hasOwnProperty;
1336 var has = function (obj, prop) {
1337 return hop.call(obj, prop);
1338 }; // Copy all own enumerable properties from source to target
1341 function extend(target, source) {
1342 for (var prop in source) {
1343 if (has(source, prop)) {
1344 target[prop] = source[prop];
1351 var reLeadingNewline = /^[ \t]*(?:\r\n|\r|\n)/;
1352 var reTrailingNewline = /(?:\r\n|\r|\n)[ \t]*$/;
1353 var reStartsWithNewlineOrIsEmpty = /^(?:[\r\n]|$)/;
1354 var reDetectIndentation = /(?:\r\n|\r|\n)([ \t]*)(?:[^ \t\r\n]|$)/;
1355 var reOnlyWhitespaceWithAtLeastOneNewline = /^[ \t]*[\r\n][ \t\r\n]*$/;
1357 function _outdentArray(strings, firstInterpolatedValueSetsIndentationLevel, options) {
1358 // If first interpolated value is a reference to outdent,
1359 // determine indentation level from the indentation of the interpolated value.
1360 var indentationLevel = 0;
1361 var match = strings[0].match(reDetectIndentation);
1364 indentationLevel = match[1].length;
1367 var reSource = "(\\r\\n|\\r|\\n).{0," + indentationLevel + "}";
1368 var reMatchIndent = new RegExp(reSource, 'g');
1370 if (firstInterpolatedValueSetsIndentationLevel) {
1371 strings = strings.slice(1);
1374 var newline = options.newline,
1375 trimLeadingNewline = options.trimLeadingNewline,
1376 trimTrailingNewline = options.trimTrailingNewline;
1377 var normalizeNewlines = typeof newline === 'string';
1378 var l = strings.length;
1379 var outdentedStrings = strings.map(function (v, i) {
1380 // Remove leading indentation from all lines
1381 v = v.replace(reMatchIndent, '$1'); // Trim a leading newline from the first string
1383 if (i === 0 && trimLeadingNewline) {
1384 v = v.replace(reLeadingNewline, '');
1385 } // Trim a trailing newline from the last string
1388 if (i === l - 1 && trimTrailingNewline) {
1389 v = v.replace(reTrailingNewline, '');
1390 } // Normalize newlines
1393 if (normalizeNewlines) {
1394 v = v.replace(/\r\n|\n|\r/g, function (_) {
1401 return outdentedStrings;
1404 function concatStringsAndValues(strings, values) {
1407 for (var i = 0, l = strings.length; i < l; i++) {
1418 function isTemplateStringsArray(v) {
1419 return has(v, 'raw') && has(v, 'length');
1422 * It is assumed that opts will not change. If this is a problem, clone your options object and pass the clone to
1429 function createInstance(options) {
1430 /** Cache of pre-processed template literal arrays */
1431 var arrayAutoIndentCache = createWeakMap();
1433 * Cache of pre-processed template literal arrays, where first interpolated value is a reference to outdent,
1434 * before interpolated values are injected.
1437 var arrayFirstInterpSetsIndentCache = createWeakMap();
1439 function outdent(stringsOrOptions) {
1442 for (var _i = 1; _i < arguments.length; _i++) {
1443 values[_i - 1] = arguments[_i];
1445 /* tslint:enable:no-shadowed-variable */
1448 if (isTemplateStringsArray(stringsOrOptions)) {
1449 var strings = stringsOrOptions; // Is first interpolated value a reference to outdent, alone on its own line, without any preceding non-whitespace?
1451 var firstInterpolatedValueSetsIndentationLevel = (values[0] === outdent || values[0] === defaultOutdent) && reOnlyWhitespaceWithAtLeastOneNewline.test(strings[0]) && reStartsWithNewlineOrIsEmpty.test(strings[1]); // Perform outdentation
1453 var cache = firstInterpolatedValueSetsIndentationLevel ? arrayFirstInterpSetsIndentCache : arrayAutoIndentCache;
1454 var renderedArray = cache.get(strings);
1456 if (!renderedArray) {
1457 renderedArray = _outdentArray(strings, firstInterpolatedValueSetsIndentationLevel, options);
1458 cache.set(strings, renderedArray);
1460 /** If no interpolated values, skip concatenation step */
1463 if (values.length === 0) {
1464 return renderedArray[0];
1466 /** Concatenate string literals with interpolated values */
1469 var rendered = concatStringsAndValues(renderedArray, firstInterpolatedValueSetsIndentationLevel ? values.slice(1) : values);
1472 // Create and return a new instance of outdent with the given options
1473 return createInstance(extend(extend({}, options), stringsOrOptions || {}));
1477 var fullOutdent = extend(outdent, {
1478 string: function (str) {
1479 return _outdentArray([str], false, options)[0];
1485 var defaultOutdent = createInstance({
1486 trimLeadingNewline: true,
1487 trimTrailingNewline: true
1489 exports.outdent = defaultOutdent; // Named exports. Simple and preferred.
1490 // import outdent from 'outdent';
1492 exports.default = defaultOutdent;
1495 // In webpack harmony-modules environments, module.exports is read-only,
1496 // so we fail gracefully.
1498 module.exports = defaultOutdent;
1499 Object.defineProperty(defaultOutdent, '__esModule', {
1502 defaultOutdent.default = defaultOutdent;
1503 defaultOutdent.outdent = defaultOutdent;
1508 function _templateObject6() {
1509 const data = _taggedTemplateLiteral(["\n Require either '@prettier' or '@format' to be present in the file's first docblock comment\n in order for it to be formatted.\n "]);
1511 _templateObject6 = function () {
1518 function _templateObject5() {
1519 const data = _taggedTemplateLiteral(["\n Format code starting at a given character offset.\n The range will extend backwards to the start of the first line containing the selected statement.\n This option cannot be used with --cursor-offset.\n "]);
1521 _templateObject5 = function () {
1528 function _templateObject4() {
1529 const data = _taggedTemplateLiteral(["\n Format code ending at a given character offset (exclusive).\n The range will extend forwards to the end of the selected statement.\n This option cannot be used with --cursor-offset.\n "]);
1531 _templateObject4 = function () {
1538 function _templateObject3() {
1539 const data = _taggedTemplateLiteral(["\n Custom directory that contains prettier plugins in node_modules subdirectory.\n Overrides default behavior when plugins are searched relatively to the location of Prettier.\n Multiple values are accepted.\n "]);
1541 _templateObject3 = function () {
1548 function _templateObject2() {
1549 const data = _taggedTemplateLiteral(["\n Maintain existing\n (mixed values within one file are normalised by looking at what's used after the first line)\n "]);
1551 _templateObject2 = function () {
1558 function _templateObject() {
1559 const data = _taggedTemplateLiteral(["\n Print (to stderr) where a cursor at the given position would move to after formatting.\n This option cannot be used with --range-start and --range-end.\n "]);
1561 _templateObject = function () {
1571 const CATEGORY_CONFIG = "Config";
1572 const CATEGORY_EDITOR = "Editor";
1573 const CATEGORY_FORMAT = "Format";
1574 const CATEGORY_OTHER = "Other";
1575 const CATEGORY_OUTPUT = "Output";
1576 const CATEGORY_GLOBAL = "Global";
1577 const CATEGORY_SPECIAL = "Special";
1579 * @typedef {Object} OptionInfo
1580 * @property {string} [since] - available since version
1581 * @property {string} category
1582 * @property {'int' | 'boolean' | 'choice' | 'path'} type
1583 * @property {boolean} [array] - indicate it's an array of the specified type
1584 * @property {OptionValueInfo} [default]
1585 * @property {OptionRangeInfo} [range] - for type int
1586 * @property {string} description
1587 * @property {string} [deprecated] - deprecated since version
1588 * @property {OptionRedirectInfo} [redirect] - redirect deprecated option
1589 * @property {(value: any) => boolean} [exception]
1590 * @property {OptionChoiceInfo[]} [choices] - for type choice
1591 * @property {string} [cliName]
1592 * @property {string} [cliCategory]
1593 * @property {string} [cliDescription]
1595 * @typedef {number | boolean | string} OptionValue
1596 * @typedef {OptionValue | [{ value: OptionValue[] }] | Array<{ since: string, value: OptionValue}>} OptionValueInfo
1598 * @typedef {Object} OptionRedirectInfo
1599 * @property {string} option
1600 * @property {OptionValue} value
1602 * @typedef {Object} OptionRangeInfo
1603 * @property {number} start - recommended range start
1604 * @property {number} end - recommended range end
1605 * @property {number} step - recommended range step
1607 * @typedef {Object} OptionChoiceInfo
1608 * @property {boolean | string} value - boolean for the option that is originally boolean type
1609 * @property {string} description
1610 * @property {string} [since] - undefined if available since the first version of the option
1611 * @property {string} [deprecated] - deprecated since version
1612 * @property {OptionValueInfo} [redirect] - redirect deprecated value
1615 /** @type {{ [name: string]: OptionInfo }} */
1620 category: CATEGORY_SPECIAL,
1628 description: outdent(_templateObject()),
1629 cliCategory: CATEGORY_EDITOR
1633 category: CATEGORY_GLOBAL,
1642 description: "Which end of line characters to apply.",
1645 description: "Line Feed only (\\n), common on Linux and macOS as well as inside git repos"
1648 description: "Carriage Return + Line Feed characters (\\r\\n), common on Windows"
1651 description: "Carriage Return character only (\\r), used very rarely"
1654 description: outdent(_templateObject2())
1659 category: CATEGORY_SPECIAL,
1661 description: "Specify the input filepath. This will be used to do parser inference.",
1662 cliName: "stdin-filepath",
1663 cliCategory: CATEGORY_OTHER,
1664 cliDescription: "Path to the file to pretend that stdin comes from."
1668 category: CATEGORY_SPECIAL,
1671 description: "Insert @format pragma into file's first docblock comment.",
1672 cliCategory: CATEGORY_OTHER
1676 category: CATEGORY_GLOBAL,
1685 description: "Which parser to use.",
1686 exception: value => typeof value === "string" || typeof value === "function",
1693 description: "JavaScript"
1695 value: "babel-flow",
1701 description: "TypeScript"
1703 value: "typescript",
1705 description: "TypeScript"
1709 description: "JavaScript"
1713 description: "JavaScript"
1733 description: "JSON5"
1735 value: "json-stringify",
1737 description: "JSON.stringify"
1741 description: "GraphQL"
1745 description: "Markdown"
1761 description: "Handlebars"
1769 description: "Angular"
1773 description: "Lightning Web Components"
1783 category: CATEGORY_GLOBAL,
1784 description: "Add a plugin. Multiple plugins can be passed as separate `--plugin`s.",
1785 exception: value => typeof value === "string" || typeof value === "object",
1787 cliCategory: CATEGORY_CONFIG
1796 category: CATEGORY_GLOBAL,
1797 description: outdent(_templateObject3()),
1798 exception: value => typeof value === "string" || typeof value === "object",
1799 cliName: "plugin-search-dir",
1800 cliCategory: CATEGORY_CONFIG
1804 category: CATEGORY_GLOBAL,
1807 description: "The line length where Prettier will try wrap.",
1816 category: CATEGORY_SPECIAL,
1824 description: outdent(_templateObject4()),
1825 cliCategory: CATEGORY_EDITOR
1829 category: CATEGORY_SPECIAL,
1837 description: outdent(_templateObject5()),
1838 cliCategory: CATEGORY_EDITOR
1842 category: CATEGORY_SPECIAL,
1845 description: outdent(_templateObject6()),
1846 cliCategory: CATEGORY_OTHER
1850 category: CATEGORY_GLOBAL,
1852 description: "Number of spaces per indentation level.",
1861 category: CATEGORY_GLOBAL,
1864 description: "Indent with tabs instead of spaces."
1866 embeddedLanguageFormatting: {
1868 category: CATEGORY_GLOBAL,
1874 description: "Control how Prettier formats quoted code embedded in the file.",
1877 description: "Format embedded code if Prettier can automatically identify it."
1880 description: "Never automatically format embedded code."
1900 const currentVersion = require$$3.version;
1901 const coreOptions$1 = coreOptions.options;
1903 * Strings in `plugins` and `pluginSearchDirs` are handled by a wrapped version
1904 * of this function created by `withPlugins`. Don't pass them here directly.
1905 * @param {object} param0
1906 * @param {(string | object)[]=} param0.plugins Strings are resolved by `withPlugins`.
1907 * @param {string[]=} param0.pluginSearchDirs Added by `withPlugins`.
1908 * @param {boolean=} param0.showUnreleased
1909 * @param {boolean=} param0.showDeprecated
1910 * @param {boolean=} param0.showInternal
1913 function getSupportInfo({
1915 showUnreleased = false,
1916 showDeprecated = false,
1917 showInternal = false
1919 // pre-release version is smaller than the normal version in semver,
1920 // we need to treat it as the normal one so as to test new features.
1921 const version = currentVersion.split("-", 1)[0];
1922 const languages = plugins.reduce((all, plugin) => all.concat(plugin.languages || []), []).filter(filterSince);
1923 const options = arrayify(Object.assign({}, ...plugins.map(({
1925 }) => 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 => {
1926 option = Object.assign({}, option);
1928 if (Array.isArray(option.default)) {
1929 option.default = option.default.length === 1 ? option.default[0].value : option.default.filter(filterSince).sort((info1, info2) => semver$1.compare(info2.since, info1.since))[0].value;
1932 if (Array.isArray(option.choices)) {
1933 option.choices = option.choices.filter(option => filterSince(option) && filterDeprecated(option));
1935 if (option.name === "parser") {
1936 collectParsersFromLanguages(option, languages, plugins);
1940 const pluginDefaults = plugins.filter(plugin => plugin.defaultOptions && plugin.defaultOptions[option.name] !== undefined).reduce((reduced, plugin) => {
1941 reduced[plugin.name] = plugin.defaultOptions[option.name];
1944 return Object.assign({}, option, {
1953 function filterSince(object) {
1954 return showUnreleased || !("since" in object) || object.since && semver$1.gte(version, object.since);
1957 function filterDeprecated(object) {
1958 return showDeprecated || !("deprecated" in object) || object.deprecated && semver$1.lt(version, object.deprecated);
1961 function mapInternal(object) {
1966 const newObject = _objectWithoutPropertiesLoose(object, ["cliName", "cliCategory", "cliDescription"]);
1972 function collectParsersFromLanguages(option, languages, plugins) {
1973 const existingValues = new Set(option.choices.map(choice => choice.value));
1975 for (const language of languages) {
1976 if (language.parsers) {
1977 for (const value of language.parsers) {
1978 if (!existingValues.has(value)) {
1979 existingValues.add(value);
1980 const plugin = plugins.find(plugin => plugin.parsers && plugin.parsers[value]);
1981 let description = language.name;
1983 if (plugin && plugin.name) {
1984 description += " (plugin: ".concat(plugin.name, ")");
1987 option.choices.push({
2002 getSupportInfo: getSupportInfo$1
2004 const notAsciiRegex = /[^\x20-\x7F]/;
2006 const getPenultimate = arr => arr[arr.length - 2];
2008 * @typedef {{backwards?: boolean}} SkipOptions
2012 * @param {string | RegExp} chars
2013 * @returns {(text: string, index: number | false, opts?: SkipOptions) => number | false}
2017 function skip(chars) {
2018 return (text, index, opts) => {
2019 const backwards = opts && opts.backwards; // Allow `skip` functions to be threaded together without having
2020 // to check for failures (did someone say monads?).
2022 /* istanbul ignore next */
2024 if (index === false) {
2033 while (cursor >= 0 && cursor < length) {
2034 const c = text.charAt(cursor);
2036 if (chars instanceof RegExp) {
2037 if (!chars.test(c)) {
2040 } else if (!chars.includes(c)) {
2044 backwards ? cursor-- : cursor++;
2047 if (cursor === -1 || cursor === length) {
2048 // If we reached the beginning or end of the file, return the
2049 // out-of-bounds cursor. It's up to the caller to handle this
2050 // correctly. We don't want to indicate `false` though if it
2051 // actually skipped valid characters.
2059 * @type {(text: string, index: number | false, opts?: SkipOptions) => number | false}
2063 const skipWhitespace = skip(/\s/);
2065 * @type {(text: string, index: number | false, opts?: SkipOptions) => number | false}
2068 const skipSpaces = skip(" \t");
2070 * @type {(text: string, index: number | false, opts?: SkipOptions) => number | false}
2073 const skipToLineEnd = skip(",; \t");
2075 * @type {(text: string, index: number | false, opts?: SkipOptions) => number | false}
2078 const skipEverythingButNewLine = skip(/[^\n\r]/);
2080 * @param {string} text
2081 * @param {number | false} index
2082 * @returns {number | false}
2085 function skipInlineComment(text, index) {
2086 /* istanbul ignore next */
2087 if (index === false) {
2091 if (text.charAt(index) === "/" && text.charAt(index + 1) === "*") {
2092 for (let i = index + 2; i < text.length; ++i) {
2093 if (text.charAt(i) === "*" && text.charAt(i + 1) === "/") {
2102 * @param {string} text
2103 * @param {number | false} index
2104 * @returns {number | false}
2108 function skipTrailingComment(text, index) {
2109 /* istanbul ignore next */
2110 if (index === false) {
2114 if (text.charAt(index) === "/" && text.charAt(index + 1) === "/") {
2115 return skipEverythingButNewLine(text, index);
2119 } // This one doesn't use the above helper function because it wants to
2120 // test \r\n in order and `skip` doesn't support ordering and we only
2121 // want to skip one newline. It's simple to implement.
2124 * @param {string} text
2125 * @param {number | false} index
2126 * @param {SkipOptions=} opts
2127 * @returns {number | false}
2131 function skipNewline(text, index, opts) {
2132 const backwards = opts && opts.backwards;
2134 if (index === false) {
2138 const atIndex = text.charAt(index);
2141 // We already replace `\r\n` with `\n` before parsing
2143 /* istanbul ignore next */
2144 if (text.charAt(index - 1) === "\r" && atIndex === "\n") {
2148 if (atIndex === "\n" || atIndex === "\r" || atIndex === "\u2028" || atIndex === "\u2029") {
2152 // We already replace `\r\n` with `\n` before parsing
2154 /* istanbul ignore next */
2155 if (atIndex === "\r" && text.charAt(index + 1) === "\n") {
2159 if (atIndex === "\n" || atIndex === "\r" || atIndex === "\u2028" || atIndex === "\u2029") {
2167 * @param {string} text
2168 * @param {number} index
2169 * @param {SkipOptions=} opts
2170 * @returns {boolean}
2174 function hasNewline(text, index, opts) {
2176 const idx = skipSpaces(text, opts.backwards ? index - 1 : index, opts);
2177 const idx2 = skipNewline(text, idx, opts);
2178 return idx !== idx2;
2181 * @param {string} text
2182 * @param {number} start
2183 * @param {number} end
2184 * @returns {boolean}
2188 function hasNewlineInRange(text, start, end) {
2189 for (let i = start; i < end; ++i) {
2190 if (text.charAt(i) === "\n") {
2196 } // Note: this function doesn't ignore leading comments unlike isNextLineEmpty
2200 * @param {string} text
2202 * @param {(node: N) => number} locStart
2206 function isPreviousLineEmpty(text, node, locStart) {
2207 /** @type {number | false} */
2208 let idx = locStart(node) - 1;
2209 idx = skipSpaces(text, idx, {
2212 idx = skipNewline(text, idx, {
2215 idx = skipSpaces(text, idx, {
2218 const idx2 = skipNewline(text, idx, {
2221 return idx !== idx2;
2224 * @param {string} text
2225 * @param {number} index
2226 * @returns {boolean}
2230 function isNextLineEmptyAfterIndex(text, index) {
2231 /** @type {number | false} */
2233 /** @type {number | false} */
2237 while (idx !== oldIdx) {
2238 // We need to skip all the potential trailing inline comments
2240 idx = skipToLineEnd(text, idx);
2241 idx = skipInlineComment(text, idx);
2242 idx = skipSpaces(text, idx);
2245 idx = skipTrailingComment(text, idx);
2246 idx = skipNewline(text, idx);
2247 return idx !== false && hasNewline(text, idx);
2251 * @param {string} text
2253 * @param {(node: N) => number} locEnd
2254 * @returns {boolean}
2258 function isNextLineEmpty(text, node, locEnd) {
2259 return isNextLineEmptyAfterIndex(text, locEnd(node));
2262 * @param {string} text
2263 * @param {number} idx
2264 * @returns {number | false}
2268 function getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, idx) {
2269 /** @type {number | false} */
2271 /** @type {number | false} */
2275 while (nextIdx !== oldIdx) {
2277 nextIdx = skipSpaces(text, nextIdx);
2278 nextIdx = skipInlineComment(text, nextIdx);
2279 nextIdx = skipTrailingComment(text, nextIdx);
2280 nextIdx = skipNewline(text, nextIdx);
2287 * @param {string} text
2289 * @param {(node: N) => number} locEnd
2290 * @returns {number | false}
2294 function getNextNonSpaceNonCommentCharacterIndex(text, node, locEnd) {
2295 return getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, locEnd(node));
2299 * @param {string} text
2301 * @param {(node: N) => number} locEnd
2306 function getNextNonSpaceNonCommentCharacter(text, node, locEnd) {
2307 return text.charAt( // @ts-ignore => TBD: can return false, should we define a fallback?
2308 getNextNonSpaceNonCommentCharacterIndex(text, node, locEnd));
2309 } // Not using, but it's public utils
2311 /* istanbul ignore next */
2314 * @param {string} text
2315 * @param {number} index
2316 * @param {SkipOptions=} opts
2317 * @returns {boolean}
2321 function hasSpaces(text, index, opts) {
2323 const idx = skipSpaces(text, opts.backwards ? index - 1 : index, opts);
2324 return idx !== index;
2327 * @param {string} value
2328 * @param {number} tabWidth
2329 * @param {number=} startIndex
2334 function getAlignmentSize(value, tabWidth, startIndex) {
2335 startIndex = startIndex || 0;
2338 for (let i = startIndex; i < value.length; ++i) {
2339 if (value[i] === "\t") {
2340 // Tabs behave in a way that they are aligned to the nearest
2341 // multiple of tabWidth:
2342 // 0 -> 4, 1 -> 4, 2 -> 4, 3 -> 4
2343 // 4 -> 8, 5 -> 8, 6 -> 8, 7 -> 8 ...
2344 size = size + tabWidth - size % tabWidth;
2353 * @param {string} value
2354 * @param {number} tabWidth
2359 function getIndentSize(value, tabWidth) {
2360 const lastNewlineIndex = value.lastIndexOf("\n");
2362 if (lastNewlineIndex === -1) {
2366 return getAlignmentSize( // All the leading whitespaces
2367 value.slice(lastNewlineIndex + 1).match(/^[\t ]*/)[0], tabWidth);
2370 * @typedef {'"' | "'"} Quote
2375 * @param {string} raw
2376 * @param {Quote} preferredQuote
2381 function getPreferredQuote(raw, preferredQuote) {
2382 // `rawContent` is the string exactly like it appeared in the input source
2383 // code, without its enclosing quotes.
2384 const rawContent = raw.slice(1, -1);
2385 /** @type {{ quote: '"', regex: RegExp }} */
2391 /** @type {{ quote: "'", regex: RegExp }} */
2397 const preferred = preferredQuote === "'" ? single : double;
2398 const alternate = preferred === single ? double : single;
2399 let result = preferred.quote; // If `rawContent` contains at least one of the quote preferred for enclosing
2400 // the string, we might want to enclose with the alternate quote instead, to
2401 // minimize the number of escaped quotes.
2403 if (rawContent.includes(preferred.quote) || rawContent.includes(alternate.quote)) {
2404 const numPreferredQuotes = (rawContent.match(preferred.regex) || []).length;
2405 const numAlternateQuotes = (rawContent.match(alternate.regex) || []).length;
2406 result = numPreferredQuotes > numAlternateQuotes ? alternate.quote : preferred.quote;
2412 function printString(raw, options, isDirectiveLiteral) {
2413 // `rawContent` is the string exactly like it appeared in the input source
2414 // code, without its enclosing quotes.
2415 const rawContent = raw.slice(1, -1); // Check for the alternate quote, to determine if we're allowed to swap
2416 // the quotes on a DirectiveLiteral.
2418 const canChangeDirectiveQuotes = !rawContent.includes('"') && !rawContent.includes("'");
2419 /** @type {Quote} */
2421 const enclosingQuote = options.parser === "json" ? '"' : options.__isInHtmlAttribute ? "'" : getPreferredQuote(raw, options.singleQuote ? "'" : '"'); // Directives are exact code unit sequences, which means that you can't
2422 // change the escape sequences they use.
2423 // See https://github.com/prettier/prettier/issues/1555
2424 // and https://tc39.github.io/ecma262/#directive-prologue
2426 if (isDirectiveLiteral) {
2427 if (canChangeDirectiveQuotes) {
2428 return enclosingQuote + rawContent + enclosingQuote;
2432 } // It might sound unnecessary to use `makeString` even if the string already
2433 // is enclosed with `enclosingQuote`, but it isn't. The string could contain
2434 // unnecessary escapes (such as in `"\'"`). Always using `makeString` makes
2435 // sure that we consistently output the minimum amount of escaped quotes.
2438 return makeString(rawContent, enclosingQuote, !(options.parser === "css" || options.parser === "less" || options.parser === "scss" || options.embeddedInHtml));
2441 * @param {string} rawContent
2442 * @param {Quote} enclosingQuote
2443 * @param {boolean=} unescapeUnnecessaryEscapes
2448 function makeString(rawContent, enclosingQuote, unescapeUnnecessaryEscapes) {
2449 const otherQuote = enclosingQuote === '"' ? "'" : '"'; // Matches _any_ escape and unescaped quotes (both single and double).
2451 const regex = /\\([\S\s])|(["'])/g; // Escape and unescape single and double quotes as needed to be able to
2452 // enclose `rawContent` with `enclosingQuote`.
2454 const newContent = rawContent.replace(regex, (match, escaped, quote) => {
2455 // If we matched an escape, and the escaped character is a quote of the
2456 // other type than we intend to enclose the string with, there's no need for
2457 // it to be escaped, so return it _without_ the backslash.
2458 if (escaped === otherQuote) {
2460 } // If we matched an unescaped quote and it is of the _same_ type as we
2461 // intend to enclose the string with, it must be escaped, so return it with
2465 if (quote === enclosingQuote) {
2466 return "\\" + quote;
2471 } // Unescape any unnecessarily escaped character.
2472 // Adapted from https://github.com/eslint/eslint/blob/de0b4ad7bd820ade41b1f606008bea68683dc11a/lib/rules/no-useless-escape.js#L27
2475 return unescapeUnnecessaryEscapes && /^[^\n\r"'0-7\\bfnrt-vx\u2028\u2029]$/.test(escaped) ? escaped : "\\" + escaped;
2477 return enclosingQuote + newContent + enclosingQuote;
2480 function printNumber(rawNumber) {
2481 return rawNumber.toLowerCase() // Remove unnecessary plus and zeroes from scientific notation.
2482 .replace(/^([+-]?[\d.]+e)(?:\+|(-))?0*(\d)/, "$1$2$3") // Remove unnecessary scientific notation (1e0).
2483 .replace(/^([+-]?[\d.]+)e[+-]?0+$/, "$1") // Make sure numbers always start with a digit.
2484 .replace(/^([+-])?\./, "$10.") // Remove extraneous trailing decimal zeroes.
2485 .replace(/(\.\d+?)0+(?=e|$)/, "$1") // Remove trailing dot.
2486 .replace(/\.(?=e|$)/, "");
2489 * @param {string} str
2490 * @param {string} target
2495 function getMaxContinuousCount(str, target) {
2496 const results = str.match(new RegExp("(".concat(escapeStringRegexp(target), ")+"), "g"));
2498 if (results === null) {
2502 return results.reduce((maxCount, result) => Math.max(maxCount, result.length / target.length), 0);
2505 function getMinNotPresentContinuousCount(str, target) {
2506 const matches = str.match(new RegExp("(".concat(escapeStringRegexp(target), ")+"), "g"));
2508 if (matches === null) {
2512 const countPresent = new Map();
2515 for (const match of matches) {
2516 const count = match.length / target.length;
2517 countPresent.set(count, true);
2524 for (let i = 1; i < max; i++) {
2525 if (!countPresent.get(i)) {
2533 * @param {string} text
2538 function getStringWidth(text) {
2541 } // shortcut to avoid needless string `RegExp`s, replacements, and allocations within `string-width`
2544 if (!notAsciiRegex.test(text)) {
2548 return stringWidth_1(text);
2551 function isNodeIgnoreComment(comment) {
2552 return comment.value.trim() === "prettier-ignore";
2555 function addCommentHelper(node, comment) {
2556 const comments = node.comments || (node.comments = []);
2557 comments.push(comment);
2558 comment.printed = false; // For some reason, TypeScript parses `// x` inside of JSXText as a comment
2559 // We already "print" it via the raw text, we don't need to re-print it as a
2562 /* istanbul ignore next */
2564 if (node.type === "JSXText") {
2565 comment.printed = true;
2569 function addLeadingComment(node, comment) {
2570 comment.leading = true;
2571 comment.trailing = false;
2572 addCommentHelper(node, comment);
2575 function addDanglingComment(node, comment, marker) {
2576 comment.leading = false;
2577 comment.trailing = false;
2580 comment.marker = marker;
2583 addCommentHelper(node, comment);
2586 function addTrailingComment(node, comment) {
2587 comment.leading = false;
2588 comment.trailing = true;
2589 addCommentHelper(node, comment);
2592 function replaceEndOfLineWith(text, replacement) {
2595 for (const part of text.split("\n")) {
2596 if (parts.length !== 0) {
2597 parts.push(replacement);
2606 function inferParserByLanguage(language, options) {
2609 } = getSupportInfo$1({
2610 plugins: options.plugins
2612 const matched = languages.find(({
2614 }) => name.toLowerCase() === language) || languages.find(({
2616 }) => Array.isArray(aliases) && aliases.includes(language)) || languages.find(({
2618 }) => Array.isArray(extensions) && extensions.includes(".".concat(language)));
2619 return matched && matched.parsers[0];
2622 function isFrontMatterNode(node) {
2623 return node && node.type === "front-matter";
2626 function getShebang(text) {
2627 if (!text.startsWith("#!")) {
2631 const index = text.indexOf("\n");
2637 return text.slice(0, index);
2641 inferParserByLanguage,
2642 replaceEndOfLineWith,
2644 getMaxContinuousCount,
2645 getMinNotPresentContinuousCount,
2648 getNextNonSpaceNonCommentCharacterIndexWithStartIndex,
2649 getNextNonSpaceNonCommentCharacterIndex,
2650 getNextNonSpaceNonCommentCharacter,
2655 skipEverythingButNewLine,
2657 skipTrailingComment,
2659 isNextLineEmptyAfterIndex,
2661 isPreviousLineEmpty,
2670 isNodeIgnoreComment,
2679 function guessEndOfLine(text) {
2680 const index = text.indexOf("\r");
2683 return text.charAt(index + 1) === "\n" ? "crlf" : "cr";
2689 function convertEndOfLineToChars(value) {
2702 function countEndOfLineChars(text, eol) {
2704 /* istanbul ignore else */
2708 } else if (eol === "\r") {
2710 } else if (eol === "\r\n") {
2713 throw new Error("Unexpected \"eol\" ".concat(JSON.stringify(eol), "."));
2716 const endOfLines = text.match(regex);
2717 return endOfLines ? endOfLines.length : 0;
2720 function normalizeEndOfLine(text) {
2721 return text.replace(/\r\n?/g, "\n");
2726 convertEndOfLineToChars,
2727 countEndOfLineChars,
2732 getStringWidth: getStringWidth$1
2735 convertEndOfLineToChars: convertEndOfLineToChars$1
2742 /** @type {Record<symbol, typeof MODE_BREAK | typeof MODE_FLAT>} */
2745 const MODE_BREAK = 1;
2746 const MODE_FLAT = 2;
2748 function rootIndent() {
2756 function makeIndent(ind, options) {
2757 return generateInd(ind, {
2762 function makeAlign(indent, n, options) {
2763 if (n === -Infinity) {
2764 return indent.root || rootIndent();
2768 return generateInd(indent, {
2777 if (n.type === "root") {
2778 return Object.assign({}, indent, {
2783 const alignType = typeof n === "string" ? "stringAlign" : "numberAlign";
2784 return generateInd(indent, {
2790 function generateInd(ind, newPart, options) {
2791 const queue = newPart.type === "dedent" ? ind.queue.slice(0, -1) : ind.queue.concat(newPart);
2797 for (const part of queue) {
2798 switch (part.type) {
2802 if (options.useTabs) {
2805 addSpaces(options.tabWidth);
2813 length += part.n.length;
2818 lastSpaces += part.n;
2821 /* istanbul ignore next */
2824 throw new Error("Unexpected type '".concat(part.type, "'"));
2829 return Object.assign({}, ind, {
2835 function addTabs(count) {
2836 value += "\t".repeat(count);
2837 length += options.tabWidth * count;
2840 function addSpaces(count) {
2841 value += " ".repeat(count);
2846 if (options.useTabs) {
2853 function flushTabs() {
2861 function flushSpaces() {
2862 if (lastSpaces > 0) {
2863 addSpaces(lastSpaces);
2869 function resetLast() {
2875 function trim$1(out) {
2876 if (out.length === 0) {
2880 let trimCount = 0; // Trim whitespace at the end of line
2882 while (out.length > 0 && typeof out[out.length - 1] === "string" && out[out.length - 1].match(/^[\t ]*$/)) {
2883 trimCount += out.pop().length;
2886 if (out.length && typeof out[out.length - 1] === "string") {
2887 const trimmed = out[out.length - 1].replace(/[\t ]*$/, "");
2888 trimCount += out[out.length - 1].length - trimmed.length;
2889 out[out.length - 1] = trimmed;
2895 function fits(next, restCommands, width, options, mustBeFlat) {
2896 let restIdx = restCommands.length;
2897 const cmds = [next]; // `out` is only used for width counting because `trim` requires to look
2898 // backwards for space characters.
2902 while (width >= 0) {
2903 if (cmds.length === 0) {
2904 if (restIdx === 0) {
2908 cmds.push(restCommands[restIdx - 1]);
2913 const [ind, mode, doc] = cmds.pop();
2915 if (typeof doc === "string") {
2917 width -= getStringWidth$1(doc);
2921 for (let i = doc.parts.length - 1; i >= 0; i--) {
2922 cmds.push([ind, mode, doc.parts[i]]);
2928 cmds.push([makeIndent(ind, options), mode, doc.contents]);
2932 cmds.push([makeAlign(ind, doc.n, options), mode, doc.contents]);
2936 width += trim$1(out);
2940 if (mustBeFlat && doc.break) {
2944 cmds.push([ind, doc.break ? MODE_BREAK : mode, doc.contents]);
2947 groupModeMap[doc.id] = cmds[cmds.length - 1][1];
2953 for (let i = doc.parts.length - 1; i >= 0; i--) {
2954 cmds.push([ind, mode, doc.parts[i]]);
2961 const groupMode = doc.groupId ? groupModeMap[doc.groupId] : mode;
2963 if (groupMode === MODE_BREAK) {
2964 if (doc.breakContents) {
2965 cmds.push([ind, mode, doc.breakContents]);
2969 if (groupMode === MODE_FLAT) {
2970 if (doc.flatContents) {
2971 cmds.push([ind, mode, doc.flatContents]);
3005 function printDocToString(doc, options) {
3007 const width = options.printWidth;
3008 const newLine = convertEndOfLineToChars$1(options.endOfLine);
3009 let pos = 0; // cmds is basically a stack. We've turned a recursive call into a
3010 // while loop which is much faster. The while loop below adds new
3011 // cmds to the array instead of recursively calling `print`.
3013 const cmds = [[rootIndent(), MODE_BREAK, doc]];
3015 let shouldRemeasure = false;
3016 let lineSuffix = [];
3018 while (cmds.length !== 0) {
3019 const [ind, mode, doc] = cmds.pop();
3021 if (typeof doc === "string") {
3022 const formatted = newLine !== "\n" && doc.includes("\n") ? doc.replace(/\n/g, newLine) : doc;
3023 out.push(formatted);
3024 pos += getStringWidth$1(formatted);
3028 out.push(cursor$1.placeholder);
3032 for (let i = doc.parts.length - 1; i >= 0; i--) {
3033 cmds.push([ind, mode, doc.parts[i]]);
3039 cmds.push([makeIndent(ind, options), mode, doc.contents]);
3043 cmds.push([makeAlign(ind, doc.n, options), mode, doc.contents]);
3053 if (!shouldRemeasure) {
3054 cmds.push([ind, doc.break ? MODE_BREAK : MODE_FLAT, doc.contents]);
3062 shouldRemeasure = false;
3063 const next = [ind, MODE_FLAT, doc.contents];
3064 const rem = width - pos;
3066 if (!doc.break && fits(next, cmds, rem, options)) {
3069 // Expanded states are a rare case where a document
3070 // can manually provide multiple representations of
3071 // itself. It provides an array of documents
3072 // going from the least expanded (most flattened)
3073 // representation first to the most expanded. If a
3074 // group has these, we need to manually go through
3075 // these states and find the first one that fits.
3076 if (doc.expandedStates) {
3077 const mostExpanded = doc.expandedStates[doc.expandedStates.length - 1];
3080 cmds.push([ind, MODE_BREAK, mostExpanded]);
3083 for (let i = 1; i < doc.expandedStates.length + 1; i++) {
3084 if (i >= doc.expandedStates.length) {
3085 cmds.push([ind, MODE_BREAK, mostExpanded]);
3088 const state = doc.expandedStates[i];
3089 const cmd = [ind, MODE_FLAT, state];
3091 if (fits(cmd, cmds, rem, options)) {
3099 cmds.push([ind, MODE_BREAK, doc.contents]);
3108 groupModeMap[doc.id] = cmds[cmds.length - 1][1];
3112 // Fills each line with as much code as possible before moving to a new
3113 // line with the same indentation.
3115 // Expects doc.parts to be an array of alternating content and
3116 // whitespace. The whitespace contains the linebreaks.
3119 // ["I", line, "love", line, "monkeys"]
3121 // [{ type: group, ... }, softline, { type: group, ... }]
3123 // It uses this parts structure to handle three main layout cases:
3124 // * The first two content items fit on the same line without
3126 // -> output the first content item and the whitespace "flat".
3127 // * Only the first content item fits on the line without breaking
3128 // -> output the first content item "flat" and the whitespace with
3130 // * Neither content item fits on the line without breaking
3131 // -> output the first content item and the whitespace with "break".
3135 const rem = width - pos;
3140 if (parts.length === 0) {
3144 const [content, whitespace] = parts;
3145 const contentFlatCmd = [ind, MODE_FLAT, content];
3146 const contentBreakCmd = [ind, MODE_BREAK, content];
3147 const contentFits = fits(contentFlatCmd, [], rem, options, true);
3149 if (parts.length === 1) {
3151 cmds.push(contentFlatCmd);
3153 cmds.push(contentBreakCmd);
3159 const whitespaceFlatCmd = [ind, MODE_FLAT, whitespace];
3160 const whitespaceBreakCmd = [ind, MODE_BREAK, whitespace];
3162 if (parts.length === 2) {
3164 cmds.push(whitespaceFlatCmd);
3165 cmds.push(contentFlatCmd);
3167 cmds.push(whitespaceBreakCmd);
3168 cmds.push(contentBreakCmd);
3172 } // At this point we've handled the first pair (context, separator)
3173 // and will create a new fill doc for the rest of the content.
3174 // Ideally we wouldn't mutate the array here but copying all the
3175 // elements to a new array would make this algorithm quadratic,
3176 // which is unusable for large arrays (e.g. large texts in JSX).
3180 const remainingCmd = [ind, mode, fill$1(parts)];
3181 const secondContent = parts[0];
3182 const firstAndSecondContentFlatCmd = [ind, MODE_FLAT, concat$1([content, whitespace, secondContent])];
3183 const firstAndSecondContentFits = fits(firstAndSecondContentFlatCmd, [], rem, options, true);
3185 if (firstAndSecondContentFits) {
3186 cmds.push(remainingCmd);
3187 cmds.push(whitespaceFlatCmd);
3188 cmds.push(contentFlatCmd);
3189 } else if (contentFits) {
3190 cmds.push(remainingCmd);
3191 cmds.push(whitespaceBreakCmd);
3192 cmds.push(contentFlatCmd);
3194 cmds.push(remainingCmd);
3195 cmds.push(whitespaceBreakCmd);
3196 cmds.push(contentBreakCmd);
3204 const groupMode = doc.groupId ? groupModeMap[doc.groupId] : mode;
3206 if (groupMode === MODE_BREAK) {
3207 if (doc.breakContents) {
3208 cmds.push([ind, mode, doc.breakContents]);
3212 if (groupMode === MODE_FLAT) {
3213 if (doc.flatContents) {
3214 cmds.push([ind, mode, doc.flatContents]);
3222 lineSuffix.push([ind, mode, doc.contents]);
3225 case "line-suffix-boundary":
3226 if (lineSuffix.length > 0) {
3227 cmds.push([ind, mode, {
3246 // This line was forced into the output even if we
3247 // were in flattened mode, so we need to tell the next
3248 // group that no matter what, it needs to remeasure
3249 // because the previous measurement didn't accurately
3250 // capture the entire expression (this is necessary
3251 // for nested groups)
3252 shouldRemeasure = true;
3258 if (lineSuffix.length) {
3259 cmds.push([ind, mode, doc]);
3260 cmds.push(...lineSuffix.reverse());
3267 out.push(newLine, ind.root.value);
3268 pos = ind.root.length;
3275 out.push(newLine + ind.value);
3284 } // Flush remaining line-suffix contents at the end of the document, in case
3285 // there is no new line after the line-suffix.
3288 if (cmds.length === 0 && lineSuffix.length) {
3289 cmds.push(...lineSuffix.reverse());
3294 const cursorPlaceholderIndex = out.indexOf(cursor$1.placeholder);
3296 if (cursorPlaceholderIndex !== -1) {
3297 const otherCursorPlaceholderIndex = out.indexOf(cursor$1.placeholder, cursorPlaceholderIndex + 1);
3298 const beforeCursor = out.slice(0, cursorPlaceholderIndex).join("");
3299 const aroundCursor = out.slice(cursorPlaceholderIndex + 1, otherCursorPlaceholderIndex).join("");
3300 const afterCursor = out.slice(otherCursorPlaceholderIndex + 1).join("");
3302 formatted: beforeCursor + aroundCursor + afterCursor,
3303 cursorNodeStart: beforeCursor.length,
3304 cursorNodeText: aroundCursor
3309 formatted: out.join("")
3318 literalline: literalline$1,
3320 } = docBuilders; // Using a unique object to compare by reference.
3322 const traverseDocOnExitStackMarker = {};
3324 function traverseDoc(doc, onEnter, onExit, shouldTraverseConditionalGroups) {
3325 const docsStack = [doc];
3327 while (docsStack.length !== 0) {
3328 const doc = docsStack.pop();
3330 if (doc === traverseDocOnExitStackMarker) {
3331 onExit(docsStack.pop());
3336 docsStack.push(doc, traverseDocOnExitStackMarker);
3339 if ( // Should Recurse
3340 !onEnter || onEnter(doc) !== false) {
3341 // When there are multiple parts to process,
3342 // the parts need to be pushed onto the stack in reverse order,
3343 // so that they are processed in the original order
3344 // when the stack is popped.
3345 if (doc.type === "concat" || doc.type === "fill") {
3346 for (let ic = doc.parts.length, i = ic - 1; i >= 0; --i) {
3347 docsStack.push(doc.parts[i]);
3349 } else if (doc.type === "if-break") {
3350 if (doc.flatContents) {
3351 docsStack.push(doc.flatContents);
3354 if (doc.breakContents) {
3355 docsStack.push(doc.breakContents);
3357 } else if (doc.type === "group" && doc.expandedStates) {
3358 if (shouldTraverseConditionalGroups) {
3359 for (let ic = doc.expandedStates.length, i = ic - 1; i >= 0; --i) {
3360 docsStack.push(doc.expandedStates[i]);
3363 docsStack.push(doc.contents);
3365 } else if (doc.contents) {
3366 docsStack.push(doc.contents);
3372 function mapDoc(doc, cb) {
3373 if (doc.type === "concat" || doc.type === "fill") {
3374 const parts = doc.parts.map(part => mapDoc(part, cb));
3375 return cb(Object.assign({}, doc, {
3378 } else if (doc.type === "if-break") {
3379 const breakContents = doc.breakContents && mapDoc(doc.breakContents, cb);
3380 const flatContents = doc.flatContents && mapDoc(doc.flatContents, cb);
3381 return cb(Object.assign({}, doc, {
3385 } else if (doc.contents) {
3386 const contents = mapDoc(doc.contents, cb);
3387 return cb(Object.assign({}, doc, {
3395 function findInDoc(doc, fn, defaultValue) {
3396 let result = defaultValue;
3397 let hasStopped = false;
3399 function findInDocOnEnterFn(doc) {
3400 const maybeResult = fn(doc);
3402 if (maybeResult !== undefined) {
3404 result = maybeResult;
3412 traverseDoc(doc, findInDocOnEnterFn);
3416 function isEmpty(n) {
3417 return typeof n === "string" && n.length === 0;
3420 function isLineNextFn(doc) {
3421 if (typeof doc === "string") {
3425 if (doc.type === "line") {
3430 function isLineNext(doc) {
3431 return findInDoc(doc, isLineNextFn, false);
3434 function willBreakFn(doc) {
3435 if (doc.type === "group" && doc.break) {
3439 if (doc.type === "line" && doc.hard) {
3443 if (doc.type === "break-parent") {
3448 function willBreak(doc) {
3449 return findInDoc(doc, willBreakFn, false);
3452 function breakParentGroup(groupStack) {
3453 if (groupStack.length > 0) {
3454 const parentGroup = groupStack[groupStack.length - 1]; // Breaks are not propagated through conditional groups because
3455 // the user is expected to manually handle what breaks.
3457 if (!parentGroup.expandedStates) {
3458 parentGroup.break = true;
3465 function propagateBreaks(doc) {
3466 const alreadyVisitedSet = new Set();
3467 const groupStack = [];
3469 function propagateBreaksOnEnterFn(doc) {
3470 if (doc.type === "break-parent") {
3471 breakParentGroup(groupStack);
3474 if (doc.type === "group") {
3475 groupStack.push(doc);
3477 if (alreadyVisitedSet.has(doc)) {
3481 alreadyVisitedSet.add(doc);
3485 function propagateBreaksOnExitFn(doc) {
3486 if (doc.type === "group") {
3487 const group = groupStack.pop();
3490 breakParentGroup(groupStack);
3495 traverseDoc(doc, propagateBreaksOnEnterFn, propagateBreaksOnExitFn,
3496 /* shouldTraverseConditionalGroups */
3500 function removeLinesFn(doc) {
3501 // Force this doc into flat mode by statically converting all
3502 // lines into spaces (or soft lines into nothing). Hard lines
3503 // should still output because there's too great of a chance
3504 // of breaking existing assumptions otherwise.
3505 if (doc.type === "line" && !doc.hard) {
3506 return doc.soft ? "" : " ";
3507 } else if (doc.type === "if-break") {
3508 return doc.flatContents || "";
3514 function removeLines(doc) {
3515 return mapDoc(doc, removeLinesFn);
3518 function getInnerParts(doc) {
3522 let lastPart; // Avoid a falsy element like ""
3524 for (let i = doc.parts.length; i > 0 && !lastPart; i--) {
3525 lastPart = parts[i - 1];
3528 if (lastPart.type === "group") {
3529 parts = lastPart.contents.parts;
3535 function stripTrailingHardline(doc, withInnerParts = false) {
3536 // HACK remove ending hardline, original PR: #1984
3537 if (doc.type === "concat" && doc.parts.length !== 0) {
3538 const parts = withInnerParts ? getInnerParts(doc) : doc.parts;
3539 const lastPart = parts[parts.length - 1];
3541 if (lastPart.type === "concat") {
3542 if (lastPart.parts.length === 2 && lastPart.parts[0].hard && lastPart.parts[1].type === "break-parent") {
3545 parts: parts.slice(0, -1)
3551 parts: doc.parts.slice(0, -1).concat(stripTrailingHardline(lastPart))
3559 function normalizeParts(parts) {
3560 const newParts = [];
3561 const restParts = parts.filter(Boolean);
3563 while (restParts.length !== 0) {
3564 const part = restParts.shift();
3570 if (part.type === "concat") {
3571 restParts.unshift(...part.parts);
3575 if (newParts.length !== 0 && typeof newParts[newParts.length - 1] === "string" && typeof part === "string") {
3576 newParts[newParts.length - 1] += part;
3580 newParts.push(part);
3586 function normalizeDoc(doc) {
3587 return mapDoc(doc, currentDoc => {
3588 if (!currentDoc.parts) {
3592 return Object.assign({}, currentDoc, {
3593 parts: normalizeParts(currentDoc.parts)
3598 function replaceNewlinesWithLiterallines(doc) {
3599 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);
3611 stripTrailingHardline,
3614 replaceNewlinesWithLiterallines
3617 function flattenDoc(doc) {
3618 if (doc.type === "concat") {
3621 for (let i = 0; i < doc.parts.length; ++i) {
3622 const doc2 = doc.parts[i];
3624 if (typeof doc2 !== "string" && doc2.type === "concat") {
3625 res.push(...flattenDoc(doc2).parts);
3627 const flattened = flattenDoc(doc2);
3629 if (flattened !== "") {
3630 res.push(flattened);
3635 return Object.assign({}, doc, {
3638 } else if (doc.type === "if-break") {
3639 return Object.assign({}, doc, {
3640 breakContents: doc.breakContents != null ? flattenDoc(doc.breakContents) : null,
3641 flatContents: doc.flatContents != null ? flattenDoc(doc.flatContents) : null
3643 } else if (doc.type === "group") {
3644 return Object.assign({}, doc, {
3645 contents: flattenDoc(doc.contents),
3646 expandedStates: doc.expandedStates ? doc.expandedStates.map(flattenDoc) : doc.expandedStates
3648 } else if (doc.contents) {
3649 return Object.assign({}, doc, {
3650 contents: flattenDoc(doc.contents)
3657 function printDoc(doc) {
3658 if (typeof doc === "string") {
3659 return JSON.stringify(doc);
3662 if (doc.type === "line") {
3664 return "literalline";
3678 if (doc.type === "break-parent") {
3679 return "breakParent";
3682 if (doc.type === "trim") {
3686 if (doc.type === "concat") {
3687 return "[" + doc.parts.map(printDoc).join(", ") + "]";
3690 if (doc.type === "indent") {
3691 return "indent(" + printDoc(doc.contents) + ")";
3694 if (doc.type === "align") {
3695 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) + ")";
3698 if (doc.type === "if-break") {
3699 return "ifBreak(" + printDoc(doc.breakContents) + (doc.flatContents ? ", " + printDoc(doc.flatContents) : "") + ")";
3702 if (doc.type === "group") {
3703 if (doc.expandedStates) {
3704 return "conditionalGroup(" + "[" + doc.expandedStates.map(printDoc).join(",") + "])";
3707 return (doc.break ? "wrappedGroup" : "group") + "(" + printDoc(doc.contents) + ")";
3710 if (doc.type === "fill") {
3711 return "fill" + "(" + doc.parts.map(printDoc).join(", ") + ")";
3714 if (doc.type === "line-suffix") {
3715 return "lineSuffix(" + printDoc(doc.contents) + ")";
3718 if (doc.type === "line-suffix-boundary") {
3719 return "lineSuffixBoundary";
3722 throw new Error("Unknown doc type " + doc.type);
3726 printDocToDebug(doc) {
3727 return printDoc(flattenDoc(doc));
3733 * @typedef {import("./doc-builders").Doc} Doc
3738 builders: docBuilders,
3739 printer: docPrinter,