{"version":3,"file":"terra-draw.umd.js","sources":["../src/common.ts","../src/store/store-feature-validation.ts","../src/validations/common-validations.ts","../src/modes/base.mode.ts","../src/geometry/measure/haversine-distance.ts","../src/geometry/helpers.ts","../src/geometry/limit-decimal-precision.ts","../src/geometry/project/web-mercator.ts","../src/geometry/shape/create-circle.ts","../src/geometry/boolean/self-intersects.ts","../src/geometry/boolean/is-valid-coordinate.ts","../src/validations/polygon.validation.ts","../src/modes/base.behavior.ts","../src/geometry/ensure-right-hand-rule.ts","../src/geometry/boolean/right-hand-rule.ts","../src/modes/mutate-feature.behavior.ts","../src/modes/circle/circle.mode.ts","../src/util/styling.ts","../src/geometry/shape/web-mercator-distortion.ts","../src/geometry/measure/pixel-distance.ts","../src/geometry/coordinates-identical.ts","../src/modes/read-feature.behavior.ts","../src/modes/freehand/freehand.mode.ts","../src/geometry/shape/create-bbox.ts","../src/modes/click-bounding-box.behavior.ts","../src/modes/pixel-distance.behavior.ts","../src/modes/coordinate-snapping.behavior.ts","../src/geometry/measure/destination.ts","../src/geometry/measure/bearing.ts","../src/geometry/measure/slice-along.ts","../src/geometry/shape/great-circle-coordinates.ts","../src/modes/insert-coordinates.behavior.ts","../src/validations/linestring.validation.ts","../src/geometry/point-on-line.ts","../src/modes/line-snapping.behavior.ts","../src/geometry/web-mercator-point-on-line.ts","../src/geometry/get-coordinates.ts","../src/modes/closing-points.behavior.ts","../src/modes/select/behaviors/coordinate-point.behavior.ts","../src/modes/linestring/linestring.mode.ts","../src/validations/point.validation.ts","../src/modes/point-search.behavior.ts","../src/modes/point/point.mode.ts","../src/modes/polygon/polygon.mode.ts","../src/modes/rectangle/rectangle.mode.ts","../src/modes/render/render.mode.ts","../src/geometry/measure/rhumb-bearing.ts","../src/geometry/measure/rhumb-destination.ts","../src/geometry/midpoint-coordinate.ts","../src/geometry/get-midpoints.ts","../src/modes/select/behaviors/midpoint.behavior.ts","../src/modes/select/behaviors/selection-point.behavior.ts","../src/geometry/boolean/point-in-polygon.ts","../src/geometry/measure/pixel-distance-to-line.ts","../src/modes/select/behaviors/feature-at-pointer-event.behavior.ts","../src/modes/select/behaviors/drag-feature.behavior.ts","../src/modes/select/behaviors/drag-coordinate.behavior.ts","../src/geometry/centroid.ts","../src/geometry/transform/rotate.ts","../src/geometry/web-mercator-centroid.ts","../src/modes/select/behaviors/rotate-feature.behavior.ts","../src/geometry/measure/rhumb-distance.ts","../src/modes/select/behaviors/scale-feature.behavior.ts","../src/geometry/transform/scale.ts","../src/modes/select/behaviors/drag-coordinate-resize.behavior.ts","../src/modes/select/select.mode.ts","../src/modes/static/static.mode.ts","../src/store/spatial-index/quickselect.ts","../src/store/spatial-index/rbush.ts","../src/store/spatial-index/spatial-index.ts","../src/store/store.ts","../src/util/id.ts","../src/geometry/measure/area.ts","../src/validations/min-size.validation.ts","../src/validations/not-self-intersecting.validation.ts","../src/geometry/calculate-relative-angle.ts","../src/modes/angled-rectangle/angled-rectangle.mode.ts","../src/geometry/determine-halfplane.ts","../src/geometry/clockwise.ts","../src/modes/sector/sector.mode.ts","../src/modes/sensor/sensor.mode.ts","../src/common/adapter-listener.ts","../src/common/base.adapter.ts","../src/validation-reasons.ts","../src/modes/freehand-linestring/freehand-linestring.mode.ts","../src/store/valid-json.ts","../src/modes/marker/marker.mode.ts","../src/terra-draw.ts","../src/validations/max-size.validation.ts"],"sourcesContent":["import { LineString, Polygon, Position } from \"geojson\";\nimport {\n\tStoreChangeHandler,\n\tGeoJSONStore,\n\tGeoJSONStoreFeatures,\n\tFeatureId,\n} from \"./store/store\";\n\nexport type HexColor = `#${string}`;\n\nexport type HexColorStyling =\n\t| HexColor\n\t| ((feature: GeoJSONStoreFeatures) => HexColor);\n\nexport type NumericStyling =\n\t| number\n\t| ((feature: GeoJSONStoreFeatures) => number);\n\nexport type UrlStyling = string | ((feature: GeoJSONStoreFeatures) => string);\n\nexport interface TerraDrawAdapterStyling {\n\tpointColor: HexColor;\n\tpointWidth: number;\n\tpointOpacity?: number;\n\tpointOutlineColor: HexColor;\n\tpointOutlineOpacity?: number;\n\tpointOutlineWidth: number;\n\tpolygonFillColor: HexColor;\n\tpolygonFillOpacity: number;\n\tpolygonOutlineColor: HexColor;\n\tpolygonOutlineOpacity?: number;\n\tpolygonOutlineWidth: number;\n\tlineStringWidth: number;\n\tlineStringColor: HexColor;\n\tlineStringOpacity?: number;\n\tzIndex: number;\n\tmarkerUrl?: string;\n\tmarkerHeight?: number;\n\tmarkerWidth?: number;\n}\n\nexport type CartesianPoint = { x: number; y: number };\n\n// Neither buttons nor touch/pen contact changed since last event\t-1\n// Mouse move with no buttons pressed, Pen moved while hovering with no buttons pressed\t—\n// Left Mouse, Touch Contact, Pen contact\t0\n// Middle Mouse\t1\n// Right Mouse, Pen barrel button\t2\nexport interface TerraDrawMouseEvent {\n\tlng: number;\n\tlat: number;\n\tcontainerX: number;\n\tcontainerY: number;\n\tbutton: \"neither\" | \"left\" | \"middle\" | \"right\";\n\theldKeys: string[];\n\tisContextMenu: boolean;\n}\n\nexport interface TerraDrawKeyboardEvent {\n\tkey: string;\n\theldKeys: string[];\n\tpreventDefault: () => void;\n}\n\nexport type Cursor = Parameters<SetCursor>[0];\n\nexport type SetCursor = (\n\tcursor:\n\t\t| \"unset\"\n\t\t| \"grab\"\n\t\t| \"grabbing\"\n\t\t| \"crosshair\"\n\t\t| \"pointer\"\n\t\t| \"wait\"\n\t\t| \"move\",\n) => void;\n\nexport type Project = (lng: number, lat: number) => CartesianPoint;\nexport type Unproject = (x: number, y: number) => { lat: number; lng: number };\nexport type GetLngLatFromEvent = (event: PointerEvent | MouseEvent) => {\n\tlng: number;\n\tlat: number;\n} | null;\n\nexport type Projection = \"web-mercator\" | \"globe\";\n\nexport const FinishActions = {\n\tDraw: \"draw\",\n\tEdit: \"edit\",\n\tDeleteCoordinate: \"deleteCoordinate\",\n\tInsertMidpoint: \"insertMidpoint\",\n\tDragCoordinate: \"dragCoordinate\",\n\tDragFeature: \"dragFeature\",\n\tDragCoordinateResize: \"dragCoordinateResize\",\n} as const;\n\nexport type DrawInteractions =\n\t| \"click-move\"\n\t| \"click-drag\"\n\t| \"click-move-or-drag\";\n\nexport type DrawType = \"click\" | \"drag\";\n\nexport type Actions = (typeof FinishActions)[keyof typeof FinishActions];\n\nexport type OnFinishContext = { mode: string; action: Actions };\n\nexport type TerraDrawOnChangeContext =\n\t| { origin: \"api\"; target?: \"geometry\" | \"properties\" }\n\t| { target?: \"geometry\" | \"properties\" };\n\nexport type TerraDrawGeoJSONStore = GeoJSONStore<\n\tTerraDrawOnChangeContext | undefined,\n\tFeatureId\n>;\n\nexport interface TerraDrawModeRegisterConfig {\n\tmode: string;\n\tstore: TerraDrawGeoJSONStore;\n\tsetDoubleClickToZoom: (enabled: boolean) => void;\n\tsetCursor: SetCursor;\n\tonChange: StoreChangeHandler<TerraDrawOnChangeContext | undefined>;\n\tonSelect: (selectedId: string) => void;\n\tonDeselect: (deselectedId: string) => void;\n\tonFinish: (finishedId: string, context: OnFinishContext) => void;\n\tproject: Project;\n\tunproject: Unproject;\n\tcoordinatePrecision: number;\n}\n\nexport enum UpdateTypes {\n\tCommit = \"commit\",\n\tProvisional = \"provisional\",\n\tFinish = \"finish\",\n}\n\ntype ValidationContext = Pick<\n\tTerraDrawModeRegisterConfig,\n\t\"project\" | \"unproject\" | \"coordinatePrecision\"\n> & {\n\tupdateType: UpdateTypes;\n};\n\nexport type Validation = (\n\tfeature: GeoJSONStoreFeatures,\n\tcontext: ValidationContext,\n) => {\n\tvalid: boolean;\n\treason?: string;\n};\n\nexport interface Snapping {\n\ttoLine?: boolean;\n\ttoCoordinate?: boolean;\n\ttoCustom?: (\n\t\tevent: TerraDrawMouseEvent,\n\t\tcontext: {\n\t\t\tcurrentId?: FeatureId;\n\t\t\tcurrentCoordinate?: number;\n\t\t\tgetCurrentGeometrySnapshot: () => (Polygon | LineString) | null;\n\t\t\tproject: Project;\n\t\t\tunproject: Unproject;\n\t\t},\n\t) => Position | undefined;\n}\n\nexport type TerraDrawModeState =\n\t| \"unregistered\"\n\t| \"registered\"\n\t| \"started\"\n\t| \"drawing\"\n\t| \"selecting\"\n\t| \"stopped\";\n\nexport interface TerraDrawCallbacks {\n\tgetState: () => TerraDrawModeState;\n\tonKeyUp: (event: TerraDrawKeyboardEvent) => void;\n\tonKeyDown: (event: TerraDrawKeyboardEvent) => void;\n\tonClick: (event: TerraDrawMouseEvent) => void;\n\tonMouseMove: (event: TerraDrawMouseEvent) => void;\n\tonDragStart: (\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) => void;\n\tonDrag: (\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) => void;\n\tonDragEnd: (\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) => void;\n\tonClear: () => void;\n\tonReady?(): void;\n}\n\nexport interface TerraDrawChanges {\n\tcreated: GeoJSONStoreFeatures[];\n\tupdated: GeoJSONStoreFeatures[];\n\tunchanged: GeoJSONStoreFeatures[];\n\tdeletedIds: FeatureId[];\n}\n\nexport type TerraDrawStylingFunction = {\n\t[mode: string]: (feature: GeoJSONStoreFeatures) => TerraDrawAdapterStyling;\n};\n\nexport type TerraDrawHandledEvents = Extract<\n\tkeyof HTMLElementEventMap,\n\t| \"pointerdown\"\n\t| \"pointerup\"\n\t| \"pointermove\"\n\t| \"contextmenu\"\n\t| \"keyup\"\n\t| \"keydown\"\n>;\n\nexport interface TerraDrawAdapter {\n\tproject: Project;\n\tunproject: Unproject;\n\tsetCursor: SetCursor;\n\tgetLngLatFromEvent: GetLngLatFromEvent;\n\tsetDoubleClickToZoom: (enabled: boolean) => void;\n\tgetMapEventElement: (eventType?: TerraDrawHandledEvents) => HTMLElement;\n\tregister(callbacks: TerraDrawCallbacks): void;\n\tunregister(): void;\n\trender(changes: TerraDrawChanges, styling: TerraDrawStylingFunction): void;\n\tclear(): void;\n\tgetCoordinatePrecision(): number;\n}\n\nconst MARKER_URL_BASE =\n\t\"https://raw.githubusercontent.com/JamesLMilner/terra-draw/refs/heads/main/assets/markers\";\n\nexport const MARKER_URL_DEFAULT = `${MARKER_URL_BASE}/marker-blue.png`;\n\nexport const SELECT_PROPERTIES = {\n\tSELECTED: \"selected\",\n\tMID_POINT: \"midPoint\",\n\tSELECTION_POINT_FEATURE_ID: \"selectionPointFeatureId\",\n\tSELECTION_POINT: \"selectionPoint\",\n} as const;\n\nexport const COMMON_PROPERTIES = {\n\tMODE: \"mode\",\n\tCURRENTLY_DRAWING: \"currentlyDrawing\",\n\tEDITED: \"edited\",\n\tCLOSING_POINT: \"closingPoint\",\n\tSNAPPING_POINT: \"snappingPoint\",\n\tCOORDINATE_POINT: \"coordinatePoint\",\n\tCOORDINATE_POINT_FEATURE_ID: \"coordinatePointFeatureId\",\n\tCOORDINATE_POINT_IDS: \"coordinatePointIds\",\n\tPROVISIONAL_COORDINATE_COUNT: \"provisionalCoordinateCount\",\n\tCOMMITTED_COORDINATE_COUNT: \"committedCoordinateCount\",\n\tMARKER: \"marker\",\n} as const;\n\nconst GUIDANCE_POINT_PROPERTY_KEYS = [\n\tCOMMON_PROPERTIES.EDITED,\n\tSELECT_PROPERTIES.SELECTION_POINT,\n\tSELECT_PROPERTIES.MID_POINT,\n\tCOMMON_PROPERTIES.CLOSING_POINT,\n\tCOMMON_PROPERTIES.SNAPPING_POINT,\n\tCOMMON_PROPERTIES.COORDINATE_POINT,\n];\n\nexport type GuidancePointProperties =\n\t(typeof GUIDANCE_POINT_PROPERTY_KEYS)[number];\n\n/**\n * Lower z-index represents layers that are lower in the stack\n * and higher z-index represents layers that are higher in the stack\n * i.e. a layer with z-index 10 will be rendered below a layer with z-index 20\n */\nexport const Z_INDEX = {\n\tLAYER_ONE: 10,\n\tLAYER_TWO: 20,\n\tLAYER_THREE: 30,\n\tLAYER_FOUR: 40,\n\tLAYER_FIVE: 50,\n} as const;\n","import { Validation } from \"../common\";\nimport { FeatureId, IdStrategy } from \"./store\";\n\nexport const StoreValidationErrors = {\n\tFeatureHasNoId: \"Feature has no id\",\n\tFeatureIsNotObject: \"Feature is not object\",\n\tInvalidTrackedProperties: \"updatedAt and createdAt are not valid timestamps\",\n\tFeatureHasNoMode: \"Feature does not have a set mode\",\n\tFeatureIdIsNotValidGeoJSON: `Feature must be string or number as per GeoJSON spec`,\n\tFeatureIdIsNotValid: `Feature must match the id strategy (default is UUID4)`,\n\tFeatureHasNoGeometry: \"Feature has no geometry\",\n\tFeatureHasNoProperties: \"Feature has no properties\",\n\tFeatureGeometryNotSupported: \"Feature is not Point, LineString or Polygon\",\n\tFeatureCoordinatesNotAnArray: \"Feature coordinates is not an array\",\n\tInvalidModeProperty: \"Feature does not have a valid mode property\",\n} as const;\n\nfunction isObject(\n\tfeature: unknown,\n): feature is Record<string | number, unknown> {\n\treturn Boolean(\n\t\tfeature &&\n\t\t\ttypeof feature === \"object\" &&\n\t\t\tfeature !== null &&\n\t\t\t!Array.isArray(feature),\n\t);\n}\n\nexport function hasModeProperty(\n\tfeature: unknown,\n): feature is { properties: { mode: string } } {\n\treturn Boolean(\n\t\tfeature &&\n\t\t\ttypeof feature === \"object\" &&\n\t\t\t\"properties\" in feature &&\n\t\t\ttypeof feature.properties === \"object\" &&\n\t\t\tfeature.properties !== null &&\n\t\t\t\"mode\" in feature.properties,\n\t);\n}\n\nfunction dateIsValid(timestamp: unknown): boolean {\n\treturn (\n\t\ttypeof timestamp === \"number\" &&\n\t\t!isNaN(new Date(timestamp as number).valueOf())\n\t);\n}\n\nexport function isValidTimestamp(timestamp: unknown): boolean {\n\tif (!dateIsValid(timestamp)) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nexport function isValidStoreFeature(\n\tfeature: unknown,\n\tisValidId: IdStrategy<FeatureId>[\"isValidId\"],\n): ReturnType<Validation> {\n\tlet error;\n\tif (!isObject(feature)) {\n\t\terror = StoreValidationErrors.FeatureIsNotObject;\n\t} else if (feature.id === null || feature.id === undefined) {\n\t\terror = StoreValidationErrors.FeatureHasNoId;\n\t} else if (typeof feature.id !== \"string\" && typeof feature.id !== \"number\") {\n\t\terror = StoreValidationErrors.FeatureIdIsNotValidGeoJSON;\n\t} else if (!isValidId(feature.id)) {\n\t\terror = StoreValidationErrors.FeatureIdIsNotValid;\n\t} else if (!isObject(feature.geometry)) {\n\t\terror = StoreValidationErrors.FeatureHasNoGeometry;\n\t} else if (!isObject(feature.properties)) {\n\t\terror = StoreValidationErrors.FeatureHasNoProperties;\n\t} else if (\n\t\ttypeof feature.geometry.type !== \"string\" ||\n\t\t![\"Polygon\", \"LineString\", \"Point\"].includes(feature.geometry.type)\n\t) {\n\t\terror = StoreValidationErrors.FeatureGeometryNotSupported;\n\t} else if (!Array.isArray(feature.geometry.coordinates)) {\n\t\terror = StoreValidationErrors.FeatureCoordinatesNotAnArray;\n\t} else if (\n\t\t!feature.properties.mode ||\n\t\ttypeof feature.properties.mode !== \"string\"\n\t) {\n\t\treturn { valid: false, reason: StoreValidationErrors.InvalidModeProperty };\n\t}\n\n\tif (error) {\n\t\treturn { valid: false, reason: error };\n\t}\n\n\treturn { valid: true };\n}\n","export const ValidationReasonFeatureNotPolygon = \"Feature is not a Polygon\";\nexport const ValidationReasonModeMismatch =\n\t\"Feature mode property does not match the mode being added to\";\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport {\n\tTerraDrawOnChangeContext,\n\tHexColor,\n\tOnFinishContext,\n\tProjection,\n\tTerraDrawAdapterStyling,\n\tTerraDrawGeoJSONStore,\n\tTerraDrawKeyboardEvent,\n\tTerraDrawModeRegisterConfig,\n\tTerraDrawModeState,\n\tTerraDrawMouseEvent,\n\tUpdateTypes,\n\tValidation,\n\tHexColorStyling,\n\tNumericStyling,\n\tUrlStyling,\n} from \"../common\";\nimport {\n\tFeatureId,\n\tGeoJSONStoreFeatures,\n\tStoreChangeHandler,\n} from \"../store/store\";\nimport { isValidStoreFeature } from \"../store/store-feature-validation\";\nimport { ValidationReasonModeMismatch } from \"../validations/common-validations\";\n\nexport type CustomStyling = Record<\n\tstring,\n\tstring | number | HexColorStyling | NumericStyling | UrlStyling\n>;\n\nexport enum ModeTypes {\n\tDrawing = \"drawing\",\n\tSelect = \"select\",\n\tStatic = \"static\",\n\tRender = \"render\",\n}\n\nexport const DefaultPointerEvents = {\n\trightClick: true,\n\tcontextMenu: false,\n\tleftClick: true,\n\tonDragStart: true,\n\tonDrag: true,\n\tonDragEnd: true,\n} as const;\n\ntype AllowPointerEvent = boolean | ((event: TerraDrawMouseEvent) => boolean);\n\nexport type ModeUpdateOptions<Mode> = Omit<Mode, \"modeName\">;\n\nexport interface PointerEvents {\n\tleftClick: AllowPointerEvent;\n\trightClick: AllowPointerEvent;\n\tcontextMenu: AllowPointerEvent;\n\tonDragStart: AllowPointerEvent;\n\tonDrag: AllowPointerEvent;\n\tonDragEnd: AllowPointerEvent;\n}\n\nexport type BaseModeOptions<Styling extends CustomStyling> = {\n\tmodeName?: string;\n\tstyles?: Partial<Styling>;\n\tpointerDistance?: number;\n\tvalidation?: Validation;\n\tprojection?: Projection;\n\tpointerEvents?: PointerEvents;\n};\n\nexport abstract class TerraDrawBaseDrawMode<Styling extends CustomStyling> {\n\t// State\n\tprotected _state: TerraDrawModeState = \"unregistered\";\n\tget state() {\n\t\treturn this._state;\n\t}\n\tset state(_) {\n\t\tthrow new Error(\"Please use the modes lifecycle methods\");\n\t}\n\n\t// Styles\n\tprotected _styles: Partial<Styling> = {};\n\tget styles(): Partial<Styling> {\n\t\treturn this._styles;\n\t}\n\tset styles(styling: Partial<Styling>) {\n\t\tif (typeof styling !== \"object\") {\n\t\t\tthrow new Error(\"Styling must be an object\");\n\t\t}\n\n\t\t// Note: This may not be initialised yet as styles can be set/changed pre-registration\n\t\tif (this.onStyleChange) {\n\t\t\tthis.onStyleChange([], \"styling\");\n\t\t}\n\t\tthis._styles = styling;\n\t}\n\n\tprotected pointerEvents: PointerEvents = DefaultPointerEvents;\n\tprotected behaviors: TerraDrawModeBehavior[] = [];\n\tprotected validate: Validation | undefined;\n\tprotected pointerDistance: number = 40;\n\tprotected coordinatePrecision!: number;\n\tprotected onStyleChange!: StoreChangeHandler<\n\t\tTerraDrawOnChangeContext | undefined\n\t>;\n\tprotected store!: TerraDrawGeoJSONStore;\n\tprotected projection: Projection = \"web-mercator\";\n\n\tprotected setDoubleClickToZoom!: TerraDrawModeRegisterConfig[\"setDoubleClickToZoom\"];\n\tprotected unproject!: TerraDrawModeRegisterConfig[\"unproject\"];\n\tprotected project!: TerraDrawModeRegisterConfig[\"project\"];\n\tprotected setCursor!: TerraDrawModeRegisterConfig[\"setCursor\"];\n\tprotected registerBehaviors(behaviorConfig: BehaviorConfig): void {}\n\n\tprivate isInitialUpdate = false;\n\n\tconstructor(\n\t\toptions?: BaseModeOptions<Styling>,\n\t\twillCallUpdateOptionsInParentClass = false,\n\t) {\n\t\t// Note: We want to updateOptions on the base class by default, but we don't want it to be\n\t\t// called twice if the extending class is going to call it as well\n\t\tif (!willCallUpdateOptionsInParentClass) {\n\t\t\tthis.updateOptions({ ...options });\n\t\t} else {\n\t\t\t// Indicates we are about to have updateOptions called in the parent class\n\t\t\tthis.isInitialUpdate = true;\n\t\t}\n\t}\n\n\tupdateOptions(options?: BaseModeOptions<Styling>) {\n\t\tif (options?.styles) {\n\t\t\t// Note: we are updating this.styles and not this._styles - this is because\n\t\t\t// once registered we want to trigger the onStyleChange\n\t\t\tthis.styles = { ...this._styles, ...options.styles };\n\t\t}\n\n\t\tif (options?.pointerDistance) {\n\t\t\tthis.pointerDistance = options.pointerDistance;\n\t\t}\n\t\tif (options?.validation) {\n\t\t\tthis.validate = options && options.validation;\n\t\t}\n\t\tif (options?.projection) {\n\t\t\tthis.projection = options.projection;\n\t\t}\n\n\t\tif (options?.pointerEvents !== undefined) {\n\t\t\tthis.pointerEvents = options.pointerEvents;\n\t\t}\n\n\t\tif (options?.modeName && this.isInitialUpdate === true) {\n\t\t\tthis.mode = options.modeName;\n\t\t}\n\n\t\tthis.isInitialUpdate = false;\n\t}\n\n\tprotected allowPointerEvent(\n\t\tpointerEvent: AllowPointerEvent,\n\t\tevent: TerraDrawMouseEvent,\n\t) {\n\t\tif (typeof pointerEvent === \"boolean\") {\n\t\t\treturn pointerEvent;\n\t\t}\n\t\tif (typeof pointerEvent === \"function\") {\n\t\t\treturn pointerEvent(event);\n\t\t}\n\t\treturn true;\n\t}\n\n\ttype = ModeTypes.Drawing;\n\tmode = \"base\";\n\n\tprotected setDrawing() {\n\t\tif (this._state === \"started\") {\n\t\t\tthis._state = \"drawing\";\n\t\t} else {\n\t\t\tthrow new Error(\"Mode must be unregistered or stopped to start\");\n\t\t}\n\t}\n\n\tprotected setStarted() {\n\t\tif (\n\t\t\tthis._state === \"stopped\" ||\n\t\t\tthis._state === \"registered\" ||\n\t\t\tthis._state === \"drawing\" ||\n\t\t\tthis._state === \"selecting\"\n\t\t) {\n\t\t\tthis._state = \"started\";\n\t\t\tthis.setDoubleClickToZoom(false);\n\t\t} else {\n\t\t\tthrow new Error(\"Mode must be unregistered or stopped to start\");\n\t\t}\n\t}\n\n\tprotected setStopped() {\n\t\tif (this._state === \"started\") {\n\t\t\tthis._state = \"stopped\";\n\t\t\tthis.setDoubleClickToZoom(true);\n\t\t} else {\n\t\t\tthrow new Error(\"Mode must be started to be stopped\");\n\t\t}\n\t}\n\n\tregister(config: TerraDrawModeRegisterConfig) {\n\t\tif (this._state === \"unregistered\") {\n\t\t\tthis._state = \"registered\";\n\t\t\tthis.store = config.store;\n\t\t\tthis.store.registerOnChange(config.onChange);\n\t\t\tthis.setDoubleClickToZoom = config.setDoubleClickToZoom;\n\t\t\tthis.project = config.project;\n\t\t\tthis.unproject = config.unproject;\n\t\t\tthis.onSelect = config.onSelect;\n\t\t\tthis.onDeselect = config.onDeselect;\n\t\t\tthis.setCursor = config.setCursor;\n\t\t\tthis.onStyleChange = config.onChange;\n\t\t\tthis.onFinish = config.onFinish;\n\t\t\tthis.coordinatePrecision = config.coordinatePrecision;\n\n\t\t\tthis.registerBehaviors({\n\t\t\t\tmode: config.mode,\n\t\t\t\tstore: this.store,\n\t\t\t\tproject: this.project,\n\t\t\t\tunproject: this.unproject,\n\t\t\t\tpointerDistance: this.pointerDistance,\n\t\t\t\tcoordinatePrecision: config.coordinatePrecision,\n\t\t\t\tprojection: this.projection,\n\t\t\t});\n\t\t} else {\n\t\t\tthrow new Error(\"Can not register unless mode is unregistered\");\n\t\t}\n\t}\n\n\tvalidateFeature(feature: unknown): ReturnType<Validation> {\n\t\treturn this.performFeatureValidation(feature);\n\t}\n\n\tafterFeatureAdded(feature: GeoJSONStoreFeatures) {}\n\n\tafterFeatureUpdated(feature: GeoJSONStoreFeatures) {}\n\n\tprivate performFeatureValidation(feature: unknown): ReturnType<Validation> {\n\t\tif (this._state === \"unregistered\") {\n\t\t\tthrow new Error(\"Mode must be registered\");\n\t\t}\n\n\t\tconst validStoreFeature = isValidStoreFeature(\n\t\t\tfeature,\n\t\t\tthis.store.idStrategy.isValidId,\n\t\t);\n\n\t\t// We also want tp validate based on any specific valdiations passed in\n\t\tif (this.validate) {\n\t\t\tconst validation = this.validate(feature as GeoJSONStoreFeatures, {\n\t\t\t\tproject: this.project,\n\t\t\t\tunproject: this.unproject,\n\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\tupdateType: UpdateTypes.Provisional,\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\t// validatedFeature: feature as GeoJSONStoreFeatures,\n\t\t\t\tvalid: validStoreFeature.valid && validation.valid,\n\t\t\t\treason: validation.reason,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\t// validatedFeature: feature as GeoJSONStoreFeatures,\n\t\t\tvalid: validStoreFeature.valid,\n\t\t\treason: validStoreFeature.reason,\n\t\t};\n\t}\n\n\tprotected validateModeFeature(\n\t\tfeature: unknown,\n\t\tmodeValidationFn: (feature: GeoJSONStoreFeatures) => ReturnType<Validation>,\n\t): ReturnType<Validation> {\n\t\tconst validation = this.performFeatureValidation(feature);\n\t\tif (validation.valid) {\n\t\t\tconst validatedFeature = feature as GeoJSONStoreFeatures;\n\t\t\tconst matches = validatedFeature.properties.mode === this.mode;\n\t\t\tif (!matches) {\n\t\t\t\treturn {\n\t\t\t\t\tvalid: false,\n\t\t\t\t\treason: ValidationReasonModeMismatch,\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst modeValidation = modeValidationFn(validatedFeature);\n\t\t\treturn modeValidation;\n\t\t}\n\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\treason: validation.reason,\n\t\t};\n\t}\n\n\tabstract start(): void;\n\tabstract stop(): void;\n\tabstract cleanUp(): void;\n\tabstract styleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling;\n\n\tonFinish(finishedId: FeatureId, context: OnFinishContext) {}\n\tonDeselect(deselectedId: FeatureId) {}\n\tonSelect(selectedId: FeatureId) {}\n\tonKeyDown(event: TerraDrawKeyboardEvent) {}\n\tonKeyUp(event: TerraDrawKeyboardEvent) {}\n\tonMouseMove(event: TerraDrawMouseEvent) {}\n\tonClick(event: TerraDrawMouseEvent) {}\n\tonDragStart(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {}\n\tonDrag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {}\n\tonDragEnd(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {}\n\n\tprotected getHexColorStylingValue(\n\t\tvalue: HexColor | ((feature: GeoJSONStoreFeatures) => HexColor) | undefined,\n\t\tdefaultValue: HexColor,\n\t\tfeature: GeoJSONStoreFeatures,\n\t): HexColor {\n\t\treturn this.getStylingValue(value, defaultValue, feature);\n\t}\n\n\tprotected getNumericStylingValue(\n\t\tvalue: number | ((feature: GeoJSONStoreFeatures) => number) | undefined,\n\t\tdefaultValue: number,\n\t\tfeature: GeoJSONStoreFeatures,\n\t): number {\n\t\treturn this.getStylingValue(value, defaultValue, feature);\n\t}\n\n\tprotected getUrlStylingValue(\n\t\tvalue: UrlStyling | undefined,\n\t\tdefaultValue: string,\n\t\tfeature: GeoJSONStoreFeatures,\n\t): string {\n\t\treturn this.getStylingValue(value, defaultValue, feature);\n\t}\n\n\tprivate getStylingValue<T extends string | number>(\n\t\tvalue: T | ((feature: GeoJSONStoreFeatures) => T) | undefined,\n\t\tdefaultValue: T,\n\t\tfeature: GeoJSONStoreFeatures,\n\t) {\n\t\tif (value === undefined) {\n\t\t\treturn defaultValue;\n\t\t} else if (typeof value === \"function\") {\n\t\t\treturn value(feature);\n\t\t} else {\n\t\t\treturn value;\n\t\t}\n\t}\n}\n\nexport abstract class TerraDrawBaseSelectMode<\n\tStyling extends CustomStyling,\n> extends TerraDrawBaseDrawMode<Styling> {\n\tpublic type = ModeTypes.Select;\n\n\tpublic abstract selectFeature(featureId: FeatureId): void;\n\tpublic abstract deselectFeature(featureId: FeatureId): void;\n}\n","import { Position } from \"geojson\";\n\nexport function haversineDistanceKilometers(\n\tpointOne: Position,\n\tpointTwo: Position,\n) {\n\tconst toRadians = (latOrLng: number) => (latOrLng * Math.PI) / 180;\n\n\tconst phiOne = toRadians(pointOne[1]);\n\tconst lambdaOne = toRadians(pointOne[0]);\n\tconst phiTwo = toRadians(pointTwo[1]);\n\tconst lambdaTwo = toRadians(pointTwo[0]);\n\tconst deltaPhi = phiTwo - phiOne;\n\tconst deltalambda = lambdaTwo - lambdaOne;\n\n\tconst a =\n\t\tMath.sin(deltaPhi / 2) * Math.sin(deltaPhi / 2) +\n\t\tMath.cos(phiOne) *\n\t\t\tMath.cos(phiTwo) *\n\t\t\tMath.sin(deltalambda / 2) *\n\t\t\tMath.sin(deltalambda / 2);\n\tconst c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n\n\tconst radius = 6371e3;\n\tconst distance = radius * c;\n\n\treturn distance / 1000;\n}\n","export const earthRadius = 6371008.8;\n\nexport function degreesToRadians(degrees: number): number {\n\tconst radians = degrees % 360;\n\treturn (radians * Math.PI) / 180;\n}\n\nexport function lengthToRadians(distance: number): number {\n\tconst factor = earthRadius / 1000;\n\treturn distance / factor;\n}\n\nexport function radiansToDegrees(radians: number): number {\n\tconst degrees = radians % (2 * Math.PI);\n\treturn (degrees * 180) / Math.PI;\n}\n","export function limitPrecision(num: number, decimalLimit = 9) {\n\tconst decimals = Math.pow(10, decimalLimit);\n\treturn Math.round(num * decimals) / decimals;\n}\n","import { CartesianPoint } from \"../../common\";\n\nconst RADIANS_TO_DEGREES = 57.29577951308232 as const; // 180 / Math.PI\nconst DEGREES_TO_RADIANS = 0.017453292519943295 as const; // Math.PI / 180\nconst R = 6378137 as const;\n\n/**\n * Convert longitude and latitude to web mercator x and y\n * @param lng\n * @param lat\n * @returns - web mercator x and y\n */\nexport const lngLatToWebMercatorXY = (\n\tlng: number,\n\tlat: number,\n): CartesianPoint => ({\n\tx: lng === 0 ? 0 : lng * DEGREES_TO_RADIANS * R,\n\ty:\n\t\tlat === 0\n\t\t\t? 0\n\t\t\t: Math.log(Math.tan(Math.PI / 4 + (lat * DEGREES_TO_RADIANS) / 2)) * R,\n});\n\n/**\n * Convert web mercator x and y to longitude and latitude\n * @param x - web mercator x\n * @param y - web mercator y\n * @returns - longitude and latitude\n */\nexport const webMercatorXYToLngLat = (\n\tx: number,\n\ty: number,\n): { lng: number; lat: number } => ({\n\tlng: x === 0 ? 0 : RADIANS_TO_DEGREES * (x / R),\n\tlat:\n\t\ty === 0\n\t\t\t? 0\n\t\t\t: (2 * Math.atan(Math.exp(y / R)) - Math.PI / 2) * RADIANS_TO_DEGREES,\n});\n","import { Feature, Polygon, Position } from \"geojson\";\nimport {\n\tdegreesToRadians,\n\tlengthToRadians,\n\tradiansToDegrees,\n} from \"../helpers\";\nimport { limitPrecision } from \"../limit-decimal-precision\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"../project/web-mercator\";\n\n// Adapted from the @turf/circle module which is MIT Licensed\n// https://github.com/Turfjs/turf/blob/master/packages/turf-circle/index.ts\n\nfunction destination(\n\torigin: Position,\n\tdistance: number,\n\tbearing: number,\n): Position {\n\tconst longitude1 = degreesToRadians(origin[0]);\n\tconst latitude1 = degreesToRadians(origin[1]);\n\tconst bearingRad = degreesToRadians(bearing);\n\tconst radians = lengthToRadians(distance);\n\n\t// Main\n\tconst latitude2 = Math.asin(\n\t\tMath.sin(latitude1) * Math.cos(radians) +\n\t\t\tMath.cos(latitude1) * Math.sin(radians) * Math.cos(bearingRad),\n\t);\n\tconst longitude2 =\n\t\tlongitude1 +\n\t\tMath.atan2(\n\t\t\tMath.sin(bearingRad) * Math.sin(radians) * Math.cos(latitude1),\n\t\t\tMath.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2),\n\t\t);\n\tconst lng = radiansToDegrees(longitude2);\n\tconst lat = radiansToDegrees(latitude2);\n\n\treturn [lng, lat];\n}\n\nexport function circle(options: {\n\tcenter: Position;\n\tradiusKilometers: number;\n\tcoordinatePrecision: number;\n\tsteps?: number;\n}): Feature<Polygon> {\n\tconst { center, radiusKilometers, coordinatePrecision } = options;\n\tconst steps = options.steps ? options.steps : 64;\n\n\tconst coordinates: Position[] = [];\n\tfor (let i = 0; i < steps; i++) {\n\t\tconst circleCoordinate = destination(\n\t\t\tcenter,\n\t\t\tradiusKilometers,\n\t\t\t(i * -360) / steps,\n\t\t);\n\n\t\tcoordinates.push([\n\t\t\tlimitPrecision(circleCoordinate[0], coordinatePrecision),\n\t\t\tlimitPrecision(circleCoordinate[1], coordinatePrecision),\n\t\t]);\n\t}\n\tcoordinates.push(coordinates[0]);\n\n\treturn {\n\t\ttype: \"Feature\",\n\t\tgeometry: { type: \"Polygon\", coordinates: [coordinates] },\n\t\tproperties: {},\n\t};\n}\n\nexport function circleWebMercator(options: {\n\tcenter: Position;\n\tradiusKilometers: number;\n\tcoordinatePrecision: number;\n\tsteps?: number;\n}): GeoJSON.Feature<GeoJSON.Polygon> {\n\tconst { center, radiusKilometers, coordinatePrecision } = options;\n\tconst steps = options.steps ? options.steps : 64;\n\n\tconst radiusMeters = radiusKilometers * 1000;\n\n\tconst [lng, lat] = center;\n\tconst { x, y } = lngLatToWebMercatorXY(lng, lat);\n\n\tconst coordinates: Position[] = [];\n\tfor (let i = 0; i < steps; i++) {\n\t\tconst angle = (((i * 360) / steps) * Math.PI) / 180;\n\t\tconst dx = radiusMeters * Math.cos(angle);\n\t\tconst dy = radiusMeters * Math.sin(angle);\n\t\tconst [wx, wy] = [x + dx, y + dy];\n\t\tconst { lng, lat } = webMercatorXYToLngLat(wx, wy);\n\t\tcoordinates.push([\n\t\t\tlimitPrecision(lng, coordinatePrecision),\n\t\t\tlimitPrecision(lat, coordinatePrecision),\n\t\t]);\n\t}\n\n\t// Close the circle by adding the first point at the end\n\tcoordinates.push(coordinates[0]);\n\n\treturn {\n\t\ttype: \"Feature\",\n\t\tgeometry: { type: \"Polygon\", coordinates: [coordinates] },\n\t\tproperties: {},\n\t};\n}\n","// Based on - https://github.com/mclaeysb/geojson-polygon-self-intersections\n// MIT License - Copyright (c) 2016 Manuel Claeys Bouuaert\n\nimport { Feature, LineString, Polygon, Position } from \"geojson\";\n// import * as rbush from \"rbush\";\n\ntype SelfIntersectsOptions = {\n\tepsilon: number;\n\t// reportVertexOnVertex: boolean;\n\t// reportVertexOnEdge: boolean;\n};\n\nexport function selfIntersects(\n\tfeature: Feature<Polygon> | Feature<LineString>,\n): boolean {\n\tconst options: SelfIntersectsOptions = {\n\t\tepsilon: 0,\n\t\t// reportVertexOnVertex: false,\n\t\t// reportVertexOnEdge: false,\n\t};\n\n\tlet coord: number[][][];\n\n\tif (feature.geometry.type === \"Polygon\") {\n\t\tcoord = feature.geometry.coordinates;\n\t} else if (feature.geometry.type === \"LineString\") {\n\t\tcoord = [feature.geometry.coordinates];\n\t} else {\n\t\tthrow new Error(\"Self intersects only accepts Polygons and LineStrings\");\n\t}\n\n\tconst output: number[][] = [];\n\tconst seen: { [key: string]: boolean } = {};\n\n\tfor (let ring0 = 0; ring0 < coord.length; ring0++) {\n\t\tfor (let edge0 = 0; edge0 < coord[ring0].length - 1; edge0++) {\n\t\t\tfor (let ring1 = 0; ring1 < coord.length; ring1++) {\n\t\t\t\tfor (let edge1 = 0; edge1 < coord[ring1].length - 1; edge1++) {\n\t\t\t\t\t// speedup possible if only interested in unique: start last two loops at ring0 and edge0+1\n\t\t\t\t\tifInteresctionAddToOutput(ring0, edge0, ring1, edge1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn output.length > 0;\n\n\t// true if frac is (almost) 1.0 or 0.0\n\t// function isBoundaryCase(frac: number) {\n\t//   const e2 = options.epsilon * options.epsilon;\n\t//   return e2 >= (frac - 1) * (frac - 1) || e2 >= frac * frac;\n\t// }\n\n\tfunction isOutside(frac: number) {\n\t\treturn frac < 0 - options.epsilon || frac > 1 + options.epsilon;\n\t}\n\t// Function to check if two edges intersect and add the intersection to the output\n\tfunction ifInteresctionAddToOutput(\n\t\tring0: number,\n\t\tedge0: number,\n\t\tring1: number,\n\t\tedge1: number,\n\t) {\n\t\tconst start0 = coord[ring0][edge0];\n\t\tconst end0 = coord[ring0][edge0 + 1];\n\t\tconst start1 = coord[ring1][edge1];\n\t\tconst end1 = coord[ring1][edge1 + 1];\n\n\t\tconst intersection = intersect(start0, end0, start1, end1);\n\n\t\tif (intersection === null) {\n\t\t\treturn; // discard parallels and coincidence\n\t\t}\n\n\t\tlet frac0;\n\t\tlet frac1;\n\n\t\tif (end0[0] !== start0[0]) {\n\t\t\tfrac0 = (intersection[0] - start0[0]) / (end0[0] - start0[0]);\n\t\t} else {\n\t\t\tfrac0 = (intersection[1] - start0[1]) / (end0[1] - start0[1]);\n\t\t}\n\t\tif (end1[0] !== start1[0]) {\n\t\t\tfrac1 = (intersection[0] - start1[0]) / (end1[0] - start1[0]);\n\t\t} else {\n\t\t\tfrac1 = (intersection[1] - start1[1]) / (end1[1] - start1[1]);\n\t\t}\n\n\t\t// There are roughly three cases we need to deal with.\n\t\t// 1. If at least one of the fracs lies outside [0,1], there is no intersection.\n\t\tif (isOutside(frac0) || isOutside(frac1)) {\n\t\t\treturn; // require segment intersection\n\t\t}\n\n\t\t// 2. If both are either exactly 0 or exactly 1, this is not an intersection but just\n\t\t// two edge segments sharing a common vertex.\n\t\t// if (isBoundaryCase(frac0) && isBoundaryCase(frac1)) {\n\t\t//   if (!options.reportVertexOnVertex) {\n\t\t//     return;\n\t\t//   }\n\t\t// }\n\n\t\t// // 3. If only one of the fractions is exactly 0 or 1, this is\n\t\t// // a vertex-on-edge situation.\n\t\t// if (isBoundaryCase(frac0) || isBoundaryCase(frac1)) {\n\t\t//   if (!options.reportVertexOnEdge) {\n\t\t//     return;\n\t\t//   }\n\t\t// }\n\n\t\tconst key = intersection.toString();\n\t\tconst unique = !seen[key];\n\t\tif (unique) {\n\t\t\tseen[key] = true;\n\t\t}\n\n\t\toutput.push(intersection);\n\t}\n}\n\nfunction equalArrays(array1: Position, array2: Position) {\n\treturn array1[0] === array2[0] && array1[1] === array2[1];\n}\n\n// Function to compute where two lines (not segments) intersect. From https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection\nfunction intersect(\n\tstart0: Position,\n\tend0: Position,\n\tstart1: Position,\n\tend1: Position,\n) {\n\tif (\n\t\tequalArrays(start0, start1) ||\n\t\tequalArrays(start0, end1) ||\n\t\tequalArrays(end0, start1) ||\n\t\tequalArrays(end1, start1)\n\t) {\n\t\treturn null;\n\t}\n\n\tconst x0 = start0[0],\n\t\ty0 = start0[1],\n\t\tx1 = end0[0],\n\t\ty1 = end0[1],\n\t\tx2 = start1[0],\n\t\ty2 = start1[1],\n\t\tx3 = end1[0],\n\t\ty3 = end1[1];\n\n\tconst denom = (x0 - x1) * (y2 - y3) - (y0 - y1) * (x2 - x3);\n\tif (denom === 0) {\n\t\treturn null;\n\t}\n\n\tconst x4 =\n\t\t((x0 * y1 - y0 * x1) * (x2 - x3) - (x0 - x1) * (x2 * y3 - y2 * x3)) / denom;\n\n\tconst y4 =\n\t\t((x0 * y1 - y0 * x1) * (y2 - y3) - (y0 - y1) * (x2 * y3 - y2 * x3)) / denom;\n\n\treturn [x4, y4];\n}\n","import { Position } from \"geojson\";\n\nexport function validLatitude(lat: number) {\n\treturn lat >= -90 && lat <= 90;\n}\n\nexport function validLongitude(lng: number) {\n\treturn lng >= -180 && lng <= 180;\n}\n\nexport function coordinatePrecisionIsValid(\n\tcoordinate: Position,\n\tcoordinatePrecision: number,\n) {\n\treturn (\n\t\tgetDecimalPlaces(coordinate[0]) <= coordinatePrecision &&\n\t\tgetDecimalPlaces(coordinate[1]) <= coordinatePrecision\n\t);\n}\n\nexport function coordinateIsValid(coordinate: unknown[]) {\n\treturn (\n\t\tcoordinate.length === 2 &&\n\t\ttypeof coordinate[0] === \"number\" &&\n\t\ttypeof coordinate[1] === \"number\" &&\n\t\tcoordinate[0] !== Infinity &&\n\t\tcoordinate[1] !== Infinity &&\n\t\tvalidLongitude(coordinate[0]) &&\n\t\tvalidLatitude(coordinate[1])\n\t);\n}\n\nexport function getDecimalPlaces(value: number): number {\n\tlet current = 1;\n\tlet precision = 0;\n\twhile (Math.round(value * current) / current !== value) {\n\t\tcurrent *= 10;\n\t\tprecision++;\n\t}\n\n\treturn precision;\n}\n","import { Feature, Polygon, Position } from \"geojson\";\nimport { GeoJSONStoreFeatures } from \"../terra-draw\";\nimport { selfIntersects } from \"../geometry/boolean/self-intersects\";\nimport {\n\tcoordinateIsValid,\n\tcoordinatePrecisionIsValid,\n} from \"../geometry/boolean/is-valid-coordinate\";\nimport { Validation } from \"../common\";\n\nexport const ValidationReasonFeatureNotPolygon = \"Feature is not a Polygon\";\nexport const ValidationReasonFeatureHasHoles = \"Feature has holes\";\nexport const ValidationReasonFeatureLessThanFourCoordinates =\n\t\"Feature has less than 4 coordinates\";\nexport const ValidationReasonFeatureHasInvalidCoordinates =\n\t\"Feature has invalid coordinates\";\nexport const ValidationReasonFeatureCoordinatesNotClosed =\n\t\"Feature coordinates are not closed\";\nexport const ValidationReasonFeatureInvalidCoordinatePrecision =\n\t\"Feature has coordinates with excessive precision\";\n\nexport function ValidatePolygonFeature(\n\tfeature: GeoJSONStoreFeatures,\n\tcoordinatePrecision: number,\n): ReturnType<Validation> {\n\tif (feature.geometry.type !== \"Polygon\") {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\treason: ValidationReasonFeatureNotPolygon,\n\t\t};\n\t}\n\n\tif (feature.geometry.coordinates.length !== 1) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\treason: ValidationReasonFeatureHasHoles,\n\t\t};\n\t}\n\n\tif (feature.geometry.coordinates[0].length < 4) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\treason: ValidationReasonFeatureLessThanFourCoordinates,\n\t\t};\n\t}\n\n\tfor (let i = 0; i < feature.geometry.coordinates[0].length; i++) {\n\t\tif (!coordinateIsValid(feature.geometry.coordinates[0][i])) {\n\t\t\treturn {\n\t\t\t\tvalid: false,\n\t\t\t\treason: ValidationReasonFeatureHasInvalidCoordinates,\n\t\t\t};\n\t\t}\n\n\t\tif (\n\t\t\t!coordinatePrecisionIsValid(\n\t\t\t\tfeature.geometry.coordinates[0][i],\n\t\t\t\tcoordinatePrecision,\n\t\t\t)\n\t\t) {\n\t\t\treturn {\n\t\t\t\tvalid: false,\n\t\t\t\treason: ValidationReasonFeatureInvalidCoordinatePrecision,\n\t\t\t};\n\t\t}\n\t}\n\n\tif (\n\t\t!coordinatesMatch(\n\t\t\tfeature.geometry.coordinates[0][0],\n\t\t\tfeature.geometry.coordinates[0][\n\t\t\t\tfeature.geometry.coordinates[0].length - 1\n\t\t\t],\n\t\t)\n\t) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\treason: ValidationReasonFeatureCoordinatesNotClosed,\n\t\t};\n\t}\n\n\treturn { valid: true };\n}\n\nexport function ValidateNonIntersectingPolygonFeature(\n\tfeature: GeoJSONStoreFeatures,\n\tcoordinatePrecision: number,\n): ReturnType<Validation> {\n\tconst validatePolygonFeature = ValidatePolygonFeature(\n\t\tfeature,\n\t\tcoordinatePrecision,\n\t);\n\n\tif (!validatePolygonFeature.valid) {\n\t\treturn validatePolygonFeature;\n\t}\n\n\tif (selfIntersects(feature as Feature<Polygon>)) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\treason: \"Feature intersects itself\",\n\t\t};\n\t}\n\n\treturn { valid: true };\n}\n\n/**\n * Check if two coordinates are identical\n * @param coordinateOne - coordinate to compare\n * @param coordinateTwo - coordinate to compare with\n * @returns boolean\n */\nfunction coordinatesMatch(coordinateOne: Position, coordinateTwo: Position) {\n\treturn (\n\t\tcoordinateOne[0] === coordinateTwo[0] &&\n\t\tcoordinateOne[1] === coordinateTwo[1]\n\t);\n}\n","import {\n\tProject,\n\tProjection,\n\tTerraDrawGeoJSONStore,\n\tUnproject,\n} from \"../common\";\n\nexport type BehaviorConfig = {\n\tstore: TerraDrawGeoJSONStore;\n\tmode: string;\n\tproject: Project;\n\tunproject: Unproject;\n\tpointerDistance: number;\n\tcoordinatePrecision: number;\n\tprojection: Projection;\n};\n\nexport class TerraDrawModeBehavior {\n\tprotected store: TerraDrawGeoJSONStore;\n\tprotected mode: string;\n\tprotected project: Project;\n\tprotected unproject: Unproject;\n\tprotected pointerDistance: number;\n\tprotected coordinatePrecision: number;\n\tprotected projection: Projection;\n\n\tconstructor({\n\t\tstore,\n\t\tmode,\n\t\tproject,\n\t\tunproject,\n\t\tpointerDistance,\n\t\tcoordinatePrecision,\n\t\tprojection,\n\t}: BehaviorConfig) {\n\t\tthis.store = store;\n\t\tthis.mode = mode;\n\t\tthis.project = project;\n\t\tthis.unproject = unproject;\n\t\tthis.pointerDistance = pointerDistance;\n\t\tthis.coordinatePrecision = coordinatePrecision;\n\t\tthis.projection = projection;\n\t}\n}\n","import { Feature, Polygon } from \"geojson\";\nimport { followsRightHandRule } from \"./boolean/right-hand-rule\";\n\nexport function ensureRightHandRule(polygon: Polygon): undefined | Polygon {\n\tconst isFollowingRightHandRule = followsRightHandRule(polygon);\n\tif (!isFollowingRightHandRule) {\n\t\treturn {\n\t\t\ttype: \"Polygon\",\n\t\t\tcoordinates: [polygon.coordinates[0].reverse()],\n\t\t} as Polygon;\n\t}\n}\n","import { Polygon } from \"geojson\";\n\n/**\n * Checks if a GeoJSON Polygon follows the right-hand rule.\n * @param polygon - The GeoJSON Polygon to check.\n * @returns {boolean} - True if the polygon follows the right-hand rule (counterclockwise outer ring), otherwise false.\n */\nexport function followsRightHandRule(polygon: Polygon): boolean {\n\tconst outerRing = polygon.coordinates[0];\n\n\tlet sum = 0;\n\tfor (let i = 0; i < outerRing.length - 1; i++) {\n\t\tconst [x1, y1] = outerRing[i];\n\t\tconst [x2, y2] = outerRing[i + 1];\n\t\tsum += (x2 - x1) * (y2 + y1);\n\t}\n\n\treturn sum < 0; // Right-hand rule: counterclockwise = negative area\n}\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { FeatureId } from \"../extend\";\nimport {\n\tGeoJSONStoreFeatures,\n\tGeoJSONStoreGeometries,\n\tJSONObject,\n\tJSON,\n} from \"../store/store\";\nimport { Polygon, Position, LineString, Point, Feature } from \"geojson\";\nimport {\n\tActions,\n\tGuidancePointProperties,\n\tSELECT_PROPERTIES,\n\tUpdateTypes,\n\tValidation,\n} from \"../common\";\nimport { ensureRightHandRule } from \"../geometry/ensure-right-hand-rule\";\n\ntype MutateFeatureBehaviorOptions = {\n\tvalidate: Validation | undefined;\n};\n\nexport const Mutations = {\n\tInsertBefore: \"insert-before\",\n\tInsertAfter: \"insert-after\",\n\tUpdate: \"update\",\n\tDelete: \"delete\",\n\tReplace: \"replace\",\n} as const;\n\n// Coordinate mutations assume that the index is relative to the original array\n// of coordinates before any mutations are applied.\ntype InsertBeforeMutation = {\n\ttype: typeof Mutations.InsertBefore;\n\tindex: number;\n\tcoordinate: Position;\n};\n\ntype InsertAfterMutation = {\n\ttype: typeof Mutations.InsertAfter;\n\tindex: number;\n\tcoordinate: Position;\n};\n\ntype UpdateMutation = {\n\ttype: typeof Mutations.Update;\n\tindex: number;\n\tcoordinate: Position;\n};\ntype DeleteMutation = { type: typeof Mutations.Delete; index: number };\n\nexport type ReplaceMutation<ReplacedGeometry extends GeoJSONStoreGeometries> = {\n\ttype: typeof Mutations.Replace;\n\tcoordinates: ReplacedGeometry[\"coordinates\"];\n};\n\nexport type CoordinateMutation =\n\t| InsertBeforeMutation\n\t| InsertAfterMutation\n\t| UpdateMutation\n\t| DeleteMutation;\n\ntype ValidProperties = Record<string, JSON | undefined>;\n\ntype FinishContext = { updateType: UpdateTypes.Finish; action: Actions };\n\ntype MutateContext =\n\t| FinishContext\n\t| { updateType: UpdateTypes.Commit | UpdateTypes.Provisional };\n\nexport type UpdateGeometry<G extends GeoJSONStoreGeometries> = {\n\tfeatureId: FeatureId;\n\tcoordinateMutations?: ReplaceMutation<G> | CoordinateMutation[];\n\tpropertyMutations?: ValidProperties;\n\tcontext: MutateContext;\n};\n\nexport class MutateFeatureBehavior extends TerraDrawModeBehavior {\n\tconstructor(config: BehaviorConfig, options: MutateFeatureBehaviorOptions) {\n\t\tsuper(config);\n\t\tthis.options = options;\n\t}\n\n\tprivate options: MutateFeatureBehaviorOptions;\n\n\tpublic createPoint({\n\t\tcoordinates,\n\t\tproperties,\n\t\tcontext,\n\t}: {\n\t\tcoordinates: Position;\n\t\tproperties: JSONObject;\n\t\tcontext?: FinishContext;\n\t}) {\n\t\t// Create point is slightly different in that creating can also be the finish action\n\t\t// because there is only one step to creating a point.\n\t\tif (context?.updateType === UpdateTypes.Finish) {\n\t\t\tconst valid = this.validateGeometryWithUpdateType({\n\t\t\t\tgeometry: { type: \"Point\", coordinates },\n\t\t\t\tproperties,\n\t\t\t\tupdateType: UpdateTypes.Finish,\n\t\t\t});\n\n\t\t\tif (!valid) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tconst created = this.handleCreateFeature({\n\t\t\tgeometry: { type: \"Point\", coordinates },\n\t\t\tproperties,\n\t\t});\n\n\t\treturn created;\n\t}\n\n\tpublic createLineString({\n\t\tcoordinates,\n\t\tproperties,\n\t}: {\n\t\tcoordinates: LineString[\"coordinates\"];\n\t\tproperties: JSONObject;\n\t}) {\n\t\treturn this.handleCreateFeature({\n\t\t\tgeometry: { type: \"LineString\", coordinates },\n\t\t\tproperties,\n\t\t});\n\t}\n\n\tpublic createPolygon({\n\t\tcoordinates,\n\t\tproperties,\n\t}: {\n\t\tcoordinates: Polygon[\"coordinates\"][0];\n\t\tproperties: JSONObject;\n\t}) {\n\t\tconst corrected = ensureRightHandRule({\n\t\t\ttype: \"Polygon\",\n\t\t\tcoordinates: [coordinates],\n\t\t});\n\n\t\treturn this.handleCreateFeature({\n\t\t\tgeometry: {\n\t\t\t\ttype: \"Polygon\",\n\t\t\t\tcoordinates: corrected ? corrected.coordinates : [coordinates],\n\t\t\t},\n\t\t\tproperties,\n\t\t});\n\t}\n\n\tpublic createGuidancePoint({\n\t\tcoordinate,\n\t\ttype,\n\t}: {\n\t\tcoordinate: Position;\n\t\ttype: GuidancePointProperties;\n\t}) {\n\t\treturn this.createGuidancePoints({ coordinates: [coordinate], type })[0];\n\t}\n\n\tpublic createGuidancePoints({\n\t\tcoordinates,\n\t\ttype,\n\t\tadditionalProperties,\n\t}: {\n\t\tcoordinates: Position[];\n\t\ttype: GuidancePointProperties;\n\t\tadditionalProperties?: (index: number) => JSONObject;\n\t}) {\n\t\tconst features = coordinates.map((coordinate, i) => ({\n\t\t\ttype: \"Feature\" as const,\n\t\t\tgeometry: { type: \"Point\" as const, coordinates: coordinate },\n\t\t\tproperties: {\n\t\t\t\tmode: this.mode,\n\t\t\t\t[type]: true,\n\t\t\t\t...(additionalProperties ? additionalProperties(i) : {}),\n\t\t\t},\n\t\t}));\n\n\t\tconst ids = this.createFeatures(features);\n\t\treturn ids;\n\t}\n\n\tpublic updatePoint({\n\t\tfeatureId,\n\t\tcoordinateMutations,\n\t\tpropertyMutations,\n\t\tcontext,\n\t}: UpdateGeometry<Point>) {\n\t\treturn this.handleMutateFeature<Point>({\n\t\t\ttype: \"Point\",\n\t\t\tfeatureId,\n\t\t\tcoordinateMutations,\n\t\t\tpropertyMutations,\n\t\t\tcontext,\n\t\t});\n\t}\n\n\tpublic updatePolygon({\n\t\tfeatureId,\n\t\tcoordinateMutations,\n\t\tcontext,\n\t\tpropertyMutations,\n\t}: UpdateGeometry<Polygon>) {\n\t\treturn this.handleMutateFeature({\n\t\t\ttype: \"Polygon\",\n\t\t\tfeatureId,\n\t\t\tcoordinateMutations,\n\t\t\tpropertyMutations,\n\t\t\tcontext,\n\t\t});\n\t}\n\n\tpublic updateLineString({\n\t\tfeatureId,\n\t\tcoordinateMutations,\n\t\tcontext,\n\t\tpropertyMutations,\n\t}: UpdateGeometry<LineString>) {\n\t\treturn this.handleMutateFeature({\n\t\t\ttype: \"LineString\",\n\t\t\tfeatureId,\n\t\t\tcoordinateMutations,\n\t\t\tpropertyMutations,\n\t\t\tcontext,\n\t\t});\n\t}\n\n\tpublic deleteFeatureIfPresent(featureId: FeatureId | undefined) {\n\t\tif (featureId && this.store.has(featureId)) {\n\t\t\tthis.store.delete([featureId]);\n\t\t}\n\t}\n\n\tpublic deleteFeaturesIfPresent(featureIds: FeatureId[]) {\n\t\tif (featureIds.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst existing = featureIds.filter((id) => this.store.has(id));\n\n\t\tif (existing.length) {\n\t\t\tthis.store.delete(existing);\n\t\t}\n\t}\n\n\tpublic setDeselected(featureIds: FeatureId[]) {\n\t\tconst updateSelectedFeatures = featureIds\n\t\t\t.filter((id) => this.store.has(id))\n\t\t\t.map((id) => ({\n\t\t\t\tfeatureId: id,\n\t\t\t\tproperties: {\n\t\t\t\t\t[SELECT_PROPERTIES.SELECTED]: false,\n\t\t\t\t} as ValidProperties,\n\t\t\t}));\n\n\t\tthis.updateFeatureProperties(updateSelectedFeatures);\n\t}\n\n\tpublic setSelected(featureId: FeatureId) {\n\t\tconst { type } = this.store.getGeometryCopy(featureId);\n\t\tconst update = {\n\t\t\tfeatureId,\n\t\t\tpropertyMutations: {\n\t\t\t\t[SELECT_PROPERTIES.SELECTED]: true,\n\t\t\t},\n\t\t\tcontext: { updateType: UpdateTypes.Commit },\n\t\t} as const;\n\n\t\tif (type === \"Polygon\") {\n\t\t\tthis.updatePolygon(update);\n\t\t} else if (type === \"LineString\") {\n\t\t\tthis.updateLineString(update);\n\t\t} else if (type === \"Point\") {\n\t\t\tthis.updatePoint(update);\n\t\t}\n\t}\n\n\tpublic updateGuidancePoints(\n\t\tguidancePoints: {\n\t\t\tfeatureId: FeatureId;\n\t\t\tcoordinate: Position;\n\t\t}[],\n\t) {\n\t\tthis.updateFeatureGeometries(\n\t\t\tguidancePoints.map(({ featureId, coordinate }) => ({\n\t\t\t\tid: featureId,\n\t\t\t\tgeometry: {\n\t\t\t\t\ttype: \"Point\",\n\t\t\t\t\tcoordinates: coordinate,\n\t\t\t\t} as Point,\n\t\t\t})),\n\t\t);\n\t}\n\n\tprivate handleCreateFeature<G extends GeoJSONStoreGeometries>({\n\t\tgeometry,\n\t\tproperties,\n\t}: {\n\t\tgeometry: G;\n\t\tproperties: JSONObject;\n\t}) {\n\t\treturn this.createFeatureWithGeometry<G>({\n\t\t\tgeometry,\n\t\t\tproperties,\n\t\t});\n\t}\n\n\tprivate handleMutateFeature<G extends GeoJSONStoreGeometries>({\n\t\ttype,\n\t\tfeatureId,\n\t\tcoordinateMutations,\n\t\tpropertyMutations,\n\t\tcontext,\n\t}: UpdateGeometry<G> & { type: G[\"type\"] }) {\n\t\tconst updated = this.mutateFeature<G>({\n\t\t\ttype,\n\t\t\tfeatureId,\n\t\t\tcoordinateMutations,\n\t\t\tpropertyMutations,\n\t\t\tcontext:\n\t\t\t\tcontext.updateType === UpdateTypes.Finish\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...context,\n\t\t\t\t\t\t\tcorrectRightHandRule: true,\n\t\t\t\t\t\t}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\t...context,\n\t\t\t\t\t\t},\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst feature = this.buildFeatureWithGeometry<G>(featureId);\n\n\t\t// Handle special case where there are no coordinate mutations but we want to validate on finish\n\t\tif (context.updateType === UpdateTypes.Finish) {\n\t\t\tif (!coordinateMutations) {\n\t\t\t\tif (\n\t\t\t\t\t!this.validateGeometryWithUpdateType({\n\t\t\t\t\t\tgeometry: feature.geometry,\n\t\t\t\t\t\tproperties: feature.properties,\n\t\t\t\t\t\tupdateType: context.updateType,\n\t\t\t\t\t})\n\t\t\t\t) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn feature;\n\t}\n\n\tpublic epsilonOffset() {\n\t\t// We must add a very small epsilon value so that Mapbox GL\n\t\t// renders the polygon - There might be a cleaner solution?\n\t\tconst epsilon = 1 / Math.pow(10, this.coordinatePrecision - 1);\n\t\tconst offset = Math.max(0.000001, epsilon);\n\t\treturn offset;\n\t}\n\n\tprivate mutateFeature<G extends GeoJSONStoreGeometries>({\n\t\ttype,\n\t\tfeatureId,\n\t\tcoordinateMutations,\n\t\tpropertyMutations,\n\t\tcontext,\n\t}: {\n\t\ttype: G[\"type\"];\n\t\tfeatureId: FeatureId;\n\t\tcoordinateMutations?: CoordinateMutation[] | ReplaceMutation<G>;\n\t\tpropertyMutations?: ValidProperties;\n\t\tcontext: MutateContext & { correctRightHandRule?: boolean };\n\t}): boolean {\n\t\tif (!featureId) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst existingGeometry = this.store.getGeometryCopy(featureId);\n\t\tconst existingProperties = this.store.getPropertiesCopy(featureId);\n\n\t\tif (existingGeometry.type !== type) {\n\t\t\tthrow new Error(\n\t\t\t\t`${type} geometries cannot be updated on features with ${existingGeometry.type} geometries`,\n\t\t\t);\n\t\t}\n\n\t\tif (coordinateMutations) {\n\t\t\tlet updatedGeometry = this.applyCoordinateMutations(\n\t\t\t\texistingGeometry,\n\t\t\t\tcoordinateMutations,\n\t\t\t);\n\n\t\t\t// For polygons, we may need to enforce the right-hand rule\n\t\t\tif (context.correctRightHandRule && updatedGeometry.type === \"Polygon\") {\n\t\t\t\tconst correctedGeometry = ensureRightHandRule(updatedGeometry);\n\t\t\t\tif (correctedGeometry) {\n\t\t\t\t\tupdatedGeometry = correctedGeometry;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\t!this.validateGeometryWithUpdateType({\n\t\t\t\t\tgeometry: updatedGeometry,\n\t\t\t\t\tproperties: existingProperties,\n\t\t\t\t\tupdateType: context.updateType,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis.updateFeatureGeometries([\n\t\t\t\t{ id: featureId, geometry: updatedGeometry },\n\t\t\t]);\n\t\t}\n\n\t\tif (propertyMutations) {\n\t\t\tthis.updateFeatureProperties([\n\t\t\t\t{ featureId, properties: propertyMutations },\n\t\t\t]);\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tprivate applyCoordinateMutations<\n\t\tUpdatedGeometry extends LineString | Polygon | Point,\n\t>(\n\t\tupdatedGeometry: UpdatedGeometry,\n\t\tcoordinatesMutations:\n\t\t\t| CoordinateMutation[]\n\t\t\t| ReplaceMutation<UpdatedGeometry>,\n\t): UpdatedGeometry {\n\t\tif (this.isReplaceMutation(coordinatesMutations)) {\n\t\t\treturn {\n\t\t\t\t...updatedGeometry,\n\t\t\t\tcoordinates: coordinatesMutations.coordinates,\n\t\t\t};\n\t\t}\n\n\t\tif (updatedGeometry.type === \"Point\") {\n\t\t\tthrow new Error(\n\t\t\t\t\"Coordinate mutations are not supported for Point geometries\",\n\t\t\t);\n\t\t}\n\n\t\t// Determine the original coordinates array and how to write back\n\t\tconst isPolygon = updatedGeometry.type === \"Polygon\";\n\t\tconst originalCoordinates: Position[] = isPolygon\n\t\t\t? // work on a shallow copy of the exterior ring\n\t\t\t\t(updatedGeometry as Polygon).coordinates[0].slice()\n\t\t\t: (updatedGeometry as LineString).coordinates.slice();\n\n\t\tconst originalLength = originalCoordinates.length;\n\n\t\t// Normalize indices relative to the original array length\n\t\tconst normalizeIndex = (index: number): number => {\n\t\t\tconst normalized = index < 0 ? originalLength + index : index;\n\n\t\t\tif (normalized < 0 || normalized >= originalLength) {\n\t\t\t\tthrow new RangeError(\n\t\t\t\t\t`Index ${index} (normalized to ${normalized}) is out of bounds`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn normalized;\n\t\t};\n\n\t\t// For each original index i (0..originalLength-1), store\n\t\t// the last non-insert mutation (update/delete) that targets i\n\t\tconst nonInsertByIndex: (CoordinateMutation | undefined)[] = new Array(\n\t\t\toriginalLength,\n\t\t).fill(undefined);\n\n\t\t// For inserts, we track before/after arrays per index, plus a tailAfter array\n\t\tconst insertsBeforeByIndex: CoordinateMutation[][] = Array.from(\n\t\t\t{ length: originalLength },\n\t\t\t() => [],\n\t\t);\n\t\tconst insertsAfterByIndex: CoordinateMutation[][] = Array.from(\n\t\t\t{ length: originalLength },\n\t\t\t() => [],\n\t\t);\n\t\tconst tailAfter: CoordinateMutation[] = [];\n\n\t\t// 1) Scan mutations in the order provided\n\t\tfor (const mutation of coordinatesMutations as CoordinateMutation[]) {\n\t\t\tif (\n\t\t\t\tmutation.type === Mutations.InsertBefore ||\n\t\t\t\tmutation.type === Mutations.InsertAfter\n\t\t\t) {\n\t\t\t\t// Normalize but allow index === originalLength for INSERT_AFTER as tail append\n\t\t\t\tconst rawIndex = mutation.index;\n\t\t\t\tconst normalized = rawIndex < 0 ? originalLength + rawIndex : rawIndex;\n\n\t\t\t\tif (normalized < 0 || normalized > originalLength) {\n\t\t\t\t\tthrow new RangeError(\n\t\t\t\t\t\t`Index ${mutation.index} (normalized to ${normalized}) is out of bounds`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (mutation.type === Mutations.InsertBefore) {\n\t\t\t\t\tif (normalized >= originalLength) {\n\t\t\t\t\t\tthrow new RangeError(\n\t\t\t\t\t\t\t`INSERT_BEFORE index ${mutation.index} (normalized to ${normalized}) is out of bounds for length ${originalLength}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tinsertsBeforeByIndex[normalized].push(mutation);\n\t\t\t\t} else {\n\t\t\t\t\t// INSERT_AFTER\n\t\t\t\t\tif (normalized === originalLength) {\n\t\t\t\t\t\t// tail append\n\t\t\t\t\t\ttailAfter.push(mutation);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tinsertsAfterByIndex[normalized].push(mutation);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Non-insert: UPDATE/DELETE\n\t\t\tconst normalizedIndex = normalizeIndex(mutation.index);\n\n\t\t\t// For update/delete, the *last* one wins at each original index\n\t\t\tnonInsertByIndex[normalizedIndex] = {\n\t\t\t\t...mutation,\n\t\t\t\tindex: normalizedIndex,\n\t\t\t};\n\t\t}\n\n\t\t// 2) Build the new coordinates array from scratch\n\t\tconst newCoordinates: Position[] = [];\n\n\t\tfor (let i = 0; i < originalLength; i++) {\n\t\t\t// Inserts that go before the element originally at i\n\t\t\tconst beforeInserts = insertsBeforeByIndex[i];\n\t\t\tfor (const insertMutation of beforeInserts) {\n\t\t\t\tnewCoordinates.push(\n\t\t\t\t\t(insertMutation as InsertBeforeMutation).coordinate,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst mutation = nonInsertByIndex[i];\n\n\t\t\tif (!mutation) {\n\t\t\t\t// No update/delete targeting this index: keep the original coordinate\n\t\t\t\tnewCoordinates.push(originalCoordinates[i]);\n\t\t\t} else if (mutation.type === Mutations.Delete) {\n\t\t\t\t// Skip this original coordinate\n\t\t\t} else {\n\t\t\t\t// Must be update\n\t\t\t\tnewCoordinates.push((mutation as UpdateMutation).coordinate);\n\t\t\t}\n\n\t\t\t// Inserts that go after the element originally at i\n\t\t\tconst afterInserts = insertsAfterByIndex[i];\n\t\t\tfor (const insertMutation of afterInserts) {\n\t\t\t\tnewCoordinates.push((insertMutation as InsertAfterMutation).coordinate);\n\t\t\t}\n\t\t}\n\n\t\t// 3) Tail inserts (INSERT_AFTER with index === originalLength)\n\t\tfor (const insertMutation of tailAfter) {\n\t\t\tnewCoordinates.push((insertMutation as InsertAfterMutation).coordinate);\n\t\t}\n\n\t\t// 4) Return a new geometry object with the updated coordinates\n\t\tif (isPolygon) {\n\t\t\tconst polygon = updatedGeometry as Polygon;\n\t\t\treturn {\n\t\t\t\t...polygon,\n\t\t\t\tcoordinates: [newCoordinates, ...polygon.coordinates.slice(1)],\n\t\t\t} as typeof updatedGeometry;\n\t\t}\n\n\t\t// Is LineString\n\t\treturn {\n\t\t\t...updatedGeometry,\n\t\t\tcoordinates: newCoordinates,\n\t\t} as typeof updatedGeometry;\n\t}\n\n\tprivate isReplaceMutation<G extends GeoJSONStoreGeometries>(\n\t\tmutation: CoordinateMutation[] | ReplaceMutation<G>,\n\t): mutation is ReplaceMutation<G> {\n\t\treturn (mutation as ReplaceMutation<G>).type === Mutations.Replace;\n\t}\n\n\t// Shared helpers for LineString / Polygon logic\n\tprivate createFeatureWithGeometry<G extends GeoJSONStoreGeometries>({\n\t\tgeometry,\n\t\tproperties,\n\t}: {\n\t\tgeometry: G;\n\t\tproperties: GeoJSONStoreFeatures<G>[\"properties\"];\n\t}) {\n\t\tconst [id] = this.createFeatures([\n\t\t\t{\n\t\t\t\ttype: \"Feature\",\n\t\t\t\tgeometry,\n\t\t\t\tproperties,\n\t\t\t},\n\t\t]);\n\n\t\tconst created = {\n\t\t\tid,\n\t\t\ttype: \"Feature\",\n\t\t\tproperties: this.store.getPropertiesCopy(id),\n\t\t\tgeometry: this.store.getGeometryCopy<G>(id),\n\t\t} as GeoJSONStoreFeatures<G> & { id: FeatureId };\n\n\t\treturn created;\n\t}\n\n\tprivate validateGeometryWithUpdateType({\n\t\tgeometry,\n\t\tproperties,\n\t\tupdateType,\n\t}: {\n\t\tgeometry: GeoJSONStoreGeometries;\n\t\tproperties?: ValidProperties;\n\t\tupdateType: UpdateTypes;\n\t}): boolean {\n\t\tif (!this.options.validate) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst validationResult = this.options.validate(\n\t\t\t{\n\t\t\t\ttype: \"Feature\",\n\t\t\t\tgeometry,\n\t\t\t\tproperties: properties ? properties : {},\n\t\t\t} as GeoJSONStoreFeatures,\n\t\t\t{\n\t\t\t\tproject: this.project,\n\t\t\t\tunproject: this.unproject,\n\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\tupdateType,\n\t\t\t},\n\t\t);\n\n\t\treturn validationResult.valid;\n\t}\n\n\tprivate buildFeatureWithGeometry<G extends GeoJSONStoreGeometries>(\n\t\tfeatureId: FeatureId,\n\t) {\n\t\treturn {\n\t\t\tid: featureId,\n\t\t\ttype: \"Feature\",\n\t\t\tproperties: this.store.getPropertiesCopy(featureId),\n\t\t\tgeometry: this.store.getGeometryCopy<G>(featureId),\n\t\t} as GeoJSONStoreFeatures<G>;\n\t}\n\n\tprivate createFeatures<G extends GeoJSONStoreGeometries>(\n\t\tfeatures: GeoJSONStoreFeatures<G>[],\n\t) {\n\t\treturn this.store.create(features);\n\t}\n\n\tprivate updateFeatureGeometries<G extends GeoJSONStoreGeometries>(\n\t\tupdates: {\n\t\t\tid: FeatureId;\n\t\t\tgeometry: G;\n\t\t}[],\n\t) {\n\t\tthis.store.updateGeometry(updates);\n\t}\n\n\tprivate updateFeatureProperties(\n\t\tproperties: {\n\t\t\tfeatureId: FeatureId;\n\t\t\tproperties: ValidProperties;\n\t\t}[],\n\t) {\n\t\tconst updates = properties\n\t\t\t.map(({ featureId, properties }) => {\n\t\t\t\treturn Object.entries(properties).map(([key, value]) => ({\n\t\t\t\t\tid: featureId,\n\t\t\t\t\tproperty: key,\n\t\t\t\t\tvalue,\n\t\t\t\t}));\n\t\t\t})\n\t\t\t.flat();\n\n\t\tthis.store.updateProperty(updates);\n\t}\n}\n","import { Feature, Position } from \"geojson\";\nimport {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n\tProjection,\n\tZ_INDEX,\n\tCOMMON_PROPERTIES,\n\tFinishActions,\n\tDrawInteractions,\n\tDrawType,\n} from \"../../common\";\nimport { haversineDistanceKilometers } from \"../../geometry/measure/haversine-distance\";\nimport { circle, circleWebMercator } from \"../../geometry/shape/create-circle\";\nimport {\n\tFeatureId,\n\tGeoJSONStoreFeatures,\n\tStoreValidation,\n} from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tModeUpdateOptions,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { ValidateNonIntersectingPolygonFeature } from \"../../validations/polygon.validation\";\nimport { Polygon } from \"geojson\";\nimport { calculateWebMercatorDistortion } from \"../../geometry/shape/web-mercator-distortion\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { MutateFeatureBehavior, Mutations } from \"../mutate-feature.behavior\";\nimport { ReadFeatureBehavior } from \"../read-feature.behavior\";\n\ntype TerraDrawCircleModeKeyEvents = {\n\tcancel: KeyboardEvent[\"key\"] | null;\n\tfinish: KeyboardEvent[\"key\"] | null;\n};\n\nconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\ntype CirclePolygonStyling = {\n\tfillColor: HexColorStyling;\n\tfillOpacity: NumericStyling;\n\toutlineColor: HexColorStyling;\n\toutlineWidth: NumericStyling;\n\toutlineOpacity: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n}\n\nconst defaultCursors = {\n\tstart: \"crosshair\",\n} as Required<Cursors>;\n\ninterface TerraDrawCircleModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tkeyEvents?: TerraDrawCircleModeKeyEvents | null;\n\tcursors?: Cursors;\n\tstartingRadiusKilometers?: number;\n\tprojection?: Projection;\n\tdrawInteraction?: DrawInteractions;\n\tsegments?: number;\n}\n\nexport class TerraDrawCircleMode extends TerraDrawBaseDrawMode<CirclePolygonStyling> {\n\tmode = \"circle\";\n\tprivate center: Position | undefined;\n\tprivate endPosition: Position | undefined;\n\tprivate segments = 64;\n\n\tprivate currentCircleId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawCircleModeKeyEvents = defaultKeyEvents;\n\tprivate cursors: Required<Cursors> = defaultCursors;\n\tprivate startingRadiusKilometers = 0.00001;\n\tprivate cursorMovedAfterInitialCursorDown = false;\n\tprivate drawInteraction = \"click-move\";\n\tprivate drawType: DrawType | undefined;\n\n\t// Behaviors\n\tprivate mutateFeature!: MutateFeatureBehavior;\n\n\t/**\n\t * Create a new circle mode instance\n\t * @param options - Options to customize the behavior of the circle mode\n\t * @param options.keyEvents - Key events to cancel or finish the mode\n\t * @param options.cursors - Cursors to use for the mode\n\t * @param options.styles - Custom styling for the circle\n\t * @param options.pointerDistance - Distance in pixels to consider a pointer close to a vertex\n\t * @param options.startingRadiusKilometers - The starting radius of the circle in kilometers\n\t * @param options.projection - The map projection being used\n\t * @param options.drawInteraction - The type of draw interaction to use\n\t *\n\t */\n\tconstructor(options?: TerraDrawCircleModeOptions<CirclePolygonStyling>) {\n\t\tsuper(options, true);\n\t\tthis.updateOptions(options);\n\t}\n\n\toverride updateOptions(\n\t\toptions?: ModeUpdateOptions<\n\t\t\tTerraDrawCircleModeOptions<CirclePolygonStyling>\n\t\t>,\n\t) {\n\t\tsuper.updateOptions(options);\n\n\t\tif (options?.cursors) {\n\t\t\tthis.cursors = { ...this.cursors, ...options.cursors };\n\t\t}\n\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = { cancel: null, finish: null };\n\t\t} else if (options?.keyEvents) {\n\t\t\tthis.keyEvents = { ...this.keyEvents, ...options.keyEvents };\n\t\t}\n\n\t\tif (options?.startingRadiusKilometers) {\n\t\t\tthis.startingRadiusKilometers = options.startingRadiusKilometers;\n\t\t}\n\n\t\tif (options?.drawInteraction) {\n\t\t\tthis.drawInteraction = options.drawInteraction;\n\t\t}\n\n\t\tif (options?.segments) {\n\t\t\tthis.segments = options.segments < 3 ? 3 : options.segments;\n\t\t}\n\t}\n\n\tprivate close() {\n\t\tif (this.currentCircleId === undefined || this.endPosition === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst updated = this.updateCircle(this.endPosition, UpdateTypes.Finish);\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\t\tconst featureId = this.currentCircleId;\n\n\t\tthis.cursorMovedAfterInitialCursorDown = false;\n\t\tthis.center = undefined;\n\t\tthis.currentCircleId = undefined;\n\t\tthis.drawType = undefined;\n\n\t\t// Go back to started state\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.onFinish(featureId, {\n\t\t\tmode: this.mode,\n\t\t\taction: FinishActions.Draw,\n\t\t});\n\t}\n\n\tprivate beginDrawing(\n\t\tevent: TerraDrawMouseEvent,\n\t\tdrawType: DrawType = \"click\",\n\t): void {\n\t\tthis.center = [event.lng, event.lat];\n\t\tthis.endPosition = [event.lng, event.lat];\n\n\t\tconst startingCircle = circle({\n\t\t\tcenter: this.center,\n\t\t\tradiusKilometers: this.startingRadiusKilometers,\n\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t});\n\n\t\tconst created = this.mutateFeature.createPolygon({\n\t\t\tcoordinates: startingCircle.geometry.coordinates[0],\n\t\t\tproperties: {\n\t\t\t\tmode: this.mode,\n\t\t\t\tradiusKilometers: this.startingRadiusKilometers,\n\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: true,\n\t\t\t},\n\t\t});\n\n\t\tif (!created) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.currentCircleId = created.id;\n\t\tthis.cursorMovedAfterInitialCursorDown = false;\n\t\tthis.drawType = drawType;\n\t\tthis.setDrawing();\n\t}\n\n\tprivate dragDrawAllowed() {\n\t\treturn (\n\t\t\tthis.drawInteraction === \"click-drag\" ||\n\t\t\tthis.drawInteraction === \"click-move-or-drag\"\n\t\t);\n\t}\n\n\tprivate moveDrawAllowed() {\n\t\treturn (\n\t\t\tthis.drawInteraction === \"click-move\" ||\n\t\t\tthis.drawInteraction === \"click-move-or-drag\"\n\t\t);\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\tif (\n\t\t\tthis.moveDrawAllowed() &&\n\t\t\t((event.button === \"right\" &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.rightClick, event)) ||\n\t\t\t\t(event.button === \"left\" &&\n\t\t\t\t\tthis.allowPointerEvent(this.pointerEvents.leftClick, event)) ||\n\t\t\t\t(event.isContextMenu &&\n\t\t\t\t\tthis.allowPointerEvent(this.pointerEvents.contextMenu, event)))\n\t\t) {\n\t\t\tif (!this.center) {\n\t\t\t\tthis.beginDrawing(event);\n\t\t\t} else if (this.center && this.currentCircleId !== undefined) {\n\t\t\t\tthis.endPosition = [event.lng, event.lat];\n\n\t\t\t\t// Finish drawing\n\t\t\t\tthis.close();\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tthis.cursorMovedAfterInitialCursorDown = true;\n\t\tthis.endPosition = [event.lng, event.lat];\n\t\tthis.updateCircle(this.endPosition, UpdateTypes.Provisional);\n\t}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tif (event.key === this.keyEvents.cancel) {\n\t\t\tthis.cleanUp();\n\t\t} else if (event.key === this.keyEvents.finish) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDragStart(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (this.state === \"drawing\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\tthis.allowPointerEvent(this.pointerEvents.onDragStart, event) &&\n\t\t\tthis.dragDrawAllowed()\n\t\t) {\n\t\t\tthis.beginDrawing(event, \"drag\");\n\t\t\tsetMapDraggability(false);\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDrag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (\n\t\t\tthis.allowPointerEvent(this.pointerEvents.onDrag, event) &&\n\t\t\tthis.dragDrawAllowed() &&\n\t\t\tthis.drawType === \"drag\"\n\t\t) {\n\t\t\tthis.cursorMovedAfterInitialCursorDown = true;\n\t\t\tthis.endPosition = [event.lng, event.lat];\n\t\t\tthis.updateCircle(this.endPosition, UpdateTypes.Provisional);\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDragEnd(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (\n\t\t\tthis.allowPointerEvent(this.pointerEvents.onDragEnd, event) &&\n\t\t\tthis.dragDrawAllowed() &&\n\t\t\tthis.drawType === \"drag\"\n\t\t) {\n\t\t\tthis.endPosition = [event.lng, event.lat];\n\t\t\t// Finish drawing\n\t\t\tthis.close();\n\t\t\tsetMapDraggability(true);\n\t\t}\n\t}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tconst currentId = this.currentCircleId;\n\n\t\tthis.center = undefined;\n\t\tthis.currentCircleId = undefined;\n\t\tthis.drawType = undefined;\n\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.mutateFeature.deleteFeatureIfPresent(currentId);\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"Polygon\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tstyles.polygonFillColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.fillColor,\n\t\t\t\tstyles.polygonFillColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonOutlineColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.outlineColor,\n\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonOutlineWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.outlineWidth,\n\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonOutlineOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.outlineOpacity,\n\t\t\t\t1,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonFillOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.fillOpacity,\n\t\t\t\tstyles.polygonFillOpacity,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.zIndex = Z_INDEX.LAYER_ONE;\n\n\t\t\treturn styles;\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): StoreValidation {\n\t\treturn this.validateModeFeature(feature, (baseValidatedFeature) =>\n\t\t\tValidateNonIntersectingPolygonFeature(\n\t\t\t\tbaseValidatedFeature,\n\t\t\t\tthis.coordinatePrecision,\n\t\t\t),\n\t\t);\n\t}\n\n\tprivate updateCircle(endPosition: Position, updateType: UpdateTypes) {\n\t\tif (this.currentCircleId === undefined || this.center === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst isFinish = updateType === UpdateTypes.Finish;\n\n\t\tlet updatedCircle: Feature<Polygon> | undefined;\n\t\tlet newRadius: number | undefined;\n\n\t\tif (this.cursorMovedAfterInitialCursorDown) {\n\t\t\tnewRadius = haversineDistanceKilometers(this.center, endPosition);\n\n\t\t\tif (this.projection === \"web-mercator\") {\n\t\t\t\t// We want to track the mouse cursor, but we need to adjust the radius based\n\t\t\t\t// on the distortion of the web mercator projection\n\t\t\t\tconst distortion = calculateWebMercatorDistortion(\n\t\t\t\t\tthis.center,\n\t\t\t\t\tendPosition,\n\t\t\t\t);\n\n\t\t\t\tupdatedCircle = circleWebMercator({\n\t\t\t\t\tcenter: this.center,\n\t\t\t\t\tradiusKilometers: newRadius * distortion,\n\t\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\t\tsteps: this.segments,\n\t\t\t\t});\n\t\t\t} else if (this.projection === \"globe\") {\n\t\t\t\tupdatedCircle = circle({\n\t\t\t\t\tcenter: this.center,\n\t\t\t\t\tradiusKilometers: newRadius,\n\t\t\t\t\tcoordinatePrecision: this.coordinatePrecision,\n\t\t\t\t\tsteps: this.segments,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Invalid projection\");\n\t\t\t}\n\t\t}\n\n\t\tconst propertyMutations: {\n\t\t\tradiusKilometers?: number;\n\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]?: boolean;\n\t\t} = {};\n\n\t\tif (updatedCircle && newRadius) {\n\t\t\tpropertyMutations.radiusKilometers = newRadius;\n\t\t}\n\n\t\tif (isFinish) {\n\t\t\tpropertyMutations[COMMON_PROPERTIES.CURRENTLY_DRAWING] = undefined;\n\t\t}\n\n\t\treturn this.mutateFeature.updatePolygon({\n\t\t\tfeatureId: this.currentCircleId,\n\t\t\tcoordinateMutations: updatedCircle\n\t\t\t\t? {\n\t\t\t\t\t\ttype: Mutations.Replace,\n\t\t\t\t\t\tcoordinates: updatedCircle.geometry.coordinates,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t\tpropertyMutations,\n\t\t\tcontext: isFinish\n\t\t\t\t? {\n\t\t\t\t\t\tupdateType,\n\t\t\t\t\t\taction: FinishActions.Draw,\n\t\t\t\t\t}\n\t\t\t\t: { updateType },\n\t\t});\n\t}\n\n\tafterFeatureUpdated(feature: GeoJSONStoreFeatures): void {\n\t\t// If we are in the middle of drawing a circle and the feature being updated is the current circle,\n\t\t// we need to reset the drawing state\n\t\tif (this.currentCircleId === feature.id) {\n\t\t\tthis.cursorMovedAfterInitialCursorDown = false;\n\t\t\tthis.center = undefined;\n\t\t\tthis.currentCircleId = undefined;\n\t\t\tthis.drawType = undefined;\n\t\t\tif (this.state === \"drawing\") {\n\t\t\t\tthis.setStarted();\n\t\t\t}\n\t\t}\n\t}\n\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.mutateFeature = new MutateFeatureBehavior(config, {\n\t\t\tvalidate: this.validate,\n\t\t});\n\t}\n}\n","import { TerraDrawAdapterStyling } from \"../common\";\n\nexport const getDefaultStyling = (): TerraDrawAdapterStyling => {\n\treturn {\n\t\tpolygonFillColor: \"#3f97e0\",\n\t\tpolygonOutlineColor: \"#3f97e0\",\n\t\tpolygonOutlineWidth: 4,\n\t\tpolygonOutlineOpacity: 1,\n\t\tpolygonFillOpacity: 0.3,\n\t\tpointColor: \"#3f97e0\",\n\t\tpointOpacity: 1,\n\t\tpointOutlineColor: \"#ffffff\",\n\t\tpointOutlineOpacity: 1,\n\t\tpointOutlineWidth: 0,\n\t\tpointWidth: 6,\n\t\tlineStringColor: \"#3f97e0\",\n\t\tlineStringWidth: 4,\n\t\tlineStringOpacity: 1,\n\t\tzIndex: 0,\n\t\tmarkerUrl: undefined,\n\t\tmarkerHeight: undefined,\n\t\tmarkerWidth: undefined,\n\t};\n};\n","import { Position } from \"geojson\";\nimport { haversineDistanceKilometers } from \"../measure/haversine-distance\";\nimport { lngLatToWebMercatorXY } from \"../project/web-mercator\";\n\n/*\n * Function to calculate the web mercator vs geodesic distortion between two coordinates\n * Value of 1 means no distortion, higher values mean higher distortion\n * */\nexport function calculateWebMercatorDistortion(\n\tsource: Position,\n\ttarget: Position,\n): number {\n\tconst geodesicDistance = haversineDistanceKilometers(source, target) * 1000;\n\tif (geodesicDistance === 0) {\n\t\treturn 1;\n\t}\n\n\tconst { x: x1, y: y1 } = lngLatToWebMercatorXY(source[0], source[1]);\n\tconst { x: x2, y: y2 } = lngLatToWebMercatorXY(target[0], target[1]);\n\tconst euclideanDistance = Math.sqrt(\n\t\tMath.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2),\n\t);\n\treturn euclideanDistance / geodesicDistance;\n}\n","import { CartesianPoint } from \"../../common\";\n\nexport const cartesianDistance = (\n\tpointOne: CartesianPoint,\n\tpointTwo: CartesianPoint,\n) => {\n\tconst { x: x1, y: y1 } = pointOne;\n\tconst { x: x2, y: y2 } = pointTwo;\n\tconst y = x2 - x1;\n\tconst x = y2 - y1;\n\treturn Math.sqrt(x * x + y * y);\n};\n","import { Position } from \"geojson\";\n\nexport function coordinatesIdentical(\n\tcoordinate: Position,\n\tcoordinateTwo: Position,\n) {\n\treturn (\n\t\tcoordinate[0] === coordinateTwo[0] && coordinate[1] === coordinateTwo[1]\n\t);\n}\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { FeatureId } from \"../extend\";\nimport { GeoJSONStoreGeometries, JSONObject } from \"../store/store\";\nimport { Position, Point } from \"geojson\";\nimport { coordinatesIdentical } from \"../geometry/coordinates-identical\";\n\nexport class ReadFeatureBehavior extends TerraDrawModeBehavior {\n\tconstructor(config: BehaviorConfig) {\n\t\tsuper(config);\n\t}\n\n\tpublic getGeometryType(featureId: FeatureId) {\n\t\treturn this.store.getGeometryCopy(featureId).type;\n\t}\n\n\tpublic coordinateAtIndexIsIdentical({\n\t\tfeatureId,\n\t\tnewCoordinate,\n\t\tindex,\n\t}: {\n\t\tfeatureId: FeatureId;\n\t\tnewCoordinate: Position;\n\t\tindex: number;\n\t}) {\n\t\tconst geometry = this.store.getGeometryCopy(featureId);\n\n\t\tlet coordinate;\n\n\t\tif (geometry.type === \"Polygon\") {\n\t\t\tcoordinate = geometry.coordinates[0][index];\n\t\t} else if (geometry.type === \"LineString\") {\n\t\t\tcoordinate = geometry.coordinates[index];\n\t\t} else {\n\t\t\tif (index !== 0) {\n\t\t\t\tthrow new Error(\"Point geometries only have one coordinate at index 0\");\n\t\t\t}\n\t\t\tcoordinate = geometry.coordinates;\n\t\t}\n\n\t\treturn coordinatesIdentical(newCoordinate, coordinate);\n\t}\n\n\tpublic getGeometry<G extends GeoJSONStoreGeometries>(featureId: FeatureId) {\n\t\treturn this.store.getGeometryCopy<G>(featureId);\n\t}\n\n\tpublic getCoordinates<G extends Exclude<GeoJSONStoreGeometries, Point>>(\n\t\tfeatureId: FeatureId,\n\t) {\n\t\tconst { type, coordinates } = this.store.getGeometryCopy<G>(featureId);\n\t\treturn type === \"Polygon\" ? coordinates[0] : coordinates;\n\t}\n\n\tpublic getCoordinate<G extends Exclude<GeoJSONStoreGeometries, Point>>(\n\t\tfeatureId: FeatureId,\n\t\tindex: number,\n\t) {\n\t\tconst coords = this.getCoordinates<G>(featureId);\n\t\tconst normalizedIndex = index < 0 ? coords.length + index : index;\n\n\t\tif (normalizedIndex < 0 || normalizedIndex >= coords.length) {\n\t\t\tthrow new RangeError(\n\t\t\t\t`Index ${index} (normalized to ${normalizedIndex}) is out of bounds`,\n\t\t\t);\n\t\t}\n\n\t\treturn coords[normalizedIndex];\n\t}\n\n\tpublic getProperties(featureId: FeatureId) {\n\t\treturn this.store.getPropertiesCopy(featureId);\n\t}\n\n\tpublic hasFeature(featureId: FeatureId) {\n\t\treturn this.store.has(featureId);\n\t}\n\n\tpublic getAllFeatureIdsWhere(equals: (properties: JSONObject) => boolean) {\n\t\treturn this.store.copyAllWhere(equals).map(({ id }) => id as FeatureId);\n\t}\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n\tCOMMON_PROPERTIES,\n\tZ_INDEX,\n\tFinishActions,\n\tDrawInteractions,\n\tDrawType,\n} from \"../../common\";\n\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tModeUpdateOptions,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tFeatureId,\n\tGeoJSONStoreFeatures,\n\tStoreValidation,\n} from \"../../store/store\";\nimport { cartesianDistance } from \"../../geometry/measure/pixel-distance\";\nimport { ValidatePolygonFeature } from \"../../validations/polygon.validation\";\nimport { MutateFeatureBehavior, Mutations } from \"../mutate-feature.behavior\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { ReadFeatureBehavior } from \"../read-feature.behavior\";\n\ntype TerraDrawFreehandModeKeyEvents = {\n\tcancel: KeyboardEvent[\"key\"] | null;\n\tfinish: KeyboardEvent[\"key\"] | null;\n};\n\nconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\ntype FreehandPolygonStyling = {\n\tfillColor: HexColorStyling;\n\tfillOpacity: NumericStyling;\n\toutlineColor: HexColorStyling;\n\toutlineOpacity: NumericStyling;\n\toutlineWidth: NumericStyling;\n\tclosingPointColor: HexColorStyling;\n\tclosingPointOpacity: NumericStyling;\n\tclosingPointWidth: NumericStyling;\n\tclosingPointOutlineColor: HexColorStyling;\n\tclosingPointOutlineOpacity: NumericStyling;\n\tclosingPointOutlineWidth: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n\tclose?: Cursor;\n}\n\nconst defaultCursors = {\n\tstart: \"crosshair\",\n\tclose: \"pointer\",\n} as Required<Cursors>;\n\ninterface TerraDrawFreehandModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tminDistance?: number;\n\tsmoothing?: number;\n\tpreventPointsNearClose?: boolean;\n\tautoClose?: boolean;\n\tautoCloseTimeout?: number;\n\tkeyEvents?: TerraDrawFreehandModeKeyEvents | null;\n\tcursors?: Cursors;\n\tdrawInteraction?: DrawInteractions;\n}\n\nexport class TerraDrawFreehandMode extends TerraDrawBaseDrawMode<FreehandPolygonStyling> {\n\tmode = \"freehand\";\n\n\tprivate canClose = false;\n\tprivate currentId: FeatureId | undefined;\n\tprivate closingPointId: FeatureId | undefined;\n\tprivate minDistance: number = 20;\n\tprivate keyEvents: TerraDrawFreehandModeKeyEvents = defaultKeyEvents;\n\tprivate cursors: Required<Cursors> = defaultCursors;\n\tprivate preventPointsNearClose: boolean = true;\n\tprivate autoClose: boolean = false;\n\tprivate autoCloseTimeout = 500;\n\tprivate hasLeftStartingPoint = false;\n\tprivate preventNewFeature = false;\n\tprivate drawInteraction = \"click-move\";\n\tprivate drawType: DrawType | undefined;\n\tprivate smoothing = 0;\n\n\t// Behaviors\n\tprivate mutateFeature!: MutateFeatureBehavior;\n\tprivate readFeature!: ReadFeatureBehavior;\n\n\tconstructor(options?: TerraDrawFreehandModeOptions<FreehandPolygonStyling>) {\n\t\tsuper(options, true);\n\t\tthis.updateOptions(options);\n\t}\n\n\tpublic updateOptions(\n\t\toptions?: ModeUpdateOptions<\n\t\t\tTerraDrawFreehandModeOptions<FreehandPolygonStyling>\n\t\t>,\n\t): void {\n\t\tsuper.updateOptions(options);\n\n\t\tif (options?.minDistance) {\n\t\t\tthis.minDistance = options.minDistance;\n\t\t}\n\n\t\tif (options?.smoothing !== undefined) {\n\t\t\tconst minimumSmoothing = 0;\n\t\t\tconst maximumSmoothing = 0.999;\n\t\t\tthis.smoothing = Math.min(\n\t\t\t\tMath.max(options.smoothing, minimumSmoothing),\n\t\t\t\tmaximumSmoothing,\n\t\t\t);\n\t\t}\n\n\t\tif (options?.preventPointsNearClose !== undefined) {\n\t\t\tthis.preventPointsNearClose = options.preventPointsNearClose;\n\t\t}\n\n\t\tif (options?.autoClose !== undefined) {\n\t\t\tthis.autoClose = options.autoClose;\n\t\t}\n\n\t\tif (options?.autoCloseTimeout) {\n\t\t\tthis.autoCloseTimeout = options.autoCloseTimeout;\n\t\t}\n\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = { cancel: null, finish: null };\n\t\t} else if (options?.keyEvents) {\n\t\t\tthis.keyEvents = { ...this.keyEvents, ...options.keyEvents };\n\t\t}\n\n\t\tif (options?.cursors) {\n\t\t\tthis.cursors = { ...this.cursors, ...options.cursors };\n\t\t}\n\n\t\tif (options?.drawInteraction) {\n\t\t\tthis.drawInteraction = options.drawInteraction;\n\t\t}\n\t}\n\n\tprivate moveDrawAllowed() {\n\t\treturn (\n\t\t\tthis.drawInteraction === \"click-move\" ||\n\t\t\tthis.drawInteraction === \"click-move-or-drag\"\n\t\t);\n\t}\n\n\tprivate dragDrawAllowed() {\n\t\treturn (\n\t\t\tthis.drawInteraction === \"click-drag\" ||\n\t\t\tthis.drawInteraction === \"click-move-or-drag\"\n\t\t);\n\t}\n\n\tprivate beginDrawing(\n\t\tevent: TerraDrawMouseEvent,\n\t\tdrawType: DrawType = \"click\",\n\t) {\n\t\tconst { id: createdId } = this.mutateFeature.createPolygon({\n\t\t\tcoordinates: [\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\t[event.lng, event.lat],\n\t\t\t],\n\t\t\tproperties: {\n\t\t\t\tmode: this.mode,\n\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: true,\n\t\t\t},\n\t\t});\n\n\t\tthis.currentId = createdId;\n\t\tthis.drawType = drawType;\n\n\t\tthis.closingPointId = this.mutateFeature.createGuidancePoint({\n\t\t\tcoordinate: [event.lng, event.lat],\n\t\t\ttype: COMMON_PROPERTIES.CLOSING_POINT,\n\t\t});\n\n\t\tthis.canClose = true;\n\n\t\tif (this.state !== \"drawing\") {\n\t\t\tthis.setDrawing();\n\t\t}\n\t}\n\n\tprivate addCoordinate(event: TerraDrawMouseEvent) {\n\t\tif (this.currentId === undefined || this.canClose === false) {\n\t\t\tthis.setCursor(this.cursors.start);\n\t\t\treturn;\n\t\t}\n\n\t\tconst [previousLng, previousLat] = this.readFeature.getCoordinate(\n\t\t\tthis.currentId,\n\t\t\t-2,\n\t\t);\n\t\tconst { x, y } = this.project(previousLng, previousLat);\n\t\tconst distance = cartesianDistance(\n\t\t\t{ x, y },\n\t\t\t{ x: event.containerX, y: event.containerY },\n\t\t);\n\n\t\tconst [closingLng, closingLat] = this.readFeature.getCoordinate(\n\t\t\tthis.currentId,\n\t\t\t0,\n\t\t);\n\t\tconst { x: closingX, y: closingY } = this.project(closingLng, closingLat);\n\t\tconst closingDistance = cartesianDistance(\n\t\t\t{ x: closingX, y: closingY },\n\t\t\t{ x: event.containerX, y: event.containerY },\n\t\t);\n\n\t\tif (closingDistance < this.pointerDistance) {\n\t\t\tif (this.autoClose && this.hasLeftStartingPoint) {\n\t\t\t\tthis.preventNewFeature = true;\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tthis.preventNewFeature = false;\n\t\t\t\t}, this.autoCloseTimeout);\n\n\t\t\t\tthis.close();\n\t\t\t}\n\n\t\t\tthis.setCursor(this.cursors.close);\n\n\t\t\tif (this.preventPointsNearClose) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.hasLeftStartingPoint = true;\n\t\t\tthis.setCursor(this.cursors.start);\n\t\t}\n\n\t\tif (distance < this.minDistance) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst coordinate = this.getSmoothedCoordinate(\n\t\t\t[previousLng, previousLat],\n\t\t\t[event.lng, event.lat],\n\t\t);\n\n\t\tthis.mutateFeature.updatePolygon({\n\t\t\tfeatureId: this.currentId,\n\t\t\tcoordinateMutations: [\n\t\t\t\t{\n\t\t\t\t\ttype: Mutations.InsertBefore,\n\t\t\t\t\tindex: -1,\n\t\t\t\t\tcoordinate,\n\t\t\t\t},\n\t\t\t],\n\t\t\tcontext: { updateType: UpdateTypes.Provisional },\n\t\t});\n\t}\n\n\t/**\n\t * Uses a simple linear interpolation to smooth the coordinates. The smoothing factor determines how\n\t * much influence the previous coordinate has on the new coordinate. A smoothing factor of 0 means\n\t * no smoothing (the target coordinate is used as is), while a smoothing factor close to 1 means a\n\t * lot of smoothing (the new coordinate will be very close to the previous coordinate).\n\t * The default value is 0, which means no smoothing.\n\t * @param previousCoordinate\n\t * @param targetCoordinate\n\t * @returns\n\t */\n\tprivate getSmoothedCoordinate(\n\t\tpreviousCoordinate: [number, number],\n\t\ttargetCoordinate: [number, number],\n\t): [number, number] {\n\t\tif (this.smoothing === 0) {\n\t\t\treturn targetCoordinate;\n\t\t}\n\n\t\tconst [previousLongitude, previousLatitude] = previousCoordinate;\n\t\tconst [targetLongitude, targetLatitude] = targetCoordinate;\n\n\t\treturn [\n\t\t\tpreviousLongitude * this.smoothing +\n\t\t\t\ttargetLongitude * (1 - this.smoothing),\n\t\t\tpreviousLatitude * this.smoothing + targetLatitude * (1 - this.smoothing),\n\t\t];\n\t}\n\n\tprivate close() {\n\t\tif (this.currentId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst updated = this.mutateFeature.updatePolygon({\n\t\t\tfeatureId: this.currentId,\n\t\t\tpropertyMutations: {\n\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: undefined,\n\t\t\t},\n\t\t\tcontext: { updateType: UpdateTypes.Finish, action: FinishActions.Draw },\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst featureId = this.currentId;\n\n\t\tthis.mutateFeature.deleteFeatureIfPresent(this.closingPointId);\n\n\t\tthis.canClose = false;\n\t\tthis.currentId = undefined;\n\t\tthis.closingPointId = undefined;\n\t\tthis.hasLeftStartingPoint = false;\n\t\tthis.drawType = undefined;\n\t\t// Go back to started state\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.onFinish(featureId, {\n\t\t\tmode: this.mode,\n\t\t\taction: FinishActions.Draw,\n\t\t});\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tif (!this.moveDrawAllowed() || this.drawType !== \"click\") {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.addCoordinate(event);\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\tif (\n\t\t\tthis.moveDrawAllowed() &&\n\t\t\t((event.button === \"right\" &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.rightClick, event)) ||\n\t\t\t\t(event.button === \"left\" &&\n\t\t\t\t\tthis.allowPointerEvent(this.pointerEvents.leftClick, event)) ||\n\t\t\t\t(event.isContextMenu &&\n\t\t\t\t\tthis.allowPointerEvent(this.pointerEvents.contextMenu, event)))\n\t\t) {\n\t\t\tif (this.preventNewFeature) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.canClose === false) {\n\t\t\t\tthis.beginDrawing(event);\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tif (event.key === this.keyEvents.cancel) {\n\t\t\tthis.cleanUp();\n\t\t} else if (event.key === this.keyEvents.finish) {\n\t\t\tif (this.canClose === true) {\n\t\t\t\tthis.close();\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDragStart(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (this.state === \"drawing\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.preventNewFeature) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\tthis.allowPointerEvent(this.pointerEvents.onDragStart, event) &&\n\t\t\tthis.dragDrawAllowed()\n\t\t) {\n\t\t\tthis.beginDrawing(event, \"drag\");\n\t\t\tsetMapDraggability(false);\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDrag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (\n\t\t\tthis.allowPointerEvent(this.pointerEvents.onDrag, event) &&\n\t\t\tthis.dragDrawAllowed() &&\n\t\t\tthis.drawType === \"drag\"\n\t\t) {\n\t\t\tthis.addCoordinate(event);\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDragEnd(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (\n\t\t\tthis.allowPointerEvent(this.pointerEvents.onDragEnd, event) &&\n\t\t\tthis.dragDrawAllowed() &&\n\t\t\tthis.drawType === \"drag\"\n\t\t) {\n\t\t\tthis.preventNewFeature = true;\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.preventNewFeature = false;\n\t\t\t}, this.autoCloseTimeout);\n\n\t\t\tthis.close();\n\t\t\tsetMapDraggability(true);\n\t\t}\n\t}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tconst cleanUpId = this.currentId;\n\t\tconst cleanUpClosingPointId = this.closingPointId;\n\n\t\tthis.closingPointId = undefined;\n\t\tthis.currentId = undefined;\n\t\tthis.canClose = false;\n\t\tthis.hasLeftStartingPoint = false;\n\t\tthis.drawType = undefined;\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.mutateFeature.deleteFeatureIfPresent(cleanUpId);\n\t\tthis.mutateFeature.deleteFeatureIfPresent(cleanUpClosingPointId);\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"Polygon\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tstyles.polygonFillColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.fillColor,\n\t\t\t\tstyles.polygonFillColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonOutlineColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.outlineColor,\n\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonOutlineOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.outlineOpacity,\n\t\t\t\t1,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonOutlineWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.outlineWidth,\n\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonFillOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.fillOpacity,\n\t\t\t\tstyles.polygonFillOpacity,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.zIndex = Z_INDEX.LAYER_ONE;\n\n\t\t\treturn styles;\n\t\t} else if (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"Point\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.closingPointWidth,\n\t\t\t\tstyles.pointWidth,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.closingPointColor,\n\t\t\t\tstyles.pointColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.closingPointOpacity,\n\t\t\t\tstyles.pointOpacity === undefined ? 1 : styles.pointOpacity,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.closingPointOutlineColor,\n\t\t\t\tstyles.pointOutlineColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.closingPointOutlineWidth,\n\t\t\t\t2,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.closingPointOutlineOpacity,\n\t\t\t\tstyles.pointOutlineOpacity === undefined\n\t\t\t\t\t? 1\n\t\t\t\t\t: styles.pointOutlineOpacity,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.zIndex = Z_INDEX.LAYER_FIVE;\n\n\t\t\treturn styles;\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): StoreValidation {\n\t\treturn this.validateModeFeature(feature, (baseValidatedFeature) =>\n\t\t\tValidatePolygonFeature(baseValidatedFeature, this.coordinatePrecision),\n\t\t);\n\t}\n\n\tafterFeatureUpdated(feature: GeoJSONStoreFeatures) {\n\t\t// NOTE: This handles the case we are currently drawing a polygon\n\t\t// We need to reset the drawing state because it is very complicated (impossible?)\n\t\t// to recover the drawing state after a feature update\n\t\tif (this.currentId === feature.id) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.closingPointId);\n\t\t\tthis.canClose = false;\n\t\t\tthis.currentId = undefined;\n\t\t\tthis.closingPointId = undefined;\n\t\t\tthis.hasLeftStartingPoint = false;\n\t\t}\n\t}\n\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.readFeature = new ReadFeatureBehavior(config);\n\t\tthis.mutateFeature = new MutateFeatureBehavior(config, {\n\t\t\tvalidate: this.validate,\n\t\t});\n\t}\n}\n","import { Feature, Polygon } from \"geojson\";\nimport { Unproject } from \"../../common\";\n\nexport function createBBoxFromPoint({\n\tunproject,\n\tpoint,\n\tpointerDistance,\n}: {\n\tpoint: {\n\t\tx: number;\n\t\ty: number;\n\t};\n\tunproject: Unproject;\n\tpointerDistance: number;\n}) {\n\tconst halfDist = pointerDistance / 2;\n\tconst { x, y } = point;\n\n\treturn {\n\t\ttype: \"Feature\",\n\t\tproperties: {},\n\t\tgeometry: {\n\t\t\ttype: \"Polygon\",\n\t\t\tcoordinates: [\n\t\t\t\t[\n\t\t\t\t\tunproject(x - halfDist, y - halfDist), // TopLeft\n\t\t\t\t\tunproject(x + halfDist, y - halfDist), // TopRight\n\t\t\t\t\tunproject(x + halfDist, y + halfDist), // BottomRight\n\t\t\t\t\tunproject(x - halfDist, y + halfDist), // BottomLeft\n\t\t\t\t\tunproject(x - halfDist, y - halfDist), // TopLeft\n\t\t\t\t].map((c) => [c.lng, c.lat]),\n\t\t\t],\n\t\t},\n\t} as Feature<Polygon>;\n}\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { TerraDrawMouseEvent } from \"../common\";\nimport { createBBoxFromPoint } from \"../geometry/shape/create-bbox\";\n\nexport class ClickBoundingBoxBehavior extends TerraDrawModeBehavior {\n\tconstructor(config: BehaviorConfig) {\n\t\tsuper(config);\n\t}\n\n\tpublic create(event: TerraDrawMouseEvent) {\n\t\tconst { containerX: x, containerY: y } = event;\n\t\treturn createBBoxFromPoint({\n\t\t\tunproject: this.unproject,\n\t\t\tpoint: { x, y },\n\t\t\tpointerDistance: this.pointerDistance,\n\t\t});\n\t}\n}\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { TerraDrawMouseEvent } from \"../common\";\n\nimport { Position } from \"geojson\";\nimport { cartesianDistance } from \"../geometry/measure/pixel-distance\";\n\nexport class PixelDistanceBehavior extends TerraDrawModeBehavior {\n\tconstructor(config: BehaviorConfig) {\n\t\tsuper(config);\n\t}\n\tpublic measure(clickEvent: TerraDrawMouseEvent, secondCoordinate: Position) {\n\t\tconst { x, y } = this.project(secondCoordinate[0], secondCoordinate[1]);\n\n\t\tconst distance = cartesianDistance(\n\t\t\t{ x, y },\n\t\t\t{ x: clickEvent.containerX, y: clickEvent.containerY },\n\t\t);\n\n\t\treturn distance;\n\t}\n}\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { TerraDrawMouseEvent } from \"../common\";\nimport { Feature, Position } from \"geojson\";\nimport { ClickBoundingBoxBehavior } from \"./click-bounding-box.behavior\";\nimport { BBoxPolygon, FeatureId } from \"../store/store\";\nimport { PixelDistanceBehavior } from \"./pixel-distance.behavior\";\n\nexport class CoordinateSnappingBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly pixelDistance: PixelDistanceBehavior,\n\t\tprivate readonly clickBoundingBox: ClickBoundingBoxBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\t/** Returns the nearest snappable coordinate - on first click there is no currentId so no need to provide */\n\tpublic getSnappableCoordinateFirstClick = (event: TerraDrawMouseEvent) => {\n\t\tconst snappble = this.getSnappable(event, (feature) => {\n\t\t\treturn Boolean(\n\t\t\t\tfeature.properties && feature.properties.mode === this.mode,\n\t\t\t);\n\t\t});\n\n\t\treturn snappble.coordinate;\n\t};\n\n\tpublic getSnappableCoordinate = (\n\t\tevent: TerraDrawMouseEvent,\n\t\tcurrentFeatureId: FeatureId,\n\t) => {\n\t\tconst snappable = this.getSnappable(event, (feature) => {\n\t\t\treturn Boolean(\n\t\t\t\tfeature.properties &&\n\t\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\t\tfeature.id !== currentFeatureId,\n\t\t\t);\n\t\t});\n\n\t\treturn snappable.coordinate;\n\t};\n\n\tpublic getSnappable(\n\t\tevent: TerraDrawMouseEvent,\n\t\tfilter?: (feature: Feature) => boolean,\n\t) {\n\t\tconst bbox = this.clickBoundingBox.create(event) as BBoxPolygon;\n\n\t\tconst features = this.store.search(bbox, filter);\n\n\t\tconst closest: {\n\t\t\tcoordinate: undefined | Position;\n\t\t\tminDist: number;\n\t\t\tfeatureId: undefined | FeatureId;\n\t\t\tfeatureCoordinateIndex: undefined | number;\n\t\t} = {\n\t\t\tfeatureId: undefined,\n\t\t\tfeatureCoordinateIndex: undefined,\n\t\t\tcoordinate: undefined,\n\t\t\tminDist: Infinity,\n\t\t};\n\n\t\tfeatures.forEach((feature) => {\n\t\t\tlet coordinates: Position[];\n\t\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\t\tcoordinates = feature.geometry.coordinates[0];\n\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\tcoordinates = feature.geometry.coordinates;\n\t\t\t} else {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcoordinates.forEach((coord, coordIndex) => {\n\t\t\t\tconst dist = this.pixelDistance.measure(event, coord);\n\t\t\t\tif (dist < closest.minDist && dist < this.pointerDistance) {\n\t\t\t\t\tclosest.coordinate = coord;\n\t\t\t\t\tclosest.minDist = dist;\n\t\t\t\t\tclosest.featureId = feature.id;\n\t\t\t\t\tclosest.featureCoordinateIndex = coordIndex;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\treturn closest;\n\t}\n}\n","import { Position } from \"geojson\";\nimport {\n\tdegreesToRadians,\n\tlengthToRadians,\n\tradiansToDegrees,\n} from \"../helpers\";\nimport { CartesianPoint } from \"../../common\";\n\n// Adapted from @turf/destination module which is MIT Licensed\n// https://github.com/Turfjs/turf/blob/master/packages/turf-desination/index.ts\n\nexport function destination(\n\torigin: Position,\n\tdistance: number,\n\tbearing: number,\n): Position {\n\tconst longitude1 = degreesToRadians(origin[0]);\n\tconst latitude1 = degreesToRadians(origin[1]);\n\tconst bearingRad = degreesToRadians(bearing);\n\tconst radians = lengthToRadians(distance);\n\n\tconst latitude2 = Math.asin(\n\t\tMath.sin(latitude1) * Math.cos(radians) +\n\t\t\tMath.cos(latitude1) * Math.sin(radians) * Math.cos(bearingRad),\n\t);\n\tconst longitude2 =\n\t\tlongitude1 +\n\t\tMath.atan2(\n\t\t\tMath.sin(bearingRad) * Math.sin(radians) * Math.cos(latitude1),\n\t\t\tMath.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2),\n\t\t);\n\tconst lng = radiansToDegrees(longitude2);\n\tconst lat = radiansToDegrees(latitude2);\n\n\treturn [lng, lat];\n}\n\n// Function to create a destination point in Web Mercator projection\nexport function webMercatorDestination(\n\t{ x, y }: CartesianPoint,\n\tdistance: number,\n\tbearing: number,\n): CartesianPoint {\n\t// Convert origin to Web Mercator\n\tconst bearingRad = degreesToRadians(bearing);\n\n\t// Calculate the destination coordinates\n\tconst deltaX = distance * Math.cos(bearingRad);\n\tconst deltaY = distance * Math.sin(bearingRad);\n\n\tconst newX = x + deltaX;\n\tconst newY = y + deltaY;\n\n\treturn { x: newX, y: newY };\n}\n","import { Position } from \"geojson\";\nimport { degreesToRadians, radiansToDegrees } from \"../helpers\";\nimport { CartesianPoint } from \"../../common\";\n\n// Adapted from the @turf/bearing module which is MIT Licensed\n// https://github.com/Turfjs/turf/tree/master/packages/turf-bearing\n\nexport function bearing(start: Position, end: Position): number {\n\tconst lon1 = degreesToRadians(start[0]);\n\tconst lon2 = degreesToRadians(end[0]);\n\tconst lat1 = degreesToRadians(start[1]);\n\tconst lat2 = degreesToRadians(end[1]);\n\tconst a = Math.sin(lon2 - lon1) * Math.cos(lat2);\n\tconst b =\n\t\tMath.cos(lat1) * Math.sin(lat2) -\n\t\tMath.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);\n\n\treturn radiansToDegrees(Math.atan2(a, b));\n}\n\nexport function webMercatorBearing(\n\t{ x: x1, y: y1 }: CartesianPoint,\n\t{ x: x2, y: y2 }: CartesianPoint,\n): number {\n\tconst deltaX = x2 - x1;\n\tconst deltaY = y2 - y1;\n\n\tif (deltaX === 0 && deltaY === 0) {\n\t\treturn 0; // No movement\n\t}\n\n\t// Calculate the angle in radians\n\tlet angle = Math.atan2(deltaY, deltaX);\n\n\t// Convert the angle to degrees\n\tangle = angle * (180 / Math.PI);\n\n\t// Normalize to -180 to 180\n\tif (angle > 180) {\n\t\tangle -= 360;\n\t} else if (angle < -180) {\n\t\tangle += 360;\n\t}\n\n\treturn angle;\n}\n\nexport function normalizeBearing(bearing: number): number {\n\treturn (bearing + 360) % 360;\n}\n","import { LineString, Position } from \"geojson\";\nimport { destination } from \"./destination\";\nimport { bearing } from \"./bearing\";\nimport { haversineDistanceKilometers } from \"./haversine-distance\";\n\n// Adapted from @turf/line-slice-along module which is MIT licensed\n// https://github.com/Turfjs/turf/blob/master/packages/turf-line-slice-along/index.ts\n\nexport function lineSliceAlong(\n\tcoords: LineString[\"coordinates\"],\n\tstartDist: number,\n\tstopDist: number,\n): Position[] {\n\tconst slice: Position[] = [];\n\n\tconst origCoordsLength = coords.length;\n\n\tlet travelled = 0;\n\tlet overshot, direction, interpolated;\n\tfor (let i = 0; i < coords.length; i++) {\n\t\tif (startDist >= travelled && i === coords.length - 1) {\n\t\t\tbreak;\n\t\t} else if (travelled > startDist && slice.length === 0) {\n\t\t\tovershot = startDist - travelled;\n\t\t\tif (!overshot) {\n\t\t\t\tslice.push(coords[i]);\n\t\t\t\treturn slice;\n\t\t\t}\n\t\t\tdirection = bearing(coords[i], coords[i - 1]) - 180;\n\t\t\tinterpolated = destination(coords[i], overshot, direction);\n\t\t\tslice.push(interpolated);\n\t\t}\n\n\t\tif (travelled >= stopDist) {\n\t\t\tovershot = stopDist - travelled;\n\t\t\tif (!overshot) {\n\t\t\t\tslice.push(coords[i]);\n\t\t\t\treturn slice;\n\t\t\t}\n\t\t\tdirection = bearing(coords[i], coords[i - 1]) - 180;\n\t\t\tinterpolated = destination(coords[i], overshot, direction);\n\t\t\tslice.push(interpolated);\n\t\t\treturn slice;\n\t\t}\n\n\t\tif (travelled >= startDist) {\n\t\t\tslice.push(coords[i]);\n\t\t}\n\n\t\tif (i === coords.length - 1) {\n\t\t\treturn slice;\n\t\t}\n\n\t\ttravelled += haversineDistanceKilometers(coords[i], coords[i + 1]);\n\t}\n\n\tif (travelled < startDist && coords.length === origCoordsLength) {\n\t\tthrow new Error(\"Start position is beyond line\");\n\t}\n\n\tconst last = coords[coords.length - 1];\n\treturn [last, last];\n}\n","import { Position } from \"geojson\";\n\nfunction toRadians(degrees: number): number {\n\treturn degrees * (Math.PI / 180);\n}\n\nfunction toDegrees(radians: number): number {\n\treturn radians * (180 / Math.PI);\n}\n\nexport function generateGreatCircleCoordinates(\n\tstart: Position,\n\tend: Position,\n\tnumberOfPoints: number,\n): Position[] {\n\tconst points: Position[] = [];\n\n\tconst lat1 = toRadians(start[1]);\n\tconst lon1 = toRadians(start[0]);\n\tconst lat2 = toRadians(end[1]);\n\tconst lon2 = toRadians(end[0]);\n\n\tnumberOfPoints += 1;\n\n\t// Calculate the angular distance between the two points using the Haversine formula\n\tconst d =\n\t\t2 *\n\t\tMath.asin(\n\t\t\tMath.sqrt(\n\t\t\t\tMath.sin((lat2 - lat1) / 2) ** 2 +\n\t\t\t\t\tMath.cos(lat1) * Math.cos(lat2) * Math.sin((lon2 - lon1) / 2) ** 2,\n\t\t\t),\n\t\t);\n\n\tif (d === 0 || isNaN(d)) {\n\t\t// Start and end coordinates are the same, or distance calculation failed, return empty array\n\t\treturn points;\n\t}\n\n\tfor (let i = 0; i <= numberOfPoints; i++) {\n\t\tconst f = i / numberOfPoints; // Fraction of the total distance for the current point\n\t\tconst A = Math.sin((1 - f) * d) / Math.sin(d); // Interpolation factor A\n\t\tconst B = Math.sin(f * d) / Math.sin(d); // Interpolation factor B\n\n\t\t// Calculate the x, y, z coordinates of the intermediate point\n\t\tconst x =\n\t\t\tA * Math.cos(lat1) * Math.cos(lon1) + B * Math.cos(lat2) * Math.cos(lon2);\n\t\tconst y =\n\t\t\tA * Math.cos(lat1) * Math.sin(lon1) + B * Math.cos(lat2) * Math.sin(lon2);\n\t\tconst z = A * Math.sin(lat1) + B * Math.sin(lat2);\n\n\t\t// Calculate the latitude and longitude of the intermediate point from the x, y, z coordinates\n\t\tif (isNaN(x) || isNaN(y) || isNaN(z)) {\n\t\t\t// Skip this point if any coordinate is NaN\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst lat = Math.atan2(z, Math.sqrt(x ** 2 + y ** 2));\n\t\tconst lon = Math.atan2(y, x);\n\n\t\tif (isNaN(lat) || isNaN(lon)) {\n\t\t\t// Skip this point if any coordinate is NaN\n\t\t\tcontinue;\n\t\t}\n\n\t\tpoints.push([toDegrees(lon), toDegrees(lat)]);\n\t}\n\n\treturn points.slice(1, -1);\n}\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { Position } from \"geojson\";\nimport { haversineDistanceKilometers } from \"../geometry/measure/haversine-distance\";\nimport { lineSliceAlong } from \"../geometry/measure/slice-along\";\nimport { limitPrecision } from \"../geometry/limit-decimal-precision\";\nimport { generateGreatCircleCoordinates } from \"../geometry/shape/great-circle-coordinates\";\n\nexport class InsertCoordinatesBehavior extends TerraDrawModeBehavior {\n\tconstructor(readonly config: BehaviorConfig) {\n\t\tsuper(config);\n\t}\n\n\tpublic generateInsertionCoordinates(\n\t\tcoordinateOne: Position,\n\t\tcoordinateTwo: Position,\n\t\tsegmentLength: number,\n\t): Position[] {\n\t\tconst line = [coordinateOne, coordinateTwo];\n\n\t\tlet lineLength = 0;\n\t\tfor (let i = 0; i < line.length - 1; i++) {\n\t\t\tlineLength += haversineDistanceKilometers(line[0], line[1]);\n\t\t}\n\n\t\t// If the line is shorter than the segment length then the original line is returned.\n\t\tif (lineLength <= segmentLength) {\n\t\t\treturn line;\n\t\t}\n\n\t\tlet numberOfSegments = lineLength / segmentLength - 1;\n\n\t\t// If numberOfSegments is integer, no need to plus 1\n\t\tif (!Number.isInteger(numberOfSegments)) {\n\t\t\tnumberOfSegments = Math.floor(numberOfSegments) + 1;\n\t\t}\n\n\t\tconst segments: Position[][] = [];\n\t\tfor (let i = 0; i < numberOfSegments; i++) {\n\t\t\tconst outline = lineSliceAlong(\n\t\t\t\tline,\n\t\t\t\tsegmentLength * i,\n\t\t\t\tsegmentLength * (i + 1),\n\t\t\t);\n\t\t\tsegments.push(outline);\n\t\t}\n\n\t\tconst coordinates: Position[] = [];\n\t\tfor (let i = 0; i < segments.length; i++) {\n\t\t\tconst line = segments[i];\n\t\t\tcoordinates.push(line[1]);\n\t\t}\n\n\t\tconst limitedCoordinates = this.limitCoordinates(coordinates);\n\n\t\treturn limitedCoordinates;\n\t}\n\n\tpublic generateInsertionGeodesicCoordinates(\n\t\tcoordinateOne: Position,\n\t\tcoordinateTwo: Position,\n\t\tsegmentLength: number,\n\t): Position[] {\n\t\tconst distance = haversineDistanceKilometers(coordinateOne, coordinateTwo);\n\t\tconst numberOfPoints = Math.floor(distance / segmentLength);\n\t\tconst coordinates = generateGreatCircleCoordinates(\n\t\t\tcoordinateOne,\n\t\t\tcoordinateTwo,\n\t\t\tnumberOfPoints,\n\t\t);\n\t\tconst limitedCoordinates = this.limitCoordinates(coordinates);\n\n\t\treturn limitedCoordinates;\n\t}\n\n\tprivate limitCoordinates(coordinates: Position[]) {\n\t\treturn coordinates.map((coordinate) => [\n\t\t\tlimitPrecision(coordinate[0], this.config.coordinatePrecision),\n\t\t\tlimitPrecision(coordinate[1], this.config.coordinatePrecision),\n\t\t]);\n\t}\n}\n","import { Validation } from \"../common\";\nimport { GeoJSONStoreFeatures } from \"../terra-draw\";\nimport {\n\tcoordinateIsValid,\n\tcoordinatePrecisionIsValid,\n} from \"../geometry/boolean/is-valid-coordinate\";\n\nexport const ValidationReasonFeatureIsNotALineString =\n\t\"Feature is not a LineString\";\nexport const ValidationReasonFeatureHasLessThanTwoCoordinates =\n\t\"Feature has less than 2 coordinates\";\nexport const ValidationReasonFeatureInvalidCoordinates =\n\t\"Feature has invalid coordinates\";\nexport const ValidationReasonFeatureInvalidCoordinatePrecision =\n\t\"Feature has coordinates with excessive precision\";\n\nexport function ValidateLineStringFeature(\n\tfeature: GeoJSONStoreFeatures,\n\tcoordinatePrecision: number,\n): ReturnType<Validation> {\n\tif (feature.geometry.type !== \"LineString\") {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\treason: ValidationReasonFeatureIsNotALineString,\n\t\t};\n\t}\n\n\tif (feature.geometry.coordinates.length < 2) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\treason: ValidationReasonFeatureHasLessThanTwoCoordinates,\n\t\t};\n\t}\n\n\tfor (let i = 0; i < feature.geometry.coordinates.length; i++) {\n\t\tif (!coordinateIsValid(feature.geometry.coordinates[i])) {\n\t\t\treturn {\n\t\t\t\tvalid: false,\n\t\t\t\treason: ValidationReasonFeatureInvalidCoordinates,\n\t\t\t};\n\t\t}\n\n\t\tif (\n\t\t\t!coordinatePrecisionIsValid(\n\t\t\t\tfeature.geometry.coordinates[i],\n\t\t\t\tcoordinatePrecision,\n\t\t\t)\n\t\t) {\n\t\t\treturn {\n\t\t\t\tvalid: false,\n\t\t\t\treason: ValidationReasonFeatureInvalidCoordinatePrecision,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn { valid: true };\n}\n","import { Feature, Point, Position, LineString } from \"geojson\";\nimport { degreesToRadians, radiansToDegrees } from \"./helpers\";\nimport { haversineDistanceKilometers } from \"./measure/haversine-distance\";\n\n// nearestPointOnLine is adapted from the @turf/midpoint which is MIT Licensed\n// https://github.com/Turfjs/turf/tree/master/packages/turf-nearest-point-on-line\n\nexport function nearestPointOnLine(\n\tinputCoordinate: Position,\n\tlines: [Position, Position][],\n):\n\t| {\n\t\t\tcoordinate: Position;\n\t\t\tdistance: number;\n\t\t\tlineIndex: number;\n\t  }\n\t| undefined {\n\tlet closestPoint: Position = [Infinity, Infinity];\n\tlet closestDistance = Infinity;\n\tlet lineIndex = 0;\n\n\tfor (let line of lines) {\n\t\tconst startPosition: Position = line[0];\n\t\tconst stopPosition: Position = line[1];\n\n\t\t// sectionLength\n\t\tlet intersectPosition: Position;\n\t\tlet intersectDistance: number = Infinity;\n\n\t\t// Short circuit if snap point is start or end position of the line segment.\n\t\tif (\n\t\t\tstartPosition[0] === inputCoordinate[0] &&\n\t\t\tstartPosition[1] === inputCoordinate[1]\n\t\t) {\n\t\t\tintersectPosition = startPosition;\n\t\t} else if (\n\t\t\tstopPosition[0] === inputCoordinate[0] &&\n\t\t\tstopPosition[1] === inputCoordinate[1]\n\t\t) {\n\t\t\tintersectPosition = stopPosition;\n\t\t} else {\n\t\t\t// Otherwise, find the nearest point the hard way.\n\t\t\t[intersectPosition] = nearestPointOnSegment(\n\t\t\t\tstartPosition,\n\t\t\t\tstopPosition,\n\t\t\t\tinputCoordinate,\n\t\t\t);\n\t\t}\n\n\t\tif (intersectPosition) {\n\t\t\tintersectDistance = haversineDistanceKilometers(\n\t\t\t\tinputCoordinate,\n\t\t\t\tintersectPosition,\n\t\t\t);\n\n\t\t\tif (intersectDistance < closestDistance) {\n\t\t\t\tclosestPoint = intersectPosition;\n\t\t\t\tclosestDistance = intersectDistance;\n\t\t\t\tlineIndex = lines.indexOf(line);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn closestDistance === Infinity\n\t\t? undefined\n\t\t: { coordinate: closestPoint, distance: closestDistance, lineIndex };\n}\n\n/*\n * Plan is to externalise these vector functions to a simple third party\n * library.\n * Possible candidate is @amandaghassaei/vector-math though having some import\n * issues.\n */\ntype Vector = [number, number, number];\n\nfunction dot(v1: Vector, v2: Vector): number {\n\tconst [v1x, v1y, v1z] = v1;\n\tconst [v2x, v2y, v2z] = v2;\n\treturn v1x * v2x + v1y * v2y + v1z * v2z;\n}\n\n// https://en.wikipedia.org/wiki/Cross_product\nfunction cross(v1: Vector, v2: Vector): Vector {\n\tconst [v1x, v1y, v1z] = v1;\n\tconst [v2x, v2y, v2z] = v2;\n\treturn [v1y * v2z - v1z * v2y, v1z * v2x - v1x * v2z, v1x * v2y - v1y * v2x];\n}\n\nfunction magnitude(v: Vector) {\n\treturn Math.sqrt(Math.pow(v[0], 2) + Math.pow(v[1], 2) + Math.pow(v[2], 2));\n}\n\nfunction angle(v1: Vector, v2: Vector): number {\n\tconst theta = dot(v1, v2) / (magnitude(v1) * magnitude(v2));\n\treturn Math.acos(Math.min(Math.max(theta, -1), 1));\n}\n\nfunction lngLatToVector(a: Position): Vector {\n\tconst lat = degreesToRadians(a[1]);\n\tconst lng = degreesToRadians(a[0]);\n\treturn [\n\t\tMath.cos(lat) * Math.cos(lng),\n\t\tMath.cos(lat) * Math.sin(lng),\n\t\tMath.sin(lat),\n\t];\n}\n\nfunction vectorToLngLat(v: Vector): Position {\n\tconst [x, y, z] = v;\n\tconst lat = radiansToDegrees(Math.asin(z));\n\tconst lng = radiansToDegrees(Math.atan2(y, x));\n\n\treturn [lng, lat];\n}\n\nfunction nearestPointOnSegment(\n\tposA: Position, // start point of segment to measure to\n\tposB: Position, // end point of segment to measure to\n\tposC: Position, // point to measure from\n): [Position, boolean, boolean] {\n\t// Based heavily on this article on finding cross track distance to an arc:\n\t// https://gis.stackexchange.com/questions/209540/projecting-cross-track-distance-on-great-circle\n\n\t// Convert spherical (lng, lat) to cartesian vector coords (x, y, z)\n\t// In the below https://tikz.net/spherical_1/ we convert lng (𝜙) and lat (𝜃)\n\t// into vectors with x, y, and z components with a length (r) of 1.\n\tconst A = lngLatToVector(posA); // the vector from 0,0,0 to posA\n\tconst B = lngLatToVector(posB); // ... to posB\n\tconst C = lngLatToVector(posC); // ... to posC\n\n\t// Components of target point.\n\tconst [Cx, Cy, Cz] = C;\n\n\t// Calculate coefficients.\n\tconst [D, E, F] = cross(A, B);\n\tconst a = E * Cz - F * Cy;\n\tconst b = F * Cx - D * Cz;\n\tconst c = D * Cy - E * Cx;\n\n\tconst f = c * E - b * F;\n\tconst g = a * F - c * D;\n\tconst h = b * D - a * E;\n\n\tconst t = 1 / Math.sqrt(Math.pow(f, 2) + Math.pow(g, 2) + Math.pow(h, 2));\n\n\t// Vectors to the two points these great circles intersect.\n\tconst I1: Vector = [f * t, g * t, h * t];\n\tconst I2: Vector = [-1 * f * t, -1 * g * t, -1 * h * t];\n\n\t// Figure out which is the closest intersection to this segment of the great\n\t// circle.\n\tconst angleAB = angle(A, B);\n\tconst angleAI1 = angle(A, I1);\n\tconst angleBI1 = angle(B, I1);\n\tconst angleAI2 = angle(A, I2);\n\tconst angleBI2 = angle(B, I2);\n\n\tlet I: Vector;\n\n\tif (\n\t\t(angleAI1 < angleAI2 && angleAI1 < angleBI2) ||\n\t\t(angleBI1 < angleAI2 && angleBI1 < angleBI2)\n\t) {\n\t\tI = I1;\n\t} else {\n\t\tI = I2;\n\t}\n\n\t// I is the closest intersection to the segment, though might not actually be\n\t// ON the segment.\n\n\t// If angle AI or BI is greater than angleAB, I lies on the circle *beyond* A\n\t// and B so use the closest of A or B as the intersection\n\tif (angle(A, I) > angleAB || angle(B, I) > angleAB) {\n\t\tif (\n\t\t\thaversineDistanceKilometers(vectorToLngLat(I), vectorToLngLat(A)) <=\n\t\t\thaversineDistanceKilometers(vectorToLngLat(I), vectorToLngLat(B))\n\t\t) {\n\t\t\treturn [vectorToLngLat(A), true, false];\n\t\t} else {\n\t\t\treturn [vectorToLngLat(B), false, true];\n\t\t}\n\t}\n\n\t// As angleAI nor angleBI don't exceed angleAB, I is on the segment\n\treturn [vectorToLngLat(I), false, false];\n}\n","import { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { TerraDrawMouseEvent } from \"../common\";\nimport { Feature, Position } from \"geojson\";\nimport { ClickBoundingBoxBehavior } from \"./click-bounding-box.behavior\";\nimport { BBoxPolygon, FeatureId } from \"../store/store\";\nimport { PixelDistanceBehavior } from \"./pixel-distance.behavior\";\nimport { nearestPointOnLine } from \"../geometry/point-on-line\";\nimport { webMercatorNearestPointOnLine } from \"../geometry/web-mercator-point-on-line\";\nimport { limitPrecision } from \"../geometry/limit-decimal-precision\";\n\nexport class LineSnappingBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly pixelDistance: PixelDistanceBehavior,\n\t\tprivate readonly clickBoundingBox: ClickBoundingBoxBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\t/** Returns the nearest snappable coordinate - on first click there is no currentId so no need to provide */\n\tpublic getSnappableCoordinateFirstClick = (event: TerraDrawMouseEvent) => {\n\t\tconst snappable = this.getSnappable(event, (feature) => {\n\t\t\treturn Boolean(\n\t\t\t\tfeature.properties && feature.properties.mode === this.mode,\n\t\t\t);\n\t\t});\n\n\t\treturn snappable.coordinate\n\t\t\t? [\n\t\t\t\t\tlimitPrecision(\n\t\t\t\t\t\tsnappable.coordinate[0],\n\t\t\t\t\t\tthis.config.coordinatePrecision,\n\t\t\t\t\t),\n\t\t\t\t\tlimitPrecision(\n\t\t\t\t\t\tsnappable.coordinate[1],\n\t\t\t\t\t\tthis.config.coordinatePrecision,\n\t\t\t\t\t),\n\t\t\t\t]\n\t\t\t: undefined;\n\t};\n\n\tpublic getSnappableCoordinate = (\n\t\tevent: TerraDrawMouseEvent,\n\t\tcurrentFeatureId: FeatureId,\n\t) => {\n\t\tconst snappable = this.getSnappable(event, (feature) => {\n\t\t\treturn Boolean(\n\t\t\t\tfeature.properties &&\n\t\t\t\t\tfeature.properties.mode === this.mode &&\n\t\t\t\t\tfeature.id !== currentFeatureId,\n\t\t\t);\n\t\t});\n\n\t\treturn snappable.coordinate\n\t\t\t? [\n\t\t\t\t\tlimitPrecision(\n\t\t\t\t\t\tsnappable.coordinate[0],\n\t\t\t\t\t\tthis.config.coordinatePrecision,\n\t\t\t\t\t),\n\t\t\t\t\tlimitPrecision(\n\t\t\t\t\t\tsnappable.coordinate[1],\n\t\t\t\t\t\tthis.config.coordinatePrecision,\n\t\t\t\t\t),\n\t\t\t\t]\n\t\t\t: undefined;\n\t};\n\n\tpublic getSnappable(\n\t\tevent: TerraDrawMouseEvent,\n\t\tfilter?: (feature: Feature) => boolean,\n\t) {\n\t\tconst boundingBox = this.clickBoundingBox.create(event) as BBoxPolygon;\n\t\tconst features = this.store.search(boundingBox, filter);\n\t\tconst closest: {\n\t\t\tcoordinate: undefined | Position;\n\t\t\tminDistance: number;\n\t\t\tfeatureId: undefined | FeatureId;\n\t\t\tfeatureCoordinateIndex: undefined | number;\n\t\t} = {\n\t\t\tfeatureId: undefined,\n\t\t\tfeatureCoordinateIndex: undefined,\n\t\t\tcoordinate: undefined,\n\t\t\tminDistance: Infinity,\n\t\t};\n\t\tfeatures.forEach((feature) => {\n\t\t\tlet coordinates: Position[];\n\t\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\t\tcoordinates = feature.geometry.coordinates[0];\n\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\tcoordinates = feature.geometry.coordinates;\n\t\t\t} else {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst lines: [Position, Position][] = [];\n\n\t\t\tfor (let i = 0; i < coordinates.length - 1; i++) {\n\t\t\t\tlines.push([coordinates[i], coordinates[i + 1]]);\n\t\t\t}\n\n\t\t\tlet nearest:\n\t\t\t\t| {\n\t\t\t\t\t\tcoordinate: Position;\n\t\t\t\t\t\tlineIndex: number;\n\t\t\t\t\t\tdistance: number;\n\t\t\t\t  }\n\t\t\t\t| undefined;\n\n\t\t\tconst lngLat: Position = [event.lng, event.lat];\n\n\t\t\tif (this.config.projection === \"web-mercator\") {\n\t\t\t\tnearest = webMercatorNearestPointOnLine(lngLat, lines);\n\t\t\t} else if (this.config.projection === \"globe\") {\n\t\t\t\tnearest = nearestPointOnLine(lngLat, lines);\n\t\t\t}\n\n\t\t\tif (!nearest) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst distance = this.pixelDistance.measure(event, nearest.coordinate);\n\t\t\tif (distance < closest.minDistance && distance < this.pointerDistance) {\n\t\t\t\tclosest.featureId = feature.id;\n\t\t\t\tclosest.coordinate = [\n\t\t\t\t\tlimitPrecision(\n\t\t\t\t\t\tnearest.coordinate[0],\n\t\t\t\t\t\tthis.config.coordinatePrecision,\n\t\t\t\t\t),\n\t\t\t\t\tlimitPrecision(\n\t\t\t\t\t\tnearest.coordinate[1],\n\t\t\t\t\t\tthis.config.coordinatePrecision,\n\t\t\t\t\t),\n\t\t\t\t];\n\t\t\t\tclosest.featureCoordinateIndex = nearest.lineIndex;\n\t\t\t\tclosest.minDistance = distance;\n\t\t\t}\n\t\t});\n\n\t\treturn closest;\n\t}\n}\n","import { Position } from \"geojson\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"./project/web-mercator\";\nimport { cartesianDistance } from \"./measure/pixel-distance\";\nimport { CartesianPoint } from \"../common\";\n\n// nearestPointOnLine is adapted from the @turf/midpoint which is MIT Licensed\n// https://github.com/Turfjs/turf/tree/master/packages/turf-nearest-point-on-line\n\n/**\n * Takes two points and finds the closest point on the line between them to a third point.\n * @param lines\n * @param inputCoordinate\n * @returns\n */\nexport function webMercatorNearestPointOnLine(\n\tinputCoordinate: Position,\n\tlines: [Position, Position][],\n):\n\t| {\n\t\t\tcoordinate: Position;\n\t\t\tlineIndex: number;\n\t\t\tdistance: number;\n\t  }\n\t| undefined {\n\tlet closestPoint: Position = [Infinity, Infinity];\n\tlet closestDistance = Infinity;\n\tlet lineIndex = 0;\n\n\tfor (let line of lines) {\n\t\tconst startPosition: Position = line[0];\n\t\tconst stopPosition: Position = line[1];\n\n\t\t// sectionLength\n\t\tlet intersectPosition: Position;\n\t\tlet intersectDistance: number = Infinity;\n\n\t\tconst start = lngLatToWebMercatorXY(startPosition[0], startPosition[1]);\n\t\tconst stop = lngLatToWebMercatorXY(stopPosition[0], stopPosition[1]);\n\t\tconst source = lngLatToWebMercatorXY(\n\t\t\tinputCoordinate[0],\n\t\t\tinputCoordinate[1],\n\t\t);\n\n\t\t// Short circuit if snap point is start or end position of the line segment.\n\t\tif (\n\t\t\tstartPosition[0] === inputCoordinate[0] &&\n\t\t\tstartPosition[1] === inputCoordinate[1]\n\t\t) {\n\t\t\tintersectPosition = startPosition;\n\t\t} else if (\n\t\t\tstopPosition[0] === inputCoordinate[0] &&\n\t\t\tstopPosition[1] === inputCoordinate[1]\n\t\t) {\n\t\t\tintersectPosition = stopPosition;\n\t\t} else {\n\t\t\t// Otherwise, find the nearest point the hard way.\n\t\t\tconst { x, y } = findNearestPointOnLine(start, stop, source);\n\n\t\t\tconst { lng, lat } = webMercatorXYToLngLat(x, y);\n\t\t\tintersectPosition = [lng, lat];\n\t\t}\n\n\t\tif (intersectPosition) {\n\t\t\tintersectDistance = cartesianDistance(\n\t\t\t\tsource,\n\t\t\t\tlngLatToWebMercatorXY(intersectPosition[0], intersectPosition[1]),\n\t\t\t);\n\n\t\t\tif (intersectDistance < closestDistance) {\n\t\t\t\tclosestPoint = intersectPosition;\n\t\t\t\tclosestDistance = intersectDistance;\n\t\t\t\tlineIndex = lines.indexOf(line);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn closestDistance === Infinity\n\t\t? undefined\n\t\t: {\n\t\t\t\tcoordinate: closestPoint,\n\t\t\t\tlineIndex: lineIndex,\n\t\t\t\tdistance: closestDistance,\n\t\t\t};\n}\n\n/**\n * Finds the nearest Web Mercator coordinate on a line to a given coordinate.\n * @param pointA - The first point of the line (Web Mercator coordinate).\n * @param pointB - The second point of the line (Web Mercator coordinate).\n * @param target - The target point to which the nearest point on the line is calculated.\n * @returns The nearest Web Mercator coordinate on the line to the target.\n */\nfunction findNearestPointOnLine(\n\tpointA: CartesianPoint,\n\tpointB: CartesianPoint,\n\ttarget: CartesianPoint,\n): CartesianPoint {\n\t// Vector from pointA to pointB\n\tconst lineVector = {\n\t\tx: pointB.x - pointA.x,\n\t\ty: pointB.y - pointA.y,\n\t};\n\n\t// Vector from pointA to the target point\n\tconst targetVector = {\n\t\tx: target.x - pointA.x,\n\t\ty: target.y - pointA.y,\n\t};\n\n\t// Compute the dot product of the target vector with the line vector\n\tconst dotProduct =\n\t\ttargetVector.x * lineVector.x + targetVector.y * lineVector.y;\n\n\t// Compute the length squared of the line vector\n\tconst lineLengthSquared =\n\t\tlineVector.x * lineVector.x + lineVector.y * lineVector.y;\n\n\t// Find the projection of the target vector onto the line vector\n\tconst t = Math.max(0, Math.min(1, dotProduct / lineLengthSquared));\n\n\t// Compute the nearest point on the line\n\tconst nearestPoint = {\n\t\tx: pointA.x + t * lineVector.x,\n\t\ty: pointA.y + t * lineVector.y,\n\t};\n\n\treturn nearestPoint;\n}\n","import { Position } from \"geojson\";\n\nexport function isPolygonArray(\n\tcoords: Position[] | Position[][],\n): coords is Position[][] {\n\treturn (\n\t\tArray.isArray(coords) &&\n\t\tcoords.length > 0 &&\n\t\tArray.isArray(coords[0]) &&\n\t\tArray.isArray(coords[0][0])\n\t);\n}\n\nexport const getUnclosedCoordinates = (\n\tfeatureCoordinates: Position[] | Position[][],\n): Position[] => {\n\tconst isPolygon = isPolygonArray(featureCoordinates);\n\tconst coordinates = isPolygon\n\t\t? (featureCoordinates as Position[][])[0].slice(0, -1)\n\t\t: (featureCoordinates as Position[]);\n\n\treturn coordinates;\n};\n\nexport const getClosedCoordinates = (\n\tfeatureCoordinates: Position[] | Position[][],\n): Position[] => {\n\tconst isPolygon = isPolygonArray(featureCoordinates);\n\tconst coordinates = isPolygon\n\t\t? (featureCoordinates as Position[][])[0]\n\t\t: (featureCoordinates as Position[]);\n\n\treturn coordinates;\n};\n","import { Position } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { COMMON_PROPERTIES, TerraDrawMouseEvent } from \"../common\";\nimport { PixelDistanceBehavior } from \"./pixel-distance.behavior\";\nimport { MutateFeatureBehavior } from \"./mutate-feature.behavior\";\nimport { FeatureId } from \"../extend\";\nimport { ReadFeatureBehavior } from \"./read-feature.behavior\";\nimport {\n\tgetClosedCoordinates,\n\tisPolygonArray,\n} from \"../geometry/get-coordinates\";\n\nexport class ClosingPointsBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly pixelDistance: PixelDistanceBehavior,\n\t\tprivate readonly mutateFeatureBehavior: MutateFeatureBehavior,\n\t\tprivate readonly readFeatureBehavior: ReadFeatureBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tprivate _startEndPoints: FeatureId[] = [];\n\n\tget ids() {\n\t\treturn this._startEndPoints.concat();\n\t}\n\n\tset ids(_: FeatureId[]) {}\n\n\tpublic create(selectedCoords: Position[] | Position[][]) {\n\t\tif (this.ids.length) {\n\t\t\tthrow new Error(\"Opening and closing points already created\");\n\t\t}\n\n\t\tconst isPolygon = isPolygonArray(selectedCoords);\n\t\tconst coordinates = getClosedCoordinates(selectedCoords);\n\n\t\tif (isPolygon) {\n\t\t\tif (coordinates.length <= 3) {\n\t\t\t\tthrow new Error(\"Requires at least 4 coordinates\");\n\t\t\t}\n\n\t\t\tthis._startEndPoints = this.mutateFeatureBehavior.createGuidancePoints({\n\t\t\t\tcoordinates: [coordinates[0], coordinates[coordinates.length - 2]],\n\t\t\t\ttype: COMMON_PROPERTIES.CLOSING_POINT,\n\t\t\t});\n\t\t} else {\n\t\t\tthis._startEndPoints = [\n\t\t\t\tthis.mutateFeatureBehavior.createGuidancePoint({\n\t\t\t\t\tcoordinate: coordinates[coordinates.length - 2] as Position,\n\t\t\t\t\ttype: COMMON_PROPERTIES.CLOSING_POINT,\n\t\t\t\t}),\n\t\t\t];\n\t\t}\n\t}\n\n\tpublic delete() {\n\t\tif (!this.ids.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.mutateFeatureBehavior.deleteFeaturesIfPresent(this.ids);\n\t\tthis._startEndPoints = [];\n\t}\n\n\tpublic updateOne(index: number, updatedCoordinate: Position) {\n\t\tthis.mutateFeatureBehavior.updateGuidancePoints([\n\t\t\t{\n\t\t\t\tfeatureId: this.ids[index],\n\t\t\t\tcoordinate: updatedCoordinate,\n\t\t\t},\n\t\t]);\n\t}\n\n\tpublic update(updatedCoordinates: Position[] | Position[][]) {\n\t\tconst coordinates = getClosedCoordinates(updatedCoordinates);\n\n\t\tif (this.ids.length === 1) {\n\t\t\tthis.mutateFeatureBehavior.updateGuidancePoints([\n\t\t\t\t{\n\t\t\t\t\tfeatureId: this.ids[0],\n\t\t\t\t\tcoordinate: coordinates[coordinates.length - 2],\n\t\t\t\t},\n\t\t\t]);\n\t\t\treturn;\n\t\t} else if (this.ids.length === 2) {\n\t\t\tthis.mutateFeatureBehavior.updateGuidancePoints([\n\t\t\t\t{\n\t\t\t\t\tfeatureId: this.ids[0],\n\t\t\t\t\tcoordinate: coordinates[0],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tfeatureId: this.ids[1],\n\t\t\t\t\tcoordinate: coordinates[coordinates.length - 3],\n\t\t\t\t},\n\t\t\t]);\n\t\t}\n\t}\n\n\tpublic isLineStringClosingPoint(event: TerraDrawMouseEvent) {\n\t\tif (this.ids.length !== 1) {\n\t\t\treturn { isClosing: false };\n\t\t}\n\n\t\tconst closing = this.readFeatureBehavior.getGeometry(this.ids[0]);\n\n\t\tconst distance = this.pixelDistance.measure(\n\t\t\tevent,\n\t\t\tclosing.coordinates as Position,\n\t\t);\n\n\t\tconst isClosing = distance < this.pointerDistance;\n\n\t\treturn { isClosing };\n\t}\n\n\tpublic isPolygonClosingPoints(event: TerraDrawMouseEvent) {\n\t\tif (this.ids.length !== 2) {\n\t\t\treturn { isClosing: false, isPreviousClosing: false };\n\t\t}\n\n\t\tconst opening = this.readFeatureBehavior.getGeometry(this.ids[0]);\n\t\tconst closing = this.readFeatureBehavior.getGeometry(this.ids[1]);\n\n\t\tconst distance = this.pixelDistance.measure(\n\t\t\tevent,\n\t\t\topening.coordinates as Position,\n\t\t);\n\n\t\tconst distancePrevious = this.pixelDistance.measure(\n\t\t\tevent,\n\t\t\tclosing.coordinates as Position,\n\t\t);\n\n\t\tconst isClosing = distance < this.pointerDistance;\n\t\tconst isPreviousClosing = distancePrevious < this.pointerDistance;\n\n\t\treturn { isClosing, isPreviousClosing };\n\t}\n}\n","import { Point, Position } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { FeatureId } from \"../../../store/store\";\nimport { COMMON_PROPERTIES, UpdateTypes } from \"../../../common\";\nimport { ReadFeatureBehavior } from \"../../read-feature.behavior\";\nimport { MutateFeatureBehavior } from \"../../mutate-feature.behavior\";\nimport { getUnclosedCoordinates } from \"../../../geometry/get-coordinates\";\n\nexport class CoordinatePointBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\tconfig: BehaviorConfig,\n\t\tprivate readonly readFeature: ReadFeatureBehavior,\n\t\tprivate readonly mutateFeature: MutateFeatureBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tpublic createOrUpdate({\n\t\tfeatureId,\n\t\tfeatureCoordinates,\n\t}: {\n\t\tfeatureId: FeatureId;\n\t\tfeatureCoordinates: Position[] | Position[][];\n\t}) {\n\t\t// Handle the edge case where the feature is deleted before create or update\n\t\tif (!this.readFeature.hasFeature(featureId)) {\n\t\t\tthis.deleteOrphanedPoints(featureId);\n\t\t\treturn;\n\t\t}\n\n\t\tconst coordinates = getUnclosedCoordinates(featureCoordinates);\n\n\t\tconst existingProperties = this.readFeature.getProperties(featureId);\n\n\t\tconst existingCoordinatePointIds =\n\t\t\texistingProperties.coordinatePointIds as FeatureId[];\n\n\t\t// If no existing coordinate points, create them\n\t\tif (!existingCoordinatePointIds) {\n\t\t\tconst coordinatePointIds = this.createPoints(\n\t\t\t\tcoordinates,\n\t\t\t\texistingProperties.mode as string,\n\t\t\t\tfeatureId,\n\t\t\t);\n\t\t\tthis.setFeatureCoordinatePoints(featureId, coordinatePointIds);\n\t\t}\n\t\t// If the existing coordinate points are present in the store, update them\n\t\telse if (\n\t\t\texistingCoordinatePointIds &&\n\t\t\texistingCoordinatePointIds.every((id) => this.readFeature.hasFeature(id))\n\t\t) {\n\t\t\t// Check if the coordinates have changed\n\t\t\tconst existingCoordinates =\n\t\t\t\texistingProperties.coordinatePointIds as FeatureId[];\n\t\t\tconst existingCoordinatePoints = existingCoordinates.map(\n\t\t\t\t(id) => this.readFeature.getGeometry(id).coordinates as Position,\n\t\t\t);\n\n\t\t\t// If the number of coordinates has changed, delete and recreate as it's too\n\t\t\t// complex to update the existing coordinates unless someone is feeling brave\n\t\t\tif (existingCoordinates.length !== coordinates.length) {\n\t\t\t\tthis.deleteCoordinatePoints(existingCoordinates);\n\t\t\t\tconst coordinatePointIds = this.createPoints(\n\t\t\t\t\tcoordinates,\n\t\t\t\t\texistingProperties.mode as string,\n\t\t\t\t\tfeatureId,\n\t\t\t\t);\n\t\t\t\tthis.setFeatureCoordinatePoints(featureId, coordinatePointIds);\n\t\t\t} else {\n\t\t\t\tconst updates: {\n\t\t\t\t\tfeatureId: FeatureId;\n\t\t\t\t\tcoordinate: Position;\n\t\t\t\t}[] = [];\n\t\t\t\t// Update the coordinates\n\t\t\t\tcoordinates.forEach((coordinate, i) => {\n\t\t\t\t\t// If the coordinates are the same, don't update\n\t\t\t\t\tif (\n\t\t\t\t\t\tcoordinate[0] === existingCoordinatePoints[i][0] &&\n\t\t\t\t\t\tcoordinate[1] === existingCoordinatePoints[i][1]\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tupdates.push({\n\t\t\t\t\t\tfeatureId: existingCoordinates[i],\n\t\t\t\t\t\tcoordinate: coordinate,\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tthis.mutateFeature.updateGuidancePoints(updates);\n\t\t\t}\n\t\t}\n\t\t// If the existing coordinate points are not present in the store, delete them and recreate\n\t\telse {\n\t\t\t// If there are any leftover coordinate points we remove them\n\t\t\tconst existingPoints = existingCoordinatePointIds.filter((id) =>\n\t\t\t\tthis.readFeature.hasFeature(id),\n\t\t\t);\n\t\t\tif (existingPoints.length) {\n\t\t\t\tthis.deleteCoordinatePoints(existingPoints);\n\t\t\t}\n\n\t\t\t// Create new coordinate points\n\t\t\tconst coordinatePointIds = this.createPoints(\n\t\t\t\tcoordinates,\n\t\t\t\texistingProperties.mode as string,\n\t\t\t\tfeatureId,\n\t\t\t);\n\t\t\tthis.setFeatureCoordinatePoints(featureId, coordinatePointIds);\n\t\t}\n\t}\n\n\tpublic deletePointsByFeatureIds(features: FeatureId[]) {\n\t\tfor (const featureId of features) {\n\t\t\tthis.deleteIfPresent(featureId);\n\t\t}\n\t}\n\n\tpublic updateOneAtIndex(\n\t\tfeatureId: FeatureId,\n\t\tindex: number,\n\t\tupdatedCoordinate: Position,\n\t) {\n\t\tconst featureProperties = this.readFeature.getProperties(featureId);\n\t\tconst coordinatePointIds =\n\t\t\tfeatureProperties.coordinatePointIds as FeatureId[];\n\n\t\tif (\n\t\t\t!coordinatePointIds ||\n\t\t\tcoordinatePointIds.length === 0 ||\n\t\t\tcoordinatePointIds[index] === undefined\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.mutateFeature.updateGuidancePoints([\n\t\t\t{\n\t\t\t\tfeatureId: coordinatePointIds[index],\n\t\t\t\tcoordinate: updatedCoordinate,\n\t\t\t},\n\t\t]);\n\t}\n\n\tpublic updateAllInPlace({\n\t\tfeatureId,\n\t\tfeatureCoordinates,\n\t}: {\n\t\tfeatureId: FeatureId;\n\t\tfeatureCoordinates: Position[] | Position[][];\n\t}) {\n\t\tconst featureProperties = this.readFeature.getProperties(featureId);\n\n\t\tif (!featureProperties.coordinatePointIds) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst coordinates = getUnclosedCoordinates(featureCoordinates);\n\t\tconst coordinatePointIds =\n\t\t\tfeatureProperties.coordinatePointIds as FeatureId[];\n\n\t\tif (coordinates.length !== coordinatePointIds.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.mutateFeature.updateGuidancePoints(\n\t\t\t(featureProperties.coordinatePointIds as FeatureId[]).map((id, i) => ({\n\t\t\t\tfeatureId: id,\n\t\t\t\tcoordinate: coordinates[i],\n\t\t\t})),\n\t\t);\n\t}\n\n\tprivate createPoints(\n\t\tfeatureCoordinates: Position[],\n\t\tmode: string,\n\t\tfeatureId: FeatureId,\n\t) {\n\t\treturn this.mutateFeature.createGuidancePoints({\n\t\t\tcoordinates: featureCoordinates,\n\t\t\ttype: COMMON_PROPERTIES.COORDINATE_POINT,\n\t\t\tadditionalProperties: (i) => ({\n\t\t\t\tmode,\n\t\t\t\t[COMMON_PROPERTIES.COORDINATE_POINT]: true,\n\t\t\t\t[COMMON_PROPERTIES.COORDINATE_POINT_FEATURE_ID]: featureId,\n\t\t\t\tindex: i,\n\t\t\t}),\n\t\t});\n\t}\n\n\tprivate setFeatureCoordinatePoints(\n\t\tfeatureId: FeatureId,\n\t\tvalue: FeatureId[] | null,\n\t\tupdateType:\n\t\t\t| UpdateTypes.Provisional\n\t\t\t| UpdateTypes.Commit = UpdateTypes.Commit,\n\t) {\n\t\tconst type = this.readFeature.getGeometryType(featureId);\n\n\t\tconst update = {\n\t\t\tfeatureId,\n\t\t\tpropertyMutations: {\n\t\t\t\t[COMMON_PROPERTIES.COORDINATE_POINT_IDS]: value,\n\t\t\t},\n\t\t\tcontext: {\n\t\t\t\tupdateType,\n\t\t\t},\n\t\t};\n\n\t\tif (type === \"Polygon\") {\n\t\t\tthis.mutateFeature.updatePolygon(update);\n\t\t} else if (type === \"LineString\") {\n\t\t\tthis.mutateFeature.updateLineString(update);\n\t\t} else {\n\t\t\tthrow new Error(\"Unsupported geometry type for coordinate points\");\n\t\t}\n\t}\n\n\tprivate deleteCoordinatePoints(coordinatePointIds: FeatureId[]) {\n\t\t// We have to account for someone manually deleting the coordinate points or only partially restoring them\n\t\t// from some persistent storage. Essentially we cannot assume they are all present in the store.\n\n\t\tthis.mutateFeature.deleteFeaturesIfPresent(coordinatePointIds);\n\t}\n\n\tprivate deleteIfPresent(featureId: FeatureId) {\n\t\tif (!this.readFeature.hasFeature(featureId)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst existingFeatureProps = this.readFeature.getProperties(featureId);\n\t\tconst coordinatePoints =\n\t\t\texistingFeatureProps.coordinatePointIds as FeatureId[];\n\n\t\tif (coordinatePoints) {\n\t\t\tthis.deleteCoordinatePoints(coordinatePoints);\n\t\t\tthis.setFeatureCoordinatePoints(featureId, null);\n\t\t}\n\t}\n\n\tprivate deleteOrphanedPoints(featureId: FeatureId) {\n\t\tconst orphanedCoordinatePointIds = this.readFeature.getAllFeatureIdsWhere(\n\t\t\t(properties) =>\n\t\t\t\tproperties[COMMON_PROPERTIES.COORDINATE_POINT_FEATURE_ID] === featureId,\n\t\t);\n\n\t\tthis.mutateFeature.deleteFeaturesIfPresent(orphanedCoordinatePointIds);\n\t}\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n\tCartesianPoint,\n\tZ_INDEX,\n\tSnapping,\n\tCOMMON_PROPERTIES,\n\tFinishActions,\n} from \"../../common\";\nimport { Feature, LineString, Position } from \"geojson\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tModeUpdateOptions,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../click-bounding-box.behavior\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { CoordinateSnappingBehavior } from \"../coordinate-snapping.behavior\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tFeatureId,\n\tGeoJSONStoreFeatures,\n\tStoreValidation,\n} from \"../../store/store\";\nimport { InsertCoordinatesBehavior } from \"../insert-coordinates.behavior\";\nimport { haversineDistanceKilometers } from \"../../geometry/measure/haversine-distance\";\nimport { coordinatesIdentical } from \"../../geometry/coordinates-identical\";\nimport { ValidateLineStringFeature } from \"../../validations/linestring.validation\";\nimport { LineSnappingBehavior } from \"../line-snapping.behavior\";\nimport {\n\tMutateFeatureBehavior,\n\tMutations,\n\tReplaceMutation,\n\ttype CoordinateMutation,\n} from \"../mutate-feature.behavior\";\nimport { ReadFeatureBehavior } from \"../read-feature.behavior\";\nimport { ClosingPointsBehavior } from \"../closing-points.behavior\";\nimport { CoordinatePointBehavior } from \"../select/behaviors/coordinate-point.behavior\";\n\ntype TerraDrawLineStringModeKeyEvents = {\n\tcancel: KeyboardEvent[\"key\"] | null;\n\tfinish: KeyboardEvent[\"key\"] | null;\n};\n\nconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" } as const;\n\ntype LineStringStyling = {\n\tlineStringWidth: NumericStyling;\n\tlineStringColor: HexColorStyling;\n\tlineStringOpacity: NumericStyling;\n\tclosingPointColor: HexColorStyling;\n\tclosingPointWidth: NumericStyling;\n\tclosingPointOpacity: NumericStyling;\n\tclosingPointOutlineColor: HexColorStyling;\n\tclosingPointOutlineWidth: NumericStyling;\n\tclosingPointOutlineOpacity: NumericStyling;\n\tsnappingPointColor: HexColorStyling;\n\tsnappingPointWidth: NumericStyling;\n\tsnappingPointOpacity: NumericStyling;\n\tsnappingPointOutlineColor: HexColorStyling;\n\tsnappingPointOutlineWidth: NumericStyling;\n\tsnappingPointOutlineOpacity: NumericStyling;\n\tcoordinatePointColor: HexColorStyling;\n\tcoordinatePointOpacity: NumericStyling;\n\tcoordinatePointWidth: NumericStyling;\n\tcoordinatePointOutlineColor: HexColorStyling;\n\tcoordinatePointOutlineWidth: NumericStyling;\n\tcoordinatePointOutlineOpacity: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n\tclose?: Cursor;\n\tdragStart?: Cursor;\n\tdragEnd?: Cursor;\n}\n\nconst defaultCursors = {\n\tstart: \"crosshair\",\n\tclose: \"pointer\",\n\tdragStart: \"grabbing\",\n\tdragEnd: \"crosshair\",\n} as Required<Cursors>;\n\ninterface InertCoordinates {\n\tstrategy: \"amount\"; // In future this could be extended\n\tvalue: number;\n}\n\ninterface TerraDrawLineStringModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tsnapping?: Snapping;\n\tpointerDistance?: number;\n\tkeyEvents?: TerraDrawLineStringModeKeyEvents | null;\n\tcursors?: Cursors;\n\tinsertCoordinates?: InertCoordinates;\n\teditable?: boolean;\n\tshowCoordinatePoints?: boolean;\n\tfinishOnNthCoordinate?: number;\n}\n\nexport class TerraDrawLineStringMode extends TerraDrawBaseDrawMode<LineStringStyling> {\n\tmode = \"linestring\";\n\n\tprivate currentCoordinate = 0;\n\tprivate currentId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawLineStringModeKeyEvents = defaultKeyEvents;\n\tprivate snapping: Snapping | undefined;\n\tprivate cursors: Required<Cursors> = defaultCursors;\n\tprivate mouseMove = false;\n\tprivate insertCoordinates: InertCoordinates | undefined;\n\tprivate lastCommittedCoordinates: Position[] | undefined;\n\tprivate snappedPointId: FeatureId | undefined;\n\tprivate lastMouseMoveEvent: TerraDrawMouseEvent | undefined;\n\tprivate showCoordinatePoints = false;\n\tprivate finishOnNthCoordinate: number | undefined;\n\n\t// Editable properties\n\tprivate editable: boolean = false;\n\tprivate editedFeatureId: FeatureId | undefined;\n\tprivate editedFeatureCoordinateIndex: number | undefined;\n\tprivate editedSnapType: \"line\" | \"coordinate\" | undefined;\n\tprivate editedInsertIndex: number | undefined;\n\tprivate editedPointId: FeatureId | undefined;\n\n\t// Behaviors\n\tprivate coordinateSnapping!: CoordinateSnappingBehavior;\n\tprivate insertPoint!: InsertCoordinatesBehavior;\n\tprivate lineSnapping!: LineSnappingBehavior;\n\tprivate pixelDistance!: PixelDistanceBehavior;\n\tprivate clickBoundingBox!: ClickBoundingBoxBehavior;\n\tprivate mutateFeature!: MutateFeatureBehavior;\n\tprivate readFeature!: ReadFeatureBehavior;\n\tprivate closingPoints!: ClosingPointsBehavior;\n\tprivate coordinatePoints!: CoordinatePointBehavior;\n\n\tconstructor(options?: TerraDrawLineStringModeOptions<LineStringStyling>) {\n\t\tsuper(options, true);\n\t\tthis.updateOptions(options);\n\t}\n\n\tupdateOptions(\n\t\toptions?: ModeUpdateOptions<\n\t\t\tTerraDrawLineStringModeOptions<LineStringStyling>\n\t\t>,\n\t) {\n\t\tsuper.updateOptions(options);\n\n\t\tif (\n\t\t\toptions?.finishOnNthCoordinate !== undefined &&\n\t\t\tNumber.isInteger(options.finishOnNthCoordinate) &&\n\t\t\toptions.finishOnNthCoordinate > 1\n\t\t) {\n\t\t\tthis.finishOnNthCoordinate = Math.floor(options.finishOnNthCoordinate);\n\t\t}\n\n\t\tif (options?.cursors) {\n\t\t\tthis.cursors = { ...this.cursors, ...options.cursors };\n\t\t}\n\n\t\tif (options?.snapping) {\n\t\t\tthis.snapping = options.snapping;\n\t\t}\n\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = { cancel: null, finish: null };\n\t\t} else if (options?.keyEvents) {\n\t\t\tthis.keyEvents = { ...this.keyEvents, ...options.keyEvents };\n\t\t}\n\n\t\tif (options?.insertCoordinates) {\n\t\t\tthis.insertCoordinates = options.insertCoordinates;\n\t\t}\n\n\t\tif (options && options.editable) {\n\t\t\tthis.editable = options.editable;\n\t\t}\n\n\t\tif (options?.showCoordinatePoints !== undefined) {\n\t\t\tthis.showCoordinatePoints = options.showCoordinatePoints;\n\n\t\t\t// If we are showing coordinate points, we need to add them all\n\t\t\tif (this.coordinatePoints && options.showCoordinatePoints === true) {\n\t\t\t\tconst features = this.store.copyAllWhere(\n\t\t\t\t\t(properties) => properties.mode === this.mode,\n\t\t\t\t);\n\t\t\t\tfeatures.forEach((feature) => {\n\t\t\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\t\t\tfeatureId: feature.id as FeatureId,\n\t\t\t\t\t\tfeatureCoordinates: feature.geometry.coordinates as Position[],\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t} else if (this.coordinatePoints && this.showCoordinatePoints === false) {\n\t\t\t\tconst featuresWithCoordinates = this.store.copyAllWhere(\n\t\t\t\t\t(properties) =>\n\t\t\t\t\t\tproperties.mode === this.mode &&\n\t\t\t\t\t\tBoolean(\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\tproperties[\n\t\t\t\t\t\t\t\t\tCOMMON_PROPERTIES.COORDINATE_POINT_IDS\n\t\t\t\t\t\t\t\t] as FeatureId[]\n\t\t\t\t\t\t\t)?.length,\n\t\t\t\t\t\t),\n\t\t\t\t);\n\n\t\t\t\tthis.coordinatePoints.deletePointsByFeatureIds(\n\t\t\t\t\tfeaturesWithCoordinates.map((f) => f.id as FeatureId),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate shouldFinishOnCommit(geometry: LineString) {\n\t\tif (!this.finishOnNthCoordinate) {\n\t\t\treturn false;\n\t\t}\n\t\t// While drawing, LineString coordinates contain a trailing \"live\" coordinate.\n\t\t// Committed coordinates exclude that last \"live\" coordinate.\n\t\tconst committedCoordinateCount = Math.max(\n\t\t\t0,\n\t\t\tgeometry.coordinates.length - 1,\n\t\t);\n\t\treturn committedCoordinateCount >= this.finishOnNthCoordinate;\n\t}\n\n\tprivate updateSnappedCoordinate(event: TerraDrawMouseEvent) {\n\t\tconst snappedCoordinate = this.snapCoordinate(event);\n\n\t\tif (snappedCoordinate) {\n\t\t\tif (this.snappedPointId) {\n\t\t\t\tthis.mutateFeature.updateGuidancePoints([\n\t\t\t\t\t{\n\t\t\t\t\t\tfeatureId: this.snappedPointId,\n\t\t\t\t\t\tcoordinate: snappedCoordinate,\n\t\t\t\t\t},\n\t\t\t\t]);\n\t\t\t} else {\n\t\t\t\tthis.snappedPointId = this.mutateFeature.createGuidancePoint({\n\t\t\t\t\tcoordinate: snappedCoordinate,\n\t\t\t\t\ttype: COMMON_PROPERTIES.SNAPPING_POINT,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tevent.lng = snappedCoordinate[0];\n\t\t\tevent.lat = snappedCoordinate[1];\n\t\t} else if (this.snappedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\t\tthis.snappedPointId = undefined;\n\t\t}\n\n\t\treturn snappedCoordinate;\n\t}\n\n\tprivate close() {\n\t\tif (this.currentId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst updated = this.mutateFeature.updateLineString({\n\t\t\tfeatureId: this.currentId,\n\t\t\tcontext: { updateType: UpdateTypes.Finish, action: FinishActions.Draw },\n\t\t\tcoordinateMutations: [\n\t\t\t\t{\n\t\t\t\t\ttype: Mutations.Delete,\n\t\t\t\t\tindex: -1,\n\t\t\t\t},\n\t\t\t],\n\t\t\tpropertyMutations: {\n\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: undefined,\n\t\t\t},\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.showCoordinatePoints) {\n\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\tfeatureId: this.currentId,\n\t\t\t\tfeatureCoordinates: updated.geometry.coordinates,\n\t\t\t});\n\t\t}\n\n\t\tconst featureId = this.currentId;\n\n\t\tthis.currentCoordinate = 0;\n\t\tthis.currentId = undefined;\n\t\tthis.lastCommittedCoordinates = undefined;\n\n\t\t// Go back to started state\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.closingPoints.delete();\n\n\t\tif (this.snappedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\t\tthis.snappedPointId = undefined;\n\t\t}\n\n\t\tif (this.editedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.editedPointId);\n\t\t\tthis.editedPointId = undefined;\n\n\t\t\t// Reset edit state\n\t\t\tthis.editedFeatureId = undefined;\n\t\t\tthis.editedFeatureCoordinateIndex = undefined;\n\t\t\tthis.editedInsertIndex = undefined;\n\t\t\tthis.editedSnapType = undefined;\n\t\t}\n\n\t\tthis.onFinish(featureId, { mode: this.mode, action: FinishActions.Draw });\n\t}\n\n\tprivate generateInsertCoordinates(startCoord: Position, endCoord: Position) {\n\t\tif (!this.insertCoordinates || !this.lastCommittedCoordinates) {\n\t\t\tthrow new Error(\"Not able to insert coordinates\");\n\t\t}\n\n\t\t// Other strategies my be implemented in the future\n\t\tif (this.insertCoordinates.strategy !== \"amount\") {\n\t\t\tthrow new Error(\"Strategy does not exist\");\n\t\t}\n\n\t\tconst distance = haversineDistanceKilometers(startCoord, endCoord);\n\t\tconst segmentDistance = distance / (this.insertCoordinates.value + 1);\n\t\tlet insertedCoordinates: Position[] = [];\n\n\t\tif (this.projection === \"globe\") {\n\t\t\tinsertedCoordinates =\n\t\t\t\tthis.insertPoint.generateInsertionGeodesicCoordinates(\n\t\t\t\t\tstartCoord,\n\t\t\t\t\tendCoord,\n\t\t\t\t\tsegmentDistance,\n\t\t\t\t);\n\t\t} else if (this.projection === \"web-mercator\") {\n\t\t\tinsertedCoordinates = this.insertPoint.generateInsertionCoordinates(\n\t\t\t\tstartCoord,\n\t\t\t\tendCoord,\n\t\t\t\tsegmentDistance,\n\t\t\t);\n\t\t}\n\n\t\treturn insertedCoordinates;\n\t}\n\n\tprivate createLine(startingCoord: Position) {\n\t\tconst created = this.mutateFeature.createLineString({\n\t\t\tcoordinates: [\n\t\t\t\tstartingCoord,\n\t\t\t\tstartingCoord, // This is the 'live' point that changes on mouse move\n\t\t\t],\n\t\t\tproperties: {\n\t\t\t\tmode: this.mode,\n\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: true,\n\t\t\t},\n\t\t});\n\n\t\tthis.lastCommittedCoordinates = created.geometry.coordinates;\n\t\tthis.currentId = created.id as FeatureId;\n\t\tthis.currentCoordinate++;\n\t\tthis.setDrawing();\n\n\t\tif (this.showCoordinatePoints) {\n\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\tfeatureId: this.currentId,\n\t\t\t\tfeatureCoordinates: created.geometry.coordinates,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate firstUpdateToLine(updatedCoord: Position) {\n\t\tif (!this.currentId) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We are creating the point so we immediately want\n\t\t// to set the point cursor to show it can be closed\n\t\tthis.setCursor(this.cursors.close);\n\n\t\tconst updated = this.mutateFeature.updateLineString({\n\t\t\tfeatureId: this.currentId,\n\t\t\tcontext: { updateType: UpdateTypes.Commit },\n\t\t\tcoordinateMutations: [\n\t\t\t\t{\n\t\t\t\t\ttype: Mutations.InsertAfter,\n\t\t\t\t\tindex: -1,\n\t\t\t\t\tcoordinate: updatedCoord,\n\t\t\t\t},\n\t\t\t],\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.closingPoints.create(updated.geometry.coordinates);\n\n\t\tif (this.showCoordinatePoints) {\n\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\tfeatureId: this.currentId,\n\t\t\t\tfeatureCoordinates: updated.geometry.coordinates,\n\t\t\t});\n\t\t}\n\n\t\tthis.lastCommittedCoordinates = updated.geometry.coordinates;\n\t\tthis.currentCoordinate++;\n\n\t\tif (this.shouldFinishOnCommit(updated.geometry)) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\tprivate updateToLine(event: TerraDrawMouseEvent, updatedCoord: Position) {\n\t\tif (!this.currentId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { isClosing } = this.closingPoints.isLineStringClosingPoint(event);\n\n\t\t// If the pointer is hovered over the closing point we show the close cursor\n\t\tif (isClosing) {\n\t\t\tthis.close();\n\t\t\treturn;\n\t\t}\n\n\t\t// The cursor will immediately change to closing because the\n\t\t// closing point will be underneath the cursor\n\t\tthis.setCursor(this.cursors.close);\n\n\t\tconst updated = this.mutateFeature.updateLineString({\n\t\t\tfeatureId: this.currentId,\n\t\t\tcontext: { updateType: UpdateTypes.Commit },\n\t\t\tcoordinateMutations: [\n\t\t\t\t{ type: Mutations.InsertAfter, index: -1, coordinate: updatedCoord },\n\t\t\t],\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.closingPoints.update(updated.geometry.coordinates);\n\n\t\tif (this.showCoordinatePoints) {\n\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\tfeatureId: this.currentId,\n\t\t\t\tfeatureCoordinates: updated.geometry.coordinates,\n\t\t\t});\n\t\t}\n\n\t\tthis.lastCommittedCoordinates = updated.geometry.coordinates;\n\n\t\tthis.currentCoordinate++;\n\n\t\tif (this.shouldFinishOnCommit(updated.geometry)) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.insertPoint = new InsertCoordinatesBehavior(config);\n\t\tthis.clickBoundingBox = new ClickBoundingBoxBehavior(config);\n\t\tthis.pixelDistance = new PixelDistanceBehavior(config);\n\t\tthis.lineSnapping = new LineSnappingBehavior(\n\t\t\tconfig,\n\t\t\tthis.pixelDistance,\n\t\t\tthis.clickBoundingBox,\n\t\t);\n\t\tthis.coordinateSnapping = new CoordinateSnappingBehavior(\n\t\t\tconfig,\n\t\t\tthis.pixelDistance,\n\t\t\tthis.clickBoundingBox,\n\t\t);\n\t\tthis.readFeature = new ReadFeatureBehavior(config);\n\t\tthis.mutateFeature = new MutateFeatureBehavior(config, {\n\t\t\tvalidate: this.validate,\n\t\t});\n\t\tthis.closingPoints = new ClosingPointsBehavior(\n\t\t\tconfig,\n\t\t\tthis.pixelDistance,\n\t\t\tthis.mutateFeature,\n\t\t\tthis.readFeature,\n\t\t);\n\t\tthis.coordinatePoints = new CoordinatePointBehavior(\n\t\t\tconfig,\n\t\t\tthis.readFeature,\n\t\t\tthis.mutateFeature,\n\t\t);\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tthis.mouseMove = true;\n\t\tthis.setCursor(this.cursors.start);\n\t\tthis.lastMouseMoveEvent = event;\n\n\t\tconst snappedCoordinate = this.updateSnappedCoordinate(event);\n\n\t\tconst updatedCoord = snappedCoordinate\n\t\t\t? snappedCoordinate\n\t\t\t: [event.lng, event.lat];\n\n\t\tif (this.currentId === undefined || this.currentCoordinate === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { isClosing } = this.closingPoints.isLineStringClosingPoint(event);\n\n\t\t// If the pointer is hovered over the closing point we show the close cursor\n\t\tif (isClosing) {\n\t\t\tthis.setCursor(this.cursors.close);\n\t\t}\n\n\t\t// Default mutation is just to update the final coordinate\n\t\tlet coordinateMutations:\n\t\t\t| CoordinateMutation[]\n\t\t\t| ReplaceMutation<LineString> = [\n\t\t\t{\n\t\t\t\ttype: Mutations.Update,\n\t\t\t\tindex: -1,\n\t\t\t\tcoordinate: updatedCoord,\n\t\t\t},\n\t\t];\n\n\t\tif (this.insertCoordinates) {\n\t\t\tconst insertCoordinates = this.getInsertCoordinates(updatedCoord);\n\n\t\t\tif (insertCoordinates) {\n\t\t\t\tcoordinateMutations = {\n\t\t\t\t\ttype: Mutations.Replace,\n\t\t\t\t\tcoordinates: insertCoordinates,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tconst updated = this.mutateFeature.updateLineString({\n\t\t\tcoordinateMutations,\n\t\t\tfeatureId: this.currentId,\n\t\t\tcontext: { updateType: UpdateTypes.Provisional },\n\t\t});\n\n\t\t// Keep coordinate points in sync with the provisional \"live\" coordinate\n\t\tif (updated && this.showCoordinatePoints) {\n\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\tfeatureId: this.currentId,\n\t\t\t\tfeatureCoordinates: updated.geometry.coordinates,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate getInsertCoordinates(endCoord: Position) {\n\t\tif (!this.lastCommittedCoordinates) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst index = this.lastCommittedCoordinates.length - 1;\n\t\tconst startCoord = this.lastCommittedCoordinates[index];\n\n\t\tif (coordinatesIdentical(startCoord, endCoord)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst insertedCoordinates = this.generateInsertCoordinates(\n\t\t\tstartCoord,\n\t\t\tendCoord,\n\t\t);\n\n\t\tconst startCoordinates = this.lastCommittedCoordinates.slice(0, -1);\n\n\t\treturn [...startCoordinates, ...insertedCoordinates, endCoord];\n\t}\n\n\tprivate onRightClick(event: TerraDrawMouseEvent) {\n\t\tif (!this.editable || this.state !== \"started\") {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { featureId, featureCoordinateIndex: coordinateIndex } =\n\t\t\tthis.coordinateSnapping.getSnappable(event, (feature) =>\n\t\t\t\tthis.lineStringFilter(feature),\n\t\t\t);\n\n\t\tif (!featureId || coordinateIndex === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst geometry = this.readFeature.getGeometry(featureId);\n\n\t\tlet coordinates;\n\t\tif (geometry.type === \"LineString\") {\n\t\t\tcoordinates = geometry.coordinates;\n\n\t\t\t// Prevent creating an invalid linestring\n\t\t\tif (coordinates.length <= 2) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\tconst updated = this.mutateFeature.updateLineString({\n\t\t\tfeatureId,\n\t\t\tcoordinateMutations: [{ type: Mutations.Delete, index: coordinateIndex }],\n\t\t\tcontext: { updateType: UpdateTypes.Finish, action: FinishActions.Edit },\n\t\t});\n\n\t\tif (updated && this.showCoordinatePoints) {\n\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\tfeatureId,\n\t\t\t\tfeatureCoordinates: updated.geometry.coordinates,\n\t\t\t});\n\t\t}\n\n\t\tif (this.snappedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\t\tthis.snappedPointId = undefined;\n\t\t}\n\n\t\tif (this.editedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.editedPointId);\n\t\t\tthis.editedPointId = undefined;\n\n\t\t\t// Reset edit state\n\t\t\tthis.editedFeatureId = undefined;\n\t\t\tthis.editedFeatureCoordinateIndex = undefined;\n\t\t\tthis.editedInsertIndex = undefined;\n\t\t\tthis.editedSnapType = undefined;\n\t\t}\n\n\t\tthis.closingPoints.delete();\n\n\t\tthis.onFinish(featureId, {\n\t\t\tmode: this.mode,\n\t\t\taction: FinishActions.DeleteCoordinate,\n\t\t});\n\t}\n\n\tprivate onLeftClick(event: TerraDrawMouseEvent) {\n\t\t// Reset the snapping point\n\t\tif (this.snappedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\t\tthis.snappedPointId = undefined;\n\t\t}\n\n\t\tconst snappedCoordinate = this.snapCoordinate(event);\n\t\tconst updatedCoordinate = snappedCoordinate\n\t\t\t? snappedCoordinate\n\t\t\t: [event.lng, event.lat];\n\n\t\tif (this.currentCoordinate === 0) {\n\t\t\tthis.createLine(updatedCoordinate);\n\t\t} else if (this.currentCoordinate === 1 && this.currentId) {\n\t\t\tthis.firstUpdateToLine(updatedCoordinate);\n\t\t} else if (this.currentId) {\n\t\t\tthis.updateToLine(event, updatedCoordinate);\n\t\t}\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\tif (\n\t\t\tthis.currentId !== undefined &&\n\t\t\t!this.readFeature.hasFeature(this.currentId)\n\t\t) {\n\t\t\tthis.cleanUp();\n\t\t}\n\n\t\tif (\n\t\t\t(event.button === \"right\" &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.rightClick, event)) ||\n\t\t\t(event.button === \"left\" &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.leftClick, event)) ||\n\t\t\t(event.isContextMenu &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.contextMenu, event))\n\t\t) {\n\t\t\t// We want pointer devices (mobile/tablet) to have\n\t\t\t// similar behaviour to mouse based devices so we\n\t\t\t// trigger a mousemove event before every click\n\t\t\t// if one has not been triggered to emulate this\n\t\t\tif (this.currentCoordinate > 0 && !this.mouseMove) {\n\t\t\t\tthis.onMouseMove(event);\n\t\t\t}\n\t\t\tthis.mouseMove = false;\n\n\t\t\tif (event.button === \"right\") {\n\t\t\t\tthis.onRightClick(event);\n\t\t\t} else if (event.button === \"left\") {\n\t\t\t\tthis.onLeftClick(event);\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyDown() {\n\t\t// no-op\n\t}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tif (event.key === this.keyEvents.cancel) {\n\t\t\tthis.cleanUp();\n\t\t}\n\n\t\tif (event.key === this.keyEvents.finish) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDragStart(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (!this.allowPointerEvent(this.pointerEvents.onDragStart, event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.editable) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet snappedCoordinate: Position | undefined = undefined;\n\n\t\tif (this.state === \"started\") {\n\t\t\tconst lineSnapped = this.lineSnapping.getSnappable(event, (feature) =>\n\t\t\t\tthis.lineStringFilter(feature),\n\t\t\t);\n\n\t\t\tif (lineSnapped.coordinate) {\n\t\t\t\tthis.editedSnapType = \"line\";\n\t\t\t\tthis.editedFeatureCoordinateIndex = lineSnapped.featureCoordinateIndex;\n\t\t\t\tthis.editedFeatureId = lineSnapped.featureId;\n\t\t\t\tsnappedCoordinate = lineSnapped.coordinate;\n\t\t\t}\n\n\t\t\tconst coordinateSnapped = this.coordinateSnapping.getSnappable(\n\t\t\t\tevent,\n\t\t\t\t(feature) => this.lineStringFilter(feature),\n\t\t\t);\n\n\t\t\tif (coordinateSnapped.coordinate) {\n\t\t\t\tthis.editedSnapType = \"coordinate\";\n\t\t\t\tthis.editedFeatureCoordinateIndex =\n\t\t\t\t\tcoordinateSnapped.featureCoordinateIndex;\n\t\t\t\tthis.editedFeatureId = coordinateSnapped.featureId;\n\t\t\t\tsnappedCoordinate = coordinateSnapped.coordinate;\n\t\t\t}\n\t\t}\n\n\t\t// We only need to stop the map dragging if\n\t\t// we actually have something selected\n\t\tif (!this.editedFeatureId || !snappedCoordinate) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Create a point to drag when editing\n\t\tif (!this.editedPointId) {\n\t\t\tthis.editedPointId = this.mutateFeature.createGuidancePoint({\n\t\t\t\tcoordinate: snappedCoordinate,\n\t\t\t\ttype: COMMON_PROPERTIES.EDITED,\n\t\t\t});\n\t\t}\n\n\t\t// Drag Feature\n\t\tthis.setCursor(this.cursors.dragStart);\n\n\t\tsetMapDraggability(false);\n\t}\n\n\t/** @internal */\n\tonDrag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (!this.allowPointerEvent(this.pointerEvents.onDrag, event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\tthis.editedFeatureId === undefined ||\n\t\t\tthis.editedFeatureCoordinateIndex === undefined\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Either it's a coordinate drag or a line drag where the line coordinate has already been inserted\n\t\tif (\n\t\t\tthis.editedSnapType === \"coordinate\" ||\n\t\t\t(this.editedSnapType === \"line\" && this.editedInsertIndex !== undefined)\n\t\t) {\n\t\t\tconst updated = this.mutateFeature.updateLineString({\n\t\t\t\tfeatureId: this.editedFeatureId,\n\t\t\t\tcontext: { updateType: UpdateTypes.Provisional },\n\t\t\t\tcoordinateMutations: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: Mutations.Update,\n\t\t\t\t\t\tindex: this.editedFeatureCoordinateIndex,\n\t\t\t\t\t\tcoordinate: [event.lng, event.lat],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t});\n\n\t\t\tif (!updated) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.showCoordinatePoints) {\n\t\t\t\t// If a point was inserted we need to update all coordinate points\n\t\t\t\tif (this.editedInsertIndex !== undefined) {\n\t\t\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\t\t\tfeatureId: this.editedFeatureId,\n\t\t\t\t\t\tfeatureCoordinates: updated.geometry.coordinates,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// Else we are only updating one point\n\t\t\t\telse {\n\t\t\t\t\tthis.coordinatePoints.updateOneAtIndex(\n\t\t\t\t\t\tthis.editedFeatureId,\n\t\t\t\t\t\tthis.editedFeatureCoordinateIndex,\n\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (\n\t\t\tthis.editedSnapType === \"line\" &&\n\t\t\tthis.editedInsertIndex === undefined\n\t\t) {\n\t\t\t// Splice inserts _before_ the index, so we need to add 1\n\t\t\tthis.editedInsertIndex = this.editedFeatureCoordinateIndex + 1;\n\n\t\t\tconst inserted = this.mutateFeature.updateLineString({\n\t\t\t\tfeatureId: this.editedFeatureId,\n\t\t\t\tcontext: { updateType: UpdateTypes.Provisional },\n\t\t\t});\n\n\t\t\tif (!inserted) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.showCoordinatePoints) {\n\t\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\t\tfeatureId: this.editedFeatureId,\n\t\t\t\t\tfeatureCoordinates: inserted.geometry.coordinates,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// We have inserted a point, need to change the edit index\n\t\t\t// so it can be moved correctly when it gets dragged again\n\t\t\tthis.editedFeatureCoordinateIndex++;\n\t\t}\n\n\t\tif (this.snapping && this.snappedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\t\tthis.snappedPointId = undefined;\n\t\t}\n\n\t\tif (this.editedPointId) {\n\t\t\tthis.mutateFeature.updateGuidancePoints([\n\t\t\t\t{\n\t\t\t\t\tfeatureId: this.editedPointId,\n\t\t\t\t\tcoordinate: [event.lng, event.lat],\n\t\t\t\t},\n\t\t\t]);\n\t\t}\n\n\t\tthis.mutateFeature.updateLineString({\n\t\t\tfeatureId: this.editedFeatureId,\n\t\t\tcontext: { updateType: UpdateTypes.Provisional },\n\t\t\tpropertyMutations: { [COMMON_PROPERTIES.EDITED]: true },\n\t\t});\n\t}\n\n\t/** @internal */\n\tonDragEnd(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (!this.allowPointerEvent(this.pointerEvents.onDragEnd, event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.editedFeatureId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.setCursor(this.cursors.dragEnd);\n\n\t\tconst updated = this.mutateFeature.updateLineString({\n\t\t\tfeatureId: this.editedFeatureId,\n\t\t\tpropertyMutations: { [COMMON_PROPERTIES.EDITED]: false },\n\t\t\tcontext: { updateType: UpdateTypes.Finish, action: FinishActions.Edit },\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst featureId = this.editedFeatureId;\n\n\t\tsetMapDraggability(true);\n\n\t\tif (this.snappedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\t\tthis.snappedPointId = undefined;\n\t\t}\n\n\t\tif (this.editedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.editedPointId);\n\t\t\tthis.editedPointId = undefined;\n\n\t\t\t// Reset edit state\n\t\t\tthis.editedFeatureId = undefined;\n\t\t\tthis.editedFeatureCoordinateIndex = undefined;\n\t\t\tthis.editedInsertIndex = undefined;\n\t\t\tthis.editedSnapType = undefined;\n\t\t}\n\n\t\tthis.closingPoints.delete();\n\n\t\tthis.onFinish(featureId, { mode: this.mode, action: FinishActions.Edit });\n\t}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tconst currentId = this.currentId;\n\t\tconst snappedPointId = this.snappedPointId;\n\n\t\tthis.snappedPointId = undefined;\n\t\tthis.currentId = undefined;\n\t\tthis.currentCoordinate = 0;\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tif (currentId && this.showCoordinatePoints) {\n\t\t\tthis.coordinatePoints.deletePointsByFeatureIds([currentId]);\n\t\t}\n\n\t\tthis.mutateFeature.deleteFeatureIfPresent(currentId);\n\t\tthis.mutateFeature.deleteFeatureIfPresent(snappedPointId);\n\t\tthis.closingPoints.delete();\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"LineString\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tstyles.lineStringColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.lineStringColor,\n\t\t\t\tstyles.lineStringColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.lineStringOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.lineStringOpacity,\n\t\t\t\tstyles.lineStringOpacity === undefined ? 1 : styles.lineStringOpacity,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.lineStringWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.lineStringWidth,\n\t\t\t\tstyles.lineStringWidth,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.zIndex = Z_INDEX.LAYER_ONE;\n\n\t\t\treturn styles;\n\t\t} else if (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"Point\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tconst closingPoint = feature.properties[COMMON_PROPERTIES.CLOSING_POINT];\n\t\t\tconst snappingPoint =\n\t\t\t\tfeature.properties[COMMON_PROPERTIES.SNAPPING_POINT];\n\t\t\tconst coordinatePoint =\n\t\t\t\tfeature.properties[COMMON_PROPERTIES.COORDINATE_POINT];\n\n\t\t\tconst pointType = closingPoint\n\t\t\t\t? \"closingPoint\"\n\t\t\t\t: snappingPoint\n\t\t\t\t\t? \"snappingPoint\"\n\t\t\t\t\t: coordinatePoint\n\t\t\t\t\t\t? \"coordinatePoint\"\n\t\t\t\t\t\t: undefined;\n\n\t\t\tif (!pointType) {\n\t\t\t\treturn styles;\n\t\t\t}\n\n\t\t\tconst styleMap = {\n\t\t\t\tclosingPoint: {\n\t\t\t\t\twidth: this.styles.closingPointWidth,\n\t\t\t\t\tcolor: this.styles.closingPointColor,\n\t\t\t\t\topacity: this.styles.closingPointOpacity,\n\t\t\t\t\toutlineColor: this.styles.closingPointOutlineColor,\n\t\t\t\t\toutlineWidth: this.styles.closingPointOutlineWidth,\n\t\t\t\t\toutlineOpacity: this.styles.closingPointOutlineOpacity,\n\t\t\t\t},\n\t\t\t\tsnappingPoint: {\n\t\t\t\t\twidth: this.styles.snappingPointWidth,\n\t\t\t\t\tcolor: this.styles.snappingPointColor,\n\t\t\t\t\topacity: this.styles.snappingPointOpacity,\n\t\t\t\t\toutlineColor: this.styles.snappingPointOutlineColor,\n\t\t\t\t\toutlineWidth: this.styles.snappingPointOutlineWidth,\n\t\t\t\t\toutlineOpacity: this.styles.snappingPointOutlineOpacity,\n\t\t\t\t},\n\t\t\t\tcoordinatePoint: {\n\t\t\t\t\twidth: this.styles.coordinatePointWidth,\n\t\t\t\t\tcolor: this.styles.coordinatePointColor,\n\t\t\t\t\topacity: this.styles.coordinatePointOpacity,\n\t\t\t\t\toutlineColor: this.styles.coordinatePointOutlineColor,\n\t\t\t\t\toutlineWidth: this.styles.coordinatePointOutlineWidth,\n\t\t\t\t\toutlineOpacity: this.styles.coordinatePointOutlineOpacity,\n\t\t\t\t},\n\t\t\t};\n\n\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\tstyleMap[pointType].width,\n\t\t\t\tstyles.pointWidth,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOpacity = this.getNumericStylingValue(\n\t\t\t\tstyleMap[pointType].opacity,\n\t\t\t\t1,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\tstyleMap[pointType].color,\n\t\t\t\tstyles.pointColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\tstyleMap[pointType].outlineColor,\n\t\t\t\t\"#ffffff\",\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineWidth = this.getNumericStylingValue(\n\t\t\t\tstyleMap[pointType].outlineWidth,\n\t\t\t\t2,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineOpacity = this.getNumericStylingValue(\n\t\t\t\tstyleMap[pointType].outlineOpacity,\n\t\t\t\t1,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tif (coordinatePoint) {\n\t\t\t\tstyles.zIndex = Z_INDEX.LAYER_TWO;\n\t\t\t} else {\n\t\t\t\tstyles.zIndex = Z_INDEX.LAYER_FIVE;\n\t\t\t}\n\n\t\t\treturn styles;\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): StoreValidation {\n\t\treturn this.validateModeFeature(feature, (baseValidatedFeature) =>\n\t\t\tValidateLineStringFeature(baseValidatedFeature, this.coordinatePrecision),\n\t\t);\n\t}\n\n\tprivate lineStringFilter(feature: Feature) {\n\t\treturn Boolean(\n\t\t\tfeature.geometry.type === \"LineString\" &&\n\t\t\t\tfeature.properties &&\n\t\t\t\tfeature.properties.mode === this.mode,\n\t\t);\n\t}\n\n\tprivate snapCoordinate(event: TerraDrawMouseEvent) {\n\t\tlet snappedCoordinate: Position | undefined;\n\n\t\tif (this.snapping?.toLine) {\n\t\t\tlet snapped: Position | undefined;\n\t\t\tif (this.currentId) {\n\t\t\t\tsnapped = this.lineSnapping.getSnappableCoordinate(\n\t\t\t\t\tevent,\n\t\t\t\t\tthis.currentId,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tsnapped = this.lineSnapping.getSnappableCoordinateFirstClick(event);\n\t\t\t}\n\n\t\t\tif (snapped) {\n\t\t\t\tsnappedCoordinate = snapped;\n\t\t\t}\n\t\t}\n\n\t\tif (this.snapping?.toCoordinate) {\n\t\t\tlet snapped: Position | undefined;\n\t\t\tif (this.currentId) {\n\t\t\t\tsnapped = this.coordinateSnapping.getSnappableCoordinate(\n\t\t\t\t\tevent,\n\t\t\t\t\tthis.currentId,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tsnapped =\n\t\t\t\t\tthis.coordinateSnapping.getSnappableCoordinateFirstClick(event);\n\t\t\t}\n\n\t\t\tif (snapped) {\n\t\t\t\tsnappedCoordinate = snapped;\n\t\t\t}\n\t\t}\n\n\t\tif (this.snapping?.toCustom) {\n\t\t\tconst snapped = this.snapping.toCustom(event, {\n\t\t\t\tcurrentCoordinate: this.currentCoordinate,\n\t\t\t\tcurrentId: this.currentId,\n\t\t\t\tgetCurrentGeometrySnapshot: this.currentId\n\t\t\t\t\t? () =>\n\t\t\t\t\t\t\tthis.readFeature.getGeometry<LineString>(\n\t\t\t\t\t\t\t\tthis.currentId as FeatureId,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t: () => null,\n\t\t\t\tproject: this.project,\n\t\t\t\tunproject: this.unproject,\n\t\t\t});\n\n\t\t\tif (snapped) {\n\t\t\t\tsnappedCoordinate = snapped;\n\t\t\t}\n\t\t}\n\n\t\treturn snappedCoordinate;\n\t}\n\n\tafterFeatureUpdated(feature: GeoJSONStoreFeatures) {\n\t\t// Clean up here is important to get right as we need to make a best effort to avoid erroneous\n\t\t// internal state.\n\n\t\t// IF we have coordinate points showing these need to be completely recreated\n\t\tif (this.showCoordinatePoints) {\n\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\tfeatureId: feature.id as FeatureId,\n\t\t\t\tfeatureCoordinates: feature.geometry.coordinates as Position[],\n\t\t\t});\n\t\t}\n\n\t\t// If we are editing a feature by dragging one of its points\n\t\t// we want to clear that state up as new polygon might be completely\n\t\t// different in terms of it's coordinates\n\t\tif (this.editedFeatureId === feature.id && this.editedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.editedPointId);\n\t\t\tthis.editedPointId = undefined;\n\t\t\tthis.editedFeatureId = undefined;\n\t\t\tthis.editedFeatureCoordinateIndex = undefined;\n\t\t\tthis.editedSnapType = undefined;\n\t\t}\n\n\t\t// We can recalculate the snapped point from the last mouse event if there was one\n\t\tif (this.snappedPointId && this.lastMouseMoveEvent) {\n\t\t\tthis.updateSnappedCoordinate(\n\t\t\t\tthis.lastMouseMoveEvent as TerraDrawMouseEvent,\n\t\t\t);\n\t\t}\n\n\t\t// NOTE: This handles the case we are currently drawing a polygon\n\t\t// We need to reset the drawing state because it is very complicated (impossible?)\n\t\t// to recover the drawing state after a feature update\n\t\tif (this.currentId === feature.id) {\n\t\t\tthis.closingPoints.delete();\n\n\t\t\tthis.currentCoordinate = 0;\n\t\t\tthis.currentId = undefined;\n\n\t\t\t// Go back to started state\n\t\t\tif (this.state === \"drawing\") {\n\t\t\t\tthis.setStarted();\n\t\t\t}\n\t\t}\n\t}\n\n\tafterFeatureAdded(feature: GeoJSONStoreFeatures) {\n\t\tif (this.showCoordinatePoints) {\n\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\tfeatureId: feature.id as FeatureId,\n\t\t\t\tfeatureCoordinates: feature.geometry.coordinates as Position[],\n\t\t\t});\n\t\t}\n\t}\n}\n","import { Validation } from \"../common\";\nimport { GeoJSONStoreFeatures } from \"../terra-draw\";\nimport {\n\tcoordinateIsValid,\n\tcoordinatePrecisionIsValid,\n} from \"../geometry/boolean/is-valid-coordinate\";\n\nexport const ValidationReasonFeatureNotPoint = \"Feature is not a Point\";\nexport const ValidationReasonFeatureInvalidCoordinates =\n\t\"Feature has invalid coordinates\";\nexport const ValidationReasonFeatureInvalidCoordinatePrecision =\n\t\"Feature has coordinates with excessive precision\";\n\nexport function ValidatePointFeature(\n\tfeature: GeoJSONStoreFeatures,\n\tcoordinatePrecision: number,\n): ReturnType<Validation> {\n\tif (feature.geometry.type !== \"Point\") {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\treason: ValidationReasonFeatureNotPoint,\n\t\t};\n\t}\n\n\tif (!coordinateIsValid(feature.geometry.coordinates)) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\treason: ValidationReasonFeatureInvalidCoordinates,\n\t\t};\n\t}\n\n\tif (\n\t\t!coordinatePrecisionIsValid(\n\t\t\tfeature.geometry.coordinates,\n\t\t\tcoordinatePrecision,\n\t\t)\n\t) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\treason: ValidationReasonFeatureInvalidCoordinatePrecision,\n\t\t};\n\t}\n\n\treturn { valid: true };\n}\n","import { Position } from \"geojson\";\nimport { TerraDrawMouseEvent } from \"../common\";\nimport { BBoxPolygon, GeoJSONStoreFeatures } from \"../store/store\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"./base.behavior\";\nimport { ClickBoundingBoxBehavior } from \"./click-bounding-box.behavior\";\nimport { PixelDistanceBehavior } from \"./pixel-distance.behavior\";\n\nexport class PointSearchBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\tconfig: BehaviorConfig,\n\t\tprivate readonly pixelDistance: PixelDistanceBehavior,\n\t\tprivate readonly clickBoundingBox: ClickBoundingBoxBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tpublic getNearestPointFeature(event: TerraDrawMouseEvent) {\n\t\tconst bbox = this.clickBoundingBox.create(event) as BBoxPolygon;\n\t\tconst features = this.store.search(bbox);\n\n\t\tlet distance = Infinity;\n\t\tlet clickedFeature: GeoJSONStoreFeatures | undefined = undefined;\n\n\t\tfor (let i = 0; i < features.length; i++) {\n\t\t\tconst feature = features[i];\n\t\t\tconst isPoint =\n\t\t\t\tfeature.geometry.type === \"Point\" &&\n\t\t\t\tfeature.properties.mode === this.mode;\n\n\t\t\tif (!isPoint) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst position = feature.geometry.coordinates as Position;\n\t\t\tconst distanceToFeature = this.pixelDistance.measure(event, position);\n\n\t\t\tif (\n\t\t\t\tdistanceToFeature > distance ||\n\t\t\t\tdistanceToFeature > this.pointerDistance\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tdistance = distanceToFeature;\n\t\t\tclickedFeature = feature;\n\t\t}\n\n\t\treturn clickedFeature;\n\t}\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tNumericStyling,\n\tHexColorStyling,\n\tCursor,\n\tUpdateTypes,\n\tCOMMON_PROPERTIES,\n\tZ_INDEX,\n\tFinishActions,\n} from \"../../common\";\nimport {\n\tFeatureId,\n\tGeoJSONStoreFeatures,\n\tStoreValidation,\n} from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tModeUpdateOptions,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { ValidatePointFeature } from \"../../validations/point.validation\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../click-bounding-box.behavior\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { PointSearchBehavior } from \"../point-search.behavior\";\nimport { MutateFeatureBehavior, Mutations } from \"../mutate-feature.behavior\";\n\ntype PointModeStyling = {\n\tpointWidth: NumericStyling;\n\tpointColor: HexColorStyling;\n\tpointOpacity: NumericStyling;\n\tpointOutlineColor: HexColorStyling;\n\tpointOutlineOpacity: NumericStyling;\n\tpointOutlineWidth: NumericStyling;\n\teditedPointColor: HexColorStyling;\n\teditedPointWidth: NumericStyling;\n\teditedPointOutlineColor: HexColorStyling;\n\teditedPointOutlineWidth: NumericStyling;\n};\n\ninterface Cursors {\n\tcreate?: Cursor;\n\tdragStart?: Cursor;\n\tdragEnd?: Cursor;\n}\n\nconst defaultCursors = {\n\tcreate: \"crosshair\",\n\tdragStart: \"grabbing\",\n\tdragEnd: \"crosshair\",\n} as Required<Cursors>;\n\ninterface TerraDrawPointModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tcursors?: Cursors;\n\teditable?: boolean;\n}\n\nexport class TerraDrawPointMode extends TerraDrawBaseDrawMode<PointModeStyling> {\n\tmode = \"point\";\n\n\t// Options\n\tprivate cursors: Required<Cursors> = defaultCursors;\n\tprivate editable: boolean = false;\n\n\t// Internal state\n\tprivate editedFeatureId: FeatureId | undefined;\n\n\t// Behaviors\n\tprivate pixelDistance!: PixelDistanceBehavior;\n\tprivate clickBoundingBox!: ClickBoundingBoxBehavior;\n\tprivate pointSearch!: PointSearchBehavior;\n\tprivate mutateFeature!: MutateFeatureBehavior;\n\n\tconstructor(options?: TerraDrawPointModeOptions<PointModeStyling>) {\n\t\tsuper(options, true);\n\t\tthis.updateOptions(options);\n\t}\n\n\tupdateOptions(\n\t\toptions?: ModeUpdateOptions<TerraDrawPointModeOptions<PointModeStyling>>,\n\t): void {\n\t\tsuper.updateOptions(options);\n\n\t\tif (options?.cursors) {\n\t\t\tthis.cursors = { ...this.cursors, ...options.cursors };\n\t\t}\n\n\t\tif (options?.editable) {\n\t\t\tthis.editable = options.editable;\n\t\t}\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.create);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\tif (\n\t\t\t(event.button === \"right\" &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.rightClick, event)) ||\n\t\t\t(event.isContextMenu &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.contextMenu, event))\n\t\t) {\n\t\t\tthis.onRightClick(event);\n\t\t\treturn;\n\t\t} else if (\n\t\t\tevent.button === \"left\" &&\n\t\t\tthis.allowPointerEvent(this.pointerEvents.leftClick, event)\n\t\t) {\n\t\t\tthis.onLeftClick(event);\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/** @internal */\n\tonMouseMove() {}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonKeyUp() {}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tthis.editedFeatureId = undefined;\n\t}\n\n\tonDragStart(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (!this.allowPointerEvent(this.pointerEvents.onDragStart, event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.editable) {\n\t\t\tconst nearestPointFeature =\n\t\t\t\tthis.pointSearch.getNearestPointFeature(event);\n\t\t\tthis.editedFeatureId = nearestPointFeature?.id;\n\t\t}\n\n\t\t// We only need to stop the map dragging if\n\t\t// we actually have something selected\n\t\tif (!this.editedFeatureId) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Drag Feature\n\t\tthis.setCursor(this.cursors.dragStart);\n\n\t\tsetMapDraggability(false);\n\t}\n\n\t/** @internal */\n\tonDrag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (!this.allowPointerEvent(this.pointerEvents.onDrag, event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.editedFeatureId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.mutateFeature.updatePoint({\n\t\t\tfeatureId: this.editedFeatureId,\n\t\t\tcoordinateMutations: {\n\t\t\t\ttype: Mutations.Replace,\n\t\t\t\tcoordinates: [event.lng, event.lat],\n\t\t\t},\n\t\t\tpropertyMutations: {\n\t\t\t\t[COMMON_PROPERTIES.EDITED]: true,\n\t\t\t},\n\t\t\tcontext: { updateType: UpdateTypes.Provisional },\n\t\t});\n\t}\n\n\t/** @internal */\n\tonDragEnd(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (!this.allowPointerEvent(this.pointerEvents.onDragEnd, event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.editedFeatureId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst updated = this.mutateFeature.updatePoint({\n\t\t\tfeatureId: this.editedFeatureId,\n\t\t\tpropertyMutations: {\n\t\t\t\tmode: this.mode,\n\t\t\t\t[COMMON_PROPERTIES.EDITED]: false,\n\t\t\t},\n\t\t\tcontext: { updateType: UpdateTypes.Finish, action: \"edit\" },\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst featureId = this.editedFeatureId;\n\n\t\tthis.setCursor(this.cursors.dragEnd);\n\t\tthis.editedFeatureId = undefined;\n\t\tsetMapDraggability(true);\n\n\t\tthis.onFinish(featureId, {\n\t\t\tmode: this.mode,\n\t\t\taction: FinishActions.Draw,\n\t\t});\n\t}\n\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.pixelDistance = new PixelDistanceBehavior(config);\n\t\tthis.clickBoundingBox = new ClickBoundingBoxBehavior(config);\n\t\tthis.pointSearch = new PointSearchBehavior(\n\t\t\tconfig,\n\t\t\tthis.pixelDistance,\n\t\t\tthis.clickBoundingBox,\n\t\t);\n\t\tthis.mutateFeature = new MutateFeatureBehavior(config, {\n\t\t\tvalidate: this.validate,\n\t\t});\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"Point\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tconst isEdited = Boolean(\n\t\t\t\tfeature.id && this.editedFeatureId === feature.id,\n\t\t\t);\n\n\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\tisEdited ? this.styles.editedPointWidth : this.styles.pointWidth,\n\t\t\t\tstyles.pointWidth,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.pointOpacity,\n\t\t\t\tstyles.pointOpacity === undefined ? 1 : styles.pointOpacity,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\tisEdited ? this.styles.editedPointColor : this.styles.pointColor,\n\t\t\t\tstyles.pointColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\tisEdited\n\t\t\t\t\t? this.styles.editedPointOutlineColor\n\t\t\t\t\t: this.styles.pointOutlineColor,\n\t\t\t\tstyles.pointOutlineColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.pointOutlineOpacity,\n\t\t\t\tstyles.pointOutlineOpacity === undefined\n\t\t\t\t\t? 1\n\t\t\t\t\t: styles.pointOutlineOpacity,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineWidth = this.getNumericStylingValue(\n\t\t\t\tisEdited\n\t\t\t\t\t? this.styles.editedPointOutlineWidth\n\t\t\t\t\t: this.styles.pointOutlineWidth,\n\t\t\t\t2,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.zIndex = Z_INDEX.LAYER_THREE;\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): StoreValidation {\n\t\treturn this.validateModeFeature(feature, (baseValidatedFeature) =>\n\t\t\tValidatePointFeature(baseValidatedFeature, this.coordinatePrecision),\n\t\t);\n\t}\n\n\tprivate onLeftClick(event: TerraDrawMouseEvent) {\n\t\tconst feature = this.mutateFeature.createPoint({\n\t\t\tcoordinates: [event.lng, event.lat],\n\t\t\tproperties: {\n\t\t\t\tmode: this.mode,\n\t\t\t},\n\t\t\tcontext: { updateType: UpdateTypes.Finish, action: FinishActions.Draw },\n\t\t});\n\n\t\tif (feature) {\n\t\t\tthis.onFinish(feature.id, {\n\t\t\t\tmode: this.mode,\n\t\t\t\taction: FinishActions.Draw,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate onRightClick(event: TerraDrawMouseEvent) {\n\t\t// We only want to be able to delete points if the mode is editable\n\t\tif (!this.editable) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst clickedFeature = this.pointSearch.getNearestPointFeature(event);\n\n\t\tif (clickedFeature) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(clickedFeature.id as FeatureId);\n\t\t}\n\t}\n\n\tafterFeatureUpdated(feature: GeoJSONStoreFeatures) {\n\t\t// If we are editing a point by dragging it we want to clear that state\n\t\t// up as new point location might be completely  different in terms of it's location\n\t\tif (this.editedFeatureId === feature.id) {\n\t\t\tthis.editedFeatureId = undefined;\n\t\t\tthis.setCursor(this.cursors.create);\n\t\t}\n\t}\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n\tCOMMON_PROPERTIES,\n\tZ_INDEX,\n\tSnapping,\n\tFinishActions,\n} from \"../../common\";\nimport { Feature, Polygon, Position } from \"geojson\";\nimport {\n\tTerraDrawBaseDrawMode,\n\tBaseModeOptions,\n\tCustomStyling,\n\tPointerEvents,\n\tModeUpdateOptions,\n} from \"../base.mode\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../click-bounding-box.behavior\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { ClosingPointsBehavior } from \"../closing-points.behavior\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tFeatureId,\n\tGeoJSONStoreFeatures,\n\tStoreValidation,\n} from \"../../store/store\";\nimport { ValidatePolygonFeature } from \"../../validations/polygon.validation\";\nimport { LineSnappingBehavior } from \"../line-snapping.behavior\";\nimport { CoordinateSnappingBehavior } from \"../coordinate-snapping.behavior\";\nimport { CoordinatePointBehavior } from \"../select/behaviors/coordinate-point.behavior\";\nimport {\n\tCoordinateMutation,\n\tMutateFeatureBehavior,\n\tMutations,\n} from \"../mutate-feature.behavior\";\nimport { ReadFeatureBehavior } from \"../read-feature.behavior\";\n\ntype TerraDrawPolygonModeKeyEvents = {\n\tcancel?: KeyboardEvent[\"key\"] | null;\n\tfinish?: KeyboardEvent[\"key\"] | null;\n};\n\nconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\ntype PolygonStyling = {\n\tfillColor: HexColorStyling;\n\tfillOpacity: NumericStyling;\n\toutlineColor: HexColorStyling;\n\toutlineOpacity: NumericStyling;\n\toutlineWidth: NumericStyling;\n\tclosingPointWidth: NumericStyling;\n\tclosingPointColor: HexColorStyling;\n\tclosingPointOpacity: NumericStyling;\n\tclosingPointOutlineWidth: NumericStyling;\n\tclosingPointOutlineColor: HexColorStyling;\n\tclosingPointOutlineOpacity: NumericStyling;\n\tsnappingPointWidth: NumericStyling;\n\tsnappingPointColor: HexColorStyling;\n\tsnappingPointOpacity: NumericStyling;\n\tsnappingPointOutlineWidth: NumericStyling;\n\tsnappingPointOutlineColor: HexColorStyling;\n\tsnappingPointOutlineOpacity: NumericStyling;\n\teditedPointWidth: NumericStyling;\n\teditedPointColor: HexColorStyling;\n\teditedPointOpacity: NumericStyling;\n\teditedPointOutlineWidth: NumericStyling;\n\teditedPointOutlineColor: HexColorStyling;\n\teditedPointOutlineOpacity: NumericStyling;\n\tcoordinatePointWidth: NumericStyling;\n\tcoordinatePointColor: HexColorStyling;\n\tcoordinatePointOpacity: NumericStyling;\n\tcoordinatePointOutlineWidth: NumericStyling;\n\tcoordinatePointOutlineColor: HexColorStyling;\n\tcoordinatePointOutlineOpacity: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n\tclose?: Cursor;\n\tdragStart?: Cursor;\n\tdragEnd?: Cursor;\n}\n\nconst defaultCursors = {\n\tstart: \"crosshair\",\n\tclose: \"pointer\",\n\tdragStart: \"grabbing\",\n\tdragEnd: \"crosshair\",\n} as Required<Cursors>;\n\ninterface TerraDrawPolygonModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tsnapping?: Snapping;\n\tpointerDistance?: number;\n\tkeyEvents?: TerraDrawPolygonModeKeyEvents | null;\n\tpointerEvents?: PointerEvents;\n\tcursors?: Cursors;\n\teditable?: boolean;\n\tshowCoordinatePoints?: boolean;\n}\n\nexport class TerraDrawPolygonMode extends TerraDrawBaseDrawMode<PolygonStyling> {\n\tmode = \"polygon\";\n\n\tprivate currentCoordinate = 0;\n\tprivate currentId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawPolygonModeKeyEvents = defaultKeyEvents;\n\tprivate cursors: Required<Cursors> = defaultCursors;\n\tprivate mouseMove = false;\n\tprivate showCoordinatePoints = false;\n\tprivate lastMouseMoveEvent: TerraDrawMouseEvent | undefined;\n\n\t// Snapping\n\tprivate snapping: Snapping | undefined;\n\tprivate snappedPointId: FeatureId | undefined;\n\n\t// Editable\n\tprivate editable: boolean = false;\n\tprivate editedFeatureId: FeatureId | undefined;\n\tprivate editedFeatureCoordinateIndex: number | undefined;\n\tprivate editedSnapType: \"line\" | \"coordinate\" | undefined;\n\tprivate editedInsertIndex: number | undefined;\n\tprivate editedPointId: FeatureId | undefined;\n\n\t// Behaviors\n\tprivate coordinatePoints!: CoordinatePointBehavior;\n\tprivate lineSnapping!: LineSnappingBehavior;\n\tprivate coordinateSnapping!: CoordinateSnappingBehavior;\n\tprivate pixelDistance!: PixelDistanceBehavior;\n\tprivate closingPoints!: ClosingPointsBehavior;\n\tprivate clickBoundingBox!: ClickBoundingBoxBehavior;\n\tprivate mutateFeature!: MutateFeatureBehavior;\n\tprivate readFeature!: ReadFeatureBehavior;\n\n\tconstructor(options?: TerraDrawPolygonModeOptions<PolygonStyling>) {\n\t\tsuper(options, true);\n\t\tthis.updateOptions(options);\n\t}\n\n\toverride updateOptions(\n\t\toptions?: ModeUpdateOptions<TerraDrawPolygonModeOptions<PolygonStyling>>,\n\t) {\n\t\tsuper.updateOptions(options);\n\n\t\tif (options?.cursors) {\n\t\t\tthis.cursors = { ...this.cursors, ...options.cursors };\n\t\t}\n\n\t\t// null is the case where we want to explicitly turn key bindings off\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = { cancel: null, finish: null };\n\t\t} else if (options?.keyEvents) {\n\t\t\tthis.keyEvents = { ...this.keyEvents, ...options.keyEvents };\n\t\t}\n\n\t\tif (options?.snapping) {\n\t\t\tthis.snapping = options.snapping;\n\t\t}\n\n\t\tif (options?.editable !== undefined) {\n\t\t\tthis.editable = options.editable;\n\t\t}\n\n\t\tif (options?.pointerEvents !== undefined) {\n\t\t\tthis.pointerEvents = options.pointerEvents;\n\t\t}\n\n\t\tif (options?.showCoordinatePoints !== undefined) {\n\t\t\tthis.showCoordinatePoints = options.showCoordinatePoints;\n\n\t\t\t// If we are not showing coordinate points, we need to add them all\n\t\t\tif (this.coordinatePoints && options.showCoordinatePoints === true) {\n\t\t\t\tconst features = this.store.copyAllWhere(\n\t\t\t\t\t(properties) => properties.mode === this.mode,\n\t\t\t\t);\n\t\t\t\tfeatures.forEach((feature) => {\n\t\t\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\t\t\tfeatureId: feature.id as FeatureId,\n\t\t\t\t\t\tfeatureCoordinates: feature.geometry.coordinates as Position[][],\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t} else if (this.coordinatePoints && this.showCoordinatePoints === false) {\n\t\t\t\tconst featuresWithCoordinates = this.store.copyAllWhere(\n\t\t\t\t\t(properties) =>\n\t\t\t\t\t\tproperties.mode === this.mode &&\n\t\t\t\t\t\tBoolean(\n\t\t\t\t\t\t\tproperties[COMMON_PROPERTIES.COORDINATE_POINT_IDS] as FeatureId[],\n\t\t\t\t\t\t),\n\t\t\t\t);\n\n\t\t\t\tthis.coordinatePoints.deletePointsByFeatureIds(\n\t\t\t\t\tfeaturesWithCoordinates.map((f) => f.id as FeatureId),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate close() {\n\t\tif (this.currentId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentPolygonCoordinates = this.readFeature.getCoordinates<Polygon>(\n\t\t\tthis.currentId,\n\t\t);\n\n\t\t// We don't want to allow closing if there is not enough\n\t\t// coordinates. We have extra because we insert them on mouse\n\t\t// move\n\t\tif (currentPolygonCoordinates.length < 5) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst updated = this.mutateFeature.updatePolygon({\n\t\t\tfeatureId: this.currentId,\n\t\t\tcoordinateMutations: [{ type: Mutations.Delete, index: -2 }],\n\t\t\tpropertyMutations: {\n\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: undefined,\n\t\t\t\t[COMMON_PROPERTIES.COMMITTED_COORDINATE_COUNT]: undefined,\n\t\t\t\t[COMMON_PROPERTIES.PROVISIONAL_COORDINATE_COUNT]: undefined,\n\t\t\t},\n\t\t\tcontext: {\n\t\t\t\tupdateType: UpdateTypes.Finish,\n\t\t\t\taction: FinishActions.Draw,\n\t\t\t},\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.showCoordinatePoints) {\n\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\tfeatureId: this.currentId,\n\t\t\t\tfeatureCoordinates: updated.geometry.coordinates,\n\t\t\t});\n\t\t}\n\n\t\t// Go back to started state\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tif (this.editedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.editedPointId);\n\t\t\tthis.editedPointId = undefined;\n\t\t}\n\n\t\tif (this.snappedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\t\tthis.snappedPointId = undefined;\n\t\t}\n\n\t\tthis.closingPoints.delete();\n\n\t\tconst featureId = this.currentId;\n\n\t\tthis.currentCoordinate = 0;\n\t\tthis.currentId = undefined;\n\n\t\tthis.onFinish(featureId, {\n\t\t\tmode: this.mode,\n\t\t\taction: FinishActions.Draw,\n\t\t});\n\t}\n\n\t/** @internal */\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.readFeature = new ReadFeatureBehavior(config);\n\t\tthis.mutateFeature = new MutateFeatureBehavior(config, {\n\t\t\tvalidate: this.validate,\n\t\t});\n\t\tthis.clickBoundingBox = new ClickBoundingBoxBehavior(config);\n\t\tthis.pixelDistance = new PixelDistanceBehavior(config);\n\t\tthis.lineSnapping = new LineSnappingBehavior(\n\t\t\tconfig,\n\t\t\tthis.pixelDistance,\n\t\t\tthis.clickBoundingBox,\n\t\t);\n\t\tthis.coordinateSnapping = new CoordinateSnappingBehavior(\n\t\t\tconfig,\n\t\t\tthis.pixelDistance,\n\t\t\tthis.clickBoundingBox,\n\t\t);\n\t\tthis.closingPoints = new ClosingPointsBehavior(\n\t\t\tconfig,\n\t\t\tthis.pixelDistance,\n\t\t\tthis.mutateFeature,\n\t\t\tthis.readFeature,\n\t\t);\n\n\t\tthis.coordinatePoints = new CoordinatePointBehavior(\n\t\t\tconfig,\n\t\t\tthis.readFeature,\n\t\t\tthis.mutateFeature,\n\t\t);\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\tprivate updateSnappedCoordinate(event: TerraDrawMouseEvent) {\n\t\tconst snappedCoordinate = this.snapCoordinate(event);\n\n\t\tif (snappedCoordinate) {\n\t\t\tif (this.snappedPointId) {\n\t\t\t\tthis.mutateFeature.updateGuidancePoints([\n\t\t\t\t\t{\n\t\t\t\t\t\tfeatureId: this.snappedPointId,\n\t\t\t\t\t\tcoordinate: snappedCoordinate,\n\t\t\t\t\t},\n\t\t\t\t]);\n\t\t\t} else {\n\t\t\t\tthis.snappedPointId = this.mutateFeature.createGuidancePoint({\n\t\t\t\t\tcoordinate: snappedCoordinate,\n\t\t\t\t\ttype: COMMON_PROPERTIES.SNAPPING_POINT,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tevent.lng = snappedCoordinate[0];\n\t\t\tevent.lat = snappedCoordinate[1];\n\t\t} else if (this.snappedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\t\tthis.snappedPointId = undefined;\n\t\t}\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tthis.mouseMove = true;\n\t\tthis.setCursor(this.cursors.start);\n\n\t\tthis.lastMouseMoveEvent = event;\n\t\tthis.updateSnappedCoordinate(event);\n\n\t\tif (this.currentId === undefined || this.currentCoordinate === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst firstCoordinate = this.readFeature.getCoordinate<Polygon>(\n\t\t\tthis.currentId,\n\t\t\t0,\n\t\t);\n\t\tconst eventCoordinate = [event.lng, event.lat];\n\n\t\tlet coordinateMutations: CoordinateMutation[];\n\n\t\tif (this.currentCoordinate === 1) {\n\t\t\tcoordinateMutations = [\n\t\t\t\t{ type: Mutations.Update, index: 1, coordinate: eventCoordinate },\n\t\t\t\t{\n\t\t\t\t\ttype: Mutations.Update,\n\t\t\t\t\tindex: 2,\n\t\t\t\t\tcoordinate: [\n\t\t\t\t\t\tevent.lng,\n\t\t\t\t\t\tevent.lat - this.mutateFeature.epsilonOffset(),\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t];\n\t\t} else if (this.currentCoordinate === 2) {\n\t\t\tcoordinateMutations = [\n\t\t\t\t{ type: Mutations.Update, index: 2, coordinate: eventCoordinate },\n\t\t\t];\n\t\t} else {\n\t\t\tconst { isClosing, isPreviousClosing } =\n\t\t\t\tthis.closingPoints.isPolygonClosingPoints(event);\n\n\t\t\tif (isPreviousClosing || isClosing) {\n\t\t\t\tif (this.snappedPointId) {\n\t\t\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\t\t\t\tthis.snappedPointId = undefined;\n\t\t\t\t}\n\n\t\t\t\tthis.setCursor(this.cursors.close);\n\n\t\t\t\tcoordinateMutations = [\n\t\t\t\t\t{ type: Mutations.Update, index: -1, coordinate: firstCoordinate },\n\t\t\t\t\t{ type: Mutations.Update, index: -2, coordinate: firstCoordinate },\n\t\t\t\t];\n\t\t\t} else {\n\t\t\t\tcoordinateMutations = [\n\t\t\t\t\t{ type: Mutations.Update, index: -2, coordinate: eventCoordinate },\n\t\t\t\t\t{ type: Mutations.Update, index: -1, coordinate: firstCoordinate },\n\t\t\t\t];\n\t\t\t}\n\t\t}\n\n\t\tconst updated = this.mutateFeature.updatePolygon({\n\t\t\tfeatureId: this.currentId,\n\t\t\tcoordinateMutations,\n\t\t\tpropertyMutations: {\n\t\t\t\t[COMMON_PROPERTIES.PROVISIONAL_COORDINATE_COUNT]:\n\t\t\t\t\tthis.currentCoordinate + 1,\n\t\t\t},\n\t\t\tcontext: { updateType: UpdateTypes.Provisional },\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.showCoordinatePoints) {\n\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\tfeatureId: this.currentId,\n\t\t\t\tfeatureCoordinates: updated.geometry.coordinates,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate snapCoordinate(event: TerraDrawMouseEvent): undefined | Position {\n\t\tlet snappedCoordinate: Position | undefined = undefined;\n\n\t\tif (this.snapping?.toLine) {\n\t\t\tlet snapped: Position | undefined;\n\t\t\tif (this.currentId) {\n\t\t\t\tsnapped = this.lineSnapping.getSnappableCoordinate(\n\t\t\t\t\tevent,\n\t\t\t\t\tthis.currentId,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tsnapped = this.lineSnapping.getSnappableCoordinateFirstClick(event);\n\t\t\t}\n\n\t\t\tif (snapped) {\n\t\t\t\tsnappedCoordinate = snapped;\n\t\t\t}\n\t\t}\n\n\t\tif (this.snapping?.toCoordinate) {\n\t\t\tlet snapped: Position | undefined = undefined;\n\t\t\tif (this.currentId) {\n\t\t\t\tsnapped = this.coordinateSnapping.getSnappableCoordinate(\n\t\t\t\t\tevent,\n\t\t\t\t\tthis.currentId,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tsnapped =\n\t\t\t\t\tthis.coordinateSnapping.getSnappableCoordinateFirstClick(event);\n\t\t\t}\n\n\t\t\tif (snapped) {\n\t\t\t\tsnappedCoordinate = snapped;\n\t\t\t}\n\t\t}\n\n\t\tif (this.snapping?.toCustom) {\n\t\t\tconst snapped = this.snapping.toCustom(event, {\n\t\t\t\tcurrentCoordinate: this.currentCoordinate,\n\t\t\t\tcurrentId: this.currentId,\n\t\t\t\tgetCurrentGeometrySnapshot: this.currentId\n\t\t\t\t\t? () =>\n\t\t\t\t\t\t\tthis.readFeature.getGeometry<Polygon>(this.currentId as FeatureId)\n\t\t\t\t\t: () => null,\n\t\t\t\tproject: this.project,\n\t\t\t\tunproject: this.unproject,\n\t\t\t});\n\n\t\t\tif (snapped) {\n\t\t\t\tsnappedCoordinate = snapped;\n\t\t\t}\n\t\t}\n\n\t\treturn snappedCoordinate;\n\t}\n\n\tprivate polygonFilter(feature: Feature) {\n\t\treturn Boolean(\n\t\t\tfeature.geometry.type === \"Polygon\" &&\n\t\t\t\tfeature.properties &&\n\t\t\t\tfeature.properties.mode === this.mode,\n\t\t);\n\t}\n\n\tprivate onRightClick(event: TerraDrawMouseEvent) {\n\t\t// Right click is only relevant when editable is true\n\t\tif (!this.editable || this.state !== \"started\") {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { featureId, featureCoordinateIndex: coordinateIndex } =\n\t\t\tthis.coordinateSnapping.getSnappable(event, (feature) =>\n\t\t\t\tthis.polygonFilter(feature),\n\t\t\t);\n\n\t\tif (!featureId || coordinateIndex === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst geometry = this.readFeature.getGeometry(featureId);\n\n\t\tif (geometry.type !== \"Polygon\") {\n\t\t\treturn;\n\t\t}\n\n\t\tconst coordinates = geometry.coordinates[0];\n\n\t\t// Prevent creating an invalid polygon\n\t\tif (coordinates.length <= 4) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst isFinalPolygonCoordinate =\n\t\t\tcoordinateIndex === 0 || coordinateIndex === coordinates.length - 1;\n\n\t\tlet coordinateMutations: CoordinateMutation[];\n\n\t\tif (isFinalPolygonCoordinate) {\n\t\t\t// Deleting the final coordinate in a polygon breaks it\n\t\t\t// because GeoJSON expects a duplicate, so we need to fix\n\t\t\t// it by adding the new first coordinate to the end\n\n\t\t\t// The second coordinate becomes the first coordinate, so we need to\n\t\t\t// add it to the end to maintain the closed polygon\n\t\t\tconst secondCoordinate = coordinates[1];\n\n\t\t\tcoordinateMutations = [\n\t\t\t\t{ type: Mutations.Delete, index: 0 },\n\t\t\t\t{ type: Mutations.Delete, index: -1 },\n\t\t\t\t{\n\t\t\t\t\ttype: Mutations.InsertAfter,\n\t\t\t\t\tindex: -1,\n\t\t\t\t\tcoordinate: secondCoordinate,\n\t\t\t\t},\n\t\t\t];\n\t\t} else {\n\t\t\t// Remove coordinate from array\n\t\t\tcoordinateMutations = [\n\t\t\t\t{ type: Mutations.Delete, index: coordinateIndex },\n\t\t\t];\n\t\t}\n\n\t\tconst updated = this.mutateFeature.updatePolygon({\n\t\t\tfeatureId,\n\t\t\tcoordinateMutations,\n\t\t\tcontext: { updateType: UpdateTypes.Finish, action: FinishActions.Edit },\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.showCoordinatePoints) {\n\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\tfeatureId,\n\t\t\t\tfeatureCoordinates: updated.geometry.coordinates,\n\t\t\t});\n\t\t}\n\n\t\tif (this.snappedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\t\tthis.snappedPointId = undefined;\n\n\t\t\tif (this.snapping) {\n\t\t\t\tconst snappedCoordinate = this.snapCoordinate(event);\n\t\t\t\tif (snappedCoordinate) {\n\t\t\t\t\tconst [snappedPointId] = this.mutateFeature.createGuidancePoints({\n\t\t\t\t\t\ttype: COMMON_PROPERTIES.SNAPPING_POINT,\n\t\t\t\t\t\tcoordinates: [snappedCoordinate],\n\t\t\t\t\t});\n\t\t\t\t\tthis.snappedPointId = snappedPointId;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.onFinish(featureId, { mode: this.mode, action: FinishActions.Edit });\n\t}\n\n\tprivate onLeftClick(event: TerraDrawMouseEvent) {\n\t\t// Reset the snapping point\n\t\tif (this.snappedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\t\tthis.snappedPointId = undefined;\n\t\t}\n\n\t\tconst snappedCoordinate = this.snapCoordinate(event);\n\n\t\tlet eventCoordinate = snappedCoordinate\n\t\t\t? snappedCoordinate\n\t\t\t: [event.lng, event.lat];\n\n\t\tif (this.currentCoordinate === 0) {\n\t\t\tconst { id, geometry } = this.mutateFeature.createPolygon({\n\t\t\t\tcoordinates: [\n\t\t\t\t\teventCoordinate,\n\t\t\t\t\teventCoordinate,\n\t\t\t\t\teventCoordinate,\n\t\t\t\t\teventCoordinate,\n\t\t\t\t],\n\t\t\t\tproperties: {\n\t\t\t\t\tmode: this.mode,\n\t\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: true,\n\t\t\t\t\t[COMMON_PROPERTIES.COMMITTED_COORDINATE_COUNT]:\n\t\t\t\t\t\tthis.currentCoordinate + 1,\n\t\t\t\t\t[COMMON_PROPERTIES.PROVISIONAL_COORDINATE_COUNT]:\n\t\t\t\t\t\tthis.currentCoordinate + 1,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (this.showCoordinatePoints) {\n\t\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\t\tfeatureId: id,\n\t\t\t\t\tfeatureCoordinates: geometry.coordinates,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.currentId = id;\n\t\t\tthis.currentCoordinate++;\n\n\t\t\t// Ensure the state is updated to reflect drawing has started\n\t\t\tthis.setDrawing();\n\t\t} else if (this.currentCoordinate === 1 && this.currentId) {\n\t\t\tconst isIdentical = this.readFeature.coordinateAtIndexIsIdentical({\n\t\t\t\tfeatureId: this.currentId,\n\t\t\t\tnewCoordinate: eventCoordinate,\n\t\t\t\tindex: 0,\n\t\t\t});\n\n\t\t\tif (isIdentical) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst updated = this.mutateFeature.updatePolygon({\n\t\t\t\tfeatureId: this.currentId,\n\t\t\t\tcoordinateMutations: [\n\t\t\t\t\t{ type: Mutations.Update, index: 1, coordinate: eventCoordinate },\n\t\t\t\t\t{ type: Mutations.Update, index: 2, coordinate: eventCoordinate },\n\t\t\t\t],\n\t\t\t\tpropertyMutations: {\n\t\t\t\t\t[COMMON_PROPERTIES.COMMITTED_COORDINATE_COUNT]:\n\t\t\t\t\t\tthis.currentCoordinate + 1,\n\t\t\t\t},\n\t\t\t\tcontext: { updateType: UpdateTypes.Commit },\n\t\t\t});\n\n\t\t\tif (!updated) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.showCoordinatePoints) {\n\t\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\t\tfeatureId: this.currentId,\n\t\t\t\t\tfeatureCoordinates: updated.geometry.coordinates,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.currentCoordinate++;\n\t\t} else if (this.currentCoordinate === 2 && this.currentId) {\n\t\t\tconst isIdentical = this.readFeature.coordinateAtIndexIsIdentical({\n\t\t\t\tfeatureId: this.currentId,\n\t\t\t\tnewCoordinate: eventCoordinate,\n\t\t\t\tindex: 1,\n\t\t\t});\n\n\t\t\tif (isIdentical) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst updated = this.mutateFeature.updatePolygon({\n\t\t\t\tfeatureId: this.currentId,\n\t\t\t\tcoordinateMutations: [\n\t\t\t\t\t{ type: Mutations.Update, index: 2, coordinate: eventCoordinate },\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: Mutations.InsertAfter,\n\t\t\t\t\t\tindex: 2,\n\t\t\t\t\t\tcoordinate: eventCoordinate,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tpropertyMutations: {\n\t\t\t\t\t[COMMON_PROPERTIES.COMMITTED_COORDINATE_COUNT]:\n\t\t\t\t\t\tthis.currentCoordinate + 1,\n\t\t\t\t},\n\t\t\t\tcontext: { updateType: UpdateTypes.Commit },\n\t\t\t});\n\n\t\t\tif (!updated) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.showCoordinatePoints) {\n\t\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\t\tfeatureId: this.currentId,\n\t\t\t\t\tfeatureCoordinates: updated.geometry.coordinates,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (this.currentCoordinate === 2) {\n\t\t\t\tthis.closingPoints.create(updated.geometry.coordinates);\n\t\t\t}\n\n\t\t\tthis.currentCoordinate++;\n\t\t} else if (this.currentId) {\n\t\t\tconst { isClosing, isPreviousClosing } =\n\t\t\t\tthis.closingPoints.isPolygonClosingPoints(event);\n\n\t\t\tif (isPreviousClosing || isClosing) {\n\t\t\t\tthis.close();\n\t\t\t} else {\n\t\t\t\tconst isIdentical = this.readFeature.coordinateAtIndexIsIdentical({\n\t\t\t\t\tfeatureId: this.currentId,\n\t\t\t\t\tnewCoordinate: eventCoordinate,\n\t\t\t\t\tindex: this.currentCoordinate - 1,\n\t\t\t\t});\n\n\t\t\t\tif (isIdentical) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// If not close to the final point, keep adding points\n\t\t\t\tconst updated = this.mutateFeature.updatePolygon({\n\t\t\t\t\tfeatureId: this.currentId,\n\t\t\t\t\tcoordinateMutations: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: Mutations.InsertBefore,\n\t\t\t\t\t\t\tindex: -1,\n\t\t\t\t\t\t\tcoordinate: eventCoordinate,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tpropertyMutations: {\n\t\t\t\t\t\t[COMMON_PROPERTIES.COMMITTED_COORDINATE_COUNT]:\n\t\t\t\t\t\t\tthis.currentCoordinate + 1,\n\t\t\t\t\t},\n\t\t\t\t\tcontext: { updateType: UpdateTypes.Commit },\n\t\t\t\t});\n\n\t\t\t\tif (!updated) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (this.showCoordinatePoints) {\n\t\t\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\t\t\tfeatureId: this.currentId,\n\t\t\t\t\t\tfeatureCoordinates: updated.geometry.coordinates,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tthis.currentCoordinate++;\n\n\t\t\t\t// Update closing points straight away\n\t\t\t\tif (this.closingPoints.ids.length) {\n\t\t\t\t\tthis.closingPoints.update(updated.geometry.coordinates);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\t// We want pointer devices (mobile/tablet) to have\n\t\t// similar behaviour to mouse based devices so we\n\t\t// trigger a mousemove event before every click\n\t\t// if one has not been trigged to emulate this\n\t\tif (this.currentCoordinate > 0 && !this.mouseMove) {\n\t\t\tthis.onMouseMove(event);\n\t\t}\n\t\tthis.mouseMove = false;\n\n\t\tif (\n\t\t\t(event.button === \"right\" &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.rightClick, event)) ||\n\t\t\t(event.isContextMenu &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.contextMenu, event))\n\t\t) {\n\t\t\tthis.onRightClick(event);\n\t\t\treturn;\n\t\t} else if (\n\t\t\tevent.button === \"left\" &&\n\t\t\tthis.allowPointerEvent(this.pointerEvents.leftClick, event)\n\t\t) {\n\t\t\tthis.onLeftClick(event);\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tif (event.key === this.keyEvents.cancel) {\n\t\t\tthis.cleanUp();\n\t\t} else if (event.key === this.keyEvents.finish) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\tonDragStart(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (!this.allowPointerEvent(this.pointerEvents.onDragStart, event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.editable) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet snappedCoordinate: Position | undefined = undefined;\n\n\t\tif (this.state === \"started\") {\n\t\t\t// Here we reuse the snapping logic to find the feature and coordinate\n\t\t\t// that we want to edit. We can drag a arbitrary polygon coordinate point\n\t\t\t// or an arbitrary point on one of its 'lines\n\n\t\t\tconst lineSnapped = this.lineSnapping.getSnappable(event, (feature) =>\n\t\t\t\tthis.polygonFilter(feature),\n\t\t\t);\n\n\t\t\tif (lineSnapped.coordinate) {\n\t\t\t\tthis.editedSnapType = \"line\";\n\t\t\t\tthis.editedFeatureCoordinateIndex = lineSnapped.featureCoordinateIndex;\n\t\t\t\tthis.editedFeatureId = lineSnapped.featureId;\n\t\t\t\tsnappedCoordinate = lineSnapped.coordinate;\n\t\t\t}\n\n\t\t\tconst coordinateSnapped = this.coordinateSnapping.getSnappable(\n\t\t\t\tevent,\n\t\t\t\t(feature) => this.polygonFilter(feature),\n\t\t\t);\n\n\t\t\tif (coordinateSnapped.coordinate) {\n\t\t\t\tthis.editedSnapType = \"coordinate\";\n\t\t\t\tthis.editedFeatureCoordinateIndex =\n\t\t\t\t\tcoordinateSnapped.featureCoordinateIndex;\n\t\t\t\tthis.editedFeatureId = coordinateSnapped.featureId;\n\t\t\t\tsnappedCoordinate = coordinateSnapped.coordinate;\n\t\t\t}\n\t\t}\n\n\t\t// We only need to stop the map dragging if\n\t\t// we actually have something selected\n\t\tif (!this.editedFeatureId || !snappedCoordinate) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Create a point to drag when editing\n\t\tif (!this.editedPointId) {\n\t\t\tthis.editedPointId = this.mutateFeature.createGuidancePoint({\n\t\t\t\tcoordinate: snappedCoordinate,\n\t\t\t\ttype: COMMON_PROPERTIES.EDITED,\n\t\t\t});\n\t\t}\n\n\t\t// Drag Feature\n\t\tthis.setCursor(this.cursors.dragStart);\n\n\t\tsetMapDraggability(false);\n\t}\n\n\t/** @internal */\n\tonDrag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (!this.allowPointerEvent(this.pointerEvents.onDrag, event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\tthis.editedFeatureId === undefined ||\n\t\t\tthis.editedFeatureCoordinateIndex === undefined\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst featureCopy: Polygon = this.readFeature.getGeometry(\n\t\t\tthis.editedFeatureId,\n\t\t);\n\n\t\tconst eventCoordinate: Position = [event.lng, event.lat];\n\n\t\tlet coordinateMutations: CoordinateMutation[] = [];\n\n\t\t// Either it's a coordinate drag or a line drag where the line coordinate has already been inserted\n\t\tif (\n\t\t\tthis.editedSnapType === \"coordinate\" ||\n\t\t\t(this.editedSnapType === \"line\" && this.editedInsertIndex !== undefined)\n\t\t) {\n\t\t\t// Account for the first and last point being the same\n\t\t\tconst isStartingOrEndingCoordinate =\n\t\t\t\tthis.editedFeatureCoordinateIndex === 0 ||\n\t\t\t\tthis.editedFeatureCoordinateIndex ===\n\t\t\t\t\tfeatureCopy.coordinates[0].length - 1;\n\n\t\t\tif (isStartingOrEndingCoordinate) {\n\t\t\t\tcoordinateMutations = [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: Mutations.Update,\n\t\t\t\t\t\tindex: 0,\n\t\t\t\t\t\tcoordinate: eventCoordinate,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: Mutations.Update,\n\t\t\t\t\t\tindex: -1,\n\t\t\t\t\t\tcoordinate: eventCoordinate,\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t} else {\n\t\t\t\tcoordinateMutations = [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: Mutations.Update,\n\t\t\t\t\t\tindex: this.editedFeatureCoordinateIndex,\n\t\t\t\t\t\tcoordinate: eventCoordinate,\n\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t}\n\t\t} else if (\n\t\t\tthis.editedSnapType === \"line\" &&\n\t\t\tthis.editedInsertIndex === undefined\n\t\t) {\n\t\t\tthis.editedInsertIndex = this.editedFeatureCoordinateIndex + 1;\n\n\t\t\tcoordinateMutations = [\n\t\t\t\t{\n\t\t\t\t\ttype: Mutations.InsertBefore,\n\t\t\t\t\tindex: this.editedInsertIndex,\n\t\t\t\t\tcoordinate: eventCoordinate,\n\t\t\t\t},\n\t\t\t];\n\n\t\t\t// We have inserted a point, need to change the edit index\n\t\t\t// so it can be moved correctly when it gets dragged again\n\t\t\tthis.editedFeatureCoordinateIndex++;\n\t\t}\n\n\t\t// No changes\n\t\tif (coordinateMutations.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst updated = this.mutateFeature.updatePolygon({\n\t\t\tfeatureId: this.editedFeatureId,\n\t\t\tcoordinateMutations,\n\t\t\tpropertyMutations: {\n\t\t\t\t[COMMON_PROPERTIES.EDITED]: true,\n\t\t\t},\n\t\t\tcontext: { updateType: UpdateTypes.Provisional },\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.showCoordinatePoints) {\n\t\t\t// If a point was inserted we need to update all coordinate points\n\t\t\tif (this.editedInsertIndex) {\n\t\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\t\tfeatureId: this.editedFeatureId,\n\t\t\t\t\tfeatureCoordinates: updated.geometry.coordinates,\n\t\t\t\t});\n\t\t\t}\n\t\t\t// Else we are only updating one point\n\t\t\telse {\n\t\t\t\tthis.coordinatePoints.updateOneAtIndex(\n\t\t\t\t\tthis.editedFeatureId,\n\t\t\t\t\tthis.editedFeatureCoordinateIndex,\n\t\t\t\t\tupdated.geometry.coordinates[0][this.editedFeatureCoordinateIndex],\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (this.snapping && this.snappedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\t\tthis.snappedPointId = undefined;\n\t\t}\n\n\t\tif (this.editedPointId) {\n\t\t\tthis.mutateFeature.updateGuidancePoints([\n\t\t\t\t{\n\t\t\t\t\tfeatureId: this.editedPointId,\n\t\t\t\t\tcoordinate: eventCoordinate,\n\t\t\t\t},\n\t\t\t]);\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDragEnd(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (!this.allowPointerEvent(this.pointerEvents.onDragEnd, event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.editedFeatureId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.setCursor(this.cursors.dragEnd);\n\n\t\tconst updated = this.mutateFeature.updatePolygon({\n\t\t\tfeatureId: this.editedFeatureId,\n\t\t\tpropertyMutations: {\n\t\t\t\t[COMMON_PROPERTIES.EDITED]: false,\n\t\t\t},\n\t\t\tcontext: { updateType: UpdateTypes.Finish, action: FinishActions.Edit },\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst featureId = this.editedFeatureId;\n\n\t\tif (this.editedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.editedPointId);\n\t\t\tthis.editedPointId = undefined;\n\t\t}\n\n\t\tif (this.snappedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\t\tthis.snappedPointId = undefined;\n\t\t}\n\n\t\t// Reset edit state\n\t\tthis.editedFeatureId = undefined;\n\t\tthis.editedFeatureCoordinateIndex = undefined;\n\t\tthis.editedInsertIndex = undefined;\n\t\tthis.editedSnapType = undefined;\n\n\t\tsetMapDraggability(true);\n\n\t\tthis.onFinish(featureId, {\n\t\t\tmode: this.mode,\n\t\t\taction: FinishActions.Draw,\n\t\t});\n\t}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tconst cleanUpId = this.currentId;\n\t\tconst snappedPointId = this.snappedPointId;\n\t\tconst editedPointId = this.editedPointId;\n\n\t\tthis.currentId = undefined;\n\t\tthis.snappedPointId = undefined;\n\t\tthis.editedPointId = undefined;\n\t\tthis.editedFeatureId = undefined;\n\t\tthis.editedFeatureCoordinateIndex = undefined;\n\t\tthis.editedInsertIndex = undefined;\n\t\tthis.editedSnapType = undefined;\n\t\tthis.currentCoordinate = 0;\n\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tif (cleanUpId) {\n\t\t\tthis.coordinatePoints.deletePointsByFeatureIds([cleanUpId]);\n\t\t}\n\n\t\tthis.mutateFeature.deleteFeatureIfPresent(cleanUpId);\n\t\tthis.mutateFeature.deleteFeatureIfPresent(editedPointId);\n\t\tthis.mutateFeature.deleteFeatureIfPresent(snappedPointId);\n\n\t\tif (this.closingPoints.ids.length) {\n\t\t\tthis.closingPoints.delete();\n\t\t}\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (feature.properties.mode === this.mode) {\n\t\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\t\tstyles.polygonFillColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.fillColor,\n\t\t\t\t\tstyles.polygonFillColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.outlineColor,\n\t\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.outlineWidth,\n\t\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonFillOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.fillOpacity,\n\t\t\t\t\tstyles.polygonFillOpacity,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.outlineOpacity,\n\t\t\t\t\t1,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = Z_INDEX.LAYER_ONE;\n\t\t\t\treturn styles;\n\t\t\t} else if (feature.geometry.type === \"Point\") {\n\t\t\t\tconst editedPoint = feature.properties[COMMON_PROPERTIES.EDITED];\n\t\t\t\tconst closingPoint =\n\t\t\t\t\tfeature.properties[COMMON_PROPERTIES.CLOSING_POINT];\n\t\t\t\tconst snappingPoint =\n\t\t\t\t\tfeature.properties[COMMON_PROPERTIES.SNAPPING_POINT];\n\t\t\t\tconst coordinatePoint =\n\t\t\t\t\tfeature.properties[COMMON_PROPERTIES.COORDINATE_POINT];\n\n\t\t\t\tconst pointType = editedPoint\n\t\t\t\t\t? \"editedPoint\"\n\t\t\t\t\t: closingPoint\n\t\t\t\t\t\t? \"closingPoint\"\n\t\t\t\t\t\t: snappingPoint\n\t\t\t\t\t\t\t? \"snappingPoint\"\n\t\t\t\t\t\t\t: coordinatePoint\n\t\t\t\t\t\t\t\t? \"coordinatePoint\"\n\t\t\t\t\t\t\t\t: undefined;\n\n\t\t\t\tif (!pointType) {\n\t\t\t\t\treturn styles;\n\t\t\t\t}\n\n\t\t\t\tconst styleMap = {\n\t\t\t\t\teditedPoint: {\n\t\t\t\t\t\twidth: this.styles.editedPointOutlineWidth,\n\t\t\t\t\t\tcolor: this.styles.editedPointColor,\n\t\t\t\t\t\topacity: this.styles.editedPointOpacity,\n\t\t\t\t\t\toutlineColor: this.styles.editedPointOutlineColor,\n\t\t\t\t\t\toutlineWidth: this.styles.editedPointOutlineWidth,\n\t\t\t\t\t\toutlineOpacity: this.styles.editedPointOutlineOpacity,\n\t\t\t\t\t},\n\t\t\t\t\tclosingPoint: {\n\t\t\t\t\t\twidth: this.styles.closingPointWidth,\n\t\t\t\t\t\tcolor: this.styles.closingPointColor,\n\t\t\t\t\t\topacity: this.styles.closingPointOpacity,\n\t\t\t\t\t\toutlineColor: this.styles.closingPointOutlineColor,\n\t\t\t\t\t\toutlineWidth: this.styles.closingPointOutlineWidth,\n\t\t\t\t\t\toutlineOpacity: this.styles.closingPointOutlineOpacity,\n\t\t\t\t\t},\n\t\t\t\t\tsnappingPoint: {\n\t\t\t\t\t\twidth: this.styles.snappingPointWidth,\n\t\t\t\t\t\tcolor: this.styles.snappingPointColor,\n\t\t\t\t\t\topacity: this.styles.snappingPointOpacity,\n\t\t\t\t\t\toutlineColor: this.styles.snappingPointOutlineColor,\n\t\t\t\t\t\toutlineWidth: this.styles.snappingPointOutlineWidth,\n\t\t\t\t\t\toutlineOpacity: this.styles.snappingPointOutlineOpacity,\n\t\t\t\t\t},\n\t\t\t\t\tcoordinatePoint: {\n\t\t\t\t\t\twidth: this.styles.coordinatePointWidth,\n\t\t\t\t\t\tcolor: this.styles.coordinatePointColor,\n\t\t\t\t\t\topacity: this.styles.coordinatePointOpacity,\n\t\t\t\t\t\toutlineColor: this.styles.coordinatePointOutlineColor,\n\t\t\t\t\t\toutlineWidth: this.styles.coordinatePointOutlineWidth,\n\t\t\t\t\t\toutlineOpacity: this.styles.coordinatePointOutlineOpacity,\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\t\tstyleMap[pointType].width,\n\t\t\t\t\tstyles.pointWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOpacity = this.getNumericStylingValue(\n\t\t\t\t\tstyleMap[pointType].opacity,\n\t\t\t\t\t1,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\t\tstyleMap[pointType].color,\n\t\t\t\t\tstyles.pointColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tstyleMap[pointType].outlineColor,\n\t\t\t\t\tstyles.pointOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineOpacity = this.getNumericStylingValue(\n\t\t\t\t\tstyleMap[pointType].outlineOpacity,\n\t\t\t\t\t1,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tstyleMap[pointType].outlineWidth,\n\t\t\t\t\t2,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tif (editedPoint) {\n\t\t\t\t\tstyles.zIndex = Z_INDEX.LAYER_FOUR;\n\t\t\t\t} else if (coordinatePoint) {\n\t\t\t\t\tstyles.zIndex = Z_INDEX.LAYER_TWO;\n\t\t\t\t} else {\n\t\t\t\t\tstyles.zIndex = Z_INDEX.LAYER_THREE;\n\t\t\t\t}\n\n\t\t\t\treturn styles;\n\t\t\t}\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tafterFeatureAdded(feature: GeoJSONStoreFeatures) {\n\t\tif (this.showCoordinatePoints) {\n\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\tfeatureId: feature.id as FeatureId,\n\t\t\t\tfeatureCoordinates: feature.geometry.coordinates as Position[][],\n\t\t\t});\n\t\t}\n\t}\n\n\tafterFeatureUpdated(feature: GeoJSONStoreFeatures) {\n\t\t// Clean up here is important to get right as we need to make a best effort to avoid erroneous\n\t\t// internal state.\n\n\t\t// IF we have coordinate points showing these need to be completely recreated\n\t\tif (this.showCoordinatePoints) {\n\t\t\tthis.coordinatePoints.createOrUpdate({\n\t\t\t\tfeatureId: feature.id as FeatureId,\n\t\t\t\tfeatureCoordinates: feature.geometry.coordinates as Position[][],\n\t\t\t});\n\t\t}\n\n\t\t// If we are editing a feature by dragging one of its points\n\t\t// we want to clear that state up as new polygon might be completely\n\t\t// different in terms of it's coordinates\n\t\tif (this.editedFeatureId === feature.id && this.editedPointId) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.editedPointId);\n\t\t\tthis.editedPointId = undefined;\n\t\t\tthis.editedFeatureId = undefined;\n\t\t\tthis.editedFeatureCoordinateIndex = undefined;\n\t\t\tthis.editedSnapType = undefined;\n\t\t}\n\n\t\t// We can recalculate the snapped point from the last mouse event if there was one\n\t\tif (this.snappedPointId && this.lastMouseMoveEvent) {\n\t\t\tthis.updateSnappedCoordinate(\n\t\t\t\tthis.lastMouseMoveEvent as TerraDrawMouseEvent,\n\t\t\t);\n\t\t}\n\n\t\t// NOTE: This handles the case we are currently drawing a polygon\n\t\t// We need to reset the drawing state because it is very complicated (impossible?)\n\t\t// to recover the drawing state after a feature update\n\t\tif (this.currentId === feature.id) {\n\t\t\tthis.currentCoordinate = 0;\n\t\t\tthis.currentId = undefined;\n\t\t\tthis.closingPoints.delete();\n\n\t\t\t// Go back to started state\n\t\t\tif (this.state === \"drawing\") {\n\t\t\t\tthis.setStarted();\n\t\t\t}\n\t\t}\n\t}\n\n\tvalidateFeature(feature: unknown): StoreValidation {\n\t\treturn this.validateModeFeature(feature, (baseValidatedFeature) =>\n\t\t\tValidatePolygonFeature(baseValidatedFeature, this.coordinatePrecision),\n\t\t);\n\t}\n}\n","import { Position } from \"geojson\";\nimport {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n\tZ_INDEX,\n\tCOMMON_PROPERTIES,\n\tFinishActions,\n\tDrawInteractions,\n\tDrawType,\n} from \"../../common\";\nimport {\n\tFeatureId,\n\tGeoJSONStoreFeatures,\n\tStoreValidation,\n} from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tModeUpdateOptions,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { ValidateNonIntersectingPolygonFeature } from \"../../validations/polygon.validation\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { MutateFeatureBehavior, Mutations } from \"../mutate-feature.behavior\";\nimport { ReadFeatureBehavior } from \"../read-feature.behavior\";\n\ntype TerraDrawRectangleModeKeyEvents = {\n\tcancel: KeyboardEvent[\"key\"] | null;\n\tfinish: KeyboardEvent[\"key\"] | null;\n};\n\nconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\ntype RectanglePolygonStyling = {\n\tfillColor: HexColorStyling;\n\tfillOpacity: NumericStyling;\n\toutlineColor: HexColorStyling;\n\toutlineOpacity: NumericStyling;\n\toutlineWidth: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n}\n\nconst defaultCursors = {\n\tstart: \"crosshair\",\n} as Required<Cursors>;\n\ninterface TerraDrawRectangleModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tkeyEvents?: TerraDrawRectangleModeKeyEvents | null;\n\tcursors?: Cursors;\n\tdrawInteraction?: DrawInteractions;\n}\n\nexport class TerraDrawRectangleMode extends TerraDrawBaseDrawMode<RectanglePolygonStyling> {\n\tmode = \"rectangle\";\n\tprivate startPosition: Position | undefined;\n\tprivate endPosition: Position | undefined;\n\tprivate currentRectangleId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawRectangleModeKeyEvents = defaultKeyEvents;\n\tprivate cursors: Required<Cursors> = defaultCursors;\n\tprivate drawInteraction = \"click-move\";\n\tprivate drawType: DrawType | undefined;\n\n\t// Behaviors\n\tprivate mutateFeature!: MutateFeatureBehavior;\n\tprivate readFeature!: ReadFeatureBehavior;\n\n\tconstructor(\n\t\toptions?: TerraDrawRectangleModeOptions<RectanglePolygonStyling>,\n\t) {\n\t\tsuper(options, true);\n\t\tthis.updateOptions(options);\n\t}\n\n\toverride updateOptions(\n\t\toptions?: ModeUpdateOptions<\n\t\t\tTerraDrawRectangleModeOptions<RectanglePolygonStyling>\n\t\t>,\n\t) {\n\t\tsuper.updateOptions(options);\n\n\t\tif (options?.cursors) {\n\t\t\tthis.cursors = { ...this.cursors, ...options.cursors };\n\t\t}\n\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = { cancel: null, finish: null };\n\t\t} else if (options?.keyEvents) {\n\t\t\tthis.keyEvents = { ...this.keyEvents, ...options.keyEvents };\n\t\t}\n\n\t\tif (options?.drawInteraction) {\n\t\t\tthis.drawInteraction = options.drawInteraction;\n\t\t}\n\t}\n\n\tprivate updateRectangle(endPosition: Position, updateType: UpdateTypes) {\n\t\tif (!this.startPosition || !this.currentRectangleId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst isFinish = updateType === UpdateTypes.Finish;\n\n\t\treturn this.mutateFeature.updatePolygon({\n\t\t\tfeatureId: this.currentRectangleId,\n\t\t\tcoordinateMutations: [\n\t\t\t\t{\n\t\t\t\t\ttype: Mutations.Update,\n\t\t\t\t\tindex: 1,\n\t\t\t\t\tcoordinate: [endPosition[0], this.startPosition[1]],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: Mutations.Update,\n\t\t\t\t\tindex: 2,\n\t\t\t\t\tcoordinate: endPosition,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: Mutations.Update,\n\t\t\t\t\tindex: 3,\n\t\t\t\t\tcoordinate: [this.startPosition[0], endPosition[1]],\n\t\t\t\t},\n\t\t\t],\n\t\t\tpropertyMutations: isFinish\n\t\t\t\t? {\n\t\t\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: undefined,\n\t\t\t\t\t}\n\t\t\t\t: {},\n\t\t\tcontext: isFinish\n\t\t\t\t? {\n\t\t\t\t\t\tupdateType,\n\t\t\t\t\t\taction: FinishActions.Draw,\n\t\t\t\t\t}\n\t\t\t\t: { updateType },\n\t\t});\n\t}\n\n\tprivate close() {\n\t\tif (!this.currentRectangleId || !this.endPosition) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst updated = this.updateRectangle(this.endPosition, UpdateTypes.Finish);\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst featureId = this.currentRectangleId;\n\n\t\tthis.startPosition = undefined;\n\t\tthis.currentRectangleId = undefined;\n\t\tthis.drawType = undefined;\n\t\t// Go back to started state\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.onFinish(featureId, {\n\t\t\tmode: this.mode,\n\t\t\taction: FinishActions.Draw,\n\t\t});\n\t}\n\n\tprivate beginDrawing(\n\t\tevent: TerraDrawMouseEvent,\n\t\tdrawType: DrawType = \"click\",\n\t) {\n\t\tthis.startPosition = [event.lng, event.lat];\n\t\tthis.endPosition = [event.lng, event.lat];\n\n\t\tconst feature = this.mutateFeature.createPolygon({\n\t\t\tcoordinates: [\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\t[event.lng, event.lat],\n\t\t\t\t[event.lng, event.lat],\n\t\t\t],\n\t\t\tproperties: {\n\t\t\t\tmode: this.mode,\n\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: true,\n\t\t\t},\n\t\t});\n\t\tthis.currentRectangleId = feature.id;\n\n\t\tthis.drawType = drawType;\n\t\tthis.setDrawing();\n\t}\n\n\t/** TODO: Probably should be private? */\n\t/** @internal */\n\tmoveDrawAllowed() {\n\t\treturn (\n\t\t\tthis.drawInteraction === \"click-move\" ||\n\t\t\tthis.drawInteraction === \"click-move-or-drag\"\n\t\t);\n\t}\n\n\t/** TODO: Probably should be private? */\n\t/** @internal */\n\tdragDrawAllowed() {\n\t\treturn (\n\t\t\tthis.drawInteraction === \"click-drag\" ||\n\t\t\tthis.drawInteraction === \"click-move-or-drag\"\n\t\t);\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\tif (\n\t\t\tthis.moveDrawAllowed() &&\n\t\t\t((event.button === \"right\" &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.rightClick, event)) ||\n\t\t\t\t(event.button === \"left\" &&\n\t\t\t\t\tthis.allowPointerEvent(this.pointerEvents.leftClick, event)) ||\n\t\t\t\t(event.isContextMenu &&\n\t\t\t\t\tthis.allowPointerEvent(this.pointerEvents.contextMenu, event)))\n\t\t) {\n\t\t\tif (!this.startPosition) {\n\t\t\t\tthis.beginDrawing(event);\n\t\t\t} else {\n\t\t\t\tthis.endPosition = [event.lng, event.lat];\n\t\t\t\t// Finish drawing\n\t\t\t\tthis.close();\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tthis.endPosition = [event.lng, event.lat];\n\t\tthis.updateRectangle(this.endPosition, UpdateTypes.Provisional);\n\t}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tif (event.key === this.keyEvents.cancel) {\n\t\t\tthis.cleanUp();\n\t\t} else if (event.key === this.keyEvents.finish) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDragStart(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (this.state === \"drawing\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\tthis.allowPointerEvent(this.pointerEvents.onDragStart, event) &&\n\t\t\tthis.dragDrawAllowed()\n\t\t) {\n\t\t\tthis.beginDrawing(event, \"drag\");\n\t\t\tsetMapDraggability(false);\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDrag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (\n\t\t\tthis.allowPointerEvent(this.pointerEvents.onDrag, event) &&\n\t\t\tthis.dragDrawAllowed() &&\n\t\t\tthis.drawType === \"drag\"\n\t\t) {\n\t\t\tthis.endPosition = [event.lng, event.lat];\n\t\t\tthis.updateRectangle(this.endPosition, UpdateTypes.Provisional);\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDragEnd(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (\n\t\t\tthis.allowPointerEvent(this.pointerEvents.onDragEnd, event) &&\n\t\t\tthis.dragDrawAllowed() &&\n\t\t\tthis.drawType === \"drag\"\n\t\t) {\n\t\t\tthis.endPosition = [event.lng, event.lat];\n\t\t\t// Finish drawing\n\t\t\tthis.close();\n\t\t\tsetMapDraggability(true);\n\t\t}\n\t}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tconst cleanUpId = this.currentRectangleId;\n\n\t\tthis.startPosition = undefined;\n\t\tthis.currentRectangleId = undefined;\n\n\t\tthis.drawType = undefined;\n\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.mutateFeature.deleteFeatureIfPresent(cleanUpId);\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"Polygon\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tstyles.polygonFillColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.fillColor,\n\t\t\t\tstyles.polygonFillColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonOutlineColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.outlineColor,\n\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonOutlineOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.outlineOpacity,\n\t\t\t\t1,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonOutlineWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.outlineWidth,\n\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonFillOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.fillOpacity,\n\t\t\t\tstyles.polygonFillOpacity,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.zIndex = Z_INDEX.LAYER_ONE;\n\n\t\t\treturn styles;\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): StoreValidation {\n\t\treturn this.validateModeFeature(feature, (baseValidatedFeature) =>\n\t\t\tValidateNonIntersectingPolygonFeature(\n\t\t\t\tbaseValidatedFeature,\n\t\t\t\tthis.coordinatePrecision,\n\t\t\t),\n\t\t);\n\t}\n\n\tafterFeatureUpdated(feature: GeoJSONStoreFeatures): void {\n\t\t// If we are in the middle of drawing a rectangle and the feature being updated is the current rectangle,\n\t\t// we need to reset the drawing state\n\t\tif (this.currentRectangleId === feature.id) {\n\t\t\tthis.startPosition = undefined;\n\t\t\tthis.currentRectangleId = undefined;\n\t\t\tthis.drawType = undefined;\n\t\t\tif (this.state === \"drawing\") {\n\t\t\t\tthis.setStarted();\n\t\t\t}\n\t\t}\n\t}\n\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.readFeature = new ReadFeatureBehavior(config);\n\t\tthis.mutateFeature = new MutateFeatureBehavior(config, {\n\t\t\tvalidate: this.validate,\n\t\t});\n\t}\n}\n","import {\n\tHexColorStyling,\n\tNumericStyling,\n\tTerraDrawAdapterStyling,\n} from \"../../common\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tModeTypes,\n\tModeUpdateOptions,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { GeoJSONStoreFeatures } from \"../../terra-draw\";\nimport { ValidatePointFeature } from \"../../validations/point.validation\";\nimport { ValidatePolygonFeature } from \"../../validations/polygon.validation\";\nimport { ValidateLineStringFeature } from \"../../validations/linestring.validation\";\nimport { StoreValidation } from \"../../store/store\";\n\ntype RenderModeStyling = {\n\tpointColor: HexColorStyling;\n\tpointWidth: NumericStyling;\n\tpointOpacity: NumericStyling;\n\tpointOutlineColor: HexColorStyling;\n\tpointOutlineOpacity: NumericStyling;\n\tpointOutlineWidth: NumericStyling;\n\tpolygonFillColor: HexColorStyling;\n\tpolygonFillOpacity: NumericStyling;\n\tpolygonOutlineColor: HexColorStyling;\n\tpolygonOutlineWidth: NumericStyling;\n\tlineStringWidth: NumericStyling;\n\tlineStringColor: HexColorStyling;\n\tlineStringOpacity: NumericStyling;\n\tzIndex: NumericStyling;\n};\n\ninterface TerraDrawRenderModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\t// styles need to be there else we could fall back to BaseModeOptions\n\tstyles: Partial<T>;\n}\n\nexport class TerraDrawRenderMode extends TerraDrawBaseDrawMode<RenderModeStyling> {\n\tpublic type = ModeTypes.Render; // The type of the mode\n\tpublic mode = \"render\"; // This gets changed dynamically\n\n\tconstructor(options: TerraDrawRenderModeOptions<RenderModeStyling>) {\n\t\tif (!options.modeName) {\n\t\t\tthrow new Error(\"Mode name is required for TerraDrawRenderMode\");\n\t\t}\n\n\t\tsuper(options, true);\n\t\tthis.updateOptions(options);\n\t}\n\n\tupdateOptions(\n\t\toptions?: ModeUpdateOptions<TerraDrawRenderModeOptions<RenderModeStyling>>,\n\t): void {\n\t\tsuper.updateOptions(options);\n\t}\n\n\t/** @internal */\n\tregisterBehaviors(behaviorConfig: BehaviorConfig) {\n\t\t// TODO: this is probably abusing\n\t\t// registerBehaviors but it works quite well conceptually\n\n\t\t// We can set the mode name dynamically\n\t\tthis.mode = behaviorConfig.mode;\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.setStopped();\n\t}\n\n\t/** @internal */\n\tonKeyUp() {}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonClick() {}\n\n\t/** @internal */\n\tonDragStart() {}\n\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\n\n\t/** @internal */\n\tonMouseMove() {}\n\n\t/** @internal */\n\tcleanUp() {}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst defaultStyles = getDefaultStyling();\n\n\t\treturn {\n\t\t\tpointColor: this.getHexColorStylingValue(\n\t\t\t\tthis.styles.pointColor,\n\t\t\t\tdefaultStyles.pointColor,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tpointWidth: this.getNumericStylingValue(\n\t\t\t\tthis.styles.pointWidth,\n\t\t\t\tdefaultStyles.pointWidth,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tpointOpacity: this.getNumericStylingValue(\n\t\t\t\tthis.styles.pointOpacity,\n\t\t\t\tdefaultStyles.pointOpacity as number,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tpointOutlineColor: this.getHexColorStylingValue(\n\t\t\t\tthis.styles.pointOutlineColor,\n\t\t\t\tdefaultStyles.pointOutlineColor,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tpointOutlineWidth: this.getNumericStylingValue(\n\t\t\t\tthis.styles.pointOutlineWidth,\n\t\t\t\tdefaultStyles.pointOutlineWidth,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tpointOutlineOpacity: this.getNumericStylingValue(\n\t\t\t\tthis.styles.pointOutlineOpacity,\n\t\t\t\tdefaultStyles.pointOutlineOpacity as number,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tpolygonFillColor: this.getHexColorStylingValue(\n\t\t\t\tthis.styles.polygonFillColor,\n\t\t\t\tdefaultStyles.polygonFillColor,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tpolygonFillOpacity: this.getNumericStylingValue(\n\t\t\t\tthis.styles.polygonFillOpacity,\n\t\t\t\tdefaultStyles.polygonFillOpacity,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tpolygonOutlineColor: this.getHexColorStylingValue(\n\t\t\t\tthis.styles.polygonOutlineColor,\n\t\t\t\tdefaultStyles.polygonOutlineColor,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tpolygonOutlineWidth: this.getNumericStylingValue(\n\t\t\t\tthis.styles.polygonOutlineWidth,\n\t\t\t\tdefaultStyles.polygonOutlineWidth,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tlineStringWidth: this.getNumericStylingValue(\n\t\t\t\tthis.styles.lineStringWidth,\n\t\t\t\tdefaultStyles.lineStringWidth,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tlineStringColor: this.getHexColorStylingValue(\n\t\t\t\tthis.styles.lineStringColor,\n\t\t\t\tdefaultStyles.lineStringColor,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tlineStringOpacity: this.getNumericStylingValue(\n\t\t\t\tthis.styles.lineStringOpacity,\n\t\t\t\tdefaultStyles.lineStringOpacity as number,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t\tzIndex: this.getNumericStylingValue(\n\t\t\t\tthis.styles.zIndex,\n\t\t\t\tdefaultStyles.zIndex,\n\t\t\t\tfeature,\n\t\t\t),\n\t\t};\n\t}\n\n\tvalidateFeature(feature: unknown): StoreValidation {\n\t\tconst validationResult = super.validateFeature(feature);\n\t\tif (validationResult.valid) {\n\t\t\tconst validatedFeature = feature as GeoJSONStoreFeatures;\n\n\t\t\tconst featureIsValid =\n\t\t\t\tValidatePointFeature(validatedFeature, this.coordinatePrecision)\n\t\t\t\t\t.valid ||\n\t\t\t\tValidatePolygonFeature(validatedFeature, this.coordinatePrecision)\n\t\t\t\t\t.valid ||\n\t\t\t\tValidateLineStringFeature(validatedFeature, this.coordinatePrecision)\n\t\t\t\t\t.valid;\n\n\t\t\tif (featureIsValid) {\n\t\t\t\treturn { valid: true };\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tvalid: featureIsValid,\n\t\t\t\treason: \"Feature is not a valid Point, Polygon or LineString feature\",\n\t\t\t};\n\t\t}\n\n\t\treturn validationResult;\n\t}\n}\n","import { Position } from \"geojson\";\nimport { degreesToRadians, radiansToDegrees } from \"../helpers\";\n\n// Based on Turf.js Rhumb Bearing module which is MIT Licensed\n// https://github.com/Turfjs/turf/blob/master/packages/turf-rhumb-bearing/index.ts\n\nexport function rhumbBearing(start: Position, end: Position): number {\n\tconst from = start;\n\tconst to = end;\n\n\t// φ => phi\n\t// Δλ => deltaLambda\n\t// Δψ => deltaPsi\n\t// θ => theta\n\tconst phi1 = degreesToRadians(from[1]);\n\tconst phi2 = degreesToRadians(to[1]);\n\tlet deltaLambda = degreesToRadians(to[0] - from[0]);\n\n\t// if deltaLambdaon over 180° take shorter rhumb line across the anti-meridian:\n\tif (deltaLambda > Math.PI) {\n\t\tdeltaLambda -= 2 * Math.PI;\n\t}\n\tif (deltaLambda < -Math.PI) {\n\t\tdeltaLambda += 2 * Math.PI;\n\t}\n\n\tconst deltaPsi = Math.log(\n\t\tMath.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4),\n\t);\n\n\tconst theta = Math.atan2(deltaLambda, deltaPsi);\n\n\tconst bear360 = (radiansToDegrees(theta) + 360) % 360;\n\n\tconst bear180 = bear360 > 180 ? -(360 - bear360) : bear360;\n\n\treturn bear180;\n}\n","import { Position } from \"geojson\";\nimport { degreesToRadians, earthRadius } from \"../helpers\";\n\n// Based on @turf/rhumb-destination module which is MIT Licensed\n// https://github.com/Turfjs/turf/blob/master/packages/turf-rhumb-destination/index.ts\n\nexport function rhumbDestination(\n\torigin: Position,\n\tdistanceMeters: number,\n\tbearing: number,\n): Position {\n\tconst wasNegativeDistance = distanceMeters < 0;\n\tlet distanceInMeters = distanceMeters;\n\n\tif (wasNegativeDistance) {\n\t\tdistanceInMeters = -Math.abs(distanceInMeters);\n\t}\n\n\tconst delta = distanceInMeters / earthRadius; // angular distance in radians\n\tconst lambda1 = (origin[0] * Math.PI) / 180; // to radians, but without normalize to 𝜋\n\tconst phi1 = degreesToRadians(origin[1]);\n\tconst theta = degreesToRadians(bearing);\n\n\tconst DeltaPhi = delta * Math.cos(theta);\n\tlet phi2 = phi1 + DeltaPhi;\n\n\t// check for going past the pole, normalise latitude if so\n\tif (Math.abs(phi2) > Math.PI / 2) {\n\t\tphi2 = phi2 > 0 ? Math.PI - phi2 : -Math.PI - phi2;\n\t}\n\n\tconst DeltaPsi = Math.log(\n\t\tMath.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4),\n\t);\n\t// E-W course becomes ill-conditioned with 0/0\n\tconst q = Math.abs(DeltaPsi) > 10e-12 ? DeltaPhi / DeltaPsi : Math.cos(phi1);\n\n\tconst DeltaLambda = (delta * Math.sin(theta)) / q;\n\tconst lambda2 = lambda1 + DeltaLambda;\n\n\t// normalise to −180..+180°\n\tconst destination = [\n\t\t(((lambda2 * 180) / Math.PI + 540) % 360) - 180,\n\t\t(phi2 * 180) / Math.PI,\n\t];\n\n\t// compensate the crossing of the 180th meridian (https://macwright.org/2016/09/26/the-180th-meridian.html)\n\t// solution from https://github.com/mapbox/mapbox-gl-js/issues/3250#issuecomment-294887678\n\tdestination[0] +=\n\t\tdestination[0] - origin[0] > 180\n\t\t\t? -360\n\t\t\t: origin[0] - destination[0] > 180\n\t\t\t\t? 360\n\t\t\t\t: 0;\n\treturn destination;\n}\n","import { Position } from \"geojson\";\nimport { limitPrecision } from \"./limit-decimal-precision\";\nimport { Project, Unproject } from \"../common\";\nimport { haversineDistanceKilometers } from \"./measure/haversine-distance\";\nimport { rhumbBearing } from \"./measure/rhumb-bearing\";\nimport { rhumbDestination } from \"./measure/rhumb-destination\";\n\n// midpointCoordinate is adapted from the @turf/midpoint which is MIT Licensed\n// https://github.com/Turfjs/turf/tree/master/packages/turf-midpoint\n\nexport function midpointCoordinate(\n\tcoordinates1: Position,\n\tcoordinates2: Position,\n\tprecision: number,\n\tproject: Project,\n\tunproject: Unproject,\n) {\n\tconst projectedCoordinateOne = project(coordinates1[0], coordinates1[1]);\n\tconst projectedCoordinateTwo = project(coordinates2[0], coordinates2[1]);\n\n\tconst { lng, lat } = unproject(\n\t\t(projectedCoordinateOne.x + projectedCoordinateTwo.x) / 2,\n\t\t(projectedCoordinateOne.y + projectedCoordinateTwo.y) / 2,\n\t);\n\n\treturn [limitPrecision(lng, precision), limitPrecision(lat, precision)];\n}\n\n/* Get the geodesic midpoint coordinate between two coordinates */\nexport function geodesicMidpointCoordinate(\n\tcoordinates1: Position,\n\tcoordinates2: Position,\n\tprecision: number,\n) {\n\tconst dist = haversineDistanceKilometers(coordinates1, coordinates2) * 1000;\n\tconst heading = rhumbBearing(coordinates1, coordinates2);\n\tconst midpoint = rhumbDestination(coordinates1, dist / 2, heading);\n\treturn [\n\t\tlimitPrecision(midpoint[0], precision),\n\t\tlimitPrecision(midpoint[1], precision),\n\t];\n}\n","import { Position } from \"geojson\";\nimport { Project, Projection, Unproject } from \"../common\";\nimport {\n\tmidpointCoordinate,\n\tgeodesicMidpointCoordinate,\n} from \"./midpoint-coordinate\";\n\nexport function getMidPointCoordinates({\n\tfeatureCoords,\n\tprecision,\n\tunproject,\n\tproject,\n\tprojection,\n}: {\n\tfeatureCoords: Position[];\n\tprecision: number;\n\tproject: Project;\n\tunproject: Unproject;\n\tprojection: Projection;\n}) {\n\tconst midPointCoords: Position[] = [];\n\tfor (let i = 0; i < featureCoords.length - 1; i++) {\n\t\tlet mid;\n\t\tif (projection === \"web-mercator\") {\n\t\t\tmid = midpointCoordinate(\n\t\t\t\tfeatureCoords[i],\n\t\t\t\tfeatureCoords[i + 1],\n\t\t\t\tprecision,\n\t\t\t\tproject,\n\t\t\t\tunproject,\n\t\t\t);\n\t\t} else if (projection === \"globe\") {\n\t\t\tmid = geodesicMidpointCoordinate(\n\t\t\t\tfeatureCoords[i],\n\t\t\t\tfeatureCoords[i + 1],\n\t\t\t\tprecision,\n\t\t\t);\n\t\t} else {\n\t\t\tthrow new Error(\"Invalid projection\");\n\t\t}\n\n\t\tmidPointCoords.push(mid);\n\t}\n\treturn midPointCoords;\n}\n","import { LineString, Point, Polygon, Position } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { getMidPointCoordinates } from \"../../../geometry/get-midpoints\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport {\n\tCOMMON_PROPERTIES,\n\tProjection,\n\tSELECT_PROPERTIES,\n\tTerraDrawMouseEvent,\n\tUpdateTypes,\n} from \"../../../common\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../../store/store\";\nimport { CoordinatePointBehavior } from \"./coordinate-point.behavior\";\nimport {\n\tMutateFeatureBehavior,\n\tMutations,\n} from \"../../mutate-feature.behavior\";\nimport { ReadFeatureBehavior } from \"../../read-feature.behavior\";\nimport { getClosedCoordinates } from \"../../../geometry/get-coordinates\";\nimport { PixelDistanceBehavior } from \"../../pixel-distance.behavior\";\n\nexport class MidPointBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly selectionPointBehavior: SelectionPointBehavior,\n\t\tprivate readonly coordinatePointBehavior: CoordinatePointBehavior,\n\t\tprivate readonly mutateFeature: MutateFeatureBehavior,\n\t\tprivate readonly readFeature: ReadFeatureBehavior,\n\t\tprivate readonly pixelDistance: PixelDistanceBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tprivate _midPoints: FeatureId[] = [];\n\n\tprivate getMidpointConfig(coordinates: Position[]) {\n\t\treturn {\n\t\t\tfeatureCoords: coordinates,\n\t\t\tprecision: this.coordinatePrecision,\n\t\t\tproject: this.config.project,\n\t\t\tunproject: this.config.unproject,\n\t\t\tprojection: this.config.projection as Projection,\n\t\t};\n\t}\n\n\tget ids() {\n\t\treturn this._midPoints.concat();\n\t}\n\n\tset ids(_: FeatureId[]) {}\n\n\tpublic getNearestMidPoint(event: TerraDrawMouseEvent) {\n\t\tlet closestMidPointDistance = Infinity;\n\t\tlet closestMidPointId: FeatureId | undefined = undefined;\n\n\t\tthis.ids.forEach((id) => {\n\t\t\tconst geometry = this.readFeature.getGeometry<Point>(id);\n\t\t\tconst distance = this.pixelDistance.measure(event, geometry.coordinates);\n\n\t\t\tif (\n\t\t\t\tdistance < this.pointerDistance &&\n\t\t\t\tdistance < closestMidPointDistance\n\t\t\t) {\n\t\t\t\tclosestMidPointDistance = distance;\n\t\t\t\tclosestMidPointId = id;\n\t\t\t}\n\t\t});\n\n\t\treturn closestMidPointId;\n\t}\n\n\tpublic insert({\n\t\tfeatureId,\n\t\tmidPointId,\n\t}: {\n\t\tfeatureId: FeatureId;\n\t\tmidPointId: FeatureId;\n\t}) {\n\t\tconst midPoint = this.readFeature.getGeometry(midPointId);\n\t\tconst { midPointFeatureId, midPointSegment } =\n\t\t\tthis.readFeature.getProperties(midPointId);\n\t\tconst geometry = this.readFeature.getGeometry<Polygon | LineString>(\n\t\t\tmidPointFeatureId as FeatureId,\n\t\t);\n\n\t\tconst update = {\n\t\t\tfeatureId: midPointFeatureId as FeatureId,\n\t\t\tcoordinateMutations: [\n\t\t\t\t{\n\t\t\t\t\ttype: Mutations.InsertAfter,\n\t\t\t\t\tindex: midPointSegment as number,\n\t\t\t\t\tcoordinate: midPoint.coordinates as Position,\n\t\t\t\t},\n\t\t\t],\n\t\t\tcontext: {\n\t\t\t\tupdateType: UpdateTypes.Commit as const,\n\t\t\t},\n\t\t};\n\n\t\tlet updated: GeoJSONStoreFeatures<Polygon | LineString> | null = null;\n\n\t\tif (geometry.type === \"Polygon\") {\n\t\t\tupdated = this.mutateFeature.updatePolygon(update);\n\t\t} else if (geometry.type === \"LineString\") {\n\t\t\tupdated = this.mutateFeature.updateLineString(update);\n\t\t} else {\n\t\t\tthrow new Error(\"Midpoints can only be added to polygons or linestrings\");\n\t\t}\n\n\t\tif (!updated) {\n\t\t\tthrow new Error(\"Failed to insert midpoint coordinate\");\n\t\t}\n\n\t\tconst featureCoordinates = updated.geometry.coordinates;\n\n\t\t// We need to update the coordinate points to reflect the new midpoint\n\t\tconst featureProperties = this.readFeature.getProperties(featureId);\n\n\t\tif (featureProperties[COMMON_PROPERTIES.COORDINATE_POINT_IDS]) {\n\t\t\tthis.coordinatePointBehavior.createOrUpdate({\n\t\t\t\tfeatureId,\n\t\t\t\tfeatureCoordinates,\n\t\t\t});\n\t\t}\n\n\t\t// TODO: is there a way of just updating the selection points rather\n\t\t// than fully deleting / recreating?\n\t\t// Recreate the selection points\n\t\tthis.mutateFeature.deleteFeaturesIfPresent([\n\t\t\t...this.selectionPointBehavior.ids,\n\t\t\t...this._midPoints,\n\t\t]);\n\n\t\t// We don't need to check if flags are correct\n\t\t// because selection points are prerequisite for midpoints\n\t\tthis.create({\n\t\t\tfeatureCoordinates,\n\t\t\tfeatureId: midPointFeatureId as FeatureId,\n\t\t});\n\n\t\tthis.selectionPointBehavior.create({\n\t\t\tfeatureCoordinates,\n\t\t\tfeatureId: featureId,\n\t\t});\n\t}\n\n\tpublic create({\n\t\tfeatureCoordinates,\n\t\tfeatureId,\n\t}: {\n\t\tfeatureCoordinates: Position[] | Position[][];\n\t\tfeatureId: FeatureId;\n\t}) {\n\t\tif (!this.readFeature.hasFeature(featureId)) {\n\t\t\tthrow new Error(\"Store does not have feature with this id\");\n\t\t}\n\n\t\tconst coordinates = getClosedCoordinates(featureCoordinates);\n\t\tconst midpoints = getMidPointCoordinates(\n\t\t\tthis.getMidpointConfig(coordinates),\n\t\t);\n\n\t\tthis._midPoints = this.mutateFeature.createGuidancePoints({\n\t\t\tadditionalProperties: (i) => ({\n\t\t\t\tmode: this.mode,\n\t\t\t\tmidPointSegment: i,\n\t\t\t\tmidPointFeatureId: featureId,\n\t\t\t\t[SELECT_PROPERTIES.MID_POINT]: true,\n\t\t\t}),\n\t\t\tcoordinates: midpoints,\n\t\t\ttype: SELECT_PROPERTIES.MID_POINT,\n\t\t});\n\t}\n\n\tpublic delete() {\n\t\tif (!this._midPoints.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.mutateFeature.deleteFeaturesIfPresent(this._midPoints);\n\t\tthis._midPoints = [];\n\t}\n\n\tpublic updateAllInPlace({\n\t\tfeatureCoordinates,\n\t}: {\n\t\tfeatureCoordinates: Position[] | Position[][];\n\t}) {\n\t\tif (this._midPoints.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst coordinates = getClosedCoordinates(featureCoordinates);\n\t\tconst midpoints = getMidPointCoordinates(\n\t\t\tthis.getMidpointConfig(coordinates),\n\t\t);\n\n\t\tthis.mutateFeature.updateGuidancePoints(\n\t\t\tthis._midPoints.map((id, i) => ({\n\t\t\t\tfeatureId: id,\n\t\t\t\tcoordinate: midpoints[i],\n\t\t\t})),\n\t\t);\n\t}\n\n\tpublic updateOneAtIndex(\n\t\tindex: number,\n\t\tfeatureCoordinates: Position[] | Position[][],\n\t) {\n\t\tif (index < 0) {\n\t\t\t// -1 would be the final index\n\t\t\tindex = this._midPoints.length + index;\n\t\t}\n\n\t\tif (this._midPoints[index] === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst coordinates = getClosedCoordinates(featureCoordinates);\n\t\tconst midpoints = getMidPointCoordinates(\n\t\t\tthis.getMidpointConfig(coordinates),\n\t\t);\n\n\t\tthis.mutateFeature.updateGuidancePoints([\n\t\t\t{\n\t\t\t\tfeatureId: this._midPoints[index],\n\t\t\t\tcoordinate: midpoints[index],\n\t\t\t},\n\t\t]);\n\t}\n}\n","import { Position } from \"geojson\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { FeatureId } from \"../../../store/store\";\nimport { SELECT_PROPERTIES } from \"../../../common\";\nimport { MutateFeatureBehavior } from \"../../mutate-feature.behavior\";\nimport { getUnclosedCoordinates } from \"../../../geometry/get-coordinates\";\nimport { ReadFeatureBehavior } from \"../../read-feature.behavior\";\n\nexport type SelectionPointProperties = {\n\tmode: string;\n\tindex: number;\n\t[SELECT_PROPERTIES.SELECTION_POINT_FEATURE_ID]: string;\n\t[SELECT_PROPERTIES.SELECTION_POINT]: true;\n};\n\nexport class SelectionPointBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\tconfig: BehaviorConfig,\n\t\tmutateFeatureBehavior: MutateFeatureBehavior,\n\t) {\n\t\tsuper(config);\n\t\tthis.mutateFeature = mutateFeatureBehavior;\n\t}\n\n\tprivate mutateFeature: MutateFeatureBehavior;\n\n\tprivate _selectionPoints: FeatureId[] = [];\n\n\tget ids() {\n\t\treturn this._selectionPoints.concat();\n\t}\n\n\tset ids(_: FeatureId[]) {}\n\n\tpublic create({\n\t\tfeatureId,\n\t\tfeatureCoordinates,\n\t}: {\n\t\tfeatureId: FeatureId;\n\t\tfeatureCoordinates: Position[] | Position[][];\n\t}) {\n\t\tconst coordinates = getUnclosedCoordinates(featureCoordinates);\n\n\t\tthis._selectionPoints = this.mutateFeature.createGuidancePoints({\n\t\t\tcoordinates,\n\t\t\ttype: SELECT_PROPERTIES.SELECTION_POINT,\n\t\t\tadditionalProperties: (index) => ({\n\t\t\t\t[SELECT_PROPERTIES.SELECTION_POINT_FEATURE_ID]: featureId,\n\t\t\t\tindex,\n\t\t\t}),\n\t\t});\n\t}\n\n\tpublic delete() {\n\t\tif (!this.ids.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.mutateFeature.deleteFeaturesIfPresent(this.ids);\n\t\tthis._selectionPoints = [];\n\t}\n\n\tpublic updateAllInPlace({\n\t\tfeatureCoordinates,\n\t}: {\n\t\tfeatureCoordinates: Position[] | Position[][];\n\t}) {\n\t\tif (this._selectionPoints.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst coordinates = getUnclosedCoordinates(featureCoordinates);\n\n\t\tif (coordinates.length !== this._selectionPoints.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.mutateFeature.updateGuidancePoints(\n\t\t\tthis._selectionPoints.map((id, i) => ({\n\t\t\t\tfeatureId: id,\n\t\t\t\tcoordinate: coordinates[i],\n\t\t\t})),\n\t\t);\n\t}\n\n\tpublic updateOneAtIndex(index: number, updatedCoordinate: Position) {\n\t\tif (this._selectionPoints[index] === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.mutateFeature.updateGuidancePoints([\n\t\t\t{\n\t\t\t\tfeatureId: this._selectionPoints[index],\n\t\t\t\tcoordinate: updatedCoordinate,\n\t\t\t},\n\t\t]);\n\t}\n}\n","import { Position } from \"geojson\";\n\n// Based on which-polygon (Mapbox)\n// https://github.com/mapbox/which-polygon/blob/2eb5b8a427d018ebd964c05acd3b9166c4558b2c/index.js#L81\n// ISC License - Copyright (c) 2017, Mapbox\n\nexport function pointInPolygon(point: Position, rings: Position[][]) {\n\tlet inside = false;\n\tfor (let i = 0, len = rings.length; i < len; i++) {\n\t\tconst ring = rings[i];\n\t\tfor (let j = 0, len2 = ring.length, k = len2 - 1; j < len2; k = j++) {\n\t\t\tif (rayIntersect(point, ring[j], ring[k])) {\n\t\t\t\tinside = !inside;\n\t\t\t}\n\t\t}\n\t}\n\treturn inside;\n}\n\nfunction rayIntersect(p: Position, p1: Position, p2: Position) {\n\treturn (\n\t\tp1[1] > p[1] !== p2[1] > p[1] &&\n\t\tp[0] < ((p2[0] - p1[0]) * (p[1] - p1[1])) / (p2[1] - p1[1]) + p1[0]\n\t);\n}\n","import { CartesianPoint } from \"../../common\";\n\nexport const pixelDistanceToLine = (\n\tpoint: CartesianPoint,\n\tlinePointOne: CartesianPoint,\n\tlinePointTwo: CartesianPoint,\n) => {\n\tconst square = (x: number) => {\n\t\treturn x * x;\n\t};\n\tconst dist2 = (v: CartesianPoint, w: CartesianPoint) => {\n\t\treturn square(v.x - w.x) + square(v.y - w.y);\n\t};\n\tconst distToSegmentSquared = (\n\t\tp: CartesianPoint,\n\t\tv: CartesianPoint,\n\t\tw: CartesianPoint,\n\t) => {\n\t\tconst l2 = dist2(v, w);\n\n\t\tif (l2 === 0) {\n\t\t\treturn dist2(p, v);\n\t\t}\n\n\t\tlet t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;\n\t\tt = Math.max(0, Math.min(1, t));\n\n\t\treturn dist2(p, { x: v.x + t * (w.x - v.x), y: v.y + t * (w.y - v.y) });\n\t};\n\n\treturn Math.sqrt(distToSegmentSquared(point, linePointOne, linePointTwo));\n};\n","import { SELECT_PROPERTIES, TerraDrawMouseEvent } from \"../../../common\";\nimport { BBoxPolygon, GeoJSONStoreFeatures } from \"../../../store/store\";\n\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../../click-bounding-box.behavior\";\n\nimport { pointInPolygon } from \"../../../geometry/boolean/point-in-polygon\";\nimport { PixelDistanceBehavior } from \"../../pixel-distance.behavior\";\nimport { pixelDistanceToLine } from \"../../../geometry/measure/pixel-distance-to-line\";\n\nexport class FeatureAtPointerEventBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly createClickBoundingBox: ClickBoundingBoxBehavior,\n\t\tprivate readonly pixelDistance: PixelDistanceBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tpublic find(event: TerraDrawMouseEvent, hasSelection: boolean) {\n\t\tlet clickedPoint: GeoJSONStoreFeatures | undefined = undefined;\n\t\tlet clickedPointDistance = Infinity;\n\t\tlet clickedLineString: GeoJSONStoreFeatures | undefined = undefined;\n\t\tlet clickedLineStringDistance = Infinity;\n\t\tlet clickedPolygon: GeoJSONStoreFeatures | undefined = undefined;\n\n\t\tconst bbox = this.createClickBoundingBox.create(event);\n\t\tconst features = this.store.search(bbox as BBoxPolygon);\n\n\t\tfor (let i = 0; i < features.length; i++) {\n\t\t\tconst feature = features[i];\n\t\t\tconst geometry = feature.geometry;\n\n\t\t\tif (geometry.type === \"Point\") {\n\t\t\t\t// Ignore selection points always, and ignore mid points\n\t\t\t\t// when nothing is selected\n\t\t\t\tconst isSelectionPoint = feature.properties.selectionPoint;\n\t\t\t\tconst isCoordinatePoint = feature.properties.coordinatePoint;\n\t\t\t\tconst isNonSelectedMidPoint =\n\t\t\t\t\t!hasSelection && feature.properties[SELECT_PROPERTIES.MID_POINT];\n\n\t\t\t\tif (isSelectionPoint || isCoordinatePoint || isNonSelectedMidPoint) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst distance = this.pixelDistance.measure(\n\t\t\t\t\tevent,\n\t\t\t\t\tgeometry.coordinates,\n\t\t\t\t);\n\n\t\t\t\tif (\n\t\t\t\t\t!feature.properties[SELECT_PROPERTIES.MID_POINT] &&\n\t\t\t\t\tdistance < this.pointerDistance &&\n\t\t\t\t\tdistance < clickedPointDistance\n\t\t\t\t) {\n\t\t\t\t\tclickedPointDistance = distance;\n\t\t\t\t\tclickedPoint = feature;\n\t\t\t\t}\n\t\t\t} else if (geometry.type === \"LineString\") {\n\t\t\t\tif (clickedPoint) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tfor (let i = 0; i < geometry.coordinates.length - 1; i++) {\n\t\t\t\t\tconst coord = geometry.coordinates[i];\n\t\t\t\t\tconst nextCoord = geometry.coordinates[i + 1];\n\t\t\t\t\tconst distanceToLine = pixelDistanceToLine(\n\t\t\t\t\t\t{ x: event.containerX, y: event.containerY },\n\t\t\t\t\t\tthis.project(coord[0], coord[1]),\n\t\t\t\t\t\tthis.project(nextCoord[0], nextCoord[1]),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tdistanceToLine < this.pointerDistance &&\n\t\t\t\t\t\tdistanceToLine < clickedLineStringDistance\n\t\t\t\t\t) {\n\t\t\t\t\t\tclickedLineStringDistance = distanceToLine;\n\t\t\t\t\t\tclickedLineString = feature;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (geometry.type === \"Polygon\") {\n\t\t\t\tif (clickedPoint || clickedLineString) {\n\t\t\t\t\t// We already have a clicked feature\n\t\t\t\t\t// so we can ignore the polygon\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst clickInsidePolygon = pointInPolygon(\n\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\tgeometry.coordinates,\n\t\t\t\t);\n\n\t\t\t\tif (clickInsidePolygon) {\n\t\t\t\t\tclickedPolygon = feature;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tclickedFeature: clickedPoint || clickedLineString || clickedPolygon,\n\t\t};\n\t}\n}\n","import { TerraDrawMouseEvent, UpdateTypes, Validation } from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { FeatureAtPointerEventBehavior } from \"./feature-at-pointer-event.behavior\";\nimport { LineString, Polygon, Position } from \"geojson\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\nimport { limitPrecision } from \"../../../geometry/limit-decimal-precision\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../../store/store\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"../../../geometry/project/web-mercator\";\nimport { CoordinatePointBehavior } from \"./coordinate-point.behavior\";\nimport { ReadFeatureBehavior } from \"../../read-feature.behavior\";\nimport {\n\tMutateFeatureBehavior,\n\tMutations,\n} from \"../../mutate-feature.behavior\";\nimport { getUnclosedCoordinates } from \"../../../geometry/get-coordinates\";\n\nexport class DragFeatureBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly featuresAtCursorEvent: FeatureAtPointerEventBehavior,\n\t\tprivate readonly selectionPoints: SelectionPointBehavior,\n\t\tprivate readonly midPoints: MidPointBehavior,\n\t\tprivate readonly coordinatePoints: CoordinatePointBehavior,\n\t\tprivate readonly readFeature: ReadFeatureBehavior,\n\t\tprivate readonly mutateFeature: MutateFeatureBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tprivate draggedFeatureId: FeatureId | null = null;\n\n\tprivate dragPosition: Position | undefined;\n\n\tstartDragging(event: TerraDrawMouseEvent, id: FeatureId) {\n\t\tthis.draggedFeatureId = id;\n\t\tthis.dragPosition = [event.lng, event.lat];\n\t}\n\n\tstopDragging() {\n\t\tthis.draggedFeatureId = null;\n\t\tthis.dragPosition = undefined;\n\t}\n\n\tisDragging() {\n\t\treturn this.draggedFeatureId !== null;\n\t}\n\n\tcanDrag(event: TerraDrawMouseEvent, selectedId: FeatureId) {\n\t\tconst { clickedFeature } = this.featuresAtCursorEvent.find(event, true);\n\n\t\t// If the cursor is not over the selected\n\t\t// feature then we don't want to drag\n\t\tif (!clickedFeature || clickedFeature.id !== selectedId) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tdrag(event: TerraDrawMouseEvent) {\n\t\tif (!this.draggedFeatureId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst geometry = this.readFeature.getGeometry(this.draggedFeatureId);\n\t\tconst cursorCoord = [event.lng, event.lat];\n\n\t\t// Update the geometry of the dragged feature\n\t\tif (geometry.type === \"Polygon\" || geometry.type === \"LineString\") {\n\t\t\tlet updatedCoords: Position[];\n\t\t\tlet upToCoord: number;\n\n\t\t\tif (geometry.type === \"Polygon\") {\n\t\t\t\tupdatedCoords = geometry.coordinates[0];\n\t\t\t\tupToCoord = updatedCoords.length - 1;\n\t\t\t} else {\n\t\t\t\t// Must be LineString here\n\t\t\t\tupdatedCoords = geometry.coordinates;\n\t\t\t\tupToCoord = updatedCoords.length;\n\t\t\t}\n\n\t\t\tif (!this.dragPosition) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < upToCoord; i++) {\n\t\t\t\tconst coordinate = updatedCoords[i];\n\n\t\t\t\tlet updatedLng: number;\n\t\t\t\tlet updatedLat: number;\n\n\t\t\t\tif (this.config.projection === \"web-mercator\") {\n\t\t\t\t\tconst webMercatorDragPosition = lngLatToWebMercatorXY(\n\t\t\t\t\t\tthis.dragPosition[0],\n\t\t\t\t\t\tthis.dragPosition[1],\n\t\t\t\t\t);\n\t\t\t\t\tconst webMercatorCursorCoord = lngLatToWebMercatorXY(\n\t\t\t\t\t\tcursorCoord[0],\n\t\t\t\t\t\tcursorCoord[1],\n\t\t\t\t\t);\n\t\t\t\t\tconst webMercatorCoordinate = lngLatToWebMercatorXY(\n\t\t\t\t\t\tcoordinate[0],\n\t\t\t\t\t\tcoordinate[1],\n\t\t\t\t\t);\n\n\t\t\t\t\tconst delta = {\n\t\t\t\t\t\tx: webMercatorDragPosition.x - webMercatorCursorCoord.x,\n\t\t\t\t\t\ty: webMercatorDragPosition.y - webMercatorCursorCoord.y,\n\t\t\t\t\t};\n\n\t\t\t\t\tconst updatedX = webMercatorCoordinate.x - delta.x;\n\t\t\t\t\tconst updatedY = webMercatorCoordinate.y - delta.y;\n\n\t\t\t\t\tconst { lng, lat } = webMercatorXYToLngLat(updatedX, updatedY);\n\n\t\t\t\t\tupdatedLng = lng;\n\t\t\t\t\tupdatedLat = lat;\n\t\t\t\t} else {\n\t\t\t\t\tconst delta = [\n\t\t\t\t\t\tthis.dragPosition[0] - cursorCoord[0],\n\t\t\t\t\t\tthis.dragPosition[1] - cursorCoord[1],\n\t\t\t\t\t];\n\t\t\t\t\tupdatedLng = coordinate[0] - delta[0];\n\t\t\t\t\tupdatedLat = coordinate[1] - delta[1];\n\t\t\t\t}\n\n\t\t\t\t// Keep precision limited when calculating new coordinates\n\t\t\t\tupdatedLng = limitPrecision(\n\t\t\t\t\tupdatedLng,\n\t\t\t\t\tthis.config.coordinatePrecision,\n\t\t\t\t);\n\n\t\t\t\tupdatedLat = limitPrecision(\n\t\t\t\t\tupdatedLat,\n\t\t\t\t\tthis.config.coordinatePrecision,\n\t\t\t\t);\n\n\t\t\t\t// Ensure that coordinates do not exceed\n\t\t\t\t// lng lat limits. Long term we may want to figure out\n\t\t\t\t// proper handling of anti meridian crossings\n\t\t\t\tif (\n\t\t\t\t\tupdatedLng > 180 ||\n\t\t\t\t\tupdatedLng < -180 ||\n\t\t\t\t\tupdatedLat > 90 ||\n\t\t\t\t\tupdatedLat < -90\n\t\t\t\t) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tupdatedCoords[i] = [updatedLng, updatedLat];\n\t\t\t}\n\n\t\t\t// Set final coordinate identical to first\n\t\t\t// We only want to do this for polygons!\n\t\t\tif (geometry.type === \"Polygon\") {\n\t\t\t\tupdatedCoords[updatedCoords.length - 1] = [\n\t\t\t\t\tupdatedCoords[0][0],\n\t\t\t\t\tupdatedCoords[0][1],\n\t\t\t\t];\n\t\t\t}\n\n\t\t\tconst featureId = this.draggedFeatureId as FeatureId;\n\n\t\t\tlet updated: GeoJSONStoreFeatures<Polygon | LineString> | null = null;\n\n\t\t\tif (geometry.type === \"Polygon\") {\n\t\t\t\tupdated = this.mutateFeature.updatePolygon({\n\t\t\t\t\tfeatureId,\n\t\t\t\t\tcoordinateMutations: {\n\t\t\t\t\t\ttype: Mutations.Replace,\n\t\t\t\t\t\tcoordinates: [updatedCoords],\n\t\t\t\t\t},\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\tupdateType: UpdateTypes.Provisional as const,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} else if (geometry.type === \"LineString\") {\n\t\t\t\tupdated = this.mutateFeature.updateLineString({\n\t\t\t\t\tfeatureId,\n\t\t\t\t\tcoordinateMutations: {\n\t\t\t\t\t\ttype: Mutations.Replace,\n\t\t\t\t\t\tcoordinates: updatedCoords,\n\t\t\t\t\t},\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\tupdateType: UpdateTypes.Provisional as const,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!updated) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst featureCoordinates = updated.geometry.coordinates;\n\n\t\t\t// Perform the update to the midpoints and selection points\n\t\t\tthis.midPoints.updateAllInPlace({ featureCoordinates });\n\t\t\tthis.selectionPoints.updateAllInPlace({ featureCoordinates });\n\t\t\tthis.coordinatePoints.updateAllInPlace({ featureId, featureCoordinates });\n\n\t\t\tthis.dragPosition = [event.lng, event.lat];\n\n\t\t\t// Update mid point positions\n\t\t} else if (geometry.type === \"Point\") {\n\t\t\t// For cursor points we can simply move it\n\t\t\t// to the dragged position\n\t\t\tthis.mutateFeature.updatePoint({\n\t\t\t\tfeatureId: this.draggedFeatureId,\n\t\t\t\tcoordinateMutations: {\n\t\t\t\t\ttype: Mutations.Replace,\n\t\t\t\t\tcoordinates: cursorCoord,\n\t\t\t\t},\n\t\t\t\tcontext: {\n\t\t\t\t\tupdateType: UpdateTypes.Provisional as const,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tthis.dragPosition = [event.lng, event.lat];\n\t\t}\n\t}\n}\n","import {\n\tSnapping,\n\tTerraDrawMouseEvent,\n\tUpdateTypes,\n\tValidation,\n} from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\n\nimport { LineString, Polygon, Position, Point, Feature } from \"geojson\";\nimport { PixelDistanceBehavior } from \"../../pixel-distance.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { selfIntersects } from \"../../../geometry/boolean/self-intersects\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../../store/store\";\nimport { CoordinatePointBehavior } from \"./coordinate-point.behavior\";\nimport { CoordinateSnappingBehavior } from \"../../coordinate-snapping.behavior\";\nimport { LineSnappingBehavior } from \"../../line-snapping.behavior\";\nimport { ReadFeatureBehavior } from \"../../read-feature.behavior\";\nimport {\n\tMutateFeatureBehavior,\n\tMutations,\n} from \"../../mutate-feature.behavior\";\n\nexport class DragCoordinateBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly pixelDistance: PixelDistanceBehavior,\n\t\tprivate readonly selectionPoints: SelectionPointBehavior,\n\t\tprivate readonly midPoints: MidPointBehavior,\n\t\tprivate readonly coordinatePoints: CoordinatePointBehavior,\n\t\tprivate readonly coordinateSnapping: CoordinateSnappingBehavior,\n\t\tprivate readonly lineSnapping: LineSnappingBehavior,\n\t\tprivate readonly readFeature: ReadFeatureBehavior,\n\t\tprivate readonly mutateFeature: MutateFeatureBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tprivate draggedCoordinate: { id: null | FeatureId; index: number } = {\n\t\tid: null,\n\t\tindex: -1,\n\t};\n\n\tprivate getClosestCoordinate(\n\t\tevent: TerraDrawMouseEvent,\n\t\tgeometry: Polygon | LineString | Point,\n\t) {\n\t\tconst closestCoordinate = {\n\t\t\tdist: Infinity,\n\t\t\tindex: -1,\n\t\t\tisFirstOrLastPolygonCoord: false,\n\t\t};\n\n\t\tlet geomCoordinates: Position[] | undefined;\n\n\t\tif (geometry.type === \"LineString\") {\n\t\t\tgeomCoordinates = geometry.coordinates;\n\t\t} else if (geometry.type === \"Polygon\") {\n\t\t\tgeomCoordinates = geometry.coordinates[0];\n\t\t} else {\n\t\t\t// We don't want to handle dragging\n\t\t\t// points here\n\t\t\treturn closestCoordinate;\n\t\t}\n\n\t\t// Look through the selected features coordinates\n\t\t// and try to find a coordinate that is draggable\n\t\tfor (let i = 0; i < geomCoordinates.length; i++) {\n\t\t\tconst coord = geomCoordinates[i];\n\t\t\tconst distance = this.pixelDistance.measure(event, coord);\n\n\t\t\tif (\n\t\t\t\tdistance < this.pointerDistance &&\n\t\t\t\tdistance < closestCoordinate.dist\n\t\t\t) {\n\t\t\t\t// We don't create a point for the final\n\t\t\t\t// polygon coord, so we must set it to the first\n\t\t\t\t// coordinate instead\n\t\t\t\tconst isFirstOrLastPolygonCoord =\n\t\t\t\t\tgeometry.type === \"Polygon\" &&\n\t\t\t\t\t(i === geomCoordinates.length - 1 || i === 0);\n\n\t\t\t\tclosestCoordinate.dist = distance;\n\t\t\t\tclosestCoordinate.index = isFirstOrLastPolygonCoord ? 0 : i;\n\t\t\t\tclosestCoordinate.isFirstOrLastPolygonCoord = isFirstOrLastPolygonCoord;\n\t\t\t}\n\t\t}\n\n\t\treturn closestCoordinate;\n\t}\n\n\tpublic getDraggable(event: TerraDrawMouseEvent, selectedId: FeatureId) {\n\t\tconst geometry = this.readFeature.getGeometry(selectedId);\n\t\tconst closestCoordinate = this.getClosestCoordinate(event, geometry);\n\n\t\treturn closestCoordinate;\n\t}\n\n\tpublic getDraggableIndex(\n\t\tevent: TerraDrawMouseEvent,\n\t\tselectedId: FeatureId,\n\t): number {\n\t\tconst geometry = this.readFeature.getGeometry(selectedId);\n\t\tconst closestCoordinate = this.getClosestCoordinate(event, geometry);\n\n\t\t// No coordinate was within the pointer distance\n\t\tif (closestCoordinate.index === -1) {\n\t\t\treturn -1;\n\t\t}\n\t\treturn closestCoordinate.index;\n\t}\n\n\tprivate snapCoordinate(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsnapping: Snapping,\n\t\tdraggedFeature: GeoJSONStoreFeatures,\n\t): Position {\n\t\tlet snappedCoordinate: Position = [event.lng, event.lat];\n\n\t\t// This is a uniform filter we can use across all snapping behaviors\n\t\tconst filter = (feature: Feature) => {\n\t\t\treturn Boolean(\n\t\t\t\tfeature.properties &&\n\t\t\t\t\tfeature.properties.mode === draggedFeature.properties.mode &&\n\t\t\t\t\tfeature.id !== this.draggedCoordinate.id,\n\t\t\t);\n\t\t};\n\n\t\tif (snapping?.toLine) {\n\t\t\tlet snapped: Position | undefined;\n\n\t\t\tsnapped = this.lineSnapping.getSnappable(event, filter).coordinate;\n\n\t\t\tif (snapped) {\n\t\t\t\tsnappedCoordinate = snapped;\n\t\t\t}\n\t\t}\n\n\t\tif (snapping.toCoordinate) {\n\t\t\tlet snapped: Position | undefined = undefined;\n\n\t\t\tsnapped = this.coordinateSnapping.getSnappable(event, filter).coordinate;\n\n\t\t\tif (snapped) {\n\t\t\t\tsnappedCoordinate = snapped;\n\t\t\t}\n\t\t}\n\n\t\tif (snapping?.toCustom) {\n\t\t\tlet snapped: Position | undefined = undefined;\n\n\t\t\tsnapped = snapping.toCustom(event, {\n\t\t\t\tcurrentCoordinate: this.draggedCoordinate.index,\n\t\t\t\tcurrentId: draggedFeature.id,\n\t\t\t\tgetCurrentGeometrySnapshot: draggedFeature.id\n\t\t\t\t\t? () =>\n\t\t\t\t\t\t\tthis.readFeature.getGeometry<Polygon>(\n\t\t\t\t\t\t\t\tdraggedFeature.id as FeatureId,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t: () => null,\n\t\t\t\tproject: this.project,\n\t\t\t\tunproject: this.unproject,\n\t\t\t});\n\n\t\t\tif (snapped) {\n\t\t\t\tsnappedCoordinate = snapped;\n\t\t\t}\n\t\t}\n\n\t\treturn snappedCoordinate;\n\t}\n\n\tdrag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tallowSelfIntersection: boolean,\n\t\tsnapping: Snapping,\n\t): boolean {\n\t\tconst draggedFeatureId = this.draggedCoordinate.id;\n\n\t\tif (draggedFeatureId === null) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst index = this.draggedCoordinate.index;\n\t\tconst geometry = this.readFeature.getGeometry(draggedFeatureId);\n\t\tconst properties = this.readFeature.getProperties(draggedFeatureId);\n\n\t\tconst updatedCoordinates = (\n\t\t\tgeometry.type === \"LineString\"\n\t\t\t\t? geometry.coordinates\n\t\t\t\t: geometry.coordinates[0]\n\t\t) as Position[];\n\n\t\tconst isFirstOrLastPolygonCoord =\n\t\t\tgeometry.type === \"Polygon\" &&\n\t\t\t(index === updatedCoordinates.length - 1 || index === 0);\n\n\t\tconst draggedFeature: GeoJSONStoreFeatures = {\n\t\t\ttype: \"Feature\",\n\t\t\tid: draggedFeatureId,\n\t\t\tgeometry,\n\t\t\tproperties,\n\t\t};\n\n\t\tconst updatedCoordinate = this.snapCoordinate(\n\t\t\tevent,\n\t\t\tsnapping,\n\t\t\tdraggedFeature,\n\t\t);\n\n\t\t// Ensure that coordinates do not exceed\n\t\t// lng lat limits. Long term we may want to figure out\n\t\t// proper handling of anti meridian crossings\n\t\tif (\n\t\t\tevent.lng > 180 ||\n\t\t\tevent.lng < -180 ||\n\t\t\tevent.lat > 90 ||\n\t\t\tevent.lat < -90\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// We want to update the actual Polygon/LineString itself -\n\t\t// for Polygons we want the first and last coordinates to match\n\t\tif (isFirstOrLastPolygonCoord) {\n\t\t\tconst lastCoordIndex = updatedCoordinates.length - 1;\n\t\t\tupdatedCoordinates[0] = updatedCoordinate;\n\t\t\tupdatedCoordinates[lastCoordIndex] = updatedCoordinate;\n\t\t} else {\n\t\t\tupdatedCoordinates[index] = updatedCoordinate;\n\t\t}\n\n\t\tif (\n\t\t\tgeometry.type !== \"Point\" &&\n\t\t\t!allowSelfIntersection &&\n\t\t\tselfIntersects({\n\t\t\t\ttype: \"Feature\",\n\t\t\t\tgeometry: geometry,\n\t\t\t\tproperties: {},\n\t\t\t} as Feature<Polygon>)\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst featureId = draggedFeatureId as FeatureId;\n\n\t\tlet updated: GeoJSONStoreFeatures | null = null;\n\n\t\tif (geometry.type === \"Polygon\") {\n\t\t\tupdated = this.mutateFeature.updatePolygon({\n\t\t\t\tfeatureId,\n\t\t\t\tcoordinateMutations: {\n\t\t\t\t\ttype: Mutations.Replace,\n\t\t\t\t\tcoordinates: [updatedCoordinates],\n\t\t\t\t},\n\t\t\t\tcontext: {\n\t\t\t\t\tupdateType: UpdateTypes.Provisional as const,\n\t\t\t\t},\n\t\t\t});\n\t\t} else if (geometry.type === \"LineString\") {\n\t\t\tupdated = this.mutateFeature.updateLineString({\n\t\t\t\tfeatureId,\n\t\t\t\tcoordinateMutations: {\n\t\t\t\t\ttype: Mutations.Replace,\n\t\t\t\t\tcoordinates: updatedCoordinates,\n\t\t\t\t},\n\t\t\t\tcontext: {\n\t\t\t\t\tupdateType: UpdateTypes.Provisional as const,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tif (!updated) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Perform the update to the midpoints and selection points\n\t\tif (index > 0) {\n\t\t\tthis.midPoints.updateOneAtIndex(index - 1, updatedCoordinates);\n\t\t} else {\n\t\t\tthis.midPoints.updateOneAtIndex(-1, updatedCoordinates);\n\t\t}\n\t\tthis.midPoints.updateOneAtIndex(index, updatedCoordinates);\n\t\tthis.selectionPoints.updateOneAtIndex(index, updatedCoordinate);\n\t\tthis.coordinatePoints.updateOneAtIndex(featureId, index, updatedCoordinate);\n\n\t\treturn true;\n\t}\n\n\tisDragging() {\n\t\treturn this.draggedCoordinate.id !== null;\n\t}\n\n\tstartDragging(id: FeatureId, index: number) {\n\t\tthis.draggedCoordinate = {\n\t\t\tid,\n\t\t\tindex,\n\t\t};\n\t}\n\n\tstopDragging() {\n\t\tthis.draggedCoordinate = {\n\t\t\tid: null,\n\t\t\tindex: -1,\n\t\t};\n\t}\n}\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\n\n// Adapter from the @turf/bearing which is MIT Licensed\n// https://github.com/Turfjs/turf/tree/master/packages/turf-centroid\n\nexport function centroid(geojson: Feature<Polygon | LineString>): Position {\n\tlet xSum = 0;\n\tlet ySum = 0;\n\tlet len = 0;\n\n\tconst coordinates =\n\t\tgeojson.geometry.type === \"Polygon\"\n\t\t\t? geojson.geometry.coordinates[0].slice(0, -1)\n\t\t\t: geojson.geometry.coordinates;\n\n\tcoordinates.forEach((coord: Position) => {\n\t\txSum += coord[0];\n\t\tySum += coord[1];\n\t\tlen++;\n\t}, true);\n\n\treturn [xSum / len, ySum / len];\n}\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\nimport { centroid } from \"../centroid\";\nimport { rhumbBearing } from \"../measure/rhumb-bearing\";\nimport { rhumbDestination } from \"../measure/rhumb-destination\";\nimport { rhumbDistance } from \"../measure/rhumb-distance\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"../project/web-mercator\";\nimport { CartesianPoint } from \"../../common\";\n\n// Adapted on @turf/transform-rotate module which is MIT licensed\n// https://github.com/Turfjs/turf/tree/master/packages/turf-transform-rotate\n\nexport function transformRotate(\n\tfeature: Feature<Polygon | LineString>,\n\tangle: number,\n) {\n\t// Shortcut no-rotation\n\tif (angle === 0 || angle === 360 || angle === -360) {\n\t\treturn feature;\n\t}\n\n\t// Use centroid of GeoJSON if pivot is not provided\n\tconst pivot = centroid(feature);\n\n\tconst coordinates =\n\t\tfeature.geometry.type === \"Polygon\"\n\t\t\t? feature.geometry.coordinates[0]\n\t\t\t: feature.geometry.coordinates;\n\n\tcoordinates.forEach((pointCoords: Position) => {\n\t\tconst initialAngle = rhumbBearing(pivot, pointCoords);\n\t\tconst finalAngle = initialAngle + angle;\n\t\tconst distance = rhumbDistance(pivot, pointCoords);\n\t\tconst newCoords = rhumbDestination(pivot, distance, finalAngle);\n\t\tpointCoords[0] = newCoords[0];\n\t\tpointCoords[1] = newCoords[1];\n\t});\n\n\treturn feature;\n}\n\n/**\n * Rotate a GeoJSON Polygon geometry in web mercator\n * @param polygon - GeoJSON Polygon geometry\n * @param angle - rotation angle in degrees\n * @returns - rotated GeoJSON Polygon geometry\n */\nexport const transformRotateWebMercator = (\n\tfeature: Feature<Polygon> | Feature<LineString>,\n\tangle: number,\n) => {\n\tif (angle === 0 || angle === 360 || angle === -360) {\n\t\treturn feature;\n\t}\n\n\tconst DEGREES_TO_RADIANS = 0.017453292519943295 as const; // Math.PI / 180\n\n\tconst coordinates =\n\t\tfeature.geometry.type === \"Polygon\"\n\t\t\t? feature.geometry.coordinates[0]\n\t\t\t: feature.geometry.coordinates;\n\tconst angleRad = angle * DEGREES_TO_RADIANS;\n\n\t// Convert polygon coordinates to Web Mercator\n\tconst webMercatorCoords = coordinates.map(([lng, lat]) =>\n\t\tlngLatToWebMercatorXY(lng, lat),\n\t);\n\n\t// Find centroid of the polygon in Web Mercator\n\tconst centroid = webMercatorCoords.reduce(\n\t\t(acc: CartesianPoint, coord: CartesianPoint) => ({\n\t\t\tx: acc.x + coord.x,\n\t\t\ty: acc.y + coord.y,\n\t\t}),\n\t\t{ x: 0, y: 0 },\n\t);\n\tcentroid.x /= webMercatorCoords.length;\n\tcentroid.y /= webMercatorCoords.length;\n\n\t// Rotate the coordinates around the centroid\n\tconst rotatedWebMercatorCoords = webMercatorCoords.map((coord) => ({\n\t\tx:\n\t\t\tcentroid.x +\n\t\t\t(coord.x - centroid.x) * Math.cos(angleRad) -\n\t\t\t(coord.y - centroid.y) * Math.sin(angleRad),\n\t\ty:\n\t\t\tcentroid.y +\n\t\t\t(coord.x - centroid.x) * Math.sin(angleRad) +\n\t\t\t(coord.y - centroid.y) * Math.cos(angleRad),\n\t}));\n\n\t// Convert rotated Web Mercator coordinates back to geographic\n\tconst rotatedCoordinates = rotatedWebMercatorCoords.map(\n\t\t({ x, y }) =>\n\t\t\t[\n\t\t\t\twebMercatorXYToLngLat(x, y).lng,\n\t\t\t\twebMercatorXYToLngLat(x, y).lat,\n\t\t\t] as Position,\n\t);\n\n\tif (feature.geometry.type === \"Polygon\") {\n\t\tfeature.geometry.coordinates[0] = rotatedCoordinates;\n\t} else {\n\t\tfeature.geometry.coordinates = rotatedCoordinates;\n\t}\n\n\treturn feature;\n};\n","import { Feature, LineString, Polygon, Position } from \"geojson\";\nimport { lngLatToWebMercatorXY } from \"./project/web-mercator\";\nimport { CartesianPoint } from \"../common\";\n\n/**\n * Calculates the centroid of a GeoJSON Polygon or LineString in Web Mercator\n\n * @param {Feature<Polygon | LineString>} feature - The GeoJSON Feature containing either a Polygon or LineString\n * @returns {{ x: number, y: number }} The centroid of the polygon or line string in Web Mercator coordinates.\n */\nexport function webMercatorCentroid(feature: Feature<Polygon | LineString>) {\n\tconst coordinates =\n\t\tfeature.geometry.type === \"Polygon\"\n\t\t\t? feature.geometry.coordinates[0]\n\t\t\t: feature.geometry.coordinates;\n\n\tconst webMercatorCoordinates = coordinates.map((coord) => {\n\t\tconst { x, y } = lngLatToWebMercatorXY(coord[0], coord[1]);\n\t\treturn [x, y];\n\t});\n\n\tif (feature.geometry.type === \"Polygon\") {\n\t\treturn calculatePolygonCentroid(webMercatorCoordinates);\n\t} else {\n\t\treturn calculateLineStringMidpoint(webMercatorCoordinates);\n\t}\n}\n\nfunction calculatePolygonCentroid(\n\twebMercatorCoordinates: Position[],\n): CartesianPoint {\n\tlet area = 0;\n\tlet centroidX = 0;\n\tlet centroidY = 0;\n\n\tconst n = webMercatorCoordinates.length;\n\n\tfor (let i = 0; i < n - 1; i++) {\n\t\tconst [x1, y1] = webMercatorCoordinates[i];\n\t\tconst [x2, y2] = webMercatorCoordinates[i + 1];\n\n\t\tconst crossProduct = x1 * y2 - x2 * y1;\n\t\tarea += crossProduct;\n\t\tcentroidX += (x1 + x2) * crossProduct;\n\t\tcentroidY += (y1 + y2) * crossProduct;\n\t}\n\n\tarea /= 2;\n\tcentroidX /= 6 * area;\n\tcentroidY /= 6 * area;\n\n\treturn { x: centroidX, y: centroidY };\n}\n\nfunction calculateLineStringMidpoint(lineString: Position[]): CartesianPoint {\n\tconst n = lineString.length;\n\tlet totalX = 0;\n\tlet totalY = 0;\n\n\tfor (let i = 0; i < n; i++) {\n\t\tconst [x, y] = lineString[i];\n\t\ttotalX += x;\n\t\ttotalY += y;\n\t}\n\n\treturn { x: totalX / n, y: totalY / n };\n}\n","import {\n\tCartesianPoint,\n\tTerraDrawMouseEvent,\n\tUpdateTypes,\n\tValidation,\n} from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { Feature, LineString, Polygon, Position } from \"geojson\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\nimport {\n\ttransformRotate,\n\ttransformRotateWebMercator,\n} from \"../../../geometry/transform/rotate\";\nimport { centroid } from \"../../../geometry/centroid\";\nimport { rhumbBearing } from \"../../../geometry/measure/rhumb-bearing\";\nimport { limitPrecision } from \"../../../geometry/limit-decimal-precision\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../../store/store\";\nimport { webMercatorCentroid } from \"../../../geometry/web-mercator-centroid\";\nimport { lngLatToWebMercatorXY } from \"../../../geometry/project/web-mercator\";\nimport { webMercatorBearing } from \"../../../geometry/measure/bearing\";\nimport { CoordinatePointBehavior } from \"./coordinate-point.behavior\";\nimport { ReadFeatureBehavior } from \"../../read-feature.behavior\";\nimport {\n\tMutateFeatureBehavior,\n\tMutations,\n\tUpdateGeometry,\n} from \"../../mutate-feature.behavior\";\n\nexport class RotateFeatureBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly selectionPoints: SelectionPointBehavior,\n\t\tprivate readonly midPoints: MidPointBehavior,\n\t\tprivate readonly coordinatePoints: CoordinatePointBehavior,\n\t\tprivate readonly readFeature: ReadFeatureBehavior,\n\t\tprivate readonly mutateFeature: MutateFeatureBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tprivate lastBearing: number | undefined;\n\tprivate selectedGeometry: Polygon | LineString | undefined;\n\tprivate selectedGeometryCentroid: Position | undefined;\n\tprivate selectedGeometryWebMercatorCentroid: CartesianPoint | undefined;\n\n\treset() {\n\t\tthis.lastBearing = undefined;\n\t\tthis.selectedGeometry = undefined;\n\t\tthis.selectedGeometryWebMercatorCentroid = undefined;\n\t\tthis.selectedGeometryCentroid = undefined;\n\t}\n\n\trotate(event: TerraDrawMouseEvent, selectedId: FeatureId) {\n\t\tif (!this.selectedGeometry) {\n\t\t\tthis.selectedGeometry = this.readFeature.getGeometry<\n\t\t\t\tLineString | Polygon\n\t\t\t>(selectedId);\n\t\t}\n\n\t\tconst geometry = this.selectedGeometry;\n\n\t\t// Update the geometry of the dragged feature\n\t\tif (geometry.type !== \"Polygon\" && geometry.type !== \"LineString\") {\n\t\t\treturn;\n\t\t}\n\n\t\tconst mouseCoord = [event.lng, event.lat];\n\n\t\tlet bearing: number;\n\t\tconst updatedFeature = { type: \"Feature\", geometry, properties: {} } as\n\t\t\t| Feature<Polygon>\n\t\t\t| Feature<LineString>;\n\n\t\tif (this.config.projection === \"web-mercator\") {\n\t\t\t// Cache the centroid of the selected geometry\n\t\t\t// to avoid recalculating it on every cursor move\n\t\t\tif (!this.selectedGeometryWebMercatorCentroid) {\n\t\t\t\tthis.selectedGeometryWebMercatorCentroid =\n\t\t\t\t\twebMercatorCentroid(updatedFeature);\n\t\t\t}\n\n\t\t\tconst cursorWebMercator = lngLatToWebMercatorXY(event.lng, event.lat);\n\n\t\t\tbearing = webMercatorBearing(\n\t\t\t\tthis.selectedGeometryWebMercatorCentroid,\n\t\t\t\tcursorWebMercator,\n\t\t\t);\n\n\t\t\tif (bearing === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!this.lastBearing) {\n\t\t\t\tthis.lastBearing = bearing;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst angle = this.lastBearing - bearing;\n\n\t\t\ttransformRotateWebMercator(updatedFeature, -angle);\n\t\t} else if (this.config.projection === \"globe\") {\n\t\t\t// Cache the centroid of the selected geometry\n\t\t\t// to avoid recalculating it on every cursor move\n\t\t\tif (!this.selectedGeometryCentroid) {\n\t\t\t\tthis.selectedGeometryCentroid = centroid({\n\t\t\t\t\ttype: \"Feature\",\n\t\t\t\t\tgeometry,\n\t\t\t\t\tproperties: {},\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tbearing = rhumbBearing(this.selectedGeometryCentroid, mouseCoord);\n\n\t\t\t// We need an original bearing to compare against\n\t\t\tif (!this.lastBearing) {\n\t\t\t\tthis.lastBearing = bearing + 180;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst angle = this.lastBearing - (bearing + 180);\n\n\t\t\ttransformRotate(updatedFeature, -angle);\n\t\t} else {\n\t\t\tthrow new Error(\"Unsupported projection\");\n\t\t}\n\n\t\t// Coordinates are either polygon or linestring at this point\n\t\tconst updatedCoords: Position[] =\n\t\t\tgeometry.type === \"Polygon\"\n\t\t\t\t? geometry.coordinates[0]\n\t\t\t\t: geometry.coordinates;\n\n\t\t// Ensure that coordinate precision is maintained\n\t\tupdatedCoords.forEach((coordinate) => {\n\t\t\tcoordinate[0] = limitPrecision(coordinate[0], this.coordinatePrecision);\n\t\t\tcoordinate[1] = limitPrecision(coordinate[1], this.coordinatePrecision);\n\t\t});\n\n\t\tconst update = {\n\t\t\tfeatureId: selectedId,\n\t\t\tcoordinateMutations: {\n\t\t\t\ttype: Mutations.Replace,\n\t\t\t\tcoordinates:\n\t\t\t\t\tgeometry.type === \"Polygon\" ? [updatedCoords] : updatedCoords,\n\t\t\t},\n\t\t\tcontext: {\n\t\t\t\tupdateType: UpdateTypes.Provisional as const,\n\t\t\t},\n\t\t};\n\n\t\tlet updated: GeoJSONStoreFeatures<Polygon | LineString> | null = null;\n\t\tif (updatedFeature.geometry.type === \"Polygon\") {\n\t\t\tupdated = this.mutateFeature.updatePolygon(\n\t\t\t\tupdate as UpdateGeometry<Polygon>,\n\t\t\t);\n\t\t} else if (updatedFeature.geometry.type === \"LineString\") {\n\t\t\tupdated = this.mutateFeature.updateLineString(\n\t\t\t\tupdate as UpdateGeometry<LineString>,\n\t\t\t);\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!updated) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst featureCoordinates = updated.geometry.coordinates;\n\n\t\t// Perform the update to the midpoints and selection points\n\t\tthis.midPoints.updateAllInPlace({ featureCoordinates });\n\t\tthis.selectionPoints.updateAllInPlace({ featureCoordinates });\n\t\tthis.coordinatePoints.updateAllInPlace({\n\t\t\tfeatureId: selectedId,\n\t\t\tfeatureCoordinates,\n\t\t});\n\n\t\tif (this.projection === \"web-mercator\") {\n\t\t\tthis.lastBearing = bearing;\n\t\t} else if (this.projection === \"globe\") {\n\t\t\tthis.lastBearing = bearing + 180;\n\t\t}\n\t}\n}\n","import { Position } from \"geojson\";\nimport { earthRadius } from \"../helpers\";\n\n// Adapted from @turf/rhumb-distance module\n// https://github.com/Turfjs/turf/blob/master/packages/turf-rhumb-distance/index.ts\n\nexport function rhumbDistance(destination: Position, origin: Position): number {\n\t// compensate the crossing of the 180th meridian (https://macwright.org/2016/09/26/the-180th-meridian.html)\n\t// solution from https://github.com/mapbox/mapbox-gl-js/issues/3250#issuecomment-294887678\n\tdestination[0] +=\n\t\tdestination[0] - origin[0] > 180\n\t\t\t? -360\n\t\t\t: origin[0] - destination[0] > 180\n\t\t\t\t? 360\n\t\t\t\t: 0;\n\n\t// see www.edwilliams.org/avform.htm#Rhumb\n\n\tconst R = earthRadius;\n\tconst phi1 = (origin[1] * Math.PI) / 180;\n\tconst phi2 = (destination[1] * Math.PI) / 180;\n\tconst DeltaPhi = phi2 - phi1;\n\tlet DeltaLambda = (Math.abs(destination[0] - origin[0]) * Math.PI) / 180;\n\n\t// if dLon over 180° take shorter rhumb line across the anti-meridian:\n\tif (DeltaLambda > Math.PI) {\n\t\tDeltaLambda -= 2 * Math.PI;\n\t}\n\n\t// on Mercator projection, longitude distances shrink by latitude; q is the 'stretch factor'\n\t// q becomes ill-conditioned along E-W line (0/0); use empirical tolerance to avoid it\n\tconst DeltaPsi = Math.log(\n\t\tMath.tan(phi2 / 2 + Math.PI / 4) / Math.tan(phi1 / 2 + Math.PI / 4),\n\t);\n\tconst q = Math.abs(DeltaPsi) > 10e-12 ? DeltaPhi / DeltaPsi : Math.cos(phi1);\n\n\t// distance is pythagoras on 'stretched' Mercator projection\n\tconst delta = Math.sqrt(\n\t\tDeltaPhi * DeltaPhi + q * q * DeltaLambda * DeltaLambda,\n\t); // angular distance in radians\n\n\tconst distanceMeters = delta * R;\n\n\treturn distanceMeters;\n}\n","import { TerraDrawMouseEvent, Validation } from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { FeatureId } from \"../../../store/store\";\nimport { DragCoordinateResizeBehavior } from \"./drag-coordinate-resize.behavior\";\n\nexport class ScaleFeatureBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly dragCoordinateResizeBehavior: DragCoordinateResizeBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tpublic scale(event: TerraDrawMouseEvent, featureId: FeatureId) {\n\t\tif (!this.dragCoordinateResizeBehavior.isDragging()) {\n\t\t\tconst index = this.dragCoordinateResizeBehavior.getDraggableIndex(\n\t\t\t\tevent,\n\t\t\t\tfeatureId,\n\t\t\t);\n\t\t\tthis.dragCoordinateResizeBehavior.startDragging(featureId, index);\n\t\t}\n\n\t\tthis.dragCoordinateResizeBehavior.drag(event, \"center-fixed\");\n\t}\n\n\tpublic reset() {\n\t\tthis.dragCoordinateResizeBehavior.stopDragging();\n\t}\n}\n","import { Position } from \"geojson\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"../project/web-mercator\";\n\nexport function transformScaleWebMercatorCoordinates({\n\tcoordinates,\n\toriginX,\n\toriginY,\n\txScale,\n\tyScale,\n}: {\n\tcoordinates: Position[];\n\toriginX: number;\n\toriginY: number;\n\txScale: number;\n\tyScale: number;\n}): void {\n\tif (xScale === 1 && yScale === 1) {\n\t\t// No scaling needed, return early\n\t\treturn;\n\t}\n\n\tcoordinates.forEach((coordinate) => {\n\t\tconst { x, y } = lngLatToWebMercatorXY(coordinate[0], coordinate[1]);\n\n\t\tconst updatedX = originX + (x - originX) * xScale;\n\t\tconst updatedY = originY + (y - originY) * yScale;\n\n\t\tconst { lng, lat } = webMercatorXYToLngLat(updatedX, updatedY);\n\n\t\tcoordinate[0] = lng;\n\t\tcoordinate[1] = lat;\n\t});\n}\n","import {\n\tCartesianPoint,\n\tTerraDrawMouseEvent,\n\tUpdateTypes,\n\tValidation,\n} from \"../../../common\";\nimport { BehaviorConfig, TerraDrawModeBehavior } from \"../../base.behavior\";\nimport { LineString, Polygon, Position, Point, Feature } from \"geojson\";\nimport { PixelDistanceBehavior } from \"../../pixel-distance.behavior\";\nimport { MidPointBehavior } from \"./midpoint.behavior\";\nimport { SelectionPointBehavior } from \"./selection-point.behavior\";\nimport {\n\tFeatureId,\n\tGeoJSONStoreFeatures,\n\tGeoJSONStoreGeometries,\n} from \"../../../store/store\";\nimport { limitPrecision } from \"../../../geometry/limit-decimal-precision\";\nimport { cartesianDistance } from \"../../../geometry/measure/pixel-distance\";\nimport { coordinatePrecisionIsValid } from \"../../../geometry/boolean/is-valid-coordinate\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"../../../geometry/project/web-mercator\";\nimport { webMercatorCentroid } from \"../../../geometry/web-mercator-centroid\";\nimport { CoordinatePointBehavior } from \"./coordinate-point.behavior\";\nimport { transformScaleWebMercatorCoordinates } from \"../../../geometry/transform/scale\";\nimport { ReadFeatureBehavior } from \"../../read-feature.behavior\";\nimport {\n\tMutateFeatureBehavior,\n\tMutations,\n} from \"../../mutate-feature.behavior\";\n\nexport type ResizeOptions =\n\t| \"center\"\n\t| \"opposite\"\n\t| \"center-fixed\"\n\t| \"opposite-fixed\";\n\ntype BoundingBoxIndex = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;\n\ntype BoundingBox = readonly [\n\tnumber[],\n\tnumber[],\n\tnumber[],\n\tnumber[],\n\tnumber[],\n\tnumber[],\n\tnumber[],\n\tnumber[],\n];\n\nexport class DragCoordinateResizeBehavior extends TerraDrawModeBehavior {\n\tconstructor(\n\t\treadonly config: BehaviorConfig,\n\t\tprivate readonly pixelDistance: PixelDistanceBehavior,\n\t\tprivate readonly selectionPoints: SelectionPointBehavior,\n\t\tprivate readonly midPoints: MidPointBehavior,\n\t\tprivate readonly coordinatePoints: CoordinatePointBehavior,\n\t\tprivate readonly readFeature: ReadFeatureBehavior,\n\t\tprivate readonly mutateFeature: MutateFeatureBehavior,\n\t) {\n\t\tsuper(config);\n\t}\n\n\tprivate minimumScale = 0.0001;\n\n\tprivate draggedCoordinate: { id: null | FeatureId; index: number } = {\n\t\tid: null,\n\t\tindex: -1,\n\t};\n\n\t// This map provides the oppsite corner of the bbox\n\t// to the index of the coordinate provided\n\t//   0    1    2\n\t//   *----*----*\n\t// \t |\t\t   |\n\t// 7 *\t\t   *  3\n\t//   |\t\t   |\n\t//   *----*----*\n\t// \t 6    5    4\n\t//\n\tprivate boundingBoxMaps = {\n\t\topposite: {\n\t\t\t0: 4,\n\t\t\t1: 5,\n\t\t\t2: 6,\n\t\t\t3: 7,\n\t\t\t4: 0,\n\t\t\t5: 1,\n\t\t\t6: 2,\n\t\t\t7: 3,\n\t\t},\n\t};\n\n\tprivate getClosestCoordinate(\n\t\tevent: TerraDrawMouseEvent,\n\t\tgeometry: Polygon | LineString | Point,\n\t) {\n\t\tconst closestCoordinate = {\n\t\t\tdist: Infinity,\n\t\t\tindex: -1,\n\t\t\tisFirstOrLastPolygonCoord: false,\n\t\t};\n\n\t\tlet geomCoordinates: Position[] | undefined;\n\n\t\tif (geometry.type === \"LineString\") {\n\t\t\tgeomCoordinates = geometry.coordinates;\n\t\t} else if (geometry.type === \"Polygon\") {\n\t\t\tgeomCoordinates = geometry.coordinates[0];\n\t\t} else {\n\t\t\t// We don't want to handle dragging\n\t\t\t// points here\n\t\t\treturn closestCoordinate;\n\t\t}\n\n\t\t// Look through the selected features coordinates\n\t\t// and try to find a coordinate that is draggable\n\t\tfor (let i = 0; i < geomCoordinates.length; i++) {\n\t\t\tconst coord = geomCoordinates[i];\n\t\t\tconst distance = this.pixelDistance.measure(event, coord);\n\n\t\t\tif (\n\t\t\t\tdistance < this.pointerDistance &&\n\t\t\t\tdistance < closestCoordinate.dist\n\t\t\t) {\n\t\t\t\t// We don't create a point for the final\n\t\t\t\t// polygon coord, so we must set it to the first\n\t\t\t\t// coordinate instead\n\t\t\t\tconst isFirstOrLastPolygonCoord =\n\t\t\t\t\tgeometry.type === \"Polygon\" &&\n\t\t\t\t\t(i === geomCoordinates.length - 1 || i === 0);\n\n\t\t\t\tclosestCoordinate.dist = distance;\n\t\t\t\tclosestCoordinate.index = isFirstOrLastPolygonCoord ? 0 : i;\n\t\t\t\tclosestCoordinate.isFirstOrLastPolygonCoord = isFirstOrLastPolygonCoord;\n\t\t\t}\n\t\t}\n\n\t\treturn closestCoordinate;\n\t}\n\n\tprivate isValidDragWebMercator(\n\t\tindex: BoundingBoxIndex,\n\t\tdistanceX: number,\n\t\tdistanceY: number,\n\t) {\n\t\tswitch (index) {\n\t\t\tcase 0:\n\t\t\t\tif (distanceX <= 0 || distanceY >= 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tif (distanceY >= 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tif (distanceX >= 0 || distanceY >= 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\tif (distanceX >= 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\tif (distanceX >= 0 || distanceY <= 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 5:\n\t\t\t\tif (distanceY <= 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 6:\n\t\t\t\tif (distanceX <= 0 || distanceY <= 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 7:\n\t\t\t\tif (distanceX <= 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tprivate getSelectedFeatureDataWebMercator() {\n\t\tif (!this.draggedCoordinate.id || this.draggedCoordinate.index === -1) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst feature = this.getFeature(this.draggedCoordinate.id);\n\t\tif (!feature) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst updatedCoords = this.getNormalisedCoordinates(feature.geometry);\n\t\tconst boundingBox = this.getBBoxWebMercator(updatedCoords);\n\n\t\treturn {\n\t\t\tboundingBox,\n\t\t\tfeature,\n\t\t\tupdatedCoords,\n\t\t\tselectedCoordinate: updatedCoords[this.draggedCoordinate.index],\n\t\t};\n\t}\n\n\tprivate centerWebMercatorDrag(event: TerraDrawMouseEvent) {\n\t\tconst featureData = this.getSelectedFeatureDataWebMercator();\n\t\tif (!featureData) {\n\t\t\treturn null;\n\t\t}\n\t\tconst { feature, boundingBox, updatedCoords, selectedCoordinate } =\n\t\t\tfeatureData;\n\n\t\tconst webMercatorOrigin = webMercatorCentroid(feature);\n\n\t\tif (!webMercatorOrigin) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst webMercatorSelected = lngLatToWebMercatorXY(\n\t\t\tselectedCoordinate[0],\n\t\t\tselectedCoordinate[1],\n\t\t);\n\n\t\tconst { closestBBoxIndex } = this.getIndexesWebMercator(\n\t\t\tboundingBox,\n\t\t\twebMercatorSelected,\n\t\t);\n\n\t\tconst webMercatorCursor = lngLatToWebMercatorXY(event.lng, event.lat);\n\n\t\tthis.scaleWebMercator({\n\t\t\tclosestBBoxIndex,\n\t\t\tupdatedCoords,\n\t\t\twebMercatorCursor,\n\t\t\twebMercatorSelected,\n\t\t\twebMercatorOrigin,\n\t\t});\n\n\t\treturn updatedCoords;\n\t}\n\n\tprivate centerFixedWebMercatorDrag(event: TerraDrawMouseEvent) {\n\t\tconst featureData = this.getSelectedFeatureDataWebMercator();\n\t\tif (!featureData) {\n\t\t\treturn null;\n\t\t}\n\t\tconst { feature, boundingBox, updatedCoords, selectedCoordinate } =\n\t\t\tfeatureData;\n\n\t\tconst webMercatorOrigin = webMercatorCentroid(feature);\n\n\t\tif (!webMercatorOrigin) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst webMercatorSelected = lngLatToWebMercatorXY(\n\t\t\tselectedCoordinate[0],\n\t\t\tselectedCoordinate[1],\n\t\t);\n\n\t\tconst { closestBBoxIndex } = this.getIndexesWebMercator(\n\t\t\tboundingBox,\n\t\t\twebMercatorSelected,\n\t\t);\n\n\t\tconst webMercatorCursor = lngLatToWebMercatorXY(event.lng, event.lat);\n\n\t\tthis.scaleFixedWebMercator({\n\t\t\tclosestBBoxIndex,\n\t\t\tupdatedCoords,\n\t\t\twebMercatorCursor,\n\t\t\twebMercatorSelected,\n\t\t\twebMercatorOrigin,\n\t\t});\n\n\t\treturn updatedCoords;\n\t}\n\n\tprivate scaleFixedWebMercator({\n\t\tclosestBBoxIndex,\n\t\twebMercatorOrigin,\n\t\twebMercatorSelected,\n\t\twebMercatorCursor,\n\t\tupdatedCoords,\n\t}: {\n\t\tclosestBBoxIndex: BoundingBoxIndex;\n\t\tupdatedCoords: Position[];\n\t\twebMercatorCursor: CartesianPoint;\n\t\twebMercatorSelected: CartesianPoint;\n\t\twebMercatorOrigin: CartesianPoint;\n\t}) {\n\t\tconst cursorDistanceX = webMercatorOrigin.x - webMercatorCursor.x;\n\t\tconst cursorDistanceY = webMercatorOrigin.y - webMercatorCursor.y;\n\n\t\tconst valid = this.isValidDragWebMercator(\n\t\t\tclosestBBoxIndex,\n\t\t\tcursorDistanceX,\n\t\t\tcursorDistanceY,\n\t\t);\n\n\t\tif (!valid) {\n\t\t\treturn null;\n\t\t}\n\n\t\tlet scale =\n\t\t\tcartesianDistance(webMercatorOrigin, webMercatorCursor) /\n\t\t\tcartesianDistance(webMercatorOrigin, webMercatorSelected);\n\n\t\tif (scale < 0) {\n\t\t\tscale = this.minimumScale;\n\t\t}\n\n\t\ttransformScaleWebMercatorCoordinates({\n\t\t\tcoordinates: updatedCoords,\n\t\t\toriginX: webMercatorOrigin.x,\n\t\t\toriginY: webMercatorOrigin.y,\n\t\t\txScale: scale,\n\t\t\tyScale: scale,\n\t\t});\n\n\t\t// this.performWebMercatorScale(\n\t\t// \tupdatedCoords,\n\t\t// \twebMercatorOrigin.x,\n\t\t// \twebMercatorOrigin.y,\n\t\t// \tscale,\n\t\t// \tscale,\n\t\t// );\n\n\t\treturn updatedCoords;\n\t}\n\n\tprivate oppositeFixedWebMercatorDrag(event: TerraDrawMouseEvent) {\n\t\tconst featureData = this.getSelectedFeatureDataWebMercator();\n\t\tif (!featureData) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst { boundingBox, updatedCoords, selectedCoordinate } = featureData;\n\n\t\tconst webMercatorSelected = lngLatToWebMercatorXY(\n\t\t\tselectedCoordinate[0],\n\t\t\tselectedCoordinate[1],\n\t\t);\n\n\t\tconst { oppositeBboxIndex, closestBBoxIndex } = this.getIndexesWebMercator(\n\t\t\tboundingBox,\n\t\t\twebMercatorSelected,\n\t\t);\n\n\t\tconst webMercatorOrigin = {\n\t\t\tx: boundingBox[oppositeBboxIndex][0],\n\t\t\ty: boundingBox[oppositeBboxIndex][1],\n\t\t};\n\t\tconst webMercatorCursor = lngLatToWebMercatorXY(event.lng, event.lat);\n\n\t\tthis.scaleFixedWebMercator({\n\t\t\tclosestBBoxIndex,\n\t\t\tupdatedCoords,\n\t\t\twebMercatorCursor,\n\t\t\twebMercatorSelected,\n\t\t\twebMercatorOrigin,\n\t\t});\n\n\t\treturn updatedCoords;\n\t}\n\n\tprivate oppositeWebMercatorDrag(event: TerraDrawMouseEvent) {\n\t\tconst featureData = this.getSelectedFeatureDataWebMercator();\n\t\tif (!featureData) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst { boundingBox, updatedCoords, selectedCoordinate } = featureData;\n\n\t\tconst webMercatorSelected = lngLatToWebMercatorXY(\n\t\t\tselectedCoordinate[0],\n\t\t\tselectedCoordinate[1],\n\t\t);\n\n\t\tconst { oppositeBboxIndex, closestBBoxIndex } = this.getIndexesWebMercator(\n\t\t\tboundingBox,\n\t\t\twebMercatorSelected,\n\t\t);\n\n\t\tconst webMercatorOrigin = {\n\t\t\tx: boundingBox[oppositeBboxIndex][0],\n\t\t\ty: boundingBox[oppositeBboxIndex][1],\n\t\t};\n\t\tconst webMercatorCursor = lngLatToWebMercatorXY(event.lng, event.lat);\n\n\t\tthis.scaleWebMercator({\n\t\t\tclosestBBoxIndex,\n\t\t\tupdatedCoords,\n\t\t\twebMercatorCursor,\n\t\t\twebMercatorSelected,\n\t\t\twebMercatorOrigin,\n\t\t});\n\n\t\treturn updatedCoords;\n\t}\n\n\tprivate scaleWebMercator({\n\t\tclosestBBoxIndex,\n\t\twebMercatorOrigin,\n\t\twebMercatorSelected,\n\t\twebMercatorCursor,\n\t\tupdatedCoords,\n\t}: {\n\t\tclosestBBoxIndex: BoundingBoxIndex;\n\t\tupdatedCoords: Position[];\n\t\twebMercatorCursor: CartesianPoint;\n\t\twebMercatorSelected: CartesianPoint;\n\t\twebMercatorOrigin: CartesianPoint;\n\t}) {\n\t\tconst cursorDistanceX = webMercatorOrigin.x - webMercatorCursor.x;\n\t\tconst cursorDistanceY = webMercatorOrigin.y - webMercatorCursor.y;\n\n\t\tconst valid = this.isValidDragWebMercator(\n\t\t\tclosestBBoxIndex,\n\t\t\tcursorDistanceX,\n\t\t\tcursorDistanceY,\n\t\t);\n\n\t\tif (!valid) {\n\t\t\treturn null;\n\t\t}\n\n\t\tlet xScale = 1;\n\t\tif (\n\t\t\tcursorDistanceX !== 0 &&\n\t\t\tclosestBBoxIndex !== 1 &&\n\t\t\tclosestBBoxIndex !== 5\n\t\t) {\n\t\t\tconst currentDistanceX = webMercatorOrigin.x - webMercatorSelected.x;\n\t\t\txScale = 1 - (currentDistanceX - cursorDistanceX) / cursorDistanceX;\n\t\t}\n\n\t\tlet yScale = 1;\n\t\tif (\n\t\t\tcursorDistanceY !== 0 &&\n\t\t\tclosestBBoxIndex !== 3 &&\n\t\t\tclosestBBoxIndex !== 7\n\t\t) {\n\t\t\tconst currentDistanceY = webMercatorOrigin.y - webMercatorSelected.y;\n\t\t\tyScale = 1 - (currentDistanceY - cursorDistanceY) / cursorDistanceY;\n\t\t}\n\n\t\tif (!this.validateScale(xScale, yScale)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (xScale < 0) {\n\t\t\txScale = this.minimumScale;\n\t\t}\n\n\t\tif (yScale < 0) {\n\t\t\tyScale = this.minimumScale;\n\t\t}\n\n\t\tthis.performWebMercatorScale(\n\t\t\tupdatedCoords,\n\t\t\twebMercatorOrigin.x,\n\t\t\twebMercatorOrigin.y,\n\t\t\txScale,\n\t\t\tyScale,\n\t\t);\n\n\t\treturn updatedCoords;\n\t}\n\n\tprivate getFeature(id: FeatureId) {\n\t\tif (this.draggedCoordinate.id === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst geometry = this.readFeature.getGeometry(id);\n\n\t\t// Update the geometry of the dragged feature\n\t\tif (geometry.type !== \"Polygon\" && geometry.type !== \"LineString\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst feature = {\n\t\t\tid,\n\t\t\ttype: \"Feature\",\n\t\t\tgeometry,\n\t\t\tproperties: {},\n\t\t} as GeoJSONStoreFeatures<Polygon | LineString>;\n\n\t\treturn feature;\n\t}\n\n\tprivate getNormalisedCoordinates(geometry: Polygon | LineString) {\n\t\t// Coordinates are either polygon or linestring at this point\n\t\treturn geometry.type === \"Polygon\"\n\t\t\t? geometry.coordinates[0]\n\t\t\t: geometry.coordinates;\n\t}\n\n\tprivate validateScale(xScale: number, yScale: number) {\n\t\tconst validX = !isNaN(xScale) && yScale < Number.MAX_SAFE_INTEGER;\n\t\tconst validY = !isNaN(yScale) && yScale < Number.MAX_SAFE_INTEGER;\n\n\t\treturn validX && validY;\n\t}\n\n\tprivate performWebMercatorScale(\n\t\tcoordinates: Position[],\n\t\toriginX: number,\n\t\toriginY: number,\n\t\txScale: number,\n\t\tyScale: number,\n\t) {\n\t\tcoordinates.forEach((coordinate) => {\n\t\t\tconst { x, y } = lngLatToWebMercatorXY(coordinate[0], coordinate[1]);\n\n\t\t\tconst updatedX = originX + (x - originX) * xScale;\n\t\t\tconst updatedY = originY + (y - originY) * yScale;\n\n\t\t\tconst { lng, lat } = webMercatorXYToLngLat(updatedX, updatedY);\n\n\t\t\tcoordinate[0] = lng;\n\t\t\tcoordinate[1] = lat;\n\t\t});\n\t}\n\n\tprivate getBBoxWebMercator(coordinates: Position[]) {\n\t\tconst bbox: [number, number, number, number] = [\n\t\t\tInfinity,\n\t\t\tInfinity,\n\t\t\t-Infinity,\n\t\t\t-Infinity,\n\t\t];\n\n\t\t// Convert from [lng, lat] -> [x, y]\n\t\tcoordinates = coordinates.map((coord) => {\n\t\t\tconst { x, y } = lngLatToWebMercatorXY(coord[0], coord[1]);\n\t\t\treturn [x, y];\n\t\t});\n\n\t\tcoordinates.forEach(([x, y]) => {\n\t\t\tif (x < bbox[0]) {\n\t\t\t\tbbox[0] = x;\n\t\t\t}\n\n\t\t\tif (y < bbox[1]) {\n\t\t\t\tbbox[1] = y;\n\t\t\t}\n\n\t\t\tif (x > bbox[2]) {\n\t\t\t\tbbox[2] = x;\n\t\t\t}\n\n\t\t\tif (y > bbox[3]) {\n\t\t\t\tbbox[3] = y;\n\t\t\t}\n\t\t});\n\n\t\tconst [west, south, east, north] = bbox;\n\n\t\t//   Bounding box is represented as follows:\n\t\t//\n\t\t//   0    1    2\n\t\t//   *----*----*\n\t\t// \t |\t\t   |\n\t\t// 7 *\t\t   *  3\n\t\t//   |\t\t   |\n\t\t//   *----*----*\n\t\t// \t 6    5    4\n\t\t//\n\t\tconst topLeft = [west, north];\n\t\tconst topRight = [east, north];\n\t\tconst lowRight = [east, south];\n\t\tconst lowLeft = [west, south];\n\n\t\tconst midTop = [(west + east) / 2, north];\n\t\tconst midRight = [east, north + (south - north) / 2];\n\t\tconst midBottom = [(west + east) / 2, south];\n\t\tconst midLeft = [west, north + (south - north) / 2];\n\n\t\treturn [\n\t\t\ttopLeft, // 0\n\t\t\tmidTop, // 1\n\t\t\ttopRight, // 2\n\t\t\tmidRight, // 3\n\t\t\tlowRight, // 4\n\t\t\tmidBottom, // 5\n\t\t\tlowLeft, // 6\n\t\t\tmidLeft, // 7\n\t\t] as const;\n\t}\n\n\tprivate getIndexesWebMercator(\n\t\tboundingBox: BoundingBox,\n\t\tselectedXY: CartesianPoint,\n\t) {\n\t\tlet closestIndex: BoundingBoxIndex | undefined;\n\t\tlet closestDistance = Infinity;\n\n\t\tfor (let i = 0; i < boundingBox.length; i++) {\n\t\t\tconst distance = cartesianDistance(\n\t\t\t\t{ x: selectedXY.x, y: selectedXY.y },\n\t\t\t\t{ x: boundingBox[i][0], y: boundingBox[i][1] },\n\t\t\t);\n\n\t\t\tif (distance < closestDistance) {\n\t\t\t\tclosestIndex = i as BoundingBoxIndex;\n\t\t\t\tclosestDistance = distance;\n\t\t\t}\n\t\t}\n\n\t\tif (closestIndex === undefined) {\n\t\t\tthrow new Error(\"No closest coordinate found\");\n\t\t}\n\n\t\t// Depending on where what the origin is set to, we need to find the position to\n\t\t// scale from\n\t\tconst oppositeIndex = this.boundingBoxMaps[\"opposite\"][\n\t\t\tclosestIndex\n\t\t] as BoundingBoxIndex;\n\n\t\treturn {\n\t\t\toppositeBboxIndex: oppositeIndex,\n\t\t\tclosestBBoxIndex: closestIndex,\n\t\t} as const;\n\t}\n\n\t/**\n\t * @returns - true if the feature is being dragged (resized), false otherwise\n\t */\n\tpublic isDragging() {\n\t\treturn this.draggedCoordinate.id !== null;\n\t}\n\n\t/**\n\t * Starts the resizing of the feature\n\t * @param id - feature id of the feature that is being dragged\n\t * @param index - index of the coordinate that is being dragged\n\t * @returns - void\n\t */\n\tpublic startDragging(id: FeatureId, index: number) {\n\t\tthis.draggedCoordinate = {\n\t\t\tid,\n\t\t\tindex,\n\t\t};\n\t}\n\n\t/**\n\t * Stops the resizing of the feature\n\t * @returns - void\t *\n\t */\n\tpublic stopDragging() {\n\t\tthis.draggedCoordinate = {\n\t\t\tid: null,\n\t\t\tindex: -1,\n\t\t};\n\t}\n\n\t/**\n\t * Returns the index of the coordinate that is going to be dragged\n\t * @param event - cursor event\n\t * @param selectedId - feature id of the feature that is selected\n\t * @returns - the index to be dragged\n\t */\n\tpublic getDraggableIndex(\n\t\tevent: TerraDrawMouseEvent,\n\t\tselectedId: FeatureId,\n\t): number {\n\t\tconst geometry = this.readFeature.getGeometry(selectedId);\n\t\tconst closestCoordinate = this.getClosestCoordinate(event, geometry);\n\n\t\t// No coordinate was within the pointer distance\n\t\tif (closestCoordinate.index === -1) {\n\t\t\treturn -1;\n\t\t}\n\t\treturn closestCoordinate.index;\n\t}\n\n\t/**\n\t * Resizes the feature based on the cursor event\n\t * @param event - cursor event\n\t * @param resizeOption - the resize option, either \"center\" or \"opposite\"\n\t * @returns - true is resize was successful, false otherwise\n\t */\n\tpublic drag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tresizeOption: ResizeOptions,\n\t): boolean {\n\t\tif (!this.draggedCoordinate.id) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst feature = this.getFeature(this.draggedCoordinate.id);\n\t\tif (!feature) {\n\t\t\treturn false;\n\t\t}\n\n\t\tlet updatedCoords: Position[] | null = null;\n\n\t\tif (resizeOption === \"center\") {\n\t\t\tupdatedCoords = this.centerWebMercatorDrag(event);\n\t\t} else if (resizeOption === \"opposite\") {\n\t\t\tupdatedCoords = this.oppositeWebMercatorDrag(event);\n\t\t} else if (resizeOption === \"center-fixed\") {\n\t\t\tupdatedCoords = this.centerFixedWebMercatorDrag(event);\n\t\t} else if (resizeOption === \"opposite-fixed\") {\n\t\t\tupdatedCoords = this.oppositeFixedWebMercatorDrag(event);\n\t\t}\n\n\t\tif (!updatedCoords) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Ensure that coordinate precision is maintained\n\t\tfor (let i = 0; i < updatedCoords.length; i++) {\n\t\t\tconst coordinate = updatedCoords[i];\n\t\t\tcoordinate[0] = limitPrecision(coordinate[0], this.coordinatePrecision);\n\t\t\tcoordinate[1] = limitPrecision(coordinate[1], this.coordinatePrecision);\n\n\t\t\t// Ensure the coordinate we are about to update with is valid\n\t\t\tif (!coordinatePrecisionIsValid(coordinate, this.coordinatePrecision)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tconst featureId = feature.id as FeatureId;\n\n\t\tlet updated: GeoJSONStoreFeatures<Polygon | LineString> | null = null;\n\n\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\tupdated = this.mutateFeature.updatePolygon({\n\t\t\t\tfeatureId,\n\t\t\t\tcoordinateMutations: {\n\t\t\t\t\ttype: Mutations.Replace,\n\t\t\t\t\tcoordinates: [updatedCoords],\n\t\t\t\t},\n\t\t\t\tcontext: {\n\t\t\t\t\tupdateType: UpdateTypes.Provisional as const,\n\t\t\t\t},\n\t\t\t});\n\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\tupdated = this.mutateFeature.updateLineString({\n\t\t\t\tfeatureId,\n\t\t\t\tcoordinateMutations: {\n\t\t\t\t\ttype: Mutations.Replace,\n\t\t\t\t\tcoordinates: updatedCoords,\n\t\t\t\t},\n\t\t\t\tcontext: {\n\t\t\t\t\tupdateType: UpdateTypes.Provisional as const,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tif (!updated) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst featureCoordinates = updated.geometry.coordinates;\n\n\t\t// Perform the update to the midpoints and selection points\n\t\tthis.midPoints.updateAllInPlace({ featureCoordinates });\n\t\tthis.selectionPoints.updateAllInPlace({ featureCoordinates });\n\t\tthis.coordinatePoints.updateAllInPlace({ featureId, featureCoordinates });\n\n\t\treturn true;\n\t}\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawKeyboardEvent,\n\tSELECT_PROPERTIES,\n\tTerraDrawAdapterStyling,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tValidation,\n\tUpdateTypes,\n\tZ_INDEX,\n\tSnapping,\n\tUrlStyling,\n\tCOMMON_PROPERTIES,\n\tMARKER_URL_DEFAULT,\n\tFinishActions,\n} from \"../../common\";\nimport { LineString, Point, Polygon, Position } from \"geojson\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tModeUpdateOptions,\n\tTerraDrawBaseSelectMode,\n} from \"../base.mode\";\nimport { MidPointBehavior } from \"./behaviors/midpoint.behavior\";\nimport {\n\tSelectionPointBehavior,\n\tSelectionPointProperties,\n} from \"./behaviors/selection-point.behavior\";\nimport { FeatureAtPointerEventBehavior } from \"./behaviors/feature-at-pointer-event.behavior\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../click-bounding-box.behavior\";\nimport { DragFeatureBehavior } from \"./behaviors/drag-feature.behavior\";\nimport { DragCoordinateBehavior } from \"./behaviors/drag-coordinate.behavior\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { RotateFeatureBehavior } from \"./behaviors/rotate-feature.behavior\";\nimport { ScaleFeatureBehavior } from \"./behaviors/scale-feature.behavior\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tDragCoordinateResizeBehavior,\n\tResizeOptions,\n} from \"./behaviors/drag-coordinate-resize.behavior\";\nimport { CoordinatePointBehavior } from \"./behaviors/coordinate-point.behavior\";\nimport { CoordinateSnappingBehavior } from \"../coordinate-snapping.behavior\";\nimport { LineSnappingBehavior } from \"../line-snapping.behavior\";\nimport { MutateFeatureBehavior, Mutations } from \"../mutate-feature.behavior\";\nimport { ReadFeatureBehavior } from \"../read-feature.behavior\";\n\ntype TerraDrawSelectModeKeyEvents = {\n\tdeselect: KeyboardEvent[\"key\"] | null;\n\tdelete: KeyboardEvent[\"key\"] | null;\n\trotate: KeyboardEvent[\"key\"][] | null;\n\tscale: KeyboardEvent[\"key\"][] | null;\n};\n\nconst defaultKeyEvents = {\n\tdeselect: \"Escape\",\n\tdelete: \"Delete\",\n\trotate: [\"Control\", \"r\"],\n\tscale: [\"Control\", \"s\"],\n};\n\ntype ModeFlags = {\n\tfeature?: {\n\t\tvalidation?: Validation;\n\t\tdraggable?: boolean;\n\t\trotateable?: boolean;\n\t\tscaleable?: boolean;\n\t\tselfIntersectable?: boolean;\n\t\tcoordinates?: {\n\t\t\tsnappable?: boolean | Snapping;\n\t\t\tmidpoints?:\n\t\t\t\t| boolean\n\t\t\t\t| {\n\t\t\t\t\t\tdraggable?: boolean;\n\t\t\t\t  };\n\t\t\tdraggable?: boolean;\n\t\t\tresizable?: ResizeOptions;\n\t\t\tdeletable?: boolean;\n\t\t};\n\t};\n};\n\ntype SelectionStyling = {\n\t// Point\n\tselectedPointColor: HexColorStyling;\n\tselectedPointWidth: NumericStyling;\n\tselectedPointOpacity: NumericStyling;\n\tselectedPointOutlineColor: HexColorStyling;\n\tselectedPointOutlineWidth: NumericStyling;\n\tselectedPointOutlineOpacity: NumericStyling;\n\n\t// Marker\n\tselectedMarkerUrl: UrlStyling;\n\tselectedMarkerHeight: NumericStyling;\n\tselectedMarkerWidth: NumericStyling;\n\n\t// LineString\n\tselectedLineStringColor: HexColorStyling;\n\tselectedLineStringWidth: NumericStyling;\n\tselectedLineStringOpacity: NumericStyling;\n\n\t// Polygon\n\tselectedPolygonColor: HexColorStyling;\n\tselectedPolygonFillOpacity: NumericStyling;\n\tselectedPolygonOutlineColor: HexColorStyling;\n\tselectedPolygonOutlineOpacity: NumericStyling;\n\tselectedPolygonOutlineWidth: NumericStyling;\n\n\t// Selection Points (points at vertices of a polygon/linestring feature)\n\tselectionPointWidth: NumericStyling;\n\tselectionPointColor: HexColorStyling;\n\tselectionPointOpacity: NumericStyling;\n\tselectionPointOutlineColor: HexColorStyling;\n\tselectionPointOutlineWidth: NumericStyling;\n\tselectionPointOutlineOpacity: NumericStyling;\n\n\t// Mid points (points at mid point of a polygon/linestring feature)\n\tmidPointColor: HexColorStyling;\n\tmidPointOutlineColor: HexColorStyling;\n\tmidPointOpacity: NumericStyling;\n\tmidPointWidth: NumericStyling;\n\tmidPointOutlineWidth: NumericStyling;\n\tmidPointOutlineOpacity: NumericStyling;\n};\n\ninterface Cursors {\n\tpointerOver?: Cursor;\n\tdragStart?: Cursor;\n\tdragEnd?: Cursor;\n\tinsertMidpoint?: Cursor;\n}\n\nconst defaultCursors = {\n\tpointerOver: \"move\",\n\tdragStart: \"move\",\n\tdragEnd: \"move\",\n\tinsertMidpoint: \"crosshair\",\n} as Required<Cursors>;\n\ninterface TerraDrawSelectModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tpointerDistance?: number;\n\tflags?: { [mode: string]: ModeFlags };\n\tkeyEvents?: TerraDrawSelectModeKeyEvents | null;\n\tdragEventThrottle?: number;\n\tcursors?: Cursors;\n\tallowManualDeselection?: boolean;\n}\n\nexport class TerraDrawSelectMode extends TerraDrawBaseSelectMode<SelectionStyling> {\n\tpublic mode = \"select\";\n\n\tprivate allowManualDeselection = true;\n\tprivate dragEventThrottle = 5;\n\tprivate dragEventCount = 0;\n\tprivate selected: FeatureId[] = [];\n\n\tprivate flags: { [mode: string]: ModeFlags } = {};\n\tprivate keyEvents: TerraDrawSelectModeKeyEvents = defaultKeyEvents;\n\tprivate cursors: Required<Cursors> = defaultCursors;\n\tprivate validations: Record<string, Validation> = {};\n\n\tprivate dragTarget:\n\t\t| { type: \"none\" }\n\t\t| { type: \"feature\"; featureId: FeatureId }\n\t\t| { type: \"coordinate\"; featureId: FeatureId; coordinateIndex: number }\n\t\t| { type: \"resize\"; featureId: FeatureId; coordinateIndex: number }\n\t\t| { type: \"midpoint\"; featureId: FeatureId; midPointId: FeatureId } = {\n\t\ttype: \"none\",\n\t};\n\n\t// Behaviors\n\tprivate selectionPoints!: SelectionPointBehavior;\n\tprivate midPoints!: MidPointBehavior;\n\tprivate coordinateSnap!: CoordinateSnappingBehavior;\n\tprivate featuresAtMouseEvent!: FeatureAtPointerEventBehavior;\n\tprivate pixelDistance!: PixelDistanceBehavior;\n\tprivate clickBoundingBox!: ClickBoundingBoxBehavior;\n\tprivate dragFeature!: DragFeatureBehavior;\n\tprivate dragCoordinate!: DragCoordinateBehavior;\n\tprivate rotateFeature!: RotateFeatureBehavior;\n\tprivate scaleFeature!: ScaleFeatureBehavior;\n\tprivate dragCoordinateResizeFeature!: DragCoordinateResizeBehavior;\n\tprivate coordinatePoints!: CoordinatePointBehavior;\n\tprivate lineSnap!: LineSnappingBehavior;\n\tprivate mutateFeature!: MutateFeatureBehavior;\n\tprivate readFeature!: ReadFeatureBehavior;\n\n\tconstructor(options?: TerraDrawSelectModeOptions<SelectionStyling>) {\n\t\tsuper(options, true);\n\t\tthis.updateOptions(options);\n\t}\n\n\toverride updateOptions(\n\t\toptions?: ModeUpdateOptions<TerraDrawSelectModeOptions<SelectionStyling>>,\n\t) {\n\t\tsuper.updateOptions(options);\n\n\t\tif (options && options.cursors) {\n\t\t\tthis.cursors = { ...this.cursors, ...options.cursors };\n\t\t} else {\n\t\t\tthis.cursors = defaultCursors;\n\t\t}\n\n\t\t// We want to have some defaults, but also allow key bindings\n\t\t// to be explicitly turned off\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = {\n\t\t\t\tdeselect: null,\n\t\t\t\tdelete: null,\n\t\t\t\trotate: null,\n\t\t\t\tscale: null,\n\t\t\t};\n\t\t} else if (options?.keyEvents) {\n\t\t\tthis.keyEvents = { ...this.keyEvents, ...options.keyEvents };\n\t\t}\n\n\t\tif (options?.dragEventThrottle !== undefined) {\n\t\t\tthis.dragEventThrottle = options.dragEventThrottle;\n\t\t}\n\n\t\tif (options?.allowManualDeselection !== undefined) {\n\t\t\tthis.allowManualDeselection = options.allowManualDeselection;\n\t\t}\n\n\t\t// Flags and Validations\n\t\tif (options?.flags) {\n\t\t\tthis.flags = { ...this.flags, ...options.flags };\n\t\t\tthis.validations = {};\n\n\t\t\tfor (const mode in this.flags) {\n\t\t\t\tconst feature = this.flags[mode].feature;\n\t\t\t\tif (feature && feature.validation) {\n\t\t\t\t\tthis.validations[mode] = feature.validation;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tselectFeature(featureId: FeatureId) {\n\t\tthis.select(featureId, false);\n\t}\n\n\tsetSelecting() {\n\t\tif (this._state === \"started\") {\n\t\t\tthis._state = \"selecting\";\n\t\t} else {\n\t\t\tthrow new Error(\"Mode must be started to move to selecting state\");\n\t\t}\n\t}\n\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.readFeature = new ReadFeatureBehavior(config);\n\t\tthis.mutateFeature = new MutateFeatureBehavior(config, {\n\t\t\tvalidate: (feature, context) => {\n\t\t\t\tconst mode = feature.properties.mode as string;\n\n\t\t\t\t// By default all changes are valid\n\t\t\t\tif (!this.validations || !this.validations[mode]) {\n\t\t\t\t\treturn { valid: true };\n\t\t\t\t}\n\n\t\t\t\treturn this.validations[mode](feature, context);\n\t\t\t},\n\t\t});\n\n\t\tthis.pixelDistance = new PixelDistanceBehavior(config);\n\t\tthis.clickBoundingBox = new ClickBoundingBoxBehavior(config);\n\t\tthis.featuresAtMouseEvent = new FeatureAtPointerEventBehavior(\n\t\t\tconfig,\n\t\t\tthis.clickBoundingBox,\n\t\t\tthis.pixelDistance,\n\t\t);\n\n\t\tthis.selectionPoints = new SelectionPointBehavior(\n\t\t\tconfig,\n\t\t\tthis.mutateFeature,\n\t\t);\n\t\tthis.coordinatePoints = new CoordinatePointBehavior(\n\t\t\tconfig,\n\t\t\tthis.readFeature,\n\t\t\tthis.mutateFeature,\n\t\t);\n\t\tthis.midPoints = new MidPointBehavior(\n\t\t\tconfig,\n\t\t\tthis.selectionPoints,\n\t\t\tthis.coordinatePoints,\n\t\t\tthis.mutateFeature,\n\t\t\tthis.readFeature,\n\t\t\tthis.pixelDistance,\n\t\t);\n\t\tthis.coordinateSnap = new CoordinateSnappingBehavior(\n\t\t\tconfig,\n\t\t\tthis.pixelDistance,\n\t\t\tthis.clickBoundingBox,\n\t\t);\n\t\tthis.lineSnap = new LineSnappingBehavior(\n\t\t\tconfig,\n\t\t\tthis.pixelDistance,\n\t\t\tthis.clickBoundingBox,\n\t\t);\n\t\tthis.rotateFeature = new RotateFeatureBehavior(\n\t\t\tconfig,\n\t\t\tthis.selectionPoints,\n\t\t\tthis.midPoints,\n\t\t\tthis.coordinatePoints,\n\t\t\tthis.readFeature,\n\t\t\tthis.mutateFeature,\n\t\t);\n\n\t\tthis.dragFeature = new DragFeatureBehavior(\n\t\t\tconfig,\n\t\t\tthis.featuresAtMouseEvent,\n\t\t\tthis.selectionPoints,\n\t\t\tthis.midPoints,\n\t\t\tthis.coordinatePoints,\n\t\t\tthis.readFeature,\n\t\t\tthis.mutateFeature,\n\t\t);\n\t\tthis.dragCoordinate = new DragCoordinateBehavior(\n\t\t\tconfig,\n\t\t\tthis.pixelDistance,\n\t\t\tthis.selectionPoints,\n\t\t\tthis.midPoints,\n\t\t\tthis.coordinatePoints,\n\t\t\tthis.coordinateSnap,\n\t\t\tthis.lineSnap,\n\t\t\tthis.readFeature,\n\t\t\tthis.mutateFeature,\n\t\t);\n\t\tthis.dragCoordinateResizeFeature = new DragCoordinateResizeBehavior(\n\t\t\tconfig,\n\t\t\tthis.pixelDistance,\n\t\t\tthis.selectionPoints,\n\t\t\tthis.midPoints,\n\t\t\tthis.coordinatePoints,\n\t\t\tthis.readFeature,\n\t\t\tthis.mutateFeature,\n\t\t);\n\t\tthis.scaleFeature = new ScaleFeatureBehavior(\n\t\t\tconfig,\n\t\t\tthis.dragCoordinateResizeFeature,\n\t\t);\n\t}\n\n\tpublic deselectFeature(id: FeatureId) {\n\t\tthis.deselect(id);\n\t}\n\n\tprivate deselect(id: FeatureId) {\n\t\tif (!this.selected.includes(id)) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.mutateFeature.setDeselected(this.selected);\n\n\t\tthis.onDeselect(this.selected[0]);\n\t\tthis.selected = [];\n\t\tthis.selectionPoints.delete();\n\t\tthis.midPoints.delete();\n\t\tthis.dragTarget = { type: \"none\" };\n\t}\n\n\tprivate deleteSelected() {\n\t\t// Delete all selected features\n\t\t// from the store and clear selected\n\t\t// We don't need to set selected false\n\t\t// as we're going to delete the feature\n\n\t\tif (this.selected.length) {\n\t\t\tthis.mutateFeature.deleteFeaturesIfPresent(this.selected);\n\t\t}\n\n\t\tthis.selected = [];\n\t\tthis.dragTarget = { type: \"none\" };\n\t}\n\n\tprivate clearDragTargetAndCursor() {\n\t\tthis.dragTarget = { type: \"none\" };\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\tprivate getSelectedFlags(featureId: FeatureId) {\n\t\tconst properties = this.readFeature.getProperties(featureId);\n\t\tconst modeFlags = this.flags[properties.mode as string];\n\n\t\tconst featureFlags = modeFlags?.feature;\n\n\t\tconst coordinatesFlags = featureFlags?.coordinates;\n\t\tconst midpointsDraggable =\n\t\t\ttypeof coordinatesFlags?.midpoints === \"object\" &&\n\t\t\tcoordinatesFlags.midpoints.draggable;\n\n\t\tconst hasDraggableFlags =\n\t\t\tfeatureFlags &&\n\t\t\t(featureFlags.draggable ||\n\t\t\t\tcoordinatesFlags?.draggable ||\n\t\t\t\tcoordinatesFlags?.resizable ||\n\t\t\t\tmidpointsDraggable);\n\n\t\treturn {\n\t\t\tfeatureFlags,\n\t\t\tcoordinatesFlags,\n\t\t\thasDraggableFlags,\n\t\t};\n\t}\n\n\tprivate onRightClick(event: TerraDrawMouseEvent) {\n\t\tif (!this.selectionPoints.ids.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet clickedSelectionPointProps: SelectionPointProperties | undefined;\n\n\t\tlet clickedFeatureDistance = Infinity;\n\n\t\tthis.selectionPoints.ids.forEach((id) => {\n\t\t\tconst geometry = this.readFeature.getGeometry<Point>(id);\n\t\t\tconst distance = this.pixelDistance.measure(event, geometry.coordinates);\n\n\t\t\tif (\n\t\t\t\tdistance < this.pointerDistance &&\n\t\t\t\tdistance < clickedFeatureDistance\n\t\t\t) {\n\t\t\t\tclickedFeatureDistance = distance;\n\t\t\t\tclickedSelectionPointProps = this.readFeature.getProperties(\n\t\t\t\t\tid,\n\t\t\t\t) as SelectionPointProperties;\n\t\t\t}\n\t\t});\n\n\t\tif (!clickedSelectionPointProps) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst featureId = clickedSelectionPointProps.selectionPointFeatureId;\n\t\tconst coordinateIndex = clickedSelectionPointProps.index;\n\n\t\t// We allow for preventing deleting coordinates via flags\n\t\tconst properties = this.readFeature.getProperties(featureId);\n\t\tconst modeFlags = this.flags[properties.mode as string];\n\n\t\t// Check if we can actually delete the coordinate\n\t\tconst cannotDelete =\n\t\t\t!modeFlags ||\n\t\t\t!modeFlags.feature ||\n\t\t\t!modeFlags.feature.coordinates ||\n\t\t\t!modeFlags.feature.coordinates.deletable;\n\n\t\tif (cannotDelete) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst geometry = this.readFeature.getGeometry(featureId);\n\n\t\tlet coordinates: Position[];\n\t\tif (geometry.type === \"Polygon\") {\n\t\t\tcoordinates = geometry.coordinates[0];\n\n\t\t\t// Prevent creating an invalid polygon\n\t\t\tif (coordinates.length <= 4) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else if (geometry.type === \"LineString\") {\n\t\t\tcoordinates = geometry.coordinates;\n\n\t\t\t// Prevent creating an invalid linestring\n\t\t\tif (coordinates.length <= 2) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\tconst isFinalPolygonCoordinate =\n\t\t\tgeometry.type === \"Polygon\" &&\n\t\t\t(coordinateIndex === 0 || coordinateIndex === coordinates.length - 1);\n\n\t\tif (isFinalPolygonCoordinate) {\n\t\t\t// Deleting the final coordinate in a polygon breaks it\n\t\t\t// because GeoJSON expects a duplicate, so we need to fix\n\t\t\t// it by adding the new first coordinate to the end\n\t\t\tcoordinates.shift();\n\t\t\tcoordinates.pop();\n\t\t\tcoordinates.push([coordinates[0][0], coordinates[0][1]]);\n\t\t} else {\n\t\t\t// Remove coordinate from array\n\t\t\tcoordinates.splice(coordinateIndex, 1);\n\t\t}\n\n\t\tlet updated: GeoJSONStoreFeatures<Polygon | LineString> | null = null;\n\n\t\tif (geometry.type === \"Polygon\") {\n\t\t\tupdated = this.mutateFeature.updatePolygon({\n\t\t\t\tfeatureId,\n\t\t\t\tcoordinateMutations: {\n\t\t\t\t\ttype: Mutations.Replace,\n\t\t\t\t\tcoordinates: [coordinates],\n\t\t\t\t},\n\t\t\t\tcontext: {\n\t\t\t\t\tupdateType: UpdateTypes.Commit,\n\t\t\t\t},\n\t\t\t});\n\t\t} else if (geometry.type === \"LineString\") {\n\t\t\tupdated = this.mutateFeature.updateLineString({\n\t\t\t\tfeatureId,\n\t\t\t\tcoordinateMutations: {\n\t\t\t\t\ttype: Mutations.Replace,\n\t\t\t\t\tcoordinates: coordinates,\n\t\t\t\t},\n\t\t\t\tcontext: {\n\t\t\t\t\tupdateType: UpdateTypes.Commit,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst featureCoordinates = updated.geometry.coordinates;\n\n\t\tthis.mutateFeature.deleteFeaturesIfPresent([\n\t\t\t...this.midPoints.ids,\n\t\t\t...this.selectionPoints.ids,\n\t\t]);\n\n\t\tif (properties.coordinatePointIds) {\n\t\t\tthis.coordinatePoints.createOrUpdate({ featureId, featureCoordinates });\n\t\t}\n\n\t\tthis.selectionPoints.create({\n\t\t\tfeatureCoordinates,\n\t\t\tfeatureId,\n\t\t});\n\n\t\tif (\n\t\t\tmodeFlags &&\n\t\t\tmodeFlags.feature &&\n\t\t\tmodeFlags.feature.coordinates &&\n\t\t\tmodeFlags.feature.coordinates.midpoints\n\t\t) {\n\t\t\tthis.midPoints.create({ featureCoordinates, featureId });\n\t\t}\n\n\t\tthis.onFinish(featureId, {\n\t\t\taction: FinishActions.DeleteCoordinate,\n\t\t\tmode: this.mode,\n\t\t});\n\t}\n\n\tprivate select(featureId: FeatureId, fromCursor = true) {\n\t\tif (this.selected[0] === featureId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { mode } = this.readFeature.getProperties(featureId);\n\n\t\t// This will be undefined for points\n\t\tconst modeFlags = this.flags[mode as string];\n\n\t\t// If feature is not selectable then return\n\t\tif (!modeFlags || !modeFlags.feature) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst previouslySelectedId = this.selected[0];\n\n\t\t// If we have something currently selected\n\t\tif (previouslySelectedId) {\n\t\t\t// If it matches the current selected feature id, do nothing\n\t\t\tif (previouslySelectedId === featureId) {\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\t// If it's a different feature set selected\n\t\t\t\t// to false on previously selected feature\n\t\t\t\tthis.deselect(previouslySelectedId);\n\t\t\t}\n\t\t}\n\n\t\tif (fromCursor) {\n\t\t\tthis.setCursor(this.cursors.pointerOver);\n\t\t}\n\n\t\t// Select feature\n\t\tthis.selected = [featureId];\n\n\t\tthis.mutateFeature.setSelected(featureId);\n\n\t\tthis.onSelect(featureId);\n\n\t\t// Get the clicked feature\n\t\tconst { type, coordinates: featureCoordinates } =\n\t\t\tthis.readFeature.getGeometry(featureId);\n\n\t\tif (type !== \"LineString\" && type !== \"Polygon\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (featureCoordinates && modeFlags && modeFlags.feature.coordinates) {\n\t\t\tthis.selectionPoints.create({\n\t\t\t\tfeatureCoordinates,\n\t\t\t\tfeatureId,\n\t\t\t});\n\n\t\t\tif (modeFlags.feature.coordinates.midpoints) {\n\t\t\t\tthis.midPoints.create({\n\t\t\t\t\tfeatureCoordinates,\n\t\t\t\t\tfeatureId,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate onLeftClick(event: TerraDrawMouseEvent) {\n\t\tconst { clickedFeature } = this.featuresAtMouseEvent.find(\n\t\t\tevent,\n\t\t\tthis.selected.length > 0,\n\t\t);\n\n\t\tconst midPointClicked = this.midPoints.getNearestMidPoint(event);\n\n\t\tconst selectedId = this.selected[0];\n\n\t\tif (selectedId) {\n\t\t\tconst { featureFlags } = this.getSelectedFlags(selectedId);\n\n\t\t\tif (featureFlags?.coordinates?.midpoints && midPointClicked) {\n\t\t\t\t// If coordinates are draggable we want to check if the click is closer to a coordinate than the midpoint,\n\t\t\t\t// if it is we don't want to trigger the midpoint drag\n\t\t\t\tif (featureFlags.coordinates.draggable) {\n\t\t\t\t\tconst closestMidPointDistance = this.pixelDistance.measure(\n\t\t\t\t\t\tevent,\n\t\t\t\t\t\tthis.readFeature.getGeometry<Point>(midPointClicked).coordinates,\n\t\t\t\t\t);\n\t\t\t\t\tconst { dist: dragCoordinateDistance } =\n\t\t\t\t\t\tthis.dragCoordinate.getDraggable(event, selectedId);\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tdragCoordinateDistance !== undefined &&\n\t\t\t\t\t\tclosestMidPointDistance > dragCoordinateDistance\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.midPoints.insert({\n\t\t\t\t\tfeatureId: selectedId,\n\t\t\t\t\tmidPointId: midPointClicked as FeatureId,\n\t\t\t\t});\n\n\t\t\t\tthis.onFinish(this.selected[0], {\n\t\t\t\t\taction: FinishActions.InsertMidpoint,\n\t\t\t\t\tmode: this.mode,\n\t\t\t\t});\n\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (clickedFeature?.id) {\n\t\t\tthis.select(clickedFeature.id, true);\n\t\t} else if (this.selected.length && this.allowManualDeselection) {\n\t\t\tthis.deselect(this.selected[0]);\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setSelecting();\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStarted();\n\t\tthis.setStopped();\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\tif (\n\t\t\t(event.button === \"right\" &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.rightClick, event)) ||\n\t\t\t(event.isContextMenu &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.contextMenu, event))\n\t\t) {\n\t\t\tthis.onRightClick(event);\n\t\t} else if (\n\t\t\tevent.button === \"left\" &&\n\t\t\tthis.allowPointerEvent(this.pointerEvents.leftClick, event)\n\t\t) {\n\t\t\tthis.onLeftClick(event);\n\t\t}\n\t}\n\n\tprivate canScale(event: TerraDrawKeyboardEvent | TerraDrawMouseEvent) {\n\t\treturn (\n\t\t\tthis.keyEvents.scale &&\n\t\t\tthis.keyEvents.scale.every((key) => event.heldKeys.includes(key))\n\t\t);\n\t}\n\n\tprivate canRotate(event: TerraDrawKeyboardEvent | TerraDrawMouseEvent) {\n\t\treturn (\n\t\t\tthis.keyEvents.rotate &&\n\t\t\tthis.keyEvents.rotate.every((key) => event.heldKeys.includes(key))\n\t\t);\n\t}\n\n\tprivate preventDefaultKeyEvent(event: TerraDrawKeyboardEvent) {\n\t\tconst isRotationKeys = this.canRotate(event);\n\t\tconst isScaleKeys = this.canScale(event);\n\n\t\t// If we are deliberately rotating or scaling then prevent default\n\t\tif (isRotationKeys || isScaleKeys) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyDown(event: TerraDrawKeyboardEvent) {\n\t\tthis.preventDefaultKeyEvent(event);\n\t}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tthis.preventDefaultKeyEvent(event);\n\n\t\tif (this.keyEvents.delete && event.key === this.keyEvents.delete) {\n\t\t\tif (!this.selected.length) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst selectedId = this.selected[0];\n\n\t\t\t// We are technically deselecting\n\t\t\t// because the selected feature is deleted\n\t\t\t// and will no longer exist or be selected\n\t\t\tconst previouslySelected = this.selected[0];\n\t\t\tthis.onDeselect(previouslySelected);\n\n\t\t\t// Delete coordinate point first if they are present, this needs\n\t\t\t// to be done before deleting the feature\n\t\t\tthis.coordinatePoints.deletePointsByFeatureIds([selectedId]);\n\n\t\t\t// Delete all selected features\n\t\t\tthis.deleteSelected();\n\n\t\t\t// Remove all selection points\n\t\t\tthis.selectionPoints.delete();\n\t\t\tthis.midPoints.delete();\n\t\t} else if (\n\t\t\tthis.keyEvents.deselect &&\n\t\t\tevent.key === this.keyEvents.deselect\n\t\t) {\n\t\t\tthis.cleanUp();\n\t\t}\n\t}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tif (this.selected.length) {\n\t\t\tthis.deselect(this.selected[0]);\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDragStart(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (!this.allowPointerEvent(this.pointerEvents.onDragStart, event)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We only need to stop the map dragging if\n\t\t// we actually have something selected\n\t\tconst selectedId = this.selected[0];\n\t\tif (!selectedId) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If the selected feature is not draggable\n\t\t// don't do anything\n\t\tconst { featureFlags, coordinatesFlags, hasDraggableFlags } =\n\t\t\tthis.getSelectedFlags(selectedId);\n\n\t\tif (!hasDraggableFlags) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.dragEventCount = 0;\n\n\t\tconst pointerOverTarget =\n\t\t\tthis.dragTarget.type !== \"none\" &&\n\t\t\tthis.dragTarget.featureId === selectedId\n\t\t\t\t? this.dragTarget\n\t\t\t\t: { type: \"none\" as const };\n\n\t\tconst draggableCoordinateIndex =\n\t\t\tpointerOverTarget.type === \"coordinate\"\n\t\t\t\t? pointerOverTarget.coordinateIndex\n\t\t\t\t: this.dragCoordinate.getDraggableIndex(event, selectedId);\n\n\t\tconst resizableCoordinateIndex =\n\t\t\tpointerOverTarget.type === \"resize\"\n\t\t\t\t? pointerOverTarget.coordinateIndex\n\t\t\t\t: this.dragCoordinateResizeFeature.getDraggableIndex(event, selectedId);\n\n\t\tconst resizableCoordinate =\n\t\t\tcoordinatesFlags?.resizable && resizableCoordinateIndex !== -1;\n\n\t\tconst draggableCoordinate =\n\t\t\tcoordinatesFlags?.draggable && draggableCoordinateIndex !== -1;\n\n\t\tconst draggableMidPoint =\n\t\t\tcoordinatesFlags &&\n\t\t\ttypeof coordinatesFlags.midpoints === \"object\" &&\n\t\t\tcoordinatesFlags.midpoints.draggable;\n\n\t\tconst draggableFeature =\n\t\t\tfeatureFlags?.draggable &&\n\t\t\t(pointerOverTarget.type === \"feature\" ||\n\t\t\t\tthis.dragFeature.canDrag(event, selectedId));\n\n\t\t// Resize Coordinate\n\t\tif (resizableCoordinate) {\n\t\t\tthis.setCursor(this.cursors.dragStart);\n\n\t\t\tthis.dragCoordinateResizeFeature.startDragging(\n\t\t\t\tselectedId,\n\t\t\t\tresizableCoordinateIndex,\n\t\t\t);\n\n\t\t\tsetMapDraggability(false);\n\t\t\treturn;\n\t\t}\n\n\t\t// Drag Coordinate\n\t\tif (draggableCoordinate) {\n\t\t\tthis.setCursor(this.cursors.dragStart);\n\n\t\t\tthis.dragCoordinate.startDragging(selectedId, draggableCoordinateIndex);\n\n\t\t\tsetMapDraggability(false);\n\t\t\treturn;\n\t\t}\n\n\t\t// Dragging Midpoint\n\t\tif (draggableMidPoint) {\n\t\t\tconst draggedMidPointId =\n\t\t\t\tpointerOverTarget.type === \"midpoint\"\n\t\t\t\t\t? pointerOverTarget.midPointId\n\t\t\t\t\t: this.midPoints.getNearestMidPoint(event);\n\n\t\t\tif (this.selected.length && draggedMidPointId) {\n\t\t\t\t// We insert the midpoint first\n\t\t\t\tthis.midPoints.insert({\n\t\t\t\t\tfeatureId: selectedId,\n\t\t\t\t\tmidPointId: draggedMidPointId,\n\t\t\t\t});\n\n\t\t\t\tthis.onFinish(this.selected[0], {\n\t\t\t\t\taction: FinishActions.InsertMidpoint,\n\t\t\t\t\tmode: this.mode,\n\t\t\t\t});\n\n\t\t\t\tconst draggableCoordinateIndexAfterInsert =\n\t\t\t\t\tthis.dragCoordinate.getDraggableIndex(event, selectedId);\n\n\t\t\t\tthis.dragCoordinate.startDragging(\n\t\t\t\t\tselectedId,\n\t\t\t\t\tdraggableCoordinateIndexAfterInsert,\n\t\t\t\t);\n\n\t\t\t\tsetMapDraggability(false);\n\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Drag Feature\n\t\tif (draggableFeature) {\n\t\t\tthis.setCursor(this.cursors.dragStart);\n\t\t\tthis.dragFeature.startDragging(event, selectedId);\n\t\t\tsetMapDraggability(false);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonDrag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (!this.allowPointerEvent(this.pointerEvents.onDrag, event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst selectedId = this.selected[0];\n\n\t\t// If nothing selected we can return early\n\t\tif (!selectedId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst properties = this.readFeature.getProperties(selectedId);\n\t\tconst modeFlags = this.flags[properties.mode as string];\n\t\tconst canSelfIntersect: boolean =\n\t\t\t(modeFlags &&\n\t\t\t\tmodeFlags.feature &&\n\t\t\t\tmodeFlags.feature.selfIntersectable) === true;\n\n\t\t// Ensure drag count is incremented\n\t\tthis.dragEventCount++;\n\n\t\t// Return if we haven't hit the drag throttle limit\n\t\t// (i.e. we only want to drag every nth event)\n\t\tif (this.dragEventCount % this.dragEventThrottle === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if should rotate\n\t\tif (\n\t\t\tmodeFlags &&\n\t\t\tmodeFlags.feature &&\n\t\t\tmodeFlags.feature.rotateable &&\n\t\t\tthis.canRotate(event)\n\t\t) {\n\t\t\tsetMapDraggability(false);\n\t\t\tthis.rotateFeature.rotate(event, selectedId);\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if should scale\n\t\tif (\n\t\t\tmodeFlags &&\n\t\t\tmodeFlags.feature &&\n\t\t\tmodeFlags.feature.scaleable &&\n\t\t\tthis.canScale(event)\n\t\t) {\n\t\t\tsetMapDraggability(false);\n\n\t\t\tthis.scaleFeature.scale(event, selectedId);\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\tthis.dragCoordinateResizeFeature.isDragging() &&\n\t\t\tmodeFlags.feature &&\n\t\t\tmodeFlags.feature.coordinates &&\n\t\t\tmodeFlags.feature.coordinates.resizable\n\t\t) {\n\t\t\tif (this.projection === \"globe\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Globe is currently unsupported projection for resizable\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tsetMapDraggability(false);\n\t\t\tthis.dragCoordinateResizeFeature.drag(\n\t\t\t\tevent,\n\t\t\t\tmodeFlags.feature.coordinates.resizable,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if coordinate is draggable and is dragged\n\t\tif (this.dragCoordinate.isDragging()) {\n\t\t\tconst snappable = modeFlags.feature?.coordinates?.snappable;\n\n\t\t\tlet snapOptions: Snapping = { toCoordinate: false };\n\t\t\tif (snappable === true) {\n\t\t\t\tsnapOptions = { toCoordinate: true };\n\t\t\t} else if (typeof snappable === \"object\") {\n\t\t\t\tsnapOptions = snappable;\n\t\t\t}\n\n\t\t\tthis.dragCoordinate.drag(event, canSelfIntersect, snapOptions);\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if feature is draggable and is dragged\n\t\tif (this.dragFeature.isDragging()) {\n\t\t\tthis.dragFeature.drag(event);\n\t\t\treturn;\n\t\t}\n\n\t\tsetMapDraggability(true);\n\t}\n\n\t/** @internal */\n\tonDragEnd(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (!this.allowPointerEvent(this.pointerEvents.onDragEnd, event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.setCursor(this.cursors.dragEnd);\n\n\t\t// If we have finished dragging a coordinate or a feature\n\t\t// lets fire an onFinish event which can be listened to\n\t\tif (this.dragCoordinate.isDragging()) {\n\t\t\tthis.onFinish(this.selected[0], {\n\t\t\t\tmode: this.mode,\n\t\t\t\taction: FinishActions.DragCoordinate,\n\t\t\t});\n\t\t} else if (this.dragFeature.isDragging()) {\n\t\t\tthis.onFinish(this.selected[0], {\n\t\t\t\tmode: this.mode,\n\t\t\t\taction: FinishActions.DragFeature,\n\t\t\t});\n\t\t} else if (this.dragCoordinateResizeFeature.isDragging()) {\n\t\t\tthis.onFinish(this.selected[0], {\n\t\t\t\tmode: this.mode,\n\t\t\t\taction: FinishActions.DragCoordinateResize,\n\t\t\t});\n\t\t}\n\n\t\tthis.dragCoordinate.stopDragging();\n\t\tthis.dragFeature.stopDragging();\n\t\tthis.dragCoordinateResizeFeature.stopDragging();\n\t\tthis.rotateFeature.reset();\n\t\tthis.scaleFeature.reset();\n\t\tsetMapDraggability(true);\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tconst selectedId = this.selected[0];\n\t\tif (!selectedId) {\n\t\t\tthis.clearDragTargetAndCursor();\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\tthis.dragFeature.isDragging() ||\n\t\t\tthis.dragCoordinate.isDragging() ||\n\t\t\tthis.dragCoordinateResizeFeature.isDragging()\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { featureFlags } = this.getSelectedFlags(selectedId);\n\t\tif (!featureFlags) {\n\t\t\tthis.clearDragTargetAndCursor();\n\t\t\treturn;\n\t\t}\n\n\t\tlet nearbyMidPoint: FeatureId | undefined = undefined;\n\t\tconst coordinatesFlags = featureFlags.coordinates;\n\n\t\tif (coordinatesFlags?.midpoints) {\n\t\t\tnearbyMidPoint = this.midPoints.getNearestMidPoint(event);\n\t\t\tif (nearbyMidPoint) {\n\t\t\t\tthis.dragTarget = {\n\t\t\t\t\ttype: \"midpoint\",\n\t\t\t\t\tfeatureId: selectedId,\n\t\t\t\t\tmidPointId: nearbyMidPoint,\n\t\t\t\t};\n\t\t\t\tthis.setCursor(this.cursors.insertMidpoint);\n\t\t\t\t// We don't return here because we want to check if a coordinate or resize handle is closer.\n\t\t\t\t// If it is, we want to give priority to dragging that target over inserting a midpoint.\n\t\t\t}\n\t\t}\n\n\t\tif (coordinatesFlags && coordinatesFlags.draggable) {\n\t\t\tconst { index, dist: closestDraggableCoordinateDistance } =\n\t\t\t\tthis.dragCoordinate.getDraggable(event, selectedId);\n\n\t\t\tif (index > -1) {\n\t\t\t\tif (nearbyMidPoint) {\n\t\t\t\t\tconst closestMidPointDistance = this.pixelDistance.measure(\n\t\t\t\t\t\tevent,\n\t\t\t\t\t\tthis.readFeature.getGeometry<Point>(nearbyMidPoint).coordinates,\n\t\t\t\t\t);\n\t\t\t\t\tif (closestMidPointDistance < closestDraggableCoordinateDistance) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.dragTarget = {\n\t\t\t\t\ttype: \"coordinate\",\n\t\t\t\t\tfeatureId: selectedId,\n\t\t\t\t\tcoordinateIndex: index,\n\t\t\t\t};\n\t\t\t\tthis.setCursor(this.cursors.pointerOver);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (coordinatesFlags && coordinatesFlags.resizable) {\n\t\t\tconst index = this.dragCoordinateResizeFeature.getDraggableIndex(\n\t\t\t\tevent,\n\t\t\t\tselectedId,\n\t\t\t);\n\t\t\tif (index > -1) {\n\t\t\t\tthis.dragTarget = {\n\t\t\t\t\ttype: \"resize\",\n\t\t\t\t\tfeatureId: selectedId,\n\t\t\t\t\tcoordinateIndex: index,\n\t\t\t\t};\n\t\t\t\tthis.setCursor(this.cursors.pointerOver);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (featureFlags.draggable && this.dragFeature.canDrag(event, selectedId)) {\n\t\t\tif (nearbyMidPoint) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.dragTarget = { type: \"feature\", featureId: selectedId };\n\t\t\tthis.setCursor(this.cursors.pointerOver);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!nearbyMidPoint) {\n\t\t\tthis.clearDragTargetAndCursor();\n\t\t}\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (\n\t\t\tfeature.properties.mode === this.mode &&\n\t\t\tfeature.geometry.type === \"Point\"\n\t\t) {\n\t\t\tif (feature.properties[SELECT_PROPERTIES.SELECTION_POINT]) {\n\t\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.selectionPointColor,\n\t\t\t\t\tstyles.pointColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectionPointOpacity,\n\t\t\t\t\t1,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.selectionPointOutlineColor,\n\t\t\t\t\tstyles.pointOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectionPointWidth,\n\t\t\t\t\tstyles.pointWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectionPointOutlineOpacity,\n\t\t\t\t\t1,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectionPointOutlineWidth,\n\t\t\t\t\t2,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = Z_INDEX.LAYER_THREE;\n\n\t\t\t\treturn styles;\n\t\t\t}\n\n\t\t\tif (feature.properties[SELECT_PROPERTIES.MID_POINT]) {\n\t\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.midPointColor,\n\t\t\t\t\tstyles.pointColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.midPointOpacity,\n\t\t\t\t\t1,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.midPointOutlineColor,\n\t\t\t\t\tstyles.pointOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.midPointWidth,\n\t\t\t\t\t4,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.midPointOutlineOpacity,\n\t\t\t\t\t1,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.midPointOutlineWidth,\n\t\t\t\t\t2,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = Z_INDEX.LAYER_FIVE;\n\n\t\t\t\treturn styles;\n\t\t\t}\n\t\t} else if (feature.properties[SELECT_PROPERTIES.SELECTED]) {\n\t\t\t// Select mode shortcuts the styling of a feature if it is selected\n\t\t\t// A selected feature from another mode will end up in this block\n\n\t\t\tif (\n\t\t\t\tfeature.geometry.type === \"Point\" &&\n\t\t\t\tfeature.properties[COMMON_PROPERTIES.MARKER]\n\t\t\t) {\n\t\t\t\tstyles.markerUrl = this.getUrlStylingValue(\n\t\t\t\t\tthis.styles.selectedMarkerUrl,\n\t\t\t\t\tMARKER_URL_DEFAULT,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\t\t\t\tstyles.markerHeight = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectedMarkerHeight,\n\t\t\t\t\t40,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\t\t\t\tstyles.markerWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectedMarkerWidth,\n\t\t\t\t\t32,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\t\t\t\treturn styles;\n\t\t\t} else if (feature.geometry.type === \"Polygon\") {\n\t\t\t\tstyles.polygonFillColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.selectedPolygonColor,\n\t\t\t\t\tstyles.polygonFillColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectedPolygonOutlineWidth,\n\t\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.selectedPolygonOutlineColor,\n\t\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectedPolygonOutlineOpacity,\n\t\t\t\t\t1,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonFillOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectedPolygonFillOpacity,\n\t\t\t\t\tstyles.polygonFillOpacity,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = Z_INDEX.LAYER_ONE;\n\t\t\t\treturn styles;\n\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\tstyles.lineStringColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.selectedLineStringColor,\n\t\t\t\t\tstyles.lineStringColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.lineStringWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectedLineStringWidth,\n\t\t\t\t\tstyles.lineStringWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = Z_INDEX.LAYER_ONE;\n\t\t\t\treturn styles;\n\t\t\t} else if (feature.geometry.type === \"Point\") {\n\t\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectedPointWidth,\n\t\t\t\t\tstyles.pointWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.selectedPointColor,\n\t\t\t\t\tstyles.pointColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectedPointOpacity,\n\t\t\t\t\t1,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.selectedPointOutlineColor,\n\t\t\t\t\tstyles.pointOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectedPointOutlineOpacity,\n\t\t\t\t\t1,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.selectedPointOutlineWidth,\n\t\t\t\t\tstyles.pointOutlineWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = Z_INDEX.LAYER_ONE;\n\t\t\t\treturn styles;\n\t\t\t}\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tafterFeatureUpdated(feature: GeoJSONStoreFeatures) {\n\t\t// If we have a selected feature and it has been updated\n\t\t// we need to update the selection points and midpoints\n\t\tif (this.selected.length && feature.id === this.selected[0]) {\n\t\t\tconst flags = this.flags[feature.properties.mode as string];\n\n\t\t\tif (!flags?.feature?.coordinates) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst type = feature.geometry.type;\n\t\t\tconst id = feature.id as FeatureId;\n\n\t\t\tthis.selectionPoints.delete();\n\t\t\tthis.midPoints.delete();\n\n\t\t\tif (type !== \"LineString\" && type !== \"Polygon\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst featureCoordinates = feature.geometry.coordinates;\n\n\t\t\tthis.selectionPoints.create({\n\t\t\t\tfeatureCoordinates,\n\t\t\t\tfeatureId: id,\n\t\t\t});\n\n\t\t\tif (flags?.feature?.coordinates?.midpoints) {\n\t\t\t\tthis.midPoints.create({\n\t\t\t\t\tfeatureCoordinates,\n\t\t\t\t\tfeatureId: id,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n}\n","import { TerraDrawAdapterStyling } from \"../../common\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport { ModeTypes, TerraDrawBaseDrawMode } from \"../base.mode\";\n\ntype StaticModeStylingExt<T extends TerraDrawAdapterStyling> = {};\ntype StaticModeStyling = StaticModeStylingExt<TerraDrawAdapterStyling>;\n\nexport class TerraDrawStaticMode extends TerraDrawBaseDrawMode<StaticModeStyling> {\n\ttype = ModeTypes.Static;\n\tmode = \"static\" as const;\n\tstart() {}\n\tstop() {}\n\tonKeyUp() {}\n\tonKeyDown() {}\n\tonClick() {}\n\tonDragStart() {}\n\tonDrag() {}\n\tonDragEnd() {}\n\tonMouseMove() {}\n\tcleanUp() {}\n\tstyleFeature() {\n\t\treturn { ...getDefaultStyling() };\n\t}\n}\n","// ISC License\n// Copyright (c) 2018, Vladimir Agafonkin\n\nexport type CompareFunction<T> = (a: T, b: T) => number;\n\nexport function quickselect<T>(\n\tarr: T[],\n\tk: number,\n\tleft: number,\n\tright: number,\n\tcompare: CompareFunction<T>,\n) {\n\twhile (right > left) {\n\t\tif (right - left > 600) {\n\t\t\tconst n = right - left + 1;\n\t\t\tconst m = k - left + 1;\n\t\t\tconst z = Math.log(n);\n\t\t\tconst s = 0.5 * Math.exp((2 * z) / 3);\n\t\t\tconst sd =\n\t\t\t\t0.5 * Math.sqrt((z * s * (n - s)) / n) * (m - n / 2 < 0 ? -1 : 1);\n\t\t\tconst newLeft = Math.max(left, Math.floor(k - (m * s) / n + sd));\n\t\t\tconst newRight = Math.min(right, Math.floor(k + ((n - m) * s) / n + sd));\n\t\t\tquickselect(arr, k, newLeft, newRight, compare);\n\t\t}\n\n\t\tconst t = arr[k];\n\t\tlet i = left;\n\t\tlet j = right;\n\n\t\tswap(arr, left, k);\n\t\tif (compare(arr[right], t) > 0) swap(arr, left, right);\n\n\t\twhile (i < j) {\n\t\t\tswap(arr, i, j);\n\t\t\ti++;\n\t\t\tj--;\n\t\t\twhile (compare(arr[i], t) < 0) i++;\n\t\t\twhile (compare(arr[j], t) > 0) j--;\n\t\t}\n\n\t\tif (compare(arr[left], t) === 0) {\n\t\t\tswap(arr, left, j);\n\t\t} else {\n\t\t\tj++;\n\t\t\tswap(arr, j, right);\n\t\t}\n\n\t\tif (j <= k) left = j + 1;\n\t\tif (k <= j) right = j - 1;\n\t}\n}\n\nfunction swap<T>(arr: T[], i: number, j: number) {\n\tconst tmp = arr[i];\n\tarr[i] = arr[j];\n\tarr[j] = tmp;\n}\n","// Base on Rbush - https://github.com/mourner/rbush\n// MIT License\n// Copyright (c) 2016 Vladimir Agafonkin\n\nimport { CompareFunction, quickselect } from \"./quickselect\";\n\nexport type Node = {\n\tchildren: Node[];\n\theight: number;\n\tleaf: boolean;\n\tminX: number;\n\tminY: number;\n\tmaxX: number;\n\tmaxY: number;\n};\n\n// calculate node's bbox from bboxes of its children\nfunction calcBBox(node: Node, toBBox: (node: Node) => any) {\n\tdistBBox(node, 0, node.children.length, toBBox, node);\n}\n\n// min bounding rectangle of node children from k to p-1\nfunction distBBox(\n\tnode: Node,\n\tk: number,\n\tp: number,\n\ttoBBox: (node: Node) => Node,\n\tdestNode?: Node,\n) {\n\tif (!destNode) destNode = createNode([]);\n\tdestNode.minX = Infinity;\n\tdestNode.minY = Infinity;\n\tdestNode.maxX = -Infinity;\n\tdestNode.maxY = -Infinity;\n\n\tfor (let i = k; i < p; i++) {\n\t\tconst child = node.children[i];\n\t\textend(destNode, node.leaf ? toBBox(child) : child);\n\t}\n\n\treturn destNode;\n}\n\nfunction extend(a: Node, b: Node) {\n\ta.minX = Math.min(a.minX, b.minX);\n\ta.minY = Math.min(a.minY, b.minY);\n\ta.maxX = Math.max(a.maxX, b.maxX);\n\ta.maxY = Math.max(a.maxY, b.maxY);\n\treturn a;\n}\n\nfunction compareNodeMinX(a: Node, b: Node) {\n\treturn a.minX - b.minX;\n}\nfunction compareNodeMinY(a: Node, b: Node) {\n\treturn a.minY - b.minY;\n}\n\nfunction bboxArea(a: Node) {\n\treturn (a.maxX - a.minX) * (a.maxY - a.minY);\n}\nfunction bboxMargin(a: {\n\tminX: number;\n\tminY: number;\n\tmaxX: number;\n\tmaxY: number;\n}) {\n\treturn a.maxX - a.minX + (a.maxY - a.minY);\n}\n\nfunction enlargedArea(a: Node, b: Node) {\n\treturn (\n\t\t(Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *\n\t\t(Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY))\n\t);\n}\n\nfunction intersectionArea(a: Node, b: Node) {\n\tconst minX = Math.max(a.minX, b.minX);\n\tconst minY = Math.max(a.minY, b.minY);\n\tconst maxX = Math.min(a.maxX, b.maxX);\n\tconst maxY = Math.min(a.maxY, b.maxY);\n\n\treturn Math.max(0, maxX - minX) * Math.max(0, maxY - minY);\n}\n\nfunction contains(a: Node, b: Node) {\n\treturn (\n\t\ta.minX <= b.minX && a.minY <= b.minY && b.maxX <= a.maxX && b.maxY <= a.maxY\n\t);\n}\n\nfunction intersects(a: Node, b: Node) {\n\treturn (\n\t\tb.minX <= a.maxX && b.minY <= a.maxY && b.maxX >= a.minX && b.maxY >= a.minY\n\t);\n}\n\nfunction createNode(children: Node[]) {\n\treturn {\n\t\tchildren,\n\t\theight: 1,\n\t\tleaf: true,\n\t\tminX: Infinity,\n\t\tminY: Infinity,\n\t\tmaxX: -Infinity,\n\t\tmaxY: -Infinity,\n\t};\n}\n\n// sort an array so that items come in groups of n unsorted items, with groups sorted between each other;\n// combines selection algorithm with binary divide & conquer approach\n\nfunction multiSelect<T>(\n\tarr: T[],\n\tleft: number,\n\tright: number,\n\tn: number,\n\tcompare: CompareFunction<T>,\n) {\n\tconst stack = [left, right];\n\n\twhile (stack.length) {\n\t\tright = stack.pop() as number;\n\t\tleft = stack.pop() as number;\n\n\t\tif (right - left <= n) continue;\n\n\t\tconst mid = left + Math.ceil((right - left) / n / 2) * n;\n\t\tquickselect(arr, mid, left, right, compare);\n\n\t\tstack.push(left, mid, mid, right);\n\t}\n}\n\nexport class RBush {\n\tprivate _maxEntries: number;\n\tprivate _minEntries: number;\n\tprivate data!: Node;\n\n\tconstructor(maxEntries: number) {\n\t\t// max entries in a node is 9 by default; min node fill is 40% for best performance\n\t\tthis._maxEntries = Math.max(4, maxEntries);\n\t\tthis._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));\n\t\tthis.clear();\n\t}\n\n\tsearch(bbox: Node): Node[] {\n\t\tlet node = this.data;\n\t\tconst result: Node[] = [];\n\n\t\tif (!intersects(bbox, node)) {\n\t\t\treturn result;\n\t\t}\n\n\t\tconst toBBox = this.toBBox;\n\t\tconst nodesToSearch = [];\n\n\t\twhile (node) {\n\t\t\tfor (let i = 0; i < node.children.length; i++) {\n\t\t\t\tconst child = node.children[i];\n\t\t\t\tconst childBBox = node.leaf ? toBBox(child) : child;\n\n\t\t\t\tif (intersects(bbox, childBBox)) {\n\t\t\t\t\tif (node.leaf) result.push(child);\n\t\t\t\t\telse if (contains(bbox, childBBox)) this._all(child, result);\n\t\t\t\t\telse nodesToSearch.push(child);\n\t\t\t\t}\n\t\t\t}\n\t\t\tnode = nodesToSearch.pop() as Node;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tcollides(bbox: Node) {\n\t\tlet node = this.data;\n\n\t\tconst intersect = intersects(bbox, node);\n\t\tif (intersect) {\n\t\t\tconst nodesToSearch = [];\n\t\t\twhile (node) {\n\t\t\t\tfor (let i = 0; i < node.children.length; i++) {\n\t\t\t\t\tconst child = node.children[i];\n\t\t\t\t\tconst childBBox = node.leaf ? this.toBBox(child) : child;\n\n\t\t\t\t\tif (intersects(bbox, childBBox)) {\n\t\t\t\t\t\tif (node.leaf || contains(bbox, childBBox)) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnodesToSearch.push(child);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnode = nodesToSearch.pop() as Node;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tload(data: Node[]): void {\n\t\tif (data.length < this._minEntries) {\n\t\t\tfor (let i = 0; i < data.length; i++) {\n\t\t\t\tthis.insert(data[i]);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// recursively build the tree with the given data from scratch using OMT algorithm\n\t\tlet node = this._build(data.slice(), 0, data.length - 1, 0);\n\n\t\tif (!this.data.children.length) {\n\t\t\t// save as is if tree is empty\n\t\t\tthis.data = node;\n\t\t} else if (this.data.height === node.height) {\n\t\t\t// split root if trees have the same height\n\t\t\tthis._splitRoot(this.data, node);\n\t\t} else {\n\t\t\tif (this.data.height < node.height) {\n\t\t\t\t// swap trees if inserted one is bigger\n\t\t\t\tconst tmpNode = this.data;\n\t\t\t\tthis.data = node;\n\t\t\t\tnode = tmpNode;\n\t\t\t}\n\n\t\t\t// insert the small tree into the large tree at appropriate level\n\t\t\tthis._insert(node, this.data.height - node.height - 1, true);\n\t\t}\n\t}\n\n\tinsert(item: Node): void {\n\t\tthis._insert(item, this.data.height - 1);\n\t}\n\n\tclear(): void {\n\t\tthis.data = createNode([]);\n\t}\n\n\tremove(item: Node): void {\n\t\tlet node: Node | null = this.data;\n\t\tconst bbox = this.toBBox(item);\n\t\tconst path = [];\n\t\tconst indexes: number[] = [];\n\t\tlet i: number | undefined;\n\t\tlet parent: Node | undefined;\n\t\tlet goingUp = false;\n\n\t\t// depth-first iterative tree traversal\n\t\twhile (node || path.length) {\n\t\t\tif (!node) {\n\t\t\t\t// go up\n\t\t\t\tnode = path.pop() as Node;\n\t\t\t\tparent = path[path.length - 1];\n\t\t\t\ti = indexes.pop() as number;\n\t\t\t\tgoingUp = true;\n\t\t\t}\n\n\t\t\tif (node.leaf) {\n\t\t\t\t// check current node\n\n\t\t\t\tconst index = node.children.indexOf(item);\n\n\t\t\t\tif (index !== -1) {\n\t\t\t\t\t// item found, remove the item and condense tree upwards\n\t\t\t\t\tnode.children.splice(index, 1);\n\t\t\t\t\tpath.push(node);\n\t\t\t\t\tthis._condense(path);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!goingUp && !node.leaf && contains(node, bbox)) {\n\t\t\t\t// go down\n\t\t\t\tpath.push(node);\n\t\t\t\tindexes.push(i as number);\n\t\t\t\ti = 0;\n\t\t\t\tparent = node;\n\t\t\t\tnode = node.children[0];\n\t\t\t} else if (parent) {\n\t\t\t\t// go right\n\t\t\t\t(i as number)++;\n\t\t\t\tnode = parent.children[i as number];\n\t\t\t\tgoingUp = false;\n\t\t\t} else {\n\t\t\t\tnode = null; // nothing found\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate toBBox<T>(item: T): T {\n\t\treturn item;\n\t}\n\n\tprivate compareMinX(a: Node, b: Node) {\n\t\treturn a.minX - b.minX;\n\t}\n\tprivate compareMinY(a: Node, b: Node) {\n\t\treturn a.minY - b.minY;\n\t}\n\n\tprivate _all(node: Node, result: Node[]) {\n\t\tconst nodesToSearch = [];\n\t\twhile (node) {\n\t\t\tif (node.leaf) result.push(...node.children);\n\t\t\telse nodesToSearch.push(...node.children);\n\n\t\t\tnode = nodesToSearch.pop() as Node;\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate _build(items: Node[], left: number, right: number, height: number) {\n\t\tconst N = right - left + 1;\n\t\tlet M = this._maxEntries;\n\t\tlet node;\n\n\t\tif (N <= M) {\n\t\t\t// reached leaf level; return leaf\n\t\t\tnode = createNode(items.slice(left, right + 1));\n\t\t\tcalcBBox(node, this.toBBox);\n\t\t\treturn node;\n\t\t}\n\n\t\tif (!height) {\n\t\t\t// target height of the bulk-loaded tree\n\t\t\theight = Math.ceil(Math.log(N) / Math.log(M));\n\n\t\t\t// target number of root entries to maximize storage utilization\n\t\t\tM = Math.ceil(N / Math.pow(M, height - 1));\n\t\t}\n\n\t\tnode = createNode([]);\n\t\tnode.leaf = false;\n\t\tnode.height = height;\n\n\t\t// split the items into M mostly square tiles\n\n\t\tconst N2 = Math.ceil(N / M);\n\t\tconst N1 = N2 * Math.ceil(Math.sqrt(M));\n\n\t\tmultiSelect(items, left, right, N1, this.compareMinX);\n\n\t\tfor (let i = left; i <= right; i += N1) {\n\t\t\tconst right2 = Math.min(i + N1 - 1, right);\n\n\t\t\tmultiSelect(items, i, right2, N2, this.compareMinY);\n\n\t\t\tfor (let j = i; j <= right2; j += N2) {\n\t\t\t\tconst right3 = Math.min(j + N2 - 1, right2);\n\n\t\t\t\t// pack each entry recursively\n\t\t\t\tnode.children.push(this._build(items, j, right3, height - 1));\n\t\t\t}\n\t\t}\n\n\t\tcalcBBox(node, this.toBBox);\n\n\t\treturn node;\n\t}\n\n\tprivate _chooseSubtree(bbox: Node, node: Node, level: number, path: Node[]) {\n\t\twhile (true) {\n\t\t\tpath.push(node);\n\n\t\t\tif (node.leaf || path.length - 1 === level) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tlet minArea = Infinity;\n\t\t\tlet minEnlargement = Infinity;\n\t\t\tlet targetNode;\n\n\t\t\tfor (let i = 0; i < node.children.length; i++) {\n\t\t\t\tconst child = node.children[i];\n\n\t\t\t\tconst area = bboxArea(child);\n\t\t\t\tconst enlargement = enlargedArea(bbox, child) - area;\n\n\t\t\t\t// choose entry with the least area enlargement\n\n\t\t\t\tif (enlargement < minEnlargement) {\n\t\t\t\t\tminEnlargement = enlargement;\n\t\t\t\t\tminArea = area < minArea ? area : minArea;\n\t\t\t\t\ttargetNode = child;\n\t\t\t\t} else if (enlargement === minEnlargement) {\n\t\t\t\t\t// otherwise choose one with the smallest area\n\t\t\t\t\tif (area < minArea) {\n\t\t\t\t\t\tminArea = area;\n\t\t\t\t\t\ttargetNode = child;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tnode = targetNode || node.children[0];\n\t\t}\n\n\t\treturn node;\n\t}\n\n\tprivate _insert(item: Node, level: number, isNode?: boolean) {\n\t\tconst bbox = isNode ? item : this.toBBox(item);\n\t\tconst insertPath: Node[] = [];\n\n\t\t// find the best node for accommodating the item, saving all nodes along the path too\n\t\tconst node = this._chooseSubtree(bbox, this.data, level, insertPath);\n\n\t\t// put the item into the node\n\t\tnode.children.push(item);\n\t\textend(node, bbox);\n\n\t\t// split on node overflow; propagate upwards if necessary\n\t\twhile (level >= 0) {\n\t\t\tif (insertPath[level].children.length > this._maxEntries) {\n\t\t\t\tthis._split(insertPath, level);\n\t\t\t\tlevel--;\n\t\t\t} else break;\n\t\t}\n\n\t\t// adjust bboxes along the insertion path\n\t\tthis._adjustParentBBoxes(bbox, insertPath, level);\n\t}\n\n\t// split overflowed node into two\n\tprivate _split(insertPath: Node[], level: number) {\n\t\tconst node = insertPath[level];\n\t\tconst M = node.children.length;\n\t\tconst m = this._minEntries;\n\n\t\tthis._chooseSplitAxis(node, m, M);\n\n\t\tconst splitIndex = this._chooseSplitIndex(node, m, M);\n\n\t\tconst newNode = createNode(\n\t\t\tnode.children.splice(splitIndex, node.children.length - splitIndex),\n\t\t);\n\t\tnewNode.height = node.height;\n\t\tnewNode.leaf = node.leaf;\n\n\t\tcalcBBox(node, this.toBBox);\n\t\tcalcBBox(newNode, this.toBBox);\n\n\t\tif (level) insertPath[level - 1].children.push(newNode);\n\t\telse this._splitRoot(node, newNode);\n\t}\n\n\tprivate _splitRoot(node: Node, newNode: Node) {\n\t\t// split root node\n\t\tthis.data = createNode([node, newNode]);\n\t\tthis.data.height = node.height + 1;\n\t\tthis.data.leaf = false;\n\t\tcalcBBox(this.data, this.toBBox);\n\t}\n\n\tprivate _chooseSplitIndex(node: Node, m: number, M: number) {\n\t\tlet index;\n\t\tlet minOverlap = Infinity;\n\t\tlet minArea = Infinity;\n\n\t\tfor (let i = m; i <= M - m; i++) {\n\t\t\tconst bbox1 = distBBox(node, 0, i, this.toBBox);\n\t\t\tconst bbox2 = distBBox(node, i, M, this.toBBox);\n\n\t\t\tconst overlap = intersectionArea(bbox1, bbox2);\n\t\t\tconst area = bboxArea(bbox1) + bboxArea(bbox2);\n\n\t\t\t// choose distribution with minimum overlap\n\t\t\tif (overlap < minOverlap) {\n\t\t\t\tminOverlap = overlap;\n\t\t\t\tindex = i;\n\n\t\t\t\tminArea = area < minArea ? area : minArea;\n\t\t\t} else if (overlap === minOverlap) {\n\t\t\t\t// otherwise choose distribution with minimum area\n\t\t\t\tif (area < minArea) {\n\t\t\t\t\tminArea = area;\n\t\t\t\t\tindex = i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn index || M - m;\n\t}\n\n\t// sorts node children by the best axis for split\n\tprivate _chooseSplitAxis(node: Node, m: number, M: number) {\n\t\tconst compareMinX = node.leaf ? this.compareMinX : compareNodeMinX;\n\t\tconst compareMinY = node.leaf ? this.compareMinY : compareNodeMinY;\n\t\tconst xMargin = this._allDistMargin(node, m, M, compareMinX);\n\t\tconst yMargin = this._allDistMargin(node, m, M, compareMinY);\n\n\t\t// if total distributions margin value is minimal for x, sort by minX,\n\t\t// otherwise it's already sorted by minY\n\t\tif (xMargin < yMargin) {\n\t\t\tnode.children.sort(compareMinX);\n\t\t}\n\t}\n\n\t// total margin of all possible split distributions where each node is at least m full\n\tprivate _allDistMargin(\n\t\tnode: Node,\n\t\tm: number,\n\t\tM: number,\n\t\tcompare: CompareFunction<Node>,\n\t) {\n\t\tnode.children.sort(compare);\n\n\t\tconst toBBox = this.toBBox;\n\t\tconst leftBBox = distBBox(node, 0, m, toBBox);\n\t\tconst rightBBox = distBBox(node, M - m, M, toBBox);\n\t\tlet margin = bboxMargin(leftBBox) + bboxMargin(rightBBox);\n\n\t\tfor (let i = m; i < M - m; i++) {\n\t\t\tconst child = node.children[i];\n\t\t\textend(leftBBox, node.leaf ? toBBox(child) : child);\n\t\t\tmargin += bboxMargin(leftBBox);\n\t\t}\n\n\t\tfor (let i = M - m - 1; i >= m; i--) {\n\t\t\tconst child = node.children[i];\n\t\t\textend(rightBBox, node.leaf ? toBBox(child) : child);\n\t\t\tmargin += bboxMargin(rightBBox);\n\t\t}\n\n\t\treturn margin;\n\t}\n\n\tprivate _adjustParentBBoxes(bbox: Node, path: Node[], level: number) {\n\t\t// adjust bboxes along the given tree path\n\t\tfor (let i = level; i >= 0; i--) {\n\t\t\textend(path[i], bbox);\n\t\t}\n\t}\n\n\tprivate _condense(path: Node[]) {\n\t\t// go through the path, removing empty nodes and updating bboxes\n\t\tfor (let i = path.length - 1, siblings; i >= 0; i--) {\n\t\t\tif (path[i].children.length === 0) {\n\t\t\t\tif (i > 0) {\n\t\t\t\t\tsiblings = path[i - 1].children;\n\t\t\t\t\tsiblings.splice(siblings.indexOf(path[i]), 1);\n\t\t\t\t} else this.clear();\n\t\t\t} else {\n\t\t\t\tcalcBBox(path[i], this.toBBox);\n\t\t\t}\n\t\t}\n\t}\n}\n","import { Position } from \"geojson\";\nimport { FeatureId, GeoJSONStoreFeatures } from \"../store\";\nimport { RBush, Node } from \"./rbush\";\n\nexport class SpatialIndex {\n\tprivate tree: RBush;\n\tprivate idToNode: Map<FeatureId, Node>;\n\tprivate nodeToId: Map<Node, FeatureId>;\n\n\tconstructor(options?: { maxEntries: number }) {\n\t\tthis.tree = new RBush(\n\t\t\toptions && options.maxEntries ? options.maxEntries : 9,\n\t\t);\n\t\tthis.idToNode = new Map();\n\t\tthis.nodeToId = new Map();\n\t}\n\n\tprivate setMaps(feature: GeoJSONStoreFeatures, bbox: Node) {\n\t\tthis.idToNode.set(feature.id as FeatureId, bbox);\n\t\tthis.nodeToId.set(bbox, feature.id as FeatureId);\n\t}\n\n\tprivate toBBox(feature: GeoJSONStoreFeatures) {\n\t\tconst longitudes: number[] = [];\n\t\tconst latitudes: number[] = [];\n\n\t\tlet coordinates: Position[];\n\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\tcoordinates = feature.geometry.coordinates[0];\n\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\tcoordinates = feature.geometry.coordinates;\n\t\t} else if (feature.geometry.type === \"Point\") {\n\t\t\tcoordinates = [feature.geometry.coordinates];\n\t\t} else {\n\t\t\tthrow new Error(\"Not a valid feature to turn into a bounding box\");\n\t\t}\n\n\t\tfor (let i = 0; i < coordinates.length; i++) {\n\t\t\tlatitudes.push(coordinates[i][1]);\n\t\t\tlongitudes.push(coordinates[i][0]);\n\t\t}\n\n\t\tconst minLat = Math.min(...latitudes);\n\t\tconst maxLat = Math.max(...latitudes);\n\t\tconst minLng = Math.min(...longitudes);\n\t\tconst maxLng = Math.max(...longitudes);\n\n\t\treturn {\n\t\t\tminX: minLng,\n\t\t\tminY: minLat,\n\t\t\tmaxX: maxLng,\n\t\t\tmaxY: maxLat,\n\t\t} as Node;\n\t}\n\n\tinsert(feature: GeoJSONStoreFeatures): void {\n\t\tif (this.idToNode.get(String(feature.id))) {\n\t\t\tthrow new Error(\"Feature already exists\");\n\t\t}\n\t\tconst bbox = this.toBBox(feature);\n\t\tthis.setMaps(feature, bbox);\n\t\tthis.tree.insert(bbox);\n\t}\n\n\tload(features: GeoJSONStoreFeatures[]): void {\n\t\tconst load: Node[] = [];\n\t\tconst seenIds: Set<string> = new Set();\n\t\tfeatures.forEach((feature) => {\n\t\t\tconst bbox = this.toBBox(feature);\n\t\t\tthis.setMaps(feature, bbox);\n\t\t\tif (seenIds.has(String(feature.id))) {\n\t\t\t\tthrow new Error(`Duplicate feature ID found ${feature.id}`);\n\t\t\t}\n\t\t\tseenIds.add(String(feature.id));\n\t\t\tload.push(bbox);\n\t\t});\n\t\tthis.tree.load(load);\n\t}\n\n\tupdate(feature: GeoJSONStoreFeatures): void {\n\t\tthis.remove(feature.id as FeatureId);\n\t\tconst bbox = this.toBBox(feature);\n\t\tthis.setMaps(feature, bbox);\n\t\tthis.tree.insert(bbox);\n\t}\n\n\tremove(featureId: FeatureId): void {\n\t\tconst node = this.idToNode.get(featureId);\n\t\tif (!node) {\n\t\t\tthrow new Error(`${featureId} not inserted into the spatial index`);\n\t\t}\n\n\t\tthis.tree.remove(node);\n\t}\n\n\tclear(): void {\n\t\tthis.tree.clear();\n\t}\n\n\tsearch(feature: GeoJSONStoreFeatures): FeatureId[] {\n\t\tconst found = this.tree.search(this.toBBox(feature));\n\t\treturn found.map((node) => {\n\t\t\treturn this.nodeToId.get(node) as FeatureId;\n\t\t});\n\t}\n\n\tcollides(feature: GeoJSONStoreFeatures): boolean {\n\t\treturn this.tree.collides(this.toBBox(feature));\n\t}\n}\n","import { Feature, Point, Polygon, LineString } from \"geojson\";\nimport { uuid4 } from \"../util/id\";\nimport { SpatialIndex } from \"./spatial-index/spatial-index\";\nimport { isValidTimestamp } from \"./store-feature-validation\";\nimport { Validation } from \"../common\";\n\nexport type JSON = string | number | boolean | null | JSONArray | JSONObject;\n\nexport interface JSONObject {\n\t[member: string]: JSON;\n}\ntype JSONArray = Array<JSON>;\n\ntype DefinedProperties = Record<string, JSON>;\n\nexport type GeoJSONStoreGeometries = Polygon | LineString | Point;\n\nexport type BBoxPolygon = Feature<Polygon, DefinedProperties>;\n\nexport type GeoJSONStoreFeatures<\n\tG extends GeoJSONStoreGeometries = GeoJSONStoreGeometries,\n> = Feature<G, DefinedProperties>;\n\nexport type StoreValidation = {\n\tid?: FeatureId;\n} & ReturnType<Validation>;\n\ntype StoreChangeEvents = \"delete\" | \"create\" | \"update\" | \"styling\";\n\nexport type StoreChangeHandler<OnChangeContext> = (\n\tids: FeatureId[],\n\tchange: StoreChangeEvents,\n\tcontext?: OnChangeContext,\n) => void;\n\nexport type FeatureId = string | number;\n\nexport type IdStrategy<Id extends FeatureId> = {\n\tisValidId: (id: Id) => boolean;\n\tgetId: () => Id;\n};\n\ntype GeoJSONStoreConfig<Id extends FeatureId> = {\n\tidStrategy?: IdStrategy<Id>;\n\ttracked?: boolean;\n};\n\nexport const defaultIdStrategy = {\n\tgetId: <FeatureId>() => uuid4() as FeatureId,\n\tisValidId: (id: FeatureId) => typeof id === \"string\" && id.length === 36,\n};\n\nconst geometryContext: JSONObject = { target: \"geometry\" };\nconst propertiesContext: JSONObject = { target: \"properties\" };\n\nexport class GeoJSONStore<\n\tOnChangeContext extends JSONObject | undefined,\n\tId extends FeatureId = FeatureId,\n> {\n\tconstructor(config?: GeoJSONStoreConfig<Id>) {\n\t\tthis.store = {};\n\t\tthis.spatialIndex = new SpatialIndex();\n\n\t\t// Setting tracked has to happen first\n\t\t// because we use it in featureValidation\n\t\tthis.tracked = config && config.tracked === false ? false : true;\n\t\tthis.idStrategy =\n\t\t\tconfig && config.idStrategy ? config.idStrategy : defaultIdStrategy;\n\t}\n\n\tpublic idStrategy: IdStrategy<Id>;\n\n\tprivate tracked: boolean;\n\n\tprivate spatialIndex: SpatialIndex;\n\n\tprivate store: {\n\t\t[key: FeatureId]: GeoJSONStoreFeatures;\n\t};\n\n\t// Default to no-op\n\tprivate _onChange: StoreChangeHandler<OnChangeContext | undefined> = () => {};\n\n\tprivate clone<T>(obj: T): T {\n\t\treturn JSON.parse(JSON.stringify(obj));\n\t}\n\n\tgetId(): FeatureId {\n\t\treturn this.idStrategy.getId();\n\t}\n\n\thas(id: FeatureId): boolean {\n\t\treturn Boolean(this.store[id]);\n\t}\n\n\tload(\n\t\tdata: GeoJSONStoreFeatures[],\n\t\tfeatureValidation?: (\n\t\t\tfeature: unknown,\n\t\t\ttracked?: boolean,\n\t\t) => StoreValidation,\n\t\tafterFeatureAdded?: (feature: GeoJSONStoreFeatures) => void,\n\t\tcontext?: OnChangeContext,\n\t): StoreValidation[] {\n\t\tif (data.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// We don't want to update the original data\n\t\tlet clonedInputFeatures = this.clone(data);\n\n\t\tconst validations: StoreValidation[] = []; // The list of validations that we will return\n\t\tconst createdFeatures: GeoJSONStoreFeatures[] = []; // Keep track of the features we created\n\n\t\t// We filter out the features that are not valid and do not add them to the store\n\t\tclonedInputFeatures = clonedInputFeatures.filter((feature) => {\n\t\t\tif (feature.id === undefined || feature.id === null) {\n\t\t\t\tfeature.id = this.idStrategy.getId();\n\t\t\t}\n\n\t\t\tconst id = feature.id as FeatureId;\n\t\t\tif (featureValidation) {\n\t\t\t\tconst validation = featureValidation(feature);\n\n\t\t\t\t// Generic error handling if the featureValidation function\n\t\t\t\t// does not throw something more specific itself\n\t\t\t\tif (!validation.valid) {\n\t\t\t\t\tvalidations.push({ id, valid: false, reason: validation.reason });\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.tracked) {\n\t\t\t\tif (!feature.properties.createdAt) {\n\t\t\t\t\tfeature.properties.createdAt = +new Date();\n\t\t\t\t} else {\n\t\t\t\t\tconst valid = isValidTimestamp(feature.properties.createdAt);\n\t\t\t\t\tif (!valid) {\n\t\t\t\t\t\tvalidations.push({\n\t\t\t\t\t\t\tid: feature.id as FeatureId,\n\t\t\t\t\t\t\tvalid: false,\n\t\t\t\t\t\t\treason: \"createdAt is not a valid numeric timestamp\",\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!feature.properties.updatedAt) {\n\t\t\t\t\tfeature.properties.updatedAt = +new Date();\n\t\t\t\t} else {\n\t\t\t\t\tconst valid = isValidTimestamp(feature.properties.updatedAt);\n\t\t\t\t\tif (!valid) {\n\t\t\t\t\t\tvalidations.push({\n\t\t\t\t\t\t\tid: feature.id as FeatureId,\n\t\t\t\t\t\t\tvalid: false,\n\t\t\t\t\t\t\treason: \"updatedAt is not a valid numeric timestamp\",\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// We have to be sure that the feature does not already exist with this ID\n\t\t\tif (this.has(id)) {\n\t\t\t\tvalidations.push({\n\t\t\t\t\tid,\n\t\t\t\t\tvalid: false,\n\t\t\t\t\treason: `Feature already exists with this id: ${id}`,\n\t\t\t\t});\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis.store[id] = feature;\n\n\t\t\tcreatedFeatures.push(feature);\n\n\t\t\tvalidations.push({ id, valid: true });\n\n\t\t\t// Feature is valid so keep it in the list\n\t\t\treturn true;\n\t\t});\n\n\t\tthis.spatialIndex.load(clonedInputFeatures);\n\n\t\t// The list of changes that we will trigger to onChange\n\t\tconst changes = createdFeatures.map(({ id }) => id as FeatureId);\n\n\t\t// Only trigger onChange with a 'create' change type if we have actually created features\n\t\tif (changes.length > 0) {\n\t\t\tthis._onChange(changes, \"create\", context);\n\n\t\t\tif (afterFeatureAdded) {\n\t\t\t\tcreatedFeatures.forEach((feature) => {\n\t\t\t\t\tafterFeatureAdded(feature);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn validations;\n\t}\n\n\tsearch(\n\t\tbbox: BBoxPolygon,\n\t\tfilter?: (feature: GeoJSONStoreFeatures) => boolean,\n\t) {\n\t\tconst features = this.spatialIndex.search(bbox).map((id) => this.store[id]);\n\t\tif (filter) {\n\t\t\treturn this.clone(features.filter(filter));\n\t\t} else {\n\t\t\treturn this.clone(features);\n\t\t}\n\t}\n\n\tregisterOnChange(onChange: StoreChangeHandler<OnChangeContext | undefined>) {\n\t\tthis._onChange = (ids, change, context) => {\n\t\t\tonChange(ids, change, context);\n\t\t};\n\t}\n\n\tgetGeometryCopy<T extends GeoJSONStoreGeometries>(id: FeatureId): T {\n\t\tconst feature = this.store[id];\n\t\tif (!feature) {\n\t\t\tthrow new Error(\n\t\t\t\t`No feature with this id (${id}), can not get geometry copy`,\n\t\t\t);\n\t\t}\n\t\treturn this.clone(feature.geometry as T);\n\t}\n\n\tgetPropertiesCopy(id: FeatureId) {\n\t\tconst feature = this.store[id];\n\t\tif (!feature) {\n\t\t\tthrow new Error(\n\t\t\t\t`No feature with this id (${id}), can not get properties copy`,\n\t\t\t);\n\t\t}\n\t\treturn this.clone(feature.properties);\n\t}\n\n\tupdateProperty(\n\t\tpropertiesToUpdate: {\n\t\t\tid: FeatureId;\n\t\t\tproperty: string;\n\t\t\tvalue: JSON | undefined;\n\t\t}[],\n\t\tcontext?: OnChangeContext,\n\t): void {\n\t\tconst ids: Set<FeatureId> = new Set();\n\t\tpropertiesToUpdate.forEach(({ id, property, value }) => {\n\t\t\tconst feature = this.store[id];\n\n\t\t\tif (!feature) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No feature with this (${id}), can not update geometry`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (feature.properties[property] === value) {\n\t\t\t\t// If the value is the same, we don't need to update\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tids.add(id);\n\n\t\t\tif (value === undefined) {\n\t\t\t\tdelete feature.properties[property];\n\t\t\t} else {\n\t\t\t\tfeature.properties[property] = value;\n\t\t\t}\n\n\t\t\t// Update the time the feature was updated\n\t\t\tif (this.tracked) {\n\t\t\t\tfeature.properties.updatedAt = +new Date();\n\t\t\t}\n\t\t});\n\n\t\tif (this._onChange && ids.size > 0) {\n\t\t\tthis._onChange(\n\t\t\t\t// NOTE: We use Array.from to convert Set to Array because microbundle cannot handle spreading Sets\n\t\t\t\tArray.from(ids),\n\t\t\t\t\"update\",\n\t\t\t\tcontext\n\t\t\t\t\t? { ...context, ...propertiesContext }\n\t\t\t\t\t: (propertiesContext as OnChangeContext),\n\t\t\t);\n\t\t}\n\t}\n\n\tupdateGeometry(\n\t\tgeometriesToUpdate: { id: FeatureId; geometry: GeoJSONStoreGeometries }[],\n\t\tcontext?: OnChangeContext,\n\t): void {\n\t\tconst ids: Set<FeatureId> = new Set();\n\t\tgeometriesToUpdate.forEach(({ id, geometry }) => {\n\t\t\tids.add(id);\n\n\t\t\tconst feature = this.store[id];\n\n\t\t\tif (!feature) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No feature with this (${id}), can not update geometry`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tfeature.geometry = this.clone(geometry);\n\n\t\t\tthis.spatialIndex.update(feature);\n\n\t\t\t// Update the time the feature was updated\n\t\t\tif (this.tracked) {\n\t\t\t\tfeature.properties.updatedAt = +new Date();\n\t\t\t}\n\t\t});\n\n\t\tif (this._onChange && ids.size > 0) {\n\t\t\tthis._onChange(\n\t\t\t\t// NOTE: We use Array.from to convert Set to Array because microbundle cannot handle spreading Sets\n\t\t\t\tArray.from(ids),\n\t\t\t\t\"update\",\n\t\t\t\tcontext\n\t\t\t\t\t? { ...context, ...geometryContext }\n\t\t\t\t\t: (geometryContext as OnChangeContext),\n\t\t\t);\n\t\t}\n\t}\n\n\tcreate<Id extends FeatureId>(\n\t\tfeatures: {\n\t\t\tgeometry: GeoJSONStoreGeometries;\n\t\t\tproperties?: JSONObject;\n\t\t}[],\n\t\tcontext?: OnChangeContext,\n\t): Id[] {\n\t\tconst ids: FeatureId[] = [];\n\t\tfeatures.forEach(({ geometry, properties }) => {\n\t\t\tlet createdAt;\n\t\t\tlet createdProperties = { ...properties };\n\n\t\t\tif (this.tracked) {\n\t\t\t\tcreatedAt = +new Date();\n\n\t\t\t\tif (properties) {\n\t\t\t\t\tcreatedProperties.createdAt =\n\t\t\t\t\t\ttypeof properties.createdAt === \"number\"\n\t\t\t\t\t\t\t? properties.createdAt\n\t\t\t\t\t\t\t: createdAt;\n\t\t\t\t\tcreatedProperties.updatedAt =\n\t\t\t\t\t\ttypeof properties.updatedAt === \"number\"\n\t\t\t\t\t\t\t? properties.updatedAt\n\t\t\t\t\t\t\t: createdAt;\n\t\t\t\t} else {\n\t\t\t\t\tcreatedProperties = { createdAt, updatedAt: createdAt };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst id = this.getId();\n\t\t\tconst feature = {\n\t\t\t\tid,\n\t\t\t\ttype: \"Feature\",\n\t\t\t\tgeometry,\n\t\t\t\tproperties: createdProperties,\n\t\t\t} as GeoJSONStoreFeatures;\n\n\t\t\tthis.store[id] = feature;\n\t\t\tthis.spatialIndex.insert(feature);\n\n\t\t\tids.push(id);\n\t\t});\n\n\t\tif (this._onChange) {\n\t\t\tthis._onChange([...ids], \"create\", context);\n\t\t}\n\n\t\treturn ids as Id[];\n\t}\n\n\tdelete(ids: FeatureId[], context?: OnChangeContext): void {\n\t\tids.forEach((id) => {\n\t\t\tif (this.store[id]) {\n\t\t\t\tdelete this.store[id];\n\t\t\t\tthis.spatialIndex.remove(id as FeatureId);\n\t\t\t} else {\n\t\t\t\tthrow new Error(`No feature with id ${id}, can not delete`);\n\t\t\t}\n\t\t});\n\n\t\tif (this._onChange) {\n\t\t\tthis._onChange([...ids], \"delete\", context);\n\t\t}\n\t}\n\n\tcopy(id: FeatureId): GeoJSONStoreFeatures {\n\t\treturn this.clone(this.store[id]);\n\t}\n\n\tcopyAll(): GeoJSONStoreFeatures[] {\n\t\treturn this.clone(Object.keys(this.store).map((id) => this.store[id]));\n\t}\n\n\tcopyAllWhere(\n\t\tequals: (properties: JSONObject) => boolean,\n\t): GeoJSONStoreFeatures[] {\n\t\treturn this.clone(\n\t\t\tObject.keys(this.store)\n\t\t\t\t.map((id) => this.store[id])\n\t\t\t\t.filter((feature) => {\n\t\t\t\t\treturn feature.properties && equals(feature.properties);\n\t\t\t\t}),\n\t\t);\n\t}\n\n\tclear(): void {\n\t\tthis.store = {};\n\t\tthis.spatialIndex.clear();\n\t}\n\n\tsize(): number {\n\t\treturn Object.keys(this.store).length;\n\t}\n}\n","export const uuid4 = function (): string {\n\treturn \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function (c) {\n\t\tconst r = (Math.random() * 16) | 0,\n\t\t\tv = c == \"x\" ? r : (r & 0x3) | 0x8;\n\t\treturn v.toString(16);\n\t});\n};\n","import { Polygon } from \"geojson\";\nimport { earthRadius } from \"../helpers\";\n\n// Adapted from @turf/area is MIT Licensed licensed https://github.com/Turfjs/turf/blob/master/packages/turf-area/index.ts\n// In turn adapted from NASA: https://dataverse.jpl.nasa.gov/file.xhtml?fileId=47998&version=2.0\n\nexport function polygonAreaSquareMeters(polygon: Polygon) {\n\tconst coords = polygon.coordinates;\n\tlet total = 0;\n\tif (coords && coords.length > 0) {\n\t\ttotal += Math.abs(ringArea(coords[0]));\n\t\tfor (let i = 1; i < coords.length; i++) {\n\t\t\ttotal -= Math.abs(ringArea(coords[i]));\n\t\t}\n\t}\n\treturn total;\n}\n\nconst FACTOR = (earthRadius * earthRadius) / 2;\nconst PI_OVER_180 = Math.PI / 180;\n\nfunction ringArea(coords: number[][]): number {\n\tconst coordsLength = coords.length;\n\n\tif (coordsLength <= 2) {\n\t\treturn 0;\n\t}\n\n\tlet total = 0;\n\n\tlet i = 0;\n\twhile (i < coordsLength) {\n\t\tconst lower = coords[i];\n\t\tconst middle = coords[i + 1 === coordsLength ? 0 : i + 1];\n\t\tconst upper =\n\t\t\tcoords[i + 2 >= coordsLength ? (i + 2) % coordsLength : i + 2];\n\n\t\tconst lowerX = lower[0] * PI_OVER_180;\n\t\tconst middleY = middle[1] * PI_OVER_180;\n\t\tconst upperX = upper[0] * PI_OVER_180;\n\n\t\ttotal += (upperX - lowerX) * Math.sin(middleY);\n\n\t\ti++;\n\t}\n\n\treturn total * FACTOR;\n}\n","import { Validation } from \"../common\";\nimport { polygonAreaSquareMeters } from \"../geometry/measure/area\";\nimport { GeoJSONStoreFeatures } from \"../terra-draw\";\nimport { ValidationReasonFeatureNotPolygon } from \"./common-validations\";\n\nexport const ValidationReasonFeatureLessThanMinSize =\n\t\"Feature is smaller than the minimum area\";\n\nexport const ValidateMinAreaSquareMeters = (\n\tfeature: GeoJSONStoreFeatures,\n\tminSize: number,\n): ReturnType<Validation> => {\n\tif (feature.geometry.type !== \"Polygon\") {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\treason: ValidationReasonFeatureNotPolygon,\n\t\t};\n\t}\n\n\tif (polygonAreaSquareMeters(feature.geometry) < minSize) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\treason: ValidationReasonFeatureLessThanMinSize,\n\t\t};\n\t}\n\n\treturn { valid: true };\n};\n","import { Feature, LineString, Polygon } from \"geojson\";\nimport { selfIntersects } from \"../geometry/boolean/self-intersects\";\nimport { GeoJSONStoreFeatures } from \"../terra-draw\";\nimport { Validation } from \"../common\";\n\nexport const ValidationReasonFeatureNotPolygonOrLineString =\n\t\"Feature is not a Polygon or LineString\";\nexport const ValidationReasonFeatureSelfIntersects =\n\t\"Feature intersects itself\";\n\nexport const ValidateNotSelfIntersecting = (\n\tfeature: GeoJSONStoreFeatures,\n): ReturnType<Validation> => {\n\tif (\n\t\tfeature.geometry.type !== \"Polygon\" &&\n\t\tfeature.geometry.type !== \"LineString\"\n\t) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\treason: ValidationReasonFeatureNotPolygonOrLineString,\n\t\t};\n\t}\n\n\tconst hasSelfIntersections = selfIntersects(\n\t\tfeature as Feature<LineString> | Feature<Polygon>,\n\t);\n\n\tif (hasSelfIntersections) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\treason: ValidationReasonFeatureSelfIntersects,\n\t\t};\n\t}\n\n\treturn { valid: true };\n};\n","import { CartesianPoint } from \"../common\";\nimport { webMercatorBearing } from \"./measure/bearing\";\n\n/**\n * Calculate the relative angle between two lines\n * @param A The first point of the first line\n * @param B The second point of the first line and the first point of the second line\n * @param C The second point of the second line\n * @returns The relative angle between the two lines\n */\nexport function calculateRelativeAngle(\n\tA: CartesianPoint,\n\tB: CartesianPoint,\n\tC: CartesianPoint,\n): number {\n\tconst bearingAB = webMercatorBearing(A, B); // Bearing from A to B\n\tconst bearingBC = webMercatorBearing(B, C); // Bearing from B to C\n\n\t// Calculate the relative angle (bearingBC relative to bearingAB)\n\tlet relativeAngle = bearingBC - bearingAB;\n\n\t// Normalize the relative angle to 0-360 range\n\tif (relativeAngle < 0) {\n\t\trelativeAngle += 360;\n\t}\n\n\t// Normalise to 0 - 90\n\tconst angle = relativeAngle - 90;\n\n\treturn 180 - Math.abs(-90 + angle);\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n\tZ_INDEX,\n\tCOMMON_PROPERTIES,\n\tFinishActions,\n} from \"../../common\";\nimport {\n\tTerraDrawBaseDrawMode,\n\tBaseModeOptions,\n\tCustomStyling,\n\tModeUpdateOptions,\n} from \"../base.mode\";\nimport { coordinatesIdentical } from \"../../geometry/coordinates-identical\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tFeatureId,\n\tGeoJSONStoreFeatures,\n\tStoreValidation,\n} from \"../../store/store\";\nimport { ValidateNonIntersectingPolygonFeature } from \"../../validations/polygon.validation\";\nimport { webMercatorDestination } from \"../../geometry/measure/destination\";\nimport { webMercatorBearing } from \"../../geometry/measure/bearing\";\nimport { midpointCoordinate } from \"../../geometry/midpoint-coordinate\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"../../geometry/project/web-mercator\";\nimport { degreesToRadians } from \"../../geometry/helpers\";\nimport { determineHalfPlane } from \"../../geometry/determine-halfplane\";\nimport { cartesianDistance } from \"../../geometry/measure/pixel-distance\";\nimport { calculateRelativeAngle } from \"../../geometry/calculate-relative-angle\";\nimport { limitPrecision } from \"../../geometry/limit-decimal-precision\";\nimport {\n\tCoordinateMutation,\n\tMutateFeatureBehavior,\n\tMutations,\n} from \"../mutate-feature.behavior\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { ReadFeatureBehavior } from \"../read-feature.behavior\";\n\ntype TerraDrawPolygonModeKeyEvents = {\n\tcancel?: KeyboardEvent[\"key\"] | null;\n\tfinish?: KeyboardEvent[\"key\"] | null;\n};\n\nconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\ntype PolygonStyling = {\n\tfillColor: HexColorStyling;\n\tfillOpacity: NumericStyling;\n\toutlineColor: HexColorStyling;\n\toutlineOpacity: NumericStyling;\n\toutlineWidth: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n\tclose?: Cursor;\n}\n\nconst defaultCursors = {\n\tstart: \"crosshair\",\n\tclose: \"pointer\",\n} as Required<Cursors>;\n\ninterface TerraDrawAngledRectangleModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tpointerDistance?: number;\n\tkeyEvents?: TerraDrawPolygonModeKeyEvents | null;\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawAngledRectangleMode extends TerraDrawBaseDrawMode<PolygonStyling> {\n\tmode = \"angled-rectangle\";\n\n\tprivate currentCoordinate = 0;\n\tprivate currentId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawPolygonModeKeyEvents = defaultKeyEvents;\n\tprivate cursors: Required<Cursors> = defaultCursors;\n\tprivate mouseMove = false;\n\n\t// Behaviors\n\tprivate mutateFeature!: MutateFeatureBehavior;\n\tprivate readFeature!: ReadFeatureBehavior;\n\n\tconstructor(options?: TerraDrawAngledRectangleModeOptions<PolygonStyling>) {\n\t\tsuper(options, true);\n\t\tthis.updateOptions(options);\n\t}\n\n\toverride updateOptions(\n\t\toptions?: ModeUpdateOptions<\n\t\t\tTerraDrawAngledRectangleModeOptions<PolygonStyling>\n\t\t>,\n\t) {\n\t\tsuper.updateOptions(options);\n\n\t\tif (options?.cursors) {\n\t\t\tthis.cursors = { ...this.cursors, ...options.cursors };\n\t\t}\n\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = { cancel: null, finish: null };\n\t\t} else if (options?.keyEvents) {\n\t\t\tthis.keyEvents = { ...this.keyEvents, ...options.keyEvents };\n\t\t}\n\t}\n\n\tprivate close() {\n\t\tif (this.currentId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst updated = this.mutateFeature.updatePolygon({\n\t\t\tfeatureId: this.currentId,\n\t\t\tpropertyMutations: {\n\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: undefined,\n\t\t\t},\n\t\t\tcontext: { updateType: UpdateTypes.Finish, action: FinishActions.Draw },\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst featureId = this.currentId;\n\n\t\tthis.currentCoordinate = 0;\n\t\tthis.currentId = undefined;\n\n\t\t// Go back to started state\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.onFinish(featureId, {\n\t\t\tmode: this.mode,\n\t\t\taction: FinishActions.Draw,\n\t\t});\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tthis.mouseMove = true;\n\t\tthis.setCursor(this.cursors.start);\n\n\t\tif (this.currentId === undefined || this.currentCoordinate === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet coordinateMutations: CoordinateMutation[] = [];\n\n\t\tif (this.currentCoordinate === 1) {\n\t\t\tcoordinateMutations = this.getUpdateForSecondCoordinate(event);\n\t\t} else if (this.currentCoordinate === 2) {\n\t\t\tcoordinateMutations = this.getNewSecondAndThirdCoordinates(event);\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.mutateFeature.updatePolygon({\n\t\t\tfeatureId: this.currentId,\n\t\t\tcoordinateMutations,\n\t\t\tcontext: { updateType: UpdateTypes.Provisional },\n\t\t});\n\t}\n\n\tprivate getUpdateForSecondCoordinate(\n\t\tevent: TerraDrawMouseEvent,\n\t): CoordinateMutation[] {\n\t\t// We must add a very small epsilon value so that Mapbox GL\n\t\t// renders the polygon - There might be a cleaner solution?\n\t\tconst offset = this.mutateFeature.epsilonOffset();\n\n\t\treturn [\n\t\t\t{\n\t\t\t\ttype: Mutations.Update,\n\t\t\t\tindex: 1,\n\t\t\t\tcoordinate: [event.lng, event.lat],\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: Mutations.Update,\n\t\t\t\tindex: 2,\n\t\t\t\tcoordinate: [event.lng, event.lat - offset],\n\t\t\t},\n\t\t];\n\t}\n\n\tprivate getNewSecondAndThirdCoordinates(\n\t\tevent: TerraDrawMouseEvent,\n\t): CoordinateMutation[] {\n\t\tif (!this.currentId) {\n\t\t\tthrow new Error(\"No current feature being drawn\");\n\t\t}\n\n\t\tconst firstCoordinate = this.readFeature.getCoordinate(this.currentId, 0);\n\t\tconst secondCoordinate = this.readFeature.getCoordinate(this.currentId, 1);\n\t\tconst midpoint = midpointCoordinate(\n\t\t\tfirstCoordinate,\n\t\t\tsecondCoordinate,\n\t\t\tthis.coordinatePrecision,\n\t\t\tthis.project,\n\t\t\tthis.unproject,\n\t\t);\n\n\t\tconst A = lngLatToWebMercatorXY(firstCoordinate[0], firstCoordinate[1]);\n\t\tconst B = lngLatToWebMercatorXY(midpoint[0], midpoint[1]);\n\t\tconst C = lngLatToWebMercatorXY(secondCoordinate[0], secondCoordinate[1]);\n\t\tconst D = lngLatToWebMercatorXY(event.lng, event.lat);\n\n\t\t// Determine if the cursor is closer to A or C\n\t\tconst distanceToA = cartesianDistance(D, A);\n\t\tconst distanceToB = cartesianDistance(D, C);\n\t\tconst ACloserThanC = distanceToA < distanceToB ? true : false;\n\n\t\t// We need to work out if the cursor is closer to A or C and then calculate the angle\n\t\t// between the cursor and the opposing midpoint\n\t\tconst relativeAngle = calculateRelativeAngle(A, B, D);\n\t\tconst theta = ACloserThanC\n\t\t\t? 90 - relativeAngle\n\t\t\t: calculateRelativeAngle(A, B, D) - 90;\n\n\t\t// We want to calculate the adjacent i.e. the calculated distance\n\t\t// between the cursor and the opposing midpoint\n\t\tconst hypotenuse = cartesianDistance(B, D);\n\t\tconst adjacent = Math.cos(degreesToRadians(theta)) * hypotenuse;\n\n\t\t// Calculate the bearing between the first and second point\n\t\tconst firstAndSecondPointBearing = webMercatorBearing(A, C);\n\n\t\t// Determine which side of the line the cursor is on\n\t\tconst side = determineHalfPlane(A, C, D);\n\n\t\t// Determine which direction to draw the rectangle\n\t\tconst angle = side === \"right\" ? -90 : 90;\n\n\t\t// Calculate the third and fourth coordinates based on the cursor position\n\t\tconst rectangleAngle = firstAndSecondPointBearing + angle;\n\t\tconst thirdCoordinateXY = webMercatorDestination(\n\t\t\tA,\n\t\t\tadjacent,\n\t\t\trectangleAngle,\n\t\t);\n\t\tconst fourthCoordinateXY = webMercatorDestination(\n\t\t\tC,\n\t\t\tadjacent,\n\t\t\trectangleAngle,\n\t\t);\n\n\t\t// Convert the third and fourth coordinates back to lng/lat\n\t\tconst thirdCoordinate = webMercatorXYToLngLat(\n\t\t\tthirdCoordinateXY.x,\n\t\t\tthirdCoordinateXY.y,\n\t\t);\n\t\tconst fourthCoordinate = webMercatorXYToLngLat(\n\t\t\tfourthCoordinateXY.x,\n\t\t\tfourthCoordinateXY.y,\n\t\t);\n\n\t\t// The final coordinates\n\t\treturn [\n\t\t\t{\n\t\t\t\ttype: Mutations.Update,\n\t\t\t\tindex: 2,\n\t\t\t\tcoordinate: [\n\t\t\t\t\tlimitPrecision(fourthCoordinate.lng, this.coordinatePrecision),\n\t\t\t\t\tlimitPrecision(fourthCoordinate.lat, this.coordinatePrecision),\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: Mutations.Update,\n\t\t\t\tindex: 3,\n\t\t\t\tcoordinate: [\n\t\t\t\t\tlimitPrecision(thirdCoordinate.lng, this.coordinatePrecision),\n\t\t\t\t\tlimitPrecision(thirdCoordinate.lat, this.coordinatePrecision),\n\t\t\t\t],\n\t\t\t},\n\t\t];\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\tif (\n\t\t\t(event.button === \"right\" &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.rightClick, event)) ||\n\t\t\t(event.button === \"left\" &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.leftClick, event)) ||\n\t\t\t(event.isContextMenu &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.contextMenu, event))\n\t\t) {\n\t\t\t// We want pointer devices (mobile/tablet) to have\n\t\t\t// similar behaviour to mouse based devices so we\n\t\t\t// trigger a mousemove event before every click\n\t\t\t// if one has not been triggered to emulate this\n\t\t\tif (this.currentCoordinate > 0 && !this.mouseMove) {\n\t\t\t\tthis.onMouseMove(event);\n\t\t\t}\n\t\t\tthis.mouseMove = false;\n\n\t\t\tif (this.currentCoordinate === 0) {\n\t\t\t\tconst { id: newId } = this.mutateFeature.createPolygon({\n\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t],\n\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tmode: this.mode,\n\t\t\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: true,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tthis.currentId = newId;\n\t\t\t\tthis.currentCoordinate++;\n\n\t\t\t\t// Ensure the state is updated to reflect drawing has started\n\t\t\t\tthis.setDrawing();\n\t\t\t} else if (this.currentCoordinate === 1 && this.currentId) {\n\t\t\t\tconst previousCoordinate = this.readFeature.getCoordinate(\n\t\t\t\t\tthis.currentId,\n\t\t\t\t\t0,\n\t\t\t\t);\n\n\t\t\t\tconst isIdentical = coordinatesIdentical(\n\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\tpreviousCoordinate,\n\t\t\t\t);\n\n\t\t\t\tif (isIdentical) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst updated = this.mutateFeature.updatePolygon({\n\t\t\t\t\tfeatureId: this.currentId,\n\t\t\t\t\tcoordinateMutations: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: Mutations.Update,\n\t\t\t\t\t\t\tindex: 1,\n\t\t\t\t\t\t\tcoordinate: [event.lng, event.lat],\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: Mutations.InsertAfter,\n\t\t\t\t\t\t\tindex: 1,\n\t\t\t\t\t\t\tcoordinate: [event.lng, event.lat],\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tcontext: { updateType: UpdateTypes.Commit },\n\t\t\t\t});\n\n\t\t\t\tif (!updated) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.currentCoordinate++;\n\t\t\t} else if (this.currentCoordinate === 2 && this.currentId) {\n\t\t\t\tthis.close();\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tif (event.key === this.keyEvents.cancel) {\n\t\t\tthis.cleanUp();\n\t\t} else if (event.key === this.keyEvents.finish) {\n\t\t\t// We don't want to close a unfinished polygon\n\t\t\tif (this.currentCoordinate < 2) {\n\t\t\t\tthis.cleanUp();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonDragStart() {}\n\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tconst currentId = this.currentId;\n\n\t\tthis.currentId = undefined;\n\t\tthis.currentCoordinate = 0;\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.mutateFeature.deleteFeatureIfPresent(currentId);\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (feature.properties.mode === this.mode) {\n\t\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\t\tstyles.polygonFillColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.fillColor,\n\t\t\t\t\tstyles.polygonFillColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.outlineColor,\n\t\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.outlineWidth,\n\t\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.outlineOpacity,\n\t\t\t\t\t1,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonFillOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.fillOpacity,\n\t\t\t\t\tstyles.polygonFillOpacity,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = Z_INDEX.LAYER_ONE;\n\t\t\t}\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): StoreValidation {\n\t\treturn this.validateModeFeature(feature, (baseValidatedFeature) =>\n\t\t\tValidateNonIntersectingPolygonFeature(\n\t\t\t\tbaseValidatedFeature,\n\t\t\t\tthis.coordinatePrecision,\n\t\t\t),\n\t\t);\n\t}\n\n\tafterFeatureUpdated(feature: GeoJSONStoreFeatures): void {\n\t\t// If we are in the middle of drawing a rectangle and the feature being updated is the current rectangle,\n\t\t// we need to reset the drawing state\n\t\tif (this.currentId === feature.id) {\n\t\t\tthis.currentId = undefined;\n\t\t\tthis.currentCoordinate = 0;\n\t\t\tif (this.state === \"drawing\") {\n\t\t\t\tthis.setStarted();\n\t\t\t}\n\t\t}\n\t}\n\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.readFeature = new ReadFeatureBehavior(config);\n\t\tthis.mutateFeature = new MutateFeatureBehavior(config, {\n\t\t\tvalidate: this.validate,\n\t\t});\n\t}\n}\n","import { CartesianPoint } from \"../common\";\n\n// Function to determine the relative position of a point to a line segment\nexport function determineHalfPlane(\n\tpoint: CartesianPoint,\n\tlineStart: CartesianPoint,\n\tlineEnd: CartesianPoint,\n): string {\n\t// Calculate the vectors\n\tconst vectorLine = { x: lineEnd.x - lineStart.x, y: lineEnd.y - lineStart.y };\n\tconst vectorPoint = { x: point.x - lineStart.x, y: point.y - lineStart.y };\n\n\t// Calculate the cross product\n\tconst crossProduct =\n\t\tvectorLine.x * vectorPoint.y - vectorLine.y * vectorPoint.x;\n\n\t// Use a small epsilon value to handle floating-point precision errors\n\tconst epsilon = 1e-10;\n\n\tif (crossProduct > epsilon) {\n\t\treturn \"left\";\n\t} else if (crossProduct < -epsilon) {\n\t\treturn \"right\";\n\t} else {\n\t\t// Technically on the line but we treat it as left\n\t\treturn \"left\";\n\t}\n}\n","import { CartesianPoint } from \"../common\";\n\nexport function isClockwiseWebMercator(\n\tcenter: CartesianPoint,\n\tsecondCoord: CartesianPoint,\n\tthirdCoord: CartesianPoint,\n): boolean {\n\t// Calculate the vectors\n\tconst vector1 = { x: secondCoord.x - center.x, y: secondCoord.y - center.y };\n\tconst vector2 = { x: thirdCoord.x - center.x, y: thirdCoord.y - center.y };\n\n\t// Calculate the cross product\n\tconst cross = vector1.x * vector2.y - vector1.y * vector2.x;\n\n\t// If the cross product is negative, the third point is on the right (clockwise)\n\t// If the cross product is positive, the third point is on the left (anticlockwise)\n\treturn cross <= 0;\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n\tZ_INDEX,\n\tCOMMON_PROPERTIES,\n\tFinishActions,\n} from \"../../common\";\nimport { Polygon, Position } from \"geojson\";\nimport {\n\tTerraDrawBaseDrawMode,\n\tBaseModeOptions,\n\tCustomStyling,\n\tModeUpdateOptions,\n} from \"../base.mode\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tFeatureId,\n\tGeoJSONStoreFeatures,\n\tStoreValidation,\n} from \"../../store/store\";\nimport { ValidateNonIntersectingPolygonFeature } from \"../../validations/polygon.validation\";\nimport { webMercatorDestination } from \"../../geometry/measure/destination\";\nimport {\n\tnormalizeBearing,\n\twebMercatorBearing,\n} from \"../../geometry/measure/bearing\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"../../geometry/project/web-mercator\";\nimport { cartesianDistance } from \"../../geometry/measure/pixel-distance\";\nimport { isClockwiseWebMercator } from \"../../geometry/clockwise\";\nimport { limitPrecision } from \"../../geometry/limit-decimal-precision\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { ReadFeatureBehavior } from \"../read-feature.behavior\";\nimport {\n\tCoordinateMutation,\n\tMutateFeatureBehavior,\n\tMutations,\n\tReplaceMutation,\n} from \"../mutate-feature.behavior\";\n\ntype TerraDrawSectorModeKeyEvents = {\n\tcancel?: KeyboardEvent[\"key\"] | null;\n\tfinish?: KeyboardEvent[\"key\"] | null;\n};\n\nconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\ntype SectorPolygonStyling = {\n\tfillColor: HexColorStyling;\n\toutlineColor: HexColorStyling;\n\toutlineWidth: NumericStyling;\n\toutlineOpacity: NumericStyling;\n\tfillOpacity: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n\tclose?: Cursor;\n}\n\nconst defaultCursors = {\n\tstart: \"crosshair\",\n\tclose: \"pointer\",\n} as Required<Cursors>;\n\ninterface TerraDrawSectorModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tarcPoints?: number;\n\tpointerDistance?: number;\n\tkeyEvents?: TerraDrawSectorModeKeyEvents | null;\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawSectorMode extends TerraDrawBaseDrawMode<SectorPolygonStyling> {\n\tmode = \"sector\";\n\n\tprivate currentCoordinate = 0;\n\tprivate currentId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawSectorModeKeyEvents = defaultKeyEvents;\n\tprivate direction: \"clockwise\" | \"anticlockwise\" | undefined;\n\tprivate arcPoints: number = 64;\n\tprivate cursors: Required<Cursors> = defaultCursors;\n\tprivate mouseMove = false;\n\n\t// Behaviors\n\tprivate readFeature!: ReadFeatureBehavior;\n\tprivate mutateFeature!: MutateFeatureBehavior;\n\n\tconstructor(options?: TerraDrawSectorModeOptions<SectorPolygonStyling>) {\n\t\tsuper(options, true);\n\t\tthis.updateOptions(options);\n\t}\n\n\toverride updateOptions(\n\t\toptions?: ModeUpdateOptions<\n\t\t\tTerraDrawSectorModeOptions<SectorPolygonStyling>\n\t\t>,\n\t) {\n\t\tsuper.updateOptions(options);\n\n\t\tif (options?.cursors) {\n\t\t\tthis.cursors = { ...this.cursors, ...options.cursors };\n\t\t}\n\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = { cancel: null, finish: null };\n\t\t} else if (options?.keyEvents) {\n\t\t\tthis.keyEvents = { ...this.keyEvents, ...options.keyEvents };\n\t\t}\n\n\t\tif (options?.arcPoints) {\n\t\t\tthis.arcPoints = options.arcPoints;\n\t\t}\n\t}\n\n\tprivate close() {\n\t\tif (this.currentId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst updated = this.mutateFeature.updatePolygon({\n\t\t\tfeatureId: this.currentId,\n\t\t\tpropertyMutations: {\n\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: undefined,\n\t\t\t},\n\t\t\tcoordinateMutations: {\n\t\t\t\t// Trigger right-hand rule enforcement\n\t\t\t\tcoordinates: this.readFeature.getGeometry<Polygon>(this.currentId)\n\t\t\t\t\t.coordinates,\n\t\t\t\ttype: Mutations.Replace,\n\t\t\t},\n\t\t\tcontext: {\n\t\t\t\tupdateType: UpdateTypes.Finish,\n\t\t\t\taction: FinishActions.Draw,\n\t\t\t},\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst featureId = this.currentId;\n\n\t\tthis.currentCoordinate = 0;\n\t\tthis.currentId = undefined;\n\t\tthis.direction = undefined;\n\n\t\t// Go back to started state\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.onFinish(featureId, {\n\t\t\tmode: this.mode,\n\t\t\taction: FinishActions.Draw,\n\t\t});\n\t}\n\n\tprivate getSectorCoordinates(event: TerraDrawMouseEvent) {\n\t\tconst currentPolygonCoordinates = this.readFeature.getCoordinates<Polygon>(\n\t\t\tthis.currentId!,\n\t\t);\n\t\tconst center = currentPolygonCoordinates[0];\n\t\tconst arcCoordOne = currentPolygonCoordinates[1];\n\t\tconst arcCoordTwo = [event.lng, event.lat];\n\n\t\t// Convert coordinates to Web Mercator\n\t\tconst webMercatorCenter = lngLatToWebMercatorXY(center[0], center[1]);\n\t\tconst webMercatorArcCoordOne = lngLatToWebMercatorXY(\n\t\t\tarcCoordOne[0],\n\t\t\tarcCoordOne[1],\n\t\t);\n\t\tconst webMercatorArcCoordTwo = lngLatToWebMercatorXY(\n\t\t\tarcCoordTwo[0],\n\t\t\tarcCoordTwo[1],\n\t\t);\n\n\t\t// We want to determine the direction of the sector, whether\n\t\t// it is clockwise or anticlockwise\n\t\tif (this.direction === undefined) {\n\t\t\tconst clockwise = isClockwiseWebMercator(\n\t\t\t\twebMercatorCenter,\n\t\t\t\twebMercatorArcCoordOne,\n\t\t\t\twebMercatorArcCoordTwo,\n\t\t\t);\n\t\t\tthis.direction = clockwise ? \"clockwise\" : \"anticlockwise\";\n\t\t}\n\n\t\t// Calculate the radius (distance from center to second point in Web Mercator)\n\t\tconst radius = cartesianDistance(webMercatorCenter, webMercatorArcCoordOne);\n\n\t\t// Calculate bearings for the second and third points in Web Mercator\n\t\tconst startBearing = webMercatorBearing(\n\t\t\twebMercatorCenter,\n\t\t\twebMercatorArcCoordOne,\n\t\t);\n\t\tconst endBearing = webMercatorBearing(\n\t\t\twebMercatorCenter,\n\t\t\twebMercatorArcCoordTwo,\n\t\t);\n\n\t\t// Generate points along the arc in Web Mercator\n\t\tconst numberOfPoints = this.arcPoints; // Number of points to approximate the arc\n\t\tconst coordinates: Position[] = [center]; // Start with the center (in WGS84)\n\n\t\t// Corrected version to calculate deltaBearing\n\t\tconst normalizedStart = normalizeBearing(startBearing);\n\t\tconst normalizedEnd = normalizeBearing(endBearing);\n\n\t\t// Calculate the delta bearing based on the direction\n\t\tlet deltaBearing;\n\t\tif (this.direction === \"anticlockwise\") {\n\t\t\tdeltaBearing = normalizedEnd - normalizedStart;\n\t\t\tif (deltaBearing < 0) {\n\t\t\t\tdeltaBearing += 360; // Adjust for wrap-around\n\t\t\t}\n\t\t} else {\n\t\t\tdeltaBearing = normalizedStart - normalizedEnd;\n\t\t\tif (deltaBearing < 0) {\n\t\t\t\tdeltaBearing += 360; // Adjust for wrap-around\n\t\t\t}\n\t\t}\n\n\t\tconst bearingStep =\n\t\t\t((this.direction === \"anticlockwise\" ? 1 : -1) * deltaBearing) /\n\t\t\tnumberOfPoints;\n\n\t\t// Add the first coordinate to the polygon\n\t\tcoordinates.push(arcCoordOne);\n\n\t\t// Add all the arc points\n\t\tfor (let i = 0; i <= numberOfPoints; i++) {\n\t\t\tconst currentBearing = normalizedStart + i * bearingStep;\n\t\t\tconst pointOnArc = webMercatorDestination(\n\t\t\t\twebMercatorCenter,\n\t\t\t\tradius,\n\t\t\t\tcurrentBearing,\n\t\t\t);\n\t\t\tconst { lng, lat } = webMercatorXYToLngLat(pointOnArc.x, pointOnArc.y);\n\n\t\t\tconst nextCoord = [\n\t\t\t\tlimitPrecision(lng, this.coordinatePrecision),\n\t\t\t\tlimitPrecision(lat, this.coordinatePrecision),\n\t\t\t];\n\n\t\t\tconst notIdentical =\n\t\t\t\tnextCoord[0] !== coordinates[coordinates.length - 1][0] &&\n\t\t\t\tnextCoord[1] !== coordinates[coordinates.length - 1][1];\n\t\t\tif (notIdentical) {\n\t\t\t\tcoordinates.push(nextCoord);\n\t\t\t}\n\t\t}\n\n\t\t// Close the polygon\n\t\tcoordinates.push(center);\n\n\t\treturn coordinates;\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tthis.mouseMove = true;\n\t\tthis.setCursor(this.cursors.start);\n\n\t\tif (this.currentId === undefined || this.currentCoordinate === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet mutations: CoordinateMutation[] | ReplaceMutation<Polygon>;\n\n\t\tif (this.currentCoordinate === 1) {\n\t\t\t// We must add a very small epsilon value so that Mapbox GL\n\t\t\t// renders the polygon - There might be a cleaner solution?\n\t\t\tconst offset = this.mutateFeature.epsilonOffset();\n\n\t\t\tmutations = [\n\t\t\t\t{\n\t\t\t\t\ttype: Mutations.Update,\n\t\t\t\t\tindex: 1,\n\t\t\t\t\tcoordinate: [event.lng, event.lat],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: Mutations.Update,\n\t\t\t\t\tindex: 2,\n\t\t\t\t\tcoordinate: [event.lng, event.lat - offset],\n\t\t\t\t},\n\t\t\t];\n\t\t} else if (this.currentCoordinate === 2) {\n\t\t\tconst sectorCoordinates = this.getSectorCoordinates(event);\n\t\t\tif (!sectorCoordinates) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tmutations = {\n\t\t\t\ttype: Mutations.Replace,\n\t\t\t\tcoordinates: [sectorCoordinates],\n\t\t\t};\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.mutateFeature.updatePolygon({\n\t\t\tfeatureId: this.currentId,\n\t\t\tcoordinateMutations: mutations,\n\t\t\tcontext: {\n\t\t\t\tupdateType: UpdateTypes.Provisional,\n\t\t\t},\n\t\t});\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\tif (\n\t\t\t(event.button === \"right\" &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.rightClick, event)) ||\n\t\t\t(event.button === \"left\" &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.leftClick, event)) ||\n\t\t\t(event.isContextMenu &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.contextMenu, event))\n\t\t) {\n\t\t\t// We want pointer devices (mobile/tablet) to have\n\t\t\t// similar behaviour to mouse based devices so we\n\t\t\t// trigger a mousemove event before every click\n\t\t\t// if one has not been triggered to emulate this\n\t\t\tif (this.currentCoordinate > 0 && !this.mouseMove) {\n\t\t\t\tthis.onMouseMove(event);\n\t\t\t}\n\t\t\tthis.mouseMove = false;\n\n\t\t\tif (this.currentCoordinate === 0) {\n\t\t\t\tconst created = this.mutateFeature.createPolygon({\n\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t],\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tmode: this.mode,\n\t\t\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: true,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tthis.currentId = created?.id;\n\t\t\t\tthis.currentCoordinate++;\n\n\t\t\t\t// Ensure the state is updated to reflect drawing has started\n\t\t\t\tthis.setDrawing();\n\t\t\t} else if (this.currentCoordinate === 1 && this.currentId) {\n\t\t\t\tconst isIdentical = this.readFeature.coordinateAtIndexIsIdentical({\n\t\t\t\t\tfeatureId: this.currentId,\n\t\t\t\t\tindex: 0,\n\t\t\t\t\tnewCoordinate: [event.lng, event.lat],\n\t\t\t\t});\n\n\t\t\t\tif (isIdentical) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst updated = this.mutateFeature.updatePolygon({\n\t\t\t\t\tfeatureId: this.currentId,\n\t\t\t\t\tcoordinateMutations: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: Mutations.Update,\n\t\t\t\t\t\t\tindex: 1,\n\t\t\t\t\t\t\tcoordinate: [event.lng, event.lat],\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: Mutations.Update,\n\t\t\t\t\t\t\tindex: 2,\n\t\t\t\t\t\t\tcoordinate: [event.lng, event.lat],\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\tupdateType: UpdateTypes.Provisional,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tif (!updated) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.currentCoordinate++;\n\t\t\t} else if (this.currentCoordinate === 2 && this.currentId) {\n\t\t\t\tthis.close();\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tif (event.key === this.keyEvents.cancel) {\n\t\t\tthis.cleanUp();\n\t\t} else if (event.key === this.keyEvents.finish) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyDown() {\n\t\t// no-op\n\t}\n\n\t/** @internal */\n\tonDragStart() {\n\t\t// no-op\n\t}\n\n\t/** @internal */\n\tonDrag() {\n\t\t// no-op\n\t}\n\n\t/** @internal */\n\tonDragEnd() {\n\t\t// no-op\n\t}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tconst currentId = this.currentId;\n\n\t\tthis.currentId = undefined;\n\t\tthis.direction = undefined;\n\t\tthis.currentCoordinate = 0;\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.mutateFeature.deleteFeatureIfPresent(currentId);\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (feature.properties.mode === this.mode) {\n\t\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\t\tstyles.polygonFillColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.fillColor,\n\t\t\t\t\tstyles.polygonFillColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.outlineColor,\n\t\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.outlineWidth,\n\t\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.outlineOpacity,\n\t\t\t\t\t1,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonFillOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.fillOpacity,\n\t\t\t\t\tstyles.polygonFillOpacity,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = Z_INDEX.LAYER_ONE;\n\t\t\t}\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): StoreValidation {\n\t\treturn this.validateModeFeature(feature, (baseValidatedFeature) =>\n\t\t\tValidateNonIntersectingPolygonFeature(\n\t\t\t\tbaseValidatedFeature,\n\t\t\t\tthis.coordinatePrecision,\n\t\t\t),\n\t\t);\n\t}\n\n\tafterFeatureUpdated(feature: GeoJSONStoreFeatures): void {\n\t\t// If we are in the middle of drawing a sector and the feature being updated is the current sector,\n\t\t// we need to reset the drawing state\n\t\tif (this.currentId === feature.id) {\n\t\t\tthis.currentId = undefined;\n\t\t\tthis.direction = undefined;\n\t\t\tthis.currentCoordinate = 0;\n\t\t\tif (this.state === \"drawing\") {\n\t\t\t\tthis.setStarted();\n\t\t\t}\n\t\t}\n\t}\n\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.readFeature = new ReadFeatureBehavior(config);\n\t\tthis.mutateFeature = new MutateFeatureBehavior(config, {\n\t\t\tvalidate: this.validate,\n\t\t});\n\t}\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n\tZ_INDEX,\n\tCOMMON_PROPERTIES,\n\tFinishActions,\n} from \"../../common\";\nimport { LineString, Point, Polygon, Position } from \"geojson\";\nimport {\n\tTerraDrawBaseDrawMode,\n\tBaseModeOptions,\n\tCustomStyling,\n\tModeUpdateOptions,\n} from \"../base.mode\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tFeatureId,\n\tGeoJSONStoreFeatures,\n\tStoreValidation,\n} from \"../../store/store\";\nimport { ValidateNonIntersectingPolygonFeature } from \"../../validations/polygon.validation\";\nimport { webMercatorDestination } from \"../../geometry/measure/destination\";\nimport {\n\tnormalizeBearing,\n\twebMercatorBearing,\n} from \"../../geometry/measure/bearing\";\nimport {\n\tlngLatToWebMercatorXY,\n\twebMercatorXYToLngLat,\n} from \"../../geometry/project/web-mercator\";\nimport { cartesianDistance } from \"../../geometry/measure/pixel-distance\";\nimport { isClockwiseWebMercator } from \"../../geometry/clockwise\";\nimport { limitPrecision } from \"../../geometry/limit-decimal-precision\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { ReadFeatureBehavior } from \"../read-feature.behavior\";\nimport { MutateFeatureBehavior, Mutations } from \"../mutate-feature.behavior\";\n\ntype TerraDrawSensorModeKeyEvents = {\n\tcancel?: KeyboardEvent[\"key\"] | null;\n\tfinish?: KeyboardEvent[\"key\"] | null;\n};\n\nconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\ntype SensorPolygonStyling = {\n\tcenterPointColor: HexColorStyling;\n\tcenterPointWidth: NumericStyling;\n\tcenterPointOpacity: NumericStyling;\n\tcenterPointOutlineColor: HexColorStyling;\n\tcenterPointOutlineWidth: NumericStyling;\n\tcenterPointOutlineOpacity: NumericStyling;\n\toutlineColor: HexColorStyling;\n\toutlineWidth: NumericStyling;\n\toutlineOpacity: NumericStyling;\n\tfillColor: HexColorStyling;\n\tfillOpacity: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n\tclose?: Cursor;\n}\n\nconst defaultCursors = {\n\tstart: \"crosshair\",\n\tclose: \"pointer\",\n} as Required<Cursors>;\n\ninterface TerraDrawSensorModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tarcPoints?: number;\n\tpointerDistance?: number;\n\tkeyEvents?: TerraDrawSensorModeKeyEvents | null;\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawSensorMode extends TerraDrawBaseDrawMode<SensorPolygonStyling> {\n\tmode = \"sensor\";\n\n\tprivate currentCoordinate = 0;\n\tprivate currentId: FeatureId | undefined;\n\tprivate currentInitialArcId: FeatureId | undefined;\n\tprivate currentStartingPointId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawSensorModeKeyEvents = defaultKeyEvents;\n\tprivate direction: \"clockwise\" | \"anticlockwise\" | undefined;\n\tprivate arcPoints: number = 64;\n\tprivate cursors: Required<Cursors> = defaultCursors;\n\tprivate mouseMove = false;\n\n\t// Behaviors\n\tprivate readFeature!: ReadFeatureBehavior;\n\tprivate mutateFeature!: MutateFeatureBehavior;\n\n\tconstructor(options?: TerraDrawSensorModeOptions<SensorPolygonStyling>) {\n\t\tsuper(options, true);\n\t\tthis.updateOptions(options);\n\t}\n\n\toverride updateOptions(\n\t\toptions?: ModeUpdateOptions<\n\t\t\tTerraDrawSensorModeOptions<SensorPolygonStyling>\n\t\t>,\n\t): void {\n\t\tsuper.updateOptions(options);\n\n\t\tif (options?.cursors) {\n\t\t\tthis.cursors = { ...this.cursors, ...options.cursors };\n\t\t}\n\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = { cancel: null, finish: null };\n\t\t} else if (options?.keyEvents) {\n\t\t\tthis.keyEvents = { ...this.keyEvents, ...options.keyEvents };\n\t\t}\n\n\t\tif (options?.arcPoints) {\n\t\t\tthis.arcPoints = options.arcPoints;\n\t\t}\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tthis.mouseMove = true;\n\t\tthis.setCursor(this.cursors.start);\n\n\t\tif (\n\t\t\tthis.currentInitialArcId === undefined ||\n\t\t\tthis.currentStartingPointId === undefined ||\n\t\t\tthis.currentCoordinate === 0\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.currentCoordinate === 2) {\n\t\t\tconst coordinates = this.getUpdatedLineStringCoordinates(event);\n\t\t\tif (!coordinates) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.mutateFeature.updateLineString({\n\t\t\t\tfeatureId: this.currentInitialArcId,\n\t\t\t\tcoordinateMutations: {\n\t\t\t\t\ttype: Mutations.Replace,\n\t\t\t\t\tcoordinates: coordinates,\n\t\t\t\t},\n\t\t\t\tcontext: {\n\t\t\t\t\tupdateType: UpdateTypes.Provisional,\n\t\t\t\t},\n\t\t\t});\n\t\t} else if (this.currentCoordinate === 3) {\n\t\t\tconst coordinates = this.getUpdatedPolygonCoordinates(event);\n\t\t\tif (!coordinates) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If the polygon doesn't exist, create it\n\t\t\t// else update the existing geometry\n\t\t\tif (!this.currentId) {\n\t\t\t\tconst created = this.mutateFeature.createPolygon({\n\t\t\t\t\tcoordinates,\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tmode: this.mode,\n\t\t\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: true,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tif (!created) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.currentId = created.id;\n\t\t\t} else {\n\t\t\t\tthis.mutateFeature.updatePolygon({\n\t\t\t\t\tfeatureId: this.currentId,\n\t\t\t\t\tcoordinateMutations: {\n\t\t\t\t\t\ttype: Mutations.Replace,\n\t\t\t\t\t\tcoordinates: [coordinates],\n\t\t\t\t\t},\n\t\t\t\t\tcontext: { updateType: UpdateTypes.Provisional },\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\tif (\n\t\t\t(event.button === \"right\" &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.rightClick, event)) ||\n\t\t\t(event.button === \"left\" &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.leftClick, event)) ||\n\t\t\t(event.isContextMenu &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.contextMenu, event))\n\t\t) {\n\t\t\t// We want pointer devices (mobile/tablet) to have\n\t\t\t// similar behaviour to mouse based devices so we\n\t\t\t// trigger a mousemove event before every click\n\t\t\t// if one has not been triggered to emulate this\n\t\t\tif (this.currentCoordinate > 0 && !this.mouseMove) {\n\t\t\t\tthis.onMouseMove(event);\n\t\t\t}\n\t\t\tthis.mouseMove = false;\n\n\t\t\tif (this.currentCoordinate === 0) {\n\t\t\t\tconst created = this.mutateFeature.createPoint({\n\t\t\t\t\tcoordinates: [event.lng, event.lat],\n\t\t\t\t\tproperties: { mode: this.mode },\n\t\t\t\t});\n\t\t\t\tif (!created) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.currentStartingPointId = created.id;\n\t\t\t\tthis.currentCoordinate++;\n\n\t\t\t\t// Ensure the state is updated to reflect drawing has started\n\t\t\t\tthis.setDrawing();\n\t\t\t} else if (this.currentCoordinate === 1 && this.currentStartingPointId) {\n\t\t\t\tconst created = this.mutateFeature.createLineString({\n\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t],\n\t\t\t\t\tproperties: { mode: this.mode },\n\t\t\t\t});\n\t\t\t\tif (!created) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.currentInitialArcId = created.id;\n\t\t\t\tthis.currentCoordinate++;\n\t\t\t} else if (this.currentCoordinate === 2 && this.currentStartingPointId) {\n\t\t\t\tthis.currentCoordinate++;\n\t\t\t\t// pass\n\t\t\t} else if (this.currentCoordinate === 3 && this.currentStartingPointId) {\n\t\t\t\tthis.close();\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tif (event.key === this.keyEvents.cancel) {\n\t\t\tthis.cleanUp();\n\t\t} else if (event.key === this.keyEvents.finish) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyDown() {\n\t\t// no-op\n\t}\n\n\t/** @internal */\n\tonDragStart() {\n\t\t// no-op\n\t}\n\n\t/** @internal */\n\tonDrag() {\n\t\t// no-op\n\t}\n\n\t/** @internal */\n\tonDragEnd() {\n\t\t// no-op\n\t}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tthis.mutateFeature.deleteFeatureIfPresent(this.currentStartingPointId);\n\t\tthis.mutateFeature.deleteFeatureIfPresent(this.currentInitialArcId);\n\t\tthis.mutateFeature.deleteFeatureIfPresent(this.currentId);\n\n\t\tthis.currentStartingPointId = undefined;\n\t\tthis.direction = undefined;\n\t\tthis.currentId = undefined;\n\t\tthis.currentCoordinate = 0;\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (feature.properties.mode === this.mode) {\n\t\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\t\tstyles.polygonFillColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.fillColor,\n\t\t\t\t\tstyles.polygonFillColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.outlineColor,\n\t\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.outlineWidth,\n\t\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonOutlineOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.outlineOpacity,\n\t\t\t\t\t1,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.polygonFillOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.fillOpacity,\n\t\t\t\t\tstyles.polygonFillOpacity,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = Z_INDEX.LAYER_ONE;\n\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\tstyles.lineStringColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.outlineColor,\n\t\t\t\t\tstyles.polygonOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.lineStringWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.outlineWidth,\n\t\t\t\t\tstyles.polygonOutlineWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = Z_INDEX.LAYER_ONE;\n\t\t\t} else if (feature.geometry.type === \"Point\") {\n\t\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.centerPointColor,\n\t\t\t\t\tstyles.pointColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.centerPointOpacity,\n\t\t\t\t\t1,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.centerPointWidth,\n\t\t\t\t\tstyles.pointWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\t\tthis.styles.centerPointOutlineColor,\n\t\t\t\t\tstyles.pointOutlineColor,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineOpacity = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.centerPointOutlineOpacity,\n\t\t\t\t\t1,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.pointOutlineWidth = this.getNumericStylingValue(\n\t\t\t\t\tthis.styles.centerPointOutlineWidth,\n\t\t\t\t\tstyles.pointOutlineWidth,\n\t\t\t\t\tfeature,\n\t\t\t\t);\n\n\t\t\t\tstyles.zIndex = Z_INDEX.LAYER_TWO;\n\t\t\t}\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): StoreValidation {\n\t\treturn this.validateModeFeature(feature, (baseValidatedFeature) =>\n\t\t\tValidateNonIntersectingPolygonFeature(\n\t\t\t\tbaseValidatedFeature,\n\t\t\t\tthis.coordinatePrecision,\n\t\t\t),\n\t\t);\n\t}\n\n\tafterFeatureUpdated(feature: GeoJSONStoreFeatures): void {\n\t\t// If we are in the middle of drawing a sensor and the feature being updated is the current sensor,\n\t\t// we need to reset the drawing state\n\t\tif (this.currentId === feature.id) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.currentStartingPointId);\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.currentInitialArcId);\n\t\t\tthis.currentStartingPointId = undefined;\n\t\t\tthis.direction = undefined;\n\t\t\tthis.currentId = undefined;\n\t\t\tthis.currentCoordinate = 0;\n\n\t\t\tif (this.state === \"drawing\") {\n\t\t\t\tthis.setStarted();\n\t\t\t}\n\t\t}\n\t}\n\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.readFeature = new ReadFeatureBehavior(config);\n\t\tthis.mutateFeature = new MutateFeatureBehavior(config, {\n\t\t\tvalidate: this.validate,\n\t\t});\n\t}\n\n\tprivate close() {\n\t\tif (this.currentStartingPointId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst finishedCurrentStartingPointId = this.currentStartingPointId;\n\t\tconst finishedInitialArcId = this.currentInitialArcId;\n\n\t\t// Fix right hand rule if necessary\n\t\tif (this.currentId) {\n\t\t\tconst updated = this.mutateFeature.updatePolygon({\n\t\t\t\tfeatureId: this.currentId,\n\t\t\t\tpropertyMutations: {\n\t\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: undefined,\n\t\t\t\t},\n\t\t\t\tcoordinateMutations: {\n\t\t\t\t\t// Trigger right-hand rule enforcement\n\t\t\t\t\tcoordinates: this.readFeature.getGeometry<Polygon>(this.currentId)\n\t\t\t\t\t\t.coordinates,\n\t\t\t\t\ttype: Mutations.Replace,\n\t\t\t\t},\n\t\t\t\tcontext: { updateType: UpdateTypes.Finish, action: FinishActions.Draw },\n\t\t\t});\n\n\t\t\tif (!updated) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tconst featureId = this.currentId;\n\n\t\tthis.mutateFeature.deleteFeatureIfPresent(finishedCurrentStartingPointId);\n\t\tthis.mutateFeature.deleteFeatureIfPresent(finishedInitialArcId);\n\n\t\tthis.currentCoordinate = 0;\n\t\tthis.currentStartingPointId = undefined;\n\t\tthis.currentInitialArcId = undefined;\n\t\tthis.currentId = undefined;\n\t\tthis.direction = undefined;\n\n\t\t// Go back to started state\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tif (featureId) {\n\t\t\tthis.onFinish(featureId, { mode: this.mode, action: FinishActions.Draw });\n\t\t}\n\t}\n\n\tprivate getUpdatedPolygonCoordinates(event: TerraDrawMouseEvent) {\n\t\tif (\n\t\t\tthis.currentInitialArcId === undefined ||\n\t\t\tthis.currentStartingPointId === undefined ||\n\t\t\tthis.currentCoordinate < 3\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst coordinates = this.readFeature.getCoordinates<LineString>(\n\t\t\tthis.currentInitialArcId,\n\t\t);\n\n\t\tif (coordinates.length < 2) {\n\t\t\treturn;\n\t\t}\n\n\t\t// This shouldn't happen but we protect against it in case as we can't calculate if the cursor\n\t\t// is in the sector otherwise\n\t\tif (!this.direction) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst center = this.readFeature.getGeometry<Point>(\n\t\t\tthis.currentStartingPointId,\n\t\t).coordinates;\n\n\t\tconst firstCoord = coordinates[0];\n\t\tconst lastCoord = coordinates[coordinates.length - 1];\n\n\t\tconst webMercatorCursor = lngLatToWebMercatorXY(event.lng, event.lat);\n\t\tconst webMercatorCoordOne = lngLatToWebMercatorXY(\n\t\t\tfirstCoord[0],\n\t\t\tfirstCoord[1],\n\t\t);\n\t\tconst webMercatorCoordTwo = lngLatToWebMercatorXY(\n\t\t\tlastCoord[0],\n\t\t\tlastCoord[1],\n\t\t);\n\n\t\tconst webMercatorCenter = lngLatToWebMercatorXY(center[0], center[1]);\n\n\t\tconst innerRadius = cartesianDistance(\n\t\t\twebMercatorCenter,\n\t\t\twebMercatorCoordOne,\n\t\t);\n\n\t\tconst outerRadius = cartesianDistance(webMercatorCenter, webMercatorCursor);\n\n\t\tconst hasLessThanZeroSize = outerRadius < innerRadius;\n\n\t\t// If the cursor is inside the inner radius, the depth of the sensor is always 0\n\t\tconst radiusCalculationPosition = hasLessThanZeroSize\n\t\t\t? webMercatorCoordOne\n\t\t\t: webMercatorCursor;\n\n\t\tconst cursorBearing = webMercatorBearing(\n\t\t\twebMercatorCenter,\n\t\t\twebMercatorCursor,\n\t\t);\n\n\t\tconst startBearing = webMercatorBearing(\n\t\t\twebMercatorCenter,\n\t\t\twebMercatorCoordOne,\n\t\t);\n\t\tconst endBearing = webMercatorBearing(\n\t\t\twebMercatorCenter,\n\t\t\twebMercatorCoordTwo,\n\t\t);\n\n\t\tconst normalizedStart = normalizeBearing(startBearing);\n\t\tconst normalizedEnd = normalizeBearing(endBearing);\n\t\tconst normalizedCursor = normalizeBearing(cursorBearing);\n\n\t\tconst notInSector = this.notInSector({\n\t\t\tnormalizedCursor,\n\t\t\tnormalizedStart,\n\t\t\tnormalizedEnd,\n\t\t\tdirection: this.direction,\n\t\t});\n\n\t\t// If it's not a valid cursor movement then we don't update\n\t\tif (notInSector) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Calculate the delta bearing based on the direction\n\t\tconst deltaBearing = this.getDeltaBearing(\n\t\t\tthis.direction,\n\t\t\tnormalizedStart,\n\t\t\tnormalizedEnd,\n\t\t);\n\n\t\t// Number of points to approximate the arc\n\t\tconst numberOfPoints = this.arcPoints;\n\n\t\t// Calculate bearing step\n\t\tconst multiplier = this.direction === \"anticlockwise\" ? 1 : -1;\n\t\tconst bearingStep = (multiplier * deltaBearing) / numberOfPoints;\n\n\t\tconst radius = cartesianDistance(\n\t\t\twebMercatorCenter,\n\t\t\tradiusCalculationPosition,\n\t\t);\n\n\t\t// Add all the arc points\n\t\tconst finalArc = [];\n\t\tfor (let i = 0; i <= numberOfPoints; i++) {\n\t\t\tconst currentBearing = normalizedStart + i * bearingStep;\n\t\t\tconst pointOnArc = webMercatorDestination(\n\t\t\t\twebMercatorCenter,\n\t\t\t\tradius,\n\t\t\t\tcurrentBearing,\n\t\t\t);\n\t\t\tconst { lng, lat } = webMercatorXYToLngLat(pointOnArc.x, pointOnArc.y);\n\n\t\t\tconst nextCoord = [\n\t\t\t\tlimitPrecision(lng, this.coordinatePrecision),\n\t\t\t\tlimitPrecision(lat, this.coordinatePrecision),\n\t\t\t];\n\n\t\t\tconst notIdentical =\n\t\t\t\tnextCoord[0] !== coordinates[coordinates.length - 1][0] &&\n\t\t\t\tnextCoord[1] !== coordinates[coordinates.length - 1][1];\n\t\t\tif (notIdentical) {\n\t\t\t\tfinalArc.unshift(nextCoord);\n\t\t\t}\n\t\t}\n\n\t\tcoordinates.push(...finalArc);\n\n\t\t// Close the polygon\n\t\tcoordinates.push(coordinates[0]);\n\n\t\treturn coordinates;\n\t}\n\n\tprivate getUpdatedLineStringCoordinates(event: TerraDrawMouseEvent) {\n\t\tif (\n\t\t\tthis.currentInitialArcId === undefined ||\n\t\t\tthis.currentStartingPointId === undefined ||\n\t\t\tthis.currentCoordinate < 2\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentPolygonCoordinates = this.readFeature.getGeometry<LineString>(\n\t\t\tthis.currentInitialArcId,\n\t\t).coordinates;\n\t\tconst center = this.readFeature.getGeometry<Point>(\n\t\t\tthis.currentStartingPointId,\n\t\t).coordinates;\n\n\t\tconst arcCoordOne = currentPolygonCoordinates[0];\n\t\tconst arcCoordTwo = [event.lng, event.lat];\n\n\t\tconst webMercatorArcCoordOne = lngLatToWebMercatorXY(\n\t\t\tarcCoordOne[0],\n\t\t\tarcCoordOne[1],\n\t\t);\n\t\tconst webMercatorArcCoordTwo = lngLatToWebMercatorXY(\n\t\t\tarcCoordTwo[0],\n\t\t\tarcCoordTwo[1],\n\t\t);\n\t\tconst webMercatorCenter = lngLatToWebMercatorXY(center[0], center[1]);\n\n\t\tconst radius = cartesianDistance(webMercatorCenter, webMercatorArcCoordOne);\n\n\t\t// We want to determine the direction of the sector, whether\n\t\t// it is clockwise or anticlockwise\n\t\tif (this.direction === undefined) {\n\t\t\tconst clockwise = isClockwiseWebMercator(\n\t\t\t\twebMercatorCenter,\n\t\t\t\twebMercatorArcCoordOne,\n\t\t\t\twebMercatorArcCoordTwo,\n\t\t\t);\n\t\t\tthis.direction = clockwise ? \"clockwise\" : \"anticlockwise\";\n\t\t}\n\n\t\t// Calculate bearings for the second and third points in Web Mercator\n\t\tconst startBearing = webMercatorBearing(\n\t\t\twebMercatorCenter,\n\t\t\twebMercatorArcCoordOne,\n\t\t);\n\t\tconst endBearing = webMercatorBearing(\n\t\t\twebMercatorCenter,\n\t\t\twebMercatorArcCoordTwo,\n\t\t);\n\n\t\t// Generate points along the arc in Web Mercator\n\t\tconst numberOfPoints = this.arcPoints; // Number of points to approximate the arc\n\t\tconst coordinates: Position[] = [arcCoordOne];\n\n\t\t// Corrected version to calculate deltaBearing\n\t\tconst normalizedStart = normalizeBearing(startBearing);\n\t\tconst normalizedEnd = normalizeBearing(endBearing);\n\n\t\t// Calculate the delta bearing based on the direction\n\t\tlet deltaBearing;\n\t\tif (this.direction === \"anticlockwise\") {\n\t\t\tdeltaBearing = normalizedEnd - normalizedStart;\n\t\t\tif (deltaBearing < 0) {\n\t\t\t\tdeltaBearing += 360; // Adjust for wrap-around\n\t\t\t}\n\t\t} else {\n\t\t\tdeltaBearing = normalizedStart - normalizedEnd;\n\t\t\tif (deltaBearing < 0) {\n\t\t\t\tdeltaBearing += 360; // Adjust for wrap-around\n\t\t\t}\n\t\t}\n\n\t\tconst bearingStep =\n\t\t\t((this.direction === \"anticlockwise\" ? 1 : -1) * deltaBearing) /\n\t\t\tnumberOfPoints;\n\n\t\t// Add all the arc points\n\t\tfor (let i = 0; i <= numberOfPoints; i++) {\n\t\t\tconst currentBearing = normalizedStart + i * bearingStep;\n\t\t\tconst pointOnArc = webMercatorDestination(\n\t\t\t\twebMercatorCenter,\n\t\t\t\tradius,\n\t\t\t\tcurrentBearing,\n\t\t\t);\n\t\t\tconst { lng, lat } = webMercatorXYToLngLat(pointOnArc.x, pointOnArc.y);\n\n\t\t\tconst nextCoord = [\n\t\t\t\tlimitPrecision(lng, this.coordinatePrecision),\n\t\t\t\tlimitPrecision(lat, this.coordinatePrecision),\n\t\t\t];\n\n\t\t\tconst notIdentical =\n\t\t\t\tnextCoord[0] !== coordinates[coordinates.length - 1][0] &&\n\t\t\t\tnextCoord[1] !== coordinates[coordinates.length - 1][1];\n\t\t\tif (notIdentical) {\n\t\t\t\tcoordinates.push(nextCoord);\n\t\t\t}\n\t\t}\n\n\t\treturn coordinates;\n\t}\n\n\tprivate getDeltaBearing(\n\t\tdirection: \"anticlockwise\" | \"clockwise\",\n\t\tnormalizedStart: number,\n\t\tnormalizedEnd: number,\n\t) {\n\t\tlet deltaBearing;\n\t\tif (direction === \"anticlockwise\") {\n\t\t\tdeltaBearing = normalizedEnd - normalizedStart;\n\t\t\tif (deltaBearing < 0) {\n\t\t\t\tdeltaBearing += 360; // Adjust for wrap-around\n\t\t\t}\n\t\t} else {\n\t\t\tdeltaBearing = normalizedStart - normalizedEnd;\n\t\t\tif (deltaBearing < 0) {\n\t\t\t\tdeltaBearing += 360; // Adjust for wrap-around\n\t\t\t}\n\t\t}\n\t\treturn deltaBearing;\n\t}\n\n\tprivate notInSector({\n\t\tnormalizedCursor,\n\t\tnormalizedStart,\n\t\tnormalizedEnd,\n\t\tdirection,\n\t}: {\n\t\tnormalizedCursor: number;\n\t\tnormalizedStart: number;\n\t\tnormalizedEnd: number;\n\t\tdirection: \"clockwise\" | \"anticlockwise\";\n\t}) {\n\t\tif (direction === \"clockwise\") {\n\t\t\t// Handle clockwise direction\n\t\t\tif (normalizedStart <= normalizedEnd) {\n\t\t\t\t// Standard case (no wrap-around)\n\t\t\t\treturn (\n\t\t\t\t\tnormalizedCursor >= normalizedStart &&\n\t\t\t\t\tnormalizedCursor <= normalizedEnd\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// Handle wrap-around across 360 degrees\n\t\t\t\treturn (\n\t\t\t\t\tnormalizedCursor >= normalizedStart ||\n\t\t\t\t\tnormalizedCursor <= normalizedEnd\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\t// Handle anticlockwise direction\n\t\t\tif (normalizedStart >= normalizedEnd) {\n\t\t\t\t// Standard case (no wrap-around)\n\t\t\t\treturn (\n\t\t\t\t\tnormalizedCursor <= normalizedStart &&\n\t\t\t\t\tnormalizedCursor >= normalizedEnd\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// Handle wrap-around across 360 degrees\n\t\t\t\treturn (\n\t\t\t\t\tnormalizedCursor <= normalizedStart ||\n\t\t\t\t\tnormalizedCursor >= normalizedEnd\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n","export class AdapterListener<Callback extends (...args: any[]) => any> {\n\tpublic name: string;\n\tpublic callback: (...args: any[]) => any;\n\tpublic registered = false;\n\tpublic register: any;\n\tpublic unregister: any;\n\n\t/**\n\t * Creates a new AdapterListener instance with the provided configuration.\n\t *\n\t * @param {Object} config - The configuration object for the listener.\n\t * @param {string} config.name - The name of the event listener.\n\t * @param {Function} config.callback - The callback function to be called when the event is triggered.\n\t * @param {Function} config.unregister - The function to unregister the event listeners.\n\t * @param {Function} config.register - The function to register the event listeners.\n\t */\n\tconstructor({\n\t\tname,\n\t\tcallback,\n\t\tunregister,\n\t\tregister,\n\t}: {\n\t\tname: string;\n\t\tcallback: Callback;\n\t\tunregister: (callbacks: Callback) => void;\n\t\tregister: (callback: Callback) => void;\n\t}) {\n\t\tthis.name = name;\n\n\t\t// Function to register the event listeners\n\t\tthis.register = () => {\n\t\t\tif (!this.registered) {\n\t\t\t\tthis.registered = true;\n\t\t\t\tregister(callback);\n\t\t\t}\n\t\t};\n\n\t\t// Function to unregister the event listeners\n\t\tthis.unregister = () => {\n\t\t\tif (this.register) {\n\t\t\t\tthis.registered = false;\n\t\t\t\tunregister(callback);\n\t\t\t}\n\t\t};\n\n\t\tthis.callback = callback;\n\t}\n}\n","import {\n\tProject,\n\tUnproject,\n\tTerraDrawCallbacks,\n\tTerraDrawChanges,\n\tTerraDrawMouseEvent,\n\tSetCursor,\n\tTerraDrawStylingFunction,\n\tGetLngLatFromEvent,\n\tTerraDrawAdapter,\n\tTerraDrawHandledEvents,\n} from \"../common\";\nimport { limitPrecision } from \"../geometry/limit-decimal-precision\";\nimport { cartesianDistance } from \"../geometry/measure/pixel-distance\";\nimport { AdapterListener } from \"./adapter-listener\";\n\ntype BasePointerListener = (event: PointerEvent) => void;\ntype BaseKeyboardListener = (event: KeyboardEvent) => void;\ntype BaseMouseListener = (event: MouseEvent) => void;\n\nexport type BaseAdapterConfig = {\n\tignoreMismatchedPointerEvents?: boolean;\n\tcoordinatePrecision?: number;\n\tminPixelDragDistanceDrawing?: number;\n\tminPixelDragDistance?: number;\n\tminPixelDragDistanceSelecting?: number;\n};\n\nexport abstract class TerraDrawBaseAdapter implements TerraDrawAdapter {\n\tconstructor(config: BaseAdapterConfig) {\n\t\tthis._ignoreMismatchedPointerEvents =\n\t\t\ttypeof config.ignoreMismatchedPointerEvents === \"boolean\"\n\t\t\t\t? config.ignoreMismatchedPointerEvents\n\t\t\t\t: false;\n\n\t\tthis._minPixelDragDistance =\n\t\t\ttypeof config.minPixelDragDistance === \"number\"\n\t\t\t\t? config.minPixelDragDistance\n\t\t\t\t: 1;\n\n\t\tthis._minPixelDragDistanceSelecting =\n\t\t\ttypeof config.minPixelDragDistanceSelecting === \"number\"\n\t\t\t\t? config.minPixelDragDistanceSelecting\n\t\t\t\t: 1;\n\n\t\tthis._minPixelDragDistanceDrawing =\n\t\t\ttypeof config.minPixelDragDistanceDrawing === \"number\"\n\t\t\t\t? config.minPixelDragDistanceDrawing\n\t\t\t\t: 8;\n\n\t\tthis._coordinatePrecision =\n\t\t\ttypeof config.coordinatePrecision === \"number\"\n\t\t\t\t? config.coordinatePrecision\n\t\t\t\t: 9;\n\t}\n\n\tprivate _nextKeyUpIsContextMenu = false;\n\tprivate _lastPointerDownEventTarget: EventTarget | undefined;\n\n\tprotected _ignoreMismatchedPointerEvents = false;\n\tprotected _minPixelDragDistance: number;\n\tprotected _minPixelDragDistanceDrawing: number;\n\tprotected _minPixelDragDistanceSelecting: number;\n\tprotected _lastDrawEvent: TerraDrawMouseEvent | undefined;\n\tprotected _coordinatePrecision: number;\n\tprotected _heldKeys: Set<string> = new Set();\n\tprotected _listeners: AdapterListener<\n\t\tBasePointerListener | BaseKeyboardListener | BaseMouseListener\n\t>[] = [];\n\tprotected _dragState: \"not-dragging\" | \"pre-dragging\" | \"dragging\" =\n\t\t\"not-dragging\";\n\tprotected _currentModeCallbacks: TerraDrawCallbacks | undefined;\n\n\tpublic abstract getMapEventElement(\n\t\teventType?: TerraDrawHandledEvents,\n\t): HTMLElement;\n\n\tprotected getButton(event: PointerEvent | MouseEvent) {\n\t\tif (event.button === -1) {\n\t\t\treturn \"neither\";\n\t\t} else if (event.button === 0) {\n\t\t\treturn \"left\";\n\t\t} else if (event.button === 1) {\n\t\t\treturn \"middle\";\n\t\t} else if (event.button === 2) {\n\t\t\treturn \"right\";\n\t\t}\n\n\t\t// This shouldn't happen (?)\n\t\treturn \"neither\";\n\t}\n\n\tprotected getMapElementXYPosition(event: PointerEvent | MouseEvent) {\n\t\tconst mapElement = this.getMapEventElement(\n\t\t\tevent.type as Extract<\n\t\t\t\tTerraDrawHandledEvents,\n\t\t\t\t\"pointerdown\" | \"pointerup\" | \"pointermove\"\n\t\t\t>,\n\t\t);\n\t\tconst { left, top } = mapElement.getBoundingClientRect();\n\n\t\treturn {\n\t\t\tcontainerX: event.clientX - left,\n\t\t\tcontainerY: event.clientY - top,\n\t\t};\n\t}\n\n\tprotected getDrawEventFromEvent(\n\t\tevent: PointerEvent | MouseEvent,\n\t\tisContextMenu = false,\n\t): TerraDrawMouseEvent | null {\n\t\tconst latLng = this.getLngLatFromEvent(event);\n\n\t\tif (!latLng) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst { lng, lat } = latLng;\n\t\tconst { containerX, containerY } = this.getMapElementXYPosition(event);\n\t\tconst button = this.getButton(event);\n\t\tconst heldKeys = Array.from(this._heldKeys);\n\n\t\treturn {\n\t\t\tlng: limitPrecision(lng, this._coordinatePrecision),\n\t\t\tlat: limitPrecision(lat, this._coordinatePrecision),\n\t\t\tcontainerX,\n\t\t\tcontainerY,\n\t\t\tbutton,\n\t\t\theldKeys,\n\t\t\tisContextMenu,\n\t\t};\n\t}\n\n\t/**\n\t * Registers the provided callbacks for the current drawing mode and attaches\n\t * the necessary event listeners.\n\t * @param {TerraDrawCallbacks} callbacks - An object containing callback functions\n\t * for handling various drawing events in the current mode.\n\t */\n\tpublic register(callbacks: TerraDrawCallbacks) {\n\t\tthis._currentModeCallbacks = callbacks;\n\n\t\tthis._listeners = this.getAdapterListeners();\n\n\t\tthis._listeners.forEach((listener) => {\n\t\t\tlistener.register();\n\t\t});\n\t}\n\n\t/**\n\t * Gets the coordinate precision. The coordinate precision is the number of decimal places in geometry\n\t * coordinates stored in the store.\n\t * @returns {number} The coordinate precision.\n\t */\n\tpublic getCoordinatePrecision() {\n\t\treturn this._coordinatePrecision;\n\t}\n\n\tprotected getAdapterListeners() {\n\t\treturn [\n\t\t\tnew AdapterListener<BasePointerListener>({\n\t\t\t\tname: \"pointerdown\",\n\t\t\t\tcallback: (event) => {\n\t\t\t\t\tif (!this._currentModeCallbacks) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// We don't support multitouch as this point in time\n\t\t\t\t\tif (!event.isPrimary) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst drawEvent = this.getDrawEventFromEvent(event);\n\t\t\t\t\tif (!drawEvent) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis._dragState = \"pre-dragging\";\n\n\t\t\t\t\t// On pointer devices pointer mouse move events won't be\n\t\t\t\t\t// triggered so this._lastDrawEvent will not get set in\n\t\t\t\t\t// pointermove listener, so we must set it here.\n\t\t\t\t\tthis._lastDrawEvent = drawEvent;\n\n\t\t\t\t\tthis._lastPointerDownEventTarget = event.target\n\t\t\t\t\t\t? event.target\n\t\t\t\t\t\t: undefined;\n\t\t\t\t},\n\t\t\t\tregister: (callback) => {\n\t\t\t\t\tthis.getMapEventElement(\"pointerdown\").addEventListener(\n\t\t\t\t\t\t\"pointerdown\",\n\t\t\t\t\t\tcallback,\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tunregister: (callback) => {\n\t\t\t\t\tthis.getMapEventElement(\"pointerdown\").removeEventListener(\n\t\t\t\t\t\t\"pointerdown\",\n\t\t\t\t\t\tcallback,\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t}),\n\t\t\tnew AdapterListener<BasePointerListener>({\n\t\t\t\tname: \"pointermove\",\n\t\t\t\tcallback: (event) => {\n\t\t\t\t\tif (!this._currentModeCallbacks) return;\n\n\t\t\t\t\t// We don't support multitouch as this point in time\n\t\t\t\t\tif (!event.isPrimary) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tevent.preventDefault();\n\n\t\t\t\t\tconst drawEvent = this.getDrawEventFromEvent(event);\n\t\t\t\t\tif (!drawEvent) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this._dragState === \"not-dragging\") {\n\t\t\t\t\t\t// If we're not dragging we can trigger the onMouseMove event\n\t\t\t\t\t\tthis._currentModeCallbacks.onMouseMove(drawEvent);\n\t\t\t\t\t\tthis._lastDrawEvent = drawEvent;\n\t\t\t\t\t} else if (this._dragState === \"pre-dragging\") {\n\t\t\t\t\t\t// This should always be set because of pointerdown event\n\t\t\t\t\t\tif (!this._lastDrawEvent) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst lastEventXY = {\n\t\t\t\t\t\t\tx: this._lastDrawEvent.containerX,\n\t\t\t\t\t\t\ty: this._lastDrawEvent.containerY,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst currentEventXY = {\n\t\t\t\t\t\t\tx: drawEvent.containerX,\n\t\t\t\t\t\t\ty: drawEvent.containerY,\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// We only want to prevent micro drags when we are\n\t\t\t\t\t\t// drawing as doing in on selection can cause janky\n\t\t\t\t\t\t// behaviours\n\t\t\t\t\t\tconst modeState = this._currentModeCallbacks.getState();\n\n\t\t\t\t\t\tconst pixelDistanceToCheck = cartesianDistance(\n\t\t\t\t\t\t\tlastEventXY,\n\t\t\t\t\t\t\tcurrentEventXY,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// We start off assuming it is not a microdrag\n\t\t\t\t\t\tlet isMicroDrag = false;\n\n\t\t\t\t\t\tif (modeState === \"drawing\") {\n\t\t\t\t\t\t\t// We want to ignore very small pointer movements when holding\n\t\t\t\t\t\t\t// the map down as these are normally done by accident when\n\t\t\t\t\t\t\t// drawing and is not an intended drag\n\t\t\t\t\t\t\tisMicroDrag =\n\t\t\t\t\t\t\t\tpixelDistanceToCheck < this._minPixelDragDistanceDrawing;\n\t\t\t\t\t\t} else if (modeState === \"selecting\") {\n\t\t\t\t\t\t\t// Similarly when selecting, we want to ignore very small pointer\n\t\t\t\t\t\t\t// movements when holding the map down as these are normally done\n\t\t\t\t\t\t\t// by accident when drawing and is not an intended drag\n\t\t\t\t\t\t\tisMicroDrag =\n\t\t\t\t\t\t\t\tpixelDistanceToCheck < this._minPixelDragDistanceSelecting;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Same as above, but when not drawing we generally want a much lower tolerance\n\t\t\t\t\t\t\tisMicroDrag = pixelDistanceToCheck < this._minPixelDragDistance;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// If it is a microdrag we do not register it by returning early\n\t\t\t\t\t\tif (isMicroDrag) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// If we are dragging it is not a context menu key up event any more\n\t\t\t\t\t\tthis._nextKeyUpIsContextMenu = false;\n\n\t\t\t\t\t\tthis._dragState = \"dragging\";\n\t\t\t\t\t\tthis._currentModeCallbacks.onDragStart(\n\t\t\t\t\t\t\tdrawEvent,\n\t\t\t\t\t\t\t(enabled: boolean) => {\n\t\t\t\t\t\t\t\tthis.setDraggability.bind(this)(enabled);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (this._dragState === \"dragging\") {\n\t\t\t\t\t\tthis._currentModeCallbacks.onDrag(drawEvent, (enabled: boolean) => {\n\t\t\t\t\t\t\tthis.setDraggability.bind(this)(enabled);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement(\"pointermove\");\n\t\t\t\t\tmapElement.addEventListener(\"pointermove\", callback);\n\t\t\t\t},\n\t\t\t\tunregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement(\"pointermove\");\n\t\t\t\t\tmapElement.removeEventListener(\"pointermove\", callback);\n\t\t\t\t},\n\t\t\t}),\n\t\t\tnew AdapterListener<BaseMouseListener>({\n\t\t\t\tname: \"contextmenu\",\n\t\t\t\tcallback: (event) => {\n\t\t\t\t\tif (!this._currentModeCallbacks) return;\n\n\t\t\t\t\t// We do not want the context menu to open\n\t\t\t\t\tevent.preventDefault();\n\n\t\t\t\t\t// We signify that the next keyup event is related to the context menu\n\t\t\t\t\t// and we want to set isContextMenu to true\n\t\t\t\t\tthis._nextKeyUpIsContextMenu = true;\n\t\t\t\t},\n\t\t\t\tregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement(\"contextmenu\");\n\t\t\t\t\tmapElement.addEventListener(\"contextmenu\", callback);\n\t\t\t\t},\n\t\t\t\tunregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement(\"contextmenu\");\n\t\t\t\t\tmapElement.removeEventListener(\"contextmenu\", callback);\n\t\t\t\t},\n\t\t\t}),\n\t\t\tnew AdapterListener<BasePointerListener>({\n\t\t\t\tname: \"pointerup\",\n\t\t\t\tcallback: (event) => {\n\t\t\t\t\tif (!this._currentModeCallbacks) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (event.target !== this.getMapEventElement(\"pointerup\")) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// We want to ignore pointer up events where the down event was not on the map element\n\t\t\t\t\tif (\n\t\t\t\t\t\tthis._ignoreMismatchedPointerEvents &&\n\t\t\t\t\t\tthis._lastPointerDownEventTarget !== event.target\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis._lastPointerDownEventTarget = undefined;\n\n\t\t\t\t\t// We don't support multitouch as this point in time\n\t\t\t\t\tif (!event.isPrimary) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst drawEvent = this.getDrawEventFromEvent(event);\n\n\t\t\t\t\tif (!drawEvent) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this._dragState === \"dragging\") {\n\t\t\t\t\t\tthis._currentModeCallbacks.onDragEnd(drawEvent, (enabled) => {\n\t\t\t\t\t\t\tthis.setDraggability.bind(this)(enabled);\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tthis._dragState === \"not-dragging\" ||\n\t\t\t\t\t\tthis._dragState === \"pre-dragging\"\n\t\t\t\t\t) {\n\t\t\t\t\t\t// If we're not dragging or about to drag we\n\t\t\t\t\t\t// can trigger the onClick event\n\t\t\t\t\t\t// We want to reset it to false after we have used it\n\t\t\t\t\t\tif (this._nextKeyUpIsContextMenu) {\n\t\t\t\t\t\t\tdrawEvent.isContextMenu = true;\n\t\t\t\t\t\t\tthis._nextKeyUpIsContextMenu = false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._currentModeCallbacks.onClick(drawEvent);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Ensure we go back to the regular behaviour\n\t\t\t\t\t// not dragging and re-enable dragging on the actual map\n\t\t\t\t\tthis._dragState = \"not-dragging\";\n\t\t\t\t\tthis.setDraggability(true);\n\t\t\t\t},\n\t\t\t\tregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement(\"pointerup\");\n\t\t\t\t\tmapElement.addEventListener(\"pointerup\", callback);\n\t\t\t\t},\n\t\t\t\tunregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement(\"pointerup\");\n\t\t\t\t\tmapElement.removeEventListener(\"pointerup\", callback);\n\t\t\t\t},\n\t\t\t}),\n\t\t\tnew AdapterListener({\n\t\t\t\tname: \"keyup\",\n\t\t\t\tcallback: (event: KeyboardEvent) => {\n\t\t\t\t\t// map has no keypress event, so we add one to the canvas itself\n\n\t\t\t\t\tif (!this._currentModeCallbacks) return;\n\n\t\t\t\t\tthis._heldKeys.delete(event.key);\n\n\t\t\t\t\tthis._currentModeCallbacks.onKeyUp({\n\t\t\t\t\t\tkey: event.key,\n\t\t\t\t\t\theldKeys: Array.from(this._heldKeys),\n\t\t\t\t\t\tpreventDefault: () => event.preventDefault(),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement(\"keyup\");\n\t\t\t\t\tmapElement.addEventListener(\"keyup\", callback);\n\t\t\t\t},\n\t\t\t\tunregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement(\"keyup\");\n\t\t\t\t\tmapElement.removeEventListener(\"keyup\", callback);\n\t\t\t\t},\n\t\t\t}),\n\t\t\tnew AdapterListener({\n\t\t\t\tname: \"keydown\",\n\t\t\t\tcallback: (event: KeyboardEvent) => {\n\t\t\t\t\tif (!this._currentModeCallbacks) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis._heldKeys.add(event.key);\n\n\t\t\t\t\tthis._currentModeCallbacks.onKeyDown({\n\t\t\t\t\t\tkey: event.key,\n\t\t\t\t\t\theldKeys: Array.from(this._heldKeys),\n\t\t\t\t\t\tpreventDefault: () => event.preventDefault(),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement(\"keydown\");\n\t\t\t\t\tmapElement.addEventListener(\"keydown\", callback);\n\t\t\t\t},\n\t\t\t\tunregister: (callback) => {\n\t\t\t\t\tconst mapElement = this.getMapEventElement(\"keydown\");\n\t\t\t\t\tmapElement.removeEventListener(\"keydown\", callback);\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t}\n\n\t/**\n\t * Unregisters the event listeners for the current drawing mode.\n\t * This is typically called when switching between drawing modes or\n\t * stopping the drawing process.\n\t */\n\tpublic unregister() {\n\t\tthis._listeners.forEach((listener) => {\n\t\t\tlistener.unregister();\n\t\t});\n\n\t\tthis.clear();\n\n\t\t// This has to come last because we call this._currentModeCallbacks.onClear()\n\t\tthis._currentModeCallbacks = undefined;\n\t\tthis._lastDrawEvent = undefined;\n\t\tthis._lastPointerDownEventTarget = undefined;\n\t\tthis._nextKeyUpIsContextMenu = false;\n\t}\n\n\tpublic abstract clear(): void;\n\n\tpublic abstract project(...args: Parameters<Project>): ReturnType<Project>;\n\n\tpublic abstract unproject(\n\t\t...args: Parameters<Unproject>\n\t): ReturnType<Unproject>;\n\n\tpublic abstract setCursor(\n\t\t...args: Parameters<SetCursor>\n\t): ReturnType<SetCursor>;\n\n\tpublic abstract getLngLatFromEvent(\n\t\t...event: Parameters<GetLngLatFromEvent>\n\t): ReturnType<GetLngLatFromEvent>;\n\n\tpublic abstract setDraggability(enabled: boolean): void;\n\n\tpublic abstract setDoubleClickToZoom(enabled: boolean): void;\n\n\tpublic abstract render(\n\t\tchanges: TerraDrawChanges,\n\t\tstyling: TerraDrawStylingFunction,\n\t): void;\n}\n","import {\n\tValidationReasonModeMismatch,\n\tValidationReasonFeatureNotPolygon,\n} from \"./validations/common-validations\";\nimport { ValidationReasonFeatureLessThanMinSize } from \"./validations/min-size.validation\";\nimport {\n\tValidationReasonFeatureNotPolygonOrLineString,\n\tValidationReasonFeatureSelfIntersects,\n} from \"./validations/not-self-intersecting.validation\";\nimport {\n\tValidationReasonFeatureInvalidCoordinates,\n\tValidationReasonFeatureNotPoint,\n\tValidationReasonFeatureInvalidCoordinatePrecision,\n} from \"./validations/point.validation\";\nimport {\n\tValidationReasonFeatureHasHoles,\n\tValidationReasonFeatureLessThanFourCoordinates,\n\tValidationReasonFeatureHasInvalidCoordinates,\n\tValidationReasonFeatureCoordinatesNotClosed,\n} from \"./validations/polygon.validation\";\n\nexport const ValidationReasons = {\n\tValidationReasonFeatureNotPoint,\n\tValidationReasonFeatureInvalidCoordinates,\n\tValidationReasonFeatureInvalidCoordinatePrecision,\n\tValidationReasonFeatureNotPolygon,\n\tValidationReasonFeatureHasHoles,\n\tValidationReasonFeatureLessThanFourCoordinates,\n\tValidationReasonFeatureHasInvalidCoordinates,\n\tValidationReasonFeatureCoordinatesNotClosed,\n\tValidationReasonFeatureNotPolygonOrLineString,\n\tValidationReasonFeatureSelfIntersects,\n\tValidationReasonFeatureLessThanMinSize,\n\tValidationReasonModeMismatch,\n};\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n\tCOMMON_PROPERTIES,\n\tZ_INDEX,\n\tFinishActions,\n} from \"../../common\";\n\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tModeUpdateOptions,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tFeatureId,\n\tGeoJSONStoreFeatures,\n\tStoreValidation,\n} from \"../../store/store\";\nimport { cartesianDistance } from \"../../geometry/measure/pixel-distance\";\nimport { ValidateLineStringFeature } from \"../../validations/linestring.validation\";\nimport { MutateFeatureBehavior, Mutations } from \"../mutate-feature.behavior\";\nimport { ReadFeatureBehavior } from \"../read-feature.behavior\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { ClosingPointsBehavior } from \"../closing-points.behavior\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\n\ntype TerraDrawFreehandLineStringModeKeyEvents = {\n\tcancel: KeyboardEvent[\"key\"] | null;\n\tfinish: KeyboardEvent[\"key\"] | null;\n};\n\nconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" };\n\ntype FreehandLineStringStyling = {\n\tlineStringWidth: NumericStyling;\n\tlineStringColor: HexColorStyling;\n\tlineStringOpacity: NumericStyling;\n\tclosingPointColor: HexColorStyling;\n\tclosingPointOpacity: NumericStyling;\n\tclosingPointWidth: NumericStyling;\n\tclosingPointOutlineColor: HexColorStyling;\n\tclosingPointOutlineWidth: NumericStyling;\n\tclosingPointOutlineOpacity: NumericStyling;\n};\n\ninterface Cursors {\n\tstart?: Cursor;\n\tclose?: Cursor;\n}\n\nconst defaultCursors = {\n\tstart: \"crosshair\",\n\tclose: \"pointer\",\n} as Required<Cursors>;\n\ninterface TerraDrawFreehandLineStringModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tminDistance?: number;\n\tkeyEvents?: TerraDrawFreehandLineStringModeKeyEvents | null;\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawFreehandLineStringMode extends TerraDrawBaseDrawMode<FreehandLineStringStyling> {\n\tmode = \"freehand-linestring\";\n\n\tprivate canClose = false;\n\tprivate currentId: FeatureId | undefined;\n\tprivate minDistance: number = 20;\n\tprivate keyEvents: TerraDrawFreehandLineStringModeKeyEvents =\n\t\tdefaultKeyEvents;\n\tprivate cursors: Required<Cursors> = defaultCursors;\n\tprivate preventNewFeature = false;\n\n\t// Behaviors\n\tprivate mutateFeature!: MutateFeatureBehavior;\n\tprivate readFeature!: ReadFeatureBehavior;\n\tprivate pixelDistance!: PixelDistanceBehavior;\n\tprivate closingPoints!: ClosingPointsBehavior;\n\n\tconstructor(\n\t\toptions?: TerraDrawFreehandLineStringModeOptions<FreehandLineStringStyling>,\n\t) {\n\t\tsuper(options, true);\n\t\tthis.updateOptions(options);\n\t}\n\n\tpublic updateOptions(\n\t\toptions?: ModeUpdateOptions<\n\t\t\tTerraDrawFreehandLineStringModeOptions<FreehandLineStringStyling>\n\t\t>,\n\t): void {\n\t\tsuper.updateOptions(options);\n\n\t\tif (options?.minDistance) {\n\t\t\tthis.minDistance = options.minDistance;\n\t\t}\n\n\t\tif (options?.keyEvents === null) {\n\t\t\tthis.keyEvents = { cancel: null, finish: null };\n\t\t} else if (options?.keyEvents) {\n\t\t\tthis.keyEvents = { ...this.keyEvents, ...options.keyEvents };\n\t\t}\n\n\t\tif (options?.cursors) {\n\t\t\tthis.cursors = { ...this.cursors, ...options.cursors };\n\t\t}\n\t}\n\n\tprivate close() {\n\t\tif (this.currentId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst updated = this.mutateFeature.updateLineString({\n\t\t\tfeatureId: this.currentId,\n\t\t\tpropertyMutations: {\n\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: undefined,\n\t\t\t},\n\t\t\tcontext: { updateType: UpdateTypes.Finish, action: FinishActions.Draw },\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst featureId = this.currentId;\n\n\t\tthis.closingPoints.delete();\n\n\t\tthis.canClose = false;\n\t\tthis.currentId = undefined;\n\n\t\t// Go back to started state\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.onFinish(featureId, {\n\t\t\tmode: this.mode,\n\t\t\taction: FinishActions.Draw,\n\t\t});\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.start);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonMouseMove(event: TerraDrawMouseEvent) {\n\t\tif (this.currentId === undefined || this.canClose === false) {\n\t\t\tthis.setCursor(this.cursors.start);\n\t\t\treturn;\n\t\t}\n\n\t\tconst [previousLng, previousLat] = this.readFeature.getCoordinate(\n\t\t\tthis.currentId,\n\t\t\t-2,\n\t\t);\n\t\tconst { x, y } = this.project(previousLng, previousLat);\n\t\tconst distance = cartesianDistance(\n\t\t\t{ x, y },\n\t\t\t{ x: event.containerX, y: event.containerY },\n\t\t);\n\n\t\tconst [closingLng, closingLat] = this.readFeature.getCoordinate(\n\t\t\tthis.currentId,\n\t\t\t-1,\n\t\t);\n\t\tconst { x: closingX, y: closingY } = this.project(closingLng, closingLat);\n\t\tconst closingDistance = cartesianDistance(\n\t\t\t{ x: closingX, y: closingY },\n\t\t\t{ x: event.containerX, y: event.containerY },\n\t\t);\n\n\t\tif (closingDistance < this.pointerDistance) {\n\t\t\tthis.setCursor(this.cursors.close);\n\t\t} else {\n\t\t\tthis.setCursor(this.cursors.start);\n\t\t}\n\n\t\t// The cursor must have moved a minimum distance\n\t\t// before we add another coordinate\n\t\tif (distance < this.minDistance) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst updated = this.mutateFeature.updateLineString({\n\t\t\tfeatureId: this.currentId,\n\t\t\tcoordinateMutations: [\n\t\t\t\t{\n\t\t\t\t\ttype: Mutations.InsertAfter,\n\t\t\t\t\tindex: -1,\n\t\t\t\t\tcoordinate: [event.lng, event.lat],\n\t\t\t\t},\n\t\t\t],\n\t\t\tcontext: { updateType: UpdateTypes.Provisional },\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.closingPoints.update(updated.geometry.coordinates);\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\tif (\n\t\t\t(event.button === \"right\" &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.rightClick, event)) ||\n\t\t\t(event.button === \"left\" &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.leftClick, event)) ||\n\t\t\t(event.isContextMenu &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.contextMenu, event))\n\t\t) {\n\t\t\tif (this.preventNewFeature) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.canClose === false) {\n\t\t\t\tconst { id: createdId, geometry } = this.mutateFeature.createLineString(\n\t\t\t\t\t{\n\t\t\t\t\t\tcoordinates: [\n\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t\t[event.lng, event.lat],\n\t\t\t\t\t\t],\n\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\tmode: this.mode,\n\t\t\t\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tthis.closingPoints.create(geometry.coordinates);\n\t\t\t\tthis.currentId = createdId;\n\t\t\t\tthis.canClose = true;\n\n\t\t\t\t// We could already be in drawing due to updating the existing linestring\n\t\t\t\t// via afterFeatureUpdated\n\t\t\t\tif (this.state !== \"drawing\") {\n\t\t\t\t\tthis.setDrawing();\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonKeyUp(event: TerraDrawKeyboardEvent) {\n\t\tif (event.key === this.keyEvents.cancel) {\n\t\t\tthis.cleanUp();\n\t\t} else if (event.key === this.keyEvents.finish) {\n\t\t\tif (this.canClose === true) {\n\t\t\t\tthis.close();\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tonDragStart() {}\n\n\t/** @internal */\n\tonDrag() {}\n\n\t/** @internal */\n\tonDragEnd() {}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tconst cleanUpId = this.currentId;\n\n\t\tthis.currentId = undefined;\n\t\tthis.canClose = false;\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.mutateFeature.deleteFeatureIfPresent(cleanUpId);\n\t\tthis.closingPoints.delete();\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"LineString\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tstyles.lineStringColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.lineStringColor,\n\t\t\t\tstyles.lineStringColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.lineStringOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.lineStringOpacity,\n\t\t\t\tstyles.lineStringOpacity === undefined ? 1 : styles.lineStringOpacity,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.lineStringWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.lineStringWidth,\n\t\t\t\tstyles.lineStringWidth,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.zIndex = Z_INDEX.LAYER_ONE;\n\n\t\t\treturn styles;\n\t\t} else if (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"Point\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.closingPointWidth,\n\t\t\t\tstyles.pointWidth,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.closingPointOpacity,\n\t\t\t\t1,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.closingPointColor,\n\t\t\t\tstyles.pointColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.closingPointOutlineColor,\n\t\t\t\tstyles.pointOutlineColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.closingPointOutlineOpacity,\n\t\t\t\t1,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles.closingPointOutlineWidth,\n\t\t\t\t2,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.zIndex = Z_INDEX.LAYER_FIVE;\n\n\t\t\treturn styles;\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): StoreValidation {\n\t\treturn this.validateModeFeature(feature, (baseValidatedFeature) =>\n\t\t\tValidateLineStringFeature(baseValidatedFeature, this.coordinatePrecision),\n\t\t);\n\t}\n\n\tafterFeatureUpdated(feature: GeoJSONStoreFeatures) {\n\t\t// NOTE: This handles the case we are currently drawing a linestring\n\t\t// We need to reset the drawing state because it is very complicated (impossible?)\n\t\t// to recover the drawing state after a feature update\n\t\tif (this.currentId === feature.id) {\n\t\t\tthis.closingPoints.delete();\n\t\t\tthis.canClose = false;\n\t\t\tthis.currentId = undefined;\n\t\t}\n\t}\n\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.readFeature = new ReadFeatureBehavior(config);\n\t\tthis.mutateFeature = new MutateFeatureBehavior(config, {\n\t\t\tvalidate: this.validate,\n\t\t});\n\t\tthis.pixelDistance = new PixelDistanceBehavior(config);\n\t\tthis.closingPoints = new ClosingPointsBehavior(\n\t\t\tconfig,\n\t\t\tthis.pixelDistance,\n\t\t\tthis.mutateFeature,\n\t\t\tthis.readFeature,\n\t\t);\n\t}\n}\n","/**\n * Checks if a value is a valid JSON value.\n * @param value - The value to check\n * @returns true if the value is valid JSON, false otherwise\n */\nexport function isValidJSONValue(value: unknown): value is JSON {\n\t// null is valid JSON\n\tif (value === null) {\n\t\treturn true;\n\t}\n\n\t// boolean is valid JSON\n\tif (typeof value === \"boolean\") {\n\t\treturn true;\n\t}\n\n\t// string is valid JSON\n\tif (typeof value === \"string\") {\n\t\treturn true;\n\t}\n\n\t// undefined is not valid JSON\n\tif (value === undefined) {\n\t\treturn false;\n\t}\n\n\t// number must be finite to be valid JSON\n\tif (typeof value === \"number\") {\n\t\treturn Number.isFinite(value);\n\t}\n\n\t// BigInt is not a valid JSON type\n\tif (typeof value === \"bigint\") {\n\t\treturn false;\n\t}\n\n\t// Symbols are not valid JSON types\n\tif (typeof value === \"symbol\") {\n\t\treturn false;\n\t}\n\n\t// Functions are not valid JSON types\n\tif (typeof value === \"function\") {\n\t\treturn false;\n\t}\n\n\t// Regular expressions are not valid JSON types\n\tif (value instanceof RegExp) {\n\t\treturn false;\n\t}\n\n\t// Maps are not valid JSON types\n\tif (value instanceof Map) {\n\t\treturn false;\n\t}\n\n\t// Sets are not valid JSON types\n\tif (value instanceof Set) {\n\t\treturn false;\n\t}\n\n\t// Dates are not valid JSON types\n\tif (value instanceof Date) {\n\t\treturn false;\n\t}\n\n\t// Class instances are not valid JSON types (only plain objects)\n\tif (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n\t\tconst proto = Object.getPrototypeOf(value);\n\t\tif (proto !== Object.prototype && proto !== null) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Typed Arrays are not valid JSON types\n\tif (ArrayBuffer.isView(value) && !(value instanceof DataView)) {\n\t\treturn false;\n\t}\n\n\t// Array: all elements must be valid JSON\n\tif (Array.isArray(value)) {\n\t\tfor (const item of value) {\n\t\t\tif (!isValidJSONValue(item)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Object: must be plain object with string keys\n\tif (typeof value === \"object\") {\n\t\treturn Object.keys(value).every(\n\t\t\t(key) =>\n\t\t\t\ttypeof key === \"string\" &&\n\t\t\t\tisValidJSONValue(value[key as keyof typeof value] as unknown),\n\t\t);\n\t}\n\n\t// Other types (shouldn't reach here) are not valid JSON\n\treturn false;\n}\n","import {\n\tTerraDrawMouseEvent,\n\tTerraDrawAdapterStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n\tCOMMON_PROPERTIES,\n\tZ_INDEX,\n\tUrlStyling,\n\tMARKER_URL_DEFAULT,\n\tFinishActions,\n} from \"../../common\";\nimport {\n\tFeatureId,\n\tGeoJSONStoreFeatures,\n\tStoreValidation,\n} from \"../../store/store\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tBaseModeOptions,\n\tCustomStyling,\n\tModeUpdateOptions,\n\tTerraDrawBaseDrawMode,\n} from \"../base.mode\";\nimport { ValidatePointFeature } from \"../../validations/point.validation\";\nimport { BehaviorConfig } from \"../base.behavior\";\nimport { ClickBoundingBoxBehavior } from \"../click-bounding-box.behavior\";\nimport { PixelDistanceBehavior } from \"../pixel-distance.behavior\";\nimport { MutateFeatureBehavior, Mutations } from \"../mutate-feature.behavior\";\nimport { PointSearchBehavior } from \"../point-search.behavior\";\n\ntype MarkerModeStyling = {\n\t/** Marker must be a PNG or JPG  */\n\tmarkerUrl: UrlStyling;\n\tmarkerHeight: NumericStyling;\n\tmarkerWidth: NumericStyling;\n};\n\ninterface Cursors {\n\tcreate?: Cursor;\n\tdragStart?: Cursor;\n\tdragEnd?: Cursor;\n}\n\nconst defaultCursors = {\n\tcreate: \"crosshair\",\n\tdragStart: \"grabbing\",\n\tdragEnd: \"crosshair\",\n} as Required<Cursors>;\n\ninterface TerraDrawMarkerModeOptions<T extends CustomStyling>\n\textends BaseModeOptions<T> {\n\tcursors?: Cursors;\n\teditable?: boolean;\n}\n\nexport class TerraDrawMarkerMode extends TerraDrawBaseDrawMode<MarkerModeStyling> {\n\tmode = \"marker\" as const;\n\n\t// Options\n\tprivate cursors: Required<Cursors> = defaultCursors;\n\tprivate editable: boolean = false;\n\n\t// Internal state\n\tprivate editedFeatureId: FeatureId | undefined;\n\n\t// Behaviors\n\tprivate pixelDistance!: PixelDistanceBehavior;\n\tprivate clickBoundingBox!: ClickBoundingBoxBehavior;\n\tprivate pointSearch!: PointSearchBehavior;\n\tprivate mutateFeature!: MutateFeatureBehavior;\n\n\tconstructor(options?: TerraDrawMarkerModeOptions<MarkerModeStyling>) {\n\t\tsuper(options, true);\n\t\tthis.updateOptions(options);\n\t}\n\n\tupdateOptions(\n\t\toptions?: ModeUpdateOptions<TerraDrawMarkerModeOptions<MarkerModeStyling>>,\n\t): void {\n\t\tsuper.updateOptions(options);\n\n\t\tif (options?.cursors) {\n\t\t\tthis.cursors = { ...this.cursors, ...options.cursors };\n\t\t}\n\n\t\tif (options?.editable) {\n\t\t\tthis.editable = options.editable;\n\t\t}\n\t}\n\n\t/** @internal */\n\tstart() {\n\t\tthis.setStarted();\n\t\tthis.setCursor(this.cursors.create);\n\t}\n\n\t/** @internal */\n\tstop() {\n\t\tthis.cleanUp();\n\t\tthis.setStopped();\n\t\tthis.setCursor(\"unset\");\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\tif (\n\t\t\t(event.button === \"right\" &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.rightClick, event)) ||\n\t\t\t(event.isContextMenu &&\n\t\t\t\tthis.allowPointerEvent(this.pointerEvents.contextMenu, event))\n\t\t) {\n\t\t\tthis.onRightClick(event);\n\t\t\treturn;\n\t\t} else if (\n\t\t\tevent.button === \"left\" &&\n\t\t\tthis.allowPointerEvent(this.pointerEvents.leftClick, event)\n\t\t) {\n\t\t\tthis.onLeftClick(event);\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/** @internal */\n\tonMouseMove() {}\n\n\t/** @internal */\n\tonKeyDown() {}\n\n\t/** @internal */\n\tonKeyUp() {}\n\n\t/** @internal */\n\tcleanUp() {\n\t\tthis.editedFeatureId = undefined;\n\t}\n\n\tonDragStart(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (!this.allowPointerEvent(this.pointerEvents.onDragStart, event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.editable) {\n\t\t\tconst nearestPointFeature =\n\t\t\t\tthis.pointSearch.getNearestPointFeature(event);\n\t\t\tthis.editedFeatureId = nearestPointFeature?.id;\n\t\t}\n\n\t\t// We only need to stop the map dragging if\n\t\t// we actually have something selected\n\t\tif (!this.editedFeatureId) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Drag Feature\n\t\tthis.setCursor(this.cursors.dragStart);\n\n\t\tsetMapDraggability(false);\n\t}\n\n\t/** @internal */\n\tonDrag(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (!this.allowPointerEvent(this.pointerEvents.onDrag, event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.editedFeatureId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.mutateFeature.updatePoint({\n\t\t\tfeatureId: this.editedFeatureId,\n\t\t\tcoordinateMutations: {\n\t\t\t\ttype: Mutations.Replace,\n\t\t\t\tcoordinates: [event.lng, event.lat],\n\t\t\t},\n\t\t\tpropertyMutations: {\n\t\t\t\t[COMMON_PROPERTIES.EDITED]: true,\n\t\t\t},\n\t\t\tcontext: { updateType: UpdateTypes.Provisional },\n\t\t});\n\t}\n\n\t/** @internal */\n\tonDragEnd(\n\t\tevent: TerraDrawMouseEvent,\n\t\tsetMapDraggability: (enabled: boolean) => void,\n\t) {\n\t\tif (!this.allowPointerEvent(this.pointerEvents.onDragEnd, event)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.editedFeatureId === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst updated = this.mutateFeature.updatePoint({\n\t\t\tfeatureId: this.editedFeatureId,\n\t\t\tpropertyMutations: {\n\t\t\t\tmode: this.mode,\n\t\t\t\t[COMMON_PROPERTIES.EDITED]: false,\n\t\t\t},\n\t\t\tcontext: { updateType: UpdateTypes.Finish, action: \"edit\" },\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst featureId = this.editedFeatureId;\n\n\t\tthis.setCursor(this.cursors.dragEnd);\n\t\tthis.editedFeatureId = undefined;\n\t\tsetMapDraggability(true);\n\n\t\tthis.onFinish(featureId, {\n\t\t\tmode: this.mode,\n\t\t\taction: FinishActions.Draw,\n\t\t});\n\t}\n\n\tregisterBehaviors(config: BehaviorConfig) {\n\t\tthis.pixelDistance = new PixelDistanceBehavior(config);\n\t\tthis.clickBoundingBox = new ClickBoundingBoxBehavior(config);\n\t\tthis.pointSearch = new PointSearchBehavior(\n\t\t\tconfig,\n\t\t\tthis.pixelDistance,\n\t\t\tthis.clickBoundingBox,\n\t\t);\n\t\tthis.mutateFeature = new MutateFeatureBehavior(config, {\n\t\t\tvalidate: this.validate,\n\t\t});\n\t}\n\n\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (\n\t\t\tfeature.type === \"Feature\" &&\n\t\t\tfeature.geometry.type === \"Point\" &&\n\t\t\tfeature.properties.mode === this.mode\n\t\t) {\n\t\t\tstyles.zIndex = Z_INDEX.LAYER_THREE;\n\t\t\tstyles.markerHeight = this.getNumericStylingValue(\n\t\t\t\tthis.styles?.markerHeight,\n\t\t\t\t40,\n\t\t\t\tfeature,\n\t\t\t);\n\t\t\tstyles.markerWidth = this.getNumericStylingValue(\n\t\t\t\tthis.styles?.markerWidth,\n\t\t\t\t32,\n\t\t\t\tfeature,\n\t\t\t);\n\t\t\tstyles.markerUrl = this.getUrlStylingValue(\n\t\t\t\tthis.styles?.markerUrl,\n\t\t\t\tMARKER_URL_DEFAULT,\n\t\t\t\tfeature,\n\t\t\t);\n\t\t}\n\n\t\treturn styles;\n\t}\n\n\tvalidateFeature(feature: unknown): StoreValidation {\n\t\treturn this.validateModeFeature(feature, (baseValidatedFeature) =>\n\t\t\tValidatePointFeature(baseValidatedFeature, this.coordinatePrecision),\n\t\t);\n\t}\n\n\tprivate onLeftClick(event: TerraDrawMouseEvent) {\n\t\tconst feature = this.mutateFeature.createPoint({\n\t\t\tcoordinates: [event.lng, event.lat],\n\t\t\tproperties: {\n\t\t\t\tmode: this.mode,\n\t\t\t\t[COMMON_PROPERTIES.MARKER]: true,\n\t\t\t},\n\t\t\tcontext: { updateType: UpdateTypes.Finish, action: FinishActions.Draw },\n\t\t});\n\n\t\tif (feature) {\n\t\t\tthis.onFinish(feature.id, {\n\t\t\t\tmode: this.mode,\n\t\t\t\taction: FinishActions.Draw,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate onRightClick(event: TerraDrawMouseEvent) {\n\t\t// We only want to be able to delete points if the mode is editable\n\t\tif (!this.editable) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst clickedFeature = this.pointSearch.getNearestPointFeature(event);\n\n\t\tif (clickedFeature) {\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(clickedFeature.id as FeatureId);\n\t\t}\n\t}\n\n\tafterFeatureUpdated(feature: GeoJSONStoreFeatures) {\n\t\t// If we are editing a point by dragging it we want to clear that state\n\t\t// up as new point location might be completely  different in terms of it's location\n\t\tif (this.editedFeatureId === feature.id) {\n\t\t\tthis.editedFeatureId = undefined;\n\t\t\tthis.setCursor(this.cursors.create);\n\t\t}\n\t}\n}\n","/**\n * @module terra-draw\n */\nimport {\n\tTerraDrawAdapter,\n\tTerraDrawAdapterStyling,\n\tGetLngLatFromEvent,\n\tProject,\n\tSetCursor,\n\tTerraDrawChanges,\n\tTerraDrawStylingFunction,\n\tUnproject,\n\tHexColor,\n\tTerraDrawKeyboardEvent,\n\tTerraDrawMouseEvent,\n\tSELECT_PROPERTIES,\n\tOnFinishContext,\n\tCOMMON_PROPERTIES,\n\tTerraDrawGeoJSONStore,\n\tTerraDrawOnChangeContext,\n\tProjection,\n\tTerraDrawHandledEvents,\n} from \"./common\";\nimport {\n\tModeTypes,\n\tTerraDrawBaseDrawMode,\n\tTerraDrawBaseSelectMode,\n} from \"./modes/base.mode\";\nimport { TerraDrawCircleMode } from \"./modes/circle/circle.mode\";\nimport { TerraDrawFreehandMode } from \"./modes/freehand/freehand.mode\";\nimport { TerraDrawLineStringMode } from \"./modes/linestring/linestring.mode\";\nimport { TerraDrawPointMode } from \"./modes/point/point.mode\";\nimport { TerraDrawPolygonMode } from \"./modes/polygon/polygon.mode\";\nimport { TerraDrawRectangleMode } from \"./modes/rectangle/rectangle.mode\";\nimport { TerraDrawRenderMode } from \"./modes/render/render.mode\";\nimport { TerraDrawSelectMode } from \"./modes/select/select.mode\";\nimport { TerraDrawStaticMode } from \"./modes/static/static.mode\";\nimport {\n\tBBoxPolygon,\n\tFeatureId,\n\tGeoJSONStore,\n\tGeoJSONStoreFeatures,\n\tGeoJSONStoreGeometries,\n\tIdStrategy,\n\tJSON,\n\tJSONObject,\n\tStoreChangeHandler,\n\tStoreValidation,\n} from \"./store/store\";\nimport { BehaviorConfig } from \"./modes/base.behavior\";\nimport { cartesianDistance } from \"./geometry/measure/pixel-distance\";\nimport { pixelDistanceToLine } from \"./geometry/measure/pixel-distance-to-line\";\nimport { Feature, LineString, Polygon, Position } from \"geojson\";\nimport { pointInPolygon } from \"./geometry/boolean/point-in-polygon\";\nimport { createBBoxFromPoint } from \"./geometry/shape/create-bbox\";\nimport { ValidateMinAreaSquareMeters } from \"./validations/min-size.validation\";\nimport { ValidateMaxAreaSquareMeters } from \"./validations/max-size.validation\";\nimport { ValidateNotSelfIntersecting } from \"./validations/not-self-intersecting.validation\";\nimport { TerraDrawAngledRectangleMode } from \"./modes/angled-rectangle/angled-rectangle.mode\";\nimport { TerraDrawSectorMode } from \"./modes/sector/sector.mode\";\nimport { TerraDrawSensorMode } from \"./modes/sensor/sensor.mode\";\nimport * as TerraDrawExtend from \"./extend\";\nimport { hasModeProperty } from \"./store/store-feature-validation\";\nimport { ValidationReasons } from \"./validation-reasons\";\nimport { TerraDrawFreehandLineStringMode } from \"./modes/freehand-linestring/freehand-linestring.mode\";\nimport { lngLatToWebMercatorXY } from \"./geometry/project/web-mercator\";\nimport { transformRotateWebMercator } from \"./geometry/transform/rotate\";\nimport { transformScaleWebMercatorCoordinates } from \"./geometry/transform/scale\";\nimport { limitPrecision } from \"./geometry/limit-decimal-precision\";\nimport { isValidJSONValue } from \"./store/valid-json\";\nimport { haversineDistanceKilometers } from \"./geometry/measure/haversine-distance\";\nimport { TerraDrawMarkerMode } from \"./modes/marker/marker.mode\";\n\n// Helper type to determine the instance type of a class\ntype InstanceType<T extends new (...args: any[]) => any> = T extends new (\n\t...args: any[]\n) => infer R\n\t? R\n\t: never;\n\ntype FinishListener = (id: FeatureId, context: OnFinishContext) => void;\ntype ChangeListener = (\n\tids: FeatureId[],\n\ttype: string,\n\tcontext?: TerraDrawOnChangeContext,\n) => void;\ntype SelectListener = (id: FeatureId) => void;\ntype DeselectListener = (id: FeatureId) => void;\n\ninterface TerraDrawEventListeners {\n\tready: () => void;\n\tfinish: FinishListener;\n\tchange: ChangeListener;\n\tselect: SelectListener;\n\tdeselect: DeselectListener;\n}\n\ntype GetFeatureOptions = {\n\tpointerDistance?: number;\n\tincludePolygonsWithinPointerDistance?: boolean;\n\tignoreSelectFeatures?: boolean;\n\tignoreCoordinatePoints?: boolean;\n\tignoreCurrentlyDrawing?: boolean;\n\tignoreClosingPoints?: boolean;\n\tignoreSnappingPoints?: boolean;\n\taddClosestCoordinateInfoToProperties?: boolean;\n};\n\ntype TerraDrawEvents = keyof TerraDrawEventListeners;\n\nclass TerraDraw {\n\tprivate _modes: {\n\t\t[mode: string]: TerraDrawBaseDrawMode<any> | TerraDrawBaseSelectMode<any>;\n\t};\n\tprivate _mode: TerraDrawBaseDrawMode<any> | TerraDrawBaseSelectMode<any>;\n\tprivate _adapter: TerraDrawAdapter;\n\tprivate _enabled = false;\n\tprivate _store: TerraDrawGeoJSONStore;\n\tprivate _eventListeners: {\n\t\tready: (() => void)[];\n\t\tchange: ChangeListener[];\n\t\tfinish: FinishListener[];\n\t\tselect: SelectListener[];\n\t\tdeselect: DeselectListener[];\n\t};\n\tprivate _instanceSelectModes: string[];\n\n\tconstructor(options: {\n\t\tadapter: TerraDrawAdapter;\n\t\tmodes: TerraDrawBaseDrawMode<any>[];\n\t\tidStrategy?: IdStrategy<FeatureId>;\n\t\ttracked?: boolean;\n\t}) {\n\t\tthis._adapter = options.adapter;\n\t\tthis._instanceSelectModes = [];\n\n\t\tthis._mode = new TerraDrawStaticMode();\n\n\t\t// Keep track of if there are duplicate modes\n\t\tconst duplicateModeTracker = new Set();\n\n\t\t// Construct a map of the mode name to the mode\n\t\tconst modesMap = options.modes.reduce<{\n\t\t\t[mode: string]: TerraDrawBaseDrawMode<any>;\n\t\t}>((modeMap, currentMode) => {\n\t\t\tif (duplicateModeTracker.has(currentMode.mode)) {\n\t\t\t\tthrow new Error(`There is already a ${currentMode.mode} mode provided`);\n\t\t\t}\n\t\t\tduplicateModeTracker.add(currentMode.mode);\n\t\t\tmodeMap[currentMode.mode] = currentMode;\n\t\t\treturn modeMap;\n\t\t}, {});\n\n\t\t// Construct an array of the mode keys (names)\n\t\tconst modeKeys = Object.keys(modesMap);\n\n\t\t// Ensure at least one draw mode is provided\n\t\tif (modeKeys.length === 0) {\n\t\t\tthrow new Error(\"No modes provided\");\n\t\t}\n\n\t\t// Track the select modes in the order they are provided\n\t\tmodeKeys.forEach((mode) => {\n\t\t\tif (modesMap[mode].type !== ModeTypes.Select) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._instanceSelectModes.push(mode);\n\t\t});\n\n\t\tthis._modes = { ...modesMap, static: this._mode };\n\t\tthis._eventListeners = {\n\t\t\tchange: [],\n\t\t\tselect: [],\n\t\t\tdeselect: [],\n\t\t\tfinish: [],\n\t\t\tready: [],\n\t\t};\n\t\tthis._store = new GeoJSONStore<\n\t\t\tTerraDrawOnChangeContext | undefined,\n\t\t\tFeatureId\n\t\t>({\n\t\t\ttracked: options.tracked ? true : false,\n\t\t\tidStrategy: options.idStrategy ? options.idStrategy : undefined,\n\t\t});\n\n\t\tconst getChanged = (\n\t\t\tids: FeatureId[],\n\t\t): {\n\t\t\tchanged: GeoJSONStoreFeatures[];\n\t\t\tunchanged: GeoJSONStoreFeatures[];\n\t\t} => {\n\t\t\tconst changed: GeoJSONStoreFeatures[] = [];\n\n\t\t\tconst unchanged = this._store.copyAll().filter((f) => {\n\t\t\t\tif (ids.includes(f.id as string)) {\n\t\t\t\t\tchanged.push(f);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t});\n\n\t\t\treturn { changed, unchanged };\n\t\t};\n\n\t\tconst onFinish = (finishedId: FeatureId, context: OnFinishContext) => {\n\t\t\tif (!this._enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._eventListeners.finish.forEach((listener) => {\n\t\t\t\tlistener(finishedId, context);\n\t\t\t});\n\t\t};\n\n\t\tconst onChange: StoreChangeHandler<TerraDrawOnChangeContext | undefined> = (\n\t\t\tids,\n\t\t\tevent,\n\t\t\tcontext,\n\t\t) => {\n\t\t\tif (!this._enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._eventListeners.change.forEach((listener) => {\n\t\t\t\tlistener(ids, event, context);\n\t\t\t});\n\n\t\t\tconst { changed, unchanged } = getChanged(ids);\n\n\t\t\tif (event === \"create\") {\n\t\t\t\tthis._adapter.render(\n\t\t\t\t\t{\n\t\t\t\t\t\tcreated: changed,\n\t\t\t\t\t\tdeletedIds: [],\n\t\t\t\t\t\tunchanged,\n\t\t\t\t\t\tupdated: [],\n\t\t\t\t\t},\n\t\t\t\t\tthis.getModeStyles(),\n\t\t\t\t);\n\t\t\t} else if (event === \"update\") {\n\t\t\t\tthis._adapter.render(\n\t\t\t\t\t{\n\t\t\t\t\t\tcreated: [],\n\t\t\t\t\t\tdeletedIds: [],\n\t\t\t\t\t\tunchanged,\n\t\t\t\t\t\tupdated: changed,\n\t\t\t\t\t},\n\t\t\t\t\tthis.getModeStyles(),\n\t\t\t\t);\n\t\t\t} else if (event === \"delete\") {\n\t\t\t\tthis._adapter.render(\n\t\t\t\t\t{ created: [], deletedIds: ids, unchanged, updated: [] },\n\t\t\t\t\tthis.getModeStyles(),\n\t\t\t\t);\n\t\t\t} else if (event === \"styling\") {\n\t\t\t\tthis._adapter.render(\n\t\t\t\t\t{ created: [], deletedIds: [], unchanged, updated: [] },\n\t\t\t\t\tthis.getModeStyles(),\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\tconst onSelect = (selectedId: string) => {\n\t\t\tif (!this._enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._eventListeners.select.forEach((listener) => {\n\t\t\t\tlistener(selectedId);\n\t\t\t});\n\n\t\t\tconst { changed, unchanged } = getChanged([selectedId]);\n\n\t\t\tthis._adapter.render(\n\t\t\t\t{ created: [], deletedIds: [], unchanged, updated: changed },\n\t\t\t\tthis.getModeStyles(),\n\t\t\t);\n\t\t};\n\n\t\tconst onDeselect = (deselectedId: string) => {\n\t\t\tif (!this._enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._eventListeners.deselect.forEach((listener) => {\n\t\t\t\tlistener(deselectedId);\n\t\t\t});\n\n\t\t\tconst { changed, unchanged } = getChanged([deselectedId]);\n\n\t\t\t// onDeselect can be called after a delete call which means that\n\t\t\t// you are deselecting a feature that has been deleted. We\n\t\t\t// double check here to ensure that the feature still exists.\n\t\t\tif (changed) {\n\t\t\t\tthis._adapter.render(\n\t\t\t\t\t{\n\t\t\t\t\t\tcreated: [],\n\t\t\t\t\t\tdeletedIds: [],\n\t\t\t\t\t\tunchanged,\n\t\t\t\t\t\tupdated: changed,\n\t\t\t\t\t},\n\t\t\t\t\tthis.getModeStyles(),\n\t\t\t\t);\n\t\t\t}\n\t\t};\n\n\t\t// Register stores and callbacks\n\t\tObject.keys(this._modes).forEach((modeId) => {\n\t\t\tthis._modes[modeId].register({\n\t\t\t\tmode: modeId,\n\t\t\t\tstore: this._store,\n\t\t\t\tsetCursor: this._adapter.setCursor.bind(this._adapter),\n\t\t\t\tproject: this._adapter.project.bind(this._adapter),\n\t\t\t\tunproject: this._adapter.unproject.bind(this._adapter),\n\t\t\t\tsetDoubleClickToZoom: this._adapter.setDoubleClickToZoom.bind(\n\t\t\t\t\tthis._adapter,\n\t\t\t\t),\n\t\t\t\tonChange: onChange,\n\t\t\t\tonSelect: onSelect,\n\t\t\t\tonDeselect: onDeselect,\n\t\t\t\tonFinish: onFinish,\n\t\t\t\tcoordinatePrecision: this._adapter.getCoordinatePrecision(),\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate checkEnabled() {\n\t\tif (!this._enabled) {\n\t\t\tthrow new Error(\"Terra Draw is not enabled\");\n\t\t}\n\t}\n\n\tprivate getModeStyles() {\n\t\tconst modeStyles: {\n\t\t\t[key: string]: (feature: GeoJSONStoreFeatures) => TerraDrawAdapterStyling;\n\t\t} = {};\n\n\t\tconst activeSelectMode = this._instanceSelectModes.includes(this._mode.mode)\n\t\t\t? this._mode.mode\n\t\t\t: undefined;\n\n\t\tObject.keys(this._modes).forEach((mode) => {\n\t\t\tmodeStyles[mode] = (feature: GeoJSONStoreFeatures) => {\n\t\t\t\t// If the feature is selected, we want to use the select mode styling\n\t\t\t\tif (\n\t\t\t\t\tactiveSelectMode &&\n\t\t\t\t\tfeature.properties[SELECT_PROPERTIES.SELECTED]\n\t\t\t\t) {\n\t\t\t\t\treturn this._modes[activeSelectMode].styleFeature.bind(\n\t\t\t\t\t\tthis._modes[activeSelectMode],\n\t\t\t\t\t)(feature);\n\t\t\t\t}\n\n\t\t\t\t// Otherwise use regular styling\n\t\t\t\treturn this._modes[mode].styleFeature.bind(this._modes[mode])(feature);\n\t\t\t};\n\t\t});\n\t\treturn modeStyles;\n\t}\n\n\tprivate featuresAtLocation(\n\t\t{\n\t\t\tlng,\n\t\t\tlat,\n\t\t}: {\n\t\t\tlng: number;\n\t\t\tlat: number;\n\t\t},\n\t\toptions?: GetFeatureOptions,\n\t) {\n\t\tconst pointerDistance =\n\t\t\toptions && options.pointerDistance !== undefined\n\t\t\t\t? options.pointerDistance\n\t\t\t\t: 30; // default is 30px\n\n\t\tconst ignoreSelectFeatures =\n\t\t\toptions && options.ignoreSelectFeatures !== undefined\n\t\t\t\t? options.ignoreSelectFeatures\n\t\t\t\t: true;\n\n\t\tconst ignoreCoordinatePoints =\n\t\t\toptions && options.ignoreCoordinatePoints !== undefined\n\t\t\t\t? options.ignoreCoordinatePoints\n\t\t\t\t: false;\n\n\t\tconst ignoreCurrentlyDrawing =\n\t\t\toptions && options.ignoreCurrentlyDrawing !== undefined\n\t\t\t\t? options.ignoreCurrentlyDrawing\n\t\t\t\t: false;\n\n\t\tconst ignoreClosingPoints =\n\t\t\toptions && options.ignoreClosingPoints !== undefined\n\t\t\t\t? options.ignoreClosingPoints\n\t\t\t\t: false;\n\n\t\tconst ignoreSnappingPoints =\n\t\t\toptions && options.ignoreSnappingPoints !== undefined\n\t\t\t\t? options.ignoreSnappingPoints\n\t\t\t\t: false;\n\n\t\tconst unproject = this._adapter.unproject.bind(this._adapter);\n\t\tconst project = this._adapter.project.bind(this._adapter);\n\n\t\tconst inputPoint = project(lng, lat);\n\n\t\tconst bbox = createBBoxFromPoint({\n\t\t\tunproject,\n\t\t\tpoint: inputPoint,\n\t\t\tpointerDistance,\n\t\t});\n\n\t\tconst features = this._store.search(bbox as BBoxPolygon);\n\n\t\treturn features\n\t\t\t.filter((feature) => {\n\t\t\t\tif (\n\t\t\t\t\tignoreSelectFeatures &&\n\t\t\t\t\t(feature.properties[SELECT_PROPERTIES.MID_POINT] ||\n\t\t\t\t\t\tfeature.properties[SELECT_PROPERTIES.SELECTION_POINT])\n\t\t\t\t) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tignoreCoordinatePoints &&\n\t\t\t\t\tfeature.properties[COMMON_PROPERTIES.COORDINATE_POINT]\n\t\t\t\t) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tignoreClosingPoints &&\n\t\t\t\t\tfeature.properties[COMMON_PROPERTIES.CLOSING_POINT]\n\t\t\t\t) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tignoreCurrentlyDrawing &&\n\t\t\t\t\tfeature.properties[COMMON_PROPERTIES.CURRENTLY_DRAWING]\n\t\t\t\t) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tignoreSnappingPoints &&\n\t\t\t\t\tfeature.properties[COMMON_PROPERTIES.SNAPPING_POINT]\n\t\t\t\t) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (feature.geometry.type === \"Point\") {\n\t\t\t\t\tconst pointCoordinates = feature.geometry.coordinates;\n\t\t\t\t\tconst pointXY = project(pointCoordinates[0], pointCoordinates[1]);\n\t\t\t\t\tconst distance = cartesianDistance(inputPoint, pointXY);\n\t\t\t\t\treturn distance < pointerDistance;\n\t\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\t\tconst coordinates: Position[] = feature.geometry.coordinates;\n\n\t\t\t\t\tfor (let i = 0; i < coordinates.length - 1; i++) {\n\t\t\t\t\t\tconst coord = coordinates[i];\n\t\t\t\t\t\tconst nextCoord = coordinates[i + 1];\n\t\t\t\t\t\tconst distanceToLine = pixelDistanceToLine(\n\t\t\t\t\t\t\tinputPoint,\n\t\t\t\t\t\t\tproject(coord[0], coord[1]),\n\t\t\t\t\t\t\tproject(nextCoord[0], nextCoord[1]),\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (distanceToLine < pointerDistance) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t} else {\n\t\t\t\t\tconst lngLatInsidePolygon = pointInPolygon(\n\t\t\t\t\t\t[lng, lat],\n\t\t\t\t\t\tfeature.geometry.coordinates,\n\t\t\t\t\t);\n\n\t\t\t\t\tif (lngLatInsidePolygon) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (options?.includePolygonsWithinPointerDistance) {\n\t\t\t\t\t\tconst rings: Position[][] = feature.geometry.coordinates;\n\n\t\t\t\t\t\tfor (const ring of rings) {\n\t\t\t\t\t\t\tfor (let i = 0; i < ring.length - 1; i++) {\n\t\t\t\t\t\t\t\tconst coord = ring[i];\n\t\t\t\t\t\t\t\tconst nextCoord = ring[i + 1];\n\n\t\t\t\t\t\t\t\tconst projectedStart = project(coord[0], coord[1]);\n\t\t\t\t\t\t\t\tconst projectedEnd = project(nextCoord[0], nextCoord[1]);\n\n\t\t\t\t\t\t\t\tconst distanceToEdge = pixelDistanceToLine(\n\t\t\t\t\t\t\t\t\tinputPoint,\n\t\t\t\t\t\t\t\t\tprojectedStart,\n\t\t\t\t\t\t\t\t\tprojectedEnd,\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\tif (distanceToEdge < pointerDistance) {\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t})\n\t\t\t.map((feature) => {\n\t\t\t\tif (!options?.addClosestCoordinateInfoToProperties) {\n\t\t\t\t\treturn feature;\n\t\t\t\t}\n\n\t\t\t\tlet coordinates;\n\t\t\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\t\t\tcoordinates = feature.geometry.coordinates[0].slice(0, -1); // Remove the closing coordinate as it's always the same as the first\n\t\t\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\t\t\tcoordinates = feature.geometry.coordinates;\n\t\t\t\t} else {\n\t\t\t\t\t// Ignore points\n\t\t\t\t\treturn feature;\n\t\t\t\t}\n\n\t\t\t\tlet closestIndex = -1;\n\t\t\t\tlet closestDistance = Infinity;\n\t\t\t\tlet closestCoordinate;\n\n\t\t\t\t// Find the closest coordinate in the polygon/linestring to the pointer event\n\t\t\t\tfor (let i = 0; i < coordinates.length; i++) {\n\t\t\t\t\tconst coordinate = coordinates[i];\n\t\t\t\t\tconst distance = cartesianDistance(\n\t\t\t\t\t\tproject(coordinate[0], coordinate[1]),\n\t\t\t\t\t\tinputPoint,\n\t\t\t\t\t);\n\n\t\t\t\t\tif (distance < closestDistance) {\n\t\t\t\t\t\tclosestIndex = i;\n\t\t\t\t\t\tclosestDistance = distance;\n\t\t\t\t\t\tclosestCoordinate = coordinate;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfeature.properties.closestCoordinateIndexToEvent = closestIndex;\n\t\t\t\tfeature.properties.closestCoordinatePixelDistanceToEvent =\n\t\t\t\t\tclosestDistance;\n\t\t\t\tfeature.properties.closestCoordinateDistanceKmToEvent =\n\t\t\t\t\thaversineDistanceKilometers(closestCoordinate!, [lng, lat]);\n\n\t\t\t\treturn feature;\n\t\t\t});\n\t}\n\n\tprivate getSelectModeOrThrow(selectMode: string | undefined = undefined) {\n\t\tconst foundSelectMode = this.getSelectMode({\n\t\t\tswitchToSelectMode: true,\n\t\t\tselectMode,\n\t\t});\n\n\t\tif (!foundSelectMode) {\n\t\t\tthrow new Error(\"No select mode defined in instance\");\n\t\t}\n\n\t\treturn foundSelectMode;\n\t}\n\n\tprivate getSelectMode({\n\t\tswitchToSelectMode,\n\t\tselectMode,\n\t}: {\n\t\tswitchToSelectMode: boolean;\n\t\tselectMode?: string;\n\t}) {\n\t\tthis.checkEnabled();\n\t\tconst currentMode = this.getMode();\n\n\t\tif (this._instanceSelectModes.length === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (\n\t\t\tselectMode !== undefined &&\n\t\t\t!this._instanceSelectModes.includes(selectMode)\n\t\t) {\n\t\t\tthrow new Error(`No select mode with this name present: ${selectMode}`);\n\t\t}\n\n\t\tlet modeToUse: string;\n\n\t\t// Explicit select mode provided, we use that\n\t\tif (selectMode !== undefined) {\n\t\t\tmodeToUse = selectMode;\n\t\t}\n\t\t// No explicit select mode provided, but we are currently in a select mode, we use the current mode\n\t\telse if (this._instanceSelectModes.includes(currentMode)) {\n\t\t\tmodeToUse = currentMode;\n\t\t}\n\t\t// Finally we default to the first select mode provided in the instance\n\t\telse {\n\t\t\tmodeToUse = this._instanceSelectModes[0];\n\t\t}\n\n\t\t// If we're not already in the select mode, we switch to it\n\t\tif (switchToSelectMode && currentMode !== modeToUse) {\n\t\t\tthis.setMode(modeToUse);\n\t\t}\n\n\t\tconst mode = this._modes[modeToUse] as TerraDrawBaseSelectMode<any>;\n\n\t\treturn mode;\n\t}\n\n\tprivate isGuidanceFeature(feature: GeoJSONStoreFeatures): boolean {\n\t\treturn Boolean(\n\t\t\tfeature.properties[SELECT_PROPERTIES.MID_POINT] ||\n\t\t\t\tfeature.properties[SELECT_PROPERTIES.SELECTION_POINT] ||\n\t\t\t\tfeature.properties[COMMON_PROPERTIES.COORDINATE_POINT] ||\n\t\t\t\tfeature.properties[COMMON_PROPERTIES.SNAPPING_POINT],\n\t\t);\n\t}\n\n\t/**\n\t * @deprecated This method is scheduled for removal in the next major version. Instead use the 'updateModeOptions' method passing the\n\t * styles property in the options object, and this will dynamically update the styles for the mode.\n\t *\n\t * Allows the setting of a style for a given mode\n\t *\n\t * @param mode - The mode you wish to set a style for\n\t * @param styles - The styles you wish to set for the mode - this is\n\t * the same as the initialisation style schema\n\t */\n\tsetModeStyles<Styling extends Record<string, number | HexColor>>(\n\t\tmode: string,\n\t\tstyles: Styling,\n\t) {\n\t\tthis.checkEnabled();\n\t\tif (!this._modes[mode]) {\n\t\t\tthrow new Error(\"No mode with this name present\");\n\t\t}\n\n\t\t// TODO: Not sure why this fails TypeScript with TerraDrawBaseSelectMode?\n\t\t(this._modes[mode] as TerraDrawBaseDrawMode<any>).styles = styles;\n\t}\n\n\t/**\n\t * Allow updating of the current options passed to the mode dynamically\n\t * after the mode has been started. You can also use this method to update styles\n\t * as these are passed from the options object.\n\t * @param mode - the mode name you wish to update (the mode name is the public 'mode' property of the mode class)\n\t * @param options - the options object - this allows _partial_ updating of the modes options (i.e. you do not need to pass the whole options object)\n\t */\n\tupdateModeOptions<Mode extends { new (...args: any[]): any }>(\n\t\tmode: InstanceType<Mode>[\"mode\"],\n\t\toptions: Omit<NonNullable<ConstructorParameters<Mode>[0]>, \"modeName\">,\n\t) {\n\t\tthis.checkEnabled();\n\t\tif (!this._modes[mode]) {\n\t\t\tthrow new Error(\"No mode with this name present\");\n\t\t}\n\n\t\tthis._modes[mode].updateOptions(\n\t\t\toptions as TerraDrawExtend.BaseModeOptions<any>,\n\t\t);\n\t}\n\n\t/**\n\t * Allows the user to get a snapshot (copy) of all given features\n\t *\n\t * @returns An array of all given features in the instances store\n\t */\n\tgetSnapshot() {\n\t\t// This is a read only method so we do not need to check if enabled\n\t\treturn this._store.copyAll();\n\t}\n\n\t/**\n\t * Allows the user to get a snapshot (copy) of a given feature by id\n\t *\n\t * @returns A copy of the features in the instances store\n\t */\n\tgetSnapshotFeature(id: FeatureId) {\n\t\tif (!this._store.has(id)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn this._store.copy(id);\n\t}\n\n\t/**\n\t * Removes all data from the current store and ensures any rendered data is cleared\n\t * from the map.\n\t */\n\tclear() {\n\t\tthis.checkEnabled();\n\t\tthis._adapter.clear();\n\t}\n\n\t/**\n\t * A property used to determine whether the instance is active or not. You\n\t * can use the start method to set this to true, and stop method to set this to false.\n\t * This is a read only property.\n\t *\n\t * @return true or false depending on if the instance is stopped or started\n\t * @readonly\n\t */\n\tget enabled(): boolean {\n\t\treturn this._enabled;\n\t}\n\n\t/**\n\t * enabled is a read only property and will throw and error if you try and set it.\n\t */\n\tset enabled(_) {\n\t\tthrow new Error(\"Enabled is read only\");\n\t}\n\n\t/**\n\t * A method for getting the current mode name\n\t * @return the current mode name\n\t */\n\tgetMode(): string {\n\t\t// This is a read only method so we do not need to check if enabled\n\t\treturn this._mode.mode;\n\t}\n\n\t/**\n\t * Get the state of the mode i.e. if we are currently unregistered, registered, drawing etc. This can\n\t * be used to make decisions based on what the current mode is doing.\n\t * @returns the current mode state as a string\n\t */\n\tgetModeState() {\n\t\treturn this._mode.state;\n\t}\n\n\t/**\n\t * A method for setting the current mode by name. Under the hood this will stop\n\t * the previous mode and start the new one.\n\t * @param mode - The mode name you wish to start\n\t */\n\tsetMode(mode: string) {\n\t\tthis.checkEnabled();\n\n\t\tif (this._modes[mode]) {\n\t\t\t// Before we swap modes we want to\n\t\t\t// clean up any state that has been left behind,\n\t\t\t// for example current drawing geometries\n\t\t\t// and mode state\n\t\t\tthis._mode.stop();\n\n\t\t\t// Swap the mode to the new mode\n\t\t\tthis._mode = this._modes[mode];\n\n\t\t\t// Start the new mode\n\t\t\tthis._mode.start();\n\t\t} else {\n\t\t\t// If the mode doesn't exist, we throw an error\n\t\t\tthrow new Error(\"No mode with this name present\");\n\t\t}\n\t}\n\n\t/**\n\t * A method for removing features to the store\n\t * @param ids\n\t * @returns\n\t */\n\tremoveFeatures(ids: FeatureId[]) {\n\t\tthis.checkEnabled();\n\n\t\tconst coordinatePointsToDelete: FeatureId[] = [];\n\n\t\tconst idsToDelete: FeatureId[] = [];\n\n\t\tlet modeToCleanUp: undefined | string = undefined;\n\n\t\tids.forEach((id) => {\n\t\t\t// Deselect any passed features - this removes all selection points and midpoints\n\t\t\tif (!this._store.has(id)) {\n\t\t\t\tthrow new Error(`No feature with id ${id}, can not delete`);\n\t\t\t}\n\n\t\t\tconst properties = this._store.getPropertiesCopy(id);\n\t\t\tif (properties[SELECT_PROPERTIES.SELECTED]) {\n\t\t\t\tthis.deselectFeature(id);\n\t\t\t}\n\n\t\t\t// Special case where the feature being deleted is currently being drawn\n\t\t\tif (properties[COMMON_PROPERTIES.CURRENTLY_DRAWING]) {\n\t\t\t\tif (this._modes[properties.mode as string]) {\n\t\t\t\t\tmodeToCleanUp = properties.mode as string;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If the feature has coordinate points, we want to remove them as well\n\t\t\tif (properties[COMMON_PROPERTIES.COORDINATE_POINT_IDS]) {\n\t\t\t\tcoordinatePointsToDelete.push(\n\t\t\t\t\t...(properties[\n\t\t\t\t\t\tCOMMON_PROPERTIES.COORDINATE_POINT_IDS\n\t\t\t\t\t] as FeatureId[]),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tidsToDelete.push(id);\n\t\t});\n\n\t\tthis._store.delete([...idsToDelete, ...coordinatePointsToDelete], {\n\t\t\torigin: \"api\",\n\t\t});\n\n\t\t// Clean up should be safe to call without throwing errors\n\t\t// as all internal modes wrap deletes in try catch blocks\n\t\tif (\n\t\t\tmodeToCleanUp &&\n\t\t\tthis._modes[modeToCleanUp] &&\n\t\t\tthis._modes[modeToCleanUp].cleanUp()\n\t\t) {\n\t\t\tthis._modes[modeToCleanUp].cleanUp();\n\t\t}\n\t}\n\n\t/**\n\t * Provides the ability to programmatically select a feature using the instances provided select mode.\n\t * If not select mode is provided in the instance, an error will be thrown. If the instance is not currently\n\t * in a select mode, it will switch to the first select mode provided in the constructor unless\n\t * a select mode name is explicitly provided.\n\t * @param id - the id of the feature to select\n\t * @param selectMode - optional select mode name to use when selecting the feature\n\t */\n\tselectFeature(id: FeatureId, selectMode?: string) {\n\t\tconst selectModeInstance = this.getSelectModeOrThrow(selectMode);\n\n\t\tselectModeInstance.selectFeature(id);\n\t}\n\n\t/**\n\t * Provides the ability to programmatically deselect a feature using the instances provided select mode.\n\t * If not select mode is provided in the instance, an error will be thrown. If the instance is not currently\n\t * in a select mode, it will switch to the first select mode provided in the constructor.\n\t * @param id  - the id of the feature to deselect\n\t */\n\tdeselectFeature(id: FeatureId) {\n\t\tconst selectModeInstance = this.getSelectModeOrThrow();\n\n\t\tselectModeInstance.deselectFeature(id);\n\t}\n\n\t/**\n\t * Returns the next feature id from the store - defaults to UUID4 unless you have\n\t * set a custom idStrategy. This method can be useful if you are needing creating features\n\t * outside of the Terra Draw instance but want to add them in to the store.\n\t * @returns a id, either number of string based on whatever the configured idStrategy is\n\t *\n\t */\n\tgetFeatureId(): FeatureId {\n\t\treturn this._store.getId();\n\t}\n\n\t/**\n\t * Returns true or false depending on if the Terra Draw instance has a feature with a given id\n\t * @returns a boolean determining if the instance has a feature with the given id\n\t */\n\thasFeature(id: FeatureId): boolean {\n\t\treturn this._store.has(id);\n\t}\n\n\t/**\n\t * Checks if a property name is reserved and cannot be used.\n\t * @param propertyName - the property name to check\n\t * @returns\n\t */\n\tprivate checkIsReservedProperty(propertyName: string) {\n\t\tconst UNAVAILABLE_PROPERTIES = [\n\t\t\t...Object.values(SELECT_PROPERTIES),\n\t\t\t...Object.values(COMMON_PROPERTIES),\n\t\t] as const;\n\n\t\treturn !UNAVAILABLE_PROPERTIES.includes(\n\t\t\tpropertyName as unknown as (typeof UNAVAILABLE_PROPERTIES)[number],\n\t\t);\n\t}\n\n\t/**\n\t * Updates a features properties. This can be used to programmatically change the properties of a feature.\n\t * The update is a shallow merge so only the properties you provide will be updated. Certain internal properties\n\t * are reserved and cannot be updated.\n\t * @param id - the id of the feature to update the property for\n\t * @param properties - an object of key value pairs that will be shallowly merged in to the features properties\n\t */\n\tupdateFeatureProperties(\n\t\tid: FeatureId,\n\t\tproperties: Record<string, JSON | undefined>,\n\t) {\n\t\tif (!this._store.has(id)) {\n\t\t\tthrow new Error(`No feature with id ${id} present in store`);\n\t\t}\n\n\t\tconst feature = this._store.copy(id);\n\n\t\t// We don't want users to be able to update guidance features directly\n\t\tif (this.isGuidanceFeature(feature)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Guidance features are not allowed to be updated directly.`,\n\t\t\t);\n\t\t}\n\n\t\tconst mode = feature.properties.mode;\n\t\tconst modeToUpdate = this._modes[mode as string];\n\n\t\tif (!modeToUpdate) {\n\t\t\tthrow new Error(`No mode with name ${mode} present in instance`);\n\t\t}\n\n\t\tconst entries = Object.entries(properties);\n\n\t\t// Check that none of the properties are reserved\n\t\tentries.forEach(([propertyName, value]) => {\n\t\t\tconst isReservedProperty = this.checkIsReservedProperty(propertyName);\n\n\t\t\tif (!isReservedProperty) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`You are trying to update a reserved property name: ${propertyName}. Please choose another name.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (value !== undefined && !isValidJSONValue(value)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Invalid JSON value provided for property ${propertyName}`,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\tthis._store.updateProperty(\n\t\t\tentries.map(([propertyName, value]) => ({\n\t\t\t\tid: feature.id as FeatureId,\n\t\t\t\tproperty: propertyName,\n\t\t\t\tvalue,\n\t\t\t})),\n\t\t\t{ origin: \"api\" }, // origin is used to indicate that this update has come from an API call\n\t\t);\n\t}\n\n\t/**\n\t * Updates a features geometry. This an be used to programmatically change the coordinates of a feature. This\n\t * can be useful for if you want to modify a geometry via a button or some similar user interaction.\n\t * @param id - the id of the feature to update the geometry for\n\t * @param geometry - the new geometry that will replace the existing geometry\n\t */\n\tupdateFeatureGeometry(id: FeatureId, geometry: GeoJSONStoreGeometries) {\n\t\tif (!this._store.has(id)) {\n\t\t\tthrow new Error(`No feature with id ${id} present in store`);\n\t\t}\n\n\t\tconst feature = this._store.copy(id);\n\n\t\t// We don't want users to be able to update guidance features directly\n\t\tif (this.isGuidanceFeature(feature)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Guidance features are not allowed to be updated directly.`,\n\t\t\t);\n\t\t}\n\n\t\t// Ensure that the geometry is valid\n\t\tif (!feature || !geometry || !geometry.type || !geometry.coordinates) {\n\t\t\tthrow new Error(\"Invalid geometry provided\");\n\t\t}\n\t\tif (geometry.type !== feature.geometry.type) {\n\t\t\tthrow new Error(\n\t\t\t\t`Geometry type mismatch: expected ${feature.geometry.type}, got ${geometry.type}`,\n\t\t\t);\n\t\t}\n\n\t\tconst mode = feature.properties.mode;\n\t\tconst modeToUpdate = this._modes[mode as string];\n\n\t\tif (!modeToUpdate) {\n\t\t\tthrow new Error(`No mode with name ${mode} present in instance`);\n\t\t}\n\n\t\tconst updatedFeature = { ...feature, geometry };\n\n\t\tconst validationResult = modeToUpdate.validateFeature(updatedFeature);\n\n\t\tif (!validationResult.valid) {\n\t\t\tthrow new Error(\n\t\t\t\t`Feature validation failed: ${validationResult.reason || \"Unknown reason\"}`,\n\t\t\t);\n\t\t}\n\n\t\tthis._store.updateGeometry(\n\t\t\t[{ id: feature.id as FeatureId, geometry }],\n\t\t\t{ origin: \"api\" }, // origin is used to indicate that this update has come from an API call\n\t\t);\n\n\t\t// If the mode has an afterFeatureUpdated method, we call it\n\t\tif (modeToUpdate.afterFeatureUpdated) {\n\t\t\tmodeToUpdate.afterFeatureUpdated(updatedFeature);\n\n\t\t\tconst featureIsSelected =\n\t\t\t\tupdatedFeature.properties[SELECT_PROPERTIES.SELECTED];\n\t\t\tconst selectModePresent = this.getSelectMode({\n\t\t\t\tswitchToSelectMode: false,\n\t\t\t});\n\n\t\t\tif (selectModePresent && featureIsSelected) {\n\t\t\t\tselectModePresent.afterFeatureUpdated(updatedFeature);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * A method for transforming a feature's geometry. This can be used to rotate or scale a feature's geometry.\n\t * This matches the functionality of the scale and rotate behaviors in the select mode.\n\t * @param id - the id of the feature to transform\n\t * @param transformation - the transformation to apply to the feature's geometry\n\t */\n\ttransformFeatureGeometry(\n\t\tid: FeatureId,\n\t\ttransformation:\n\t\t\t| {\n\t\t\t\t\tprojection?: Exclude<Projection, \"globe\">;\n\t\t\t\t\torigin: Position;\n\t\t\t\t\ttype: \"rotate\";\n\t\t\t\t\toptions: {\n\t\t\t\t\t\tangle: number;\n\t\t\t\t\t};\n\t\t\t  }\n\t\t\t| {\n\t\t\t\t\tprojection?: Exclude<Projection, \"globe\">;\n\t\t\t\t\torigin: Position;\n\t\t\t\t\ttype: \"scale\";\n\t\t\t\t\toptions: {\n\t\t\t\t\t\txScale: number;\n\t\t\t\t\t\tyScale: number;\n\t\t\t\t\t};\n\t\t\t  },\n\t) {\n\t\tif (!this._store.has(id)) {\n\t\t\tthrow new Error(`No feature with id ${id} present in store`);\n\t\t}\n\n\t\tlet feature = this._store.copy(id);\n\n\t\t// We don't want users to be able to update guidance features directly\n\t\tif (this.isGuidanceFeature(feature)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Guidance features are not allowed to be updated directly.`,\n\t\t\t);\n\t\t}\n\n\t\tconst mode = feature.properties.mode;\n\t\tconst modeToUpdate = this._modes[mode as string];\n\n\t\tif (!modeToUpdate) {\n\t\t\tthrow new Error(`No mode with name ${mode} present in instance`);\n\t\t}\n\n\t\tlet coordinates: Position[];\n\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\tcoordinates = feature.geometry.coordinates[0];\n\t\t} else if (feature.geometry.type === \"LineString\") {\n\t\t\tcoordinates = feature.geometry.coordinates;\n\t\t} else {\n\t\t\tthrow new Error(\n\t\t\t\t`Feature geometry type ${feature.geometry.type} is not supported for transformation`,\n\t\t\t);\n\t\t}\n\n\t\tif (transformation.projection == \"web-mercator\") {\n\t\t\tif (transformation.type === \"scale\") {\n\t\t\t\tconst { x: originX, y: originY } = lngLatToWebMercatorXY(\n\t\t\t\t\ttransformation.origin[0],\n\t\t\t\t\ttransformation.origin[1],\n\t\t\t\t);\n\n\t\t\t\tconst xScale = transformation.options.xScale || 1;\n\t\t\t\tconst yScale = transformation.options.yScale || 1;\n\n\t\t\t\ttransformScaleWebMercatorCoordinates({\n\t\t\t\t\tcoordinates,\n\t\t\t\t\toriginX,\n\t\t\t\t\toriginY,\n\t\t\t\t\txScale,\n\t\t\t\t\tyScale,\n\t\t\t\t});\n\t\t\t} else if (transformation.type === \"rotate\") {\n\t\t\t\tconst angle = transformation.options.angle || 0;\n\t\t\t\tfeature = transformRotateWebMercator(\n\t\t\t\t\tfeature as Feature<Polygon> | Feature<LineString>,\n\t\t\t\t\tangle,\n\t\t\t\t) as GeoJSONStoreFeatures;\n\n\t\t\t\tcoordinates =\n\t\t\t\t\tfeature.geometry.type === \"Polygon\"\n\t\t\t\t\t\t? (feature.geometry as Polygon).coordinates[0]\n\t\t\t\t\t\t: (feature.geometry as LineString).coordinates;\n\t\t\t}\n\n\t\t\tcoordinates = coordinates.map((coord) => [\n\t\t\t\tlimitPrecision(coord[0], this._adapter.getCoordinatePrecision()),\n\t\t\t\tlimitPrecision(coord[1], this._adapter.getCoordinatePrecision()),\n\t\t\t]);\n\n\t\t\tfeature.geometry.coordinates =\n\t\t\t\tfeature.geometry.type === \"Polygon\" ? [coordinates] : coordinates;\n\t\t} else {\n\t\t\tthrow new Error(\n\t\t\t\t`Projection ${transformation.projection} is not currently supported for transformation`,\n\t\t\t);\n\t\t}\n\n\t\tthis._store.updateGeometry(\n\t\t\t[{ id: feature.id as FeatureId, geometry: feature.geometry }],\n\t\t\t{ origin: \"api\" }, // origin is used to indicate that this update has come from an API call\n\t\t);\n\n\t\tif (modeToUpdate.afterFeatureUpdated) {\n\t\t\tmodeToUpdate.afterFeatureUpdated(feature);\n\t\t\tconst featureIsSelected = feature.properties[SELECT_PROPERTIES.SELECTED];\n\t\t\tconst selectModePresent = this.getSelectMode({\n\t\t\t\tswitchToSelectMode: false,\n\t\t\t});\n\n\t\t\tif (selectModePresent && featureIsSelected) {\n\t\t\t\tselectModePresent.afterFeatureUpdated(feature);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * A method for adding features to the store. This method will validate the features\n\t * returning an array of validation results. Features must match one of the modes enabled\n\t * in the instance.\n\t * @param features - an array of GeoJSON features\n\t * @returns an array of validation results\n\t */\n\taddFeatures(features: GeoJSONStoreFeatures[]): StoreValidation[] {\n\t\tthis.checkEnabled();\n\n\t\tif (features.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn this._store.load(\n\t\t\tfeatures,\n\t\t\t(feature) => {\n\t\t\t\t// If the feature has a mode property, we use that to validate the feature\n\t\t\t\tif (hasModeProperty(feature)) {\n\t\t\t\t\tconst featureMode = feature.properties.mode;\n\t\t\t\t\tconst modeToAddTo = this._modes[featureMode];\n\n\t\t\t\t\t// if the mode does not exist, we return false\n\t\t\t\t\tif (!modeToAddTo) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tid: (feature as { id?: FeatureId }).id,\n\t\t\t\t\t\t\tvalid: false,\n\t\t\t\t\t\t\treason: `${featureMode} mode is not in the list of instantiated modes`,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\t// use the inbuilt validation of the mode\n\t\t\t\t\tconst validation = modeToAddTo.validateFeature.bind(modeToAddTo);\n\t\t\t\t\tconst validationResult = validation(feature);\n\t\t\t\t\tconst valid = validationResult.valid;\n\t\t\t\t\tconst reason = validationResult.reason\n\t\t\t\t\t\t? validationResult.reason\n\t\t\t\t\t\t: !validationResult.valid\n\t\t\t\t\t\t\t? \"Feature is invalid\"\n\t\t\t\t\t\t\t: undefined;\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: (feature as { id?: FeatureId }).id,\n\t\t\t\t\t\tvalid,\n\t\t\t\t\t\treason,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// If the feature does not have a mode property, we return false\n\t\t\t\treturn {\n\t\t\t\t\tid: (feature as { id?: FeatureId }).id,\n\t\t\t\t\tvalid: false,\n\t\t\t\t\treason: \"Mode property does not exist\",\n\t\t\t\t};\n\t\t\t},\n\t\t\t(feature) => {\n\t\t\t\tif (hasModeProperty(feature)) {\n\t\t\t\t\tconst featureMode = feature.properties.mode;\n\t\t\t\t\tconst modeToAddTo = this._modes[featureMode];\n\t\t\t\t\tif (modeToAddTo && modeToAddTo.afterFeatureAdded) {\n\t\t\t\t\t\tmodeToAddTo.afterFeatureAdded(feature);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ origin: \"api\" },\n\t\t);\n\t}\n\n\t/**\n\t * A method starting Terra Draw. It put the instance into a started state, and\n\t * in registers the passed adapter giving it all the callbacks required to operate.\n\t */\n\tstart() {\n\t\t// If the instance is already enabled, we do nothing\n\t\tif (this._enabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._enabled = true;\n\t\tthis._adapter.register({\n\t\t\tonReady: () => {\n\t\t\t\tthis._eventListeners.ready.forEach((listener) => {\n\t\t\t\t\tlistener();\n\t\t\t\t});\n\t\t\t},\n\t\t\tgetState: () => {\n\t\t\t\treturn this._mode.state;\n\t\t\t},\n\t\t\tonClick: (event) => {\n\t\t\t\tthis._mode.onClick(event);\n\t\t\t},\n\t\t\tonMouseMove: (event) => {\n\t\t\t\tthis._mode.onMouseMove(event);\n\t\t\t},\n\t\t\tonKeyDown: (event) => {\n\t\t\t\tthis._mode.onKeyDown(event);\n\t\t\t},\n\t\t\tonKeyUp: (event) => {\n\t\t\t\tthis._mode.onKeyUp(event);\n\t\t\t},\n\t\t\tonDragStart: (event, setMapDraggability) => {\n\t\t\t\tthis._mode.onDragStart(event, setMapDraggability);\n\t\t\t},\n\t\t\tonDrag: (event, setMapDraggability) => {\n\t\t\t\tthis._mode.onDrag(event, setMapDraggability);\n\t\t\t},\n\t\t\tonDragEnd: (event, setMapDraggability) => {\n\t\t\t\tthis._mode.onDragEnd(event, setMapDraggability);\n\t\t\t},\n\t\t\tonClear: () => {\n\t\t\t\t// Ensure that the mode resets its state\n\t\t\t\t// as it may be storing feature ids internally in it's instance\n\t\t\t\tthis._mode.cleanUp();\n\n\t\t\t\t// Remove all features from the store\n\t\t\t\tthis._store.clear();\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * Gets the features at a given longitude and latitude.\n\t * Will return point and linestrings that are a given pixel distance\n\t * away from the lng/lat and any polygons which contain it.\n\t */\n\tgetFeaturesAtLngLat(\n\t\tlngLat: { lng: number; lat: number },\n\t\toptions?: GetFeatureOptions,\n\t) {\n\t\tconst { lng, lat } = lngLat;\n\n\t\treturn this.featuresAtLocation(\n\t\t\t{\n\t\t\t\tlng,\n\t\t\t\tlat,\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t}\n\n\t/**\n\t * Takes a given pointer event and will return point and linestrings that are\n\t * a given pixel distance away from the longitude/latitude, and any polygons which contain it.\n\t */\n\tgetFeaturesAtPointerEvent(\n\t\tevent: PointerEvent | MouseEvent,\n\t\toptions?: GetFeatureOptions,\n\t) {\n\t\tconst getLngLatFromEvent = this._adapter.getLngLatFromEvent.bind(\n\t\t\tthis._adapter,\n\t\t);\n\n\t\tconst lngLat = getLngLatFromEvent(event);\n\n\t\t// If the pointer event is outside the container or the underlying library is\n\t\t// not ready we can get null as a returned value\n\t\tif (lngLat === null) {\n\t\t\treturn [];\n\t\t}\n\n\t\treturn this.featuresAtLocation(lngLat, options);\n\t}\n\n\t/**\n\t * A method for stopping Terra Draw. Will clear the store, deregister the adapter and\n\t * remove any rendered layers in the process.\n\t */\n\tstop() {\n\t\t// If the instance is already stopped, we do nothing\n\t\tif (!this._enabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._enabled = false;\n\t\tthis._adapter.unregister();\n\t}\n\n\t/**\n\t * Registers a Terra Draw event\n\t *\n\t * @param event - The name of the event you wish to listen for\n\t * @param callback - The callback with you wish to be called when this event occurs\n\t *\n\t */\n\ton<T extends TerraDrawEvents>(\n\t\tevent: T,\n\t\tcallback: TerraDrawEventListeners[T],\n\t) {\n\t\tconst listeners = this._eventListeners[\n\t\t\tevent\n\t\t] as TerraDrawEventListeners[T][];\n\t\tif (!listeners.includes(callback)) {\n\t\t\tlisteners.push(callback);\n\t\t}\n\t}\n\n\t/**\n\t * Unregisters a Terra Draw event\n\t *\n\t * @param event - The name of the event you wish to unregister\n\t * @param callback - The callback you originally provided to the 'on' method\n\t *\n\t */\n\toff<T extends TerraDrawEvents>(\n\t\tevent: TerraDrawEvents,\n\t\tcallback: TerraDrawEventListeners[T],\n\t) {\n\t\tconst listeners = this._eventListeners[\n\t\t\tevent\n\t\t] as TerraDrawEventListeners[T][];\n\t\tif (listeners.includes(callback)) {\n\t\t\tlisteners.splice(listeners.indexOf(callback), 1);\n\t\t}\n\t}\n}\n\nexport {\n\tTerraDraw,\n\ttype IdStrategy,\n\ttype TerraDrawEvents,\n\ttype TerraDrawEventListeners,\n\n\t// Modes\n\tTerraDrawSelectMode,\n\tTerraDrawPointMode,\n\tTerraDrawLineStringMode,\n\tTerraDrawPolygonMode,\n\tTerraDrawCircleMode,\n\tTerraDrawFreehandMode,\n\tTerraDrawFreehandLineStringMode,\n\tTerraDrawRenderMode,\n\tTerraDrawRectangleMode,\n\tTerraDrawAngledRectangleMode,\n\tTerraDrawSectorMode,\n\tTerraDrawSensorMode,\n\tTerraDrawMarkerMode,\n\n\t// Types that are required for 3rd party developers to extend\n\tTerraDrawExtend,\n\n\t// TerraDrawBaseMode\n\ttype BehaviorConfig,\n\ttype GeoJSONStoreFeatures,\n\ttype GeoJSONStoreGeometries,\n\ttype HexColor,\n\ttype TerraDrawMouseEvent,\n\ttype TerraDrawAdapterStyling,\n\ttype TerraDrawKeyboardEvent,\n\n\t// TerraDrawBaseAdapter\n\ttype TerraDrawHandledEvents,\n\ttype TerraDrawChanges,\n\ttype TerraDrawStylingFunction,\n\ttype Project,\n\ttype Unproject,\n\ttype SetCursor,\n\ttype GetLngLatFromEvent,\n\n\t// Validations\n\tValidateMinAreaSquareMeters,\n\tValidateMaxAreaSquareMeters,\n\tValidateNotSelfIntersecting,\n\tValidationReasons,\n};\n","import { Validation } from \"../common\";\nimport { polygonAreaSquareMeters } from \"../geometry/measure/area\";\nimport { GeoJSONStoreFeatures } from \"../terra-draw\";\nimport { ValidationReasonFeatureNotPolygon } from \"./common-validations\";\n\nexport const ValidationMaxAreaSquareMetersReason =\n\t\"Feature is larger than the maximum area\";\n\nexport const ValidateMaxAreaSquareMeters = (\n\tfeature: GeoJSONStoreFeatures,\n\tmaxSize: number,\n): ReturnType<Validation> => {\n\tif (feature.geometry.type !== \"Polygon\") {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\treason: ValidationReasonFeatureNotPolygon,\n\t\t};\n\t}\n\n\tconst size = polygonAreaSquareMeters(feature.geometry);\n\n\tif (size > maxSize) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\treason: ValidationMaxAreaSquareMetersReason,\n\t\t};\n\t}\n\n\treturn { valid: true };\n};\n"],"names":["UpdateTypes","FinishActions","MARKER_URL_DEFAULT","MARKER_URL_BASE","SELECT_PROPERTIES","SELECTED","MID_POINT","SELECTION_POINT_FEATURE_ID","SELECTION_POINT","COMMON_PROPERTIES","MODE","CURRENTLY_DRAWING","EDITED","CLOSING_POINT","SNAPPING_POINT","COORDINATE_POINT","COORDINATE_POINT_FEATURE_ID","COORDINATE_POINT_IDS","PROVISIONAL_COORDINATE_COUNT","COMMITTED_COORDINATE_COUNT","MARKER","Z_INDEX","isObject","feature","Boolean","Array","isArray","hasModeProperty","properties","isValidTimestamp","timestamp","isNaN","Date","valueOf","dateIsValid","ModeTypes","ValidationReasonFeatureNotPolygon","ValidationReasonModeMismatch","DefaultPointerEvents","rightClick","contextMenu","leftClick","onDragStart","onDrag","onDragEnd","TerraDrawBaseDrawMode","options","willCallUpdateOptionsInParentClass","_state","_styles","pointerEvents","this","behaviors","validate","pointerDistance","coordinatePrecision","onStyleChange","store","projection","setDoubleClickToZoom","unproject","project","setCursor","isInitialUpdate","type","Drawing","mode","updateOptions","_extends","_proto","prototype","registerBehaviors","behaviorConfig","styles","validation","undefined","modeName","allowPointerEvent","pointerEvent","event","setDrawing","Error","setStarted","setStopped","register","config","registerOnChange","onChange","onSelect","onDeselect","onFinish","validateFeature","performFeatureValidation","afterFeatureAdded","afterFeatureUpdated","validStoreFeature","isValidId","error","id","geometry","includes","coordinates","valid","reason","isValidStoreFeature","idStrategy","updateType","Provisional","validateModeFeature","modeValidationFn","finishedId","context","deselectedId","selectedId","onKeyDown","onKeyUp","onMouseMove","onClick","setMapDraggability","getHexColorStylingValue","value","defaultValue","getStylingValue","getNumericStylingValue","getUrlStylingValue","_createClass","key","get","set","_","styling","TerraDrawBaseSelectMode","_TerraDrawBaseDrawMod","_len","_this","arguments","length","args","_key","call","apply","concat","Select","_inheritsLoose","haversineDistanceKilometers","pointOne","pointTwo","toRadians","latOrLng","Math","PI","phiOne","lambdaOne","phiTwo","deltaPhi","deltalambda","a","sin","cos","atan2","sqrt","earthRadius","degreesToRadians","degrees","lengthToRadians","distance","radiansToDegrees","radians","limitPrecision","num","decimalLimit","decimals","pow","round","RADIANS_TO_DEGREES","DEGREES_TO_RADIANS","R","lngLatToWebMercatorXY","lng","lat","x","y","log","tan","webMercatorXYToLngLat","atan","exp","destination","origin","bearing","longitude1","latitude1","bearingRad","latitude2","asin","circle","center","radiusKilometers","steps","i","circleCoordinate","push","selfIntersects","coord","output","ring0","edge0","ring1","edge1","ifInteresctionAddToOutput","isOutside","frac","frac1","start0","end0","start1","end1","intersection","equalArrays","x0","y0","x1","y1","x2","y2","x3","y3","denom","intersect","toString","array1","array2","coordinatePrecisionIsValid","coordinate","getDecimalPlaces","coordinateIsValid","Infinity","current","precision","ValidationReasonFeatureHasHoles","ValidationReasonFeatureLessThanFourCoordinates","ValidationReasonFeatureHasInvalidCoordinates","ValidationReasonFeatureCoordinatesNotClosed","ValidatePolygonFeature","coordinateOne","coordinateTwo","ValidateNonIntersectingPolygonFeature","validatePolygonFeature","TerraDrawModeBehavior","_ref","ensureRightHandRule","polygon","isFollowingRightHandRule","outerRing","sum","_outerRing$i","_outerRing","followsRightHandRule","reverse","Mutations","MutateFeatureBehavior","_TerraDrawModeBehavio","createPoint","Finish","validateGeometryWithUpdateType","handleCreateFeature","createLineString","_ref2","createPolygon","_ref3","corrected","createGuidancePoint","_ref4","createGuidancePoints","_ref5","_this2","additionalProperties","features","map","_extends2","createFeatures","updatePoint","_ref6","handleMutateFeature","featureId","coordinateMutations","propertyMutations","updatePolygon","_ref7","updateLineString","_ref8","deleteFeatureIfPresent","has","deleteFeaturesIfPresent","featureIds","_this3","existing","filter","setDeselected","_this4","updateSelectedFeatures","_properties","updateFeatureProperties","setSelected","_propertyMutations","getGeometryCopy","update","Commit","updateGuidancePoints","guidancePoints","updateFeatureGeometries","_ref9","_ref0","createFeatureWithGeometry","_ref1","mutateFeature","correctRightHandRule","buildFeatureWithGeometry","epsilonOffset","epsilon","max","_ref10","existingGeometry","existingProperties","getPropertiesCopy","updatedGeometry","applyCoordinateMutations","correctedGeometry","coordinatesMutations","isReplaceMutation","_step","isPolygon","originalCoordinates","slice","originalLength","normalizeIndex","index","normalized","RangeError","nonInsertByIndex","fill","insertsBeforeByIndex","from","insertsAfterByIndex","tailAfter","_iterator","_createForOfIteratorHelperLoose","done","mutation","normalizedIndex","rawIndex","newCoordinates","_step2","_iterator2","_step3","_iterator3","_i","_tailAfter","_ref11","_ref12","create","updates","updateGeometry","_ref13","Object","entries","_ref14","property","flat","updateProperty","defaultKeyEvents","cancel","finish","defaultCursors","start","TerraDrawCircleMode","endPosition","segments","currentCircleId","keyEvents","cursors","startingRadiusKilometers","cursorMovedAfterInitialCursorDown","drawInteraction","drawType","close","updateCircle","state","action","beginDrawing","startingCircle","created","dragDrawAllowed","moveDrawAllowed","stop","cleanUp","button","isContextMenu","currentId","styleFeature","polygonFillColor","polygonOutlineColor","polygonOutlineWidth","polygonOutlineOpacity","polygonFillOpacity","pointColor","pointOpacity","pointOutlineColor","pointOutlineOpacity","pointOutlineWidth","pointWidth","lineStringColor","lineStringWidth","lineStringOpacity","zIndex","markerUrl","markerHeight","markerWidth","fillColor","outlineColor","outlineWidth","outlineOpacity","fillOpacity","baseValidatedFeature","updatedCircle","newRadius","isFinish","distortion","source","target","geodesicDistance","_lngLatToWebMercatorX","_lngLatToWebMercatorX2","calculateWebMercatorDistortion","radiusMeters","angle","dx","dy","_webMercatorXYToLngLa","circleWebMercator","cartesianDistance","coordinatesIdentical","ReadFeatureBehavior","getGeometryType","coordinateAtIndexIsIdentical","newCoordinate","getGeometry","getCoordinates","_this$store$getGeomet","getCoordinate","coords","getProperties","hasFeature","getAllFeatureIdsWhere","equals","copyAllWhere","TerraDrawFreehandMode","canClose","closingPointId","minDistance","preventPointsNearClose","autoClose","autoCloseTimeout","hasLeftStartingPoint","preventNewFeature","smoothing","readFeature","min","_this$mutateFeature$c","addCoordinate","_this$readFeature$get","previousLng","previousLat","_this$project","containerX","containerY","_this$readFeature$get2","_this$project2","setTimeout","getSmoothedCoordinate","previousCoordinate","targetCoordinate","targetLatitude","cleanUpId","cleanUpClosingPointId","getDefaultStyling","closingPointWidth","closingPointColor","closingPointOpacity","closingPointOutlineColor","closingPointOutlineWidth","closingPointOutlineOpacity","createBBoxFromPoint","point","halfDist","c","ClickBoundingBoxBehavior","PixelDistanceBehavior","measure","clickEvent","secondCoordinate","CoordinateSnappingBehavior","pixelDistance","clickBoundingBox","getSnappableCoordinateFirstClick","getSnappable","getSnappableCoordinate","currentFeatureId","bbox","search","closest","featureCoordinateIndex","minDist","forEach","coordIndex","dist","webMercatorDestination","end","lon1","lon2","lat1","lat2","b","webMercatorBearing","deltaX","deltaY","normalizeBearing","lineSliceAlong","startDist","stopDist","overshot","direction","interpolated","origCoordsLength","travelled","last","toDegrees","InsertCoordinatesBehavior","generateInsertionCoordinates","segmentLength","line","lineLength","numberOfSegments","Number","isInteger","floor","outline","limitCoordinates","generateInsertionGeodesicCoordinates","numberOfPoints","points","d","f","A","B","z","lon","generateGreatCircleCoordinates","ValidateLineStringFeature","magnitude","v","v1","v2","theta","v2y","v1z","v2z","dot","acos","lngLatToVector","vectorToLngLat","LineSnappingBehavior","snappable","boundingBox","nearest","lines","lngLat","inputCoordinate","pointA","pointB","lineVector","targetVector","dotProduct","t","closestPoint","closestDistance","lineIndex","startPosition","stopPosition","intersectPosition","intersectDistance","_findNearestPointOnLi","indexOf","webMercatorNearestPointOnLine","posA","posB","posC","C","Cx","Cy","Cz","_cross","v1y","v2x","v1x","D","E","F","g","h","I1","I2","angleAB","angleAI1","angleBI1","angleAI2","angleBI2","I","nearestPointOnLine","isPolygonArray","getUnclosedCoordinates","featureCoordinates","getClosedCoordinates","ClosingPointsBehavior","mutateFeatureBehavior","readFeatureBehavior","_startEndPoints","selectedCoords","ids","updateOne","updatedCoordinate","updatedCoordinates","isLineStringClosingPoint","isClosing","closing","isPolygonClosingPoints","isPreviousClosing","opening","distancePrevious","CoordinatePointBehavior","createOrUpdate","existingCoordinatePointIds","coordinatePointIds","every","existingCoordinates","existingCoordinatePoints","deleteCoordinatePoints","createPoints","setFeatureCoordinatePoints","existingPoints","deleteOrphanedPoints","deletePointsByFeatureIds","deleteIfPresent","updateOneAtIndex","updateAllInPlace","featureProperties","coordinatePoints","orphanedCoordinatePointIds","dragStart","dragEnd","TerraDrawLineStringMode","currentCoordinate","snapping","mouseMove","insertCoordinates","lastCommittedCoordinates","snappedPointId","lastMouseMoveEvent","showCoordinatePoints","finishOnNthCoordinate","editable","editedFeatureId","editedFeatureCoordinateIndex","editedSnapType","editedInsertIndex","editedPointId","coordinateSnapping","insertPoint","lineSnapping","closingPoints","featuresWithCoordinates","_properties$COMMON_PR","shouldFinishOnCommit","updateSnappedCoordinate","snappedCoordinate","snapCoordinate","updated","generateInsertCoordinates","startCoord","endCoord","strategy","segmentDistance","insertedCoordinates","createLine","startingCoord","firstUpdateToLine","updatedCoord","updateToLine","getInsertCoordinates","startCoordinates","onRightClick","_this$coordinateSnapp","lineStringFilter","coordinateIndex","onLeftClick","lineSnapped","coordinateSnapped","_propertyMutations2","inserted","_propertyMutations3","coordinatePoint","pointType","styleMap","closingPoint","width","color","opacity","snappingPoint","snappingPointWidth","snappingPointColor","snappingPointOpacity","snappingPointOutlineColor","snappingPointOutlineWidth","snappingPointOutlineOpacity","coordinatePointWidth","coordinatePointColor","coordinatePointOpacity","coordinatePointOutlineColor","coordinatePointOutlineWidth","coordinatePointOutlineOpacity","_this5","_this$snapping","_this$snapping2","_this$snapping3","snapped","_this6","toLine","toCoordinate","toCustom","getCurrentGeometrySnapshot","ValidationReasonFeatureNotPoint","ValidationReasonFeatureInvalidCoordinates","ValidationReasonFeatureInvalidCoordinatePrecision","ValidatePointFeature","PointSearchBehavior","getNearestPointFeature","clickedFeature","distanceToFeature","TerraDrawPointMode","pointSearch","nearestPointFeature","isEdited","editedPointWidth","editedPointColor","editedPointOutlineColor","editedPointOutlineWidth","TerraDrawPolygonMode","firstCoordinate","eventCoordinate","_this$closingPoints$i","polygonFilter","_this$mutateFeature$c2","_propertyMutations4","_this$closingPoints$i2","_propertyMutations5","_propertyMutations6","featureCopy","_propertyMutations7","editedPoint","editedPointOpacity","editedPointOutlineOpacity","TerraDrawRectangleMode","currentRectangleId","updateRectangle","TerraDrawRenderMode","Render","validationResult","validatedFeature","featureIsValid","rhumbBearing","to","phi1","phi2","deltaLambda","deltaPsi","bear360","rhumbDestination","distanceMeters","distanceInMeters","abs","delta","lambda1","DeltaPhi","DeltaPsi","q","midpointCoordinate","coordinates1","coordinates2","projectedCoordinateOne","projectedCoordinateTwo","_unproject","geodesicMidpointCoordinate","midpoint","getMidPointCoordinates","featureCoords","midPointCoords","mid","MidPointBehavior","selectionPointBehavior","coordinatePointBehavior","_midPoints","getMidpointConfig","getNearestMidPoint","closestMidPointDistance","closestMidPointId","insert","midPointId","midPoint","midPointFeatureId","midPointSegment","midpoints","SelectionPointBehavior","_selectionPoints","pointInPolygon","rings","p","p1","p2","inside","len","ring","j","len2","k","pixelDistanceToLine","linePointOne","linePointTwo","square","dist2","w","l2","distToSegmentSquared","FeatureAtPointerEventBehavior","createClickBoundingBox","find","hasSelection","clickedPoint","clickedPointDistance","clickedLineString","clickedLineStringDistance","clickedPolygon","selectionPoint","nextCoord","distanceToLine","DragFeatureBehavior","featuresAtCursorEvent","selectionPoints","midPoints","draggedFeatureId","dragPosition","startDragging","stopDragging","isDragging","canDrag","drag","cursorCoord","updatedCoords","upToCoord","updatedLng","updatedLat","webMercatorDragPosition","webMercatorCursorCoord","webMercatorCoordinate","DragCoordinateBehavior","draggedCoordinate","getClosestCoordinate","geomCoordinates","closestCoordinate","isFirstOrLastPolygonCoord","getDraggable","getDraggableIndex","draggedFeature","allowSelfIntersection","lastCoordIndex","centroid","geojson","xSum","ySum","transformRotateWebMercator","angleRad","webMercatorCoords","reduce","acc","rotatedCoordinates","webMercatorCentroid","webMercatorCoordinates","area","centroidX","centroidY","n","_webMercatorCoordinat","_webMercatorCoordinat2","crossProduct","calculatePolygonCentroid","lineString","totalX","totalY","_lineString$i","calculateLineStringMidpoint","RotateFeatureBehavior","lastBearing","selectedGeometry","selectedGeometryCentroid","selectedGeometryWebMercatorCentroid","reset","rotate","mouseCoord","updatedFeature","cursorWebMercator","pivot","pointCoords","finalAngle","DeltaLambda","rhumbDistance","newCoords","transformRotate","ScaleFeatureBehavior","dragCoordinateResizeBehavior","scale","transformScaleWebMercatorCoordinates","originX","originY","xScale","yScale","DragCoordinateResizeBehavior","minimumScale","boundingBoxMaps","opposite","isValidDragWebMercator","distanceX","distanceY","getSelectedFeatureDataWebMercator","getFeature","getNormalisedCoordinates","getBBoxWebMercator","selectedCoordinate","centerWebMercatorDrag","featureData","webMercatorOrigin","webMercatorSelected","closestBBoxIndex","getIndexesWebMercator","webMercatorCursor","scaleWebMercator","centerFixedWebMercatorDrag","scaleFixedWebMercator","oppositeFixedWebMercatorDrag","_this$getIndexesWebMe3","oppositeBboxIndex","oppositeWebMercatorDrag","_this$getIndexesWebMe4","cursorDistanceX","cursorDistanceY","validateScale","performWebMercatorScale","validX","MAX_SAFE_INTEGER","validY","west","south","east","north","selectedXY","closestIndex","resizeOption","deselect","delete","pointerOver","insertMidpoint","TerraDrawSelectMode","_TerraDrawBaseSelectM","allowManualDeselection","dragEventThrottle","dragEventCount","selected","flags","validations","dragTarget","coordinateSnap","featuresAtMouseEvent","dragFeature","dragCoordinate","rotateFeature","scaleFeature","dragCoordinateResizeFeature","lineSnap","selectFeature","select","setSelecting","deselectFeature","deleteSelected","clearDragTargetAndCursor","getSelectedFlags","modeFlags","featureFlags","coordinatesFlags","hasDraggableFlags","draggable","resizable","clickedSelectionPointProps","clickedFeatureDistance","selectionPointFeatureId","deletable","splice","shift","pop","fromCursor","previouslySelectedId","midPointClicked","_featureFlags$coordin","dragCoordinateDistance","canScale","heldKeys","canRotate","preventDefaultKeyEvent","isRotationKeys","isScaleKeys","preventDefault","_this$getSelectedFlag2","pointerOverTarget","draggableCoordinateIndex","resizableCoordinateIndex","resizableCoordinate","draggableCoordinate","draggableMidPoint","draggableFeature","draggedMidPointId","draggableCoordinateIndexAfterInsert","canSelfIntersect","selfIntersectable","rotateable","scaleable","_modeFlags$feature","snapOptions","nearbyMidPoint","_this$dragCoordinate$2","closestDraggableCoordinateDistance","selectionPointColor","selectionPointOpacity","selectionPointOutlineColor","selectionPointWidth","selectionPointOutlineOpacity","selectionPointOutlineWidth","midPointColor","midPointOpacity","midPointOutlineColor","midPointWidth","midPointOutlineOpacity","midPointOutlineWidth","selectedMarkerUrl","selectedMarkerHeight","selectedMarkerWidth","selectedPolygonColor","selectedPolygonOutlineWidth","selectedPolygonOutlineColor","selectedPolygonOutlineOpacity","selectedPolygonFillOpacity","selectedLineStringColor","selectedLineStringWidth","selectedPointWidth","selectedPointColor","selectedPointOpacity","selectedPointOutlineColor","selectedPointOutlineOpacity","selectedPointOutlineWidth","_flags$feature","_flags$feature2","TerraDrawStaticMode","Static","quickselect","arr","left","right","compare","m","s","sd","swap","tmp","calcBBox","node","toBBox","distBBox","children","destNode","createNode","minX","minY","maxX","maxY","child","extend","leaf","compareNodeMinX","compareNodeMinY","bboxArea","bboxMargin","contains","intersects","height","multiSelect","stack","ceil","RBush","maxEntries","_maxEntries","_minEntries","data","clear","result","nodesToSearch","childBBox","_all","collides","load","_build","_splitRoot","tmpNode","_insert","item","remove","parent","path","indexes","goingUp","_condense","compareMinX","compareMinY","items","N","M","N2","N1","right2","right3","_chooseSubtree","level","minArea","minEnlargement","targetNode","enlargement","isNode","insertPath","_split","_adjustParentBBoxes","_chooseSplitAxis","splitIndex","_chooseSplitIndex","newNode","minOverlap","bbox1","bbox2","overlap","_allDistMargin","sort","leftBBox","rightBBox","margin","siblings","SpatialIndex","tree","idToNode","nodeToId","Map","setMaps","longitudes","latitudes","minLat","maxLat","String","seenIds","Set","add","defaultIdStrategy","getId","replace","r","random","geometryContext","propertiesContext","GeoJSONStore","tracked","spatialIndex","_onChange","clone","obj","JSON","parse","stringify","featureValidation","clonedInputFeatures","createdFeatures","createdAt","updatedAt","changes","change","propertiesToUpdate","size","geometriesToUpdate","createdProperties","copy","copyAll","_this7","keys","_this8","polygonAreaSquareMeters","total","ringArea","FACTOR","PI_OVER_180","coordsLength","ValidationReasonFeatureLessThanMinSize","ValidationReasonFeatureNotPolygonOrLineString","ValidationReasonFeatureSelfIntersects","calculateRelativeAngle","bearingAB","relativeAngle","TerraDrawAngledRectangleMode","getUpdateForSecondCoordinate","getNewSecondAndThirdCoordinates","offset","lineStart","lineEnd","ACloserThanC","hypotenuse","adjacent","rectangleAngle","thirdCoordinateXY","fourthCoordinateXY","thirdCoordinate","fourthCoordinate","isClockwiseWebMercator","secondCoord","thirdCoord","TerraDrawSectorMode","arcPoints","getSectorCoordinates","currentPolygonCoordinates","arcCoordOne","arcCoordTwo","webMercatorCenter","webMercatorArcCoordOne","webMercatorArcCoordTwo","clockwise","deltaBearing","radius","startBearing","endBearing","normalizedStart","normalizedEnd","bearingStep","pointOnArc","mutations","sectorCoordinates","TerraDrawSensorMode","currentInitialArcId","currentStartingPointId","getUpdatedLineStringCoordinates","getUpdatedPolygonCoordinates","centerPointColor","centerPointOpacity","centerPointWidth","centerPointOutlineColor","centerPointOutlineOpacity","centerPointOutlineWidth","finishedCurrentStartingPointId","finishedInitialArcId","firstCoord","lastCoord","webMercatorCoordOne","webMercatorCoordTwo","innerRadius","radiusCalculationPosition","cursorBearing","normalizedCursor","notInSector","getDeltaBearing","finalArc","unshift","_webMercatorXYToLngLa2","AdapterListener","name","callback","unregister","registered","TerraDrawBaseAdapter","_nextKeyUpIsContextMenu","_lastPointerDownEventTarget","_ignoreMismatchedPointerEvents","_minPixelDragDistance","_minPixelDragDistanceDrawing","_minPixelDragDistanceSelecting","_lastDrawEvent","_coordinatePrecision","_heldKeys","_listeners","_dragState","_currentModeCallbacks","ignoreMismatchedPointerEvents","minPixelDragDistance","minPixelDragDistanceSelecting","minPixelDragDistanceDrawing","getButton","getMapElementXYPosition","_mapElement$getBoundi","getMapEventElement","getBoundingClientRect","clientX","clientY","top","getDrawEventFromEvent","latLng","getLngLatFromEvent","_this$getMapElementXY","callbacks","getAdapterListeners","listener","getCoordinatePrecision","isPrimary","drawEvent","addEventListener","removeEventListener","lastEventXY","currentEventXY","modeState","getState","pixelDistanceToCheck","enabled","setDraggability","bind","ValidationReasons","TerraDrawFreehandLineStringMode","closingDistance","createdId","isValidJSONValue","isFinite","RegExp","proto","getPrototypeOf","ArrayBuffer","isView","DataView","TerraDrawMarkerMode","_this$styles","_this$styles2","_this$styles3","TerraDraw","_modes","_mode","_adapter","_enabled","_store","_eventListeners","_instanceSelectModes","adapter","duplicateModeTracker","modesMap","modes","modeMap","currentMode","modeKeys","static","ready","getChanged","changed","unchanged","_getChanged","render","deletedIds","getModeStyles","_getChanged2","_getChanged3","modeId","checkEnabled","modeStyles","activeSelectMode","featuresAtLocation","ignoreSelectFeatures","ignoreCoordinatePoints","ignoreCurrentlyDrawing","ignoreClosingPoints","ignoreSnappingPoints","inputPoint","pointCoordinates","pointXY","includePolygonsWithinPointerDistance","projectedStart","projectedEnd","addClosestCoordinateInfoToProperties","closestCoordinateIndexToEvent","closestCoordinatePixelDistanceToEvent","closestCoordinateDistanceKmToEvent","getSelectModeOrThrow","selectMode","foundSelectMode","getSelectMode","switchToSelectMode","modeToUse","getMode","setMode","isGuidanceFeature","setModeStyles","updateModeOptions","getSnapshot","getSnapshotFeature","getModeState","removeFeatures","coordinatePointsToDelete","idsToDelete","modeToCleanUp","getFeatureId","checkIsReservedProperty","propertyName","values","updateFeatureGeometry","modeToUpdate","featureIsSelected","selectModePresent","transformFeatureGeometry","transformation","addFeatures","featureMode","modeToAddTo","onReady","onClear","getFeaturesAtLngLat","getFeaturesAtPointerEvent","on","listeners","off","maxSize","minSize"],"mappings":"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"}
