Buckets:
| import Webpack from 'webpack'; | |
| import { isMinimal } from 'std-env'; | |
| import prettyTime from 'pretty-time'; | |
| import path, { sep, delimiter } from 'path'; | |
| import chalk from 'chalk'; | |
| import _consola from 'consola'; | |
| function first(arr) { | |
| return arr[0]; | |
| } | |
| function last(arr) { | |
| return arr.length ? arr[arr.length - 1] : null; | |
| } | |
| function startCase(str) { | |
| return str[0].toUpperCase() + str.substr(1); | |
| } | |
| function firstMatch(regex, str) { | |
| const m = regex.exec(str); | |
| return m ? m[0] : null; | |
| } | |
| function hasValue(s) { | |
| return s && s.length; | |
| } | |
| function removeAfter(delimiter, str) { | |
| return first(str.split(delimiter)) || ""; | |
| } | |
| function removeBefore(delimiter, str) { | |
| return last(str.split(delimiter)) || ""; | |
| } | |
| function range(len) { | |
| const arr = []; | |
| for (let i = 0; i < len; i++) { | |
| arr.push(i); | |
| } | |
| return arr; | |
| } | |
| function shortenPath(path = "") { | |
| const cwd = process.cwd() + sep; | |
| return String(path).replace(cwd, ""); | |
| } | |
| function objectValues(obj) { | |
| return Object.keys(obj).map((key) => obj[key]); | |
| } | |
| /** | |
| * @typedef MarkdownTableOptions | |
| * @property {string|null|Array.<string|null|undefined>} [align] | |
| * @property {boolean} [padding=true] | |
| * @property {boolean} [delimiterStart=true] | |
| * @property {boolean} [delimiterStart=true] | |
| * @property {boolean} [delimiterEnd=true] | |
| * @property {boolean} [alignDelimiters=true] | |
| * @property {(value: string) => number} [stringLength] | |
| */ | |
| /** | |
| * Create a table from a matrix of strings. | |
| * | |
| * @param {Array.<Array.<string|null|undefined>>} table | |
| * @param {MarkdownTableOptions} [options] | |
| * @returns {string} | |
| */ | |
| function markdownTable(table, options) { | |
| const settings = options || {}; | |
| const align = (settings.align || []).concat(); | |
| const stringLength = settings.stringLength || defaultStringLength; | |
| /** @type {number[]} Character codes as symbols for alignment per column. */ | |
| const alignments = []; | |
| let rowIndex = -1; | |
| /** @type {string[][]} Cells per row. */ | |
| const cellMatrix = []; | |
| /** @type {number[][]} Sizes of each cell per row. */ | |
| const sizeMatrix = []; | |
| /** @type {number[]} */ | |
| const longestCellByColumn = []; | |
| let mostCellsPerRow = 0; | |
| /** @type {number} */ | |
| let columnIndex; | |
| /** @type {string[]} Cells of current row */ | |
| let row; | |
| /** @type {number[]} Sizes of current row */ | |
| let sizes; | |
| /** @type {number} Sizes of current cell */ | |
| let size; | |
| /** @type {string} Current cell */ | |
| let cell; | |
| /** @type {string[]} Chunks of current line. */ | |
| let line; | |
| /** @type {string} */ | |
| let before; | |
| /** @type {string} */ | |
| let after; | |
| /** @type {number} */ | |
| let code; | |
| // This is a superfluous loop if we don’t align delimiters, but otherwise we’d | |
| // do superfluous work when aligning, so optimize for aligning. | |
| while (++rowIndex < table.length) { | |
| columnIndex = -1; | |
| row = []; | |
| sizes = []; | |
| if (table[rowIndex].length > mostCellsPerRow) { | |
| mostCellsPerRow = table[rowIndex].length; | |
| } | |
| while (++columnIndex < table[rowIndex].length) { | |
| cell = serialize(table[rowIndex][columnIndex]); | |
| if (settings.alignDelimiters !== false) { | |
| size = stringLength(cell); | |
| sizes[columnIndex] = size; | |
| if ( | |
| longestCellByColumn[columnIndex] === undefined || | |
| size > longestCellByColumn[columnIndex] | |
| ) { | |
| longestCellByColumn[columnIndex] = size; | |
| } | |
| } | |
| row.push(cell); | |
| } | |
| cellMatrix[rowIndex] = row; | |
| sizeMatrix[rowIndex] = sizes; | |
| } | |
| // Figure out which alignments to use. | |
| columnIndex = -1; | |
| if (typeof align === 'object' && 'length' in align) { | |
| while (++columnIndex < mostCellsPerRow) { | |
| alignments[columnIndex] = toAlignment(align[columnIndex]); | |
| } | |
| } else { | |
| code = toAlignment(align); | |
| while (++columnIndex < mostCellsPerRow) { | |
| alignments[columnIndex] = code; | |
| } | |
| } | |
| // Inject the alignment row. | |
| columnIndex = -1; | |
| row = []; | |
| sizes = []; | |
| while (++columnIndex < mostCellsPerRow) { | |
| code = alignments[columnIndex]; | |
| before = ''; | |
| after = ''; | |
| if (code === 99 /* `c` */) { | |
| before = ':'; | |
| after = ':'; | |
| } else if (code === 108 /* `l` */) { | |
| before = ':'; | |
| } else if (code === 114 /* `r` */) { | |
| after = ':'; | |
| } | |
| // There *must* be at least one hyphen-minus in each alignment cell. | |
| size = | |
| settings.alignDelimiters === false | |
| ? 1 | |
| : Math.max( | |
| 1, | |
| longestCellByColumn[columnIndex] - before.length - after.length | |
| ); | |
| cell = before + '-'.repeat(size) + after; | |
| if (settings.alignDelimiters !== false) { | |
| size = before.length + size + after.length; | |
| if (size > longestCellByColumn[columnIndex]) { | |
| longestCellByColumn[columnIndex] = size; | |
| } | |
| sizes[columnIndex] = size; | |
| } | |
| row[columnIndex] = cell; | |
| } | |
| // Inject the alignment row. | |
| cellMatrix.splice(1, 0, row); | |
| sizeMatrix.splice(1, 0, sizes); | |
| rowIndex = -1; | |
| /** @type {string[]} */ | |
| const lines = []; | |
| while (++rowIndex < cellMatrix.length) { | |
| row = cellMatrix[rowIndex]; | |
| sizes = sizeMatrix[rowIndex]; | |
| columnIndex = -1; | |
| line = []; | |
| while (++columnIndex < mostCellsPerRow) { | |
| cell = row[columnIndex] || ''; | |
| before = ''; | |
| after = ''; | |
| if (settings.alignDelimiters !== false) { | |
| size = longestCellByColumn[columnIndex] - (sizes[columnIndex] || 0); | |
| code = alignments[columnIndex]; | |
| if (code === 114 /* `r` */) { | |
| before = ' '.repeat(size); | |
| } else if (code === 99 /* `c` */) { | |
| if (size % 2) { | |
| before = ' '.repeat(size / 2 + 0.5); | |
| after = ' '.repeat(size / 2 - 0.5); | |
| } else { | |
| before = ' '.repeat(size / 2); | |
| after = before; | |
| } | |
| } else { | |
| after = ' '.repeat(size); | |
| } | |
| } | |
| if (settings.delimiterStart !== false && !columnIndex) { | |
| line.push('|'); | |
| } | |
| if ( | |
| settings.padding !== false && | |
| // Don’t add the opening space if we’re not aligning and the cell is | |
| // empty: there will be a closing space. | |
| !(settings.alignDelimiters === false && cell === '') && | |
| (settings.delimiterStart !== false || columnIndex) | |
| ) { | |
| line.push(' '); | |
| } | |
| if (settings.alignDelimiters !== false) { | |
| line.push(before); | |
| } | |
| line.push(cell); | |
| if (settings.alignDelimiters !== false) { | |
| line.push(after); | |
| } | |
| if (settings.padding !== false) { | |
| line.push(' '); | |
| } | |
| if ( | |
| settings.delimiterEnd !== false || | |
| columnIndex !== mostCellsPerRow - 1 | |
| ) { | |
| line.push('|'); | |
| } | |
| } | |
| lines.push( | |
| settings.delimiterEnd === false | |
| ? line.join('').replace(/ +$/, '') | |
| : line.join('') | |
| ); | |
| } | |
| return lines.join('\n') | |
| } | |
| /** | |
| * @param {string|null|undefined} [value] | |
| * @returns {string} | |
| */ | |
| function serialize(value) { | |
| return value === null || value === undefined ? '' : String(value) | |
| } | |
| /** | |
| * @param {string} value | |
| * @returns {number} | |
| */ | |
| function defaultStringLength(value) { | |
| return value.length | |
| } | |
| /** | |
| * @param {string|null|undefined} value | |
| * @returns {number} | |
| */ | |
| function toAlignment(value) { | |
| const code = typeof value === 'string' ? value.charCodeAt(0) : 0; | |
| return code === 67 /* `C` */ || code === 99 /* `c` */ | |
| ? 99 /* `c` */ | |
| : code === 76 /* `L` */ || code === 108 /* `l` */ | |
| ? 108 /* `l` */ | |
| : code === 82 /* `R` */ || code === 114 /* `r` */ | |
| ? 114 /* `r` */ | |
| : 0 | |
| } | |
| function isUnicodeSupported() { | |
| if (process.platform !== 'win32') { | |
| return process.env.TERM !== 'linux'; // Linux console (kernel) | |
| } | |
| return Boolean(process.env.CI) || | |
| Boolean(process.env.WT_SESSION) || // Windows Terminal | |
| process.env.ConEmuTask === '{cmd::Cmder}' || // ConEmu and cmder | |
| process.env.TERM_PROGRAM === 'vscode' || | |
| process.env.TERM === 'xterm-256color' || | |
| process.env.TERM === 'alacritty'; | |
| } | |
| const {platform} = process; | |
| const common = { | |
| square: '█', | |
| squareDarkShade: '▓', | |
| squareMediumShade: '▒', | |
| squareLightShade: '░', | |
| squareTop: '▀', | |
| squareBottom: '▄', | |
| squareLeft: '▌', | |
| squareRight: '▐', | |
| squareCenter: '■', | |
| bullet: '●', | |
| dot: '․', | |
| ellipsis: '…', | |
| pointerSmall: '›', | |
| triangleUp: '▲', | |
| triangleUpSmall: '▴', | |
| triangleDown: '▼', | |
| triangleDownSmall: '▾', | |
| triangleLeftSmall: '◂', | |
| triangleRightSmall: '▸', | |
| home: '⌂', | |
| heart: '♥', | |
| musicNote: '♪', | |
| musicNoteBeamed: '♫', | |
| arrowUp: '↑', | |
| arrowDown: '↓', | |
| arrowLeft: '←', | |
| arrowRight: '→', | |
| arrowLeftRight: '↔', | |
| arrowUpDown: '↕', | |
| almostEqual: '≈', | |
| notEqual: '≠', | |
| lessOrEqual: '≤', | |
| greaterOrEqual: '≥', | |
| identical: '≡', | |
| infinity: '∞', | |
| subscriptZero: '₀', | |
| subscriptOne: '₁', | |
| subscriptTwo: '₂', | |
| subscriptThree: '₃', | |
| subscriptFour: '₄', | |
| subscriptFive: '₅', | |
| subscriptSix: '₆', | |
| subscriptSeven: '₇', | |
| subscriptEight: '₈', | |
| subscriptNine: '₉', | |
| oneHalf: '½', | |
| oneThird: '⅓', | |
| oneQuarter: '¼', | |
| oneFifth: '⅕', | |
| oneSixth: '⅙', | |
| oneEighth: '⅛', | |
| twoThirds: '⅔', | |
| twoFifths: '⅖', | |
| threeQuarters: '¾', | |
| threeFifths: '⅗', | |
| threeEighths: '⅜', | |
| fourFifths: '⅘', | |
| fiveSixths: '⅚', | |
| fiveEighths: '⅝', | |
| sevenEighths: '⅞', | |
| line: '─', | |
| lineBold: '━', | |
| lineDouble: '═', | |
| lineDashed0: '┄', | |
| lineDashed1: '┅', | |
| lineDashed2: '┈', | |
| lineDashed3: '┉', | |
| lineDashed4: '╌', | |
| lineDashed5: '╍', | |
| lineDashed6: '╴', | |
| lineDashed7: '╶', | |
| lineDashed8: '╸', | |
| lineDashed9: '╺', | |
| lineDashed10: '╼', | |
| lineDashed11: '╾', | |
| lineDashed12: '−', | |
| lineDashed13: '–', | |
| lineDashed14: '‐', | |
| lineDashed15: '⁃', | |
| lineVertical: '│', | |
| lineVerticalBold: '┃', | |
| lineVerticalDouble: '║', | |
| lineVerticalDashed0: '┆', | |
| lineVerticalDashed1: '┇', | |
| lineVerticalDashed2: '┊', | |
| lineVerticalDashed3: '┋', | |
| lineVerticalDashed4: '╎', | |
| lineVerticalDashed5: '╏', | |
| lineVerticalDashed6: '╵', | |
| lineVerticalDashed7: '╷', | |
| lineVerticalDashed8: '╹', | |
| lineVerticalDashed9: '╻', | |
| lineVerticalDashed10: '╽', | |
| lineVerticalDashed11: '╿', | |
| lineDownLeft: '┐', | |
| lineDownLeftArc: '╮', | |
| lineDownBoldLeftBold: '┓', | |
| lineDownBoldLeft: '┒', | |
| lineDownLeftBold: '┑', | |
| lineDownDoubleLeftDouble: '╗', | |
| lineDownDoubleLeft: '╖', | |
| lineDownLeftDouble: '╕', | |
| lineDownRight: '┌', | |
| lineDownRightArc: '╭', | |
| lineDownBoldRightBold: '┏', | |
| lineDownBoldRight: '┎', | |
| lineDownRightBold: '┍', | |
| lineDownDoubleRightDouble: '╔', | |
| lineDownDoubleRight: '╓', | |
| lineDownRightDouble: '╒', | |
| lineUpLeft: '┘', | |
| lineUpLeftArc: '╯', | |
| lineUpBoldLeftBold: '┛', | |
| lineUpBoldLeft: '┚', | |
| lineUpLeftBold: '┙', | |
| lineUpDoubleLeftDouble: '╝', | |
| lineUpDoubleLeft: '╜', | |
| lineUpLeftDouble: '╛', | |
| lineUpRight: '└', | |
| lineUpRightArc: '╰', | |
| lineUpBoldRightBold: '┗', | |
| lineUpBoldRight: '┖', | |
| lineUpRightBold: '┕', | |
| lineUpDoubleRightDouble: '╚', | |
| lineUpDoubleRight: '╙', | |
| lineUpRightDouble: '╘', | |
| lineUpDownLeft: '┤', | |
| lineUpBoldDownBoldLeftBold: '┫', | |
| lineUpBoldDownBoldLeft: '┨', | |
| lineUpDownLeftBold: '┥', | |
| lineUpBoldDownLeftBold: '┩', | |
| lineUpDownBoldLeftBold: '┪', | |
| lineUpDownBoldLeft: '┧', | |
| lineUpBoldDownLeft: '┦', | |
| lineUpDoubleDownDoubleLeftDouble: '╣', | |
| lineUpDoubleDownDoubleLeft: '╢', | |
| lineUpDownLeftDouble: '╡', | |
| lineUpDownRight: '├', | |
| lineUpBoldDownBoldRightBold: '┣', | |
| lineUpBoldDownBoldRight: '┠', | |
| lineUpDownRightBold: '┝', | |
| lineUpBoldDownRightBold: '┡', | |
| lineUpDownBoldRightBold: '┢', | |
| lineUpDownBoldRight: '┟', | |
| lineUpBoldDownRight: '┞', | |
| lineUpDoubleDownDoubleRightDouble: '╠', | |
| lineUpDoubleDownDoubleRight: '╟', | |
| lineUpDownRightDouble: '╞', | |
| lineDownLeftRight: '┬', | |
| lineDownBoldLeftBoldRightBold: '┳', | |
| lineDownLeftBoldRightBold: '┯', | |
| lineDownBoldLeftRight: '┰', | |
| lineDownBoldLeftBoldRight: '┱', | |
| lineDownBoldLeftRightBold: '┲', | |
| lineDownLeftRightBold: '┮', | |
| lineDownLeftBoldRight: '┭', | |
| lineDownDoubleLeftDoubleRightDouble: '╦', | |
| lineDownDoubleLeftRight: '╥', | |
| lineDownLeftDoubleRightDouble: '╤', | |
| lineUpLeftRight: '┴', | |
| lineUpBoldLeftBoldRightBold: '┻', | |
| lineUpLeftBoldRightBold: '┷', | |
| lineUpBoldLeftRight: '┸', | |
| lineUpBoldLeftBoldRight: '┹', | |
| lineUpBoldLeftRightBold: '┺', | |
| lineUpLeftRightBold: '┶', | |
| lineUpLeftBoldRight: '┵', | |
| lineUpDoubleLeftDoubleRightDouble: '╩', | |
| lineUpDoubleLeftRight: '╨', | |
| lineUpLeftDoubleRightDouble: '╧', | |
| lineUpDownLeftRight: '┼', | |
| lineUpBoldDownBoldLeftBoldRightBold: '╋', | |
| lineUpDownBoldLeftBoldRightBold: '╈', | |
| lineUpBoldDownLeftBoldRightBold: '╇', | |
| lineUpBoldDownBoldLeftRightBold: '╊', | |
| lineUpBoldDownBoldLeftBoldRight: '╉', | |
| lineUpBoldDownLeftRight: '╀', | |
| lineUpDownBoldLeftRight: '╁', | |
| lineUpDownLeftBoldRight: '┽', | |
| lineUpDownLeftRightBold: '┾', | |
| lineUpBoldDownBoldLeftRight: '╂', | |
| lineUpDownLeftBoldRightBold: '┿', | |
| lineUpBoldDownLeftBoldRight: '╃', | |
| lineUpBoldDownLeftRightBold: '╄', | |
| lineUpDownBoldLeftBoldRight: '╅', | |
| lineUpDownBoldLeftRightBold: '╆', | |
| lineUpDoubleDownDoubleLeftDoubleRightDouble: '╬', | |
| lineUpDoubleDownDoubleLeftRight: '╫', | |
| lineUpDownLeftDoubleRightDouble: '╪', | |
| lineCross: '╳', | |
| lineBackslash: '╲', | |
| lineSlash: '╱' | |
| }; | |
| const mainSymbols = { | |
| ...common, | |
| // The main symbols for those do not look that good on Ubuntu. | |
| ...( | |
| platform === 'linux' ? | |
| { | |
| circleQuestionMark: '?⃝', | |
| questionMarkPrefix: '?⃝' | |
| } : | |
| { | |
| circleQuestionMark: '?', | |
| questionMarkPrefix: '?' | |
| } | |
| ), | |
| tick: '✔', | |
| info: 'ℹ', | |
| warning: '⚠', | |
| cross: '✖', | |
| squareSmall: '◻', | |
| squareSmallFilled: '◼', | |
| circle: '◯', | |
| circleFilled: '◉', | |
| circleDotted: '◌', | |
| circleDouble: '◎', | |
| circleCircle: 'ⓞ', | |
| circleCross: 'ⓧ', | |
| circlePipe: 'Ⓘ', | |
| radioOn: '◉', | |
| radioOff: '◯', | |
| checkboxOn: '☒', | |
| checkboxOff: '☐', | |
| checkboxCircleOn: 'ⓧ', | |
| checkboxCircleOff: 'Ⓘ', | |
| pointer: '❯', | |
| triangleUpOutline: '△', | |
| triangleLeft: '◀', | |
| triangleRight: '▶', | |
| lozenge: '◆', | |
| lozengeOutline: '◇', | |
| hamburger: '☰', | |
| smiley: '㋡', | |
| mustache: '෴', | |
| star: '★', | |
| play: '▶', | |
| nodejs: '⬢', | |
| oneSeventh: '⅐', | |
| oneNinth: '⅑', | |
| oneTenth: '⅒' | |
| }; | |
| const fallbackSymbols = { | |
| ...common, | |
| tick: '√', | |
| info: 'i', | |
| warning: '‼', | |
| cross: '×', | |
| squareSmall: '□', | |
| squareSmallFilled: '■', | |
| circle: '( )', | |
| circleFilled: '(*)', | |
| circleDotted: '( )', | |
| circleDouble: '( )', | |
| circleCircle: '(○)', | |
| circleCross: '(×)', | |
| circlePipe: '(│)', | |
| circleQuestionMark: '(?)', | |
| radioOn: '(*)', | |
| radioOff: '( )', | |
| checkboxOn: '[×]', | |
| checkboxOff: '[ ]', | |
| checkboxCircleOn: '(×)', | |
| checkboxCircleOff: '( )', | |
| questionMarkPrefix: '?', | |
| pointer: '>', | |
| triangleUpOutline: '∆', | |
| triangleLeft: '◄', | |
| triangleRight: '►', | |
| lozenge: '♦', | |
| lozengeOutline: '◊', | |
| hamburger: '≡', | |
| smiley: '☺', | |
| mustache: '┌─┐', | |
| star: '✶', | |
| play: '►', | |
| nodejs: '♦', | |
| oneSeventh: '1/7', | |
| oneNinth: '1/9', | |
| oneTenth: '1/10' | |
| }; | |
| const shouldUseMain = isUnicodeSupported(); | |
| const figures = shouldUseMain ? mainSymbols : fallbackSymbols; | |
| const { bullet, tick, cross, pointerSmall, radioOff } = figures; | |
| const nodeModules = `${delimiter}node_modules${delimiter}`; | |
| const BAR_LENGTH = 25; | |
| const BLOCK_CHAR = "\u2588"; | |
| const BLOCK_CHAR2 = "\u2588"; | |
| const NEXT = " " + chalk.blue(pointerSmall) + " "; | |
| const BULLET = bullet; | |
| const TICK = tick; | |
| const CROSS = cross; | |
| const CIRCLE_OPEN = radioOff; | |
| const consola = _consola.withTag("webpackbar"); | |
| const colorize = (color) => { | |
| if (color[0] === "#") { | |
| return chalk.hex(color); | |
| } | |
| return chalk[color] || chalk.keyword(color); | |
| }; | |
| const renderBar = (progress, color) => { | |
| const w = progress * (BAR_LENGTH / 100); | |
| const bg = chalk.white(BLOCK_CHAR); | |
| const fg = colorize(color)(BLOCK_CHAR2); | |
| return range(BAR_LENGTH).map((i) => i < w ? fg : bg).join(""); | |
| }; | |
| function createTable(data) { | |
| return markdownTable(data); | |
| } | |
| function ellipsisLeft(str, n) { | |
| if (str.length <= n - 3) { | |
| return str; | |
| } | |
| return `...${str.substr(str.length - n - 1)}`; | |
| } | |
| const parseRequest = (requestStr) => { | |
| const parts = (requestStr || "").split("!"); | |
| const file = path.relative(process.cwd(), removeAfter("?", removeBefore(nodeModules, parts.pop()))); | |
| const loaders = parts.map((part) => firstMatch(/[a-z0-9-@]+-loader/, part)).filter(hasValue); | |
| return { | |
| file: hasValue(file) ? file : null, | |
| loaders | |
| }; | |
| }; | |
| const formatRequest = (request) => { | |
| const loaders = request.loaders.join(NEXT); | |
| if (!loaders.length) { | |
| return request.file || ""; | |
| } | |
| return `${loaders}${NEXT}${request.file}`; | |
| }; | |
| function hook(compiler, hookName, fn) { | |
| if (compiler.hooks) { | |
| compiler.hooks[hookName].tap("WebpackBar:" + hookName, fn); | |
| } else { | |
| compiler.plugin(hookName, fn); | |
| } | |
| } | |
| const ESC = '\u001B['; | |
| const OSC = '\u001B]'; | |
| const BEL = '\u0007'; | |
| const SEP = ';'; | |
| const isTerminalApp = process.env.TERM_PROGRAM === 'Apple_Terminal'; | |
| const ansiEscapes = {}; | |
| ansiEscapes.cursorTo = (x, y) => { | |
| if (typeof x !== 'number') { | |
| throw new TypeError('The `x` argument is required'); | |
| } | |
| if (typeof y !== 'number') { | |
| return ESC + (x + 1) + 'G'; | |
| } | |
| return ESC + (y + 1) + ';' + (x + 1) + 'H'; | |
| }; | |
| ansiEscapes.cursorMove = (x, y) => { | |
| if (typeof x !== 'number') { | |
| throw new TypeError('The `x` argument is required'); | |
| } | |
| let returnValue = ''; | |
| if (x < 0) { | |
| returnValue += ESC + (-x) + 'D'; | |
| } else if (x > 0) { | |
| returnValue += ESC + x + 'C'; | |
| } | |
| if (y < 0) { | |
| returnValue += ESC + (-y) + 'A'; | |
| } else if (y > 0) { | |
| returnValue += ESC + y + 'B'; | |
| } | |
| return returnValue; | |
| }; | |
| ansiEscapes.cursorUp = (count = 1) => ESC + count + 'A'; | |
| ansiEscapes.cursorDown = (count = 1) => ESC + count + 'B'; | |
| ansiEscapes.cursorForward = (count = 1) => ESC + count + 'C'; | |
| ansiEscapes.cursorBackward = (count = 1) => ESC + count + 'D'; | |
| ansiEscapes.cursorLeft = ESC + 'G'; | |
| ansiEscapes.cursorSavePosition = isTerminalApp ? '\u001B7' : ESC + 's'; | |
| ansiEscapes.cursorRestorePosition = isTerminalApp ? '\u001B8' : ESC + 'u'; | |
| ansiEscapes.cursorGetPosition = ESC + '6n'; | |
| ansiEscapes.cursorNextLine = ESC + 'E'; | |
| ansiEscapes.cursorPrevLine = ESC + 'F'; | |
| ansiEscapes.cursorHide = ESC + '?25l'; | |
| ansiEscapes.cursorShow = ESC + '?25h'; | |
| ansiEscapes.eraseLines = count => { | |
| let clear = ''; | |
| for (let i = 0; i < count; i++) { | |
| clear += ansiEscapes.eraseLine + (i < count - 1 ? ansiEscapes.cursorUp() : ''); | |
| } | |
| if (count) { | |
| clear += ansiEscapes.cursorLeft; | |
| } | |
| return clear; | |
| }; | |
| ansiEscapes.eraseEndLine = ESC + 'K'; | |
| ansiEscapes.eraseStartLine = ESC + '1K'; | |
| ansiEscapes.eraseLine = ESC + '2K'; | |
| ansiEscapes.eraseDown = ESC + 'J'; | |
| ansiEscapes.eraseUp = ESC + '1J'; | |
| ansiEscapes.eraseScreen = ESC + '2J'; | |
| ansiEscapes.scrollUp = ESC + 'S'; | |
| ansiEscapes.scrollDown = ESC + 'T'; | |
| ansiEscapes.clearScreen = '\u001Bc'; | |
| ansiEscapes.clearTerminal = process.platform === 'win32' ? | |
| `${ansiEscapes.eraseScreen}${ESC}0f` : | |
| // 1. Erases the screen (Only done in case `2` is not supported) | |
| // 2. Erases the whole screen including scrollback buffer | |
| // 3. Moves cursor to the top-left position | |
| // More info: https://www.real-world-systems.com/docs/ANSIcode.html | |
| `${ansiEscapes.eraseScreen}${ESC}3J${ESC}H`; | |
| ansiEscapes.beep = BEL; | |
| ansiEscapes.link = (text, url) => { | |
| return [ | |
| OSC, | |
| '8', | |
| SEP, | |
| SEP, | |
| url, | |
| BEL, | |
| text, | |
| OSC, | |
| '8', | |
| SEP, | |
| SEP, | |
| BEL | |
| ].join(''); | |
| }; | |
| ansiEscapes.image = (buffer, options = {}) => { | |
| let returnValue = `${OSC}1337;File=inline=1`; | |
| if (options.width) { | |
| returnValue += `;width=${options.width}`; | |
| } | |
| if (options.height) { | |
| returnValue += `;height=${options.height}`; | |
| } | |
| if (options.preserveAspectRatio === false) { | |
| returnValue += ';preserveAspectRatio=0'; | |
| } | |
| return returnValue + ':' + buffer.toString('base64') + BEL; | |
| }; | |
| ansiEscapes.iTerm = { | |
| setCwd: (cwd = process.cwd()) => `${OSC}50;CurrentDir=${cwd}${BEL}`, | |
| annotation: (message, options = {}) => { | |
| let returnValue = `${OSC}1337;`; | |
| const hasX = typeof options.x !== 'undefined'; | |
| const hasY = typeof options.y !== 'undefined'; | |
| if ((hasX || hasY) && !(hasX && hasY && typeof options.length !== 'undefined')) { | |
| throw new Error('`x`, `y` and `length` must be defined when `x` or `y` is defined'); | |
| } | |
| message = message.replace(/\|/g, ''); | |
| returnValue += options.isHidden ? 'AddHiddenAnnotation=' : 'AddAnnotation='; | |
| if (options.length > 0) { | |
| returnValue += | |
| (hasX ? | |
| [message, options.length, options.x, options.y] : | |
| [options.length, message]).join('|'); | |
| } else { | |
| returnValue += message; | |
| } | |
| return returnValue + BEL; | |
| } | |
| }; | |
| function ansiRegex({onlyFirst = false} = {}) { | |
| const pattern = [ | |
| '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', | |
| '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))' | |
| ].join('|'); | |
| return new RegExp(pattern, onlyFirst ? undefined : 'g'); | |
| } | |
| function stripAnsi(string) { | |
| if (typeof string !== 'string') { | |
| throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``); | |
| } | |
| return string.replace(ansiRegex(), ''); | |
| } | |
| /* eslint-disable yoda */ | |
| function isFullwidthCodePoint(codePoint) { | |
| if (!Number.isInteger(codePoint)) { | |
| return false; | |
| } | |
| // Code points are derived from: | |
| // https://unicode.org/Public/UNIDATA/EastAsianWidth.txt | |
| return codePoint >= 0x1100 && ( | |
| codePoint <= 0x115F || // Hangul Jamo | |
| codePoint === 0x2329 || // LEFT-POINTING ANGLE BRACKET | |
| codePoint === 0x232A || // RIGHT-POINTING ANGLE BRACKET | |
| // CJK Radicals Supplement .. Enclosed CJK Letters and Months | |
| (0x2E80 <= codePoint && codePoint <= 0x3247 && codePoint !== 0x303F) || | |
| // Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A | |
| (0x3250 <= codePoint && codePoint <= 0x4DBF) || | |
| // CJK Unified Ideographs .. Yi Radicals | |
| (0x4E00 <= codePoint && codePoint <= 0xA4C6) || | |
| // Hangul Jamo Extended-A | |
| (0xA960 <= codePoint && codePoint <= 0xA97C) || | |
| // Hangul Syllables | |
| (0xAC00 <= codePoint && codePoint <= 0xD7A3) || | |
| // CJK Compatibility Ideographs | |
| (0xF900 <= codePoint && codePoint <= 0xFAFF) || | |
| // Vertical Forms | |
| (0xFE10 <= codePoint && codePoint <= 0xFE19) || | |
| // CJK Compatibility Forms .. Small Form Variants | |
| (0xFE30 <= codePoint && codePoint <= 0xFE6B) || | |
| // Halfwidth and Fullwidth Forms | |
| (0xFF01 <= codePoint && codePoint <= 0xFF60) || | |
| (0xFFE0 <= codePoint && codePoint <= 0xFFE6) || | |
| // Kana Supplement | |
| (0x1B000 <= codePoint && codePoint <= 0x1B001) || | |
| // Enclosed Ideographic Supplement | |
| (0x1F200 <= codePoint && codePoint <= 0x1F251) || | |
| // CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane | |
| (0x20000 <= codePoint && codePoint <= 0x3FFFD) | |
| ); | |
| } | |
| var emojiRegex = function () { | |
| // https://mths.be/emoji | |
| return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g; | |
| }; | |
| function stringWidth(string) { | |
| if (typeof string !== 'string' || string.length === 0) { | |
| return 0; | |
| } | |
| string = stripAnsi(string); | |
| if (string.length === 0) { | |
| return 0; | |
| } | |
| string = string.replace(emojiRegex(), ' '); | |
| let width = 0; | |
| for (let index = 0; index < string.length; index++) { | |
| const codePoint = string.codePointAt(index); | |
| // Ignore control characters | |
| if (codePoint <= 0x1F || (codePoint >= 0x7F && codePoint <= 0x9F)) { | |
| continue; | |
| } | |
| // Ignore combining characters | |
| if (codePoint >= 0x300 && codePoint <= 0x36F) { | |
| continue; | |
| } | |
| // Surrogates | |
| if (codePoint > 0xFFFF) { | |
| index++; | |
| } | |
| width += isFullwidthCodePoint(codePoint) ? 2 : 1; | |
| } | |
| return width; | |
| } | |
| const ANSI_BACKGROUND_OFFSET = 10; | |
| const wrapAnsi16 = (offset = 0) => code => `\u001B[${code + offset}m`; | |
| const wrapAnsi256 = (offset = 0) => code => `\u001B[${38 + offset};5;${code}m`; | |
| const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u001B[${38 + offset};2;${red};${green};${blue}m`; | |
| function assembleStyles() { | |
| const codes = new Map(); | |
| const styles = { | |
| modifier: { | |
| reset: [0, 0], | |
| // 21 isn't widely supported and 22 does the same thing | |
| bold: [1, 22], | |
| dim: [2, 22], | |
| italic: [3, 23], | |
| underline: [4, 24], | |
| overline: [53, 55], | |
| inverse: [7, 27], | |
| hidden: [8, 28], | |
| strikethrough: [9, 29] | |
| }, | |
| color: { | |
| black: [30, 39], | |
| red: [31, 39], | |
| green: [32, 39], | |
| yellow: [33, 39], | |
| blue: [34, 39], | |
| magenta: [35, 39], | |
| cyan: [36, 39], | |
| white: [37, 39], | |
| // Bright color | |
| blackBright: [90, 39], | |
| redBright: [91, 39], | |
| greenBright: [92, 39], | |
| yellowBright: [93, 39], | |
| blueBright: [94, 39], | |
| magentaBright: [95, 39], | |
| cyanBright: [96, 39], | |
| whiteBright: [97, 39] | |
| }, | |
| bgColor: { | |
| bgBlack: [40, 49], | |
| bgRed: [41, 49], | |
| bgGreen: [42, 49], | |
| bgYellow: [43, 49], | |
| bgBlue: [44, 49], | |
| bgMagenta: [45, 49], | |
| bgCyan: [46, 49], | |
| bgWhite: [47, 49], | |
| // Bright color | |
| bgBlackBright: [100, 49], | |
| bgRedBright: [101, 49], | |
| bgGreenBright: [102, 49], | |
| bgYellowBright: [103, 49], | |
| bgBlueBright: [104, 49], | |
| bgMagentaBright: [105, 49], | |
| bgCyanBright: [106, 49], | |
| bgWhiteBright: [107, 49] | |
| } | |
| }; | |
| // Alias bright black as gray (and grey) | |
| styles.color.gray = styles.color.blackBright; | |
| styles.bgColor.bgGray = styles.bgColor.bgBlackBright; | |
| styles.color.grey = styles.color.blackBright; | |
| styles.bgColor.bgGrey = styles.bgColor.bgBlackBright; | |
| for (const [groupName, group] of Object.entries(styles)) { | |
| for (const [styleName, style] of Object.entries(group)) { | |
| styles[styleName] = { | |
| open: `\u001B[${style[0]}m`, | |
| close: `\u001B[${style[1]}m` | |
| }; | |
| group[styleName] = styles[styleName]; | |
| codes.set(style[0], style[1]); | |
| } | |
| Object.defineProperty(styles, groupName, { | |
| value: group, | |
| enumerable: false | |
| }); | |
| } | |
| Object.defineProperty(styles, 'codes', { | |
| value: codes, | |
| enumerable: false | |
| }); | |
| styles.color.close = '\u001B[39m'; | |
| styles.bgColor.close = '\u001B[49m'; | |
| styles.color.ansi = wrapAnsi16(); | |
| styles.color.ansi256 = wrapAnsi256(); | |
| styles.color.ansi16m = wrapAnsi16m(); | |
| styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET); | |
| styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET); | |
| styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET); | |
| // From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js | |
| Object.defineProperties(styles, { | |
| rgbToAnsi256: { | |
| value: (red, green, blue) => { | |
| // We use the extended greyscale palette here, with the exception of | |
| // black and white. normal palette only has 4 greyscale shades. | |
| if (red === green && green === blue) { | |
| if (red < 8) { | |
| return 16; | |
| } | |
| if (red > 248) { | |
| return 231; | |
| } | |
| return Math.round(((red - 8) / 247) * 24) + 232; | |
| } | |
| return 16 + | |
| (36 * Math.round(red / 255 * 5)) + | |
| (6 * Math.round(green / 255 * 5)) + | |
| Math.round(blue / 255 * 5); | |
| }, | |
| enumerable: false | |
| }, | |
| hexToRgb: { | |
| value: hex => { | |
| const matches = /(?<colorString>[a-f\d]{6}|[a-f\d]{3})/i.exec(hex.toString(16)); | |
| if (!matches) { | |
| return [0, 0, 0]; | |
| } | |
| let {colorString} = matches.groups; | |
| if (colorString.length === 3) { | |
| colorString = colorString.split('').map(character => character + character).join(''); | |
| } | |
| const integer = Number.parseInt(colorString, 16); | |
| return [ | |
| (integer >> 16) & 0xFF, | |
| (integer >> 8) & 0xFF, | |
| integer & 0xFF | |
| ]; | |
| }, | |
| enumerable: false | |
| }, | |
| hexToAnsi256: { | |
| value: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)), | |
| enumerable: false | |
| }, | |
| ansi256ToAnsi: { | |
| value: code => { | |
| if (code < 8) { | |
| return 30 + code; | |
| } | |
| if (code < 16) { | |
| return 90 + (code - 8); | |
| } | |
| let red; | |
| let green; | |
| let blue; | |
| if (code >= 232) { | |
| red = (((code - 232) * 10) + 8) / 255; | |
| green = red; | |
| blue = red; | |
| } else { | |
| code -= 16; | |
| const remainder = code % 36; | |
| red = Math.floor(code / 36) / 5; | |
| green = Math.floor(remainder / 6) / 5; | |
| blue = (remainder % 6) / 5; | |
| } | |
| const value = Math.max(red, green, blue) * 2; | |
| if (value === 0) { | |
| return 30; | |
| } | |
| let result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red)); | |
| if (value === 2) { | |
| result += 60; | |
| } | |
| return result; | |
| }, | |
| enumerable: false | |
| }, | |
| rgbToAnsi: { | |
| value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)), | |
| enumerable: false | |
| }, | |
| hexToAnsi: { | |
| value: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)), | |
| enumerable: false | |
| } | |
| }); | |
| return styles; | |
| } | |
| const ansiStyles = assembleStyles(); | |
| const ESCAPES = new Set([ | |
| '\u001B', | |
| '\u009B', | |
| ]); | |
| const END_CODE = 39; | |
| const ANSI_ESCAPE_BELL = '\u0007'; | |
| const ANSI_CSI = '['; | |
| const ANSI_OSC = ']'; | |
| const ANSI_SGR_TERMINATOR = 'm'; | |
| const ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`; | |
| const wrapAnsiCode = code => `${ESCAPES.values().next().value}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`; | |
| const wrapAnsiHyperlink = uri => `${ESCAPES.values().next().value}${ANSI_ESCAPE_LINK}${uri}${ANSI_ESCAPE_BELL}`; | |
| // Calculate the length of words split on ' ', ignoring | |
| // the extra characters added by ansi escape codes | |
| const wordLengths = string => string.split(' ').map(character => stringWidth(character)); | |
| // Wrap a long word across multiple rows | |
| // Ansi escape codes do not count towards length | |
| const wrapWord = (rows, word, columns) => { | |
| const characters = [...word]; | |
| let isInsideEscape = false; | |
| let isInsideLinkEscape = false; | |
| let visible = stringWidth(stripAnsi(rows[rows.length - 1])); | |
| for (const [index, character] of characters.entries()) { | |
| const characterLength = stringWidth(character); | |
| if (visible + characterLength <= columns) { | |
| rows[rows.length - 1] += character; | |
| } else { | |
| rows.push(character); | |
| visible = 0; | |
| } | |
| if (ESCAPES.has(character)) { | |
| isInsideEscape = true; | |
| isInsideLinkEscape = characters.slice(index + 1).join('').startsWith(ANSI_ESCAPE_LINK); | |
| } | |
| if (isInsideEscape) { | |
| if (isInsideLinkEscape) { | |
| if (character === ANSI_ESCAPE_BELL) { | |
| isInsideEscape = false; | |
| isInsideLinkEscape = false; | |
| } | |
| } else if (character === ANSI_SGR_TERMINATOR) { | |
| isInsideEscape = false; | |
| } | |
| continue; | |
| } | |
| visible += characterLength; | |
| if (visible === columns && index < characters.length - 1) { | |
| rows.push(''); | |
| visible = 0; | |
| } | |
| } | |
| // It's possible that the last row we copy over is only | |
| // ansi escape characters, handle this edge-case | |
| if (!visible && rows[rows.length - 1].length > 0 && rows.length > 1) { | |
| rows[rows.length - 2] += rows.pop(); | |
| } | |
| }; | |
| // Trims spaces from a string ignoring invisible sequences | |
| const stringVisibleTrimSpacesRight = string => { | |
| const words = string.split(' '); | |
| let last = words.length; | |
| while (last > 0) { | |
| if (stringWidth(words[last - 1]) > 0) { | |
| break; | |
| } | |
| last--; | |
| } | |
| if (last === words.length) { | |
| return string; | |
| } | |
| return words.slice(0, last).join(' ') + words.slice(last).join(''); | |
| }; | |
| // The wrap-ansi module can be invoked in either 'hard' or 'soft' wrap mode | |
| // | |
| // 'hard' will never allow a string to take up more than columns characters | |
| // | |
| // 'soft' allows long words to expand past the column length | |
| const exec = (string, columns, options = {}) => { | |
| if (options.trim !== false && string.trim() === '') { | |
| return ''; | |
| } | |
| let returnValue = ''; | |
| let escapeCode; | |
| let escapeUrl; | |
| const lengths = wordLengths(string); | |
| let rows = ['']; | |
| for (const [index, word] of string.split(' ').entries()) { | |
| if (options.trim !== false) { | |
| rows[rows.length - 1] = rows[rows.length - 1].trimStart(); | |
| } | |
| let rowLength = stringWidth(rows[rows.length - 1]); | |
| if (index !== 0) { | |
| if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) { | |
| // If we start with a new word but the current row length equals the length of the columns, add a new row | |
| rows.push(''); | |
| rowLength = 0; | |
| } | |
| if (rowLength > 0 || options.trim === false) { | |
| rows[rows.length - 1] += ' '; | |
| rowLength++; | |
| } | |
| } | |
| // In 'hard' wrap mode, the length of a line is never allowed to extend past 'columns' | |
| if (options.hard && lengths[index] > columns) { | |
| const remainingColumns = (columns - rowLength); | |
| const breaksStartingThisLine = 1 + Math.floor((lengths[index] - remainingColumns - 1) / columns); | |
| const breaksStartingNextLine = Math.floor((lengths[index] - 1) / columns); | |
| if (breaksStartingNextLine < breaksStartingThisLine) { | |
| rows.push(''); | |
| } | |
| wrapWord(rows, word, columns); | |
| continue; | |
| } | |
| if (rowLength + lengths[index] > columns && rowLength > 0 && lengths[index] > 0) { | |
| if (options.wordWrap === false && rowLength < columns) { | |
| wrapWord(rows, word, columns); | |
| continue; | |
| } | |
| rows.push(''); | |
| } | |
| if (rowLength + lengths[index] > columns && options.wordWrap === false) { | |
| wrapWord(rows, word, columns); | |
| continue; | |
| } | |
| rows[rows.length - 1] += word; | |
| } | |
| if (options.trim !== false) { | |
| rows = rows.map(row => stringVisibleTrimSpacesRight(row)); | |
| } | |
| const pre = [...rows.join('\n')]; | |
| for (const [index, character] of pre.entries()) { | |
| returnValue += character; | |
| if (ESCAPES.has(character)) { | |
| const {groups} = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`).exec(pre.slice(index).join('')) || {groups: {}}; | |
| if (groups.code !== undefined) { | |
| const code = Number.parseFloat(groups.code); | |
| escapeCode = code === END_CODE ? undefined : code; | |
| } else if (groups.uri !== undefined) { | |
| escapeUrl = groups.uri.length === 0 ? undefined : groups.uri; | |
| } | |
| } | |
| const code = ansiStyles.codes.get(Number(escapeCode)); | |
| if (pre[index + 1] === '\n') { | |
| if (escapeUrl) { | |
| returnValue += wrapAnsiHyperlink(''); | |
| } | |
| if (escapeCode && code) { | |
| returnValue += wrapAnsiCode(code); | |
| } | |
| } else if (character === '\n') { | |
| if (escapeCode && code) { | |
| returnValue += wrapAnsiCode(escapeCode); | |
| } | |
| if (escapeUrl) { | |
| returnValue += wrapAnsiHyperlink(escapeUrl); | |
| } | |
| } | |
| } | |
| return returnValue; | |
| }; | |
| // For each newline, invoke the method separately | |
| function wrapAnsi(string, columns, options) { | |
| return String(string) | |
| .normalize() | |
| .replace(/\r\n/g, '\n') | |
| .split('\n') | |
| .map(line => exec(line, columns, options)) | |
| .join('\n'); | |
| } | |
| const originalWrite = Symbol("webpackbarWrite"); | |
| class LogUpdate { | |
| constructor() { | |
| this.prevLineCount = 0; | |
| this.listening = false; | |
| this.extraLines = ""; | |
| this._onData = this._onData.bind(this); | |
| this._streams = [process.stdout, process.stderr]; | |
| } | |
| render(lines) { | |
| this.listen(); | |
| const wrappedLines = wrapAnsi(lines, this.columns, { | |
| trim: false, | |
| hard: true, | |
| wordWrap: false | |
| }); | |
| const data = ansiEscapes.eraseLines(this.prevLineCount) + wrappedLines + "\n" + this.extraLines; | |
| this.write(data); | |
| const _lines = data.split("\n"); | |
| this.prevLineCount = _lines.length; | |
| } | |
| get columns() { | |
| return (process.stderr.columns || 80) - 2; | |
| } | |
| write(data) { | |
| const stream = process.stderr; | |
| if (stream.write[originalWrite]) { | |
| stream.write[originalWrite].call(stream, data, "utf-8"); | |
| } else { | |
| stream.write(data, "utf-8"); | |
| } | |
| } | |
| clear() { | |
| this.done(); | |
| this.write(ansiEscapes.eraseLines(this.prevLineCount)); | |
| } | |
| done() { | |
| this.stopListen(); | |
| this.prevLineCount = 0; | |
| this.extraLines = ""; | |
| } | |
| _onData(data) { | |
| const str = String(data); | |
| const lines = str.split("\n").length - 1; | |
| if (lines > 0) { | |
| this.prevLineCount += lines; | |
| this.extraLines += data; | |
| } | |
| } | |
| listen() { | |
| if (this.listening) { | |
| return; | |
| } | |
| for (const stream of this._streams) { | |
| if (stream.write[originalWrite]) { | |
| continue; | |
| } | |
| const write = (data, ...args) => { | |
| if (!stream.write[originalWrite]) { | |
| return stream.write(data, ...args); | |
| } | |
| this._onData(data); | |
| return stream.write[originalWrite].call(stream, data, ...args); | |
| }; | |
| write[originalWrite] = stream.write; | |
| stream.write = write; | |
| } | |
| this.listening = true; | |
| } | |
| stopListen() { | |
| for (const stream of this._streams) { | |
| if (stream.write[originalWrite]) { | |
| stream.write = stream.write[originalWrite]; | |
| } | |
| } | |
| this.listening = false; | |
| } | |
| } | |
| const logUpdate = new LogUpdate(); | |
| let lastRender = Date.now(); | |
| class FancyReporter { | |
| allDone() { | |
| logUpdate.done(); | |
| } | |
| done(context) { | |
| this._renderStates(context.statesArray); | |
| if (context.hasErrors) { | |
| logUpdate.done(); | |
| } | |
| } | |
| progress(context) { | |
| if (Date.now() - lastRender > 50) { | |
| this._renderStates(context.statesArray); | |
| } | |
| } | |
| _renderStates(statesArray) { | |
| lastRender = Date.now(); | |
| const renderedStates = statesArray.map((c) => this._renderState(c)).join("\n\n"); | |
| logUpdate.render("\n" + renderedStates + "\n"); | |
| } | |
| _renderState(state) { | |
| const color = colorize(state.color); | |
| let line1; | |
| let line2; | |
| if (state.progress >= 0 && state.progress < 100) { | |
| line1 = [ | |
| color(BULLET), | |
| color(state.name), | |
| renderBar(state.progress, state.color), | |
| state.message, | |
| `(${state.progress || 0}%)`, | |
| chalk.grey(state.details[0] || ""), | |
| chalk.grey(state.details[1] || "") | |
| ].join(" "); | |
| line2 = state.request ? " " + chalk.grey(ellipsisLeft(formatRequest(state.request), logUpdate.columns)) : ""; | |
| } else { | |
| let icon = " "; | |
| if (state.hasErrors) { | |
| icon = CROSS; | |
| } else if (state.progress === 100) { | |
| icon = TICK; | |
| } else if (state.progress === -1) { | |
| icon = CIRCLE_OPEN; | |
| } | |
| line1 = color(`${icon} ${state.name}`); | |
| line2 = chalk.grey(" " + state.message); | |
| } | |
| return line1 + "\n" + line2; | |
| } | |
| } | |
| class SimpleReporter { | |
| start(context) { | |
| consola.info(`Compiling ${context.state.name}`); | |
| } | |
| change(context, { shortPath }) { | |
| consola.debug(`${shortPath} changed.`, `Rebuilding ${context.state.name}`); | |
| } | |
| done(context) { | |
| const { hasError, message, name } = context.state; | |
| consola[hasError ? "error" : "success"](`${name}: ${message}`); | |
| } | |
| } | |
| const DB = { | |
| loader: { | |
| get: (loader) => startCase(loader) | |
| }, | |
| ext: { | |
| get: (ext) => `${ext} files`, | |
| vue: "Vue Single File components", | |
| js: "JavaScript files", | |
| sass: "SASS files", | |
| scss: "SASS files", | |
| unknown: "Unknown files" | |
| } | |
| }; | |
| function getDescription(category, keyword) { | |
| if (!DB[category]) { | |
| return startCase(keyword); | |
| } | |
| if (DB[category][keyword]) { | |
| return DB[category][keyword]; | |
| } | |
| if (DB[category].get) { | |
| return DB[category].get(keyword); | |
| } | |
| return "-"; | |
| } | |
| function formatStats(allStats) { | |
| const lines = []; | |
| Object.keys(allStats).forEach((category) => { | |
| const stats = allStats[category]; | |
| lines.push(`> Stats by ${chalk.bold(startCase(category))}`); | |
| let totalRequests = 0; | |
| const totalTime = [0, 0]; | |
| const data = [ | |
| [startCase(category), "Requests", "Time", "Time/Request", "Description"] | |
| ]; | |
| Object.keys(stats).forEach((item) => { | |
| const stat = stats[item]; | |
| totalRequests += stat.count || 0; | |
| const description = getDescription(category, item); | |
| totalTime[0] += stat.time[0]; | |
| totalTime[1] += stat.time[1]; | |
| const avgTime = [stat.time[0] / stat.count, stat.time[1] / stat.count]; | |
| data.push([ | |
| item, | |
| stat.count || "-", | |
| prettyTime(stat.time), | |
| prettyTime(avgTime), | |
| description | |
| ]); | |
| }); | |
| data.push(["Total", totalRequests, prettyTime(totalTime), "", ""]); | |
| lines.push(createTable(data)); | |
| }); | |
| return `${lines.join("\n\n")} | |
| `; | |
| } | |
| class Profiler { | |
| constructor() { | |
| this.requests = []; | |
| } | |
| onRequest(request) { | |
| if (!request) { | |
| return; | |
| } | |
| if (this.requests.length) { | |
| const lastReq = this.requests[this.requests.length - 1]; | |
| if (lastReq.start) { | |
| lastReq.time = process.hrtime(lastReq.start); | |
| delete lastReq.start; | |
| } | |
| } | |
| if (!request.file || !request.loaders.length) { | |
| return; | |
| } | |
| this.requests.push({ | |
| request, | |
| start: process.hrtime() | |
| }); | |
| } | |
| getStats() { | |
| const loaderStats = {}; | |
| const extStats = {}; | |
| const getStat = (stats, name) => { | |
| if (!stats[name]) { | |
| stats[name] = { | |
| count: 0, | |
| time: [0, 0] | |
| }; | |
| } | |
| return stats[name]; | |
| }; | |
| const addToStat = (stats, name, count, time) => { | |
| const stat = getStat(stats, name); | |
| stat.count += count; | |
| stat.time[0] += time[0]; | |
| stat.time[1] += time[1]; | |
| }; | |
| this.requests.forEach(({ request, time = [0, 0] }) => { | |
| request.loaders.forEach((loader) => { | |
| addToStat(loaderStats, loader, 1, time); | |
| }); | |
| const ext = request.file && path.extname(request.file).substr(1); | |
| addToStat(extStats, ext && ext.length ? ext : "unknown", 1, time); | |
| }); | |
| return { | |
| ext: extStats, | |
| loader: loaderStats | |
| }; | |
| } | |
| getFormattedStats() { | |
| return formatStats(this.getStats()); | |
| } | |
| } | |
| class ProfileReporter { | |
| progress(context) { | |
| if (!context.state.profiler) { | |
| context.state.profiler = new Profiler(); | |
| } | |
| context.state.profiler.onRequest(context.state.request); | |
| } | |
| done(context) { | |
| if (context.state.profiler) { | |
| context.state.profile = context.state.profiler.getFormattedStats(); | |
| delete context.state.profiler; | |
| } | |
| } | |
| allDone(context) { | |
| let str = ""; | |
| for (const state of context.statesArray) { | |
| const color = colorize(state.color); | |
| if (state.profile) { | |
| str += color(` | |
| Profile results for ${chalk.bold(state.name)} | |
| `) + ` | |
| ${state.profile} | |
| `; | |
| delete state.profile; | |
| } | |
| } | |
| process.stderr.write(str); | |
| } | |
| } | |
| class StatsReporter { | |
| constructor(options) { | |
| this.options = Object.assign({ | |
| chunks: false, | |
| children: false, | |
| modules: false, | |
| colors: true, | |
| warnings: true, | |
| errors: true | |
| }, options); | |
| } | |
| done(context, { stats }) { | |
| const str = stats.toString(this.options); | |
| if (context.hasErrors) { | |
| process.stderr.write("\n" + str + "\n"); | |
| } else { | |
| context.state.statsString = str; | |
| } | |
| } | |
| allDone(context) { | |
| let str = ""; | |
| for (const state of context.statesArray) { | |
| if (state.statsString) { | |
| str += "\n" + state.statsString + "\n"; | |
| delete state.statsString; | |
| } | |
| } | |
| process.stderr.write(str); | |
| } | |
| } | |
| const reporters = { | |
| __proto__: null, | |
| fancy: FancyReporter, | |
| basic: SimpleReporter, | |
| profile: ProfileReporter, | |
| stats: StatsReporter | |
| }; | |
| const DEFAULTS = { | |
| name: "webpack", | |
| color: "green", | |
| reporters: isMinimal ? ["basic"] : ["fancy"], | |
| reporter: null | |
| }; | |
| const DEFAULT_STATE = { | |
| start: null, | |
| progress: -1, | |
| done: false, | |
| message: "", | |
| details: [], | |
| request: null, | |
| hasErrors: false | |
| }; | |
| const globalStates = {}; | |
| class WebpackBarPlugin extends Webpack.ProgressPlugin { | |
| constructor(options) { | |
| super({ activeModules: true }); | |
| this.options = Object.assign({}, DEFAULTS, options); | |
| this.handler = (percent, message, ...details) => { | |
| this.updateProgress(percent, message, details); | |
| }; | |
| const _reporters = Array.from(this.options.reporters || []).concat(this.options.reporter).filter(Boolean).map((reporter) => { | |
| if (Array.isArray(reporter)) { | |
| return { reporter: reporter[0], options: reporter[1] }; | |
| } | |
| if (typeof reporter === "string") { | |
| return { reporter }; | |
| } | |
| return { reporter }; | |
| }); | |
| this.reporters = _reporters.map(({ reporter, options: options2 = {} }) => { | |
| if (typeof reporter === "string") { | |
| if (this.options[reporter] === false) { | |
| return void 0; | |
| } | |
| options2 = { ...this.options[reporter], ...options2 }; | |
| reporter = reporters[reporter] || require(reporter); | |
| } | |
| if (typeof reporter === "function") { | |
| try { | |
| reporter = new reporter(options2); | |
| } catch (err) { | |
| reporter = reporter(options2); | |
| } | |
| } | |
| return reporter; | |
| }).filter(Boolean); | |
| } | |
| callReporters(fn, payload = {}) { | |
| for (const reporter of this.reporters) { | |
| if (typeof reporter[fn] === "function") { | |
| try { | |
| reporter[fn](this, payload); | |
| } catch (e) { | |
| process.stdout.write(e.stack + "\n"); | |
| } | |
| } | |
| } | |
| } | |
| get hasRunning() { | |
| return objectValues(this.states).some((state) => !state.done); | |
| } | |
| get hasErrors() { | |
| return objectValues(this.states).some((state) => state.hasErrors); | |
| } | |
| get statesArray() { | |
| return objectValues(this.states).sort((s1, s2) => s1.name.localeCompare(s2.name)); | |
| } | |
| get states() { | |
| return globalStates; | |
| } | |
| get state() { | |
| return globalStates[this.options.name]; | |
| } | |
| _ensureState() { | |
| if (!this.states[this.options.name]) { | |
| this.states[this.options.name] = { | |
| ...DEFAULT_STATE, | |
| color: this.options.color, | |
| name: startCase(this.options.name) | |
| }; | |
| } | |
| } | |
| apply(compiler) { | |
| if (compiler.webpackbar) { | |
| return; | |
| } | |
| compiler.webpackbar = this; | |
| super.apply(compiler); | |
| hook(compiler, "afterPlugins", () => { | |
| this._ensureState(); | |
| }); | |
| hook(compiler, "compile", () => { | |
| this._ensureState(); | |
| Object.assign(this.state, { | |
| ...DEFAULT_STATE, | |
| start: process.hrtime() | |
| }); | |
| this.callReporters("start"); | |
| }); | |
| hook(compiler, "invalid", (fileName, changeTime) => { | |
| this._ensureState(); | |
| this.callReporters("change", { | |
| path: fileName, | |
| shortPath: shortenPath(fileName), | |
| time: changeTime | |
| }); | |
| }); | |
| hook(compiler, "done", (stats) => { | |
| this._ensureState(); | |
| if (this.state.done) { | |
| return; | |
| } | |
| const hasErrors = stats.hasErrors(); | |
| const status = hasErrors ? "with some errors" : "successfully"; | |
| const time = this.state.start ? " in " + prettyTime(process.hrtime(this.state.start), 2) : ""; | |
| Object.assign(this.state, { | |
| ...DEFAULT_STATE, | |
| progress: 100, | |
| done: true, | |
| message: `Compiled ${status}${time}`, | |
| hasErrors | |
| }); | |
| this.callReporters("progress"); | |
| this.callReporters("done", { stats }); | |
| if (!this.hasRunning) { | |
| this.callReporters("beforeAllDone"); | |
| this.callReporters("allDone"); | |
| this.callReporters("afterAllDone"); | |
| } | |
| }); | |
| } | |
| updateProgress(percent = 0, message = "", details = []) { | |
| const progress = Math.floor(percent * 100); | |
| const activeModule = details.pop(); | |
| Object.assign(this.state, { | |
| progress, | |
| message: message || "", | |
| details, | |
| request: parseRequest(activeModule) | |
| }); | |
| this.callReporters("progress"); | |
| } | |
| } | |
| export { WebpackBarPlugin as default }; | |
Xet Storage Details
- Size:
- 62.2 kB
- Xet hash:
- 6b301363efc0068ce0d7fc66611886c83f96c0c3d558829c6be556a7356b3185
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.