import { r as registerInstance, c as createEvent, h, g as getElement } from './index-BIwHMk6j.js';
import { b as n, r as rt, c as it, L as Le } from './index.esm-CMeGYws2.js';
import { A as ARROW_DOWN, a as ESCAPE, b as ARROW_UP, E as ENTER, T as TAB } from './keycodes-CwMJvF_Z.js';
import { o as overArg, U as Uint8Array, c as isPrototype, a as getTag, d as baseUnary, n as nodeUtil, i as isBuffer, S as Stack, g as getAllKeys } from './_Uint8Array-CUI8uY-p.js';
import { d as defineProperty } from './_defineProperty-DZ483KPn.js';
import { c as isObject, e as eq, S as Symbol, i as isObjectLike, a as isArray, r as root } from './_MapCache-BgAfMcRA.js';
import { c as createRandomString } from './random-string-C2JP2nLw.js';
import { h as hasHasManyRelation, b as hasLabel, c as getRelationProperty } from './limetype-DvPoeXt-.js';
import { i as isNonNull } from './non-null-CkTg5UPD.js';
import { i as isSymbol } from './isSymbol-_IkM6xCs.js';

/** Used to match a single whitespace character. */
var reWhitespace = /\s/;

/**
 * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
 * character of `string`.
 *
 * @private
 * @param {string} string The string to inspect.
 * @returns {number} Returns the index of the last non-whitespace character.
 */
function trimmedEndIndex(string) {
  var index = string.length;

  while (index-- && reWhitespace.test(string.charAt(index))) {}
  return index;
}

/** Used to match leading whitespace. */
var reTrimStart = /^\s+/;

/**
 * The base implementation of `_.trim`.
 *
 * @private
 * @param {string} string The string to trim.
 * @returns {string} Returns the trimmed string.
 */
function baseTrim(string) {
  return string
    ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
    : string;
}

/** Used as references for various `Number` constants. */
var NAN = 0 / 0;

/** Used to detect bad signed hexadecimal string values. */
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;

/** Used to detect binary string values. */
var reIsBinary = /^0b[01]+$/i;

/** Used to detect octal string values. */
var reIsOctal = /^0o[0-7]+$/i;

/** Built-in method references without a dependency on `root`. */
var freeParseInt = parseInt;

/**
 * Converts `value` to a number.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to process.
 * @returns {number} Returns the number.
 * @example
 *
 * _.toNumber(3.2);
 * // => 3.2
 *
 * _.toNumber(Number.MIN_VALUE);
 * // => 5e-324
 *
 * _.toNumber(Infinity);
 * // => Infinity
 *
 * _.toNumber('3.2');
 * // => 3.2
 */
function toNumber(value) {
  if (typeof value == 'number') {
    return value;
  }
  if (isSymbol(value)) {
    return NAN;
  }
  if (isObject(value)) {
    var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
    value = isObject(other) ? (other + '') : other;
  }
  if (typeof value != 'string') {
    return value === 0 ? value : +value;
  }
  value = baseTrim(value);
  var isBinary = reIsBinary.test(value);
  return (isBinary || reIsOctal.test(value))
    ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
    : (reIsBadHex.test(value) ? NAN : +value);
}

/** Built-in value references. */
var objectCreate = Object.create;

/**
 * The base implementation of `_.create` without support for assigning
 * properties to the created object.
 *
 * @private
 * @param {Object} proto The object to inherit from.
 * @returns {Object} Returns the new object.
 */
var baseCreate = (function() {
  function object() {}
  return function(proto) {
    if (!isObject(proto)) {
      return {};
    }
    if (objectCreate) {
      return objectCreate(proto);
    }
    object.prototype = proto;
    var result = new object;
    object.prototype = undefined;
    return result;
  };
}());

/**
 * A specialized version of `_.forEach` for arrays without support for
 * iteratee shorthands.
 *
 * @private
 * @param {Array} [array] The array to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array} Returns `array`.
 */
function arrayEach(array, iteratee) {
  var index = -1,
      length = array == null ? 0 : array.length;

  while (++index < length) {
    if (iteratee(array[index], index, array) === false) {
      break;
    }
  }
  return array;
}

/**
 * The base implementation of `assignValue` and `assignMergeValue` without
 * value checks.
 *
 * @private
 * @param {Object} object The object to modify.
 * @param {string} key The key of the property to assign.
 * @param {*} value The value to assign.
 */
function baseAssignValue(object, key, value) {
  if (key == '__proto__' && defineProperty) {
    defineProperty(object, key, {
      'configurable': true,
      'enumerable': true,
      'value': value,
      'writable': true
    });
  } else {
    object[key] = value;
  }
}

/** Used for built-in method references. */
var objectProto$1 = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty$1 = objectProto$1.hasOwnProperty;

/**
 * Assigns `value` to `key` of `object` if the existing value is not equivalent
 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
 * for equality comparisons.
 *
 * @private
 * @param {Object} object The object to modify.
 * @param {string} key The key of the property to assign.
 * @param {*} value The value to assign.
 */
function assignValue(object, key, value) {
  var objValue = object[key];
  if (!(hasOwnProperty$1.call(object, key) && eq(objValue, value)) ||
      (value === undefined && !(key in object))) {
    baseAssignValue(object, key, value);
  }
}

/** Built-in value references. */
var getPrototype = overArg(Object.getPrototypeOf, Object);

/** Detect free variable `exports`. */
var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;

/** Detect free variable `module`. */
freeExports && typeof module == 'object' && module && !module.nodeType && module;

/**
 * Creates a clone of  `buffer`.
 *
 * @private
 * @param {Buffer} buffer The buffer to clone.
 * @param {boolean} [isDeep] Specify a deep clone.
 * @returns {Buffer} Returns the cloned buffer.
 */
function cloneBuffer(buffer, isDeep) {
  {
    return buffer.slice();
  }
}

/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Initializes an array clone.
 *
 * @private
 * @param {Array} array The array to clone.
 * @returns {Array} Returns the initialized clone.
 */
