import {
  difference,
  elem,
  foldMap,
  foldMapWithIndex,
  getEq,
  getFoldable,
  getFoldableWithIndex,
  getShow,
  intersection,
  isEmpty,
  isSubmap,
  lookup,
  member,
  reduce,
  reduceRight,
  reduceRightWithIndex,
  reduceWithIndex,
  size,
  union
} from "./chunk-PNN7UU5H.mjs";
import {
  map2 as map
} from "./chunk-3AL4EMTU.mjs";
import {
  separated
} from "./chunk-RAKKSTP2.mjs";
import {
  wiltDefault,
  witherDefault
} from "./chunk-DQQFH64X.mjs";
import {
  flap
} from "./chunk-WKK6AYQI.mjs";
import {
  isLeft,
  isNone,
  isSome,
  none,
  some
} from "./chunk-WPJQNT3M.mjs";
import {
  pipe
} from "./chunk-ZI34HWXZ.mjs";
import {
  __export
} from "./chunk-QK4PKNB3.mjs";

// src/Map.ts
var Map_exports = {};
__export(Map_exports, {
  Compactable: () => Compactable,
  Filterable: () => Filterable,
  Functor: () => Functor,
  URI: () => URI,
  collect: () => collect,
  compact: () => compact,
  deleteAt: () => deleteAt,
  difference: () => difference2,
  elem: () => elem2,
  empty: () => empty,
  filter: () => filter,
  filterMap: () => filterMap,
  filterMapWithIndex: () => filterMapWithIndex,
  filterWithIndex: () => filterWithIndex,
  flap: () => flap2,
  foldMap: () => foldMap2,
  foldMapWithIndex: () => foldMapWithIndex2,
  fromFoldable: () => fromFoldable,
  getDifferenceMagma: () => getDifferenceMagma,
  getEq: () => getEq2,
  getFilterableWithIndex: () => getFilterableWithIndex,
  getFoldable: () => getFoldable2,
  getFoldableWithIndex: () => getFoldableWithIndex2,
  getIntersectionSemigroup: () => getIntersectionSemigroup,
  getMonoid: () => getMonoid,
  getShow: () => getShow2,
  getTraversableWithIndex: () => getTraversableWithIndex,
  getUnionMonoid: () => getUnionMonoid,
  getUnionSemigroup: () => getUnionSemigroup,
  getWitherable: () => getWitherable,
  insertAt: () => insertAt,
  intersection: () => intersection2,
  isEmpty: () => isEmpty2,
  isSubmap: () => isSubmap2,
  keys: () => keys,
  lookup: () => lookup2,
  lookupWithKey: () => lookupWithKey,
  map: () => map2,
  mapWithIndex: () => mapWithIndex,
  map_: () => map_,
  member: () => member2,
  modifyAt: () => modifyAt,
  partition: () => partition,
  partitionMap: () => partitionMap,
  partitionMapWithIndex: () => partitionMapWithIndex,
  partitionWithIndex: () => partitionWithIndex,
  pop: () => pop,
  reduce: () => reduce2,
  reduceRight: () => reduceRight2,
  reduceRightWithIndex: () => reduceRightWithIndex2,
  reduceWithIndex: () => reduceWithIndex2,
  separate: () => separate,
  singleton: () => singleton,
  size: () => size2,
  toArray: () => toArray,
  toUnfoldable: () => toUnfoldable,
  union: () => union2,
  updateAt: () => updateAt,
  upsertAt: () => upsertAt,
  values: () => values
});
var getShow2 = getShow;
var size2 = size;
var isEmpty2 = isEmpty;
var member2 = member;
var elem2 = elem;
var keys = (O) => (m) => Array.from(m.keys()).sort(O.compare);
var values = (O) => (m) => Array.from(m.values()).sort(O.compare);
function collect(O) {
  const keysO = keys(O);
  return (f) => (m) => {
    const out = [];
    const ks = keysO(m);
    for (const key of ks) {
      out.push(f(key, m.get(key)));
    }
    return out;
  };
}
function toArray(O) {
  return collect(O)((k, a) => [k, a]);
}
function toUnfoldable(ord, U) {
  const toArrayO = toArray(ord);
  return (d) => {
    const kas = toArrayO(d);
    const len = kas.length;
    return U.unfold(0, (b) => b < len ? some([kas[b], b + 1]) : none);
  };
}
var upsertAt = (E) => {
  const lookupWithKeyE = lookupWithKey(E);
  return (k, a) => {
    const lookupWithKeyEk = lookupWithKeyE(k);
    return (m) => {
      const found = lookupWithKeyEk(m);
      if (isNone(found)) {
        const out = new Map(m);
        out.set(k, a);
        return out;
      } else if (found.value[1] !== a) {
        const out = new Map(m);
        out.set(found.value[0], a);
        return out;
      }
      return m;
    };
  };
};
var deleteAt = (E) => {
  const lookupWithKeyE = lookupWithKey(E);
  return (k) => (m) => {
    const found = lookupWithKeyE(k, m);
    if (isSome(found)) {
      const r = new Map(m);
      r.delete(found.value[0]);
      return r;
    }
    return m;
  };
};
var updateAt = (E) => {
  const modifyAtE = modifyAt(E);
  return (k, a) => modifyAtE(k, () => a);
};
var modifyAt = (E) => {
  const lookupWithKeyE = lookupWithKey(E);
  return (k, f) => (m) => {
    const found = lookupWithKeyE(k, m);
    if (isNone(found)) {
      return none;
    }
    const r = new Map(m);
    r.set(found.value[0], f(found.value[1]));
    return some(r);
  };
};
function pop(E) {
  const lookupE = lookup2(E);
  const deleteAtE = deleteAt(E);
  return (k) => {
    const deleteAtEk = deleteAtE(k);
    return (m) => pipe(
      lookupE(k, m),
      map((a) => [a, deleteAtEk(m)])
    );
  };
}
function lookupWithKey(E) {
  return (k, m) => {
    if (m === void 0) {
      const lookupWithKeyE = lookupWithKey(E);
      return (m2) => lookupWithKeyE(k, m2);
    }
    const entries = m.entries();
    let e;
    while (!(e = entries.next()).done) {
      const [ka, a] = e.value;
      if (E.equals(ka, k)) {
        return some([ka, a]);
      }
    }
    return none;
  };
}
var lookup2 = lookup;
var isSubmap2 = isSubmap;
var getEq2 = getEq;
function getMonoid(SK, SA) {
  const lookupWithKeyS = lookupWithKey(SK);
  return {
    concat: (mx, my) => {
      if (isEmpty2(mx)) {
        return my;
      }
      if (isEmpty2(my)) {
        return mx;
      }
      const r = new Map(mx);
      const entries = my.entries();
      let e;
      while (!(e = entries.next()).done) {
        const [k, a] = e.value;
        const mxOptA = lookupWithKeyS(k, mx);
        if (isSome(mxOptA)) {
          r.set(mxOptA.value[0], SA.concat(mxOptA.value[1], a));
        } else {
          r.set(k, a);
        }
      }
      return r;
    },
    empty: /* @__PURE__ */ new Map()
  };
}
var singleton = (k, a) => /* @__PURE__ */ new Map([[k, a]]);
function fromFoldable(E, M, F) {
  return (fka) => {
    const lookupWithKeyE = lookupWithKey(E);
    return F.reduce(fka, /* @__PURE__ */ new Map(), (b, [k, a]) => {
      const bOpt = lookupWithKeyE(k, b);
      if (isSome(bOpt)) {
        b.set(bOpt.value[0], M.concat(bOpt.value[1], a));
      } else {
        b.set(k, a);
      }
      return b;
    });
  };
}
var _mapWithIndex = (fa, f) => {
  const m = /* @__PURE__ */ new Map();
  const entries = fa.entries();
  let e;
  while (!(e = entries.next()).done) {
    const [key, a] = e.value;
    m.set(key, f(key, a));
  }
  return m;
};
var partitionMapWithIndex = (f) => (fa) => {
  const left = /* @__PURE__ */ new Map();
  const right = /* @__PURE__ */ new Map();
  const entries = fa.entries();
  let e;
  while (!(e = entries.next()).done) {
    const [k, a] = e.value;
    const ei = f(k, a);
    if (isLeft(ei)) {
      left.set(k, ei.left);
    } else {
      right.set(k, ei.right);
    }
  }
  return separated(left, right);
};
function partitionWithIndex(predicateWithIndex) {
  return (fa) => {
    const left = /* @__PURE__ */ new Map();
    const right = /* @__PURE__ */ new Map();
    const entries = fa.entries();
    let e;
    while (!(e = entries.next()).done) {
      const [k, a] = e.value;
      if (predicateWithIndex(k, a)) {
        right.set(k, a);
      } else {
        left.set(k, a);
      }
    }
    return separated(left, right);
  };
}
var filterMapWithIndex = (f) => (fa) => {
  const m = /* @__PURE__ */ new Map();
  const entries = fa.entries();
  let e;
  while (!(e = entries.next()).done) {
    const [k, a] = e.value;
    const o = f(k, a);
    if (isSome(o)) {
      m.set(k, o.value);
    }
  }
  return m;
};
function filterWithIndex(p) {
  return (m) => {
    const out = /* @__PURE__ */ new Map();
    const entries = m.entries();
    let e;
    while (!(e = entries.next()).done) {
      const [k, a] = e.value;
      if (p(k, a)) {
        out.set(k, a);
      }
    }
    return out;
  };
}
var _map = (fa, f) => _mapWithIndex(fa, (_, a) => f(a));
var _filter = (fa, p) => _filterWithIndex(fa, (_, a) => p(a));
var _filterMap = (fa, f) => _filterMapWithIndex(fa, (_, a) => f(a));
var _partition = (fa, predicate) => _partitionWithIndex(fa, (_, a) => predicate(a));
var _partitionMap = (fa, f) => _partitionMapWithIndex(fa, (_, a) => f(a));
var _filterWithIndex = (fa, p) => pipe(fa, filterWithIndex(p));
var _filterMapWithIndex = (fa, f) => pipe(fa, filterMapWithIndex(f));
var _partitionWithIndex = (fa, p) => pipe(fa, partitionWithIndex(p));
var _partitionMapWithIndex = (fa, f) => pipe(fa, partitionMapWithIndex(f));
var compact = (fa) => {
  const m = /* @__PURE__ */ new Map();
  const entries = fa.entries();
  let e;
  while (!(e = entries.next()).done) {
    const [k, oa] = e.value;
    if (isSome(oa)) {
      m.set(k, oa.value);
    }
  }
  return m;
};
var filter = (predicate) => (fa) => _filter(fa, predicate);
var filterMap = (f) => (fa) => _filterMap(fa, f);
var map2 = (f) => (fa) => _map(fa, f);
var mapWithIndex = (f) => (fa) => _mapWithIndex(fa, f);
var partition = (predicate) => (fa) => _partition(fa, predicate);
var partitionMap = (f) => (fa) => _partitionMap(fa, f);
var separate = (fa) => {
  const left = /* @__PURE__ */ new Map();
  const right = /* @__PURE__ */ new Map();
  const entries = fa.entries();
  let e;
  while (!(e = entries.next()).done) {
    const [k, ei] = e.value;
    if (isLeft(ei)) {
      left.set(k, ei.left);
    } else {
      right.set(k, ei.right);
    }
  }
  return separated(left, right);
};
var URI = "Map";
var getUnionSemigroup = (E, S) => {
  const unionES = union2(E, S);
  return {
    concat: (first, second) => unionES(second)(first)
  };
};
var getUnionMonoid = (E, S) => ({
  concat: getUnionSemigroup(E, S).concat,
  empty: /* @__PURE__ */ new Map()
});
var getIntersectionSemigroup = (E, S) => {
  const intersectionES = intersection2(E, S);
  return {
    concat: (first, second) => intersectionES(second)(first)
  };
};
var getDifferenceMagma = (E) => () => {
  const differenceE = difference2(E);
  return {
    concat: (first, second) => differenceE(second)(first)
  };
};
function getFilterableWithIndex() {
  return {
    URI,
    _E: void 0,
    map: _map,
    mapWithIndex: _mapWithIndex,
    compact,
    separate,
    filter: _filter,
    filterMap: _filterMap,
    partition: _partition,
    partitionMap: _partitionMap,
    partitionMapWithIndex: _partitionMapWithIndex,
    partitionWithIndex: _partitionWithIndex,
    filterMapWithIndex: _filterMapWithIndex,
    filterWithIndex: _filterWithIndex
  };
}
function getWitherable(O) {
  const TWI = getTraversableWithIndex(O);
  return {
    URI,
    _E: void 0,
    map: _map,
    compact,
    separate,
    filter: _filter,
    filterMap: _filterMap,
    partition: _partition,
    partitionMap: _partitionMap,
    reduce: TWI.reduce,
    foldMap: TWI.foldMap,
    reduceRight: TWI.reduceRight,
    traverse: TWI.traverse,
    sequence: TWI.sequence,
    mapWithIndex: _mapWithIndex,
    reduceWithIndex: TWI.reduceWithIndex,
    foldMapWithIndex: TWI.foldMapWithIndex,
    reduceRightWithIndex: TWI.reduceRightWithIndex,
    traverseWithIndex: TWI.traverseWithIndex,
    wilt: wiltDefault(TWI, Compactable),
    wither: witherDefault(TWI, Compactable)
  };
}
var reduce2 = reduce;
var foldMap2 = foldMap;
var reduceRight2 = reduceRight;
var getFoldable2 = (O) => {
  return {
    ...getFoldable(O),
    URI
  };
};
var reduceWithIndex2 = reduceWithIndex;
var foldMapWithIndex2 = foldMapWithIndex;
var reduceRightWithIndex2 = reduceRightWithIndex;
var getFoldableWithIndex2 = (O) => {
  return {
    ...getFoldableWithIndex(O),
    URI
  };
};
var getTraversableWithIndex = (O) => {
  const FWI = getFoldableWithIndex2(O);
  const keysO = keys(O);
  const traverseWithIndex = (F) => {
    return (ta, f) => {
      let fm = F.of(/* @__PURE__ */ new Map());
      const ks = keysO(ta);
      const len = ks.length;
      for (let i = 0; i < len; i++) {
        const key = ks[i];
        const a = ta.get(key);
        fm = F.ap(
          F.map(fm, (m) => (b) => m.set(key, b)),
          f(key, a)
        );
      }
      return fm;
    };
  };
  const traverse = (F) => {
    const traverseWithIndexF = traverseWithIndex(F);
    return (ta, f) => traverseWithIndexF(ta, (_, a) => f(a));
  };
  const sequence = (F) => {
    const traverseWithIndexF = traverseWithIndex(F);
    return (ta) => traverseWithIndexF(ta, (_, a) => a);
  };
  return {
    URI,
    _E: void 0,
    map: _map,
    mapWithIndex: _mapWithIndex,
    reduce: FWI.reduce,
    foldMap: FWI.foldMap,
    reduceRight: FWI.reduceRight,
    reduceWithIndex: FWI.reduceWithIndex,
    foldMapWithIndex: FWI.foldMapWithIndex,
    reduceRightWithIndex: FWI.reduceRightWithIndex,
    traverse,
    sequence,
    traverseWithIndex
  };
};
var Functor = {
  URI,
  map: _map
};
var flap2 = /* @__PURE__ */ flap(Functor);
var Compactable = {
  URI,
  compact,
  separate
};
var Filterable = {
  URI,
  map: _map,
  compact,
  separate,
  filter: _filter,
  filterMap: _filterMap,
  partition: _partition,
  partitionMap: _partitionMap
};
var copy = (m) => new Map(m);
var union2 = (E, M) => {
  const unionEM = union(E, M);
  return (second) => (first) => {
    if (isEmpty2(first)) {
      return copy(second);
    }
    if (isEmpty2(second)) {
      return copy(first);
    }
    return unionEM(second)(first);
  };
};
var intersection2 = (E, M) => {
  const intersectionEM = intersection(E, M);
  return (second) => (first) => {
    if (isEmpty2(first) || isEmpty2(second)) {
      return /* @__PURE__ */ new Map();
    }
    return intersectionEM(second)(first);
  };
};
var difference2 = (E) => {
  const differenceE = difference(E);
  return (second) => (first) => {
    if (isEmpty2(first)) {
      return copy(second);
    }
    if (isEmpty2(second)) {
      return copy(first);
    }
    return differenceE(second)(first);
  };
};
var empty = /* @__PURE__ */ new Map();
var insertAt = upsertAt;
var map_ = Filterable;

