text: "use strict";
  
  exports.__esModule = true;
  exports.stringify = stringify;
  exports.createReplacer = exports.getNormalizedValue = exports.indexOf = exports.getStringifiedDocumentFragment = exports.getStringifiedArrayBuffer = exports.getStringifiedArrayBufferNoSupport = exports.getStringifiedArrayBufferModern = exports.getStringifiedArrayBufferFallback = exports.getSortedObject = exports.getSortedIterablePairs = exports.sort = exports.getPrefixedValue = exports.shouldSortPair = exports.shouldSort = exports.getSortedEvent = exports.getIntegerHashValue = exports.getCircularValue = exports.getFunctionName = void 0;
  
  var _fastStringify = _interopRequireDefault(require("fast-stringify"));
  
  var _constants = require("./constants");
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  // external dependencies
  // constants
  var charCodeAt = String.prototype.charCodeAt;
  var toString = Object.prototype.toString;
  var keys = Object.keys;
  /**
   * @function getFunctionName
   *
   * @description
   * get the name of the function based on a series of fallback attempts
   *
   * @param {function} fn the function to test
   * @returns {string} the function name
   */
  
  var getFunctionName = function getFunctionName(fn) {
    return fn.name || (fn.toString().match(/^\s*function\s*([^\(]*)/i) || [])[1] || 'anonymous';
  };
  /**
   * @function getCircularValue
   *
   * @description
   * get the value used when circular references are found
   *
   * @returns {string} the value for stringification
   */
  
  
  exports.getFunctionName = getFunctionName;
  
  var getCircularValue = function getCircularValue() {
    return _constants.CIRCULAR_VALUE;
  };
  /**
   * @function getIntegerHashValue
   *
   * @description
   * based on string passed, get the integer hash value
   * through bitwise operation (based on spinoff of dbj2
   * with enhancements for reduced collisions)
   *
   * @param {string} string the string to get the hash value for
   * @returns {number} the hash value
   */
  
  
  exports.getCircularValue = getCircularValue;
  
  var getIntegerHashValue = function getIntegerHashValue(string) {
    var index = string.length,
        hashA = 5381,
        hashB = 52711,
        charCode;
  
    while (index--) {
      charCode = charCodeAt.call(string, index);
      hashA = hashA * 33 ^ charCode;
      hashB = hashB * 33 ^ charCode;
    }
  
    return (hashA >>> 0) * 4096 + (hashB >>> 0);
  };
  /**
   * @function getSortedEvent
   *
   * @description
   * get the event object sorted by its properties
   *
   * @param {boolean} bubbles does the event bubble up through the DOM
   * @param {function} alias to stopPropagation
   * @param {boolean} cancelable is the event cancelable
   * @param {boolean} composed can the event bubble across the boundary to shadow DOM
   * @param {HTMLElement} [currentTarget] registered target for the event
   * @param {boolean} defaultPrevented has preventDefault been called on the event
   * @param {string} eventPhase the phase of the event flow being processed
   * @param {boolean} isTrusted was the event initiated by the browser
   * @param {HTMLElement} [target] the target with which the event was dispatched
   * @param {number} timeStamp the time at which the event was created
   * @param {string} type the name of the event
   * @returns {Object} the event object with all properties sorted
   */
  
  
  exports.getIntegerHashValue = getIntegerHashValue;
  
  var getSortedEvent = function getSortedEvent(_ref) {
    var bubbles = _ref.bubbles,
        cancelBubble = _ref.cancelBubble,
        cancelable = _ref.cancelable,
        composed = _ref.composed,
        currentTarget = _ref.currentTarget,
        defaultPrevented = _ref.defaultPrevented,
        eventPhase = _ref.eventPhase,
        isTrusted = _ref.isTrusted,
        returnValue = _ref.returnValue,
        target = _ref.target,
        type = _ref.type;
    return {
      bubbles: bubbles,
      cancelBubble: cancelBubble,
      cancelable: cancelable,
      composed: composed,
      currentTarget: currentTarget,
      defaultPrevented: defaultPrevented,
      eventPhase: eventPhase,
      isTrusted: isTrusted,
      returnValue: returnValue,
      target: target,
      type: type
    };
  };
  /**
   * @function shouldSort
   *
   * @description
   * get the sort result based on the two values to compare
   *
   * @param {string} valueA the first value to compare
   * @param {string} valueB the second value to compare
   * @returns {boolean} should the value be sorted
   */
  
  
  exports.getSortedEvent = getSortedEvent;
  
  var shouldSort = function shouldSort(valueA, valueB) {
    return valueA > valueB;
  };
  /**
   * @function shouldSortPair
   *
   * @description
   * get the sort result based on the two pairs to compare
   *
   * @param {Object} pairA the first pair to compare
   * @param {Object} pairB the second pair to compare
   * @returns {boolean} should the value be sorted
   */
  
  
  exports.shouldSort = shouldSort;
  
  var shouldSortPair = function shouldSortPair(pairA, pairB) {
    return shouldSort(pairA[0], pairB[0]);
  };
  /**
   * @function getPrefixedValue
   *
   * @description
   * get the value prefixed by the tag
   *
   * @param {string} tag the object tag
   * @param {any} value the value to stringify
   * @returns {string} the prefixed stringified value
   */
  
  
  exports.shouldSortPair = shouldSortPair;
  
  var getPrefixedValue = function getPrefixedValue(tag, value) {
    return tag + "|" + value;
  };
  /**
   * @function sort
   *
   * @description
   * sort the array based on the fn passed
   *
   * @param {Array<any>} array the array to sort
   * @param {function} fn the sorting function
   * @returns {Array<any>} the sorted array
   */
  
  
  exports.getPrefixedValue = getPrefixedValue;
  
  var sort = function sort(array, fn) {
    var subIndex, value;
  
    for (var index = 0; index < array.length; index++) {
      value = array[index];
  
      for (subIndex = index - 1; ~subIndex && fn(array[subIndex], value); subIndex--) {
        array[subIndex + 1] = array[subIndex];
      }
  
      array[subIndex + 1] = value;
    }
  
    return array;
  };
  /**
   * @function getIterablePairs
   *
   * @description
   * get the pairs in the iterable for stringification
   *
   * @param {Map|Set} iterable the iterable to get the pairs for
   * @returns {Array<{key: string, value: any}>} the pairs
   */
  
  
  exports.sort = sort;
  
  var getSortedIterablePairs = function getSortedIterablePairs(iterable) {
    var isMap = typeof iterable.get === 'function';
    var pairs = [];
    iterable.forEach(function (value, key) {
      // eslint-disable-next-line no-use-before-define
      pairs.push(isMap ? [stringify(key), stringify(value)] : [stringify(value)]);
    });
    sort(pairs, shouldSortPair);
    var finalPairs = new Array(iterable.size);
    var pair;
  
    for (var index = 0; index < iterable.size; index++) {
      pair = pairs[index];
      finalPairs[index] = isMap ? "[" + pair[0] + "," + pair[1] + "]" : pair[0];
    }
  
    return getPrefixedValue(getFunctionName(iterable.constructor), "[" + finalPairs.join(',') + "]");
  };
  /**
   * @function getSortedObject
   *
   * @description
   * get the object with the keys sorted
   *
   * @param {Object} object the object to sort
   * @returns {Object} the sorted object
   */
  
  
  exports.getSortedIterablePairs = getSortedIterablePairs;
  
  var getSortedObject = function getSortedObject(object) {
    var objectKeys = sort(keys(object), shouldSort);
    var newObject = {};
    var key;
  
    for (var index = 0; index < objectKeys.length; index++) {
      key = objectKeys[index];
      newObject[key] = object[key];
    }
  
    return newObject;
  };
  /**
   * @function getStringifiedArrayBufferFallback
   *
   * @description
   * get the string value of the buffer passed based on a Buffer
   *
   * @param {ArrayBuffer} buffer the array buffer to convert
   * @returns {string} the stringified buffer
   */
  
  
  exports.getSortedObject = getSortedObject;
  
  var getStringifiedArrayBufferFallback = function getStringifiedArrayBufferFallback(buffer) {
    return String.fromCharCode.apply(null, new Uint16Array(buffer));
  };
  /**
   * @function getStringifiedArrayBufferModern
   *
   * @description
   * get the string value of the buffer passed based on a Uint16Array
   *
   * @param {ArrayBuffer} buffer the array buffer to convert
   * @returns {string} the stringified buffer
   */
  
  
  exports.getStringifiedArrayBufferFallback = getStringifiedArrayBufferFallback;
  
  var getStringifiedArrayBufferModern = function getStringifiedArrayBufferModern(buffer) {
    return Buffer.from(buffer).toString('utf8');
  };
  /**
   * @function getStringifiedArrayBufferNoSupport
   *
   * @description
   * return a placeholder when no arraybuffer support exists
   *
   * @returns {string} the placeholder
   */
  
  
  exports.getStringifiedArrayBufferModern = getStringifiedArrayBufferModern;
  
  var getStringifiedArrayBufferNoSupport = function getStringifiedArrayBufferNoSupport() {
    return '';
  };
  /**
   * @function getStringifiedArrayBuffer
   *
   * @description
   * get the string value of the buffer passed
   *
   * @param {ArrayBuffer} buffer the array buffer to convert
   * @returns {string} the stringified buffer
   */
  
  
  exports.getStringifiedArrayBufferNoSupport = getStringifiedArrayBufferNoSupport;
  
  var getStringifiedArrayBuffer = function () {
    if (_constants.HAS_BUFFER_FROM_SUPPORT) {
      return getStringifiedArrayBufferModern;
    }
  
    if (_constants.HAS_UINT16ARRAY_SUPPORT) {
      return getStringifiedArrayBufferFallback;
    }
  
    return getStringifiedArrayBufferNoSupport;
  }();
  /**
   * @function getStringifiedDocumentFragment
   *
   * @description
   * build a string based on all the fragment's children
   *
   * @param {DocumentFragment} fragment the fragment to stringify
   * @returns {string} the stringified fragment
   */
  
  
  exports.getStringifiedArrayBuffer = getStringifiedArrayBuffer;
  
  var getStringifiedDocumentFragment = function getStringifiedDocumentFragment(fragment) {
    var children = fragment.children;
    var innerHTML = '';
  
    for (var index = 0; index < children.length; index++) {
      innerHTML += children[index].outerHTML;
    }
  
    return innerHTML;
  };
  /**
   * @function indexOf
   *
   * @description
   * get the index of the value in the array (faster than native indexOf)
   *
   * @param {Array<any>} array the array to get the index of the value at
   * @param {any} value the value to match
   * @returns {number} the index of the value in array
   */
  
  
  exports.getStringifiedDocumentFragment = getStringifiedDocumentFragment;
  
  var indexOf = function indexOf(array, value) {
    for (var index = 0; index < array.length; index++) {
      if (array[index] === value) {
        return index;
      }
    }
  
    return -1;
  };
  /**
   * @function getNormalizedValue
   *
   * @description
   * get the value normalized for stringification
   *
   * @param {any} value the value to normalize
   * @param {WeakMap|Object} sortedCache the cache of sorted objects
   * @param {string} [passedTag] the previously-calculated tag
   * @returns {any} the normalized value
   */
  
  
  exports.indexOf = indexOf;
  
  var getNormalizedValue = function getNormalizedValue(value, sortedCache, passedTag) {
    if (passedTag === void 0) {
      var type = typeof value;
  
      if (type === 'string') {
        return value;
      }
  
      if (_constants.PRIMITIVE_TAGS[type]) {
        return getPrefixedValue(type, value);
      }
  
      if (value === null) {
        return getPrefixedValue('null', value);
      }
    }
  
    var tag = passedTag || toString.call(value);
  
    if (_constants.SELF_TAGS[tag]) {
      return value;
    }
  
    if (tag === _constants.OBJECT_CLASS_TYPE_MAP.OBJECT) {
      if (~indexOf(sortedCache, value)) {
        return _constants.CIRCULAR_VALUE;
      }
  
      sortedCache.push(value);
      return getSortedObject(value, sortedCache);
    }
  
    if (_constants.TOSTRING_TAGS[tag]) {
      return getPrefixedValue(_constants.OBJECT_CLASS_MAP[tag], value.toString());
    }
  
    if (_constants.ITERABLE_TAGS[tag]) {
      if (~indexOf(sortedCache, value)) {
        return _constants.CIRCULAR_VALUE;
      }
  
      sortedCache.push(value);
      return getSortedIterablePairs(value);
    }
  
    if (tag === _constants.OBJECT_CLASS_TYPE_MAP.DATE) {
      return getPrefixedValue(_constants.OBJECT_CLASS_MAP[tag], value.getTime());
    }
  
    if (tag === _constants.OBJECT_CLASS_TYPE_MAP.ERROR) {
      return getPrefixedValue(_constants.OBJECT_CLASS_MAP[tag], value.stack);
    }
  
    if (tag === _constants.OBJECT_CLASS_TYPE_MAP.EVENT) {
      return getSortedEvent(value);
    }
  
    if (_constants.UNPARSEABLE_TAGS[tag]) {
      return getPrefixedValue(_constants.OBJECT_CLASS_MAP[tag], 'NOT_ENUMERABLE');
    }
  
    if (_constants.HTML_ELEMENT_REGEXP.test(tag) || _constants.SVG_ELEMENT_REGEXP.test(tag)) {
      return getPrefixedValue(tag.slice(8, -1), value.outerHTML);
    }
  
    if (tag === _constants.OBJECT_CLASS_TYPE_MAP.DOCUMENTFRAGMENT) {
      return getPrefixedValue(_constants.OBJECT_CLASS_MAP[tag], getStringifiedDocumentFragment(value));
    }
  
    if (_constants.TYPEDARRAY_TAGS[tag]) {
      return getPrefixedValue(_constants.OBJECT_CLASS_MAP[tag], value.join(','));
    }
  
    if (tag === _constants.OBJECT_CLASS_TYPE_MAP.ARRAYBUFFER) {
      return getPrefixedValue(_constants.OBJECT_CLASS_MAP[tag], getStringifiedArrayBuffer(value));
    }
  
    if (tag === _constants.OBJECT_CLASS_TYPE_MAP.DATAVIEW) {
      return getPrefixedValue(_constants.OBJECT_CLASS_MAP[tag], getStringifiedArrayBuffer(value.buffer));
    }
  
    return value;
  };
  /**
   * @function replacer
   *
   * @description
   * create the replacer function used for stringification
   *
   * @param {WeakSet|Object} sortedCache the cache to use for sorting objects
   * @returns {function(key: string, value: any)} function getting the normalized value
   */
  
  
  exports.getNormalizedValue = getNormalizedValue;
  
  var createReplacer = function createReplacer(sortedCache) {
    return function (key, value) {
      return getNormalizedValue(value, sortedCache);
    };
  };
  /**
   * @function stringify
   *
   * @description
   * stringify the value based on the options passed
   *
   * @param {any} value the value to stringify
   * @returns {string} the stringified value
   */
  
  
  exports.createReplacer = createReplacer;
  
  function stringify(value) {
    if (!value || typeof value !== 'object') {
      return getNormalizedValue(value);
    }
  
    var tag = toString.call(value);
    return tag === _constants.OBJECT_CLASS_TYPE_MAP.DATE || tag === _constants.OBJECT_CLASS_TYPE_MAP.REGEXP ? getNormalizedValue(value, void 0, tag) : (0, _fastStringify.default)(value, createReplacer([]), null, getCircularValue);
  }