/**
 * ldesign v0.4.2
 * (c) 2023 ldesign
 * @license MIT
 */

import { _ as _classCallCheck, a as _createClass } from '../../../_chunks/dep-b343e307.mjs';
import { _ as _defineProperty } from '../../../_chunks/dep-eb20e23f.mjs';
import { i as isArray_1 } from '../../../_chunks/dep-e3b14d70.mjs';
import { i as isFunction_1 } from '../../../_chunks/dep-6b22dd27.mjs';
import { i as isNumber_1 } from '../../../_chunks/dep-6eea369f.mjs';
import { i as isString_1 } from '../../../_chunks/dep-1cf2b129.mjs';
import '../../../_chunks/dep-a0b4a044.mjs';
import { _ as _SetCache, a as _arrayIncludes, b as _arrayIncludesWith, c as _cacheHas } from '../../../_chunks/dep-5d966cee.mjs';
import { _ as _arrayMap } from '../../../_chunks/dep-37ba476d.mjs';
import { _ as _baseUnary } from '../../../_chunks/dep-1b058de3.mjs';
import { a as _baseFlatten } from '../../../_chunks/dep-774ac2d0.mjs';
import { _ as _baseRest, i as isArrayLikeObject_1 } from '../../../_chunks/dep-c7e9ce16.mjs';
import { c as camelCase_1 } from '../../../_chunks/dep-f6649a46.mjs';
import { i as isPlainObject_1 } from '../../../_chunks/dep-ba3c0b2e.mjs';
import mitt from 'mitt';
import { TreeNode } from './tree-node.mjs';
import '../../../_chunks/dep-b4041200.mjs';
import '../../../_chunks/dep-c959a6fb.mjs';
import '../../../_chunks/dep-0f0c89ff.mjs';
import '../../../_chunks/dep-c31e1d9e.mjs';
import '../../../_chunks/dep-66d6733b.mjs';
import '../../../_chunks/dep-0bfbf721.mjs';
import '../../../_chunks/dep-39cc276d.mjs';
import '../../../_chunks/dep-8f777748.mjs';
import '../../../_chunks/dep-ae357f26.mjs';
import '../../../_chunks/dep-be27d184.mjs';
import '../../../_chunks/dep-23a0f453.mjs';
import '../../../_chunks/dep-05fa17c9.mjs';
import '../../../_chunks/dep-3afa94cf.mjs';
import '../../../_chunks/dep-2cfd5b3a.mjs';
import '../../../_chunks/dep-92e7085e.mjs';
import '../../../_chunks/dep-10085c61.mjs';
import '../../../_chunks/dep-1fe0ad42.mjs';
import '../../../_chunks/dep-d54f2690.mjs';
import '../../../_chunks/dep-59c8420d.mjs';
import '../../../_chunks/dep-74848b92.mjs';
import '../../../_chunks/dep-79821ff2.mjs';
import '../../../_chunks/dep-352691c2.mjs';
import '../../../_chunks/dep-a9c8a5d5.mjs';
import '../../../_chunks/dep-c852a61a.mjs';
import '../../../_chunks/dep-beaa677e.mjs';
import '../../../_chunks/dep-e091cfd9.mjs';
import '../../../_chunks/dep-cfcedf47.mjs';
import '../../../_chunks/dep-6f89b77e.mjs';
import '../../../_chunks/dep-51aacdc9.mjs';
import '../../../_chunks/dep-4c3e8dd5.mjs';
import '../../../_chunks/dep-7acc11cb.mjs';
import '../log/index.mjs';
import '../log/log.mjs';
import './tree-node-model.mjs';
import '../../../_chunks/dep-30451c48.mjs';
import '../../../_chunks/dep-0cfc2d3f.mjs';
import '../../../_chunks/dep-e9bfe96d.mjs';
import '../../../_chunks/dep-ea5448a5.mjs';
import '../../../_chunks/dep-b2af48ba.mjs';
import '../../../_chunks/dep-bf74f1c2.mjs';
import '../../../_chunks/dep-44f056cd.mjs';

var SetCache = _SetCache,
  arrayIncludes = _arrayIncludes,
  arrayIncludesWith = _arrayIncludesWith,
  arrayMap = _arrayMap,
  baseUnary = _baseUnary,
  cacheHas = _cacheHas;

/** Used as the size to enable large array optimizations. */
var LARGE_ARRAY_SIZE = 200;