export {
  getShow2 as getShow,
  size2 as size,
  isEmpty2 as isEmpty,
  member2 as member,
  elem2 as elem,
  keys,
  values,
  collect,
  toArray,
  toUnfoldable,
  upsertAt,
  deleteAt,
  updateAt,
  modifyAt,
  pop,
  lookupWithKey,
  lookup2 as lookup,
  isSubmap2 as isSubmap,
  getEq2 as getEq,
  getMonoid,
  singleton,
  fromFoldable,
  partitionMapWithIndex,
  partitionWithIndex,
  filterMapWithIndex,
  filterWithIndex,
  compact,
  filter,
  filterMap,
  map2 as map,
  mapWithIndex,
  partition,
  partitionMap,
  separate,
  URI,
  getUnionSemigroup,
  getUnionMonoid,
  getIntersectionSemigroup,
  getDifferenceMagma,
  getFilterableWithIndex,
  getWitherable,
  reduce2 as reduce,
  foldMap2 as foldMap,
  reduceRight2 as reduceRight,
  getFoldable2 as getFoldable,
  reduceWithIndex2 as reduceWithIndex,
  foldMapWithIndex2 as foldMapWithIndex,
  reduceRightWithIndex2 as reduceRightWithIndex,
  getFoldableWithIndex2 as getFoldableWithIndex,
  getTraversableWithIndex,
  Functor,
  flap2 as flap,
  Compactable,
  Filterable,
  union2 as union,
  intersection2 as intersection,
  difference2 as difference,
  empty,
  insertAt,
  map_,
  Map_exports
};
