text: const advancedDetermine = require("@hugoalh/advanced-determine");
  const reCharacters = require("../third-party-module-convert/char-regex.js");
  const undefinish = require("@hugoalh/undefinish");
  /**
   * @function stringOverflow
   * @description Clip the string when longer than maximum length with ellipsis.
   * @param {string} item String that need to clip.
   * @param {number} maximumLength Maximum length of the target string.
   * @param {object} [option={}] Option.
   * @param {string} [option.ellipsis="..."] Ellipsis.
   * @param {("center"|"end"|"left"|"middle"|"right"|"start")} [option.position="end"] Ellipsis position.
   * @returns {string} A clipped string.
   */
  function stringOverflow(item, maximumLength, option = {}) {
  	if (typeof item !== "string") {
  		throw new TypeError(`Argument \`item\` must be type of string!`);
  	};
  	if (!advancedDetermine.isPlainObject(option, { super: true })) {
  		throw new TypeError(`Argument \`option\` must be type of plain object!`);
  	};
  	if (!advancedDetermine.isNumber(maximumLength, { finite: true, integer: true, positive: true, safe: true })) {
  		throw new TypeError(`Argument \`maximumLength\` must be type of number (finite, integer, positive, and safe)!`);
  	};
  	option.ellipsis = undefinish(option.ellipsis, "...");
  	if (typeof option.ellipsis !== "string") {
  		throw new TypeError(`Argument \`option.ellipsis\` must be type of string!`);
  	};
  	if (option.ellipsis.length >= maximumLength) {
  		throw new ReferenceError(`Ellipsis also overflow!`);
  	};
  	option.position = undefinish(option.position, "end");
  	if (typeof option.position !== "string") {
  		throw new TypeError(`Argument \`option.position\` must be type of string!`);
  	};
  	if (item.length <= maximumLength) {
  		return item;
  	};
  	let resultLengthMaximum = maximumLength - option.ellipsis.length;
  	let resultLengthLeft;
  	let resultLengthRight;
  	if (option.position.search(/^(?:e(?:nd)?|r(?:ight)?)$/giu) === 0) {
  		resultLengthLeft = resultLengthMaximum;
  		resultLengthRight = 0;
  	} else if (option.position.search(/^(?:c(?:enter)?|m(?:iddle)?)$/giu) === 0) {
  		let resultLengthHalf = Math.floor(resultLengthMaximum / 2);
  		resultLengthLeft = resultLengthHalf;
  		resultLengthRight = resultLengthHalf;
  	} else if (option.position.search(/^(?:l(?:eft)?|s(?:tart)?)$/giu) === 0) {
  		resultLengthLeft = 0;
  		resultLengthRight = resultLengthMaximum;
  	} else {
  		throw new SyntaxError(`Argument \`option.position\`'s value is not in the list!`);
  	};
  	let itemCharacters = (
  		item.match(reCharacters()) ||
  		[]
  	);
  	let itemVisualLength = itemCharacters.length;
  	let resultLeft = "";
  	for (let index = 0; index < itemVisualLength; index++) {
  		let key = itemCharacters[index];
  		if (resultLeft.length + key.length > resultLengthLeft) {
  			break;
  		};
  		resultLeft = `${resultLeft}${key}`;
  	};
  	let resultRight = "";
  	for (let index = itemVisualLength - 1; index >= 0; index--) {
  		let key = itemCharacters[index];
  		if (resultRight.length + key.length > resultLengthRight) {
  			break;
  		};
  		resultRight = `${key}${resultRight}`;
  	};
  	return `${resultLeft}${option.ellipsis}${resultRight}`;
  };
  module.exports = stringOverflow;
  