webpackbar
Version:
Elegant ProgressBar and Profiler for Webpack and Rspack
1,519 lines (1,398 loc) • 70.7 kB
JavaScript
import { isMinimal } from 'std-env';
import prettyTime from 'pretty-time';
import path, { sep, delimiter } from 'node:path';
import c, { blue, grey, bold } from 'ansis';
import { consola as consola$1 } from 'consola';
import process$1 from 'node:process';
function first(arr) {
return arr[0];
}
function last(arr) {
return arr.length > 0 ? arr[arr.length - 1] : null;
}
function startCase(str) {
return str[0].toUpperCase() + str.slice(1);
}
function firstMatch(regex, str) {
const m = regex.exec(str);
return m ? m[0] : null;
}
function hasValue(s) {
return s && s.length > 0;
}
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]);
}
// To do: next major: remove.
/**
* @typedef {Options} MarkdownTableOptions
* Configuration.
*/
/**
* @typedef Options
* Configuration.
* @property {boolean | null | undefined} [alignDelimiters=true]
* Whether to align the delimiters (default: `true`);
* they are aligned by default:
*
* ```markdown
* | Alpha | B |
* | ----- | ----- |
* | C | Delta |
* ```
*
* Pass `false` to make them staggered:
*
* ```markdown
* | Alpha | B |
* | - | - |
* | C | Delta |
* ```
* @property {ReadonlyArray<string | null | undefined> | string | null | undefined} [align]
* How to align columns (default: `''`);
* one style for all columns or styles for their respective columns;
* each style is either `'l'` (left), `'r'` (right), or `'c'` (center);
* other values are treated as `''`, which doesn’t place the colon in the
* alignment row but does align left;
* *only the lowercased first character is used, so `Right` is fine.*
* @property {boolean | null | undefined} [delimiterEnd=true]
* Whether to end each row with the delimiter (default: `true`).
*
* > 👉 **Note**: please don’t use this: it could create fragile structures
* > that aren’t understandable to some markdown parsers.
*
* When `true`, there are ending delimiters:
*
* ```markdown
* | Alpha | B |
* | ----- | ----- |
* | C | Delta |
* ```
*
* When `false`, there are no ending delimiters:
*
* ```markdown
* | Alpha | B
* | ----- | -----
* | C | Delta
* ```
* @property {boolean | null | undefined} [delimiterStart=true]
* Whether to begin each row with the delimiter (default: `true`).
*
* > 👉 **Note**: please don’t use this: it could create fragile structures
* > that aren’t understandable to some markdown parsers.
*
* When `true`, there are starting delimiters:
*
* ```markdown
* | Alpha | B |
* | ----- | ----- |
* | C | Delta |
* ```
*
* When `false`, there are no starting delimiters:
*
* ```markdown
* Alpha | B |
* ----- | ----- |
* C | Delta |
* ```
* @property {boolean | null | undefined} [padding=true]
* Whether to add a space of padding between delimiters and cells
* (default: `true`).
*
* When `true`, there is padding:
*
* ```markdown
* | Alpha | B |
* | ----- | ----- |
* | C | Delta |
* ```
*
* When `false`, there is no padding:
*
* ```markdown
* |Alpha|B |
* |-----|-----|
* |C |Delta|
* ```
* @property {((value: string) => number) | null | undefined} [stringLength]
* Function to detect the length of table cell content (optional);
* this is used when aligning the delimiters (`|`) between table cells;
* full-width characters and emoji mess up delimiter alignment when viewing
* the markdown source;
* to fix this, you can pass this function,
* which receives the cell content and returns its “visible” size;
* note that what is and isn’t visible depends on where the text is displayed.
*
* Without such a function, the following:
*
* ```js
* markdownTable([
* ['Alpha', 'Bravo'],
* ['中文', 'Charlie'],
* ['👩❤️👩', 'Delta']
* ])
* ```
*
* Yields:
*
* ```markdown
* | Alpha | Bravo |
* | - | - |
* | 中文 | Charlie |
* | 👩❤️👩 | Delta |
* ```
*
* With [`string-width`](https://github.com/sindresorhus/string-width):
*
* ```js
* import stringWidth from 'string-width'
*
* markdownTable(
* [
* ['Alpha', 'Bravo'],
* ['中文', 'Charlie'],
* ['👩❤️👩', 'Delta']
* ],
* {stringLength: stringWidth}
* )
* ```
*
* Yields:
*
* ```markdown
* | Alpha | Bravo |
* | ----- | ------- |
* | 中文 | Charlie |
* | 👩❤️👩 | Delta |
* ```
*/
/**
* @param {string} value
* Cell value.
* @returns {number}
* Cell size.
*/
function defaultStringLength(value) {
return value.length
}
/**
* Generate a markdown
* ([GFM](https://docs.github.com/en/github/writing-on-github/working-with-advanced-formatting/organizing-information-with-tables))
* table.
*
* @param {ReadonlyArray<ReadonlyArray<string | null | undefined>>} table
* Table data (matrix of strings).
* @param {Readonly<Options> | null | undefined} [options]
* Configuration (optional).
* @returns {string}
* Result.
*/
function markdownTable(table, options) {
const settings = options || {};
// To do: next major: change to spread.
const align = (settings.align || []).concat();
const stringLength = settings.stringLength || defaultStringLength;
/** @type {Array<number>} Character codes as symbols for alignment per column. */
const alignments = [];
/** @type {Array<Array<string>>} Cells per row. */
const cellMatrix = [];
/** @type {Array<Array<number>>} Sizes of each cell per row. */
const sizeMatrix = [];
/** @type {Array<number>} */
const longestCellByColumn = [];
let mostCellsPerRow = 0;
let rowIndex = -1;
// 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) {
/** @type {Array<string>} */
const row = [];
/** @type {Array<number>} */
const sizes = [];
let columnIndex = -1;
if (table[rowIndex].length > mostCellsPerRow) {
mostCellsPerRow = table[rowIndex].length;
}
while (++columnIndex < table[rowIndex].length) {
const cell = serialize(table[rowIndex][columnIndex]);
if (settings.alignDelimiters !== false) {
const 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.
let columnIndex = -1;
if (typeof align === 'object' && 'length' in align) {
while (++columnIndex < mostCellsPerRow) {
alignments[columnIndex] = toAlignment(align[columnIndex]);
}
} else {
const code = toAlignment(align);
while (++columnIndex < mostCellsPerRow) {
alignments[columnIndex] = code;
}
}
// Inject the alignment row.
columnIndex = -1;
/** @type {Array<string>} */
const row = [];
/** @type {Array<number>} */
const sizes = [];
while (++columnIndex < mostCellsPerRow) {
const code = alignments[columnIndex];
let before = '';
let 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.
let size =
settings.alignDelimiters === false
? 1
: Math.max(
1,
longestCellByColumn[columnIndex] - before.length - after.length
);
const 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 {Array<string>} */
const lines = [];
while (++rowIndex < cellMatrix.length) {
const row = cellMatrix[rowIndex];
const sizes = sizeMatrix[rowIndex];
columnIndex = -1;
/** @type {Array<string>} */
const line = [];
while (++columnIndex < mostCellsPerRow) {
const cell = row[columnIndex] || '';
let before = '';
let after = '';
if (settings.alignDelimiters !== false) {
const size =
longestCellByColumn[columnIndex] - (sizes[columnIndex] || 0);
const 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]
* Value to serialize.
* @returns {string}
* Result.
*/
function serialize(value) {
return value === null || value === undefined ? '' : String(value)
}
/**
* @param {string | null | undefined} value
* Value.
* @returns {number}
* Alignment.
*/
function toAlignment(value) {
const code = typeof value === 'string' ? value.codePointAt(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() {
const {env} = process$1;
const {TERM, TERM_PROGRAM} = env;
if (process$1.platform !== 'win32') {
return TERM !== 'linux'; // Linux console (kernel)
}
return Boolean(env.WT_SESSION) // Windows Terminal
|| Boolean(env.TERMINUS_SUBLIME) // Terminus (<0.2.27)
|| env.ConEmuTask === '{cmd::Cmder}' // ConEmu and cmder
|| TERM_PROGRAM === 'Terminus-Sublime'
|| TERM_PROGRAM === 'vscode'
|| TERM === 'xterm-256color'
|| TERM === 'alacritty'
|| TERM === 'rxvt-unicode'
|| TERM === 'rxvt-unicode-256color'
|| env.TERMINAL_EMULATOR === 'JetBrains-JediTerm';
}
const common = {
circleQuestionMark: '(?)',
questionMarkPrefix: '(?)',
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 specialMainSymbols = {
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 specialFallbackSymbols = {
tick: '√',
info: 'i',
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: '1/7',
oneNinth: '1/9',
oneTenth: '1/10',
};
const mainSymbols = {...common, ...specialMainSymbols};
const fallbackSymbols = {...common, ...specialFallbackSymbols};
const shouldUseMain = isUnicodeSupported();
const figures = shouldUseMain ? mainSymbols : fallbackSymbols;
const figures$1 = figures;
const { bullet, tick, cross, pointerSmall, radioOff } = figures$1;
const nodeModules = `${delimiter}node_modules${delimiter}`;
const BAR_LENGTH = 25;
const BLOCK_CHAR = "\u2588";
const BLOCK_CHAR2 = "\u2588";
const NEXT = " " + blue(pointerSmall) + " ";
const BULLET = bullet;
const TICK = tick;
const CROSS = cross;
const CIRCLE_OPEN = radioOff;
const consola = consola$1.withTag("webpackbar");
const colorize = (color) => {
return color[0] === "#" ? c.hex(color) : c[color] || c.reset;
};
const renderBar = (progress, color) => {
const w = progress * (BAR_LENGTH / 100);
const bg = c.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.slice(str.length - n - 1)}`;
}
function eraseLines(count) {
let clear = "";
for (let i = 0; i < count; i++) {
clear += `\x1B[2K` + (i < count - 1 ? `\x1B[1A` : "");
}
if (count)
clear += `\x1B[G`;
return clear;
}
const parseRequest = (requestStr) => {
const parts = (requestStr || "").split("!");
const file = path.relative(
process.cwd(),
removeAfter("?", removeBefore(nodeModules, parts.pop()))
);
const loaders = parts.map((part) => firstMatch(/[\d@a-z-]+-loader/, part)).filter((v) => hasValue(v));
return {
file: hasValue(file) ? file : null,
loaders
};
};
const formatRequest = (request) => {
const loaders = request.loaders.join(NEXT);
if (loaders.length === 0) {
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);
}
}
function ansiRegex({onlyFirst = false} = {}) {
// Valid string terminator sequences are BEL, ESC\, and 0x9c
const ST = '(?:\\u0007|\\u001B\\u005C|\\u009C)';
const pattern = [
`[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?${ST})`,
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))',
].join('|');
return new RegExp(pattern, onlyFirst ? undefined : 'g');
}
const regex = ansiRegex();
function stripAnsi(string) {
if (typeof string !== 'string') {
throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
}
// Even though the regex is global, we don't need to reset the `.lastIndex`
// because unlike `.exec()` and `.test()`, `.replace()` does it automatically
// and doing it manually has a performance penalty.
return string.replace(regex, '');
}
// Generated code.
function isAmbiguous(x) {
return x === 0xA1
|| x === 0xA4
|| x === 0xA7
|| x === 0xA8
|| x === 0xAA
|| x === 0xAD
|| x === 0xAE
|| x >= 0xB0 && x <= 0xB4
|| x >= 0xB6 && x <= 0xBA
|| x >= 0xBC && x <= 0xBF
|| x === 0xC6
|| x === 0xD0
|| x === 0xD7
|| x === 0xD8
|| x >= 0xDE && x <= 0xE1
|| x === 0xE6
|| x >= 0xE8 && x <= 0xEA
|| x === 0xEC
|| x === 0xED
|| x === 0xF0
|| x === 0xF2
|| x === 0xF3
|| x >= 0xF7 && x <= 0xFA
|| x === 0xFC
|| x === 0xFE
|| x === 0x101
|| x === 0x111
|| x === 0x113
|| x === 0x11B
|| x === 0x126
|| x === 0x127
|| x === 0x12B
|| x >= 0x131 && x <= 0x133
|| x === 0x138
|| x >= 0x13F && x <= 0x142
|| x === 0x144
|| x >= 0x148 && x <= 0x14B
|| x === 0x14D
|| x === 0x152
|| x === 0x153
|| x === 0x166
|| x === 0x167
|| x === 0x16B
|| x === 0x1CE
|| x === 0x1D0
|| x === 0x1D2
|| x === 0x1D4
|| x === 0x1D6
|| x === 0x1D8
|| x === 0x1DA
|| x === 0x1DC
|| x === 0x251
|| x === 0x261
|| x === 0x2C4
|| x === 0x2C7
|| x >= 0x2C9 && x <= 0x2CB
|| x === 0x2CD
|| x === 0x2D0
|| x >= 0x2D8 && x <= 0x2DB
|| x === 0x2DD
|| x === 0x2DF
|| x >= 0x300 && x <= 0x36F
|| x >= 0x391 && x <= 0x3A1
|| x >= 0x3A3 && x <= 0x3A9
|| x >= 0x3B1 && x <= 0x3C1
|| x >= 0x3C3 && x <= 0x3C9
|| x === 0x401
|| x >= 0x410 && x <= 0x44F
|| x === 0x451
|| x === 0x2010
|| x >= 0x2013 && x <= 0x2016
|| x === 0x2018
|| x === 0x2019
|| x === 0x201C
|| x === 0x201D
|| x >= 0x2020 && x <= 0x2022
|| x >= 0x2024 && x <= 0x2027
|| x === 0x2030
|| x === 0x2032
|| x === 0x2033
|| x === 0x2035
|| x === 0x203B
|| x === 0x203E
|| x === 0x2074
|| x === 0x207F
|| x >= 0x2081 && x <= 0x2084
|| x === 0x20AC
|| x === 0x2103
|| x === 0x2105
|| x === 0x2109
|| x === 0x2113
|| x === 0x2116
|| x === 0x2121
|| x === 0x2122
|| x === 0x2126
|| x === 0x212B
|| x === 0x2153
|| x === 0x2154
|| x >= 0x215B && x <= 0x215E
|| x >= 0x2160 && x <= 0x216B
|| x >= 0x2170 && x <= 0x2179
|| x === 0x2189
|| x >= 0x2190 && x <= 0x2199
|| x === 0x21B8
|| x === 0x21B9
|| x === 0x21D2
|| x === 0x21D4
|| x === 0x21E7
|| x === 0x2200
|| x === 0x2202
|| x === 0x2203
|| x === 0x2207
|| x === 0x2208
|| x === 0x220B
|| x === 0x220F
|| x === 0x2211
|| x === 0x2215
|| x === 0x221A
|| x >= 0x221D && x <= 0x2220
|| x === 0x2223
|| x === 0x2225
|| x >= 0x2227 && x <= 0x222C
|| x === 0x222E
|| x >= 0x2234 && x <= 0x2237
|| x === 0x223C
|| x === 0x223D
|| x === 0x2248
|| x === 0x224C
|| x === 0x2252
|| x === 0x2260
|| x === 0x2261
|| x >= 0x2264 && x <= 0x2267
|| x === 0x226A
|| x === 0x226B
|| x === 0x226E
|| x === 0x226F
|| x === 0x2282
|| x === 0x2283
|| x === 0x2286
|| x === 0x2287
|| x === 0x2295
|| x === 0x2299
|| x === 0x22A5
|| x === 0x22BF
|| x === 0x2312
|| x >= 0x2460 && x <= 0x24E9
|| x >= 0x24EB && x <= 0x254B
|| x >= 0x2550 && x <= 0x2573
|| x >= 0x2580 && x <= 0x258F
|| x >= 0x2592 && x <= 0x2595
|| x === 0x25A0
|| x === 0x25A1
|| x >= 0x25A3 && x <= 0x25A9
|| x === 0x25B2
|| x === 0x25B3
|| x === 0x25B6
|| x === 0x25B7
|| x === 0x25BC
|| x === 0x25BD
|| x === 0x25C0
|| x === 0x25C1
|| x >= 0x25C6 && x <= 0x25C8
|| x === 0x25CB
|| x >= 0x25CE && x <= 0x25D1
|| x >= 0x25E2 && x <= 0x25E5
|| x === 0x25EF
|| x === 0x2605
|| x === 0x2606
|| x === 0x2609
|| x === 0x260E
|| x === 0x260F
|| x === 0x261C
|| x === 0x261E
|| x === 0x2640
|| x === 0x2642
|| x === 0x2660
|| x === 0x2661
|| x >= 0x2663 && x <= 0x2665
|| x >= 0x2667 && x <= 0x266A
|| x === 0x266C
|| x === 0x266D
|| x === 0x266F
|| x === 0x269E
|| x === 0x269F
|| x === 0x26BF
|| x >= 0x26C6 && x <= 0x26CD
|| x >= 0x26CF && x <= 0x26D3
|| x >= 0x26D5 && x <= 0x26E1
|| x === 0x26E3
|| x === 0x26E8
|| x === 0x26E9
|| x >= 0x26EB && x <= 0x26F1
|| x === 0x26F4
|| x >= 0x26F6 && x <= 0x26F9
|| x === 0x26FB
|| x === 0x26FC
|| x === 0x26FE
|| x === 0x26FF
|| x === 0x273D
|| x >= 0x2776 && x <= 0x277F
|| x >= 0x2B56 && x <= 0x2B59
|| x >= 0x3248 && x <= 0x324F
|| x >= 0xE000 && x <= 0xF8FF
|| x >= 0xFE00 && x <= 0xFE0F
|| x === 0xFFFD
|| x >= 0x1F100 && x <= 0x1F10A
|| x >= 0x1F110 && x <= 0x1F12D
|| x >= 0x1F130 && x <= 0x1F169
|| x >= 0x1F170 && x <= 0x1F18D
|| x === 0x1F18F
|| x === 0x1F190
|| x >= 0x1F19B && x <= 0x1F1AC
|| x >= 0xE0100 && x <= 0xE01EF
|| x >= 0xF0000 && x <= 0xFFFFD
|| x >= 0x100000 && x <= 0x10FFFD;
}
function isFullWidth(x) {
return x === 0x3000
|| x >= 0xFF01 && x <= 0xFF60
|| x >= 0xFFE0 && x <= 0xFFE6;
}
function isWide(x) {
return x >= 0x1100 && x <= 0x115F
|| x === 0x231A
|| x === 0x231B
|| x === 0x2329
|| x === 0x232A
|| x >= 0x23E9 && x <= 0x23EC
|| x === 0x23F0
|| x === 0x23F3
|| x === 0x25FD
|| x === 0x25FE
|| x === 0x2614
|| x === 0x2615
|| x >= 0x2630 && x <= 0x2637
|| x >= 0x2648 && x <= 0x2653
|| x === 0x267F
|| x >= 0x268A && x <= 0x268F
|| x === 0x2693
|| x === 0x26A1
|| x === 0x26AA
|| x === 0x26AB
|| x === 0x26BD
|| x === 0x26BE
|| x === 0x26C4
|| x === 0x26C5
|| x === 0x26CE
|| x === 0x26D4
|| x === 0x26EA
|| x === 0x26F2
|| x === 0x26F3
|| x === 0x26F5
|| x === 0x26FA
|| x === 0x26FD
|| x === 0x2705
|| x === 0x270A
|| x === 0x270B
|| x === 0x2728
|| x === 0x274C
|| x === 0x274E
|| x >= 0x2753 && x <= 0x2755
|| x === 0x2757
|| x >= 0x2795 && x <= 0x2797
|| x === 0x27B0
|| x === 0x27BF
|| x === 0x2B1B
|| x === 0x2B1C
|| x === 0x2B50
|| x === 0x2B55
|| x >= 0x2E80 && x <= 0x2E99
|| x >= 0x2E9B && x <= 0x2EF3
|| x >= 0x2F00 && x <= 0x2FD5
|| x >= 0x2FF0 && x <= 0x2FFF
|| x >= 0x3001 && x <= 0x303E
|| x >= 0x3041 && x <= 0x3096
|| x >= 0x3099 && x <= 0x30FF
|| x >= 0x3105 && x <= 0x312F
|| x >= 0x3131 && x <= 0x318E
|| x >= 0x3190 && x <= 0x31E5
|| x >= 0x31EF && x <= 0x321E
|| x >= 0x3220 && x <= 0x3247
|| x >= 0x3250 && x <= 0xA48C
|| x >= 0xA490 && x <= 0xA4C6
|| x >= 0xA960 && x <= 0xA97C
|| x >= 0xAC00 && x <= 0xD7A3
|| x >= 0xF900 && x <= 0xFAFF
|| x >= 0xFE10 && x <= 0xFE19
|| x >= 0xFE30 && x <= 0xFE52
|| x >= 0xFE54 && x <= 0xFE66
|| x >= 0xFE68 && x <= 0xFE6B
|| x >= 0x16FE0 && x <= 0x16FE4
|| x === 0x16FF0
|| x === 0x16FF1
|| x >= 0x17000 && x <= 0x187F7
|| x >= 0x18800 && x <= 0x18CD5
|| x >= 0x18CFF && x <= 0x18D08
|| x >= 0x1AFF0 && x <= 0x1AFF3
|| x >= 0x1AFF5 && x <= 0x1AFFB
|| x === 0x1AFFD
|| x === 0x1AFFE
|| x >= 0x1B000 && x <= 0x1B122
|| x === 0x1B132
|| x >= 0x1B150 && x <= 0x1B152
|| x === 0x1B155
|| x >= 0x1B164 && x <= 0x1B167
|| x >= 0x1B170 && x <= 0x1B2FB
|| x >= 0x1D300 && x <= 0x1D356
|| x >= 0x1D360 && x <= 0x1D376
|| x === 0x1F004
|| x === 0x1F0CF
|| x === 0x1F18E
|| x >= 0x1F191 && x <= 0x1F19A
|| x >= 0x1F200 && x <= 0x1F202
|| x >= 0x1F210 && x <= 0x1F23B
|| x >= 0x1F240 && x <= 0x1F248
|| x === 0x1F250
|| x === 0x1F251
|| x >= 0x1F260 && x <= 0x1F265
|| x >= 0x1F300 && x <= 0x1F320
|| x >= 0x1F32D && x <= 0x1F335
|| x >= 0x1F337 && x <= 0x1F37C
|| x >= 0x1F37E && x <= 0x1F393
|| x >= 0x1F3A0 && x <= 0x1F3CA
|| x >= 0x1F3CF && x <= 0x1F3D3
|| x >= 0x1F3E0 && x <= 0x1F3F0
|| x === 0x1F3F4
|| x >= 0x1F3F8 && x <= 0x1F43E
|| x === 0x1F440
|| x >= 0x1F442 && x <= 0x1F4FC
|| x >= 0x1F4FF && x <= 0x1F53D
|| x >= 0x1F54B && x <= 0x1F54E
|| x >= 0x1F550 && x <= 0x1F567
|| x === 0x1F57A
|| x === 0x1F595
|| x === 0x1F596
|| x === 0x1F5A4
|| x >= 0x1F5FB && x <= 0x1F64F
|| x >= 0x1F680 && x <= 0x1F6C5
|| x === 0x1F6CC
|| x >= 0x1F6D0 && x <= 0x1F6D2
|| x >= 0x1F6D5 && x <= 0x1F6D7
|| x >= 0x1F6DC && x <= 0x1F6DF
|| x === 0x1F6EB
|| x === 0x1F6EC
|| x >= 0x1F6F4 && x <= 0x1F6FC
|| x >= 0x1F7E0 && x <= 0x1F7EB
|| x === 0x1F7F0
|| x >= 0x1F90C && x <= 0x1F93A
|| x >= 0x1F93C && x <= 0x1F945
|| x >= 0x1F947 && x <= 0x1F9FF
|| x >= 0x1FA70 && x <= 0x1FA7C
|| x >= 0x1FA80 && x <= 0x1FA89
|| x >= 0x1FA8F && x <= 0x1FAC6
|| x >= 0x1FACE && x <= 0x1FADC
|| x >= 0x1FADF && x <= 0x1FAE9
|| x >= 0x1FAF0 && x <= 0x1FAF8
|| x >= 0x20000 && x <= 0x2FFFD
|| x >= 0x30000 && x <= 0x3FFFD;
}
function validate(codePoint) {
if (!Number.isSafeInteger(codePoint)) {
throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
}
}
function eastAsianWidth(codePoint, {ambiguousAsWide = false} = {}) {
validate(codePoint);
if (
isFullWidth(codePoint)
|| isWide(codePoint)
|| (ambiguousAsWide && isAmbiguous(codePoint))
) {
return 2;
}
return 1;
}
const emojiRegex = () => {
// https://mths.be/emoji
return /[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\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?|[\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](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\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-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE])))?))?|\uDC6F(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE89\uDE8F-\uDEC2\uDEC6\uDECE-\uDEDC\uDEDF-\uDEE9]|\uDD3C(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF])?|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g;
};
const segmenter = new Intl.Segmenter();
const defaultIgnorableCodePointRegex = /^\p{Default_Ignorable_Code_Point}$/u;
function stringWidth(string, options = {}) {
if (typeof string !== 'string' || string.length === 0) {
return 0;
}
const {
ambiguousIsNarrow = true,
countAnsiEscapeCodes = false,
} = options;
if (!countAnsiEscapeCodes) {
string = stripAnsi(string);
}
if (string.length === 0) {
return 0;
}
let width = 0;
const eastAsianWidthOptions = {ambiguousAsWide: !ambiguousIsNarrow};
for (const {segment: character} of segmenter.segment(string)) {
const codePoint = character.codePointAt(0);
// Ignore control characters
if (codePoint <= 0x1F || (codePoint >= 0x7F && codePoint <= 0x9F)) {
continue;
}
// Ignore zero-width characters
if (
(codePoint >= 0x20_0B && codePoint <= 0x20_0F) // Zero-width space, non-joiner, joiner, left-to-right mark, right-to-left mark
|| codePoint === 0xFE_FF // Zero-width no-break space
) {
continue;
}
// Ignore combining characters
if (
(codePoint >= 0x3_00 && codePoint <= 0x3_6F) // Combining diacritical marks
|| (codePoint >= 0x1A_B0 && codePoint <= 0x1A_FF) // Combining diacritical marks extended
|| (codePoint >= 0x1D_C0 && codePoint <= 0x1D_FF) // Combining diacritical marks supplement
|| (codePoint >= 0x20_D0 && codePoint <= 0x20_FF) // Combining diacritical marks for symbols
|| (codePoint >= 0xFE_20 && codePoint <= 0xFE_2F) // Combining half marks
) {
continue;
}
// Ignore surrogate pairs
if (codePoint >= 0xD8_00 && codePoint <= 0xDF_FF) {
continue;
}
// Ignore variation selectors
if (codePoint >= 0xFE_00 && codePoint <= 0xFE_0F) {
continue;
}
// This covers some of the above cases, but we still keep them for performance reasons.
if (defaultIgnorableCodePointRegex.test(character)) {
continue;
}
// TODO: Use `/\p{RGI_Emoji}/v` when targeting Node.js 20.
if (emojiRegex().test(character)) {
width += 2;
continue;
}
width += eastAsianWidth(codePoint, eastAsianWidthOptions);
}
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`;
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],
gray: [90, 39], // Alias of `blackBright`
grey: [90, 39], // Alias of `blackBright`
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],
bgGray: [100, 49], // Alias of `bgBlackBright`
bgGrey: [100, 49], // Alias of `bgBlackBright`
bgRedBright: [101, 49],
bgGreenBright: [102, 49],
bgYellowBright: [103, 49],
bgBlueBright: [104, 49],
bgMagentaBright: [105, 49],
bgCyanBright: [106, 49],
bgWhiteBright: [107, 49],
},
};
Object.keys(styles.modifier);
const foregroundColorNames = Object.keys(styles.color);
const backgroundColorNames = Object.keys(styles.bgColor);
[...foregroundColorNames, ...backgroundColorNames];
function assembleStyles() {
const codes = new Map();
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 = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
if (!matches) {
return [0, 0, 0];
}
let [colorString] = matches;
if (colorString.length === 3) {
colorString = [...colorString].map(character => character + character).join('');
}
const integer = Number.parseInt(colorString, 16);
return [
/* eslint-disable no-bitwise */
(integer >> 16) & 0xFF,
(integer >> 8) & 0xFF,
integer & 0xFF,
/* eslint-enable no-bitwise */
];
},
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;
}
// eslint-disable-next-line no-bitwise
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 =