var stringKebabCase = kebabCase$1;
var wordSeparators = /[\s\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?@\[\]^_`{|}~]+/;
var capital_plus_lower = /[A-ZÀ-Ý\u00C0-\u00D6\u00D9-\u00DD][a-zà-ÿ]/g;
var capitals = /[A-ZÀ-Ý\u00C0-\u00D6\u00D9-\u00DD]+/g;
function kebabCase$1(str) {
  str = str.replace(capital_plus_lower, function(match) {
    return " " + (match[0].toLowerCase() || match[0]) + match[1];
  });
  str = str.replace(capitals, function(match) {
    return " " + match.toLowerCase();
  });
  return str.trim().split(wordSeparators).join("-").replace(/^-/, "").replace(/-\s*$/, "");
}
var stringCamelCase = camelCase$1;
var wordSeparatorsRegEx = /[\s\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?@\[\]^_`{|}~]+/;
var basicCamelRegEx = /^[a-z\u00E0-\u00FCA-Z\u00C0-\u00DC][\d|a-z\u00E0-\u00FCA-Z\u00C0-\u00DC]*$/;
var fourOrMoreConsecutiveCapsRegEx = /([A-Z\u00C0-\u00DC]{4,})/g;
var allCapsRegEx = /^[A-Z\u00C0-\u00DC]+$/;
function camelCase$1(str) {
  var words = str.split(wordSeparatorsRegEx);
  var len = words.length;
  var mappedWords = new Array(len);
  for (var i = 0; i < len; i++) {
    var word = words[i];
    if (word === "") {
      continue;
    }
    var isCamelCase = basicCamelRegEx.test(word) && !allCapsRegEx.test(word);
    if (isCamelCase) {
      word = word.replace(fourOrMoreConsecutiveCapsRegEx, function(match, p1, offset) {
        return deCap(match, word.length - offset - match.length == 0);
      });
    }
    var firstLetter = word[0];
    firstLetter = i > 0 ? firstLetter.toUpperCase() : firstLetter.toLowerCase();
    mappedWords[i] = firstLetter + (!isCamelCase ? word.slice(1).toLowerCase() : word.slice(1));
  }
  return mappedWords.join("");
}
function deCap(match, endOfWord) {
  var arr = match.split("");
  var first = arr.shift().toUpperCase();
  var last = endOfWord ? arr.pop().toLowerCase() : arr.pop();
  return first + arr.join("").toLowerCase() + last;
}
var objectIsEmpty = isEmpty$1;
function isEmpty$1(obj) {
  if (obj == null) {
    return true;
  }
  if (Array.isArray(obj)) {
    return !obj.length;
  }
  if (typeof obj == "string") {
    return !obj.length;
  }
  var type = {}.toString.call(obj);
  if (type == "[object Object]") {
    return !Object.keys(obj).length && !Object.getOwnPropertySymbols(obj).length;
  }
  if (type == "[object Map]" || type == "[object Set]") {
    return !obj.size;
  }
  return Object(obj) !== obj || !Object.keys(obj).length;
}
var objectHas = has$1;
function has$1(obj, propsArg) {
  if (!obj) {
    return false;
  }
  var props, prop;
  if (Array.isArray(propsArg)) {
    props = propsArg.slice(0);
  }
  if (typeof propsArg == "string") {
    props = propsArg.split(".");
  }
  if (typeof propsArg == "symbol") {
    props = [propsArg];
  }
  if (!Array.isArray(props)) {
    throw new Error("props arg must be an array, a string or a symbol");
  }
  while (props.length) {
    prop = props.shift();
    if (obj == null) {
      return false;
    }
    if (!Object.prototype.hasOwnProperty.call(obj, prop)) {
      return false;
    }
    if (props.length === 0) {
      return true;
    }
    obj = obj[prop];
  }
  return false;
}
/**
 * Returns a camelCase-formatted string.
 *
 * @param {string} input - String to convert.
 *
 * @access public
 *
 * @return {string} *camelCase*-formatted string.
 *
 * @example
 * camelCase('New super Test-title') // => 'newSuperTestTitle'
 * camelCase(null) // => ''
 *
 * @preserve
 */
