11cb0ef41Sopenharmony_ciconst stringWidth = require('string-width');
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_cifunction codeRegex(capture) {
41cb0ef41Sopenharmony_ci  return capture ? /\u001b\[((?:\d*;){0,5}\d*)m/g : /\u001b\[(?:\d*;){0,5}\d*m/g;
51cb0ef41Sopenharmony_ci}
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_cifunction strlen(str) {
81cb0ef41Sopenharmony_ci  let code = codeRegex();
91cb0ef41Sopenharmony_ci  let stripped = ('' + str).replace(code, '');
101cb0ef41Sopenharmony_ci  let split = stripped.split('\n');
111cb0ef41Sopenharmony_ci  return split.reduce(function (memo, s) {
121cb0ef41Sopenharmony_ci    return stringWidth(s) > memo ? stringWidth(s) : memo;
131cb0ef41Sopenharmony_ci  }, 0);
141cb0ef41Sopenharmony_ci}
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_cifunction repeat(str, times) {
171cb0ef41Sopenharmony_ci  return Array(times + 1).join(str);
181cb0ef41Sopenharmony_ci}
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_cifunction pad(str, len, pad, dir) {
211cb0ef41Sopenharmony_ci  let length = strlen(str);
221cb0ef41Sopenharmony_ci  if (len + 1 >= length) {
231cb0ef41Sopenharmony_ci    let padlen = len - length;
241cb0ef41Sopenharmony_ci    switch (dir) {
251cb0ef41Sopenharmony_ci      case 'right': {
261cb0ef41Sopenharmony_ci        str = repeat(pad, padlen) + str;
271cb0ef41Sopenharmony_ci        break;
281cb0ef41Sopenharmony_ci      }
291cb0ef41Sopenharmony_ci      case 'center': {
301cb0ef41Sopenharmony_ci        let right = Math.ceil(padlen / 2);
311cb0ef41Sopenharmony_ci        let left = padlen - right;
321cb0ef41Sopenharmony_ci        str = repeat(pad, left) + str + repeat(pad, right);
331cb0ef41Sopenharmony_ci        break;
341cb0ef41Sopenharmony_ci      }
351cb0ef41Sopenharmony_ci      default: {
361cb0ef41Sopenharmony_ci        str = str + repeat(pad, padlen);
371cb0ef41Sopenharmony_ci        break;
381cb0ef41Sopenharmony_ci      }
391cb0ef41Sopenharmony_ci    }
401cb0ef41Sopenharmony_ci  }
411cb0ef41Sopenharmony_ci  return str;
421cb0ef41Sopenharmony_ci}
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_cilet codeCache = {};
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_cifunction addToCodeCache(name, on, off) {
471cb0ef41Sopenharmony_ci  on = '\u001b[' + on + 'm';
481cb0ef41Sopenharmony_ci  off = '\u001b[' + off + 'm';
491cb0ef41Sopenharmony_ci  codeCache[on] = { set: name, to: true };
501cb0ef41Sopenharmony_ci  codeCache[off] = { set: name, to: false };
511cb0ef41Sopenharmony_ci  codeCache[name] = { on: on, off: off };
521cb0ef41Sopenharmony_ci}
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci//https://github.com/Marak/colors.js/blob/master/lib/styles.js
551cb0ef41Sopenharmony_ciaddToCodeCache('bold', 1, 22);
561cb0ef41Sopenharmony_ciaddToCodeCache('italics', 3, 23);
571cb0ef41Sopenharmony_ciaddToCodeCache('underline', 4, 24);
581cb0ef41Sopenharmony_ciaddToCodeCache('inverse', 7, 27);
591cb0ef41Sopenharmony_ciaddToCodeCache('strikethrough', 9, 29);
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_cifunction updateState(state, controlChars) {
621cb0ef41Sopenharmony_ci  let controlCode = controlChars[1] ? parseInt(controlChars[1].split(';')[0]) : 0;
631cb0ef41Sopenharmony_ci  if ((controlCode >= 30 && controlCode <= 39) || (controlCode >= 90 && controlCode <= 97)) {
641cb0ef41Sopenharmony_ci    state.lastForegroundAdded = controlChars[0];
651cb0ef41Sopenharmony_ci    return;
661cb0ef41Sopenharmony_ci  }
671cb0ef41Sopenharmony_ci  if ((controlCode >= 40 && controlCode <= 49) || (controlCode >= 100 && controlCode <= 107)) {
681cb0ef41Sopenharmony_ci    state.lastBackgroundAdded = controlChars[0];
691cb0ef41Sopenharmony_ci    return;
701cb0ef41Sopenharmony_ci  }
711cb0ef41Sopenharmony_ci  if (controlCode === 0) {
721cb0ef41Sopenharmony_ci    for (let i in state) {
731cb0ef41Sopenharmony_ci      /* istanbul ignore else */
741cb0ef41Sopenharmony_ci      if (Object.prototype.hasOwnProperty.call(state, i)) {
751cb0ef41Sopenharmony_ci        delete state[i];
761cb0ef41Sopenharmony_ci      }
771cb0ef41Sopenharmony_ci    }
781cb0ef41Sopenharmony_ci    return;
791cb0ef41Sopenharmony_ci  }
801cb0ef41Sopenharmony_ci  let info = codeCache[controlChars[0]];
811cb0ef41Sopenharmony_ci  if (info) {
821cb0ef41Sopenharmony_ci    state[info.set] = info.to;
831cb0ef41Sopenharmony_ci  }
841cb0ef41Sopenharmony_ci}
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_cifunction readState(line) {
871cb0ef41Sopenharmony_ci  let code = codeRegex(true);
881cb0ef41Sopenharmony_ci  let controlChars = code.exec(line);
891cb0ef41Sopenharmony_ci  let state = {};
901cb0ef41Sopenharmony_ci  while (controlChars !== null) {
911cb0ef41Sopenharmony_ci    updateState(state, controlChars);
921cb0ef41Sopenharmony_ci    controlChars = code.exec(line);
931cb0ef41Sopenharmony_ci  }
941cb0ef41Sopenharmony_ci  return state;
951cb0ef41Sopenharmony_ci}
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_cifunction unwindState(state, ret) {
981cb0ef41Sopenharmony_ci  let lastBackgroundAdded = state.lastBackgroundAdded;
991cb0ef41Sopenharmony_ci  let lastForegroundAdded = state.lastForegroundAdded;
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ci  delete state.lastBackgroundAdded;
1021cb0ef41Sopenharmony_ci  delete state.lastForegroundAdded;
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  Object.keys(state).forEach(function (key) {
1051cb0ef41Sopenharmony_ci    if (state[key]) {
1061cb0ef41Sopenharmony_ci      ret += codeCache[key].off;
1071cb0ef41Sopenharmony_ci    }
1081cb0ef41Sopenharmony_ci  });
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  if (lastBackgroundAdded && lastBackgroundAdded != '\u001b[49m') {
1111cb0ef41Sopenharmony_ci    ret += '\u001b[49m';
1121cb0ef41Sopenharmony_ci  }
1131cb0ef41Sopenharmony_ci  if (lastForegroundAdded && lastForegroundAdded != '\u001b[39m') {
1141cb0ef41Sopenharmony_ci    ret += '\u001b[39m';
1151cb0ef41Sopenharmony_ci  }
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci  return ret;
1181cb0ef41Sopenharmony_ci}
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_cifunction rewindState(state, ret) {
1211cb0ef41Sopenharmony_ci  let lastBackgroundAdded = state.lastBackgroundAdded;
1221cb0ef41Sopenharmony_ci  let lastForegroundAdded = state.lastForegroundAdded;
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci  delete state.lastBackgroundAdded;
1251cb0ef41Sopenharmony_ci  delete state.lastForegroundAdded;
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci  Object.keys(state).forEach(function (key) {
1281cb0ef41Sopenharmony_ci    if (state[key]) {
1291cb0ef41Sopenharmony_ci      ret = codeCache[key].on + ret;
1301cb0ef41Sopenharmony_ci    }
1311cb0ef41Sopenharmony_ci  });
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci  if (lastBackgroundAdded && lastBackgroundAdded != '\u001b[49m') {
1341cb0ef41Sopenharmony_ci    ret = lastBackgroundAdded + ret;
1351cb0ef41Sopenharmony_ci  }
1361cb0ef41Sopenharmony_ci  if (lastForegroundAdded && lastForegroundAdded != '\u001b[39m') {
1371cb0ef41Sopenharmony_ci    ret = lastForegroundAdded + ret;
1381cb0ef41Sopenharmony_ci  }
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci  return ret;
1411cb0ef41Sopenharmony_ci}
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_cifunction truncateWidth(str, desiredLength) {
1441cb0ef41Sopenharmony_ci  if (str.length === strlen(str)) {
1451cb0ef41Sopenharmony_ci    return str.substr(0, desiredLength);
1461cb0ef41Sopenharmony_ci  }
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ci  while (strlen(str) > desiredLength) {
1491cb0ef41Sopenharmony_ci    str = str.slice(0, -1);
1501cb0ef41Sopenharmony_ci  }
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ci  return str;
1531cb0ef41Sopenharmony_ci}
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_cifunction truncateWidthWithAnsi(str, desiredLength) {
1561cb0ef41Sopenharmony_ci  let code = codeRegex(true);
1571cb0ef41Sopenharmony_ci  let split = str.split(codeRegex());
1581cb0ef41Sopenharmony_ci  let splitIndex = 0;
1591cb0ef41Sopenharmony_ci  let retLen = 0;
1601cb0ef41Sopenharmony_ci  let ret = '';
1611cb0ef41Sopenharmony_ci  let myArray;
1621cb0ef41Sopenharmony_ci  let state = {};
1631cb0ef41Sopenharmony_ci
1641cb0ef41Sopenharmony_ci  while (retLen < desiredLength) {
1651cb0ef41Sopenharmony_ci    myArray = code.exec(str);
1661cb0ef41Sopenharmony_ci    let toAdd = split[splitIndex];
1671cb0ef41Sopenharmony_ci    splitIndex++;
1681cb0ef41Sopenharmony_ci    if (retLen + strlen(toAdd) > desiredLength) {
1691cb0ef41Sopenharmony_ci      toAdd = truncateWidth(toAdd, desiredLength - retLen);
1701cb0ef41Sopenharmony_ci    }
1711cb0ef41Sopenharmony_ci    ret += toAdd;
1721cb0ef41Sopenharmony_ci    retLen += strlen(toAdd);
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ci    if (retLen < desiredLength) {
1751cb0ef41Sopenharmony_ci      if (!myArray) {
1761cb0ef41Sopenharmony_ci        break;
1771cb0ef41Sopenharmony_ci      } // full-width chars may cause a whitespace which cannot be filled
1781cb0ef41Sopenharmony_ci      ret += myArray[0];
1791cb0ef41Sopenharmony_ci      updateState(state, myArray);
1801cb0ef41Sopenharmony_ci    }
1811cb0ef41Sopenharmony_ci  }
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_ci  return unwindState(state, ret);
1841cb0ef41Sopenharmony_ci}
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_cifunction truncate(str, desiredLength, truncateChar) {
1871cb0ef41Sopenharmony_ci  truncateChar = truncateChar || '…';
1881cb0ef41Sopenharmony_ci  let lengthOfStr = strlen(str);
1891cb0ef41Sopenharmony_ci  if (lengthOfStr <= desiredLength) {
1901cb0ef41Sopenharmony_ci    return str;
1911cb0ef41Sopenharmony_ci  }
1921cb0ef41Sopenharmony_ci  desiredLength -= strlen(truncateChar);
1931cb0ef41Sopenharmony_ci
1941cb0ef41Sopenharmony_ci  let ret = truncateWidthWithAnsi(str, desiredLength);
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ci  return ret + truncateChar;
1971cb0ef41Sopenharmony_ci}
1981cb0ef41Sopenharmony_ci
1991cb0ef41Sopenharmony_cifunction defaultOptions() {
2001cb0ef41Sopenharmony_ci  return {
2011cb0ef41Sopenharmony_ci    chars: {
2021cb0ef41Sopenharmony_ci      top: '─',
2031cb0ef41Sopenharmony_ci      'top-mid': '┬',
2041cb0ef41Sopenharmony_ci      'top-left': '┌',
2051cb0ef41Sopenharmony_ci      'top-right': '┐',
2061cb0ef41Sopenharmony_ci      bottom: '─',
2071cb0ef41Sopenharmony_ci      'bottom-mid': '┴',
2081cb0ef41Sopenharmony_ci      'bottom-left': '└',
2091cb0ef41Sopenharmony_ci      'bottom-right': '┘',
2101cb0ef41Sopenharmony_ci      left: '│',
2111cb0ef41Sopenharmony_ci      'left-mid': '├',
2121cb0ef41Sopenharmony_ci      mid: '─',
2131cb0ef41Sopenharmony_ci      'mid-mid': '┼',
2141cb0ef41Sopenharmony_ci      right: '│',
2151cb0ef41Sopenharmony_ci      'right-mid': '┤',
2161cb0ef41Sopenharmony_ci      middle: '│',
2171cb0ef41Sopenharmony_ci    },
2181cb0ef41Sopenharmony_ci    truncate: '…',
2191cb0ef41Sopenharmony_ci    colWidths: [],
2201cb0ef41Sopenharmony_ci    rowHeights: [],
2211cb0ef41Sopenharmony_ci    colAligns: [],
2221cb0ef41Sopenharmony_ci    rowAligns: [],
2231cb0ef41Sopenharmony_ci    style: {
2241cb0ef41Sopenharmony_ci      'padding-left': 1,
2251cb0ef41Sopenharmony_ci      'padding-right': 1,
2261cb0ef41Sopenharmony_ci      head: ['red'],
2271cb0ef41Sopenharmony_ci      border: ['grey'],
2281cb0ef41Sopenharmony_ci      compact: false,
2291cb0ef41Sopenharmony_ci    },
2301cb0ef41Sopenharmony_ci    head: [],
2311cb0ef41Sopenharmony_ci  };
2321cb0ef41Sopenharmony_ci}
2331cb0ef41Sopenharmony_ci
2341cb0ef41Sopenharmony_cifunction mergeOptions(options, defaults) {
2351cb0ef41Sopenharmony_ci  options = options || {};
2361cb0ef41Sopenharmony_ci  defaults = defaults || defaultOptions();
2371cb0ef41Sopenharmony_ci  let ret = Object.assign({}, defaults, options);
2381cb0ef41Sopenharmony_ci  ret.chars = Object.assign({}, defaults.chars, options.chars);
2391cb0ef41Sopenharmony_ci  ret.style = Object.assign({}, defaults.style, options.style);
2401cb0ef41Sopenharmony_ci  return ret;
2411cb0ef41Sopenharmony_ci}
2421cb0ef41Sopenharmony_ci
2431cb0ef41Sopenharmony_ci// Wrap on word boundary
2441cb0ef41Sopenharmony_cifunction wordWrap(maxLength, input) {
2451cb0ef41Sopenharmony_ci  let lines = [];
2461cb0ef41Sopenharmony_ci  let split = input.split(/(\s+)/g);
2471cb0ef41Sopenharmony_ci  let line = [];
2481cb0ef41Sopenharmony_ci  let lineLength = 0;
2491cb0ef41Sopenharmony_ci  let whitespace;
2501cb0ef41Sopenharmony_ci  for (let i = 0; i < split.length; i += 2) {
2511cb0ef41Sopenharmony_ci    let word = split[i];
2521cb0ef41Sopenharmony_ci    let newLength = lineLength + strlen(word);
2531cb0ef41Sopenharmony_ci    if (lineLength > 0 && whitespace) {
2541cb0ef41Sopenharmony_ci      newLength += whitespace.length;
2551cb0ef41Sopenharmony_ci    }
2561cb0ef41Sopenharmony_ci    if (newLength > maxLength) {
2571cb0ef41Sopenharmony_ci      if (lineLength !== 0) {
2581cb0ef41Sopenharmony_ci        lines.push(line.join(''));
2591cb0ef41Sopenharmony_ci      }
2601cb0ef41Sopenharmony_ci      line = [word];
2611cb0ef41Sopenharmony_ci      lineLength = strlen(word);
2621cb0ef41Sopenharmony_ci    } else {
2631cb0ef41Sopenharmony_ci      line.push(whitespace || '', word);
2641cb0ef41Sopenharmony_ci      lineLength = newLength;
2651cb0ef41Sopenharmony_ci    }
2661cb0ef41Sopenharmony_ci    whitespace = split[i + 1];
2671cb0ef41Sopenharmony_ci  }
2681cb0ef41Sopenharmony_ci  if (lineLength) {
2691cb0ef41Sopenharmony_ci    lines.push(line.join(''));
2701cb0ef41Sopenharmony_ci  }
2711cb0ef41Sopenharmony_ci  return lines;
2721cb0ef41Sopenharmony_ci}
2731cb0ef41Sopenharmony_ci
2741cb0ef41Sopenharmony_ci// Wrap text (ignoring word boundaries)
2751cb0ef41Sopenharmony_cifunction textWrap(maxLength, input) {
2761cb0ef41Sopenharmony_ci  let lines = [];
2771cb0ef41Sopenharmony_ci  let line = '';
2781cb0ef41Sopenharmony_ci  function pushLine(str, ws) {
2791cb0ef41Sopenharmony_ci    if (line.length && ws) line += ws;
2801cb0ef41Sopenharmony_ci    line += str;
2811cb0ef41Sopenharmony_ci    while (line.length > maxLength) {
2821cb0ef41Sopenharmony_ci      lines.push(line.slice(0, maxLength));
2831cb0ef41Sopenharmony_ci      line = line.slice(maxLength);
2841cb0ef41Sopenharmony_ci    }
2851cb0ef41Sopenharmony_ci  }
2861cb0ef41Sopenharmony_ci  let split = input.split(/(\s+)/g);
2871cb0ef41Sopenharmony_ci  for (let i = 0; i < split.length; i += 2) {
2881cb0ef41Sopenharmony_ci    pushLine(split[i], i && split[i - 1]);
2891cb0ef41Sopenharmony_ci  }
2901cb0ef41Sopenharmony_ci  if (line.length) lines.push(line);
2911cb0ef41Sopenharmony_ci  return lines;
2921cb0ef41Sopenharmony_ci}
2931cb0ef41Sopenharmony_ci
2941cb0ef41Sopenharmony_cifunction multiLineWordWrap(maxLength, input, wrapOnWordBoundary = true) {
2951cb0ef41Sopenharmony_ci  let output = [];
2961cb0ef41Sopenharmony_ci  input = input.split('\n');
2971cb0ef41Sopenharmony_ci  const handler = wrapOnWordBoundary ? wordWrap : textWrap;
2981cb0ef41Sopenharmony_ci  for (let i = 0; i < input.length; i++) {
2991cb0ef41Sopenharmony_ci    output.push.apply(output, handler(maxLength, input[i]));
3001cb0ef41Sopenharmony_ci  }
3011cb0ef41Sopenharmony_ci  return output;
3021cb0ef41Sopenharmony_ci}
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_cifunction colorizeLines(input) {
3051cb0ef41Sopenharmony_ci  let state = {};
3061cb0ef41Sopenharmony_ci  let output = [];
3071cb0ef41Sopenharmony_ci  for (let i = 0; i < input.length; i++) {
3081cb0ef41Sopenharmony_ci    let line = rewindState(state, input[i]);
3091cb0ef41Sopenharmony_ci    state = readState(line);
3101cb0ef41Sopenharmony_ci    let temp = Object.assign({}, state);
3111cb0ef41Sopenharmony_ci    output.push(unwindState(temp, line));
3121cb0ef41Sopenharmony_ci  }
3131cb0ef41Sopenharmony_ci  return output;
3141cb0ef41Sopenharmony_ci}
3151cb0ef41Sopenharmony_ci
3161cb0ef41Sopenharmony_ci/**
3171cb0ef41Sopenharmony_ci * Credit: Matheus Sampaio https://github.com/matheussampaio
3181cb0ef41Sopenharmony_ci */
3191cb0ef41Sopenharmony_cifunction hyperlink(url, text) {
3201cb0ef41Sopenharmony_ci  const OSC = '\u001B]';
3211cb0ef41Sopenharmony_ci  const BEL = '\u0007';
3221cb0ef41Sopenharmony_ci  const SEP = ';';
3231cb0ef41Sopenharmony_ci
3241cb0ef41Sopenharmony_ci  return [OSC, '8', SEP, SEP, url || text, BEL, text, OSC, '8', SEP, SEP, BEL].join('');
3251cb0ef41Sopenharmony_ci}
3261cb0ef41Sopenharmony_ci
3271cb0ef41Sopenharmony_cimodule.exports = {
3281cb0ef41Sopenharmony_ci  strlen: strlen,
3291cb0ef41Sopenharmony_ci  repeat: repeat,
3301cb0ef41Sopenharmony_ci  pad: pad,
3311cb0ef41Sopenharmony_ci  truncate: truncate,
3321cb0ef41Sopenharmony_ci  mergeOptions: mergeOptions,
3331cb0ef41Sopenharmony_ci  wordWrap: multiLineWordWrap,
3341cb0ef41Sopenharmony_ci  colorizeLines: colorizeLines,
3351cb0ef41Sopenharmony_ci  hyperlink,
3361cb0ef41Sopenharmony_ci};
337