/**
 * The base implementation of methods like `_.difference` without support
 * for excluding multiple arrays or iteratee shorthands.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {Array} values The values to exclude.
 * @param {Function} [iteratee] The iteratee invoked per element.
 * @param {Function} [comparator] The comparator invoked per element.
 * @returns {Array} Returns the new array of filtered values.
 */
function baseDifference$1(array, values, iteratee, comparator) {
  var index = -1,
    includes = arrayIncludes,
    isCommon = true,
    length = array.length,
    result = [],
    valuesLength = values.length;
  if (!length) {
    return result;
  }
  if (iteratee) {
    values = arrayMap(values, baseUnary(iteratee));
  }
  if (comparator) {
    includes = arrayIncludesWith;
    isCommon = false;
  } else if (values.length >= LARGE_ARRAY_SIZE) {
    includes = cacheHas;
    isCommon = false;
    values = new SetCache(values);
  }
  outer: while (++index < length) {
    var value = array[index],
      computed = iteratee == null ? value : iteratee(value);
    value = comparator || value !== 0 ? value : 0;
    if (isCommon && computed === computed) {
      var valuesIndex = valuesLength;
      while (valuesIndex--) {
        if (values[valuesIndex] === computed) {
          continue outer;
        }
      }
      result.push(value);
    } else if (!includes(values, computed, comparator)) {
      result.push(value);
    }
  }
  return result;
}
var _baseDifference = baseDifference$1;

var baseDifference = _baseDifference,
  baseFlatten = _baseFlatten,
  baseRest = _baseRest,
  isArrayLikeObject = isArrayLikeObject_1;

/**
 * Creates an array of `array` values not included in the other given arrays
 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
 * for equality comparisons. The order and references of result values are
 * determined by the first array.
 *
 * **Note:** Unlike `_.pullAll`, this method returns a new array.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Array
 * @param {Array} array The array to inspect.
 * @param {...Array} [values] The values to exclude.
 * @returns {Array} Returns the new array of filtered values.
 * @see _.without, _.xor
 * @example
 *
 * _.difference([2, 1], [2, 3]);
 * // => [1]
 */
