UNPKG

@watergis/maplibre-gl-terradraw

Version:

This plugin is to add controls to your Maplibre for drawing powered by Terra Draw library.

5,043 lines 236 kB
var Xe = Object.defineProperty;
var Ke = (s, t, e) => t in s ? Xe(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e;
var B = (s, t, e) => Ke(s, typeof t != "symbol" ? t + "" : t, e);
import "maplibre-gl";
function I() {
  return I = Object.assign ? Object.assign.bind() : function(s) {
    for (var t = 1; t < arguments.length; t++) {
      var e = arguments[t];
      for (var i in e) ({}).hasOwnProperty.call(e, i) && (s[i] = e[i]);
    }
    return s;
  }, I.apply(null, arguments);
}
var M;
(function(s) {
  s.Commit = "commit", s.Provisional = "provisional", s.Finish = "finish";
})(M || (M = {}));
const V = { SELECTED: "selected", MID_POINT: "midPoint", SELECTION_POINT: "selectionPoint" }, U = "edited", st = "closingPoint", _t = "snappingPoint", Lt = "coordinatePoint", kt = "coordinatePointIds";
function Mt(s) {
  return !!(s && typeof s == "object" && s !== null && !Array.isArray(s));
}
function zt(s) {
  return !!(s && typeof s == "object" && "properties" in s && typeof s.properties == "object" && s.properties !== null && "mode" in s.properties);
}
function Xt(s) {
  return !!function(t) {
    return typeof t == "number" && !isNaN(new Date(t).valueOf());
  }(s);
}
const Ye = "Feature mode property does not match the mode being added to";
var $;
(function(s) {
  s.Drawing = "drawing", s.Select = "select", s.Static = "static", s.Render = "render";
})($ || ($ = {}));
let N = class {
  get state() {
    return this._state;
  }
  set state(t) {
    throw new Error("Please use the modes lifecycle methods");
  }
  get styles() {
    return this._styles;
  }
  set styles(t) {
    if (typeof t != "object") throw new Error("Styling must be an object");
    this.onStyleChange && this.onStyleChange([], "styling"), this._styles = t;
  }
  registerBehaviors(t) {
  }
  constructor(t, e = !1) {
    this._state = "unregistered", this._styles = {}, this.behaviors = [], this.validate = void 0, this.pointerDistance = 40, this.coordinatePrecision = void 0, this.onStyleChange = void 0, this.store = void 0, this.projection = "web-mercator", this.setDoubleClickToZoom = void 0, this.unproject = void 0, this.project = void 0, this.setCursor = void 0, this.type = $.Drawing, this.mode = "base", e || this.updateOptions(t);
  }
  updateOptions(t) {
    t != null && t.styles && (this.styles = I({}, this._styles, t.styles)), t != null && t.pointerDistance && (this.pointerDistance = t.pointerDistance), t != null && t.validation && (this.validate = t && t.validation), t != null && t.projection && (this.projection = t.projection);
  }
  setDrawing() {
    if (this._state !== "started") throw new Error("Mode must be unregistered or stopped to start");
    this._state = "drawing";
  }
  setStarted() {
    if (this._state !== "stopped" && this._state !== "registered" && this._state !== "drawing" && this._state !== "selecting") throw new Error("Mode must be unregistered or stopped to start");
    this._state = "started", this.setDoubleClickToZoom(!1);
  }
  setStopped() {
    if (this._state !== "started") throw new Error("Mode must be started to be stopped");
    this._state = "stopped", this.setDoubleClickToZoom(!0);
  }
  register(t) {
    if (this._state !== "unregistered") throw new Error("Can not register unless mode is unregistered");
    this._state = "registered", this.store = t.store, this.store.registerOnChange(t.onChange), this.setDoubleClickToZoom = t.setDoubleClickToZoom, this.project = t.project, this.unproject = t.unproject, this.onSelect = t.onSelect, this.onDeselect = t.onDeselect, this.setCursor = t.setCursor, this.onStyleChange = t.onChange, this.onFinish = t.onFinish, this.coordinatePrecision = t.coordinatePrecision, this.registerBehaviors({ mode: t.mode, store: this.store, project: this.project, unproject: this.unproject, pointerDistance: this.pointerDistance, coordinatePrecision: t.coordinatePrecision, projection: this.projection });
  }
  validateFeature(t) {
    return this.performFeatureValidation(t);
  }
  afterFeatureAdded(t) {
  }
  performFeatureValidation(t) {
    if (this._state === "unregistered") throw new Error("Mode must be registered");
    const e = function(i, o) {
      let r;
      if (Mt(i)) if (i.id == null) r = "Feature has no id";
      else if (typeof i.id != "string" && typeof i.id != "number") r = "Feature must be string or number as per GeoJSON spec";
      else if (o(i.id)) if (Mt(i.geometry)) if (Mt(i.properties)) if (typeof i.geometry.type == "string" && ["Polygon", "LineString", "Point"].includes(i.geometry.type)) if (Array.isArray(i.geometry.coordinates)) {
        if (!i.properties.mode || typeof i.properties.mode != "string") return { valid: !1, reason: "Feature does not have a valid mode property" };
      } else r = "Feature coordinates is not an array";
      else r = "Feature is not Point, LineString or Polygon";
      else r = "Feature has no properties";
      else r = "Feature has no geometry";
      else r = "Feature must match the id strategy (default is UUID4)";
      else r = "Feature is not object";
      return r ? { valid: !1, reason: r } : { valid: !0 };
    }(t, this.store.idStrategy.isValidId);
    if (this.validate) {
      const i = this.validate(t, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Provisional });
      return { valid: e.valid && i.valid, reason: i.reason };
    }
    return { valid: e.valid, reason: e.reason };
  }
  validateModeFeature(t, e) {
    const i = this.performFeatureValidation(t);
    return i.valid ? t.properties.mode !== this.mode ? { valid: !1, reason: Ye } : e(t) : { valid: !1, reason: i.reason };
  }
  onFinish(t, e) {
  }
  onDeselect(t) {
  }
  onSelect(t) {
  }
  onKeyDown(t) {
  }
  onKeyUp(t) {
  }
  onMouseMove(t) {
  }
  onClick(t) {
  }
  onDragStart(t, e) {
  }
  onDrag(t, e) {
  }
  onDragEnd(t, e) {
  }
  getHexColorStylingValue(t, e, i) {
    return this.getStylingValue(t, e, i);
  }
  getNumericStylingValue(t, e, i) {
    return this.getStylingValue(t, e, i);
  }
  getStylingValue(t, e, i) {
    return t === void 0 ? e : typeof t == "function" ? t(i) : t;
  }
}, $e = class extends N {
  constructor(...t) {
    super(...t), this.type = $.Select;
  }
};
function T(s, t) {
  const e = (d) => d * Math.PI / 180, i = e(s[1]), o = e(s[0]), r = e(t[1]), n = r - i, a = e(t[0]) - o, l = Math.sin(n / 2) * Math.sin(n / 2) + Math.cos(i) * Math.cos(r) * Math.sin(a / 2) * Math.sin(a / 2);
  return 2 * Math.atan2(Math.sqrt(l), Math.sqrt(1 - l)) * 6371e3 / 1e3;
}
const me = 63710088e-1;
function O(s) {
  return s % 360 * Math.PI / 180;
}
function ve(s) {
  return s / 6371.0088;
}
function R(s) {
  return s % (2 * Math.PI) * 180 / Math.PI;
}
function F(s, t = 9) {
  const e = Math.pow(10, t);
  return Math.round(s * e) / e;
}
const Kt = 57.29577951308232, Yt = 0.017453292519943295, ft = 6378137, x = (s, t) => ({ x: s === 0 ? 0 : s * Yt * ft, y: t === 0 ? 0 : Math.log(Math.tan(Math.PI / 4 + t * Yt / 2)) * ft }), W = (s, t) => ({ lng: s === 0 ? 0 : Kt * (s / ft), lat: t === 0 ? 0 : (2 * Math.atan(Math.exp(t / ft)) - Math.PI / 2) * Kt });
function He(s, t, e) {
  const i = O(s[0]), o = O(s[1]), r = O(e), n = ve(t), a = Math.asin(Math.sin(o) * Math.cos(n) + Math.cos(o) * Math.sin(n) * Math.cos(r));
  return [R(i + Math.atan2(Math.sin(r) * Math.sin(n) * Math.cos(o), Math.cos(n) - Math.sin(o) * Math.sin(a))), R(a)];
}
function $t(s) {
  const { center: t, radiusKilometers: e, coordinatePrecision: i } = s, o = s.steps ? s.steps : 64, r = [];
  for (let n = 0; n < o; n++) {
    const a = He(t, e, -360 * n / o);
    r.push([F(a[0], i), F(a[1], i)]);
  }
  return r.push(r[0]), { type: "Feature", geometry: { type: "Polygon", coordinates: [r] }, properties: {} };
}
function Bt(s) {
  let t;
  if (s.geometry.type === "Polygon") t = s.geometry.coordinates;
  else {
    if (s.geometry.type !== "LineString") throw new Error("Self intersects only accepts Polygons and LineStrings");
    t = [s.geometry.coordinates];
  }
  const e = [];
  for (let r = 0; r < t.length; r++) for (let n = 0; n < t[r].length - 1; n++) for (let a = 0; a < t.length; a++) for (let l = 0; l < t[a].length - 1; l++) o(r, n, a, l);
  return e.length > 0;
  function i(r) {
    return r < 0 || r > 1;
  }
  function o(r, n, a, l) {
    const d = t[r][n], h = t[r][n + 1], c = t[a][l], u = t[a][l + 1], p = function(m, v, f, C) {
      if (ht(m, f) || ht(m, C) || ht(v, f) || ht(C, f)) return null;
      const P = m[0], S = m[1], b = v[0], w = v[1], D = f[0], G = f[1], _ = C[0], j = C[1], z = (P - b) * (G - j) - (S - w) * (D - _);
      return z === 0 ? null : [((P * w - S * b) * (D - _) - (P - b) * (D * j - G * _)) / z, ((P * w - S * b) * (G - j) - (S - w) * (D * j - G * _)) / z];
    }(d, h, c, u);
    if (p === null) return;
    let g, y;
    g = h[0] !== d[0] ? (p[0] - d[0]) / (h[0] - d[0]) : (p[1] - d[1]) / (h[1] - d[1]), y = u[0] !== c[0] ? (p[0] - c[0]) / (u[0] - c[0]) : (p[1] - c[1]) / (u[1] - c[1]), i(g) || i(y) || (p.toString(), e.push(p));
  }
}
function ht(s, t) {
  return s[0] === t[0] && s[1] === t[1];
}
function xt(s, t) {
  return Ht(s[0]) <= t && Ht(s[1]) <= t;
}
function Wt(s) {
  return s.length === 2 && typeof s[0] == "number" && typeof s[1] == "number" && s[0] !== 1 / 0 && s[1] !== 1 / 0 && (e = s[0]) >= -180 && e <= 180 && (t = s[1]) >= -90 && t <= 90;
  var t, e;
}
function Ht(s) {
  let t = 1, e = 0;
  for (; Math.round(s * t) / t !== s; ) t *= 10, e++;
  return e;
}
const qe = "Feature has holes", Je = "Feature has less than 4 coordinates", Ze = "Feature has invalid coordinates", Qe = "Feature coordinates are not closed";
function It(s, t) {
  if (s.geometry.type !== "Polygon") return { valid: !1, reason: "Feature is not a Polygon" };
  if (s.geometry.coordinates.length !== 1) return { valid: !1, reason: qe };
  if (s.geometry.coordinates[0].length < 4) return { valid: !1, reason: Je };
  for (let o = 0; o < s.geometry.coordinates[0].length; o++) {
    if (!Wt(s.geometry.coordinates[0][o])) return { valid: !1, reason: Ze };
    if (!xt(s.geometry.coordinates[0][o], t)) return { valid: !1, reason: "Feature has coordinates with excessive precision" };
  }
  return (e = s.geometry.coordinates[0][0])[0] !== (i = s.geometry.coordinates[0][s.geometry.coordinates[0].length - 1])[0] || e[1] !== i[1] ? { valid: !1, reason: Qe } : { valid: !0 };
  var e, i;
}
function lt(s, t) {
  const e = It(s, t);
  return e.valid ? Bt(s) ? { valid: !1, reason: "Feature intersects itself" } : { valid: !0 } : e;
}
const ti = { cancel: "Escape", finish: "Enter" }, ei = { start: "crosshair" };
class Ce extends N {
  constructor(t) {
    super(t, !0), this.mode = "circle", this.center = void 0, this.clickCount = 0, this.currentCircleId = void 0, this.keyEvents = ti, this.cursors = ei, this.startingRadiusKilometers = 1e-5, this.cursorMovedAfterInitialCursorDown = !1, this.updateOptions(t);
  }
  updateOptions(t) {
    super.updateOptions(t), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors)), (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { cancel: null, finish: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents)), t != null && t.startingRadiusKilometers && (this.startingRadiusKilometers = t.startingRadiusKilometers);
  }
  close() {
    if (this.currentCircleId === void 0) return;
    const t = this.currentCircleId;
    if (this.validate && t) {
      const e = this.store.getGeometryCopy(t);
      if (!this.validate({ type: "Feature", id: t, geometry: e, properties: {} }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Finish }).valid) return;
    }
    this.cursorMovedAfterInitialCursorDown = !1, this.center = void 0, this.currentCircleId = void 0, this.clickCount = 0, this.state === "drawing" && this.setStarted(), this.onFinish(t, { mode: this.mode, action: "draw" });
  }
  start() {
    this.setStarted(), this.setCursor(this.cursors.start);
  }
  stop() {
    this.cleanUp(), this.setStopped(), this.setCursor("unset");
  }
  onClick(t) {
    if (this.clickCount === 0) {
      this.center = [t.lng, t.lat];
      const e = $t({ center: this.center, radiusKilometers: this.startingRadiusKilometers, coordinatePrecision: this.coordinatePrecision }), [i] = this.store.create([{ geometry: e.geometry, properties: { mode: this.mode, radiusKilometers: this.startingRadiusKilometers } }]);
      this.currentCircleId = i, this.clickCount++, this.cursorMovedAfterInitialCursorDown = !1, this.setDrawing();
    } else this.clickCount === 1 && this.center && this.currentCircleId !== void 0 && this.cursorMovedAfterInitialCursorDown && this.updateCircle(t), this.close();
  }
  onMouseMove(t) {
    this.cursorMovedAfterInitialCursorDown = !0, this.updateCircle(t);
  }
  onKeyDown() {
  }
  onKeyUp(t) {
    t.key === this.keyEvents.cancel ? this.cleanUp() : t.key === this.keyEvents.finish && this.close();
  }
  onDragStart() {
  }
  onDrag() {
  }
  onDragEnd() {
  }
  cleanUp() {
    const t = this.currentCircleId;
    this.center = void 0, this.currentCircleId = void 0, this.clickCount = 0, this.state === "drawing" && this.setStarted();
    try {
      t !== void 0 && this.store.delete([t]);
    } catch {
    }
  }
  styleFeature(t) {
    const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
    return t.type === "Feature" && t.geometry.type === "Polygon" && t.properties.mode === this.mode && (e.polygonFillColor = this.getHexColorStylingValue(this.styles.fillColor, e.polygonFillColor, t), e.polygonOutlineColor = this.getHexColorStylingValue(this.styles.outlineColor, e.polygonOutlineColor, t), e.polygonOutlineWidth = this.getNumericStylingValue(this.styles.outlineWidth, e.polygonOutlineWidth, t), e.polygonFillOpacity = this.getNumericStylingValue(this.styles.fillOpacity, e.polygonFillOpacity, t), e.zIndex = 10), e;
  }
  validateFeature(t) {
    return this.validateModeFeature(t, (e) => lt(e, this.coordinatePrecision));
  }
  updateCircle(t) {
    if (this.clickCount === 1 && this.center && this.currentCircleId) {
      const e = T(this.center, [t.lng, t.lat]);
      let i;
      if (this.projection === "web-mercator") {
        const o = function(r, n) {
          const a = 1e3 * T(r, n);
          if (a === 0) return 1;
          const { x: l, y: d } = x(r[0], r[1]), { x: h, y: c } = x(n[0], n[1]);
          return Math.sqrt(Math.pow(h - l, 2) + Math.pow(c - d, 2)) / a;
        }(this.center, [t.lng, t.lat]);
        i = function(r) {
          const { center: n, radiusKilometers: a, coordinatePrecision: l } = r, d = r.steps ? r.steps : 64, h = 1e3 * a, [c, u] = n, { x: p, y: g } = x(c, u), y = [];
          for (let m = 0; m < d; m++) {
            const v = 360 * m / d * Math.PI / 180, f = h * Math.cos(v), C = h * Math.sin(v), [P, S] = [p + f, g + C], { lng: b, lat: w } = W(P, S);
            y.push([F(b, l), F(w, l)]);
          }
          return y.push(y[0]), { type: "Feature", geometry: { type: "Polygon", coordinates: [y] }, properties: {} };
        }({ center: this.center, radiusKilometers: e * o, coordinatePrecision: this.coordinatePrecision });
      } else {
        if (this.projection !== "globe") throw new Error("Invalid projection");
        i = $t({ center: this.center, radiusKilometers: e, coordinatePrecision: this.coordinatePrecision });
      }
      if (this.validate && !this.validate({ type: "Feature", id: this.currentCircleId, geometry: i.geometry, properties: { radiusKilometers: e } }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Provisional }).valid) return;
      this.store.updateGeometry([{ id: this.currentCircleId, geometry: i.geometry }]), this.store.updateProperty([{ id: this.currentCircleId, property: "radiusKilometers", value: e }]);
    }
  }
}
const E = (s, t) => {
  const { x: e, y: i } = s, { x: o, y: r } = t, n = o - e, a = r - i;
  return Math.sqrt(a * a + n * n);
};
function dt(s) {
  if (!function(e) {
    const i = e.coordinates[0];
    let o = 0;
    for (let r = 0; r < i.length - 1; r++) {
      const [n, a] = i[r], [l, d] = i[r + 1];
      o += (l - n) * (d + a);
    }
    return o < 0;
  }(s)) return { type: "Polygon", coordinates: [s.coordinates[0].reverse()] };
}
const ii = { cancel: "Escape", finish: "Enter" }, oi = { start: "crosshair", close: "pointer" };
class Pe extends N {
  constructor(t) {
    super(t, !0), this.mode = "freehand", this.startingClick = !1, this.currentId = void 0, this.closingPointId = void 0, this.minDistance = 20, this.keyEvents = ii, this.cursors = oi, this.preventPointsNearClose = !0, this.autoClose = !1, this.autoCloseTimeout = 500, this.hasLeftStartingPoint = !1, this.preventNewFeature = !1, this.updateOptions(t);
  }
  updateOptions(t) {
    super.updateOptions(t), t != null && t.minDistance && (this.minDistance = t.minDistance), (t == null ? void 0 : t.preventPointsNearClose) !== void 0 && (this.preventPointsNearClose = t.preventPointsNearClose), (t == null ? void 0 : t.autoClose) !== void 0 && (this.autoClose = t.autoClose), t != null && t.autoCloseTimeout && (this.autoCloseTimeout = t.autoCloseTimeout), (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { cancel: null, finish: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents)), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors));
  }
  close() {
    if (this.currentId === void 0) return;
    if (this.currentId) {
      const e = dt(this.store.getGeometryCopy(this.currentId));
      e && this.store.updateGeometry([{ id: this.currentId, geometry: e }]);
    }
    const t = this.currentId;
    if (this.validate && t) {
      const e = this.store.getGeometryCopy(t);
      if (!this.validate({ type: "Feature", id: t, geometry: e, properties: {} }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Finish }).valid) return;
    }
    this.closingPointId && this.store.delete([this.closingPointId]), this.startingClick = !1, this.currentId = void 0, this.closingPointId = void 0, this.hasLeftStartingPoint = !1, this.state === "drawing" && this.setStarted(), this.onFinish(t, { mode: this.mode, action: "draw" });
  }
  start() {
    this.setStarted(), this.setCursor(this.cursors.start);
  }
  stop() {
    this.cleanUp(), this.setStopped(), this.setCursor("unset");
  }
  onMouseMove(t) {
    if (this.currentId === void 0 || this.startingClick === !1) return;
    const e = this.store.getGeometryCopy(this.currentId), i = e.coordinates[0].length - 2, [o, r] = e.coordinates[0][i], { x: n, y: a } = this.project(o, r), l = E({ x: n, y: a }, { x: t.containerX, y: t.containerY }), [d, h] = e.coordinates[0][0], { x: c, y: u } = this.project(d, h);
    if (E({ x: c, y: u }, { x: t.containerX, y: t.containerY }) < this.pointerDistance) {
      if (this.autoClose && this.hasLeftStartingPoint && (this.preventNewFeature = !0, setTimeout(() => {
        this.preventNewFeature = !1;
      }, this.autoCloseTimeout), this.close()), this.setCursor(this.cursors.close), this.preventPointsNearClose) return;
    } else this.hasLeftStartingPoint = !0, this.setCursor(this.cursors.start);
    if (l < this.minDistance) return;
    e.coordinates[0].pop();
    const p = { type: "Polygon", coordinates: [[...e.coordinates[0], [t.lng, t.lat], e.coordinates[0][0]]] };
    this.validate && !this.validate({ type: "Feature", id: this.currentId, geometry: p, properties: {} }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Provisional }).valid || this.store.updateGeometry([{ id: this.currentId, geometry: p }]);
  }
  onClick(t) {
    if (!this.preventNewFeature) {
      if (this.startingClick === !1) {
        const [e, i] = this.store.create([{ geometry: { type: "Polygon", coordinates: [[[t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat]]] }, properties: { mode: this.mode } }, { geometry: { type: "Point", coordinates: [t.lng, t.lat] }, properties: { mode: this.mode, [st]: !0 } }]);
        return this.currentId = e, this.closingPointId = i, this.startingClick = !0, void this.setDrawing();
      }
      this.close();
    }
  }
  onKeyDown() {
  }
  onKeyUp(t) {
    t.key === this.keyEvents.cancel ? this.cleanUp() : t.key === this.keyEvents.finish && this.startingClick === !0 && this.close();
  }
  onDragStart() {
  }
  onDrag() {
  }
  onDragEnd() {
  }
  cleanUp() {
    const t = this.currentId, e = this.closingPointId;
    this.closingPointId = void 0, this.currentId = void 0, this.startingClick = !1, this.state === "drawing" && this.setStarted();
    try {
      t !== void 0 && this.store.delete([t]), e !== void 0 && this.store.delete([e]);
    } catch {
    }
  }
  styleFeature(t) {
    const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
    return t.type === "Feature" && t.geometry.type === "Polygon" && t.properties.mode === this.mode ? (e.polygonFillColor = this.getHexColorStylingValue(this.styles.fillColor, e.polygonFillColor, t), e.polygonOutlineColor = this.getHexColorStylingValue(this.styles.outlineColor, e.polygonOutlineColor, t), e.polygonOutlineWidth = this.getNumericStylingValue(this.styles.outlineWidth, e.polygonOutlineWidth, t), e.polygonFillOpacity = this.getNumericStylingValue(this.styles.fillOpacity, e.polygonFillOpacity, t), e.zIndex = 10, e) : (t.type === "Feature" && t.geometry.type === "Point" && t.properties.mode === this.mode && (e.pointWidth = this.getNumericStylingValue(this.styles.closingPointWidth, e.pointWidth, t), e.pointColor = this.getHexColorStylingValue(this.styles.closingPointColor, e.pointColor, t), e.pointOutlineColor = this.getHexColorStylingValue(this.styles.closingPointOutlineColor, e.pointOutlineColor, t), e.pointOutlineWidth = this.getNumericStylingValue(this.styles.closingPointOutlineWidth, 2, t), e.zIndex = 40), e);
  }
  validateFeature(t) {
    return this.validateModeFeature(t, (e) => It(e, this.coordinatePrecision));
  }
}
class k {
  constructor({ store: t, mode: e, project: i, unproject: o, pointerDistance: r, coordinatePrecision: n, projection: a }) {
    this.store = void 0, this.mode = void 0, this.project = void 0, this.unproject = void 0, this.pointerDistance = void 0, this.coordinatePrecision = void 0, this.projection = void 0, this.store = t, this.mode = e, this.project = i, this.unproject = o, this.pointerDistance = r, this.coordinatePrecision = n, this.projection = a;
  }
}
function Se({ unproject: s, point: t, pointerDistance: e }) {
  const i = e / 2, { x: o, y: r } = t;
  return { type: "Feature", properties: {}, geometry: { type: "Polygon", coordinates: [[s(o - i, r - i), s(o + i, r - i), s(o + i, r + i), s(o - i, r + i), s(o - i, r - i)].map((n) => [n.lng, n.lat])] } };
}
class rt extends k {
  constructor(t) {
    super(t);
  }
  create(t) {
    const { containerX: e, containerY: i } = t;
    return Se({ unproject: this.unproject, point: { x: e, y: i }, pointerDistance: this.pointerDistance });
  }
}
class nt extends k {
  constructor(t) {
    super(t);
  }
  measure(t, e) {
    const { x: i, y: o } = this.project(e[0], e[1]);
    return E({ x: i, y: o }, { x: t.containerX, y: t.containerY });
  }
}
class mt extends k {
  constructor(t, e, i) {
    super(t), this.config = void 0, this.pixelDistance = void 0, this.clickBoundingBox = void 0, this.getSnappableCoordinateFirstClick = (o) => this.getSnappable(o, (r) => !!(r.properties && r.properties.mode === this.mode)).coordinate, this.getSnappableCoordinate = (o, r) => this.getSnappable(o, (n) => !!(n.properties && n.properties.mode === this.mode && n.id !== r)).coordinate, this.config = t, this.pixelDistance = e, this.clickBoundingBox = i;
  }
  getSnappable(t, e) {
    const i = this.clickBoundingBox.create(t), o = this.store.search(i, e), r = { featureId: void 0, featureCoordinateIndex: void 0, coordinate: void 0, minDist: 1 / 0 };
    return o.forEach((n) => {
      let a;
      if (n.geometry.type === "Polygon") a = n.geometry.coordinates[0];
      else {
        if (n.geometry.type !== "LineString") return;
        a = n.geometry.coordinates;
      }
      a.forEach((l, d) => {
        const h = this.pixelDistance.measure(t, l);
        h < r.minDist && h < this.pointerDistance && (r.coordinate = l, r.minDist = h, r.featureId = n.id, r.featureCoordinateIndex = d);
      });
    }), r;
  }
}
function qt(s, t, e) {
  const i = O(s[0]), o = O(s[1]), r = O(e), n = ve(t), a = Math.asin(Math.sin(o) * Math.cos(n) + Math.cos(o) * Math.sin(n) * Math.cos(r));
  return [R(i + Math.atan2(Math.sin(r) * Math.sin(n) * Math.cos(o), Math.cos(n) - Math.sin(o) * Math.sin(a))), R(a)];
}
function at({ x: s, y: t }, e, i) {
  const o = O(i);
  return { x: s + e * Math.cos(o), y: t + e * Math.sin(o) };
}
function Jt(s, t) {
  const e = O(s[0]), i = O(t[0]), o = O(s[1]), r = O(t[1]), n = Math.sin(i - e) * Math.cos(r), a = Math.cos(o) * Math.sin(r) - Math.sin(o) * Math.cos(r) * Math.cos(i - e);
  return R(Math.atan2(n, a));
}
function A({ x: s, y: t }, { x: e, y: i }) {
  let o = Math.atan2(i - t, e - s);
  return o *= 180 / Math.PI, o > 180 ? o -= 360 : o < -180 && (o += 360), o;
}
function Y(s) {
  return (s + 360) % 360;
}
function si(s, t, e) {
  const i = [], o = s.length;
  let r, n, a, l = 0;
  for (let h = 0; h < s.length && !(t >= l && h === s.length - 1); h++) {
    if (l > t && i.length === 0) {
      if (r = t - l, !r) return i.push(s[h]), i;
      n = Jt(s[h], s[h - 1]) - 180, a = qt(s[h], r, n), i.push(a);
    }
    if (l >= e) return r = e - l, r ? (n = Jt(s[h], s[h - 1]) - 180, a = qt(s[h], r, n), i.push(a), i) : (i.push(s[h]), i);
    if (l >= t && i.push(s[h]), h === s.length - 1) return i;
    l += T(s[h], s[h + 1]);
  }
  if (l < t && s.length === o) throw new Error("Start position is beyond line");
  const d = s[s.length - 1];
  return [d, d];
}
function ct(s) {
  return s * (Math.PI / 180);
}
function Zt(s) {
  return s * (180 / Math.PI);
}
class ri extends k {
  constructor(t) {
    super(t), this.config = void 0, this.config = t;
  }
  generateInsertionCoordinates(t, e, i) {
    const o = [t, e];
    let r = 0;
    for (let d = 0; d < o.length - 1; d++) r += T(o[0], o[1]);
    if (r <= i) return o;
    let n = r / i - 1;
    Number.isInteger(n) || (n = Math.floor(n) + 1);
    const a = [];
    for (let d = 0; d < n; d++) {
      const h = si(o, i * d, i * (d + 1));
      a.push(h);
    }
    const l = [];
    for (let d = 0; d < a.length; d++) l.push(a[d][1]);
    return this.limitCoordinates(l);
  }
  generateInsertionGeodesicCoordinates(t, e, i) {
    const o = T(t, e), r = function(n, a, l) {
      const d = [], h = ct(n[1]), c = ct(n[0]), u = ct(a[1]), p = ct(a[0]);
      l += 1;
      const g = 2 * Math.asin(Math.sqrt(Math.sin((u - h) / 2) ** 2 + Math.cos(h) * Math.cos(u) * Math.sin((p - c) / 2) ** 2));
      if (g === 0 || isNaN(g)) return d;
      for (let y = 0; y <= l; y++) {
        const m = y / l, v = Math.sin((1 - m) * g) / Math.sin(g), f = Math.sin(m * g) / Math.sin(g), C = v * Math.cos(h) * Math.cos(c) + f * Math.cos(u) * Math.cos(p), P = v * Math.cos(h) * Math.sin(c) + f * Math.cos(u) * Math.sin(p), S = v * Math.sin(h) + f * Math.sin(u);
        if (isNaN(C) || isNaN(P) || isNaN(S)) continue;
        const b = Math.atan2(S, Math.sqrt(C ** 2 + P ** 2)), w = Math.atan2(P, C);
        isNaN(b) || isNaN(w) || d.push([Zt(w), Zt(b)]);
      }
      return d.slice(1, -1);
    }(t, e, Math.floor(o / i));
    return this.limitCoordinates(r);
  }
  limitCoordinates(t) {
    return t.map((e) => [F(e[0], this.config.coordinatePrecision), F(e[1], this.config.coordinatePrecision)]);
  }
}
function Z(s, t) {
  return s[0] === t[0] && s[1] === t[1];
}
function xe(s, t) {
  if (s.geometry.type !== "LineString") return { valid: !1, reason: "Feature is not a LineString" };
  if (s.geometry.coordinates.length < 2) return { valid: !1, reason: "Feature has less than 2 coordinates" };
  for (let e = 0; e < s.geometry.coordinates.length; e++) {
    if (!Wt(s.geometry.coordinates[e])) return { valid: !1, reason: "Feature has invalid coordinates" };
    if (!xt(s.geometry.coordinates[e], t)) return { valid: !1, reason: "Feature has coordinates with excessive precision" };
  }
  return { valid: !0 };
}
function Qt(s) {
  return Math.sqrt(Math.pow(s[0], 2) + Math.pow(s[1], 2) + Math.pow(s[2], 2));
}
function X(s, t) {
  const e = function(i, o) {
    const [r, n, a] = i, [l, d, h] = o;
    return r * l + n * d + a * h;
  }(s, t) / (Qt(s) * Qt(t));
  return Math.acos(Math.min(Math.max(e, -1), 1));
}
function wt(s) {
  const t = O(s[1]), e = O(s[0]);
  return [Math.cos(t) * Math.cos(e), Math.cos(t) * Math.sin(e), Math.sin(t)];
}
function K(s) {
  const [t, e, i] = s, o = R(Math.asin(i));
  return [R(Math.atan2(e, t)), o];
}
function ni(s, t, e) {
  const i = wt(s), o = wt(t), r = wt(e), [n, a, l] = r, [d, h, c] = function(j, z) {
    const [Gt, At, Tt] = j, [Ut, Vt, Rt] = z;
    return [At * Rt - Tt * Vt, Tt * Ut - Gt * Rt, Gt * Vt - At * Ut];
  }(i, o), u = h * l - c * a, p = c * n - d * l, g = d * a - h * n, y = g * h - p * c, m = u * c - g * d, v = p * d - u * h, f = 1 / Math.sqrt(Math.pow(y, 2) + Math.pow(m, 2) + Math.pow(v, 2)), C = [y * f, m * f, v * f], P = [-1 * y * f, -1 * m * f, -1 * v * f], S = X(i, o), b = X(i, C), w = X(o, C), D = X(i, P), G = X(o, P);
  let _;
  return _ = b < D && b < G || w < D && w < G ? C : P, X(i, _) > S || X(o, _) > S ? T(K(_), K(i)) <= T(K(_), K(o)) ? [K(i), !0, !1] : [K(o), !1, !0] : [K(_), !1, !1];
}
function ai(s, t, e) {
  const i = t.x - s.x, o = t.y - s.y, r = Math.max(0, Math.min(1, ((e.x - s.x) * i + (e.y - s.y) * o) / (i * i + o * o)));
  return { x: s.x + r * i, y: s.y + r * o };
}
class Ie extends k {
  constructor(t, e, i) {
    super(t), this.config = void 0, this.pixelDistance = void 0, this.clickBoundingBox = void 0, this.getSnappableCoordinateFirstClick = (o) => this.getSnappable(o, (r) => !!(r.properties && r.properties.mode === this.mode)).coordinate, this.getSnappableCoordinate = (o, r) => this.getSnappable(o, (n) => !!(n.properties && n.properties.mode === this.mode && n.id !== r)).coordinate, this.config = t, this.pixelDistance = e, this.clickBoundingBox = i;
  }
  getSnappable(t, e) {
    const i = this.clickBoundingBox.create(t), o = this.store.search(i, e), r = { featureId: void 0, featureCoordinateIndex: void 0, coordinate: void 0, minDistance: 1 / 0 };
    return o.forEach((n) => {
      let a;
      if (n.geometry.type === "Polygon") a = n.geometry.coordinates[0];
      else {
        if (n.geometry.type !== "LineString") return;
        a = n.geometry.coordinates;
      }
      const l = [];
      for (let u = 0; u < a.length - 1; u++) l.push([a[u], a[u + 1]]);
      let d;
      const h = [t.lng, t.lat];
      if (this.config.projection === "web-mercator" ? d = function(u, p) {
        let g = [1 / 0, 1 / 0], y = 1 / 0, m = 0;
        for (let v of p) {
          const f = v[0], C = v[1];
          let P, S = 1 / 0;
          const b = x(f[0], f[1]), w = x(C[0], C[1]), D = x(u[0], u[1]);
          if (f[0] === u[0] && f[1] === u[1]) P = f;
          else if (C[0] === u[0] && C[1] === u[1]) P = C;
          else {
            const { x: G, y: _ } = ai(b, w, D), { lng: j, lat: z } = W(G, _);
            P = [j, z];
          }
          P && (S = E(D, x(P[0], P[1])), S < y && (g = P, y = S, m = p.indexOf(v)));
        }
        return y === 1 / 0 ? void 0 : { coordinate: g, lineIndex: m, distance: y };
      }(h, l) : this.config.projection === "globe" && (d = function(u, p) {
        let g = [1 / 0, 1 / 0], y = 1 / 0, m = 0;
        for (let v of p) {
          const f = v[0], C = v[1];
          let P, S = 1 / 0;
          f[0] === u[0] && f[1] === u[1] ? P = f : C[0] === u[0] && C[1] === u[1] ? P = C : [P] = ni(f, C, u), P && (S = T(u, P), S < y && (g = P, y = S, m = p.indexOf(v)));
        }
        return y === 1 / 0 ? void 0 : { coordinate: g, distance: y, lineIndex: m };
      }(h, l)), !d) return;
      const c = this.pixelDistance.measure(t, d.coordinate);
      c < r.minDistance && c < this.pointerDistance && (r.featureId = n.id, r.coordinate = d.coordinate, r.featureCoordinateIndex = d.lineIndex, r.minDistance = c);
    }), r;
  }
}
const li = { cancel: "Escape", finish: "Enter" }, di = { start: "crosshair", close: "pointer", dragStart: "grabbing", dragEnd: "crosshair" };
class be extends N {
  constructor(t) {
    super(t, !0), this.mode = "linestring", this.currentCoordinate = 0, this.currentId = void 0, this.closingPointId = void 0, this.keyEvents = li, this.snapping = void 0, this.cursors = di, this.mouseMove = !1, this.insertCoordinates = void 0, this.lastCommitedCoordinates = void 0, this.snappedPointId = void 0, this.editable = !1, this.editedFeatureId = void 0, this.editedFeatureCoordinateIndex = void 0, this.editedSnapType = void 0, this.editedInsertIndex = void 0, this.editedPointId = void 0, this.coordinateSnapping = void 0, this.insertPoint = void 0, this.lineSnapping = void 0, this.pixelDistance = void 0, this.clickBoundingBox = void 0, this.updateOptions(t);
  }
  updateOptions(t) {
    super.updateOptions(t), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors)), t != null && t.snapping && (this.snapping = t.snapping), (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { cancel: null, finish: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents)), t != null && t.insertCoordinates && (this.insertCoordinates = t.insertCoordinates), t && t.editable && (this.editable = t.editable);
  }
  close() {
    if (this.currentId === void 0) return;
    const t = this.store.getGeometryCopy(this.currentId);
    t.coordinates.pop(), this.updateGeometries([...t.coordinates], void 0, M.Commit);
    const e = this.currentId;
    this.closingPointId && this.store.delete([this.closingPointId]), this.snappedPointId && this.store.delete([this.snappedPointId]), this.currentCoordinate = 0, this.currentId = void 0, this.closingPointId = void 0, this.snappedPointId = void 0, this.lastCommitedCoordinates = void 0, this.state === "drawing" && this.setStarted(), this.onFinish(e, { mode: this.mode, action: "draw" });
  }
  updateGeometries(t, e, i) {
    if (!this.currentId) return;
    const o = { type: "LineString", coordinates: t };
    if (this.validate && !this.validate({ type: "Feature", geometry: o }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: i }).valid) return;
    const r = [{ id: this.currentId, geometry: o }];
    this.closingPointId && e && r.push({ id: this.closingPointId, geometry: { type: "Point", coordinates: e } }), i === "commit" && (this.lastCommitedCoordinates = o.coordinates), this.store.updateGeometry(r);
  }
  generateInsertCoordinates(t, e) {
    if (!this.insertCoordinates || !this.lastCommitedCoordinates) throw new Error("Not able to insert coordinates");
    if (this.insertCoordinates.strategy !== "amount") throw new Error("Strategy does not exist");
    const i = T(t, e) / (this.insertCoordinates.value + 1);
    let o = [];
    return this.projection === "globe" ? o = this.insertPoint.generateInsertionGeodesicCoordinates(t, e, i) : this.projection === "web-mercator" && (o = this.insertPoint.generateInsertionCoordinates(t, e, i)), o;
  }
  createLine(t) {
    const [e] = this.store.create([{ geometry: { type: "LineString", coordinates: [t, t] }, properties: { mode: this.mode } }]);
    this.lastCommitedCoordinates = [t, t], this.currentId = e, this.currentCoordinate++, this.setDrawing();
  }
  firstUpdateToLine(t) {
    if (!this.currentId) return;
    const e = this.store.getGeometryCopy(this.currentId).coordinates, [i] = this.store.create([{ geometry: { type: "Point", coordinates: [...t] }, properties: { mode: this.mode } }]);
    this.closingPointId = i, this.setCursor(this.cursors.close);
    const o = [...e, t];
    this.updateGeometries(o, void 0, M.Commit), this.currentCoordinate++;
  }
  updateToLine(t, e) {
    if (!this.currentId) return;
    const i = this.store.getGeometryCopy(this.currentId).coordinates, [o, r] = this.lastCommitedCoordinates ? this.lastCommitedCoordinates[this.lastCommitedCoordinates.length - 1] : i[i.length - 2], { x: n, y: a } = this.project(o, r);
    if (E({ x: n, y: a }, { x: e.x, y: e.y }) < this.pointerDistance) return void this.close();
    this.setCursor(this.cursors.close);
    const l = [...i, t];
    this.updateGeometries(l, i[i.length - 1], M.Commit), this.currentCoordinate++;
  }
  registerBehaviors(t) {
    this.coordinateSnapping = new mt(t, new nt(t), new rt(t)), this.insertPoint = new ri(t), this.clickBoundingBox = new rt(t), this.pixelDistance = new nt(t), this.lineSnapping = new Ie(t, this.pixelDistance, this.clickBoundingBox), this.coordinateSnapping = new mt(t, this.pixelDistance, this.clickBoundingBox);
  }
  start() {
    this.setStarted(), this.setCursor(this.cursors.start);
  }
  stop() {
    this.cleanUp(), this.setStopped(), this.setCursor("unset");
  }
  onMouseMove(t) {
    this.mouseMove = !0, this.setCursor(this.cursors.start);
    const e = this.snapCoordinate(t);
    if (e) {
      if (this.snappedPointId) this.store.updateGeometry([{ id: this.snappedPointId, geometry: { type: "Point", coordinates: e } }]);
      else {
        const [n] = this.store.create([{ geometry: { type: "Point", coordinates: e }, properties: { mode: this.mode, [_t]: !0 } }]);
        this.snappedPointId = n;
      }
      t.lng = e[0], t.lat = e[1];
    } else this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0);
    const i = e || [t.lng, t.lat];
    if (this.currentId === void 0 || this.currentCoordinate === 0) return;
    const o = this.store.getGeometryCopy(this.currentId).coordinates;
    if (o.pop(), this.closingPointId) {
      const [n, a] = o[o.length - 1], { x: l, y: d } = this.project(n, a);
      E({ x: l, y: d }, { x: t.containerX, y: t.containerY }) < this.pointerDistance && this.setCursor(this.cursors.close);
    }
    let r = [...o, i];
    if (this.insertCoordinates && this.currentId && this.lastCommitedCoordinates) {
      const n = this.lastCommitedCoordinates[this.lastCommitedCoordinates.length - 1], a = i;
      if (!Z(n, a)) {
        const l = this.generateInsertCoordinates(n, a);
        r = [...this.lastCommitedCoordinates.slice(0, -1), ...l, i];
      }
    }
    this.updateGeometries(r, void 0, M.Provisional);
  }
  onRightClick(t) {
    if (!this.editable || this.state !== "started") return;
    const { featureId: e, featureCoordinateIndex: i } = this.coordinateSnapping.getSnappable(t, (n) => this.lineStringFilter(n));
    if (!e || i === void 0) return;
    const o = this.store.getGeometryCopy(e);
    let r;
    if (o.type === "LineString" && (r = o.coordinates, !(r.length <= 2))) {
      if (r.splice(i, 1), this.validate && !this.validate({ id: e, type: "Feature", geometry: o, properties: {} }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Commit }).valid) return;
      this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0), this.store.updateGeometry([{ id: e, geometry: o }]), this.onFinish(e, { mode: this.mode, action: "edit" });
    }
  }
  onLeftClick(t) {
    this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0);
    const e = this.snapCoordinate(t) || [t.lng, t.lat];
    this.currentCoordinate === 0 ? this.createLine(e) : this.currentCoordinate === 1 && this.currentId ? this.firstUpdateToLine(e) : this.currentId && this.updateToLine(e, { x: t.containerX, y: t.containerY });
  }
  onClick(t) {
    this.currentCoordinate > 0 && !this.mouseMove && this.onMouseMove(t), this.mouseMove = !1, t.button === "right" ? this.onRightClick(t) : t.button === "left" && this.onLeftClick(t);
  }
  onKeyDown() {
  }
  onKeyUp(t) {
    t.key === this.keyEvents.cancel && this.cleanUp(), t.key === this.keyEvents.finish && this.close();
  }
  onDragStart(t, e) {
    if (!this.editable) return;
    let i;
    if (this.state === "started") {
      const o = this.lineSnapping.getSnappable(t, (n) => this.lineStringFilter(n));
      o.coordinate && (this.editedSnapType = "line", this.editedFeatureCoordinateIndex = o.featureCoordinateIndex, this.editedFeatureId = o.featureId, i = o.coordinate);
      const r = this.coordinateSnapping.getSnappable(t, (n) => this.lineStringFilter(n));
      r.coordinate && (this.editedSnapType = "coordinate", this.editedFeatureCoordinateIndex = r.featureCoordinateIndex, this.editedFeatureId = r.featureId, i = r.coordinate);
    }
    if (this.editedFeatureId && i) {
      if (!this.editedPointId) {
        const [o] = this.store.create([{ geometry: { type: "Point", coordinates: i }, properties: { mode: this.mode, [U]: !0 } }]);
        this.editedPointId = o;
      }
      this.setCursor(this.cursors.dragStart), e(!1);
    }
  }
  onDrag(t, e) {
    if (this.editedFeatureId === void 0 || this.editedFeatureCoordinateIndex === void 0) return;
    const i = this.store.getGeometryCopy(this.editedFeatureId);
    this.editedSnapType === "coordinate" || this.editedSnapType === "line" && this.editedInsertIndex !== void 0 ? i.coordinates[this.editedFeatureCoordinateIndex] = [t.lng, t.lat] : this.editedSnapType === "line" && this.editedInsertIndex === void 0 && (this.editedInsertIndex = this.editedFeatureCoordinateIndex + 1, i.coordinates.splice(this.editedInsertIndex, 0, [t.lng, t.lat]), this.editedFeatureCoordinateIndex++);
    const o = { type: "LineString", coordinates: i.coordinates };
    this.validate && !this.validate({ type: "Feature", geometry: o, properties: this.store.getPropertiesCopy(this.editedFeatureId) }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Provisional }).valid || (this.snapping && this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0), this.store.updateGeometry([{ id: this.editedFeatureId, geometry: o }]), this.editedPointId && this.store.updateGeometry([{ id: this.editedPointId, geometry: { type: "Point", coordinates: [t.lng, t.lat] } }]), this.store.updateProperty([{ id: this.editedFeatureId, property: U, value: !0 }]), e(!0));
  }
  onDragEnd(t, e) {
    this.editedFeatureId !== void 0 && (this.setCursor(this.cursors.dragEnd), this.editedPointId && (this.store.delete([this.editedPointId]), this.editedPointId = void 0), this.store.updateProperty([{ id: this.editedFeatureId, property: U, value: !1 }]), this.onFinish(this.editedFeatureId, { mode: this.mode, action: "edit" }), this.editedFeatureId = void 0, this.editedFeatureCoordinateIndex = void 0, this.editedInsertIndex = void 0, this.editedSnapType = void 0, e(!0));
  }
  cleanUp() {
    const t = this.currentId, e = this.closingPointId, i = this.snappedPointId;
    this.closingPointId = void 0, this.snappedPointId = void 0, this.currentId = void 0, this.currentCoordinate = 0, this.state === "drawing" && this.setStarted();
    try {
      t !== void 0 && this.store.delete([t]), i !== void 0 && this.store.delete([i]), e !== void 0 && this.store.delete([e]);
    } catch {
    }
  }
  styleFeature(t) {
    const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
    if (t.type === "Feature" && t.geometry.type === "LineString" && t.properties.mode === this.mode) return e.lineStringColor = this.getHexColorStylingValue(this.styles.lineStringColor, e.lineStringColor, t), e.lineStringWidth = this.getNumericStylingValue(this.styles.lineStringWidth, e.lineStringWidth, t), e.zIndex = 10, e;
    if (t.type === "Feature" && t.geometry.type === "Point" && t.properties.mode === this.mode) {
      const i = t.properties[st];
      return e.pointColor = this.getHexColorStylingValue(i ? this.styles.closingPointColor : this.styles.snappingPointColor, e.pointColor, t), e.pointWidth = this.getNumericStylingValue(i ? this.styles.closingPointWidth : this.styles.snappingPointWidth, e.pointWidth, t), e.pointOutlineColor = this.getHexColorStylingValue(i ? this.styles.closingPointOutlineColor : this.styles.snappingPointOutlineColor, "#ffffff", t), e.pointOutlineWidth = this.getNumericStylingValue(i ? this.styles.closingPointOutlineWidth : this.styles.snappingPointOutlineWidth, 2, t), e.zIndex = 40, e;
    }
    return e;
  }
  validateFeature(t) {
    return this.validateModeFeature(t, (e) => xe(e, this.coordinatePrecision));
  }
  lineStringFilter(t) {
    return !!(t.geometry.type === "LineString" && t.properties && t.properties.mode === this.mode);
  }
  snapCoordinate(t) {
    var e, i;
    let o;
    return (e = this.snapping) != null && e.toCoordinate && (o = this.currentId ? this.coordinateSnapping.getSnappableCoordinate(t, this.currentId) : this.coordinateSnapping.getSnappableCoordinateFirstClick(t)), (i = this.snapping) != null && i.toCustom && (o = this.snapping.toCustom(t)), o;
  }
}
const hi = "Feature is not a Point", ci = "Feature has invalid coordinates", ui = "Feature has coordinates with excessive precision";
function Me(s, t) {
  return s.geometry.type !== "Point" ? { valid: !1, reason: hi } : Wt(s.geometry.coordinates) ? xt(s.geometry.coordinates, t) ? { valid: !0 } : { valid: !1, reason: ui } : { valid: !1, reason: ci };
}
const pi = { create: "crosshair", dragStart: "grabbing", dragEnd: "crosshair" };
class we extends N {
  constructor(t) {
    super(t, !0), this.mode = "point", this.cursors = pi, this.editable = !1, this.editedFeatureId = void 0, this.pixelDistance = void 0, this.clickBoundingBox = void 0, this.updateOptions(t);
  }
  updateOptions(t) {
    super.updateOptions(t), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors)), t != null && t.editable && (this.editable = t.editable);
  }
  start() {
    this.setStarted(), this.setCursor(this.cursors.create);
  }
  stop() {
    this.cleanUp(), this.setStopped(), this.setCursor("unset");
  }
  onClick(t) {
    if (!this.store) throw new Error("Mode must be registered first");
    t.button === "right" ? this.onRightClick(t) : t.button === "left" && this.onLeftClick(t);
  }
  onMouseMove() {
  }
  onKeyDown() {
  }
  onKeyUp() {
  }
  cleanUp() {
    this.editedFeatureId = void 0;
  }
  onDragStart(t, e) {
    if (this.editable) {
      const i = this.getNearestPointFeature(t);
      this.editedFeatureId = i == null ? void 0 : i.id;
    }
    this.editedFeatureId && (this.setCursor(this.cursors.dragStart), e(!1));
  }
  onDrag(t, e) {
    this.editedFeatureId !== void 0 && (this.validate && !this.validate({ type: "Feature", geometry: { type: "Point", coordinates: [t.lng, t.lat] }, properties: this.store.getPropertiesCopy(this.editedFeatureId) }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Finish }).valid || (this.store.updateGeometry([{ id: this.editedFeatureId, geometry: { type: "Point", coordinates: [t.lng, t.lat] } }]), this.store.updateProperty([{ id: this.editedFeatureId, property: U, value: !0 }]), e(!0)));
  }
  onDragEnd(t, e) {
    this.editedFeatureId !== void 0 && (this.onFinish(this.editedFeatureId, { mode: this.mode, action: "edit" }), this.setCursor(this.cursors.dragEnd), this.store.updateProperty([{ id: this.editedFeatureId, property: U, value: !1 }]), this.editedFeatureId = void 0, e(!0));
  }
  registerBehaviors(t) {
    this.pixelDistance = new nt(t), this.clickBoundingBox = new rt(t);
  }
  styleFeature(t) {
    const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
    if (t.type === "Feature" && t.geometry.type === "Point" && t.properties.mode === this.mode) {
      const i = !!(t.id && this.editedFeatureId === t.id);
      e.pointWidth = this.getNumericStylingValue(i ? this.styles.editedPointWidth : this.styles.pointWidth, e.pointWidth, t), e.pointColor = this.getHexColorStylingValue(i ? this.styles.editedPointColor : this.styles.pointColor, e.pointColor, t), e.pointOutlineColor = this.getHexColorStylingValue(i ? this.styles.editedPointOutlineColor : this.styles.pointOutlineColor, e.pointOutlineColor, t), e.pointOutlineWidth = this.getNumericStylingValue(i ? this.styles.editedPointOutlineWidth : this.styles.pointOutlineWidth, 2, t), e.zIndex = 30;
    }
    return e;
  }
  validateFeature(t) {
    return this.validateModeFeature(t, (e) => Me(e, this.coordinatePrecision));
  }
  onLeftClick(t) {
    const e = { type: "Point", coordinates: [t.lng, t.lat] }, i = { mode: this.mode };
    if (this.validate && !this.validate({ type: "Feature", geometry: e, properties: i }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Finish }).valid) return;
    const [o] = this.store.create([{ geometry: e, properties: i }]);
    this.onFinish(o, { mode: this.mode, action: "draw" });
  }
  onRightClick(t) {
    if (!this.editable) return;
    const e = this.getNearestPointFeature(t);
    e && this.store.delete([e.id]);
  }
  getNearestPointFeature(t) {
    const e = this.clickBoundingBox.create(t), i = this.store.search(e);
    let o, r = 1 / 0;
    for (let n = 0; n < i.length; n++) {
      const a = i[n];
      if (a.geometry.type !== "Point" || a.properties.mode !== this.mode) continue;
      const l = this.pixelDistance.measure(t, a.geometry.coordinates);
      l > r || l > this.pointerDistance || (r = l, o = a);
    }
    return o;
  }
}
class gi extends k {
  constructor(t, e) {
    super(t), this.config = void 0, this.pixelDistance = void 0, this._startEndPoints = [], this.config = t, this.pixelDistance = e;
  }
  get ids() {
    return this._startEndPoints.concat();
  }
  set ids(t) {
  }
  create(t, e) {
    if (this.ids.length) throw new Error("Opening and closing points already created");
    if (t.length <= 3) throw new Error("Requires at least 4 coordinates");
    this._startEndPoints = this.store.create([{ geometry: { type: "Point", coordinates: t[0] }, properties: { mode: e, [st]: !0 } }, { geometry: { type: "Point", coordinates: t[t.length - 2] }, properties: { mode: e, [st]: !0 } }]);
  }
  delete() {
    this.ids.length && (this.store.delete(this.ids), this._startEndPoints = []);
  }
  update(t) {
    if (this.ids.length !== 2) throw new Error("No closing points to update");
    this.store.updateGeometry([{ id: this.ids[0], geometry: { type: "Point", coordinates: t[0] } }, { id: this.ids[1], geometry: { type: "Point", coordinates: t[t.length - 3] } }]);
  }
  isClosingPoint(t) {
    const e = this.store.getGeometryCopy(this.ids[0]), i = this.store.getGeometryCopy(this.ids[1]), o = this.pixelDistance.measure(t, e.coordinates), r = this.pixelDistance.measure(t, i.coordinates);
    return { isClosing: o < this.pointerDistance, isPreviousClosing: r < this.pointerDistance };
  }
}
class Fe extends k {
  constructor(t) {
    super(t);
  }
  createOrUpdate(t) {
    const e = this.store.getGeometryCopy(t), i = this.store.getPropertiesCopy(t);
    let o;
    if (e.type === "Polygon") o = e.coordinates[0].slice(0, -1);
    else {
      if (e.type !== "LineString") return;
      o = e.coordinates;
    }
    const r = this.store.getPropertiesCopy(t);
    if (r.coordinatePointIds) {
      const n = r.coordinatePointIds, a = n.map((l) => this.store.getGeometryCopy(l).coordinates);
      if (n.length !== o.length) {
        this.deleteCoordinatePoints(n);
        const l = this.createPoints(o, i.mode);
        this.setFeatureCoordinatePoints(t, l);
      } else o.forEach((l, d) => {
        l[0] === a[d][0] && l[1] === a[d][1] || this.store.updateGeometry([{ id: n[d], geometry: { type: "Point", coordinates: l } }]);
      });
    } else {
      const n = this.createPoints(o, i.mode);
      this.setFeatureCoordinatePoints(t, n);
    }
  }
  deletePointsByFeatureIds(t) {
    for (const e of t) this.deleteIfPresent(e);
  }
  getUpdated(t, e) {
    const i = this.store.getPropertiesCopy(t);
    if (i.coordinatePointIds) return i.coordinatePointIds.map((o, r) => ({ id: o, geometry: I({}, this.store.getGeometryCopy(o), { coordinates: e[r] }) }));
  }
  createPoints(t, e) {
    return this.store.create(t.map((i) => ({ geometry: { type: "Point", coordinates: i }, properties: { mode: e, [Lt]: !0 } })));
  }
  setFeatureCoordinatePoints(t, e) {
    this.store.updateProperty([{ id: t, property: kt, value: e }]);
  }
  deleteCoordinatePoints(t) {
    this.store.delete(t);
  }
  deleteIfPresent(t) {
    const e = this.store.getPropertiesCopy(t);
    e.coordinatePointIds && (this.deleteCoordinatePoints(e.coordinatePointIds), this.setFeatureCoordinatePoints(t, null));
  }
}
const yi = { cancel: "Escape", finish: "Enter" }, fi = { start: "crosshair", close: "pointer", dragStart: "grabbing", dragEnd: "crosshair" };
class Ee extends N {
  constructor(t) {
    super(t, !0), this.mode = "polygon", this.currentCoordinate = 0, this.currentId = void 0, this.keyEvents = yi, this.cursors = fi, this.mouseMove = !1, this.showCoordinatePoints = !1, this.snapping = void 0, this.snappedPointId = void 0, this.editable = !1, this.editedFeatureId = void 0, this.editedFeatureCoordinateIndex = void 0, this.editedSnapType = void 0, this.editedInsertIndex = void 0, this.editedPointId = void 0, this.coordinatePoints = void 0, this.lineSnapping = void 0, this.coordinateSnapping = void 0, this.pixelDistance = void 0, this.closingPoints = void 0, this.clickBoundingBox = void 0, this.updateOptions(t);
  }
  updateOptions(t) {
    if (super.updateOptions(t), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors)), (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { cancel: null, finish: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents)), t != null && t.snapping && (this.snapping = t.snapping), (t == null ? void 0 : t.editable) !== void 0 && (this.editable = t.editable), (t == null ? void 0 : t.showCoordinatePoints) !== void 0) {
      if (this.showCoordinatePoints = t.showCoordinatePoints, this.coordinatePoints && t.showCoordinatePoints === !0) this.store.copyAllWhere((e) => e.mode === this.mode).map((e) => e.id).forEach((e) => {
        this.coordinatePoints.createOrUpdate(e);
      });
      else if (this.coordinatePoints && this.showCoordinatePoints === !1) {
        const e = this.store.copyAllWhere((i) => i.mode === this.mode && !!i[kt]);
        this.coordinatePoints.deletePointsByFeatureIds(e.map((i) => i.id));
      }
    }
  }
  close() {
    if (this.currentId === void 0) return;
    const t = this.store.getGeometryCopy(this.currentId).coordinates[0];
    if (t.length < 5 || !this.updatePolygonGeometry([...t.slice(0, -2), t[0]], M.Finish)) return;
    const e = this.currentId;
    if (this.currentId) {
      const i = dt(this.store.getGeometryCopy(this.currentId));
      i && this.store.updateGeometry([{ id: this.currentId, geometry: i }]);
    }
    this.snappedPointId && this.store.delete([this.snappedPointId]), this.currentCoordinate = 0, this.currentId = void 0, this.snappedPointId = void 0, this.closingPoints.delete(), this.state === "drawing" && this.setStarted(), this.onFinish(e, { mode: this.mode, action: "draw" });
  }
  registerBehaviors(t) {
    this.clickBoundingBox = new rt(t), this.pixelDistance = new nt(t), this.lineSnapping = new Ie(t, this.pixelDistance, this.clickBoundingBox), this.coordinateSnapping = new mt(t, this.pixelDistance, this.clickBoundingBox), this.closingPoints = new gi(t, this.pixelDistance), this.coordinatePoints = new Fe(t);
  }
  start() {
    this.setStarted(), this.setCursor(this.cursors.start);
  }
  stop() {
    this.cleanUp(), this.setStopped(), this.setCursor("unset");
  }
  onMouseMove(t) {
    this.mouseMove = !0, this.setCursor(this.cursors.start);
    const e = this.snapCoordinate(t);
    if (e) {
      if (this.snappedPointId) this.store.updateGeometry([{ id: this.snappedPointId, geometry: { type: "Point", coordinates: e } }]);
      else {
        const [r] = this.store.create([{ geometry: { type: "Point", coordinates: e }, properties: { mode: this.mode, [_t]: !0 } }]);
        this.snappedPointId = r;
      }
      t.lng = e[0], t.lat = e[1];
    } else this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0);
    if (this.currentId === void 0 || this.currentCoordinate === 0) return;
    const i = this.store.getGeometryCopy(this.currentId).coordinates[0];
    let o;
    if (this.currentCoordinate === 1) {
      const r = 1 / Math.pow(10, this.coordinatePrecision - 1), n = Math.max(1e-6, r);
      o = [i[0], [t.lng, t.lat], [t.lng, t.lat - n], i[0]];
    } else if (this.currentCoordinate === 2) o = [i[0], i[1], [t.lng, t.lat], i[0]];
    else {
      const { isClosing: r, isPreviousClosing: n } = this.closingPoints.isClosingPoint(t);
      n || r ? (this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0), this.setCursor(this.cursors.close), o = [...i.slice(0, -2), i[0], i[0]]) : o = [...i.slice(0, -2), [t.lng, t.lat], i[0]];
    }
    this.updatePolygonGeometry(o, M.Provisional);
  }
  updatePolygonGeometry(t, e) {
    if (!this.currentId) return !1;
    const i = { type: "Polygon", coordinates: [t] };
    return !(this.validate && !this.validate({ type: "Feature", geometry: i }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: e }).valid || (this.store.updateGeometry([{ id: this.currentId, geometry: i }]), this.showCoordinatePoints && this.coordinatePoints.createOrUpdate(this.currentId), 0));
  }
  snapCoordinate(t) {
    var e, i, o;
    let r;
    if ((e = this.snapping) != null && e.toLine) {
      let n;
      n = this.currentId ? this.lineSnapping.getSnappableCoordinate(t, this.currentId) : this.lineSnapping.getSnappableCoordinateFirstClick(t), n && (r = n);
    }
    if ((i = this.snapping) != null && i.toCoordinate) {
      let n;
      n = this.currentId ? this.coordinateSnapping.getSnappableCoordinate(t, this.currentId) : this.coordinateSnapping.getSnappableCoordinateFirstClick(t), n && (r = n);
    }
    return (o = this.snapping) != null && o.toCustom && (r = this.snapping.toCustom(t, { currentCoordinate: this.currentCoordinate, currentId: this.currentId, getCurrentGeometrySnapshot: this.currentId ? () => this.store.getGeometryCopy(this.currentId) : () => null, project: this.project, unproject: this.unproject })), r;
  }
  polygonFilter(t) {
    return !!(t.geometry.type === "Polygon" && t.properties && t.properties.mode === this.mode);
  }
  onRightClick(t) {
    if (!this.editable) return;
    const { featureId: e, featureCoordinateIndex: i } = this.coordinateSnapping.getSnappable(t, (n) => this.polygonFilter(n));
    if (!e || i === void 0) return;
    const o = this.store.getGeometryCopy(e);
    let r;
    o.type === "Polygon" && (r = o.coordinates[0], r.length <= 4 || (o.type !== "Polygon" || i !== 0 && i !== r.length - 1 ? r.splice(i, 1) : (r.shift(), r.pop(), r.push([r[0][0], r[0][1]])), (!this.validate || this.validate({ id: e, type: "Feature", geometry: o, properties: {} }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Commit }).valid) && (this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0), this.store.updateGeometry([{ id: e, geometry: o }]), this.showCoordinatePoints && this.coordinatePoints.createOrUpdate(e), this.onFinish(e, { mode: this.mode, action: "edit" }))));
  }
  onLeftClick(t) {
    if (this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0), this.currentCoordinate === 0) {
      const e = this.snapCoordinate(t);
      e && (t.lng = e[0], t.lat = e[1]);
      const [i] = this.store.create([{ geometry: { type: "Polygon", coordinates: [[[t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat]]] }, properties: { mode: this.mode } }]);
      this.currentId = i, this.currentCoordinate++, this.setDrawing();
    } else if (this.currentCoordinate === 1 && this.currentId) {
      const e = this.snapCoordinate(t);
      e && (t.lng = e[0], t.lat = e[1]);
      const i = this.store.getGeometryCopy(this.currentId);
      if (Z([t.lng, t.lat], i.coordinates[0][0]) || !this.updatePolygonGeometry([i.coordinates[0][0], [t.lng, t.lat], [t.lng, t.lat], i.coordinates[0][0]], M.Commit)) return;
      this.currentCoordinate++;
    } else if (this.currentCoordinate === 2 && this.currentId) {
      const e = this.snapCoordinate(t);
      e && (t.lng = e[0], t.lat = e[1]);
      const i = this.store.getGeometryCopy(this.currentId).coordinates[0];
      if (Z([t.lng, t.lat], i[1]) || !this.updatePolygonGeometry([i[0], i[1], [t.lng, t.lat], [t.lng, t.lat], i[0]], M.Commit)) return;
      this.currentCoordinate === 2 && this.closingPoints.create(i, "polygon"), this.currentCoordinate++;
    } else if (this.currentId) {
      const e = this.store.getGeometryCopy(this.currentId).coordinates[0], { isClosing: i, isPreviousClosing: o } = this.closingPoints.isClosingPoint(t);
      if (o || i) this.close();
      else {
        const r = this.snapCoordinate(t);
        if (r && (t.lng = r[0], t.lat = r[1]), Z([t.lng, t.lat], e[this.currentCoordinate - 1])) return;
        const n = /* @__PURE__ */ function(a = [[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]]) {
          return { type: "Feature", geometry: { type: "Polygon", coordinates: a }, properties: {} };
        }([[...e.slice(0, -1), [t.lng, t.lat], e[0]]]);
        if (!this.updatePolygonGeometry(n.geometry.coordinates[0], M.Commit)) return;
        this.currentCoordinate++, this.closingPoints.ids.length && this.closingPoints.update(n.geometry.coordinates[0]);
      }
    }
  }
  onClick(t) {
    this.currentCoordinate > 0 && !this.mouseMove && this.onMouseMove(t), this.mouseMove = !1, t.button !== "right" ? t.button !== "left" || this.onLeftClick(t) : this.onRightClick(t);
  }
  onKeyUp(t) {
    t.key === this.keyEvents.cancel ? this.cleanUp() : t.key === this.keyEvents.finish && this.close();
  }
  onKeyDown() {
  }
  onDragStart(t, e) {
    if (!this.editable) return;
    let i;
    if (this.state === "started") {
      const o = this.lineSnapping.getSnappable(t, (n) => this.polygonFilter(n));
      o.coordinate && (this.editedSnapType = "line", this.editedFeatureCoordinateIndex = o.featureCoordinateIndex, this.editedFeatureId = o.featureId, i = o.coordinate);
      const r = this.coordinateSnapping.getSnappable(t, (n) => this.polygonFilter(n));
      r.coordinate && (this.editedSnapType = "coordinate", this.editedFeatureCoordinateIndex = r.featureCoordinateIndex, this.editedFeatureId = r.featureId, i = r.coordinate);
    }
    if (this.editedFeatureId && i) {
      if (!this.editedPointId) {
        const [o] = this.store.create([{ geometry: { type: "Point", coordinates: i }, properties: { mode: this.mode, [U]: !0 } }]);
        this.editedPointId = o;
      }
      this.setCursor(this.cursors.dragStart), e(!1);
    }
  }
  onDrag(t, e) {
    if (this.editedFeatureId === void 0 || this.editedFeatureCoordinateIndex === void 0) return;
    const i = this.store.getGeometryCopy(this.editedFeatureId), o = i.coordinates[0];
    this.editedSnapType === "coordinate" || this.editedSnapType === "line" && this.editedInsertIndex !== void 0 ? this.editedFeatureCoordinateIndex === 0 || this.editedFeatureCoordinateIndex === i.coordinates[0].length - 1 ? (o[0] = [t.lng, t.lat], o[o.length - 1] = [t.lng, t.lat]) : o[this.editedFeatureCoordinateIndex] = [t.lng, t.lat] : this.editedSnapType === "line" && this.editedInsertIndex === void 0 && (this.editedInsertIndex = this.editedFeatureCoordinateIndex + 1, i.coordinates[0].splice(this.editedInsertIndex, 0, [t.lng, t.lat]), this.editedFeatureCoordinateIndex++);
    const r = { type: "Polygon", coordinates: i.coordinates };
    this.validate && !this.validate({ type: "Feature", geometry: r, properties: this.store.getPropertiesCopy(this.editedFeatureId) }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Provisional }).valid || (this.snapping && this.snappedPointId && (this.store.delete([this.snappedPointId]), this.snappedPointId = void 0), this.store.updateGeometry([{ id: this.editedFeatureId, geometry: r }]), this.showCoordinatePoints && this.coordinatePoints.createOrUpdate(this.editedFeatureId), this.editedPointId && this.store.updateGeometry([{ id: this.editedPointId, geometry: { type: "Point", coordinates: [t.lng, t.lat] } }]), this.store.updateProperty([{ id: this.editedFeatureId, property: U, value: !0 }]), e(!0));
  }
  onDragEnd(t, e) {
    this.editedFeatureId !== void 0 && (this.setCursor(this.cursors.dragEnd), this.editedPointId && (this.store.delete([this.editedPointId]), this.editedPointId = void 0), this.store.updateProperty([{ id: this.editedFeatureId, property: U, value: !1 }]), this.onFinish(this.editedFeatureId, { mode: this.mode, action: "edit" }), this.editedFeatureId = void 0, this.editedFeatureCoordinateIndex = void 0, this.editedInsertIndex = void 0, this.editedSnapType = void 0, e(!0));
  }
  cleanUp() {
    const t = this.currentId, e = this.snappedPointId, i = this.editedPointId;
    this.currentId = void 0, this.snappedPointId = void 0, this.editedPointId = void 0, this.editedFeatureId = void 0, this.editedFeatureCoordinateIndex = void 0, this.editedInsertIndex = void 0, this.editedSnapType = void 0, this.currentCoordinate = 0, this.state === "drawing" && this.setStarted();
    try {
      t && this.coordinatePoints.deletePointsByFeatureIds([t]), t !== void 0 && this.store.delete([t]), i !== void 0 && this.store.delete([i]), e !== void 0 && this.store.delete([e]), this.closingPoints.ids.length && this.closingPoints.delete();
    } catch {
    }
  }
  styleFeature(t) {
    const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
    if (t.properties.mode === this.mode) {
      if (t.geometry.type === "Polygon") return e.polygonFillColor = this.getHexColorStylingValue(this.styles.fillColor, e.polygonFillColor, t), e.polygonOutlineColor = this.getHexColorStylingValue(this.styles.outlineColor, e.polygonOutlineColor, t), e.polygonOutlineWidth = this.getNumericStylingValue(this.styles.outlineWidth, e.polygonOutlineWidth, t), e.polygonFillOpacity = this.getNumericStylingValue(this.styles.fillOpacity, e.polygonFillOpacity, t), e.zIndex = 10, e;
      if (t.geometry.type === "Point") {
        const i = t.properties[U], o = t.properties[Lt], r = i ? "editedPoint" : t.properties[st] ? "closingPoint" : t.properties[_t] ? "snappingPoint" : o ? "coordinatePoint" : void 0;
        if (!r) return e;
        const n = { editedPoint: { width: this.styles.editedPointOutlineWidth, color: this.styles.editedPointColor, outlineColor: this.styles.editedPointOutlineColor, outlineWidth: this.styles.editedPointOutlineWidth }, closingPoint: { width: this.styles.closingPointWidth, color: this.styles.closingPointColor, outlineColor: this.styles.closingPointOutlineColor, outlineWidth: this.styles.closingPointOutlineWidth }, snappingPoint: { width: this.styles.snappingPointWidth, color: this.styles.snappingPointColor, outlineColor: this.styles.snappingPointOutlineColor, outlineWidth: this.styles.snappingPointOutlineWidth }, coordinatePoint: { width: this.styles.coordinatePointWidth, color: this.styles.coordinatePointColor, outlineColor: this.styles.coordinatePointOutlineColor, outlineWidth: this.styles.coordinatePointOutlineWidth } };
        return e.pointWidth = this.getNumericStylingValue(n[r].width, e.pointWidth, t), e.pointColor = this.getHexColorStylingValue(n[r].color, e.pointColor, t), e.pointOutlineColor = this.getHexColorStylingValue(n[r].outlineColor, e.pointOutlineColor, t), e.pointOutlineWidth = this.getNumericStylingValue(n[r].outlineWidth, 2, t), e.zIndex = i ? 35 : o ? 25 : 30, e;
      }
    }
    return e;
  }
  afterFeatureAdded(t) {
    this.showCoordinatePoints && this.coordinatePoints.createOrUpdate(t.id);
  }
  validateFeature(t) {
    return this.validateModeFeature(t, (e) => It(e, this.coordinatePrecision));
  }
}
const mi = { cancel: "Escape", finish: "Enter" }, vi = { start: "crosshair" };
class Oe extends N {
  constructor(t) {
    super(t, !0), this.mode = "rectangle", this.center = void 0, this.clickCount = 0, this.currentRectangleId = void 0, this.keyEvents = mi, this.cursors = vi, this.updateOptions(t);
  }
  updateOptions(t) {
    super.updateOptions(t), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors)), (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { cancel: null, finish: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents));
  }
  updateRectangle(t, e) {
    if (this.clickCount === 1 && this.center && this.currentRectangleId) {
      const i = this.store.getGeometryCopy(this.currentRectangleId).coordinates[0][0], o = { type: "Polygon", coordinates: [[i, [t.lng, i[1]], [t.lng, t.lat], [i[0], t.lat], i]] };
      if (this.validate && !this.validate({ id: this.currentRectangleId, geometry: o }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: e }).valid) return;
      this.store.updateGeometry([{ id: this.currentRectangleId, geometry: o }]);
    }
  }
  close() {
    const t = this.currentRectangleId;
    if (t) {
      const e = dt(this.store.getGeometryCopy(t));
      e && this.store.updateGeometry([{ id: t, geometry: e }]);
    }
    this.center = void 0, this.currentRectangleId = void 0, this.clickCount = 0, this.state === "drawing" && this.setStarted(), t !== void 0 && this.onFinish(t, { mode: this.mode, action: "draw" });
  }
  start() {
    this.setStarted(), this.setCursor(this.cursors.start);
  }
  stop() {
    this.cleanUp(), this.setStopped(), this.setCursor("unset");
  }
  onClick(t) {
    if (this.clickCount === 0) {
      this.center = [t.lng, t.lat];
      const [e] = this.store.create([{ geometry: { type: "Polygon", coordinates: [[[t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat]]] }, properties: { mode: this.mode } }]);
      this.currentRectangleId = e, this.clickCount++, this.setDrawing();
    } else this.updateRectangle(t, M.Finish), this.close();
  }
  onMouseMove(t) {
    this.updateRectangle(t, M.Provisional);
  }
  onKeyDown() {
  }
  onKeyUp(t) {
    t.key === this.keyEvents.cancel ? this.cleanUp() : t.key === this.keyEvents.finish && this.close();
  }
  onDragStart() {
  }
  onDrag() {
  }
  onDragEnd() {
  }
  cleanUp() {
    const t = this.currentRectangleId;
    this.center = void 0, this.currentRectangleId = void 0, this.clickCount = 0, this.state === "drawing" && this.setStarted(), t !== void 0 && this.store.delete([t]);
  }
  styleFeature(t) {
    const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
    return t.type === "Feature" && t.geometry.type === "Polygon" && t.properties.mode === this.mode && (e.polygonFillColor = this.getHexColorStylingValue(this.styles.fillColor, e.polygonFillColor, t), e.polygonOutlineColor = this.getHexColorStylingValue(this.styles.outlineColor, e.polygonOutlineColor, t), e.polygonOutlineWidth = this.getNumericStylingValue(this.styles.outlineWidth, e.polygonOutlineWidth, t), e.polygonFillOpacity = this.getNumericStylingValue(this.styles.fillOpacity, e.polygonFillOpacity, t), e.zIndex = 10), e;
  }
  validateFeature(t) {
    return this.validateModeFeature(t, (e) => lt(e, this.coordinatePrecision));
  }
}
class et extends N {
  constructor(t) {
    if (!t.modeName) throw new Error("Mode name is required for TerraDrawRenderMode");
    super(t, !0), this.type = $.Render, this.mode = "render", this.updateOptions(t);
  }
  updateOptions(t) {
    super.updateOptions(t), t != null && t.modeName && (this.mode = t.modeName);
  }
  registerBehaviors(t) {
    this.mode = t.mode;
  }
  start() {
    this.setStarted();
  }
  stop() {
    this.setStopped();
  }
  onKeyUp() {
  }
  onKeyDown() {
  }
  onClick() {
  }
  onDragStart() {
  }
  onDrag() {
  }
  onDragEnd() {
  }
  onMouseMove() {
  }
  cleanUp() {
  }
  styleFeature(t) {
    return { pointColor: this.getHexColorStylingValue(this.styles.pointColor, "#3f97e0", t), pointWidth: this.getNumericStylingValue(this.styles.pointWidth, 6, t), pointOutlineColor: this.getHexColorStylingValue(this.styles.pointOutlineColor, "#ffffff", t), pointOutlineWidth: this.getNumericStylingValue(this.styles.pointOutlineWidth, 0, t), polygonFillColor: this.getHexColorStylingValue(this.styles.polygonFillColor, "#3f97e0", t), polygonFillOpacity: this.getNumericStylingValue(this.styles.polygonFillOpacity, 0.3, t), polygonOutlineColor: this.getHexColorStylingValue(this.styles.polygonOutlineColor, "#3f97e0", t), polygonOutlineWidth: this.getNumericStylingValue(this.styles.polygonOutlineWidth, 4, t), lineStringWidth: this.getNumericStylingValue(this.styles.lineStringWidth, 4, t), lineStringColor: this.getHexColorStylingValue(this.styles.lineStringColor, "#3f97e0", t), zIndex: this.getNumericStylingValue(this.styles.zIndex, 0, t) };
  }
  validateFeature(t) {
    const e = super.validateFeature(t);
    if (e.valid) {
      const i = t, o = Me(i, this.coordinatePrecision).valid || It(i, this.coordinatePrecision).valid || xe(i, this.coordinatePrecision).valid;
      return o ? { valid: !0 } : { valid: o, reason: "Feature is not a valid Point, Polygon or LineString feature" };
    }
    return e;
  }
}
function vt(s, t) {
  const e = s, i = t, o = O(e[1]), r = O(i[1]);
  let n = O(i[0] - e[0]);
  n > Math.PI && (n -= 2 * Math.PI), n < -Math.PI && (n += 2 * Math.PI);
  const a = Math.log(Math.tan(r / 2 + Math.PI / 4) / Math.tan(o / 2 + Math.PI / 4)), l = (R(Math.atan2(n, a)) + 360) % 360;
  return l > 180 ? -(360 - l) : l;
}
function jt(s, t, e) {
  let i = t;
  t < 0 && (i = -Math.abs(i));
  const o = i / me, r = s[0] * Math.PI / 180, n = O(s[1]), a = O(e), l = o * Math.cos(a);
  let d = n + l;
  Math.abs(d) > Math.PI / 2 && (d = d > 0 ? Math.PI - d : -Math.PI - d);
  const h = Math.log(Math.tan(d / 2 + Math.PI / 4) / Math.tan(n / 2 + Math.PI / 4)), c = Math.abs(h) > 1e-11 ? l / h : Math.cos(n), u = [(180 * (r + o * Math.sin(a) / c) / Math.PI + 540) % 360 - 180, 180 * d / Math.PI];
  return u[0] += u[0] - s[0] > 180 ? -360 : s[0] - u[0] > 180 ? 360 : 0, u;
}
function De(s, t, e, i, o) {
  const r = i(s[0], s[1]), n = i(t[0], t[1]), { lng: a, lat: l } = o((r.x + n.x) / 2, (r.y + n.y) / 2);
  return [F(a, e), F(l, e)];
}
function Ci(s, t, e) {
  const i = jt(s, 1e3 * T(s, t) / 2, vt(s, t));
  return [F(i[0], e), F(i[1], e)];
}
function te({ featureCoords: s, precision: t, unproject: e, project: i, projection: o }) {
  const r = [];
  for (let n = 0; n < s.length - 1; n++) {
    let a;
    if (o === "web-mercator") a = De(s[n], s[n + 1], t, i, e);
    else {
      if (o !== "globe") throw new Error("Invalid projection");
      a = Ci(s[n], s[n + 1], t);
    }
    r.push(a);
  }
  return r;
}
class Pi extends k {
  constructor(t, e, i) {
    super(t), this.config = void 0, this.selectionPointBehavior = void 0, this.coordinatePointBehavior = void 0, this._midPoints = [], this.config = t, this.selectionPointBehavior = e, this.coordinatePointBehavior = i;
  }
  get ids() {
    return this._midPoints.concat();
  }
  set ids(t) {
  }
  insert(t, e, i) {
    const o = this.store.getGeometryCopy(e), { midPointFeatureId: r, midPointSegment: n } = this.store.getPropertiesCopy(e), a = this.store.getGeometryCopy(r), l = a.type === "Polygon" ? a.coordinates[0] : a.coordinates;
    l.splice(n + 1, 0, o.coordinates), a.coordinates = a.type === "Polygon" ? [l] : l, this.store.updateGeometry([{ id: r, geometry: a }]), this.store.getPropertiesCopy(t)[kt] && this.coordinatePointBehavior.createOrUpdate(t), this.store.delete([...this._midPoints, ...this.selectionPointBehavior.ids]), this.create(l, r, i), this.selectionPointBehavior.create(l, a.type, r);
  }
  create(t, e, i) {
    if (!this.store.has(e)) throw new Error("Store does not have feature with this id");
    this._midPoints = this.store.create(function(o, r, n, a, l, d) {
      return te({ featureCoords: o, precision: n, project: a, unproject: l, projection: d }).map((h, c) => ({ geometry: { type: "Point", coordinates: h }, properties: r(c) }));
    }(t, (o) => ({ mode: this.mode, [V.MID_POINT]: !0, midPointSegment: o, midPointFeatureId: e }), i, this.config.project, this.config.unproject, this.projection));
  }
  delete() {
    this._midPoints.length && (this.store.delete(this._midPoints), this._midPoints = []);
  }
  getUpdated(t) {
    if (this._midPoints.length !== 0) return te({ featureCoords: t, precision: this.coordinatePrecision, project: this.config.project, unproject: this.config.unproject, projection: this.config.projection }).map((e, i) => ({ id: this._midPoints[i], geometry: { type: "Point", coordinates: e } }));
  }
}
class Si extends k {
  constructor(t) {
    super(t), this._selectionPoints = [];
  }
  get ids() {
    return this._selectionPoints.concat();
  }
  set ids(t) {
  }
  create(t, e, i) {
    this._selectionPoints = this.store.create(function(o, r, n) {
      const a = [], l = r === "Polygon" ? o.length - 1 : o.length;
      for (let d = 0; d < l; d++) a.push({ geometry: { type: "Point", coordinates: o[d] }, properties: n(d) });
      return a;
    }(t, e, (o) => ({ mode: this.mode, selectionPoint: !0, selectionPointFeatureId: i, index: o })));
  }
  delete() {
    this.ids.length && (this.store.delete(this.ids), this._selectionPoints = []);
  }
  getUpdated(t) {
    if (this._selectionPoints.length !== 0) return this._selectionPoints.map((e, i) => ({ id: e, geometry: { type: "Point", coordinates: t[i] } }));
  }
  getOneUpdated(t, e) {
    if (this._selectionPoints[t] !== void 0) return { id: this._selectionPoints[t], geometry: { type: "Point", coordinates: e } };
  }
}
function _e(s, t) {
  let e = !1;
  for (let n = 0, a = t.length; n < a; n++) {
    const l = t[n];
    for (let d = 0, h = l.length, c = h - 1; d < h; c = d++) (o = l[d])[1] > (i = s)[1] != (r = l[c])[1] > i[1] && i[0] < (r[0] - o[0]) * (i[1] - o[1]) / (r[1] - o[1]) + o[0] && (e = !e);
  }
  var i, o, r;
  return e;
}
const Le = (s, t, e) => {
  const i = (r) => r * r, o = (r, n) => i(r.x - n.x) + i(r.y - n.y);
  return Math.sqrt(((r, n, a) => {
    const l = o(n, a);
    if (l === 0) return o(r, n);
    let d = ((r.x - n.x) * (a.x - n.x) + (r.y - n.y) * (a.y - n.y)) / l;
    return d = Math.max(0, Math.min(1, d)), o(r, { x: n.x + d * (a.x - n.x), y: n.y + d * (a.y - n.y) });
  })(s, t, e));
};
class xi extends k {
  constructor(t, e, i) {
    super(t), this.config = void 0, this.createClickBoundingBox = void 0, this.pixelDistance = void 0, this.config = t, this.createClickBoundingBox = e, this.pixelDistance = i;
  }
  find(t, e) {
    let i, o, r, n, a = 1 / 0, l = 1 / 0, d = 1 / 0;
    const h = this.createClickBoundingBox.create(t), c = this.store.search(h);
    for (let u = 0; u < c.length; u++) {
      const p = c[u], g = p.geometry;
      if (g.type === "Point") {
        if (p.properties.selectionPoint || p.properties.coordinatePoint || !e && p.properties[V.MID_POINT]) continue;
        const y = this.pixelDistance.measure(t, g.coordinates);
        p.properties[V.MID_POINT] && y < this.pointerDistance && y < d ? (d = y, r = p) : !p.properties[V.MID_POINT] && y < this.pointerDistance && y < a && (a = y, i = p);
      } else if (g.type === "LineString") {
        if (i) continue;
        for (let y = 0; y < g.coordinates.length - 1; y++) {
          const m = g.coordinates[y], v = g.coordinates[y + 1], f = Le({ x: t.containerX, y: t.containerY }, this.project(m[0], m[1]), this.project(v[0], v[1]));
          f < this.pointerDistance && f < l && (l = f, o = p);
        }
      } else if (g.type === "Polygon") {
        if (i || o) continue;
        _e([t.lng, t.lat], g.coordinates) && (n = p);
      }
    }
    return { clickedFeature: i || o || n, clickedMidPoint: r };
  }
}
class Ii extends k {
  constructor(t, e, i, o, r) {
    super(t), this.config = void 0, this.featuresAtCursorEvent = void 0, this.selectionPoints = void 0, this.midPoints = void 0, this.coordinatePoints = void 0, this.draggedFeatureId = null, this.dragPosition = void 0, this.config = t, this.featuresAtCursorEvent = e, this.selectionPoints = i, this.midPoints = o, this.coordinatePoints = r;
  }
  startDragging(t, e) {
    this.draggedFeatureId = e, this.dragPosition = [t.lng, t.lat];
  }
  stopDragging() {
    this.draggedFeatureId = null, this.dragPosition = void 0;
  }
  isDragging() {
    return this.draggedFeatureId !== null;
  }
  canDrag(t, e) {
    const { clickedFeature: i } = this.featuresAtCursorEvent.find(t, !0);
    return !(!i || i.id !== e);
  }
  drag(t, e) {
    if (!this.draggedFeatureId) return;
    const i = this.store.getGeometryCopy(this.draggedFeatureId), o = [t.lng, t.lat];
    if (i.type === "Polygon" || i.type === "LineString") {
      let r, n;
      if (i.type === "Polygon" ? (r = i.coordinates[0], n = r.length - 1) : (r = i.coordinates, n = r.length), !this.dragPosition) return !1;
      for (let h = 0; h < n; h++) {
        const c = r[h];
        let u, p;
        if (this.config.projection === "web-mercator") {
          const g = x(this.dragPosition[0], this.dragPosition[1]), y = x(o[0], o[1]), m = x(c[0], c[1]), v = { x: g.x - y.x, y: g.y - y.y }, f = m.x - v.x, C = m.y - v.y, { lng: P, lat: S } = W(f, C);
          u = P, p = S;
        } else {
          const g = [this.dragPosition[0] - o[0], this.dragPosition[1] - o[1]];
          u = c[0] - g[0], p = c[1] - g[1];
        }
        if (u = F(u, this.config.coordinatePrecision), p = F(p, this.config.coordinatePrecision), u > 180 || u < -180 || p > 90 || p < -90) return !1;
        r[h] = [u, p];
      }
      i.type === "Polygon" && (r[r.length - 1] = [r[0][0], r[0][1]]);
      const a = this.selectionPoints.getUpdated(r) || [], l = this.midPoints.getUpdated(r) || [], d = this.coordinatePoints.getUpdated(this.draggedFeatureId, r) || [];
      if (e && !e({ type: "Feature", id: this.draggedFeatureId, geometry: i, properties: {} }, { project: this.config.project, unproject: this.config.unproject, coordinatePrecision: this.config.coordinatePrecision, updateType: M.Provisional }).valid) return !1;
      this.store.updateGeometry([{ id: this.draggedFeatureId, geometry: i }, ...a, ...l, ...d]), this.dragPosition = [t.lng, t.lat];
    } else i.type === "Point" && (this.store.updateGeometry([{ id: this.draggedFeatureId, geometry: { type: "Point", coordinates: o } }]), this.dragPosition = [t.lng, t.lat]);
  }
}
class bi extends k {
  constructor(t, e, i, o, r, n) {
    super(t), this.config = void 0, this.pixelDistance = void 0, this.selectionPoints = void 0, this.midPoints = void 0, this.coordinatePoints = void 0, this.coordinateSnapping = void 0, this.draggedCoordinate = { id: null, index: -1 }, this.config = t, this.pixelDistance = e, this.selectionPoints = i, this.midPoints = o, this.coordinatePoints = r, this.coordinateSnapping = n;
  }
  getClosestCoordinate(t, e) {
    const i = { dist: 1 / 0, index: -1, isFirstOrLastPolygonCoord: !1 };
    let o;
    if (e.type === "LineString") o = e.coordinates;
    else {
      if (e.type !== "Polygon") return i;
      o = e.coordinates[0];
    }
    for (let r = 0; r < o.length; r++) {
      const n = this.pixelDistance.measure(t, o[r]);
      if (n < this.pointerDistance && n < i.dist) {
        const a = e.type === "Polygon" && (r === o.length - 1 || r === 0);
        i.dist = n, i.index = a ? 0 : r, i.isFirstOrLastPolygonCoord = a;
      }
    }
    return i;
  }
  getDraggableIndex(t, e) {
    const i = this.store.getGeometryCopy(e), o = this.getClosestCoordinate(t, i);
    return o.index === -1 ? -1 : o.index;
  }
  drag(t, e, i, o) {
    if (this.draggedCoordinate.id === null) return !1;
    const r = this.draggedCoordinate.index, n = this.store.getGeometryCopy(this.draggedCoordinate.id), a = this.store.getPropertiesCopy(this.draggedCoordinate.id), l = n.type === "LineString" ? n.coordinates : n.coordinates[0], d = n.type === "Polygon" && (r === l.length - 1 || r === 0);
    let h = [t.lng, t.lat];
    if (o) {
      let y;
      y = this.coordinateSnapping.getSnappable(t, (m) => !!(m.properties && m.properties.mode === a.mode && m.id !== this.draggedCoordinate.id)).coordinate, y && (h = y);
    }
    if (t.lng > 180 || t.lng < -180 || t.lat > 90 || t.lat < -90) return !1;
    if (d) {
      const y = l.length - 1;
      l[0] = h, l[y] = h;
    } else l[r] = h;
    const c = this.selectionPoints.getOneUpdated(r, h), u = c ? [c] : [], p = this.midPoints.getUpdated(l) || [], g = this.coordinatePoints.getUpdated(this.draggedCoordinate.id, l) || [];
    return !(n.type !== "Point" && !e && Bt({ geometry: n }) || i && !i({ type: "Feature", id: this.draggedCoordinate.id, geometry: n, properties: {} }, { project: this.config.project, unproject: this.config.unproject, coordinatePrecision: this.config.coordinatePrecision, updateType: M.Provisional }).valid || (this.store.updateGeometry([{ id: this.draggedCoordinate.id, geometry: n }, ...u, ...p, ...g]), 0));
  }
  isDragging() {
    return this.draggedCoordinate.id !== null;
  }
  startDragging(t, e) {
    this.draggedCoordinate = { id: t, index: e };
  }
  stopDragging() {
    this.draggedCoordinate = { id: null, index: -1 };
  }
}
function Ct(s) {
  let t = 0, e = 0, i = 0;
  return (s.geometry.type === "Polygon" ? s.geometry.coordinates[0].slice(0, -1) : s.geometry.coordinates).forEach((o) => {
    t += o[0], e += o[1], i++;
  }, !0), [t / i, e / i];
}
function ke(s, t) {
  s[0] += s[0] - t[0] > 180 ? -360 : t[0] - s[0] > 180 ? 360 : 0;
  const e = me, i = t[1] * Math.PI / 180, o = s[1] * Math.PI / 180, r = o - i;
  let n = Math.abs(s[0] - t[0]) * Math.PI / 180;
  n > Math.PI && (n -= 2 * Math.PI);
  const a = Math.log(Math.tan(o / 2 + Math.PI / 4) / Math.tan(i / 2 + Math.PI / 4)), l = Math.abs(a) > 1e-11 ? r / a : Math.cos(i);
  return Math.sqrt(r * r + l * l * n * n) * e;
}
function Pt(s) {
  const t = (s.geometry.type === "Polygon" ? s.geometry.coordinates[0] : s.geometry.coordinates).map((e) => {
    const { x: i, y: o } = x(e[0], e[1]);
    return [i, o];
  });
  return s.geometry.type === "Polygon" ? function(e) {
    let i = 0, o = 0, r = 0;
    const n = e.length;
    for (let a = 0; a < n - 1; a++) {
      const [l, d] = e[a], [h, c] = e[a + 1], u = l * c - h * d;
      i += u, o += (l + h) * u, r += (d + c) * u;
    }
    return i /= 2, o /= 6 * i, r /= 6 * i, { x: o, y: r };
  }(t) : function(e) {
    const i = e.length;
    let o = 0, r = 0;
    for (let n = 0; n < i; n++) {
      const [a, l] = e[n];
      o += a, r += l;
    }
    return { x: o / i, y: r / i };
  }(t);
}
class Mi extends k {
  constructor(t, e, i, o) {
    super(t), this.config = void 0, this.selectionPoints = void 0, this.midPoints = void 0, this.coordinatePoints = void 0, this.lastBearing = void 0, this.config = t, this.selectionPoints = e, this.midPoints = i, this.coordinatePoints = o;
  }
  reset() {
    this.lastBearing = void 0;
  }
  rotate(t, e, i) {
    const o = this.store.getGeometryCopy(e);
    if (o.type !== "Polygon" && o.type !== "LineString") return;
    const r = [t.lng, t.lat];
    let n;
    const a = { type: "Feature", geometry: o, properties: {} };
    if (this.config.projection === "web-mercator") {
      if (n = A(Pt(a), x(t.lng, t.lat)), !this.lastBearing) return void (this.lastBearing = n);
      ((u, p) => {
        if (p === 0 || p === 360 || p === -360) return u;
        const g = 0.017453292519943295 * p, y = (u.geometry.type === "Polygon" ? u.geometry.coordinates[0] : u.geometry.coordinates).map(([f, C]) => x(f, C)), m = y.reduce((f, C) => ({ x: f.x + C.x, y: f.y + C.y }), { x: 0, y: 0 });
        m.x /= y.length, m.y /= y.length;
        const v = y.map((f) => ({ x: m.x + (f.x - m.x) * Math.cos(g) - (f.y - m.y) * Math.sin(g), y: m.y + (f.x - m.x) * Math.sin(g) + (f.y - m.y) * Math.cos(g) })).map(({ x: f, y: C }) => [W(f, C).lng, W(f, C).lat]);
        u.geometry.type === "Polygon" ? u.geometry.coordinates[0] = v : u.geometry.coordinates = v;
      })(a, -(this.lastBearing - n));
    } else {
      if (this.config.projection !== "globe") throw new Error("Unsupported projection");
      if (n = vt(Ct({ geometry: o }), r), !this.lastBearing) return void (this.lastBearing = n + 180);
      (function(u, p) {
        if (p === 0 || p === 360 || p === -360) return u;
        const g = Ct(u);
        (u.geometry.type === "Polygon" ? u.geometry.coordinates[0] : u.geometry.coordinates).forEach((y) => {
          const m = vt(g, y) + p, v = ke(g, y), f = jt(g, v, m);
          y[0] = f[0], y[1] = f[1];
        });
      })(a, -(this.lastBearing - (n + 180)));
    }
    const l = o.type === "Polygon" ? o.coordinates[0] : o.coordinates;
    l.forEach((u) => {
      u[0] = F(u[0], this.coordinatePrecision), u[1] = F(u[1], this.coordinatePrecision);
    });
    const d = this.midPoints.getUpdated(l) || [], h = this.selectionPoints.getUpdated(l) || [], c = this.coordinatePoints.getUpdated(e, l) || [];
    if (i && !i({ id: e, type: "Feature", geometry: o, properties: {} }, { project: this.config.project, unproject: this.config.unproject, coordinatePrecision: this.config.coordinatePrecision, updateType: M.Provisional })) return !1;
    this.store.updateGeometry([{ id: e, geometry: o }, ...h, ...d, ...c]), this.projection === "web-mercator" ? this.lastBearing = n : this.projection === "globe" && (this.lastBearing = n + 180);
  }
}
class wi extends k {
  constructor(t, e, i, o) {
    super(t), this.config = void 0, this.selectionPoints = void 0, this.midPoints = void 0, this.coordinatePoints = void 0, this.lastDistance = void 0, this.config = t, this.selectionPoints = e, this.midPoints = i, this.coordinatePoints = o;
  }
  reset() {
    this.lastDistance = void 0;
  }
  scale(t, e, i) {
    const o = this.store.getGeometryCopy(e);
    if (o.type !== "Polygon" && o.type !== "LineString") return;
    const r = [t.lng, t.lat], n = { type: "Feature", geometry: o, properties: {} };
    let a;
    const l = Pt(n);
    if (this.config.projection === "web-mercator") {
      const g = x(t.lng, t.lat);
      a = E(l, g);
    } else {
      if (this.config.projection !== "globe") throw new Error("Invalid projection");
      a = T(Ct({ geometry: o }), r);
    }
    if (!this.lastDistance) return void (this.lastDistance = a);
    const d = 1 - (this.lastDistance - a) / a;
    if (this.config.projection === "web-mercator") {
      const { lng: g, lat: y } = W(l.x, l.y);
      (function(m, v, f) {
        if (v === 1) return m;
        const C = (m.geometry.type === "Polygon" ? m.geometry.coordinates[0] : m.geometry.coordinates).map(([b, w]) => x(b, w)), P = x(f[0], f[1]), S = C.map((b) => ({ x: P.x + (b.x - P.x) * v, y: P.y + (b.y - P.y) * v })).map(({ x: b, y: w }) => [W(b, w).lng, W(b, w).lat]);
        m.geometry.type === "Polygon" ? m.geometry.coordinates[0] = S : m.geometry.coordinates = S;
      })(n, d, [g, y]);
    } else this.config.projection === "globe" && function(g, y, m, v = "xy") {
      y === 1 || (g.geometry.type === "Polygon" ? g.geometry.coordinates[0] : g.geometry.coordinates).forEach((f) => {
        const C = ke(m, f), P = vt(m, f), S = jt(m, C * y, P);
        v !== "x" && v !== "xy" || (f[0] = S[0]), v !== "y" && v !== "xy" || (f[1] = S[1]);
      });
    }(n, d, Ct(n));
    const h = o.type === "Polygon" ? o.coordinates[0] : o.coordinates;
    h.forEach((g) => {
      g[0] = F(g[0], this.coordinatePrecision), g[1] = F(g[1], this.coordinatePrecision);
    });
    const c = this.midPoints.getUpdated(h) || [], u = this.selectionPoints.getUpdated(h) || [], p = this.coordinatePoints.getUpdated(e, h) || [];
    if (i && !i({ id: e, type: "Feature", geometry: o, properties: {} }, { project: this.config.project, unproject: this.config.unproject, coordinatePrecision: this.config.coordinatePrecision, updateType: M.Provisional })) return !1;
    this.store.updateGeometry([{ id: e, geometry: o }, ...u, ...c, ...p]), this.lastDistance = a;
  }
}
class Fi extends k {
  constructor(t, e, i, o, r) {
    super(t), this.config = void 0, this.pixelDistance = void 0, this.selectionPoints = void 0, this.midPoints = void 0, this.coordinatePoints = void 0, this.minimumScale = 1e-4, this.draggedCoordinate = { id: null, index: -1 }, this.boundingBoxMaps = { opposite: { 0: 4, 1: 5, 2: 6, 3: 7, 4: 0, 5: 1, 6: 2, 7: 3 } }, this.config = t, this.pixelDistance = e, this.selectionPoints = i, this.midPoints = o, this.coordinatePoints = r;
  }
  getClosestCoordinate(t, e) {
    const i = { dist: 1 / 0, index: -1, isFirstOrLastPolygonCoord: !1 };
    let o;
    if (e.type === "LineString") o = e.coordinates;
    else {
      if (e.type !== "Polygon") return i;
      o = e.coordinates[0];
    }
    for (let r = 0; r < o.length; r++) {
      const n = this.pixelDistance.measure(t, o[r]);
      if (n < this.pointerDistance && n < i.dist) {
        const a = e.type === "Polygon" && (r === o.length - 1 || r === 0);
        i.dist = n, i.index = a ? 0 : r, i.isFirstOrLastPolygonCoord = a;
      }
    }
    return i;
  }
  isValidDragWebMercator(t, e, i) {
    switch (t) {
      case 0:
        if (e <= 0 || i >= 0) return !1;
        break;
      case 1:
        if (i >= 0) return !1;
        break;
      case 2:
        if (e >= 0 || i >= 0) return !1;
        break;
      case 3:
        if (e >= 0) return !1;
        break;
      case 4:
        if (e >= 0 || i <= 0) return !1;
        break;
      case 5:
        if (i <= 0) return !1;
        break;
      case 6:
        if (e <= 0 || i <= 0) return !1;
        break;
      case 7:
        if (e <= 0) return !1;
    }
    return !0;
  }
  getSelectedFeatureDataWebMercator() {
    if (!this.draggedCoordinate.id || this.draggedCoordinate.index === -1) return null;
    const t = this.getFeature(this.draggedCoordinate.id);
    if (!t) return null;
    const e = this.getNormalisedCoordinates(t.geometry);
    return { boundingBox: this.getBBoxWebMercator(e), feature: t, updatedCoords: e, selectedCoordinate: e[this.draggedCoordinate.index] };
  }
  centerWebMercatorDrag(t) {
    const e = this.getSelectedFeatureDataWebMercator();
    if (!e) return null;
    const { feature: i, boundingBox: o, updatedCoords: r, selectedCoordinate: n } = e, a = Pt(i);
    if (!a) return null;
    const l = x(n[0], n[1]), { closestBBoxIndex: d } = this.getIndexesWebMercator(o, l), h = x(t.lng, t.lat);
    return this.scaleWebMercator({ closestBBoxIndex: d, updatedCoords: r, webMercatorCursor: h, webMercatorSelected: l, webMercatorOrigin: a }), r;
  }
  centerFixedWebMercatorDrag(t) {
    const e = this.getSelectedFeatureDataWebMercator();
    if (!e) return null;
    const { feature: i, boundingBox: o, updatedCoords: r, selectedCoordinate: n } = e, a = Pt(i);
    if (!a) return null;
    const l = x(n[0], n[1]), { closestBBoxIndex: d } = this.getIndexesWebMercator(o, l), h = x(t.lng, t.lat);
    return this.scaleFixedWebMercator({ closestBBoxIndex: d, updatedCoords: r, webMercatorCursor: h, webMercatorSelected: l, webMercatorOrigin: a }), r;
  }
  scaleFixedWebMercator({ closestBBoxIndex: t, webMercatorOrigin: e, webMercatorSelected: i, webMercatorCursor: o, updatedCoords: r }) {
    if (!this.isValidDragWebMercator(t, e.x - o.x, e.y - o.y)) return null;
    let n = E(e, o) / E(e, i);
    return n < 0 && (n = this.minimumScale), this.performWebMercatorScale(r, e.x, e.y, n, n), r;
  }
  oppositeFixedWebMercatorDrag(t) {
    const e = this.getSelectedFeatureDataWebMercator();
    if (!e) return null;
    const { boundingBox: i, updatedCoords: o, selectedCoordinate: r } = e, n = x(r[0], r[1]), { oppositeBboxIndex: a, closestBBoxIndex: l } = this.getIndexesWebMercator(i, n), d = { x: i[a][0], y: i[a][1] }, h = x(t.lng, t.lat);
    return this.scaleFixedWebMercator({ closestBBoxIndex: l, updatedCoords: o, webMercatorCursor: h, webMercatorSelected: n, webMercatorOrigin: d }), o;
  }
  oppositeWebMercatorDrag(t) {
    const e = this.getSelectedFeatureDataWebMercator();
    if (!e) return null;
    const { boundingBox: i, updatedCoords: o, selectedCoordinate: r } = e, n = x(r[0], r[1]), { oppositeBboxIndex: a, closestBBoxIndex: l } = this.getIndexesWebMercator(i, n), d = { x: i[a][0], y: i[a][1] }, h = x(t.lng, t.lat);
    return this.scaleWebMercator({ closestBBoxIndex: l, updatedCoords: o, webMercatorCursor: h, webMercatorSelected: n, webMercatorOrigin: d }), o;
  }
  scaleWebMercator({ closestBBoxIndex: t, webMercatorOrigin: e, webMercatorSelected: i, webMercatorCursor: o, updatedCoords: r }) {
    const n = e.x - o.x, a = e.y - o.y;
    if (!this.isValidDragWebMercator(t, n, a)) return null;
    let l = 1;
    n !== 0 && t !== 1 && t !== 5 && (l = 1 - (e.x - i.x - n) / n);
    let d = 1;
    return a !== 0 && t !== 3 && t !== 7 && (d = 1 - (e.y - i.y - a) / a), this.validateScale(l, d) ? (l < 0 && (l = this.minimumScale), d < 0 && (d = this.minimumScale), this.performWebMercatorScale(r, e.x, e.y, l, d), r) : null;
  }
  getFeature(t) {
    if (this.draggedCoordinate.id === null) return null;
    const e = this.store.getGeometryCopy(t);
    return e.type !== "Polygon" && e.type !== "LineString" ? null : { id: t, type: "Feature", geometry: e, properties: {} };
  }
  getNormalisedCoordinates(t) {
    return t.type === "Polygon" ? t.coordinates[0] : t.coordinates;
  }
  validateScale(t, e) {
    const i = !isNaN(t) && e < Number.MAX_SAFE_INTEGER, o = !isNaN(e) && e < Number.MAX_SAFE_INTEGER;
    return i && o;
  }
  performWebMercatorScale(t, e, i, o, r) {
    t.forEach((n) => {
      const { x: a, y: l } = x(n[0], n[1]), d = e + (a - e) * o, h = i + (l - i) * r, { lng: c, lat: u } = W(d, h);
      n[0] = c, n[1] = u;
    });
  }
  getBBoxWebMercator(t) {
    const e = [1 / 0, 1 / 0, -1 / 0, -1 / 0];
    (t = t.map((a) => {
      const { x: l, y: d } = x(a[0], a[1]);
      return [l, d];
    })).forEach(([a, l]) => {
      a < e[0] && (e[0] = a), l < e[1] && (e[1] = l), a > e[2] && (e[2] = a), l > e[3] && (e[3] = l);
    });
    const [i, o, r, n] = e;
    return [[i, n], [(i + r) / 2, n], [r, n], [r, n + (o - n) / 2], [r, o], [(i + r) / 2, o], [i, o], [i, n + (o - n) / 2]];
  }
  getIndexesWebMercator(t, e) {
    let i, o = 1 / 0;
    for (let r = 0; r < t.length; r++) {
      const n = E({ x: e.x, y: e.y }, { x: t[r][0], y: t[r][1] });
      n < o && (i = r, o = n);
    }
    if (i === void 0) throw new Error("No closest coordinate found");
    return { oppositeBboxIndex: this.boundingBoxMaps.opposite[i], closestBBoxIndex: i };
  }
  isDragging() {
    return this.draggedCoordinate.id !== null;
  }
  startDragging(t, e) {
    this.draggedCoordinate = { id: t, index: e };
  }
  stopDragging() {
    this.draggedCoordinate = { id: null, index: -1 };
  }
  getDraggableIndex(t, e) {
    const i = this.store.getGeometryCopy(e), o = this.getClosestCoordinate(t, i);
    return o.index === -1 ? -1 : o.index;
  }
  drag(t, e, i) {
    if (!this.draggedCoordinate.id) return !1;
    const o = this.getFeature(this.draggedCoordinate.id);
    if (!o) return !1;
    let r = null;
    if (e === "center" ? r = this.centerWebMercatorDrag(t) : e === "opposite" ? r = this.oppositeWebMercatorDrag(t) : e === "center-fixed" ? r = this.centerFixedWebMercatorDrag(t) : e === "opposite-fixed" && (r = this.oppositeFixedWebMercatorDrag(t)), !r) return !1;
    for (let h = 0; h < r.length; h++) {
      const c = r[h];
      if (c[0] = F(c[0], this.coordinatePrecision), c[1] = F(c[1], this.coordinatePrecision), !xt(c, this.coordinatePrecision)) return !1;
    }
    const n = this.midPoints.getUpdated(r) || [], a = this.selectionPoints.getUpdated(r) || [], l = this.coordinatePoints.getUpdated(o.id, r) || [], d = { type: o.geometry.type, coordinates: o.geometry.type === "Polygon" ? [r] : r };
    return !(i && !i({ id: this.draggedCoordinate.id, type: "Feature", geometry: d, properties: {} }, { project: this.config.project, unproject: this.config.unproject, coordinatePrecision: this.config.coordinatePrecision, updateType: M.Provisional }).valid || (this.store.updateGeometry([{ id: this.draggedCoordinate.id, geometry: d }, ...a, ...n, ...l]), 0));
  }
}
const Ei = { deselect: "Escape", delete: "Delete", rotate: ["Control", "r"], scale: ["Control", "s"] }, ee = { pointerOver: "move", dragStart: "move", dragEnd: "move", insertMidpoint: "crosshair" };
class Be extends $e {
  constructor(t) {
    super(t, !0), this.mode = "select", this.allowManualDeselection = !0, this.dragEventThrottle = 5, this.dragEventCount = 0, this.selected = [], this.flags = {}, this.keyEvents = Ei, this.cursors = ee, this.validations = {}, this.selectionPoints = void 0, this.midPoints = void 0, this.coordinateSnap = void 0, this.featuresAtMouseEvent = void 0, this.pixelDistance = void 0, this.clickBoundingBox = void 0, this.dragFeature = void 0, this.dragCoordinate = void 0, this.rotateFeature = void 0, this.scaleFeature = void 0, this.dragCoordinateResizeFeature = void 0, this.coordinatePoints = void 0, this.updateOptions(t);
  }
  updateOptions(t) {
    if (super.updateOptions(t), this.cursors = t && t.cursors ? I({}, this.cursors, t.cursors) : ee, (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { deselect: null, delete: null, rotate: null, scale: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents)), (t == null ? void 0 : t.dragEventThrottle) !== void 0 && (this.dragEventThrottle = t.dragEventThrottle), (t == null ? void 0 : t.allowManualDeselection) !== void 0 && (this.allowManualDeselection = t.allowManualDeselection), t != null && t.flags) {
      this.flags = I({}, this.flags, t.flags), this.validations = {};
      for (const e in this.flags) {
        const i = this.flags[e].feature;
        i && i.validation && (this.validations[e] = i.validation);
      }
    }
  }
  createOrUpdateCoordinatePoint(t) {
    const e = this.store.getPropertiesCopy(t);
    e.coordinatePointIds && this.store.delete(e.coordinatePointIds);
    const i = this.store.getGeometryCopy(t), o = this.store.create(i.coordinates[0].map((r) => ({ geometry: { type: "Point", coordinates: r }, properties: { mode: this.mode, [Lt]: !0 } })));
    this.store.updateProperty([{ id: t, property: "coordinatePointIds", value: o }]);
  }
  selectFeature(t) {
    this.select(t, !1);
  }
  setSelecting() {
    if (this._state !== "started") throw new Error("Mode must be started to move to selecting state");
    this._state = "selecting";
  }
  registerBehaviors(t) {
    this.pixelDistance = new nt(t), this.clickBoundingBox = new rt(t), this.featuresAtMouseEvent = new xi(t, this.clickBoundingBox, this.pixelDistance), this.selectionPoints = new Si(t), this.coordinatePoints = new Fe(t), this.midPoints = new Pi(t, this.selectionPoints, this.coordinatePoints), this.coordinateSnap = new mt(t, this.pixelDistance, this.clickBoundingBox), this.rotateFeature = new Mi(t, this.selectionPoints, this.midPoints, this.coordinatePoints), this.scaleFeature = new wi(t, this.selectionPoints, this.midPoints, this.coordinatePoints), this.dragFeature = new Ii(t, this.featuresAtMouseEvent, this.selectionPoints, this.midPoints, this.coordinatePoints), this.dragCoordinate = new bi(t, this.pixelDistance, this.selectionPoints, this.midPoints, this.coordinatePoints, this.coordinateSnap), this.dragCoordinateResizeFeature = new Fi(t, this.pixelDistance, this.selectionPoints, this.midPoints, this.coordinatePoints);
  }
  deselectFeature() {
    this.deselect();
  }
  deselect() {
    const t = this.selected.filter((e) => this.store.has(e)).map((e) => ({ id: e, property: V.SELECTED, value: !1 }));
    this.store.updateProperty(t), this.onDeselect(this.selected[0]), this.selected = [], this.selectionPoints.delete(), this.midPoints.delete();
  }
  deleteSelected() {
    this.store.delete(this.selected), this.selected = [];
  }
  onRightClick(t) {
    if (!this.selectionPoints.ids.length) return;
    let e, i = 1 / 0;
    if (this.selectionPoints.ids.forEach((u) => {
      const p = this.store.getGeometryCopy(u), g = this.pixelDistance.measure(t, p.coordinates);
      g < this.pointerDistance && g < i && (i = g, e = this.store.getPropertiesCopy(u));
    }), !e) return;
    const o = e.selectionPointFeatureId, r = e.index, n = this.store.getPropertiesCopy(o), a = this.flags[n.mode], l = this.validations[n.mode];
    if (!(a && a.feature && a.feature.coordinates && a.feature.coordinates.deletable)) return;
    const d = this.store.getGeometryCopy(o);
    let h;
    if (d.type === "Polygon") {
      if (h = d.coordinates[0], h.length <= 4) return;
    } else if (d.type === "LineString" && (h = d.coordinates, h.length <= 2)) return;
    if (!h || (d.type !== "Polygon" || r !== 0 && r !== h.length - 1 ? h.splice(r, 1) : (h.shift(), h.pop(), h.push([h[0][0], h[0][1]])), l && !l({ id: o, type: "Feature", geometry: d, properties: n }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: M.Commit }).valid)) return;
    const c = [...this.midPoints.ids, ...this.selectionPoints.ids];
    this.store.delete(c), this.store.updateGeometry([{ id: o, geometry: d }]), n.coordinatePointIds && this.coordinatePoints.createOrUpdate(o), this.selectionPoints.create(h, d.type, o), a && a.feature && a.feature.coordinates && a.feature.coordinates.midpoints && this.midPoints.create(h, o, this.coordinatePrecision);
  }
  select(t, e = !0) {
    if (this.selected[0] === t) return;
    const { mode: i } = this.store.getPropertiesCopy(t), o = this.flags[i];
    if (!o || !o.feature) return;
    const r = this.selected[0];
    if (r) {
      if (r === t) return;
      this.deselect();
    }
    e && this.setCursor(this.cursors.pointerOver), this.selected = [t], this.store.updateProperty([{ id: t, property: "selected", value: !0 }]), this.onSelect(t);
    const { type: n, coordinates: a } = this.store.getGeometryCopy(t);
    if (n !== "LineString" && n !== "Polygon") return;
    const l = n === "LineString" ? a : a[0];
    l && o && o.feature.coordinates && (this.selectionPoints.create(l, n, t), o.feature.coordinates.midpoints && this.midPoints.create(l, t, this.coordinatePrecision));
  }
  onLeftClick(t) {
    const { clickedFeature: e, clickedMidPoint: i } = this.featuresAtMouseEvent.find(t, this.selected.length > 0);
    if (this.selected.length && i) this.midPoints.insert(this.selected[0], i.id, this.coordinatePrecision);
    else if (e && e.id) this.select(e.id, !0);
    else if (this.selected.length && this.allowManualDeselection) return void this.deselect();
  }
  start() {
    this.setStarted(), this.setSelecting();
  }
  stop() {
    this.cleanUp(), this.setStarted(), this.setStopped();
  }
  onClick(t) {
    t.button !== "right" ? t.button === "left" && this.onLeftClick(t) : this.onRightClick(t);
  }
  canScale(t) {
    return this.keyEvents.scale && this.keyEvents.scale.every((e) => t.heldKeys.includes(e));
  }
  canRotate(t) {
    return this.keyEvents.rotate && this.keyEvents.rotate.every((e) => t.heldKeys.includes(e));
  }
  preventDefaultKeyEvent(t) {
    const e = this.canRotate(t), i = this.canScale(t);
    (e || i) && t.preventDefault();
  }
  onKeyDown(t) {
    this.preventDefaultKeyEvent(t);
  }
  onKeyUp(t) {
    if (this.preventDefaultKeyEvent(t), this.keyEvents.delete && t.key === this.keyEvents.delete) {
      if (!this.selected.length) return;
      this.onDeselect(this.selected[0]), this.deleteSelected(), this.selectionPoints.delete(), this.midPoints.delete();
    } else this.keyEvents.deselect && t.key === this.keyEvents.deselect && this.cleanUp();
  }
  cleanUp() {
    this.selected.length && this.deselect();
  }
  onDragStart(t, e) {
    if (!this.selected.length) return;
    const i = this.store.getPropertiesCopy(this.selected[0]), o = this.flags[i.mode];
    if (!(o && o.feature && (o.feature.draggable || o.feature.coordinates && o.feature.coordinates.draggable || o.feature.coordinates && o.feature.coordinates.resizable || o.feature.coordinates && typeof o.feature.coordinates.midpoints == "object" && o.feature.coordinates.midpoints.draggable))) return;
    this.dragEventCount = 0;
    const r = this.selected[0], n = this.dragCoordinate.getDraggableIndex(t, r);
    if (o && o.feature && o.feature.coordinates && (o.feature.coordinates.draggable || o.feature.coordinates.resizable) && n !== -1) return this.setCursor(this.cursors.dragStart), o.feature.coordinates.resizable ? this.dragCoordinateResizeFeature.startDragging(r, n) : this.dragCoordinate.startDragging(r, n), void e(!1);
    if (o && o.feature && o.feature.coordinates && typeof o.feature.coordinates.midpoints == "object" && o.feature.coordinates.midpoints.draggable) {
      const { clickedMidPoint: a } = this.featuresAtMouseEvent.find(t, this.selected.length > 0);
      if (this.selected.length && a) {
        this.midPoints.insert(r, a.id, this.coordinatePrecision);
        const l = this.dragCoordinate.getDraggableIndex(t, r);
        return this.dragCoordinate.startDragging(r, l), void e(!1);
      }
    }
    return o && o.feature && o.feature.draggable && this.dragFeature.canDrag(t, r) ? (this.setCursor(this.cursors.dragStart), this.dragFeature.startDragging(t, r), void e(!1)) : void 0;
  }
  onDrag(t, e) {
    const i = this.selected[0];
    if (!i) return;
    const o = this.store.getPropertiesCopy(i), r = this.flags[o.mode], n = (r && r.feature && r.feature.selfIntersectable) === !0;
    if (this.dragEventCount++, this.dragEventCount % this.dragEventThrottle == 0) return;
    const a = this.validations[o.mode];
    if (r && r.feature && r.feature.rotateable && this.canRotate(t)) return e(!1), void this.rotateFeature.rotate(t, i, a);
    if (r && r.feature && r.feature.scaleable && this.canScale(t)) return e(!1), void this.scaleFeature.scale(t, i, a);
    if (this.dragCoordinateResizeFeature.isDragging() && r.feature && r.feature.coordinates && r.feature.coordinates.resizable) {
      if (this.projection === "globe") throw new Error("Globe is currently unsupported projection for resizable");
      return e(!1), void this.dragCoordinateResizeFeature.drag(t, r.feature.coordinates.resizable, a);
    }
    if (this.dragCoordinate.isDragging()) {
      var l;
      const d = !!(!((l = r.feature) == null || (l = l.coordinates) == null) && l.snappable);
      this.dragCoordinate.drag(t, n, a, d);
    } else this.dragFeature.isDragging() ? this.dragFeature.drag(t, a) : e(!0);
  }
  onDragEnd(t, e) {
    this.setCursor(this.cursors.dragEnd), this.dragCoordinate.isDragging() ? this.onFinish(this.selected[0], { mode: this.mode, action: "dragCoordinate" }) : this.dragFeature.isDragging() ? this.onFinish(this.selected[0], { mode: this.mode, action: "dragFeature" }) : this.dragCoordinateResizeFeature.isDragging() && this.onFinish(this.selected[0], { mode: this.mode, action: "dragCoordinateResize" }), this.dragCoordinate.stopDragging(), this.dragFeature.stopDragging(), this.dragCoordinateResizeFeature.stopDragging(), this.rotateFeature.reset(), this.scaleFeature.reset(), e(!0);
  }
  onMouseMove(t) {
    if (!this.selected.length) return void this.setCursor("unset");
    if (this.dragFeature.isDragging()) return;
    let e = !1;
    this.midPoints.ids.forEach((r) => {
      if (e) return;
      const n = this.store.getGeometryCopy(r);
      this.pixelDistance.measure(t, n.coordinates) < this.pointerDistance && (e = !0);
    });
    let i = !1;
    if (this.selectionPoints.ids.forEach((r) => {
      const n = this.store.getGeometryCopy(r);
      this.pixelDistance.measure(t, n.coordinates) < this.pointerDistance && (e = !1, i = !0);
    }), e) return void this.setCursor(this.cursors.insertMidpoint);
    const { clickedFeature: o } = this.featuresAtMouseEvent.find(t, !0);
    this.setCursor(this.selected.length > 0 && (o && o.id === this.selected[0] || i) ? this.cursors.pointerOver : "unset");
  }
  styleFeature(t) {
    const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
    if (t.properties.mode === this.mode && t.geometry.type === "Point") {
      if (t.properties.selectionPoint) return e.pointColor = this.getHexColorStylingValue(this.styles.selectionPointColor, e.pointColor, t), e.pointOutlineColor = this.getHexColorStylingValue(this.styles.selectionPointOutlineColor, e.pointOutlineColor, t), e.pointWidth = this.getNumericStylingValue(this.styles.selectionPointWidth, e.pointWidth, t), e.pointOutlineWidth = this.getNumericStylingValue(this.styles.selectionPointOutlineWidth, 2, t), e.zIndex = 30, e;
      if (t.properties.midPoint) return e.pointColor = this.getHexColorStylingValue(this.styles.midPointColor, e.pointColor, t), e.pointOutlineColor = this.getHexColorStylingValue(this.styles.midPointOutlineColor, e.pointOutlineColor, t), e.pointWidth = this.getNumericStylingValue(this.styles.midPointWidth, 4, t), e.pointOutlineWidth = this.getNumericStylingValue(this.styles.midPointOutlineWidth, 2, t), e.zIndex = 40, e;
    } else if (t.properties[V.SELECTED]) {
      if (t.geometry.type === "Polygon") return e.polygonFillColor = this.getHexColorStylingValue(this.styles.selectedPolygonColor, e.polygonFillColor, t), e.polygonOutlineWidth = this.getNumericStylingValue(this.styles.selectedPolygonOutlineWidth, e.polygonOutlineWidth, t), e.polygonOutlineColor = this.getHexColorStylingValue(this.styles.selectedPolygonOutlineColor, e.polygonOutlineColor, t), e.polygonFillOpacity = this.getNumericStylingValue(this.styles.selectedPolygonFillOpacity, e.polygonFillOpacity, t), e.zIndex = 10, e;
      if (t.geometry.type === "LineString") return e.lineStringColor = this.getHexColorStylingValue(this.styles.selectedLineStringColor, e.lineStringColor, t), e.lineStringWidth = this.getNumericStylingValue(this.styles.selectedLineStringWidth, e.lineStringWidth, t), e.zIndex = 10, e;
      if (t.geometry.type === "Point") return e.pointWidth = this.getNumericStylingValue(this.styles.selectedPointWidth, e.pointWidth, t), e.pointColor = this.getHexColorStylingValue(this.styles.selectedPointColor, e.pointColor, t), e.pointOutlineColor = this.getHexColorStylingValue(this.styles.selectedPointOutlineColor, e.pointOutlineColor, t), e.pointOutlineWidth = this.getNumericStylingValue(this.styles.selectedPointOutlineWidth, e.pointOutlineWidth, t), e.zIndex = 10, e;
    }
    return e;
  }
}
class Oi extends N {
  constructor(...t) {
    super(...t), this.type = $.Static, this.mode = "static";
  }
  start() {
  }
  stop() {
  }
  onKeyUp() {
  }
  onKeyDown() {
  }
  onClick() {
  }
  onDragStart() {
  }
  onDrag() {
  }
  onDragEnd() {
  }
  onMouseMove() {
  }
  cleanUp() {
  }
  styleFeature() {
    return I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
  }
}
function We(s, t, e, i, o) {
  for (; i > e; ) {
    if (i - e > 600) {
      const l = i - e + 1, d = t - e + 1, h = Math.log(l), c = 0.5 * Math.exp(2 * h / 3), u = 0.5 * Math.sqrt(h * c * (l - c) / l) * (d - l / 2 < 0 ? -1 : 1);
      We(s, t, Math.max(e, Math.floor(t - d * c / l + u)), Math.min(i, Math.floor(t + (l - d) * c / l + u)), o);
    }
    const r = s[t];
    let n = e, a = i;
    for (Q(s, e, t), o(s[i], r) > 0 && Q(s, e, i); n < a; ) {
      for (Q(s, n, a), n++, a--; o(s[n], r) < 0; ) n++;
      for (; o(s[a], r) > 0; ) a--;
    }
    o(s[e], r) === 0 ? Q(s, e, a) : (a++, Q(s, a, i)), a <= t && (e = a + 1), t <= a && (i = a - 1);
  }
}
function Q(s, t, e) {
  const i = s[t];
  s[t] = s[e], s[e] = i;
}
function H(s, t) {
  it(s, 0, s.children.length, t, s);
}
function it(s, t, e, i, o) {
  o || (o = J([])), o.minX = 1 / 0, o.minY = 1 / 0, o.maxX = -1 / 0, o.maxY = -1 / 0;
  for (let r = t; r < e; r++) {
    const n = s.children[r];
    ot(o, s.leaf ? i(n) : n);
  }
  return o;
}
function ot(s, t) {
  return s.minX = Math.min(s.minX, t.minX), s.minY = Math.min(s.minY, t.minY), s.maxX = Math.max(s.maxX, t.maxX), s.maxY = Math.max(s.maxY, t.maxY), s;
}
function Di(s, t) {
  return s.minX - t.minX;
}
function _i(s, t) {
  return s.minY - t.minY;
}
function Ft(s) {
  return (s.maxX - s.minX) * (s.maxY - s.minY);
}
function ut(s) {
  return s.maxX - s.minX + (s.maxY - s.minY);
}
function Li(s, t) {
  const e = Math.max(s.minX, t.minX), i = Math.max(s.minY, t.minY), o = Math.min(s.maxX, t.maxX), r = Math.min(s.maxY, t.maxY);
  return Math.max(0, o - e) * Math.max(0, r - i);
}
function Et(s, t) {
  return s.minX <= t.minX && s.minY <= t.minY && t.maxX <= s.maxX && t.maxY <= s.maxY;
}
function pt(s, t) {
  return t.minX <= s.maxX && t.minY <= s.maxY && t.maxX >= s.minX && t.maxY >= s.minY;
}
function J(s) {
  return { children: s, height: 1, leaf: !0, minX: 1 / 0, minY: 1 / 0, maxX: -1 / 0, maxY: -1 / 0 };
}
function ie(s, t, e, i, o) {
  const r = [t, e];
  for (; r.length; ) {
    if ((e = r.pop()) - (t = r.pop()) <= i) continue;
    const n = t + Math.ceil((e - t) / i / 2) * i;
    We(s, n, t, e, o), r.push(t, n, n, e);
  }
}
class ki {
  constructor(t) {
    this._maxEntries = void 0, this._minEntries = void 0, this.data = void 0, this._maxEntries = Math.max(4, t), this._minEntries = Math.max(2, Math.ceil(0.4 * this._maxEntries)), this.clear();
  }
  search(t) {
    let e = this.data;
    const i = [];
    if (!pt(t, e)) return i;
    const o = this.toBBox, r = [];
    for (; e; ) {
      for (let n = 0; n < e.children.length; n++) {
        const a = e.children[n], l = e.leaf ? o(a) : a;
        pt(t, l) && (e.leaf ? i.push(a) : Et(t, l) ? this._all(a, i) : r.push(a));
      }
      e = r.pop();
    }
    return i;
  }
  collides(t) {
    let e = this.data;
    if (pt(t, e)) {
      const i = [];
      for (; e; ) {
        for (let o = 0; o < e.children.length; o++) {
          const r = e.children[o], n = e.leaf ? this.toBBox(r) : r;
          if (pt(t, n)) {
            if (e.leaf || Et(t, n)) return !0;
            i.push(r);
          }
        }
        e = i.pop();
      }
    }
    return !1;
  }
  load(t) {
    if (t.length < this._minEntries) {
      for (let i = 0; i < t.length; i++) this.insert(t[i]);
      return;
    }
    let e = this._build(t.slice(), 0, t.length - 1, 0);
    if (this.data.children.length) if (this.data.height === e.height) this._splitRoot(this.data, e);
    else {
      if (this.data.height < e.height) {
        const i = this.data;
        this.data = e, e = i;
      }
      this._insert(e, this.data.height - e.height - 1, !0);
    }
    else this.data = e;
  }
  insert(t) {
    this._insert(t, this.data.height - 1);
  }
  clear() {
    this.data = J([]);
  }
  remove(t) {
    let e = this.data;
    const i = this.toBBox(t), o = [], r = [];
    let n, a, l = !1;
    for (; e || o.length; ) {
      if (e || (e = o.pop(), a = o[o.length - 1], n = r.pop(), l = !0), e.leaf) {
        const d = e.children.indexOf(t);
        d !== -1 && (e.children.splice(d, 1), o.push(e), this._condense(o));
      }
      l || e.leaf || !Et(e, i) ? a ? (n++, e = a.children[n], l = !1) : e = null : (o.push(e), r.push(n), n = 0, a = e, e = e.children[0]);
    }
  }
  toBBox(t) {
    return t;
  }
  compareMinX(t, e) {
    return t.minX - e.minX;
  }
  compareMinY(t, e) {
    return t.minY - e.minY;
  }
  _all(t, e) {
    const i = [];
    for (; t; ) t.leaf ? e.push(...t.children) : i.push(...t.children), t = i.pop();
    return e;
  }
  _build(t, e, i, o) {
    const r = i - e + 1;
    let n, a = this._maxEntries;
    if (r <= a) return n = J(t.slice(e, i + 1)), H(n, this.toBBox), n;
    o || (o = Math.ceil(Math.log(r) / Math.log(a)), a = Math.ceil(r / Math.pow(a, o - 1))), n = J([]), n.leaf = !1, n.height = o;
    const l = Math.ceil(r / a), d = l * Math.ceil(Math.sqrt(a));
    ie(t, e, i, d, this.compareMinX);
    for (let h = e; h <= i; h += d) {
      const c = Math.min(h + d - 1, i);
      ie(t, h, c, l, this.compareMinY);
      for (let u = h; u <= c; u += l) {
        const p = Math.min(u + l - 1, c);
        n.children.push(this._build(t, u, p, o - 1));
      }
    }
    return H(n, this.toBBox), n;
  }
  _chooseSubtree(t, e, i, o) {
    for (; o.push(e), !e.leaf && o.length - 1 !== i; ) {
      let a, l = 1 / 0, d = 1 / 0;
      for (let h = 0; h < e.children.length; h++) {
        const c = e.children[h], u = Ft(c), p = (r = t, n = c, (Math.max(n.maxX, r.maxX) - Math.min(n.minX, r.minX)) * (Math.max(n.maxY, r.maxY) - Math.min(n.minY, r.minY)) - u);
        p < d ? (d = p, l = u < l ? u : l, a = c) : p === d && u < l && (l = u, a = c);
      }
      e = a || e.children[0];
    }
    var r, n;
    return e;
  }
  _insert(t, e, i) {
    const o = i ? t : this.toBBox(t), r = [], n = this._chooseSubtree(o, this.data, e, r);
    for (n.children.push(t), ot(n, o); e >= 0 && r[e].children.length > this._maxEntries; ) this._split(r, e), e--;
    this._adjustParentBBoxes(o, r, e);
  }
  _split(t, e) {
    const i = t[e], o = i.children.length, r = this._minEntries;
    this._chooseSplitAxis(i, r, o);
    const n = this._chooseSplitIndex(i, r, o), a = J(i.children.splice(n, i.children.length - n));
    a.height = i.height, a.leaf = i.leaf, H(i, this.toBBox), H(a, this.toBBox), e ? t[e - 1].children.push(a) : this._splitRoot(i, a);
  }
  _splitRoot(t, e) {
    this.data = J([t, e]), this.data.height = t.height + 1, this.data.leaf = !1, H(this.data, this.toBBox);
  }
  _chooseSplitIndex(t, e, i) {
    let o, r = 1 / 0, n = 1 / 0;
    for (let a = e; a <= i - e; a++) {
      const l = it(t, 0, a, this.toBBox), d = it(t, a, i, this.toBBox), h = Li(l, d), c = Ft(l) + Ft(d);
      h < r ? (r = h, o = a, n = c < n ? c : n) : h === r && c < n && (n = c, o = a);
    }
    return o || i - e;
  }
  _chooseSplitAxis(t, e, i) {
    const o = t.leaf ? this.compareMinX : Di, r = t.leaf ? this.compareMinY : _i;
    this._allDistMargin(t, e, i, o) < this._allDistMargin(t, e, i, r) && t.children.sort(o);
  }
  _allDistMargin(t, e, i, o) {
    t.children.sort(o);
    const r = this.toBBox, n = it(t, 0, e, r), a = it(t, i - e, i, r);
    let l = ut(n) + ut(a);
    for (let d = e; d < i - e; d++) {
      const h = t.children[d];
      ot(n, t.leaf ? r(h) : h), l += ut(n);
    }
    for (let d = i - e - 1; d >= e; d--) {
      const h = t.children[d];
      ot(a, t.leaf ? r(h) : h), l += ut(a);
    }
    return l;
  }
  _adjustParentBBoxes(t, e, i) {
    for (let o = i; o >= 0; o--) ot(e[o], t);
  }
  _condense(t) {
    for (let e, i = t.length - 1; i >= 0; i--) t[i].children.length === 0 ? i > 0 ? (e = t[i - 1].children, e.splice(e.indexOf(t[i]), 1)) : this.clear() : H(t[i], this.toBBox);
  }
}
class Bi {
  constructor(t) {
    this.tree = void 0, this.idToNode = void 0, this.nodeToId = void 0, this.tree = new ki(t && t.maxEntries ? t.maxEntries : 9), this.idToNode = /* @__PURE__ */ new Map(), this.nodeToId = /* @__PURE__ */ new Map();
  }
  setMaps(t, e) {
    this.idToNode.set(t.id, e), this.nodeToId.set(e, t.id);
  }
  toBBox(t) {
    const e = [], i = [];
    let o;
    if (t.geometry.type === "Polygon") o = t.geometry.coordinates[0];
    else if (t.geometry.type === "LineString") o = t.geometry.coordinates;
    else {
      if (t.geometry.type !== "Point") throw new Error("Not a valid feature to turn into a bounding box");
      o = [t.geometry.coordinates];
    }
    for (let a = 0; a < o.length; a++) i.push(o[a][1]), e.push(o[a][0]);
    const r = Math.min(...i), n = Math.max(...i);
    return { minX: Math.min(...e), minY: r, maxX: Math.max(...e), maxY: n };
  }
  insert(t) {
    if (this.idToNode.get(String(t.id))) throw new Error("Feature already exists");
    const e = this.toBBox(t);
    this.setMaps(t, e), this.tree.insert(e);
  }
  load(t) {
    const e = [], i = /* @__PURE__ */ new Set();
    t.forEach((o) => {
      const r = this.toBBox(o);
      if (this.setMaps(o, r), i.has(String(o.id))) throw new Error(`Duplicate feature ID found ${o.id}`);
      i.add(String(o.id)), e.push(r);
    }), this.tree.load(e);
  }
  update(t) {
    this.remove(t.id);
    const e = this.toBBox(t);
    this.setMaps(t, e), this.tree.insert(e);
  }
  remove(t) {
    const e = this.idToNode.get(t);
    if (!e) throw new Error(`${t} not inserted into the spatial index`);
    this.tree.remove(e);
  }
  clear() {
    this.tree.clear();
  }
  search(t) {
    return this.tree.search(this.toBBox(t)).map((e) => this.nodeToId.get(e));
  }
  collides(t) {
    return this.tree.collides(this.toBBox(t));
  }
}
const Wi = { getId: () => "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(s) {
  const t = 16 * Math.random() | 0;
  return (s == "x" ? t : 3 & t | 8).toString(16);
}), isValidId: (s) => typeof s == "string" && s.length === 36 };
class ji {
  constructor(t) {
    this.idStrategy = void 0, this.tracked = void 0, this.spatialIndex = void 0, this.store = void 0, this._onChange = () => {
    }, this.store = {}, this.spatialIndex = new Bi(), this.tracked = !t || t.tracked !== !1, this.idStrategy = t && t.idStrategy ? t.idStrategy : Wi;
  }
  clone(t) {
    return JSON.parse(JSON.stringify(t));
  }
  getId() {
    return this.idStrategy.getId();
  }
  has(t) {
    return !!this.store[t];
  }
  load(t, e, i) {
    if (t.length === 0) return [];
    let o = this.clone(t);
    const r = [], n = [];
    return o = o.filter((a) => {
      a.id == null && (a.id = this.idStrategy.getId());
      const l = a.id;
      if (e) {
        const d = e(a);
        if (!d.valid) return n.push({ id: l, valid: !1, reason: d.reason }), !1;
      }
      if (this.tracked) {
        if (a.properties.createdAt) {
          if (!Xt(a.properties.createdAt)) return n.push({ id: a.id, valid: !1, reason: "createdAt is not a valid numeric timestamp" }), !1;
        } else a.properties.createdAt = +/* @__PURE__ */ new Date();
        if (a.properties.updatedAt) {
          if (!Xt(a.properties.updatedAt)) return n.push({ id: a.id, valid: !1, reason: "updatedAt is not a valid numeric timestamp" }), !1;
        } else a.properties.updatedAt = +/* @__PURE__ */ new Date();
      }
      return this.has(l) ? (n.push({ id: l, valid: !1, reason: `Feature already exists with this id: ${l}` }), !1) : (this.store[l] = a, r.push(l), i && i(a), n.push({ id: l, valid: !0 }), !0);
    }), this.spatialIndex.load(o), this._onChange(r, "create"), n;
  }
  search(t, e) {
    const i = this.spatialIndex.search(t).map((o) => this.store[o]);
    return this.clone(e ? i.filter(e) : i);
  }
  registerOnChange(t) {
    this._onChange = (e, i) => {
      t(e, i);
    };
  }
  getGeometryCopy(t) {
    const e = this.store[t];
    if (!e) throw new Error(`No feature with this id (${t}), can not get geometry copy`);
    return this.clone(e.geometry);
  }
  getPropertiesCopy(t) {
    const e = this.store[t];
    if (!e) throw new Error(`No feature with this id (${t}), can not get properties copy`);
    return this.clone(e.properties);
  }
  updateProperty(t) {
    const e = [];
    t.forEach(({ id: i, property: o, value: r }) => {
      const n = this.store[i];
      if (!n) throw new Error(`No feature with this (${i}), can not update geometry`);
      e.push(i), n.properties[o] = r, this.tracked && (n.properties.updatedAt = +/* @__PURE__ */ new Date());
    }), this._onChange && this._onChange(e, "update");
  }
  updateGeometry(t) {
    const e = [];
    t.forEach(({ id: i, geometry: o }) => {
      e.push(i);
      const r = this.store[i];
      if (!r) throw new Error(`No feature with this (${i}), can not update geometry`);
      r.geometry = this.clone(o), this.spatialIndex.update(r), this.tracked && (r.properties.updatedAt = +/* @__PURE__ */ new Date());
    }), this._onChange && this._onChange(e, "update");
  }
  create(t) {
    const e = [];
    return t.forEach(({ geometry: i, properties: o }) => {
      let r, n = I({}, o);
      this.tracked && (r = +/* @__PURE__ */ new Date(), o ? (n.createdAt = typeof o.createdAt == "number" ? o.createdAt : r, n.updatedAt = typeof o.updatedAt == "number" ? o.updatedAt : r) : n = { createdAt: r, updatedAt: r });
      const a = this.getId(), l = { id: a, type: "Feature", geometry: i, properties: n };
      this.store[a] = l, this.spatialIndex.insert(l), e.push(a);
    }), this._onChange && this._onChange([...e], "create"), e;
  }
  delete(t) {
    t.forEach((e) => {
      if (!this.store[e]) throw new Error("No feature with this id, can not delete");
      delete this.store[e], this.spatialIndex.remove(e);
    }), this._onChange && this._onChange([...t], "delete");
  }
  copy(t) {
    return this.clone(this.store[t]);
  }
  copyAll() {
    return this.clone(Object.keys(this.store).map((t) => this.store[t]));
  }
  copyAllWhere(t) {
    return this.clone(Object.keys(this.store).map((e) => this.store[e]).filter((e) => e.properties && t(e.properties)));
  }
  clear() {
    this.store = {}, this.spatialIndex.clear();
  }
  size() {
    return Object.keys(this.store).length;
  }
}
const Ni = "Feature is not a Polygon or LineString", Gi = "Feature intersects itself", Ai = (s) => s.geometry.type !== "Polygon" && s.geometry.type !== "LineString" ? { valid: !1, reason: Ni } : Bt(s) ? { valid: !1, reason: Gi } : { valid: !0 };
function oe(s, t, e) {
  const i = A(s, t);
  let o = A(t, e) - i;
  return o < 0 && (o += 360), 180 - Math.abs(o - 90 - 90);
}
const Ti = { cancel: "Escape", finish: "Enter" }, Ui = { start: "crosshair", close: "pointer" };
class je extends N {
  constructor(t) {
    super(t, !0), this.mode = "angled-rectangle", this.currentCoordinate = 0, this.currentId = void 0, this.keyEvents = Ti, this.cursors = Ui, this.mouseMove = !1, this.updateOptions(t);
  }
  updateOptions(t) {
    super.updateOptions(t), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors)), (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { cancel: null, finish: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents));
  }
  close() {
    if (this.currentId === void 0) return;
    const t = this.currentId;
    this.currentCoordinate = 0, this.currentId = void 0, this.state === "drawing" && this.setStarted(), this.onFinish(t, { mode: this.mode, action: "draw" });
  }
  start() {
    this.setStarted(), this.setCursor(this.cursors.start);
  }
  stop() {
    this.cleanUp(), this.setStopped(), this.setCursor("unset");
  }
  onMouseMove(t) {
    if (this.mouseMove = !0, this.setCursor(this.cursors.start), this.currentId === void 0 || this.currentCoordinate === 0) return;
    const e = this.store.getGeometryCopy(this.currentId).coordinates[0];
    let i;
    if (this.currentCoordinate === 1) {
      const o = 1 / Math.pow(10, this.coordinatePrecision - 1), r = Math.max(1e-6, o);
      i = [e[0], [t.lng, t.lat], [t.lng, t.lat - r], e[0]];
    } else if (this.currentCoordinate === 2) {
      const o = e[0], r = e[1], n = De(o, r, this.coordinatePrecision, this.project, this.unproject), a = x(o[0], o[1]), l = x(n[0], n[1]), d = x(r[0], r[1]), h = x(t.lng, t.lat), c = E(h, a) < E(h, d), u = oe(a, l, h), p = c ? 90 - u : oe(a, l, h) - 90, g = E(l, h), y = Math.cos(O(p)) * g, m = A(a, d) + (function(S, b, w) {
        const D = (w.x - b.x) * (S.y - b.y) - (w.y - b.y) * (S.x - b.x);
        return D > 1e-10 ? "left" : D < -1e-10 ? "right" : "left";
      }(a, d, h) === "right" ? -90 : 90), v = at(a, y, m), f = at(d, y, m), C = W(v.x, v.y), P = W(f.x, f.y);
      i = [e[0], e[1], [P.lng, P.lat], [C.lng, C.lat], e[0]];
    }
    i && this.updatePolygonGeometry(this.currentId, i, M.Provisional);
  }
  updatePolygonGeometry(t, e, i) {
    const o = { type: "Polygon", coordinates: [e] };
    return !(this.validate && !this.validate({ type: "Feature", geometry: o }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: i }).valid || (this.store.updateGeometry([{ id: t, geometry: o }]), 0));
  }
  onClick(t) {
    if (this.currentCoordinate > 0 && !this.mouseMove && this.onMouseMove(t), this.mouseMove = !1, this.currentCoordinate === 0) {
      const [e] = this.store.create([{ geometry: { type: "Polygon", coordinates: [[[t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat]]] }, properties: { mode: this.mode } }]);
      this.currentId = e, this.currentCoordinate++, this.setDrawing();
    } else if (this.currentCoordinate === 1 && this.currentId) {
      const e = this.store.getGeometryCopy(this.currentId);
      if (Z([t.lng, t.lat], e.coordinates[0][0]) || !this.updatePolygonGeometry(this.currentId, [e.coordinates[0][0], [t.lng, t.lat], [t.lng, t.lat], e.coordinates[0][0]], M.Commit)) return;
      this.currentCoordinate++;
    } else this.currentCoordinate === 2 && this.currentId && this.close();
  }
  onKeyUp(t) {
    if (t.key === this.keyEvents.cancel) this.cleanUp();
    else if (t.key === this.keyEvents.finish) {
      if (this.currentCoordinate < 2) return void this.cleanUp();
      this.close();
    }
  }
  onKeyDown() {
  }
  onDragStart() {
  }
  onDrag() {
  }
  onDragEnd() {
  }
  cleanUp() {
    try {
      this.currentId && this.store.delete([this.currentId]);
    } catch {
    }
    this.currentId = void 0, this.currentCoordinate = 0, this.state === "drawing" && this.setStarted();
  }
  styleFeature(t) {
    const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
    return t.properties.mode === this.mode && t.geometry.type === "Polygon" && (e.polygonFillColor = this.getHexColorStylingValue(this.styles.fillColor, e.polygonFillColor, t), e.polygonOutlineColor = this.getHexColorStylingValue(this.styles.outlineColor, e.polygonOutlineColor, t), e.polygonOutlineWidth = this.getNumericStylingValue(this.styles.outlineWidth, e.polygonOutlineWidth, t), e.polygonFillOpacity = this.getNumericStylingValue(this.styles.fillOpacity, e.polygonFillOpacity, t), e.zIndex = 10), e;
  }
  validateFeature(t) {
    return this.validateModeFeature(t, (e) => lt(e, this.coordinatePrecision));
  }
}
function Ne(s, t, e) {
  return (t.x - s.x) * (e.y - s.y) - (t.y - s.y) * (e.x - s.x) <= 0;
}
const Vi = { cancel: "Escape", finish: "Enter" }, Ri = { start: "crosshair", close: "pointer" };
class Ge extends N {
  constructor(t) {
    super(t, !0), this.mode = "sector", this.currentCoordinate = 0, this.currentId = void 0, this.keyEvents = Vi, this.direction = void 0, this.arcPoints = 64, this.cursors = Ri, this.mouseMove = !1, this.updateOptions(t);
  }
  updateOptions(t) {
    super.updateOptions(t), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors)), (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { cancel: null, finish: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents)), t != null && t.arcPoints && (this.arcPoints = t.arcPoints);
  }
  close() {
    if (this.currentId === void 0) return;
    const t = dt(this.store.getGeometryCopy(this.currentId));
    t && this.store.updateGeometry([{ id: this.currentId, geometry: t }]);
    const e = this.currentId;
    this.currentCoordinate = 0, this.currentId = void 0, this.direction = void 0, this.state === "drawing" && this.setStarted(), this.onFinish(e, { mode: this.mode, action: "draw" });
  }
  start() {
    this.setStarted(), this.setCursor(this.cursors.start);
  }
  stop() {
    this.cleanUp(), this.setStopped(), this.setCursor("unset");
  }
  onMouseMove(t) {
    if (this.mouseMove = !0, this.setCursor(this.cursors.start), this.currentId === void 0 || this.currentCoordinate === 0) return;
    const e = this.store.getGeometryCopy(this.currentId).coordinates[0];
    let i;
    if (this.currentCoordinate === 1) {
      const o = 1 / Math.pow(10, this.coordinatePrecision - 1), r = Math.max(1e-6, o);
      i = [e[0], [t.lng, t.lat], [t.lng, t.lat - r], e[0]];
    } else if (this.currentCoordinate === 2) {
      const o = e[0], r = e[1], n = [t.lng, t.lat], a = x(o[0], o[1]), l = x(r[0], r[1]), d = x(n[0], n[1]);
      if (this.direction === void 0) {
        const C = Ne(a, l, d);
        this.direction = C ? "clockwise" : "anticlockwise";
      }
      const h = E(a, l), c = A(a, l), u = A(a, d), p = this.arcPoints, g = [o], y = Y(c), m = Y(u);
      let v;
      this.direction === "anticlockwise" ? (v = m - y, v < 0 && (v += 360)) : (v = y - m, v < 0 && (v += 360));
      const f = (this.direction === "anticlockwise" ? 1 : -1) * v / p;
      g.push(r);
      for (let C = 0; C <= p; C++) {
        const P = at(a, h, y + C * f), { lng: S, lat: b } = W(P.x, P.y), w = [F(S, this.coordinatePrecision), F(b, this.coordinatePrecision)];
        w[0] !== g[g.length - 1][0] && w[1] !== g[g.length - 1][1] && g.push(w);
      }
      g.push(o), i = [...g];
    }
    i && this.updatePolygonGeometry(this.currentId, i, M.Provisional);
  }
  updatePolygonGeometry(t, e, i) {
    const o = { type: "Polygon", coordinates: [e] };
    return !(this.validate && !this.validate({ type: "Feature", geometry: o }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: i }).valid || (this.store.updateGeometry([{ id: t, geometry: o }]), 0));
  }
  onClick(t) {
    if (this.currentCoordinate > 0 && !this.mouseMove && this.onMouseMove(t), this.mouseMove = !1, this.currentCoordinate === 0) {
      const [e] = this.store.create([{ geometry: { type: "Polygon", coordinates: [[[t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat], [t.lng, t.lat]]] }, properties: { mode: this.mode } }]);
      this.currentId = e, this.currentCoordinate++, this.setDrawing();
    } else if (this.currentCoordinate === 1 && this.currentId) {
      const e = this.store.getGeometryCopy(this.currentId);
      if (Z([t.lng, t.lat], e.coordinates[0][0]) || !this.updatePolygonGeometry(this.currentId, [e.coordinates[0][0], [t.lng, t.lat], [t.lng, t.lat], e.coordinates[0][0]], M.Commit)) return;
      this.currentCoordinate++;
    } else this.currentCoordinate === 2 && this.currentId && this.close();
  }
  onKeyUp(t) {
    t.key === this.keyEvents.cancel ? this.cleanUp() : t.key === this.keyEvents.finish && this.close();
  }
  onKeyDown() {
  }
  onDragStart() {
  }
  onDrag() {
  }
  onDragEnd() {
  }
  cleanUp() {
    try {
      this.currentId && this.store.delete([this.currentId]);
    } catch {
    }
    this.currentId = void 0, this.direction = void 0, this.currentCoordinate = 0, this.state === "drawing" && this.setStarted();
  }
  styleFeature(t) {
    const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
    return t.properties.mode === this.mode && t.geometry.type === "Polygon" && (e.polygonFillColor = this.getHexColorStylingValue(this.styles.fillColor, e.polygonFillColor, t), e.polygonOutlineColor = this.getHexColorStylingValue(this.styles.outlineColor, e.polygonOutlineColor, t), e.polygonOutlineWidth = this.getNumericStylingValue(this.styles.outlineWidth, e.polygonOutlineWidth, t), e.polygonFillOpacity = this.getNumericStylingValue(this.styles.fillOpacity, e.polygonFillOpacity, t), e.zIndex = 10), e;
  }
  validateFeature(t) {
    return this.validateModeFeature(t, (e) => lt(e, this.coordinatePrecision));
  }
}
const zi = { cancel: "Escape", finish: "Enter" }, Xi = { start: "crosshair", close: "pointer" };
class Ae extends N {
  constructor(t) {
    super(t, !0), this.mode = "sensor", this.currentCoordinate = 0, this.currentId = void 0, this.currentInitialArcId = void 0, this.currentStartingPointId = void 0, this.keyEvents = zi, this.direction = void 0, this.arcPoints = 64, this.cursors = Xi, this.mouseMove = !1, this.updateOptions(t);
  }
  updateOptions(t) {
    super.updateOptions(t), t != null && t.cursors && (this.cursors = I({}, this.cursors, t.cursors)), (t == null ? void 0 : t.keyEvents) === null ? this.keyEvents = { cancel: null, finish: null } : t != null && t.keyEvents && (this.keyEvents = I({}, this.keyEvents, t.keyEvents)), t != null && t.arcPoints && (this.arcPoints = t.arcPoints);
  }
  close() {
    if (this.currentStartingPointId === void 0) return;
    const t = this.currentStartingPointId, e = this.currentInitialArcId, i = this.currentId;
    if (t && this.store.delete([t]), e && this.store.delete([e]), this.currentId) {
      const o = dt(this.store.getGeometryCopy(this.currentId));
      o && this.store.updateGeometry([{ id: this.currentId, geometry: o }]);
    }
    this.currentCoordinate = 0, this.currentStartingPointId = void 0, this.currentInitialArcId = void 0, this.currentId = void 0, this.direction = void 0, this.state === "drawing" && this.setStarted(), i && this.onFinish(i, { mode: this.mode, action: "draw" });
  }
  start() {
    this.setStarted(), this.setCursor(this.cursors.start);
  }
  stop() {
    this.cleanUp(), this.setStopped(), this.setCursor("unset");
  }
  onMouseMove(t) {
    if (this.mouseMove = !0, this.setCursor(this.cursors.start), this.currentInitialArcId !== void 0 && this.currentStartingPointId !== void 0 && this.currentCoordinate !== 0) {
      if (this.currentCoordinate === 2) {
        const e = this.store.getGeometryCopy(this.currentInitialArcId).coordinates, i = this.store.getGeometryCopy(this.currentStartingPointId).coordinates, o = e[0], r = [t.lng, t.lat], n = x(o[0], o[1]), a = x(r[0], r[1]), l = x(i[0], i[1]), d = E(l, n);
        if (this.direction === void 0) {
          const f = Ne(l, n, a);
          this.direction = f ? "clockwise" : "anticlockwise";
        }
        const h = A(l, n), c = A(l, a), u = this.arcPoints, p = [o], g = Y(h), y = Y(c);
        let m;
        this.direction === "anticlockwise" ? (m = y - g, m < 0 && (m += 360)) : (m = g - y, m < 0 && (m += 360));
        const v = (this.direction === "anticlockwise" ? 1 : -1) * m / u;
        for (let f = 0; f <= u; f++) {
          const C = at(l, d, g + f * v), { lng: P, lat: S } = W(C.x, C.y), b = [F(P, this.coordinatePrecision), F(S, this.coordinatePrecision)];
          b[0] !== p[p.length - 1][0] && b[1] !== p[p.length - 1][1] && p.push(b);
        }
        this.updateLineStringGeometry(this.currentInitialArcId, p, M.Provisional);
      } else if (this.currentCoordinate === 3) {
        const e = this.store.getGeometryCopy(this.currentInitialArcId).coordinates;
        if (e.length < 2 || !this.direction) return;
        const i = this.store.getGeometryCopy(this.currentStartingPointId).coordinates, o = e[0], r = e[e.length - 1], n = x(t.lng, t.lat), a = x(o[0], o[1]), l = x(r[0], r[1]), d = x(i[0], i[1]), h = E(d, a), c = E(d, n) < h ? a : n, u = A(d, n), p = A(d, a), g = A(d, l), y = Y(p), m = Y(g), v = Y(u);
        if (this.notInSector({ normalizedCursor: v, normalizedStart: y, normalizedEnd: m, direction: this.direction })) return;
        const f = this.getDeltaBearing(this.direction, y, m), C = this.arcPoints, P = (this.direction === "anticlockwise" ? 1 : -1) * f / C, S = E(d, c), b = [];
        for (let w = 0; w <= C; w++) {
          const D = at(d, S, y + w * P), { lng: G, lat: _ } = W(D.x, D.y), j = [F(G, this.coordinatePrecision), F(_, this.coordinatePrecision)];
          j[0] !== e[e.length - 1][0] && j[1] !== e[e.length - 1][1] && b.unshift(j);
        }
        e.push(...b), e.push(e[0]), this.currentId ? this.updatePolygonGeometry(this.currentId, e, M.Provisional) : [this.currentId] = this.store.create([{ geometry: { type: "Polygon", coordinates: [e] }, properties: { mode: this.mode } }]);
      }
    }
  }
  updateLineStringGeometry(t, e, i) {
    const o = { type: "LineString", coordinates: e };
    return !(this.validate && !this.validate({ type: "Feature", geometry: o }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: i }).valid || (this.store.updateGeometry([{ id: t, geometry: o }]), 0));
  }
  updatePolygonGeometry(t, e, i) {
    const o = { type: "Polygon", coordinates: [e] };
    return !(this.validate && !this.validate({ type: "Feature", geometry: o }, { project: this.project, unproject: this.unproject, coordinatePrecision: this.coordinatePrecision, updateType: i }).valid || (this.store.updateGeometry([{ id: t, geometry: o }]), 0));
  }
  onClick(t) {
    if (this.currentCoordinate > 0 && !this.mouseMove && this.onMouseMove(t), this.mouseMove = !1, this.currentCoordinate === 0) {
      const [e] = this.store.create([{ geometry: { type: "Point", coordinates: [t.lng, t.lat] }, properties: { mode: this.mode } }]);
      this.currentStartingPointId = e, this.currentCoordinate++, this.setDrawing();
    } else if (this.currentCoordinate === 1 && this.currentStartingPointId) {
      const [e] = this.store.create([{ geometry: { type: "LineString", coordinates: [[t.lng, t.lat], [t.lng, t.lat]] }, properties: { mode: this.mode } }]);
      this.currentInitialArcId = e, this.currentCoordinate++;
    } else this.currentCoordinate === 2 && this.currentStartingPointId ? this.currentCoordinate++ : this.currentCoordinate === 3 && this.currentStartingPointId && this.close();
  }
  onKeyUp(t) {
    t.key === this.keyEvents.cancel ? this.cleanUp() : t.key === this.keyEvents.finish && this.close();
  }
  onKeyDown() {
  }
  onDragStart() {
  }
  onDrag() {
  }
  onDragEnd() {
  }
  cleanUp() {
    try {
      this.currentStartingPointId && this.store.delete([this.currentStartingPointId]), this.currentInitialArcId && this.store.delete([this.currentInitialArcId]), this.currentId && this.store.delete([this.currentId]);
    } catch {
    }
    this.currentStartingPointId = void 0, this.direction = void 0, this.currentId = void 0, this.currentCoordinate = 0, this.state === "drawing" && this.setStarted();
  }
  styleFeature(t) {
    const e = I({}, { polygonFillColor: "#3f97e0", polygonOutlineColor: "#3f97e0", polygonOutlineWidth: 4, polygonFillOpacity: 0.3, pointColor: "#3f97e0", pointOutlineColor: "#ffffff", pointOutlineWidth: 0, pointWidth: 6, lineStringColor: "#3f97e0", lineStringWidth: 4, zIndex: 0 });
    return t.properties.mode === this.mode && (t.geometry.type === "Polygon" ? (e.polygonFillColor = this.getHexColorStylingValue(this.styles.fillColor, e.polygonFillColor, t), e.polygonOutlineColor = this.getHexColorStylingValue(this.styles.outlineColor, e.polygonOutlineColor, t), e.polygonOutlineWidth = this.getNumericStylingValue(this.styles.outlineWidth, e.polygonOutlineWidth, t), e.polygonFillOpacity = this.getNumericStylingValue(this.styles.fillOpacity, e.polygonFillOpacity, t), e.zIndex = 10) : t.geometry.type === "LineString" ? (e.lineStringColor = this.getHexColorStylingValue(this.styles.outlineColor, e.polygonOutlineColor, t), e.lineStringWidth = this.getNumericStylingValue(this.styles.outlineWidth, e.polygonOutlineWidth, t), e.zIndex = 10) : t.geometry.type === "Point" && (e.pointColor = this.getHexColorStylingValue(this.styles.centerPointColor, e.pointColor, t), e.pointWidth = this.getNumericStylingValue(this.styles.centerPointWidth, e.pointWidth, t), e.pointOutlineColor = this.getHexColorStylingValue(this.styles.centerPointOutlineColor, e.pointOutlineColor, t), e.pointOutlineWidth = this.getNumericStylingValue(this.styles.centerPointOutlineWidth, e.pointOutlineWidth, t), e.zIndex = 20)), e;
  }
  validateFeature(t) {
    return this.validateModeFeature(t, (e) => lt(e, this.coordinatePrecision));
  }
  getDeltaBearing(t, e, i) {
    let o;
    return t === "anticlockwise" ? (o = i - e, o < 0 && (o += 360)) : (o = e - i, o < 0 && (o += 360)), o;
  }
  notInSector({ normalizedCursor: t, normalizedStart: e, normalizedEnd: i, direction: o }) {
    return o === "clockwise" ? e <= i ? t >= e && t <= i : t >= e || t <= i : e >= i ? t <= e && t >= i : t <= e || t >= i;
  }
}
class q {
  constructor({ name: t, callback: e, unregister: i, register: o }) {
    this.name = void 0, this.callback = void 0, this.registered = !1, this.register = void 0, this.unregister = void 0, this.name = t, this.register = () => {
      this.registered || (this.registered = !0, o(e));
    }, this.unregister = () => {
      this.register && (this.registered = !1, i(e));
    }, this.callback = e;
  }
}
var Ki = { __proto__: null, TerraDrawBaseAdapter: class {
  constructor(s) {
    this._minPixelDragDistance = void 0, this._minPixelDragDistanceDrawing = void 0, this._minPixelDragDistanceSelecting = void 0, this._lastDrawEvent = void 0, this._coordinatePrecision = void 0, this._heldKeys = /* @__PURE__ */ new Set(), this._listeners = [], this._dragState = "not-dragging", this._currentModeCallbacks = void 0, this._minPixelDragDistance = typeof s.minPixelDragDistance == "number" ? s.minPixelDragDistance : 1, this._minPixelDragDistanceSelecting = typeof s.minPixelDragDistanceSelecting == "number" ? s.minPixelDragDistanceSelecting : 1, this._minPixelDragDistanceDrawing = typeof s.minPixelDragDistanceDrawing == "number" ? s.minPixelDragDistanceDrawing : 8, this._coordinatePrecision = typeof s.coordinatePrecision == "number" ? s.coordinatePrecision : 9;
  }
  getButton(s) {
    return s.button === -1 ? "neither" : s.button === 0 ? "left" : s.button === 1 ? "middle" : s.button === 2 ? "right" : "neither";
  }
  getMapElementXYPosition(s) {
    const t = this.getMapEventElement(), { left: e, top: i } = t.getBoundingClientRect();
    return { containerX: s.clientX - e, containerY: s.clientY - i };
  }
  getDrawEventFromEvent(s) {
    const t = this.getLngLatFromEvent(s);
    if (!t) return null;
    const { lng: e, lat: i } = t, { containerX: o, containerY: r } = this.getMapElementXYPosition(s), n = this.getButton(s), a = Array.from(this._heldKeys);
    return { lng: F(e, this._coordinatePrecision), lat: F(i, this._coordinatePrecision), containerX: o, containerY: r, button: n, heldKeys: a };
  }
  register(s) {
    this._currentModeCallbacks = s, this._listeners = this.getAdapterListeners(), this._listeners.forEach((t) => {
      t.register();
    });
  }
  getCoordinatePrecision() {
    return this._coordinatePrecision;
  }
  getAdapterListeners() {
    return [new q({ name: "pointerdown", callback: (s) => {
      if (!this._currentModeCallbacks || !s.isPrimary) return;
      const t = this.getDrawEventFromEvent(s);
      t && (this._dragState = "pre-dragging", this._lastDrawEvent = t);
    }, register: (s) => {
      this.getMapEventElement().addEventListener("pointerdown", s);
    }, unregister: (s) => {
      this.getMapEventElement().removeEventListener("pointerdown", s);
    } }), new q({ name: "pointermove", callback: (s) => {
      if (!this._currentModeCallbacks || !s.isPrimary) return;
      s.preventDefault();
      const t = this.getDrawEventFromEvent(s);
      if (t) if (this._dragState === "not-dragging") this._currentModeCallbacks.onMouseMove(t), this._lastDrawEvent = t;
      else if (this._dragState === "pre-dragging") {
        if (!this._lastDrawEvent) return;
        const e = { x: this._lastDrawEvent.containerX, y: this._lastDrawEvent.containerY }, i = { x: t.containerX, y: t.containerY }, o = this._currentModeCallbacks.getState(), r = E(e, i);
        let n = !1;
        if (n = o === "drawing" ? r < this._minPixelDragDistanceDrawing : o === "selecting" ? r < this._minPixelDragDistanceSelecting : r < this._minPixelDragDistance, n) return;
        this._dragState = "dragging", this._currentModeCallbacks.onDragStart(t, (a) => {
          this.setDraggability.bind(this)(a);
        });
      } else this._dragState === "dragging" && this._currentModeCallbacks.onDrag(t, (e) => {
        this.setDraggability.bind(this)(e);
      });
    }, register: (s) => {
      this.getMapEventElement().addEventListener("pointermove", s);
    }, unregister: (s) => {
      this.getMapEventElement().removeEventListener("pointermove", s);
    } }), new q({ name: "contextmenu", callback: (s) => {
      this._currentModeCallbacks && s.preventDefault();
    }, register: (s) => {
      this.getMapEventElement().addEventListener("contextmenu", s);
    }, unregister: (s) => {
      this.getMapEventElement().removeEventListener("contextmenu", s);
    } }), new q({ name: "pointerup", callback: (s) => {
      if (!this._currentModeCallbacks || s.target !== this.getMapEventElement() || !s.isPrimary) return;
      const t = this.getDrawEventFromEvent(s);
      t && (this._dragState === "dragging" ? this._currentModeCallbacks.onDragEnd(t, (e) => {
        this.setDraggability.bind(this)(e);
      }) : this._dragState !== "not-dragging" && this._dragState !== "pre-dragging" || this._currentModeCallbacks.onClick(t), this._dragState = "not-dragging", this.setDraggability(!0));
    }, register: (s) => {
      this.getMapEventElement().addEventListener("pointerup", s);
    }, unregister: (s) => {
      this.getMapEventElement().removeEventListener("pointerup", s);
    } }), new q({ name: "keyup", callback: (s) => {
      this._currentModeCallbacks && (this._heldKeys.delete(s.key), this._currentModeCallbacks.onKeyUp({ key: s.key, heldKeys: Array.from(this._heldKeys), preventDefault: () => s.preventDefault() }));
    }, register: (s) => {
      this.getMapEventElement().addEventListener("keyup", s);
    }, unregister: (s) => {
      this.getMapEventElement().removeEventListener("keyup", s);
    } }), new q({ name: "keydown", callback: (s) => {
      this._currentModeCallbacks && (this._heldKeys.add(s.key), this._currentModeCallbacks.onKeyDown({ key: s.key, heldKeys: Array.from(this._heldKeys), preventDefault: () => s.preventDefault() }));
    }, register: (s) => {
      this.getMapEventElement().addEventListener("keydown", s);
    }, unregister: (s) => {
      this.getMapEventElement().removeEventListener("keydown", s);
    } })];
  }
  unregister() {
    this._listeners.forEach((s) => {
      s.unregister();
    }), this.clear();
  }
} };
class Yi {
  constructor(t) {
    this._modes = void 0, this._mode = void 0, this._adapter = void 0, this._enabled = !1, this._store = void 0, this._eventListeners = void 0, this._instanceSelectMode = void 0, this._adapter = t.adapter, this._mode = new Oi();
    const e = /* @__PURE__ */ new Set(), i = t.modes.reduce((h, c) => {
      if (e.has(c.mode)) throw new Error(`There is already a ${c.mode} mode provided`);
      return e.add(c.mode), h[c.mode] = c, h;
    }, {}), o = Object.keys(i);
    if (o.length === 0) throw new Error("No modes provided");
    o.forEach((h) => {
      if (i[h].type === $.Select) {
        if (this._instanceSelectMode) throw new Error("only one type of select mode can be provided");
        this._instanceSelectMode = h;
      }
    }), this._modes = I({}, i, { static: this._mode }), this._eventListeners = { change: [], select: [], deselect: [], finish: [], ready: [] }, this._store = new ji({ tracked: !!t.tracked, idStrategy: t.idStrategy ? t.idStrategy : void 0 });
    const r = (h) => {
      const c = [], u = this._store.copyAll().filter((p) => !h.includes(p.id) || (c.push(p), !1));
      return { changed: c, unchanged: u };
    }, n = (h, c) => {
      this._enabled && this._eventListeners.finish.forEach((u) => {
        u(h, c);
      });
    }, a = (h, c) => {
      if (!this._enabled) return;
      this._eventListeners.change.forEach((g) => {
        g(h, c);
      });
      const { changed: u, unchanged: p } = r(h);
      c === "create" ? this._adapter.render({ created: u, deletedIds: [], unchanged: p, updated: [] }, this.getModeStyles()) : c === "update" ? this._adapter.render({ created: [], deletedIds: [], unchanged: p, updated: u }, this.getModeStyles()) : c === "delete" ? this._adapter.render({ created: [], deletedIds: h, unchanged: p, updated: [] }, this.getModeStyles()) : c === "styling" && this._adapter.render({ created: [], deletedIds: [], unchanged: p, updated: [] }, this.getModeStyles());
    }, l = (h) => {
      if (!this._enabled) return;
      this._eventListeners.select.forEach((p) => {
        p(h);
      });
      const { changed: c, unchanged: u } = r([h]);
      this._adapter.render({ created: [], deletedIds: [], unchanged: u, updated: c }, this.getModeStyles());
    }, d = (h) => {
      if (!this._enabled) return;
      this._eventListeners.deselect.forEach((p) => {
        p();
      });
      const { changed: c, unchanged: u } = r([h]);
      c && this._adapter.render({ created: [], deletedIds: [], unchanged: u, updated: c }, this.getModeStyles());
    };
    Object.keys(this._modes).forEach((h) => {
      this._modes[h].register({ mode: h, store: this._store, setCursor: this._adapter.setCursor.bind(this._adapter), project: this._adapter.project.bind(this._adapter), unproject: this._adapter.unproject.bind(this._adapter), setDoubleClickToZoom: this._adapter.setDoubleClickToZoom.bind(this._adapter), onChange: a, onSelect: l, onDeselect: d, onFinish: n, coordinatePrecision: this._adapter.getCoordinatePrecision() });
    });
  }
  checkEnabled() {
    if (!this._enabled) throw new Error("Terra Draw is not enabled");
  }
  getModeStyles() {
    const t = {};
    return Object.keys(this._modes).forEach((e) => {
      t[e] = (i) => this._instanceSelectMode && i.properties[V.SELECTED] ? this._modes[this._instanceSelectMode].styleFeature.bind(this._modes[this._instanceSelectMode])(i) : this._modes[e].styleFeature.bind(this._modes[e])(i);
    }), t;
  }
  featuresAtLocation({ lng: t, lat: e }, i) {
    const o = i && i.pointerDistance !== void 0 ? i.pointerDistance : 30, r = !i || i.ignoreSelectFeatures === void 0 || i.ignoreSelectFeatures, n = this._adapter.unproject.bind(this._adapter), a = this._adapter.project.bind(this._adapter), l = a(t, e), d = Se({ unproject: n, point: l, pointerDistance: o });
    return this._store.search(d).filter((h) => {
      if (r && (h.properties[V.MID_POINT] || h.properties[V.SELECTION_POINT])) return !1;
      if (h.geometry.type === "Point") {
        const c = h.geometry.coordinates, u = a(c[0], c[1]);
        return E(l, u) < o;
      }
      if (h.geometry.type === "LineString") {
        const c = h.geometry.coordinates;
        for (let u = 0; u < c.length - 1; u++) {
          const p = c[u], g = c[u + 1];
          if (Le(l, a(p[0], p[1]), a(g[0], g[1])) < o) return !0;
        }
        return !1;
      }
      return !!_e([t, e], h.geometry.coordinates) || void 0;
    });
  }
  getSelectMode() {
    if (this.checkEnabled(), !this._instanceSelectMode) throw new Error("No select mode defined in instance");
    return this.getMode() !== this._instanceSelectMode && this.setMode(this._instanceSelectMode), this._modes[this._instanceSelectMode];
  }
  setModeStyles(t, e) {
    if (this.checkEnabled(), !this._modes[t]) throw new Error("No mode with this name present");
    this._modes[t].styles = e;
  }
  updateModeOptions(t, e) {
    if (this.checkEnabled(), !this._modes[t]) throw new Error("No mode with this name present");
    this._modes[t].updateOptions(e);
  }
  getSnapshot() {
    return this._store.copyAll();
  }
  getSnapshotFeature(t) {
    if (this._store.has(t)) return this._store.copy(t);
  }
  clear() {
    this.checkEnabled(), this._adapter.clear();
  }
  get enabled() {
    return this._enabled;
  }
  set enabled(t) {
    throw new Error("Enabled is read only");
  }
  getMode() {
    return this._mode.mode;
  }
  setMode(t) {
    if (this.checkEnabled(), !this._modes[t]) throw new Error("No mode with this name present");
    this._mode.stop(), this._mode = this._modes[t], this._mode.start();
  }
  removeFeatures(t) {
    this.checkEnabled(), this._store.delete(t);
  }
  selectFeature(t) {
    this.getSelectMode().selectFeature(t);
  }
  deselectFeature(t) {
    this.getSelectMode().deselectFeature(t);
  }
  getFeatureId() {
    return this._store.getId();
  }
  hasFeature(t) {
    return this._store.has(t);
  }
  addFeatures(t) {
    return this.checkEnabled(), t.length === 0 ? [] : this._store.load(t, (e) => {
      if (zt(e)) {
        const i = e.properties.mode, o = this._modes[i];
        if (!o) return { id: e.id, valid: !1, reason: `${i} mode is not in the list of instantiated modes` };
        const r = o.validateFeature.bind(o)(e);
        return { id: e.id, valid: r.valid, reason: r.reason ? r.reason : r.valid ? void 0 : "Feature is invalid" };
      }
      return { id: e.id, valid: !1, reason: "Mode property does not exist" };
    }, (e) => {
      if (zt(e)) {
        const i = this._modes[e.properties.mode];
        i && i.afterFeatureAdded && i.afterFeatureAdded(e);
      }
    });
  }
  start() {
    this._enabled = !0, this._adapter.register({ onReady: () => {
      this._eventListeners.ready.forEach((t) => {
        t();
      });
    }, getState: () => this._mode.state, onClick: (t) => {
      this._mode.onClick(t);
    }, onMouseMove: (t) => {
      this._mode.onMouseMove(t);
    }, onKeyDown: (t) => {
      this._mode.onKeyDown(t);
    }, onKeyUp: (t) => {
      this._mode.onKeyUp(t);
    }, onDragStart: (t, e) => {
      this._mode.onDragStart(t, e);
    }, onDrag: (t, e) => {
      this._mode.onDrag(t, e);
    }, onDragEnd: (t, e) => {
      this._mode.onDragEnd(t, e);
    }, onClear: () => {
      this._mode.cleanUp(), this._store.clear();
    } });
  }
  getFeaturesAtLngLat(t, e) {
    const { lng: i, lat: o } = t;
    return this.featuresAtLocation({ lng: i, lat: o }, e);
  }
  getFeaturesAtPointerEvent(t, e) {
    const i = this._adapter.getLngLatFromEvent.bind(this._adapter)(t);
    return i === null ? [] : this.featuresAtLocation(i, e);
  }
  stop() {
    this._enabled = !1, this._adapter.unregister();
  }
  on(t, e) {
    const i = this._eventListeners[t];
    i.includes(e) || i.push(e);
  }
  off(t, e) {
    const i = this._eventListeners[t];
    i.includes(e) && i.splice(i.indexOf(e), 1);
  }
}
class $i extends Ki.TerraDrawBaseAdapter {
  constructor(t) {
    super(t), this._initialDragPan = void 0, this._initialDragRotate = void 0, this._nextRender = void 0, this._map = void 0, this._container = void 0, this._rendered = !1, this.changedIds = { deletion: !1, points: !1, linestrings: !1, polygons: !1, styling: !1 }, this._map = t.map, this._container = this._map.getContainer(), this._initialDragRotate = this._map.dragRotate.isEnabled(), this._initialDragPan = this._map.dragPan.isEnabled();
  }
  clearLayers() {
    this._rendered && (["point", "linestring", "polygon"].forEach((t) => {
      const e = `td-${t.toLowerCase()}`;
      this._map.removeLayer(e), t === "polygon" && this._map.removeLayer(e + "-outline"), this._map.removeSource(e);
    }), this._rendered = !1, this._nextRender && (cancelAnimationFrame(this._nextRender), this._nextRender = void 0));
  }
  _addGeoJSONSource(t, e) {
    this._map.addSource(t, { type: "geojson", data: { type: "FeatureCollection", features: e }, tolerance: 0 });
  }
  _addFillLayer(t) {
    return this._map.addLayer({ id: t, source: t, type: "fill", paint: { "fill-color": ["get", "polygonFillColor"], "fill-opacity": ["get", "polygonFillOpacity"] } });
  }
  _addFillOutlineLayer(t) {
    return this._map.addLayer({ id: t + "-outline", source: t, type: "line", paint: { "line-width": ["get", "polygonOutlineWidth"], "line-color": ["get", "polygonOutlineColor"] } });
  }
  _addLineLayer(t) {
    return this._map.addLayer({ id: t, source: t, type: "line", paint: { "line-width": ["get", "lineStringWidth"], "line-color": ["get", "lineStringColor"] } });
  }
  _addPointLayer(t) {
    return this._map.addLayer({ id: t, source: t, type: "circle", paint: { "circle-stroke-color": ["get", "pointOutlineColor"], "circle-stroke-width": ["get", "pointOutlineWidth"], "circle-radius": ["get", "pointWidth"], "circle-color": ["get", "pointColor"] } });
  }
  _addLayer(t, e) {
    e === "Point" && this._addPointLayer(t), e === "LineString" && this._addLineLayer(t), e === "Polygon" && (this._addFillLayer(t), this._addFillOutlineLayer(t));
  }
  _addGeoJSONLayer(t, e) {
    const i = `td-${t.toLowerCase()}`;
    return this._addGeoJSONSource(i, e), this._addLayer(i, t), i;
  }
  _setGeoJSONLayerData(t, e) {
    const i = `td-${t.toLowerCase()}`;
    return this._map.getSource(i).setData({ type: "FeatureCollection", features: e }), i;
  }
  updateChangedIds(t) {
    [...t.updated, ...t.created].forEach((e) => {
      e.geometry.type === "Point" ? this.changedIds.points = !0 : e.geometry.type === "LineString" ? this.changedIds.linestrings = !0 : e.geometry.type === "Polygon" && (this.changedIds.polygons = !0);
    }), t.deletedIds.length > 0 && (this.changedIds.deletion = !0), t.created.length === 0 && t.updated.length === 0 && t.deletedIds.length === 0 && (this.changedIds.styling = !0);
  }
  getLngLatFromEvent(t) {
    const { left: e, top: i } = this._container.getBoundingClientRect();
    return this.unproject(t.clientX - e, t.clientY - i);
  }
  getMapEventElement() {
    return this._map.getCanvas();
  }
  setDraggability(t) {
    t ? (this._initialDragRotate && this._map.dragRotate.enable(), this._initialDragPan && this._map.dragPan.enable()) : (this._initialDragRotate && this._map.dragRotate.disable(), this._initialDragPan && this._map.dragPan.disable());
  }
  project(t, e) {
    const { x: i, y: o } = this._map.project({ lng: t, lat: e });
    return { x: i, y: o };
  }
  unproject(t, e) {
    const { lng: i, lat: o } = this._map.unproject({ x: t, y: e });
    return { lng: i, lat: o };
  }
  setCursor(t) {
    const e = this._map.getCanvas();
    t === "unset" ? e.style.removeProperty("cursor") : e.style.cursor = t;
  }
  setDoubleClickToZoom(t) {
    t ? this._map.doubleClickZoom.enable() : this._map.doubleClickZoom.disable();
  }
  render(t, e) {
    this.updateChangedIds(t), this._nextRender && cancelAnimationFrame(this._nextRender), this._nextRender = requestAnimationFrame(() => {
      const i = [...t.created, ...t.updated, ...t.unchanged], o = [], r = [], n = [];
      for (let a = 0; a < i.length; a++) {
        const l = i[a], { properties: d } = l, h = e[d.mode](l);
        l.geometry.type === "Point" ? (d.pointColor = h.pointColor, d.pointOutlineColor = h.pointOutlineColor, d.pointOutlineWidth = h.pointOutlineWidth, d.pointWidth = h.pointWidth, o.push(l)) : l.geometry.type === "LineString" ? (d.lineStringColor = h.lineStringColor, d.lineStringWidth = h.lineStringWidth, r.push(l)) : l.geometry.type === "Polygon" && (d.polygonFillColor = h.polygonFillColor, d.polygonFillOpacity = h.polygonFillOpacity, d.polygonOutlineColor = h.polygonOutlineColor, d.polygonOutlineWidth = h.polygonOutlineWidth, n.push(l));
      }
      if (this._rendered) {
        const a = this.changedIds.deletion || this.changedIds.styling, l = a || this.changedIds.linestrings, d = a || this.changedIds.polygons;
        let h;
        (a || this.changedIds.points) && (h = this._setGeoJSONLayerData("Point", o)), l && this._setGeoJSONLayerData("LineString", r), d && this._setGeoJSONLayerData("Polygon", n), h && this._map.moveLayer(h);
      } else {
        const a = this._addGeoJSONLayer("Point", o);
        this._addGeoJSONLayer("LineString", r), this._addGeoJSONLayer("Polygon", n), this._rendered = !0, a && this._map.moveLayer(a);
      }
      this.changedIds = { points: !1, linestrings: !1, polygons: !1, deletion: !1, styling: !1 };
    });
  }
  clear() {
    this._currentModeCallbacks && (this._currentModeCallbacks.onClear(), this.clearLayers());
  }
  getCoordinatePrecision() {
    return super.getCoordinatePrecision();
  }
  unregister() {
    return super.unregister();
  }
  register(t) {
    var e;
    super.register(t), (e = this._currentModeCallbacks) != null && e.onReady && this._currentModeCallbacks.onReady();
  }
}
const ko = [
  "render",
  "point",
  "linestring",
  "polygon",
  "rectangle",
  "circle",
  "freehand",
  "angled-rectangle",
  "sensor",
  "sector",
  "select",
  "delete-selection",
  "delete",
  "download"
], Hi = {
  modes: [
    "render",
    "point",
    "linestring",
    "polygon",
    "rectangle",
    "angled-rectangle",
    "sensor",
    "sector",
    "circle",
    "freehand",
    "select",
    "delete-selection",
    "delete",
    "download"
  ],
  open: !1
}, yt = {
  modes: [
    "render",
    "point",
    "linestring",
    "polygon",
    "rectangle",
    "angled-rectangle",
    "sensor",
    "sector",
    "circle",
    "freehand",
    "select",
    "delete-selection",
    "delete",
    "download"
  ],
  open: !1,
  // see styling parameters of Terra Draw at https://github.com/JamesLMilner/terra-draw/blob/main/guides/5.STYLING.md
  modeOptions: {
    point: new we({
      editable: !0,
      styles: {
        pointColor: "#FFFFFF",
        pointWidth: 5,
        pointOutlineColor: "#666666",
        pointOutlineWidth: 1
      }
    }),
    linestring: new be({
      editable: !0,
      styles: {
        lineStringColor: "#666666",
        lineStringWidth: 2,
        closingPointColor: "#FFFFFF",
        closingPointWidth: 3,
        closingPointOutlineColor: "#666666",
        closingPointOutlineWidth: 1
      }
    }),
    polygon: new Ee({
      editable: !0,
      styles: {
        fillColor: "#EDEFF0",
        fillOpacity: 0.7,
        outlineColor: "#666666",
        outlineWidth: 2,
        closingPointColor: "#FAFAFA",
        closingPointWidth: 3,
        closingPointOutlineColor: "#666666",
        closingPointOutlineWidth: 1
      }
    }),
    rectangle: new Oe({
      styles: {
        fillColor: "#EDEFF0",
        fillOpacity: 0.7,
        outlineColor: "#666666",
        outlineWidth: 2
      }
    }),
    "angled-rectangle": new je({
      styles: {
        fillColor: "#EDEFF0",
        fillOpacity: 0.7,
        outlineColor: "#666666",
        outlineWidth: 2
      }
    }),
    circle: new Ce({
      styles: {
        fillColor: "#EDEFF0",
        fillOpacity: 0.7,
        outlineColor: "#666666",
        outlineWidth: 2
      }
    }),
    freehand: new Pe({
      styles: {
        fillColor: "#EDEFF0",
        fillOpacity: 0.7,
        outlineColor: "#666666",
        outlineWidth: 2,
        closingPointColor: "#FAFAFA",
        closingPointWidth: 3,
        closingPointOutlineColor: "#666666",
        closingPointOutlineWidth: 1
      }
    }),
    sensor: new Ae({
      styles: {
        fillColor: "#EDEFF0",
        fillOpacity: 0.7,
        outlineColor: "#666666",
        outlineWidth: 2,
        centerPointColor: "#FAFAFA",
        centerPointWidth: 3,
        centerPointOutlineColor: "#666666",
        centerPointOutlineWidth: 1
      }
    }),
    sector: new Ge({
      styles: {
        fillColor: "#EDEFF0",
        fillOpacity: 0.7,
        outlineColor: "#666666",
        outlineWidth: 2
      }
    }),
    select: new Be({
      flags: {
        point: {
          feature: {
            draggable: !1
          }
        },
        polygon: {
          feature: {
            draggable: !0,
            rotateable: !0,
            scaleable: !0,
            coordinates: {
              midpoints: !0,
              draggable: !0,
              deletable: !0
            }
          }
        },
        linestring: {
          feature: {
            draggable: !0,
            rotateable: !0,
            scaleable: !0,
            coordinates: {
              midpoints: !0,
              draggable: !0,
              deletable: !0
            }
          }
        },
        freehand: {
          feature: {
            draggable: !0,
            coordinates: {
              midpoints: !0,
              draggable: !0,
              deletable: !0
            }
          }
        },
        circle: {
          feature: {
            draggable: !0,
            coordinates: {
              midpoints: !0,
              draggable: !0,
              deletable: !0
            }
          }
        },
        rectangle: {
          feature: {
            draggable: !0,
            rotateable: !0,
            scaleable: !0,
            coordinates: {
              midpoints: !0,
              draggable: !0,
              deletable: !0
            }
          }
        },
        "angled-rectangle": {
          feature: {
            draggable: !0,
            rotateable: !0,
            scaleable: !0,
            coordinates: {
              midpoints: !0,
              draggable: !0,
              deletable: !0
            }
          }
        },
        sensor: {
          feature: {
            draggable: !0,
            rotateable: !0,
            scaleable: !0,
            coordinates: {
              midpoints: !0,
              draggable: !0,
              deletable: !0
            }
          }
        },
        sector: {
          feature: {
            draggable: !0,
            rotateable: !0,
            scaleable: !0,
            coordinates: {
              midpoints: !0,
              draggable: !0,
              deletable: !0
            }
          }
        }
      }
    })
  },
  pointLayerLabelSpec: {
    id: "terradraw-measure-point-label",
    type: "symbol",
    source: "terradraw-measure-point-source",
    filter: ["all", ["==", "$type", "Point"], ["==", "mode", "point"]],
    layout: {
      "text-field": [
        "case",
        ["all", ["has", "elevation"], [">", ["get", "elevation"], 0]],
        ["concat", "Alt. ", ["to-string", ["floor", ["get", "elevation"]]], " m"],
        ""
      ],
      "symbol-placement": "point",
      "text-size": [
        "interpolate",
        ["linear"],
        ["zoom"],
        5,
        10,
        10,
        12,
        13,
        14,
        14,
        16,
        18,
        18
      ],
      "text-overlap": "always",
      "text-variable-anchor": ["left", "right", "top", "bottom"],
      "text-radial-offset": 0.5,
      "text-justify": "center",
      "text-letter-spacing": 0.05
    },
    paint: {
      "text-halo-color": "#F7F7F7",
      "text-halo-width": 2,
      "text-color": "#232E3D"
    }
  },
  lineLayerLabelSpec: {
    id: "terradraw-measure-line-label",
    type: "symbol",
    source: "terradraw-measure-line-source",
    filter: ["==", "$type", "Point"],
    layout: {
      "text-field": [
        "concat",
        ["to-string", ["get", "distance"]],
        " ",
        ["get", "unit"],
        [
          "case",
          ["==", ["get", "total"], 0],
          "",
          ["concat", `
(`, ["to-string", ["get", "total"]], " ", ["get", "totalUnit"], ")"]
        ],
        [
          "case",
          ["all", ["has", "elevation"], [">", ["get", "elevation"], 0]],
          ["concat", `
Alt. `, ["to-string", ["floor", ["get", "elevation"]]], " m"],
          ""
        ]
      ],
      "symbol-placement": "point",
      "text-size": [
        "interpolate",
        ["linear"],
        ["zoom"],
        5,
        10,
        10,
        12,
        13,
        14,
        14,
        16,
        18,
        18
      ],
      "text-overlap": "always",
      "text-variable-anchor": ["left", "right", "top", "bottom"],
      "text-radial-offset": 0.5,
      "text-justify": "center",
      "text-letter-spacing": 0.05
    },
    paint: {
      "text-halo-color": "#F7F7F7",
      "text-halo-width": 2,
      "text-color": "#232E3D"
    }
  },
  lineLayerNodeSpec: {
    id: "terradraw-measure-line-node",
    type: "circle",
    source: "terradraw-measure-line-source",
    filter: ["==", "$type", "Point"],
    layout: {},
    paint: {
      "circle-radius": 3,
      "circle-color": "#FFFFFF",
      "circle-stroke-color": "#000000",
      "circle-stroke-width": 1
    }
  },
  polygonLayerSpec: {
    id: "terradraw-measure-polygon-label",
    type: "symbol",
    source: "terradraw-measure-polygon-source",
    filter: ["==", "$type", "Point"],
    layout: {
      "text-field": ["concat", ["to-string", ["get", "area"]], " ", ["get", "unit"]],
      "symbol-placement": "point",
      "text-size": [
        "interpolate",
        ["linear"],
        ["zoom"],
        5,
        10,
        10,
        12,
        13,
        14,
        14,
        16,
        18,
        18
      ],
      "text-overlap": "always",
      "text-letter-spacing": 0.05
    },
    paint: {
      "text-halo-color": "#F7F7F7",
      "text-halo-width": 2,
      "text-color": "#232E3D"
    }
  },
  computeElevation: !1,
  terrainSource: {
    url: "https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png",
    encoding: "terrarium",
    tileSize: 256,
    minzoom: 5,
    maxzoom: 15,
    tms: !1
  },
  distanceUnit: "kilometers",
  distancePrecision: 2,
  areaUnit: "metric",
  areaPrecision: 2
}, qi = () => ({
  render: new et({
    modeName: "render",
    styles: {}
  }),
  point: new we({
    editable: !0
  }),
  linestring: new be({
    editable: !0
  }),
  polygon: new Ee({
    editable: !0,
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    validation: (t, e) => {
      const i = e.updateType;
      return i === "finish" || i === "commit" ? Ai(t) : { valid: !0 };
    }
  }),
  rectangle: new Oe(),
  "angled-rectangle": new je(),
  circle: new Ce(),
  freehand: new Pe(),
  sensor: new Ae(),
  sector: new Ge(),
  select: new Be({
    flags: {
      point: {
        feature: {
          draggable: !0
        }
      },
      polygon: {
        feature: {
          draggable: !0,
          rotateable: !0,
          scaleable: !0,
          coordinates: {
            midpoints: !0,
            draggable: !0,
            deletable: !0
          }
        }
      },
      linestring: {
        feature: {
          draggable: !0,
          rotateable: !0,
          scaleable: !0,
          coordinates: {
            midpoints: !0,
            draggable: !0,
            deletable: !0
          }
        }
      },
      freehand: {
        feature: {
          draggable: !0,
          coordinates: {
            midpoints: !0,
            draggable: !0,
            deletable: !0
          }
        }
      },
      circle: {
        feature: {
          draggable: !0,
          coordinates: {
            midpoints: !0,
            draggable: !0,
            deletable: !0
          }
        }
      },
      rectangle: {
        feature: {
          draggable: !0,
          rotateable: !0,
          scaleable: !0,
          coordinates: {
            midpoints: !0,
            draggable: !0,
            deletable: !0
          }
        }
      },
      "angled-rectangle": {
        feature: {
          draggable: !0,
          rotateable: !0,
          scaleable: !0,
          coordinates: {
            midpoints: !0,
            draggable: !0,
            deletable: !0
          }
        }
      },
      sensor: {
        feature: {
          draggable: !0,
          rotateable: !0,
          scaleable: !0,
          coordinates: {
            midpoints: !0,
            draggable: !0,
            deletable: !0
          }
        }
      },
      sector: {
        feature: {
          draggable: !0,
          rotateable: !0,
          scaleable: !0,
          coordinates: {
            midpoints: !0,
            draggable: !0,
            deletable: !0
          }
        }
      }
    }
  }),
  delete: new et({
    modeName: "delete",
    styles: {}
  }),
  "delete-selection": new et({
    modeName: "delete-selection",
    styles: {}
  }),
  download: new et({
    modeName: "download",
    styles: {}
  })
});
var L = 63710088e-1, Ji = {
  centimeters: L * 100,
  centimetres: L * 100,
  degrees: 360 / (2 * Math.PI),
  feet: L * 3.28084,
  inches: L * 39.37,
  kilometers: L / 1e3,
  kilometres: L / 1e3,
  meters: L,
  metres: L,
  miles: L / 1609.344,
  millimeters: L * 1e3,
  millimetres: L * 1e3,
  nauticalmiles: L / 1852,
  radians: 1,
  yards: L * 1.0936
};
function Zi(s, t, e = {}) {
  const i = { type: "Feature" };
  return (e.id === 0 || e.id) && (i.id = e.id), e.bbox && (i.bbox = e.bbox), i.properties = t || {}, i.geometry = s, i;
}
function Qi(s, t, e = {}) {
  if (!s)
    throw new Error("coordinates is required");
  if (!Array.isArray(s))
    throw new Error("coordinates must be an Array");
  if (s.length < 2)
    throw new Error("coordinates must be at least 2 numbers long");
  if (!se(s[0]) || !se(s[1]))
    throw new Error("coordinates must contain numbers");
  return Zi({
    type: "Point",
    coordinates: s
  }, t, e);
}
function to(s, t = "kilometers") {
  const e = Ji[t];
  if (!e)
    throw new Error(t + " units is invalid");
  return s * e;
}
function gt(s) {
  return s % 360 * Math.PI / 180;
}
function se(s) {
  return !isNaN(s) && s !== null && !Array.isArray(s);
}
function Te(s, t, e) {
  if (s !== null)
    for (var i, o, r, n, a, l, d, h = 0, c = 0, u, p = s.type, g = p === "FeatureCollection", y = p === "Feature", m = g ? s.features.length : 1, v = 0; v < m; v++) {
      d = g ? s.features[v].geometry : y ? s.geometry : s, u = d ? d.type === "GeometryCollection" : !1, a = u ? d.geometries.length : 1;
      for (var f = 0; f < a; f++) {
        var C = 0, P = 0;
        if (n = u ? d.geometries[f] : d, n !== null) {
          l = n.coordinates;
          var S = n.type;
          switch (h = S === "Polygon" || S === "MultiPolygon" ? 1 : 0, S) {
            case null:
              break;
            case "Point":
              if (t(
                l,
                c,
                v,
                C,
                P
              ) === !1)
                return !1;
              c++, C++;
              break;
            case "LineString":
            case "MultiPoint":
              for (i = 0; i < l.length; i++) {
                if (t(
                  l[i],
                  c,
                  v,
                  C,
                  P
                ) === !1)
                  return !1;
                c++, S === "MultiPoint" && C++;
              }
              S === "LineString" && C++;
              break;
            case "Polygon":
            case "MultiLineString":
              for (i = 0; i < l.length; i++) {
                for (o = 0; o < l[i].length - h; o++) {
                  if (t(
                    l[i][o],
                    c,
                    v,
                    C,
                    P
                  ) === !1)
                    return !1;
                  c++;
                }
                S === "MultiLineString" && C++, S === "Polygon" && P++;
              }
              S === "Polygon" && C++;
              break;
            case "MultiPolygon":
              for (i = 0; i < l.length; i++) {
                for (P = 0, o = 0; o < l[i].length; o++) {
                  for (r = 0; r < l[i][o].length - h; r++) {
                    if (t(
                      l[i][o][r],
                      c,
                      v,
                      C,
                      P
                    ) === !1)
                      return !1;
                    c++;
                  }
                  P++;
                }
                C++;
              }
              break;
            case "GeometryCollection":
              for (i = 0; i < n.geometries.length; i++)
                if (Te(n.geometries[i], t) === !1)
                  return !1;
              break;
            default:
              throw new Error("Unknown Geometry Type");
          }
        }
      }
    }
}
function eo(s, t) {
  var e, i, o, r, n, a, l, d, h, c, u = 0, p = s.type === "FeatureCollection", g = s.type === "Feature", y = p ? s.features.length : 1;
  for (e = 0; e < y; e++) {
    for (a = p ? s.features[e].geometry : g ? s.geometry : s, d = p ? s.features[e].properties : g ? s.properties : {}, h = p ? s.features[e].bbox : g ? s.bbox : void 0, c = p ? s.features[e].id : g ? s.id : void 0, l = a ? a.type === "GeometryCollection" : !1, n = l ? a.geometries.length : 1, o = 0; o < n; o++) {
      if (r = l ? a.geometries[o] : a, r === null) {
        if (t(
          null,
          u,
          d,
          h,
          c
        ) === !1)
          return !1;
        continue;
      }
      switch (r.type) {
        case "Point":
        case "LineString":
        case "MultiPoint":
        case "Polygon":
        case "MultiLineString":
        case "MultiPolygon": {
          if (t(
            r,
            u,
            d,
            h,
            c
          ) === !1)
            return !1;
          break;
        }
        case "GeometryCollection": {
          for (i = 0; i < r.geometries.length; i++)
            if (t(
              r.geometries[i],
              u,
              d,
              h,
              c
            ) === !1)
              return !1;
          break;
        }
        default:
          throw new Error("Unknown Geometry Type");
      }
    }
    u++;
  }
}
function io(s, t, e) {
  var i = e;
  return eo(
    s,
    function(o, r, n, a, l) {
      r === 0 && e === void 0 ? i = o : i = t(
        i,
        o,
        r,
        n,
        a,
        l
      );
    }
  ), i;
}
function oo(s) {
  return io(
    s,
    (t, e) => t + so(e),
    0
  );
}
function so(s) {
  let t = 0, e;
  switch (s.type) {
    case "Polygon":
      return re(s.coordinates);
    case "MultiPolygon":
      for (e = 0; e < s.coordinates.length; e++)
        t += re(s.coordinates[e]);
      return t;
    case "Point":
    case "MultiPoint":
    case "LineString":
    case "MultiLineString":
      return 0;
  }
  return 0;
}
function re(s) {
  let t = 0;
  if (s && s.length > 0) {
    t += Math.abs(ne(s[0]));
    for (let e = 1; e < s.length; e++)
      t -= Math.abs(ne(s[e]));
  }
  return t;
}
var ro = L * L / 2, Ot = Math.PI / 180;
function ne(s) {
  const t = s.length - 1;
  if (t <= 2) return 0;
  let e = 0, i = 0;
  for (; i < t; ) {
    const o = s[i], r = s[i + 1 === t ? 0 : i + 1], n = s[i + 2 >= t ? (i + 2) % t : i + 2], a = o[0] * Ot, l = r[1] * Ot, d = n[0] * Ot;
    e += (d - a) * Math.sin(l), i++;
  }
  return e * ro;
}
var no = oo;
const ao = (s, t) => {
  let e = s, i = "m²";
  return t === "metric" ? s >= 1e6 ? (e = s / 1e6, i = "km²") : s >= 1e4 && (e = s / 1e4, i = "ha") : s >= 258998811e-2 ? (e = s / 258998811e-2, i = "mi²") : s >= 4046.856 ? (e = s / 4046.856, i = "acre") : s >= 0.83612736 && (e = s / 0.83612736, i = "yd²"), { area: e, unit: i };
}, ae = (s, t, e) => {
  if (s.geometry.type !== "Polygon") return s;
  const i = no(s.geometry), o = ao(i, t);
  return o.area = parseFloat(o.area.toFixed(e)), s.properties.area = o.area, s.properties.unit = o.unit, s;
};
function le(s) {
  if (!s)
    throw new Error("coord is required");
  if (!Array.isArray(s)) {
    if (s.type === "Feature" && s.geometry !== null && s.geometry.type === "Point")
      return [...s.geometry.coordinates];
    if (s.type === "Point")
      return [...s.coordinates];
  }
  if (Array.isArray(s) && s.length >= 2 && !Array.isArray(s[0]) && !Array.isArray(s[1]))
    return [...s];
  throw new Error("coord must be GeoJSON Point or an Array of numbers");
}
function lo(s, t, e = {}) {
  var i = le(s), o = le(t), r = gt(o[1] - i[1]), n = gt(o[0] - i[0]), a = gt(i[1]), l = gt(o[1]), d = Math.pow(Math.sin(r / 2), 2) + Math.pow(Math.sin(n / 2), 2) * Math.cos(a) * Math.cos(l);
  return to(
    2 * Math.atan2(Math.sqrt(d), Math.sqrt(1 - d)),
    e.units
  );
}
var ho = lo;
const de = (s) => s === "degrees" ? "°" : s === "miles" ? "mi" : s === "radians" ? "rad" : "km", Dt = (s) => {
  if (s >= 1)
    return {
      distance: s,
      unit: "km"
    };
  const t = s * 1e3;
  return t >= 1 ? {
    distance: t,
    unit: "m"
  } : {
    distance: t * 100,
    unit: "cm"
  };
}, he = (s, t, e, i, o, r) => {
  if (s.geometry.type !== "LineString") return s;
  const n = s.geometry.coordinates;
  let a = 0;
  const l = [];
  for (let d = 0; d < n.length - 1; d++) {
    const h = n[d], c = n[d + 1], u = ho(h, c, { units: t });
    a += u;
    const p = JSON.parse(JSON.stringify(s));
    if (p.id = `${p.id}-${d}`, p.geometry.coordinates = [h, c], p.properties.originalId = s.id, p.properties.distance = u, p.properties.total = a, p.properties.unit = de(t), p.properties.totalUnit = de(t), o === !0 && r === void 0) {
      const g = i == null ? void 0 : i.queryTerrainElevation(h);
      g && (p.properties.elevation_start = g);
      const y = i == null ? void 0 : i.queryTerrainElevation(c);
      y && (p.properties.elevation_end = y);
    }
    l.push(p);
  }
  if (s.properties.distance = l[l.length - 1].properties.total, s.properties.unit = l[l.length - 1].properties.unit, s.properties.segments = JSON.parse(JSON.stringify(l)), t === "kilometers") {
    const d = Dt(s.properties.distance);
    s.properties.distance = d.distance, s.properties.unit = d.unit, s.properties.segments.forEach(
      (h) => {
        const c = Dt(h.properties.distance);
        h.properties.distance = c.distance, h.properties.unit = c.unit;
        const u = Dt(h.properties.total);
        h.properties.total = u.distance, h.properties.totalUnit = u.unit;
      }
    );
  }
  return s.properties.distance = parseFloat(
    s.properties.distance.toFixed(e)
  ), s.properties.segments.forEach(
    (d) => {
      d.properties.distance = parseFloat(
        d.properties.distance.toFixed(e)
      ), d.properties.total = parseFloat(
        d.properties.total.toFixed(e)
      );
    }
  ), s;
}, ce = (s) => s.charAt(0).toUpperCase() + s.slice(1), bt = ["td-point", "td-linestring", "td-polygon"];
var ge, ye, fe;
const Bo = [
  ...bt,
  (ge = yt.polygonLayerSpec) == null ? void 0 : ge.source,
  (ye = yt.lineLayerLabelSpec) == null ? void 0 : ye.source,
  (fe = yt.pointLayerLabelSpec) == null ? void 0 : fe.source
], Ue = (s, t, e = bt) => {
  const i = JSON.parse(JSON.stringify(s));
  return t && (t.onlyTerraDrawLayers === !0 ? (i.layers = i.layers.filter((o) => "source" in o && e.includes(o.source)), Object.keys(i.sources).forEach((o) => {
    e.includes(o) || delete i.sources[o];
  })) : t.excludeTerraDrawLayers === !0 && (i.layers = i.layers.filter((o) => "source" in o && !e.includes(o.source)), Object.keys(i.sources).forEach((o) => {
    e.includes(o) && delete i.sources[o];
  }))), i;
}, co = (s, t = 250) => {
  let e;
  return (...i) => {
    clearTimeout(e), e = setTimeout(() => s(...i), t);
  };
}, ue = (s, t, e, i) => {
  if (s.geometry.type !== "Point") return s;
  const o = s.geometry.coordinates;
  if (e === !0 && i === void 0) {
    const r = t == null ? void 0 : t.queryTerrainElevation(o);
    r && (s.properties.elevation = r);
  }
  return s;
};
var uo = Object.defineProperty, po = (s, t, e) => t in s ? uo(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e, tt = (s, t, e) => po(s, typeof t != "symbol" ? t + "" : t, e), St = 2 * Math.PI * 6378137 / 2;
function go(s) {
  return s = s || 256, 2 * Math.PI * 6378137 / s;
}
function yo(s, t, e = { enable: !0, decimal: 1 }) {
  s = Nt(s);
  var i = s[0], o = s[1], r = i * St / 180, n = Math.log(Math.tan((90 + o) * Math.PI / 360)) / (Math.PI / 180);
  return n = n * St / 180, e.enable && (r = Number(r.toFixed(e.decimal)), n = Number(n.toFixed(e.decimal))), [r, n];
}
function fo(s, t, e) {
  var i = s[0], o = s[1], r = xo(t, e), n = (i + St) / r, a = (o + St) / r;
  return [n, a, t];
}
function Ve(s, t, e) {
  s = Nt(s);
  var i = yo(s), o = fo(i, t);
  return vo(o);
}
function mo(s, t, e) {
  if (s = Nt(s), t === 0)
    return [0, 0, 0];
  var i = Ve(s, t);
  return Co(i);
}
function vo(s, t, e) {
  t = t || 256;
  var i = s[0], o = s[1], r = s[2];
  if (r === 0) return [0, 0, 0];
  Re(r);
  var n = Math.ceil(i / t) - 1, a = Math.ceil(o / t) - 1;
  return n < 0 && (n = 0), a < 0 && (a = 0), [n, a, r];
}
function Co(s, t) {
  Po(s);
  var e = s[0], i = s[1], o = s[2];
  if (o === 0)
    return [0, 0, 0];
  var r = e, n = Math.pow(2, o) - 1 - i;
  return [r, n, o];
}
function Po(s, t) {
  var e = s[0], i = s[1], o = s[2];
  if (o == null) throw new Error("<zoom> is required");
  if (e == null) throw new Error("<x> is required");
  if (i == null) throw new Error("<y> is required");
  return o = Re(o), s = So(s), s;
}
function So(s) {
  var t = s[0], e = s[1], i = s[2], o = Math.pow(2, i);
  return t = t % o, t < 0 && (t = t + o), [t, e, i];
}
function Re(s) {
  if (s === !1) return s;
  if (s == null)
    throw new Error("<zoom> is required");
  if (s < 0)
    throw new Error("<zoom> cannot be less than 0");
  if (s > 32)
    throw new Error("<zoom> cannot be greater than 32");
  return s;
}
function Nt(s, t) {
  var e = bo(s[0]), i = Io(s[1]);
  return i > 85 && (i = 85), i < -85 && (i = -85), [e, i];
}
function xo(s, t) {
  return go(t) / Math.pow(2, s);
}
function Io(s) {
  if (s == null) throw new Error("lat is required");
  return (s > 90 || s < -90) && (s = s % 180, s > 90 && (s = -180 + s), s < -90 && (s = 180 + s), s === 0 && (s = 0)), s;
}
function bo(s) {
  if (s == null) throw new Error("lng is required");
  return (s > 180 || s < -180) && (s = s % 360, s > 180 && (s = -360 + s), s < -180 && (s = 360 + s), s === 0 && (s = 0)), s;
}
class ze {
  /**
   * Constructor
   * @param url URL for terrain RGB raster tilesets
   * @param tileSize size of tile. 256 or 512
   * @param tms whether it is Tile Map Service
   * @param minzoom minzoom for terrain RGB raster tilesets
   * @param maxzoom maxzoom for terrain RGB raster tilesets
   * @param tms whether it is Tile Map Service
   */
  constructor(t, e, i, o, r) {
    tt(this, "url"), tt(this, "tileSize"), tt(this, "tms"), tt(this, "minzoom"), tt(this, "maxzoom"), this.url = t, this.tileSize = e, this.tms = r, this.minzoom = i, this.maxzoom = o, this.tms = r;
  }
  /**
   * Get the value from target coordinates and zoom level by using certain formula.
   * @param lnglat coordinates
   * @param z  zoom level
   * @returns the value calculated by certain formula
   */
  getValue(t, e) {
    return new Promise(
      (i, o) => {
        const r = t[0], n = t[1];
        let a = e;
        e > this.maxzoom ? a = this.maxzoom : e < this.minzoom && (a = this.minzoom);
        const l = this.tms ? Ve([r, n], a) : mo([r, n], a), d = this.url.replace(/{x}/g, l[0].toString()).replace(/{y}/g, l[1].toString()).replace(/{z}/g, l[2].toString());
        let h = this.getUrlExtension(d);
        switch (h || (h = "png"), h) {
          case "png":
          case "webp":
            this.getValueFromRaster(d, l, r, n).then((c) => {
              i(c);
            });
            break;
          default:
            o(new Error(`Invalid file extension: ${h}`));
            break;
        }
      }
    );
  }
  /**
   * Get the value calculated from coordinates on WEBP raster tileset
   * @param url tile URL
   * @param tile tile index info
   * @param lng longitude
   * @param lat latitude
   * @returns the value calculated from coordinates. If tile does not exist returns undefined
   */
  async getValueFromRaster(t, e, i, o) {
    const r = await fetch(t);
    if (!r.ok) {
      if (r.status === 404)
        return;
      throw new Error(`Failed to fetch tile: ${r.statusText}`);
    }
    const n = await r.blob();
    return new Promise((a, l) => {
      const d = new Image();
      d.onload = () => {
        const h = document.createElement("canvas");
        h.width = d.width, h.height = d.height;
        const c = h.getContext("2d");
        if (!c) return l(new Error("Failed to create canvas context"));
        c.drawImage(d, 0, 0);
        const u = c.getImageData(0, 0, d.width, d.height).data, p = this.pixels2rgba(new Uint8Array(u), e, i, o), g = this.calc(p[0], p[1], p[2], p[3]);
        a(g);
      }, d.onerror = () => a(void 0), d.src = URL.createObjectURL(n);
    });
  }
  /**
   * Get RGBA values from coordinates information
   * @param pixels pixels info
   * @param tile tile index info
   * @param lng longitude
   * @param lat latitude
   * @returns RGBA values
   */
  pixels2rgba(t, e, i, o) {
    const r = [];
    for (let d = 0; d < t.length; d += 4) {
      const h = t[d], c = t[d + 1], u = t[d + 2], p = t[d + 3], g = [h, c, u, p];
      r.push(g);
    }
    const n = this.tileToBBOX(e), a = this.getPixelPosition(i, o, n), l = a[0] + a[1] * this.tileSize;
    return r[l];
  }
  /**
   * Get the position in pixel from the coordinates
   * @param lng longitude
   * @param lat latitude
   * @param bbox bbox (minx, miny, maxx, maxy)
   * @returns The position in pixel
   */
  getPixelPosition(t, e, i) {
    const o = this.tileSize, r = this.tileSize, n = i[2] - i[0], a = i[3] - i[1], l = (t - i[0]) / n, d = (e - i[1]) / a, h = Math.floor(o * l), c = Math.floor(r * (1 - d));
    return [h, c];
  }
  /**
   * Get file extenstion name from the URL
   * @param url URL for tilesets
   * @returns file extenstion either png or webp
   */
  getUrlExtension(t) {
    let e = t.split(/[#?]/)[0].split(".").pop();
    return e && (e = e.trim()), e;
  }
  /**
   * Get the bbox of a tile
   * @param {Array<number>} tile
   * @returns {Array<number>} bbox
   * @example
   * var bbox = tileToBBOX([5, 10, 10])
   * //=bbox
   */
  tileToBBOX(t) {
    const e = this.tile2lon(t[0] + 1, t[2]), i = this.tile2lon(t[0], t[2]), o = this.tile2lat(t[1] + 1, t[2]), r = this.tile2lat(t[1], t[2]);
    return [i, o, e, r];
  }
  tile2lon(t, e) {
    return t / Math.pow(2, e) * 360 - 180;
  }
  tile2lat(t, e) {
    const i = 180 / Math.PI, o = Math.PI - 2 * Math.PI * t / Math.pow(2, e);
    return i * Math.atan(0.5 * (Math.exp(o) - Math.exp(-o)));
  }
}
class Mo extends ze {
  /**
   * Constructor
   * @param url URL for terrain RGB raster tilesets
   * @param tileSize size of tile. 256 or 512
   * @param tms whether it is Tile Map Service
   * @param minzoom minzoom for terrain RGB raster tilesets. default is 5
   * @param maxzoom maxzoom for terrain RGB raster tilesets. default is 15
   */
  constructor(t, e, i = 5, o = 15, r = !1) {
    super(t, e, i, o, r);
  }
  /**
   * Get an altitude calculated from terrain RGB information
   * @param lnglat coordinates
   * @param z zoom level
   * @returns an altitude calculated from terrain RGB information
   */
  async getElevation(t, e) {
    return await this.getValue(t, e);
  }
  /**
   * Formula for calculating an elevation from RGB
   * @param r red
   * @param g green
   * @param b blue
   * @returns an elevation calculated
   */
  calc(t, e, i) {
    return -1e4 + (t * 256 * 256 + e * 256 + i) * 0.1;
  }
}
class wo extends ze {
  /**
   * Constructor
   * @param url URL for terrarium raster tilesets
   * @param tileSize size of tile. 256 or 512
   * @param tms whether it is Tile Map Service
   * @param minzoom minzoom for terrain RGB raster tilesets. default is 5
   * @param maxzoom maxzoom for terrain RGB raster tilesets. default is 15
   */
  constructor(t, e, i = 5, o = 15, r = !1) {
    super(t, e, i, o, r);
  }
  /**
   * Get an altitude calculated from terrain RGB information
   * @param lnglat coordinates
   * @param z zoom level
   * @returns an altitude calculated from terrain RGB information
   */
  async getElevation(t, e) {
    return await this.getValue(t, e);
  }
  /**
   * Formula for calculating an elevation from RGB
   * https://github.com/tilezen/joerd/blob/master/docs/formats.md#terrarium
   * @param r red
   * @param g green
   * @param b blue
   * @returns an elevation calculated
   */
  calc(t, e, i) {
    const o = t * 256 + e + i / 256 - 32768;
    return parseInt(o.toFixed(0));
  }
}
const pe = async (s, t) => {
  const e = [];
  for (const i of s)
    e.push(
      new Promise((o) => {
        if (i.geometry.type !== "Point" && o(i), t) {
          const r = t.url, n = t.encoding ?? "mapbox", a = t.tileSize ?? 512, l = t.minzoom ?? 5, d = t.maxzoom ?? 15, h = t.tms ?? !1;
          (n === "mapbox" ? new Mo(r, a, l, d, h) : new wo(r, a, l, d, h)).getElevation(i.geometry.coordinates, d).then((c) => {
            c && (i.properties.elevation = c), o(i);
          }).catch(() => o(i));
        } else
          o(i);
      })
    );
  return await Promise.all(e);
}, Wo = (s, t = 9) => {
  function e(o) {
    return [Number(o[0].toFixed(t)), Number(o[1].toFixed(t))];
  }
  function i(o) {
    const r = o.type;
    let n = o.coordinates;
    switch (r) {
      case "Point":
        n = e(n);
        break;
      case "LineString":
      case "MultiPoint":
        n = n.map(e);
        break;
      case "Polygon":
      case "MultiLineString":
        n = n.map((a) => a.map(e));
        break;
      case "MultiPolygon":
        n = n.map(
          (a) => a.map((l) => l.map(e))
        );
        break;
    }
    return {
      ...o,
      coordinates: n
    };
  }
  return s.map((o) => ({
    ...o,
    geometry: i(o.geometry)
  }));
};
class Fo {
  /**
   * Constructor
   * @param options Plugin control options
   */
  constructor(t) {
    B(this, "controlContainer");
    B(this, "map");
    B(this, "modeButtons", {});
    B(this, "_isExpanded", !1);
    B(this, "terradraw");
    B(this, "options", Hi);
    B(this, "events", {});
    B(this, "defaultMode", "render");
    this.modeButtons = {}, t && (this.options = Object.assign(this.options, t));
  }
  /**
   * get the state of whether the control is expanded or collapsed
   */
  get isExpanded() {
    return this._isExpanded;
  }
  /**
   * set the state of the control either expanded or collapsed.
   * terradraw mode will be reset if the state is changed.
   * either `expanded` or `collapsed` event is dispatched when changed
   */
  set isExpanded(t) {
    var o, r;
    this._isExpanded = t;
    const e = document.getElementsByClassName("maplibregl-terradraw-add-control");
    for (let n = 0; n < e.length; n++) {
      const a = e.item(n);
      a && (this.isExpanded ? a.classList.remove("hidden") : a.classList.add("hidden"));
    }
    const i = document.getElementsByClassName("maplibregl-terradraw-render-button");
    i && i.length > 0 && (this.isExpanded ? (o = i.item(0)) == null || o.classList.add("enabled") : ((r = i.item(0)) == null || r.classList.remove("enabled"), this.resetActiveMode())), this.toggleDeleteSelectionButton(), this.toggleButtonsWhenNoFeature(), this.isExpanded ? this.dispatchEvent("expanded") : this.dispatchEvent("collapsed");
  }
  /**
   * Get the default control position
   * @returns default control position. Default is 'top-right'
   */
  getDefaultPosition() {
    return "top-right";
  }
  /**
   * add the plugin control to maplibre
   * @param map Maplibre Map object
   * @returns HTML Element
   */
  onAdd(t) {
    var o, r, n, a, l;
    if (this.options && this.options.modes && this.options.modes.length === 0)
      throw new Error("At least a mode must be enabled.");
    this.map = t;
    const e = qi(), i = [];
    return (r = (o = this.options) == null ? void 0 : o.modes) == null || r.forEach((d) => {
      if (this.options.modeOptions && this.options.modeOptions[d]) {
        const h = this.options.modeOptions[d];
        if (d === "select") {
          const c = e[d];
          if (c) {
            const u = c.flags;
            Object.keys(u).forEach((p) => {
              h.flags[p] || (h.flags[p] = u[p]);
            });
          }
        }
        i.push(h);
      } else e[d] && i.push(e[d]);
    }), i.forEach((d) => {
      d.state !== "unregistered" && (d._state = "unregistered");
    }), (a = (n = this.options) == null ? void 0 : n.modes) != null && a.includes("render") || (i.push(
      new et({
        modeName: "default",
        styles: {}
      })
    ), this.defaultMode = "default"), this.isExpanded = this.options.open === !0, this.terradraw = new Yi({
      adapter: new $i({ map: t, ...this.options.adapterOptions }),
      modes: i
    }), this.terradraw.start(), this.controlContainer = document.createElement("div"), this.controlContainer.classList.add("maplibregl-ctrl"), this.controlContainer.classList.add("maplibregl-ctrl-group"), i.forEach((d) => {
      d.mode !== "default" && this.addTerradrawButton(d.mode);
    }), Object.values(this.modeButtons).forEach((d) => {
      var h;
      (h = this.controlContainer) == null || h.appendChild(d);
    }), (l = this.terradraw) == null || l.on("change", this.toggleButtonsWhenNoFeature.bind(this)), this.toggleButtonsWhenNoFeature(), this.controlContainer;
  }
  /**
   * Remove the plugin control from maplibre
   * @returns void
   */
  onRemove() {
    !this.controlContainer || !this.controlContainer.parentNode || !this.map || (this.deactivate(), this.modeButtons = {}, this.terradraw = void 0, this.map = void 0, this.controlContainer.parentNode.removeChild(this.controlContainer));
  }
  /**
   * Register an event for the plugin
   * @param event event type
   * @param callback
   */
  on(t, e) {
    this.events[t] ? this.events[t].push(e) : this.events[t] = [e];
  }
  /**
   * Unregister an event for the plugin
   * @param event event type
   * @param callback
   * @returns
   */
  off(t, e) {
    if (!this.events[t]) return;
    const i = this.events[t].findIndex((o) => o === e);
    i !== -1 && this.events[t].splice(i, 1);
  }
  /**
   * Dispatch an event. Pass the current snapshot of features and mode
   * @param event event type
   * @param args additional arguments
   */
  dispatchEvent(t, e) {
    this.events[t] && this.events[t].forEach((i) => {
      var n, a;
      const o = (n = this.terradraw) == null ? void 0 : n.getSnapshot(), r = o == null ? void 0 : o.filter((l) => l.properties.selected === !0);
      i({
        feature: r,
        mode: (a = this.terradraw) == null ? void 0 : a.getMode(),
        ...e
      });
    });
  }
  /**
   * Activate Terra Draw to start drawing
   */
  activate() {
    this.terradraw && (this.terradraw.enabled || (this.terradraw.start(), this.dispatchEvent("mode-changed")));
  }
  /**
   * Deactivate Terra Draw to stop drawing
   */
  deactivate() {
    this.terradraw && this.terradraw.enabled && (this.resetActiveMode(), this.dispatchEvent("mode-changed"), this.terradraw.stop());
  }
  /**
   * Get the Terra Draw instance.
   * For the Terra Draw API, please refer to https://terradraw.io/#/api
   * @returns Terra Draw instance
   */
  getTerraDrawInstance() {
    return this.terradraw;
  }
  /**
   * Toggle editor control
   */
  toggleEditor() {
    this.terradraw && (this.isExpanded = !this.isExpanded);
  }
  /**
   * Reset active mode to back to render mode
   */
  resetActiveMode() {
    var e;
    if (!this.terradraw) return;
    this.terradraw.enabled || this.terradraw.start();
    const t = document.getElementsByClassName("maplibregl-terradraw-add-control");
    for (let i = 0; i < t.length; i++) {
      const o = t.item(i);
      o && o.classList.remove("active");
    }
    (e = this.terradraw) == null || e.setMode(this.defaultMode);
  }
  /**
   * Add Terra Draw drawing mode button
   * @param mode Terra Draw mode name
   */
  addTerradrawButton(t) {
    const e = document.createElement("button");
    e.type = "button", this.modeButtons[t] = e, t === "render" ? (e.classList.add(`maplibregl-terradraw-${t}-button`), this.isExpanded && e.classList.add("enabled"), e.type = "button", e.title = ce("expand or collapse drawing tool"), e.addEventListener("click", this.toggleEditor.bind(this))) : (e.classList.add("maplibregl-terradraw-add-control"), this.isExpanded || e.classList.add("hidden"), e.title = ce(t.replace(/-/g, " ")), t === "delete" ? (e.classList.add(`maplibregl-terradraw-${t}-button`), e.addEventListener("click", () => {
      this.terradraw && this.terradraw.enabled && (this.terradraw.clear(), this.deactivate(), this.toggleDeleteSelectionButton(), this.toggleButtonsWhenNoFeature(), this.dispatchEvent("feature-deleted"));
    })) : t === "delete-selection" ? (e.classList.add(`maplibregl-terradraw-${t}-button`), e.classList.add("hidden-delete-selection"), e.addEventListener("click", () => {
      var r;
      if (!this.terradraw || !this.terradraw.enabled) return;
      const o = ((r = this.terradraw) == null ? void 0 : r.getSnapshot()).filter((n) => n.properties.selected === !0);
      if (o.length > 0) {
        const n = o.map((a) => a.id);
        this.terradraw.removeFeatures(n);
        for (const a of n)
          this.terradraw.deselectFeature(a);
        this.dispatchEvent("feature-deleted", { deletedIds: n });
      }
      this.toggleDeleteSelectionButton(), this.toggleButtonsWhenNoFeature();
    })) : t === "download" ? (e.classList.add(`maplibregl-terradraw-${t}-button`), e.addEventListener("click", this.handleDownload.bind(this))) : (e.classList.add(`maplibregl-terradraw-add-${t}-button`), e.addEventListener("click", () => {
      if (!this.terradraw) return;
      const i = e.classList.contains("active");
      this.activate(), this.resetActiveMode(), i || (this.terradraw.setMode(t), e.classList.add("active")), this.toggleDeleteSelectionButton(), this.toggleButtonsWhenNoFeature();
    })));
  }
  /**
   * get GeoJSON features
   * @param onlySelected If true, returns only selected features. Default is false.
   * @returns FeatureCollection in GeoJSON format
   */
  getFeatures(t = !1) {
    var r;
    if (!this.terradraw) return;
    const o = {
      type: "FeatureCollection",
      features: ((r = this.terradraw) == null ? void 0 : r.getSnapshot()).filter((n) => n.properties.mode !== "select")
    };
    return t !== !0 || (o.features = o.features.filter((n) => n.properties.selected === !0)), o;
  }
  /**
   * clean maplibre style to filter only for terradraw related layers or without them.
   * If options are not set, returns original style given to the function.
   *
   * This can be useful incase users only want to get terradraw related layers or without it.
   *
   * Usage:
   * `cleanStyle(map.getStyle, { excludeTerraDrawLayers: true})`
   * `cleanStyle(map.getStyle, { onlyTerraDrawLayers: true})`
   *
   * @param style maplibre style spec
   * @param options.excludeTerraDrawLayers return maplibre style without terradraw layers and sources
   * @param options.onlyTerraDrawLayers return maplibre style with only terradraw layers and sources
   * @returns
   */
  cleanStyle(t, e) {
    return Ue(t, e, bt);
  }
  /**
   * Download button click event handler
   */
  handleDownload() {
    const t = this.getFeatures(!1), e = "data:application/json;charset=utf-8," + encodeURIComponent(JSON.stringify(t)), i = document.createElement("a");
    i.setAttribute("href", e), i.setAttribute("download", "data.geojson"), document.body.appendChild(i), i.click(), i.remove();
  }
  /**
   * Toggle the state of buttons when there is no features
   */
  toggleButtonsWhenNoFeature() {
    if (!this.controlContainer) return;
    const t = this.getFeatures(!1), e = !!(t && t.features.length > 0), i = [
      "maplibregl-terradraw-add-select-button",
      "maplibregl-terradraw-download-button",
      "maplibregl-terradraw-delete-button"
    ];
    for (const o of i) {
      const r = this.controlContainer.getElementsByClassName(o);
      for (let n = 0; n < r.length; n++) {
        const a = r.item(n);
        a && (a.disabled = !e);
      }
    }
  }
  /**
   * Toggle the state of delete-select button
   */
  toggleDeleteSelectionButton() {
    var a, l;
    const t = ((a = this.terradraw) == null ? void 0 : a.enabled) || !1, e = (l = this.terradraw) == null ? void 0 : l.getMode(), i = this.getFeatures(!1), o = i && i.features.length > 0, r = o && t && e === "select", n = document.getElementsByClassName("maplibregl-terradraw-delete-selection-button");
    for (let d = 0; d < n.length; d++) {
      const h = n.item(d);
      h && (r ? h.classList.remove("hidden-delete-selection") : h.classList.add("hidden-delete-selection"));
    }
    if (!o) {
      const d = document.getElementsByClassName("maplibregl-terradraw-add-select-button");
      for (let h = 0; h < d.length; h++) {
        const c = d.item(h);
        c && c.classList.remove("active");
      }
    }
  }
}
function Eo(s, t = {}) {
  let e = 0, i = 0, o = 0;
  return Te(
    s,
    function(r) {
      e += r[0], i += r[1], o++;
    }
  ), Qi([e / o, i / o], t.properties);
}
class jo extends Fo {
  /**
   * Constructor
   * @param options Plugin control options
   */
  constructor(e) {
    let i = yt;
    e && (i = Object.assign(i, e));
    super({
      modes: i.modes,
      open: i.open,
      modeOptions: i.modeOptions
    });
    B(this, "measureOptions");
    /**
     * Handle deselect event of terradraw
     */
    B(this, "handleTerradrawDeselect", () => {
      if (this.map && this.computeElevation === !0 && this.measureOptions.terrainSource !== void 0) {
        const e = this.getTerraDrawInstance();
        if (!e) return;
        const i = e.getSnapshot(), o = i.filter(
          (n) => n.properties.mode === "linestring" && n.geometry.type === "LineString"
        );
        if (o.length > 0)
          for (const n of o)
            this.computeElevationByLineFeatureID(n.id);
        const r = i.filter(
          (n) => n.properties.mode === "point" && n.geometry.type === "Point"
        );
        if (r.length > 0)
          for (const n of r)
            this.computeElevationByPointFeatureID(n.id);
      }
    });
    /**
     * Handle finish event of terradraw. It will be called after finishing adding a feature
     * @param id Feature ID
     */
    B(this, "handleTerradrawFeatureReady", co((e) => {
      this.map && (this.computeElevationByLineFeatureID(e), this.computeElevationByPointFeatureID(e));
    }, 300));
    /**
     * Compute elevation by a LineString feature ID
     * @param id FeatureID
     */
    B(this, "computeElevationByLineFeatureID", async (e) => {
      if (this.map && this.computeElevation === !0) {
        const i = this.map.getStyle().sources[this.measureOptions.lineLayerLabelSpec.source];
        if (i && typeof i.data != "string" && i.data.type === "FeatureCollection") {
          const o = i.data.features.filter(
            (r) => {
              var n;
              return ((n = r.properties) == null ? void 0 : n.originalId) === e && r.geometry.type === "Point";
            }
          );
          if (o && o.length > 0) {
            const r = await pe(
              o,
              this.measureOptions.terrainSource
            );
            this.replaceGeoJSONSource(
              r,
              this.measureOptions.lineLayerLabelSpec.source,
              "linestring"
            );
          }
        }
      }
    });
    /**
     * Compute elevation by a Point feature ID
     * @param id FeatureID
     */
    B(this, "computeElevationByPointFeatureID", async (e) => {
      if (this.map && this.computeElevation === !0) {
        const i = this.map.getStyle().sources[this.measureOptions.pointLayerLabelSpec.source];
        if (i && typeof i.data != "string" && i.data.type === "FeatureCollection") {
          const o = i.data.features.filter(
            (r) => {
              var n;
              return r.id === e && r.geometry.type === "Point" && ((n = r.properties) == null ? void 0 : n.mode) === "point";
            }
          );
          if (o && o.length > 0) {
            const r = await pe(
              o,
              this.measureOptions.terrainSource
            );
            this.replaceGeoJSONSource(
              r,
              this.measureOptions.pointLayerLabelSpec.source,
              "point"
            );
          }
        }
      }
    });
    this.measureOptions = i;
  }
  /**
   * The unit of distance can be degrees, radians, miles, or kilometers (default 'kilometers')
   * The measuring result will be recalculated once new value is set
   */
  get distanceUnit() {
    return this.measureOptions.distanceUnit ?? "kilometers";
  }
  set distanceUnit(e) {
    const i = this.measureOptions.distanceUnit === e;
    this.measureOptions.distanceUnit = e, this.measureOptions.distanceUnit === "degrees" ? this.distancePrecision = 6 : this.distancePrecision = 2, i || this.recalc();
  }
  /**
   * The precision of distance value. It will be set different value dwhen distance unit is changed. Using setter to override the value if you want.
   */
  get distancePrecision() {
    return this.measureOptions.distancePrecision ?? 2;
  }
  set distancePrecision(e) {
    const i = this.measureOptions.distancePrecision === e;
    this.measureOptions.distancePrecision = e, i || this.recalc();
  }
  /**
   * The unit of area can be metric (m², ha, km²) or imperial (yd², acre, mi²). Default is metric.
   * The measuring result will be recalculated once new value is set
   */
  get areaUnit() {
    return this.measureOptions.areaUnit ?? "metric";
  }
  set areaUnit(e) {
    const i = this.measureOptions.areaUnit === e;
    this.measureOptions.areaUnit = e, i || this.recalc();
  }
  /**
   * The precision of area value. Using setter to override the value if you want.
   */
  get areaPrecision() {
    return this.measureOptions.areaPrecision ?? 2;
  }
  set areaPrecision(e) {
    const i = this.measureOptions.areaPrecision === e;
    this.measureOptions.areaPrecision = e, i || this.recalc();
  }
  /**
   * The flag of whether computing elevation. Default is false.
   * Using setter to override the value if you want.
   */
  get computeElevation() {
    return this.measureOptions.computeElevation ?? !1;
  }
  set computeElevation(e) {
    const i = this.measureOptions.computeElevation === e;
    this.measureOptions.computeElevation = e, i || this.recalc();
  }
  /**
   * add the plugin control to maplibre
   * @param map Maplibre Map object
   * @returns HTML Element
   */
  onAdd(e) {
    return this.controlContainer = super.onAdd(e), this.controlContainer;
  }
  /**
   * Remove the plugin control from maplibre
   * @returns void
   */
  onRemove() {
    this.unregisterMesureControl(), super.onRemove();
  }
  /**
   * Activate Terra Draw to start drawing
   */
  activate() {
    super.activate(), this.registerMesureControl();
  }
  /**
   * Recalculate area and distance in TerraDraw snapshot
   *
   * if you use `addFeatures` to restore GeoJSON features to TerraDraw, this recalc method needs to be called to re-measure again.
   *
   * For example, the below code is an example usage.
   * ```
   * drawInstance?.addFeatures(initData);
   * map?.once('idle', ()=>{
   *   drawControl.recalc()
   * })
   * ```
   */
  recalc() {
    const e = this.getTerraDrawInstance();
    if (e) {
      this.registerMesureControl();
      const i = e.getSnapshot();
      for (const o of i) {
        const r = o.id, n = o.geometry.type, a = o.properties.mode;
        a === "linestring" && n === "LineString" ? (this.measureLine(r), this.computeElevationByLineFeatureID(r)) : a === "point" && n === "Point" ? (this.measurePoint(r), this.computeElevationByPointFeatureID(r)) : !["point", "linestring", "select", "render"].includes(a) && n === "Polygon" && this.measurePolygon(r);
      }
    }
  }
  /**
   * clean maplibre style to filter only for terradraw related layers or without them.
   * If options are not set, returns original style given to the function.
   *
   * This can be useful incase users only want to get terradraw related layers or without it.
   *
   * Usage:
   * `cleanStyle(map.getStyle, { excludeTerraDrawLayers: true})`
   * `cleanStyle(map.getStyle, { onlyTerraDrawLayers: true})`
   *
   * @param style maplibre style spec
   * @param options.excludeTerraDrawLayers return maplibre style without terradraw layers and sources
   * @param options.onlyTerraDrawLayers return maplibre style with only terradraw layers and sources
   * @returns
   */
  cleanStyle(e, i) {
    var l, d, h;
    const o = bt, r = (l = this.measureOptions.polygonLayerSpec) == null ? void 0 : l.source;
    r && o.push(r);
    const n = (d = this.measureOptions.lineLayerLabelSpec) == null ? void 0 : d.source;
    n && o.push(n);
    const a = (h = this.measureOptions.pointLayerLabelSpec) == null ? void 0 : h.source;
    return a && o.push(a), Ue(e, i, o);
  }
  /**
   * Register  measure control related maplibre sources and layers
   */
  registerMesureControl() {
    var r, n, a;
    if (!this.map) return;
    const e = (r = this.options.modes) == null ? void 0 : r.filter((l) => ["linestring"].includes(l));
    ((n = this.options.modes) == null ? void 0 : n.find((l) => l === "point")) && (this.map.getSource(
      this.measureOptions.pointLayerLabelSpec.source
    ) || this.map.addSource(
      this.measureOptions.pointLayerLabelSpec.source,
      {
        type: "geojson",
        data: { type: "FeatureCollection", features: [] }
      }
    ), this.map.getLayer(this.measureOptions.pointLayerLabelSpec.id) || this.map.addLayer(this.measureOptions.pointLayerLabelSpec)), e && e.length > 0 && (this.map.getSource(
      this.measureOptions.lineLayerLabelSpec.source
    ) || this.map.addSource(
      this.measureOptions.lineLayerLabelSpec.source,
      {
        type: "geojson",
        data: { type: "FeatureCollection", features: [] }
      }
    ), this.map.getLayer(this.measureOptions.lineLayerNodeSpec.id) || this.map.addLayer(this.measureOptions.lineLayerNodeSpec), this.map.getLayer(this.measureOptions.lineLayerLabelSpec.id) || this.map.addLayer(this.measureOptions.lineLayerLabelSpec));
    const o = (a = this.options.modes) == null ? void 0 : a.filter(
      (l) => [
        "polygon",
        "rectangle",
        "angled-rectangle",
        "circle",
        "sector",
        "sensor",
        "freehand"
      ].includes(l)
    );
    if (o && o.length > 0 && (this.map.getSource(
      this.measureOptions.polygonLayerSpec.source
    ) || this.map.addSource(
      this.measureOptions.polygonLayerSpec.source,
      {
        type: "geojson",
        data: { type: "FeatureCollection", features: [] }
      }
    ), this.map.getLayer(this.measureOptions.polygonLayerSpec.id) || this.map.addLayer(this.measureOptions.polygonLayerSpec)), e && e.length > 0 || o && o.length > 0) {
      const l = this.getTerraDrawInstance();
      l && (l.on("change", this.handleTerradrawFeatureChanged.bind(this)), l.on("finish", this.handleTerradrawFeatureReady.bind(this)), l.on("deselect", this.handleTerradrawDeselect.bind(this)), this.on("feature-deleted", this.onFeatureDeleted.bind(this)));
    }
  }
  /**
   * Handle change event of TerraDraw
   * @param ids Feature IDs
   */
  handleTerradrawFeatureChanged(e, i) {
    if (!this.map || i === "styling") return;
    const r = [
      this.measureOptions.pointLayerLabelSpec,
      this.measureOptions.lineLayerLabelSpec,
      this.measureOptions.lineLayerNodeSpec,
      this.measureOptions.polygonLayerSpec
    ].map((l) => l.source);
    if (i === "delete") {
      this.clearMeasureFeatures(r, e);
      return;
    }
    const n = this.getTerraDrawInstance();
    if (!n) return;
    const a = n.getSnapshot();
    for (const l of e) {
      const d = a.find((h) => h.id === l);
      if (d) {
        const h = d.geometry.type, c = d.properties.mode;
        c === "linestring" && h === "LineString" ? this.measureLine(l) : c === "point" && h === "Point" ? this.measurePoint(l) : !["point", "linestring", "select", "render"].includes(c) && h === "Polygon" && this.measurePolygon(l);
      } else
        this.clearMeasureFeatures(r, [l]);
    }
  }
  /**
   * Unregister measure control related maplibre sources and layers
   */
  unregisterMesureControl() {
    this.off("feature-deleted", this.onFeatureDeleted.bind(this)), this.map && (this.map.getLayer(this.measureOptions.pointLayerLabelSpec.id) && this.map.removeLayer(
      this.measureOptions.pointLayerLabelSpec.id
    ), this.map.getLayer(this.measureOptions.lineLayerLabelSpec.id) && this.map.removeLayer(this.measureOptions.lineLayerLabelSpec.id), this.map.getLayer(this.measureOptions.lineLayerNodeSpec.id) && this.map.removeLayer(this.measureOptions.lineLayerNodeSpec.id), this.map.getLayer(this.measureOptions.polygonLayerSpec.id) && this.map.removeLayer(this.measureOptions.polygonLayerSpec.id), this.map.getSource(
      this.measureOptions.pointLayerLabelSpec.source
    ) && this.map.removeSource(
      this.measureOptions.pointLayerLabelSpec.source
    ), this.map.getSource(
      this.measureOptions.lineLayerLabelSpec.source
    ) && this.map.removeSource(
      this.measureOptions.lineLayerLabelSpec.source
    ), this.map.getSource(this.measureOptions.polygonLayerSpec.source) && this.map.removeSource(
      this.measureOptions.polygonLayerSpec.source
    ));
  }
  /**
   * Clear GeoJSON feature related to measure control by TerraDraw feature ID
   * @param sourceIds the array of source ID to delete
   * @param ids the array of feature ID. Optional, if undefined, delete all labels for source
   * @returns void
   */
  clearMeasureFeatures(e, i = void 0) {
    var o;
    if (this.map)
      for (const r of e) {
        const n = this.map.getStyle().sources[r];
        n && typeof n.data != "string" && n.data.type === "FeatureCollection" && (i === void 0 ? n.data.features = [] : n.data.features = n.data.features.filter((a) => {
          var l;
          return (l = a.properties) != null && l.originalId ? !i.includes(a.properties.originalId) : !i.includes(a.id);
        }), (o = this.map.getSource(r)) == null || o.setData(n.data));
      }
  }
  /**
   * Replace GeoJSON source with updated features for a given source ID
   * @param updatedFeatures Updated GeoJSON features
   * @param sourceId Source ID to update
   * @param type either 'linestring' or 'point'
   */
  replaceGeoJSONSource(e, i, o) {
    var n, a;
    if (!this.map) return;
    const r = this.map.getStyle().sources[i];
    if (r && typeof r.data != "string" && r.data.type === "FeatureCollection") {
      const l = [];
      for (const h of e)
        (n = this.terradraw) != null && n.getSnapshotFeature(h.id) && l.push(h);
      const d = l.map((h) => h.id);
      if (typeof r.data != "string" && r.data.type === "FeatureCollection") {
        o === "linestring" ? r.data.features = [
          ...r.data.features = r.data.features.filter(
            (c) => {
              var u;
              return !(d.includes((u = c.properties) == null ? void 0 : u.originalId) && c.geometry.type === "Point");
            }
          ),
          ...l
        ] : o === "point" && (r.data.features = [
          ...r.data.features = r.data.features.filter(
            (c) => !(d.includes(c.id) && c.geometry.type === "Point")
          ),
          ...l
        ]);
        const h = {};
        r.data.features.forEach((c) => {
          var p;
          const u = c.id;
          h[u] ? !h[u].properties.elevation && ((p = c.properties) != null && p.elevation) && (h[u] = c) : h[u] = c;
        }), r.data.features = Array.from(Object.values(h)), (a = this.map.getSource(i)) == null || a.setData(r.data);
      }
    }
  }
  /**
   * measure polygon area for given feature ID
   * @param id terradraw feature id
   */
  measurePolygon(e) {
    var n;
    if (!this.map) return;
    const i = this.getTerraDrawInstance();
    if (!i) return;
    const o = i.getSnapshot();
    let r = o == null ? void 0 : o.find((a) => a.id === e && a.geometry.type === "Polygon");
    if (r) {
      const a = this.map.getStyle().sources[this.measureOptions.polygonLayerSpec.source];
      if (a) {
        typeof a.data != "string" && a.data.type === "FeatureCollection" && (a.data.features = a.data.features.filter(
          (d) => {
            var h;
            return ((h = d.properties) == null ? void 0 : h.originalId) !== e;
          }
        ));
        const l = JSON.parse(JSON.stringify(r));
        l.id = l.id + "-area-label", l.geometry = Eo(r.geometry).geometry, l.properties.originalId = r.id, r = ae(r, this.areaUnit, this.areaPrecision), l.properties.area = r.properties.area, l.properties.unit = r.properties.unit, typeof a.data != "string" && a.data.type === "FeatureCollection" && a.data.features.push(l), (n = this.map.getSource(
          this.measureOptions.polygonLayerSpec.source
        )) == null || n.setData(a.data), this.map.moveLayer(this.measureOptions.polygonLayerSpec.id), this.map.getLayer(this.measureOptions.lineLayerLabelSpec.id) && this.map.moveLayer(
          this.measureOptions.lineLayerLabelSpec.id
        ), this.map.getLayer(this.measureOptions.lineLayerNodeSpec.id) && this.map.moveLayer(
          this.measureOptions.lineLayerNodeSpec.id
        ), this.map.getLayer(
          this.measureOptions.pointLayerLabelSpec.id
        ) && this.map.moveLayer(
          this.measureOptions.pointLayerLabelSpec.id
        );
      }
    }
  }
  /**
   * measure line distance for given feature ID
   * @param id terradraw feature id
   */
  measureLine(e) {
    var n;
    if (!this.map) return;
    const i = this.getTerraDrawInstance();
    if (!i) return;
    const o = i.getSnapshot();
    let r = o == null ? void 0 : o.find((a) => a.id === e && a.geometry.type === "LineString");
    if (r) {
      const a = this.map.getStyle().sources[this.measureOptions.lineLayerLabelSpec.source];
      if (a) {
        typeof a.data != "string" && a.data.type === "FeatureCollection" && (a.data.features = a.data.features.filter(
          (d) => {
            var h;
            return ((h = d.properties) == null ? void 0 : h.originalId) !== e;
          }
        )), r = he(
          r,
          this.distanceUnit,
          this.distancePrecision,
          this.map,
          this.computeElevation,
          this.measureOptions.terrainSource
        );
        const l = r.properties.segments;
        for (let d = 0; d < l.length; d++) {
          const h = l[d];
          typeof a.data != "string" && a.data.type === "FeatureCollection" && a.data.features.push(h);
          const c = h.geometry.coordinates, u = c[0], p = c[1];
          if (d === 0) {
            const y = JSON.parse(JSON.stringify(h));
            y.id = `${h.id}-node-${d}`, y.geometry = {
              type: "Point",
              coordinates: u
            }, y.properties.distance = 0, y.properties.total = 0, h.properties.elevation_start && (y.properties.elevation = h.properties.elevation_start), typeof a.data != "string" && a.data.type === "FeatureCollection" && a.data.features.push(y);
          }
          const g = JSON.parse(JSON.stringify(h));
          g.id = `${h.id}-node-${d + 1}`, g.geometry = {
            type: "Point",
            coordinates: p
          }, h.properties.elevation_end && (g.properties.elevation = h.properties.elevation_end), typeof a.data != "string" && a.data.type === "FeatureCollection" && a.data.features.push(g);
        }
        (n = this.map.getSource(
          this.measureOptions.lineLayerLabelSpec.source
        )) == null || n.setData(a.data), this.map.getLayer(this.measureOptions.polygonLayerSpec.id) && this.map.moveLayer(this.measureOptions.polygonLayerSpec.id), this.map.moveLayer(this.measureOptions.lineLayerLabelSpec.id), this.map.moveLayer(this.measureOptions.lineLayerNodeSpec.id), this.map.getLayer(
          this.measureOptions.pointLayerLabelSpec.id
        ) && this.map.moveLayer(
          this.measureOptions.pointLayerLabelSpec.id
        );
      }
    }
  }
  /**
   * measure point elevation for given feature ID
   * @param id terradraw feature id
   */
  measurePoint(e) {
    var n;
    if (!this.map) return;
    const i = this.getTerraDrawInstance();
    if (!i) return;
    const o = i.getSnapshot();
    let r = o == null ? void 0 : o.find((a) => a.id === e && a.geometry.type === "Point");
    if (r) {
      const a = this.map.getStyle().sources[this.measureOptions.pointLayerLabelSpec.source];
      a && (typeof a.data != "string" && a.data.type === "FeatureCollection" && (a.data.features = a.data.features.filter((l) => l.id !== e)), r = ue(
        r,
        this.map,
        this.computeElevation,
        this.measureOptions.terrainSource
      ), this.computeElevation === !0 && typeof a.data != "string" && a.data.type === "FeatureCollection" && a.data.features.push(r), (n = this.map.getSource(
        this.measureOptions.pointLayerLabelSpec.source
      )) == null || n.setData(a.data), this.map.getLayer(this.measureOptions.polygonLayerSpec.id) && this.map.moveLayer(this.measureOptions.polygonLayerSpec.id), this.map.getLayer(this.measureOptions.lineLayerLabelSpec.id) && (this.map.moveLayer(
        this.measureOptions.lineLayerLabelSpec.id
      ), this.map.moveLayer(
        this.measureOptions.lineLayerNodeSpec.id
      )), this.map.moveLayer(
        this.measureOptions.pointLayerLabelSpec.id
      ));
    }
  }
  /**
   * Event definition when feature is deleted by terradraw
   */
  onFeatureDeleted(e) {
    if (!this.map) return;
    if (this.getTerraDrawInstance()) {
      let o = [];
      typeof e == "object" && e !== null && "deletedIds" in e && (o = e.deletedIds);
      const n = [
        this.measureOptions.pointLayerLabelSpec,
        this.measureOptions.lineLayerLabelSpec,
        this.measureOptions.lineLayerNodeSpec,
        this.measureOptions.polygonLayerSpec
      ].map((a) => a.source);
      o && o.length > 0 ? this.clearMeasureFeatures(n, o) : this.clearMeasureFeatures(n, void 0);
    }
  }
  /**
   * get GeoJSON features
   * @param onlySelected If true, returns only selected features. Default is false.
   * @returns FeatureCollection in GeoJSON format
   */
  getFeatures(e = !1) {
    const i = super.getFeatures(e);
    if (!i || !this.terradraw) return i;
    for (let o = 0; o < i.features.length; o++) {
      const r = i.features[o];
      if (!this.map || !this.map.loaded()) continue;
      const n = r.geometry.type;
      n === "LineString" ? i.features[o] = he(
        r,
        this.distanceUnit,
        this.distancePrecision,
        this.map,
        this.computeElevation,
        this.measureOptions.terrainSource
      ) : n === "Polygon" ? i.features[o] = ae(r, this.areaUnit, this.areaPrecision) : n === "Point" && (i.features[o] = ue(
        r,
        this.map,
        this.computeElevation,
        this.measureOptions.terrainSource
      ));
    }
    return i;
  }
}
export {
  ko as AvailableModes,
  jo as MaplibreMeasureControl,
  Fo as MaplibreTerradrawControl,
  Bo as TERRADRAW_MEASURE_SOURCE_IDS,
  bt as TERRADRAW_SOURCE_IDS,
  ae as calcArea,
  he as calcDistance,
  ce as capitalize,
  Ue as cleanMaplibreStyle,
  ao as convertAreaUnit,
  Dt as convertMetricDistance,
  co as debounce,
  Hi as defaultControlOptions,
  yt as defaultMeasureControlOptions,
  qi as getDefaultModeOptions,
  de as getDistanceUnitName,
  ue as queryElevationByPoint,
  pe as queryElevationFromRasterDEM,
  Wo as roundFeatureCoordinates
};
//# sourceMappingURL=maplibre-gl-terradraw.es.js.map