const camelCase = (input) => lowerFirst(stringCamelCase(input ?? ""));
/**
 * Returns a PascalCase-formatted string.
 *
 * @param {string} input - String to convert.
 *
 * @access public
 *
 * @return {string} *PascalCase*-formatted string.
 *
 * Usage:
 * ```js
 * pascalCase('New super Test-title') // => 'NewSuperTestTitle'
 * pascalCase(null) // => ''
 * ```
 *
 * @preserve
 */
const pascalCase = (input) => upperFirst(stringCamelCase(input ?? ""));
/**
 * Returns a snake_case-formatted string.
 *
 * @param {string} input - String to convert.
 *
 * @access public
 *
 * @return {string} *snake_case*-formatted string.
 *
 * Usage:
 * ```js
 * snakeCase('New super Test-title') // => 'new_super_test_title'
 * snakeCase(null) // => ''
 * ```
 *
 * @preserve
 */
const snakeCase = (input) => kebabCase(input ?? "").replaceAll("-", "_");
const kebabCase = (input) => stringKebabCase(input ?? "");
/**
 * Checks if value is an empty object or collection.
 *
 * @param {*} input - Value to check.
 *
 * @returns true if the object is empty, false otherwise.
 *
 * Usage:
 * ```js
 * isEmpty({}) // => true
 * isEmpty([]) // => true
 * isEmpty('') // => true
 * isEmpty({ a: 1 }) // => false
 * isEmpty([1, 2, 3]) // => false
 * ```
 *
 * @preserve
 */
const isEmpty = (input) => objectIsEmpty(input);
/**
 * Returns the string with its first character converted to uppercase.
 *
 * @param {string} input - String to convert.
 *
 * @return {string} string with its first character converted to uppercase.
 *
 * @example
 * upperFirst('new super Test-title') // => 'New super Test-title'
 *
 * @preserve
 */
const upperFirst = (input) => {
  if (typeof input === "undefined") {
    return "";
  }
  if (input === true) {
    return "True";
  } else if (input === false) {
    return "False";
  }
  if (typeof input !== "string") {
    input = String(input);
  }
  if (input.length < 2) {
    return input.toUpperCase();
  }
  return input.charAt(0).toUpperCase() + input.slice(1);
};
/**
 * Returns the string with its first character converted to lowercase.
 *
 * @param {string} input - String to convert.
 *
 * @return {string} string with its first character converted to lowercase.
 *
 * @example
 * lowerFirst('New super Test-title') // => 'new super Test-title'
 *
 * @preserve
 */
const lowerFirst = (input) => {
  if (typeof input === "undefined") {
    return "";
  }
  if (input === true) {
    return "true";
  } else if (input === false) {
    return "false";
  }
  if (typeof input !== "string") {
    input = String(input);
  }
  if (input?.length < 2) {
    return input.toLowerCase();
  }
  return input.charAt(0).toLowerCase() + input.slice(1);
};
/**
 * Checks if `key` is a direct property of `object`. Key may be a path of a value separated by `.`
 *
 * @param {object} obj - Object to check.
 * @param {string} key - Key to check.
 *
 * @return {boolean} true if key is a direct property, false otherwise.
 *
 * Usage:
 * ```js
 * has({ a: 1 }, 'a') // => true
 * has({ a: 1 }, 'b') // => false
 * has({ a: { b: 2 } }, 'a.b') // => true
 * has({ a: { b: 3 } }, 'a.c') // => false
 * ```
 *
 * @preserve
 */
const has = (obj, key) => objectHas(obj, key);
/*
 * Checks if value is a plain object, that is, an object created by the Object constructor or one with a `[[Prototype]]` of `null`.
 *
 * @param {*} value - Value to check.
 * @returns {boolean} true if value is a plain object, false otherwise.
 *
 * Usage:
 * ```js
 * isPlainObject({ a: 2 }) // => true
 * isPlainObject('Lorem') // => false
 * isPlainObject([]) // => false
 * isPlainObject(new Boolean()) // => false
 * ```
 *
 * @preserve
 */
