| 'use strict'; | 
| const sliceAnsi = require('slice-ansi'); | 
| const stringWidth = require('string-width'); | 
|   | 
| function getIndexOfNearestSpace(string, index, shouldSearchRight) { | 
|     if (string.charAt(index) === ' ') { | 
|         return index; | 
|     } | 
|   | 
|     for (let i = 1; i <= 3; i++) { | 
|         if (shouldSearchRight) { | 
|             if (string.charAt(index + i) === ' ') { | 
|                 return index + i; | 
|             } | 
|         } else if (string.charAt(index - i) === ' ') { | 
|             return index - i; | 
|         } | 
|     } | 
|   | 
|     return index; | 
| } | 
|   | 
| module.exports = (text, columns, options) => { | 
|     options = { | 
|         position: 'end', | 
|         preferTruncationOnSpace: false, | 
|         ...options | 
|     }; | 
|   | 
|     const {position, space, preferTruncationOnSpace} = options; | 
|     let ellipsis = '…'; | 
|     let ellipsisWidth = 1; | 
|   | 
|     if (typeof text !== 'string') { | 
|         throw new TypeError(`Expected \`input\` to be a string, got ${typeof text}`); | 
|     } | 
|   | 
|     if (typeof columns !== 'number') { | 
|         throw new TypeError(`Expected \`columns\` to be a number, got ${typeof columns}`); | 
|     } | 
|   | 
|     if (columns < 1) { | 
|         return ''; | 
|     } | 
|   | 
|     if (columns === 1) { | 
|         return ellipsis; | 
|     } | 
|   | 
|     const length = stringWidth(text); | 
|   | 
|     if (length <= columns) { | 
|         return text; | 
|     } | 
|   | 
|     if (position === 'start') { | 
|         if (preferTruncationOnSpace) { | 
|             const nearestSpace = getIndexOfNearestSpace(text, length - columns + 1, true); | 
|             return ellipsis + sliceAnsi(text, nearestSpace, length).trim(); | 
|         } | 
|   | 
|         if (space === true) { | 
|             ellipsis += ' '; | 
|             ellipsisWidth = 2; | 
|         } | 
|   | 
|         return ellipsis + sliceAnsi(text, length - columns + ellipsisWidth, length); | 
|     } | 
|   | 
|     if (position === 'middle') { | 
|         if (space === true) { | 
|             ellipsis = ' ' + ellipsis + ' '; | 
|             ellipsisWidth = 3; | 
|         } | 
|   | 
|         const half = Math.floor(columns / 2); | 
|   | 
|         if (preferTruncationOnSpace) { | 
|             const spaceNearFirstBreakPoint = getIndexOfNearestSpace(text, half); | 
|             const spaceNearSecondBreakPoint = getIndexOfNearestSpace(text, length - (columns - half) + 1, true); | 
|             return sliceAnsi(text, 0, spaceNearFirstBreakPoint) + ellipsis + sliceAnsi(text, spaceNearSecondBreakPoint, length).trim(); | 
|         } | 
|   | 
|         return ( | 
|             sliceAnsi(text, 0, half) + | 
|             ellipsis + | 
|             sliceAnsi(text, length - (columns - half) + ellipsisWidth, length) | 
|         ); | 
|     } | 
|   | 
|     if (position === 'end') { | 
|         if (preferTruncationOnSpace) { | 
|             const nearestSpace = getIndexOfNearestSpace(text, columns - 1); | 
|             return sliceAnsi(text, 0, nearestSpace) + ellipsis; | 
|         } | 
|   | 
|         if (space === true) { | 
|             ellipsis = ' ' + ellipsis; | 
|             ellipsisWidth = 2; | 
|         } | 
|   | 
|         return sliceAnsi(text, 0, columns - ellipsisWidth) + ellipsis; | 
|     } | 
|   | 
|     throw new Error(`Expected \`options.position\` to be either \`start\`, \`middle\` or \`end\`, got ${position}`); | 
| }; |