function initCloneArray(array) {
  var length = array.length,
      result = new array.constructor(length);

  // Add properties assigned by `RegExp#exec`.
  if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
    result.index = array.index;
    result.input = array.input;
  }
  return result;
}

/**
 * Creates a clone of `arrayBuffer`.
 *
 * @private
 * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
 * @returns {ArrayBuffer} Returns the cloned array buffer.
 */
function cloneArrayBuffer(arrayBuffer) {
  var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
  new Uint8Array(result).set(new Uint8Array(arrayBuffer));
  return result;
}

/**
 * Creates a clone of `dataView`.
 *
 * @private
 * @param {Object} dataView The data view to clone.
 * @param {boolean} [isDeep] Specify a deep clone.
 * @returns {Object} Returns the cloned data view.
 */
function cloneDataView(dataView, isDeep) {
  var buffer = cloneArrayBuffer(dataView.buffer) ;
  return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
}

/** Used to match `RegExp` flags from their coerced string values. */
var reFlags = /\w*$/;

/**
 * Creates a clone of `regexp`.
 *
 * @private
 * @param {Object} regexp The regexp to clone.
 * @returns {Object} Returns the cloned regexp.
 */
function cloneRegExp(regexp) {
  var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
  result.lastIndex = regexp.lastIndex;
  return result;
}

/** Used to convert symbols to primitives and strings. */
var symbolProto = Symbol ? Symbol.prototype : undefined,
    symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;

/**
 * Creates a clone of the `symbol` object.
 *
 * @private
 * @param {Object} symbol The symbol object to clone.
 * @returns {Object} Returns the cloned symbol object.
 */
function cloneSymbol(symbol) {
  return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
}

/**
 * Creates a clone of `typedArray`.
 *
 * @private
 * @param {Object} typedArray The typed array to clone.
 * @param {boolean} [isDeep] Specify a deep clone.
 * @returns {Object} Returns the cloned typed array.
 */
function cloneTypedArray(typedArray, isDeep) {
  var buffer = cloneArrayBuffer(typedArray.buffer) ;
  return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
}

/** `Object#toString` result references. */
var boolTag$1 = '[object Boolean]',
    dateTag$1 = '[object Date]',
    mapTag$2 = '[object Map]',
    numberTag$1 = '[object Number]',
    regexpTag$1 = '[object RegExp]',
    setTag$2 = '[object Set]',
    stringTag$1 = '[object String]',
    symbolTag$1 = '[object Symbol]';

var arrayBufferTag$1 = '[object ArrayBuffer]',
    dataViewTag$1 = '[object DataView]',
    float32Tag$1 = '[object Float32Array]',
    float64Tag$1 = '[object Float64Array]',
    int8Tag$1 = '[object Int8Array]',
    int16Tag$1 = '[object Int16Array]',
    int32Tag$1 = '[object Int32Array]',
    uint8Tag$1 = '[object Uint8Array]',
    uint8ClampedTag$1 = '[object Uint8ClampedArray]',
    uint16Tag$1 = '[object Uint16Array]',
    uint32Tag$1 = '[object Uint32Array]';

/**
 * Initializes an object clone based on its `toStringTag`.
 *
 * **Note:** This function only supports cloning values with tags of
 * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
 *
 * @private
 * @param {Object} object The object to clone.
 * @param {string} tag The `toStringTag` of the object to clone.
 * @param {boolean} [isDeep] Specify a deep clone.
 * @returns {Object} Returns the initialized clone.
 */
function initCloneByTag(object, tag, isDeep) {
  var Ctor = object.constructor;
  switch (tag) {
    case arrayBufferTag$1:
      return cloneArrayBuffer(object);

    case boolTag$1:
    case dateTag$1:
      return new Ctor(+object);

    case dataViewTag$1:
      return cloneDataView(object);

    case float32Tag$1: case float64Tag$1:
    case int8Tag$1: case int16Tag$1: case int32Tag$1:
    case uint8Tag$1: case uint8ClampedTag$1: case uint16Tag$1: case uint32Tag$1:
      return cloneTypedArray(object);

    case mapTag$2:
      return new Ctor;

    case numberTag$1:
    case stringTag$1:
      return new Ctor(object);

    case regexpTag$1:
      return cloneRegExp(object);

    case setTag$2:
      return new Ctor;

    case symbolTag$1:
      return cloneSymbol(object);
  }
}

/**
 * Initializes an object clone.
 *
 * @private
 * @param {Object} object The object to clone.
 * @returns {Object} Returns the initialized clone.
 */
function initCloneObject(object) {
  return (typeof object.constructor == 'function' && !isPrototype(object))
    ? baseCreate(getPrototype(object))
    : {};
}

/** `Object#toString` result references. */
var mapTag$1 = '[object Map]';

/**
 * The base implementation of `_.isMap` without Node.js optimizations.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
 */
function baseIsMap(value) {
  return isObjectLike(value) && getTag(value) == mapTag$1;
}

/* Node.js helper references. */
var nodeIsMap = nodeUtil && nodeUtil.isMap;

/**
 * Checks if `value` is classified as a `Map` object.
 *
 * @static
 * @memberOf _
 * @since 4.3.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
 * @example
 *
 * _.isMap(new Map);
 * // => true
 *
 * _.isMap(new WeakMap);
 * // => false
 */
var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;

/** `Object#toString` result references. */
var setTag$1 = '[object Set]';

/**
 * The base implementation of `_.isSet` without Node.js optimizations.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
 */
function baseIsSet(value) {
  return isObjectLike(value) && getTag(value) == setTag$1;
}

/* Node.js helper references. */
var nodeIsSet = nodeUtil && nodeUtil.isSet;

/**
 * Checks if `value` is classified as a `Set` object.
 *
 * @static
 * @memberOf _
 * @since 4.3.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
 * @example
 *
 * _.isSet(new Set);
 * // => true
 *
 * _.isSet(new WeakSet);
 * // => false
 */
var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;