const isPlainObject = (value) => {
  if (typeof value !== "object" || value === null) {
    return false;
  }
  if (Object.prototype.toString.call(value) !== "[object Object]") {
    return false;
  }
  const proto = Object.getPrototypeOf(value);
  if (proto === null) {
    return true;
  }
  const Ctor = Object.prototype.hasOwnProperty.call(proto, "constructor") && proto.constructor;
  return typeof Ctor === "function" && Ctor instanceof Ctor && Function.prototype.call(Ctor) === Function.prototype.call(value);
};
/**
 * Checks if value is the language type of `Object`. (e.g. arrays, functions, objects, regexes, new Number(0), and new String(’’))
 *
 * @param {*} input - Value to check.
 *
 * @returns {boolean} true if value is an array, false otherwise.
 *
 * Usage:
 * ```js
 * isObject({}) // => true
 * isObject([1, 2, 3]) // => true
 * isObject(() => {}) // => true
 * isObject(null) // => false
 * ```
 *
 * @preserve
 */
const isObject = (input) => input instanceof Object;
/**
 * Performs a deep comparison between two values to determine if they are equivalent.
 *
 * **Note**: works for simple types, arrays, and objects. Might not work for all the types the lodash version supports.
 *
 * @param {*} first First value to compare.
 * @param {*} second Second value to compare.
 *
 * @returns true if the values are equivalent, false otherwise.
 *
 * Usage:
 * ```js
 * isEqual({ a: 1 }, { a: 1 }) // => true
 * isEqual({ a: 1 }, { a: 2 }) // => false
 * isEqual({ a: 1 }, 'b') // => false
 * ```
 *
 * @preserve
 */
const isEqual = (first, second) => {
  if (first === second) {
    return true;
  }
  if ((first === void 0 || second === void 0 || first === null || second === null) && (first || second)) {
    return false;
  }
  const firstType = first?.constructor.name;
  const secondType = second?.constructor.name;
  if (firstType !== secondType) {
    return false;
  }
  if (firstType === "Array") {
    if (first.length !== second.length) {
      return false;
    }
    let equal = true;
    for (let i = 0; i < first.length; i++) {
      if (!isEqual(first[i], second[i])) {
        equal = false;
        break;
      }
    }
    return equal;
  }
  if (firstType === "Object") {
    let equal = true;
    const fKeys = Object.keys(first);
    const sKeys = Object.keys(second);
    if (fKeys.length !== sKeys.length) {
      return false;
    }
    for (let i = 0; i < fKeys.length; i++) {
      if (first[fKeys[i]] && second[fKeys[i]]) {
        if (first[fKeys[i]] === second[fKeys[i]]) {
          continue;
        }
        if (first[fKeys[i]] && (first[fKeys[i]].constructor.name === "Array" || first[fKeys[i]].constructor.name === "Object")) {
          equal = isEqual(first[fKeys[i]], second[fKeys[i]]);
          if (!equal) {
            break;
          }
        } else if (first[fKeys[i]] !== second[fKeys[i]]) {
          equal = false;
          break;
        }
      } else if (first[fKeys[i]] && !second[fKeys[i]] || !first[fKeys[i]] && second[fKeys[i]]) {
        equal = false;
        break;
      }
    }
    return equal;
  }
  return first === second;
};
/**
 * Checks if value is the language type of `String`.
 *
 * @param {*} value - Value to check.
 * @returns {boolean} true if value is a string, false otherwise.
 *
 * Usage:
 * ```js
 * isString('Lorem') // => true
 * isString(2) // => false
 * isString([]) // => false
 * isString(new String('Lorem')) // => false
 * ```
 *
 * @preserve
 */
const isString = (value) => typeof value === "string" || value instanceof String;
export {
  camelCase,
  has,
  isEmpty,
  isEqual,
  isObject,
  isPlainObject,
  isString,
  kebabCase,
  lowerFirst,
  pascalCase,
  snakeCase,
  upperFirst
};