var difference = baseRest(function (array, values) {
  return isArrayLikeObject(array) ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) : [];
});
var difference_1 = difference;

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
var TreeStore = /*#__PURE__*/function () {
  function TreeStore(options) {
    _classCallCheck(this, TreeStore);
    _defineProperty(this, "children", void 0);
    _defineProperty(this, "nodes", void 0);
    _defineProperty(this, "nodeMap", void 0);
    _defineProperty(this, "privateMap", void 0);
    _defineProperty(this, "config", void 0);
    _defineProperty(this, "activedMap", void 0);
    _defineProperty(this, "updatedMap", void 0);
    _defineProperty(this, "checkedMap", void 0);
    _defineProperty(this, "expandedMap", void 0);
    _defineProperty(this, "filterMap", void 0);
    _defineProperty(this, "updateTimer", void 0);
    _defineProperty(this, "shouldReflow", void 0);
    _defineProperty(this, "hasFilter", void 0);
    _defineProperty(this, "prevFilter", void 0);
    _defineProperty(this, "emitter", void 0);
    var config = _objectSpread({
      prefix: "t",
      keys: {},
      expandAll: false,
      expandLevel: 0,
      expandMutex: false,
      expandParent: false,
      activable: false,
      activeMultiple: false,
      checkable: false,
      checkStrictly: false,
      disabled: false,
      draggable: false,
      load: null,
      lazy: false,
      valueMode: "onlyLeaf",
      filter: null,
      onLoad: null,
      onReflow: null,
      onUpdate: null,
      allowFoldNodeOnFilter: false
    }, options);
    this.config = config;
    this.nodes = [];
    this.children = [];
    this.nodeMap = /* @__PURE__ */new Map();
    this.privateMap = /* @__PURE__ */new Map();
    this.activedMap = /* @__PURE__ */new Map();
    this.expandedMap = /* @__PURE__ */new Map();
    this.checkedMap = /* @__PURE__ */new Map();
    this.updatedMap = /* @__PURE__ */new Map();
    this.filterMap = /* @__PURE__ */new Map();
    this.prevFilter = null;
    this.updateTimer = null;
    this.shouldReflow = false;
    this.hasFilter = isFunction_1(config.filter);
    this.emitter = mitt();
  }
  _createClass(TreeStore, [{
    key: "setConfig",
    value: function setConfig(options) {
      var config = this.config;
      var hasChanged = false;
      Object.keys(options).forEach(function (key) {
        var val = options[key];
        if (val !== config[key]) {
          hasChanged = true;
          config[key] = val;
        }
      });
      this.hasFilter = isFunction_1(config.filter);
      if (hasChanged) {
        this.refreshState();
      }
    }
  }, {
    key: "getChildren",
    value: function getChildren() {
      return this.children;
    }
  }, {
    key: "getNode",
    value: function getNode(item) {
      var node = null;
      if (isString_1(item) || isNumber_1(item)) node = this.nodeMap.get(item);else if (item instanceof TreeNode) node = this.nodeMap.get(item.value);
      return node;
    }
  }, {
    key: "getIndex",
    value: function getIndex(node) {
      return this.nodes.indexOf(node);
    }
  }, {
    key: "getParent",
    value: function getParent(value) {
      var parent = null;
      var node = this.getNode(value);
      if (node) parent = node.getParent();
      return parent;
    }
  }, {
    key: "getParents",
    value: function getParents(value) {
      var node = this.getNode(value);
      var parents = [];
      if (node) parents = node.getParents();
      return parents;
    }
  }, {
    key: "getNodeIndex",
    value: function getNodeIndex(value) {
      var node = this.getNode(value);
      var index = -1;
      if (node) index = node.getIndex();
      return index;
    }
  }, {
    key: "getNodes",
    value: function getNodes(item, options) {
      var nodes = [];
      var val = "";
      if (isString_1(item) || isNumber_1(item)) val = item;else if (item instanceof TreeNode) val = item.value;
      if (!val) {
        nodes = this.nodes.slice(0);
      } else {
        var node = this.getNode(val);
        if (node) nodes = node.walk();
      }
      if (options) {
        var conf = _objectSpread({
          filter: null,
          level: Infinity
        }, options);
        if (isNumber_1(conf.level) && conf.level !== Infinity) nodes = nodes.filter(function (node) {
          return node.level <= conf.level;
        });
        if (isFunction_1(conf.filter)) {
          nodes = nodes.filter(function (node) {
            var nodeModel = node.getModel();
            return conf.filter(nodeModel);
          });
        }
        if (isPlainObject_1(conf.props)) {
          nodes = nodes.filter(function (node) {
            var result = Object.keys(conf.props).every(function (key) {
              var propEqual = node[key] === conf.props[key];
              return propEqual;
            });
            return result;
          });
        }
      }
      return nodes;
    }
  }, {
    key: "append",
    value: function append(list) {
      var _this = this;
      list.forEach(function (item) {
        var node = new TreeNode(_this, item);
        _this.children.push(node);
      });
      this.reflow();
    }
  }, {
    key: "reload",
    value: function reload(list) {
      this.expandedMap.clear();
      this.checkedMap.clear();
      this.activedMap.clear();
      this.filterMap.clear();
      this.removeAll();
      this.append(list);
    }
  }, {
    key: "parseNodeData",
    value: function parseNodeData(para, item) {
      var value = "";
      var node = null;
      var data = null;
      if (isString_1(para) || isNumber_1(para)) {
        value = para;
        data = item;
        node = this.getNode(value);
      } else if (para instanceof TreeNode) {
        node = para;
        data = item;
      } else {
        data = para;
      }
      var spec = {
        node: node,
        data: data
      };
      return spec;
    }
  }, {
    key: "appendNodes",
    value: function appendNodes(para, item) {
      var spec = this.parseNodeData(para, item);
      if (spec.data) {
        if (!spec.node) {
          if (spec.data instanceof TreeNode) spec.data.appendTo(this);else if (Array.isArray(spec.data)) this.append(spec.data);else this.append([spec.data]);
        } else {
          if (spec.data instanceof TreeNode) spec.data.appendTo(this, spec.node);else if (isArray_1(spec.data)) spec.node.append(spec.data);else spec.node.append([spec.data]);
          spec.node.updateRelated();
        }
      }
    }
  }, {
    key: "insertBefore",
    value: function insertBefore(value, item) {
      var node = this.getNode(value);
      if (node) node.insertBefore(item);
    }
  }, {
    key: "insertAfter",
    value: function insertAfter(value, item) {
      var node = this.getNode(value);
      if (node) node.insertAfter(item);
    }
  }, {
    key: "refreshNodes",
    value: function refreshNodes() {
      var children = this.children,
        nodes = this.nodes;
      nodes.length = 0;
      children.forEach(function (node) {
        var list = node.walk();
        Array.prototype.push.apply(nodes, list);
      });
    }
  }, {
    key: "refreshState",
    value: function refreshState() {
      var nodes = this.nodes;
      nodes.forEach(function (node) {
        node.update();
        node.updateChecked();
      });
    }
  }, {
    key: "reflow",
    value: function reflow(node) {
      this.shouldReflow = true;
      this.updated(node);
    }
  }, {
    key: "updated",
    value: function updated(node) {
      var _this2 = this;
      if (node !== null && node !== void 0 && node.value) this.updatedMap.set(node.value, true);
      if (this.updateTimer) return;
      this.updateTimer = setTimeout(function () {
        clearTimeout(_this2.updateTimer);
        _this2.updateTimer = null;
        if (_this2.shouldReflow) {
          _this2.refreshNodes();
          _this2.emit("reflow");
        }
        _this2.lockFilterPathNodes();
        var updatedList = Array.from(_this2.updatedMap.keys());
        if (updatedList.length > 0) {
          var updatedNodes = updatedList.map(function (value) {
            return _this2.getNode(value);
          });
          _this2.emit("update", {
            nodes: updatedNodes,
            map: _this2.updatedMap
          });
        } else if (_this2.shouldReflow) {
          _this2.emit("update", {
            nodes: [],
            map: _this2.updatedMap
          });
        }
        _this2.shouldReflow = false;
        _this2.updatedMap.clear();
      });
    }
  }, {
    key: "getActived",
    value: function getActived(map) {
      var activedMap = map || this.activedMap;
      return Array.from(activedMap.keys());
    }
  }, {
    key: "getActivedNodes",
    value: function getActivedNodes(item) {
      var nodes = this.getNodes(item);
      nodes = nodes.filter(function (node) {
        return node.isActived();
      });
      return nodes;
    }
  }, {
    key: "replaceActived",
    value: function replaceActived(list) {
      this.resetActived();
      this.setActived(list);
    }
  }, {
    key: "setActived",
    value: function setActived(actived) {
      var _this3 = this;
      var activeMultiple = this.config.activeMultiple;
      var list = actived.slice(0);
      if (!activeMultiple) list.length = 1;
      list.forEach(function (val) {
        _this3.activedMap.set(val, true);
        var node = _this3.getNode(val);
        if (node) node.update();
      });
    }
  }, {
    key: "resetActived",
    value: function resetActived() {
      var actived = this.getActived();
      this.activedMap.clear();
      var relatedNodes = this.getRelatedNodes(actived);
      relatedNodes.forEach(function (node) {
        node.update();
      });
    }
  }, {
    key: "getExpanded",
    value: function getExpanded(map) {
      var expandedMap = map || this.expandedMap;
      return Array.from(expandedMap.keys());
    }
  }, {
    key: "replaceExpanded",
    value: function replaceExpanded(list) {
      var expanded = this.getExpanded();
      var added = difference_1(list, expanded);
      var removed = difference_1(expanded, list);
      this.setExpandedDirectly(removed, false);
      this.updateExpanded(removed);
      this.setExpanded(added);
    }
  }, {
    key: "setExpanded",
    value: function setExpanded(list) {
      this.setExpandedDirectly(list);
      this.updateExpanded(list);
    }
  }, {
    key: "setExpandedDirectly",
    value: function setExpandedDirectly(list) {
      var _this4 = this;
      var expanded = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      list.forEach(function (val) {
        if (expanded) {
          _this4.expandedMap.set(val, true);
          var node = _this4.getNode(val);
          if (node) node.afterExpanded();
        } else {
          _this4.expandedMap["delete"](val);
        }
      });
    }
  }, {
    key: "resetExpanded",
    value: function resetExpanded() {
      var expanded = this.getExpanded();
      this.expandedMap.clear();
      this.updateExpanded(expanded);
    }
  }, {
    key: "updateExpanded",
    value: function updateExpanded(list) {
      var relatedNodes = this.getRelatedNodes(list, {
        withParents: false
      });
      relatedNodes.forEach(function (node) {
        node.update();
      });
    }
  }, {
    key: "getChecked",
    value: function getChecked(map) {
      var nodes = this.nodes,
        config = this.config;
      var valueMode = config.valueMode,
        checkStrictly = config.checkStrictly;
      var list = [];
      var checkedMap = map || this.checkedMap;
      nodes.forEach(function (node) {
        if (node.isChecked(checkedMap)) {
          if (valueMode === "parentFirst" && !checkStrictly) {
            if (!node.parent || !node.parent.isChecked(checkedMap)) list.push(node.value);
          } else if (valueMode === "onlyLeaf" && !checkStrictly) {
            if (node.isLeaf()) list.push(node.value);
          } else {
            list.push(node.value);
          }
        }
      });
      return list;
    }
  }, {
    key: "getCheckedNodes",
    value: function getCheckedNodes(item) {
      var nodes = this.getNodes(item);
      nodes = nodes.filter(function (node) {
        return node.isChecked();
      });
      return nodes;
    }
  }, {
    key: "replaceChecked",
    value: function replaceChecked(list) {
      this.resetChecked();
      this.setChecked(list, true);
    }
  }, {
    key: "setChecked",
    value: function setChecked(list, isFromValueChange) {
      var _this5 = this;
      var _this$config = this.config,
        valueMode = _this$config.valueMode,
        checkStrictly = _this$config.checkStrictly,
        checkable = _this$config.checkable;
      if (!checkable) return;
      list.forEach(function (val) {
        var node = _this5.getNode(val);
        if (node) {
          if (valueMode === "parentFirst" && !checkStrictly) {
            var childrenNodes = node.walk();
            childrenNodes.forEach(function (childNode) {
              _this5.checkedMap.set(childNode.value, true);
            });
          } else {
            _this5.checkedMap.set(val, true);
            node.updateChecked(isFromValueChange);
          }
        }
      });
      if (!checkStrictly) {
        var checked = this.getChecked();
        var relatedNodes = this.getRelatedNodes(checked);
        relatedNodes.forEach(function (node) {
          node.updateChecked();
        });
      }
    }
  }, {
    key: "resetChecked",
    value: function resetChecked() {
      var checked = this.getChecked();
      var relatedNodes = this.getRelatedNodes(checked);
      this.checkedMap.clear();
      relatedNodes.forEach(function (node) {
        node.updateChecked();
      });
    }
  }, {
    key: "updateAll",
    value: function updateAll() {
      var nodes = this.getNodes();
      nodes.forEach(function (node) {
        node.update();
      });
    }
  }, {
    key: "remove",
    value: function remove(value) {
      var node = this.getNode(value);
      if (node) node.remove();
    }
  }, {
    key: "removeAll",
    value: function removeAll() {
      var nodes = this.getNodes();
      nodes.forEach(function (node) {
        node.remove();
      });
    }
  }, {
    key: "getRelatedNodes",
    value: function getRelatedNodes(list, options) {
      var _this6 = this;
      var conf = _objectSpread({
        withParents: true
      }, options);
      var map = /* @__PURE__ */new Map();
      list.forEach(function (value) {
        if (map.get(value)) return;
        var node = _this6.getNode(value);
        if (node) {
          var parents = node.getParents();
          var children = node.walk();
          var related = [];
          if (conf.withParents) related = parents.concat(children);else related = children;
          related.forEach(function (relatedNode) {
            map.set(relatedNode.value, relatedNode);
          });
        }
      });
      var relatedNodes = Array.from(map.values());
      return relatedNodes;
    }
  }, {
    key: "emit",
    value: function emit(name, state) {
      var config = this.config,
        emitter = this.emitter;
      var methodName = camelCase_1("on-".concat(name));
      var method = config[methodName];
      if (isFunction_1(method)) method(state);
      emitter.emit(name, state);
    }
  }, {
    key: "lockFilterPathNodes",
    value: function lockFilterPathNodes() {
      var config = this.config;
      var allNodes = this.getNodes();
      if (this.prevFilter) {
        allNodes.forEach(function (node) {
          if (node.vmIsLocked) {
            node.lock(false);
          }
        });
      }
      var currentFilter = config.filter;
      if (!currentFilter || !isFunction_1(currentFilter)) return;
      this.prevFilter = config.filter;
      allNodes.reverse().forEach(function (node) {
        var parent = node.getParent();
        if (!parent) return;
        if (node.vmIsRest || node.vmIsLocked) {
          if (!parent.vmIsLocked) {
            parent.lock(true);
          }
        }
      });
    }
  }]);
  return TreeStore;
}();

export { TreeStore, TreeStore as default };
//# sourceMappingURL=tree-store.mjs.map