/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
    arrayTag = '[object Array]',
    boolTag = '[object Boolean]',
    dateTag = '[object Date]',
    errorTag = '[object Error]',
    funcTag = '[object Function]',
    genTag = '[object GeneratorFunction]',
    mapTag = '[object Map]',
    numberTag = '[object Number]',
    objectTag = '[object Object]',
    regexpTag = '[object RegExp]',
    setTag = '[object Set]',
    stringTag = '[object String]',
    symbolTag = '[object Symbol]',
    weakMapTag = '[object WeakMap]';

var arrayBufferTag = '[object ArrayBuffer]',
    dataViewTag = '[object DataView]',
    float32Tag = '[object Float32Array]',
    float64Tag = '[object Float64Array]',
    int8Tag = '[object Int8Array]',
    int16Tag = '[object Int16Array]',
    int32Tag = '[object Int32Array]',
    uint8Tag = '[object Uint8Array]',
    uint8ClampedTag = '[object Uint8ClampedArray]',
    uint16Tag = '[object Uint16Array]',
    uint32Tag = '[object Uint32Array]';

/** Used to identify `toStringTag` values supported by `_.clone`. */
var cloneableTags = {};
cloneableTags[argsTag] = cloneableTags[arrayTag] =
cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
cloneableTags[boolTag] = cloneableTags[dateTag] =
cloneableTags[float32Tag] = cloneableTags[float64Tag] =
cloneableTags[int8Tag] = cloneableTags[int16Tag] =
cloneableTags[int32Tag] = cloneableTags[mapTag] =
cloneableTags[numberTag] = cloneableTags[objectTag] =
cloneableTags[regexpTag] = cloneableTags[setTag] =
cloneableTags[stringTag] = cloneableTags[symbolTag] =
cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
cloneableTags[errorTag] = cloneableTags[funcTag] =
cloneableTags[weakMapTag] = false;

/**
 * The base implementation of `_.clone` and `_.cloneDeep` which tracks
 * traversed objects.
 *
 * @private
 * @param {*} value The value to clone.
 * @param {boolean} bitmask The bitmask flags.
 *  1 - Deep clone
 *  2 - Flatten inherited properties
 *  4 - Clone symbols
 * @param {Function} [customizer] The function to customize cloning.
 * @param {string} [key] The key of `value`.
 * @param {Object} [object] The parent object of `value`.
 * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
 * @returns {*} Returns the cloned value.
 */
function baseClone(value, bitmask, customizer, key, object, stack) {
  var result;
  if (result !== undefined) {
    return result;
  }
  if (!isObject(value)) {
    return value;
  }
  var isArr = isArray(value);
  if (isArr) {
    result = initCloneArray(value);
  } else {
    var tag = getTag(value),
        isFunc = tag == funcTag || tag == genTag;

    if (isBuffer(value)) {
      return cloneBuffer(value);
    }
    if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
      result = (isFunc) ? {} : initCloneObject(value);
    } else {
      if (!cloneableTags[tag]) {
        return object ? value : {};
      }
      result = initCloneByTag(value, tag);
    }
  }
  // Check for circular references and return its corresponding clone.
  stack || (stack = new Stack);
  var stacked = stack.get(value);
  if (stacked) {
    return stacked;
  }
  stack.set(value, result);

  if (isSet(value)) {
    value.forEach(function(subValue) {
      result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
    });
  } else if (isMap(value)) {
    value.forEach(function(subValue, key) {
      result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
    });
  }

  var keysFunc = (getAllKeys)
    ;

  var props = isArr ? undefined : keysFunc(value);
  arrayEach(props || value, function(subValue, key) {
    if (props) {
      key = subValue;
      subValue = value[key];
    }
    // Recursively populate clone (susceptible to call stack limits).
    assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
  });
  return result;
}

/** Used to compose bitmasks for cloning. */
var CLONE_DEEP_FLAG = 1,
    CLONE_SYMBOLS_FLAG = 4;

/**
 * This method is like `_.clone` except that it recursively clones `value`.
 *
 * @static
 * @memberOf _
 * @since 1.0.0
 * @category Lang
 * @param {*} value The value to recursively clone.
 * @returns {*} Returns the deep cloned value.
 * @see _.clone
 * @example
 *
 * var objects = [{ 'a': 1 }, { 'b': 2 }];
 *
 * var deep = _.cloneDeep(objects);
 * console.log(deep[0] === objects[0]);
 * // => false
 */
function cloneDeep(value) {
  return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
}

/**
 * Gets the timestamp of the number of milliseconds that have elapsed since
 * the Unix epoch (1 January 1970 00:00:00 UTC).
 *
 * @static
 * @memberOf _
 * @since 2.4.0
 * @category Date
 * @returns {number} Returns the timestamp.
 * @example
 *
 * _.defer(function(stamp) {
 *   console.log(_.now() - stamp);
 * }, _.now());
 * // => Logs the number of milliseconds it took for the deferred invocation.
 */
var now = function() {
  return root.Date.now();
};

/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
    nativeMin = Math.min;

/**
 * Creates a debounced function that delays invoking `func` until after `wait`
 * milliseconds have elapsed since the last time the debounced function was
 * invoked. The debounced function comes with a `cancel` method to cancel
 * delayed `func` invocations and a `flush` method to immediately invoke them.
 * Provide `options` to indicate whether `func` should be invoked on the
 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
 * with the last arguments provided to the debounced function. Subsequent
 * calls to the debounced function return the result of the last `func`
 * invocation.
 *
 * **Note:** If `leading` and `trailing` options are `true`, `func` is
 * invoked on the trailing edge of the timeout only if the debounced function
 * is invoked more than once during the `wait` timeout.
 *
 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
 *
 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
 * for details over the differences between `_.debounce` and `_.throttle`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Function
 * @param {Function} func The function to debounce.
 * @param {number} [wait=0] The number of milliseconds to delay.
 * @param {Object} [options={}] The options object.
 * @param {boolean} [options.leading=false]
 *  Specify invoking on the leading edge of the timeout.
 * @param {number} [options.maxWait]
 *  The maximum time `func` is allowed to be delayed before it's invoked.
 * @param {boolean} [options.trailing=true]
 *  Specify invoking on the trailing edge of the timeout.
 * @returns {Function} Returns the new debounced function.
 * @example
 *
 * // Avoid costly calculations while the window size is in flux.
 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
 *
 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
 * jQuery(element).on('click', _.debounce(sendMail, 300, {
 *   'leading': true,
 *   'trailing': false
 * }));
 *
 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
 * var source = new EventSource('/stream');
 * jQuery(source).on('message', debounced);
 *
 * // Cancel the trailing debounced invocation.
 * jQuery(window).on('popstate', debounced.cancel);
 */
function debounce(func, wait, options) {
  var lastArgs,
      lastThis,
      maxWait,
      result,
      timerId,
      lastCallTime,
      lastInvokeTime = 0,
      leading = false,
      maxing = false,
      trailing = true;

  if (typeof func != 'function') {
    throw new TypeError(FUNC_ERROR_TEXT);
  }
  wait = toNumber(wait) || 0;
  if (isObject(options)) {
    leading = !!options.leading;
    maxing = 'maxWait' in options;
    maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
    trailing = 'trailing' in options ? !!options.trailing : trailing;
  }

  function invokeFunc(time) {
    var args = lastArgs,
        thisArg = lastThis;

    lastArgs = lastThis = undefined;
    lastInvokeTime = time;
    result = func.apply(thisArg, args);
    return result;
  }

  function leadingEdge(time) {
    // Reset any `maxWait` timer.
    lastInvokeTime = time;
    // Start the timer for the trailing edge.
    timerId = setTimeout(timerExpired, wait);
    // Invoke the leading edge.
    return leading ? invokeFunc(time) : result;
  }

  function remainingWait(time) {
    var timeSinceLastCall = time - lastCallTime,
        timeSinceLastInvoke = time - lastInvokeTime,
        timeWaiting = wait - timeSinceLastCall;

    return maxing
      ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
      : timeWaiting;
  }

  function shouldInvoke(time) {
    var timeSinceLastCall = time - lastCallTime,
        timeSinceLastInvoke = time - lastInvokeTime;

    // Either this is the first call, activity has stopped and we're at the
    // trailing edge, the system time has gone backwards and we're treating
    // it as the trailing edge, or we've hit the `maxWait` limit.
    return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
      (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
  }

  function timerExpired() {
    var time = now();
    if (shouldInvoke(time)) {
      return trailingEdge(time);
    }
    // Restart the timer.
    timerId = setTimeout(timerExpired, remainingWait(time));
  }

  function trailingEdge(time) {
    timerId = undefined;

    // Only invoke if we have `lastArgs` which means `func` has been
    // debounced at least once.
    if (trailing && lastArgs) {
      return invokeFunc(time);
    }
    lastArgs = lastThis = undefined;
    return result;
  }

  function cancel() {
    if (timerId !== undefined) {
      clearTimeout(timerId);
    }
    lastInvokeTime = 0;
    lastArgs = lastCallTime = lastThis = timerId = undefined;
  }

  function flush() {
    return timerId === undefined ? result : trailingEdge(now());
  }

  function debounced() {
    var time = now(),
        isInvoking = shouldInvoke(time);

    lastArgs = arguments;
    lastThis = this;
    lastCallTime = time;

    if (isInvoking) {
      if (timerId === undefined) {
        return leadingEdge(lastCallTime);
      }
      if (maxing) {
        // Handle invocations in a tight loop.
        clearTimeout(timerId);
        timerId = setTimeout(timerExpired, wait);
        return invokeFunc(lastCallTime);
      }
    }
    if (timerId === undefined) {
      timerId = setTimeout(timerExpired, wait);
    }
    return result;
  }
  debounced.cancel = cancel;
  debounced.flush = flush;
  return debounced;
}

const getItemIndex = (direction, currentItemIndex, numberOfItems) => {
    const increment = direction === ARROW_DOWN ? 1 : -1;
    return (currentItemIndex + increment + numberOfItems) % numberOfItems;
};
/**
 *
 * @param items
 * @param highlightedItemIndex
 */
function getUpdatedItems(items, highlightedItemIndex) {
    return items.map((item, index) => {
        const newItem = cloneDeep(item);
        return Object.assign(Object.assign({}, newItem), { selected: index === highlightedItemIndex });
    });
}

/**
 * Get the limetypes that should be available for mentions
 *
 * @param limetypes all limetypes
 * @returns mention limetypes
 */
function getMentionLimetypes(limetypes) {
    return Object.values(limetypes).filter((limetype) => {
        return (hasLabel(limetype, 'user') || hasHasManyRelation(limetype, 'user'));
    });
}
const MAX_MENTION_SEARCH_RESULTS = 10;
class MentionsService {
    get limeObjectService() {
        return this.platform.get(n.LimeObjectRepository);
    }
    get queryService() {
        return this.platform.get(n.Query);
    }
    get viewFactoryRegistry() {
        return this.platform.get(n.ViewFactoryRegistry);
    }
    get translator() {
        var _a;
        return (_a = this.platform) === null || _a === void 0 ? void 0 : _a.get(n.Translate);
    }
    get triggerCharacter() {
        return this._triggerCharacter;
    }
    get triggerHandler() {
        return this._triggerHandler;
    }
    constructor(platform, context, searchableLimetypes) {
        this.platform = platform;
        this.context = context;
        this.searchableLimetypes = searchableLimetypes;
        this.groupCounts = {};
        this._triggerCharacter = '@';
        this._triggerHandler = {
            searcher: (query) => this.searcher(query),
            inserter: (triggerFunction, item) => this.inserter(triggerFunction, item),
            emptySearchMessage: 'Start typing a name...',
            noItemsFoundMessage: 'No results for your search...',
            nodeDefinition: {
                customElement: {
                    tagName: 'limebb-mention',
                    attributes: ['limetype', 'objectid', 'href'],
                },
                mapAttributes: (item) => ({
                    limetype: item.value.getLimetype().name,
                    objectid: item.value.id,
                    href: `object/${this.context.limetype}/${this.context.id}`,
                }),
            },
        };
        this.searcher = async (query) => {
            if (!query) {
                return [];
            }
            const { objects } = await this.limeObjectService.search(query, this.searchableLimetypes, MAX_MENTION_SEARCH_RESULTS);
            return this.createSearchListItems(objects);
        };
        this.inserter = async (triggerFunction, item) => {
            var _a;
            const nodeDefinition = this.triggerHandler.nodeDefinition;
            if (!nodeDefinition) {
                return;
            }
            triggerFunction.insert({
                node: {
                    tagName: nodeDefinition.customElement.tagName,
                    attributes: nodeDefinition.mapAttributes(item),
                },
                children: [(_a = item.value) === null || _a === void 0 ? void 0 : _a.descriptive],
            });
        };
    }
    async initialize() {
        await this.loadGroupCounts();
    }
    async loadGroupCounts() {
        const groupCountsLoads = this.searchableLimetypes
            .filter((limetype) => !hasLabel(limetype, 'user') &&
            hasHasManyRelation(limetype, 'user'))
            .map((limetype) => this.getGroupCounts(limetype));
        for (const groupCount of await Promise.all(groupCountsLoads)) {
            Object.assign(this.groupCounts, groupCount);
        }
    }
    async getGroupCounts(limetype) {
        var _a;
        const coworkerProperty = getRelationProperty(limetype, 'user');
        const limetypeName = limetype.name;
        try {
            const result = await this.queryService.execute({
                limetype: limetypeName,
                responseFormat: {
                    object: {
                        _id: null,
                        [coworkerProperty.name]: {
                            count: {
                                aggregate: {
                                    op: rt.Count,
                                },
                            },
                        },
                    },
                },
            });
            if (!((_a = result.objects) === null || _a === void 0 ? void 0 : _a.length)) {
                return { [limetypeName]: {} };
            }
            const groupCount = this.createGroupCount(result.objects, coworkerProperty.name);
            return { [limetypeName]: groupCount };
        }
        catch (error) {
            console.error(`Error fetching group count for limetype: ${limetype.name}`, error);
            return { [limetypeName]: {} };
        }
    }
    createGroupCount(objects, coworkerPropertyName) {
        const groupCount = {};
        for (const object of objects) {
            const { _id: id, [coworkerPropertyName]: aggregateProperty } = object;
            groupCount[id] = aggregateProperty.count;
        }
        return groupCount;
    }
    createSearchListItems(searchObjects = []) {
        const items = searchObjects.map((object) => this.createSearchListItem(object));
        return items.filter(isNonNull);
    }
    createSearchListItem(object) {
        const createSearchItem = this.viewFactoryRegistry.getFactory('search');
        const limeobject = this.limeObjectService.getObject(object._limetype, object._id);
        if (!limeobject) {
            return null;
        }
        const searchListItem = createSearchItem(limeobject, this.context);
        const primaryComponent = this.getGroupCountComponent(limeobject);
        return Object.assign(Object.assign({}, searchListItem), (primaryComponent ? { primaryComponent: primaryComponent } : {}));
    }
    getGroupCountComponent(limeobject) {
        var _a;
        const limetype = limeobject.getLimetype();
        const groupCount = (_a = this.groupCounts[limetype.name]) === null || _a === void 0 ? void 0 : _a[limeobject.id];
        const coworkerProperty = getRelationProperty(limetype, 'user');
        if (groupCount === undefined || !coworkerProperty) {
            return;
        }
        const coworkerLimetype = coworkerProperty.relation.getLimetype();
        return {
            name: 'limebb-mention-group-counter',
            props: {
                count: groupCount,
                limetype: coworkerLimetype,
                helperLabel: this.translator.get('webclient.notification-center.members-will-be-notified'),
            },
        };
    }
}

const CORE_API_PATH = 'api/v1';
const FILE_PATH = 'file';
const FIFTY = 50;
const THOUSAND_BYTES = 1024;
const MAX_FILE_SIZE = FIFTY * THOUSAND_BYTES * THOUSAND_BYTES; // 50 MB
class FileUpload {
    constructor(file, http) {
        this.file = file;
        this.http = http;
        this.uploadCancelled = false;
        this.getUrl = (fileid) => {
            return `${CORE_API_PATH}/${FILE_PATH}/${fileid !== null && fileid !== void 0 ? fileid : ''}`;
        };
    }
    async initialize() {
        this.uploadService = await this.http.createFileUpload(it.Post, this.getUrl(), this.file);
        if (this.progressCallback) {
            this.uploadService.onProgress = this.progressCallback;
        }
    }
    async upload() {
        return this.uploadService.upload();
    }
    getFileName() {
        return this.file.name;
    }
    cancel() {
        this.uploadService.cancel();
        this.uploadCancelled = true;
    }
    set onProgress(callback) {
        this.progressCallback = callback;
        if (this.uploadService) {
            this.uploadService.onProgress = callback;
        }
    }
}

const UPLOAD_COMPLETED = 100;
class UploadHandler {
    constructor(platform) {
        this.platform = platform;
    }
    /**
     * Handles image paste events in the text editor
     *
     * @param imageInserter - The image inserter with the file info
     * @returns Promise resolving to the uploaded file wrapper or undefined if upload fails
     */
    async handleImagePasted(imageInserter) {
        const fileInfo = imageInserter === null || imageInserter === void 0 ? void 0 : imageInserter.fileInfo;
        if (!fileInfo) {
            return;
        }
        if (!this.validateImageSize(fileInfo)) {
            return;
        }
        imageInserter.insertThumbnail();
        const uploadedFile = await this.createFileUpload(fileInfo);
        const fileUrl = uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.href;
        const fileId = uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.fileId;
        if (fileUrl && fileId !== undefined) {
            imageInserter.insertImage(fileUrl);
        }
        else {
            imageInserter.insertFailedThumbnail();
        }
        return uploadedFile;
    }
    /**
     * Extracts a file ID from a image source string.
     *
     * This function parses a URL to find a file ID that appears before
     * '/contents/' at the end of the URL.
     *
     * @param src - The URL string to parse
     * @returns The extracted file ID or undefined if no match is found
     *
     * @example
     * // Returns 123
     * parseFileIdFromSrc('/api/file/123/contents/');
     *
     * @example
     * // Returns 456
     * parseFileIdFromSrc('https://example.com/limepkg-email/api/v1/file/456/contents/');
     *
     * @example
     * // Returns undefined
     * parseFileIdFromSrc('/invalid/url/format/');
     */
    parseFileIdFromSrc(src) {
        if (src) {
            const regex = /\/(\d+)\/contents\/?$/;
            const matches = regex.exec(src);
            if (matches && matches[1]) {
                return Number(matches[1]);
            }
        }
    }
    /**
     * Validates that the image file size is within limits
     *
     * @param fileInfo - The file info to validate
     * @returns True if file size is valid, false otherwise
     */
    validateImageSize(fileInfo) {
        if (!fileInfo.fileContent) {
            return false;
        }
        return fileInfo.fileContent.size <= MAX_FILE_SIZE;
    }
    /**
     * Creates and uploads a file
     *
     * @param fileInfo - The file info to upload
     * @returns Promise resolving to the uploaded file wrapper or undefined if upload fails
     */
    async createFileUpload(fileInfo) {
        var _a;
        if (!fileInfo.fileContent) {
            return;
        }
        const imageFile = new FileUpload(fileInfo.fileContent, this.http);
        await imageFile.initialize();
        const imageUpload = Object.assign(Object.assign({}, fileInfo), { progress: 0, file: imageFile, state: 'added', fileId: undefined, href: undefined, id: fileInfo.id });
        imageFile.onProgress = (progress) => {
            if (imageUpload.progress === 0) {
                imageUpload.state = 'uploading';
            }
            imageUpload.progress = progress;
            if (progress === UPLOAD_COMPLETED) {
                imageUpload.state = 'finalizing';
            }
        };
        const response = await imageFile.upload();
        imageUpload.fileId = response.id;
        imageUpload.filename = response.filename;
        imageUpload.extension = response.extension;
        imageUpload.contentType = response.contentType;
        imageUpload.size = response.size;
        imageUpload.state = 'done';
        imageUpload.href = (_a = response._links) === null || _a === void 0 ? void 0 : _a.contents.href;
        return imageUpload;
    }
    get http() {
        return this.platform.get(n.Http);
    }
}

const textEditorCss = () => `:host(limebb-text-editor){display:block;width:100%;min-width:5rem;min-height:5rem;height:100%;max-height:var(--text-editor-max-height, calc(100vh - (env(safe-area-inset-top) + env(safe-area-inset-bottom)) - 4rem))}`;

var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
        r = Reflect.decorate(decorators, target, key, desc);
    else
        for (var i = decorators.length - 1; i >= 0; i--)
            if (d = decorators[i])
                r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const DEBOUNCE_SEARCH_TIMEOUT = 300;
const LimeBBTextEditor = class {
    watchOpen() {
        this.setupHandlers();
        this.setPickerMessage();
    }
    watchQuery() {
        this.setPickerMessage();
    }
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.change = createEvent(this, "change");
        this.metadataChange = createEvent(this, "metadataChange");
        /**
         * Set to true to enable mentioning a coworker or groups of coworkers.
         *
         * Mentions already present will still be rendered with a link to the coworker or
         * the group of coworkers regardless of the value of this property
         */
        this.allowMentioning = false;
        /**
         * The type of content that the editor should handle and emit, defaults to `markdown`
         *
         * Assumed to be set only once, so not reactive to changes
         */
        this.contentType = 'markdown';
        /**
         * Defines the language for translations.
         */
        this.language = 'en';
        /**
         * Set to `true` to disable the field.
         * Use `disabled` to indicate that the field can normally be interacted
         * with, but is currently disabled. This tells the user that if certain
         * requirements are met, the field may become enabled again.
         */
        this.disabled = false;
        /**
         * Set to `true` to make the component read-only.
         * Use `readonly` when the field is only there to present the data it holds,
         * and will not become possible for the current user to edit.
         * :::note
         * Consider that it might be better to use `limel-markdown`
         * instead of `limel-text-editor` when the goal is visualizing data.
         * :::
         */
        this.readonly = false;
        /**
         * Set to `true` to indicate that the current value of the editor is
         * invalid.
         */
        this.invalid = false;
        /**
         * Set to `true` to indicate that the field is required.
         *
         * :::important
         * An empty but required field is not automatically considered invalid.
         * You must make sure to check the validity of the field on your own,
         * and properly handle the `invalid` state.
         * :::
         */
        this.required = false;
        /**
         * Specifies the visual appearance of the editor.
         *
         * - `standard`: The default editor appearance with a full toolbar and
         * standard layout.
         * - `minimal`: A compact editor appearance, ideal for limited space
         * scenarios such as mobile devices. In this mode, the toolbar is hidden
         * until the editor is focused.
         */
        this.ui = 'standard';
        /**
         * Set to `true` to allow the user to vertically resize the editor.
         * Set to `false` to disable the resize functionality.
         */
        this.allowResize = true;
        this.value = '';
        this.triggerMap = {};
        this.customElements = [];
        /**
         * Enables image pasting in the editor.
         * Default: `false`
         *
         * :::note
         * This component handles the upload process.
         * The consumer must process the uploaded images by listening to `metadataChange` event.
         * :::
         */
        this.allowInlineImages = false;
        this.items = [];
        this.highlightedItemIndex = 0;
        /**
         * Open state of the picker
         */
        this.isPickerOpen = false;
        /**
         * Loading state of the picker
         */
        this.isSearching = false;
        this.registeredTriggers = [];
        this.registeredTriggerMap = this.triggerMap;
        this.registeredCustomElements = this.customElements;
        this.activeTrigger = undefined;
        this.handleMouseClick = (event) => {
            if (!this.textEditorPickerElement) {
                return;
            }
            const clickedOnTextEditorPicker = event.target === this.textEditorPickerElement;
            if (!clickedOnTextEditorPicker) {
                this.resetTriggerAndPicker();
            }
        };
        this.handleKeyPress = (event) => {
            if (!this.isPickerOpen || !this.activeTrigger) {
                return;
            }
            const capturedKeys = [ESCAPE, ARROW_UP, ARROW_DOWN, ENTER, TAB];
            if (!capturedKeys.includes(event.key)) {
                return;
            }
            event.stopPropagation();
            event.preventDefault();
            if (event.type === 'keyup') {
                return;
            }
            const handlers = {
                [ESCAPE]: this.handleEscapeKey,
                [ENTER]: this.handleEnterOrTabKey,
                [TAB]: this.handleEnterOrTabKey,
                [ARROW_DOWN]: this.handleArrowKeyPress,
                [ARROW_UP]: this.handleArrowKeyPress,
            };
            const handler = handlers[event.key];
            if (handler) {
                handler(event);
            }
        };
        this.handleArrowKeyPress = (event) => {
            this.highlightedItemIndex = this.findNonSeparatorIndex(event.key, this.highlightedItemIndex);
        };
        this.findNonSeparatorIndex = (direction, currentIndex, depth = 0) => {
            // Safety check to avoid infinite recursion
            if (this.items.length === 0 || depth > this.items.length) {
                return currentIndex;
            }
            const nextIndex = getItemIndex(direction, currentIndex, this.items.length);
            if (!this.isListSeparator(this.items[nextIndex])) {
                return nextIndex;
            }
            return this.findNonSeparatorIndex(direction, nextIndex, depth + 1);
        };
        this.handleEscapeKey = () => {
            var _a;
            // We only call this when ESCAPE is pressed
            (_a = this.triggerFunction) === null || _a === void 0 ? void 0 : _a.stopTrigger();
            this.resetTriggerAndPicker();
        };
        this.handleEnterOrTabKey = (event) => {
            this.handleItemSelection(event);
        };
        this.handleMetadataChange = (event) => {
            event.stopPropagation();
            const editorMetadata = event.detail;
            const enhancedImages = this.getEnhancedImages(editorMetadata.images || []);
            const enhancedMetadata = Object.assign(Object.assign({}, editorMetadata), { images: enhancedImages });
            this.metadataChange.emit(enhancedMetadata);
        };
        this.handleImagePasted = (event) => {
            event.stopPropagation();
            if (!this.allowInlineImages) {
                return;
            }
            this.uploadHandler.handleImagePasted(event.detail);
        };
        this.handleTriggerStart = (event) => {
            event.stopPropagation();
            this.activeTrigger = event.detail.trigger;
            this.triggerFunction = event.detail.textEditor;
            this.isPickerOpen = true;
        };
        this.handleTriggerStop = (event) => {
            event.stopPropagation();
            this.resetTriggerAndPicker();
        };
        this.handleTriggerChange = (event) => {
            var _a;
            event.stopImmediatePropagation();
            this.editorPickerQuery = event.detail.value;
            const trigger = event.detail.trigger;
            const searcher = (_a = this.registeredTriggerMap[trigger]) === null || _a === void 0 ? void 0 : _a.searcher;
            if (searcher) {
                this.isSearching = true;
                this.debouncedSearchFn(searcher, this.editorPickerQuery);
            }
        };
        this.resetTriggerAndPicker = () => {
            this.isPickerOpen = false;
            this.activeTrigger = undefined;
            this.triggerFunction = undefined;
            this.isSearching = false;
            this.highlightedItemIndex = 0;
            this.items = [];
        };
        this.handleItemSelection = (event) => {
            var _a;
            let selectedItem;
            if (event instanceof CustomEvent) {
                selectedItem = event.detail;
            }
            else if (event instanceof KeyboardEvent) {
                const currentItem = this.items[this.highlightedItemIndex];
                if (this.isListSeparator(currentItem)) {
                    return;
                }
                selectedItem = currentItem;
            }
            else {
                return;
            }
            if (!this.activeTrigger || (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.disabled)) {
                return;
            }
            const triggerHandler = this.registeredTriggerMap[this.activeTrigger];
            try {
                triggerHandler.inserter(this.triggerFunction, selectedItem);
            }
            catch (error) {
                console.error('Error inserting', error);
            }
            this.resetTriggerAndPicker();
            (_a = this.textEditor) === null || _a === void 0 ? void 0 : _a.focus();
        };
        this.handleVisibilityChange = () => {
            if (document.visibilityState === 'hidden') {
                this.saveDraft();
            }
        };
        this.handleBeforeUnload = () => {
            this.saveDraft();
        };
        this.portalId = createRandomString();
        this.debouncedSearchFn = debounce(async (searcher, editorPickerQuery) => {
            try {
                const items = await searcher(editorPickerQuery);
                if (editorPickerQuery !== this.editorPickerQuery ||
                    !this.activeTrigger) {
                    return;
                }
                this.items = items;
            }
            catch (error) {
                console.error('Error searching', error);
            }
            finally {
                this.isSearching = false;
            }
        }, DEBOUNCE_SEARCH_TIMEOUT);
    }
    connectedCallback() {
        var _a, _b, _c, _d;
        if (this.draftIdentifier) {
            const limeObjectId = (_b = (_a = this.context) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : 'no-limeobject';
            const limeTypeName = (_d = (_c = this.context) === null || _c === void 0 ? void 0 : _c.limetype) !== null && _d !== void 0 ? _d : 'no-limetype';
            this.textEditorInnerId = [
                'text-editor-draft',
                limeTypeName,
                limeObjectId,
                this.draftIdentifier,
            ].join('-');
        }
        if (this.textEditorInnerId) {
            document.addEventListener('visibilitychange', this.handleVisibilityChange);
            window.addEventListener('beforeunload', this.handleBeforeUnload);
        }
        this.uploadHandler = new UploadHandler(this.platform);
    }
    componentWillLoad() {
        if (this.allowMentioning) {
            this.registerMentions();
        }
        this.registerTriggers();
        this.loadDraft();
    }
    disconnectedCallback() {
        // These can be called even if the listeners were not set up,
        // so we don't need to check for that
        document.removeEventListener('visibilitychange', this.handleVisibilityChange);
        window.removeEventListener('beforeunload', this.handleBeforeUnload);
        document.removeEventListener('mousedown', this.handleMouseClick);
        this.saveDraft();
        if (this.host) {
            this.host.removeEventListener('keyup', this.handleKeyPress, {
                capture: true,
            });
            this.host.removeEventListener('keydown', this.handleKeyPress, {
                capture: true,
            });
        }
        if (this.debouncedSearchFn && this.debouncedSearchFn.cancel) {
            this.debouncedSearchFn.cancel();
        }
    }
    registerMentions() {
        const mentions = new MentionsService(this.platform, this.context, this.searchableLimetypes);
        const nodeDefinition = mentions.triggerHandler.nodeDefinition;
        if (nodeDefinition) {
            this.registeredCustomElements.push(nodeDefinition.customElement);
            this.registeredTriggerMap[mentions.triggerCharacter] =
                mentions.triggerHandler;
            mentions.initialize();
        }
    }
    registerTriggers() {
        this.registeredTriggers = Object.keys(this.registeredTriggerMap);
    }
    setPickerMessage() {
        var _a;
        if (!this.activeTrigger) {
            return;
        }
        const triggerHandler = this.registeredTriggerMap[this.activeTrigger];
        if (((_a = this.editorPickerQuery) === null || _a === void 0 ? void 0 : _a.length) > 0) {
            this.pickerMessage = triggerHandler.noItemsFoundMessage;
        }
        else {
            this.pickerMessage = triggerHandler.emptySearchMessage;
        }
    }
    setupHandlers() {
        if (this.isPickerOpen) {
            this.host.addEventListener('keyup', this.handleKeyPress, {
                capture: true,
            });
            this.host.addEventListener('keydown', this.handleKeyPress, {
                capture: true,
            });
            document.addEventListener('mousedown', this.handleMouseClick);
        }
        else {
            this.host.removeEventListener('keyup', this.handleKeyPress, {
                capture: true,
            });
            this.host.removeEventListener('keydown', this.handleKeyPress, {
                capture: true,
            });
            document.removeEventListener('mousedown', this.handleMouseClick);
        }
    }
    isListSeparator(item) {
        return 'separator' in item && item.separator === true;
    }
    render() {
        return [
            h("limel-text-editor", { key: '38d692ec58c569a0429caddf7ecfe418e21ac14b', ref: (el) => (this.textEditor = el), tabindex: this.disabled ? -1 : 0, value: this.value, contentType: this.contentType, customElements: this.registeredCustomElements, "aria-disabled": this.disabled, language: this.language, triggers: this.registeredTriggers, onTriggerStart: this.handleTriggerStart, onTriggerStop: this.handleTriggerStop, onTriggerChange: this.handleTriggerChange, onImagePasted: this.handleImagePasted, onMetadataChange: this.handleMetadataChange, ui: this.ui, allowResize: this.allowResize, required: this.required, disabled: this.disabled, readonly: this.readonly, helperText: this.helperText, placeholder: this.placeholder, label: this.label, invalid: this.invalid }),
            this.renderPicker(),
        ];
    }
    renderPicker() {
        if (!this.isPickerOpen) {
            return;
        }
        return (h("limel-portal", { containerId: this.portalId, visible: this.isPickerOpen, openDirection: "top", inheritParentWidth: true, anchor: this.textEditor }, h("limebb-text-editor-picker", { ref: (el) => (this.textEditorPickerElement =
                el), items: getUpdatedItems(this.items, this.highlightedItemIndex), onItemSelected: this.handleItemSelection, emptyMessage: this.pickerMessage, isSearching: this.isSearching })));
    }
    getEnhancedImages(images) {
        return images.map((image) => {
            let fileId;
            if (image.state === 'success') {
                fileId = this.uploadHandler.parseFileIdFromSrc(image.src);
            }
            return fileId ? Object.assign(Object.assign({}, image), { fileId: fileId }) : image;
        });
    }
    loadDraft() {
        if (!this.userDataService || !this.textEditorInnerId) {
            return;
        }
        if (this.value) {
            // If the text-editor is loaded with a value, don't replace it.
            return;
        }
        const draft = this.userDataService.get(this.textEditorInnerId);
        if (draft) {
            this.change.emit(draft);
        }
    }
    saveDraft() {
        var _a, _b, _c, _d;
        if (!this.textEditorInnerId) {
            return;
        }
        const currentValue = (_a = this.value) === null || _a === void 0 ? void 0 : _a.trim();
        const existingDraft = (_b = this.userDataService) === null || _b === void 0 ? void 0 : _b.get(this.textEditorInnerId);
        // Save draft
        if (currentValue && currentValue !== existingDraft) {
            (_c = this.userDataService) === null || _c === void 0 ? void 0 : _c.set(this.textEditorInnerId, currentValue);
        }
        // Delete draft
        else if (!currentValue && existingDraft) {
            (_d = this.userDataService) === null || _d === void 0 ? void 0 : _d.set(this.textEditorInnerId, undefined);
        }
    }
    get userDataService() {
        return this.platform.get(n.UserDataRepository);
    }
    static get delegatesFocus() { return true; }
    get host() { return getElement(this); }
    static get watchers() { return {
        "isPickerOpen": [{
                "watchOpen": 0
            }],
        "editorPickerQuery": [{
                "watchQuery": 0
            }]
    }; }
};
__decorate([
    Le({
        map: [getMentionLimetypes],
    })
], LimeBBTextEditor.prototype, "searchableLimetypes", void 0);
LimeBBTextEditor.style = textEditorCss();

export { LimeBBTextEditor as limebb_text_editor };
