{"version":3,"file":"terra-draw.cjs","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/undo-redo.behavior.ts","../src/modes/linestring/linestring.mode.ts","../src/modes/polyline/polyline.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/undo-redo/keyboard-shortcuts.ts","../src/undo-redo/normalise-stack-size.ts","../src/undo-redo/undo-redo-types.ts","../src/undo-redo/mode-undo-redo.ts","../src/undo-redo/session-undo-redo.ts","../src/undo-redo/undo-redo-coordinator.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 | undefined);\n\nexport type NumericStyling =\n\t| number\n\t| ((feature: GeoJSONStoreFeatures) => number | undefined);\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\t/** lineStringDash - Tuple representing the dash pattern for the line string, where the first number is the length of the dash and the second number is the length of the gap in pixels */\n\tlineStringDash?: [number, 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\tundoRedoMaxStackSize?: 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\t| string\n\t| number\n\t| HexColorStyling\n\t| NumericStyling\n\t| UrlStyling\n\t| [number, number]\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 undoRedoMaxStackSize?: 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\t\t\tthis.undoRedoMaxStackSize = config.undoRedoMaxStackSize;\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\tundoRedoMaxStackSize: config.undoRedoMaxStackSize,\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\tif (!validStoreFeature.valid) {\n\t\t\treturn validStoreFeature;\n\t\t}\n\n\t\t// We also want to 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\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\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\tundo() {}\n\tclearHistory() {}\n\tundoSize() {\n\t\treturn 0;\n\t}\n\tredoSize() {\n\t\treturn 0;\n\t}\n\tredo() {}\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:\n\t\t\t| HexColor\n\t\t\t| ((feature: GeoJSONStoreFeatures) => HexColor | undefined)\n\t\t\t| 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:\n\t\t\t| number\n\t\t\t| ((feature: GeoJSONStoreFeatures) => number | undefined)\n\t\t\t| 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) | 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) ?? defaultValue;\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\tundoRedoMaxStackSize?: number;\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\tprotected undoRedoMaxStackSize?: number;\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\tundoRedoMaxStackSize,\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\tthis.undoRedoMaxStackSize = undoRedoMaxStackSize;\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}): GeoJSONStoreFeatures<Polygon> & { id: FeatureId };\n\tpublic createPolygon({\n\t\tcoordinates,\n\t\tproperties,\n\t\tcontext,\n\t}: {\n\t\tcoordinates: Polygon[\"coordinates\"][0];\n\t\tproperties: JSONObject;\n\t\tcontext: FinishContext;\n\t}): (GeoJSONStoreFeatures<Polygon> & { id: FeatureId }) | undefined;\n\tpublic createPolygon({\n\t\tcoordinates,\n\t\tproperties,\n\t\tcontext,\n\t}: {\n\t\tcoordinates: Polygon[\"coordinates\"][0];\n\t\tproperties: JSONObject;\n\t\tcontext?: FinishContext;\n\t}): (GeoJSONStoreFeatures<Polygon> & { id: FeatureId }) | undefined {\n\t\tconst corrected = ensureRightHandRule({\n\t\t\ttype: \"Polygon\",\n\t\t\tcoordinates: [coordinates],\n\t\t});\n\n\t\tconst polygon = {\n\t\t\ttype: \"Polygon\",\n\t\t\tcoordinates: corrected ? corrected.coordinates : [coordinates],\n\t\t} as Polygon;\n\n\t\tif (context?.updateType === UpdateTypes.Finish) {\n\t\t\tconst valid = this.validateGeometryWithUpdateType({\n\t\t\t\tgeometry: polygon,\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\treturn this.handleCreateFeature({\n\t\t\tgeometry: polygon,\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\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\tlineStringDash: 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","type UndoRedoHistoryEntry<Coordinates> = {\n\tfeatureCoordinates: Coordinates;\n\tcurrentCoordinate: number;\n};\n\ntype UndoStepResult<Coordinates> = {\n\tundoneEntry: UndoRedoHistoryEntry<Coordinates>;\n\tpreviousEntry: UndoRedoHistoryEntry<Coordinates> | undefined;\n};\n\ntype UndoRedoBehaviorOptions = {\n\tmaxStackSize?: number;\n};\n\nexport class UndoRedoBehavior<Coordinates> {\n\tprivate undoHistory: UndoRedoHistoryEntry<Coordinates>[] = [];\n\tprivate redoHistory: UndoRedoHistoryEntry<Coordinates>[] = [];\n\tprivate cloneCoordinatesFunction: (coordinates: Coordinates) => Coordinates;\n\tprivate maxStackSize: number;\n\n\tconstructor(options?: UndoRedoBehaviorOptions) {\n\t\tthis.cloneCoordinatesFunction = (coordinates) =>\n\t\t\tthis.cloneRecursively(coordinates) as Coordinates;\n\n\t\tconst configuredMaxStackSize = options?.maxStackSize;\n\t\tif (\n\t\t\tconfiguredMaxStackSize === undefined ||\n\t\t\t!Number.isFinite(configuredMaxStackSize)\n\t\t) {\n\t\t\tthis.maxStackSize = Number.POSITIVE_INFINITY;\n\t\t} else {\n\t\t\tthis.maxStackSize = Math.max(0, Math.floor(configuredMaxStackSize));\n\t\t}\n\t}\n\n\tsetMaxStackSize(maxStackSize: number) {\n\t\tif (!Number.isFinite(maxStackSize)) {\n\t\t\tthis.maxStackSize = Number.POSITIVE_INFINITY;\n\t\t\treturn;\n\t\t}\n\n\t\tthis.maxStackSize = Math.max(0, Math.floor(maxStackSize));\n\t\tthis.trimHistoryToMax(this.undoHistory);\n\t\tthis.trimHistoryToMax(this.redoHistory);\n\t}\n\n\tprivate trimHistoryToMax(history: UndoRedoHistoryEntry<Coordinates>[]) {\n\t\tif (!Number.isFinite(this.maxStackSize)) {\n\t\t\treturn;\n\t\t}\n\n\t\twhile (history.length > this.maxStackSize) {\n\t\t\thistory.shift();\n\t\t}\n\t}\n\n\tprivate pushUndoEntry(entry: UndoRedoHistoryEntry<Coordinates>) {\n\t\tif (this.maxStackSize === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.undoHistory.push(entry);\n\t\tthis.trimHistoryToMax(this.undoHistory);\n\t}\n\n\tprivate pushRedoEntry(entry: UndoRedoHistoryEntry<Coordinates>) {\n\t\tif (this.maxStackSize === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.redoHistory.push(entry);\n\t\tthis.trimHistoryToMax(this.redoHistory);\n\t}\n\n\tprivate cloneRecursively(value: unknown): unknown {\n\t\tif (Array.isArray(value)) {\n\t\t\treturn value.map((childValue) => this.cloneRecursively(childValue));\n\t\t}\n\n\t\tif (value !== null && typeof value === \"object\") {\n\t\t\treturn { ...value };\n\t\t}\n\n\t\treturn value;\n\t}\n\n\tpublic cloneCoordinates(coordinates: Coordinates): Coordinates {\n\t\treturn this.cloneCoordinatesFunction(coordinates);\n\t}\n\n\tprivate cloneEntry(\n\t\tentry: UndoRedoHistoryEntry<Coordinates>,\n\t): UndoRedoHistoryEntry<Coordinates> {\n\t\treturn {\n\t\t\tfeatureCoordinates: this.cloneCoordinates(entry.featureCoordinates),\n\t\t\tcurrentCoordinate: entry.currentCoordinate,\n\t\t};\n\t}\n\n\tclear() {\n\t\tthis.undoHistory = [];\n\t\tthis.redoHistory = [];\n\t}\n\n\tundoSize() {\n\t\treturn this.undoHistory.length;\n\t}\n\n\tredoSize() {\n\t\treturn this.redoHistory.length;\n\t}\n\n\trecordSnapshot(entry: UndoRedoHistoryEntry<Coordinates>) {\n\t\tthis.pushUndoEntry(this.cloneEntry(entry));\n\t\tthis.redoHistory = [];\n\t}\n\n\tbeginUndo(): UndoStepResult<Coordinates> | undefined {\n\t\tconst undoneEntry = this.undoHistory.pop();\n\n\t\tif (!undoneEntry) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst clonedUndoneEntry = this.cloneEntry(undoneEntry);\n\t\tthis.pushRedoEntry(clonedUndoneEntry);\n\n\t\tconst previousEntry = this.undoHistory[this.undoHistory.length - 1];\n\n\t\treturn {\n\t\t\tundoneEntry: clonedUndoneEntry,\n\t\t\tpreviousEntry: previousEntry ? this.cloneEntry(previousEntry) : undefined,\n\t\t};\n\t}\n\n\ttakeRedo(): UndoRedoHistoryEntry<Coordinates> | undefined {\n\t\tconst redoneEntry = this.redoHistory.pop();\n\n\t\tif (!redoneEntry) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn this.cloneEntry(redoneEntry);\n\t}\n\n\tcommitRedo(entry: UndoRedoHistoryEntry<Coordinates>) {\n\t\tthis.pushUndoEntry(this.cloneEntry(entry));\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\";\nimport { UndoRedoBehavior } from \"../undo-redo.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\tlineStringDash: [number, number];\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\tprivate undoRedo!: UndoRedoBehavior<Position[]>;\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\t\tthis.undoRedo.clear();\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.pushHistorySnapshot(this.currentId, this.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\t\tthis.pushHistorySnapshot(this.currentId, this.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\t\tthis.pushHistorySnapshot(this.currentId, this.currentCoordinate);\n\n\t\tif (this.shouldFinishOnCommit(updated.geometry)) {\n\t\t\tthis.close();\n\t\t}\n\t}\n\n\tundoSize() {\n\t\treturn this.undoRedo.undoSize();\n\t}\n\n\tclearHistory() {\n\t\tthis.undoRedo.clear();\n\t}\n\n\tprivate pushHistorySnapshot(featureId: FeatureId, currentCoordinate: number) {\n\t\tconst featureGeometry = this.readFeature.getGeometry<LineString>(featureId);\n\n\t\tthis.undoRedo.recordSnapshot({\n\t\t\tfeatureCoordinates: featureGeometry.coordinates,\n\t\t\tcurrentCoordinate,\n\t\t});\n\t}\n\n\tprivate updateSnappedGuidancePointFromLastMouseMove() {\n\t\tif (!this.snapping || !this.lastMouseMoveEvent) {\n\t\t\tif (this.snappedPointId) {\n\t\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\t\t\tthis.snappedPointId = undefined;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tthis.updateSnappedCoordinate(this.lastMouseMoveEvent);\n\t}\n\n\tprivate syncClosingPoints(featureCoordinates: Position[]) {\n\t\tif (this.currentCoordinate >= 2) {\n\t\t\tif (this.closingPoints.ids.length) {\n\t\t\t\tthis.closingPoints.update(featureCoordinates);\n\t\t\t} else {\n\t\t\t\tthis.closingPoints.create(featureCoordinates);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.closingPoints.delete();\n\t\t}\n\t}\n\n\tpublic undo() {\n\t\tif (this.state !== \"drawing\" || !this.currentId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst undoStepResult = this.undoRedo.beginUndo();\n\n\t\tif (!undoStepResult) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { previousEntry: previousHistoryEntry } = undoStepResult;\n\n\t\tif (!previousHistoryEntry) {\n\t\t\tconst removedFeatureId = this.currentId;\n\n\t\t\tthis.currentId = undefined;\n\t\t\tthis.currentCoordinate = 0;\n\t\t\tthis.lastCommittedCoordinates = undefined;\n\t\t\tthis.closingPoints.delete();\n\n\t\t\tif (this.state === \"drawing\") {\n\t\t\t\tthis.setStarted();\n\t\t\t}\n\n\t\t\tif (this.showCoordinatePoints) {\n\t\t\t\tthis.coordinatePoints.deletePointsByFeatureIds([removedFeatureId]);\n\t\t\t}\n\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(removedFeatureId);\n\t\t\tthis.updateSnappedGuidancePointFromLastMouseMove();\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\ttype: Mutations.Replace,\n\t\t\t\tcoordinates: previousHistoryEntry.featureCoordinates,\n\t\t\t},\n\t\t\tpropertyMutations: {\n\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: true,\n\t\t\t},\n\t\t\tcontext: { updateType: UpdateTypes.Commit },\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.currentCoordinate = previousHistoryEntry.currentCoordinate;\n\t\tthis.lastCommittedCoordinates = updated.geometry.coordinates;\n\t\tthis.syncClosingPoints(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.updateSnappedGuidancePointFromLastMouseMove();\n\t}\n\n\tpublic redoSize(): number {\n\t\treturn this.undoRedo.redoSize();\n\t}\n\n\tpublic redo() {\n\t\tconst redoneHistoryEntry = this.undoRedo.takeRedo();\n\n\t\tif (!redoneHistoryEntry) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.currentId) {\n\t\t\tconst { id, geometry } = this.mutateFeature.createLineString({\n\t\t\t\tcoordinates: redoneHistoryEntry.featureCoordinates,\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},\n\t\t\t});\n\n\t\t\tthis.currentId = id;\n\t\t\tthis.currentCoordinate = redoneHistoryEntry.currentCoordinate;\n\t\t\tthis.lastCommittedCoordinates = geometry.coordinates;\n\n\t\t\tif (this.state === \"started\") {\n\t\t\t\tthis.setDrawing();\n\t\t\t}\n\n\t\t\tthis.syncClosingPoints(geometry.coordinates);\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\t\t} else {\n\t\t\tconst updated = this.mutateFeature.updateLineString({\n\t\t\t\tfeatureId: this.currentId,\n\t\t\t\tcoordinateMutations: {\n\t\t\t\t\ttype: Mutations.Replace,\n\t\t\t\t\tcoordinates: redoneHistoryEntry.featureCoordinates,\n\t\t\t\t},\n\t\t\t\tpropertyMutations: {\n\t\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: true,\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\tthis.currentCoordinate = redoneHistoryEntry.currentCoordinate;\n\t\t\tthis.lastCommittedCoordinates = updated.geometry.coordinates;\n\t\t\tthis.syncClosingPoints(updated.geometry.coordinates);\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\t\t}\n\n\t\tthis.undoRedo.commitRedo(redoneHistoryEntry);\n\n\t\tthis.updateSnappedGuidancePointFromLastMouseMove();\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\n\t\tthis.undoRedo = new UndoRedoBehavior<Position[]>({\n\t\t\tmaxStackSize: config.undoRedoMaxStackSize,\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\tthis.lastCommittedCoordinates = undefined;\n\t\tthis.undoRedo.clear();\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.lineStringDash = this.styles.lineStringDash;\n\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\t\t\tthis.lastCommittedCoordinates = undefined;\n\t\t\tthis.undoRedo.clear();\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 {\n\tTerraDrawAdapterStyling,\n\tTerraDrawKeyboardEvent,\n\tTerraDrawMouseEvent,\n\tHexColorStyling,\n\tNumericStyling,\n\tCursor,\n\tUpdateTypes,\n\tZ_INDEX,\n\tCOMMON_PROPERTIES,\n\tFinishActions,\n\tSnapping,\n} from \"../../common\";\nimport { LineString, Polygon, 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 { LineSnappingBehavior } from \"../line-snapping.behavior\";\nimport { CoordinateSnappingBehavior } from \"../coordinate-snapping.behavior\";\nimport { getDefaultStyling } from \"../../util/styling\";\nimport {\n\tFeatureId,\n\tGeoJSONStoreFeatures,\n\tStoreValidation,\n} from \"../../store/store\";\nimport { ValidateLineStringFeature } from \"../../validations/linestring.validation\";\nimport { ValidatePolygonFeature } from \"../../validations/polygon.validation\";\nimport { ClosingPointsBehavior } from \"../closing-points.behavior\";\nimport { MutateFeatureBehavior, Mutations } from \"../mutate-feature.behavior\";\nimport { ReadFeatureBehavior } from \"../read-feature.behavior\";\n\ntype TerraDrawPolyLineModeKeyEvents = {\n\tcancel: KeyboardEvent[\"key\"] | null;\n\tfinish: KeyboardEvent[\"key\"] | null;\n};\n\nconst defaultKeyEvents = { cancel: \"Escape\", finish: \"Enter\" } as const;\n\ntype PolyLineStyling = {\n\tlineStringWidth: NumericStyling;\n\tlineStringColor: HexColorStyling;\n\tlineStringOpacity: NumericStyling;\n\tpolygonFillColor: HexColorStyling;\n\tpolygonFillOpacity: NumericStyling;\n\tpolygonOutlineColor: HexColorStyling;\n\tpolygonOutlineWidth: NumericStyling;\n\tpolygonOutlineOpacity: 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};\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 TerraDrawPolyLineModeOptions<\n\tT extends CustomStyling,\n> extends BaseModeOptions<T> {\n\tsnapping?: Snapping;\n\tkeyEvents?: TerraDrawPolyLineModeKeyEvents | null;\n\tcursors?: Cursors;\n}\n\nexport class TerraDrawPolyLineMode extends TerraDrawBaseDrawMode<PolyLineStyling> {\n\tmode = \"polyline\";\n\n\tprivate currentCoordinate = 0;\n\tprivate currentId: FeatureId | undefined;\n\tprivate keyEvents: TerraDrawPolyLineModeKeyEvents = defaultKeyEvents;\n\tprivate cursors: Required<Cursors> = defaultCursors;\n\tprivate mouseMove = false;\n\tprivate snapping: Snapping | undefined;\n\tprivate snappedPointId: FeatureId | undefined;\n\n\tprivate mutateFeature!: MutateFeatureBehavior;\n\tprivate readFeature!: ReadFeatureBehavior;\n\tprivate pixelDistance!: PixelDistanceBehavior;\n\tprivate closingPoints!: ClosingPointsBehavior;\n\tprivate clickBoundingBox!: ClickBoundingBoxBehavior;\n\tprivate lineSnapping!: LineSnappingBehavior;\n\tprivate coordinateSnapping!: CoordinateSnappingBehavior;\n\n\tconstructor(options?: TerraDrawPolyLineModeOptions<PolyLineStyling>) {\n\t\tsuper(options, true);\n\t\tthis.updateOptions(options);\n\t}\n\n\toverride updateOptions(\n\t\toptions?: ModeUpdateOptions<TerraDrawPolyLineModeOptions<PolyLineStyling>>,\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?.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\t}\n\n\t/** @internal */\n\tregisterBehaviors(config: BehaviorConfig) {\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}\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 finishLine() {\n\t\tif (!this.currentId) {\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: [{ type: Mutations.Delete, index: -1 }],\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\tconst featureId = this.currentId;\n\t\tthis.currentCoordinate = 0;\n\t\tthis.currentId = undefined;\n\t\tthis.closingPoints.delete();\n\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\tthis.snappedPointId = undefined;\n\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.onFinish(featureId, { mode: this.mode, action: FinishActions.Draw });\n\t}\n\n\tprivate toPolygonLikeCoordinates(lineCoordinates: Position[]) {\n\t\tif (lineCoordinates.length === 0) {\n\t\t\treturn [lineCoordinates];\n\t\t}\n\n\t\treturn [[...lineCoordinates, lineCoordinates[0]]];\n\t}\n\n\tprivate closeAsPolygon() {\n\t\tif (!this.currentId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst geometry = this.readFeature.getGeometry<LineString>(this.currentId);\n\t\tconst committed = geometry.coordinates.slice(0, -1);\n\n\t\tif (committed.length < 3) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst featureIdToRemove = this.currentId;\n\t\tconst closedCoordinates = [...committed, committed[0]];\n\n\t\tconst created = this.mutateFeature.createPolygon({\n\t\t\tcoordinates: closedCoordinates,\n\t\t\tproperties: {\n\t\t\t\tmode: this.mode,\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 (!created) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.mutateFeature.deleteFeatureIfPresent(featureIdToRemove);\n\n\t\tthis.currentCoordinate = 0;\n\t\tthis.currentId = undefined;\n\t\tthis.closingPoints.delete();\n\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\tthis.snappedPointId = undefined;\n\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.onFinish(created.id as FeatureId, {\n\t\t\tmode: this.mode,\n\t\t\taction: FinishActions.Draw,\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\t\tthis.updateSnappedCoordinate(event);\n\n\t\tif (!this.currentId || this.currentCoordinate === 0) {\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.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],\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\tconst { isClosing, isPreviousClosing } =\n\t\t\tthis.closingPoints.isPolygonClosingPoints(event);\n\t\tif (\n\t\t\t(isClosing && this.currentCoordinate >= 3) ||\n\t\t\t(isPreviousClosing && this.currentCoordinate >= 2)\n\t\t) {\n\t\t\tthis.setCursor(this.cursors.close);\n\t\t}\n\t}\n\n\tprivate onLeftClick(event: TerraDrawMouseEvent) {\n\t\tthis.updateSnappedCoordinate(event);\n\t\tconst clickedCoordinate: Position = [event.lng, event.lat];\n\n\t\tif (this.currentCoordinate === 0) {\n\t\t\tconst created = this.mutateFeature.createLineString({\n\t\t\t\tcoordinates: [clickedCoordinate, clickedCoordinate],\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},\n\t\t\t});\n\n\t\t\tthis.currentId = created.id as FeatureId;\n\t\t\tthis.currentCoordinate = 1;\n\t\t\tthis.setDrawing();\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.currentId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { isClosing, isPreviousClosing } =\n\t\t\tthis.closingPoints.isPolygonClosingPoints(event);\n\n\t\tif (isClosing && this.currentCoordinate >= 3) {\n\t\t\tthis.closeAsPolygon();\n\t\t\treturn;\n\t\t}\n\n\t\tif (isPreviousClosing && this.currentCoordinate >= 2) {\n\t\t\tthis.finishLine();\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.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: clickedCoordinate,\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.currentCoordinate++;\n\n\t\tif (this.currentCoordinate >= 2) {\n\t\t\tconst polygonLikeCoordinates = this.toPolygonLikeCoordinates(\n\t\t\t\tupdated.geometry.coordinates,\n\t\t\t);\n\n\t\t\tif (this.closingPoints.ids.length === 0) {\n\t\t\t\tthis.closingPoints.create(polygonLikeCoordinates);\n\t\t\t} else {\n\t\t\t\tthis.closingPoints.update(polygonLikeCoordinates);\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tonClick(event: TerraDrawMouseEvent) {\n\t\tif (\n\t\t\tevent.button === \"left\" &&\n\t\t\tthis.allowPointerEvent(this.pointerEvents.leftClick, event)\n\t\t) {\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\t\t\tthis.onLeftClick(event);\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.finishLine();\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\t\tthis.currentId = undefined;\n\t\tthis.currentCoordinate = 0;\n\n\t\tif (this.state === \"drawing\") {\n\t\t\tthis.setStarted();\n\t\t}\n\n\t\tthis.mutateFeature.deleteFeatureIfPresent(currentId);\n\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\tthis.snappedPointId = undefined;\n\t\tthis.closingPoints.delete();\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\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\t/** @internal */\n\tstyleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {\n\t\tconst styles = { ...getDefaultStyling() };\n\n\t\tif (feature.properties.mode !== this.mode) {\n\t\t\treturn styles;\n\t\t}\n\n\t\tif (feature.geometry.type === \"LineString\") {\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.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.lineStringOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.lineStringOpacity,\n\t\t\t\t1,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.zIndex = Z_INDEX.LAYER_ONE;\n\t\t\treturn styles;\n\t\t}\n\n\t\tif (feature.geometry.type === \"Polygon\") {\n\t\t\tstyles.polygonFillColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.polygonFillColor,\n\t\t\t\tstyles.polygonFillColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonFillOpacity = this.getNumericStylingValue(\n\t\t\t\tthis.styles.polygonFillOpacity,\n\t\t\t\tstyles.polygonFillOpacity,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.polygonOutlineColor = this.getHexColorStylingValue(\n\t\t\t\tthis.styles.polygonOutlineColor,\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.polygonOutlineWidth,\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.polygonOutlineOpacity,\n\t\t\t\t1,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.zIndex = Z_INDEX.LAYER_ONE;\n\t\t\treturn styles;\n\t\t}\n\n\t\tif (feature.geometry.type === \"Point\") {\n\t\t\tconst closingPoint =\n\t\t\t\tfeature.properties[COMMON_PROPERTIES.CLOSING_POINT] === true;\n\t\t\tconst snappingPoint =\n\t\t\t\tfeature.properties[COMMON_PROPERTIES.SNAPPING_POINT] === true;\n\n\t\t\tif (!closingPoint && !snappingPoint) {\n\t\t\t\treturn styles;\n\t\t\t}\n\n\t\t\tstyles.pointColor = this.getHexColorStylingValue(\n\t\t\t\tclosingPoint\n\t\t\t\t\t? this.styles.closingPointColor\n\t\t\t\t\t: this.styles.snappingPointColor,\n\t\t\t\tstyles.pointColor,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointWidth = this.getNumericStylingValue(\n\t\t\t\tclosingPoint\n\t\t\t\t\t? this.styles.closingPointWidth\n\t\t\t\t\t: this.styles.snappingPointWidth,\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\tclosingPoint\n\t\t\t\t\t? this.styles.closingPointOpacity\n\t\t\t\t\t: this.styles.snappingPointOpacity,\n\t\t\t\t1,\n\t\t\t\tfeature,\n\t\t\t);\n\n\t\t\tstyles.pointOutlineColor = this.getHexColorStylingValue(\n\t\t\t\tclosingPoint\n\t\t\t\t\t? this.styles.closingPointOutlineColor\n\t\t\t\t\t: this.styles.snappingPointOutlineColor,\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\tclosingPoint\n\t\t\t\t\t? this.styles.closingPointOutlineWidth\n\t\t\t\t\t: this.styles.snappingPointOutlineWidth,\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\tclosingPoint\n\t\t\t\t\t? this.styles.closingPointOutlineOpacity\n\t\t\t\t\t: this.styles.snappingPointOutlineOpacity,\n\t\t\t\t1,\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\tafterFeatureAdded(_feature: GeoJSONStoreFeatures) {}\n\n\tafterFeatureUpdated(feature: GeoJSONStoreFeatures) {\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.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\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, (validatedFeature) => {\n\t\t\tif (validatedFeature.geometry.type === \"LineString\") {\n\t\t\t\treturn ValidateLineStringFeature(\n\t\t\t\t\tvalidatedFeature,\n\t\t\t\t\tthis.coordinatePrecision,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (validatedFeature.geometry.type === \"Polygon\") {\n\t\t\t\treturn ValidatePolygonFeature(\n\t\t\t\t\tvalidatedFeature,\n\t\t\t\t\tthis.coordinatePrecision,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tvalid: false,\n\t\t\t\treason: \"Only LineString or Polygon features are valid\",\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\";\nimport { UndoRedoBehavior } from \"../undo-redo.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\tprivate undoRedo!: UndoRedoBehavior<Position[][]>;\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 polygonFeatures = this.store\n\t\t\t\t\t.copyAllWhere((properties) => properties.mode === this.mode)\n\t\t\t\t\t.filter((feature) => feature.geometry.type === \"Polygon\");\n\n\t\t\t\tpolygonFeatures.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\n\t\t\t\t\t.copyAllWhere(\n\t\t\t\t\t\t(properties) =>\n\t\t\t\t\t\t\tproperties.mode === this.mode &&\n\t\t\t\t\t\t\tBoolean(\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),\n\t\t\t\t\t)\n\t\t\t\t\t.filter((feature) => feature.geometry.type === \"Polygon\");\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\t\tthis.undoRedo.clear();\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\n\t\tthis.undoRedo = new UndoRedoBehavior<Position[][]>({\n\t\t\tmaxStackSize: config.undoRedoMaxStackSize,\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\tundoSize() {\n\t\treturn this.undoRedo.undoSize();\n\t}\n\n\tclearHistory() {\n\t\tthis.undoRedo.clear();\n\t}\n\n\tprivate pushHistorySnapshot(featureId: FeatureId, currentCoordinate: number) {\n\t\tconst featureGeometry = this.readFeature.getGeometry<Polygon>(featureId);\n\n\t\tthis.undoRedo.recordSnapshot({\n\t\t\tfeatureCoordinates: featureGeometry.coordinates,\n\t\t\tcurrentCoordinate,\n\t\t});\n\t}\n\n\tprivate updateSnappedGuidancePointFromLastMouseMove() {\n\t\tif (!this.snapping || !this.lastMouseMoveEvent) {\n\t\t\tif (this.snappedPointId) {\n\t\t\t\tthis.mutateFeature.deleteFeatureIfPresent(this.snappedPointId);\n\t\t\t\tthis.snappedPointId = undefined;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tthis.updateSnappedCoordinate(this.lastMouseMoveEvent);\n\t}\n\n\tprivate syncClosingPoints(featureCoordinates: Position[][]) {\n\t\tif (this.currentCoordinate >= 3) {\n\t\t\tif (this.closingPoints.ids.length) {\n\t\t\t\tthis.closingPoints.update(featureCoordinates);\n\t\t\t} else {\n\t\t\t\tthis.closingPoints.create(featureCoordinates);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.closingPoints.delete();\n\t\t}\n\t}\n\n\tpublic undo() {\n\t\tif (this.state !== \"drawing\" || !this.currentId) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst undoStepResult = this.undoRedo.beginUndo();\n\n\t\tif (!undoStepResult) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { previousEntry: previousHistoryEntry } = undoStepResult;\n\n\t\tif (!previousHistoryEntry) {\n\t\t\tconst removedFeatureId = this.currentId;\n\n\t\t\tthis.currentId = undefined;\n\t\t\tthis.currentCoordinate = 0;\n\t\t\tthis.closingPoints.delete();\n\n\t\t\tif (this.state === \"drawing\") {\n\t\t\t\tthis.setStarted();\n\t\t\t}\n\n\t\t\tif (this.showCoordinatePoints) {\n\t\t\t\tthis.coordinatePoints.deletePointsByFeatureIds([removedFeatureId]);\n\t\t\t}\n\n\t\t\tthis.mutateFeature.deleteFeatureIfPresent(removedFeatureId);\n\t\t\tthis.updateSnappedGuidancePointFromLastMouseMove();\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: {\n\t\t\t\ttype: Mutations.Replace,\n\t\t\t\tcoordinates: previousHistoryEntry.featureCoordinates,\n\t\t\t},\n\t\t\tpropertyMutations: {\n\t\t\t\t[COMMON_PROPERTIES.CURRENTLY_DRAWING]: true,\n\t\t\t\t[COMMON_PROPERTIES.COMMITTED_COORDINATE_COUNT]:\n\t\t\t\t\tpreviousHistoryEntry.currentCoordinate,\n\t\t\t\t[COMMON_PROPERTIES.PROVISIONAL_COORDINATE_COUNT]:\n\t\t\t\t\tpreviousHistoryEntry.currentCoordinate,\n\t\t\t},\n\t\t\tcontext: { updateType: UpdateTypes.Commit },\n\t\t});\n\n\t\tif (!updated) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.currentCoordinate = previousHistoryEntry.currentCoordinate;\n\t\tthis.syncClosingPoints(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.updateSnappedGuidancePointFromLastMouseMove();\n\t}\n\n\tpublic redoSize(): number {\n\t\treturn this.undoRedo.redoSize();\n\t}\n\n\tpublic redo() {\n\t\tconst redoneHistoryEntry = this.undoRedo.takeRedo();\n\n\t\tif (!redoneHistoryEntry) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.currentId) {\n\t\t\t// createPolygon can mutate the coordinates by applying the right hand rule\n\t\t\tconst coordinatesCopy = this.undoRedo.cloneCoordinates(\n\t\t\t\tredoneHistoryEntry.featureCoordinates,\n\t\t\t)[0];\n\n\t\t\tconst { id, geometry } = this.mutateFeature.createPolygon({\n\t\t\t\tcoordinates: coordinatesCopy,\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\tredoneHistoryEntry.currentCoordinate,\n\t\t\t\t\t[COMMON_PROPERTIES.PROVISIONAL_COORDINATE_COUNT]:\n\t\t\t\t\t\tredoneHistoryEntry.currentCoordinate,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tthis.currentId = id;\n\t\t\tthis.currentCoordinate = redoneHistoryEntry.currentCoordinate;\n\n\t\t\tif (this.state === \"started\") {\n\t\t\t\tthis.setDrawing();\n\t\t\t}\n\t\t\tthis.syncClosingPoints(geometry.coordinates);\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\t\t} else {\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\ttype: Mutations.Replace,\n\t\t\t\t\tcoordinates: redoneHistoryEntry.featureCoordinates,\n\t\t\t\t},\n\t\t\t\tpropertyMutations: {\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\tredoneHistoryEntry.currentCoordinate,\n\t\t\t\t\t[COMMON_PROPERTIES.PROVISIONAL_COORDINATE_COUNT]:\n\t\t\t\t\t\tredoneHistoryEntry.currentCoordinate,\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\tthis.currentCoordinate = redoneHistoryEntry.currentCoordinate;\n\t\t\tthis.syncClosingPoints(updated.geometry.coordinates);\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\t\t}\n\n\t\tthis.undoRedo.commitRedo(redoneHistoryEntry);\n\n\t\tthis.updateSnappedGuidancePointFromLastMouseMove();\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: [event.lng, event.lat],\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\t\t\tthis.pushHistorySnapshot(this.currentId, this.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\tthis.pushHistorySnapshot(this.currentId, this.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\tthis.pushHistorySnapshot(this.currentId, this.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\t\t\t\tthis.pushHistorySnapshot(this.currentId, this.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.Edit,\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\t\tthis.undoRedo.clear();\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.undoRedo.clear();\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\tlineStringDash: undefined,\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\tpointerOverFeature?: Cursor;\n\tpointerOverCoordinate?: Cursor;\n\tpointerOverResizeHandle?: 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<\n\tT extends CustomStyling,\n> extends BaseModeOptions<T> {\n\tpointerDistance?: number;\n\tflags?: { [mode: string]: ModeFlags };\n\tkeyEvents?: TerraDrawSelectModeKeyEvents | null;\n\tdragEventThrottle?: number;\n\tcursors?: Cursors;\n\tallowManualDeselection?: boolean;\n\tallowManualSelection?: boolean;\n}\n\nexport class TerraDrawSelectMode extends TerraDrawBaseSelectMode<SelectionStyling> {\n\tpublic mode = \"select\";\n\n\tprivate allowManualDeselection = true;\n\tprivate allowManualSelection = 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\tprivate getPointerOverFeatureCursor() {\n\t\treturn this.cursors.pointerOverFeature ?? this.cursors.pointerOver;\n\t}\n\n\tprivate getPointerOverCoordinateCursor() {\n\t\treturn this.cursors.pointerOverCoordinate ?? this.cursors.pointerOver;\n\t}\n\n\tprivate getPointerOverResizeHandleCursor() {\n\t\treturn this.cursors.pointerOverResizeHandle ?? this.cursors.pointerOver;\n\t}\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\tif (options?.allowManualSelection !== undefined) {\n\t\t\tthis.allowManualSelection = options.allowManualSelection;\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.getPointerOverFeatureCursor());\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\tif (this.allowManualSelection) {\n\t\t\t\tthis.select(clickedFeature.id, true);\n\t\t\t}\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.getPointerOverCoordinateCursor());\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.getPointerOverResizeHandleCursor());\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.getPointerOverFeatureCursor());\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(context: OnChangeContext): void {\n\t\tconst keys = Object.keys(this.store);\n\t\tthis.store = {};\n\t\tthis.spatialIndex.clear();\n\t\tthis._onChange(keys, \"delete\", context);\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\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],\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\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],\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\tlineStringDash: [number, number];\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.lineStringDash = this.styles.lineStringDash;\n\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","import { TerraDrawKeyboardEvent } from \"../common\";\n\ntype UndoRedoKeyboardShortcut = {\n\tkey: KeyboardEvent[\"key\"];\n\theldKeys: KeyboardEvent[\"key\"][];\n};\n\nexport interface TerraDrawUndoRedoKeyboardShortcutsInterface {\n\tisUndoKeyboardShortcut(event: TerraDrawKeyboardEvent): boolean;\n\tisRedoKeyboardShortcut(event: TerraDrawKeyboardEvent): boolean;\n}\n\nconst defaultUndoKeyboardShortcuts: UndoRedoKeyboardShortcut[] = [\n\t{ key: \"z\", heldKeys: [\"meta\"] },\n\t{ key: \"z\", heldKeys: [\"control\"] },\n];\n\nconst defaultRedoKeyboardShortcuts: UndoRedoKeyboardShortcut[] = [\n\t{ key: \"z\", heldKeys: [\"meta\", \"shift\"] },\n\t{ key: \"z\", heldKeys: [\"control\", \"shift\"] },\n\t{ key: \"y\", heldKeys: [\"control\"] },\n];\n\nexport const matchesShortcut = (\n\tevent: TerraDrawKeyboardEvent,\n\tshortcut: UndoRedoKeyboardShortcut,\n) => {\n\tconst normalizedKey = event.key.toLowerCase();\n\tconst normalizedHeldKeys = new Set(\n\t\tevent.heldKeys\n\t\t\t.map((heldKey) => heldKey.toLowerCase())\n\t\t\t.filter((heldKey) => heldKey !== normalizedKey),\n\t);\n\n\tconst shortcutKey = shortcut.key.toLowerCase();\n\tif (shortcutKey !== normalizedKey) {\n\t\treturn false;\n\t}\n\n\tconst normalizedShortcutHeldKeys = new Set(\n\t\tshortcut.heldKeys.map((shortcutHeldKey) => shortcutHeldKey.toLowerCase()),\n\t);\n\n\tif (normalizedHeldKeys.size !== normalizedShortcutHeldKeys.size) {\n\t\treturn false;\n\t}\n\n\tfor (const shortcutHeldKey of normalizedShortcutHeldKeys) {\n\t\tif (!normalizedHeldKeys.has(shortcutHeldKey)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n};\n\nexport class TerraDrawUndoRedoKeyboardShortcuts\n\timplements TerraDrawUndoRedoKeyboardShortcutsInterface\n{\n\tprivate undoKeyboardShortcuts: UndoRedoKeyboardShortcut[];\n\tprivate redoKeyboardShortcuts: UndoRedoKeyboardShortcut[];\n\n\tconstructor(options?: {\n\t\tundo?: UndoRedoKeyboardShortcut[];\n\t\tredo?: UndoRedoKeyboardShortcut[];\n\t}) {\n\t\tthis.undoKeyboardShortcuts = options?.undo ?? defaultUndoKeyboardShortcuts;\n\t\tthis.redoKeyboardShortcuts = options?.redo ?? defaultRedoKeyboardShortcuts;\n\t}\n\n\tisUndoKeyboardShortcut(event: TerraDrawKeyboardEvent): boolean {\n\t\treturn this.undoKeyboardShortcuts.some((shortcut) =>\n\t\t\tmatchesShortcut(event, shortcut),\n\t\t);\n\t}\n\n\tisRedoKeyboardShortcut(event: TerraDrawKeyboardEvent): boolean {\n\t\treturn this.redoKeyboardShortcuts.some((shortcut) =>\n\t\t\tmatchesShortcut(event, shortcut),\n\t\t);\n\t}\n}\n","export function normaliseMaxStackSize(maxStackSize?: number) {\n\tif (maxStackSize === undefined || !Number.isFinite(maxStackSize)) {\n\t\treturn Number.POSITIVE_INFINITY;\n\t}\n\n\treturn Math.max(0, Math.floor(maxStackSize));\n}\n","export interface TerraDrawUndoRedoInterface {\n\tundo(): boolean;\n\tredo(): boolean;\n\tcanUndo(): boolean;\n\tcanRedo(): boolean;\n\tclearHistory(): void;\n\tundoSize(): number;\n\tredoSize(): number;\n}\n\nexport interface TerraDrawUndoRedoOptions {\n\tmaxStackSize?: number;\n}\n\nexport const HistoryChangeCause = {\n\tUndo: \"undo\",\n\tRedo: \"redo\",\n\tPush: \"push\",\n} as const;\n\nexport const StackType = {\n\tMode: \"mode\",\n\tSession: \"session\",\n} as const;\n\nexport type StackType = (typeof StackType)[keyof typeof StackType];\nexport type HistoryCause =\n\t(typeof HistoryChangeCause)[keyof typeof HistoryChangeCause];\n\nexport type HistoryChange = {\n\tcause: HistoryCause;\n\tstack: StackType;\n\tundoStackSize: number;\n\tredoStackSize: number;\n};\n\nexport type HistoryEvent = {\n\tcause: HistoryCause;\n\tstack: StackType;\n\tundoSize: number;\n\tredoSize: number;\n};\n","import { TerraDrawModeState } from \"../common\";\nimport { normaliseMaxStackSize } from \"./normalise-stack-size\";\nimport {\n\tHistoryCause,\n\tHistoryChange,\n\tHistoryChangeCause,\n\tStackType,\n\tTerraDrawUndoRedoInterface,\n\tTerraDrawUndoRedoOptions,\n} from \"./undo-redo-types\";\n\nexport interface TerraDrawModeUndoRedoInterface\n\textends TerraDrawUndoRedoInterface {\n\tgetMaxStackSize?(): number;\n\tregister(options: {\n\t\tgetModeState: () => string;\n\t\tgetModeHistorySizes: () => { undoSize: number; redoSize: number };\n\t\tundoMode: () => void;\n\t\tredoMode: () => void;\n\t\tclearModeHistory: () => void;\n\t\tonHistoryChange: (historyChange: HistoryChange) => void;\n\t}): void;\n\tcanUndo(): boolean;\n\tcanRedo(): boolean;\n\tgetHistorySizes(): { undoSize: number; redoSize: number };\n\temitPushIfHistoryChangedFromLastSnapshot(): void;\n\temitPushIfHistoryChanged(before: {\n\t\tundoSize: number;\n\t\tredoSize: number;\n\t}): void;\n\temitHistoryChange(cause: HistoryCause): void;\n}\n\nexport class TerraDrawModeUndoRedo implements TerraDrawModeUndoRedoInterface {\n\tprivate getModeState: (() => TerraDrawModeState) | undefined;\n\tprivate getModeHistorySizes:\n\t\t| (() => { undoSize: number; redoSize: number })\n\t\t| undefined;\n\tprivate undoMode: (() => void) | undefined;\n\tprivate redoMode: (() => void) | undefined;\n\tprivate clearModeHistory: (() => void) | undefined;\n\tprivate onHistoryChange: ((historyChange: HistoryChange) => void) | undefined;\n\tprivate readonly maxStackSize: number;\n\n\tprivate lastHistorySizes = {\n\t\tundoSize: 0,\n\t\tredoSize: 0,\n\t};\n\n\tconstructor(options?: TerraDrawUndoRedoOptions) {\n\t\tthis.maxStackSize = normaliseMaxStackSize(options?.maxStackSize);\n\t}\n\n\tgetMaxStackSize() {\n\t\treturn this.maxStackSize;\n\t}\n\n\tregister(options: {\n\t\tgetModeState: () => TerraDrawModeState;\n\t\tgetModeHistorySizes: () => { undoSize: number; redoSize: number };\n\t\tundoMode: () => void;\n\t\tredoMode: () => void;\n\t\tclearModeHistory: () => void;\n\t\tonHistoryChange: (historyChange: HistoryChange) => void;\n\t}) {\n\t\tthis.getModeState = options.getModeState;\n\t\tthis.getModeHistorySizes = options.getModeHistorySizes;\n\t\tthis.undoMode = options.undoMode;\n\t\tthis.redoMode = options.redoMode;\n\t\tthis.clearModeHistory = options.clearModeHistory;\n\t\tthis.onHistoryChange = options.onHistoryChange;\n\t}\n\n\tprivate inDrawingState() {\n\t\treturn this.getModeState ? this.getModeState() === \"drawing\" : false;\n\t}\n\n\tcanUndo() {\n\t\tif (!this.inDrawingState()) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst { undoSize } = this.getHistorySizes();\n\t\treturn undoSize > 0;\n\t}\n\n\tcanRedo() {\n\t\tif (!this.inDrawingState()) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst { redoSize } = this.getHistorySizes();\n\t\treturn redoSize > 0;\n\t}\n\n\tundo() {\n\t\tif (!this.canUndo() || !this.undoMode) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.undoMode();\n\t\tthis.emitHistoryChange(HistoryChangeCause.Undo);\n\t\treturn true;\n\t}\n\n\tredo() {\n\t\tif (!this.canRedo() || !this.redoMode) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.redoMode();\n\t\tthis.emitHistoryChange(HistoryChangeCause.Redo);\n\t\treturn true;\n\t}\n\n\tclearHistory() {\n\t\tif (this.clearModeHistory) {\n\t\t\tthis.clearModeHistory();\n\t\t}\n\n\t\tthis.lastHistorySizes = {\n\t\t\tundoSize: 0,\n\t\t\tredoSize: 0,\n\t\t};\n\t}\n\n\tgetHistorySizes() {\n\t\tif (!this.getModeHistorySizes) {\n\t\t\treturn { undoSize: 0, redoSize: 0 };\n\t\t}\n\n\t\treturn this.getModeHistorySizes();\n\t}\n\n\tundoSize() {\n\t\treturn this.getHistorySizes().undoSize;\n\t}\n\n\tredoSize() {\n\t\treturn this.getHistorySizes().redoSize;\n\t}\n\n\temitPushIfHistoryChangedFromLastSnapshot() {\n\t\tif (!this.inDrawingState()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentHistorySizes = this.getHistorySizes();\n\t\tif (\n\t\t\tcurrentHistorySizes.undoSize !== this.lastHistorySizes.undoSize ||\n\t\t\tcurrentHistorySizes.redoSize !== this.lastHistorySizes.redoSize\n\t\t) {\n\t\t\tthis.emitHistoryChange(HistoryChangeCause.Push);\n\t\t}\n\t}\n\n\temitPushIfHistoryChanged(before: { undoSize: number; redoSize: number }) {\n\t\tif (!this.inDrawingState()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst after = this.getHistorySizes();\n\t\tif (\n\t\t\tafter.undoSize !== before.undoSize ||\n\t\t\tafter.redoSize !== before.redoSize\n\t\t) {\n\t\t\tthis.emitHistoryChange(HistoryChangeCause.Push);\n\t\t}\n\t}\n\n\temitHistoryChange(cause: HistoryCause) {\n\t\tif (!this.onHistoryChange) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { undoSize, redoSize } = this.getHistorySizes();\n\t\tthis.lastHistorySizes = {\n\t\t\tundoSize,\n\t\t\tredoSize,\n\t\t};\n\n\t\tthis.onHistoryChange({\n\t\t\tcause,\n\t\t\tstack: StackType.Mode,\n\t\t\tundoStackSize: undoSize,\n\t\t\tredoStackSize: redoSize,\n\t\t});\n\t}\n}\n","import { FeatureId } from \"../extend\";\nimport { TerraDrawOnChangeContext } from \"../common\";\nimport { GeoJSONStoreFeatures, TerraDraw } from \"../terra-draw\";\nimport {\n\tHistoryCause,\n\tHistoryChange,\n\tHistoryChangeCause,\n\tStackType,\n\tTerraDrawUndoRedoInterface,\n\tTerraDrawUndoRedoOptions,\n} from \"./undo-redo-types\";\nimport { normaliseMaxStackSize } from \"./normalise-stack-size\";\n\ntype BatchEntry = {\n\tid: FeatureId;\n\ttoIndex: number;\n\tsnapshot: GeoJSONStoreFeatures;\n};\n\ntype StackEntryMetadata = {\n\tentries: BatchEntry[];\n};\n\nexport interface TerraDrawSessionUndoRedoInterface extends TerraDrawUndoRedoInterface {\n\tregister(options: {\n\t\tdraw: TerraDraw;\n\t\tonHistoryChange: (historyChange: HistoryChange) => void;\n\t}): void;\n}\n\ntype RedoStackEntry = {\n\tid: FeatureId;\n\ttoIndex: number;\n\tsnapshot?: GeoJSONStoreFeatures;\n\taction: \"create\" | \"update\" | \"delete\" | \"batch-create\" | \"batch-delete\";\n\tmetadata?: StackEntryMetadata;\n};\n\ntype UndoStackEntry = {\n\tid: FeatureId;\n\ttoIndex: number;\n\taction: \"single\" | \"batch-create\" | \"batch-delete\";\n\tmetadata?: StackEntryMetadata;\n};\n\nexport class TerraDrawSessionUndoRedo implements TerraDrawSessionUndoRedoInterface {\n\tprivate draw: TerraDraw | undefined;\n\tprivate onHistoryChange: ((historyChange: HistoryChange) => void) | undefined;\n\tprivate readonly maxStackSize: number;\n\n\tprivate historyById: { [key: string]: GeoJSONStoreFeatures[] } = {};\n\tprivate undoStack: UndoStackEntry[] = [];\n\tprivate ignoreProgrammaticCreate: Record<FeatureId, boolean> = {};\n\tprivate ignoreProgrammaticDelete: Record<FeatureId, boolean> = {};\n\tprivate deletedFeatureIds: Record<FeatureId, boolean> = {};\n\tprivate redoStack: RedoStackEntry[] = [];\n\tprivate isReplayingHistory = false;\n\n\tconstructor(options?: TerraDrawUndoRedoOptions) {\n\t\tthis.maxStackSize = normaliseMaxStackSize(options?.maxStackSize);\n\t}\n\n\tregister(options: {\n\t\tdraw: TerraDraw;\n\t\tonHistoryChange: (historyChange: HistoryChange) => void;\n\t}) {\n\t\tif (this.draw === options.draw) {\n\t\t\tthis.onHistoryChange = options.onHistoryChange;\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.draw) {\n\t\t\tthis.draw.off(\"change\", this.handleChange);\n\t\t\tthis.draw.off(\"finish\", this.handleFinish);\n\t\t}\n\n\t\tthis.draw = options.draw;\n\t\tthis.draw.on(\"change\", this.handleChange);\n\t\tthis.draw.on(\"finish\", this.handleFinish);\n\t\tthis.onHistoryChange = options.onHistoryChange;\n\t}\n\n\tprivate emitStackChange = (cause: HistoryCause) => {\n\t\tthis.onHistoryChange &&\n\t\t\tthis.onHistoryChange({\n\t\t\t\tcause,\n\t\t\t\tstack: StackType.Session,\n\t\t\t\tundoStackSize: this.undoStack.length,\n\t\t\t\tredoStackSize: this.redoStack.length,\n\t\t\t});\n\t};\n\n\tprivate pushUndoStackEntry(entry: UndoStackEntry) {\n\t\tif (this.maxStackSize === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.undoStack.push(entry);\n\t\tif (this.undoStack.length > this.maxStackSize) {\n\t\t\tthis.undoStack.shift();\n\t\t}\n\t}\n\n\tprivate pushRedoStackEntry(entry: RedoStackEntry) {\n\t\tif (this.maxStackSize === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.redoStack.push(entry);\n\t\tif (this.redoStack.length > this.maxStackSize) {\n\t\t\tthis.redoStack.shift();\n\t\t}\n\t}\n\n\tprivate handleChange = (\n\t\tids: FeatureId[],\n\t\ttype: string,\n\t\tcontext?: TerraDrawOnChangeContext,\n\t) => {\n\t\tif (!this.draw || this.isDrawing()) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.maxStackSize === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (type === \"update\") {\n\t\t\tconst isApiOrigin =\n\t\t\t\tcontext !== undefined &&\n\t\t\t\t\"origin\" in context &&\n\t\t\t\tcontext.origin === \"api\";\n\n\t\t\tif (!isApiOrigin || this.isReplayingHistory) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst changed = Array.isArray(ids) ? ids : [ids];\n\t\t\tlet recordedUpdate = false;\n\n\t\t\tfor (const id of changed) {\n\t\t\t\tif (id === undefined || id === null) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst key = String(id);\n\t\t\t\tconst feature = this.draw.getSnapshotFeature(id);\n\t\t\t\tif (!feature) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (!this.historyById[key]) {\n\t\t\t\t\tthis.historyById[key] = [];\n\t\t\t\t}\n\n\t\t\t\tthis.historyById[key].push(feature);\n\t\t\t\tthis.pushUndoStackEntry({\n\t\t\t\t\tid,\n\t\t\t\t\ttoIndex: this.historyById[key].length - 1,\n\t\t\t\t\taction: \"single\",\n\t\t\t\t});\n\t\t\t\trecordedUpdate = true;\n\t\t\t}\n\n\t\t\tif (recordedUpdate) {\n\t\t\t\tthis.redoStack.length = 0;\n\t\t\t\tthis.emitStackChange(HistoryChangeCause.Push);\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (type !== \"delete\" && type !== \"create\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (type === \"create\") {\n\t\t\tconst isApiOrigin =\n\t\t\t\tcontext !== undefined &&\n\t\t\t\t\"origin\" in context &&\n\t\t\t\tcontext.origin === \"api\";\n\n\t\t\tif (!isApiOrigin) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet recordedCreate = false;\n\t\t\tconst created = Array.isArray(ids) ? ids : [ids];\n\t\t\tconst creationsForBatch: {\n\t\t\t\tid: FeatureId;\n\t\t\t\ttoIndex: number;\n\t\t\t\tsnapshot: GeoJSONStoreFeatures;\n\t\t\t}[] = [];\n\n\t\t\tfor (const id of created) {\n\t\t\t\tif (this.ignoreProgrammaticCreate[id]) {\n\t\t\t\t\tdelete this.ignoreProgrammaticCreate[id];\n\t\t\t\t\tdelete this.deletedFeatureIds[id];\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst key = String(id);\n\t\t\t\tconst feature = this.draw.getSnapshotFeature(id);\n\t\t\t\tif (!feature) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (this.deletedFeatureIds[id]) {\n\t\t\t\t\tthis.historyById[key] = [];\n\t\t\t\t\tdelete this.deletedFeatureIds[id];\n\t\t\t\t}\n\n\t\t\t\tif (!this.historyById[key]) {\n\t\t\t\t\tthis.historyById[key] = [];\n\t\t\t\t}\n\n\t\t\t\tthis.historyById[key].push(feature);\n\t\t\t\tconst toIndex = this.historyById[key].length - 1;\n\t\t\t\tcreationsForBatch.push({\n\t\t\t\t\tid,\n\t\t\t\t\ttoIndex,\n\t\t\t\t\tsnapshot: feature,\n\t\t\t\t});\n\t\t\t\trecordedCreate = true;\n\t\t\t}\n\n\t\t\tif (creationsForBatch.length > 1) {\n\t\t\t\tthis.pushUndoStackEntry({\n\t\t\t\t\tid: creationsForBatch[0].id,\n\t\t\t\t\ttoIndex: creationsForBatch[0].toIndex,\n\t\t\t\t\taction: \"batch-create\",\n\t\t\t\t\tmetadata: { entries: creationsForBatch },\n\t\t\t\t});\n\t\t\t} else if (creationsForBatch.length === 1) {\n\t\t\t\tconst creation = creationsForBatch[0];\n\t\t\t\tthis.pushUndoStackEntry({\n\t\t\t\t\tid: creation.id,\n\t\t\t\t\ttoIndex: creation.toIndex,\n\t\t\t\t\taction: \"single\",\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (recordedCreate) {\n\t\t\t\tthis.redoStack.length = 0;\n\t\t\t\tthis.emitStackChange(HistoryChangeCause.Push);\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tlet recorded = false;\n\t\tconst deleted = Array.isArray(ids) ? ids : [ids];\n\t\tconst deletionsForBatch: {\n\t\t\tid: FeatureId;\n\t\t\ttoIndex: number;\n\t\t\tsnapshot: GeoJSONStoreFeatures;\n\t\t}[] = [];\n\t\tfor (const id of deleted) {\n\t\t\tconst key = String(id);\n\n\t\t\t// Skip deletes we initiated during undo/redo\n\t\t\tif (this.ignoreProgrammaticDelete[id]) {\n\t\t\t\tdelete this.ignoreProgrammaticDelete[id];\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// We only care about features we have history for (i.e., user-created/editable features)\n\t\t\tif (!this.historyById[key]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Treat deletes (including clear) as actions that can be undone by re-adding the last snapshot\n\t\t\tconst lastIndex = this.historyById[key].length - 1;\n\t\t\tif (lastIndex >= 0) {\n\t\t\t\tconst snapshot = this.historyById[key][lastIndex];\n\t\t\t\tif (!snapshot) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tdeletionsForBatch.push({\n\t\t\t\t\tid,\n\t\t\t\t\ttoIndex: lastIndex,\n\t\t\t\t\tsnapshot,\n\t\t\t\t});\n\t\t\t\tthis.deletedFeatureIds[id] = true;\n\t\t\t\trecorded = true;\n\t\t\t}\n\t\t}\n\n\t\tif (deletionsForBatch.length > 1) {\n\t\t\tthis.pushUndoStackEntry({\n\t\t\t\tid: deletionsForBatch[0].id,\n\t\t\t\ttoIndex: deletionsForBatch[0].toIndex,\n\t\t\t\taction: \"batch-delete\",\n\t\t\t\tmetadata: { entries: deletionsForBatch },\n\t\t\t});\n\t\t} else if (deletionsForBatch.length === 1) {\n\t\t\tconst deletion = deletionsForBatch[0];\n\t\t\tthis.pushUndoStackEntry({\n\t\t\t\tid: deletion.id,\n\t\t\t\ttoIndex: deletion.toIndex,\n\t\t\t\taction: \"single\",\n\t\t\t});\n\t\t}\n\n\t\t// Any new user-driven delete should invalidate the redo history\n\t\tif (recorded) {\n\t\t\tthis.redoStack.length = 0;\n\t\t\tthis.emitStackChange(HistoryChangeCause.Push);\n\t\t}\n\t};\n\n\tprivate handleFinish = (ids: FeatureId[] | FeatureId) => {\n\t\tif (!this.draw) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.maxStackSize === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.isReplayingHistory) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst changed = Array.isArray(ids) ? ids : [ids];\n\t\tlet recordedFinishAction = false;\n\t\tfor (const id of changed) {\n\t\t\tif (id === undefined || id === null) continue;\n\n\t\t\tconst key = String(id);\n\n\t\t\tconst feature = this.draw.getSnapshotFeature(id);\n\t\t\tif (!feature) continue;\n\n\t\t\tif (!this.historyById[key]) this.historyById[key] = [];\n\t\t\tthis.historyById[key].push(feature);\n\n\t\t\tif (!recordedFinishAction) {\n\t\t\t\t// Any new finished action invalidates the redo history\n\t\t\t\tthis.redoStack.length = 0;\n\t\t\t\trecordedFinishAction = true;\n\t\t\t}\n\n\t\t\t// Record both the id and the index in that feature's history for robust undo\n\t\t\tthis.pushUndoStackEntry({\n\t\t\t\tid,\n\t\t\t\ttoIndex: this.historyById[key].length - 1,\n\t\t\t\taction: \"single\",\n\t\t\t});\n\t\t\tthis.emitStackChange(HistoryChangeCause.Push);\n\t\t}\n\t};\n\n\tprivate isDrawing() {\n\t\treturn this.draw ? this.draw.getModeState() === \"drawing\" : false;\n\t}\n\n\t// When replaying history, we want to apply the snapshot without recording\n\t// new undo action or treating it as a user-driven change\n\tprivate applySnapshotDuringReplay(\n\t\tid: FeatureId,\n\t\tsnapshot: GeoJSONStoreFeatures,\n\t) {\n\t\tif (!this.draw) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.isReplayingHistory = true;\n\t\ttry {\n\t\t\tif (this.draw.hasFeature(id)) {\n\t\t\t\tthis.ignoreProgrammaticDelete[id] = true;\n\t\t\t\tthis.draw.removeFeatures([id]);\n\t\t\t}\n\n\t\t\tthis.ignoreProgrammaticCreate[id] = true;\n\t\t\tdelete this.deletedFeatureIds[id];\n\t\t\tthis.draw.addFeatures([snapshot]);\n\t\t} finally {\n\t\t\tthis.isReplayingHistory = false;\n\t\t}\n\t}\n\n\tcanUndo() {\n\t\tif (!this.draw || this.isDrawing()) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this.undoStack.length > 0;\n\t}\n\n\tcanRedo() {\n\t\tif (!this.draw || this.isDrawing()) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this.redoStack.length > 0;\n\t}\n\n\tundo(): boolean {\n\t\tif (!this.canUndo()) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (!this.draw) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst undoStackEntry = this.undoStack.pop();\n\t\tif (!undoStackEntry) {\n\t\t\tthis.emitStackChange(HistoryChangeCause.Undo);\n\t\t\treturn false;\n\t\t}\n\n\t\tif (undoStackEntry.action === \"batch-create\") {\n\t\t\tconst entriesToDelete = undoStackEntry.metadata?.entries || [];\n\t\t\tif (entriesToDelete.length === 0) {\n\t\t\t\tthis.emitStackChange(HistoryChangeCause.Undo);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst idsToDelete = entriesToDelete.map((entry) => entry.id);\n\t\t\tidsToDelete.forEach((featureId) => {\n\t\t\t\tthis.ignoreProgrammaticDelete[featureId] = true;\n\t\t\t\tthis.deletedFeatureIds[featureId] = true;\n\t\t\t});\n\n\t\t\tthis.draw.removeFeatures(idsToDelete);\n\t\t\tthis.pushRedoStackEntry({\n\t\t\t\tid: entriesToDelete[0].id,\n\t\t\t\ttoIndex: entriesToDelete[0].toIndex,\n\t\t\t\taction: \"batch-create\",\n\t\t\t\tmetadata: { entries: entriesToDelete },\n\t\t\t});\n\t\t\tthis.emitStackChange(HistoryChangeCause.Undo);\n\t\t\treturn true;\n\t\t}\n\n\t\tif (undoStackEntry.action === \"batch-delete\") {\n\t\t\tconst entriesToRestore = undoStackEntry.metadata?.entries || [];\n\t\t\tif (entriesToRestore.length === 0) {\n\t\t\t\tthis.emitStackChange(HistoryChangeCause.Undo);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst snapshotsToRestore = entriesToRestore\n\t\t\t\t.map((entry) => entry.snapshot)\n\t\t\t\t.filter((snapshot) => snapshot !== undefined);\n\n\t\t\tif (snapshotsToRestore.length > 0) {\n\t\t\t\tentriesToRestore.forEach((entry) => {\n\t\t\t\t\tthis.ignoreProgrammaticCreate[entry.id] = true;\n\t\t\t\t\tdelete this.deletedFeatureIds[entry.id];\n\t\t\t\t});\n\t\t\t\tthis.draw.addFeatures(snapshotsToRestore);\n\t\t\t}\n\n\t\t\tthis.pushRedoStackEntry({\n\t\t\t\tid: entriesToRestore[0].id,\n\t\t\t\ttoIndex: entriesToRestore[0].toIndex,\n\t\t\t\taction: \"batch-delete\",\n\t\t\t\tmetadata: { entries: entriesToRestore },\n\t\t\t});\n\t\t\tthis.emitStackChange(HistoryChangeCause.Undo);\n\t\t\treturn true;\n\t\t}\n\n\t\tconst id = undoStackEntry.id;\n\t\tconst index = undoStackEntry.toIndex;\n\n\t\tconst key = String(id);\n\t\tconst stack = this.historyById[key];\n\t\tif (!stack || stack.length === 0) {\n\t\t\tthis.emitStackChange(HistoryChangeCause.Undo);\n\t\t\treturn false;\n\t\t}\n\n\t\t// Clamp index in case of any out-of-sync situations\n\t\tconst currentIndex = Math.min(index, stack.length - 1);\n\n\t\t// If the feature currently does not exist (e.g., after a clear/delete), restore it\n\t\tconst featureExists = this.draw.hasFeature(id);\n\t\tif (!featureExists) {\n\t\t\tconst snapshotToRestore = stack[currentIndex];\n\t\t\tif (!snapshotToRestore) {\n\t\t\t\tthis.emitStackChange(HistoryChangeCause.Undo);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis.ignoreProgrammaticCreate[id] = true;\n\t\t\tdelete this.deletedFeatureIds[id];\n\t\t\tthis.draw.addFeatures([snapshotToRestore]);\n\n\t\t\t// Allow redo to re-delete the feature; do not change undo stack size here\n\t\t\tthis.pushRedoStackEntry({\n\t\t\t\tid,\n\t\t\t\ttoIndex: currentIndex,\n\t\t\t\taction: \"delete\",\n\t\t\t\tsnapshot: snapshotToRestore,\n\t\t\t});\n\t\t\tthis.emitStackChange(HistoryChangeCause.Undo);\n\t\t\treturn true;\n\t\t}\n\n\t\t// If there is no previous state, the action was creation -> remove the feature\n\t\tif (currentIndex <= 0) {\n\t\t\t// Record redo info so we can recreate the feature\n\t\t\tthis.pushRedoStackEntry({ id, toIndex: 0, action: \"create\" });\n\n\t\t\tthis.ignoreProgrammaticDelete[id] = true;\n\t\t\tthis.deletedFeatureIds[id] = true;\n\t\t\tthis.draw.removeFeatures([id]);\n\n\t\t\t// Remove any remaining actions for this id from the undo stack\n\t\t\tthis.undoStack = this.undoStack.filter(\n\t\t\t\t(undoAction) => undoAction.id !== id,\n\t\t\t);\n\t\t\tthis.emitStackChange(HistoryChangeCause.Undo);\n\t\t\treturn true;\n\t\t}\n\n\t\t// Revert to the previous geometry for this action and truncate history to that point\n\t\tconst nextSnapshot = stack[currentIndex]; // the state we are undoing\n\t\tconst previousSnapshot = stack[currentIndex - 1]; // the state we are reverting to\n\n\t\t// Save redo info before truncating the stack\n\t\tif (nextSnapshot) {\n\t\t\tthis.pushRedoStackEntry({\n\t\t\t\tid,\n\t\t\t\ttoIndex: currentIndex,\n\t\t\t\tsnapshot: nextSnapshot,\n\t\t\t\taction: \"update\",\n\t\t\t});\n\t\t}\n\n\t\tthis.applySnapshotDuringReplay(id, previousSnapshot);\n\t\tstack.length = currentIndex; // drop the state we just undid\n\t\tthis.emitStackChange(HistoryChangeCause.Undo);\n\t\treturn true;\n\t}\n\n\tredo(): boolean {\n\t\tif (!this.canRedo()) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (!this.draw) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst poppedRedoStackEntry = this.redoStack.pop()!;\n\t\tconst { id, toIndex, snapshot, action, metadata } = poppedRedoStackEntry;\n\n\t\tif (action === \"batch-create\") {\n\t\t\tconst entriesToCreate = metadata?.entries || [];\n\t\t\tif (entriesToCreate.length === 0) {\n\t\t\t\tthis.emitStackChange(HistoryChangeCause.Redo);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst snapshotsToCreate = entriesToCreate\n\t\t\t\t.map((entry) => entry.snapshot)\n\t\t\t\t.filter((restoredSnapshot) => restoredSnapshot !== undefined);\n\n\t\t\tif (snapshotsToCreate.length > 0) {\n\t\t\t\tentriesToCreate.forEach((entry) => {\n\t\t\t\t\tthis.ignoreProgrammaticCreate[entry.id] = true;\n\t\t\t\t});\n\t\t\t\tthis.draw.addFeatures(snapshotsToCreate);\n\t\t\t}\n\n\t\t\tthis.pushUndoStackEntry({\n\t\t\t\tid: entriesToCreate[0].id,\n\t\t\t\ttoIndex: entriesToCreate[0].toIndex,\n\t\t\t\taction: \"batch-create\",\n\t\t\t\tmetadata: { entries: entriesToCreate },\n\t\t\t});\n\t\t\tthis.emitStackChange(HistoryChangeCause.Redo);\n\t\t\treturn true;\n\t\t}\n\n\t\tif (action === \"batch-delete\") {\n\t\t\tconst entriesToDelete = metadata?.entries || [];\n\t\t\tif (entriesToDelete.length === 0) {\n\t\t\t\tthis.emitStackChange(HistoryChangeCause.Redo);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst idsToDelete = entriesToDelete.map((entry) => entry.id);\n\n\t\t\tidsToDelete.forEach((featureId) => {\n\t\t\t\tthis.ignoreProgrammaticDelete[featureId] = true;\n\t\t\t\tthis.deletedFeatureIds[featureId] = true;\n\t\t\t});\n\n\t\t\tthis.draw.removeFeatures(idsToDelete);\n\t\t\tthis.pushUndoStackEntry({\n\t\t\t\tid: entriesToDelete[0].id,\n\t\t\t\ttoIndex: entriesToDelete[0].toIndex,\n\t\t\t\taction: \"batch-delete\",\n\t\t\t\tmetadata: { entries: entriesToDelete },\n\t\t\t});\n\t\t\tthis.emitStackChange(HistoryChangeCause.Redo);\n\t\t\treturn true;\n\t\t}\n\n\t\tconst key = String(id);\n\t\tconst stack = this.historyById[key] || (this.historyById[key] = []);\n\n\t\t// If the redo action is a delete, remove the feature again\n\t\tif (action === \"delete\") {\n\t\t\tthis.ignoreProgrammaticDelete[id] = true;\n\t\t\tthis.deletedFeatureIds[id] = true;\n\t\t\tthis.draw.removeFeatures([id]);\n\t\t\t// Reflect that the delete action has been reapplied by pushing back onto the undo stack\n\t\t\tthis.pushUndoStackEntry({ id, toIndex, action: \"single\" });\n\t\t\tthis.emitStackChange(HistoryChangeCause.Redo);\n\t\t\treturn true;\n\t\t}\n\n\t\tif (toIndex <= 0) {\n\t\t\t// Redo creation - recreate the initial feature\n\t\t\tconst initial = stack[0];\n\t\t\tif (!initial) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis.ignoreProgrammaticCreate[id] = true;\n\t\t\tthis.draw.addFeatures([initial]);\n\n\t\t\t// Restore the action into the history stacks\n\t\t\tthis.pushUndoStackEntry({ id, toIndex: 0, action: \"single\" });\n\t\t\tthis.emitStackChange(HistoryChangeCause.Redo);\n\t\t\treturn true;\n\t\t}\n\n\t\t// Redo an update - reapply the geometry and restore the snapshot in history\n\t\tconst next = snapshot || stack[toIndex];\n\t\tif (!next) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Ensure the history includes the redone snapshot at the correct index\n\t\tif (stack.length === toIndex) {\n\t\t\tstack.push(next);\n\t\t} else if (stack.length < toIndex) {\n\t\t\tstack[toIndex] = next;\n\t\t\tstack.length = toIndex + 1;\n\t\t} else {\n\t\t\tstack[toIndex] = next;\n\t\t\tstack.length = toIndex + 1;\n\t\t}\n\n\t\tthis.applySnapshotDuringReplay(id, next);\n\n\t\t// Restore the action into the history stacks so it can be undone again\n\t\tthis.pushUndoStackEntry({ id, toIndex, action: \"single\" });\n\t\tthis.emitStackChange(HistoryChangeCause.Redo);\n\t\treturn true;\n\t}\n\n\tclearHistory() {\n\t\tconst snapshotHistoryById: { [key: string]: GeoJSONStoreFeatures[] } = {};\n\n\t\tif (this.draw && !this.isDrawing()) {\n\t\t\tconst existingFeatures = this.draw.getSnapshot();\n\t\t\tfor (const feature of existingFeatures) {\n\t\t\t\tconst featureId = feature.id as FeatureId;\n\t\t\t\tsnapshotHistoryById[String(featureId)] = [feature];\n\t\t\t}\n\t\t}\n\n\t\tthis.historyById = snapshotHistoryById;\n\t\tthis.undoStack = [];\n\t\tthis.ignoreProgrammaticCreate = {};\n\t\tthis.ignoreProgrammaticDelete = {};\n\t\tthis.deletedFeatureIds = {};\n\t\tthis.redoStack = [];\n\t}\n\n\tundoSize() {\n\t\treturn this.undoStack.length;\n\t}\n\n\tredoSize() {\n\t\treturn this.redoStack.length;\n\t}\n}\n","import { TerraDrawModeUndoRedoInterface } from \"./mode-undo-redo\";\nimport { TerraDrawSessionUndoRedoInterface } from \"./session-undo-redo\";\nimport {\n\tHistoryChange,\n\tHistoryChangeCause,\n\tHistoryEvent,\n\tStackType,\n} from \"./undo-redo-types\";\n\ntype TerraDrawUndoRedoCoordinatorOptions = {\n\tmodeLevel?: TerraDrawModeUndoRedoInterface;\n\tsessionLevel?: TerraDrawSessionUndoRedoInterface;\n\tshouldPreferMode: () => boolean;\n\tonHistoryChange?: (historyChange: HistoryEvent) => void;\n\tshouldEmitHistoryChange?: () => boolean;\n};\n\nexport class TerraDrawUndoRedoCoordinator {\n\tprivate modeLevel?: TerraDrawModeUndoRedoInterface;\n\tprivate sessionLevel?: TerraDrawSessionUndoRedoInterface;\n\tprivate shouldPreferMode: () => boolean;\n\tprivate onHistoryChange?: (historyChange: HistoryEvent) => void;\n\tprivate shouldEmitHistoryChange: () => boolean;\n\n\tconstructor(options: TerraDrawUndoRedoCoordinatorOptions) {\n\t\tthis.modeLevel = options.modeLevel;\n\t\tthis.sessionLevel = options.sessionLevel;\n\t\tthis.shouldPreferMode = options.shouldPreferMode;\n\t\tthis.onHistoryChange = options.onHistoryChange;\n\t\tthis.shouldEmitHistoryChange =\n\t\t\toptions.shouldEmitHistoryChange ?? (() => true);\n\t}\n\n\temitStackHistoryChange(change: HistoryChange) {\n\t\tif (!this.shouldEmitHistoryChange()) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.onHistoryChange) {\n\t\t\tthis.onHistoryChange({\n\t\t\t\tcause: change.cause,\n\t\t\t\tstack: change.stack,\n\t\t\t\tundoSize: change.undoStackSize,\n\t\t\t\tredoSize: change.redoStackSize,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate hasSessionUndo() {\n\t\treturn Boolean(this.sessionLevel && this.sessionLevel.canUndo());\n\t}\n\n\tprivate hasSessionRedo() {\n\t\treturn Boolean(this.sessionLevel && this.sessionLevel.canRedo());\n\t}\n\n\tprivate activeStackForUndo(): StackType | undefined {\n\t\tif (this.shouldPreferMode() && this.modeLevel?.canUndo()) {\n\t\t\treturn StackType.Mode;\n\t\t}\n\n\t\tif (this.hasSessionUndo()) {\n\t\t\treturn StackType.Session;\n\t\t}\n\n\t\tif (this.modeLevel?.canUndo()) {\n\t\t\treturn StackType.Mode;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tprivate activeStackForRedo(): StackType | undefined {\n\t\tif (this.shouldPreferMode() && this.modeLevel?.canRedo()) {\n\t\t\treturn StackType.Mode;\n\t\t}\n\n\t\tif (this.hasSessionRedo()) {\n\t\t\treturn StackType.Session;\n\t\t}\n\n\t\tif (this.modeLevel?.canRedo()) {\n\t\t\treturn StackType.Mode;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tcanUndo() {\n\t\treturn this.activeStackForUndo() !== undefined;\n\t}\n\n\tcanRedo() {\n\t\treturn this.activeStackForRedo() !== undefined;\n\t}\n\n\tundo() {\n\t\tconst stack = this.activeStackForUndo();\n\t\tif (!stack) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (stack === StackType.Mode) {\n\t\t\treturn this.modeLevel ? this.modeLevel.undo() : false;\n\t\t}\n\n\t\tif (this.sessionLevel && this.sessionLevel.canUndo()) {\n\t\t\treturn this.sessionLevel.undo();\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tredo() {\n\t\tconst stack = this.activeStackForRedo();\n\t\tif (!stack) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (stack === StackType.Mode) {\n\t\t\treturn this.modeLevel ? this.modeLevel.redo() : false;\n\t\t}\n\n\t\tif (this.sessionLevel && this.sessionLevel.canRedo()) {\n\t\t\treturn this.sessionLevel.redo();\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tclearHistory() {\n\t\tif (this.modeLevel) {\n\t\t\tthis.modeLevel.clearHistory();\n\t\t}\n\n\t\tif (this.sessionLevel) {\n\t\t\tthis.sessionLevel.clearHistory();\n\t\t}\n\t}\n\n\temitHistoryPushForCompletedAction() {\n\t\tif (this.sessionLevel) {\n\t\t\tthis.emitStackHistoryChange({\n\t\t\t\tcause: HistoryChangeCause.Push,\n\t\t\t\tundoStackSize: this.sessionLevel.undoSize(),\n\t\t\t\tredoStackSize: this.sessionLevel.redoSize(),\n\t\t\t\tstack: StackType.Session,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.modeLevel) {\n\t\t\tthis.emitStackHistoryChange({\n\t\t\t\tcause: HistoryChangeCause.Push,\n\t\t\t\tundoStackSize: this.modeLevel.undoSize(),\n\t\t\t\tredoStackSize: this.modeLevel.redoSize(),\n\t\t\t\tstack: StackType.Mode,\n\t\t\t});\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 { TerraDrawPolyLineMode } from \"./modes/polyline/polyline.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\";\nimport {\n\tTerraDrawUndoRedoKeyboardShortcuts,\n\ttype TerraDrawUndoRedoKeyboardShortcutsInterface,\n} from \"./undo-redo/keyboard-shortcuts\";\nimport {\n\tTerraDrawModeUndoRedo,\n\ttype TerraDrawModeUndoRedoInterface,\n} from \"./undo-redo/mode-undo-redo\";\nimport {\n\tTerraDrawSessionUndoRedo,\n\tTerraDrawSessionUndoRedoInterface,\n} from \"./undo-redo/session-undo-redo\";\nimport { TerraDrawUndoRedoCoordinator } from \"./undo-redo/undo-redo-coordinator\";\nimport type {\n\tHistoryCause,\n\tHistoryEvent,\n\tStackType,\n\tTerraDrawUndoRedoInterface,\n} from \"./undo-redo/undo-redo-types\";\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;\ntype HistoryChangeListener = (event: HistoryEvent) => void;\n\ninterface TerraDrawEventListeners {\n\tready: () => void;\n\tfinish: FinishListener;\n\tchange: ChangeListener;\n\tselect: SelectListener;\n\tdeselect: DeselectListener;\n\thistory: HistoryChangeListener;\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\thistory: HistoryChangeListener[];\n\t};\n\tprivate _instanceSelectModes: string[];\n\tprivate sessionUndoRedoEnabled = false;\n\tprivate keyboardShortcutsMatcher?: TerraDrawUndoRedoKeyboardShortcutsInterface;\n\tprivate drawingUndoRedo?: TerraDrawModeUndoRedoInterface;\n\tprivate sessionUndoRedo?: TerraDrawSessionUndoRedoInterface;\n\tprivate undoRedoCoordinator?: TerraDrawUndoRedoCoordinator;\n\n\tconstructor(options: {\n\t\tadapter: TerraDrawAdapter;\n\t\tmodes: TerraDrawBaseDrawMode<any>[];\n\t\tidStrategy?: IdStrategy<FeatureId>;\n\t\ttracked?: boolean;\n\t\tundoRedo?: {\n\t\t\tmodeLevel?: TerraDrawModeUndoRedoInterface;\n\t\t\tsessionLevel?: TerraDrawSessionUndoRedoInterface;\n\t\t\tkeyboardShortcuts?: TerraDrawUndoRedoKeyboardShortcutsInterface;\n\t\t};\n\t}) {\n\t\tthis._adapter = options.adapter;\n\t\tthis._instanceSelectModes = [];\n\n\t\t// Undo/Redo options\n\t\tconst modeLevelUndoRedo = options?.undoRedo?.modeLevel;\n\t\tif (modeLevelUndoRedo) {\n\t\t\tthis.drawingUndoRedo = modeLevelUndoRedo;\n\t\t}\n\n\t\tconst keyboardShortcutsMatcher = options?.undoRedo?.keyboardShortcuts;\n\t\tif (keyboardShortcutsMatcher) {\n\t\t\tthis.keyboardShortcutsMatcher = keyboardShortcutsMatcher;\n\t\t}\n\n\t\tthis.sessionUndoRedoEnabled = Boolean(options?.undoRedo?.sessionLevel);\n\t\tconst sessionLevelUndoRedo = options?.undoRedo?.sessionLevel;\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\thistory: [],\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\n\t\t\tthis.undoRedoCoordinator?.emitHistoryPushForCompletedAction();\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\tthis.emitDrawingPushIfHistoryChangedFromLastSnapshot();\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\tundoRedoMaxStackSize: this.drawingUndoRedo?.getMaxStackSize?.(),\n\t\t\t});\n\t\t});\n\n\t\tif (this.sessionUndoRedoEnabled && sessionLevelUndoRedo) {\n\t\t\tthis.sessionUndoRedo = sessionLevelUndoRedo;\n\t\t\tsessionLevelUndoRedo.register({\n\t\t\t\tdraw: this,\n\t\t\t\tonHistoryChange: (historyChange) => {\n\t\t\t\t\tthis.undoRedoCoordinator?.emitStackHistoryChange(historyChange);\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tif (this.drawingUndoRedo) {\n\t\t\tthis.drawingUndoRedo.register({\n\t\t\t\tgetModeState: () => this.getModeState(),\n\t\t\t\tgetModeHistorySizes: () => this.getDrawingHistorySizes(),\n\t\t\t\tundoMode: () => {\n\t\t\t\t\tif (this._mode.undo) {\n\t\t\t\t\t\tthis._mode.undo();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tredoMode: () => {\n\t\t\t\t\tif (this._mode.redo) {\n\t\t\t\t\t\tthis._mode.redo();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tclearModeHistory: () => {\n\t\t\t\t\tconst modeWithClearHistory = this._mode;\n\n\t\t\t\t\tif (modeWithClearHistory.clearHistory) {\n\t\t\t\t\t\tmodeWithClearHistory.clearHistory();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tonHistoryChange: (historyChange) => {\n\t\t\t\t\tthis.undoRedoCoordinator?.emitStackHistoryChange(historyChange);\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tthis.undoRedoCoordinator = new TerraDrawUndoRedoCoordinator({\n\t\t\tmodeLevel: this.drawingUndoRedo,\n\t\t\tsessionLevel: this.sessionUndoRedo,\n\t\t\tshouldPreferMode: () => this.getModeState() === \"drawing\",\n\t\t\tonHistoryChange: (historyChange) => {\n\t\t\t\tthis._eventListeners.history.forEach((listener) => {\n\t\t\t\t\tlistener(historyChange);\n\t\t\t\t});\n\t\t\t},\n\t\t\tshouldEmitHistoryChange: () => this._enabled,\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 handleUndoRedoKeyboardShortcut(\n\t\tevent: TerraDrawKeyboardEvent,\n\t): boolean {\n\t\tif (!this.drawingUndoRedo && !this.sessionUndoRedoEnabled) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (!this.keyboardShortcutsMatcher) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst isUndoShortcut =\n\t\t\tthis.keyboardShortcutsMatcher.isUndoKeyboardShortcut(event);\n\t\tconst isRedoShortcut =\n\t\t\tthis.keyboardShortcutsMatcher.isRedoKeyboardShortcut(event);\n\n\t\tif (isUndoShortcut) {\n\t\t\tif (!this.canUndo()) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst didUndo = this.undo();\n\t\t\tif (didUndo) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t\treturn didUndo;\n\t\t}\n\n\t\tif (isRedoShortcut) {\n\t\t\tif (!this.canRedo()) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst didRedo = this.redo();\n\t\t\tif (didRedo) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t\treturn didRedo;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tprivate getDrawingHistorySizes() {\n\t\tconst undoSize =\n\t\t\tthis._mode.undoSize && typeof this._mode.undoSize === \"function\"\n\t\t\t\t? this._mode.undoSize()\n\t\t\t\t: 0;\n\n\t\tconst redoSize =\n\t\t\tthis._mode.redoSize && typeof this._mode.redoSize === \"function\"\n\t\t\t\t? this._mode.redoSize()\n\t\t\t\t: 0;\n\n\t\treturn { undoSize, redoSize };\n\t}\n\n\tprivate emitDrawingPushIfHistoryChangedFromLastSnapshot() {\n\t\tif (!this.drawingUndoRedo) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.drawingUndoRedo.emitPushIfHistoryChangedFromLastSnapshot();\n\t}\n\n\tprivate emitDrawingPushIfHistoryChanged(before: {\n\t\tundoSize: number;\n\t\tredoSize: number;\n\t}) {\n\t\tif (!this.drawingUndoRedo) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.drawingUndoRedo.emitPushIfHistoryChanged(before);\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\tfeature.properties[SELECT_PROPERTIES.SELECTION_POINT] ||\n\t\t\tfeature.properties[COMMON_PROPERTIES.COORDINATE_POINT] ||\n\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\n\t\tthis.undoRedoCoordinator?.emitHistoryPushForCompletedAction();\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\n\t\tthis.undoRedoCoordinator?.emitHistoryPushForCompletedAction();\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\n\t\tthis.undoRedoCoordinator?.emitHistoryPushForCompletedAction();\n\t}\n\n\tundo(): boolean {\n\t\tthis.checkEnabled();\n\t\treturn this.undoRedoCoordinator ? this.undoRedoCoordinator.undo() : false;\n\t}\n\n\tcanUndo(): boolean {\n\t\tthis.checkEnabled();\n\t\treturn this.undoRedoCoordinator\n\t\t\t? this.undoRedoCoordinator.canUndo()\n\t\t\t: false;\n\t}\n\n\tcanRedo(): boolean {\n\t\tthis.checkEnabled();\n\t\treturn this.undoRedoCoordinator\n\t\t\t? this.undoRedoCoordinator.canRedo()\n\t\t\t: false;\n\t}\n\n\tredo(): boolean {\n\t\tthis.checkEnabled();\n\t\treturn this.undoRedoCoordinator ? this.undoRedoCoordinator.redo() : false;\n\t}\n\n\tclearUndoRedoHistory() {\n\t\tthis.checkEnabled();\n\t\tif (this.undoRedoCoordinator) {\n\t\t\tthis.undoRedoCoordinator.clearHistory();\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\tconst drawingHistoryBeforeClick = this.drawingUndoRedo\n\t\t\t\t\t? this.drawingUndoRedo.getHistorySizes()\n\t\t\t\t\t: { undoSize: 0, redoSize: 0 };\n\t\t\t\tthis._mode.onClick(event);\n\t\t\t\tthis.emitDrawingPushIfHistoryChanged(drawingHistoryBeforeClick);\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\tif (this.handleUndoRedoKeyboardShortcut(event)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis._mode.onKeyDown(event);\n\t\t\t},\n\t\t\tonKeyUp: (event) => {\n\t\t\t\tconst drawingHistoryBeforeKeyUp = this.drawingUndoRedo\n\t\t\t\t\t? this.drawingUndoRedo.getHistorySizes()\n\t\t\t\t\t: { undoSize: 0, redoSize: 0 };\n\t\t\t\tthis._mode.onKeyUp(event);\n\t\t\t\tthis.emitDrawingPushIfHistoryChanged(drawingHistoryBeforeKeyUp);\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({ origin: \"api\" });\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\tTerraDrawPolyLineMode,\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\t// Undo Redo\n\ttype TerraDrawUndoRedoInterface,\n\ttype TerraDrawModeUndoRedoInterface,\n\tTerraDrawModeUndoRedo,\n\ttype TerraDrawUndoRedoKeyboardShortcutsInterface,\n\tTerraDrawUndoRedoKeyboardShortcuts,\n\ttype TerraDrawSessionUndoRedoInterface,\n\tTerraDrawSessionUndoRedo,\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","this","_styles","pointerEvents","behaviors","validate","pointerDistance","coordinatePrecision","undoRedoMaxStackSize","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","undo","clearHistory","undoSize","redoSize","redo","onMouseMove","onClick","setMapDraggability","getHexColorStylingValue","value","defaultValue","getStylingValue","getNumericStylingValue","getUrlStylingValue","_value","_createClass","key","get","set","_","styling","TerraDrawBaseSelectMode","_TerraDrawBaseDrawMod","_this","_len","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","_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","lineStringDash","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","max","_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","UndoRedoBehavior","undoHistory","redoHistory","cloneCoordinatesFunction","maxStackSize","cloneRecursively","configuredMaxStackSize","isFinite","POSITIVE_INFINITY","setMaxStackSize","trimHistoryToMax","history","shift","pushUndoEntry","entry","pushRedoEntry","childValue","cloneCoordinates","cloneEntry","currentCoordinate","clear","recordSnapshot","beginUndo","undoneEntry","pop","clonedUndoneEntry","previousEntry","takeRedo","redoneEntry","commitRedo","dragStart","dragEnd","TerraDrawLineStringMode","snapping","mouseMove","insertCoordinates","lastCommittedCoordinates","snappedPointId","lastMouseMoveEvent","showCoordinatePoints","finishOnNthCoordinate","editable","editedFeatureId","editedFeatureCoordinateIndex","editedSnapType","editedInsertIndex","editedPointId","coordinateSnapping","insertPoint","lineSnapping","closingPoints","undoRedo","featuresWithCoordinates","_properties$COMMON_PR","shouldFinishOnCommit","updateSnappedCoordinate","snappedCoordinate","snapCoordinate","updated","generateInsertCoordinates","startCoord","endCoord","strategy","segmentDistance","insertedCoordinates","createLine","startingCoord","pushHistorySnapshot","firstUpdateToLine","updatedCoord","updateToLine","featureGeometry","updateSnappedGuidancePointFromLastMouseMove","syncClosingPoints","_propertyMutations2","undoStepResult","previousHistoryEntry","removedFeatureId","redoneHistoryEntry","_propertyMutations3","_properties2","getInsertCoordinates","startCoordinates","onRightClick","_this$coordinateSnapp","lineStringFilter","coordinateIndex","onLeftClick","lineSnapped","coordinateSnapped","_propertyMutations4","inserted","_propertyMutations5","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","TerraDrawPolyLineMode","finishLine","toPolygonLikeCoordinates","lineCoordinates","closeAsPolygon","committed","featureIdToRemove","closedCoordinates","_this$closingPoints$i","clickedCoordinate","_this$closingPoints$i2","polygonLikeCoordinates","_feature","validatedFeature","ValidationReasonFeatureNotPoint","ValidationReasonFeatureInvalidCoordinates","ValidationReasonFeatureInvalidCoordinatePrecision","ValidatePointFeature","PointSearchBehavior","getNearestPointFeature","clickedFeature","distanceToFeature","TerraDrawPointMode","pointSearch","nearestPointFeature","isEdited","editedPointWidth","editedPointColor","editedPointOutlineColor","editedPointOutlineWidth","TerraDrawPolygonMode","coordinatesCopy","firstCoordinate","eventCoordinate","polygonFilter","_this$mutateFeature$c2","_this$mutateFeature$c3","_propertyMutations6","_propertyMutations7","_propertyMutations8","featureCopy","_propertyMutations9","editedPoint","editedPointOpacity","editedPointOutlineOpacity","TerraDrawRectangleMode","currentRectangleId","updateRectangle","TerraDrawRenderMode","Render","validationResult","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","allowManualSelection","dragEventThrottle","dragEventCount","selected","flags","validations","dragTarget","coordinateSnap","featuresAtMouseEvent","dragFeature","dragCoordinate","rotateFeature","scaleFeature","dragCoordinateResizeFeature","lineSnap","getPointerOverFeatureCursor","_this$cursors$pointer","pointerOverFeature","getPointerOverCoordinateCursor","_this$cursors$pointer2","pointerOverCoordinate","getPointerOverResizeHandleCursor","_this$cursors$pointer3","pointerOverResizeHandle","selectFeature","select","setSelecting","deselectFeature","deleteSelected","clearDragTargetAndCursor","getSelectedFlags","modeFlags","featureFlags","coordinatesFlags","hasDraggableFlags","draggable","resizable","clickedSelectionPointProps","clickedFeatureDistance","selectionPointFeatureId","deletable","splice","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","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","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","RegExp","proto","getPrototypeOf","ArrayBuffer","isView","DataView","TerraDrawMarkerMode","_this$styles","_this$styles2","_this$styles3","defaultUndoKeyboardShortcuts","defaultRedoKeyboardShortcuts","matchesShortcut","shortcut","normalizedKey","toLowerCase","normalizedHeldKeys","heldKey","normalizedShortcutHeldKeys","shortcutHeldKey","TerraDrawUndoRedoKeyboardShortcuts","_options$undo","_options$redo","undoKeyboardShortcuts","redoKeyboardShortcuts","isUndoKeyboardShortcut","some","isRedoKeyboardShortcut","normaliseMaxStackSize","HistoryChangeCause","StackType","TerraDrawModeUndoRedo","getModeState","getModeHistorySizes","undoMode","redoMode","clearModeHistory","onHistoryChange","lastHistorySizes","getMaxStackSize","inDrawingState","canUndo","getHistorySizes","canRedo","emitHistoryChange","emitPushIfHistoryChangedFromLastSnapshot","currentHistorySizes","emitPushIfHistoryChanged","before","after","cause","_this$getHistorySizes3","undoStackSize","redoStackSize","TerraDrawSessionUndoRedo","draw","historyById","undoStack","ignoreProgrammaticCreate","ignoreProgrammaticDelete","deletedFeatureIds","redoStack","isReplayingHistory","emitStackChange","handleChange","isDrawing","recorded","deletionsForBatch","lastIndex","snapshot","toIndex","pushUndoStackEntry","metadata","deletion","recordedCreate","creationsForBatch","getSnapshotFeature","creation","recordedUpdate","handleFinish","_step4","recordedFinishAction","_iterator4","off","on","pushRedoStackEntry","applySnapshotDuringReplay","removeFeatures","addFeatures","undoStackEntry","_undoStackEntry$metad","entriesToDelete","idsToDelete","_undoStackEntry$metad2","entriesToRestore","snapshotsToRestore","currentIndex","snapshotToRestore","undoAction","nextSnapshot","previousSnapshot","poppedRedoStackEntry","entriesToCreate","snapshotsToCreate","restoredSnapshot","initial","next","snapshotHistoryById","_step5","_iterator5","getSnapshot","TerraDrawUndoRedoCoordinator","_options$shouldEmitHi","modeLevel","sessionLevel","shouldPreferMode","shouldEmitHistoryChange","emitStackHistoryChange","hasSessionUndo","hasSessionRedo","activeStackForUndo","_this$modeLevel","_this$modeLevel2","activeStackForRedo","_this$modeLevel3","_this$modeLevel4","emitHistoryPushForCompletedAction","TerraDraw","_options$undoRedo","_options$undoRedo2","_options$undoRedo3","_options$undoRedo4","_modes","_mode","_adapter","_enabled","_store","_eventListeners","_instanceSelectModes","sessionUndoRedoEnabled","keyboardShortcutsMatcher","drawingUndoRedo","sessionUndoRedo","undoRedoCoordinator","adapter","modeLevelUndoRedo","keyboardShortcuts","sessionLevelUndoRedo","duplicateModeTracker","modesMap","modes","modeMap","currentMode","modeKeys","static","ready","getChanged","changed","unchanged","_this$undoRedoCoordin","emitDrawingPushIfHistoryChangedFromLastSnapshot","_getChanged","render","deletedIds","getModeStyles","_getChanged2","_getChanged3","modeId","_this$drawingUndoRedo","historyChange","_this$undoRedoCoordin2","getDrawingHistorySizes","modeWithClearHistory","_this$undoRedoCoordin3","checkEnabled","handleUndoRedoKeyboardShortcut","isUndoShortcut","isRedoShortcut","didUndo","didRedo","emitDrawingPushIfHistoryChanged","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","coordinatePointsToDelete","modeToCleanUp","getFeatureId","checkIsReservedProperty","propertyName","values","_this$undoRedoCoordin4","updateFeatureGeometry","_this$undoRedoCoordin5","modeToUpdate","featureIsSelected","selectModePresent","transformFeatureGeometry","transformation","_this$undoRedoCoordin6","clearUndoRedoHistory","featureMode","modeToAddTo","onReady","drawingHistoryBeforeClick","drawingHistoryBeforeKeyUp","onClear","getFeaturesAtLngLat","getFeaturesAtPointerEvent","listeners","maxSize","minSize"],"mappings":"iwDAwFO,IA6CKA,EA7CCC,EACN,OADMA,EAEN,OAFMA,EAGM,mBAHNA,EAII,kBAyCjB,SAAYD,GACXA,EAAA,OAAA,SACAA,EAAA,YAAA,cACAA,EAAA,OAAA,QACA,CAJD,CAAYA,IAAAA,EAIX,KAiGD,IAGaE,EAAwBC,2GAExBC,EAAoB,CAChCC,SAAU,WACVC,UAAW,WACXC,2BAA4B,0BAC5BC,gBAAiB,kBAGLC,EAAoB,CAChCC,KAAM,OACNC,kBAAmB,mBACnBC,OAAQ,SACRC,cAAe,eACfC,eAAgB,gBAChBC,iBAAkB,kBAClBC,4BAA6B,2BAC7BC,qBAAsB,qBACtBC,6BAA8B,6BAC9BC,2BAA4B,2BAC5BC,OAAQ,UAoBIC,EACD,GCrQZ,SAASC,EACRC,GAEA,OAAOC,QACND,GACoB,iBAAZA,GACK,OAAZA,IACCE,MAAMC,QAAQH,GAElB,UAEgBI,EACfJ,GAEA,OAAOC,QACND,GACoB,iBAAZA,GACP,eAAgBA,GACc,iBAAvBA,EAAQK,YACQ,OAAvBL,EAAQK,YACR,SAAUL,EAAQK,WAErB,UASgBC,EAAiBC,GAChC,QARD,SAAqBA,GACpB,MACsB,iBAAdA,IACNC,MAAM,IAAIC,KAAKF,GAAqBG,UAEvC,CAGMC,CAAYJ,EAKlB,CCtDO,ICoCKK,EDpCCC,EAAoC,2BACpCC,EACZ,gECkCD,SAAYF,GACXA,EAAA,QAAA,UACAA,EAAA,OAAA,SACAA,EAAA,OAAA,SACAA,EAAA,OAAA,QACA,CALD,CAAYA,IAAAA,EAKX,CAAA,QAEYG,EAAuB,CACnCC,YAAY,EACZC,aAAa,EACbC,WAAW,EACXC,aAAa,EACbC,QAAQ,EACRC,WAAW,GAyBUC,eAAqB,WA+C1C,SAAAA,EACCC,EACAC,QAAkC,IAAlCA,IAAAA,GAAqC,QA/C5BC,OAA6B,eAAcC,KAS3CC,QAA4B,GAgB5BC,KAAAA,cAA+Bb,EAAoBW,KACnDG,UAAqC,QACrCC,cAAQ,EAAAJ,KACRK,gBAA0B,QAC1BC,yBAAmB,EAAAN,KACnBO,0BAAoB,EAAAP,KACpBQ,mBAGAC,EAAAA,KAAAA,kBACAC,WAAyB,eAEzBC,KAAAA,iCACAC,eAAS,EAAAZ,KACTa,aACAC,EAAAA,KAAAA,sBAGFC,iBAAkB,EAyD1BC,KAAAA,KAAO9B,EAAU+B,QACjBC,KAAAA,KAAO,OAlDDpB,EAIJE,KAAKe,iBAAkB,EAHvBf,KAAKmB,cAAaC,EAAMvB,GAAAA,GAK1B,CAAC,IAAAwB,EAAAzB,EAAA0B,UA2PA,OA3PAD,EAhBSE,kBAAA,SAAkBC,GAA8B,EAAUH,EAkBpEF,cAAA,SAActB,SACTA,GAAAA,EAAS4B,SAGZzB,KAAKyB,OAAML,KAAQpB,KAAKC,QAAYJ,EAAQ4B,SAGzC5B,MAAAA,GAAAA,EAASQ,kBACZL,KAAKK,gBAAkBR,EAAQQ,iBAE5BR,MAAAA,GAAAA,EAAS6B,aACZ1B,KAAKI,SAAWP,GAAWA,EAAQ6B,kBAEhC7B,GAAAA,EAASa,aACZV,KAAKU,WAAab,EAAQa,iBAGIiB,KAA3B9B,MAAAA,OAAAA,EAAAA,EAASK,iBACZF,KAAKE,cAAgBL,EAAQK,eAGnB,MAAPL,GAAAA,EAAS+B,WAAqC,IAAzB5B,KAAKe,kBAC7Bf,KAAKkB,KAAOrB,EAAQ+B,UAGrB5B,KAAKe,iBAAkB,CACxB,EAACM,EAESQ,kBAAA,SACTC,EACAC,GAEA,MAA4B,kBAAjBD,EACHA,EAEoB,mBAAjBA,GACHA,EAAaC,EAGtB,EAACV,EAKSW,WAAA,WACT,GAAoB,YAAhBhC,KAAKD,OAGR,MAAU,IAAAkC,MAAM,iDAFhBjC,KAAKD,OAAS,SAIhB,EAACsB,EAESa,WAAA,WACT,GACiB,YAAhBlC,KAAKD,QACW,eAAhBC,KAAKD,QACW,YAAhBC,KAAKD,QACW,cAAhBC,KAAKD,OAKL,MAAU,IAAAkC,MAAM,iDAHhBjC,KAAKD,OAAS,UACdC,KAAKW,sBAAqB,EAI5B,EAACU,EAESc,WAAA,WACT,GAAoB,YAAhBnC,KAAKD,OAIR,MAAU,IAAAkC,MAAM,sCAHhBjC,KAAKD,OAAS,UACdC,KAAKW,sBAAqB,EAI5B,EAACU,EAEDe,SAAA,SAASC,GACR,GAAoB,iBAAhBrC,KAAKD,OA0BR,MAAU,IAAAkC,MAAM,gDAzBhBjC,KAAKD,OAAS,aACdC,KAAKS,MAAQ4B,EAAO5B,MACpBT,KAAKS,MAAM6B,iBAAiBD,EAAOE,UACnCvC,KAAKW,qBAAuB0B,EAAO1B,qBACnCX,KAAKa,QAAUwB,EAAOxB,QACtBb,KAAKY,UAAYyB,EAAOzB,UACxBZ,KAAKwC,SAAWH,EAAOG,SACvBxC,KAAKyC,WAAaJ,EAAOI,WACzBzC,KAAKc,UAAYuB,EAAOvB,UACxBd,KAAKQ,cAAgB6B,EAAOE,SAC5BvC,KAAK0C,SAAWL,EAAOK,SACvB1C,KAAKM,oBAAsB+B,EAAO/B,oBAClCN,KAAKO,qBAAuB8B,EAAO9B,qBAEnCP,KAAKuB,kBAAkB,CACtBL,KAAMmB,EAAOnB,KACbT,MAAOT,KAAKS,MACZI,QAASb,KAAKa,QACdD,UAAWZ,KAAKY,UAChBP,gBAAiBL,KAAKK,gBACtBC,oBAAqB+B,EAAO/B,oBAC5BI,WAAYV,KAAKU,WACjBH,qBAAsB8B,EAAO9B,sBAKhC,EAACc,EAEDsB,gBAAA,SAAgBrE,GACf,YAAYsE,yBAAyBtE,EACtC,EAAC+C,EAEDwB,kBAAA,SAAkBvE,KAAiC+C,EAEnDyB,oBAAA,SAAoBxE,GAA6B,EAAI+C,EAE7CuB,yBAAA,SAAyBtE,GAChC,GAAoB,iBAAhB0B,KAAKD,OACR,MAAU,IAAAkC,MAAM,2BAGjB,IAAMc,EFtMQ,SACfzE,EACA0E,GAEA,IAAIC,EACJ,GAAK5E,EAASC,GAEHA,GAAAA,QAAQ4E,GAClBD,EA5De,4BA6DiB,iBAAf3E,EAAQ4E,IAAyC,iBAAf5E,EAAQ4E,GAC3DD,EA1DyB,4DA2DnB,GAAKD,EAAU1E,EAAQ4E,IAEvB,GAAK7E,EAASC,EAAQ6E,UAElB,GAAC9E,EAASC,EAAQK,YAEtB,GAC2B,iBAA1BL,EAAQ6E,SAASnC,MACvB,CAAC,UAAW,aAAc,SAASoC,SAAS9E,EAAQ6E,SAASnC,SAGnDxC,MAAMC,QAAQH,EAAQ6E,SAASE,cAG1C,IAAC/E,EAAQK,WAAWuC,MACe,iBAA5B5C,EAAQK,WAAWuC,KAE1B,MAAO,CAAEoC,OAAO,EAAOC,OAtEH,oDAiEpBN,EAlE6B,2CAgE7BA,EAjE4B,mDA4D5BA,EA7DuB,iCA2DvBA,EA5DqB,+BA0DrBA,+DANAA,EAzDmB,wBAkFpB,OAAIA,EACI,CAAEK,OAAO,EAAOC,OAAQN,GAGzB,CAAEK,OAAO,EACjB,CEkK4BE,CACzBlF,EACA0B,KAAKS,MAAMgD,WAAWT,WAGvB,IAAKD,EAAkBO,MACtB,OAAOP,EAIR,GAAI/C,KAAKI,SAAU,CAClB,IAAMsB,EAAa1B,KAAKI,SAAS9B,EAAiC,CACjEuC,QAASb,KAAKa,QACdD,UAAWZ,KAAKY,UAChBN,oBAAqBN,KAAKM,oBAC1BoD,WAAY3G,EAAY4G,cAGzB,MAAO,CACNL,MAAOP,EAAkBO,OAAS5B,EAAW4B,MAC7CC,OAAQ7B,EAAW6B,OAErB,CAEA,MAAO,CACND,MAAOP,EAAkBO,MACzBC,OAAQR,EAAkBQ,OAE5B,EAAClC,EAESuC,oBAAA,SACTtF,EACAuF,GAEA,IAAMnC,EAAa1B,KAAK4C,yBAAyBtE,GACjD,OAAIoD,EAAW4B,MACWhF,EACQK,WAAWuC,OAASlB,KAAKkB,KAOnC2C,EAREvF,GAGjB,CACNgF,OAAO,EACPC,OAAQnE,GAOJ,CACNkE,OAAO,EACPC,OAAQ7B,EAAW6B,OAErB,EAAClC,EAODqB,SAAA,SAASoB,EAAuBC,KAA4B1C,EAC5DoB,WAAA,SAAWuB,GAA2B3C,EAAAA,EACtCmB,SAAA,SAASyB,GAAqB,EAAI5C,EAClC6C,UAAA,SAAUnC,GAAiCV,EAAAA,EAC3C8C,QAAA,SAAQpC,KAAiCV,EACzC+C,KAAA,aAAS/C,EACTgD,aAAA,aAAiBhD,EACjBiD,SAAA,WACC,QACD,EAACjD,EACDkD,SAAA,WACC,OAAQ,CACT,EAAClD,EACDmD,KAAA,aAASnD,EACToD,YAAA,SAAY1C,GAA0B,EAAIV,EAC1CqD,QAAA,SAAQ3C,KAA8BV,EACtC5B,YAAA,SACCsC,EACA4C,GACGtD,EAAAA,EACJ3B,OAAA,SACCqC,EACA4C,KACGtD,EACJ1B,UAAA,SACCoC,EACA4C,KACGtD,EAEMuD,wBAAA,SACTC,EAIAC,EACAxG,GAEA,OAAW0B,KAAC+E,gBAAgBF,EAAOC,EAAcxG,EAClD,EAAC+C,EAES2D,uBAAA,SACTH,EAIAC,EACAxG,GAEA,OAAO0B,KAAK+E,gBAAgBF,EAAOC,EAAcxG,EAClD,EAAC+C,EAES4D,mBAAA,SACTJ,EACAC,EACAxG,GAEA,YAAYyG,gBAAgBF,EAAOC,EAAcxG,EAClD,EAAC+C,EAEO0D,gBAAA,SACPF,EACAC,EACAxG,GAEA,YAAcqD,IAAVkD,EACIC,EACoB,mBAAVD,EACI,OAArBK,EAAOL,EAAMvG,IAAQ4G,EAAIJ,EAElBD,EAHgCK,IAAAA,CAKzC,EAACC,EAAAvF,IAAAwF,IAAA,QAAAC,IAnTD,WACC,OAAOrF,KAAKD,MACb,EAACuF,IACD,SAAUC,GACT,MAAU,IAAAtD,MAAM,yCACjB,GAACmD,CAAAA,aAAAC,IAID,WACC,OAAOrF,KAAKC,OACb,EAACqF,IACD,SAAWE,GACV,GAAuB,iBAAZA,EACV,MAAU,IAAAvD,MAAM,6BAIbjC,KAAKQ,eACRR,KAAKQ,cAAc,GAAI,WAExBR,KAAKC,QAAUuF,CAChB,KAzB0C,GAyTrBC,eAEpB,SAAAC,GAAAD,SAAAA,IAAA,QAAAE,EAAAC,EAAAC,UAAAC,OAAAC,EAAAvH,IAAAA,MAAAoH,GAAAI,EAAAA,EAAAA,EAAAJ,EAAAI,IAAAD,EAAAC,GAAAH,UAAAG,GAC6B,OAD7BL,EAAAD,EAAAO,KAAAC,MAAAR,EAAA,CAAA1F,MAAAmG,OAAAJ,WACM/E,KAAO9B,EAAUkH,OAAMT,CAAA,CAAAF,OAAAY,EAAAZ,EAAAC,GAAAD,CAAA,CAD7B,CAAQ7F,GCnYM,SAAA0G,EACfC,EACAC,GAEA,IAAMC,EAAY,SAACC,GAAgB,OAAMA,EAAWC,KAAKC,GAAM,GAAG,EAE5DC,EAASJ,EAAUF,EAAS,IAC5BO,EAAYL,EAAUF,EAAS,IAC/BQ,EAASN,EAAUD,EAAS,IAE5BQ,EAAWD,EAASF,EACpBI,EAFYR,EAAUD,EAAS,IAELM,EAE1BI,EACLP,KAAKQ,IAAIH,EAAW,GAAKL,KAAKQ,IAAIH,EAAW,GAC7CL,KAAKS,IAAIP,GACRF,KAAKS,IAAIL,GACTJ,KAAKQ,IAAIF,EAAc,GACvBN,KAAKQ,IAAIF,EAAc,GAMzB,OALU,EAAIN,KAAKU,MAAMV,KAAKW,KAAKJ,GAAIP,KAAKW,KAAK,EAAIJ,IAEtC,OAGG,GACnB,KC3BaK,EAAc,UAEX,SAAAC,EAAiBC,GAEhC,OADgBA,EAAU,IACRd,KAAKC,GAAM,GAC9B,UAEgBc,EAAgBC,GAE/B,OAAOA,EADQJ,SAEhB,CAEgB,SAAAK,EAAiBC,GAEhC,OADgBA,GAAW,EAAIlB,KAAKC,IAClB,IAAOD,KAAKC,EAC/B,UCfgBkB,EAAeC,EAAaC,QAAY,IAAZA,IAAAA,EAAe,GAC1D,IAAMC,EAAWtB,KAAKuB,IAAI,GAAIF,GAC9B,OAAOrB,KAAKwB,MAAMJ,EAAME,GAAYA,CACrC,CCDA,IAAMG,EAAqB,kBACrBC,EAAqB,oBACrBC,EAAI,QAQGC,EAAwB,SACpCC,EACAC,GACqB,MAAA,CACrBC,EAAW,IAARF,EAAY,EAAIA,EAAMH,EAAqBC,EAC9CK,EACS,IAARF,EACG,EACA9B,KAAKiC,IAAIjC,KAAKkC,IAAIlC,KAAKC,GAAK,EAAK6B,EAAMJ,EAAsB,IAAMC,EACvE,EAQYQ,EAAwB,SACpCJ,EACAC,GAAS,MAC0B,CACnCH,IAAW,IAANE,EAAU,EAAIN,GAAsBM,EAAIJ,GAC7CG,IACO,IAANE,EACG,GACC,EAAIhC,KAAKoC,KAAKpC,KAAKqC,IAAIL,EAAIL,IAAM3B,KAAKC,GAAK,GAAKwB,EACrD,ECvBD,SAASa,EACRC,EACAvB,EACAwB,GAEA,IAAMC,EAAa5B,EAAiB0B,EAAO,IACrCG,EAAY7B,EAAiB0B,EAAO,IACpCI,EAAa9B,EAAiB2B,GAC9BtB,EAAUH,EAAgBC,GAG1B4B,EAAY5C,KAAK6C,KACtB7C,KAAKQ,IAAIkC,GAAa1C,KAAKS,IAAIS,GAC9BlB,KAAKS,IAAIiC,GAAa1C,KAAKQ,IAAIU,GAAWlB,KAAKS,IAAIkC,IAWrD,MAAO,CAHK1B,EALXwB,EACAzC,KAAKU,MACJV,KAAKQ,IAAImC,GAAc3C,KAAKQ,IAAIU,GAAWlB,KAAKS,IAAIiC,GACpD1C,KAAKS,IAAIS,GAAWlB,KAAKQ,IAAIkC,GAAa1C,KAAKQ,IAAIoC,KAGzC3B,EAAiB2B,GAG9B,CAEM,SAAUE,EAAO5J,GAUtB,IAJA,IAAQ6J,EAAkD7J,EAAlD6J,OAAQC,EAA0C9J,EAA1C8J,iBAAkBrJ,EAAwBT,EAAxBS,oBAC5BsJ,EAAQ/J,EAAQ+J,MAAQ/J,EAAQ+J,MAAQ,GAExCvG,EAA0B,GACvBwG,EAAI,EAAGA,EAAID,EAAOC,IAAK,CAC/B,IAAMC,EAAmBb,EACxBS,EACAC,GACM,IAALE,EAAYD,GAGdvG,EAAY0G,KAAK,CAChBjC,EAAegC,EAAiB,GAAIxJ,GACpCwH,EAAegC,EAAiB,GAAIxJ,IAEtC,CAGA,OAFA+C,EAAY0G,KAAK1G,EAAY,IAEtB,CACNrC,KAAM,UACNmC,SAAU,CAAEnC,KAAM,UAAWqC,YAAa,CAACA,IAC3C1E,WAAY,GAEd,UC3DgBqL,EACf1L,GAEA,IAMI2L,EAEJ,GAA8B,YAA1B3L,EAAQ6E,SAASnC,KACpBiJ,EAAQ3L,EAAQ6E,SAASE,oBACW,eAA1B/E,EAAQ6E,SAASnC,KAG3B,MAAU,IAAAiB,MAAM,yDAFhBgI,EAAQ,CAAC3L,EAAQ6E,SAASE,YAG3B,CAKA,IAHA,IAAM6G,EAAqB,GAGlBC,EAAQ,EAAGA,EAAQF,EAAMnE,OAAQqE,IACzC,IAAK,IAAIC,EAAQ,EAAGA,EAAQH,EAAME,GAAOrE,OAAS,EAAGsE,IACpD,IAAK,IAAIC,EAAQ,EAAGA,EAAQJ,EAAMnE,OAAQuE,IACzC,IAAK,IAAIC,EAAQ,EAAGA,EAAQL,EAAMI,GAAOvE,OAAS,EAAGwE,IAEpDC,EAA0BJ,EAAOC,EAAOC,EAAOC,GAMnD,OAAOJ,EAAOpE,OAAS,EAQvB,SAAS0E,EAAUC,GAClB,OAAOA,EAAO,GAAuBA,EAAO,CAC7C,CAEA,SAASF,EACRJ,EACAC,EACAC,EACAC,GAEA,IAYII,EAZEC,EAASV,EAAME,GAAOC,GACtBQ,EAAOX,EAAME,GAAOC,EAAQ,GAC5BS,EAASZ,EAAMI,GAAOC,GACtBQ,EAAOb,EAAMI,GAAOC,EAAQ,GAE5BS,EAyDR,SACCJ,EACAC,EACAC,EACAC,GAEA,GACCE,EAAYL,EAAQE,IACpBG,EAAYL,EAAQG,IACpBE,EAAYJ,EAAMC,IAClBG,EAAYF,EAAMD,GAElB,OAAO,KAGR,IAAMI,EAAKN,EAAO,GACjBO,EAAKP,EAAO,GACZQ,EAAKP,EAAK,GACVQ,EAAKR,EAAK,GACVS,EAAKR,EAAO,GACZS,EAAKT,EAAO,GACZU,EAAKT,EAAK,GACVU,EAAKV,EAAK,GAELW,GAASR,EAAKE,IAAOG,EAAKE,IAAON,EAAKE,IAAOC,EAAKE,GACxD,OAAc,IAAVE,EACQ,KASL,GALJR,EAAKG,EAAKF,EAAKC,IAAOE,EAAKE,IAAON,EAAKE,IAAOE,EAAKG,EAAKF,EAAKC,IAAOE,IAGpER,EAAKG,EAAKF,EAAKC,IAAOG,EAAKE,IAAON,EAAKE,IAAOC,EAAKG,EAAKF,EAAKC,IAAOE,EAGxE,CA7FuBC,CAAUf,EAAQC,EAAMC,EAAQC,GAEhC,OAAjBC,IAaHL,EADGI,EAAK,KAAOD,EAAO,IACbE,EAAa,GAAKF,EAAO,KAAOC,EAAK,GAAKD,EAAO,KAEjDE,EAAa,GAAKF,EAAO,KAAOC,EAAK,GAAKD,EAAO,IAKvDL,EAbAI,EAAK,KAAOD,EAAO,IACbI,EAAa,GAAKJ,EAAO,KAAOC,EAAK,GAAKD,EAAO,KAEjDI,EAAa,GAAKJ,EAAO,KAAOC,EAAK,GAAKD,EAAO,MAUnCH,EAAUE,KAoBtBK,EAAaY,WAMzBzB,EAAOH,KAAKgB,IACb,CACD,CAEA,SAASC,EAAYY,EAAkBC,GACtC,OAAOD,EAAO,KAAOC,EAAO,IAAMD,EAAO,KAAOC,EAAO,EACxD,CChHgB,SAAAC,EACfC,EACAzL,GAEA,OACC0L,EAAiBD,EAAW,KAAOzL,GACnC0L,EAAiBD,EAAW,KAAOzL,CAErC,UAEgB2L,EAAkBF,GACjC,OACuB,IAAtBA,EAAWjG,QACc,iBAAlBiG,EAAW,IACO,iBAAlBA,EAAW,IACAG,WAAlBH,EAAW,IACOG,WAAlBH,EAAW,KApBkBvD,EAqBduD,EAAW,MApBZ,KAAOvD,GAAO,MALAC,EA0BdsD,EAAW,MAzBX,IAAMtD,GAAO,OADCA,EAICD,CAwB/B,CAEgB,SAAAwD,EAAiBnH,GAGhC,IAFA,IAAIsH,EAAU,EACVC,EAAY,EACTzF,KAAKwB,MAAMtD,EAAQsH,GAAWA,IAAYtH,GAChDsH,GAAW,GACXC,IAGD,OAAOA,CACR,KC/BaC,EAAkC,oBAClCC,EACZ,sCACYC,EACZ,kCACYC,EACZ,qCAIe,SAAAC,EACfnO,EACAgC,GAEA,GAA8B,YAA1BhC,EAAQ6E,SAASnC,KACpB,MAAO,CACNsC,OAAO,EACPC,OAlB8C,4BAsBhD,GAA4C,IAAxCjF,EAAQ6E,SAASE,YAAYyC,OAChC,MAAO,CACNxC,OAAO,EACPC,OAAQ8I,GAIV,GAAI/N,EAAQ6E,SAASE,YAAY,GAAGyC,OAAS,EAC5C,MAAO,CACNxC,OAAO,EACPC,OAAQ+I,GAIV,IAAK,IAAIzC,EAAI,EAAGA,EAAIvL,EAAQ6E,SAASE,YAAY,GAAGyC,OAAQ+D,IAAK,CAChE,IAAKoC,EAAkB3N,EAAQ6E,SAASE,YAAY,GAAGwG,IACtD,MAAO,CACNvG,OAAO,EACPC,OAAQgJ,GAIV,IACET,EACAxN,EAAQ6E,SAASE,YAAY,GAAGwG,GAChCvJ,GAGD,MAAO,CACNgD,OAAO,EACPC,OA3CH,mDA8CA,CAEA,OA8CyBmJ,EA5CvBpO,EAAQ6E,SAASE,YAAY,GAAG,IA8CnB,MAFmCsJ,EA3ChDrO,EAAQ6E,SAASE,YAAY,GAC5B/E,EAAQ6E,SAASE,YAAY,GAAGyC,OAAS,IA4CR,IACnC4G,EAAc,KAAOC,EAAc,GAzC5B,CACNrJ,OAAO,EACPC,OAAQiJ,GAIH,CAAElJ,OAAO,GAgCjB,IAA0BoJ,EAAyBC,CA/BnD,CAEgB,SAAAC,EACftO,EACAgC,GAEA,IAAMuM,EAAyBJ,EAC9BnO,EACAgC,GAGD,OAAKuM,EAAuBvJ,MAIxB0G,EAAe1L,GACX,CACNgF,OAAO,EACPC,OAAQ,6BAIH,CAAED,OAAO,GAVRuJ,CAWT,CCtFa,IAAAC,EAUZ,SAAAC,GACC,IAAAtM,EAAKsM,EAALtM,MACAS,EAAI6L,EAAJ7L,KACAL,EAAOkM,EAAPlM,QACAD,EAASmM,EAATnM,UACAP,EAAe0M,EAAf1M,gBACAC,EAAmByM,EAAnBzM,oBACAI,EAAUqM,EAAVrM,WACAH,EAAoBwM,EAApBxM,qBAjBSE,KAAAA,WACAS,EAAAA,KAAAA,iBACAL,aAAO,EAAAb,KACPY,eAAS,EAAAZ,KACTK,qBAAe,EAAAL,KACfM,yBAAmB,EAAAN,KACnBU,gBAAU,EAAAV,KACVO,0BAAoB,EAY7BP,KAAKS,MAAQA,EACbT,KAAKkB,KAAOA,EACZlB,KAAKa,QAAUA,EACfb,KAAKY,UAAYA,EACjBZ,KAAKK,gBAAkBA,EACvBL,KAAKM,oBAAsBA,EAC3BN,KAAKU,WAAaA,EAClBV,KAAKO,qBAAuBA,CAC7B,EC3Ce,SAAAyM,EAAoBC,GACnC,IAAMC,ECGD,SAA+BD,GAIpC,IAHA,IAAME,EAAYF,EAAQ5J,YAAY,GAElC+J,EAAM,EACDvD,EAAI,EAAGA,EAAIsD,EAAUrH,OAAS,EAAG+D,IAAK,CAC9C,IAAAwD,EAAiBF,EAAUtD,GAC3ByD,EAAiBH,EAAUtD,EAAI,GAC/BuD,IADSE,KADAD,EAAEjC,KACEkC,EACbF,GAFaC,EAAA,GAGd,CAEA,OAAOD,EAAM,CACd,CDdkCG,CAAqBN,GACtD,IAAKC,EACJ,MAAO,CACNlM,KAAM,UACNqC,YAAa,CAAC4J,EAAQ5J,YAAY,GAAGmK,WAGxC,CEWa,IAAAC,EACE,gBADFA,EAEC,eAFDA,GAGJ,SAHIA,GAIJ,SAJIA,GAKH,UAkDGC,gBAAsBC,SAAAA,GAClC,SAAAD,EAAYrL,EAAwBxC,GAAqC,IAAA8F,EAEjD,OADvBA,EAAAgI,EAAA1H,UAAM5D,IAAQsD,MAIP9F,aAAO,EAHd8F,EAAK9F,QAAUA,EAAQ8F,CACxB,CAACU,EAAAqH,EAAAC,GAAAtM,IAAAA,EAAAqM,EAAApM,UAynBAoM,OAznBArM,EAIMuM,YAAA,SAAWb,GACjB,IAAA1J,EAAW0J,EAAX1J,YACA1E,EAAUoO,EAAVpO,WACAoF,EAAOgJ,EAAPhJ,QAQA,IAAIA,MAAAA,OAAAA,EAAAA,EAASL,cAAe3G,EAAY8Q,QACzB7N,KAAK8N,+BAA+B,CACjD3K,SAAU,CAAEnC,KAAM,QAASqC,YAAAA,GAC3B1E,WAAAA,EACA+E,WAAY3G,EAAY8Q,SAa1B,OALgB7N,KAAK+N,oBAAoB,CACxC5K,SAAU,CAAEnC,KAAM,QAASqC,YAAAA,GAC3B1E,WAAAA,GAIF,EAAC0C,EAEM2M,iBAAA,SAAgBC,GAOtB,YAAYF,oBAAoB,CAC/B5K,SAAU,CAAEnC,KAAM,aAAcqC,YAPtB4K,EAAX5K,aAQC1E,WAPSsP,EAAVtP,YASD,EAAC0C,EAkBM6M,cAAA,SAAaC,GAQnB,IAPA9K,EAAW8K,EAAX9K,YACA1E,EAAUwP,EAAVxP,WACAoF,EAAOoK,EAAPpK,QAMMqK,EAAYpB,EAAoB,CACrChM,KAAM,UACNqC,YAAa,CAACA,KAGT4J,EAAU,CACfjM,KAAM,UACNqC,YAAa+K,EAAYA,EAAU/K,YAAc,CAACA,IAGnD,IAAW,MAAPU,OAAO,EAAPA,EAASL,cAAe3G,EAAY8Q,QACzB7N,KAAK8N,+BAA+B,CACjD3K,SAAU8J,EACVtO,WAAAA,EACA+E,WAAY3G,EAAY8Q,SAQ1B,OAAO7N,KAAK+N,oBAAoB,CAC/B5K,SAAU8J,EACVtO,WAAAA,GAEF,EAAC0C,EAEMgN,oBAAA,SAAmBC,GAOzB,YAAYC,qBAAqB,CAAElL,YAAa,CANtCiL,EAAVvC,YAM8D/K,KAL1DsN,EAAJtN,OAKsE,EACvE,EAACK,EAEMkN,qBAAA,SAAoBC,OAQ1BC,EAAAzO,KANAgB,EAAIwN,EAAJxN,KACA0N,EAAoBF,EAApBE,qBAMMC,EARKH,EAAXnL,YAQ6BuL,IAAI,SAAC7C,EAAYlC,OAACgF,EAAA,MAAM,CACpD7N,KAAM,UACNmC,SAAU,CAAEnC,KAAM,QAAkBqC,YAAa0I,GACjDpN,WAAUyC,GAAAyN,GACT3N,KAAMuN,EAAKvN,MAAI2N,EACd7N,IAAO,EAAI6N,GACRH,EAAuBA,EAAqB7E,GAAK,CAAA,GAEtD,GAGD,OADY7J,KAAK8O,eAAeH,EAEjC,EAACtN,EAEM0N,YAAA,SAAWC,GAMjB,OAAWhP,KAACiP,oBAA2B,CACtCjO,KAAM,QACNkO,UAPQF,EAATE,UAQCC,oBAPkBH,EAAnBG,oBAQCC,kBAPgBJ,EAAjBI,kBAQCrL,QAPMiL,EAAPjL,SASD,EAAC1C,EAEMgO,cAAA,SAAaC,GAMnB,OAAWtP,KAACiP,oBAAoB,CAC/BjO,KAAM,UACNkO,UAPQI,EAATJ,UAQCC,oBAPkBG,EAAnBH,oBAQCC,kBANgBE,EAAjBF,kBAOCrL,QARMuL,EAAPvL,SAUD,EAAC1C,EAEMkO,iBAAA,SAAgBC,GAMtB,OAAOxP,KAAKiP,oBAAoB,CAC/BjO,KAAM,aACNkO,UAPQM,EAATN,UAQCC,oBAPkBK,EAAnBL,oBAQCC,kBANgBI,EAAjBJ,kBAOCrL,QARMyL,EAAPzL,SAUD,EAAC1C,EAEMoO,uBAAA,SAAuBP,GACzBA,GAAalP,KAAKS,MAAMiP,IAAIR,IAC/BlP,KAAKS,MAAY,OAAC,CAACyO,GAErB,EAAC7N,EAEMsO,wBAAA,SAAwBC,GAAuBC,IAAAA,EACrD7P,KAAA,GAA0B,IAAtB4P,EAAW9J,OAAf,CAIA,IAAMgK,EAAWF,EAAWG,OAAO,SAAC7M,UAAO2M,EAAKpP,MAAMiP,IAAIxM,EAAG,GAEzD4M,EAAShK,QACZ9F,KAAKS,MAAK,OAAQqP,EALnB,CAOD,EAACzO,EAEM2O,cAAA,SAAcJ,GAAuBK,IAAAA,OACrCC,EAAyBN,EAC7BG,OAAO,SAAC7M,GAAO,OAAA+M,EAAKxP,MAAMiP,IAAIxM,EAAG,GACjC0L,IAAI,SAAC1L,GAAEiN,IAAAA,QAAM,CACbjB,UAAWhM,EACXvE,YAAUwR,EAAA,CAAA,EAAAA,EACRhT,EAAkBC,WAAW,EAAK+S,GAEpC,GAEFnQ,KAAKoQ,wBAAwBF,EAC9B,EAAC7O,EAEMgP,YAAA,SAAYnB,GAAoBoB,IAAAA,EAC9BtP,EAAShB,KAAKS,MAAM8P,gBAAgBrB,GAApClO,KACFwP,EAAS,CACdtB,UAAAA,EACAE,mBAAiBkB,KAAAA,EACfnT,EAAkBC,WAAW,EAAIkT,GAEnCvM,QAAS,CAAEL,WAAY3G,EAAY0T,SAGvB,YAATzP,EACHhB,KAAKqP,cAAcmB,GACA,eAATxP,EACVhB,KAAKuP,iBAAiBiB,GACH,UAATxP,GACVhB,KAAK+O,YAAYyB,EAEnB,EAACnP,EAEMqP,qBAAA,SACNC,GAKA3Q,KAAK4Q,wBACJD,EAAe/B,IAAI,SAAAiC,GAAgC,MAAA,CAClD3N,GAD8B2N,EAAT3B,UAErB/L,SAAU,CACTnC,KAAM,QACNqC,YAJyCwN,EAAV9E,YAMhC,GAEH,EAAC1K,EAEO0M,oBAAA,SAAmB+C,GAO1B,YAAYC,0BAA6B,CACxC5N,SAPO2N,EAAR3N,SAQCxE,WAPSmS,EAAVnS,YASD,EAAC0C,EAEO4N,oBAAA,SAAmB+B,GAC1B,IACA9B,EAAS8B,EAAT9B,UACAC,EAAmB6B,EAAnB7B,oBAEApL,EAAOiN,EAAPjN,QAkBA,IAhBgB/D,KAAKiR,cAAiB,CACrCjQ,KAPGgQ,EAAJhQ,KAQCkO,UAAAA,EACAC,oBAAAA,EACAC,kBAPgB4B,EAAjB5B,kBAQCrL,QACCA,EAAQL,aAAe3G,EAAY8Q,OAAMzM,KAEnC2C,EAAO,CACVmN,sBAAsB,IAAI9P,EAGvB2C,GAAAA,KAKP,YAGD,IAAMzF,EAAU0B,KAAKmR,yBAA4BjC,GAGjD,OAAInL,EAAQL,aAAe3G,EAAY8Q,QACjCsB,GAEFnP,KAAK8N,+BAA+B,CACpC3K,SAAU7E,EAAQ6E,SAClBxE,WAAYL,EAAQK,WACpB+E,WAAYK,EAAQL,aAQjBpF,EALG,IAMX,EAAC+C,EAEO4P,cAAA,SAAaG,GACpB,IAAApQ,EAAIoQ,EAAJpQ,KACAkO,EAASkC,EAATlC,UACAC,EAAmBiC,EAAnBjC,oBACAC,EAAiBgC,EAAjBhC,kBACArL,EAAOqN,EAAPrN,QAQA,IAAKmL,EACJ,OAAO,EAGR,IAAMmC,EAAmBrR,KAAKS,MAAM8P,gBAAgBrB,GAC9CoC,EAAqBtR,KAAKS,MAAM8Q,kBAAkBrC,GAExD,GAAImC,EAAiBrQ,OAASA,EAC7B,MAAU,IAAAiB,MACNjB,EAAsDqQ,kDAAAA,EAAiBrQ,oBAI5E,GAAImO,EAAqB,CACxB,IAAIqC,EAAkBxR,KAAKyR,yBAC1BJ,EACAlC,GAID,GAAIpL,EAAQmN,sBAAiD,YAAzBM,EAAgBxQ,KAAoB,CACvE,IAAM0Q,EAAoB1E,EAAoBwE,GAC1CE,IACHF,EAAkBE,EAEpB,CAEA,IACE1R,KAAK8N,+BAA+B,CACpC3K,SAAUqO,EACV7S,WAAY2S,EACZ5N,WAAYK,EAAQL,aAGrB,OAAY,EAGb1D,KAAK4Q,wBAAwB,CAC5B,CAAE1N,GAAIgM,EAAW/L,SAAUqO,IAE7B,CAQA,OANIpC,GACHpP,KAAKoQ,wBAAwB,CAC5B,CAAElB,UAAAA,EAAWvQ,WAAYyQ,MAIhB,CACZ,EAAC/N,EAEOoQ,yBAAA,SAGPD,EACAG,GAIA,GAAI3R,KAAK4R,kBAAkBD,GAC1B,OAAAvQ,KACIoQ,EAAe,CAClBnO,YAAasO,EAAqBtO,cAIpC,GAA6B,UAAzBmO,EAAgBxQ,KACnB,MAAM,IAAIiB,MACT,+DA4CF,IAvCA,IAuCmE4P,EAvC7DC,EAAqC,YAAzBN,EAAgBxQ,KAC5B+Q,EAAkCD,EAErCN,EAA4BnO,YAAY,GAAG2O,QAC1CR,EAA+BnO,YAAY2O,QAEzCC,EAAiBF,EAAoBjM,OAGrCoM,EAAiB,SAACC,GACvB,IAAMC,EAAaD,EAAQ,EAAIF,EAAiBE,EAAQA,EAExD,GAAIC,EAAa,GAAKA,GAAcH,EACnC,MAAU,IAAAI,WACAF,SAAAA,EAAwBC,mBAAAA,wBAInC,OAAOA,CACR,EAIME,EAAuD,IAAI9T,MAChEyT,GACCM,UAAK5Q,GAGD6Q,EAA+ChU,MAAMiU,KAC1D,CAAE3M,OAAQmM,GACV,WAAM,MAAA,EAAE,GAEHS,EAA8ClU,MAAMiU,KACzD,CAAE3M,OAAQmM,GACV,WAAA,MAAM,EAAE,GAEHU,EAAkC,GAGxCC,EAAAC,EAAuBlB,KAA4CE,EAAAe,KAAAE,MAAE,CAAA,IAA1DC,EAAQlB,EAAAhN,MAClB,GACCkO,EAAS/R,OAASyM,GAClBsF,EAAS/R,OAASyM,EAFnB,CAmCA,IAAMuF,EAAkBd,EAAea,EAASZ,OAGhDG,EAAiBU,GAAgB5R,KAC7B2R,EAAQ,CACXZ,MAAOa,GARR,KAhCA,CAKC,IAAMC,EAAWF,EAASZ,MACpBC,EAAaa,EAAW,EAAIhB,EAAiBgB,EAAWA,EAE9D,GAAIb,EAAa,GAAKA,EAAaH,EAClC,UAAUI,WACAU,SAAAA,EAASZ,MAAK,mBAAmBC,EAAU,sBAItD,GAAIW,EAAS/R,OAASyM,EAAwB,CAC7C,GAAI2E,GAAcH,EACjB,UAAUI,WACcU,uBAAAA,EAASZ,MAAwBC,mBAAAA,mCAA2CH,GAGrGO,EAAqBJ,GAAYrI,KAAKgJ,EACvC,MAEKX,IAAeH,EAElBU,EAAU5I,KAAKgJ,GAEfL,EAAoBN,GAAYrI,KAAKgJ,EAKxC,CAUD,CAKA,IAFA,IAAMG,EAA6B,GAE1BrJ,EAAI,EAAGA,EAAIoI,EAAgBpI,IAAK,CAGxC,IADA,IAC0CsJ,EAA1CC,EAAAP,EADsBL,EAAqB3I,MACDsJ,EAAAC,KAAAN,MACzCI,EAAenJ,KADSoJ,EAAAtO,MAEkBkH,YAI3C,IAAMgH,EAAWT,EAAiBzI,GAE7BkJ,EAGMA,EAAS/R,OAASyM,IAI5ByF,EAAenJ,KAAMgJ,EAA4BhH,YALjDmH,EAAenJ,KAAKgI,EAAoBlI,IAUzC,IADA,IACyCwJ,EAAzCC,EAAAT,EADqBH,EAAoB7I,MACAwJ,EAAAC,KAAAR,MACxCI,EAAenJ,KADSsJ,EAAAxO,MACoCkH,WAE9D,CAGA,IAAA,IAAAwH,EAAA,EAAAC,EAA6Bb,EAASY,EAAAC,EAAA1N,OAAAyN,IACrCL,EAAenJ,KADSyJ,EAAAD,GACoCxH,YAI7D,OAEC3K,KADgBoQ,EADbM,EAGQ,CACVzO,YAAW,CAAG6P,GAAc/M,OAHbqL,EAG0BnO,YAAY2O,MAAM,KAM1C,CAClB3O,YAAa6P,GAEf,EAAC7R,EAEOuQ,kBAAA,SACPmB,GAEA,OAAQA,EAAgC/R,OAASyM,EAClD,EAACpM,EAGO0P,0BAAA,SAAyB0C,GAChC,IAMOvQ,EAAMlD,KAAK8O,eAAe,CAChC,CACC9N,KAAM,UACNmC,SATMsQ,EAARtQ,SAUExE,WATQ8U,EAAV9U,cAKS,GAeT,MAPgB,CACfuE,GAAAA,EACAlC,KAAM,UACNrC,WAAYqB,KAAKS,MAAM8Q,kBAAkBrO,GACzCC,SAAUnD,KAAKS,MAAM8P,gBAAmBrN,GAI1C,EAAC7B,EAEOyM,+BAAA,SAA8B4F,GASrC,OAAK1T,KAAKH,QAAQO,UAIOJ,KAAKH,QAAQO,SACrC,CACCY,KAAM,UACNmC,SAfMuQ,EAARvQ,SAgBExE,WAfQ+U,EAAV/U,YAewC,IAEvC,CACCkC,QAASb,KAAKa,QACdD,UAAWZ,KAAKY,UAChBN,oBAAqBN,KAAKM,oBAC1BoD,WApBQgQ,EAAVhQ,aAwBwBJ,KACzB,EAACjC,EAEO8P,yBAAA,SACPjC,GAEA,MAAO,CACNhM,GAAIgM,EACJlO,KAAM,UACNrC,WAAYqB,KAAKS,MAAM8Q,kBAAkBrC,GACzC/L,SAAUnD,KAAKS,MAAM8P,gBAAmBrB,GAE1C,EAAC7N,EAEOyN,eAAA,SACPH,GAEA,OAAW3O,KAACS,MAAMkT,OAAOhF,EAC1B,EAACtN,EAEOuP,wBAAA,SACPgD,GAKA5T,KAAKS,MAAMoT,eAAeD,EAC3B,EAACvS,EAEO+O,wBAAA,SACPzR,GAKA,IAAMiV,EAAUjV,EACdiQ,IAAI,SAAAkF,GAAG,IAAA5E,EAAS4E,EAAT5E,UACP,OAAO6E,OAAOC,QADcF,EAAVnV,YACgBiQ,IAAI,SAAAqF,GAAY,MAAO,CACxD/Q,GAAIgM,EACJgF,SAF0CD,KAG1CpP,MAHiDoP,EAAA,GAIjD,EACF,GACCE,OAEFnU,KAAKS,MAAM2T,eAAeR,EAC3B,EAAClG,CAAA,CA7nBiCC,CAAQb,GCnCrCuH,GAAmB,CAAEC,OAAQ,SAAUC,OAAQ,SAc/CC,GAAiB,CACtBC,MAAO,aAaKC,gBAAoBhP,SAAAA,GA6BhC,SAAAgP,EAAY7U,GAA0D8F,IAAAA,EAEzC,OAD5BA,EAAAD,EAAAO,KAAAjG,KAAMH,GAAS,IAAKG,MA7BrBkB,KAAO,SAAQyE,EACP+D,YAAM,EAAA/D,EACNgP,iBAAWhP,EAAAA,EACXiP,SAAW,GAAEjP,EAEbkP,qBAAe,EAAAlP,EACfmP,UAA0CT,GAAgB1O,EAC1DoP,QAA6BP,GAAc7O,EAC3CqP,yBAA2B,KAAOrP,EAClCsP,mCAAoC,EAAKtP,EACzCuP,gBAAkB,aAAYvP,EAC9BwP,cAAQxP,EAAAA,EAGRsL,mBAAa,EAgBpBtL,EAAKxE,cAActB,GAAS8F,CAC7B,CAACU,EAAAqO,EAAAhP,GAAArE,IAAAA,EAAAqT,EAAApT,UAkXA,OAlXAD,EAEQF,cAAA,SACRtB,GAIA6F,EAAApE,UAAMH,cAAa8E,UAACpG,GAEhBA,MAAAA,GAAAA,EAASkV,UACZ/U,KAAK+U,QAAO3T,EAAA,CAAA,EAAQpB,KAAK+U,QAAYlV,EAAQkV,UAGnB,QAAhB,MAAPlV,OAAO,EAAPA,EAASiV,WACZ9U,KAAK8U,UAAY,CAAER,OAAQ,KAAMC,OAAQ,MAC/B1U,MAAAA,GAAAA,EAASiV,YACnB9U,KAAK8U,UAAS1T,EAAQ,GAAApB,KAAK8U,UAAcjV,EAAQiV,YAGvC,MAAPjV,GAAAA,EAASmV,2BACZhV,KAAKgV,yBAA2BnV,EAAQmV,0BAGrCnV,MAAAA,GAAAA,EAASqV,kBACZlV,KAAKkV,gBAAkBrV,EAAQqV,iBAGrB,MAAPrV,GAAAA,EAAS+U,WACZ5U,KAAK4U,SAAW/U,EAAQ+U,SAAW,EAAI,EAAI/U,EAAQ+U,SAErD,EAACvT,EAEO+T,MAAA,WACP,QAA6BzT,IAAzB3B,KAAK6U,sBAAsDlT,IAArB3B,KAAK2U,aAI/B3U,KAAKqV,aAAarV,KAAK2U,YAAa5X,EAAY8Q,QAEhE,CAGA,IAAMqB,EAAYlP,KAAK6U,gBAEvB7U,KAAKiV,mCAAoC,EACzCjV,KAAK0J,YAAS/H,EACd3B,KAAK6U,qBAAkBlT,EACvB3B,KAAKmV,cAAWxT,EAGG,YAAf3B,KAAKsV,OACRtV,KAAKkC,aAGNlC,KAAK0C,SAASwM,EAAW,CACxBhO,KAAMlB,KAAKkB,KACXqU,OAAQvY,GAfT,CAiBD,EAACqE,EAEOmU,aAAA,SACPzT,EACAoT,GAA4B,IAAAhF,OAA5BgF,IAAAA,IAAAA,EAAqB,SAErBnV,KAAK0J,OAAS,CAAC3H,EAAMyG,IAAKzG,EAAM0G,KAChCzI,KAAK2U,YAAc,CAAC5S,EAAMyG,IAAKzG,EAAM0G,KAErC,IAAMgN,EAAiBhM,EAAO,CAC7BC,OAAQ1J,KAAK0J,OACbC,iBAAkB3J,KAAKgV,yBACvB1U,oBAAqBN,KAAKM,sBAGrBoV,EAAU1V,KAAKiR,cAAc/C,cAAc,CAChD7K,YAAaoS,EAAetS,SAASE,YAAY,GACjD1E,YAAUwR,EACTjP,CAAAA,KAAMlB,KAAKkB,KACXyI,iBAAkB3J,KAAKgV,0BAAwB7E,EAC9C3S,EAAkBE,oBAAoB,EAAIyS,KAIxCuF,IAIL1V,KAAK6U,gBAAkBa,EAAQxS,GAC/BlD,KAAKiV,mCAAoC,EACzCjV,KAAKmV,SAAWA,EAChBnV,KAAKgC,aACN,EAACX,EAEOsU,gBAAA,WACP,MAC0B,oBAApBT,iBACoB,uBAAzBlV,KAAKkV,eAEP,EAAC7T,EAEOuU,gBAAA,WACP,MAC0B,eAAzB5V,KAAKkV,iBACoB,uBAAzBlV,KAAKkV,eAEP,EAAC7T,EAGDoT,MAAA,WACCzU,KAAKkC,aACLlC,KAAKc,UAAUd,KAAK+U,QAAQN,MAC7B,EAACpT,EAGDwU,KAAA,WACC7V,KAAK8V,UACL9V,KAAKmC,aACLnC,KAAKc,UAAU,QAChB,EAACO,EAGDqD,QAAA,SAAQ3C,GAEN/B,KAAK4V,oBACc,UAAjB7T,EAAMgU,QACP/V,KAAK6B,kBAAkB7B,KAAKE,cAAcZ,WAAYyC,IACpC,SAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcV,UAAWuC,IACrDA,EAAMiU,eACNhW,KAAK6B,kBAAkB7B,KAAKE,cAAcX,YAAawC,MAEpD/B,KAAK0J,OAEC1J,KAAK0J,aAAmC/H,IAAzB3B,KAAK6U,kBAC9B7U,KAAK2U,YAAc,CAAC5S,EAAMyG,IAAKzG,EAAM0G,KAGrCzI,KAAKoV,SALLpV,KAAKwV,aAAazT,GAQrB,EAACV,EAGDoD,YAAA,SAAY1C,GACX/B,KAAKiV,mCAAoC,EACzCjV,KAAK2U,YAAc,CAAC5S,EAAMyG,IAAKzG,EAAM0G,KACrCzI,KAAKqV,aAAarV,KAAK2U,YAAa5X,EAAY4G,YACjD,EAACtC,EAGD6C,UAAA,aAAc7C,EAGd8C,QAAA,SAAQpC,GACHA,EAAMqD,MAAQpF,KAAK8U,UAAUR,OAChCtU,KAAK8V,UACK/T,EAAMqD,MAAQpF,KAAK8U,UAAUP,QACvCvU,KAAKoV,OAEP,EAAC/T,EAGD5B,YAAA,SACCsC,EACA4C,GAEmB,YAAf3E,KAAKsV,OAKRtV,KAAK6B,kBAAkB7B,KAAKE,cAAcT,YAAasC,IACvD/B,KAAK2V,oBAEL3V,KAAKwV,aAAazT,EAAO,QACzB4C,GAAmB,GAErB,EAACtD,EAGD3B,OAAA,SACCqC,EACA4C,GAGC3E,KAAK6B,kBAAkB7B,KAAKE,cAAcR,OAAQqC,IAClD/B,KAAK2V,mBACa,SAAlB3V,KAAKmV,WAELnV,KAAKiV,mCAAoC,EACzCjV,KAAK2U,YAAc,CAAC5S,EAAMyG,IAAKzG,EAAM0G,KACrCzI,KAAKqV,aAAarV,KAAK2U,YAAa5X,EAAY4G,aAElD,EAACtC,EAGD1B,UAAA,SACCoC,EACA4C,GAGC3E,KAAK6B,kBAAkB7B,KAAKE,cAAcP,UAAWoC,IACrD/B,KAAK2V,mBACa,SAAlB3V,KAAKmV,WAELnV,KAAK2U,YAAc,CAAC5S,EAAMyG,IAAKzG,EAAM0G,KAErCzI,KAAKoV,QACLzQ,GAAmB,GAErB,EAACtD,EAGDyU,QAAA,WACC,IAAMG,EAAYjW,KAAK6U,gBAEvB7U,KAAK0J,YAAS/H,EACd3B,KAAK6U,qBAAkBlT,EACvB3B,KAAKmV,cAAWxT,EAEG,YAAf3B,KAAKsV,OACRtV,KAAKkC,aAGNlC,KAAKiR,cAAcxB,uBAAuBwG,EAC3C,EAAC5U,EAGD6U,aAAA,SAAa5X,GACZ,IAAMmD,EAAML,EAAA,CAAA,ECvUN,CACN+U,iBAAkB,UAClBC,oBAAqB,UACrBC,oBAAqB,EACrBC,sBAAuB,EACvBC,mBAAoB,GACpBC,WAAY,UACZC,aAAc,EACdC,kBAAmB,UACnBC,oBAAqB,EACrBC,kBAAmB,EACnBC,WAAY,EACZC,gBAAiB,UACjBC,gBAAiB,EACjBC,kBAAmB,EACnBC,OAAQ,EACRC,eAAWvV,EACXwV,kBAAcxV,EACdyV,iBAAazV,EACb0V,oBAAgB1V,IDsThB,MACkB,YAAjBrD,EAAQ0C,MACkB,YAA1B1C,EAAQ6E,SAASnC,MACjB1C,EAAQK,WAAWuC,OAASlB,KAAKkB,MAEjCO,EAAO0U,iBAAmBnW,KAAK4E,wBAC9B5E,KAAKyB,OAAO6V,UACZ7V,EAAO0U,iBACP7X,GAGDmD,EAAO2U,oBAAsBpW,KAAK4E,wBACjC5E,KAAKyB,OAAO8V,aACZ9V,EAAO2U,oBACP9X,GAGDmD,EAAO4U,oBAAsBrW,KAAKgF,uBACjChF,KAAKyB,OAAO+V,aACZ/V,EAAO4U,oBACP/X,GAGDmD,EAAO6U,sBAAwBtW,KAAKgF,uBACnChF,KAAKyB,OAAOgW,eACZ,EACAnZ,GAGDmD,EAAO8U,mBAAqBvW,KAAKgF,uBAChChF,KAAKyB,OAAOiW,YACZjW,EAAO8U,mBACPjY,GAGDmD,EAAOwV,OAAS7Y,EAETqD,GAGDA,CACR,EAACJ,EAEDsB,gBAAA,SAAgBrE,GAAgB,IAAAmQ,EAC/BzO,KAAA,YAAY4D,oBAAoBtF,EAAS,SAACqZ,GACzC,OAAA/K,EACC+K,EACAlJ,EAAKnO,oBACL,EAEH,EAACe,EAEOgU,aAAA,SAAaV,EAAuBjR,GAC3C,QAA6B/B,IAAzB3B,KAAK6U,sBAAiDlT,IAAhB3B,KAAK0J,OAA/C,CAIA,IAEIkO,EACAC,EAHEC,EAAWpU,IAAe3G,EAAY8Q,OAK5C,GAAI7N,KAAKiV,kCAGR,GAFA4C,EAAYvR,EAA4BtG,KAAK0J,OAAQiL,GAE7B,iBAApB3U,KAAKU,WAA+B,CAGvC,IAAMqX,EExYM,SACfC,EACAC,GAEA,IAAMC,EAAiE,IAA9C5R,EAA4B0R,EAAQC,GAC7D,GAAyB,IAArBC,EACH,OAAO,EAGR,IAAAC,EAAyB5P,EAAsByP,EAAO,GAAIA,EAAO,IAAtD7M,EAAEgN,EAALzP,EAAU0C,EAAE+M,EAALxP,EACfyP,EAAyB7P,EAAsB0P,EAAO,GAAIA,EAAO,IAA/C3M,EAAE8M,EAALzP,EAIf,OAH0BhC,KAAKW,KAC9BX,KAAKuB,IAFOkQ,EAAL1P,EAEOyC,EAAI,GAAKxE,KAAKuB,IAAIoD,EAAKF,EAAI,IAEf8M,CAC5B,CFyXuBG,CAClBrY,KAAK0J,OACLiL,GAGDiD,ER5UE,SAA4B/X,GAejC,IATA,IAAQ6J,EAAkD7J,EAAlD6J,OAA0BpJ,EAAwBT,EAAxBS,oBAC5BsJ,EAAQ/J,EAAQ+J,MAAQ/J,EAAQ+J,MAAQ,GAExC0O,EAAkC,IAHkBzY,EAA1C8J,iBAMhBwO,EAAiB5P,EADEmB,EAAPjB,GAAOiB,EACnB,IAAQhB,EAACyP,EAADzP,EAAGC,EAACwP,EAADxP,EAELtF,EAA0B,GACvBwG,EAAI,EAAGA,EAAID,EAAOC,IAAK,CAC/B,IAAM0O,EAAe,IAAJ1O,EAAWD,EAASjD,KAAKC,GAAM,IAC1C4R,EAAKF,EAAe3R,KAAKS,IAAImR,GAC7BE,EAAKH,EAAe3R,KAAKQ,IAAIoR,GAEnCG,EAAqB5P,EADHJ,EAAI8P,EAAI7P,EAAI8P,GACjBhQ,EAAGiQ,EAAHjQ,IACbpF,EAAY0G,KAAK,CAChBjC,EAFU4Q,EAAHlQ,IAEalI,GACpBwH,EAAeW,EAAKnI,IAEtB,CAKA,OAFA+C,EAAY0G,KAAK1G,EAAY,IAEtB,CACNrC,KAAM,UACNmC,SAAU,CAAEnC,KAAM,UAAWqC,YAAa,CAACA,IAC3C1E,WAAY,CAAA,EAEd,CQySoBga,CAAkB,CACjCjP,OAAQ1J,KAAK0J,OACbC,iBAAkBkO,EAAYE,EAC9BzX,oBAAqBN,KAAKM,oBAC1BsJ,MAAO5J,KAAK4U,UAEd,KAAO,IAAwB,UAApB5U,KAAKU,WAQf,MAAM,IAAIuB,MAAM,sBAPhB2V,EAAgBnO,EAAO,CACtBC,OAAQ1J,KAAK0J,OACbC,iBAAkBkO,EAClBvX,oBAAqBN,KAAKM,oBAC1BsJ,MAAO5J,KAAK4U,UAId,CAGD,IAAMxF,EAGF,CAAA,EAUJ,OARIwI,GAAiBC,IACpBzI,EAAkBzF,iBAAmBkO,GAGlCC,IACH1I,EAAkB5R,EAAkBE,wBAAqBiE,QAG9CsP,cAAc5B,cAAc,CACvCH,UAAWlP,KAAK6U,gBAChB1F,oBAAqByI,EAClB,CACA5W,KAAMyM,GACNpK,YAAauU,EAAczU,SAASE,kBAEpC1B,EACHyN,kBAAAA,EACArL,QAAS+T,EACN,CACApU,WAAAA,EACA6R,OAAQvY,GAER,CAAE0G,WAAAA,IA/DN,CAiED,EAACrC,EAEDyB,oBAAA,SAAoBxE,GAGf0B,KAAK6U,kBAAoBvW,EAAQ4E,KACpClD,KAAKiV,mCAAoC,EACzCjV,KAAK0J,YAAS/H,EACd3B,KAAK6U,qBAAkBlT,EACvB3B,KAAKmV,cAAWxT,EACG,YAAf3B,KAAKsV,OACRtV,KAAKkC,aAGR,EAACb,EAEDE,kBAAA,SAAkBc,GACjBrC,KAAKiR,cAAgB,IAAIvD,GAAsBrL,EAAQ,CACtDjC,SAAUJ,KAAKI,UAEjB,EAACsU,CAAA,CAlZ+BhP,CAAQ9F,GGpE5BgZ,GAAoB,SAChCrS,EACAC,GAEA,IAEMmC,EADmBnC,EAAjBkC,EADiBnC,EAAjBmC,EAGFA,EAFmBlC,EAAVmC,EADUpC,EAAVoC,EAIf,OAAOhC,KAAKW,KAAKoB,EAAIA,EAAIC,EAAIA,EAC9B,ECTgB,SAAAkQ,GACf9M,EACAY,GAEA,OACCZ,EAAW,KAAOY,EAAc,IAAMZ,EAAW,KAAOY,EAAc,EAExE,CCHA,IAAamM,gBAAoB,SAAAnL,GAChC,SAAAmL,EAAYzW,GACX,OAAAsL,EAAA1H,KAAM5D,KAAAA,IACPrC,IAAA,CAACqG,EAAAyS,EAAAnL,GAAAtM,IAAAA,EAAAyX,EAAAxX,UAsEA,OAtEAD,EAEM0X,gBAAA,SAAgB7J,GACtB,OAAOlP,KAAKS,MAAM8P,gBAAgBrB,GAAWlO,IAC9C,EAACK,EAEM2X,6BAAA,SAA4BjM,GAClC,IAUIhB,EATJkN,EAAalM,EAAbkM,cACA9G,EAAKpF,EAALoF,MAMMhP,EAAWnD,KAAKS,MAAM8P,gBARnBxD,EAATmC,WAYA,GAAsB,YAAlB/L,EAASnC,KACZ+K,EAAa5I,EAASE,YAAY,GAAG8O,WACT,eAAlBhP,EAASnC,KACnB+K,EAAa5I,EAASE,YAAY8O,OAC5B,CACN,GAAc,IAAVA,EACH,MAAU,IAAAlQ,MAAM,wDAEjB8J,EAAa5I,EAASE,WACvB,CAEA,OAAOwV,GAAqBI,EAAelN,EAC5C,EAAC1K,EAEM6X,YAAA,SAA8ChK,GACpD,OAAOlP,KAAKS,MAAM8P,gBAAmBrB,EACtC,EAAC7N,EAEM8X,eAAA,SACNjK,GAEA,IAAAkK,EAA8BpZ,KAAKS,MAAM8P,gBAAmBrB,GAA9C7L,EAAW+V,EAAX/V,YACd,MAAgB,YADJ+V,EAAJpY,KACoBqC,EAAY,GAAKA,CAC9C,EAAChC,EAEMgY,cAAA,SACNnK,EACAiD,GAEA,IAAMmH,EAAStZ,KAAKmZ,eAAkBjK,GAChC8D,EAAkBb,EAAQ,EAAImH,EAAOxT,OAASqM,EAAQA,EAE5D,GAAIa,EAAkB,GAAKA,GAAmBsG,EAAOxT,OACpD,UAAUuM,oBACAF,EAAK,mBAAmBa,EAAmC,sBAItE,OAAOsG,EAAOtG,EACf,EAAC3R,EAEMkY,cAAA,SAAcrK,GACpB,OAAOlP,KAAKS,MAAM8Q,kBAAkBrC,EACrC,EAAC7N,EAEMmY,WAAA,SAAWtK,GACjB,YAAYzO,MAAMiP,IAAIR,EACvB,EAAC7N,EAEMoY,sBAAA,SAAsBC,GAC5B,OAAO1Z,KAAKS,MAAMkZ,aAAaD,GAAQ9K,IAAI,SAAAX,GAAK,OAAAA,EAAF/K,EAAwB,EACvE,EAAC4V,CAAA,CAzE+B,CAAQhM,GCgCnCuH,GAAmB,CAAEC,OAAQ,SAAUC,OAAQ,SAqB/CC,GAAiB,CACtBC,MAAO,YACPW,MAAO,WAeKwE,gBAAsBlU,SAAAA,GAsBlC,SAAAkU,EAAY/Z,GAA8D8F,IAAAA,EAE7C,OAD5BA,EAAAD,EAAAO,KAAAjG,KAAMH,GAAS,UAtBhBqB,KAAO,WAAUyE,EAETkU,UAAW,EAAKlU,EAChBsQ,eAAStQ,EAAAA,EACTmU,sBAAcnU,EACdoU,YAAsB,GAAEpU,EACxBmP,UAA4CT,GAAgB1O,EAC5DoP,QAA6BP,GAAc7O,EAC3CqU,wBAAkC,EAAIrU,EACtCsU,WAAqB,EAAKtU,EAC1BuU,iBAAmB,IAAGvU,EACtBwU,sBAAuB,EAAKxU,EAC5ByU,mBAAoB,EAAKzU,EACzBuP,gBAAkB,aAAYvP,EAC9BwP,cAAQxP,EAAAA,EACR0U,UAAY,EAAC1U,EAGbsL,mBAAatL,EAAAA,EACb2U,mBAIP3U,EAAKxE,cAActB,GAAS8F,CAC7B,CAACU,EAAAuT,EAAAlU,GAAArE,IAAAA,EAAAuY,EAAAtY,UAgeAsY,OAheAvY,EAEMF,cAAA,SACNtB,GAIA6F,EAAApE,UAAMH,cAAa8E,KAACpG,KAAAA,GAET,MAAPA,GAAAA,EAASka,cACZ/Z,KAAK+Z,YAAcla,EAAQka,kBAGDpY,KAAhB,MAAP9B,OAAO,EAAPA,EAASwa,aAGZra,KAAKqa,UAAY1T,KAAK4T,IACrB5T,KAAK6T,IAAI3a,EAAQwa,UAHO,GACA,YAOc1Y,WAApC9B,SAAAA,EAASma,0BACZha,KAAKga,uBAAyBna,EAAQma,6BAGZrY,KAAvB9B,MAAAA,OAAAA,EAAAA,EAASoa,aACZja,KAAKia,UAAYpa,EAAQoa,WAGf,MAAPpa,GAAAA,EAASqa,mBACZla,KAAKka,iBAAmBra,EAAQqa,kBAGN,QAAhB,MAAPra,OAAO,EAAPA,EAASiV,WACZ9U,KAAK8U,UAAY,CAAER,OAAQ,KAAMC,OAAQ,MAC/B1U,MAAAA,GAAAA,EAASiV,YACnB9U,KAAK8U,UAAS1T,EAAQ,CAAA,EAAApB,KAAK8U,UAAcjV,EAAQiV,kBAG9CjV,GAAAA,EAASkV,UACZ/U,KAAK+U,QAAO3T,EAAA,CAAA,EAAQpB,KAAK+U,QAAYlV,EAAQkV,UAGnC,MAAPlV,GAAAA,EAASqV,kBACZlV,KAAKkV,gBAAkBrV,EAAQqV,gBAEjC,EAAC7T,EAEOuU,gBAAA,WACP,MAC0B,eAAzB5V,KAAKkV,iBACoB,uBAAzBlV,KAAKkV,eAEP,EAAC7T,EAEOsU,gBAAA,WACP,MAC0B,eAAzB3V,KAAKkV,iBACoB,uBAAzBlV,KAAKkV,eAEP,EAAC7T,EAEOmU,aAAA,SACPzT,EACAoT,GAA4B,IAAAhF,OAA5BgF,IAAAA,IAAAA,EAAqB,SAErB,IAAAsF,EAA0Bza,KAAKiR,cAAc/C,cAAc,CAC1D7K,YAAa,CACZ,CAACtB,EAAMyG,IAAKzG,EAAM0G,KAClB,CAAC1G,EAAMyG,IAAKzG,EAAM0G,KAClB,CAAC1G,EAAMyG,IAAKzG,EAAM0G,KAClB,CAAC1G,EAAMyG,IAAKzG,EAAM0G,MAEnB9J,YAAUwR,EAAA,CACTjP,KAAMlB,KAAKkB,MAAIiP,EACd3S,EAAkBE,oBAAoB,EAAIyS,KAI7CnQ,KAAKiW,UAbgBwE,EAAbvX,GAcRlD,KAAKmV,SAAWA,EAEhBnV,KAAK8Z,eAAiB9Z,KAAKiR,cAAc5C,oBAAoB,CAC5DtC,WAAY,CAAChK,EAAMyG,IAAKzG,EAAM0G,KAC9BzH,KAAMxD,EAAkBI,gBAGzBoC,KAAK6Z,UAAW,EAEG,YAAf7Z,KAAKsV,OACRtV,KAAKgC,YAEP,EAACX,EAEOqZ,cAAA,SAAc3Y,GAA0B,IAAA0M,EAAAzO,KAC/C,QAAuB2B,IAAnB3B,KAAKiW,YAA6C,IAAlBjW,KAAK6Z,SAAzC,CAKA,IAAAc,EAAmC3a,KAAKsa,YAAYjB,cACnDrZ,KAAKiW,WACJ,GAFK2E,EAAWD,KAAEE,EAAWF,EAAA,GAI/BG,EAAiB9a,KAAKa,QAAQ+Z,EAAaC,GACrClT,EAAWiR,GAChB,CAAElQ,EAFMoS,EAADpS,EAEFC,EAFMmS,EAADnS,GAGV,CAAED,EAAG3G,EAAMgZ,WAAYpS,EAAG5G,EAAMiZ,aAGjCC,EAAiCjb,KAAKsa,YAAYjB,cACjDrZ,KAAKiW,UACL,GAEDiF,EAAqClb,KAAKa,QAJzBoa,EAAA,GAAYA,EAI7B,IAMA,GALwBrC,GACvB,CAAElQ,EAFgBwS,EAAXxS,EAEQC,EAFgBuS,EAAXvS,GAGpB,CAAED,EAAG3G,EAAMgZ,WAAYpS,EAAG5G,EAAMiZ,aAGXhb,KAAKK,iBAY1B,GAXIL,KAAKia,WAAaja,KAAKma,uBAC1Bna,KAAKoa,mBAAoB,EACzBe,WAAW,WACV1M,EAAK2L,mBAAoB,CAC1B,EAAGpa,KAAKka,kBAERla,KAAKoV,SAGNpV,KAAKc,UAAUd,KAAK+U,QAAQK,OAExBpV,KAAKga,uBACR,YAGDha,KAAKma,sBAAuB,EAC5Bna,KAAKc,UAAUd,KAAK+U,QAAQN,OAG7B,KAAI9M,EAAW3H,KAAK+Z,aAApB,CAIA,IAAMhO,EAAa/L,KAAKob,sBACvB,CAACR,EAAaC,GACd,CAAC9Y,EAAMyG,IAAKzG,EAAM0G,MAGnBzI,KAAKiR,cAAc5B,cAAc,CAChCH,UAAWlP,KAAKiW,UAChB9G,oBAAqB,CACpB,CACCnO,KAAMyM,EACN0E,OAAQ,EACRpG,WAAAA,IAGFhI,QAAS,CAAEL,WAAY3G,EAAY4G,cAhBpC,CA5CA,MAFC3D,KAAKc,UAAUd,KAAK+U,QAAQN,MAgE9B,EAACpT,EAYO+Z,sBAAA,SACPC,EACAC,GAEA,OAAuB,IAAnBtb,KAAKqa,UACDiB,EAMD,CAHuCD,KAIzBrb,KAAKqa,UAHgBiB,EAAlBC,IAIH,EAAIvb,KAAKqa,WALgBgB,EAAkB,GAM5Crb,KAAKqa,UALiBiB,EAE1C,IAGuD,EAAItb,KAAKqa,WAEjE,EAAChZ,EAEO+T,MAAA,WAAK9E,IAAAA,EACZ,QAAuB3O,IAAnB3B,KAAKiW,WAIOjW,KAAKiR,cAAc5B,cAAc,CAChDH,UAAWlP,KAAKiW,UAChB7G,mBAAiBkB,KAAAA,EACf9S,EAAkBE,wBAAoBiE,EAAS2O,GAEjDvM,QAAS,CAAEL,WAAY3G,EAAY8Q,OAAQ0H,OAAQvY,KAGpD,CAIA,IAAMkS,EAAYlP,KAAKiW,UAEvBjW,KAAKiR,cAAcxB,uBAAuBzP,KAAK8Z,gBAE/C9Z,KAAK6Z,UAAW,EAChB7Z,KAAKiW,eAAYtU,EACjB3B,KAAK8Z,oBAAiBnY,EACtB3B,KAAKma,sBAAuB,EAC5Bna,KAAKmV,cAAWxT,EAEG,YAAf3B,KAAKsV,OACRtV,KAAKkC,aAGNlC,KAAK0C,SAASwM,EAAW,CACxBhO,KAAMlB,KAAKkB,KACXqU,OAAQvY,GAlBT,CAoBD,EAACqE,EAGDoT,MAAA,WACCzU,KAAKkC,aACLlC,KAAKc,UAAUd,KAAK+U,QAAQN,MAC7B,EAACpT,EAGDwU,KAAA,WACC7V,KAAK8V,UACL9V,KAAKmC,aACLnC,KAAKc,UAAU,QAChB,EAACO,EAGDoD,YAAA,SAAY1C,GACN/B,KAAK4V,mBAAuC,UAAlB5V,KAAKmV,UAIpCnV,KAAK0a,cAAc3Y,EACpB,EAACV,EAGDqD,QAAA,SAAQ3C,GACP,GACC/B,KAAK4V,oBACc,UAAjB7T,EAAMgU,QACP/V,KAAK6B,kBAAkB7B,KAAKE,cAAcZ,WAAYyC,IACpC,SAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcV,UAAWuC,IACrDA,EAAMiU,eACNhW,KAAK6B,kBAAkB7B,KAAKE,cAAcX,YAAawC,IACxD,CACD,GAAI/B,KAAKoa,kBACR,OAGD,IAAsB,IAAlBpa,KAAK6Z,SAGR,YAFA7Z,KAAKwV,aAAazT,GAKnB/B,KAAKoV,OACN,CACD,EAAC/T,EAGD6C,UAAA,aAAc7C,EAGd8C,QAAA,SAAQpC,GACHA,EAAMqD,MAAQpF,KAAK8U,UAAUR,OAChCtU,KAAK8V,UACK/T,EAAMqD,MAAQpF,KAAK8U,UAAUP,SACjB,IAAlBvU,KAAK6Z,UACR7Z,KAAKoV,OAGR,EAAC/T,EAGD5B,YAAA,SACCsC,EACA4C,GAEmB,YAAf3E,KAAKsV,QAILtV,KAAKoa,mBAKRpa,KAAK6B,kBAAkB7B,KAAKE,cAAcT,YAAasC,IACvD/B,KAAK2V,oBAEL3V,KAAKwV,aAAazT,EAAO,QACzB4C,GAAmB,IAErB,EAACtD,EAGD3B,OAAA,SACCqC,EACA4C,GAGC3E,KAAK6B,kBAAkB7B,KAAKE,cAAcR,OAAQqC,IAClD/B,KAAK2V,mBACa,SAAlB3V,KAAKmV,UAELnV,KAAK0a,cAAc3Y,EAErB,EAACV,EAGD1B,UAAA,SACCoC,EACA4C,GAA8CkL,IAAAA,OAG7C7P,KAAK6B,kBAAkB7B,KAAKE,cAAcP,UAAWoC,IACrD/B,KAAK2V,mBACa,SAAlB3V,KAAKmV,WAELnV,KAAKoa,mBAAoB,EACzBe,WAAW,WACVtL,EAAKuK,mBAAoB,CAC1B,EAAGpa,KAAKka,kBAERla,KAAKoV,QACLzQ,GAAmB,GAErB,EAACtD,EAGDyU,QAAA,WACC,IAAM0F,EAAYxb,KAAKiW,UACjBwF,EAAwBzb,KAAK8Z,eAEnC9Z,KAAK8Z,oBAAiBnY,EACtB3B,KAAKiW,eAAYtU,EACjB3B,KAAK6Z,UAAW,EAChB7Z,KAAKma,sBAAuB,EAC5Bna,KAAKmV,cAAWxT,EACG,YAAf3B,KAAKsV,OACRtV,KAAKkC,aAGNlC,KAAKiR,cAAcxB,uBAAuB+L,GAC1Cxb,KAAKiR,cAAcxB,uBAAuBgM,EAC3C,EAACpa,EAGD6U,aAAA,SAAa5X,GACZ,IAAMmD,EAAML,EAAQsa,CAAAA,EL/cd,CACNvF,iBAAkB,UAClBC,oBAAqB,UACrBC,oBAAqB,EACrBC,sBAAuB,EACvBC,mBAAoB,GACpBC,WAAY,UACZC,aAAc,EACdC,kBAAmB,UACnBC,oBAAqB,EACrBC,kBAAmB,EACnBC,WAAY,EACZC,gBAAiB,UACjBC,gBAAiB,EACjBC,kBAAmB,EACnBC,OAAQ,EACRC,eAAWvV,EACXwV,kBAAcxV,EACdyV,iBAAazV,EACb0V,oBAAgB1V,IK8bhB,MACkB,YAAjBrD,EAAQ0C,MACkB,YAA1B1C,EAAQ6E,SAASnC,MACjB1C,EAAQK,WAAWuC,OAASlB,KAAKkB,MAEjCO,EAAO0U,iBAAmBnW,KAAK4E,wBAC9B5E,KAAKyB,OAAO6V,UACZ7V,EAAO0U,iBACP7X,GAGDmD,EAAO2U,oBAAsBpW,KAAK4E,wBACjC5E,KAAKyB,OAAO8V,aACZ9V,EAAO2U,oBACP9X,GAGDmD,EAAO6U,sBAAwBtW,KAAKgF,uBACnChF,KAAKyB,OAAOgW,eACZ,EACAnZ,GAGDmD,EAAO4U,oBAAsBrW,KAAKgF,uBACjChF,KAAKyB,OAAO+V,aACZ/V,EAAO4U,oBACP/X,GAGDmD,EAAO8U,mBAAqBvW,KAAKgF,uBAChChF,KAAKyB,OAAOiW,YACZjW,EAAO8U,mBACPjY,GAGDmD,EAAOwV,OAAS7Y,EAETqD,GAEU,YAAjBnD,EAAQ0C,MACkB,UAA1B1C,EAAQ6E,SAASnC,MACjB1C,EAAQK,WAAWuC,OAASlB,KAAKkB,MAEjCO,EAAOoV,WAAa7W,KAAKgF,uBACxBhF,KAAKyB,OAAOka,kBACZla,EAAOoV,WACPvY,GAGDmD,EAAO+U,WAAaxW,KAAK4E,wBACxB5E,KAAKyB,OAAOma,kBACZna,EAAO+U,WACPlY,GAGDmD,EAAOgV,aAAezW,KAAKgF,uBAC1BhF,KAAKyB,OAAOoa,yBACYla,IAAxBF,EAAOgV,aAA6B,EAAIhV,EAAOgV,aAC/CnY,GAGDmD,EAAOiV,kBAAoB1W,KAAK4E,wBAC/B5E,KAAKyB,OAAOqa,yBACZra,EAAOiV,kBACPpY,GAGDmD,EAAOmV,kBAAoB5W,KAAKgF,uBAC/BhF,KAAKyB,OAAOsa,yBACZ,EACAzd,GAGDmD,EAAOkV,oBAAsB3W,KAAKgF,uBACjChF,KAAKyB,OAAOua,gCACmBra,IAA/BF,EAAOkV,oBACJ,EACAlV,EAAOkV,oBACVrY,GAGDmD,EAAOwV,OtB3QG,GsB6QHxV,GAGDA,CACR,EAACJ,EAEDsB,gBAAA,SAAgBrE,GAAgB2R,IAAAA,EAC/BjQ,KAAA,OAAWA,KAAC4D,oBAAoBtF,EAAS,SAACqZ,GAAoB,OAC7DlL,EAAuBkL,EAAsB1H,EAAK3P,oBAAoB,EAExE,EAACe,EAEDyB,oBAAA,SAAoBxE,GAIf0B,KAAKiW,YAAc3X,EAAQ4E,KAC9BlD,KAAKiR,cAAcxB,uBAAuBzP,KAAK8Z,gBAC/C9Z,KAAK6Z,UAAW,EAChB7Z,KAAKiW,eAAYtU,EACjB3B,KAAK8Z,oBAAiBnY,EACtB3B,KAAKma,sBAAuB,EAE9B,EAAC9Y,EAEDE,kBAAA,SAAkBc,GACjBrC,KAAKsa,YAAc,IAAIxB,GAAoBzW,GAC3CrC,KAAKiR,cAAgB,IAAIvD,GAAsBrL,EAAQ,CACtDjC,SAAUJ,KAAKI,UAEjB,EAACwZ,CAAA,CAzfiClU,CAAQ9F,GCzE3B,SAAAqc,GAAmBlP,GAWlC,IAVAnM,EAASmM,EAATnM,UACAsb,EAAKnP,EAALmP,MAUMC,EATSpP,EAAf1M,gBASmC,EAC3BqI,EAASwT,EAATxT,EAAGC,EAAMuT,EAANvT,EAEX,MAAO,CACN3H,KAAM,UACNrC,WAAY,CAAE,EACdwE,SAAU,CACTnC,KAAM,UACNqC,YAAa,CACZ,CACCzC,EAAU8H,EAAIyT,EAAUxT,EAAIwT,GAC5Bvb,EAAU8H,EAAIyT,EAAUxT,EAAIwT,GAC5Bvb,EAAU8H,EAAIyT,EAAUxT,EAAIwT,GAC5Bvb,EAAU8H,EAAIyT,EAAUxT,EAAIwT,GAC5Bvb,EAAU8H,EAAIyT,EAAUxT,EAAIwT,IAC3BvN,IAAI,SAACwN,GAAC,MAAK,CAACA,EAAE5T,IAAK4T,EAAE3T,IAAI,KAI/B,CC9BA,IAAa4T,gBAAyB,SAAA1O,GACrC,SAAA0O,EAAYha,GACX,OAAAsL,EAAA1H,KAAM5D,KAAAA,IACPrC,IAAA,CASC,OATAqG,EAAAgW,EAAA1O,GAAA0O,EAAA/a,UAEMqS,OAAA,SAAO5R,GAEb,OAAOka,GAAoB,CAC1Brb,UAAWZ,KAAKY,UAChBsb,MAAO,CAAExT,EAH+B3G,EAAjCgZ,WAGKpS,EAH4B5G,EAAlBiZ,YAItB3a,gBAAiBL,KAAKK,iBAExB,EAACgc,CAAA,CAZoC,CAAQvP,GCEjCwP,gBAAsB,SAAA3O,GAClC,SAAA2O,EAAYja,GACX,OAAAsL,EAAA1H,KAAAjG,KAAMqC,IACPrC,IAAA,CAUC,OAVAqG,EAAAiW,EAAA3O,GAAA2O,EAAAhb,UACMib,QAAA,SAAQC,EAAiCC,GAC/C,IAAA3B,EAAiB9a,KAAKa,QAAQ4b,EAAiB,GAAIA,EAAiB,IAOpE,OALiB7D,GAChB,CAAElQ,EAHMoS,EAADpS,EAGFC,EAHMmS,EAADnS,GAIV,CAAED,EAAG8T,EAAWzB,WAAYpS,EAAG6T,EAAWxB,YAI5C,EAACsB,CAAA,CAbiC,CAAQxP,GCC9B4P,yBAA2B/O,GACvC,SAAA+O,EACUra,EACQsa,EACAC,GAA0C,IAAAjX,EAAA,OAE3DA,EAAAgI,EAAA1H,KAAM5D,KAAAA,IAAQsD,MAJLtD,YAAA,EAAAsD,EACQgX,qBAAAhX,EACAiX,sBAAAjX,EAAAA,EAMXkX,iCAAmC,SAAC9a,GAO1C,OANiB4D,EAAKmX,aAAa/a,EAAO,SAACzD,GAC1C,OAAOC,QACND,EAAQK,YAAcL,EAAQK,WAAWuC,OAASyE,EAAKzE,KAEzD,GAEgB6K,UACjB,EAACpG,EAEMoX,uBAAyB,SAC/Bhb,EACAib,GAUA,OARkBrX,EAAKmX,aAAa/a,EAAO,SAACzD,GAC3C,OAAOC,QACND,EAAQK,YACPL,EAAQK,WAAWuC,OAASyE,EAAKzE,MACjC5C,EAAQ4E,KAAO8Z,EAElB,GAEiBjR,UAClB,EA/BUpG,EAAMtD,OAANA,EACQsD,EAAagX,cAAbA,EACAhX,EAAgBiX,iBAAhBA,EAA0CjX,CAG5D,CAsEC,OAtEAU,EAAAqW,EAAA/O,GAAA+O,EAAApb,UA4BMwb,aAAA,SACN/a,EACAgO,OAAsCtB,EAAAzO,KAEhCid,EAAOjd,KAAK4c,iBAAiBjJ,OAAO5R,GAEpC4M,EAAW3O,KAAKS,MAAMyc,OAAOD,EAAMlN,GAEnCoN,EAKF,CACHjO,eAAWvN,EACXyb,4BAAwBzb,EACxBoK,gBAAYpK,EACZ0b,QAASnR,UAwBV,OArBAyC,EAAS2O,QAAQ,SAAChf,GACjB,IAAI+E,EACJ,GAA8B,YAA1B/E,EAAQ6E,SAASnC,KACpBqC,EAAc/E,EAAQ6E,SAASE,YAAY,WACP,eAA1B/E,EAAQ6E,SAASnC,KAG3B,OAFAqC,EAAc/E,EAAQ6E,SAASE,WAGhC,CAEAA,EAAYia,QAAQ,SAACrT,EAAOsT,GAC3B,IAAMC,EAAO/O,EAAKkO,cAAcJ,QAAQxa,EAAOkI,GAC3CuT,EAAOL,EAAQE,SAAWG,EAAO/O,EAAKpO,kBACzC8c,EAAQpR,WAAa9B,EACrBkT,EAAQE,QAAUG,EAClBL,EAAQjO,UAAY5Q,EAAQ4E,GAC5Bia,EAAQC,uBAAyBG,EAEnC,EACD,GAEOJ,CACR,EAACT,CAAA,EA7E8C5P,YCIhC7D,GACfC,EACAvB,EACAwB,GAEA,IAAMC,EAAa5B,EAAiB0B,EAAO,IACrCG,EAAY7B,EAAiB0B,EAAO,IACpCI,EAAa9B,EAAiB2B,GAC9BtB,EAAUH,EAAgBC,GAE1B4B,EAAY5C,KAAK6C,KACtB7C,KAAKQ,IAAIkC,GAAa1C,KAAKS,IAAIS,GAC9BlB,KAAKS,IAAIiC,GAAa1C,KAAKQ,IAAIU,GAAWlB,KAAKS,IAAIkC,IAWrD,MAAO,CAHK1B,EALXwB,EACAzC,KAAKU,MACJV,KAAKQ,IAAImC,GAAc3C,KAAKQ,IAAIU,GAAWlB,KAAKS,IAAIiC,GACpD1C,KAAKS,IAAIS,GAAWlB,KAAKQ,IAAIkC,GAAa1C,KAAKQ,IAAIoC,KAGzC3B,EAAiB2B,GAG9B,CAGgB,SAAAkU,GAAsB1Q,EAErCpF,EACAwB,GAAe,IAFbT,EAACqE,EAADrE,EAAGC,EAACoE,EAADpE,EAKCW,EAAa9B,EAAiB2B,GASpC,MAAO,CAAET,EAHIA,EAHEf,EAAWhB,KAAKS,IAAIkC,GAMjBX,EAFLA,EAHEhB,EAAWhB,KAAKQ,IAAImC,GAMpC,CC/CgB,SAAAH,GAAQsL,EAAiBiJ,GACxC,IAAMC,EAAOnW,EAAiBiN,EAAM,IAC9BmJ,EAAOpW,EAAiBkW,EAAI,IAC5BG,EAAOrW,EAAiBiN,EAAM,IAC9BqJ,EAAOtW,EAAiBkW,EAAI,IAC5BxW,EAAIP,KAAKQ,IAAIyW,EAAOD,GAAQhX,KAAKS,IAAI0W,GACrCC,EACLpX,KAAKS,IAAIyW,GAAQlX,KAAKQ,IAAI2W,GAC1BnX,KAAKQ,IAAI0W,GAAQlX,KAAKS,IAAI0W,GAAQnX,KAAKS,IAAIwW,EAAOD,GAEnD,OAAO/V,EAAiBjB,KAAKU,MAAMH,EAAG6W,GACvC,CAEgB,SAAAC,GAAkBjR,EAAAkB,GAC5B,IAGCgQ,EAFChQ,EAALvF,EADKqE,EAALrE,EAIIwV,EAHQjQ,EAALtF,EADKoE,EAALpE,EAMT,GAAe,IAAXsV,GAA2B,IAAXC,EACnB,SAID,IAAI3F,EAAQ5R,KAAKU,MAAM6W,EAAQD,GAY/B,OATA1F,GAAiB,IAAM5R,KAAKC,IAGhB,IACX2R,GAAS,IACCA,GAAS,MACnBA,GAAS,KAGHA,CACR,CAEgB,SAAA4F,GAAiBhV,GAChC,OAAQA,EAAU,KAAO,GAC1B,UCzCgBiV,GACf9E,EACA+E,EACAC,GAQA,IANA,IAKIC,EAAUC,EAAWC,EALnBzM,EAAoB,GAEpB0M,EAAmBpF,EAAOxT,OAE5B6Y,EAAY,EAEP9U,EAAI,EAAGA,EAAIyP,EAAOxT,UACtBuY,GAAaM,GAAa9U,IAAMyP,EAAOxT,OAAS,GADlB+D,IAAK,CAGhC,GAAI8U,EAAYN,GAA8B,IAAjBrM,EAAMlM,OAAc,CAEvD,KADAyY,EAAWF,EAAYM,GAGtB,OADA3M,EAAMjI,KAAKuP,EAAOzP,IACXmI,EAERwM,EAAYrV,GAAQmQ,EAAOzP,GAAIyP,EAAOzP,EAAI,IAAM,IAChD4U,EAAexV,GAAYqQ,EAAOzP,GAAI0U,EAAUC,GAChDxM,EAAMjI,KAAK0U,EACZ,CAEA,GAAIE,GAAaL,EAEhB,OADAC,EAAWD,EAAWK,IAKtBH,EAAYrV,GAAQmQ,EAAOzP,GAAIyP,EAAOzP,EAAI,IAAM,IAChD4U,EAAexV,GAAYqQ,EAAOzP,GAAI0U,EAAUC,GAChDxM,EAAMjI,KAAK0U,GACJzM,IANNA,EAAMjI,KAAKuP,EAAOzP,IACXmI,GAYT,GAJI2M,GAAaN,GAChBrM,EAAMjI,KAAKuP,EAAOzP,IAGfA,IAAMyP,EAAOxT,OAAS,EACzB,OAAOkM,EAGR2M,GAAarY,EAA4BgT,EAAOzP,GAAIyP,EAAOzP,EAAI,GAChE,CAEA,GAAI8U,EAAYN,GAAa/E,EAAOxT,SAAW4Y,EAC9C,MAAM,IAAIzc,MAAM,iCAGjB,IAAM2c,EAAOtF,EAAOA,EAAOxT,OAAS,GACpC,MAAO,CAAC8Y,EAAMA,EACf,CC5DA,SAASnY,GAAUgB,GAClB,OAAOA,GAAWd,KAAKC,GAAK,IAC7B,CAEA,SAASiY,GAAUhX,GAClB,OAAOA,GAAW,IAAMlB,KAAKC,GAC9B,CCDa,IAAAkY,gBAA0BnR,SAAAA,GACtC,SAAAmR,EAAqBzc,GAAsBsD,IAAAA,EAAA,OAC1CA,EAAAgI,EAAA1H,UAAM5D,IAAQsD,MADMtD,cAAAsD,EAAMtD,OAANA,EAAsBsD,CAE3C,CAACU,EAAAyY,EAAAnR,GAAA,IAAAtM,EAAAyd,EAAAxd,UAqEA,OArEAD,EAEM0d,6BAAA,SACNrS,EACAC,EACAqS,GAKA,IAHA,IAAMC,EAAO,CAACvS,EAAeC,GAEzBuS,EAAa,EACRrV,EAAI,EAAGA,EAAIoV,EAAKnZ,OAAS,EAAG+D,IACpCqV,GAAc5Y,EAA4B2Y,EAAK,GAAIA,EAAK,IAIzD,GAAIC,GAAcF,EACjB,OAAOC,EAGR,IAAIE,EAAmBD,EAAaF,EAAgB,EAG/CI,OAAOC,UAAUF,KACrBA,EAAmBxY,KAAK2Y,MAAMH,GAAoB,GAInD,IADA,IAAMvK,EAAyB,GACtB/K,EAAI,EAAGA,EAAIsV,EAAkBtV,IAAK,CAC1C,IAAM0V,EAAUnB,GACfa,EACAD,EAAgBnV,EAChBmV,GAAiBnV,EAAI,IAEtB+K,EAAS7K,KAAKwV,EACf,CAGA,IADA,IAAMlc,EAA0B,GACvBwG,EAAI,EAAGA,EAAI+K,EAAS9O,OAAQ+D,IAEpCxG,EAAY0G,KADC6K,EAAS/K,GACA,IAKvB,OAF2B7J,KAAKwf,iBAAiBnc,EAGlD,EAAChC,EAEMoe,qCAAA,SACN/S,EACAC,EACAqS,GAEA,IAAMrX,EAAWrB,EAA4BoG,EAAeC,GAEtDtJ,EDtDQ,SACfoR,EACAiJ,EACAgC,GAEA,IAAMC,EAAqB,GAErB9B,EAAOpX,GAAUgO,EAAM,IACvBkJ,EAAOlX,GAAUgO,EAAM,IACvBqJ,EAAOrX,GAAUiX,EAAI,IACrBE,EAAOnX,GAAUiX,EAAI,IAE3BgC,GAAkB,EAGlB,IAAME,EACL,EACAjZ,KAAK6C,KACJ7C,KAAKW,KACJX,KAAAuB,IAAAvB,KAAKQ,KAAK2W,EAAOD,GAAQ,GAAM,GAC9BlX,KAAKS,IAAIyW,GAAQlX,KAAKS,IAAI0W,GAAKnX,KAAAuB,IAAGvB,KAAKQ,KAAKyW,EAAOD,GAAQ,GAAM,KAIrE,GAAU,IAANiC,GAAW9gB,MAAM8gB,GAEpB,OAAOD,EAGR,IAAK,IAAI9V,EAAI,EAAGA,GAAK6V,EAAgB7V,IAAK,CACzC,IAAMgW,EAAIhW,EAAI6V,EACRI,EAAInZ,KAAKQ,KAAK,EAAI0Y,GAAKD,GAAKjZ,KAAKQ,IAAIyY,GACrCG,EAAIpZ,KAAKQ,IAAI0Y,EAAID,GAAKjZ,KAAKQ,IAAIyY,GAG/BlX,EACLoX,EAAInZ,KAAKS,IAAIyW,GAAQlX,KAAKS,IAAIuW,GAAQoC,EAAIpZ,KAAKS,IAAI0W,GAAQnX,KAAKS,IAAIwW,GAC/DjV,EACLmX,EAAInZ,KAAKS,IAAIyW,GAAQlX,KAAKQ,IAAIwW,GAAQoC,EAAIpZ,KAAKS,IAAI0W,GAAQnX,KAAKQ,IAAIyW,GAC/DoC,EAAIF,EAAInZ,KAAKQ,IAAI0W,GAAQkC,EAAIpZ,KAAKQ,IAAI2W,GAG5C,KAAIhf,MAAM4J,IAAM5J,MAAM6J,IAAM7J,MAAMkhB,IAAlC,CAKA,IAAMvX,EAAM9B,KAAKU,MAAM2Y,EAAGrZ,KAAKW,KAAKX,KAAAuB,IAAAQ,EAAK,GAAC/B,KAAAuB,IAAGS,EAAK,KAC5CsX,EAAMtZ,KAAKU,MAAMsB,EAAGD,GAEtB5J,MAAM2J,IAAQ3J,MAAMmhB,IAKxBN,EAAO5V,KAAK,CAAC8U,GAAUoB,GAAMpB,GAAUpW,IAVvC,CAWD,CAEA,OAAOkX,EAAO3N,MAAM,GAAI,EACzB,CCLsBkO,CACnBxT,EACAC,EAHsBhG,KAAK2Y,MAAM3X,EAAWqX,IAQ7C,OAF2Bhf,KAAKwf,iBAAiBnc,EAGlD,EAAChC,EAEOme,iBAAA,SAAiBnc,OAAuBoL,EAAAzO,KAC/C,OAAOqD,EAAYuL,IAAI,SAAC7C,GAAe,MAAA,CACtCjE,EAAeiE,EAAW,GAAI0C,EAAKpM,OAAO/B,qBAC1CwH,EAAeiE,EAAW,GAAI0C,EAAKpM,OAAO/B,qBAC1C,EACF,EAACwe,CAAA,CAxEqCnR,CAAQb,GCS/B,SAAAqT,GACf7hB,EACAgC,GAEA,GAA8B,eAA1BhC,EAAQ6E,SAASnC,KACpB,MAAO,CACNsC,OAAO,EACPC,OAfF,+BAmBA,GAAIjF,EAAQ6E,SAASE,YAAYyC,OAAS,EACzC,MAAO,CACNxC,OAAO,EACPC,OApBF,uCAwBA,IAAK,IAAIsG,EAAI,EAAGA,EAAIvL,EAAQ6E,SAASE,YAAYyC,OAAQ+D,IAAK,CAC7D,IAAKoC,EAAkB3N,EAAQ6E,SAASE,YAAYwG,IACnD,MAAO,CACNvG,OAAO,EACPC,OA1BH,mCA8BC,IACEuI,EACAxN,EAAQ6E,SAASE,YAAYwG,GAC7BvJ,GAGD,MAAO,CACNgD,OAAO,EACPC,OApCH,mDAuCA,CAEA,MAAO,CAAED,OAAO,EACjB,CCiCA,SAAS8c,GAAUC,GAClB,OAAO1Z,KAAKW,KAAKX,KAAKuB,IAAImY,EAAE,GAAI,GAAK1Z,KAAKuB,IAAImY,EAAE,GAAI,GAAK1Z,KAAKuB,IAAImY,EAAE,GAAI,GACzE,CAEA,SAAS9H,GAAM+H,EAAYC,GAC1B,IAAMC,EAlBP,SAAaF,EAAYC,GAGxB,OAFwBD,EAAE,GACFC,EAAZE,GADYH,EAAPI,GACOH,EAAPI,GADOL,EACxB,GAAwBC,EACxB,EACD,CAceK,CAAIN,EAAIC,IAAOH,GAAUE,GAAMF,GAAUG,IACvD,OAAO5Z,KAAKka,KAAKla,KAAK4T,IAAI5T,KAAK6T,IAAIgG,GAAQ,GAAI,GAChD,CAEA,SAASM,GAAe5Z,GACvB,IAAMuB,EAAMjB,EAAiBN,EAAE,IACzBsB,EAAMhB,EAAiBN,EAAE,IAC/B,MAAO,CACNP,KAAKS,IAAIqB,GAAO9B,KAAKS,IAAIoB,GACzB7B,KAAKS,IAAIqB,GAAO9B,KAAKQ,IAAIqB,GACzB7B,KAAKQ,IAAIsB,GAEX,CAEA,SAASsY,GAAeV,GACvB,IAAO3X,EAAW2X,EAAC,GAAT1X,EAAQ0X,EAAC,GACb5X,EAAMb,EAAiBjB,KAAK6C,KADhB6W,EAAC,KAInB,MAAO,CAFKzY,EAAiBjB,KAAKU,MAAMsB,EAAGD,IAE9BD,EACd,CCxGa,IAAAuY,gBAAqB,SAAArT,GACjC,SAAAqT,EACU3e,EACQsa,EACAC,OAA0CjX,EAAA,OAE3DA,EAAAgI,EAAA1H,KAAAjG,KAAMqC,IAAOrC,MAJJqC,YAAAsD,EAAAA,EACQgX,qBAAAhX,EACAiX,sBAAA,EAAAjX,EAMXkX,iCAAmC,SAAC9a,GAC1C,IAAMkf,EAAYtb,EAAKmX,aAAa/a,EAAO,SAACzD,GAC3C,OAAOC,QACND,EAAQK,YAAcL,EAAQK,WAAWuC,OAASyE,EAAKzE,KAEzD,GAEA,OAAO+f,EAAUlV,WACd,CACAjE,EACCmZ,EAAUlV,WAAW,GACrBpG,EAAKtD,OAAO/B,qBAEbwH,EACCmZ,EAAUlV,WAAW,GACrBpG,EAAKtD,OAAO/B,2BAGbqB,CACJ,EAACgE,EAEMoX,uBAAyB,SAC/Bhb,EACAib,GAEA,IAAMiE,EAAYtb,EAAKmX,aAAa/a,EAAO,SAACzD,GAC3C,OAAOC,QACND,EAAQK,YACPL,EAAQK,WAAWuC,OAASyE,EAAKzE,MACjC5C,EAAQ4E,KAAO8Z,EAElB,GAEA,OAAOiE,EAAUlV,WACd,CACAjE,EACCmZ,EAAUlV,WAAW,GACrBpG,EAAKtD,OAAO/B,qBAEbwH,EACCmZ,EAAUlV,WAAW,GACrBpG,EAAKtD,OAAO/B,2BAGbqB,CACJ,EArDUgE,EAAMtD,OAANA,EACQsD,EAAagX,cAAbA,EACAhX,EAAgBiX,iBAAhBA,EAA0CjX,CAG5D,CA0HCqb,OA1HA3a,EAAA2a,EAAArT,GAAAqT,EAAA1f,UAkDMwb,aAAA,SACN/a,EACAgO,GAAsC,IAAAtB,EAAAzO,KAEhCkhB,EAAclhB,KAAK4c,iBAAiBjJ,OAAO5R,GAC3C4M,EAAW3O,KAAKS,MAAMyc,OAAOgE,EAAanR,GAC1CoN,EAKF,CACHjO,eAAWvN,EACXyb,4BAAwBzb,EACxBoK,gBAAYpK,EACZoY,YAAa7N,UAwDd,OAtDAyC,EAAS2O,QAAQ,SAAChf,GACjB,IAAI+E,EACJ,GAA8B,YAA1B/E,EAAQ6E,SAASnC,KACpBqC,EAAc/E,EAAQ6E,SAASE,YAAY,OACrC,IAA8B,eAA1B/E,EAAQ6E,SAASnC,KAG3B,OAFAqC,EAAc/E,EAAQ6E,SAASE,WAGhC,CAIA,IAFA,IAMI8d,EANEC,EAAgC,GAE7BvX,EAAI,EAAGA,EAAIxG,EAAYyC,OAAS,EAAG+D,IAC3CuX,EAAMrX,KAAK,CAAC1G,EAAYwG,GAAIxG,EAAYwG,EAAI,KAW7C,IAAMwX,EAAmB,CAACtf,EAAMyG,IAAKzG,EAAM0G,KAQ3C,GAN+B,iBAA3BgG,EAAKpM,OAAO3B,WACfygB,EC9FY,SACfG,EACAF,GAYA,IAJA,IAIsBvP,EAiEtB0P,EACAC,EACAvJ,EAGMwJ,EAMAC,EAMAC,EAQAC,EA9FFC,EAAyB,CAAC3V,SAAUA,UACpC4V,EAAkB5V,SAClB6V,EAAY,EAEhBnP,EAAAC,EAAiBuO,KAAKvP,EAAAe,KAAAE,MAAE,CAAA,IAAfmM,EAAIpN,EAAAhN,MACNmd,EAA0B/C,EAAK,GAC/BgD,EAAyBhD,EAAK,GAGhCiD,OAA2B,EAC3BC,EAA4BjW,SAE1BuI,EAAQlM,EAAsByZ,EAAc,GAAIA,EAAc,IAC9DnM,EAAOtN,EAAsB0Z,EAAa,GAAIA,EAAa,IAC3DjK,EAASzP,EACd+Y,EAAgB,GAChBA,EAAgB,IAIjB,GACCU,EAAc,KAAOV,EAAgB,IACrCU,EAAc,KAAOV,EAAgB,GAErCY,EAAoBF,OACd,GACNC,EAAa,KAAOX,EAAgB,IACpCW,EAAa,KAAOX,EAAgB,GAEpCY,EAAoBD,MACd,CAEN,IAAAG,GAsDIT,GANAD,EAAe,CACpBhZ,GAVDuP,EAvCuDD,GAiD5CtP,GAZX6Y,EArC0C9M,GAiDpB/L,EACrBC,EAAGsP,EAAOtP,EAAI4Y,EAAO5Y,IAKRD,GAbR+Y,EAAa,CAClB/Y,GALD8Y,EAtCiD3L,GA2CtCnN,EAAI6Y,EAAO7Y,EACrBC,EAAG6Y,EAAO7Y,EAAI4Y,EAAO5Y,IAWOD,EAAIgZ,EAAa/Y,EAAI8Y,EAAW9Y,EAOvDiZ,EAAIjb,KAAK6T,IAAI,EAAG7T,KAAK4T,IAAI,EAAGoH,GAHjCF,EAAW/Y,EAAI+Y,EAAW/Y,EAAI+Y,EAAW9Y,EAAI8Y,EAAW9Y,KAMpC,CACpBD,EAAG6Y,EAAO7Y,EAAIkZ,EAAIH,EAAW/Y,EAC7BC,EAAG4Y,EAAO5Y,EAAIiZ,EAAIH,EAAW9Y,IAjE5B+P,EAAqB5P,EAFZsZ,EAAD1Z,EAAI0Z,EAADzZ,GAGXuZ,EAAoB,CADTxJ,EAAHlQ,IAAQkQ,EAAHjQ,IAEd,CAEIyZ,IACHC,EAAoBvJ,GACnBZ,EACAzP,EAAsB2Z,EAAkB,GAAIA,EAAkB,MAGvCJ,IACvBD,EAAeK,EACfJ,EAAkBK,EAClBJ,EAAYX,EAAMiB,QAAQpD,GAG7B,CAEA,OAA2B/S,WAApB4V,OACJngB,EACA,CACAoK,WAAY8V,EACZE,UAAWA,EACXpa,SAAUma,EAEd,CDyBcQ,CAA8BjB,EAAQD,GACX,UAA3B3S,EAAKpM,OAAO3B,aACtBygB,ED1GY,SACfG,EACAF,GAYA,IAJA,IAIsBvP,EAJlBgQ,EAAyB,CAAC3V,SAAUA,UACpC4V,EAAkB5V,SAClB6V,EAAY,EAEhBnP,EAAAC,EAAiBuO,KAAKvP,EAAAe,KAAAE,MAAE,CAAf,IAKJoP,EALIjD,EAAIpN,EAAAhN,MACNmd,EAA0B/C,EAAK,GAC/BgD,EAAyBhD,EAAK,GAIhCkD,EAA4BjW,UAO/BgW,EAHAF,EAAc,KAAOV,EAAgB,IACrCU,EAAc,KAAOV,EAAgB,GAEjBU,EAEpBC,EAAa,KAAOX,EAAgB,IACpCW,EAAa,KAAOX,EAAgB,GAEhBW,GA8EtBM,EA1EGP,EA2EHQ,EA1EGP,EA2EHQ,EA1EGnB,EAkFGxB,EAAIgB,GAAeyB,GACnBxC,EAAIe,GAAe0B,GACnBE,EAAI5B,GAAe2B,GAGlBE,EAAcD,EAAVE,GAAAA,EAAUF,EAANG,GAAAA,EAAMH,EAGrB,GAAAI,EAjDO,EAFKC,GADEzC,EAoDUR,GAnDE,KACTa,GAFSJ,EAoDCR,GAjD3B,KAFiBW,EAAOJ,EAAE,KACdG,EAAYF,EAAPI,IACcD,GADxBsC,EAAiBzC,EAAZE,KADLwC,EAAiB3C,EAAE,IAEuBK,EAAKsC,EAAMxC,EAAMsC,EAAMC,GAiDjEE,EAACJ,EAAEK,GAAAA,EAACL,EAAA,GAAEM,EAACN,EAAA,GACR5b,EAAIic,EAAIN,EAAKO,EAAIR,EACjB7E,EAAIqF,EAAIT,EAAKO,EAAIL,EACjBzG,EAAI8G,EAAIN,EAAKO,EAAIR,EAEjB9C,EAAIzD,EAAI+G,EAAIpF,EAAIqF,EAChBC,EAAInc,EAAIkc,EAAIhH,EAAI8G,EAChBI,EAAIvF,EAAImF,EAAIhc,EAAIic,EAEhBvB,EAAI,EAAIjb,KAAKW,KAAKX,KAAKuB,IAAI2X,EAAG,GAAKlZ,KAAKuB,IAAImb,EAAG,GAAK1c,KAAKuB,IAAIob,EAAG,IAGhEC,EAAa,CAAC1D,EAAI+B,EAAGyB,EAAIzB,EAAG0B,EAAI1B,GAChC4B,EAAa,EAAE,EAAI3D,EAAI+B,GAAI,EAAIyB,EAAIzB,GAAI,EAAI0B,EAAI1B,GAI/C6B,EAAUlL,GAAMuH,EAAGC,GACnB2D,EAAWnL,GAAMuH,EAAGyD,GACpBI,EAAWpL,GAAMwH,EAAGwD,GACpBK,EAAWrL,GAAMuH,EAAG0D,GACpBK,EAAWtL,GAAMwH,EAAGyD,GAkBtBjL,GAAMuH,EAVTgE,EAHCJ,EAAWE,GAAYF,EAAWG,GAClCF,EAAWC,GAAYD,EAAWE,EAE/BN,EAEAC,GAQaC,GAAWlL,GAAMwH,EAAG+D,GAAKL,EAEzCnd,EAA4Bya,GAAe+C,GAAI/C,GAAejB,KAC9DxZ,EAA4Bya,GAAe+C,GAAI/C,GAAehB,IAEvD,CAACgB,GAAejB,IAAI,GAAM,GAE1B,CAACiB,GAAehB,IAAI,GAAO,GAK7B,CAACgB,GAAe+C,IAAI,GAAO,IAhJd,MAQlB3B,EAAoB7b,EACnBgb,EACAY,IAGuBJ,IACvBD,EAAeK,EACfJ,EAAkBK,EAClBJ,EAAYX,EAAMiB,QAAQpD,GAG7B,CAuDD,IACCsD,EACAC,EACAC,EApCcnC,EAAYC,EACnB0C,EAAKF,EAAKrC,EACVsC,EAAKvC,EAAKE,EAyEbmD,EA/BEhE,EACAC,EACA2C,EAGCC,EAAIC,EAAIC,EAGfC,EAAOI,EAAGC,EAAGC,EACPlc,EACA6W,EACA3B,EAEAyD,EACAwD,EACAC,EAEA1B,EAGA2B,EACAC,EAIAC,EACAC,EACAC,EACAC,EACAC,EA7FN,OAA2B3X,WAApB4V,OACJngB,EACA,CAAEoK,WAAY8V,EAAcla,SAAUma,EAAiBC,UAAAA,EAC3D,CC+CcgC,CAAmB1C,EAAQD,IAGjCD,EAAL,CAIA,IAAMxZ,EAAW8G,EAAKkO,cAAcJ,QAAQxa,EAAOof,EAAQpV,YACvDpE,EAAWwV,EAAQpD,aAAepS,EAAW8G,EAAKpO,kBACrD8c,EAAQjO,UAAY5Q,EAAQ4E,GAC5Bia,EAAQpR,WAAa,CACpBjE,EACCqZ,EAAQpV,WAAW,GACnB0C,EAAKpM,OAAO/B,qBAEbwH,EACCqZ,EAAQpV,WAAW,GACnB0C,EAAKpM,OAAO/B,sBAGd6c,EAAQC,uBAAyB+D,EAAQY,UACzC5E,EAAQpD,YAAcpS,EAhBvB,CAkBD,GAEOwV,CACR,EAAC6D,CAAA,CAjIgC,CAAQlU,GER1B,SAAAkX,GACf1K,GAEA,OACC9a,MAAMC,QAAQ6a,IACdA,EAAOxT,OAAS,GAChBtH,MAAMC,QAAQ6a,EAAO,KACrB9a,MAAMC,QAAQ6a,EAAO,GAAG,GAE1B,CAEa,IAAA2K,GAAyB,SACrCC,GAOA,OALkBF,GAAeE,GAE7BA,EAAoC,GAAGlS,MAAM,GAAI,GACjDkS,CAGL,EAEaC,GAAuB,SACnCD,GAOA,OALkBF,GAAeE,GAE7BA,EAAoC,GACpCA,CAGL,ECrBaE,gBAAsBzW,SAAAA,GAClC,SAAAyW,EACU/hB,EACQsa,EACA0H,EACAC,OAAwC3e,EAAA,OAEzDA,EAAAgI,EAAA1H,KAAAjG,KAAMqC,UALGA,YAAA,EAAAsD,EACQgX,mBAAAhX,EAAAA,EACA0e,2BAAA,EAAA1e,EACA2e,2BAAA3e,EAKV4e,gBAA+B,GAR7B5e,EAAMtD,OAANA,EACQsD,EAAagX,cAAbA,EACAhX,EAAqB0e,sBAArBA,EACA1e,EAAmB2e,oBAAnBA,EAAwC3e,CAG1D,CAACU,EAAA+d,EAAAzW,GAAA,IAAAtM,EAAA+iB,EAAA9iB,UAuHA6D,OAvHA9D,EAUMsS,OAAA,SAAO6Q,GACb,GAAIxkB,KAAKykB,IAAI3e,OACZ,MAAM,IAAI7D,MAAM,8CAGjB,IAAM6P,EAAYkS,GAAeQ,GAC3BnhB,EAAc8gB,GAAqBK,GAEzC,GAAI1S,EAAW,CACd,GAAIzO,EAAYyC,QAAU,EACzB,UAAU7D,MAAM,mCAGjBjC,KAAKukB,gBAAkBvkB,KAAKqkB,sBAAsB9V,qBAAqB,CACtElL,YAAa,CAACA,EAAY,GAAIA,EAAYA,EAAYyC,OAAS,IAC/D9E,KAAMxD,EAAkBI,eAE1B,MACCoC,KAAKukB,gBAAkB,CACtBvkB,KAAKqkB,sBAAsBhW,oBAAoB,CAC9CtC,WAAY1I,EAAYA,EAAYyC,OAAS,GAC7C9E,KAAMxD,EAAkBI,gBAI5B,EAACyD,EAAA,OAEM,WACDrB,KAAKykB,IAAI3e,SAId9F,KAAKqkB,sBAAsB1U,wBAAwB3P,KAAKykB,KACxDzkB,KAAKukB,gBAAkB,GACxB,EAACljB,EAEMqjB,UAAA,SAAUvS,EAAewS,GAC/B3kB,KAAKqkB,sBAAsB3T,qBAAqB,CAC/C,CACCxB,UAAWlP,KAAKykB,IAAItS,GACpBpG,WAAY4Y,IAGf,EAACtjB,EAEMmP,OAAA,SAAOoU,GACb,IAAMvhB,EAAc8gB,GAAqBS,GAEjB,IAApB5kB,KAAKykB,IAAI3e,OAQkB,IAApB9F,KAAKykB,IAAI3e,QACnB9F,KAAKqkB,sBAAsB3T,qBAAqB,CAC/C,CACCxB,UAAWlP,KAAKykB,IAAI,GACpB1Y,WAAY1I,EAAY,IAEzB,CACC6L,UAAWlP,KAAKykB,IAAI,GACpB1Y,WAAY1I,EAAYA,EAAYyC,OAAS,MAf/C9F,KAAKqkB,sBAAsB3T,qBAAqB,CAC/C,CACCxB,UAAWlP,KAAKykB,IAAI,GACpB1Y,WAAY1I,EAAYA,EAAYyC,OAAS,KAgBjD,EAACzE,EAEMwjB,yBAAA,SAAyB9iB,GAC/B,GAAwB,IAApB/B,KAAKykB,IAAI3e,OACZ,MAAO,CAAEgf,WAAW,GAGrB,IAAMC,EAAU/kB,KAAKskB,oBAAoBpL,YAAYlZ,KAAKykB,IAAI,IAS9D,MAAO,CAAEK,UAPQ9kB,KAAK2c,cAAcJ,QACnCxa,EACAgjB,EAAQ1hB,aAGoBrD,KAAKK,gBAGnC,EAACgB,EAEM2jB,uBAAA,SAAuBjjB,GAC7B,GAAwB,IAApB/B,KAAKykB,IAAI3e,OACZ,MAAO,CAAEgf,WAAW,EAAOG,mBAAmB,GAG/C,IAAMC,EAAUllB,KAAKskB,oBAAoBpL,YAAYlZ,KAAKykB,IAAI,IACxDM,EAAU/kB,KAAKskB,oBAAoBpL,YAAYlZ,KAAKykB,IAAI,IAExD9c,EAAW3H,KAAK2c,cAAcJ,QACnCxa,EACAmjB,EAAQ7hB,aAGH8hB,EAAmBnlB,KAAK2c,cAAcJ,QAC3Cxa,EACAgjB,EAAQ1hB,aAMT,MAAO,CAAEyhB,UAHSnd,EAAW3H,KAAKK,gBAGd4kB,kBAFME,EAAmBnlB,KAAKK,gBAGnD,EAAC8E,EAAAif,IAAAhf,IAAA,MAAAC,IAnHD,WACC,OAAOrF,KAAKukB,gBAAgBpe,QAC7B,EAACb,IAED,SAAQC,QAhB0BoI,CAAQb,GCJ9BsY,gBAAwB,SAAAzX,GACpC,SAAAyX,EACC/iB,EACiBiY,EACArJ,GAAoC,IAAAtL,EAAA,OAErDA,EAAAgI,EAAA1H,KAAAjG,KAAMqC,IAAQsD,MAHG2U,iBAAA3U,EAAAA,EACAsL,mBADAtL,EAAAA,EAAW2U,YAAXA,EACA3U,EAAasL,cAAbA,EAAoCtL,CAGtD,CAACU,EAAA+e,EAAAzX,GAAAtM,IAAAA,EAAA+jB,EAAA9jB,UAuOA,OAvOAD,EAEMgkB,eAAA,SAActY,GAMpB,IAAA0B,EAAAzO,KALAkP,EAASnC,EAATmC,UACAgV,EAAkBnX,EAAlBmX,mBAMA,GAAKlkB,KAAKsa,YAAYd,WAAWtK,GAAjC,CAKA,IAAM7L,EAAc4gB,GAAuBC,GAErC5S,EAAqBtR,KAAKsa,YAAYf,cAAcrK,GAEpDoW,EACLhU,EAAmBiU,mBAGpB,GAAKD,EAUJA,GAAAA,GACAA,EAA2BE,MAAM,SAACtiB,GAAE,OAAKuL,EAAK6L,YAAYd,WAAWtW,EAAG,GACvE,CAED,IAAMuiB,EACLnU,EAAmBiU,mBACdG,EAA2BD,EAAoB7W,IACpD,SAAC1L,GAAE,OAAKuL,EAAK6L,YAAYpB,YAAYhW,GAAIG,WAAuB,GAKjE,GAAIoiB,EAAoB3f,SAAWzC,EAAYyC,OAAQ,CACtD9F,KAAK2lB,uBAAuBF,GAC5B,IAAMF,EAAqBvlB,KAAK4lB,aAC/BviB,EACAiO,EAAmBpQ,KACnBgO,GAEDlP,KAAK6lB,2BAA2B3W,EAAWqW,EAC5C,KAAO,CACN,IAAM3R,EAGA,GAENvQ,EAAYia,QAAQ,SAACvR,EAAYlC,GAG/BkC,EAAW,KAAO2Z,EAAyB7b,GAAG,IAC9CkC,EAAW,KAAO2Z,EAAyB7b,GAAG,IAK/C+J,EAAQ7J,KAAK,CACZmF,UAAWuW,EAAoB5b,GAC/BkC,WAAYA,GAEd,GAEA/L,KAAKiR,cAAcP,qBAAqBkD,EACzC,CACD,KAEK,CAEJ,IAAMkS,EAAiBR,EAA2BvV,OAAO,SAAC7M,GAAE,OAC3DuL,EAAK6L,YAAYd,WAAWtW,EAAG,GAE5B4iB,EAAehgB,QAClB9F,KAAK2lB,uBAAuBG,GAI7B,IAAMP,EAAqBvlB,KAAK4lB,aAC/BviB,EACAiO,EAAmBpQ,KACnBgO,GAEDlP,KAAK6lB,2BAA2B3W,EAAWqW,EAC5C,KAvEiC,CAChC,IAAMA,EAAqBvlB,KAAK4lB,aAC/BviB,EACAiO,EAAmBpQ,KACnBgO,GAEDlP,KAAK6lB,2BAA2B3W,EAAWqW,EAC5C,CAjBA,MAFCvlB,KAAK+lB,qBAAqB7W,EAoF5B,EAAC7N,EAEM2kB,yBAAA,SAAyBrX,GAC/B,IAAA,IAAgCkD,EAAhCe,EAAAC,EAAwBlE,KAAQkD,EAAAe,KAAAE,MAC/B9S,KAAKimB,gBADcpU,EAAAhN,MAGrB,EAACxD,EAEM6kB,iBAAA,SACNhX,EACAiD,EACAwS,GAEA,IACMY,EADoBvlB,KAAKsa,YAAYf,cAAcrK,GAEtCqW,mBAGjBA,GAC6B,IAA9BA,EAAmBzf,aACWnE,IAA9B4jB,EAAmBpT,IAKpBnS,KAAKiR,cAAcP,qBAAqB,CACvC,CACCxB,UAAWqW,EAAmBpT,GAC9BpG,WAAY4Y,IAGf,EAACtjB,EAEM8kB,iBAAA,SAAgBlY,GAMtB,IAJAiW,EAAkBjW,EAAlBiW,mBAKMkC,EAAoBpmB,KAAKsa,YAAYf,cANlCtL,EAATiB,WAQA,GAAKkX,EAAkBb,mBAAvB,CAIA,IAAMliB,EAAc4gB,GAAuBC,GAIvC7gB,EAAYyC,SAFfsgB,EAAkBb,mBAE2Bzf,QAI9C9F,KAAKiR,cAAcP,qBACjB0V,EAAkBb,mBAAmC3W,IAAI,SAAC1L,EAAI2G,GAAC,MAAM,CACrEqF,UAAWhM,EACX6I,WAAY1I,EAAYwG,GACxB,GAdF,CAgBD,EAACxI,EAEOukB,aAAA,SACP1B,EACAhjB,EACAgO,GAEA,OAAOlP,KAAKiR,cAAc1C,qBAAqB,CAC9ClL,YAAa6gB,EACbljB,KAAMxD,EAAkBM,iBACxB4Q,qBAAsB,SAAC7E,GAACsE,IAAAA,EAAAA,OAAAA,EACvBjN,CAAAA,KAAAA,IACC1D,EAAkBM,mBAAmB,EAAIqQ,EACzC3Q,EAAkBO,6BAA8BmR,EAASf,EAC1DgE,MAAOtI,EAACsE,CAAA,GAGX,EAAC9M,EAEOwkB,2BAAA,SACP3W,EACArK,EACAnB,GAE0C4M,IAAAA,OAF1C5M,IAAAA,IAAAA,EAEwB3G,EAAY0T,QAEpC,IAAMzP,EAAOhB,KAAKsa,YAAYvB,gBAAgB7J,GAExCsB,EAAS,CACdtB,UAAAA,EACAE,mBAAiBkB,EAAAA,CAAAA,EAAAA,EACf9S,EAAkBQ,sBAAuB6G,EAAKyL,GAEhDvM,QAAS,CACRL,WAAAA,IAIF,GAAa,YAAT1C,EACHhB,KAAKiR,cAAc5B,cAAcmB,OAC3B,IAAa,eAATxP,EAGV,MAAM,IAAIiB,MAAM,mDAFhBjC,KAAKiR,cAAc1B,iBAAiBiB,EAGrC,CACD,EAACnP,EAEOskB,uBAAA,SAAuBJ,GAI9BvlB,KAAKiR,cAActB,wBAAwB4V,EAC5C,EAAClkB,EAEO4kB,gBAAA,SAAgB/W,GACvB,GAAKlP,KAAKsa,YAAYd,WAAWtK,GAAjC,CAIA,IACMmX,EADuBrmB,KAAKsa,YAAYf,cAAcrK,GAEtCqW,mBAElBc,IACHrmB,KAAK2lB,uBAAuBU,GAC5BrmB,KAAK6lB,2BAA2B3W,EAAW,MAR5C,CAUD,EAAC7N,EAEO0kB,qBAAA,SAAqB7W,GAC5B,IAAMoX,EAA6BtmB,KAAKsa,YAAYb,sBACnD,SAAC9a,GAAU,OACVA,EAAWnB,EAAkBO,+BAAiCmR,CAAS,GAGzElP,KAAKiR,cAActB,wBAAwB2W,EAC5C,EAAClB,CAAA,CA9OmC,CAAQtY,GCMhCyZ,gBAMZ,WAAA,SAAAA,EAAY1mB,GAAiC8F,IAAAA,YALrC6gB,YAAmD,GAAExmB,KACrDymB,YAAmD,GACnDC,KAAAA,qCACAC,kBAAY,EAGnB3mB,KAAK0mB,yBAA2B,SAACrjB,GAAW,OAC3CsC,EAAKihB,iBAAiBvjB,EAA2B,EAElD,IAAMwjB,EAAyBhnB,MAAAA,OAAAA,EAAAA,EAAS8mB,aAOvC3mB,KAAK2mB,kBALsBhlB,IAA3BklB,GACCzH,OAAO0H,SAASD,GAIGlgB,KAAK6T,IAAI,EAAG7T,KAAK2Y,MAAMuH,IAFvBzH,OAAO2H,iBAI7B,CAAC,IAAA1lB,EAAAklB,EAAAjlB,iBAAAD,EAED2lB,gBAAA,SAAgBL,GACVvH,OAAO0H,SAASH,IAKrB3mB,KAAK2mB,aAAehgB,KAAK6T,IAAI,EAAG7T,KAAK2Y,MAAMqH,IAC3C3mB,KAAKinB,iBAAiBjnB,KAAKwmB,aAC3BxmB,KAAKinB,iBAAiBjnB,KAAKymB,cAN1BzmB,KAAK2mB,aAAevH,OAAO2H,iBAO7B,EAAC1lB,EAEO4lB,iBAAA,SAAiBC,GACxB,GAAK9H,OAAO0H,SAAS9mB,KAAK2mB,cAI1B,KAAOO,EAAQphB,OAAS9F,KAAK2mB,cAC5BO,EAAQC,OAEV,EAAC9lB,EAEO+lB,cAAA,SAAcC,GACK,IAAtBrnB,KAAK2mB,eAIT3mB,KAAKwmB,YAAYzc,KAAKsd,GACtBrnB,KAAKinB,iBAAiBjnB,KAAKwmB,aAC5B,EAACnlB,EAEOimB,cAAA,SAAcD,GACK,IAAtBrnB,KAAK2mB,eAIT3mB,KAAKymB,YAAY1c,KAAKsd,GACtBrnB,KAAKinB,iBAAiBjnB,KAAKymB,aAC5B,EAACplB,EAEOulB,iBAAA,SAAiB/hB,GAAc4J,IAAAA,OACtC,OAAIjQ,MAAMC,QAAQoG,GACVA,EAAM+J,IAAI,SAAC2Y,GAAe,OAAA9Y,EAAKmY,iBAAiBW,EAAW,GAGrD,OAAV1iB,GAAmC,iBAAVA,EAC5BzD,EAAA,CAAA,EAAYyD,GAGNA,CACR,EAACxD,EAEMmmB,iBAAA,SAAiBnkB,GACvB,OAAOrD,KAAK0mB,yBAAyBrjB,EACtC,EAAChC,EAEOomB,WAAA,SACPJ,GAEA,MAAO,CACNnD,mBAAoBlkB,KAAKwnB,iBAAiBH,EAAMnD,oBAChDwD,kBAAmBL,EAAMK,kBAE3B,EAACrmB,EAEDsmB,MAAA,WACC3nB,KAAKwmB,YAAc,GACnBxmB,KAAKymB,YAAc,EACpB,EAACplB,EAEDiD,SAAA,WACC,OAAWtE,KAACwmB,YAAY1gB,MACzB,EAACzE,EAEDkD,SAAA,WACC,OAAWvE,KAACymB,YAAY3gB,MACzB,EAACzE,EAEDumB,eAAA,SAAeP,GACdrnB,KAAKonB,cAAcpnB,KAAKynB,WAAWJ,IACnCrnB,KAAKymB,YAAc,EACpB,EAACplB,EAEDwmB,UAAA,WACC,IAAMC,EAAc9nB,KAAKwmB,YAAYuB,MAErC,GAAKD,EAAL,CAIA,IAAME,EAAoBhoB,KAAKynB,WAAWK,GAC1C9nB,KAAKsnB,cAAcU,GAEnB,IAAMC,EAAgBjoB,KAAKwmB,YAAYxmB,KAAKwmB,YAAY1gB,OAAS,GAEjE,MAAO,CACNgiB,YAAaE,EACbC,cAAeA,EAAgBjoB,KAAKynB,WAAWQ,QAAiBtmB,EATjE,CAWD,EAACN,EAED6mB,SAAA,WACC,IAAMC,EAAcnoB,KAAKymB,YAAYsB,MAErC,GAAKI,EAIL,OAAOnoB,KAAKynB,WAAWU,EACxB,EAAC9mB,EAED+mB,WAAA,SAAWf,GACVrnB,KAAKonB,cAAcpnB,KAAKynB,WAAWJ,GACpC,EAACd,CAAA,CA/HD,GCgCKlS,GAAmB,CAAEC,OAAQ,SAAUC,OAAQ,SAkC/CC,GAAiB,CACtBC,MAAO,YACPW,MAAO,UACPiT,UAAW,WACXC,QAAS,aAoBGC,gBAAwB,SAAA7iB,GAoCpC,SAAA6iB,EAAY1oB,GAA2D8F,IAAAA,EAE1C,OAD5BA,EAAAD,EAAAO,UAAMpG,GAAS,IAAKG,MApCrBkB,KAAO,aAAYyE,EAEX+hB,kBAAoB,EAAC/hB,EACrBsQ,eAAS,EAAAtQ,EACTmP,UAA8CT,GAAgB1O,EAC9D6iB,cAAQ,EAAA7iB,EACRoP,QAA6BP,GAAc7O,EAC3C8iB,WAAY,EAAK9iB,EACjB+iB,uBAAiB,EAAA/iB,EACjBgjB,gCAAwBhjB,EACxBijB,oBAAc,EAAAjjB,EACdkjB,0BAAkBljB,EAClBmjB,sBAAuB,EAAKnjB,EAC5BojB,2BAAqBpjB,EAAAA,EAGrBqjB,UAAoB,EAAKrjB,EACzBsjB,qBAAetjB,EAAAA,EACfujB,kCAA4B,EAAAvjB,EAC5BwjB,sBAAcxjB,EACdyjB,uBAAiB,EAAAzjB,EACjB0jB,qBAAa1jB,EAGb2jB,wBAAkB3jB,EAAAA,EAClB4jB,mBAAW5jB,EACX6jB,kBAAY7jB,EAAAA,EACZgX,mBAAa,EAAAhX,EACbiX,sBAAgBjX,EAAAA,EAChBsL,mBAAa,EAAAtL,EACb2U,mBAAW3U,EACX8jB,mBAAa9jB,EAAAA,EACb0gB,sBAAgB,EAAA1gB,EAChB+jB,cAIP/jB,EAAAA,EAAKxE,cAActB,GAAS8F,CAC7B,CAACU,EAAAkiB,EAAA7iB,OAAArE,EAAAknB,EAAAjnB,UA8uCAinB,OA9uCAlnB,EAEDF,cAAA,SACCtB,GAEC4O,IAAAA,OAkCD,GAhCA/I,EAAApE,UAAMH,cAAa8E,KAAAjG,KAACH,QAGgB8B,WAAnC9B,SAAAA,EAASkpB,wBACT3J,OAAOC,UAAUxf,EAAQkpB,wBACzBlpB,EAAQkpB,sBAAwB,IAEhC/oB,KAAK+oB,sBAAwBpiB,KAAK2Y,MAAMzf,EAAQkpB,wBAG7ClpB,MAAAA,GAAAA,EAASkV,UACZ/U,KAAK+U,QAAO3T,EAAQ,CAAA,EAAApB,KAAK+U,QAAYlV,EAAQkV,gBAG1ClV,GAAAA,EAAS2oB,WACZxoB,KAAKwoB,SAAW3oB,EAAQ2oB,UAGE,QAAvB3oB,MAAAA,OAAAA,EAAAA,EAASiV,WACZ9U,KAAK8U,UAAY,CAAER,OAAQ,KAAMC,OAAQ,MACxB,MAAP1U,GAAAA,EAASiV,YACnB9U,KAAK8U,UAAS1T,EAAA,CAAA,EAAQpB,KAAK8U,UAAcjV,EAAQiV,kBAG9CjV,GAAAA,EAAS6oB,oBACZ1oB,KAAK0oB,kBAAoB7oB,EAAQ6oB,mBAG9B7oB,GAAWA,EAAQmpB,WACtBhpB,KAAKgpB,SAAWnpB,EAAQmpB,eAGarnB,KAA3B,MAAP9B,OAAO,EAAPA,EAASipB,sBAIZ,GAHA9oB,KAAK8oB,qBAAuBjpB,EAAQipB,qBAGhC9oB,KAAKqmB,mBAAqD,IAAjCxmB,EAAQipB,qBACnB9oB,KAAKS,MAAMkZ,aAC3B,SAAChb,GAAU,OAAKA,EAAWuC,OAASuN,EAAKvN,IAAI,GAErCoc,QAAQ,SAAChf,GACjBmQ,EAAK4X,iBAAiBhB,eAAe,CACpCnW,UAAW5Q,EAAQ4E,GACnBghB,mBAAoB5lB,EAAQ6E,SAASE,aAEvC,QACU,GAAArD,KAAKqmB,mBAAkD,IAA9BrmB,KAAK8oB,qBAAgC,CACxE,IAAMa,EAA0B3pB,KAAKS,MAAMkZ,aAC1C,SAAChb,GAAU,IAAAirB,EACV,OAAAjrB,EAAWuC,OAASuN,EAAKvN,MACzB3C,QAKE,OALKqrB,EAELjrB,EACCnB,EAAkBQ,4BAEnB,EAHA4rB,EAGE9jB,OACH,GAGH9F,KAAKqmB,iBAAiBL,yBACrB2D,EAAwB/a,IAAI,SAACiR,GAAM,OAAAA,EAAE3c,EAAe,GAEtD,CAEF,EAAC7B,EAEOwoB,qBAAA,SAAqB1mB,GAC5B,QAAKnD,KAAK+oB,uBAKuBpiB,KAAK6T,IACrC,EACArX,EAASE,YAAYyC,OAAS,IAEI9F,KAAK+oB,qBACzC,EAAC1nB,EAEOyoB,wBAAA,SAAwB/nB,GAC/B,IAAMgoB,EAAoB/pB,KAAKgqB,eAAejoB,GAwB9C,OAtBIgoB,GACC/pB,KAAK4oB,eACR5oB,KAAKiR,cAAcP,qBAAqB,CACvC,CACCxB,UAAWlP,KAAK4oB,eAChB7c,WAAYge,KAId/pB,KAAK4oB,eAAiB5oB,KAAKiR,cAAc5C,oBAAoB,CAC5DtC,WAAYge,EACZ/oB,KAAMxD,EAAkBK,iBAI1BkE,EAAMyG,IAAMuhB,EAAkB,GAC9BhoB,EAAM0G,IAAMshB,EAAkB,IACpB/pB,KAAK4oB,iBACf5oB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,GAGhBooB,CACR,EAAC1oB,EAEO+T,MAAA,WAAK,IAAA9E,EACZ,QAAuB3O,IAAnB3B,KAAKiW,UAAT,CAIA,IAAMgU,EAAUjqB,KAAKiR,cAAc1B,iBAAiB,CACnDL,UAAWlP,KAAKiW,UAChBlS,QAAS,CAAEL,WAAY3G,EAAY8Q,OAAQ0H,OAAQvY,GACnDmS,oBAAqB,CACpB,CACCnO,KAAMyM,GACN0E,OAAQ,IAGV/C,mBAAiBkB,EAAA,CAAA,EAAAA,EACf9S,EAAkBE,wBAAoBiE,EAAS2O,KAIlD,GAAK2Z,EAAL,CAIIjqB,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWlP,KAAKiW,UAChBiO,mBAAoB+F,EAAQ9mB,SAASE,cAIvC,IAAM6L,EAAYlP,KAAKiW,UAEvBjW,KAAK0nB,kBAAoB,EACzB1nB,KAAKiW,eAAYtU,EACjB3B,KAAK2oB,8BAA2BhnB,EAChC3B,KAAK0pB,SAAS/B,QAGK,YAAf3nB,KAAKsV,OACRtV,KAAKkC,aAGNlC,KAAKypB,cAAoB,SAErBzpB,KAAK4oB,iBACR5oB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,GAGnB3B,KAAKqpB,gBACRrpB,KAAKiR,cAAcxB,uBAAuBzP,KAAKqpB,eAC/CrpB,KAAKqpB,mBAAgB1nB,EAGrB3B,KAAKipB,qBAAkBtnB,EACvB3B,KAAKkpB,kCAA+BvnB,EACpC3B,KAAKopB,uBAAoBznB,EACzB3B,KAAKmpB,oBAAiBxnB,GAGvB3B,KAAK0C,SAASwM,EAAW,CAAEhO,KAAMlB,KAAKkB,KAAMqU,OAAQvY,GAvCpD,CAlBA,CA0DD,EAACqE,EAEO6oB,0BAAA,SAA0BC,EAAsBC,GACvD,IAAKpqB,KAAK0oB,oBAAsB1oB,KAAK2oB,yBACpC,MAAM,IAAI1mB,MAAM,kCAIjB,GAAwC,WAApCjC,KAAK0oB,kBAAkB2B,SAC1B,MAAM,IAAIpoB,MAAM,2BAGjB,IACMqoB,EADWhkB,EAA4B6jB,EAAYC,IACrBpqB,KAAK0oB,kBAAkB7jB,MAAQ,GAC/D0lB,EAAkC,GAiBtC,MAfwB,UAApBvqB,KAAKU,WACR6pB,EACCvqB,KAAKupB,YAAY9J,qCAChB0K,EACAC,EACAE,GAE4B,iBAApBtqB,KAAKU,aACf6pB,EAAsBvqB,KAAKupB,YAAYxK,6BACtCoL,EACAC,EACAE,IAIKC,CACR,EAAClpB,EAEOmpB,WAAA,SAAWC,OAAuBta,EACnCuF,EAAU1V,KAAKiR,cAAcjD,iBAAiB,CACnD3K,YAAa,CACZonB,EACAA,GAED9rB,YAAUwR,EAAA,CACTjP,KAAMlB,KAAKkB,MAAIiP,EACd3S,EAAkBE,oBAAoB,EAAIyS,KAI7CnQ,KAAK2oB,yBAA2BjT,EAAQvS,SAASE,YACjDrD,KAAKiW,UAAYP,EAAQxS,GACzBlD,KAAK0nB,oBACL1nB,KAAK0qB,oBAAoB1qB,KAAKiW,UAAWjW,KAAK0nB,mBAC9C1nB,KAAKgC,aAEDhC,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWlP,KAAKiW,UAChBiO,mBAAoBxO,EAAQvS,SAASE,aAGxC,EAAChC,EAEOspB,kBAAA,SAAkBC,GACzB,GAAK5qB,KAAKiW,UAAV,CAMAjW,KAAKc,UAAUd,KAAK+U,QAAQK,OAE5B,IAAM6U,EAAUjqB,KAAKiR,cAAc1B,iBAAiB,CACnDL,UAAWlP,KAAKiW,UAChBlS,QAAS,CAAEL,WAAY3G,EAAY0T,QACnCtB,oBAAqB,CACpB,CACCnO,KAAMyM,EACN0E,OAAQ,EACRpG,WAAY6e,MAKVX,IAILjqB,KAAKypB,cAAc9V,OAAOsW,EAAQ9mB,SAASE,aAEvCrD,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWlP,KAAKiW,UAChBiO,mBAAoB+F,EAAQ9mB,SAASE,cAIvCrD,KAAK2oB,yBAA2BsB,EAAQ9mB,SAASE,YACjDrD,KAAK0nB,oBACL1nB,KAAK0qB,oBAAoB1qB,KAAKiW,UAAWjW,KAAK0nB,mBAE1C1nB,KAAK6pB,qBAAqBI,EAAQ9mB,WACrCnD,KAAKoV,QApCN,CAsCD,EAAC/T,EAEOwpB,aAAA,SAAa9oB,EAA4B6oB,GAChD,GAAK5qB,KAAKiW,UAOV,GAHsBjW,KAAKypB,cAAc5E,yBAAyB9iB,GAA1D+iB,UAIP9kB,KAAKoV,YADN,CAOApV,KAAKc,UAAUd,KAAK+U,QAAQK,OAE5B,IAAM6U,EAAUjqB,KAAKiR,cAAc1B,iBAAiB,CACnDL,UAAWlP,KAAKiW,UAChBlS,QAAS,CAAEL,WAAY3G,EAAY0T,QACnCtB,oBAAqB,CACpB,CAAEnO,KAAMyM,EAAuB0E,OAAQ,EAAGpG,WAAY6e,MAInDX,IAILjqB,KAAKypB,cAAcjZ,OAAOyZ,EAAQ9mB,SAASE,aAEvCrD,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWlP,KAAKiW,UAChBiO,mBAAoB+F,EAAQ9mB,SAASE,cAIvCrD,KAAK2oB,yBAA2BsB,EAAQ9mB,SAASE,YAEjDrD,KAAK0nB,oBACL1nB,KAAK0qB,oBAAoB1qB,KAAKiW,UAAWjW,KAAK0nB,mBAE1C1nB,KAAK6pB,qBAAqBI,EAAQ9mB,WACrCnD,KAAKoV,QAjCN,CAmCD,EAAC/T,EAEDiD,SAAA,WACC,OAAWtE,KAAC0pB,SAASplB,UACtB,EAACjD,EAEDgD,aAAA,WACCrE,KAAK0pB,SAAS/B,OACf,EAACtmB,EAEOqpB,oBAAA,SAAoBxb,EAAsBwY,GACjD,IAAMoD,EAAkB9qB,KAAKsa,YAAYpB,YAAwBhK,GAEjElP,KAAK0pB,SAAS9B,eAAe,CAC5B1D,mBAAoB4G,EAAgBznB,YACpCqkB,kBAAAA,GAEF,EAACrmB,EAEO0pB,4CAAA,WACF/qB,KAAKwoB,UAAaxoB,KAAK6oB,mBAQ5B7oB,KAAK8pB,wBAAwB9pB,KAAK6oB,oBAP7B7oB,KAAK4oB,iBACR5oB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,EAMzB,EAACN,EAEO2pB,kBAAA,SAAkB9G,GACrBlkB,KAAK0nB,mBAAqB,EACzB1nB,KAAKypB,cAAchF,IAAI3e,OAC1B9F,KAAKypB,cAAcjZ,OAAO0T,GAE1BlkB,KAAKypB,cAAc9V,OAAOuQ,GAG3BlkB,KAAKypB,cAAa,QAEpB,EAACpoB,EAEM+C,KAAA,WAAI,IAAA6mB,EACV,GAAmB,YAAfjrB,KAAKsV,OAAwBtV,KAAKiW,UAAtC,CAIA,IAAMiV,EAAiBlrB,KAAK0pB,SAAS7B,YAErC,GAAKqD,EAAL,CAIA,IAAuBC,EAAyBD,EAAxCjD,cAER,IAAKkD,EAAsB,CAC1B,IAAMC,EAAmBprB,KAAKiW,UAiB9B,OAfAjW,KAAKiW,eAAYtU,EACjB3B,KAAK0nB,kBAAoB,EACzB1nB,KAAK2oB,8BAA2BhnB,EAChC3B,KAAKypB,cAAa,SAEC,YAAfzpB,KAAKsV,OACRtV,KAAKkC,aAGFlC,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBL,yBAAyB,CAACoF,IAGjDprB,KAAKiR,cAAcxB,uBAAuB2b,QAC1CprB,KAAK+qB,6CAEN,CAEA,IAAMd,EAAUjqB,KAAKiR,cAAc1B,iBAAiB,CACnDL,UAAWlP,KAAKiW,UAChB9G,oBAAqB,CACpBnO,KAAMyM,GACNpK,YAAa8nB,EAAqBjH,oBAEnC9U,mBAAiB6b,EAAAA,CAAAA,EAAAA,EACfztB,EAAkBE,oBAAoB,EAAIutB,GAE5ClnB,QAAS,CAAEL,WAAY3G,EAAY0T,UAG/BwZ,IAILjqB,KAAK0nB,kBAAoByD,EAAqBzD,kBAC9C1nB,KAAK2oB,yBAA2BsB,EAAQ9mB,SAASE,YACjDrD,KAAKgrB,kBAAkBf,EAAQ9mB,SAASE,aAEpCrD,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWlP,KAAKiW,UAChBiO,mBAAoB+F,EAAQ9mB,SAASE,cAIvCrD,KAAK+qB,8CApDL,CANA,CA2DD,EAAC1pB,EAEMkD,SAAA,WACN,YAAYmlB,SAASnlB,UACtB,EAAClD,EAEMmD,KAAA,WACN,IAAM6mB,EAAqBrrB,KAAK0pB,SAASxB,WAEzC,GAAKmD,EAAL,CAIA,GAAKrrB,KAAKiW,UAyBH,CAAAqV,IAAAA,EACArB,EAAUjqB,KAAKiR,cAAc1B,iBAAiB,CACnDL,UAAWlP,KAAKiW,UAChB9G,oBAAqB,CACpBnO,KAAMyM,GACNpK,YAAagoB,EAAmBnH,oBAEjC9U,mBAAiBkc,EAAAA,CAAAA,EAAAA,EACf9tB,EAAkBE,oBAAoB,EAAI4tB,GAE5CvnB,QAAS,CAAEL,WAAY3G,EAAY0T,UAGpC,IAAKwZ,EACJ,OAGDjqB,KAAK0nB,kBAAoB2D,EAAmB3D,kBAC5C1nB,KAAK2oB,yBAA2BsB,EAAQ9mB,SAASE,YACjDrD,KAAKgrB,kBAAkBf,EAAQ9mB,SAASE,aAEpCrD,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWlP,KAAKiW,UAChBiO,mBAAoB+F,EAAQ9mB,SAASE,aAGxC,KApDqB,CAAAkoB,IAAAA,EACpB9Q,EAAyBza,KAAKiR,cAAcjD,iBAAiB,CAC5D3K,YAAagoB,EAAmBnH,mBAChCvlB,YAAU4sB,GACTrqB,KAAMlB,KAAKkB,MAAIqqB,EACd/tB,EAAkBE,oBAAoB,EAAI6tB,KAJrCroB,EAAEuX,EAAFvX,GAAIC,EAAQsX,EAARtX,SAQZnD,KAAKiW,UAAY/S,EACjBlD,KAAK0nB,kBAAoB2D,EAAmB3D,kBAC5C1nB,KAAK2oB,yBAA2BxlB,EAASE,YAEtB,YAAfrD,KAAKsV,OACRtV,KAAKgC,aAGNhC,KAAKgrB,kBAAkB7nB,EAASE,aAE5BrD,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWhM,EACXghB,mBAAoB/gB,EAASE,aAGhC,CA6BArD,KAAK0pB,SAAStB,WAAWiD,GAEzBrrB,KAAK+qB,6CA1DL,CA2DD,EAAC1pB,EAGDE,kBAAA,SAAkBc,GACjBrC,KAAKupB,YAAc,IAAIzK,GAA0Bzc,GACjDrC,KAAK4c,iBAAmB,IAAIP,GAAyBha,GACrDrC,KAAK2c,cAAgB,IAAIL,GAAsBja,GAC/CrC,KAAKwpB,aAAe,IAAIxI,GACvB3e,EACArC,KAAK2c,cACL3c,KAAK4c,kBAEN5c,KAAKspB,mBAAqB,IAAI5M,GAC7Bra,EACArC,KAAK2c,cACL3c,KAAK4c,kBAEN5c,KAAKsa,YAAc,IAAIxB,GAAoBzW,GAC3CrC,KAAKiR,cAAgB,IAAIvD,GAAsBrL,EAAQ,CACtDjC,SAAUJ,KAAKI,WAEhBJ,KAAKypB,cAAgB,IAAIrF,GACxB/hB,EACArC,KAAK2c,cACL3c,KAAKiR,cACLjR,KAAKsa,aAENta,KAAKqmB,iBAAmB,IAAIjB,GAC3B/iB,EACArC,KAAKsa,YACLta,KAAKiR,eAGNjR,KAAK0pB,SAAW,IAAInD,GAA6B,CAChDI,aAActkB,EAAO9B,sBAEvB,EAACc,EAGDoT,MAAA,WACCzU,KAAKkC,aACLlC,KAAKc,UAAUd,KAAK+U,QAAQN,MAC7B,EAACpT,EAGDwU,KAAA,WACC7V,KAAK8V,UACL9V,KAAKmC,aACLnC,KAAKc,UAAU,QAChB,EAACO,EAGDoD,YAAA,SAAY1C,GACX/B,KAAKyoB,WAAY,EACjBzoB,KAAKc,UAAUd,KAAK+U,QAAQN,OAC5BzU,KAAK6oB,mBAAqB9mB,EAE1B,IAEM6oB,EAFoB5qB,KAAK8pB,wBAAwB/nB,IAIpD,CAACA,EAAMyG,IAAKzG,EAAM0G,KAErB,QAAuB9G,IAAnB3B,KAAKiW,WAAsD,IAA3BjW,KAAK0nB,kBAAzC,CAIsB1nB,KAAKypB,cAAc5E,yBAAyB9iB,GAA1D+iB,WAIP9kB,KAAKc,UAAUd,KAAK+U,QAAQK,OAI7B,IAAIjG,EAE6B,CAChC,CACCnO,KAAMyM,GACN0E,OAAQ,EACRpG,WAAY6e,IAId,GAAI5qB,KAAK0oB,kBAAmB,CAC3B,IAAMA,EAAoB1oB,KAAKwrB,qBAAqBZ,GAEhDlC,IACHvZ,EAAsB,CACrBnO,KAAMyM,GACNpK,YAAaqlB,GAGhB,CAEA,IAAMuB,EAAUjqB,KAAKiR,cAAc1B,iBAAiB,CACnDJ,oBAAAA,EACAD,UAAWlP,KAAKiW,UAChBlS,QAAS,CAAEL,WAAY3G,EAAY4G,eAIhCsmB,GAAWjqB,KAAK8oB,sBACnB9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWlP,KAAKiW,UAChBiO,mBAAoB+F,EAAQ9mB,SAASE,aAzCvC,CA4CD,EAAChC,EAEOmqB,qBAAA,SAAqBpB,GAC5B,GAAKpqB,KAAK2oB,yBAAV,CAIA,IACMwB,EAAanqB,KAAK2oB,yBADV3oB,KAAK2oB,yBAAyB7iB,OAAS,GAGrD,IAAI+S,GAAqBsR,EAAYC,GAArC,CAIA,IAAMG,EAAsBvqB,KAAKkqB,0BAChCC,EACAC,GAGKqB,EAAmBzrB,KAAK2oB,yBAAyB3W,MAAM,GAAI,GAEjE,SAAA7L,OAAWslB,EAAqBlB,EAAqBH,CAAAA,GATrD,CAPA,CAiBD,EAAC/oB,EAEOqqB,aAAA,SAAa3pB,GAA0B,IAAA8N,EAC9C7P,KAAA,GAAKA,KAAKgpB,UAA2B,YAAfhpB,KAAKsV,MAA3B,CAIA,IAAAqW,EACC3rB,KAAKspB,mBAAmBxM,aAAa/a,EAAO,SAACzD,UAC5CuR,EAAK+b,iBAAiBttB,EAAQ,GAFxB4Q,EAASyc,EAATzc,UAAmC2c,EAAeF,EAAvCvO,uBAKnB,GAAKlO,QAAiCvN,IAApBkqB,EAAlB,CAIA,IAAM1oB,EAAWnD,KAAKsa,YAAYpB,YAAYhK,GAG9C,GAAsB,eAAlB/L,EAASnC,QACEmC,EAASE,YAGPyC,QAAU,GAA1B,CAOD,IAAMmkB,EAAUjqB,KAAKiR,cAAc1B,iBAAiB,CACnDL,UAAAA,EACAC,oBAAqB,CAAC,CAAEnO,KAAMyM,GAAkB0E,MAAO0Z,IACvD9nB,QAAS,CAAEL,WAAY3G,EAAY8Q,OAAQ0H,OAAQvY,KAGhDitB,GAAWjqB,KAAK8oB,sBACnB9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAAA,EACAgV,mBAAoB+F,EAAQ9mB,SAASE,cAInCrD,KAAK4oB,iBACR5oB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,GAGnB3B,KAAKqpB,gBACRrpB,KAAKiR,cAAcxB,uBAAuBzP,KAAKqpB,eAC/CrpB,KAAKqpB,mBAAgB1nB,EAGrB3B,KAAKipB,qBAAkBtnB,EACvB3B,KAAKkpB,kCAA+BvnB,EACpC3B,KAAKopB,uBAAoBznB,EACzB3B,KAAKmpB,oBAAiBxnB,GAGvB3B,KAAKypB,cAAoB,SAEzBzpB,KAAK0C,SAASwM,EAAW,CACxBhO,KAAMlB,KAAKkB,KACXqU,OAAQvY,GAtCR,CAXD,CATA,CA4DD,EAACqE,EAEOyqB,YAAA,SAAY/pB,GAEf/B,KAAK4oB,iBACR5oB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,GAGvB,IACMgjB,EADoB3kB,KAAKgqB,eAAejoB,IAG3C,CAACA,EAAMyG,IAAKzG,EAAM0G,KAEU,IAA3BzI,KAAK0nB,kBACR1nB,KAAKwqB,WAAW7F,GACqB,IAA3B3kB,KAAK0nB,mBAA2B1nB,KAAKiW,UAC/CjW,KAAK2qB,kBAAkBhG,GACb3kB,KAAKiW,WACfjW,KAAK6qB,aAAa9oB,EAAO4iB,EAE3B,EAACtjB,EAGDqD,QAAA,SAAQ3C,QAEaJ,IAAnB3B,KAAKiW,WACJjW,KAAKsa,YAAYd,WAAWxZ,KAAKiW,YAElCjW,KAAK8V,WAIa,UAAjB/T,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcZ,WAAYyC,IACrC,SAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcV,UAAWuC,IACrDA,EAAMiU,eACNhW,KAAK6B,kBAAkB7B,KAAKE,cAAcX,YAAawC,MAMpD/B,KAAK0nB,kBAAoB,IAAM1nB,KAAKyoB,WACvCzoB,KAAKyE,YAAY1C,GAElB/B,KAAKyoB,WAAY,EAEI,UAAjB1mB,EAAMgU,OACT/V,KAAK0rB,aAAa3pB,GACS,SAAjBA,EAAMgU,QAChB/V,KAAK8rB,YAAY/pB,GAGpB,EAACV,EAGD6C,UAAA,WAAS,EAER7C,EAGD8C,QAAA,SAAQpC,GACHA,EAAMqD,MAAQpF,KAAK8U,UAAUR,QAChCtU,KAAK8V,UAGF/T,EAAMqD,MAAQpF,KAAK8U,UAAUP,QAChCvU,KAAKoV,OAEP,EAAC/T,EAGD5B,YAAA,SACCsC,EACA4C,OAA8CsL,EAAAjQ,KAE9C,GAAKA,KAAK6B,kBAAkB7B,KAAKE,cAAcT,YAAasC,IAIvD/B,KAAKgpB,SAAV,CAIA,IAAIe,OAA0CpoB,EAE9C,GAAmB,YAAf3B,KAAKsV,MAAqB,CAC7B,IAAMyW,EAAc/rB,KAAKwpB,aAAa1M,aAAa/a,EAAO,SAACzD,GAC1D,OAAA2R,EAAK2b,iBAAiBttB,EAAQ,GAG3BytB,EAAYhgB,aACf/L,KAAKmpB,eAAiB,OACtBnpB,KAAKkpB,6BAA+B6C,EAAY3O,uBAChDpd,KAAKipB,gBAAkB8C,EAAY7c,UACnC6a,EAAoBgC,EAAYhgB,YAGjC,IAAMigB,EAAoBhsB,KAAKspB,mBAAmBxM,aACjD/a,EACA,SAACzD,GAAY,OAAA2R,EAAK2b,iBAAiBttB,EAAQ,GAGxC0tB,EAAkBjgB,aACrB/L,KAAKmpB,eAAiB,aACtBnpB,KAAKkpB,6BACJ8C,EAAkB5O,uBACnBpd,KAAKipB,gBAAkB+C,EAAkB9c,UACzC6a,EAAoBiC,EAAkBjgB,WAExC,CAIK/L,KAAKipB,iBAAoBc,IAKzB/pB,KAAKqpB,gBACTrpB,KAAKqpB,cAAgBrpB,KAAKiR,cAAc5C,oBAAoB,CAC3DtC,WAAYge,EACZ/oB,KAAMxD,EAAkBG,UAK1BqC,KAAKc,UAAUd,KAAK+U,QAAQsT,WAE5B1jB,GAAmB,GA/CnB,CAgDD,EAACtD,EAGD3B,OAAA,SACCqC,EACA4C,GAA8C,IAAAsnB,EAE9C,GAAKjsB,KAAK6B,kBAAkB7B,KAAKE,cAAcR,OAAQqC,SAK7BJ,IAAzB3B,KAAKipB,sBACiCtnB,IAAtC3B,KAAKkpB,6BAFN,CAQA,GACyB,eAAxBlpB,KAAKmpB,gBACoB,SAAxBnpB,KAAKmpB,qBAAwDxnB,IAA3B3B,KAAKopB,kBACvC,CACD,IAAMa,EAAUjqB,KAAKiR,cAAc1B,iBAAiB,CACnDL,UAAWlP,KAAKipB,gBAChBllB,QAAS,CAAEL,WAAY3G,EAAY4G,aACnCwL,oBAAqB,CACpB,CACCnO,KAAMyM,GACN0E,MAAOnS,KAAKkpB,6BACZnd,WAAY,CAAChK,EAAMyG,IAAKzG,EAAM0G,SAKjC,IAAKwhB,EACJ,OAGGjqB,KAAK8oB,4BAEuBnnB,IAA3B3B,KAAKopB,kBACRppB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWlP,KAAKipB,gBAChB/E,mBAAoB+F,EAAQ9mB,SAASE,cAKtCrD,KAAKqmB,iBAAiBH,iBACrBlmB,KAAKipB,gBACLjpB,KAAKkpB,6BACL,CAACnnB,EAAMyG,IAAKzG,EAAM0G,MAItB,MAAO,GACkB,SAAxBzI,KAAKmpB,qBACsBxnB,IAA3B3B,KAAKopB,kBACJ,CAEDppB,KAAKopB,kBAAoBppB,KAAKkpB,6BAA+B,EAE7D,IAAMgD,EAAWlsB,KAAKiR,cAAc1B,iBAAiB,CACpDL,UAAWlP,KAAKipB,gBAChBllB,QAAS,CAAEL,WAAY3G,EAAY4G,eAGpC,IAAKuoB,EACJ,OAGGlsB,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWlP,KAAKipB,gBAChB/E,mBAAoBgI,EAAS/oB,SAASE,cAMxCrD,KAAKkpB,8BACN,CAEIlpB,KAAKwoB,UAAYxoB,KAAK4oB,iBACzB5oB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,GAGnB3B,KAAKqpB,eACRrpB,KAAKiR,cAAcP,qBAAqB,CACvC,CACCxB,UAAWlP,KAAKqpB,cAChBtd,WAAY,CAAChK,EAAMyG,IAAKzG,EAAM0G,QAKjCzI,KAAKiR,cAAc1B,iBAAiB,CACnCL,UAAWlP,KAAKipB,gBAChBllB,QAAS,CAAEL,WAAY3G,EAAY4G,aACnCyL,mBAAiB6c,KAAAA,EAAKzuB,EAAkBG,SAAS,EAAIsuB,IArFtD,CAuFD,EAAC5qB,EAGD1B,UAAA,SACCoC,EACA4C,OAA8CwnB,EAE9C,GAAKnsB,KAAK6B,kBAAkB7B,KAAKE,cAAcP,UAAWoC,SAI7BJ,IAAzB3B,KAAKipB,kBAITjpB,KAAKc,UAAUd,KAAK+U,QAAQuT,SAEZtoB,KAAKiR,cAAc1B,iBAAiB,CACnDL,UAAWlP,KAAKipB,gBAChB7Z,mBAAiB+c,EAAAA,CAAAA,EAAAA,EAAK3uB,EAAkBG,SAAS,EAAKwuB,GACtDpoB,QAAS,CAAEL,WAAY3G,EAAY8Q,OAAQ0H,OAAQvY,MAGpD,CAIA,IAAMkS,EAAYlP,KAAKipB,gBAEvBtkB,GAAmB,GAEf3E,KAAK4oB,iBACR5oB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,GAGnB3B,KAAKqpB,gBACRrpB,KAAKiR,cAAcxB,uBAAuBzP,KAAKqpB,eAC/CrpB,KAAKqpB,mBAAgB1nB,EAGrB3B,KAAKipB,qBAAkBtnB,EACvB3B,KAAKkpB,kCAA+BvnB,EACpC3B,KAAKopB,uBAAoBznB,EACzB3B,KAAKmpB,oBAAiBxnB,GAGvB3B,KAAKypB,cAAoB,SAEzBzpB,KAAK0C,SAASwM,EAAW,CAAEhO,KAAMlB,KAAKkB,KAAMqU,OAAQvY,GAxBpD,CAyBD,EAACqE,EAGDyU,QAAA,WACC,IAAMG,EAAYjW,KAAKiW,UACjB2S,EAAiB5oB,KAAK4oB,eAE5B5oB,KAAK4oB,oBAAiBjnB,EACtB3B,KAAKiW,eAAYtU,EACjB3B,KAAK0nB,kBAAoB,EACzB1nB,KAAK2oB,8BAA2BhnB,EAChC3B,KAAK0pB,SAAS/B,QACK,YAAf3nB,KAAKsV,OACRtV,KAAKkC,aAGF+T,GAAajW,KAAK8oB,sBACrB9oB,KAAKqmB,iBAAiBL,yBAAyB,CAAC/P,IAGjDjW,KAAKiR,cAAcxB,uBAAuBwG,GAC1CjW,KAAKiR,cAAcxB,uBAAuBmZ,GAC1C5oB,KAAKypB,cAAoB,QAC1B,EAACpoB,EAGD6U,aAAA,SAAa5X,GACZ,IAAMmD,EAAML,EAAA,CAAA,EvBjoCN,CACN+U,iBAAkB,UAClBC,oBAAqB,UACrBC,oBAAqB,EACrBC,sBAAuB,EACvBC,mBAAoB,GACpBC,WAAY,UACZC,aAAc,EACdC,kBAAmB,UACnBC,oBAAqB,EACrBC,kBAAmB,EACnBC,WAAY,EACZC,gBAAiB,UACjBC,gBAAiB,EACjBC,kBAAmB,EACnBC,OAAQ,EACRC,eAAWvV,EACXwV,kBAAcxV,EACdyV,iBAAazV,EACb0V,oBAAgB1V,IuBgnChB,GACkB,YAAjBrD,EAAQ0C,MACkB,eAA1B1C,EAAQ6E,SAASnC,MACjB1C,EAAQK,WAAWuC,OAASlB,KAAKkB,KAwBjC,OAtBAO,EAAO4V,eAAiBrX,KAAKyB,OAAO4V,eAEpC5V,EAAOqV,gBAAkB9W,KAAK4E,wBAC7B5E,KAAKyB,OAAOqV,gBACZrV,EAAOqV,gBACPxY,GAGDmD,EAAOuV,kBAAoBhX,KAAKgF,uBAC/BhF,KAAKyB,OAAOuV,uBACiBrV,IAA7BF,EAAOuV,kBAAkC,EAAIvV,EAAOuV,kBACpD1Y,GAGDmD,EAAOsV,gBAAkB/W,KAAKgF,uBAC7BhF,KAAKyB,OAAOsV,gBACZtV,EAAOsV,gBACPzY,GAGDmD,EAAOwV,OAAS7Y,EAETqD,EAEPnD,GAAiB,YAAjBA,EAAQ0C,MACkB,UAA1B1C,EAAQ6E,SAASnC,MACjB1C,EAAQK,WAAWuC,OAASlB,KAAKkB,KAChC,CACD,IAGMkrB,EACL9tB,EAAQK,WAAWnB,EAAkBM,kBAEhCuuB,EANe/tB,EAAQK,WAAWnB,EAAkBI,eAOvD,eALFU,EAAQK,WAAWnB,EAAkBK,gBAOlC,gBACAuuB,EACC,uBACAzqB,EAEL,IAAK0qB,EACJ,OAAO5qB,EAGR,IAAM6qB,EAAW,CAChBC,aAAc,CACbC,MAAOxsB,KAAKyB,OAAOka,kBACnB8Q,MAAOzsB,KAAKyB,OAAOma,kBACnB8Q,QAAS1sB,KAAKyB,OAAOoa,oBACrBtE,aAAcvX,KAAKyB,OAAOqa,yBAC1BtE,aAAcxX,KAAKyB,OAAOsa,yBAC1BtE,eAAgBzX,KAAKyB,OAAOua,4BAE7B2Q,cAAe,CACdH,MAAOxsB,KAAKyB,OAAOmrB,mBACnBH,MAAOzsB,KAAKyB,OAAOorB,mBACnBH,QAAS1sB,KAAKyB,OAAOqrB,qBACrBvV,aAAcvX,KAAKyB,OAAOsrB,0BAC1BvV,aAAcxX,KAAKyB,OAAOurB,0BAC1BvV,eAAgBzX,KAAKyB,OAAOwrB,6BAE7Bb,gBAAiB,CAChBI,MAAOxsB,KAAKyB,OAAOyrB,qBACnBT,MAAOzsB,KAAKyB,OAAO0rB,qBACnBT,QAAS1sB,KAAKyB,OAAO2rB,uBACrB7V,aAAcvX,KAAKyB,OAAO4rB,4BAC1B7V,aAAcxX,KAAKyB,OAAO6rB,4BAC1B7V,eAAgBzX,KAAKyB,OAAO8rB,gCA8C9B,OA1CA9rB,EAAOoV,WAAa7W,KAAKgF,uBACxBsnB,EAASD,GAAWG,MACpB/qB,EAAOoV,WACPvY,GAGDmD,EAAOgV,aAAezW,KAAKgF,uBAC1BsnB,EAASD,GAAWK,QACpB,EACApuB,GAGDmD,EAAO+U,WAAaxW,KAAK4E,wBACxB0nB,EAASD,GAAWI,MACpBhrB,EAAO+U,WACPlY,GAGDmD,EAAOiV,kBAAoB1W,KAAK4E,wBAC/B0nB,EAASD,GAAW9U,aACpB,UACAjZ,GAGDmD,EAAOmV,kBAAoB5W,KAAKgF,uBAC/BsnB,EAASD,GAAW7U,aACpB,EACAlZ,GAGDmD,EAAOkV,oBAAsB3W,KAAKgF,uBACjCsnB,EAASD,GAAW5U,eACpB,EACAnZ,GAIAmD,EAAOwV,OADJmV,ExCj+BK,GAGC,GwCo+BH3qB,CACR,CAEA,OAAOA,CACR,EAACJ,EAEDsB,gBAAA,SAAgBrE,GAAgBkvB,IAAAA,OAC/B,OAAOxtB,KAAK4D,oBAAoBtF,EAAS,SAACqZ,GACzC,OAAAwI,GAA0BxI,EAAsB6V,EAAKltB,oBAAoB,EAE3E,EAACe,EAEOuqB,iBAAA,SAAiBttB,GACxB,OAAOC,QACoB,eAA1BD,EAAQ6E,SAASnC,MAChB1C,EAAQK,YACRL,EAAQK,WAAWuC,OAASlB,KAAKkB,KAEpC,EAACG,EAEO2oB,eAAA,SAAejoB,OAA0B0rB,EAAAC,EAAAC,EAC5C5D,EAGC6D,EAgBAA,EApB2CC,EAAA7tB,KAoChD,GAjCiB,OAAjBytB,EAAIztB,KAAKwoB,WAALiF,EAAeK,SAGjBF,EADG5tB,KAAKiW,UACEjW,KAAKwpB,aAAazM,uBAC3Bhb,EACA/B,KAAKiW,WAGIjW,KAAKwpB,aAAa3M,iCAAiC9a,MAI7DgoB,EAAoB6D,GAIlBF,OAAJA,EAAI1tB,KAAKwoB,WAALkF,EAAeK,eAGjBH,EADG5tB,KAAKiW,UACEjW,KAAKspB,mBAAmBvM,uBACjChb,EACA/B,KAAKiW,WAILjW,KAAKspB,mBAAmBzM,iCAAiC9a,MAI1DgoB,EAAoB6D,GAIlBD,OAAJA,EAAI3tB,KAAKwoB,WAALmF,EAAeK,SAAU,CAC5B,IAAMJ,EAAU5tB,KAAKwoB,SAASwF,SAASjsB,EAAO,CAC7C2lB,kBAAmB1nB,KAAK0nB,kBACxBzR,UAAWjW,KAAKiW,UAChBgY,2BAA4BjuB,KAAKiW,UAC9B,WAAA,OACA4X,EAAKvT,YAAYpB,YAChB2U,EAAK5X,UACL,EACD,WAAM,OAAA,IAAI,EACbpV,QAASb,KAAKa,QACdD,UAAWZ,KAAKY,YAGbgtB,IACH7D,EAAoB6D,EAEtB,CAEA,OAAO7D,CACR,EAAC1oB,EAEDyB,oBAAA,SAAoBxE,GAKf0B,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAW5Q,EAAQ4E,GACnBghB,mBAAoB5lB,EAAQ6E,SAASE,cAOnCrD,KAAKipB,kBAAoB3qB,EAAQ4E,IAAMlD,KAAKqpB,gBAC/CrpB,KAAKiR,cAAcxB,uBAAuBzP,KAAKqpB,eAC/CrpB,KAAKqpB,mBAAgB1nB,EACrB3B,KAAKipB,qBAAkBtnB,EACvB3B,KAAKkpB,kCAA+BvnB,EACpC3B,KAAKmpB,oBAAiBxnB,GAInB3B,KAAK4oB,gBAAkB5oB,KAAK6oB,oBAC/B7oB,KAAK8pB,wBACJ9pB,KAAK6oB,oBAOH7oB,KAAKiW,YAAc3X,EAAQ4E,KAC9BlD,KAAKypB,cAAoB,SAEzBzpB,KAAK0nB,kBAAoB,EACzB1nB,KAAKiW,eAAYtU,EACjB3B,KAAK2oB,8BAA2BhnB,EAChC3B,KAAK0pB,SAAS/B,QAGK,YAAf3nB,KAAKsV,OACRtV,KAAKkC,aAGR,EAACb,EAEDwB,kBAAA,SAAkBvE,GACb0B,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAW5Q,EAAQ4E,GACnBghB,mBAAoB5lB,EAAQ6E,SAASE,aAGxC,EAACklB,CAAA,CArxCmC,CAAQ3oB,GCpEvCyU,GAAmB,CAAEC,OAAQ,SAAUC,OAAQ,SA8B/CC,GAAiB,CACtBC,MAAO,YACPW,MAAO,WAWK8Y,gBAAsBxoB,SAAAA,GAmBlC,SAAAwoB,EAAYruB,GAAuD8F,IAAAA,EAEtC,OAD5BA,EAAAD,EAAAO,KAAMpG,KAAAA,GAAS,UAnBhBqB,KAAO,WAAUyE,EAET+hB,kBAAoB,EAAC/hB,EACrBsQ,eAAS,EAAAtQ,EACTmP,UAA4CT,GAAgB1O,EAC5DoP,QAA6BP,GAAc7O,EAC3C8iB,WAAY,EAAK9iB,EACjB6iB,cAAQ,EAAA7iB,EACRijB,oBAAcjjB,EAAAA,EAEdsL,mBAAa,EAAAtL,EACb2U,iBAAW3U,EAAAA,EACXgX,mBAAa,EAAAhX,EACb8jB,mBAAa9jB,EAAAA,EACbiX,wBAAgBjX,EAChB6jB,kBAAY,EAAA7jB,EACZ2jB,wBAIP3jB,EAAAA,EAAKxE,cAActB,GAAS8F,CAC7B,CAACU,EAAA6nB,EAAAxoB,GAAArE,IAAAA,EAAA6sB,EAAA5sB,UA6iBA4sB,OA7iBA7sB,EAEQF,cAAA,SACRtB,GAEA6F,EAAApE,UAAMH,cAAa8E,KAACpG,KAAAA,GAEhBA,MAAAA,GAAAA,EAASkV,UACZ/U,KAAK+U,QAAO3T,EAAA,CAAA,EAAQpB,KAAK+U,QAAYlV,EAAQkV,UAGnC,MAAPlV,GAAAA,EAAS2oB,WACZxoB,KAAKwoB,SAAW3oB,EAAQ2oB,UAGE,QAAhB,MAAP3oB,OAAO,EAAPA,EAASiV,WACZ9U,KAAK8U,UAAY,CAAER,OAAQ,KAAMC,OAAQ,MACxB,MAAP1U,GAAAA,EAASiV,YACnB9U,KAAK8U,UAAS1T,EAAA,GAAQpB,KAAK8U,UAAcjV,EAAQiV,WAEnD,EAACzT,EAGDE,kBAAA,SAAkBc,GACjBrC,KAAK4c,iBAAmB,IAAIP,GAAyBha,GACrDrC,KAAK2c,cAAgB,IAAIL,GAAsBja,GAC/CrC,KAAKwpB,aAAe,IAAIxI,GACvB3e,EACArC,KAAK2c,cACL3c,KAAK4c,kBAEN5c,KAAKspB,mBAAqB,IAAI5M,GAC7Bra,EACArC,KAAK2c,cACL3c,KAAK4c,kBAEN5c,KAAKsa,YAAc,IAAIxB,GAAoBzW,GAC3CrC,KAAKiR,cAAgB,IAAIvD,GAAsBrL,EAAQ,CACtDjC,SAAUJ,KAAKI,WAEhBJ,KAAKypB,cAAgB,IAAIrF,GACxB/hB,EACArC,KAAK2c,cACL3c,KAAKiR,cACLjR,KAAKsa,YAEP,EAACjZ,EAGDoT,MAAA,WACCzU,KAAKkC,aACLlC,KAAKc,UAAUd,KAAK+U,QAAQN,MAC7B,EAACpT,EAGDwU,KAAA,WACC7V,KAAK8V,UACL9V,KAAKmC,aACLnC,KAAKc,UAAU,QAChB,EAACO,EAEO8sB,WAAA,WAAU7d,IAAAA,EACjB,GAAKtQ,KAAKiW,WAIMjW,KAAKiR,cAAc1B,iBAAiB,CACnDL,UAAWlP,KAAKiW,UAChBlS,QAAS,CAAEL,WAAY3G,EAAY8Q,OAAQ0H,OAAQvY,GACnDmS,oBAAqB,CAAC,CAAEnO,KAAMyM,GAAkB0E,OAAQ,IACxD/C,mBAAiBkB,EAAAA,GAAAA,EACf9S,EAAkBE,wBAAoBiE,EAAS2O,KAIlD,CAIA,IAAMpB,EAAYlP,KAAKiW,UACvBjW,KAAK0nB,kBAAoB,EACzB1nB,KAAKiW,eAAYtU,EACjB3B,KAAKypB,cAAoB,SACzBzpB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,EAEH,YAAf3B,KAAKsV,OACRtV,KAAKkC,aAGNlC,KAAK0C,SAASwM,EAAW,CAAEhO,KAAMlB,KAAKkB,KAAMqU,OAAQvY,GAbpD,CAcD,EAACqE,EAEO+sB,yBAAA,SAAyBC,GAChC,OAA+B,IAA3BA,EAAgBvoB,OACZ,CAACuoB,GAGF,CAAAloB,GAAAA,OAAKkoB,GAAiBA,EAAgB,KAC9C,EAAChtB,EAEOitB,eAAA,WACP,GAAKtuB,KAAKiW,UAAV,CAIA,IACMsY,EADWvuB,KAAKsa,YAAYpB,YAAwBlZ,KAAKiW,WACpC5S,YAAY2O,MAAM,GAAI,GAEjD,KAAIuc,EAAUzoB,OAAS,GAAvB,CAIA,IAAM0oB,EAAoBxuB,KAAKiW,UACzBwY,EAAiBtoB,GAAAA,OAAOooB,GAAWA,EAAU,KAE7C7Y,EAAU1V,KAAKiR,cAAc/C,cAAc,CAChD7K,YAAaorB,EACb9vB,WAAY,CACXuC,KAAMlB,KAAKkB,MAEZ6C,QAAS,CACRL,WAAY3G,EAAY8Q,OACxB0H,OAAQvY,KAIL0Y,IAIL1V,KAAKiR,cAAcxB,uBAAuB+e,GAE1CxuB,KAAK0nB,kBAAoB,EACzB1nB,KAAKiW,eAAYtU,EACjB3B,KAAKypB,cAAoB,SACzBzpB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,EAEH,YAAf3B,KAAKsV,OACRtV,KAAKkC,aAGNlC,KAAK0C,SAASgT,EAAQxS,GAAiB,CACtChC,KAAMlB,KAAKkB,KACXqU,OAAQvY,IAlCT,CAPA,CA2CD,EAACqE,EAGDoD,YAAA,SAAY1C,GAKX,GAJA/B,KAAKyoB,WAAY,EACjBzoB,KAAKc,UAAUd,KAAK+U,QAAQN,OAC5BzU,KAAK8pB,wBAAwB/nB,GAExB/B,KAAKiW,WAAwC,IAA3BjW,KAAK0nB,mBAIZ1nB,KAAKiR,cAAc1B,iBAAiB,CACnDL,UAAWlP,KAAKiW,UAChB9G,oBAAqB,CACpB,CACCnO,KAAMyM,GACN0E,OAAQ,EACRpG,WAAY,CAAChK,EAAMyG,IAAKzG,EAAM0G,OAGhC1E,QAAS,CAAEL,WAAY3G,EAAY4G,eAGpC,CAIA,IAAA+qB,EACC1uB,KAAKypB,cAAczE,uBAAuBjjB,IAD1B2sB,EAAT5J,WAGO9kB,KAAK0nB,mBAAqB,GAHLgH,EAAjBzJ,mBAIIjlB,KAAK0nB,mBAAqB,IAEhD1nB,KAAKc,UAAUd,KAAK+U,QAAQK,MAR7B,CAUD,EAAC/T,EAEOyqB,YAAA,SAAY/pB,GACnB/B,KAAK8pB,wBAAwB/nB,GAC7B,IAAM4sB,EAA8B,CAAC5sB,EAAMyG,IAAKzG,EAAM0G,KAEtD,GAA+B,IAA3BzI,KAAK0nB,kBAAyB,CAAA,IAAAvX,EAC3BuF,EAAU1V,KAAKiR,cAAcjD,iBAAiB,CACnD3K,YAAa,CAACsrB,EAAmBA,GACjChwB,YAAUwR,EACTjP,CAAAA,KAAMlB,KAAKkB,MAAIiP,EACd3S,EAAkBE,oBAAoB,EAAIyS,KAO7C,OAHAnQ,KAAKiW,UAAYP,EAAQxS,GACzBlD,KAAK0nB,kBAAoB,OACzB1nB,KAAKgC,YAEN,CAEA,GAAKhC,KAAKiW,UAAV,CAIA,IAAA2Y,EACC5uB,KAAKypB,cAAczE,uBAAuBjjB,GADxBkjB,EAAiB2J,EAAjB3J,kBAGnB,GAHiB2J,EAAT9J,WAGS9kB,KAAK0nB,mBAAqB,EAC1C1nB,KAAKsuB,sBAIN,GAAIrJ,GAAqBjlB,KAAK0nB,mBAAqB,EAClD1nB,KAAKmuB,iBADN,CAKA,IAAMlE,EAAUjqB,KAAKiR,cAAc1B,iBAAiB,CACnDL,UAAWlP,KAAKiW,UAChBlS,QAAS,CAAEL,WAAY3G,EAAY0T,QACnCtB,oBAAqB,CACpB,CACCnO,KAAMyM,EACN0E,OAAQ,EACRpG,WAAY4iB,MAKf,GAAK1E,IAILjqB,KAAK0nB,oBAED1nB,KAAK0nB,mBAAqB,GAAG,CAChC,IAAMmH,EAAyB7uB,KAAKouB,yBACnCnE,EAAQ9mB,SAASE,aAGoB,IAAlCrD,KAAKypB,cAAchF,IAAI3e,OAC1B9F,KAAKypB,cAAc9V,OAAOkb,GAE1B7uB,KAAKypB,cAAcjZ,OAAOqe,EAE5B,CA9BA,CAbA,CA4CD,EAACxtB,EAGDqD,QAAA,SAAQ3C,GAEW,SAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcV,UAAWuC,KAEjD/B,KAAK0nB,kBAAoB,IAAM1nB,KAAKyoB,WACvCzoB,KAAKyE,YAAY1C,GAElB/B,KAAKyoB,WAAY,EACjBzoB,KAAK8rB,YAAY/pB,GAEnB,EAACV,EAGD8C,QAAA,SAAQpC,GACHA,EAAMqD,MAAQpF,KAAK8U,UAAUR,OAChCtU,KAAK8V,UACK/T,EAAMqD,MAAQpF,KAAK8U,UAAUP,QACvCvU,KAAKmuB,YAEP,EAAC9sB,EAGD6C,UAAA,WAAc7C,EAAAA,EAGd5B,YAAA,aAAgB4B,EAGhB3B,OAAA,aAAW2B,EAGX1B,UAAA,aAAc0B,EAGdyU,QAAA,WACC,IAAMG,EAAYjW,KAAKiW,UACvBjW,KAAKiW,eAAYtU,EACjB3B,KAAK0nB,kBAAoB,EAEN,YAAf1nB,KAAKsV,OACRtV,KAAKkC,aAGNlC,KAAKiR,cAAcxB,uBAAuBwG,GAC1CjW,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,EACtB3B,KAAKypB,cAAa,QACnB,EAACpoB,EAEOyoB,wBAAA,SAAwB/nB,GAC/B,IAAMgoB,EAAoB/pB,KAAKgqB,eAAejoB,GAE1CgoB,GACC/pB,KAAK4oB,eACR5oB,KAAKiR,cAAcP,qBAAqB,CACvC,CACCxB,UAAWlP,KAAK4oB,eAChB7c,WAAYge,KAId/pB,KAAK4oB,eAAiB5oB,KAAKiR,cAAc5C,oBAAoB,CAC5DtC,WAAYge,EACZ/oB,KAAMxD,EAAkBK,iBAI1BkE,EAAMyG,IAAMuhB,EAAkB,GAC9BhoB,EAAM0G,IAAMshB,EAAkB,IACpB/pB,KAAK4oB,iBACf5oB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,EAExB,EAACN,EAEO2oB,eAAA,SAAejoB,GAA0B0rB,IAAAA,EAAAC,EAAAC,EAC5C5D,EAGC6D,EAgBAA,EApB2Cnf,EAChDzO,KAmCA,GAjCIytB,OAAJA,EAAIztB,KAAKwoB,WAALiF,EAAeK,SAGjBF,EADG5tB,KAAKiW,UACEjW,KAAKwpB,aAAazM,uBAC3Bhb,EACA/B,KAAKiW,WAGIjW,KAAKwpB,aAAa3M,iCAAiC9a,MAI7DgoB,EAAoB6D,GAIlBF,OAAJA,EAAI1tB,KAAKwoB,WAALkF,EAAeK,eAGjBH,EADG5tB,KAAKiW,UACEjW,KAAKspB,mBAAmBvM,uBACjChb,EACA/B,KAAKiW,WAILjW,KAAKspB,mBAAmBzM,iCAAiC9a,MAI1DgoB,EAAoB6D,UAItBD,EAAI3tB,KAAKwoB,WAALmF,EAAeK,SAAU,CAC5B,IAAMJ,EAAU5tB,KAAKwoB,SAASwF,SAASjsB,EAAO,CAC7C2lB,kBAAmB1nB,KAAK0nB,kBACxBzR,UAAWjW,KAAKiW,UAChBgY,2BAA4BjuB,KAAKiW,UAC9B,WACA,OAAAxH,EAAK6L,YAAYpB,YAChBzK,EAAKwH,UACL,EACD,WAAA,WAAU,EACbpV,QAASb,KAAKa,QACdD,UAAWZ,KAAKY,YAGbgtB,IACH7D,EAAoB6D,EAEtB,CAEA,OAAO7D,CACR,EAAC1oB,EAGD6U,aAAA,SAAa5X,GACZ,IAAMmD,EAAML,EAAA,GxB7eN,CACN+U,iBAAkB,UAClBC,oBAAqB,UACrBC,oBAAqB,EACrBC,sBAAuB,EACvBC,mBAAoB,GACpBC,WAAY,UACZC,aAAc,EACdC,kBAAmB,UACnBC,oBAAqB,EACrBC,kBAAmB,EACnBC,WAAY,EACZC,gBAAiB,UACjBC,gBAAiB,EACjBC,kBAAmB,EACnBC,OAAQ,EACRC,eAAWvV,EACXwV,kBAAcxV,EACdyV,iBAAazV,EACb0V,oBAAgB1V,IwB4dhB,GAAIrD,EAAQK,WAAWuC,OAASlB,KAAKkB,KACpC,OAAOO,EAGR,GAA8B,eAA1BnD,EAAQ6E,SAASnC,KAoBpB,OAnBAS,EAAOqV,gBAAkB9W,KAAK4E,wBAC7B5E,KAAKyB,OAAOqV,gBACZrV,EAAOqV,gBACPxY,GAGDmD,EAAOsV,gBAAkB/W,KAAKgF,uBAC7BhF,KAAKyB,OAAOsV,gBACZtV,EAAOsV,gBACPzY,GAGDmD,EAAOuV,kBAAoBhX,KAAKgF,uBAC/BhF,KAAKyB,OAAOuV,kBACZ,EACA1Y,GAGDmD,EAAOwV,OAAS7Y,EACTqD,EAGR,GAA8B,YAA1BnD,EAAQ6E,SAASnC,KAgCpB,OA/BAS,EAAO0U,iBAAmBnW,KAAK4E,wBAC9B5E,KAAKyB,OAAO0U,iBACZ1U,EAAO0U,iBACP7X,GAGDmD,EAAO8U,mBAAqBvW,KAAKgF,uBAChChF,KAAKyB,OAAO8U,mBACZ9U,EAAO8U,mBACPjY,GAGDmD,EAAO2U,oBAAsBpW,KAAK4E,wBACjC5E,KAAKyB,OAAO2U,oBACZ3U,EAAO2U,oBACP9X,GAGDmD,EAAO4U,oBAAsBrW,KAAKgF,uBACjChF,KAAKyB,OAAO4U,oBACZ5U,EAAO4U,oBACP/X,GAGDmD,EAAO6U,sBAAwBtW,KAAKgF,uBACnChF,KAAKyB,OAAO6U,sBACZ,EACAhY,GAGDmD,EAAOwV,OAAS7Y,EACTqD,EAGR,GAA8B,UAA1BnD,EAAQ6E,SAASnC,KAAkB,CACtC,IAAMurB,GACmD,IAAxDjuB,EAAQK,WAAWnB,EAAkBI,eAItC,IAAK2uB,IAFqD,IAAzDjuB,EAAQK,WAAWnB,EAAkBK,gBAGrC,OAAO4D,EAGRA,EAAO+U,WAAaxW,KAAK4E,wBACxB2nB,EACGvsB,KAAKyB,OAAOma,kBACZ5b,KAAKyB,OAAOorB,mBACfprB,EAAO+U,WACPlY,GAGDmD,EAAOoV,WAAa7W,KAAKgF,uBACxBunB,EACGvsB,KAAKyB,OAAOka,kBACZ3b,KAAKyB,OAAOmrB,mBACfnrB,EAAOoV,WACPvY,GAGDmD,EAAOgV,aAAezW,KAAKgF,uBAC1BunB,EACGvsB,KAAKyB,OAAOoa,oBACZ7b,KAAKyB,OAAOqrB,qBACf,EACAxuB,GAGDmD,EAAOiV,kBAAoB1W,KAAK4E,wBAC/B2nB,EACGvsB,KAAKyB,OAAOqa,yBACZ9b,KAAKyB,OAAOsrB,0BACftrB,EAAOiV,kBACPpY,GAGDmD,EAAOmV,kBAAoB5W,KAAKgF,uBAC/BunB,EACGvsB,KAAKyB,OAAOsa,yBACZ/b,KAAKyB,OAAOurB,0BACf,EACA1uB,GAGDmD,EAAOkV,oBAAsB3W,KAAKgF,uBACjCunB,EACGvsB,KAAKyB,OAAOua,2BACZhc,KAAKyB,OAAOwrB,4BACf,EACA3uB,GAGDmD,EAAOwV,OzClVI,EyCmVZ,CAEA,OAAOxV,CACR,EAACJ,EAEDwB,kBAAA,SAAkBisB,GAA8B,EAAIztB,EAEpDyB,oBAAA,SAAoBxE,GACf0B,KAAK4oB,iBACR5oB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,GAGnB3B,KAAKiW,YAAc3X,EAAQ4E,KAC9BlD,KAAK0nB,kBAAoB,EACzB1nB,KAAKiW,eAAYtU,EACjB3B,KAAKypB,cAAa,SAEC,YAAfzpB,KAAKsV,OACRtV,KAAKkC,aAGR,EAACb,EAEDsB,gBAAA,SAAgBrE,GAAgBuR,IAAAA,OAC/B,OAAO7P,KAAK4D,oBAAoBtF,EAAS,SAACywB,GACzC,MAAuC,eAAnCA,EAAiB5rB,SAASnC,KACtBmf,GACN4O,EACAlf,EAAKvP,qBAIgC,YAAnCyuB,EAAiB5rB,SAASnC,KACtByL,EACNsiB,EACAlf,EAAKvP,qBAIA,CACNgD,OAAO,EACPC,OAAQ,gDAEV,EACD,EAAC2qB,CAAA,CAnkBiCxoB,CAAQ9F,GC9E9BovB,GAAkC,yBAClCC,GACZ,kCACYC,GACZ,mDAEe,SAAAC,GACf7wB,EACAgC,GAEA,MAA8B,UAA1BhC,EAAQ6E,SAASnC,KACb,CACNsC,OAAO,EACPC,OAAQyrB,IAIL/iB,EAAkB3N,EAAQ6E,SAASE,aAQtCyI,EACAxN,EAAQ6E,SAASE,YACjB/C,GASK,CAAEgD,OAAO,GANR,CACNA,OAAO,EACPC,OAAQ2rB,IAdF,CACN5rB,OAAO,EACPC,OAAQ0rB,GAiBX,CCrCA,IAAaG,gBAAoB,SAAAzhB,GAChC,SAAAyhB,EACC/sB,EACiBsa,EACAC,GAA0C,IAAAjX,EAAA,OAE3DA,EAAAgI,EAAA1H,UAAM5D,IAAQsD,MAHGgX,qBAAAhX,EACAiX,sBAAA,EADAjX,EAAagX,cAAbA,EACAhX,EAAgBiX,iBAAhBA,EAA0CjX,CAG5D,CAkCC,OAlCAU,EAAA+oB,EAAAzhB,GAAAyhB,EAAA9tB,UAEM+tB,uBAAA,SAAuBttB,GAO7B,IANA,IAAMkb,EAAOjd,KAAK4c,iBAAiBjJ,OAAO5R,GACpC4M,EAAW3O,KAAKS,MAAMyc,OAAOD,GAE/BtV,EAAWuE,SACXojB,OAAmD3tB,EAE9CkI,EAAI,EAAGA,EAAI8E,EAAS7I,OAAQ+D,IAAK,CACzC,IAAMvL,EAAUqQ,EAAS9E,GAKzB,GAH2B,UAA1BvL,EAAQ6E,SAASnC,MACjB1C,EAAQK,WAAWuC,OAASlB,KAAKkB,KAElC,CAIA,IACMquB,EAAoBvvB,KAAK2c,cAAcJ,QAAQxa,EADpCzD,EAAQ6E,SAASE,aAIjCksB,EAAoB5nB,GACpB4nB,EAAoBvvB,KAAKK,kBAK1BsH,EAAW4nB,EACXD,EAAiBhxB,EAbjB,CAcD,CAEA,OAAOgxB,CACR,EAACF,CAAA,CAzC+B,CAAQtiB,GC0CnC0H,GAAiB,CACtBb,OAAQ,YACR0U,UAAW,WACXC,QAAS,aASGkH,gBAAmB9pB,SAAAA,GAgB/B,SAAA8pB,EAAY3vB,OAAqD8F,EAEpC,OAD5BA,EAAAD,EAAAO,KAAMpG,KAAAA,GAAS,IAAM8F,MAhBtBzE,KAAO,QAAOyE,EAGNoP,QAA6BP,GAAc7O,EAC3CqjB,UAAoB,EAAKrjB,EAGzBsjB,qBAAe,EAAAtjB,EAGfgX,mBAAahX,EAAAA,EACbiX,wBAAgBjX,EAChB8pB,iBAAW,EAAA9pB,EACXsL,mBAIPtL,EAAAA,EAAKxE,cAActB,GAAS8F,CAC7B,CAACU,EAAAmpB,EAAA9pB,GAAA,IAAArE,EAAAmuB,EAAAluB,UA6QAkuB,OA7QAnuB,EAEDF,cAAA,SACCtB,GAEA6F,EAAApE,UAAMH,cAAa8E,KAAAjG,KAACH,GAET,MAAPA,GAAAA,EAASkV,UACZ/U,KAAK+U,QAAO3T,EAAQ,CAAA,EAAApB,KAAK+U,QAAYlV,EAAQkV,UAG1ClV,MAAAA,GAAAA,EAASmpB,WACZhpB,KAAKgpB,SAAWnpB,EAAQmpB,SAE1B,EAAC3nB,EAGDoT,MAAA,WACCzU,KAAKkC,aACLlC,KAAKc,UAAUd,KAAK+U,QAAQpB,OAC7B,EAACtS,EAGDwU,KAAA,WACC7V,KAAK8V,UACL9V,KAAKmC,aACLnC,KAAKc,UAAU,QAChB,EAACO,EAGDqD,QAAA,SAAQ3C,GAEY,UAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcZ,WAAYyC,IACtDA,EAAMiU,eACNhW,KAAK6B,kBAAkB7B,KAAKE,cAAcX,YAAawC,GAExD/B,KAAK0rB,aAAa3pB,GAGD,SAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcV,UAAWuC,IAErD/B,KAAK8rB,YAAY/pB,EAGnB,EAACV,EAGDoD,YAAA,aAAgBpD,EAGhB6C,UAAA,aAAc7C,EAGd8C,QAAA,WAAY9C,EAAAA,EAGZyU,QAAA,WACC9V,KAAKipB,qBAAkBtnB,CACxB,EAACN,EAED5B,YAAA,SACCsC,EACA4C,GAEA,GAAK3E,KAAK6B,kBAAkB7B,KAAKE,cAAcT,YAAasC,GAA5D,CAIA,GAAI/B,KAAKgpB,SAAU,CAClB,IAAM0G,EACL1vB,KAAKyvB,YAAYJ,uBAAuBttB,GACzC/B,KAAKipB,gBAAkByG,MAAAA,OAAAA,EAAAA,EAAqBxsB,EAC7C,CAIKlD,KAAKipB,kBAKVjpB,KAAKc,UAAUd,KAAK+U,QAAQsT,WAE5B1jB,GAAmB,GAjBnB,CAkBD,EAACtD,EAGD3B,OAAA,SACCqC,EACA4C,GAA8C2L,IAAAA,EAEzCtQ,KAAK6B,kBAAkB7B,KAAKE,cAAcR,OAAQqC,SAI1BJ,IAAzB3B,KAAKipB,iBAITjpB,KAAKiR,cAAclC,YAAY,CAC9BG,UAAWlP,KAAKipB,gBAChB9Z,oBAAqB,CACpBnO,KAAMyM,GACNpK,YAAa,CAACtB,EAAMyG,IAAKzG,EAAM0G,MAEhC2G,mBAAiBkB,EAAA,CAAA,EAAAA,EACf9S,EAAkBG,SAAS,EAAI2S,GAEjCvM,QAAS,CAAEL,WAAY3G,EAAY4G,cAErC,EAACtC,EAGD1B,UAAA,SACCoC,EACA4C,GAA8CsmB,IAAAA,EAE9C,GAAKjrB,KAAK6B,kBAAkB7B,KAAKE,cAAcP,UAAWoC,SAI7BJ,IAAzB3B,KAAKipB,iBAIOjpB,KAAKiR,cAAclC,YAAY,CAC9CG,UAAWlP,KAAKipB,gBAChB7Z,mBAAiB6b,EAChB/pB,CAAAA,KAAMlB,KAAKkB,MAAI+pB,EACdztB,EAAkBG,SAAS,EAAKstB,GAElClnB,QAAS,CAAEL,WAAY3G,EAAY8Q,OAAQ0H,OAAQ,UAGpD,CAIA,IAAMrG,EAAYlP,KAAKipB,gBAEvBjpB,KAAKc,UAAUd,KAAK+U,QAAQuT,SAC5BtoB,KAAKipB,qBAAkBtnB,EACvBgD,GAAmB,GAEnB3E,KAAK0C,SAASwM,EAAW,CACxBhO,KAAMlB,KAAKkB,KACXqU,OAAQvY,GAVT,CAYD,EAACqE,EAEDE,kBAAA,SAAkBc,GACjBrC,KAAK2c,cAAgB,IAAIL,GAAsBja,GAC/CrC,KAAK4c,iBAAmB,IAAIP,GAAyBha,GACrDrC,KAAKyvB,YAAc,IAAIL,GACtB/sB,EACArC,KAAK2c,cACL3c,KAAK4c,kBAEN5c,KAAKiR,cAAgB,IAAIvD,GAAsBrL,EAAQ,CACtDjC,SAAUJ,KAAKI,UAEjB,EAACiB,EAGD6U,aAAA,SAAa5X,GACZ,IAAMmD,EAAML,EAAA,G3BpPN,CACN+U,iBAAkB,UAClBC,oBAAqB,UACrBC,oBAAqB,EACrBC,sBAAuB,EACvBC,mBAAoB,GACpBC,WAAY,UACZC,aAAc,EACdC,kBAAmB,UACnBC,oBAAqB,EACrBC,kBAAmB,EACnBC,WAAY,EACZC,gBAAiB,UACjBC,gBAAiB,EACjBC,kBAAmB,EACnBC,OAAQ,EACRC,eAAWvV,EACXwV,kBAAcxV,EACdyV,iBAAazV,EACb0V,oBAAgB1V,I2BmOhB,GACkB,YAAjBrD,EAAQ0C,MACkB,UAA1B1C,EAAQ6E,SAASnC,MACjB1C,EAAQK,WAAWuC,OAASlB,KAAKkB,KAChC,CACD,IAAMyuB,EAAWpxB,QAChBD,EAAQ4E,IAAMlD,KAAKipB,kBAAoB3qB,EAAQ4E,IAGhDzB,EAAOoV,WAAa7W,KAAKgF,uBACxB2qB,EAAW3vB,KAAKyB,OAAOmuB,iBAAmB5vB,KAAKyB,OAAOoV,WACtDpV,EAAOoV,WACPvY,GAGDmD,EAAOgV,aAAezW,KAAKgF,uBAC1BhF,KAAKyB,OAAOgV,kBACY9U,IAAxBF,EAAOgV,aAA6B,EAAIhV,EAAOgV,aAC/CnY,GAGDmD,EAAO+U,WAAaxW,KAAK4E,wBACxB+qB,EAAW3vB,KAAKyB,OAAOouB,iBAAmB7vB,KAAKyB,OAAO+U,WACtD/U,EAAO+U,WACPlY,GAGDmD,EAAOiV,kBAAoB1W,KAAK4E,wBAC/B+qB,EACG3vB,KAAKyB,OAAOquB,wBACZ9vB,KAAKyB,OAAOiV,kBACfjV,EAAOiV,kBACPpY,GAGDmD,EAAOkV,oBAAsB3W,KAAKgF,uBACjChF,KAAKyB,OAAOkV,yBACmBhV,IAA/BF,EAAOkV,oBACJ,EACAlV,EAAOkV,oBACVrY,GAGDmD,EAAOmV,kBAAoB5W,KAAKgF,uBAC/B2qB,EACG3vB,KAAKyB,OAAOsuB,wBACZ/vB,KAAKyB,OAAOmV,kBACf,EACAtY,GAGDmD,EAAOwV,O5CpBI,E4CqBZ,CAEA,OAAOxV,CACR,EAACJ,EAEDsB,gBAAA,SAAgBrE,GAAgB,IAAAmQ,EAAAzO,KAC/B,OAAWA,KAAC4D,oBAAoBtF,EAAS,SAACqZ,GAAoB,OAC7DwX,GAAqBxX,EAAsBlJ,EAAKnO,oBAAoB,EAEtE,EAACe,EAEOyqB,YAAA,SAAY/pB,GACnB,IAAMzD,EAAU0B,KAAKiR,cAAcrD,YAAY,CAC9CvK,YAAa,CAACtB,EAAMyG,IAAKzG,EAAM0G,KAC/B9J,WAAY,CACXuC,KAAMlB,KAAKkB,MAEZ6C,QAAS,CAAEL,WAAY3G,EAAY8Q,OAAQ0H,OAAQvY,KAGhDsB,GACH0B,KAAK0C,SAASpE,EAAQ4E,GAAI,CACzBhC,KAAMlB,KAAKkB,KACXqU,OAAQvY,GAGX,EAACqE,EAEOqqB,aAAA,SAAa3pB,GAEpB,GAAK/B,KAAKgpB,SAAV,CAIA,IAAMsG,EAAiBtvB,KAAKyvB,YAAYJ,uBAAuBttB,GAE3DutB,GACHtvB,KAAKiR,cAAcxB,uBAAuB6f,EAAepsB,GAL1D,CAOD,EAAC7B,EAEDyB,oBAAA,SAAoBxE,GAGf0B,KAAKipB,kBAAoB3qB,EAAQ4E,KACpClD,KAAKipB,qBAAkBtnB,EACvB3B,KAAKc,UAAUd,KAAK+U,QAAQpB,QAE9B,EAAC6b,CAAA,CAhS8B9pB,CAAQ9F,GCblCyU,GAAmB,CAAEC,OAAQ,SAAUC,OAAQ,SAyC/CC,GAAiB,CACtBC,MAAO,YACPW,MAAO,UACPiT,UAAW,WACXC,QAAS,aAcG0H,yBAAqBtqB,GAkCjC,SAAAsqB,EAAYnwB,GAAqD8F,IAAAA,EAEpC,OAD5BA,EAAAD,EAAAO,UAAMpG,GAAS,IAAKG,MAlCrBkB,KAAO,UAASyE,EAER+hB,kBAAoB,EAAC/hB,EACrBsQ,eAAStQ,EAAAA,EACTmP,UAA2CT,GAAgB1O,EAC3DoP,QAA6BP,GAAc7O,EAC3C8iB,WAAY,EAAK9iB,EACjBmjB,sBAAuB,EAAKnjB,EAC5BkjB,wBAAkBljB,EAAAA,EAGlB6iB,cAAQ,EAAA7iB,EACRijB,sBAAcjjB,EAGdqjB,UAAoB,EAAKrjB,EACzBsjB,uBAAetjB,EACfujB,kCAA4B,EAAAvjB,EAC5BwjB,sBAAcxjB,EACdyjB,uBAAiBzjB,EAAAA,EACjB0jB,mBAAa,EAAA1jB,EAGb0gB,wBAAgB1gB,EAChB6jB,kBAAY7jB,EAAAA,EACZ2jB,wBAAkB,EAAA3jB,EAClBgX,qBAAahX,EACb8jB,mBAAa9jB,EAAAA,EACbiX,sBAAgB,EAAAjX,EAChBsL,qBAAatL,EACb2U,iBAAW3U,EAAAA,EACX+jB,cAAQ,EAIf/jB,EAAKxE,cAActB,GAAS8F,CAC7B,CAACU,EAAA2pB,EAAAtqB,OAAArE,EAAA2uB,EAAA1uB,UA2zCA0uB,OA3zCA3uB,EAEQF,cAAA,SACRtB,OAAwE4O,EAAAzO,KA2BxE,GAzBA0F,EAAApE,UAAMH,cAAa8E,KAACpG,KAAAA,SAEhBA,GAAAA,EAASkV,UACZ/U,KAAK+U,QAAO3T,EAAA,CAAA,EAAQpB,KAAK+U,QAAYlV,EAAQkV,UAInB,QAAvBlV,MAAAA,OAAAA,EAAAA,EAASiV,WACZ9U,KAAK8U,UAAY,CAAER,OAAQ,KAAMC,OAAQ,YAC/B1U,GAAAA,EAASiV,YACnB9U,KAAK8U,UAAS1T,EAAA,CAAA,EAAQpB,KAAK8U,UAAcjV,EAAQiV,kBAG9CjV,GAAAA,EAAS2oB,WACZxoB,KAAKwoB,SAAW3oB,EAAQ2oB,eAGC7mB,WAAtB9B,SAAAA,EAASmpB,YACZhpB,KAAKgpB,SAAWnpB,EAAQmpB,eAGMrnB,WAA3B9B,SAAAA,EAASK,iBACZF,KAAKE,cAAgBL,EAAQK,oBAGQyB,KAA3B,MAAP9B,OAAO,EAAPA,EAASipB,sBAIZ,GAHA9oB,KAAK8oB,qBAAuBjpB,EAAQipB,qBAGhC9oB,KAAKqmB,mBAAqD,IAAjCxmB,EAAQipB,qBACZ9oB,KAAKS,MAC3BkZ,aAAa,SAAChb,UAAeA,EAAWuC,OAASuN,EAAKvN,IAAI,GAC1D6O,OAAO,SAACzR,SAAsC,YAA1BA,EAAQ6E,SAASnC,IAAkB,GAEzCsc,QAAQ,SAAChf,GACxBmQ,EAAK4X,iBAAiBhB,eAAe,CACpCnW,UAAW5Q,EAAQ4E,GACnBghB,mBAAoB5lB,EAAQ6E,SAASE,aAEvC,QACM,GAAIrD,KAAKqmB,mBAAkD,IAA9BrmB,KAAK8oB,qBAAgC,CACxE,IAAMa,EAA0B3pB,KAAKS,MACnCkZ,aACA,SAAChb,GAAU,OACVA,EAAWuC,OAASuN,EAAKvN,MACzB3C,QACCI,EACCnB,EAAkBQ,sBAEnB,GAEF+R,OAAO,SAACzR,SAAsC,YAA1BA,EAAQ6E,SAASnC,IAAkB,GAEzDhB,KAAKqmB,iBAAiBL,yBACrB2D,EAAwB/a,IAAI,SAACiR,GAAC,OAAKA,EAAE3c,EAAe,GAEtD,CAEF,EAAC7B,EAEO+T,MAAA,eAAK9E,EACZ,QAAuB3O,IAAnB3B,KAAKiW,aAIyBjW,KAAKsa,YAAYnB,eAClDnZ,KAAKiW,WAMwBnQ,OAAS,GAAvC,CAIA,IAAMmkB,EAAUjqB,KAAKiR,cAAc5B,cAAc,CAChDH,UAAWlP,KAAKiW,UAChB9G,oBAAqB,CAAC,CAAEnO,KAAMyM,GAAkB0E,OAAQ,IACxD/C,mBAAiBkB,KAAAA,EACf9S,EAAkBE,wBAAoBiE,EAAS2O,EAC/C9S,EAAkBU,iCAA6ByD,EAAS2O,EACxD9S,EAAkBS,mCAA+B0D,EAAS2O,GAE5DvM,QAAS,CACRL,WAAY3G,EAAY8Q,OACxB0H,OAAQvY,KAIV,GAAKitB,EAAL,CAIIjqB,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWlP,KAAKiW,UAChBiO,mBAAoB+F,EAAQ9mB,SAASE,cAKpB,YAAfrD,KAAKsV,OACRtV,KAAKkC,aAGFlC,KAAKqpB,gBACRrpB,KAAKiR,cAAcxB,uBAAuBzP,KAAKqpB,eAC/CrpB,KAAKqpB,mBAAgB1nB,GAGlB3B,KAAK4oB,iBACR5oB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,GAGvB3B,KAAKypB,uBAEL,IAAMva,EAAYlP,KAAKiW,UAEvBjW,KAAK0nB,kBAAoB,EACzB1nB,KAAKiW,eAAYtU,EACjB3B,KAAK0pB,SAAS/B,QAEd3nB,KAAK0C,SAASwM,EAAW,CACxBhO,KAAMlB,KAAKkB,KACXqU,OAAQvY,GAlCT,CAlBA,CAsDD,EAACqE,EAGDE,kBAAA,SAAkBc,GACjBrC,KAAKsa,YAAc,IAAIxB,GAAoBzW,GAC3CrC,KAAKiR,cAAgB,IAAIvD,GAAsBrL,EAAQ,CACtDjC,SAAUJ,KAAKI,WAEhBJ,KAAK4c,iBAAmB,IAAIP,GAAyBha,GACrDrC,KAAK2c,cAAgB,IAAIL,GAAsBja,GAC/CrC,KAAKwpB,aAAe,IAAIxI,GACvB3e,EACArC,KAAK2c,cACL3c,KAAK4c,kBAEN5c,KAAKspB,mBAAqB,IAAI5M,GAC7Bra,EACArC,KAAK2c,cACL3c,KAAK4c,kBAEN5c,KAAKypB,cAAgB,IAAIrF,GACxB/hB,EACArC,KAAK2c,cACL3c,KAAKiR,cACLjR,KAAKsa,aAGNta,KAAKqmB,iBAAmB,IAAIjB,GAC3B/iB,EACArC,KAAKsa,YACLta,KAAKiR,eAGNjR,KAAK0pB,SAAW,IAAInD,GAA+B,CAClDI,aAActkB,EAAO9B,sBAEvB,EAACc,EAGDoT,MAAA,WACCzU,KAAKkC,aACLlC,KAAKc,UAAUd,KAAK+U,QAAQN,MAC7B,EAACpT,EAGDwU,KAAA,WACC7V,KAAK8V,UACL9V,KAAKmC,aACLnC,KAAKc,UAAU,QAChB,EAACO,EAEOyoB,wBAAA,SAAwB/nB,GAC/B,IAAMgoB,EAAoB/pB,KAAKgqB,eAAejoB,GAE1CgoB,GACC/pB,KAAK4oB,eACR5oB,KAAKiR,cAAcP,qBAAqB,CACvC,CACCxB,UAAWlP,KAAK4oB,eAChB7c,WAAYge,KAId/pB,KAAK4oB,eAAiB5oB,KAAKiR,cAAc5C,oBAAoB,CAC5DtC,WAAYge,EACZ/oB,KAAMxD,EAAkBK,iBAI1BkE,EAAMyG,IAAMuhB,EAAkB,GAC9BhoB,EAAM0G,IAAMshB,EAAkB,IACpB/pB,KAAK4oB,iBACf5oB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,EAExB,EAACN,EAEDiD,SAAA,WACC,OAAWtE,KAAC0pB,SAASplB,UACtB,EAACjD,EAEDgD,aAAA,WACCrE,KAAK0pB,SAAS/B,OACf,EAACtmB,EAEOqpB,oBAAA,SAAoBxb,EAAsBwY,GACjD,IAAMoD,EAAkB9qB,KAAKsa,YAAYpB,YAAqBhK,GAE9DlP,KAAK0pB,SAAS9B,eAAe,CAC5B1D,mBAAoB4G,EAAgBznB,YACpCqkB,kBAAAA,GAEF,EAACrmB,EAEO0pB,4CAAA,WACF/qB,KAAKwoB,UAAaxoB,KAAK6oB,mBAQ5B7oB,KAAK8pB,wBAAwB9pB,KAAK6oB,oBAP7B7oB,KAAK4oB,iBACR5oB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,EAMzB,EAACN,EAEO2pB,kBAAA,SAAkB9G,GACrBlkB,KAAK0nB,mBAAqB,EACzB1nB,KAAKypB,cAAchF,IAAI3e,OAC1B9F,KAAKypB,cAAcjZ,OAAO0T,GAE1BlkB,KAAKypB,cAAc9V,OAAOuQ,GAG3BlkB,KAAKypB,sBAEP,EAACpoB,EAEM+C,KAAA,WAAI,IAAA6mB,EACV,GAAmB,YAAfjrB,KAAKsV,OAAwBtV,KAAKiW,UAAtC,CAIA,IAAMiV,EAAiBlrB,KAAK0pB,SAAS7B,YAErC,GAAKqD,EAAL,CAIA,IAAuBC,EAAyBD,EAAxCjD,cAER,IAAKkD,EAAsB,CAC1B,IAAMC,EAAmBprB,KAAKiW,UAgB9B,OAdAjW,KAAKiW,eAAYtU,EACjB3B,KAAK0nB,kBAAoB,EACzB1nB,KAAKypB,uBAEc,YAAfzpB,KAAKsV,OACRtV,KAAKkC,aAGFlC,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBL,yBAAyB,CAACoF,IAGjDprB,KAAKiR,cAAcxB,uBAAuB2b,QAC1CprB,KAAK+qB,6CAEN,CAEA,IAAMd,EAAUjqB,KAAKiR,cAAc5B,cAAc,CAChDH,UAAWlP,KAAKiW,UAChB9G,oBAAqB,CACpBnO,KAAMyM,GACNpK,YAAa8nB,EAAqBjH,oBAEnC9U,mBAAiB6b,EAAAA,GAAAA,EACfztB,EAAkBE,oBAAoB,EAAIutB,EAC1CztB,EAAkBU,4BAClBitB,EAAqBzD,kBAAiBuD,EACtCztB,EAAkBS,8BAClBktB,EAAqBzD,kBAAiBuD,GAExClnB,QAAS,CAAEL,WAAY3G,EAAY0T,UAG/BwZ,IAILjqB,KAAK0nB,kBAAoByD,EAAqBzD,kBAC9C1nB,KAAKgrB,kBAAkBf,EAAQ9mB,SAASE,aAEpCrD,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWlP,KAAKiW,UAChBiO,mBAAoB+F,EAAQ9mB,SAASE,cAIvCrD,KAAK+qB,8CAtDL,CANA,CA6DD,EAAC1pB,EAEMkD,SAAA,WACN,OAAWvE,KAAC0pB,SAASnlB,UACtB,EAAClD,EAEMmD,KAAA,WACN,IAAM6mB,EAAqBrrB,KAAK0pB,SAASxB,WAEzC,GAAKmD,EAAL,CAIA,GAAKrrB,KAAKiW,UAgCH,CAAAqV,IAAAA,EACArB,EAAUjqB,KAAKiR,cAAc5B,cAAc,CAChDH,UAAWlP,KAAKiW,UAChB9G,oBAAqB,CACpBnO,KAAMyM,GACNpK,YAAagoB,EAAmBnH,oBAEjC9U,mBAAiBkc,EAAAA,CAAAA,EAAAA,EACf9tB,EAAkBE,oBAAoB,EAAI4tB,EAC1C9tB,EAAkBU,4BAClBmtB,EAAmB3D,kBAAiB4D,EACpC9tB,EAAkBS,8BAClBotB,EAAmB3D,kBAAiB4D,GAEtCvnB,QAAS,CAAEL,WAAY3G,EAAY0T,UAGpC,IAAKwZ,EACJ,OAGDjqB,KAAK0nB,kBAAoB2D,EAAmB3D,kBAC5C1nB,KAAKgrB,kBAAkBf,EAAQ9mB,SAASE,aAEpCrD,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWlP,KAAKiW,UAChBiO,mBAAoB+F,EAAQ9mB,SAASE,aAGxC,KA9DqB,KAAA8M,EAEd8f,EAAkBjwB,KAAK0pB,SAASlC,iBACrC6D,EAAmBnH,oBAClB,GAEFzJ,EAAyBza,KAAKiR,cAAc/C,cAAc,CACzD7K,YAAa4sB,EACbtxB,YAAUwR,EAAA,CACTjP,KAAMlB,KAAKkB,MAAIiP,EACd3S,EAAkBE,oBAAoB,EAAIyS,EAC1C3S,EAAkBU,4BAClBmtB,EAAmB3D,kBAAiBvX,EACpC3S,EAAkBS,8BAClBotB,EAAmB3D,kBAAiBvX,KAR/BjN,EAAEuX,EAAFvX,GAAIC,EAAQsX,EAARtX,SAYZnD,KAAKiW,UAAY/S,EACjBlD,KAAK0nB,kBAAoB2D,EAAmB3D,kBAEzB,YAAf1nB,KAAKsV,OACRtV,KAAKgC,aAENhC,KAAKgrB,kBAAkB7nB,EAASE,aAE5BrD,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWhM,EACXghB,mBAAoB/gB,EAASE,aAGhC,CAgCArD,KAAK0pB,SAAStB,WAAWiD,GAEzBrrB,KAAK+qB,6CApEL,CAqED,EAAC1pB,EAGDoD,YAAA,SAAY1C,GAA0BkqB,IAAAA,EAOrC,GANAjsB,KAAKyoB,WAAY,EACjBzoB,KAAKc,UAAUd,KAAK+U,QAAQN,OAE5BzU,KAAK6oB,mBAAqB9mB,EAC1B/B,KAAK8pB,wBAAwB/nB,QAENJ,IAAnB3B,KAAKiW,WAAsD,IAA3BjW,KAAK0nB,kBAAzC,CAIA,IAMIvY,EANE+gB,EAAkBlwB,KAAKsa,YAAYjB,cACxCrZ,KAAKiW,UACL,GAEKka,EAAkB,CAACpuB,EAAMyG,IAAKzG,EAAM0G,KAI1C,GAA+B,IAA3BzI,KAAK0nB,kBACRvY,EAAsB,CACrB,CAAEnO,KAAMyM,GAAkB0E,MAAO,EAAGpG,WAAYokB,GAChD,CACCnvB,KAAMyM,GACN0E,MAAO,EACPpG,WAAY,CAAChK,EAAMyG,IAAKzG,EAAM0G,YAGtB,GAA2B,IAA3BzI,KAAK0nB,kBACfvY,EAAsB,CACrB,CAAEnO,KAAMyM,GAAkB0E,MAAO,EAAGpG,WAAYokB,QAE3C,CACN,IAAAzB,EACC1uB,KAAKypB,cAAczE,uBAAuBjjB,GADP2sB,EAAjBzJ,mBAAFyJ,EAAT5J,WAIH9kB,KAAK4oB,iBACR5oB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,GAGvB3B,KAAKc,UAAUd,KAAK+U,QAAQK,OAE5BjG,EAAsB,CACrB,CAAEnO,KAAMyM,GAAkB0E,OAAQ,EAAGpG,WAAYmkB,GACjD,CAAElvB,KAAMyM,GAAkB0E,OAAQ,EAAGpG,WAAYmkB,KAGlD/gB,EAAsB,CACrB,CAAEnO,KAAMyM,GAAkB0E,OAAQ,EAAGpG,WAAYokB,GACjD,CAAEnvB,KAAMyM,GAAkB0E,OAAQ,EAAGpG,WAAYmkB,GAGpD,CAEA,IAAMjG,EAAUjqB,KAAKiR,cAAc5B,cAAc,CAChDH,UAAWlP,KAAKiW,UAChB9G,oBAAAA,EACAC,mBAAiB6c,EAAA,GAAAA,EACfzuB,EAAkBS,8BAClB+B,KAAK0nB,kBAAoB,EAACuE,GAE5BloB,QAAS,CAAEL,WAAY3G,EAAY4G,eAG/BsmB,GAIDjqB,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWlP,KAAKiW,UAChBiO,mBAAoB+F,EAAQ9mB,SAASE,aAhEvC,CAmED,EAAChC,EAEO2oB,eAAA,SAAejoB,OAA0B0rB,EAAAC,EAAAC,EAI3CC,EAgBAA,EApB2C/d,EAAA7P,KAC5C+pB,OAA0CpoB,EAmC9C,UAjCA8rB,EAAIztB,KAAKwoB,WAALiF,EAAeK,SAGjBF,EADG5tB,KAAKiW,UACEjW,KAAKwpB,aAAazM,uBAC3Bhb,EACA/B,KAAKiW,WAGIjW,KAAKwpB,aAAa3M,iCAAiC9a,MAI7DgoB,EAAoB6D,GAIL,OAAjBF,EAAI1tB,KAAKwoB,WAALkF,EAAeK,eAGjBH,EADG5tB,KAAKiW,UACEjW,KAAKspB,mBAAmBvM,uBACjChb,EACA/B,KAAKiW,WAILjW,KAAKspB,mBAAmBzM,iCAAiC9a,MAI1DgoB,EAAoB6D,UAItBD,EAAI3tB,KAAKwoB,WAALmF,EAAeK,SAAU,CAC5B,IAAMJ,EAAU5tB,KAAKwoB,SAASwF,SAASjsB,EAAO,CAC7C2lB,kBAAmB1nB,KAAK0nB,kBACxBzR,UAAWjW,KAAKiW,UAChBgY,2BAA4BjuB,KAAKiW,UAC9B,WAAA,OACApG,EAAKyK,YAAYpB,YAAqBrJ,EAAKoG,UAAuB,EAClE,kBAAU,IAAA,EACbpV,QAASb,KAAKa,QACdD,UAAWZ,KAAKY,YAGbgtB,IACH7D,EAAoB6D,EAEtB,CAEA,OAAO7D,CACR,EAAC1oB,EAEO+uB,cAAA,SAAc9xB,GACrB,OAAOC,QACoB,YAA1BD,EAAQ6E,SAASnC,MAChB1C,EAAQK,YACRL,EAAQK,WAAWuC,OAASlB,KAAKkB,KAEpC,EAACG,EAEOqqB,aAAA,SAAa3pB,GAA0BkO,IAAAA,OAE9C,GAAKjQ,KAAKgpB,UAA2B,YAAfhpB,KAAKsV,MAA3B,CAIA,IAAAqW,EACC3rB,KAAKspB,mBAAmBxM,aAAa/a,EAAO,SAACzD,GAAO,OACnD2R,EAAKmgB,cAAc9xB,EAAQ,GAFrB4Q,EAASyc,EAATzc,UAAmC2c,EAAeF,EAAvCvO,uBAKnB,GAAKlO,QAAiCvN,IAApBkqB,EAAlB,CAIA,IAAM1oB,EAAWnD,KAAKsa,YAAYpB,YAAYhK,GAE9C,GAAsB,YAAlB/L,EAASnC,KAAb,CAIA,IAAMqC,EAAcF,EAASE,YAAY,GAGzC,KAAIA,EAAYyC,QAAU,GAA1B,CAIA,IA8BMmkB,EAAUjqB,KAAKiR,cAAc5B,cAAc,CAChDH,UAAAA,EACAC,oBA/BoB,IAApB0c,GAAyBA,IAAoBxoB,EAAYyC,OAAS,EAa5C,CACrB,CAAE9E,KAAMyM,GAAkB0E,MAAO,GACjC,CAAEnR,KAAMyM,GAAkB0E,OAAQ,GAClC,CACCnR,KAAMyM,EACN0E,OAAQ,EACRpG,WARuB1I,EAAY,KAaf,CACrB,CAAErC,KAAMyM,GAAkB0E,MAAO0Z,IAOlC9nB,QAAS,CAAEL,WAAY3G,EAAY8Q,OAAQ0H,OAAQvY,KAGpD,GAAKitB,EAAL,CAWA,GAPIjqB,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAAA,EACAgV,mBAAoB+F,EAAQ9mB,SAASE,cAInCrD,KAAK4oB,iBACR5oB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,EAElB3B,KAAKwoB,UAAU,CAClB,IAAMuB,EAAoB/pB,KAAKgqB,eAAejoB,GAC9C,GAAIgoB,EAAmB,CACtB,IAAAsG,EAAyBrwB,KAAKiR,cAAc1C,qBAAqB,CAChEvN,KAAMxD,EAAkBK,eACxBwF,YAAa,CAAC0mB,KAEf/pB,KAAK4oB,eAJgByH,EAIrB,EACD,CACD,CAGDrwB,KAAK0C,SAASwM,EAAW,CAAEhO,KAAMlB,KAAKkB,KAAMqU,OAAQvY,GAzBpD,CAxCA,CAPA,CANA,CATA,CAwFD,EAACqE,EAEOyqB,YAAA,SAAY/pB,GAEf/B,KAAK4oB,iBACR5oB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,GAGvB,IAEIwuB,EAFsBnwB,KAAKgqB,eAAejoB,IAI3C,CAACA,EAAMyG,IAAKzG,EAAM0G,KAErB,GAA+B,IAA3BzI,KAAK0nB,kBAAyB,CAAA6D,IAAAA,EACjC+E,EAAyBtwB,KAAKiR,cAAc/C,cAAc,CACzD7K,YAAa,CACZ8sB,EACAA,EACAA,EACAA,GAEDxxB,YAAU4sB,GACTrqB,KAAMlB,KAAKkB,MAAIqqB,EACd/tB,EAAkBE,oBAAoB,EAAI6tB,EAC1C/tB,EAAkBU,4BAClB8B,KAAK0nB,kBAAoB,EAAC6D,EAC1B/tB,EAAkBS,8BAClB+B,KAAK0nB,kBAAoB,EAAC6D,KAbrBroB,EAAEotB,EAAFptB,GAiBJlD,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWhM,EACXghB,mBApBkBoM,EAARntB,SAoBmBE,cAI/BrD,KAAKiW,UAAY/S,EACjBlD,KAAK0nB,oBACL1nB,KAAK0qB,oBAAoB1qB,KAAKiW,UAAWjW,KAAK0nB,mBAG9C1nB,KAAKgC,YACN,SAAsC,IAA3BhC,KAAK0nB,mBAA2B1nB,KAAKiW,UAAW,CAAA,IAAAkW,EAO1D,GANoBnsB,KAAKsa,YAAYtB,6BAA6B,CACjE9J,UAAWlP,KAAKiW,UAChBgD,cAAekX,EACfhe,MAAO,IAIP,OAGD,IAAM8X,EAAUjqB,KAAKiR,cAAc5B,cAAc,CAChDH,UAAWlP,KAAKiW,UAChB9G,oBAAqB,CACpB,CAAEnO,KAAMyM,GAAkB0E,MAAO,EAAGpG,WAAYokB,GAChD,CAAEnvB,KAAMyM,GAAkB0E,MAAO,EAAGpG,WAAYokB,IAEjD/gB,mBAAiB+c,EAAA,GAAAA,EACf3uB,EAAkBU,4BAClB8B,KAAK0nB,kBAAoB,EAACyE,GAE5BpoB,QAAS,CAAEL,WAAY3G,EAAY0T,UAGpC,IAAKwZ,EACJ,OAGGjqB,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWlP,KAAKiW,UAChBiO,mBAAoB+F,EAAQ9mB,SAASE,cAIvCrD,KAAK0nB,oBACL1nB,KAAK0qB,oBAAoB1qB,KAAKiW,UAAWjW,KAAK0nB,kBAC/C,SAAsC,IAA3B1nB,KAAK0nB,mBAA2B1nB,KAAKiW,UAAW,CAAA,IAAAsa,EAO1D,GANoBvwB,KAAKsa,YAAYtB,6BAA6B,CACjE9J,UAAWlP,KAAKiW,UAChBgD,cAAekX,EACfhe,MAAO,IAIP,OAGD,IAAM8X,EAAUjqB,KAAKiR,cAAc5B,cAAc,CAChDH,UAAWlP,KAAKiW,UAChB9G,oBAAqB,CACpB,CAAEnO,KAAMyM,GAAkB0E,MAAO,EAAGpG,WAAYokB,GAChD,CACCnvB,KAAMyM,EACN0E,MAAO,EACPpG,WAAYokB,IAGd/gB,mBAAiBmhB,EAAAA,GAAAA,EACf/yB,EAAkBU,4BAClB8B,KAAK0nB,kBAAoB,EAAC6I,GAE5BxsB,QAAS,CAAEL,WAAY3G,EAAY0T,UAGpC,IAAKwZ,EACJ,OAGGjqB,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWlP,KAAKiW,UAChBiO,mBAAoB+F,EAAQ9mB,SAASE,cAIR,IAA3BrD,KAAK0nB,mBACR1nB,KAAKypB,cAAc9V,OAAOsW,EAAQ9mB,SAASE,aAG5CrD,KAAK0nB,oBACL1nB,KAAK0qB,oBAAoB1qB,KAAKiW,UAAWjW,KAAK0nB,kBAC/C,SAAW1nB,KAAKiW,UAAW,CAC1B,IAAA2Y,EACC5uB,KAAKypB,cAAczE,uBAAuBjjB,GAE3C,GAHoC6sB,EAAjB3J,mBAAF2J,EAAT9J,UAIP9kB,KAAKoV,YACC,CAAA,IAAAob,EAON,GANoBxwB,KAAKsa,YAAYtB,6BAA6B,CACjE9J,UAAWlP,KAAKiW,UAChBgD,cAAekX,EACfhe,MAAOnS,KAAK0nB,kBAAoB,IAIhC,OAID,IAAMuC,EAAUjqB,KAAKiR,cAAc5B,cAAc,CAChDH,UAAWlP,KAAKiW,UAChB9G,oBAAqB,CACpB,CACCnO,KAAMyM,EACN0E,OAAQ,EACRpG,WAAYokB,IAGd/gB,mBAAiBohB,KAAAA,EACfhzB,EAAkBU,4BAClB8B,KAAK0nB,kBAAoB,EAAC8I,GAE5BzsB,QAAS,CAAEL,WAAY3G,EAAY0T,UAGpC,IAAKwZ,EACJ,OAGGjqB,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWlP,KAAKiW,UAChBiO,mBAAoB+F,EAAQ9mB,SAASE,cAIvCrD,KAAK0nB,oBACL1nB,KAAK0qB,oBAAoB1qB,KAAKiW,UAAWjW,KAAK0nB,mBAG1C1nB,KAAKypB,cAAchF,IAAI3e,QAC1B9F,KAAKypB,cAAcjZ,OAAOyZ,EAAQ9mB,SAASE,YAE7C,CACD,CACD,EAAChC,EAGDqD,QAAA,SAAQ3C,GAKH/B,KAAK0nB,kBAAoB,IAAM1nB,KAAKyoB,WACvCzoB,KAAKyE,YAAY1C,GAElB/B,KAAKyoB,WAAY,EAGE,UAAjB1mB,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcZ,WAAYyC,IACtDA,EAAMiU,eACNhW,KAAK6B,kBAAkB7B,KAAKE,cAAcX,YAAawC,GAExD/B,KAAK0rB,aAAa3pB,GAGD,SAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcV,UAAWuC,IAErD/B,KAAK8rB,YAAY/pB,EAGnB,EAACV,EAGD8C,QAAA,SAAQpC,GACHA,EAAMqD,MAAQpF,KAAK8U,UAAUR,OAChCtU,KAAK8V,UACK/T,EAAMqD,MAAQpF,KAAK8U,UAAUP,QACvCvU,KAAKoV,OAEP,EAAC/T,EAGD6C,UAAA,aAAc7C,EAEd5B,YAAA,SACCsC,EACA4C,GAA8C6oB,IAAAA,OAE9C,GAAKxtB,KAAK6B,kBAAkB7B,KAAKE,cAAcT,YAAasC,IAIvD/B,KAAKgpB,SAAV,CAIA,IAAIe,OAA0CpoB,EAE9C,GAAmB,YAAf3B,KAAKsV,MAAqB,CAK7B,IAAMyW,EAAc/rB,KAAKwpB,aAAa1M,aAAa/a,EAAO,SAACzD,UAC1DkvB,EAAK4C,cAAc9xB,EAAQ,GAGxBytB,EAAYhgB,aACf/L,KAAKmpB,eAAiB,OACtBnpB,KAAKkpB,6BAA+B6C,EAAY3O,uBAChDpd,KAAKipB,gBAAkB8C,EAAY7c,UACnC6a,EAAoBgC,EAAYhgB,YAGjC,IAAMigB,EAAoBhsB,KAAKspB,mBAAmBxM,aACjD/a,EACA,SAACzD,GAAO,OAAKkvB,EAAK4C,cAAc9xB,EAAQ,GAGrC0tB,EAAkBjgB,aACrB/L,KAAKmpB,eAAiB,aACtBnpB,KAAKkpB,6BACJ8C,EAAkB5O,uBACnBpd,KAAKipB,gBAAkB+C,EAAkB9c,UACzC6a,EAAoBiC,EAAkBjgB,WAExC,CAIK/L,KAAKipB,iBAAoBc,IAKzB/pB,KAAKqpB,gBACTrpB,KAAKqpB,cAAgBrpB,KAAKiR,cAAc5C,oBAAoB,CAC3DtC,WAAYge,EACZ/oB,KAAMxD,EAAkBG,UAK1BqC,KAAKc,UAAUd,KAAK+U,QAAQsT,WAE5B1jB,GAAmB,GAnDnB,CAoDD,EAACtD,EAGD3B,OAAA,SACCqC,EACA4C,GAA8C,IAAA8rB,EAE9C,GAAKzwB,KAAK6B,kBAAkB7B,KAAKE,cAAcR,OAAQqC,SAK7BJ,IAAzB3B,KAAKipB,sBACiCtnB,IAAtC3B,KAAKkpB,6BAFN,CAOA,IAAMwH,EAAuB1wB,KAAKsa,YAAYpB,YAC7ClZ,KAAKipB,iBAGAkH,EAA4B,CAACpuB,EAAMyG,IAAKzG,EAAM0G,KAEhD0G,EAA4C,GAuDhD,GAnDyB,eAAxBnP,KAAKmpB,gBACoB,SAAxBnpB,KAAKmpB,qBAAwDxnB,IAA3B3B,KAAKopB,kBASvCja,EALsC,IAAtCnP,KAAKkpB,8BACLlpB,KAAKkpB,+BACJwH,EAAYrtB,YAAY,GAAGyC,OAAS,EAGf,CACrB,CACC9E,KAAMyM,GACN0E,MAAO,EACPpG,WAAYokB,GAEb,CACCnvB,KAAMyM,GACN0E,OAAQ,EACRpG,WAAYokB,IAIQ,CACrB,CACCnvB,KAAMyM,GACN0E,MAAOnS,KAAKkpB,6BACZnd,WAAYokB,IAKS,SAAxBnwB,KAAKmpB,qBACsBxnB,IAA3B3B,KAAKopB,oBAELppB,KAAKopB,kBAAoBppB,KAAKkpB,6BAA+B,EAE7D/Z,EAAsB,CACrB,CACCnO,KAAMyM,EACN0E,MAAOnS,KAAKopB,kBACZrd,WAAYokB,IAMdnwB,KAAKkpB,gCAI6B,IAA/B/Z,EAAoBrJ,OAAxB,CAIA,IAAMmkB,EAAUjqB,KAAKiR,cAAc5B,cAAc,CAChDH,UAAWlP,KAAKipB,gBAChB9Z,oBAAAA,EACAC,mBAAiBqhB,EAAA,CAAA,EAAAA,EACfjzB,EAAkBG,SAAS,EAAI8yB,GAEjC1sB,QAAS,CAAEL,WAAY3G,EAAY4G,eAG/BsmB,IAIDjqB,KAAK8oB,uBAEJ9oB,KAAKopB,kBACRppB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAWlP,KAAKipB,gBAChB/E,mBAAoB+F,EAAQ9mB,SAASE,cAKtCrD,KAAKqmB,iBAAiBH,iBACrBlmB,KAAKipB,gBACLjpB,KAAKkpB,6BACLe,EAAQ9mB,SAASE,YAAY,GAAGrD,KAAKkpB,gCAKpClpB,KAAKwoB,UAAYxoB,KAAK4oB,iBACzB5oB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,GAGnB3B,KAAKqpB,eACRrpB,KAAKiR,cAAcP,qBAAqB,CACvC,CACCxB,UAAWlP,KAAKqpB,cAChBtd,WAAYokB,KA1Cf,CAjEA,CA+GD,EAAC9uB,EAGD1B,UAAA,SACCoC,EACA4C,OAA8CgsB,EAE9C,GAAK3wB,KAAK6B,kBAAkB7B,KAAKE,cAAcP,UAAWoC,SAI7BJ,IAAzB3B,KAAKipB,kBAITjpB,KAAKc,UAAUd,KAAK+U,QAAQuT,SAEZtoB,KAAKiR,cAAc5B,cAAc,CAChDH,UAAWlP,KAAKipB,gBAChB7Z,mBAAiBuhB,EAAA,GAAAA,EACfnzB,EAAkBG,SAAS,EAAKgzB,GAElC5sB,QAAS,CAAEL,WAAY3G,EAAY8Q,OAAQ0H,OAAQvY,MAGpD,CAIA,IAAMkS,EAAYlP,KAAKipB,gBAEnBjpB,KAAKqpB,gBACRrpB,KAAKiR,cAAcxB,uBAAuBzP,KAAKqpB,eAC/CrpB,KAAKqpB,mBAAgB1nB,GAGlB3B,KAAK4oB,iBACR5oB,KAAKiR,cAAcxB,uBAAuBzP,KAAK4oB,gBAC/C5oB,KAAK4oB,oBAAiBjnB,GAIvB3B,KAAKipB,qBAAkBtnB,EACvB3B,KAAKkpB,kCAA+BvnB,EACpC3B,KAAKopB,uBAAoBznB,EACzB3B,KAAKmpB,oBAAiBxnB,EAEtBgD,GAAmB,GAEnB3E,KAAK0C,SAASwM,EAAW,CACxBhO,KAAMlB,KAAKkB,KACXqU,OAAQvY,GAxBT,CA0BD,EAACqE,EAGDyU,QAAA,WACC,IAAM0F,EAAYxb,KAAKiW,UACjB2S,EAAiB5oB,KAAK4oB,eACtBS,EAAgBrpB,KAAKqpB,cAE3BrpB,KAAKiW,eAAYtU,EACjB3B,KAAK4oB,oBAAiBjnB,EACtB3B,KAAKqpB,mBAAgB1nB,EACrB3B,KAAKipB,qBAAkBtnB,EACvB3B,KAAKkpB,kCAA+BvnB,EACpC3B,KAAKopB,uBAAoBznB,EACzB3B,KAAKmpB,oBAAiBxnB,EACtB3B,KAAK0nB,kBAAoB,EACzB1nB,KAAK0pB,SAAS/B,QAEK,YAAf3nB,KAAKsV,OACRtV,KAAKkC,aAGFsZ,GACHxb,KAAKqmB,iBAAiBL,yBAAyB,CAACxK,IAGjDxb,KAAKiR,cAAcxB,uBAAuB+L,GAC1Cxb,KAAKiR,cAAcxB,uBAAuB4Z,GAC1CrpB,KAAKiR,cAAcxB,uBAAuBmZ,GAEtC5oB,KAAKypB,cAAchF,IAAI3e,QAC1B9F,KAAKypB,cAAoB,QAE3B,EAACpoB,EAGD6U,aAAA,SAAa5X,GACZ,IAAMmD,EAAML,EAAQsa,CAAAA,E5B5vCd,CACNvF,iBAAkB,UAClBC,oBAAqB,UACrBC,oBAAqB,EACrBC,sBAAuB,EACvBC,mBAAoB,GACpBC,WAAY,UACZC,aAAc,EACdC,kBAAmB,UACnBC,oBAAqB,EACrBC,kBAAmB,EACnBC,WAAY,EACZC,gBAAiB,UACjBC,gBAAiB,EACjBC,kBAAmB,EACnBC,OAAQ,EACRC,eAAWvV,EACXwV,kBAAcxV,EACdyV,iBAAazV,EACb0V,oBAAgB1V,I4B2uChB,GAAIrD,EAAQK,WAAWuC,OAASlB,KAAKkB,KAAM,CAC1C,GAA8B,YAA1B5C,EAAQ6E,SAASnC,KAgCpB,OA/BAS,EAAO0U,iBAAmBnW,KAAK4E,wBAC9B5E,KAAKyB,OAAO6V,UACZ7V,EAAO0U,iBACP7X,GAGDmD,EAAO2U,oBAAsBpW,KAAK4E,wBACjC5E,KAAKyB,OAAO8V,aACZ9V,EAAO2U,oBACP9X,GAGDmD,EAAO4U,oBAAsBrW,KAAKgF,uBACjChF,KAAKyB,OAAO+V,aACZ/V,EAAO4U,oBACP/X,GAGDmD,EAAO8U,mBAAqBvW,KAAKgF,uBAChChF,KAAKyB,OAAOiW,YACZjW,EAAO8U,mBACPjY,GAGDmD,EAAO6U,sBAAwBtW,KAAKgF,uBACnChF,KAAKyB,OAAOgW,eACZ,EACAnZ,GAGDmD,EAAOwV,OAAS7Y,EACTqD,KAC6B,UAA1BnD,EAAQ6E,SAASnC,KAAkB,CAC7C,IAAM4vB,EAActyB,EAAQK,WAAWnB,EAAkBG,QAKnDyuB,EACL9tB,EAAQK,WAAWnB,EAAkBM,kBAEhCuuB,EAAYuE,EACf,cAPFtyB,EAAQK,WAAWnB,EAAkBI,eASlC,eAPHU,EAAQK,WAAWnB,EAAkBK,gBASjC,gBACAuuB,EACC,uBACAzqB,EAEN,IAAK0qB,EACJ,OAAO5qB,EAGR,IAAM6qB,EAAW,CAChBsE,YAAa,CACZpE,MAAOxsB,KAAKyB,OAAOsuB,wBACnBtD,MAAOzsB,KAAKyB,OAAOouB,iBACnBnD,QAAS1sB,KAAKyB,OAAOovB,mBACrBtZ,aAAcvX,KAAKyB,OAAOquB,wBAC1BtY,aAAcxX,KAAKyB,OAAOsuB,wBAC1BtY,eAAgBzX,KAAKyB,OAAOqvB,2BAE7BvE,aAAc,CACbC,MAAOxsB,KAAKyB,OAAOka,kBACnB8Q,MAAOzsB,KAAKyB,OAAOma,kBACnB8Q,QAAS1sB,KAAKyB,OAAOoa,oBACrBtE,aAAcvX,KAAKyB,OAAOqa,yBAC1BtE,aAAcxX,KAAKyB,OAAOsa,yBAC1BtE,eAAgBzX,KAAKyB,OAAOua,4BAE7B2Q,cAAe,CACdH,MAAOxsB,KAAKyB,OAAOmrB,mBACnBH,MAAOzsB,KAAKyB,OAAOorB,mBACnBH,QAAS1sB,KAAKyB,OAAOqrB,qBACrBvV,aAAcvX,KAAKyB,OAAOsrB,0BAC1BvV,aAAcxX,KAAKyB,OAAOurB,0BAC1BvV,eAAgBzX,KAAKyB,OAAOwrB,6BAE7Bb,gBAAiB,CAChBI,MAAOxsB,KAAKyB,OAAOyrB,qBACnBT,MAAOzsB,KAAKyB,OAAO0rB,qBACnBT,QAAS1sB,KAAKyB,OAAO2rB,uBACrB7V,aAAcvX,KAAKyB,OAAO4rB,4BAC1B7V,aAAcxX,KAAKyB,OAAO6rB,4BAC1B7V,eAAgBzX,KAAKyB,OAAO8rB,gCAgD9B,OA5CA9rB,EAAOoV,WAAa7W,KAAKgF,uBACxBsnB,EAASD,GAAWG,MACpB/qB,EAAOoV,WACPvY,GAGDmD,EAAOgV,aAAezW,KAAKgF,uBAC1BsnB,EAASD,GAAWK,QACpB,EACApuB,GAGDmD,EAAO+U,WAAaxW,KAAK4E,wBACxB0nB,EAASD,GAAWI,MACpBhrB,EAAO+U,WACPlY,GAGDmD,EAAOiV,kBAAoB1W,KAAK4E,wBAC/B0nB,EAASD,GAAW9U,aACpB9V,EAAOiV,kBACPpY,GAGDmD,EAAOkV,oBAAsB3W,KAAKgF,uBACjCsnB,EAASD,GAAW5U,eACpB,EACAnZ,GAGDmD,EAAOmV,kBAAoB5W,KAAKgF,uBAC/BsnB,EAASD,GAAW7U,aACpB,EACAlZ,GAIAmD,EAAOwV,OADJ2Z,E7CxmCK,G6C0mCExE,E7C5mCH,GACE,G6CinCH3qB,CACR,CACD,CAEA,OAAOA,CACR,EAACJ,EAEDwB,kBAAA,SAAkBvE,GACb0B,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAW5Q,EAAQ4E,GACnBghB,mBAAoB5lB,EAAQ6E,SAASE,aAGxC,EAAChC,EAEDyB,oBAAA,SAAoBxE,GAKf0B,KAAK8oB,sBACR9oB,KAAKqmB,iBAAiBhB,eAAe,CACpCnW,UAAW5Q,EAAQ4E,GACnBghB,mBAAoB5lB,EAAQ6E,SAASE,cAOnCrD,KAAKipB,kBAAoB3qB,EAAQ4E,IAAMlD,KAAKqpB,gBAC/CrpB,KAAKiR,cAAcxB,uBAAuBzP,KAAKqpB,eAC/CrpB,KAAKqpB,mBAAgB1nB,EACrB3B,KAAKipB,qBAAkBtnB,EACvB3B,KAAKkpB,kCAA+BvnB,EACpC3B,KAAKmpB,oBAAiBxnB,GAInB3B,KAAK4oB,gBAAkB5oB,KAAK6oB,oBAC/B7oB,KAAK8pB,wBACJ9pB,KAAK6oB,oBAOH7oB,KAAKiW,YAAc3X,EAAQ4E,KAC9BlD,KAAK0nB,kBAAoB,EACzB1nB,KAAKiW,eAAYtU,EACjB3B,KAAK0pB,SAAS/B,QACd3nB,KAAKypB,uBAGc,YAAfzpB,KAAKsV,OACRtV,KAAKkC,aAGR,EAACb,EAEDsB,gBAAA,SAAgBrE,OAAgBuvB,EAAA7tB,KAC/B,OAAWA,KAAC4D,oBAAoBtF,EAAS,SAACqZ,UACzClL,EAAuBkL,EAAsBkW,EAAKvtB,oBAAoB,EAExE,EAAC0vB,CAAA,EAh2CwCpwB,GCtEpCyU,GAAmB,CAAEC,OAAQ,SAAUC,OAAQ,SAc/CC,GAAiB,CACtBC,MAAO,aAUKsc,gBAAuB,SAAArrB,GAcnC,SAAAqrB,EACClxB,OAAgE8F,EAGpC,OAD5BA,EAAAD,EAAAO,KAAAjG,KAAMH,GAAS,IAAM8F,MAhBtBzE,KAAO,YAAWyE,EACVqc,mBAAa,EAAArc,EACbgP,iBAAWhP,EAAAA,EACXqrB,wBAAkB,EAAArrB,EAClBmP,UAA6CT,GAAgB1O,EAC7DoP,QAA6BP,GAAc7O,EAC3CuP,gBAAkB,aAAYvP,EAC9BwP,gBAAQxP,EAGRsL,mBAAatL,EAAAA,EACb2U,iBAAW,EAMlB3U,EAAKxE,cAActB,GAAS8F,CAC7B,CAACU,EAAA0qB,EAAArrB,GAAA,IAAArE,EAAA0vB,EAAAzvB,UAuUA,OAvUAD,EAEQF,cAAA,SACRtB,GAIA6F,EAAApE,UAAMH,cAAa8E,KAACpG,KAAAA,SAEhBA,GAAAA,EAASkV,UACZ/U,KAAK+U,QAAO3T,EAAA,CAAA,EAAQpB,KAAK+U,QAAYlV,EAAQkV,UAGnB,cAAvBlV,SAAAA,EAASiV,WACZ9U,KAAK8U,UAAY,CAAER,OAAQ,KAAMC,OAAQ,MACxB,MAAP1U,GAAAA,EAASiV,YACnB9U,KAAK8U,UAAS1T,EAAQ,CAAA,EAAApB,KAAK8U,UAAcjV,EAAQiV,YAG9CjV,MAAAA,GAAAA,EAASqV,kBACZlV,KAAKkV,gBAAkBrV,EAAQqV,gBAEjC,EAAC7T,EAEO4vB,gBAAA,SAAgBtc,EAAuBjR,GAAuBqJ,IAAAA,EACrE,GAAK/M,KAAKgiB,eAAkBhiB,KAAKgxB,mBAAjC,CAIA,IAAMlZ,EAAWpU,IAAe3G,EAAY8Q,OAE5C,OAAW7N,KAACiR,cAAc5B,cAAc,CACvCH,UAAWlP,KAAKgxB,mBAChB7hB,oBAAqB,CACpB,CACCnO,KAAMyM,GACN0E,MAAO,EACPpG,WAAY,CAAC4I,EAAY,GAAI3U,KAAKgiB,cAAc,KAEjD,CACChhB,KAAMyM,GACN0E,MAAO,EACPpG,WAAY4I,GAEb,CACC3T,KAAMyM,GACN0E,MAAO,EACPpG,WAAY,CAAC/L,KAAKgiB,cAAc,GAAIrN,EAAY,MAGlDvF,kBAAmB0I,GAAQ/K,EAAA,CAAA,EAAAA,EAEvBvP,EAAkBE,wBAAoBiE,EAASoL,GAEhD,CAAA,EACHhJ,QAAS+T,EACN,CACApU,WAAAA,EACA6R,OAAQvY,GAER,CAAE0G,WAAAA,IAjCN,CAmCD,EAACrC,EAEO+T,MAAA,WACP,GAAKpV,KAAKgxB,oBAAuBhxB,KAAK2U,aAItB3U,KAAKixB,gBAAgBjxB,KAAK2U,YAAa5X,EAAY8Q,QAEnE,CAIA,IAAMqB,EAAYlP,KAAKgxB,mBAEvBhxB,KAAKgiB,mBAAgBrgB,EACrB3B,KAAKgxB,wBAAqBrvB,EAC1B3B,KAAKmV,cAAWxT,EAEG,YAAf3B,KAAKsV,OACRtV,KAAKkC,aAGNlC,KAAK0C,SAASwM,EAAW,CACxBhO,KAAMlB,KAAKkB,KACXqU,OAAQvY,GAdT,CAgBD,EAACqE,EAEOmU,aAAA,SACPzT,EACAoT,OAA4BhF,OAA5B,IAAAgF,IAAAA,EAAqB,SAErBnV,KAAKgiB,cAAgB,CAACjgB,EAAMyG,IAAKzG,EAAM0G,KACvCzI,KAAK2U,YAAc,CAAC5S,EAAMyG,IAAKzG,EAAM0G,KAErC,IAAMnK,EAAU0B,KAAKiR,cAAc/C,cAAc,CAChD7K,YAAa,CACZ,CAACtB,EAAMyG,IAAKzG,EAAM0G,KAClB,CAAC1G,EAAMyG,IAAKzG,EAAM0G,KAClB,CAAC1G,EAAMyG,IAAKzG,EAAM0G,KAClB,CAAC1G,EAAMyG,IAAKzG,EAAM0G,KAClB,CAAC1G,EAAMyG,IAAKzG,EAAM0G,MAEnB9J,YAAUwR,GACTjP,KAAMlB,KAAKkB,MAAIiP,EACd3S,EAAkBE,oBAAoB,EAAIyS,KAG7CnQ,KAAKgxB,mBAAqB1yB,EAAQ4E,GAElClD,KAAKmV,SAAWA,EAChBnV,KAAKgC,YACN,EAACX,EAIDuU,gBAAA,WACC,MAC0B,eAAzB5V,KAAKkV,iBACoB,uBAAzBlV,KAAKkV,eAEP,EAAC7T,EAIDsU,gBAAA,WACC,MAC0B,oBAApBT,iBACoB,uBAAzBlV,KAAKkV,eAEP,EAAC7T,EAGDoT,MAAA,WACCzU,KAAKkC,aACLlC,KAAKc,UAAUd,KAAK+U,QAAQN,MAC7B,EAACpT,EAGDwU,KAAA,WACC7V,KAAK8V,UACL9V,KAAKmC,aACLnC,KAAKc,UAAU,QAChB,EAACO,EAGDqD,QAAA,SAAQ3C,GAEN/B,KAAK4V,oBACc,UAAjB7T,EAAMgU,QACP/V,KAAK6B,kBAAkB7B,KAAKE,cAAcZ,WAAYyC,IACpC,SAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcV,UAAWuC,IACrDA,EAAMiU,eACNhW,KAAK6B,kBAAkB7B,KAAKE,cAAcX,YAAawC,MAEpD/B,KAAKgiB,eAGThiB,KAAK2U,YAAc,CAAC5S,EAAMyG,IAAKzG,EAAM0G,KAErCzI,KAAKoV,SAJLpV,KAAKwV,aAAazT,GAOrB,EAACV,EAGDoD,YAAA,SAAY1C,GACX/B,KAAK2U,YAAc,CAAC5S,EAAMyG,IAAKzG,EAAM0G,KACrCzI,KAAKixB,gBAAgBjxB,KAAK2U,YAAa5X,EAAY4G,YACpD,EAACtC,EAGD6C,UAAA,WAAc7C,EAAAA,EAGd8C,QAAA,SAAQpC,GACHA,EAAMqD,MAAQpF,KAAK8U,UAAUR,OAChCtU,KAAK8V,UACK/T,EAAMqD,MAAQpF,KAAK8U,UAAUP,QACvCvU,KAAKoV,OAEP,EAAC/T,EAGD5B,YAAA,SACCsC,EACA4C,GAEmB,YAAf3E,KAAKsV,OAKRtV,KAAK6B,kBAAkB7B,KAAKE,cAAcT,YAAasC,IACvD/B,KAAK2V,oBAEL3V,KAAKwV,aAAazT,EAAO,QACzB4C,GAAmB,GAErB,EAACtD,EAGD3B,OAAA,SACCqC,EACA4C,GAGC3E,KAAK6B,kBAAkB7B,KAAKE,cAAcR,OAAQqC,IAClD/B,KAAK2V,mBACa,SAAlB3V,KAAKmV,WAELnV,KAAK2U,YAAc,CAAC5S,EAAMyG,IAAKzG,EAAM0G,KACrCzI,KAAKixB,gBAAgBjxB,KAAK2U,YAAa5X,EAAY4G,aAErD,EAACtC,EAGD1B,UAAA,SACCoC,EACA4C,GAGC3E,KAAK6B,kBAAkB7B,KAAKE,cAAcP,UAAWoC,IACrD/B,KAAK2V,mBACa,SAAlB3V,KAAKmV,WAELnV,KAAK2U,YAAc,CAAC5S,EAAMyG,IAAKzG,EAAM0G,KAErCzI,KAAKoV,QACLzQ,GAAmB,GAErB,EAACtD,EAGDyU,QAAA,WACC,IAAM0F,EAAYxb,KAAKgxB,mBAEvBhxB,KAAKgiB,mBAAgBrgB,EACrB3B,KAAKgxB,wBAAqBrvB,EAE1B3B,KAAKmV,cAAWxT,EAEG,YAAf3B,KAAKsV,OACRtV,KAAKkC,aAGNlC,KAAKiR,cAAcxB,uBAAuB+L,EAC3C,EAACna,EAGD6U,aAAA,SAAa5X,GACZ,IAAMmD,EAAML,EAAA,G7B7UN,CACN+U,iBAAkB,UAClBC,oBAAqB,UACrBC,oBAAqB,EACrBC,sBAAuB,EACvBC,mBAAoB,GACpBC,WAAY,UACZC,aAAc,EACdC,kBAAmB,UACnBC,oBAAqB,EACrBC,kBAAmB,EACnBC,WAAY,EACZC,gBAAiB,UACjBC,gBAAiB,EACjBC,kBAAmB,EACnBC,OAAQ,EACRC,eAAWvV,EACXwV,kBAAcxV,EACdyV,iBAAazV,EACb0V,oBAAgB1V,I6B4ThB,MACkB,YAAjBrD,EAAQ0C,MACkB,YAA1B1C,EAAQ6E,SAASnC,MACjB1C,EAAQK,WAAWuC,OAASlB,KAAKkB,MAEjCO,EAAO0U,iBAAmBnW,KAAK4E,wBAC9B5E,KAAKyB,OAAO6V,UACZ7V,EAAO0U,iBACP7X,GAGDmD,EAAO2U,oBAAsBpW,KAAK4E,wBACjC5E,KAAKyB,OAAO8V,aACZ9V,EAAO2U,oBACP9X,GAGDmD,EAAO6U,sBAAwBtW,KAAKgF,uBACnChF,KAAKyB,OAAOgW,eACZ,EACAnZ,GAGDmD,EAAO4U,oBAAsBrW,KAAKgF,uBACjChF,KAAKyB,OAAO+V,aACZ/V,EAAO4U,oBACP/X,GAGDmD,EAAO8U,mBAAqBvW,KAAKgF,uBAChChF,KAAKyB,OAAOiW,YACZjW,EAAO8U,mBACPjY,GAGDmD,EAAOwV,OAAS7Y,EAETqD,GAGDA,CACR,EAACJ,EAEDsB,gBAAA,SAAgBrE,GAAgBmQ,IAAAA,OAC/B,OAAOzO,KAAK4D,oBAAoBtF,EAAS,SAACqZ,GACzC,OAAA/K,EACC+K,EACAlJ,EAAKnO,oBACL,EAEH,EAACe,EAEDyB,oBAAA,SAAoBxE,GAGf0B,KAAKgxB,qBAAuB1yB,EAAQ4E,KACvClD,KAAKgiB,mBAAgBrgB,EACrB3B,KAAKgxB,wBAAqBrvB,EAC1B3B,KAAKmV,cAAWxT,EACG,YAAf3B,KAAKsV,OACRtV,KAAKkC,aAGR,EAACb,EAEDE,kBAAA,SAAkBc,GACjBrC,KAAKsa,YAAc,IAAIxB,GAAoBzW,GAC3CrC,KAAKiR,cAAgB,IAAIvD,GAAsBrL,EAAQ,CACtDjC,SAAUJ,KAAKI,UAEjB,EAAC2wB,CAAA,CA1VkC,CAAQnxB,GCnB/BsxB,gBAAoB,SAAAxrB,GAIhC,SAAAwrB,EAAYrxB,GAAsD8F,IAAAA,EACjE,IAAK9F,EAAQ+B,SACZ,MAAM,IAAIK,MAAM,iDAIW,OAD5B0D,EAAAD,EAAAO,UAAMpG,GAAS,UARTmB,KAAO9B,EAAUiyB,OAAMxrB,EACvBzE,KAAO,SAQbyE,EAAKxE,cAActB,GAAS8F,CAC7B,CAACU,EAAA6qB,EAAAxrB,GAAArE,IAAAA,EAAA6vB,EAAA5vB,UA0JA4vB,OA1JA7vB,EAEDF,cAAA,SACCtB,GAEA6F,EAAApE,UAAMH,cAAa8E,UAACpG,EACrB,EAACwB,EAGDE,kBAAA,SAAkBC,GAKjBxB,KAAKkB,KAAOM,EAAeN,IAC5B,EAACG,EAGDoT,MAAA,WACCzU,KAAKkC,YACN,EAACb,EAGDwU,KAAA,WACC7V,KAAKmC,YACN,EAACd,EAGD8C,QAAA,aAAY9C,EAGZ6C,UAAA,WAAc7C,EAAAA,EAGdqD,QAAA,aAAYrD,EAGZ5B,YAAA,WAAgB4B,EAAAA,EAGhB3B,OAAA,aAAW2B,EAGX1B,UAAA,aAAc0B,EAGdoD,YAAA,WAAgBpD,EAAAA,EAGhByU,QAAA,aAAYzU,EAGZ6U,aAAA,SAAa5X,GAGZ,MAAO,CACNkY,WAAYxW,KAAK4E,wBAChB5E,KAAKyB,OAAO+U,W9BtGF,U8BwGVlY,GAEDuY,WAAY7W,KAAKgF,uBAChBhF,KAAKyB,OAAOoV,W9BtGF,E8BwGVvY,GAEDmY,aAAczW,KAAKgF,uBAClBhF,KAAKyB,OAAOgV,a9B/GA,E8BiHZnY,GAEDoY,kBAAmB1W,KAAK4E,wBACvB5E,KAAKyB,OAAOiV,kB9BnHK,U8BqHjBpY,GAEDsY,kBAAmB5W,KAAKgF,uBACvBhF,KAAKyB,OAAOmV,kB9BtHK,E8BwHjBtY,GAEDqY,oBAAqB3W,KAAKgF,uBACzBhF,KAAKyB,OAAOkV,oB9B5HO,E8B8HnBrY,GAED6X,iBAAkBnW,KAAK4E,wBACtB5E,KAAKyB,OAAO0U,iB9BzII,U8B2IhB7X,GAEDiY,mBAAoBvW,KAAKgF,uBACxBhF,KAAKyB,OAAO8U,mB9B1IM,G8B4IlBjY,GAED8X,oBAAqBpW,KAAK4E,wBACzB5E,KAAKyB,OAAO2U,oB9BlJO,U8BoJnB9X,GAED+X,oBAAqBrW,KAAKgF,uBACzBhF,KAAKyB,OAAO4U,oB9BtJO,E8BwJnB/X,GAEDyY,gBAAiB/W,KAAKgF,uBACrBhF,KAAKyB,OAAOsV,gB9BjJG,E8BmJfzY,GAEDwY,gBAAiB9W,KAAK4E,wBACrB5E,KAAKyB,OAAOqV,gB9BvJG,U8ByJfxY,GAED0Y,kBAAmBhX,KAAKgF,uBACvBhF,KAAKyB,OAAOuV,kB9B1JK,E8B4JjB1Y,GAED2Y,OAAQjX,KAAKgF,uBACZhF,KAAKyB,OAAOwV,O9B9JN,E8BgKN3Y,GAED+Y,oBAAgB1V,EAElB,EAACN,EAEDsB,gBAAA,SAAgBrE,GACf,IAAM8yB,EAAgB1rB,EAAApE,UAASqB,gBAAesD,KAAC3H,KAAAA,GAC/C,GAAI8yB,EAAiB9tB,MAAO,CAC3B,IAAMyrB,EAAmBzwB,EAEnB+yB,EACLlC,GAAqBJ,EAAkB/uB,KAAKM,qBAC1CgD,OACFmJ,EAAuBsiB,EAAkB/uB,KAAKM,qBAC5CgD,OACF6c,GAA0B4O,EAAkB/uB,KAAKM,qBAC/CgD,MAEH,OAAI+tB,EACI,CAAE/tB,OAAO,GAGV,CACNA,MAAO+tB,EACP9tB,OAAQ,8DAEV,CAEA,OAAO6tB,CACR,EAACF,CAAA,CArK+B,CAAQtxB,YCrCzB0xB,GAAa7c,EAAiBiJ,GAC7C,IAAMjL,EAAOgC,EACP8c,EAAK7T,EAML8T,EAAOhqB,EAAiBiL,EAAK,IAC7Bgf,EAAOjqB,EAAiB+pB,EAAG,IAC7BG,EAAclqB,EAAiB+pB,EAAG,GAAK9e,EAAK,IAG5Cif,EAAc/qB,KAAKC,KACtB8qB,GAAe,EAAI/qB,KAAKC,IAErB8qB,GAAe/qB,KAAKC,KACvB8qB,GAAe,EAAI/qB,KAAKC,IAGzB,IAAM+qB,EAAWhrB,KAAKiC,IACrBjC,KAAKkC,IAAI4oB,EAAO,EAAI9qB,KAAKC,GAAK,GAAKD,KAAKkC,IAAI2oB,EAAO,EAAI7qB,KAAKC,GAAK,IAK5DgrB,GAAWhqB,EAFHjB,KAAKU,MAAMqqB,EAAaC,IAEK,KAAO,IAIlD,OAFgBC,EAAU,MAAQ,IAAMA,GAAWA,CAGpD,CC/BgB,SAAAC,GACf3oB,EACA4oB,EACA3oB,GAEA,IACI4oB,EAAmBD,EADKA,EAAiB,IAI5CC,GAAoBprB,KAAKqrB,IAAID,IAG9B,IAAME,EAAQF,EAAmBxqB,EAC3B2qB,EAAWhpB,EAAO,GAAKvC,KAAKC,GAAM,IAClC4qB,EAAOhqB,EAAiB0B,EAAO,IAC/BsX,EAAQhZ,EAAiB2B,GAEzBgpB,EAAWF,EAAQtrB,KAAKS,IAAIoZ,GAC9BiR,EAAOD,EAAOW,EAGdxrB,KAAKqrB,IAAIP,GAAQ9qB,KAAKC,GAAK,IAC9B6qB,EAAOA,EAAO,EAAI9qB,KAAKC,GAAK6qB,GAAQ9qB,KAAKC,GAAK6qB,GAG/C,IAAMW,EAAWzrB,KAAKiC,IACrBjC,KAAKkC,IAAI4oB,EAAO,EAAI9qB,KAAKC,GAAK,GAAKD,KAAKkC,IAAI2oB,EAAO,EAAI7qB,KAAKC,GAAK,IAG5DyrB,EAAI1rB,KAAKqrB,IAAII,GAAY,MAASD,EAAWC,EAAWzrB,KAAKS,IAAIoqB,GAMjEvoB,EAAc,EACN,KAJEipB,EADKD,EAAQtrB,KAAKQ,IAAIqZ,GAAU6R,GAK3B1rB,KAAKC,GAAK,KAAO,IAAO,IACpC,IAAP6qB,EAAc9qB,KAAKC,IAWrB,OANAqC,EAAY,IACXA,EAAY,GAAKC,EAAO,GAAK,KACzB,IACDA,EAAO,GAAKD,EAAY,GAAK,IAC5B,IACA,EACEA,CACR,CC7CM,SAAUqpB,GACfC,EACAC,EACApmB,EACAvL,EACAD,GAEA,IAAM6xB,EAAyB5xB,EAAQ0xB,EAAa,GAAIA,EAAa,IAC/DG,EAAyB7xB,EAAQ2xB,EAAa,GAAIA,EAAa,IAErEG,EAAqB/xB,GACnB6xB,EAAuB/pB,EAAIgqB,EAAuBhqB,GAAK,GACvD+pB,EAAuB9pB,EAAI+pB,EAAuB/pB,GAAK,GAF5CF,EAAGkqB,EAAHlqB,IAKb,MAAO,CAACX,EALG6qB,EAAHnqB,IAKoB4D,GAAYtE,EAAeW,EAAK2D,GAC7D,UAGgBwmB,GACfL,EACAC,EACApmB,GAEA,IAEMymB,EAAWhB,GAAiBU,EAFqC,IAA1DjsB,EAA4BisB,EAAcC,GAEA,EADvClB,GAAaiB,EAAcC,IAE3C,MAAO,CACN1qB,EAAe+qB,EAAS,GAAIzmB,GAC5BtE,EAAe+qB,EAAS,GAAIzmB,GAE9B,CClCgB,SAAA0mB,GAAsB/lB,GAcrC,IAFA,IAXAgmB,EAAahmB,EAAbgmB,cACA3mB,EAASW,EAATX,UACAxL,EAASmM,EAATnM,UACAC,EAAOkM,EAAPlM,QACAH,EAAUqM,EAAVrM,WAQMsyB,EAA6B,GAC1BnpB,EAAI,EAAGA,EAAIkpB,EAAcjtB,OAAS,EAAG+D,IAAK,CAClD,IAAIopB,SACJ,GAAmB,iBAAfvyB,EACHuyB,EAAMX,GACLS,EAAclpB,GACdkpB,EAAclpB,EAAI,GAClBuC,EACAvL,EACAD,OAESF,IAAe,UAAfA,EAOV,MAAM,IAAIuB,MAAM,sBANhBgxB,EAAML,GACLG,EAAclpB,GACdkpB,EAAclpB,EAAI,GAClBuC,EAIF,CAEA4mB,EAAejpB,KAAKkpB,EACrB,CACA,OAAOD,CACR,CCvBa,IAAAE,gBAAiB,SAAAvlB,GAC7B,SAAAulB,EACU7wB,EACQ8wB,EACAC,EACAniB,EACAqJ,EACAqC,GAAoC,IAAAhX,EAAA,OAErDA,EAAAgI,EAAA1H,KAAAjG,KAAMqC,IAAOrC,MAPJqC,YAAA,EAAAsD,EACQwtB,4BAAA,EAAAxtB,EACAytB,6BAAA,EAAAztB,EACAsL,mBAAAtL,EAAAA,EACA2U,iBAAA3U,EAAAA,EACAgX,mBAAAhX,EAAAA,EAKV0tB,WAA0B,GAVxB1tB,EAAMtD,OAANA,EACQsD,EAAsBwtB,uBAAtBA,EACAxtB,EAAuBytB,wBAAvBA,EACAztB,EAAasL,cAAbA,EACAtL,EAAW2U,YAAXA,EACA3U,EAAagX,cAAbA,EAAoChX,CAGtD,CAACU,EAAA6sB,EAAAvlB,GAAA,IAAAtM,EAAA6xB,EAAA5xB,UAsMA,OAtMAD,EAIOiyB,kBAAA,SAAkBjwB,GACzB,MAAO,CACN0vB,cAAe1vB,EACf+I,UAAWpM,KAAKM,oBAChBO,QAASb,KAAKqC,OAAOxB,QACrBD,UAAWZ,KAAKqC,OAAOzB,UACvBF,WAAYV,KAAKqC,OAAO3B,WAE1B,EAACW,EAQMkyB,mBAAA,SAAmBxxB,GAA0B0M,IAAAA,EACnDzO,KAAIwzB,EAA0BtnB,SAC1BunB,OAA2C9xB,EAe/C,OAbA3B,KAAKykB,IAAInH,QAAQ,SAACpa,GACjB,IAAMC,EAAWsL,EAAK6L,YAAYpB,YAAmBhW,GAC/CyE,EAAW8G,EAAKkO,cAAcJ,QAAQxa,EAAOoB,EAASE,aAG3DsE,EAAW8G,EAAKpO,iBAChBsH,EAAW6rB,IAEXA,EAA0B7rB,EAC1B8rB,EAAoBvwB,EAEtB,GAEOuwB,CACR,EAACpyB,EAEMqyB,OAAA,SAAM3mB,GAMZ,IALAmC,EAASnC,EAATmC,UACAykB,EAAU5mB,EAAV4mB,WAKMC,EAAW5zB,KAAKsa,YAAYpB,YAAYya,GAC9ChZ,EACC3a,KAAKsa,YAAYf,cAAcoa,GADxBE,EAAiBlZ,EAAjBkZ,kBAAmBC,EAAenZ,EAAfmZ,gBAErB3wB,EAAWnD,KAAKsa,YAAYpB,YACjC2a,GAGKrjB,EAAS,CACdtB,UAAW2kB,EACX1kB,oBAAqB,CACpB,CACCnO,KAAMyM,EACN0E,MAAO2hB,EACP/nB,WAAY6nB,EAASvwB,cAGvBU,QAAS,CACRL,WAAY3G,EAAY0T,SAItBwZ,EAA6D,KAEjE,GAAsB,YAAlB9mB,EAASnC,KACZipB,EAAUjqB,KAAKiR,cAAc5B,cAAcmB,OACrC,IAAsB,eAAlBrN,EAASnC,KAGnB,MAAM,IAAIiB,MAAM,0DAFhBgoB,EAAUjqB,KAAKiR,cAAc1B,iBAAiBiB,EAG/C,CAEA,IAAKyZ,EACJ,MAAU,IAAAhoB,MAAM,wCAGjB,IAAMiiB,EAAqB+F,EAAQ9mB,SAASE,YAGlBrD,KAAKsa,YAAYf,cAAcrK,GAEnC1R,EAAkBQ,uBACvCgC,KAAKozB,wBAAwB/N,eAAe,CAC3CnW,UAAAA,EACAgV,mBAAAA,IAOFlkB,KAAKiR,cAActB,wBAAuBxJ,GAAAA,OACtCnG,KAAKmzB,uBAAuB1O,IAC5BzkB,KAAKqzB,aAKTrzB,KAAK2T,OAAO,CACXuQ,mBAAAA,EACAhV,UAAW2kB,IAGZ7zB,KAAKmzB,uBAAuBxf,OAAO,CAClCuQ,mBAAAA,EACAhV,UAAWA,GAEb,EAAC7N,EAEMsS,OAAA,SAAM1F,GAMZ4B,IAAAA,OALAqU,EAAkBjW,EAAlBiW,mBACAhV,EAASjB,EAATiB,UAKA,IAAKlP,KAAKsa,YAAYd,WAAWtK,GAChC,MAAM,IAAIjN,MAAM,4CAGjB,IAAMoB,EAAc8gB,GAAqBD,GACnC6P,EAAYjB,GACjB9yB,KAAKszB,kBAAkBjwB,IAGxBrD,KAAKqzB,WAAarzB,KAAKiR,cAAc1C,qBAAqB,CACzDG,qBAAsB,SAAC7E,GAACsE,IAAAA,EAAAA,OAAAA,EACvBjN,CAAAA,KAAM2O,EAAK3O,KACX4yB,gBAAiBjqB,EACjBgqB,kBAAmB3kB,IAClB/R,EAAkBE,YAAY,EAAI8Q,CAAA,EAEpC9K,YAAa0wB,EACb/yB,KAAM7D,EAAkBE,WAE1B,EAACgE,SAEM,WACDrB,KAAKqzB,WAAWvtB,SAIrB9F,KAAKiR,cAActB,wBAAwB3P,KAAKqzB,YAChDrzB,KAAKqzB,WAAa,GACnB,EAAChyB,EAEM8kB,iBAAA,SAAgB7X,GAKtB,GAA+B,IAA3BtO,KAAKqzB,WAAWvtB,OAApB,CAIA,IAAMzC,EAAc8gB,GARF7V,EAAlB4V,oBASM6P,EAAYjB,GACjB9yB,KAAKszB,kBAAkBjwB,IAGxBrD,KAAKiR,cAAcP,qBAClB1Q,KAAKqzB,WAAWzkB,IAAI,SAAC1L,EAAI2G,GAAO,MAAA,CAC/BqF,UAAWhM,EACX6I,WAAYgoB,EAAUlqB,GACtB,GAXF,CAaD,EAACxI,EAEM6kB,iBAAA,SACN/T,EACA+R,GAOA,GALI/R,EAAQ,IAEXA,EAAQnS,KAAKqzB,WAAWvtB,OAASqM,QAGHxQ,IAA3B3B,KAAKqzB,WAAWlhB,GAApB,CAIA,IAAM9O,EAAc8gB,GAAqBD,GACnC6P,EAAYjB,GACjB9yB,KAAKszB,kBAAkBjwB,IAGxBrD,KAAKiR,cAAcP,qBAAqB,CACvC,CACCxB,UAAWlP,KAAKqzB,WAAWlhB,GAC3BpG,WAAYgoB,EAAU5hB,KAVxB,CAaD,EAAChN,EAAA+tB,EAAA,CAAA,CAAA9tB,IAAAC,MAAAA,IAxLD,WACC,OAAWrF,KAACqzB,WAAWltB,QACxB,EAACb,IAED,SAAQC,GAAc,IAAI,CA5BG,CAAQuH,GCNzBknB,yBAAuBrmB,GACnC,SAAAqmB,EACC3xB,EACAgiB,GAA4C1e,IAAAA,EAGD,OAD3CA,EAAAgI,EAAA1H,UAAM5D,UAIC4O,mBAAatL,EAAAA,EAEbsuB,iBAAgC,GALvCtuB,EAAKsL,cAAgBoT,EAAsB1e,CAC5C,CAACU,EAAA2tB,EAAArmB,OAAAtM,EAAA2yB,EAAA1yB,iBAAAD,EAYMsS,OAAA,SAAM5G,GACZ,IAAAmC,EAASnC,EAATmC,UAMM7L,EAAc4gB,GALFlX,EAAlBmX,oBAOAlkB,KAAKi0B,iBAAmBj0B,KAAKiR,cAAc1C,qBAAqB,CAC/DlL,YAAAA,EACArC,KAAM7D,EAAkBI,gBACxBmR,qBAAsB,SAACyD,GAAKlE,IAAAA,SAAAA,EAAA,CAAA,GAC1B9Q,EAAkBG,4BAA6B4R,EAASjB,EACzDkE,MAAAA,EAAKlE,CAAA,GAGR,EAAC5M,EAEM,OAAA,WACDrB,KAAKykB,IAAI3e,SAId9F,KAAKiR,cAActB,wBAAwB3P,KAAKykB,KAChDzkB,KAAKi0B,iBAAmB,GACzB,EAAC5yB,EAEM8kB,iBAAA,SAAgBhY,GAKtB,GAAqC,IAAjCnO,KAAKi0B,iBAAiBnuB,OAA1B,CAIA,IAAMzC,EAAc4gB,GARF9V,EAAlB+V,oBAUI7gB,EAAYyC,SAAW9F,KAAKi0B,iBAAiBnuB,QAIjD9F,KAAKiR,cAAcP,qBAClB1Q,KAAKi0B,iBAAiBrlB,IAAI,SAAC1L,EAAI2G,SAAO,CACrCqF,UAAWhM,EACX6I,WAAY1I,EAAYwG,GACxB,GAZF,CAcD,EAACxI,EAEM6kB,iBAAA,SAAiB/T,EAAewS,QACDhjB,IAAjC3B,KAAKi0B,iBAAiB9hB,IAI1BnS,KAAKiR,cAAcP,qBAAqB,CACvC,CACCxB,UAAWlP,KAAKi0B,iBAAiB9hB,GACjCpG,WAAY4Y,IAGf,EAACxf,EAAA6uB,EAAA5uB,CAAAA,CAAAA,UAAAC,IApED,WACC,YAAY4uB,iBAAiB9tB,QAC9B,EAACb,IAED,SAAQC,SAjBmCuH,YCT5BonB,GAAehY,EAAiBiY,GAE/C,IADA,IAYqBC,EAAaC,EAAcC,EAZ5CC,GAAS,EACJ1qB,EAAI,EAAG2qB,EAAML,EAAMruB,OAAQ+D,EAAI2qB,EAAK3qB,IAE5C,IADA,IAAM4qB,EAAON,EAAMtqB,GACV6qB,EAAI,EAAGC,EAAOF,EAAK3uB,OAAQ8uB,EAAID,EAAO,EAAGD,EAAIC,EAAMC,EAAIF,KAS/BL,EARRI,EAAKC,IAU3B,IAFiBN,EARFlY,GAUR,KAFqCoY,EARbG,EAAKG,IAUnB,GAAKR,EAAE,IAC3BA,EAAE,IAAOE,EAAG,GAAKD,EAAG,KAAOD,EAAE,GAAKC,EAAG,KAAQC,EAAG,GAAKD,EAAG,IAAMA,EAAG,KAV/DE,GAAUA,GAIb,OAAOA,CACR,CCfO,IAAMM,GAAsB,SAClC3Y,EACA4Y,EACAC,GAEA,IAAMC,EAAS,SAACtsB,GACf,OAAOA,EAAIA,CACZ,EACMusB,EAAQ,SAAC5U,EAAmB6U,GACjC,OAAOF,EAAO3U,EAAE3X,EAAIwsB,EAAExsB,GAAKssB,EAAO3U,EAAE1X,EAAIusB,EAAEvsB,EAC3C,EAkBA,OAAOhC,KAAKW,KAjBiB,SAC5B8sB,EACA/T,EACA6U,GAEA,IAAMC,EAAKF,EAAM5U,EAAG6U,GAEpB,GAAW,IAAPC,EACH,OAAOF,EAAMb,EAAG/T,GAGjB,IAAIuB,IAAMwS,EAAE1rB,EAAI2X,EAAE3X,IAAMwsB,EAAExsB,EAAI2X,EAAE3X,IAAM0rB,EAAEzrB,EAAI0X,EAAE1X,IAAMusB,EAAEvsB,EAAI0X,EAAE1X,IAAMwsB,EAGlE,OAFAvT,EAAIjb,KAAK6T,IAAI,EAAG7T,KAAK4T,IAAI,EAAGqH,IAErBqT,EAAMb,EAAG,CAAE1rB,EAAG2X,EAAE3X,EAAIkZ,GAAKsT,EAAExsB,EAAI2X,EAAE3X,GAAIC,EAAG0X,EAAE1X,EAAIiZ,GAAKsT,EAAEvsB,EAAI0X,EAAE1X,IACnE,CAEiBysB,CAAqBlZ,EAAO4Y,EAAcC,GAC5D,ECrBaM,gBAA8B,SAAA1nB,GAC1C,SAAA0nB,EACUhzB,EACQizB,EACA3Y,GAAoC,IAAAhX,EAAA,OAErDA,EAAAgI,EAAA1H,KAAAjG,KAAMqC,IAAQsD,MAJLtD,YAAAsD,EAAAA,EACQ2vB,4BAAA3vB,EAAAA,EACAgX,mBAFRhX,EAAAA,EAAMtD,OAANA,EACQsD,EAAsB2vB,uBAAtBA,EACA3vB,EAAagX,cAAbA,EAAoChX,CAGtD,CAoFC,OApFAU,EAAAgvB,EAAA1nB,GAAA0nB,EAAA/zB,UAEMi0B,KAAA,SAAKxzB,EAA4ByzB,GAUvC,IATA,IAAIC,OAAiD9zB,EACjD+zB,EAAuBxpB,SACvBypB,OAAsDh0B,EACtDi0B,EAA4B1pB,SAC5B2pB,OAAmDl0B,EAEjDsb,EAAOjd,KAAKs1B,uBAAuB3hB,OAAO5R,GAC1C4M,EAAW3O,KAAKS,MAAMyc,OAAOD,GAE1BpT,EAAI,EAAGA,EAAI8E,EAAS7I,OAAQ+D,IAAK,CACzC,IAAMvL,EAAUqQ,EAAS9E,GACnB1G,EAAW7E,EAAQ6E,SAEzB,GAAsB,UAAlBA,EAASnC,KAAkB,CAQ9B,GALyB1C,EAAQK,WAAWm3B,gBAClBx3B,EAAQK,WAAWytB,kBAE3CoJ,GAAgBl3B,EAAQK,WAAWxB,EAAkBE,WAGtD,SAGD,IAAMsK,EAAW3H,KAAK2c,cAAcJ,QACnCxa,EACAoB,EAASE,cAIR/E,EAAQK,WAAWxB,EAAkBE,YACtCsK,EAAW3H,KAAKK,iBAChBsH,EAAW+tB,IAEXA,EAAuB/tB,EACvB8tB,EAAen3B,EAEjB,MAAO,GAAsB,eAAlB6E,EAASnC,KAAuB,CAC1C,GAAIy0B,EACH,SAGD,IAAK,IAAI5rB,EAAI,EAAGA,EAAI1G,EAASE,YAAYyC,OAAS,EAAG+D,IAAK,CACzD,IAAMI,EAAQ9G,EAASE,YAAYwG,GAC7BksB,EAAY5yB,EAASE,YAAYwG,EAAI,GACrCmsB,EAAiBnB,GACtB,CAAEnsB,EAAG3G,EAAMgZ,WAAYpS,EAAG5G,EAAMiZ,YAChChb,KAAKa,QAAQoJ,EAAM,GAAIA,EAAM,IAC7BjK,KAAKa,QAAQk1B,EAAU,GAAIA,EAAU,KAIrCC,EAAiBh2B,KAAKK,iBACtB21B,EAAiBJ,IAEjBA,EAA4BI,EAC5BL,EAAoBr3B,EAEtB,CACD,MAAO,GAAsB,YAAlB6E,EAASnC,KAAoB,CACvC,GAAIy0B,GAAgBE,EAGnB,SAG0BzB,GAC1B,CAACnyB,EAAMyG,IAAKzG,EAAM0G,KAClBtF,EAASE,eAITwyB,EAAiBv3B,EAEnB,CACD,CAEA,MAAO,CACNgxB,eAAgBmG,GAAgBE,GAAqBE,EAEvD,EAACR,CAAA,CA3FyC,CAAQvoB,GCUtCmpB,yBAAoBtoB,GAChC,SAAAsoB,EACU5zB,EACQ6zB,EACAC,EACAC,EACA/P,EACA/L,EACArJ,GAAoCtL,IAAAA,EAAA,OAErDA,EAAAgI,EAAA1H,KAAM5D,KAAAA,IAAOrC,MARJqC,YAAAsD,EAAAA,EACQuwB,2BAAAvwB,EAAAA,EACAwwB,qBAAAxwB,EAAAA,EACAywB,eAAAzwB,EAAAA,EACA0gB,sBAAA1gB,EAAAA,EACA2U,iBAAA3U,EAAAA,EACAsL,mBAAAtL,EAAAA,EAKV0wB,iBAAqC,KAAI1wB,EAEzC2wB,kBAbE3wB,EAAAA,EAAMtD,OAANA,EACQsD,EAAqBuwB,sBAArBA,EACAvwB,EAAewwB,gBAAfA,EACAxwB,EAASywB,UAATA,EACAzwB,EAAgB0gB,iBAAhBA,EACA1gB,EAAW2U,YAAXA,EACA3U,EAAasL,cAAbA,EAAoCtL,CAGtD,CAACU,EAAA4vB,EAAAtoB,GAAAtM,IAAAA,EAAA40B,EAAA30B,UAkMA,OAlMAD,EAMDk1B,cAAA,SAAcx0B,EAA4BmB,GACzClD,KAAKq2B,iBAAmBnzB,EACxBlD,KAAKs2B,aAAe,CAACv0B,EAAMyG,IAAKzG,EAAM0G,IACvC,EAACpH,EAEDm1B,aAAA,WACCx2B,KAAKq2B,iBAAmB,KACxBr2B,KAAKs2B,kBAAe30B,CACrB,EAACN,EAEDo1B,WAAA,WACC,OAAiC,OAA1Bz2B,KAAKq2B,gBACb,EAACh1B,EAEDq1B,QAAA,SAAQ30B,EAA4BkC,GACnC,IAAQqrB,EAAmBtvB,KAAKk2B,sBAAsBX,KAAKxzB,GAAO,GAA1DutB,eAIR,SAAKA,GAAkBA,EAAepsB,KAAOe,EAK9C,EAAC5C,EAEDs1B,KAAA,SAAK50B,GACJ,GAAK/B,KAAKq2B,iBAAV,CAIA,IAAMlzB,EAAWnD,KAAKsa,YAAYpB,YAAYlZ,KAAKq2B,kBAC7CO,EAAc,CAAC70B,EAAMyG,IAAKzG,EAAM0G,KAGtC,GAAsB,YAAlBtF,EAASnC,MAAwC,eAAlBmC,EAASnC,KAAuB,CAClE,IAAI61B,EACAC,EAWJ,GAPCA,EAFqB,YAAlB3zB,EAASnC,MACZ61B,EAAgB1zB,EAASE,YAAY,IACXyC,OAAS,GAGnC+wB,EAAgB1zB,EAASE,aACCyC,QAGtB9F,KAAKs2B,aACT,OAAO,EAGR,IAAK,IAAIzsB,EAAI,EAAGA,EAAIitB,EAAWjtB,IAAK,CACnC,IAAMkC,EAAa8qB,EAAchtB,GAE7BktB,OACJ,EAAIC,OAEJ,EAAA,GAA+B,iBAA3Bh3B,KAAKqC,OAAO3B,WAA+B,CAC9C,IAAMu2B,EAA0B1uB,EAC/BvI,KAAKs2B,aAAa,GAClBt2B,KAAKs2B,aAAa,IAEbY,EAAyB3uB,EAC9BquB,EAAY,GACZA,EAAY,IAEPO,EAAwB5uB,EAC7BwD,EAAW,GACXA,EAAW,IAGNkmB,EAAQ,CACbvpB,EAAGuuB,EAAwBvuB,EAAIwuB,EAAuBxuB,EACtDC,EAAGsuB,EAAwBtuB,EAAIuuB,EAAuBvuB,GAMvD+P,EAAqB5P,EAHJquB,EAAsBzuB,EAAIupB,EAAMvpB,EAChCyuB,EAAsBxuB,EAAIspB,EAAMtpB,GAIjDouB,EAFWre,EAAHlQ,IAGRwuB,EAHgBte,EAAHjQ,GAId,KAAO,CACN,IAAMwpB,EAAQ,CACbjyB,KAAKs2B,aAAa,GAAKM,EAAY,GACnC52B,KAAKs2B,aAAa,GAAKM,EAAY,IAEpCG,EAAahrB,EAAW,GAAKkmB,EAAM,GACnC+E,EAAajrB,EAAW,GAAKkmB,EAAM,EACpC,CAgBA,GAbA8E,EAAajvB,EACZivB,EACA/2B,KAAKqC,OAAO/B,qBAGb02B,EAAalvB,EACZkvB,EACAh3B,KAAKqC,OAAO/B,qBAOZy2B,EAAa,KACbA,GAAc,KACdC,EAAa,IACbA,GAAc,GAEd,OAAY,EAGbH,EAAchtB,GAAK,CAACktB,EAAYC,EACjC,CAIsB,YAAlB7zB,EAASnC,OACZ61B,EAAcA,EAAc/wB,OAAS,GAAK,CACzC+wB,EAAc,GAAG,GACjBA,EAAc,GAAG,KAInB,IAAM3nB,EAAYlP,KAAKq2B,iBAEnBpM,EAA6D,KAEjE,GAAsB,YAAlB9mB,EAASnC,KACZipB,EAAUjqB,KAAKiR,cAAc5B,cAAc,CAC1CH,UAAAA,EACAC,oBAAqB,CACpBnO,KAAMyM,GACNpK,YAAa,CAACwzB,IAEf9yB,QAAS,CACRL,WAAY3G,EAAY4G,mBAGpB,IAAsB,eAAlBR,EAASnC,KAYnB,OAXAipB,EAAUjqB,KAAKiR,cAAc1B,iBAAiB,CAC7CL,UAAAA,EACAC,oBAAqB,CACpBnO,KAAMyM,GACNpK,YAAawzB,GAEd9yB,QAAS,CACRL,WAAY3G,EAAY4G,cAK3B,CAEA,IAAKsmB,EACJ,OAAO,EAGR,IAAM/F,EAAqB+F,EAAQ9mB,SAASE,YAG5CrD,KAAKo2B,UAAUjQ,iBAAiB,CAAEjC,mBAAAA,IAClClkB,KAAKm2B,gBAAgBhQ,iBAAiB,CAAEjC,mBAAAA,IACxClkB,KAAKqmB,iBAAiBF,iBAAiB,CAAEjX,UAAAA,EAAWgV,mBAAAA,IAEpDlkB,KAAKs2B,aAAe,CAACv0B,EAAMyG,IAAKzG,EAAM0G,IAGvC,KAA6B,UAAlBtF,EAASnC,OAGnBhB,KAAKiR,cAAclC,YAAY,CAC9BG,UAAWlP,KAAKq2B,iBAChBlnB,oBAAqB,CACpBnO,KAAMyM,GACNpK,YAAauzB,GAEd7yB,QAAS,CACRL,WAAY3G,EAAY4G,eAI1B3D,KAAKs2B,aAAe,CAACv0B,EAAMyG,IAAKzG,EAAM0G,KA7JvC,CA+JD,EAACwtB,CAAA,EA7MuCnpB,GCG5BsqB,gBAAuB,SAAAzpB,GACnC,SAAAypB,EACU/0B,EACQsa,EACAwZ,EACAC,EACA/P,EACAiD,EACAE,EACAlP,EACArJ,GAAoCtL,IAAAA,EAAA,OAErDA,EAAAgI,EAAA1H,KAAM5D,KAAAA,IAAOrC,MAVJqC,YAAA,EAAAsD,EACQgX,mBAAAhX,EAAAA,EACAwwB,qBAAA,EAAAxwB,EACAywB,eAAAzwB,EAAAA,EACA0gB,sBAAA1gB,EAAAA,EACA2jB,0BAAA3jB,EACA6jB,kBAAA,EAAA7jB,EACA2U,iBAAA3U,EAAAA,EACAsL,mBAAA,EAAAtL,EAKV0xB,kBAA6D,CACpEn0B,GAAI,KACJiP,OAAQ,GAfCxM,EAAMtD,OAANA,EACQsD,EAAagX,cAAbA,EACAhX,EAAewwB,gBAAfA,EACAxwB,EAASywB,UAATA,EACAzwB,EAAgB0gB,iBAAhBA,EACA1gB,EAAkB2jB,mBAAlBA,EACA3jB,EAAY6jB,aAAZA,EACA7jB,EAAW2U,YAAXA,EACA3U,EAAasL,cAAbA,EAAoCtL,CAGtD,CAACU,EAAA+wB,EAAAzpB,GAAAtM,IAAAA,EAAA+1B,EAAA91B,UA6QA81B,OA7QA/1B,EAOOi2B,qBAAA,SACPv1B,EACAoB,GAEA,IAMIo0B,EANEC,EAAoB,CACzBha,KAAMtR,SACNiG,OAAQ,EACRslB,2BAA2B,GAK5B,GAAsB,eAAlBt0B,EAASnC,KACZu2B,EAAkBp0B,EAASE,gBACjBF,IAAkB,YAAlBA,EAASnC,KAKnB,OAAOw2B,EAJPD,EAAkBp0B,EAASE,YAAY,EAKxC,CAIA,IAAK,IAAIwG,EAAI,EAAGA,EAAI0tB,EAAgBzxB,OAAQ+D,IAAK,CAChD,IACMlC,EAAW3H,KAAK2c,cAAcJ,QAAQxa,EAD9Bw1B,EAAgB1tB,IAG9B,GACClC,EAAW3H,KAAKK,iBAChBsH,EAAW6vB,EAAkBha,KAC5B,CAID,IAAMia,EACa,YAAlBt0B,EAASnC,OACR6I,IAAM0tB,EAAgBzxB,OAAS,GAAW,IAAN+D,GAEtC2tB,EAAkBha,KAAO7V,EACzB6vB,EAAkBrlB,MAAQslB,EAA4B,EAAI5tB,EAC1D2tB,EAAkBC,0BAA4BA,CAC/C,CACD,CAEA,OAAOD,CACR,EAACn2B,EAEMq2B,aAAA,SAAa31B,EAA4BkC,GAC/C,IAAMd,EAAWnD,KAAKsa,YAAYpB,YAAYjV,GAG9C,OAF0BjE,KAAKs3B,qBAAqBv1B,EAAOoB,EAG5D,EAAC9B,EAEMs2B,kBAAA,SACN51B,EACAkC,GAEA,IAAMd,EAAWnD,KAAKsa,YAAYpB,YAAYjV,GACxCuzB,EAAoBx3B,KAAKs3B,qBAAqBv1B,EAAOoB,GAG3D,OAAiC,IAA7Bq0B,EAAkBrlB,OACb,EAEFqlB,EAAkBrlB,KAC1B,EAAC9Q,EAEO2oB,eAAA,SACPjoB,EACAymB,EACAoP,GAAoCnpB,IAc/Bmf,EAUAA,EAUAA,EAlC+Bnf,EAEpCzO,KAAI+pB,EAA8B,CAAChoB,EAAMyG,IAAKzG,EAAM0G,KAG9CsH,EAAS,SAACzR,GACf,OAAOC,QACND,EAAQK,YACPL,EAAQK,WAAWuC,OAAS02B,EAAej5B,WAAWuC,MACtD5C,EAAQ4E,KAAOuL,EAAK4oB,kBAAkBn0B,GAEzC,EA2CA,OAzCIslB,MAAAA,GAAAA,EAAUsF,SAGbF,EAAU5tB,KAAKwpB,aAAa1M,aAAa/a,EAAOgO,GAAQhE,cAGvDge,EAAoB6D,GAIlBpF,EAASuF,eAGZH,EAAU5tB,KAAKspB,mBAAmBxM,aAAa/a,EAAOgO,GAAQhE,cAG7Dge,EAAoB6D,GAIV,MAARpF,GAAAA,EAAUwF,WAGbJ,EAAUpF,EAASwF,SAASjsB,EAAO,CAClC2lB,kBAAmB1nB,KAAKq3B,kBAAkBllB,MAC1C8D,UAAW2hB,EAAe10B,GAC1B+qB,2BAA4B2J,EAAe10B,GACxC,WACA,OAAAuL,EAAK6L,YAAYpB,YAChB0e,EAAe10B,GACf,EACD,WAAM,OAAA,IAAI,EACbrC,QAASb,KAAKa,QACdD,UAAWZ,KAAKY,eAIhBmpB,EAAoB6D,GAIf7D,CACR,EAAC1oB,EAEDs1B,KAAA,SACC50B,EACA81B,EACArP,GAEA,IAAM6N,EAAmBr2B,KAAKq3B,kBAAkBn0B,GAEhD,GAAyB,OAArBmzB,EACH,OAAY,EAGb,IAAMlkB,EAAQnS,KAAKq3B,kBAAkBllB,MAC/BhP,EAAWnD,KAAKsa,YAAYpB,YAAYmd,GACxC13B,EAAaqB,KAAKsa,YAAYf,cAAc8c,GAE5CzR,EACa,eAAlBzhB,EAASnC,KACNmC,EAASE,YACTF,EAASE,YAAY,GAGnBo0B,EACa,YAAlBt0B,EAASnC,OACRmR,IAAUyS,EAAmB9e,OAAS,GAAe,IAAVqM,GASvCwS,EAAoB3kB,KAAKgqB,eAC9BjoB,EACAymB,EAT4C,CAC5CxnB,KAAM,UACNkC,GAAImzB,EACJlzB,SAAAA,EACAxE,WAAAA,IAYD,GACCoD,EAAMyG,IAAM,KACZzG,EAAMyG,KAAO,KACbzG,EAAM0G,IAAM,IACZ1G,EAAM0G,KAAO,GAEb,OAAY,EAKb,GAAIgvB,EAA2B,CAC9B,IAAMK,EAAiBlT,EAAmB9e,OAAS,EACnD8e,EAAmB,GAAKD,EACxBC,EAAmBkT,GAAkBnT,CACtC,MACCC,EAAmBzS,GAASwS,EAG7B,GACmB,UAAlBxhB,EAASnC,OACR62B,GACD7tB,EAAe,CACdhJ,KAAM,UACNmC,SAAUA,EACVxE,WAAY,CACQ,IAErB,OAAY,EAGb,IAAMuQ,EAAYmnB,EAEdpM,EAAuC,KA0B3C,MAxBsB,YAAlB9mB,EAASnC,KACZipB,EAAUjqB,KAAKiR,cAAc5B,cAAc,CAC1CH,UAAAA,EACAC,oBAAqB,CACpBnO,KAAMyM,GACNpK,YAAa,CAACuhB,IAEf7gB,QAAS,CACRL,WAAY3G,EAAY4G,eAGE,eAAlBR,EAASnC,OACnBipB,EAAUjqB,KAAKiR,cAAc1B,iBAAiB,CAC7CL,UAAAA,EACAC,oBAAqB,CACpBnO,KAAMyM,GACNpK,YAAauhB,GAEd7gB,QAAS,CACRL,WAAY3G,EAAY4G,kBAKtBsmB,IAMJjqB,KAAKo2B,UAAUlQ,iBADZ/T,EAAQ,EACqBA,EAAQ,GAEP,EAFUyS,GAI5C5kB,KAAKo2B,UAAUlQ,iBAAiB/T,EAAOyS,GACvC5kB,KAAKm2B,gBAAgBjQ,iBAAiB/T,EAAOwS,GAC7C3kB,KAAKqmB,iBAAiBH,iBAAiBhX,EAAWiD,EAAOwS,IAE9C,EACZ,EAACtjB,EAEDo1B,WAAA,WACC,OAAqC,YAAzBY,kBAAkBn0B,EAC/B,EAAC7B,EAEDk1B,cAAA,SAAcrzB,EAAeiP,GAC5BnS,KAAKq3B,kBAAoB,CACxBn0B,GAAAA,EACAiP,MAAAA,EAEF,EAAC9Q,EAEDm1B,aAAA,WACCx2B,KAAKq3B,kBAAoB,CACxBn0B,GAAI,KACJiP,OAAQ,EAEV,EAACilB,CAAA,CA1RkC,CAAQtqB,GClBtC,SAAUirB,GAASC,GACxB,IAAIC,EAAO,EACPC,EAAO,EACP1D,EAAM,EAaV,OAV2B,YAA1BwD,EAAQ70B,SAASnC,KACdg3B,EAAQ70B,SAASE,YAAY,GAAG2O,MAAM,GAAI,GAC1CgmB,EAAQ70B,SAASE,aAETia,QAAQ,SAACrT,GACpBguB,GAAQhuB,EAAM,GACdiuB,GAAQjuB,EAAM,GACduqB,GACD,GAAG,GAEI,CAACyD,EAAOzD,EAAK0D,EAAO1D,EAC5B,CC2Ba,IAAA2D,GAA6B,SACzC75B,EACAia,GAEA,GAAc,IAAVA,GAAyB,MAAVA,IAA4B,MAAXA,EACnC,OAAOja,EAGR,IAMM85B,EANqB,oBAMV7f,EAGX8f,GANqB,YAA1B/5B,EAAQ6E,SAASnC,KACd1C,EAAQ6E,SAASE,YAAY,GAC7B/E,EAAQ6E,SAASE,aAIiBuL,IAAI,SAAA7B,GACzC,OAAAxE,EAD8CwE,EAAEtE,GAAGsE,EACnD,GAA+B,GAI1BgrB,EAAWM,EAAkBC,OAClC,SAACC,EAAqBtuB,GAA2B,MAAA,CAChDvB,EAAG6vB,EAAI7vB,EAAIuB,EAAMvB,EACjBC,EAAG4vB,EAAI5vB,EAAIsB,EAAMtB,EACjB,EACD,CAAED,EAAG,EAAGC,EAAG,IAEZovB,EAASrvB,GAAK2vB,EAAkBvyB,OAChCiyB,EAASpvB,GAAK0vB,EAAkBvyB,OAGhC,IAYM0yB,EAZ2BH,EAAkBzpB,IAAI,SAAC3E,GAAK,MAAM,CAClEvB,EACCqvB,EAASrvB,GACRuB,EAAMvB,EAAIqvB,EAASrvB,GAAK/B,KAAKS,IAAIgxB,IACjCnuB,EAAMtB,EAAIovB,EAASpvB,GAAKhC,KAAKQ,IAAIixB,GACnCzvB,EACCovB,EAASpvB,GACRsB,EAAMvB,EAAIqvB,EAASrvB,GAAK/B,KAAKQ,IAAIixB,IACjCnuB,EAAMtB,EAAIovB,EAASpvB,GAAKhC,KAAKS,IAAIgxB,GACnC,GAGmDxpB,IACnD,SAAAX,GAAA,IAAGvF,EAACuF,EAADvF,EAAGC,EAACsF,EAADtF,EACL,MAAA,CACCG,EAAsBJ,EAAGC,GAAGH,IAC5BM,EAAsBJ,EAAGC,GAAGF,IAChB,GASf,MAN8B,YAA1BnK,EAAQ6E,SAASnC,KACpB1C,EAAQ6E,SAASE,YAAY,GAAKm1B,EAElCl6B,EAAQ6E,SAASE,YAAcm1B,EAGzBl6B,CACR,WCnGgBm6B,GAAoBn6B,GACnC,IAKMo6B,GAJqB,YAA1Bp6B,EAAQ6E,SAASnC,KACd1C,EAAQ6E,SAASE,YAAY,GAC7B/E,EAAQ6E,SAASE,aAEsBuL,IAAI,SAAC3E,GAC/C,IAAAkO,EAAiB5P,EAAsB0B,EAAM,GAAIA,EAAM,IACvD,MAAO,CADEkO,EAADzP,EAAIyP,EAADxP,EAEZ,GAEA,MAA8B,YAA1BrK,EAAQ6E,SAASnC,KAOtB,SACC03B,GAQA,IANA,IAAIC,EAAO,EACPC,EAAY,EACZC,EAAY,EAEVC,EAAIJ,EAAuB5yB,OAExB+D,EAAI,EAAGA,EAAIivB,EAAI,EAAGjvB,IAAK,CAC/B,IAAAkvB,EAAiBL,EAAuB7uB,GAAjCsB,EAAE4tB,EAAA,GAAE3tB,EAAE2tB,EACb,GAAAC,EAAiBN,EAAuB7uB,EAAI,GAArCwB,EAAE2tB,EAAE1tB,GAAAA,EAAE0tB,EAAA,GAEPC,EAAe9tB,EAAKG,EAAKD,EAAKD,EACpCutB,GAAQM,EACRL,IAAcztB,EAAKE,GAAM4tB,EACzBJ,IAAcztB,EAAKE,GAAM2tB,CAC1B,CAMA,MAAO,CAAEvwB,EAHTkwB,GAAa,GADbD,GAAQ,GAIehwB,EAFvBkwB,GAAa,EAAIF,EAGlB,CA9BSO,CAAyBR,GAgClC,SAAqCS,GAKpC,IAJA,IAAML,EAAIK,EAAWrzB,OACjBszB,EAAS,EACTC,EAAS,EAEJxvB,EAAI,EAAGA,EAAIivB,EAAGjvB,IAAK,CAC3B,IAAAyvB,EAAeH,EAAWtvB,GAC1BuvB,GADQE,EAAE3wB,GAEV0wB,GAFWC,EAAA,EAGZ,CAEA,MAAO,CAAE5wB,EAAG0wB,EAASN,EAAGnwB,EAAG0wB,EAASP,EACrC,CA1CSS,CAA4Bb,EAErC,CCGA,IAAac,gBAAsB,SAAA7rB,GAClC,SAAA6rB,EACUn3B,EACQ8zB,EACAC,EACA/P,EACA/L,EACArJ,GAAoCtL,IAAAA,EAAA,OAErDA,EAAAgI,EAAA1H,UAAM5D,UAPGA,YAAAsD,EAAAA,EACQwwB,qBAAA,EAAAxwB,EACAywB,iBAAAzwB,EACA0gB,sBAAA1gB,EAAAA,EACA2U,iBAAA,EAAA3U,EACAsL,qBAAAtL,EAKV8zB,iBAAW9zB,EAAAA,EACX+zB,sBAAgB,EAAA/zB,EAChBg0B,gCAAwBh0B,EACxBi0B,yCAbEj0B,EAAAA,EAAMtD,OAANA,EACQsD,EAAewwB,gBAAfA,EACAxwB,EAASywB,UAATA,EACAzwB,EAAgB0gB,iBAAhBA,EACA1gB,EAAW2U,YAAXA,EACA3U,EAAasL,cAAbA,EAAoCtL,CAGtD,CAACU,EAAAmzB,EAAA7rB,GAAAtM,IAAAA,EAAAm4B,EAAAl4B,UAgJAk4B,OAhJAn4B,EAODw4B,MAAA,WACC75B,KAAKy5B,iBAAc93B,EACnB3B,KAAK05B,sBAAmB/3B,EACxB3B,KAAK45B,yCAAsCj4B,EAC3C3B,KAAK25B,8BAA2Bh4B,CACjC,EAACN,EAEDy4B,OAAA,SAAO/3B,EAA4BkC,GAAqBwK,IAAAA,OAClDzO,KAAK05B,mBACT15B,KAAK05B,iBAAmB15B,KAAKsa,YAAYpB,YAEvCjV,IAGH,IAAMd,EAAWnD,KAAK05B,iBAGtB,GAAsB,YAAlBv2B,EAASnC,MAAwC,eAAlBmC,EAASnC,KAA5C,CAIA,IAEImI,EAFE4wB,EAAa,CAACh4B,EAAMyG,IAAKzG,EAAM0G,KAG/BuxB,EAAiB,CAAEh5B,KAAM,UAAWmC,SAAAA,EAAUxE,WAAY,IAIhE,GAA+B,iBAA3BqB,KAAKqC,OAAO3B,WAA+B,CAGzCV,KAAK45B,sCACT55B,KAAK45B,oCACJnB,GAAoBuB,IAGtB,IAAMC,EAAoB1xB,EAAsBxG,EAAMyG,IAAKzG,EAAM0G,KAOjE,GAAgB,KALhBU,EAAU6U,GACThe,KAAK45B,oCACLK,IAIA,OAGD,IAAKj6B,KAAKy5B,YAET,YADAz5B,KAAKy5B,YAActwB,GAMpBgvB,GAA2B6B,IAFbh6B,KAAKy5B,YAActwB,GAGlC,KAAO,IAA+B,UAA3BnJ,KAAKqC,OAAO3B,WAuBtB,MAAM,IAAIuB,MAAM,0BAThB,GAXKjC,KAAK25B,2BACT35B,KAAK25B,yBAA2B5B,GAAS,CACxC/2B,KAAM,UACNmC,SAAAA,EACAxE,WAAY,CAAA,KAIdwK,EAAUmoB,GAAatxB,KAAK25B,yBAA0BI,IAGjD/5B,KAAKy5B,YAET,YADAz5B,KAAKy5B,YAActwB,EAAU,MFtGjB,SACf7K,EACAia,GAGA,GAAc,IAAVA,GAAyB,MAAVA,IAA4B,MAAXA,EACnC,OAAOja,EAIR,IAAM47B,EAAQnC,GAASz5B,IAGI,YAA1BA,EAAQ6E,SAASnC,KACd1C,EAAQ6E,SAASE,YAAY,GAC7B/E,EAAQ6E,SAASE,aAETia,QAAQ,SAAC6c,GACpB,IACMC,EADe9I,GAAa4I,EAAOC,GACP5hB,EAC5B5Q,WG5BsBsB,EAAuBC,GAGpDD,EAAY,IACXA,EAAY,GAAKC,EAAO,GAAK,KACzB,IACDA,EAAO,GAAKD,EAAY,GAAK,IAC5B,IACA,EAIL,IAAMX,EAAIf,EACJiqB,EAAQtoB,EAAO,GAAKvC,KAAKC,GAAM,IAC/B6qB,EAAQxoB,EAAY,GAAKtC,KAAKC,GAAM,IACpCurB,EAAWV,EAAOD,EACpB6I,EAAe1zB,KAAKqrB,IAAI/oB,EAAY,GAAKC,EAAO,IAAMvC,KAAKC,GAAM,IAGjEyzB,EAAc1zB,KAAKC,KACtByzB,GAAe,EAAI1zB,KAAKC,IAKzB,IAAMwrB,EAAWzrB,KAAKiC,IACrBjC,KAAKkC,IAAI4oB,EAAO,EAAI9qB,KAAKC,GAAK,GAAKD,KAAKkC,IAAI2oB,EAAO,EAAI7qB,KAAKC,GAAK,IAE5DyrB,EAAI1rB,KAAKqrB,IAAII,GAAY,MAASD,EAAWC,EAAWzrB,KAAKS,IAAIoqB,GASvE,OANc7qB,KAAKW,KAClB6qB,EAAWA,EAAWE,EAAIA,EAAIgI,EAAcA,GAGd/xB,CAGhC,CHVmBgyB,CAAcJ,EAAOC,GAChCI,EAAY1I,GAAiBqI,EAAOvyB,EAAUyyB,GACpDD,EAAY,GAAKI,EAAU,GAC3BJ,EAAY,GAAKI,EAAU,EAC5B,EAGD,CEiFGC,CAAgBR,IAFFh6B,KAAKy5B,aAAetwB,EAAU,MAK7C,CAGA,IAAM0tB,EACa,YAAlB1zB,EAASnC,KACNmC,EAASE,YAAY,GACrBF,EAASE,YAGbwzB,EAAcvZ,QAAQ,SAACvR,GACtBA,EAAW,GAAKjE,EAAeiE,EAAW,GAAI0C,EAAKnO,qBACnDyL,EAAW,GAAKjE,EAAeiE,EAAW,GAAI0C,EAAKnO,oBACpD,GAEA,IAAMkQ,EAAS,CACdtB,UAAWjL,EACXkL,oBAAqB,CACpBnO,KAAMyM,GACNpK,YACmB,YAAlBF,EAASnC,KAAqB,CAAC61B,GAAiBA,GAElD9yB,QAAS,CACRL,WAAY3G,EAAY4G,cAItBsmB,EAA6D,KACjE,GAAqC,YAAjC+P,EAAe72B,SAASnC,KAC3BipB,EAAUjqB,KAAKiR,cAAc5B,cAC5BmB,OAEK,IAAqC,eAAjCwpB,EAAe72B,SAASnC,KAKlC,OAJAipB,EAAUjqB,KAAKiR,cAAc1B,iBAC5BiB,EAIF,CAEA,IAAKyZ,EACJ,OAAY,EAGb,IAAM/F,EAAqB+F,EAAQ9mB,SAASE,YAG5CrD,KAAKo2B,UAAUjQ,iBAAiB,CAAEjC,mBAAAA,IAClClkB,KAAKm2B,gBAAgBhQ,iBAAiB,CAAEjC,mBAAAA,IACxClkB,KAAKqmB,iBAAiBF,iBAAiB,CACtCjX,UAAWjL,EACXigB,mBAAAA,IAGuB,iBAApBlkB,KAAKU,WACRV,KAAKy5B,YAActwB,EACW,UAApBnJ,KAAKU,aACfV,KAAKy5B,YAActwB,EAAU,IApH9B,CAsHD,EAACqwB,CAAA,CA1JiC,CAAQ1sB,GExB9B2tB,gBAAqB9sB,SAAAA,GACjC,SAAA8sB,EACUp4B,EACQq4B,GAA0D/0B,IAAAA,EAAA,OAE3EA,EAAAgI,EAAA1H,KAAAjG,KAAMqC,UAHGA,YAAA,EAAAsD,EACQ+0B,kCADR/0B,EAAAA,EAAMtD,OAANA,EACQsD,EAA4B+0B,6BAA5BA,EAA0D/0B,CAG5E,CAACU,EAAAo0B,EAAA9sB,GAAA,IAAAtM,EAAAo5B,EAAAn5B,UAgBAm5B,OAhBAp5B,EAEMs5B,MAAA,SAAM54B,EAA4BmN,GACxC,IAAKlP,KAAK06B,6BAA6BjE,aAAc,CACpD,IAAMtkB,EAAQnS,KAAK06B,6BAA6B/C,kBAC/C51B,EACAmN,GAEDlP,KAAK06B,6BAA6BnE,cAAcrnB,EAAWiD,EAC5D,CAEAnS,KAAK06B,6BAA6B/D,KAAK50B,EAAO,eAC/C,EAACV,EAEMw4B,MAAA,WACN75B,KAAK06B,6BAA6BlE,cACnC,EAACiE,CAAA,CAtBgC9sB,CAAQb,GCC1B,SAAA8tB,GAAoC7tB,GACnD,IACA8tB,EAAO9tB,EAAP8tB,QACAC,EAAO/tB,EAAP+tB,QACAC,EAAMhuB,EAANguB,OACAC,EAAMjuB,EAANiuB,OAQe,IAAXD,GAA2B,IAAXC,GAZTjuB,EAAX1J,YAiBYia,QAAQ,SAACvR,GACpB,IAAAoM,EAAiB5P,EAAsBwD,EAAW,GAAIA,EAAW,IAKjE2M,EAAqB5P,EAHJ+xB,GAFR1iB,EAADzP,EAEwBmyB,GAAWE,EAC1BD,GAHL3iB,EAADxP,EAGqBmyB,GAAWE,GAE9BvyB,EAAGiQ,EAAHjQ,IAEbsD,EAAW,GAFA2M,EAAHlQ,IAGRuD,EAAW,GAAKtD,CACjB,EACD,KCgBawyB,yBAA6BttB,GACzC,SAAAstB,EACU54B,EACQsa,EACAwZ,EACAC,EACA/P,EACA/L,EACArJ,GAAoC,IAAAtL,EAAA,OAErDA,EAAAgI,EAAA1H,KAAM5D,KAAAA,IAAQsD,MARLtD,YAAA,EAAAsD,EACQgX,qBAAAhX,EACAwwB,qBAAA,EAAAxwB,EACAywB,iBAAAzwB,EACA0gB,sBAAA1gB,EAAAA,EACA2U,iBAAA,EAAA3U,EACAsL,qBAAAtL,EAKVu1B,aAAe,KAAMv1B,EAErB0xB,kBAA6D,CACpEn0B,GAAI,KACJiP,OAAQ,GACRxM,EAYOw1B,gBAAkB,CACzBC,SAAU,CACT,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,IArCKz1B,EAAMtD,OAANA,EACQsD,EAAagX,cAAbA,EACAhX,EAAewwB,gBAAfA,EACAxwB,EAASywB,UAATA,EACAzwB,EAAgB0gB,iBAAhBA,EACA1gB,EAAW2U,YAAXA,EACA3U,EAAasL,cAAbA,EAAoCtL,CAGtD,CAACU,EAAA40B,EAAAttB,OAAAtM,EAAA45B,EAAA35B,UA2sBA25B,OA3sBA55B,EAgCOi2B,qBAAA,SACPv1B,EACAoB,GAEA,IAMIo0B,EANEC,EAAoB,CACzBha,KAAMtR,SACNiG,OAAQ,EACRslB,2BAA2B,GAK5B,GAAsB,eAAlBt0B,EAASnC,KACZu2B,EAAkBp0B,EAASE,oBACC,YAAlBF,EAASnC,KAKnB,OAAOw2B,EAJPD,EAAkBp0B,EAASE,YAAY,EAKxC,CAIA,IAAK,IAAIwG,EAAI,EAAGA,EAAI0tB,EAAgBzxB,OAAQ+D,IAAK,CAChD,IACMlC,EAAW3H,KAAK2c,cAAcJ,QAAQxa,EAD9Bw1B,EAAgB1tB,IAG9B,GACClC,EAAW3H,KAAKK,iBAChBsH,EAAW6vB,EAAkBha,KAC5B,CAID,IAAMia,EACa,YAAlBt0B,EAASnC,OACR6I,IAAM0tB,EAAgBzxB,OAAS,GAAW,IAAN+D,GAEtC2tB,EAAkBha,KAAO7V,EACzB6vB,EAAkBrlB,MAAQslB,EAA4B,EAAI5tB,EAC1D2tB,EAAkBC,0BAA4BA,CAC/C,CACD,CAEA,OAAOD,CACR,EAACn2B,EAEOg6B,uBAAA,SACPlpB,EACAmpB,EACAC,GAEA,OAAQppB,GACP,KAAK,EACJ,GAAImpB,GAAa,GAAKC,GAAa,EAClC,OAAY,EAEb,MACD,OACC,GAAIA,GAAa,EAChB,SAED,MACD,KAAK,EACJ,GAAID,GAAa,GAAKC,GAAa,EAClC,OAAY,EAEb,MACD,OACC,GAAID,GAAa,EAChB,OAAY,EAEb,MACD,OACC,GAAIA,GAAa,GAAKC,GAAa,EAClC,OAAY,EAEb,MACD,KAAM,EACL,GAAIA,GAAa,EAChB,OAAY,EAEb,MACD,OACC,GAAID,GAAa,GAAKC,GAAa,EAClC,OAAO,EAER,MACD,KAAM,EACL,GAAID,GAAa,EAChB,OAAY,EAOf,OAAW,CACZ,EAACj6B,EAEOm6B,kCAAA,WACP,IAAKx7B,KAAKq3B,kBAAkBn0B,KAAwC,IAAlClD,KAAKq3B,kBAAkBllB,MACxD,YAGD,IAAM7T,EAAU0B,KAAKy7B,WAAWz7B,KAAKq3B,kBAAkBn0B,IACvD,IAAK5E,EACJ,OAAW,KAGZ,IAAMu4B,EAAgB72B,KAAK07B,yBAAyBp9B,EAAQ6E,UAG5D,MAAO,CACN+d,YAHmBlhB,KAAK27B,mBAAmB9E,GAI3Cv4B,QAAAA,EACAu4B,cAAAA,EACA+E,mBAAoB/E,EAAc72B,KAAKq3B,kBAAkBllB,OAE3D,EAAC9Q,EAEOw6B,sBAAA,SAAsB95B,GAC7B,IAAM+5B,EAAc97B,KAAKw7B,oCACzB,IAAKM,EACJ,OAAW,KAEZ,IAAiB5a,EAChB4a,EADgB5a,YAAa2V,EAC7BiF,EAD6BjF,cAAe+E,EAC5CE,EAD4CF,mBAGvCG,EAAoBtD,GAFzBqD,EADOx9B,SAKR,IAAKy9B,EACJ,OAAW,KAGZ,IAAMC,EAAsBzzB,EAC3BqzB,EAAmB,GACnBA,EAAmB,IAGZK,EAAqBj8B,KAAKk8B,sBACjChb,EACA8a,GAFOC,iBAKFE,EAAoB5zB,EAAsBxG,EAAMyG,IAAKzG,EAAM0G,KAUjE,OARAzI,KAAKo8B,iBAAiB,CACrBH,iBAAAA,EACApF,cAAAA,EACAsF,kBAAAA,EACAH,oBAAAA,EACAD,kBAAAA,IAGMlF,CACR,EAACx1B,EAEOg7B,2BAAA,SAA2Bt6B,GAClC,IAAM+5B,EAAc97B,KAAKw7B,oCACzB,IAAKM,EACJ,OAAO,KAER,IAAiB5a,EAChB4a,EADgB5a,YAAa2V,EAC7BiF,EAD6BjF,cAAe+E,EAC5CE,EAD4CF,mBAGvCG,EAAoBtD,GAFzBqD,EADOx9B,SAKR,IAAKy9B,EACJ,YAGD,IAAMC,EAAsBzzB,EAC3BqzB,EAAmB,GACnBA,EAAmB,IAGZK,EAAqBj8B,KAAKk8B,sBACjChb,EACA8a,GAFOC,iBAKFE,EAAoB5zB,EAAsBxG,EAAMyG,IAAKzG,EAAM0G,KAUjE,OARAzI,KAAKs8B,sBAAsB,CAC1BL,iBAAAA,EACApF,cAAAA,EACAsF,kBAAAA,EACAH,oBAAAA,EACAD,kBAAAA,IAGMlF,CACR,EAACx1B,EAEOi7B,sBAAA,SAAqBvvB,GAY5B,IAVAgvB,EAAiBhvB,EAAjBgvB,kBACAC,EAAmBjvB,EAAnBivB,oBACAG,EAAiBpvB,EAAjBovB,kBACAtF,EAAa9pB,EAAb8pB,cAiBA,IANc72B,KAAKq7B,uBAfHtuB,EAAhBkvB,iBAYwBF,EAAkBrzB,EAAIyzB,EAAkBzzB,EACxCqzB,EAAkBpzB,EAAIwzB,EAAkBxzB,GAS/D,OAAO,KAGR,IAAIgyB,EACH/hB,GAAkBmjB,EAAmBI,GACrCvjB,GAAkBmjB,EAAmBC,GAsBtC,OApBIrB,EAAQ,IACXA,EAAQ36B,KAAKk7B,cAGdN,GAAqC,CACpCv3B,YAAawzB,EACbgE,QAASkB,EAAkBrzB,EAC3BoyB,QAASiB,EAAkBpzB,EAC3BoyB,OAAQJ,EACRK,OAAQL,IAWF9D,CACR,EAACx1B,EAEOk7B,6BAAA,SAA6Bx6B,GACpC,IAAM+5B,EAAc97B,KAAKw7B,oCACzB,IAAKM,EACJ,YAGD,IAAQ5a,EAAmD4a,EAAnD5a,YAAa2V,EAAsCiF,EAAtCjF,cAAe+E,EAAuBE,EAAvBF,mBAE9BI,EAAsBzzB,EAC3BqzB,EAAmB,GACnBA,EAAmB,IAGpBY,EAAgDx8B,KAAKk8B,sBACpDhb,EACA8a,GAFOS,EAAiBD,EAAjBC,kBAAmBR,EAAgBO,EAAhBP,iBAKrBF,EAAoB,CACzBrzB,EAAGwY,EAAYub,GAAmB,GAClC9zB,EAAGuY,EAAYub,GAAmB,IAE7BN,EAAoB5zB,EAAsBxG,EAAMyG,IAAKzG,EAAM0G,KAUjE,OARAzI,KAAKs8B,sBAAsB,CAC1BL,iBAAAA,EACApF,cAAAA,EACAsF,kBAAAA,EACAH,oBAAAA,EACAD,kBAAAA,IAGMlF,CACR,EAACx1B,EAEOq7B,wBAAA,SAAwB36B,GAC/B,IAAM+5B,EAAc97B,KAAKw7B,oCACzB,IAAKM,EACJ,OAAW,KAGZ,IAAQ5a,EAAmD4a,EAAnD5a,YAAa2V,EAAsCiF,EAAtCjF,cAAe+E,EAAuBE,EAAvBF,mBAE9BI,EAAsBzzB,EAC3BqzB,EAAmB,GACnBA,EAAmB,IAGpBe,EAAgD38B,KAAKk8B,sBACpDhb,EACA8a,GAFOS,EAAiBE,EAAjBF,kBAAmBR,EAAgBU,EAAhBV,iBAKrBF,EAAoB,CACzBrzB,EAAGwY,EAAYub,GAAmB,GAClC9zB,EAAGuY,EAAYub,GAAmB,IAE7BN,EAAoB5zB,EAAsBxG,EAAMyG,IAAKzG,EAAM0G,KAUjE,OARAzI,KAAKo8B,iBAAiB,CACrBH,iBAAAA,EACApF,cAAAA,EACAsF,kBAAAA,EACAH,oBAAAA,EACAD,kBAAAA,IAGMlF,CACR,EAACx1B,EAEO+6B,iBAAA,SAAgBnuB,GAYvB,IAXAguB,EAAgBhuB,EAAhBguB,iBACAF,EAAiB9tB,EAAjB8tB,kBACAC,EAAmB/tB,EAAnB+tB,oBACAG,EAAiBluB,EAAjBkuB,kBACAtF,EAAa5oB,EAAb4oB,cAQM+F,EAAkBb,EAAkBrzB,EAAIyzB,EAAkBzzB,EAC1Dm0B,EAAkBd,EAAkBpzB,EAAIwzB,EAAkBxzB,EAQhE,IANc3I,KAAKq7B,uBAClBY,EACAW,EACAC,GAIA,OAAW,KAGZ,IAAI9B,EAAS,EAEQ,IAApB6B,GACqB,IAArBX,GACqB,IAArBA,IAGAlB,EAAS,GADgBgB,EAAkBrzB,EAAIszB,EAAoBtzB,EAClCk0B,GAAmBA,GAGrD,IAAI5B,EAAS,EAUb,OARqB,IAApB6B,GACqB,IAArBZ,GACqB,IAArBA,IAGAjB,EAAS,GADgBe,EAAkBpzB,EAAIqzB,EAAoBrzB,EAClCk0B,GAAmBA,GAGhD78B,KAAK88B,cAAc/B,EAAQC,IAI5BD,EAAS,IACZA,EAAS/6B,KAAKk7B,cAGXF,EAAS,IACZA,EAASh7B,KAAKk7B,cAGfl7B,KAAK+8B,wBACJlG,EACAkF,EAAkBrzB,EAClBqzB,EAAkBpzB,EAClBoyB,EACAC,GAGMnE,GAnBC,IAoBT,EAACx1B,EAEOo6B,WAAA,SAAWv4B,GAClB,GAAkC,OAA9BlD,KAAKq3B,kBAAkBn0B,GAC1B,OAAW,KAGZ,IAAMC,EAAWnD,KAAKsa,YAAYpB,YAAYhW,GAG9C,MAAsB,YAAlBC,EAASnC,MAAwC,eAAlBmC,EAASnC,KAChC,KAGI,CACfkC,GAAAA,EACAlC,KAAM,UACNmC,SAAAA,EACAxE,WAAY,GAId,EAAC0C,EAEOq6B,yBAAA,SAAyBv4B,GAEhC,MAAyB,YAAlBA,EAASnC,KACbmC,EAASE,YAAY,GACrBF,EAASE,WACb,EAAChC,EAEOy7B,cAAA,SAAc/B,EAAgBC,GACrC,IAAMgC,GAAUl+B,MAAMi8B,IAAWC,EAAS5b,OAAO6d,iBAC3CC,GAAUp+B,MAAMk8B,IAAWA,EAAS5b,OAAO6d,iBAEjD,OAAOD,GAAUE,CAClB,EAAC77B,EAEO07B,wBAAA,SACP15B,EACAw3B,EACAC,EACAC,EACAC,GAEA33B,EAAYia,QAAQ,SAACvR,GACpB,IAAAoM,EAAiB5P,EAAsBwD,EAAW,GAAIA,EAAW,IAKjE2M,EAAqB5P,EAHJ+xB,GAFR1iB,EAADzP,EAEwBmyB,GAAWE,EAC1BD,GAHL3iB,EAADxP,EAGqBmyB,GAAWE,GAE9BvyB,EAAGiQ,EAAHjQ,IAEbsD,EAAW,GAFA2M,EAAHlQ,IAGRuD,EAAW,GAAKtD,CACjB,EACD,EAACpH,EAEOs6B,mBAAA,SAAmBt4B,GAC1B,IAAM4Z,EAAyC,CAC9C/Q,SACAA,UACCA,UACAA,WAIF7I,EAAcA,EAAYuL,IAAI,SAAC3E,GAC9B,IAAAmO,EAAiB7P,EAAsB0B,EAAM,GAAIA,EAAM,IACvD,MAAO,CADEmO,EAAD1P,EAAI0P,EAADzP,EAEZ,IAEY2U,QAAQ,SAAAnP,GAAW,IAATzF,EAACyF,EAAExF,GAAAA,EAACwF,EAAA,GACrBzF,EAAIuU,EAAK,KACZA,EAAK,GAAKvU,GAGPC,EAAIsU,EAAK,KACZA,EAAK,GAAKtU,GAGPD,EAAIuU,EAAK,KACZA,EAAK,GAAKvU,GAGPC,EAAIsU,EAAK,KACZA,EAAK,GAAKtU,EAEZ,GAEA,IAAOw0B,EAA4BlgB,EAAI,GAA1BmgB,EAAsBngB,KAAfogB,EAAepgB,EAATqgB,GAAAA,EAASrgB,EAAI,GAsBvC,MAAO,CAVS,CAACkgB,EAAMG,GAKR,EAAEH,EAAOE,GAAQ,EAAGC,GAJlB,CAACD,EAAMC,GAKP,CAACD,EAAMC,GAASF,EAAQE,GAAS,GAJjC,CAACD,EAAMD,GAKN,EAAED,EAAOE,GAAQ,EAAGD,GAJtB,CAACD,EAAMC,GAKP,CAACD,EAAMG,GAASF,EAAQE,GAAS,GAYlD,EAACj8B,EAEO66B,sBAAA,SACPhb,EACAqc,GAKA,IAHA,IAAIC,EACA1b,EAAkB5V,SAEbrC,EAAI,EAAGA,EAAIqX,EAAYpb,OAAQ+D,IAAK,CAC5C,IAAMlC,EAAWiR,GAChB,CAAElQ,EAAG60B,EAAW70B,EAAGC,EAAG40B,EAAW50B,GACjC,CAAED,EAAGwY,EAAYrX,GAAG,GAAIlB,EAAGuY,EAAYrX,GAAG,KAGvClC,EAAWma,IACd0b,EAAe3zB,EACfiY,EAAkBna,EAEpB,CAEA,QAAqBhG,IAAjB67B,EACH,MAAU,IAAAv7B,MAAM,+BASjB,MAAO,CACNw6B,kBALqBz8B,KAAKm7B,gBAA0B,SACpDqC,GAKAvB,iBAAkBuB,EAEpB,EAACn8B,EAKMo1B,WAAA,WACN,OAAqC,OAA9Bz2B,KAAKq3B,kBAAkBn0B,EAC/B,EAAC7B,EAQMk1B,cAAA,SAAcrzB,EAAeiP,GACnCnS,KAAKq3B,kBAAoB,CACxBn0B,GAAAA,EACAiP,MAAAA,EAEF,EAAC9Q,EAMMm1B,aAAA,WACNx2B,KAAKq3B,kBAAoB,CACxBn0B,GAAI,KACJiP,OAAQ,EAEV,EAAC9Q,EAQMs2B,kBAAA,SACN51B,EACAkC,GAEA,IAAMd,EAAWnD,KAAKsa,YAAYpB,YAAYjV,GACxCuzB,EAAoBx3B,KAAKs3B,qBAAqBv1B,EAAOoB,GAG3D,OAAiC,IAA7Bq0B,EAAkBrlB,OACb,EAEFqlB,EAAkBrlB,KAC1B,EAAC9Q,EAQMs1B,KAAA,SACN50B,EACA07B,GAEA,IAAKz9B,KAAKq3B,kBAAkBn0B,GAC3B,OAAO,EAGR,IAAM5E,EAAU0B,KAAKy7B,WAAWz7B,KAAKq3B,kBAAkBn0B,IACvD,IAAK5E,EACJ,SAGD,IAAIu4B,EAAmC,KAYvC,GAVqB,WAAjB4G,EACH5G,EAAgB72B,KAAK67B,sBAAsB95B,GAChB,aAAjB07B,EACV5G,EAAgB72B,KAAK08B,wBAAwB36B,GAClB,iBAAjB07B,EACV5G,EAAgB72B,KAAKq8B,2BAA2Bt6B,GACrB,mBAAjB07B,IACV5G,EAAgB72B,KAAKu8B,6BAA6Bx6B,KAG9C80B,EACJ,OAAO,EAIR,IAAK,IAAIhtB,EAAI,EAAGA,EAAIgtB,EAAc/wB,OAAQ+D,IAAK,CAC9C,IAAMkC,EAAa8qB,EAAchtB,GAKjC,GAJAkC,EAAW,GAAKjE,EAAeiE,EAAW,GAAI/L,KAAKM,qBACnDyL,EAAW,GAAKjE,EAAeiE,EAAW,GAAI/L,KAAKM,sBAG9CwL,EAA2BC,EAAY/L,KAAKM,qBAChD,OAAO,CAET,CAEA,IAAM4O,EAAY5Q,EAAQ4E,GAEtB+mB,EAA6D,KA0BjE,GAxB8B,YAA1B3rB,EAAQ6E,SAASnC,KACpBipB,EAAUjqB,KAAKiR,cAAc5B,cAAc,CAC1CH,UAAAA,EACAC,oBAAqB,CACpBnO,KAAMyM,GACNpK,YAAa,CAACwzB,IAEf9yB,QAAS,CACRL,WAAY3G,EAAY4G,eAGU,eAA1BrF,EAAQ6E,SAASnC,OAC3BipB,EAAUjqB,KAAKiR,cAAc1B,iBAAiB,CAC7CL,UAAAA,EACAC,oBAAqB,CACpBnO,KAAMyM,GACNpK,YAAawzB,GAEd9yB,QAAS,CACRL,WAAY3G,EAAY4G,iBAKtBsmB,EACJ,SAGD,IAAM/F,EAAqB+F,EAAQ9mB,SAASE,YAO5C,OAJArD,KAAKo2B,UAAUjQ,iBAAiB,CAAEjC,mBAAAA,IAClClkB,KAAKm2B,gBAAgBhQ,iBAAiB,CAAEjC,mBAAAA,IACxClkB,KAAKqmB,iBAAiBF,iBAAiB,CAAEjX,UAAAA,EAAWgV,mBAAAA,KAEzC,CACZ,EAAC+W,CAAA,EAttBgDnuB,GCK5CuH,GAAmB,CACxBqpB,SAAU,SACVC,OAAQ,SACR7D,OAAQ,CAAC,UAAW,KACpBa,MAAO,CAAC,UAAW,MA6EdnmB,GAAiB,CACtBopB,YAAa,OACbvV,UAAW,OACXC,QAAS,OACTuV,eAAgB,aAeJC,yBAAoBC,GAoDhC,SAAAD,EAAYj+B,GAAsD8F,IAAAA,EAErC,OAD5BA,EAAAo4B,EAAA93B,KAAAjG,KAAMH,GAAS,IAAKG,MApDdkB,KAAO,SAAQyE,EAEdq4B,wBAAyB,EAAIr4B,EAC7Bs4B,sBAAuB,EAAIt4B,EAC3Bu4B,kBAAoB,EAACv4B,EACrBw4B,eAAiB,EAACx4B,EAClBy4B,SAAwB,GAAEz4B,EAE1B04B,MAAuC,CAAE14B,EAAAA,EACzCmP,UAA0CT,GAAgB1O,EAC1DoP,QAA6BP,GAAc7O,EAC3C24B,YAA0C,CAAE34B,EAAAA,EAE5C44B,WAK+D,CACtEv9B,KAAM,QACN2E,EAGOwwB,qBAAe,EAAAxwB,EACfywB,iBAASzwB,EACT64B,oBAAc,EAAA74B,EACd84B,0BAAoB94B,EAAAA,EACpBgX,mBAAa,EAAAhX,EACbiX,sBAAgBjX,EAAAA,EAChB+4B,mBAAW/4B,EACXg5B,oBAAc,EAAAh5B,EACdi5B,mBAAaj5B,EAAAA,EACbk5B,kBAAY,EAAAl5B,EACZm5B,iCAA2Bn5B,EAAAA,EAC3B0gB,sBAAgB,EAAA1gB,EAChBo5B,cAAQp5B,EAAAA,EACRsL,mBAAa,EAAAtL,EACb2U,iBAgBP3U,EAAAA,EAAKxE,cAActB,GAAS8F,CAC7B,CAACU,EAAAy3B,EAAAC,GAAA18B,IAAAA,EAAAy8B,EAAAx8B,UAkqCAw8B,OAlqCAz8B,EAfO29B,4BAAA,WAA2B,IAAAC,EAClC,cAAAA,EAAOj/B,KAAK+U,QAAQmqB,oBAAkBD,EAAIj/B,KAAK+U,QAAQ6oB,WACxD,EAACv8B,EAEO89B,+BAAA,WAA8BC,IAAAA,EACrC,OAAyCA,OAAzCA,EAAOp/B,KAAK+U,QAAQsqB,uBAAqBD,EAAIp/B,KAAK+U,QAAQ6oB,WAC3D,EAACv8B,EAEOi+B,iCAAA,WAAgCC,IAAAA,EACvC,OAA2CA,OAA3CA,EAAOv/B,KAAK+U,QAAQyqB,yBAAuBD,EAAIv/B,KAAK+U,QAAQ6oB,WAC7D,EAACv8B,EAOQF,cAAA,SACRtB,GAoCA,GAlCAk+B,EAAAz8B,UAAMH,cAAa8E,KAAAjG,KAACH,GAGnBG,KAAK+U,QADFlV,GAAWA,EAAQkV,QACV3T,EAAQ,CAAA,EAAApB,KAAK+U,QAAYlV,EAAQkV,SAE9BP,GAKW,cAAvB3U,SAAAA,EAASiV,WACZ9U,KAAK8U,UAAY,CAChB4oB,SAAU,KACVC,OAAQ,KACR7D,OAAQ,KACRa,MAAO,MAEE96B,MAAAA,GAAAA,EAASiV,YACnB9U,KAAK8U,UAAS1T,EAAA,CAAA,EAAQpB,KAAK8U,UAAcjV,EAAQiV,iBAGfnT,KAA/B9B,MAAAA,OAAAA,EAAAA,EAASq+B,qBACZl+B,KAAKk+B,kBAAoBr+B,EAAQq+B,wBAGMv8B,WAApC9B,SAAAA,EAASm+B,0BACZh+B,KAAKg+B,uBAAyBn+B,EAAQm+B,6BAGDr8B,KAA3B,MAAP9B,OAAO,EAAPA,EAASo+B,wBACZj+B,KAAKi+B,qBAAuBp+B,EAAQo+B,sBAI1B,MAAPp+B,GAAAA,EAASw+B,MAIZ,IAAK,IAAMn9B,KAHXlB,KAAKq+B,MAAKj9B,EAAQ,GAAApB,KAAKq+B,MAAUx+B,EAAQw+B,OACzCr+B,KAAKs+B,YAAc,CAAA,OAEKD,MAAO,CAC9B,IAAM//B,EAAU0B,KAAKq+B,MAAMn9B,GAAM5C,QAC7BA,GAAWA,EAAQoD,aACtB1B,KAAKs+B,YAAYp9B,GAAQ5C,EAAQoD,WAEnC,CAEF,EAACL,EAEDo+B,cAAA,SAAcvwB,GACblP,KAAK0/B,OAAOxwB,GAAW,EACxB,EAAC7N,EAEDs+B,aAAA,WACC,GAAoB,YAAhB3/B,KAAKD,OAGR,MAAM,IAAIkC,MAAM,mDAFhBjC,KAAKD,OAAS,WAIhB,EAACsB,EAEDE,kBAAA,SAAkBc,GAAsB,IAAAoM,EACvCzO,KAAAA,KAAKsa,YAAc,IAAIxB,GAAoBzW,GAC3CrC,KAAKiR,cAAgB,IAAIvD,GAAsBrL,EAAQ,CACtDjC,SAAU,SAAC9B,EAASyF,GACnB,IAAM7C,EAAO5C,EAAQK,WAAWuC,KAGhC,OAAKuN,EAAK6vB,aAAgB7vB,EAAK6vB,YAAYp9B,GAIpCuN,EAAK6vB,YAAYp9B,GAAM5C,EAASyF,GAH/B,CAAET,OAAO,EAIlB,IAGDtD,KAAK2c,cAAgB,IAAIL,GAAsBja,GAC/CrC,KAAK4c,iBAAmB,IAAIP,GAAyBha,GACrDrC,KAAKy+B,qBAAuB,IAAIpJ,GAC/BhzB,EACArC,KAAK4c,iBACL5c,KAAK2c,eAGN3c,KAAKm2B,gBAAkB,IAAInC,GAC1B3xB,EACArC,KAAKiR,eAENjR,KAAKqmB,iBAAmB,IAAIjB,GAC3B/iB,EACArC,KAAKsa,YACLta,KAAKiR,eAENjR,KAAKo2B,UAAY,IAAIlD,GACpB7wB,EACArC,KAAKm2B,gBACLn2B,KAAKqmB,iBACLrmB,KAAKiR,cACLjR,KAAKsa,YACLta,KAAK2c,eAEN3c,KAAKw+B,eAAiB,IAAI9hB,GACzBra,EACArC,KAAK2c,cACL3c,KAAK4c,kBAEN5c,KAAK++B,SAAW,IAAI/d,GACnB3e,EACArC,KAAK2c,cACL3c,KAAK4c,kBAEN5c,KAAK4+B,cAAgB,IAAIpF,GACxBn3B,EACArC,KAAKm2B,gBACLn2B,KAAKo2B,UACLp2B,KAAKqmB,iBACLrmB,KAAKsa,YACLta,KAAKiR,eAGNjR,KAAK0+B,YAAc,IAAIzI,GACtB5zB,EACArC,KAAKy+B,qBACLz+B,KAAKm2B,gBACLn2B,KAAKo2B,UACLp2B,KAAKqmB,iBACLrmB,KAAKsa,YACLta,KAAKiR,eAENjR,KAAK2+B,eAAiB,IAAIvH,GACzB/0B,EACArC,KAAK2c,cACL3c,KAAKm2B,gBACLn2B,KAAKo2B,UACLp2B,KAAKqmB,iBACLrmB,KAAKw+B,eACLx+B,KAAK++B,SACL/+B,KAAKsa,YACLta,KAAKiR,eAENjR,KAAK8+B,4BAA8B,IAAI7D,GACtC54B,EACArC,KAAK2c,cACL3c,KAAKm2B,gBACLn2B,KAAKo2B,UACLp2B,KAAKqmB,iBACLrmB,KAAKsa,YACLta,KAAKiR,eAENjR,KAAK6+B,aAAe,IAAIpE,GACvBp4B,EACArC,KAAK8+B,4BAEP,EAACz9B,EAEMu+B,gBAAA,SAAgB18B,GACtBlD,KAAK09B,SAASx6B,EACf,EAAC7B,EAEOq8B,SAAA,SAASx6B,GACXlD,KAAKo+B,SAASh7B,SAASF,KAI5BlD,KAAKiR,cAAcjB,cAAchQ,KAAKo+B,UAEtCp+B,KAAKyC,WAAWzC,KAAKo+B,SAAS,IAC9Bp+B,KAAKo+B,SAAW,GAChBp+B,KAAKm2B,yBACLn2B,KAAKo2B,UAAS,SACdp2B,KAAKu+B,WAAa,CAAEv9B,KAAM,QAC3B,EAACK,EAEOw+B,eAAA,WAMH7/B,KAAKo+B,SAASt4B,QACjB9F,KAAKiR,cAActB,wBAAwB3P,KAAKo+B,UAGjDp+B,KAAKo+B,SAAW,GAChBp+B,KAAKu+B,WAAa,CAAEv9B,KAAM,OAC3B,EAACK,EAEOy+B,yBAAA,WACP9/B,KAAKu+B,WAAa,CAAEv9B,KAAM,QAC1BhB,KAAKc,UAAU,QAChB,EAACO,EAEO0+B,iBAAA,SAAiB7wB,GACxB,IAAMvQ,EAAaqB,KAAKsa,YAAYf,cAAcrK,GAC5C8wB,EAAYhgC,KAAKq+B,MAAM1/B,EAAWuC,MAElC++B,QAAeD,SAAAA,EAAW1hC,QAE1B4hC,EAA+B,MAAZD,OAAY,EAAZA,EAAc58B,YAYvC,MAAO,CACN48B,aAAAA,EACAC,iBAAAA,EACAC,kBATAF,IACCA,EAAaG,YACbF,MAAAA,OAAAA,EAAAA,EAAkBE,aACF,MAAhBF,OAAgB,EAAhBA,EAAkBG,YAPoB,uBAAhCH,SAAAA,EAAkBnM,YACzBmM,EAAiBnM,UAAUqM,WAc7B,EAAC/+B,EAEOqqB,aAAA,SAAa3pB,GAA0B8N,IAAAA,OAC9C,GAAK7P,KAAKm2B,gBAAgB1R,IAAI3e,OAA9B,CAIA,IAAIw6B,EAEAC,EAAyBr0B,SAiB7B,GAfAlM,KAAKm2B,gBAAgB1R,IAAInH,QAAQ,SAACpa,GACjC,IAAMC,EAAW0M,EAAKyK,YAAYpB,YAAmBhW,GAC/CyE,EAAWkI,EAAK8M,cAAcJ,QAAQxa,EAAOoB,EAASE,aAG3DsE,EAAWkI,EAAKxP,iBAChBsH,EAAW44B,IAEXA,EAAyB54B,EACzB24B,EAA6BzwB,EAAKyK,YAAYf,cAC7CrW,GAGH,GAEKo9B,EAAL,CAIA,IAAMpxB,EAAYoxB,EAA2BE,wBACvC3U,EAAkByU,EAA2BnuB,MAG7CxT,EAAaqB,KAAKsa,YAAYf,cAAcrK,GAC5C8wB,EAAYhgC,KAAKq+B,MAAM1/B,EAAWuC,MASxC,GALE8+B,GACAA,EAAU1hC,SACV0hC,EAAU1hC,QAAQ+E,aAClB28B,EAAU1hC,QAAQ+E,YAAYo9B,UAEhC,CAIA,IAEIp9B,EAFEF,EAAWnD,KAAKsa,YAAYpB,YAAYhK,GAG9C,GAAsB,YAAlB/L,EAASnC,MAIZ,IAHAqC,EAAcF,EAASE,YAAY,IAGnByC,QAAU,EACzB,WAES3C,IAAkB,eAAlBA,EAASnC,KAQnB,OAJA,IAHAqC,EAAcF,EAASE,aAGPyC,QAAU,EACzB,MAIF,CAGmB,YAAlB3C,EAASnC,MACY,IAApB6qB,GAAyBA,IAAoBxoB,EAAYyC,OAAS,EAWnEzC,EAAYq9B,OAAO7U,EAAiB,IALpCxoB,EAAY8jB,QACZ9jB,EAAY0kB,MACZ1kB,EAAY0G,KAAK,CAAC1G,EAAY,GAAG,GAAIA,EAAY,GAAG,MAMrD,IAAI4mB,EAA6D,KA0BjE,GAxBsB,YAAlB9mB,EAASnC,KACZipB,EAAUjqB,KAAKiR,cAAc5B,cAAc,CAC1CH,UAAAA,EACAC,oBAAqB,CACpBnO,KAAMyM,GACNpK,YAAa,CAACA,IAEfU,QAAS,CACRL,WAAY3G,EAAY0T,UAGE,eAAlBtN,EAASnC,OACnBipB,EAAUjqB,KAAKiR,cAAc1B,iBAAiB,CAC7CL,UAAAA,EACAC,oBAAqB,CACpBnO,KAAMyM,GACNpK,YAAaA,GAEdU,QAAS,CACRL,WAAY3G,EAAY0T,WAKtBwZ,EAAL,CAIA,IAAM/F,EAAqB+F,EAAQ9mB,SAASE,YAE5CrD,KAAKiR,cAActB,wBAAuBxJ,GAAAA,OACtCnG,KAAKo2B,UAAU3R,IACfzkB,KAAKm2B,gBAAgB1R,MAGrB9lB,EAAW4mB,oBACdvlB,KAAKqmB,iBAAiBhB,eAAe,CAAEnW,UAAAA,EAAWgV,mBAAAA,IAGnDlkB,KAAKm2B,gBAAgBxiB,OAAO,CAC3BuQ,mBAAAA,EACAhV,UAAAA,IAIA8wB,GACAA,EAAU1hC,SACV0hC,EAAU1hC,QAAQ+E,aAClB28B,EAAU1hC,QAAQ+E,YAAY0wB,WAE9B/zB,KAAKo2B,UAAUziB,OAAO,CAAEuQ,mBAAAA,EAAoBhV,UAAAA,IAG7ClP,KAAK0C,SAASwM,EAAW,CACxBqG,OAAQvY,EACRkE,KAAMlB,KAAKkB,MA7BZ,CAnEA,CAlBA,CAvBA,CA2ID,EAACG,EAEOq+B,OAAA,SAAOxwB,EAAsByxB,GACpC,QADoCA,IAAAA,IAAAA,GAAa,GAC7C3gC,KAAKo+B,SAAS,KAAOlvB,EAAzB,CAIA,IAAAyL,EAAiB3a,KAAKsa,YAAYf,cAAcrK,GAG1C8wB,EAAYhgC,KAAKq+B,MAHX1jB,EAAJzZ,MAMR,GAAK8+B,GAAcA,EAAU1hC,QAA7B,CAIA,IAAMsiC,EAAuB5gC,KAAKo+B,SAAS,GAG3C,GAAIwC,EAAsB,CAEzB,GAAIA,IAAyB1xB,EAC5B,OAIAlP,KAAK09B,SAASkD,EAEhB,CAEID,GACH3gC,KAAKc,UAAUd,KAAKg/B,+BAIrBh/B,KAAKo+B,SAAW,CAAClvB,GAEjBlP,KAAKiR,cAAcZ,YAAYnB,GAE/BlP,KAAKwC,SAAS0M,GAGd,IAAA+L,EACCjb,KAAKsa,YAAYpB,YAAYhK,GADtBlO,EAAIia,EAAJja,KAAmBkjB,EAAkBjJ,EAA/B5X,YAGD,eAATrC,GAAkC,YAATA,GAIzBkjB,GAAsB8b,GAAaA,EAAU1hC,QAAQ+E,cACxDrD,KAAKm2B,gBAAgBxiB,OAAO,CAC3BuQ,mBAAAA,EACAhV,UAAAA,IAGG8wB,EAAU1hC,QAAQ+E,YAAY0wB,WACjC/zB,KAAKo2B,UAAUziB,OAAO,CACrBuQ,mBAAAA,EACAhV,UAAAA,IA5CH,CAVA,CA0DD,EAAC7N,EAEOyqB,YAAA,SAAY/pB,GACnB,IAAQutB,EAAmBtvB,KAAKy+B,qBAAqBlJ,KACpDxzB,EACA/B,KAAKo+B,SAASt4B,OAAS,GAFhBwpB,eAKFuR,EAAkB7gC,KAAKo2B,UAAU7C,mBAAmBxxB,GAEpDkC,EAAajE,KAAKo+B,SAAS,GAEjC,GAAIn6B,EAAY,CAAA,IAAA68B,EACPb,EAAiBjgC,KAAK+/B,iBAAiB97B,GAAvCg8B,aAER,GAAgB,MAAZA,GAAAa,OAAYA,EAAZb,EAAc58B,cAAdy9B,EAA2B/M,WAAa8M,EAAiB,CAG5D,GAAIZ,EAAa58B,YAAY+8B,UAAW,CACvC,IAAM5M,EAA0BxzB,KAAK2c,cAAcJ,QAClDxa,EACA/B,KAAKsa,YAAYpB,YAAmB2nB,GAAiBx9B,aAExC09B,EACb/gC,KAAK2+B,eAAejH,aAAa31B,EAAOkC,GADjCuZ,KAGR,QAC4B7b,IAA3Bo/B,GACAvN,EAA0BuN,EAE1B,MAEF,CAYA,OAVA/gC,KAAKo2B,UAAU1C,OAAO,CACrBxkB,UAAWjL,EACX0vB,WAAYkN,SAGb7gC,KAAK0C,SAAS1C,KAAKo+B,SAAS,GAAI,CAC/B7oB,OAAQvY,EACRkE,KAAMlB,KAAKkB,MAIb,CACD,CAEA,SAAIouB,GAAAA,EAAgBpsB,GACflD,KAAKi+B,sBACRj+B,KAAK0/B,OAAOpQ,EAAepsB,IAAI,WAEtBlD,KAAKo+B,SAASt4B,QAAU9F,KAAKg+B,uBAEvC,YADAh+B,KAAK09B,SAAS19B,KAAKo+B,SAAS,GAG9B,EAAC/8B,EAGDoT,MAAA,WACCzU,KAAKkC,aACLlC,KAAK2/B,cACN,EAACt+B,EAGDwU,KAAA,WACC7V,KAAK8V,UACL9V,KAAKkC,aACLlC,KAAKmC,YACN,EAACd,EAGDqD,QAAA,SAAQ3C,GAEY,UAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcZ,WAAYyC,IACtDA,EAAMiU,eACNhW,KAAK6B,kBAAkB7B,KAAKE,cAAcX,YAAawC,GAExD/B,KAAK0rB,aAAa3pB,GAED,SAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcV,UAAWuC,IAErD/B,KAAK8rB,YAAY/pB,EAEnB,EAACV,EAEO2/B,SAAA,SAASj/B,GAChB,OACC/B,KAAK8U,UAAU6lB,OACf36B,KAAK8U,UAAU6lB,MAAMnV,MAAM,SAACpgB,UAAQrD,EAAMk/B,SAAS79B,SAASgC,EAAI,EAElE,EAAC/D,EAEO6/B,UAAA,SAAUn/B,GACjB,OACK/B,KAAC8U,UAAUglB,QACf95B,KAAK8U,UAAUglB,OAAOtU,MAAM,SAACpgB,GAAG,OAAKrD,EAAMk/B,SAAS79B,SAASgC,EAAI,EAEnE,EAAC/D,EAEO8/B,uBAAA,SAAuBp/B,GAC9B,IAAMq/B,EAAiBphC,KAAKkhC,UAAUn/B,GAChCs/B,EAAcrhC,KAAKghC,SAASj/B,IAG9Bq/B,GAAkBC,IACrBt/B,EAAMu/B,gBAER,EAACjgC,EAGD6C,UAAA,SAAUnC,GACT/B,KAAKmhC,uBAAuBp/B,EAC7B,EAACV,EAGD8C,QAAA,SAAQpC,GAGP,GAFA/B,KAAKmhC,uBAAuBp/B,GAExB/B,KAAK8U,UAAgB,QAAI/S,EAAMqD,MAAQpF,KAAK8U,UAAS,OAAS,CACjE,IAAK9U,KAAKo+B,SAASt4B,OAClB,OAGD,IAAM7B,EAAajE,KAAKo+B,SAAS,GAMjCp+B,KAAKyC,WADsBzC,KAAKo+B,SAAS,IAKzCp+B,KAAKqmB,iBAAiBL,yBAAyB,CAAC/hB,IAGhDjE,KAAK6/B,iBAGL7/B,KAAKm2B,yBACLn2B,KAAKo2B,UAAS,QACf,MACCp2B,KAAK8U,UAAU4oB,UACf37B,EAAMqD,MAAQpF,KAAK8U,UAAU4oB,UAE7B19B,KAAK8V,SAEP,EAACzU,EAGDyU,QAAA,WACK9V,KAAKo+B,SAASt4B,QACjB9F,KAAK09B,SAAS19B,KAAKo+B,SAAS,GAE9B,EAAC/8B,EAGD5B,YAAA,SACCsC,EACA4C,GAEA,GAAK3E,KAAK6B,kBAAkB7B,KAAKE,cAAcT,YAAasC,GAA5D,CAMA,IAAMkC,EAAajE,KAAKo+B,SAAS,GACjC,GAAKn6B,EAAL,CAMA,IAAAs9B,EACCvhC,KAAK+/B,iBAAiB97B,GADfg8B,EAAYsB,EAAZtB,aAAcC,EAAgBqB,EAAhBrB,iBAGtB,GAHyDqB,EAAjBpB,kBAGxC,CAIAngC,KAAKm+B,eAAiB,EAEtB,IAAMqD,EACoB,SAAzBxhC,KAAKu+B,WAAWv9B,MAChBhB,KAAKu+B,WAAWrvB,YAAcjL,EAC3BjE,KAAKu+B,WACL,CAAEv9B,KAAM,QAENygC,EACsB,eAA3BD,EAAkBxgC,KACfwgC,EAAkB3V,gBAClB7rB,KAAK2+B,eAAehH,kBAAkB51B,EAAOkC,GAE3Cy9B,EACsB,WAA3BF,EAAkBxgC,KACfwgC,EAAkB3V,gBAClB7rB,KAAK8+B,4BAA4BnH,kBAAkB51B,EAAOkC,GAExD09B,GACW,MAAhBzB,OAAgB,EAAhBA,EAAkBG,aAA2C,IAA9BqB,EAE1BE,GACW,MAAhB1B,OAAgB,EAAhBA,EAAkBE,aAA2C,IAA9BqB,EAE1BI,EACL3B,GACsC,iBAA/BA,EAAiBnM,WACxBmM,EAAiBnM,UAAUqM,UAEtB0B,GACL7B,MAAAA,OAAAA,EAAAA,EAAcG,aACc,YAA3BoB,EAAkBxgC,MAClBhB,KAAK0+B,YAAYhI,QAAQ30B,EAAOkC,IAGlC,GAAI09B,EASH,OARA3hC,KAAKc,UAAUd,KAAK+U,QAAQsT,WAE5BroB,KAAK8+B,4BAA4BvI,cAChCtyB,EACAy9B,QAGD/8B,GAAmB,GAKpB,GAAIi9B,EAMH,OALA5hC,KAAKc,UAAUd,KAAK+U,QAAQsT,WAE5BroB,KAAK2+B,eAAepI,cAActyB,EAAYw9B,QAE9C98B,GAAmB,GAKpB,GAAIk9B,EAAmB,CACtB,IAAME,EACsB,aAA3BP,EAAkBxgC,KACfwgC,EAAkB7N,WAClB3zB,KAAKo2B,UAAU7C,mBAAmBxxB,GAEtC,GAAI/B,KAAKo+B,SAASt4B,QAAUi8B,EAAmB,CAE9C/hC,KAAKo2B,UAAU1C,OAAO,CACrBxkB,UAAWjL,EACX0vB,WAAYoO,IAGb/hC,KAAK0C,SAAS1C,KAAKo+B,SAAS,GAAI,CAC/B7oB,OAAQvY,EACRkE,KAAMlB,KAAKkB,OAGZ,IAAM8gC,EACLhiC,KAAK2+B,eAAehH,kBAAkB51B,EAAOkC,GAS9C,OAPAjE,KAAK2+B,eAAepI,cACnBtyB,EACA+9B,QAGDr9B,GAAmB,EAGpB,CACD,CAGA,GAAIm9B,EAIH,OAHA9hC,KAAKc,UAAUd,KAAK+U,QAAQsT,WAC5BroB,KAAK0+B,YAAYnI,cAAcx0B,EAAOkC,QACtCU,GAAmB,GAIpB3E,KAAKc,UAAU,QApGf,CATA,CAPA,CAqHD,EAACO,EAGD3B,OAAA,SACCqC,EACA4C,GAEA,GAAK3E,KAAK6B,kBAAkB7B,KAAKE,cAAcR,OAAQqC,GAAvD,CAIA,IAAMkC,EAAajE,KAAKo+B,SAAS,GAGjC,GAAKn6B,EAAL,CAIA,IAAMtF,EAAaqB,KAAKsa,YAAYf,cAActV,GAC5C+7B,EAAYhgC,KAAKq+B,MAAM1/B,EAAWuC,MAClC+gC,GAGqC,KAFzCjC,GACAA,EAAU1hC,SACV0hC,EAAU1hC,QAAQ4jC,mBAOpB,GAJAliC,KAAKm+B,iBAIDn+B,KAAKm+B,eAAiBn+B,KAAKk+B,mBAAsB,EAArD,CAKA,GACC8B,GACAA,EAAU1hC,SACV0hC,EAAU1hC,QAAQ6jC,YAClBniC,KAAKkhC,UAAUn/B,GAIf,OAFA4C,GAAmB,QACnB3E,KAAK4+B,cAAc9E,OAAO/3B,EAAOkC,GAKlC,GACC+7B,GACAA,EAAU1hC,SACV0hC,EAAU1hC,QAAQ8jC,WAClBpiC,KAAKghC,SAASj/B,GAKd,OAHA4C,GAAmB,QAEnB3E,KAAK6+B,aAAalE,MAAM54B,EAAOkC,GAIhC,GACCjE,KAAK8+B,4BAA4BrI,cACjCuJ,EAAU1hC,SACV0hC,EAAU1hC,QAAQ+E,aAClB28B,EAAU1hC,QAAQ+E,YAAYg9B,UAC7B,CACD,GAAwB,UAApBrgC,KAAKU,WACR,UAAUuB,MACT,2DASF,OALA0C,GAAmB,QACnB3E,KAAK8+B,4BAA4BnI,KAChC50B,EACAi+B,EAAU1hC,QAAQ+E,YAAYg9B,UAGhC,CAGA,GAAIrgC,KAAK2+B,eAAelI,aAAc,KAAA4L,EAC/BphB,EAA6B,OAApBohB,EAAGrC,EAAU1hC,iBAAO+jC,EAAjBA,EAAmBh/B,oBAAnBg/B,EAAgCphB,UAE9CqhB,EAAwB,CAAEvU,cAAc,GAQ5C,OAPkB,IAAd9M,EACHqhB,EAAc,CAAEvU,cAAc,GACC,iBAAd9M,IACjBqhB,EAAcrhB,QAGfjhB,KAAK2+B,eAAehI,KAAK50B,EAAOkgC,EAAkBK,EAEnD,CAGItiC,KAAK0+B,YAAYjI,aACpBz2B,KAAK0+B,YAAY/H,KAAK50B,GAIvB4C,GAAmB,EApEnB,CAhBA,CAPA,CA4FD,EAACtD,EAGD1B,UAAA,SACCoC,EACA4C,GAEK3E,KAAK6B,kBAAkB7B,KAAKE,cAAcP,UAAWoC,KAI1D/B,KAAKc,UAAUd,KAAK+U,QAAQuT,SAIxBtoB,KAAK2+B,eAAelI,aACvBz2B,KAAK0C,SAAS1C,KAAKo+B,SAAS,GAAI,CAC/Bl9B,KAAMlB,KAAKkB,KACXqU,OnEj7Ba,mBmEm7BJvV,KAAK0+B,YAAYjI,aAC3Bz2B,KAAK0C,SAAS1C,KAAKo+B,SAAS,GAAI,CAC/Bl9B,KAAMlB,KAAKkB,KACXqU,OnEr7BU,gBmEu7BDvV,KAAK8+B,4BAA4BrI,cAC3Cz2B,KAAK0C,SAAS1C,KAAKo+B,SAAS,GAAI,CAC/Bl9B,KAAMlB,KAAKkB,KACXqU,OnEz7BmB,yBmE67BrBvV,KAAK2+B,eAAenI,eACpBx2B,KAAK0+B,YAAYlI,eACjBx2B,KAAK8+B,4BAA4BtI,eACjCx2B,KAAK4+B,cAAc/E,QACnB75B,KAAK6+B,aAAahF,QAClBl1B,GAAmB,GACpB,EAACtD,EAGDoD,YAAA,SAAY1C,GACX,IAAMkC,EAAajE,KAAKo+B,SAAS,GACjC,GAAKn6B,GAKL,KACCjE,KAAK0+B,YAAYjI,cACjBz2B,KAAK2+B,eAAelI,cACpBz2B,KAAK8+B,4BAA4BrI,cAHlC,CAQA,IAAQwJ,EAAiBjgC,KAAK+/B,iBAAiB97B,GAAvCg8B,aACR,GAAKA,EAAL,CAKA,IAAIsC,OAAwC5gC,EACtCu+B,EAAmBD,EAAa58B,YAgBtC,SAdI68B,GAAAA,EAAkBnM,YACrBwO,EAAiBviC,KAAKo2B,UAAU7C,mBAAmBxxB,MAElD/B,KAAKu+B,WAAa,CACjBv9B,KAAM,WACNkO,UAAWjL,EACX0vB,WAAY4O,GAEbviC,KAAKc,UAAUd,KAAK+U,QAAQ8oB,iBAM1BqC,GAAoBA,EAAiBE,UAAW,CACnD,IAAAoC,EACCxiC,KAAK2+B,eAAejH,aAAa31B,EAAOkC,GADjCkO,EAAKqwB,EAALrwB,MAAaswB,EAAkCD,EAAxChlB,KAGf,GAAIrL,GAAS,EAAG,CACf,GAAIowB,GAC6BviC,KAAK2c,cAAcJ,QAClDxa,EACA/B,KAAKsa,YAAYpB,YAAmBqpB,GAAgBl/B,aAEvBo/B,EAC7B,OAUF,OANAziC,KAAKu+B,WAAa,CACjBv9B,KAAM,aACNkO,UAAWjL,EACX4nB,gBAAiB1Z,QAElBnS,KAAKc,UAAUd,KAAKm/B,iCAErB,CACD,CAEA,GAAIe,GAAoBA,EAAiBG,UAAW,CACnD,IAAMluB,EAAQnS,KAAK8+B,4BAA4BnH,kBAC9C51B,EACAkC,GAED,GAAIkO,GAAS,EAOZ,OANAnS,KAAKu+B,WAAa,CACjBv9B,KAAM,SACNkO,UAAWjL,EACX4nB,gBAAiB1Z,QAElBnS,KAAKc,UAAUd,KAAKs/B,mCAGtB,CAEA,GAAIW,EAAaG,WAAapgC,KAAK0+B,YAAYhI,QAAQ30B,EAAOkC,GAAa,CAC1E,GAAIs+B,EACH,OAKD,OAFAviC,KAAKu+B,WAAa,CAAEv9B,KAAM,UAAWkO,UAAWjL,QAChDjE,KAAKc,UAAUd,KAAKg/B,8BAErB,CAEKuD,GACJviC,KAAK8/B,0BAvEN,MAFC9/B,KAAK8/B,0BAJN,OAVC9/B,KAAK8/B,0BAyFP,EAACz+B,EAGD6U,aAAA,SAAa5X,GACZ,IAAMmD,EAAML,EAAQsa,CAAAA,ElDloCd,CACNvF,iBAAkB,UAClBC,oBAAqB,UACrBC,oBAAqB,EACrBC,sBAAuB,EACvBC,mBAAoB,GACpBC,WAAY,UACZC,aAAc,EACdC,kBAAmB,UACnBC,oBAAqB,EACrBC,kBAAmB,EACnBC,WAAY,EACZC,gBAAiB,UACjBC,gBAAiB,EACjBC,kBAAmB,EACnBC,OAAQ,EACRC,eAAWvV,EACXwV,kBAAcxV,EACdyV,iBAAazV,EACb0V,oBAAgB1V,IkDinChB,GACCrD,EAAQK,WAAWuC,OAASlB,KAAKkB,MACP,UAA1B5C,EAAQ6E,SAASnC,KAChB,CACD,GAAI1C,EAAQK,WAAWxB,EAAkBI,iBAuCxC,OAtCAkE,EAAO+U,WAAaxW,KAAK4E,wBACxB5E,KAAKyB,OAAOihC,oBACZjhC,EAAO+U,WACPlY,GAGDmD,EAAOgV,aAAezW,KAAKgF,uBAC1BhF,KAAKyB,OAAOkhC,sBACZ,EACArkC,GAGDmD,EAAOiV,kBAAoB1W,KAAK4E,wBAC/B5E,KAAKyB,OAAOmhC,2BACZnhC,EAAOiV,kBACPpY,GAGDmD,EAAOoV,WAAa7W,KAAKgF,uBACxBhF,KAAKyB,OAAOohC,oBACZphC,EAAOoV,WACPvY,GAGDmD,EAAOkV,oBAAsB3W,KAAKgF,uBACjChF,KAAKyB,OAAOqhC,6BACZ,EACAxkC,GAGDmD,EAAOmV,kBAAoB5W,KAAKgF,uBAC/BhF,KAAKyB,OAAOshC,2BACZ,EACAzkC,GAGDmD,EAAOwV,OnEx5BG,GmE05BHxV,EAGR,GAAInD,EAAQK,WAAWxB,EAAkBE,WAuCxC,OAtCAoE,EAAO+U,WAAaxW,KAAK4E,wBACxB5E,KAAKyB,OAAOuhC,cACZvhC,EAAO+U,WACPlY,GAGDmD,EAAOgV,aAAezW,KAAKgF,uBAC1BhF,KAAKyB,OAAOwhC,gBACZ,EACA3kC,GAGDmD,EAAOiV,kBAAoB1W,KAAK4E,wBAC/B5E,KAAKyB,OAAOyhC,qBACZzhC,EAAOiV,kBACPpY,GAGDmD,EAAOoV,WAAa7W,KAAKgF,uBACxBhF,KAAKyB,OAAO0hC,cACZ,EACA7kC,GAGDmD,EAAOkV,oBAAsB3W,KAAKgF,uBACjChF,KAAKyB,OAAO2hC,uBACZ,EACA9kC,GAGDmD,EAAOmV,kBAAoB5W,KAAKgF,uBAC/BhF,KAAKyB,OAAO4hC,qBACZ,EACA/kC,GAGDmD,EAAOwV,OnEh8BE,GmEk8BFxV,CAET,MAAO,GAAInD,EAAQK,WAAWxB,EAAkBC,UAAW,CAI1D,GAC2B,UAA1BkB,EAAQ6E,SAASnC,MACjB1C,EAAQK,WAAWnB,EAAkBW,QAiBrC,OAfAsD,EAAOyV,UAAYlX,KAAKiF,mBACvBjF,KAAKyB,OAAO6hC,kBACZrmC,EACAqB,GAEDmD,EAAO0V,aAAenX,KAAKgF,uBAC1BhF,KAAKyB,OAAO8hC,qBACZ,GACAjlC,GAEDmD,EAAO2V,YAAcpX,KAAKgF,uBACzBhF,KAAKyB,OAAO+hC,oBACZ,GACAllC,GAEMmD,EACGnD,GAA0B,YAA1BA,EAAQ6E,SAASnC,KAgC3B,OA/BAS,EAAO0U,iBAAmBnW,KAAK4E,wBAC9B5E,KAAKyB,OAAOgiC,qBACZhiC,EAAO0U,iBACP7X,GAGDmD,EAAO4U,oBAAsBrW,KAAKgF,uBACjChF,KAAKyB,OAAOiiC,4BACZjiC,EAAO4U,oBACP/X,GAGDmD,EAAO2U,oBAAsBpW,KAAK4E,wBACjC5E,KAAKyB,OAAOkiC,4BACZliC,EAAO2U,oBACP9X,GAGDmD,EAAO6U,sBAAwBtW,KAAKgF,uBACnChF,KAAKyB,OAAOmiC,8BACZ,EACAtlC,GAGDmD,EAAO8U,mBAAqBvW,KAAKgF,uBAChChF,KAAKyB,OAAOoiC,2BACZpiC,EAAO8U,mBACPjY,GAGDmD,EAAOwV,OAAS7Y,EACTqD,EACGnD,GAA0B,eAA1BA,EAAQ6E,SAASnC,KAc3B,OAbAS,EAAOqV,gBAAkB9W,KAAK4E,wBAC7B5E,KAAKyB,OAAOqiC,wBACZriC,EAAOqV,gBACPxY,GAGDmD,EAAOsV,gBAAkB/W,KAAKgF,uBAC7BhF,KAAKyB,OAAOsiC,wBACZtiC,EAAOsV,gBACPzY,GAGDmD,EAAOwV,OAAS7Y,EACTqD,EACD,GAA8B,UAA1BnD,EAAQ6E,SAASnC,KAsC3B,OArCAS,EAAOoV,WAAa7W,KAAKgF,uBACxBhF,KAAKyB,OAAOuiC,mBACZviC,EAAOoV,WACPvY,GAGDmD,EAAO+U,WAAaxW,KAAK4E,wBACxB5E,KAAKyB,OAAOwiC,mBACZxiC,EAAO+U,WACPlY,GAGDmD,EAAOgV,aAAezW,KAAKgF,uBAC1BhF,KAAKyB,OAAOyiC,qBACZ,EACA5lC,GAGDmD,EAAOiV,kBAAoB1W,KAAK4E,wBAC/B5E,KAAKyB,OAAO0iC,0BACZ1iC,EAAOiV,kBACPpY,GAGDmD,EAAOkV,oBAAsB3W,KAAKgF,uBACjChF,KAAKyB,OAAO2iC,4BACZ,EACA9lC,GAGDmD,EAAOmV,kBAAoB5W,KAAKgF,uBAC/BhF,KAAKyB,OAAO4iC,0BACZ5iC,EAAOmV,kBACPtY,GAGDmD,EAAOwV,OAAS7Y,EACTqD,CAET,CAEA,OAAOA,CACR,EAACJ,EAEDyB,oBAAA,SAAoBxE,GAGnB,GAAI0B,KAAKo+B,SAASt4B,QAAUxH,EAAQ4E,KAAOlD,KAAKo+B,SAAS,GAAI,CAAA,IAAAkG,EAAAC,EACtDlG,EAAQr+B,KAAKq+B,MAAM//B,EAAQK,WAAWuC,MAE5C,GAAU,MAALm9B,UAAKiG,EAALjG,EAAO//B,WAAPgmC,EAAgBjhC,YACpB,OAGD,IAAMrC,EAAO1C,EAAQ6E,SAASnC,KACxBkC,EAAK5E,EAAQ4E,GAKnB,GAHAlD,KAAKm2B,gBAAsB,SAC3Bn2B,KAAKo2B,UAAS,SAED,eAATp1B,GAAkC,YAATA,EAC5B,OAGD,IAAMkjB,EAAqB5lB,EAAQ6E,SAASE,YAE5CrD,KAAKm2B,gBAAgBxiB,OAAO,CAC3BuQ,mBAAAA,EACAhV,UAAWhM,IAGH,MAALm7B,GAAckG,OAATA,EAALlG,EAAO//B,UAAoB,OAAbimC,EAAdA,EAAgBlhC,cAAhBkhC,EAA6BxQ,WAChC/zB,KAAKo2B,UAAUziB,OAAO,CACrBuQ,mBAAAA,EACAhV,UAAWhM,GAGd,CACD,EAAC46B,CAAA,EAztCuCr4B,GCrJ5B++B,yBAAoB9+B,GAAA,SAAA8+B,IAAA5+B,IAAAD,IAAAA,EAAAC,EAAAC,UAAAC,OAAAC,EAAAvH,IAAAA,MAAAoH,GAAAI,EAAA,EAAAA,EAAAJ,EAAAI,IAAAD,EAAAC,GAAAH,UAAAG,GAERL,OAFQA,EAAAD,EAAAO,KAAAC,MAAAR,EAAAS,CAAAA,MAAAA,OAAAJ,KAAAJ,MAChC3E,KAAO9B,EAAUulC,OAAM9+B,EACvBzE,KAAO,SAAiByE,CAAA,CAAAU,EAAAm+B,EAAA9+B,OAAArE,EAAAmjC,EAAAljC,UAavB,OAbuBD,EACxBoT,MAAA,aAAUpT,EACVwU,KAAA,WAASxU,EAAAA,EACT8C,QAAA,aAAY9C,EACZ6C,UAAA,aAAc7C,EACdqD,QAAA,aAAYrD,EACZ5B,YAAA,aAAgB4B,EAChB3B,OAAA,WAAW2B,EAAAA,EACX1B,UAAA,WAAc0B,EAAAA,EACdoD,YAAA,WAAgBpD,EAAAA,EAChByU,QAAA,aAAYzU,EACZ6U,aAAA,WACC,OAAA9U,EAAYsa,CAAAA,EnDlBN,CACNvF,iBAAkB,UAClBC,oBAAqB,UACrBC,oBAAqB,EACrBC,sBAAuB,EACvBC,mBAAoB,GACpBC,WAAY,UACZC,aAAc,EACdC,kBAAmB,UACnBC,oBAAqB,EACrBC,kBAAmB,EACnBC,WAAY,EACZC,gBAAiB,UACjBC,gBAAiB,EACjBC,kBAAmB,EACnBC,OAAQ,EACRC,eAAWvV,EACXwV,kBAAcxV,EACdyV,iBAAazV,EACb0V,oBAAgB1V,GmDAjB,EAAC6iC,CAAA,EAfuC5kC,GCFnC,SAAU8kC,GACfC,EACA/P,EACAgQ,EACAC,EACAC,GAEA,KAAOD,EAAQD,GAAM,CACpB,GAAIC,EAAQD,EAAO,IAAK,CACvB,IAAM9L,EAAI+L,EAAQD,EAAO,EACnBG,EAAInQ,EAAIgQ,EAAO,EACf5kB,EAAIrZ,KAAKiC,IAAIkwB,GACbkM,EAAI,GAAMr+B,KAAKqC,IAAK,EAAIgX,EAAK,GAC7BilB,EACL,GAAMt+B,KAAKW,KAAM0Y,EAAIglB,GAAKlM,EAAIkM,GAAMlM,IAAMiM,EAAIjM,EAAI,EAAI,GAAK,EAAI,GAGhE4L,GAAYC,EAAK/P,EAFDjuB,KAAK6T,IAAIoqB,EAAMj+B,KAAK2Y,MAAMsV,EAAKmQ,EAAIC,EAAKlM,EAAImM,IAC3Ct+B,KAAK4T,IAAIsqB,EAAOl+B,KAAK2Y,MAAMsV,GAAMkE,EAAIiM,GAAKC,EAAKlM,EAAImM,IAC7BH,EACxC,CAEA,IAAMljB,EAAI+iB,EAAI/P,GACV/qB,EAAI+6B,EACJlQ,EAAImQ,EAKR,IAHAK,GAAKP,EAAKC,EAAMhQ,GACZkQ,EAAQH,EAAIE,GAAQjjB,GAAK,GAAGsjB,GAAKP,EAAKC,EAAMC,GAEzCh7B,EAAI6qB,GAAG,CAIb,IAHAwQ,GAAKP,EAAK96B,EAAG6qB,GACb7qB,IACA6qB,IACOoQ,EAAQH,EAAI96B,GAAI+X,GAAK,GAAG/X,IAC/B,KAAOi7B,EAAQH,EAAIjQ,GAAI9S,GAAK,GAAG8S,GAChC,CAE8B,IAA1BoQ,EAAQH,EAAIC,GAAOhjB,GACtBsjB,GAAKP,EAAKC,EAAMlQ,GAGhBwQ,GAAKP,IADLjQ,EACamQ,GAGVnQ,GAAKE,IAAGgQ,EAAOlQ,EAAI,GACnBE,GAAKF,IAAGmQ,EAAQnQ,EAAI,EACzB,CACD,CAEA,SAASwQ,GAAQP,EAAU96B,EAAW6qB,GACrC,IAAMyQ,EAAMR,EAAI96B,GAChB86B,EAAI96B,GAAK86B,EAAIjQ,GACbiQ,EAAIjQ,GAAKyQ,CACV,CCvCA,SAASC,GAASC,EAAYC,GAC7BC,GAASF,EAAM,EAAGA,EAAKG,SAAS1/B,OAAQw/B,EAAQD,EACjD,CAGA,SAASE,GACRF,EACAzQ,EACAR,EACAkR,EACAG,GAEKA,IAAUA,EAAWC,GAAW,KACrCD,EAASE,KAAOz5B,SAChBu5B,EAASG,KAAO15B,SAChBu5B,EAASI,MAAQ35B,SACjBu5B,EAASK,MAAQ55B,SAEjB,IAAK,IAAIrC,EAAI+qB,EAAG/qB,EAAIuqB,EAAGvqB,IAAK,CAC3B,IAAMk8B,EAAQV,EAAKG,SAAS37B,GAC5Bm8B,GAAOP,EAAUJ,EAAKY,KAAOX,EAAOS,GAASA,EAC9C,CAEA,OAAON,CACR,CAEA,SAASO,GAAO9+B,EAAS6W,GAKxB,OAJA7W,EAAEy+B,KAAOh/B,KAAK4T,IAAIrT,EAAEy+B,KAAM5nB,EAAE4nB,MAC5Bz+B,EAAE0+B,KAAOj/B,KAAK4T,IAAIrT,EAAE0+B,KAAM7nB,EAAE6nB,MAC5B1+B,EAAE2+B,KAAOl/B,KAAK6T,IAAItT,EAAE2+B,KAAM9nB,EAAE8nB,MAC5B3+B,EAAE4+B,KAAOn/B,KAAK6T,IAAItT,EAAE4+B,KAAM/nB,EAAE+nB,MACrB5+B,CACR,CAEA,SAASg/B,GAAgBh/B,EAAS6W,GACjC,OAAO7W,EAAEy+B,KAAO5nB,EAAE4nB,IACnB,CACA,SAASQ,GAAgBj/B,EAAS6W,GACjC,OAAO7W,EAAE0+B,KAAO7nB,EAAE6nB,IACnB,CAEA,SAASQ,GAASl/B,GACjB,OAAQA,EAAE2+B,KAAO3+B,EAAEy+B,OAASz+B,EAAE4+B,KAAO5+B,EAAE0+B,KACxC,CACA,SAASS,GAAWn/B,GAMnB,OAAOA,EAAE2+B,KAAO3+B,EAAEy+B,MAAQz+B,EAAE4+B,KAAO5+B,EAAE0+B,KACtC,CAkBA,SAASU,GAASp/B,EAAS6W,GAC1B,OACC7W,EAAEy+B,MAAQ5nB,EAAE4nB,MAAQz+B,EAAE0+B,MAAQ7nB,EAAE6nB,MAAQ7nB,EAAE8nB,MAAQ3+B,EAAE2+B,MAAQ9nB,EAAE+nB,MAAQ5+B,EAAE4+B,IAE1E,CAEA,SAASS,GAAWr/B,EAAS6W,GAC5B,OACCA,EAAE4nB,MAAQz+B,EAAE2+B,MAAQ9nB,EAAE6nB,MAAQ1+B,EAAE4+B,MAAQ/nB,EAAE8nB,MAAQ3+B,EAAEy+B,MAAQ5nB,EAAE+nB,MAAQ5+B,EAAE0+B,IAE1E,CAEA,SAASF,GAAWF,GACnB,MAAO,CACNA,SAAAA,EACAgB,OAAQ,EACRP,MAAM,EACNN,KAAMz5B,SACN05B,KAAM15B,SACN25B,MAAO35B,SACP45B,MAAO55B,SAET,CAKA,SAASu6B,GACR9B,EACAC,EACAC,EACA/L,EACAgM,GAIA,IAFA,IAAM4B,EAAQ,CAAC9B,EAAMC,GAEd6B,EAAM5gC,QAIZ,MAHA++B,EAAQ6B,EAAM3e,QACd6c,EAAO8B,EAAM3e,QAEO+Q,GAApB,CAEA,IAAM7F,EAAM2R,EAAOj+B,KAAKggC,MAAM9B,EAAQD,GAAQ9L,EAAI,GAAKA,EACvD4L,GAAYC,EAAK1R,EAAK2R,EAAMC,EAAOC,GAEnC4B,EAAM38B,KAAK66B,EAAM3R,EAAKA,EAAK4R,GAE7B,CAEa,IAAA+B,gBAKZ,WAAA,SAAAA,EAAYC,QAJJC,iBAAW,EAAA9mC,KACX+mC,iBACAC,EAAAA,KAAAA,YAIPhnC,KAAK8mC,YAAcngC,KAAK6T,IAAI,EAAGqsB,GAC/B7mC,KAAK+mC,YAAcpgC,KAAK6T,IAAI,EAAG7T,KAAKggC,KAAwB,GAAnB3mC,KAAK8mC,cAC9C9mC,KAAK2nB,OACN,CAAC,IAAAtmB,EAAAulC,EAAAtlC,iBAAAD,EAED6b,OAAA,SAAOD,GACN,IAAIooB,EAAOrlC,KAAKgnC,KACVC,EAAiB,GAEvB,IAAKV,GAAWtpB,EAAMooB,GACrB,OAAO4B,EAMR,IAHA,IAAM3B,EAAStlC,KAAKslC,OACd4B,EAAgB,GAEf7B,GAAM,CACZ,IAAK,IAAIx7B,EAAI,EAAGA,EAAIw7B,EAAKG,SAAS1/B,OAAQ+D,IAAK,CAC9C,IAAMk8B,EAAQV,EAAKG,SAAS37B,GACtBs9B,EAAY9B,EAAKY,KAAOX,EAAOS,GAASA,EAE1CQ,GAAWtpB,EAAMkqB,KAChB9B,EAAKY,KAAMgB,EAAOl9B,KAAKg8B,GAClBO,GAASrpB,EAAMkqB,GAAYnnC,KAAKonC,KAAKrB,EAAOkB,GAChDC,EAAcn9B,KAAKg8B,GAE1B,CACAV,EAAO6B,EAAcnf,KACtB,CAEA,OAAOkf,CACR,EAAC5lC,EAEDgmC,SAAA,SAASpqB,GACR,IAAIooB,EAAOrlC,KAAKgnC,KAGhB,GADkBT,GAAWtpB,EAAMooB,GAGlC,IADA,IAAM6B,EAAgB,GACf7B,GAAM,CACZ,IAAK,IAAIx7B,EAAI,EAAGA,EAAIw7B,EAAKG,SAAS1/B,OAAQ+D,IAAK,CAC9C,IAAMk8B,EAAQV,EAAKG,SAAS37B,GACtBs9B,EAAY9B,EAAKY,KAAOjmC,KAAKslC,OAAOS,GAASA,EAEnD,GAAIQ,GAAWtpB,EAAMkqB,GAAY,CAChC,GAAI9B,EAAKY,MAAQK,GAASrpB,EAAMkqB,GAC/B,OAAO,EAERD,EAAcn9B,KAAKg8B,EACpB,CACD,CACAV,EAAO6B,EAAcnf,KACtB,CAGD,OAAY,CACb,EAAC1mB,EAEDimC,KAAA,SAAKN,GACJ,GAAIA,EAAKlhC,OAAS9F,KAAK+mC,YACtB,IAAK,IAAIl9B,EAAI,EAAGA,EAAIm9B,EAAKlhC,OAAQ+D,IAChC7J,KAAK0zB,OAAOsT,EAAKn9B,QAFnB,CAQA,IAAIw7B,EAAOrlC,KAAKunC,OAAOP,EAAKh1B,QAAS,EAAGg1B,EAAKlhC,OAAS,EAAG,GAEzD,GAAK9F,KAAKgnC,KAAKxB,SAAS1/B,UAGb9F,KAAKgnC,KAAKR,SAAWnB,EAAKmB,OAEpCxmC,KAAKwnC,WAAWxnC,KAAKgnC,KAAM3B,OACrB,CACN,GAAIrlC,KAAKgnC,KAAKR,OAASnB,EAAKmB,OAAQ,CAEnC,IAAMiB,EAAUznC,KAAKgnC,KACrBhnC,KAAKgnC,KAAO3B,EACZA,EAAOoC,CACR,CAGAznC,KAAK0nC,QAAQrC,EAAMrlC,KAAKgnC,KAAKR,OAASnB,EAAKmB,OAAS,GAAG,EACxD,MAdCxmC,KAAKgnC,KAAO3B,CAPb,CAsBD,EAAChkC,EAEDqyB,OAAA,SAAOiU,GACN3nC,KAAK0nC,QAAQC,EAAM3nC,KAAKgnC,KAAKR,OAAS,EACvC,EAACnlC,EAEDsmB,MAAA,WACC3nB,KAAKgnC,KAAOtB,GAAW,GACxB,EAACrkC,EAEDumC,OAAA,SAAOD,GAUN,IATA,IAII99B,EACAg+B,EALAxC,EAAoBrlC,KAAKgnC,KACvB/pB,EAAOjd,KAAKslC,OAAOqC,GACnBG,EAAO,GACPC,EAAoB,GAGtBC,GAAU,EAGP3C,GAAQyC,EAAKhiC,QAAQ,CAS3B,GARKu/B,IAEJA,EAAOyC,EAAK/f,MACZ8f,EAASC,EAAKA,EAAKhiC,OAAS,GAC5B+D,EAAIk+B,EAAQhgB,MACZigB,GAAU,GAGP3C,EAAKY,KAAM,CAGd,IAAM9zB,EAAQkzB,EAAKG,SAASnjB,QAAQslB,IAErB,IAAXx1B,IAEHkzB,EAAKG,SAAS9E,OAAOvuB,EAAO,GAC5B21B,EAAK/9B,KAAKs7B,GACVrlC,KAAKioC,UAAUH,GAEjB,CAEKE,GAAY3C,EAAKY,OAAQK,GAASjB,EAAMpoB,GAOlC4qB,GAETh+B,IACDw7B,EAAOwC,EAAOrC,SAAS37B,GACvBm+B,GAAU,GAEV3C,EAAO,MAXPyC,EAAK/9B,KAAKs7B,GACV0C,EAAQh+B,KAAKF,GACbA,EAAI,EACJg+B,EAASxC,EACTA,EAAOA,EAAKG,SAAS,GASvB,CACD,EAACnkC,EAEOikC,OAAA,SAAUqC,GACjB,OAAOA,CACR,EAACtmC,EAEO6mC,YAAA,SAAYhhC,EAAS6W,GAC5B,OAAO7W,EAAEy+B,KAAO5nB,EAAE4nB,IACnB,EAACtkC,EACO8mC,YAAA,SAAYjhC,EAAS6W,GAC5B,OAAO7W,EAAE0+B,KAAO7nB,EAAE6nB,IACnB,EAACvkC,EAEO+lC,KAAA,SAAK/B,EAAY4B,GAExB,IADA,IAAMC,EAAgB,GACf7B,GACFA,EAAKY,KAAMgB,EAAOl9B,KAAI7D,MAAX+gC,EAAe5B,EAAKG,UAC9B0B,EAAcn9B,KAAI7D,MAAlBghC,EAAsB7B,EAAKG,UAEhCH,EAAO6B,EAAcnf,MAEtB,OAAOkf,CACR,EAAC5lC,EAEOkmC,OAAA,SAAOa,EAAexD,EAAcC,EAAe2B,GAC1D,IAEInB,EAFEgD,EAAIxD,EAAQD,EAAO,EACrB0D,EAAItoC,KAAK8mC,YAGb,GAAIuB,GAAKC,EAIR,OADAlD,GADAC,EAAOK,GAAW0C,EAAMp2B,MAAM4yB,EAAMC,EAAQ,IAC7B7kC,KAAKslC,QACbD,EAGHmB,IAEJA,EAAS7/B,KAAKggC,KAAKhgC,KAAKiC,IAAIy/B,GAAK1hC,KAAKiC,IAAI0/B,IAG1CA,EAAI3hC,KAAKggC,KAAK0B,EAAI1hC,KAAKuB,IAAIogC,EAAG9B,EAAS,MAGxCnB,EAAOK,GAAW,KACbO,MAAO,EACZZ,EAAKmB,OAASA,EAId,IAAM+B,EAAK5hC,KAAKggC,KAAK0B,EAAIC,GACnBE,EAAKD,EAAK5hC,KAAKggC,KAAKhgC,KAAKW,KAAKghC,IAEpC7B,GAAY2B,EAAOxD,EAAMC,EAAO2D,EAAIxoC,KAAKkoC,aAEzC,IAAK,IAAIr+B,EAAI+6B,EAAM/6B,GAAKg7B,EAAOh7B,GAAK2+B,EAAI,CACvC,IAAMC,EAAS9hC,KAAK4T,IAAI1Q,EAAI2+B,EAAK,EAAG3D,GAEpC4B,GAAY2B,EAAOv+B,EAAG4+B,EAAQF,EAAIvoC,KAAKmoC,aAEvC,IAAK,IAAIzT,EAAI7qB,EAAG6qB,GAAK+T,EAAQ/T,GAAK6T,EAAI,CACrC,IAAMG,EAAS/hC,KAAK4T,IAAIma,EAAI6T,EAAK,EAAGE,GAGpCpD,EAAKG,SAASz7B,KAAK/J,KAAKunC,OAAOa,EAAO1T,EAAGgU,EAAQlC,EAAS,GAC3D,CACD,CAIA,OAFApB,GAASC,EAAMrlC,KAAKslC,QAEbD,CACR,EAAChkC,EAEOsnC,eAAA,SAAe1rB,EAAYooB,EAAYuD,EAAed,GAC7D,KACCA,EAAK/9B,KAAKs7B,IAENA,EAAKY,MAAQ6B,EAAKhiC,OAAS,IAAM8iC,GAHzB,CAWZ,IAJA,IAAIC,EAAU38B,SACV48B,EAAiB58B,SACjB68B,OAEJ,EAASl/B,EAAI,EAAGA,EAAIw7B,EAAKG,SAAS1/B,OAAQ+D,IAAK,CAC9C,IAAMk8B,EAAQV,EAAKG,SAAS37B,GAEtB8uB,EAAOyN,GAASL,GAChBiD,GAjTY9hC,EAiTe+V,EAjTNc,EAiTYgoB,GA/SxCp/B,KAAK6T,IAAIuD,EAAE8nB,KAAM3+B,EAAE2+B,MAAQl/B,KAAK4T,IAAIwD,EAAE4nB,KAAMz+B,EAAEy+B,QAC9Ch/B,KAAK6T,IAAIuD,EAAE+nB,KAAM5+B,EAAE4+B,MAAQn/B,KAAK4T,IAAIwD,EAAE6nB,KAAM1+B,EAAE0+B,OA8SGjN,GAI5CqQ,EAAcF,GACjBA,EAAiBE,EACjBH,EAAUlQ,EAAOkQ,EAAUlQ,EAAOkQ,EAClCE,EAAahD,GACHiD,IAAgBF,GAEtBnQ,EAAOkQ,IACVA,EAAUlQ,EACVoQ,EAAahD,EAGhB,CAEAV,EAAO0D,GAAc1D,EAAKG,SAAS,EACpC,CAnUF,IAAsBt+B,EAAS6W,EAqU7B,OAAOsnB,CACR,EAAChkC,EAEOqmC,QAAA,SAAQC,EAAYiB,EAAeK,GAC1C,IAAMhsB,EAAOgsB,EAAStB,EAAO3nC,KAAKslC,OAAOqC,GACnCuB,EAAqB,GAGrB7D,EAAOrlC,KAAK2oC,eAAe1rB,EAAMjd,KAAKgnC,KAAM4B,EAAOM,GAOzD,IAJA7D,EAAKG,SAASz7B,KAAK49B,GACnB3B,GAAOX,EAAMpoB,GAGN2rB,GAAS,GACXM,EAAWN,GAAOpD,SAAS1/B,OAAS9F,KAAK8mC,aAC5C9mC,KAAKmpC,OAAOD,EAAYN,GACxBA,IAKF5oC,KAAKopC,oBAAoBnsB,EAAMisB,EAAYN,EAC5C,EAACvnC,EAGO8nC,OAAA,SAAOD,EAAoBN,GAClC,IAAMvD,EAAO6D,EAAWN,GAClBN,EAAIjD,EAAKG,SAAS1/B,OAClBi/B,EAAI/kC,KAAK+mC,YAEf/mC,KAAKqpC,iBAAiBhE,EAAMN,EAAGuD,GAE/B,IAAMgB,EAAatpC,KAAKupC,kBAAkBlE,EAAMN,EAAGuD,GAE7CkB,EAAU9D,GACfL,EAAKG,SAAS9E,OAAO4I,EAAYjE,EAAKG,SAAS1/B,OAASwjC,IAEzDE,EAAQhD,OAASnB,EAAKmB,OACtBgD,EAAQvD,KAAOZ,EAAKY,KAEpBb,GAASC,EAAMrlC,KAAKslC,QACpBF,GAASoE,EAASxpC,KAAKslC,QAEnBsD,EAAOM,EAAWN,EAAQ,GAAGpD,SAASz7B,KAAKy/B,QACrChC,WAAWnC,EAAMmE,EAC5B,EAACnoC,EAEOmmC,WAAA,SAAWnC,EAAYmE,GAE9BxpC,KAAKgnC,KAAOtB,GAAW,CAACL,EAAMmE,IAC9BxpC,KAAKgnC,KAAKR,OAASnB,EAAKmB,OAAS,EACjCxmC,KAAKgnC,KAAKf,MAAO,EACjBb,GAASplC,KAAKgnC,KAAMhnC,KAAKslC,OAC1B,EAACjkC,EAEOkoC,kBAAA,SAAkBlE,EAAYN,EAAWuD,GAKhD,IAJA,IAAIn2B,EAxXoBjL,EAAS6W,EAC5B4nB,EACAC,EACAC,EACAC,EAqXD2D,EAAav9B,SACb28B,EAAU38B,SAELrC,EAAIk7B,EAAGl7B,GAAKy+B,EAAIvD,EAAGl7B,IAAK,CAChC,IAAM6/B,EAAQnE,GAASF,EAAM,EAAGx7B,EAAG7J,KAAKslC,QAClCqE,EAAQpE,GAASF,EAAMx7B,EAAGy+B,EAAGtoC,KAAKslC,QAElCsE,GAhYiB1iC,EAgYUwiC,EAhYD3rB,EAgYQ4rB,EA/XpChE,EAAOh/B,KAAK6T,IAAItT,EAAEy+B,KAAM5nB,EAAE4nB,MAC1BC,EAAOj/B,KAAK6T,IAAItT,EAAE0+B,KAAM7nB,EAAE6nB,MAC1BC,EAAOl/B,KAAK4T,IAAIrT,EAAE2+B,KAAM9nB,EAAE8nB,MAC1BC,EAAOn/B,KAAK4T,IAAIrT,EAAE4+B,KAAM/nB,EAAE+nB,MAEzBn/B,KAAK6T,IAAI,EAAGqrB,EAAOF,GAAQh/B,KAAK6T,IAAI,EAAGsrB,EAAOF,IA2X7CjN,EAAOyN,GAASsD,GAAStD,GAASuD,GAGpCC,EAAUH,GACbA,EAAaG,EACbz3B,EAAQtI,EAERg/B,EAAUlQ,EAAOkQ,EAAUlQ,EAAOkQ,GACxBe,IAAYH,GAElB9Q,EAAOkQ,IACVA,EAAUlQ,EACVxmB,EAAQtI,EAGX,CAEA,OAAOsI,GAASm2B,EAAIvD,CACrB,EAAC1jC,EAGOgoC,iBAAA,SAAiBhE,EAAYN,EAAWuD,GAC/C,IAAMJ,EAAc7C,EAAKY,KAAOjmC,KAAKkoC,YAAchC,GAC7CiC,EAAc9C,EAAKY,KAAOjmC,KAAKmoC,YAAchC,GACnCnmC,KAAK6pC,eAAexE,EAAMN,EAAGuD,EAAGJ,GAChCloC,KAAK6pC,eAAexE,EAAMN,EAAGuD,EAAGH,IAK/C9C,EAAKG,SAASsE,KAAK5B,EAErB,EAAC7mC,EAGOwoC,eAAA,SACPxE,EACAN,EACAuD,EACAxD,GAEAO,EAAKG,SAASsE,KAAKhF,GAOnB,IALA,IAAMQ,EAAStlC,KAAKslC,OACdyE,EAAWxE,GAASF,EAAM,EAAGN,EAAGO,GAChC0E,EAAYzE,GAASF,EAAMiD,EAAIvD,EAAGuD,EAAGhD,GACvC2E,EAAS5D,GAAW0D,GAAY1D,GAAW2D,GAEtCngC,EAAIk7B,EAAGl7B,EAAIy+B,EAAIvD,EAAGl7B,IAAK,CAC/B,IAAMk8B,EAAQV,EAAKG,SAAS37B,GAC5Bm8B,GAAO+D,EAAU1E,EAAKY,KAAOX,EAAOS,GAASA,GAC7CkE,GAAU5D,GAAW0D,EACtB,CAEA,IAAK,IAAIlgC,EAAIy+B,EAAIvD,EAAI,EAAGl7B,GAAKk7B,EAAGl7B,IAAK,CACpC,IAAMk8B,EAAQV,EAAKG,SAAS37B,GAC5Bm8B,GAAOgE,EAAW3E,EAAKY,KAAOX,EAAOS,GAASA,GAC9CkE,GAAU5D,GAAW2D,EACtB,CAEA,OAAOC,CACR,EAAC5oC,EAEO+nC,oBAAA,SAAoBnsB,EAAY6qB,EAAcc,GAErD,IAAK,IAAI/+B,EAAI++B,EAAO/+B,GAAK,EAAGA,IAC3Bm8B,GAAO8B,EAAKj+B,GAAIoT,EAElB,EAAC5b,EAEO4mC,UAAA,SAAUH,GAEjB,IAAK,IAAyBoC,EAArBrgC,EAAIi+B,EAAKhiC,OAAS,EAAa+D,GAAK,EAAGA,IACf,IAA5Bi+B,EAAKj+B,GAAG27B,SAAS1/B,OAChB+D,EAAI,GACPqgC,EAAWpC,EAAKj+B,EAAI,GAAG27B,UACd9E,OAAOwJ,EAAS7nB,QAAQylB,EAAKj+B,IAAK,QAChC8d,QAEZyd,GAAS0C,EAAKj+B,GAAI7J,KAAKslC,OAG1B,EAACsB,CAAA,CApZD,GCxIYuD,gBAKZ,WAAA,SAAAA,EAAYtqC,GAJJuqC,KAAAA,iBACAC,cAAQ,EAAArqC,KACRsqC,cAGP,EAAAtqC,KAAKoqC,KAAO,IAAIxD,GACf/mC,GAAWA,EAAQgnC,WAAahnC,EAAQgnC,WAAa,GAEtD7mC,KAAKqqC,SAAW,IAAIE,IACpBvqC,KAAKsqC,SAAW,IAAIC,GACrB,CAAC,IAAAlpC,EAAA8oC,EAAA7oC,iBAAAD,EAEOmpC,QAAA,SAAQlsC,EAA+B2e,GAC9Cjd,KAAKqqC,SAAS/kC,IAAIhH,EAAQ4E,GAAiB+Z,GAC3Cjd,KAAKsqC,SAAShlC,IAAI2X,EAAM3e,EAAQ4E,GACjC,EAAC7B,EAEOikC,OAAA,SAAOhnC,GACd,IAGI+E,EAHEonC,EAAuB,GACvBC,EAAsB,GAG5B,GAA8B,YAA1BpsC,EAAQ6E,SAASnC,KACpBqC,EAAc/E,EAAQ6E,SAASE,YAAY,QACrC,GAA8B,eAA1B/E,EAAQ6E,SAASnC,KAC3BqC,EAAc/E,EAAQ6E,SAASE,oBACK,UAA1B/E,EAAQ6E,SAASnC,KAG3B,MAAM,IAAIiB,MAAM,mDAFhBoB,EAAc,CAAC/E,EAAQ6E,SAASE,YAGjC,CAEA,IAAK,IAAIwG,EAAI,EAAGA,EAAIxG,EAAYyC,OAAQ+D,IACvC6gC,EAAU3gC,KAAK1G,EAAYwG,GAAG,IAC9B4gC,EAAW1gC,KAAK1G,EAAYwG,GAAG,IAGhC,IAAM8gC,EAAShkC,KAAK4T,IAAGrU,MAARS,KAAY+jC,GACrBE,EAASjkC,KAAK6T,IAAGtU,MAARS,KAAY+jC,GAI3B,MAAO,CACN/E,KAJch/B,KAAK4T,IAAGrU,MAARS,KAAY8jC,GAK1B7E,KAAM+E,EACN9E,KALcl/B,KAAK6T,IAAGtU,MAARS,KAAY8jC,GAM1B3E,KAAM8E,EAER,EAACvpC,EAEDqyB,OAAA,SAAOp1B,GACN,GAAI0B,KAAKqqC,SAAShlC,IAAIwlC,OAAOvsC,EAAQ4E,KACpC,MAAM,IAAIjB,MAAM,0BAEjB,IAAMgb,EAAOjd,KAAKslC,OAAOhnC,GACzB0B,KAAKwqC,QAAQlsC,EAAS2e,GACtBjd,KAAKoqC,KAAK1W,OAAOzW,EAClB,EAAC5b,EAEDimC,KAAA,SAAK34B,GAAgC,IAAAhJ,EACpC3F,KAAMsnC,EAAe,GACfwD,EAAuB,IAAIC,IACjCp8B,EAAS2O,QAAQ,SAAChf,GACjB,IAAM2e,EAAOtX,EAAK2/B,OAAOhnC,GAEzB,GADAqH,EAAK6kC,QAAQlsC,EAAS2e,GAClB6tB,EAAQp7B,IAAIm7B,OAAOvsC,EAAQ4E,KAC9B,MAAM,IAAIjB,MAAK,8BAA+B3D,EAAQ4E,IAEvD4nC,EAAQE,IAAIH,OAAOvsC,EAAQ4E,KAC3BokC,EAAKv9B,KAAKkT,EACX,GACAjd,KAAKoqC,KAAK9C,KAAKA,EAChB,EAACjmC,EAEDmP,OAAA,SAAOlS,GACN0B,KAAK4nC,OAAOtpC,EAAQ4E,IACpB,IAAM+Z,EAAOjd,KAAKslC,OAAOhnC,GACzB0B,KAAKwqC,QAAQlsC,EAAS2e,GACtBjd,KAAKoqC,KAAK1W,OAAOzW,EAClB,EAAC5b,EAEDumC,OAAA,SAAO14B,GACN,IAAMm2B,EAAOrlC,KAAKqqC,SAAShlC,IAAI6J,GAC/B,IAAKm2B,EACJ,MAAU,IAAApjC,MAASiN,0CAGpBlP,KAAKoqC,KAAKxC,OAAOvC,EAClB,EAAChkC,EAEDsmB,MAAA,WACC3nB,KAAKoqC,KAAKziB,OACX,EAACtmB,EAED6b,OAAA,SAAO5e,OAA6BmQ,EAAAzO,KAEnC,OADcA,KAAKoqC,KAAKltB,OAAOld,KAAKslC,OAAOhnC,IAC9BsQ,IAAI,SAACy2B,GACjB,OAAO52B,EAAK67B,SAASjlC,IAAIggC,EAC1B,EACD,EAAChkC,EAEDgmC,SAAA,SAAS/oC,GACR,OAAO0B,KAAKoqC,KAAK/C,SAASrnC,KAAKslC,OAAOhnC,GACvC,EAAC6rC,CAAA,CAnGD,GCsCYc,GAAoB,CAChCC,MAAO,WAAF,MC/CE,uCAAuCC,QAAQ,QAAS,SAAU/uB,GACxE,IAAMgvB,EAAqB,GAAhBzkC,KAAK0kC,SAAiB,EAEjC,OADU,KAALjvB,EAAWgvB,EAAS,EAAJA,EAAW,GACvBz/B,SAAS,GACnB,ED2C4C,EAC5C3I,UAAW,SAACE,GAAa,MAAmB,iBAAPA,GAAiC,KAAdA,EAAG4C,MAAa,GAGnEwlC,GAA8B,CAAErzB,OAAQ,YACxCszB,GAAgC,CAAEtzB,OAAQ,cAEnCuzB,gBAIZ,WAAA,SAAAA,EAAYnpC,QAWLoB,gBAAU,EAAAzD,KAETyrC,aAAO,EAAAzrC,KAEP0rC,kBAAY,EAAA1rC,KAEZS,WAKAkrC,EAAAA,KAAAA,UAA6D,aArBpE3rC,KAAKS,MAAQ,CAAA,EACbT,KAAK0rC,aAAe,IAAIvB,GAIxBnqC,KAAKyrC,SAAUppC,IAA6B,IAAnBA,EAAOopC,QAChCzrC,KAAKyD,WACJpB,GAAUA,EAAOoB,WAAapB,EAAOoB,WAAawnC,EACpD,CAAC,IAAA5pC,EAAAmqC,EAAAlqC,UAgWA,OAhWAD,EAeOuqC,MAAA,SAASC,GAChB,OAAOC,KAAKC,MAAMD,KAAKE,UAAUH,GAClC,EAACxqC,EAED6pC,MAAA,WACC,OAAOlrC,KAAKyD,WAAWynC,OACxB,EAAC7pC,EAEDqO,IAAA,SAAIxM,GACH,OAAO3E,QAAQyB,KAAKS,MAAMyC,GAC3B,EAAC7B,EAEDimC,KAAA,SACCN,EACAiF,EAIAppC,EACAkB,GAAyB,IAAA4B,EAEzB3F,KAAA,GAAoB,IAAhBgnC,EAAKlhC,OACR,MAAO,GAIR,IAAIomC,EAAsBlsC,KAAK4rC,MAAM5E,GAE/B1I,EAAiC,GACjC6N,EAA0C,GAGhDD,EAAsBA,EAAoBn8B,OAAO,SAACzR,GAC7CA,QAAQ4E,KACX5E,EAAQ4E,GAAKyC,EAAKlC,WAAWynC,SAG9B,IAAMhoC,EAAK5E,EAAQ4E,GACnB,GAAI+oC,EAAmB,CACtB,IAAMvqC,EAAauqC,EAAkB3tC,GAIrC,IAAKoD,EAAW4B,MAEf,OADAg7B,EAAYv0B,KAAK,CAAE7G,GAAAA,EAAII,OAAO,EAAOC,OAAQ7B,EAAW6B,UACjD,CAET,CAEA,GAAIoC,EAAK8lC,QAAS,CACjB,GAAKntC,EAAQK,WAAWytC,WAIvB,IADcxtC,EAAiBN,EAAQK,WAAWytC,WAOjD,OALA9N,EAAYv0B,KAAK,CAChB7G,GAAI5E,EAAQ4E,GACZI,OAAO,EACPC,OAAQ,gDAEF,OATRjF,EAAQK,WAAWytC,WAAa,IAAIrtC,KAarC,GAAKT,EAAQK,WAAW0tC,WAIvB,IADcztC,EAAiBN,EAAQK,WAAW0tC,WAOjD,OALA/N,EAAYv0B,KAAK,CAChB7G,GAAI5E,EAAQ4E,GACZI,OAAO,EACPC,OAAQ,gDAEG,OATbjF,EAAQK,WAAW0tC,WAAa,IAAIttC,IAYtC,CAGA,OAAI4G,EAAK+J,IAAIxM,IACZo7B,EAAYv0B,KAAK,CAChB7G,GAAAA,EACAI,OAAO,EACPC,OAAM,wCAA0CL,KAE1C,IAGRyC,EAAKlF,MAAMyC,GAAM5E,EAEjB6tC,EAAgBpiC,KAAKzL,GAErBggC,EAAYv0B,KAAK,CAAE7G,GAAAA,EAAII,OAAO,KAGnB,EACZ,GAEAtD,KAAK0rC,aAAapE,KAAK4E,GAGvB,IAAMI,EAAUH,EAAgBv9B,IAAI,SAAA7B,GAAY,OAAPA,EAAF7J,EAAwB,GAa/D,OAVIopC,EAAQxmC,OAAS,IACpB9F,KAAK2rC,UAAUW,EAAS,SAAUvoC,GAE9BlB,GACHspC,EAAgB7uB,QAAQ,SAAChf,GACxBuE,EAAkBvE,EACnB,IAIKggC,CACR,EAACj9B,EAED6b,OAAA,SACCD,EACAlN,GAAmD,IAAAtB,EAEnDzO,KAAM2O,EAAW3O,KAAK0rC,aAAaxuB,OAAOD,GAAMrO,IAAI,SAAC1L,GAAE,OAAKuL,EAAKhO,MAAMyC,EAAG,GAC1E,OACYlD,KAAC4rC,MADT77B,EACepB,EAASoB,OAAOA,GAEhBpB,EAEpB,EAACtN,EAEDiB,iBAAA,SAAiBC,GAChBvC,KAAK2rC,UAAY,SAAClnB,EAAK8nB,EAAQxoC,GAC9BxB,EAASkiB,EAAK8nB,EAAQxoC,EACvB,CACD,EAAC1C,EAEDkP,gBAAA,SAAkDrN,GACjD,IAAM5E,EAAU0B,KAAKS,MAAMyC,GAC3B,IAAK5E,EACJ,MAAU,IAAA2D,MAAK,4BACciB,EAAE,gCAGhC,OAAWlD,KAAC4rC,MAAMttC,EAAQ6E,SAC3B,EAAC9B,EAEDkQ,kBAAA,SAAkBrO,GACjB,IAAM5E,EAAU0B,KAAKS,MAAMyC,GAC3B,IAAK5E,EACJ,MAAM,IAAI2D,MACmBiB,4BAAAA,oCAG9B,OAAWlD,KAAC4rC,MAAMttC,EAAQK,WAC3B,EAAC0C,EAED+S,eAAA,SACCo4B,EAKAzoC,OAAyB8L,EAAA7P,KAEnBykB,EAAsB,IAAIsmB,IAChCyB,EAAmBlvB,QAAQ,SAAArP,GAAG,IAAA/K,EAAE+K,EAAF/K,GAAIgR,EAAQjG,EAARiG,SAAUrP,EAAKoJ,EAALpJ,MACrCvG,EAAUuR,EAAKpP,MAAMyC,GAE3B,IAAK5E,EACJ,MAAU,IAAA2D,MAAK,yBACWiB,EAA8B,8BAIrD5E,EAAQK,WAAWuV,KAAcrP,IAKrC4f,EAAIumB,IAAI9nC,QAEMvB,IAAVkD,SACIvG,EAAQK,WAAWuV,GAE1B5V,EAAQK,WAAWuV,GAAYrP,EAI5BgL,EAAK47B,UACRntC,EAAQK,WAAW0tC,WAAa,IAAIttC,MAEtC,GAEIiB,KAAK2rC,WAAalnB,EAAIgoB,KAAO,GAChCzsC,KAAK2rC,UAEJntC,MAAMiU,KAAKgS,GACX,SACA1gB,EAAO3C,EAAA,CAAA,EACC2C,EAAYwnC,IAChBA,GAGP,EAAClqC,EAEDwS,eAAA,SACC64B,EACA3oC,GAAyBkM,IAAAA,OAEnBwU,EAAsB,IAAIsmB,IAChC2B,EAAmBpvB,QAAQ,SAAAnP,GAAG,IAAAjL,EAAEiL,EAAFjL,GAAIC,EAAQgL,EAARhL,SACjCshB,EAAIumB,IAAI9nC,GAER,IAAM5E,EAAU2R,EAAKxP,MAAMyC,GAE3B,IAAK5E,EACJ,MAAM,IAAI2D,MACgBiB,yBAAAA,gCAI3B5E,EAAQ6E,SAAW8M,EAAK27B,MAAMzoC,GAE9B8M,EAAKy7B,aAAal7B,OAAOlS,GAGrB2R,EAAKw7B,UACRntC,EAAQK,WAAW0tC,WAAa,IAAIttC,KAEtC,GAEIiB,KAAK2rC,WAAalnB,EAAIgoB,KAAO,GAChCzsC,KAAK2rC,UAEJntC,MAAMiU,KAAKgS,GACX,SACA1gB,EAAO3C,EACC2C,CAAAA,EAAAA,EAAYunC,IAChBA,GAGP,EAACjqC,EAEDsS,OAAA,SACChF,EAIA5K,GAAyB,IAAAypB,EAAAxtB,KAEnBykB,EAAmB,GAwCzB,OAvCA9V,EAAS2O,QAAQ,SAAAhP,GAAG,IACf89B,EADejpC,EAAQmL,EAARnL,SAAUxE,EAAU2P,EAAV3P,WAEzBguC,EAAiBvrC,EAAQzC,CAAAA,EAAAA,GAEzB6uB,EAAKie,UACRW,GAAa,IAAIrtC,KAEbJ,GACHguC,EAAkBP,UACe,iBAAzBztC,EAAWytC,UACfztC,EAAWytC,UACXA,EACJO,EAAkBN,UACe,iBAAzB1tC,EAAW0tC,UACf1tC,EAAW0tC,UACXD,GAEJO,EAAoB,CAAEP,UAAAA,EAAWC,UAAWD,IAI9C,IAAMlpC,EAAKsqB,EAAK0d,QACV5sC,EAAU,CACf4E,GAAAA,EACAlC,KAAM,UACNmC,SAAAA,EACAxE,WAAYguC,GAGbnf,EAAK/sB,MAAMyC,GAAM5E,EACjBkvB,EAAKke,aAAahY,OAAOp1B,GAEzBmmB,EAAI1a,KAAK7G,EACV,GAEIlD,KAAK2rC,WACR3rC,KAAK2rC,UAAS,GAAAxlC,OAAKse,GAAM,SAAU1gB,GAG7B0gB,CACR,EAACpjB,SAED,SAAOojB,EAAkB1gB,GAAyB8pB,IAAAA,OACjDpJ,EAAInH,QAAQ,SAACpa,GACZ,IAAI2qB,EAAKptB,MAAMyC,GAId,UAAUjB,4BAA4BiB,EAAE,2BAHjC2qB,EAAKptB,MAAMyC,GAClB2qB,EAAK6d,aAAa9D,OAAO1kC,EAI3B,GAEIlD,KAAK2rC,WACR3rC,KAAK2rC,UAASxlC,GAAAA,OAAKse,GAAM,SAAU1gB,EAErC,EAAC1C,EAEDurC,KAAA,SAAK1pC,GACJ,OAAWlD,KAAC4rC,MAAM5rC,KAAKS,MAAMyC,GAC9B,EAAC7B,EAEDwrC,QAAA,WAAO,IAAAC,EACN9sC,KAAA,YAAY4rC,MAAM73B,OAAOg5B,KAAK/sC,KAAKS,OAAOmO,IAAI,SAAC1L,GAAO,OAAA4pC,EAAKrsC,MAAMyC,EAAG,GACrE,EAAC7B,EAEDsY,aAAA,SACCD,GAA2C,IAAAszB,EAE3ChtC,KAAA,YAAY4rC,MACX73B,OAAOg5B,KAAK/sC,KAAKS,OACfmO,IAAI,SAAC1L,GAAO,OAAA8pC,EAAKvsC,MAAMyC,EAAG,GAC1B6M,OAAO,SAACzR,GACR,OAAOA,EAAQK,YAAc+a,EAAOpb,EAAQK,WAC7C,GAEH,EAAC0C,EAEDsmB,MAAA,SAAM5jB,GACL,IAAMgpC,EAAOh5B,OAAOg5B,KAAK/sC,KAAKS,OAC9BT,KAAKS,MAAQ,CAAA,EACbT,KAAK0rC,aAAa/jB,QAClB3nB,KAAK2rC,UAAUoB,EAAM,SAAUhpC,EAChC,EAAC1C,EAEDorC,KAAA,WACC,OAAO14B,OAAOg5B,KAAK/sC,KAAKS,OAAOqF,MAChC,EAAC0lC,CAAA,CAzWD,GErDK,SAAUyB,GAAwBhgC,GACvC,IAAMqM,EAASrM,EAAQ5J,YACnB6pC,EAAQ,EACZ,GAAI5zB,GAAUA,EAAOxT,OAAS,EAAG,CAChConC,GAASvmC,KAAKqrB,IAAImb,GAAS7zB,EAAO,KAClC,IAAK,IAAIzP,EAAI,EAAGA,EAAIyP,EAAOxT,OAAQ+D,IAClCqjC,GAASvmC,KAAKqrB,IAAImb,GAAS7zB,EAAOzP,IAEpC,CACA,OAAOqjC,CACR,CAEA,IAAME,GAAU7lC,kBACV8lC,GAAc1mC,KAAKC,GAAK,IAE9B,SAASumC,GAAS7zB,GACjB,IAAMg0B,EAAeh0B,EAAOxT,OAE5B,GAAIwnC,GAAgB,EACnB,OAAQ,EAMT,IAHA,IAAIJ,EAAQ,EAERrjC,EAAI,EACDA,EAAIyjC,GAUVJ,IANC5zB,EAAOzP,EAAI,GAAKyjC,GAAgBzjC,EAAI,GAAKyjC,EAAezjC,EAAI,GAIxC,GAAKwjC,GAPZ/zB,EAAOzP,GAKA,GAAKwjC,IAIG1mC,KAAKQ,IARnBmS,EAAOzP,EAAI,IAAMyjC,EAAe,EAAIzjC,EAAI,GAKhC,GAAKwjC,IAK5BxjC,IAGD,OAAOqjC,EAAQE,EAChB,KC1CaG,GACZ,2CCDYC,GACZ,yCACYC,GACZ,qCCEeC,GACf5tB,EACAC,EACA2C,GAEA,IAAMirB,EAAY3vB,GAAmB8B,EAAGC,GAIpC6tB,EAHc5vB,GAAmB+B,EAAG2C,GAGRirB,EAUhC,OAPIC,EAAgB,IACnBA,GAAiB,KAMR,IAAGjnC,KAAKqrB,IAFJ4b,EAAgB,GAEP,GACxB,CCqBA,IAAMv5B,GAAmB,CAAEC,OAAQ,SAAUC,OAAQ,SAe/CC,GAAiB,CACtBC,MAAO,YACPW,MAAO,WAUKy4B,gBAA6B,SAAAnoC,GAazC,SAAAmoC,EAAYhuC,GAA6D8F,IAAAA,EAE5C,OAD5BA,EAAAD,EAAAO,KAAAjG,KAAMH,GAAS,IAAM8F,MAbtBzE,KAAO,mBAAkByE,EAEjB+hB,kBAAoB,EAAC/hB,EACrBsQ,eAAS,EAAAtQ,EACTmP,UAA2CT,GAAgB1O,EAC3DoP,QAA6BP,GAAc7O,EAC3C8iB,WAAY,EAAK9iB,EAGjBsL,mBAAa,EAAAtL,EACb2U,iBAAW,EAIlB3U,EAAKxE,cAActB,GAAS8F,CAC7B,CAACU,EAAAwnC,EAAAnoC,OAAArE,EAAAwsC,EAAAvsC,UAsYA,OAtYAD,EAEQF,cAAA,SACRtB,GAIA6F,EAAApE,UAAMH,cAAa8E,KAAAjG,KAACH,GAEhBA,MAAAA,GAAAA,EAASkV,UACZ/U,KAAK+U,QAAO3T,EAAQ,GAAApB,KAAK+U,QAAYlV,EAAQkV,UAGnB,QAAhB,MAAPlV,OAAO,EAAPA,EAASiV,WACZ9U,KAAK8U,UAAY,CAAER,OAAQ,KAAMC,OAAQ,MACxB,MAAP1U,GAAAA,EAASiV,YACnB9U,KAAK8U,UAAS1T,KAAQpB,KAAK8U,UAAcjV,EAAQiV,WAEnD,EAACzT,EAEO+T,MAAA,WAAK9E,IAAAA,EACZ,QAAuB3O,IAAnB3B,KAAKiW,WAIOjW,KAAKiR,cAAc5B,cAAc,CAChDH,UAAWlP,KAAKiW,UAChB7G,mBAAiBkB,EAAA,GAAAA,EACf9S,EAAkBE,wBAAoBiE,EAAS2O,GAEjDvM,QAAS,CAAEL,WAAY3G,EAAY8Q,OAAQ0H,OAAQvY,KAGpD,CAIA,IAAMkS,EAAYlP,KAAKiW,UAEvBjW,KAAK0nB,kBAAoB,EACzB1nB,KAAKiW,eAAYtU,EAGE,YAAf3B,KAAKsV,OACRtV,KAAKkC,aAGNlC,KAAK0C,SAASwM,EAAW,CACxBhO,KAAMlB,KAAKkB,KACXqU,OAAQvY,GAdT,CAgBD,EAACqE,EAGDoT,MAAA,WACCzU,KAAKkC,aACLlC,KAAKc,UAAUd,KAAK+U,QAAQN,MAC7B,EAACpT,EAGDwU,KAAA,WACC7V,KAAK8V,UACL9V,KAAKmC,aACLnC,KAAKc,UAAU,QAChB,EAACO,EAGDoD,YAAA,SAAY1C,GAIX,GAHA/B,KAAKyoB,WAAY,EACjBzoB,KAAKc,UAAUd,KAAK+U,QAAQN,YAEL9S,IAAnB3B,KAAKiW,WAAsD,IAA3BjW,KAAK0nB,kBAAzC,CAIA,IAAIvY,EAA4C,GAEhD,GAA+B,IAA3BnP,KAAK0nB,kBACRvY,EAAsBnP,KAAK8tC,6BAA6B/rC,OAC9C,IAA2B,IAA3B/B,KAAK0nB,kBAGf,OAFAvY,EAAsBnP,KAAK+tC,gCAAgChsC,EAG5D,CAEA/B,KAAKiR,cAAc5B,cAAc,CAChCH,UAAWlP,KAAKiW,UAChB9G,oBAAAA,EACApL,QAAS,CAAEL,WAAY3G,EAAY4G,cAfpC,CAiBD,EAACtC,EAEOysC,6BAAA,SACP/rC,GAEA,MAAO,CACN,CACCf,KAAMyM,GACN0E,MAAO,EACPpG,WAAY,CAAChK,EAAMyG,IAAKzG,EAAM0G,MAE/B,CACCzH,KAAMyM,GACN0E,MAAO,EACPpG,WAAY,CAAChK,EAAMyG,IAAKzG,EAAM0G,MAGjC,EAACpH,EAEO0sC,gCAAA,SACPhsC,GAEA,IAAK/B,KAAKiW,UACT,MAAU,IAAAhU,MAAM,kCAGjB,IC9MDia,EACA8xB,EACAC,EAOMhV,EDqMC/I,EAAkBlwB,KAAKsa,YAAYjB,cAAcrZ,KAAKiW,UAAW,GACjEwG,EAAmBzc,KAAKsa,YAAYjB,cAAcrZ,KAAKiW,UAAW,GAClE4c,EAAWP,GAChBpC,EACAzT,EACAzc,KAAKM,oBACLN,KAAKa,QACLb,KAAKY,WAGAkf,EAAIvX,EAAsB2nB,EAAgB,GAAIA,EAAgB,IAC9DnQ,EAAIxX,EAAsBsqB,EAAS,GAAIA,EAAS,IAChDnQ,EAAIna,EAAsBkU,EAAiB,GAAIA,EAAiB,IAChEyG,EAAI3a,EAAsBxG,EAAMyG,IAAKzG,EAAM0G,KAK3CylC,EAFct1B,GAAkBsK,EAAGpD,GACrBlH,GAAkBsK,EAAGR,GAKnCkrB,EAAgBF,GAAuB5tB,EAAGC,EAAGmD,GAC7C1C,EAAQ0tB,EACX,GAAKN,EACLF,GAAuB5tB,EAAGC,EAAGmD,GAAK,GAI/BirB,EAAav1B,GAAkBmH,EAAGmD,GAClCkrB,EAAWznC,KAAKS,IAAII,EAAiBgZ,IAAU2tB,EAY/CE,EAT6BrwB,GAAmB8B,EAAG4C,IAMlC,WC5OlBuW,IAPNgV,EDgPuC/qB,GC7OPxa,GAJhCslC,EDiPoCtrB,GC7OUha,KAL9CwT,EDkPiC4D,GC5OwBnX,EAAIqlC,EAAUrlC,IADnBslC,EAAQtlC,EAAIqlC,EAAUrlC,IACjDuT,EAAMxT,EAAIslC,EAAUtlC,IAO7B,MAGR,OACGuwB,GAJK,MAKR,QAGA,SDgO2B,GAAK,IAIjCqV,EAAoB7wB,GACzBqC,EACAsuB,EACAC,GAEKE,EAAqB9wB,GAC1BiF,EACA0rB,EACAC,GAIKG,EAAkB1lC,EACvBwlC,EAAkB5lC,EAClB4lC,EAAkB3lC,GAEb8lC,EAAmB3lC,EACxBylC,EAAmB7lC,EACnB6lC,EAAmB5lC,GAIpB,MAAO,CACN,CACC3H,KAAMyM,GACN0E,MAAO,EACPpG,WAAY,CACXjE,EAAe2mC,EAAiBjmC,IAAKxI,KAAKM,qBAC1CwH,EAAe2mC,EAAiBhmC,IAAKzI,KAAKM,uBAG5C,CACCU,KAAMyM,GACN0E,MAAO,EACPpG,WAAY,CACXjE,EAAe0mC,EAAgBhmC,IAAKxI,KAAKM,qBACzCwH,EAAe0mC,EAAgB/lC,IAAKzI,KAAKM,uBAI7C,EAACe,EAGDqD,QAAA,SAAQ3C,GACP,GACmB,UAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcZ,WAAYyC,IACrC,SAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcV,UAAWuC,IACrDA,EAAMiU,eACNhW,KAAK6B,kBAAkB7B,KAAKE,cAAcX,YAAawC,GAWxD,GALI/B,KAAK0nB,kBAAoB,IAAM1nB,KAAKyoB,WACvCzoB,KAAKyE,YAAY1C,GAElB/B,KAAKyoB,WAAY,EAEc,IAA3BzoB,KAAK0nB,kBAAyB,CAAAvX,IAAAA,EACjCsK,EAAsBza,KAAKiR,cAAc/C,cAAc,CACtD7K,YAAa,CACZ,CAACtB,EAAMyG,IAAKzG,EAAM0G,KAClB,CAAC1G,EAAMyG,IAAKzG,EAAM0G,KAClB,CAAC1G,EAAMyG,IAAKzG,EAAM0G,KAClB,CAAC1G,EAAMyG,IAAKzG,EAAM0G,MAGnB9J,YAAUwR,EACTjP,CAAAA,KAAMlB,KAAKkB,MAAIiP,EACd3S,EAAkBE,oBAAoB,EAAIyS,KAG7CnQ,KAAKiW,UAbYwE,EAATvX,GAcRlD,KAAK0nB,oBAGL1nB,KAAKgC,YACN,MAAW,GAA2B,IAA3BhC,KAAK0nB,mBAA2B1nB,KAAKiW,UAAW,CAC1D,IAAMoF,EAAqBrb,KAAKsa,YAAYjB,cAC3CrZ,KAAKiW,UACL,GAQD,GALoB4C,GACnB,CAAC9W,EAAMyG,IAAKzG,EAAM0G,KAClB4S,GAIA,OAoBD,IAjBgBrb,KAAKiR,cAAc5B,cAAc,CAChDH,UAAWlP,KAAKiW,UAChB9G,oBAAqB,CACpB,CACCnO,KAAMyM,GACN0E,MAAO,EACPpG,WAAY,CAAChK,EAAMyG,IAAKzG,EAAM0G,MAE/B,CACCzH,KAAMyM,EACN0E,MAAO,EACPpG,WAAY,CAAChK,EAAMyG,IAAKzG,EAAM0G,OAGhC1E,QAAS,CAAEL,WAAY3G,EAAY0T,UAInC,OAGDzQ,KAAK0nB,mBACN,MAAsC,IAA3B1nB,KAAK0nB,mBAA2B1nB,KAAKiW,WAC/CjW,KAAKoV,OAGR,EAAC/T,EAGD8C,QAAA,SAAQpC,GACP,GAAIA,EAAMqD,MAAQpF,KAAK8U,UAAUR,OAChCtU,KAAK8V,eACK/T,GAAAA,EAAMqD,MAAQpF,KAAK8U,UAAUP,OAAQ,CAE/C,GAAIvU,KAAK0nB,kBAAoB,EAE5B,YADA1nB,KAAK8V,UAGN9V,KAAKoV,OACN,CACD,EAAC/T,EAGD6C,UAAA,aAAc7C,EAGd5B,YAAA,WAAgB4B,EAAAA,EAGhB3B,OAAA,WAAW2B,EAAAA,EAGX1B,UAAA,aAAc0B,EAGdyU,QAAA,WACC,IAAMG,EAAYjW,KAAKiW,UAEvBjW,KAAKiW,eAAYtU,EACjB3B,KAAK0nB,kBAAoB,EACN,YAAf1nB,KAAKsV,OACRtV,KAAKkC,aAGNlC,KAAKiR,cAAcxB,uBAAuBwG,EAC3C,EAAC5U,EAGD6U,aAAA,SAAa5X,GACZ,IAAMmD,EAAML,EAAQsa,CAAAA,E7D9Zd,CACNvF,iBAAkB,UAClBC,oBAAqB,UACrBC,oBAAqB,EACrBC,sBAAuB,EACvBC,mBAAoB,GACpBC,WAAY,UACZC,aAAc,EACdC,kBAAmB,UACnBC,oBAAqB,EACrBC,kBAAmB,EACnBC,WAAY,EACZC,gBAAiB,UACjBC,gBAAiB,EACjBC,kBAAmB,EACnBC,OAAQ,EACRC,eAAWvV,EACXwV,kBAAcxV,EACdyV,iBAAazV,EACb0V,oBAAgB1V,I6DibhB,OApCIrD,EAAQK,WAAWuC,OAASlB,KAAKkB,MACN,YAA1B5C,EAAQ6E,SAASnC,OACpBS,EAAO0U,iBAAmBnW,KAAK4E,wBAC9B5E,KAAKyB,OAAO6V,UACZ7V,EAAO0U,iBACP7X,GAGDmD,EAAO2U,oBAAsBpW,KAAK4E,wBACjC5E,KAAKyB,OAAO8V,aACZ9V,EAAO2U,oBACP9X,GAGDmD,EAAO4U,oBAAsBrW,KAAKgF,uBACjChF,KAAKyB,OAAO+V,aACZ/V,EAAO4U,oBACP/X,GAGDmD,EAAO6U,sBAAwBtW,KAAKgF,uBACnChF,KAAKyB,OAAOgW,eACZ,EACAnZ,GAGDmD,EAAO8U,mBAAqBvW,KAAKgF,uBAChChF,KAAKyB,OAAOiW,YACZjW,EAAO8U,mBACPjY,GAGDmD,EAAOwV,OAAS7Y,GAIXqD,CACR,EAACJ,EAEDsB,gBAAA,SAAgBrE,GAAgBmQ,IAAAA,EAC/BzO,KAAA,OAAWA,KAAC4D,oBAAoBtF,EAAS,SAACqZ,GACzC,OAAA/K,EACC+K,EACAlJ,EAAKnO,oBACL,EAEH,EAACe,EAEDyB,oBAAA,SAAoBxE,GAGf0B,KAAKiW,YAAc3X,EAAQ4E,KAC9BlD,KAAKiW,eAAYtU,EACjB3B,KAAK0nB,kBAAoB,EACN,YAAf1nB,KAAKsV,OACRtV,KAAKkC,aAGR,EAACb,EAEDE,kBAAA,SAAkBc,GACjBrC,KAAKsa,YAAc,IAAIxB,GAAoBzW,GAC3CrC,KAAKiR,cAAgB,IAAIvD,GAAsBrL,EAAQ,CACtDjC,SAAUJ,KAAKI,UAEjB,EAACytC,CAAA,CAtZwC,CAAQjuC,YE5ElC8uC,GACfhlC,EACAilC,EACAC,GAWA,OARqBD,EAAYjmC,EAAIgB,EAAOhB,IACKkmC,EAAWjmC,EAAIe,EAAOf,IADrBgmC,EAAYhmC,EAAIe,EAAOf,IACpDimC,EAAWlmC,EAAIgB,EAAOhB,IAO3B,CACjB,CCmCA,IAAM2L,GAAmB,CAAEC,OAAQ,SAAUC,OAAQ,SAe/CC,GAAiB,CACtBC,MAAO,YACPW,MAAO,WAWKy5B,gBAAoB,SAAAnpC,GAehC,SAAAmpC,EAAYhvC,GAA0D8F,IAAAA,EAEzC,OAD5BA,EAAAD,EAAAO,KAAMpG,KAAAA,GAAS,IAAM8F,MAftBzE,KAAO,SAAQyE,EAEP+hB,kBAAoB,EAAC/hB,EACrBsQ,iBAAStQ,EACTmP,UAA0CT,GAAgB1O,EAC1D6Y,eAAS7Y,EAAAA,EACTmpC,UAAoB,GAAEnpC,EACtBoP,QAA6BP,GAAc7O,EAC3C8iB,WAAY,EAAK9iB,EAGjB2U,iBAAW3U,EAAAA,EACXsL,mBAIPtL,EAAAA,EAAKxE,cAActB,GAAS8F,CAC7B,CAACU,EAAAwoC,EAAAnpC,GAAA,IAAArE,EAAAwtC,EAAAvtC,UAkaA,OAlaAD,EAEQF,cAAA,SACRtB,GAIA6F,EAAApE,UAAMH,cAAa8E,KAACpG,KAAAA,GAET,MAAPA,GAAAA,EAASkV,UACZ/U,KAAK+U,QAAO3T,EAAA,CAAA,EAAQpB,KAAK+U,QAAYlV,EAAQkV,UAGnB,QAAhB,MAAPlV,OAAO,EAAPA,EAASiV,WACZ9U,KAAK8U,UAAY,CAAER,OAAQ,KAAMC,OAAQ,MACxB,MAAP1U,GAAAA,EAASiV,YACnB9U,KAAK8U,UAAS1T,KAAQpB,KAAK8U,UAAcjV,EAAQiV,YAG9CjV,MAAAA,GAAAA,EAASivC,YACZ9uC,KAAK8uC,UAAYjvC,EAAQivC,UAE3B,EAACztC,EAEO+T,MAAA,WAAK,IAAA9E,EACZ,QAAuB3O,IAAnB3B,KAAKiW,WAIOjW,KAAKiR,cAAc5B,cAAc,CAChDH,UAAWlP,KAAKiW,UAChB7G,mBAAiBkB,EAAA,CAAA,EAAAA,EACf9S,EAAkBE,wBAAoBiE,EAAS2O,GAEjDnB,oBAAqB,CAEpB9L,YAAarD,KAAKsa,YAAYpB,YAAqBlZ,KAAKiW,WACtD5S,YACFrC,KAAMyM,IAEP1J,QAAS,CACRL,WAAY3G,EAAY8Q,OACxB0H,OAAQvY,KAIV,CAIA,IAAMkS,EAAYlP,KAAKiW,UAEvBjW,KAAK0nB,kBAAoB,EACzB1nB,KAAKiW,eAAYtU,EACjB3B,KAAKwe,eAAY7c,EAGE,YAAf3B,KAAKsV,OACRtV,KAAKkC,aAGNlC,KAAK0C,SAASwM,EAAW,CACxBhO,KAAMlB,KAAKkB,KACXqU,OAAQvY,GAfT,CAiBD,EAACqE,EAEO0tC,qBAAA,SAAqBhtC,GAC5B,IAAMitC,EAA4BhvC,KAAKsa,YAAYnB,eAClDnZ,KAAKiW,WAEAvM,EAASslC,EAA0B,GACnCC,EAAcD,EAA0B,GACxCE,EAAc,CAACntC,EAAMyG,IAAKzG,EAAM0G,KAGhC0mC,EAAoB5mC,EAAsBmB,EAAO,GAAIA,EAAO,IAC5D0lC,EAAyB7mC,EAC9B0mC,EAAY,GACZA,EAAY,IAEPI,EAAyB9mC,EAC9B2mC,EAAY,GACZA,EAAY,IAKb,QAAuBvtC,IAAnB3B,KAAKwe,UAAyB,CACjC,IAAM8wB,EAAYZ,GACjBS,EACAC,EACAC,GAEDrvC,KAAKwe,UAAY8wB,EAAY,YAAc,eAC5C,CAGA,IAqBIC,EArBEC,EAAS52B,GAAkBu2B,EAAmBC,GAG9CK,EAAezxB,GACpBmxB,EACAC,GAEKM,EAAa1xB,GAClBmxB,EACAE,GAIK3vB,EAAiB1f,KAAK8uC,UACtBzrC,EAA0B,CAACqG,GAG3BimC,EAAkBxxB,GAAiBsxB,GACnCG,EAAgBzxB,GAAiBuxB,GAIhB,kBAAnB1vC,KAAKwe,WACR+wB,EAAeK,EAAgBD,GACZ,IAClBJ,GAAgB,MAGjBA,EAAeI,EAAkBC,GACd,IAClBL,GAAgB,KAIlB,IAAMM,GACgB,kBAAnB7vC,KAAKwe,UAAgC,GAAK,GAAK+wB,EACjD7vB,EAGDrc,EAAY0G,KAAKklC,GAGjB,IAAK,IAAIplC,EAAI,EAAGA,GAAK6V,EAAgB7V,IAAK,CACzC,IACMimC,EAAaryB,GAClB0xB,EACAK,EAHsBG,EAAkB9lC,EAAIgmC,GAM7Cn3B,EAAqB5P,EAAsBgnC,EAAWpnC,EAAGonC,EAAWnnC,GAAvDF,EAAGiQ,EAAHjQ,IAEPstB,EAAY,CACjBjuB,EAHU4Q,EAAHlQ,IAGaxI,KAAKM,qBACzBwH,EAAeW,EAAKzI,KAAKM,sBAIzBy1B,EAAU,KAAO1yB,EAAYA,EAAYyC,OAAS,GAAG,IACrDiwB,EAAU,KAAO1yB,EAAYA,EAAYyC,OAAS,GAAG,IAErDzC,EAAY0G,KAAKgsB,EAEnB,CAKA,OAFA1yB,EAAY0G,KAAKL,GAEVrG,CACR,EAAChC,EAGDoT,MAAA,WACCzU,KAAKkC,aACLlC,KAAKc,UAAUd,KAAK+U,QAAQN,MAC7B,EAACpT,EAGDwU,KAAA,WACC7V,KAAK8V,UACL9V,KAAKmC,aACLnC,KAAKc,UAAU,QAChB,EAACO,EAGDoD,YAAA,SAAY1C,GAIX,GAHA/B,KAAKyoB,WAAY,EACjBzoB,KAAKc,UAAUd,KAAK+U,QAAQN,YAEL9S,IAAnB3B,KAAKiW,WAAsD,IAA3BjW,KAAK0nB,kBAAzC,CAIA,IAAIqoB,EAEJ,GAA+B,IAA3B/vC,KAAK0nB,kBACRqoB,EAAY,CACX,CACC/uC,KAAMyM,GACN0E,MAAO,EACPpG,WAAY,CAAChK,EAAMyG,IAAKzG,EAAM0G,MAE/B,CACCzH,KAAMyM,GACN0E,MAAO,EACPpG,WAAY,CAAChK,EAAMyG,IAAKzG,EAAM0G,WAG1B,IAA+B,IAA3BzI,KAAK0nB,kBAUf,OATA,IAAMsoB,EAAoBhwC,KAAK+uC,qBAAqBhtC,GACpD,IAAKiuC,EACJ,OAEDD,EAAY,CACX/uC,KAAMyM,GACNpK,YAAa,CAAC2sC,GAIhB,CAEAhwC,KAAKiR,cAAc5B,cAAc,CAChCH,UAAWlP,KAAKiW,UAChB9G,oBAAqB4gC,EACrBhsC,QAAS,CACRL,WAAY3G,EAAY4G,cAlC1B,CAqCD,EAACtC,EAGDqD,QAAA,SAAQ3C,GACP,GACmB,UAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcZ,WAAYyC,IACrC,SAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcV,UAAWuC,IACrDA,EAAMiU,eACNhW,KAAK6B,kBAAkB7B,KAAKE,cAAcX,YAAawC,GAWxD,GALI/B,KAAK0nB,kBAAoB,IAAM1nB,KAAKyoB,WACvCzoB,KAAKyE,YAAY1C,GAElB/B,KAAKyoB,WAAY,EAEc,IAA3BzoB,KAAK0nB,kBAAyB,CAAA,IAAAvX,EAC3BuF,EAAU1V,KAAKiR,cAAc/C,cAAc,CAChD7K,YAAa,CACZ,CAACtB,EAAMyG,IAAKzG,EAAM0G,KAClB,CAAC1G,EAAMyG,IAAKzG,EAAM0G,KAClB,CAAC1G,EAAMyG,IAAKzG,EAAM0G,KAClB,CAAC1G,EAAMyG,IAAKzG,EAAM0G,MAEnB9J,YAAUwR,EACTjP,CAAAA,KAAMlB,KAAKkB,MAAIiP,EACd3S,EAAkBE,oBAAoB,EAAIyS,KAG7CnQ,KAAKiW,UAAYP,MAAAA,OAAAA,EAAAA,EAASxS,GAC1BlD,KAAK0nB,oBAGL1nB,KAAKgC,YACN,SAAsC,IAA3BhC,KAAK0nB,mBAA2B1nB,KAAKiW,UAAW,CAO1D,GANoBjW,KAAKsa,YAAYtB,6BAA6B,CACjE9J,UAAWlP,KAAKiW,UAChB9D,MAAO,EACP8G,cAAe,CAAClX,EAAMyG,IAAKzG,EAAM0G,OAIjC,OAsBD,IAnBgBzI,KAAKiR,cAAc5B,cAAc,CAChDH,UAAWlP,KAAKiW,UAChB9G,oBAAqB,CACpB,CACCnO,KAAMyM,GACN0E,MAAO,EACPpG,WAAY,CAAChK,EAAMyG,IAAKzG,EAAM0G,MAE/B,CACCzH,KAAMyM,GACN0E,MAAO,EACPpG,WAAY,CAAChK,EAAMyG,IAAKzG,EAAM0G,OAGhC1E,QAAS,CACRL,WAAY3G,EAAY4G,eAKzB,OAGD3D,KAAK0nB,mBACN,MAAsC,IAA3B1nB,KAAK0nB,mBAA2B1nB,KAAKiW,WAC/CjW,KAAKoV,OAGR,EAAC/T,EAGD8C,QAAA,SAAQpC,GACHA,EAAMqD,MAAQpF,KAAK8U,UAAUR,OAChCtU,KAAK8V,UACK/T,EAAMqD,MAAQpF,KAAK8U,UAAUP,QACvCvU,KAAKoV,OAEP,EAAC/T,EAGD6C,UAAA,WAEC7C,EAAAA,EAGD5B,YAAA,WAAW,EAEV4B,EAGD3B,OAAA,WAAM,EAEL2B,EAGD1B,UAAA,WAEC0B,EAAAA,EAGDyU,QAAA,WACC,IAAMG,EAAYjW,KAAKiW,UAEvBjW,KAAKiW,eAAYtU,EACjB3B,KAAKwe,eAAY7c,EACjB3B,KAAK0nB,kBAAoB,EACN,YAAf1nB,KAAKsV,OACRtV,KAAKkC,aAGNlC,KAAKiR,cAAcxB,uBAAuBwG,EAC3C,EAAC5U,EAGD6U,aAAA,SAAa5X,GACZ,IAAMmD,EAAML,EAAQsa,CAAAA,EhE7bd,CACNvF,iBAAkB,UAClBC,oBAAqB,UACrBC,oBAAqB,EACrBC,sBAAuB,EACvBC,mBAAoB,GACpBC,WAAY,UACZC,aAAc,EACdC,kBAAmB,UACnBC,oBAAqB,EACrBC,kBAAmB,EACnBC,WAAY,EACZC,gBAAiB,UACjBC,gBAAiB,EACjBC,kBAAmB,EACnBC,OAAQ,EACRC,eAAWvV,EACXwV,kBAAcxV,EACdyV,iBAAazV,EACb0V,oBAAgB1V,IgEgdhB,OApCIrD,EAAQK,WAAWuC,OAASlB,KAAKkB,MACN,YAA1B5C,EAAQ6E,SAASnC,OACpBS,EAAO0U,iBAAmBnW,KAAK4E,wBAC9B5E,KAAKyB,OAAO6V,UACZ7V,EAAO0U,iBACP7X,GAGDmD,EAAO2U,oBAAsBpW,KAAK4E,wBACjC5E,KAAKyB,OAAO8V,aACZ9V,EAAO2U,oBACP9X,GAGDmD,EAAO4U,oBAAsBrW,KAAKgF,uBACjChF,KAAKyB,OAAO+V,aACZ/V,EAAO4U,oBACP/X,GAGDmD,EAAO6U,sBAAwBtW,KAAKgF,uBACnChF,KAAKyB,OAAOgW,eACZ,EACAnZ,GAGDmD,EAAO8U,mBAAqBvW,KAAKgF,uBAChChF,KAAKyB,OAAOiW,YACZjW,EAAO8U,mBACPjY,GAGDmD,EAAOwV,OAAS7Y,GAIXqD,CACR,EAACJ,EAEDsB,gBAAA,SAAgBrE,GAAgB,IAAAmQ,EAAAzO,KAC/B,OAAWA,KAAC4D,oBAAoBtF,EAAS,SAACqZ,GACzC,OAAA/K,EACC+K,EACAlJ,EAAKnO,oBACL,EAEH,EAACe,EAEDyB,oBAAA,SAAoBxE,GAGf0B,KAAKiW,YAAc3X,EAAQ4E,KAC9BlD,KAAKiW,eAAYtU,EACjB3B,KAAKwe,eAAY7c,EACjB3B,KAAK0nB,kBAAoB,EACN,YAAf1nB,KAAKsV,OACRtV,KAAKkC,aAGR,EAACb,EAEDE,kBAAA,SAAkBc,GACjBrC,KAAKsa,YAAc,IAAIxB,GAAoBzW,GAC3CrC,KAAKiR,cAAgB,IAAIvD,GAAsBrL,EAAQ,CACtDjC,SAAUJ,KAAKI,UAEjB,EAACyuC,CAAA,CApb+B,CAAQjvC,GCjCnCyU,GAAmB,CAAEC,OAAQ,SAAUC,OAAQ,SAqB/CC,GAAiB,CACtBC,MAAO,YACPW,MAAO,WAWK66B,yBAAoBvqC,GAiBhC,SAAAuqC,EAAYpwC,GAA0D8F,IAAAA,EAEzC,OAD5BA,EAAAD,EAAAO,UAAMpG,GAAS,IAAKG,MAjBrBkB,KAAO,SAAQyE,EAEP+hB,kBAAoB,EAAC/hB,EACrBsQ,eAAStQ,EAAAA,EACTuqC,2BAAmBvqC,EACnBwqC,4BAAsBxqC,EAAAA,EACtBmP,UAA0CT,GAAgB1O,EAC1D6Y,eAAS7Y,EAAAA,EACTmpC,UAAoB,GAAEnpC,EACtBoP,QAA6BP,GAAc7O,EAC3C8iB,WAAY,EAAK9iB,EAGjB2U,iBAAW,EAAA3U,EACXsL,qBAIPtL,EAAKxE,cAActB,GAAS8F,CAC7B,CAACU,EAAA4pC,EAAAvqC,GAAA,IAAArE,EAAA4uC,EAAA3uC,UAsqBA2uC,OAtqBA5uC,EAEQF,cAAA,SACRtB,GAIA6F,EAAApE,UAAMH,cAAa8E,KAAAjG,KAACH,GAEhBA,MAAAA,GAAAA,EAASkV,UACZ/U,KAAK+U,QAAO3T,EAAQ,CAAA,EAAApB,KAAK+U,QAAYlV,EAAQkV,UAGnB,cAAvBlV,SAAAA,EAASiV,WACZ9U,KAAK8U,UAAY,CAAER,OAAQ,KAAMC,OAAQ,MACxB,MAAP1U,GAAAA,EAASiV,YACnB9U,KAAK8U,UAAS1T,EAAA,CAAA,EAAQpB,KAAK8U,UAAcjV,EAAQiV,kBAG9CjV,GAAAA,EAASivC,YACZ9uC,KAAK8uC,UAAYjvC,EAAQivC,UAE3B,EAACztC,EAGDoT,MAAA,WACCzU,KAAKkC,aACLlC,KAAKc,UAAUd,KAAK+U,QAAQN,MAC7B,EAACpT,EAGDwU,KAAA,WACC7V,KAAK8V,UACL9V,KAAKmC,aACLnC,KAAKc,UAAU,QAChB,EAACO,EAGDoD,YAAA,SAAY1C,GAIX,GAHA/B,KAAKyoB,WAAY,EACjBzoB,KAAKc,UAAUd,KAAK+U,QAAQN,YAGE9S,IAA7B3B,KAAKkwC,0BAC2BvuC,IAAhC3B,KAAKmwC,wBACsB,IAA3BnwC,KAAK0nB,kBAKN,GAA+B,IAA3B1nB,KAAK0nB,kBAAyB,CACjC,IAAMrkB,EAAcrD,KAAKowC,gCAAgCruC,GACzD,IAAKsB,EACJ,OAGDrD,KAAKiR,cAAc1B,iBAAiB,CACnCL,UAAWlP,KAAKkwC,oBAChB/gC,oBAAqB,CACpBnO,KAAMyM,GACNpK,YAAaA,GAEdU,QAAS,CACRL,WAAY3G,EAAY4G,cAG3B,MAAW,GAA2B,IAA3B3D,KAAK0nB,kBAAyB,CACxC,IAAMrkB,EAAcrD,KAAKqwC,6BAA6BtuC,GACtD,IAAKsB,EACJ,OAKD,GAAKrD,KAAKiW,UAaTjW,KAAKiR,cAAc5B,cAAc,CAChCH,UAAWlP,KAAKiW,UAChB9G,oBAAqB,CACpBnO,KAAMyM,GACNpK,YAAa,CAACA,IAEfU,QAAS,CAAEL,WAAY3G,EAAY4G,mBAnBhB,CAAAwM,IAAAA,EACduF,EAAU1V,KAAKiR,cAAc/C,cAAc,CAChD7K,YAAAA,EACA1E,YAAUwR,EACTjP,CAAAA,KAAMlB,KAAKkB,MAAIiP,EACd3S,EAAkBE,oBAAoB,EAAIyS,KAG7C,IAAKuF,EACJ,OAED1V,KAAKiW,UAAYP,EAAQxS,EAC1B,CAUD,CACD,EAAC7B,EAGDqD,QAAA,SAAQ3C,GACP,GACmB,UAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcZ,WAAYyC,IACrC,SAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcV,UAAWuC,IACrDA,EAAMiU,eACNhW,KAAK6B,kBAAkB7B,KAAKE,cAAcX,YAAawC,GAWxD,GALI/B,KAAK0nB,kBAAoB,IAAM1nB,KAAKyoB,WACvCzoB,KAAKyE,YAAY1C,GAElB/B,KAAKyoB,WAAY,EAEc,IAA3BzoB,KAAK0nB,kBAAyB,CACjC,IAAMhS,EAAU1V,KAAKiR,cAAcrD,YAAY,CAC9CvK,YAAa,CAACtB,EAAMyG,IAAKzG,EAAM0G,KAC/B9J,WAAY,CAAEuC,KAAMlB,KAAKkB,QAE1B,IAAKwU,EACJ,OAED1V,KAAKmwC,uBAAyBz6B,EAAQxS,GACtClD,KAAK0nB,oBAGL1nB,KAAKgC,YACN,SAAsC,IAA3BhC,KAAK0nB,mBAA2B1nB,KAAKmwC,uBAAwB,CACvE,IAAMz6B,EAAU1V,KAAKiR,cAAcjD,iBAAiB,CACnD3K,YAAa,CACZ,CAACtB,EAAMyG,IAAKzG,EAAM0G,KAClB,CAAC1G,EAAMyG,IAAKzG,EAAM0G,MAEnB9J,WAAY,CAAEuC,KAAMlB,KAAKkB,QAE1B,IAAKwU,EACJ,OAED1V,KAAKkwC,oBAAsBx6B,EAAQxS,GACnClD,KAAK0nB,mBACN,MAAsC,IAA3B1nB,KAAK0nB,mBAA2B1nB,KAAKmwC,uBAC/CnwC,KAAK0nB,oBAEgC,IAA3B1nB,KAAK0nB,mBAA2B1nB,KAAKmwC,wBAC/CnwC,KAAKoV,OAGR,EAAC/T,EAGD8C,QAAA,SAAQpC,GACHA,EAAMqD,MAAQpF,KAAK8U,UAAUR,OAChCtU,KAAK8V,UACK/T,EAAMqD,MAAQpF,KAAK8U,UAAUP,QACvCvU,KAAKoV,OAEP,EAAC/T,EAGD6C,UAAA,aAEC7C,EAGD5B,YAAA,aAEC4B,EAGD3B,OAAA,WAEC2B,EAAAA,EAGD1B,UAAA,WAEC0B,EAAAA,EAGDyU,QAAA,WACC9V,KAAKiR,cAAcxB,uBAAuBzP,KAAKmwC,wBAC/CnwC,KAAKiR,cAAcxB,uBAAuBzP,KAAKkwC,qBAC/ClwC,KAAKiR,cAAcxB,uBAAuBzP,KAAKiW,WAE/CjW,KAAKmwC,4BAAyBxuC,EAC9B3B,KAAKwe,eAAY7c,EACjB3B,KAAKiW,eAAYtU,EACjB3B,KAAK0nB,kBAAoB,EACN,YAAf1nB,KAAKsV,OACRtV,KAAKkC,YAEP,EAACb,EAGD6U,aAAA,SAAa5X,GACZ,IAAMmD,EAAML,EAAQsa,CAAAA,EjEzSd,CACNvF,iBAAkB,UAClBC,oBAAqB,UACrBC,oBAAqB,EACrBC,sBAAuB,EACvBC,mBAAoB,GACpBC,WAAY,UACZC,aAAc,EACdC,kBAAmB,UACnBC,oBAAqB,EACrBC,kBAAmB,EACnBC,WAAY,EACZC,gBAAiB,UACjBC,gBAAiB,EACjBC,kBAAmB,EACnBC,OAAQ,EACRC,eAAWvV,EACXwV,kBAAcxV,EACdyV,iBAAazV,EACb0V,oBAAgB1V,IiEgXhB,OAxFIrD,EAAQK,WAAWuC,OAASlB,KAAKkB,OACN,YAA1B5C,EAAQ6E,SAASnC,MACpBS,EAAO0U,iBAAmBnW,KAAK4E,wBAC9B5E,KAAKyB,OAAO6V,UACZ7V,EAAO0U,iBACP7X,GAGDmD,EAAO2U,oBAAsBpW,KAAK4E,wBACjC5E,KAAKyB,OAAO8V,aACZ9V,EAAO2U,oBACP9X,GAGDmD,EAAO4U,oBAAsBrW,KAAKgF,uBACjChF,KAAKyB,OAAO+V,aACZ/V,EAAO4U,oBACP/X,GAGDmD,EAAO6U,sBAAwBtW,KAAKgF,uBACnChF,KAAKyB,OAAOgW,eACZ,EACAnZ,GAGDmD,EAAO8U,mBAAqBvW,KAAKgF,uBAChChF,KAAKyB,OAAOiW,YACZjW,EAAO8U,mBACPjY,GAGDmD,EAAOwV,OAAS7Y,GACoB,eAA1BE,EAAQ6E,SAASnC,MAC3BS,EAAOqV,gBAAkB9W,KAAK4E,wBAC7B5E,KAAKyB,OAAO8V,aACZ9V,EAAO2U,oBACP9X,GAGDmD,EAAOsV,gBAAkB/W,KAAKgF,uBAC7BhF,KAAKyB,OAAO+V,aACZ/V,EAAO4U,oBACP/X,GAGDmD,EAAOwV,OAAS7Y,GACoB,UAA1BE,EAAQ6E,SAASnC,OAC3BS,EAAO+U,WAAaxW,KAAK4E,wBACxB5E,KAAKyB,OAAO6uC,iBACZ7uC,EAAO+U,WACPlY,GAGDmD,EAAOgV,aAAezW,KAAKgF,uBAC1BhF,KAAKyB,OAAO8uC,mBACZ,EACAjyC,GAGDmD,EAAOoV,WAAa7W,KAAKgF,uBACxBhF,KAAKyB,OAAO+uC,iBACZ/uC,EAAOoV,WACPvY,GAGDmD,EAAOiV,kBAAoB1W,KAAK4E,wBAC/B5E,KAAKyB,OAAOgvC,wBACZhvC,EAAOiV,kBACPpY,GAGDmD,EAAOkV,oBAAsB3W,KAAKgF,uBACjChF,KAAKyB,OAAOivC,0BACZ,EACApyC,GAGDmD,EAAOmV,kBAAoB5W,KAAKgF,uBAC/BhF,KAAKyB,OAAOkvC,wBACZlvC,EAAOmV,kBACPtY,GAGDmD,EAAOwV,OlF3GC,KkF+GHxV,CACR,EAACJ,EAEDsB,gBAAA,SAAgBrE,OAAgBmQ,EAAAzO,KAC/B,OAAWA,KAAC4D,oBAAoBtF,EAAS,SAACqZ,UACzC/K,EACC+K,EACAlJ,EAAKnO,oBACL,EAEH,EAACe,EAEDyB,oBAAA,SAAoBxE,GAGf0B,KAAKiW,YAAc3X,EAAQ4E,KAC9BlD,KAAKiR,cAAcxB,uBAAuBzP,KAAKmwC,wBAC/CnwC,KAAKiR,cAAcxB,uBAAuBzP,KAAKkwC,qBAC/ClwC,KAAKmwC,4BAAyBxuC,EAC9B3B,KAAKwe,eAAY7c,EACjB3B,KAAKiW,eAAYtU,EACjB3B,KAAK0nB,kBAAoB,EAEN,YAAf1nB,KAAKsV,OACRtV,KAAKkC,aAGR,EAACb,EAEDE,kBAAA,SAAkBc,GACjBrC,KAAKsa,YAAc,IAAIxB,GAAoBzW,GAC3CrC,KAAKiR,cAAgB,IAAIvD,GAAsBrL,EAAQ,CACtDjC,SAAUJ,KAAKI,UAEjB,EAACiB,EAEO+T,MAAA,WACP,QAAoCzT,IAAhC3B,KAAKmwC,uBAAT,CAIA,IAIoB7/B,EAJdsgC,EAAiC5wC,KAAKmwC,uBACtCU,EAAuB7wC,KAAKkwC,oBAGlC,GAAIlwC,KAAKiW,YACQjW,KAAKiR,cAAc5B,cAAc,CAChDH,UAAWlP,KAAKiW,UAChB7G,mBAAiBkB,EAAAA,CAAAA,EAAAA,EACf9S,EAAkBE,wBAAoBiE,EAAS2O,GAEjDnB,oBAAqB,CAEpB9L,YAAarD,KAAKsa,YAAYpB,YAAqBlZ,KAAKiW,WACtD5S,YACFrC,KAAMyM,IAEP1J,QAAS,CAAEL,WAAY3G,EAAY8Q,OAAQ0H,OAAQvY,KAInD,OAIF,IAAMkS,EAAYlP,KAAKiW,UAEvBjW,KAAKiR,cAAcxB,uBAAuBmhC,GAC1C5wC,KAAKiR,cAAcxB,uBAAuBohC,GAE1C7wC,KAAK0nB,kBAAoB,EACzB1nB,KAAKmwC,4BAAyBxuC,EAC9B3B,KAAKkwC,yBAAsBvuC,EAC3B3B,KAAKiW,eAAYtU,EACjB3B,KAAKwe,eAAY7c,EAGE,YAAf3B,KAAKsV,OACRtV,KAAKkC,aAGFgN,GACHlP,KAAK0C,SAASwM,EAAW,CAAEhO,KAAMlB,KAAKkB,KAAMqU,OAAQvY,GA3CrD,CA6CD,EAACqE,EAEOgvC,6BAAA,SAA6BtuC,GACpC,UAC8BJ,IAA7B3B,KAAKkwC,0BAC2BvuC,IAAhC3B,KAAKmwC,wBACLnwC,KAAK0nB,kBAAoB,GAH1B,CAQA,IAAMrkB,EAAcrD,KAAKsa,YAAYnB,eACpCnZ,KAAKkwC,qBAGN,KAAI7sC,EAAYyC,OAAS,IAMpB9F,KAAKwe,UAAV,CAIA,IAAM9U,EAAS1J,KAAKsa,YAAYpB,YAC/BlZ,KAAKmwC,wBACJ9sC,YAEIytC,EAAaztC,EAAY,GACzB0tC,EAAY1tC,EAAYA,EAAYyC,OAAS,GAE7Cq2B,EAAoB5zB,EAAsBxG,EAAMyG,IAAKzG,EAAM0G,KAC3DuoC,EAAsBzoC,EAC3BuoC,EAAW,GACXA,EAAW,IAENG,EAAsB1oC,EAC3BwoC,EAAU,GACVA,EAAU,IAGL5B,EAAoB5mC,EAAsBmB,EAAO,GAAIA,EAAO,IAE5DwnC,EAAct4B,GACnBu2B,EACA6B,GAQKG,EALcv4B,GAAkBu2B,EAAmBhT,GAEf+U,EAIvCF,EACA7U,EAEGiV,EAAgBpzB,GACrBmxB,EACAhT,GAGKsT,EAAezxB,GACpBmxB,EACA6B,GAEKtB,EAAa1xB,GAClBmxB,EACA8B,GAGKtB,EAAkBxxB,GAAiBsxB,GACnCG,EAAgBzxB,GAAiBuxB,GACjC2B,EAAmBlzB,GAAiBizB,GAU1C,IARoBpxC,KAAKsxC,YAAY,CACpCD,iBAAAA,EACA1B,gBAAAA,EACAC,cAAAA,EACApxB,UAAWxe,KAAKwe,YAIjB,CAyBA,IApBA,IAAM+wB,EAAevvC,KAAKuxC,gBACzBvxC,KAAKwe,UACLmxB,EACAC,GAIKlwB,EAAiB1f,KAAK8uC,UAItBe,GADgC,kBAAnB7vC,KAAKwe,UAAgC,GAAK,GAC3B+wB,EAAgB7vB,EAE5C8vB,EAAS52B,GACdu2B,EACAgC,GAIKK,EAAW,GACR3nC,EAAI,EAAGA,GAAK6V,EAAgB7V,IAAK,CACzC,IACMimC,EAAaryB,GAClB0xB,EACAK,EAHsBG,EAAkB9lC,EAAIgmC,GAM7Cn3B,EAAqB5P,EAAsBgnC,EAAWpnC,EAAGonC,EAAWnnC,GAAvDF,EAAGiQ,EAAHjQ,IAEPstB,EAAY,CACjBjuB,EAHU4Q,EAAHlQ,IAGaxI,KAAKM,qBACzBwH,EAAeW,EAAKzI,KAAKM,sBAIzBy1B,EAAU,KAAO1yB,EAAYA,EAAYyC,OAAS,GAAG,IACrDiwB,EAAU,KAAO1yB,EAAYA,EAAYyC,OAAS,GAAG,IAErD0rC,EAASC,QAAQ1b,EAEnB,CAOA,OALA1yB,EAAY0G,KAAI7D,MAAhB7C,EAAoBmuC,GAGpBnuC,EAAY0G,KAAK1G,EAAY,IAEtBA,CAlDP,CA/DA,CAdA,CAgID,EAAChC,EAEO+uC,gCAAA,SAAgCruC,GACvC,UAC8BJ,IAA7B3B,KAAKkwC,0BAC2BvuC,IAAhC3B,KAAKmwC,wBACLnwC,KAAK0nB,kBAAoB,GAH1B,CAQA,IAAMsnB,EAA4BhvC,KAAKsa,YAAYpB,YAClDlZ,KAAKkwC,qBACJ7sC,YACIqG,EAAS1J,KAAKsa,YAAYpB,YAC/BlZ,KAAKmwC,wBACJ9sC,YAEI4rC,EAAcD,EAA0B,GACxCE,EAAc,CAACntC,EAAMyG,IAAKzG,EAAM0G,KAEhC2mC,EAAyB7mC,EAC9B0mC,EAAY,GACZA,EAAY,IAEPI,EAAyB9mC,EAC9B2mC,EAAY,GACZA,EAAY,IAEPC,EAAoB5mC,EAAsBmB,EAAO,GAAIA,EAAO,IAE5D8lC,EAAS52B,GAAkBu2B,EAAmBC,GAIpD,QAAuBztC,IAAnB3B,KAAKwe,UAAyB,CACjC,IAAM8wB,EAAYZ,GACjBS,EACAC,EACAC,GAEDrvC,KAAKwe,UAAY8wB,EAAY,YAAc,eAC5C,CAGA,IAkBIC,EAlBEE,EAAezxB,GACpBmxB,EACAC,GAEKM,EAAa1xB,GAClBmxB,EACAE,GAIK3vB,EAAiB1f,KAAK8uC,UACtBzrC,EAA0B,CAAC4rC,GAG3BU,EAAkBxxB,GAAiBsxB,GACnCG,EAAgBzxB,GAAiBuxB,GAIhB,kBAAnB1vC,KAAKwe,WACR+wB,EAAeK,EAAgBD,GACZ,IAClBJ,GAAgB,MAGjBA,EAAeI,EAAkBC,GACd,IAClBL,GAAgB,KASlB,IALA,IAAMM,GACgB,kBAAnB7vC,KAAKwe,UAAgC,GAAK,GAAK+wB,EACjD7vB,EAGQ7V,EAAI,EAAGA,GAAK6V,EAAgB7V,IAAK,CACzC,IACMimC,EAAaryB,GAClB0xB,EACAK,EAHsBG,EAAkB9lC,EAAIgmC,GAM7C6B,EAAqB5oC,EAAsBgnC,EAAWpnC,EAAGonC,EAAWnnC,GAAvDF,EAAGipC,EAAHjpC,IAEPstB,EAAY,CACjBjuB,EAHU4pC,EAAHlpC,IAGaxI,KAAKM,qBACzBwH,EAAeW,EAAKzI,KAAKM,sBAIzBy1B,EAAU,KAAO1yB,EAAYA,EAAYyC,OAAS,GAAG,IACrDiwB,EAAU,KAAO1yB,EAAYA,EAAYyC,OAAS,GAAG,IAErDzC,EAAY0G,KAAKgsB,EAEnB,CAEA,OAAO1yB,CA9FP,CA+FD,EAAChC,EAEOkwC,gBAAA,SACP/yB,EACAmxB,EACAC,GAEA,IAAIL,EAYJ,MAXkB,kBAAd/wB,GACH+wB,EAAeK,EAAgBD,GACZ,IAClBJ,GAAgB,MAGjBA,EAAeI,EAAkBC,GACd,IAClBL,GAAgB,KAGXA,CACR,EAACluC,EAEOiwC,YAAA,SAAWvkC,GAClB,IAAAskC,EAAgBtkC,EAAhBskC,iBACA1B,EAAe5iC,EAAf4iC,gBACAC,EAAa7iC,EAAb6iC,cAQA,MAAkB,cAPT7iC,EAATyR,UASKmxB,GAAmBC,EAGrByB,GAAoB1B,GACpB0B,GAAoBzB,EAKpByB,GAAoB1B,GACpB0B,GAAoBzB,EAKlBD,GAAmBC,EAGrByB,GAAoB1B,GACpB0B,GAAoBzB,EAKpByB,GAAoB1B,GACpB0B,GAAoBzB,CAIxB,EAACK,CAAA,EA1rBuCrwC,GCjF5B+xC,GAgBZ,SAAA5kC,GAUC,IAAApH,EAAA3F,KATA4xC,EAAI7kC,EAAJ6kC,KACAC,EAAQ9kC,EAAR8kC,SACAC,EAAU/kC,EAAV+kC,WACA1vC,EAAQ2K,EAAR3K,cAnBMwvC,UAAI,EAAA5xC,KACJ6xC,cAAQ,EAAA7xC,KACR+xC,YAAa,EACb3vC,KAAAA,cACA0vC,EAAAA,KAAAA,gBAsBN,EAAA9xC,KAAK4xC,KAAOA,EAGZ5xC,KAAKoC,SAAW,WACVuD,EAAKosC,aACTpsC,EAAKosC,YAAa,EAClB3vC,EAASyvC,GAEX,EAGA7xC,KAAK8xC,WAAa,WACbnsC,EAAKvD,WACRuD,EAAKosC,YAAa,EAClBD,EAAWD,GAEb,EAEA7xC,KAAK6xC,SAAWA,CACjB,oICjBA,SAAAG,EAAY3vC,GA2BJ4vC,KAAAA,yBAA0B,EAAKjyC,KAC/BkyC,iCAEEC,EAAAA,KAAAA,gCAAiC,EAAKnyC,KACtCoyC,2BAAqB,EAAApyC,KACrBqyC,kCAA4B,EAAAryC,KAC5BsyC,oCACAC,EAAAA,KAAAA,oBACAC,EAAAA,KAAAA,0BACAC,EAAAA,KAAAA,UAAyB,IAAI1H,IAAK/qC,KAClC0yC,WAEJ,GACIC,KAAAA,WACT,eAAc3yC,KACL4yC,2BAzCT,EAAA5yC,KAAKmyC,+BAC4C,kBAAzC9vC,EAAOwwC,+BACXxwC,EAAOwwC,8BAGX7yC,KAAKoyC,sBACmC,iBAAhC/vC,EAAOywC,qBACXzwC,EAAOywC,qBACP,EAEJ9yC,KAAKsyC,+BAC4C,iBAAzCjwC,EAAO0wC,8BACX1wC,EAAO0wC,8BACP,EAEJ/yC,KAAKqyC,6BAC0C,iBAAvChwC,EAAO2wC,4BACX3wC,EAAO2wC,4BACP,EAEJhzC,KAAKwyC,qBACkC,iBAA/BnwC,EAAO/B,oBACX+B,EAAO/B,oBACP,CACL,CAAC,IAAAe,EAAA2wC,EAAA1wC,UA6YA,OA7YAD,EAuBS4xC,UAAA,SAAUlxC,GACnB,OAAsB,IAAlBA,EAAMgU,OACF,UACoB,IAAjBhU,EAAMgU,OACT,OACoB,IAAjBhU,EAAMgU,OACT,SACoB,IAAjBhU,EAAMgU,OACT,QAID,SACR,EAAC1U,EAES6xC,wBAAA,SAAwBnxC,GACjC,IAMAoxC,EANmBnzC,KAAKozC,mBACvBrxC,EAAMf,MAK0BqyC,wBAEjC,MAAO,CACNt4B,WAAYhZ,EAAMuxC,QAHPH,EAAJvO,KAIP5pB,WAAYjZ,EAAMwxC,QAJFJ,EAAHK,IAMf,EAACnyC,EAESoyC,sBAAA,SACT1xC,EACAiU,QAAAA,IAAAA,IAAAA,GAAgB,GAEhB,IAAM09B,EAAS1zC,KAAK2zC,mBAAmB5xC,GAEvC,IAAK2xC,EACJ,OAAW,KAGZ,IAAQlrC,EAAakrC,EAAblrC,IAAKC,EAAQirC,EAARjrC,IACbmrC,EAAmC5zC,KAAKkzC,wBAAwBnxC,GAAxDgZ,EAAU64B,EAAV74B,WAAYC,EAAU44B,EAAV54B,WACdjF,EAAS/V,KAAKizC,UAAUlxC,GACxBk/B,EAAWziC,MAAMiU,KAAKzS,KAAKyyC,WAEjC,MAAO,CACNjqC,IAAKV,EAAeU,EAAKxI,KAAKwyC,sBAC9B/pC,IAAKX,EAAeW,EAAKzI,KAAKwyC,sBAC9Bz3B,WAAAA,EACAC,WAAAA,EACAjF,OAAAA,EACAkrB,SAAAA,EACAjrB,cAAAA,EAEF,EAAC3U,EAQMe,SAAA,SAASyxC,GACf7zC,KAAK4yC,sBAAwBiB,EAE7B7zC,KAAK0yC,WAAa1yC,KAAK8zC,sBAEvB9zC,KAAK0yC,WAAWp1B,QAAQ,SAACy2B,GACxBA,EAAS3xC,UACV,EACD,EAACf,EAOM2yC,uBAAA,WACN,OAAWh0C,KAACwyC,oBACb,EAACnxC,EAESyyC,oBAAA,WAAmBnuC,IAAAA,EAC5B3F,KAAA,MAAO,CACN,IAAI2xC,GAAqC,CACxCC,KAAM,cACNC,SAAU,SAAC9vC,GACV,GAAK4D,EAAKitC,uBAKL7wC,EAAMkyC,UAAX,CAIA,IAAMC,EAAYvuC,EAAK8tC,sBAAsB1xC,GACxCmyC,IAILvuC,EAAKgtC,WAAa,eAKlBhtC,EAAK4sC,eAAiB2B,EAEtBvuC,EAAKusC,4BAA8BnwC,EAAMkW,OACtClW,EAAMkW,YACNtW,EAhBH,CAiBD,EACAS,SAAU,SAACyvC,GACVlsC,EAAKytC,mBAAmB,eAAee,iBACtC,cACAtC,EAEF,EACAC,WAAY,SAACD,GACZlsC,EAAKytC,mBAAmB,eAAegB,oBACtC,cACAvC,EAEF,IAED,IAAIF,GAAqC,CACxCC,KAAM,cACNC,SAAU,SAAC9vC,GACV,GAAK4D,EAAKitC,uBAGL7wC,EAAMkyC,UAAX,CAIAlyC,EAAMu/B,iBAEN,IAAM4S,EAAYvuC,EAAK8tC,sBAAsB1xC,GAC7C,GAAKmyC,EAIL,GAAwB,iBAApBvuC,EAAKgtC,WAERhtC,EAAKitC,sBAAsBnuC,YAAYyvC,GACvCvuC,EAAK4sC,eAAiB2B,OAChB,GAAwB,iBAApBvuC,EAAKgtC,WAA+B,CAE9C,IAAKhtC,EAAK4sC,eACT,OAGD,IAAM8B,EAAc,CACnB3rC,EAAG/C,EAAK4sC,eAAex3B,WACvBpS,EAAGhD,EAAK4sC,eAAev3B,YAElBs5B,EAAiB,CACtB5rC,EAAGwrC,EAAUn5B,WACbpS,EAAGurC,EAAUl5B,YAMRu5B,EAAY5uC,EAAKitC,sBAAsB4B,WAEvCC,EAAuB77B,GAC5By7B,EACAC,GAwBD,GAlBkB,YAAdC,EAKFE,EAAuB9uC,EAAK0sC,6BACL,cAAdkC,EAKTE,EAAuB9uC,EAAK2sC,+BAGfmC,EAAuB9uC,EAAKysC,sBAK1C,OAIDzsC,EAAKssC,yBAA0B,EAE/BtsC,EAAKgtC,WAAa,WAClBhtC,EAAKitC,sBAAsBnzC,YAC1By0C,EACA,SAACQ,GACA/uC,EAAKgvC,gBAAgBC,KAAKjvC,EAA1BA,CAAgC+uC,EACjC,EAEF,KAA+B,aAApB/uC,EAAKgtC,YACfhtC,EAAKitC,sBAAsBlzC,OAAOw0C,EAAW,SAACQ,GAC7C/uC,EAAKgvC,gBAAgBC,KAAKjvC,EAA1BA,CAAgC+uC,EACjC,EA5ED,CA8ED,EACAtyC,SAAU,SAACyvC,GACSlsC,EAAKytC,mBAAmB,eAChCe,iBAAiB,cAAetC,EAC5C,EACAC,WAAY,SAACD,GACOlsC,EAAKytC,mBAAmB,eAChCgB,oBAAoB,cAAevC,EAC/C,IAED,IAAIF,GAAmC,CACtCC,KAAM,cACNC,SAAU,SAAC9vC,GACL4D,EAAKitC,wBAGV7wC,EAAMu/B,iBAIN37B,EAAKssC,yBAA0B,EAChC,EACA7vC,SAAU,SAACyvC,GACSlsC,EAAKytC,mBAAmB,eAChCe,iBAAiB,cAAetC,EAC5C,EACAC,WAAY,SAACD,GACOlsC,EAAKytC,mBAAmB,eAChCgB,oBAAoB,cAAevC,EAC/C,IAED,IAAIF,GAAqC,CACxCC,KAAM,YACNC,SAAU,SAAC9vC,GACV,GAAK4D,EAAKitC,uBAIN7wC,EAAMkW,SAAWtS,EAAKytC,mBAAmB,gBAM5CztC,EAAKwsC,gCACLxsC,EAAKusC,8BAAgCnwC,EAAMkW,UAK5CtS,EAAKusC,iCAA8BvwC,EAG9BI,EAAMkyC,WAAX,CAIA,IAAMC,EAAYvuC,EAAK8tC,sBAAsB1xC,GAExCmyC,IAImB,aAApBvuC,EAAKgtC,WACRhtC,EAAKitC,sBAAsBjzC,UAAUu0C,EAAW,SAACQ,GAChD/uC,EAAKgvC,gBAAgBC,KAAKjvC,EAA1BA,CAAgC+uC,EACjC,GAEoB,iBAApB/uC,EAAKgtC,YACe,iBAApBhtC,EAAKgtC,aAKDhtC,EAAKssC,0BACRiC,EAAUl+B,eAAgB,EAC1BrQ,EAAKssC,yBAA0B,GAGhCtsC,EAAKitC,sBAAsBluC,QAAQwvC,IAKpCvuC,EAAKgtC,WAAa,eAClBhtC,EAAKgvC,iBAAgB,GA9BrB,CA+BD,EACAvyC,SAAU,SAACyvC,GACSlsC,EAAKytC,mBAAmB,aAChCe,iBAAiB,YAAatC,EAC1C,EACAC,WAAY,SAACD,GACOlsC,EAAKytC,mBAAmB,aAChCgB,oBAAoB,YAAavC,EAC7C,IAED,IAAIF,GAAgB,CACnBC,KAAM,QACNC,SAAU,SAAC9vC,GAGL4D,EAAKitC,wBAEVjtC,EAAK8sC,UAAS,OAAQ1wC,EAAMqD,KAE5BO,EAAKitC,sBAAsBzuC,QAAQ,CAClCiB,IAAKrD,EAAMqD,IACX67B,SAAUziC,MAAMiU,KAAK9M,EAAK8sC,WAC1BnR,eAAgB,WAAF,OAAQv/B,EAAMu/B,gBAAgB,IAE9C,EACAl/B,SAAU,SAACyvC,GACSlsC,EAAKytC,mBAAmB,SAChCe,iBAAiB,QAAStC,EACtC,EACAC,WAAY,SAACD,GACOlsC,EAAKytC,mBAAmB,SAChCgB,oBAAoB,QAASvC,EACzC,IAED,IAAIF,GAAgB,CACnBC,KAAM,UACNC,SAAU,SAAC9vC,GACL4D,EAAKitC,wBAIVjtC,EAAK8sC,UAAUzH,IAAIjpC,EAAMqD,KAEzBO,EAAKitC,sBAAsB1uC,UAAU,CACpCkB,IAAKrD,EAAMqD,IACX67B,SAAUziC,MAAMiU,KAAK9M,EAAK8sC,WAC1BnR,eAAgB,kBAAMv/B,EAAMu/B,gBAAgB,IAE9C,EACAl/B,SAAU,SAACyvC,GACSlsC,EAAKytC,mBAAmB,WAChCe,iBAAiB,UAAWtC,EACxC,EACAC,WAAY,SAACD,GACOlsC,EAAKytC,mBAAmB,WAChCgB,oBAAoB,UAAWvC,EAC3C,IAGH,EAACxwC,EAOMywC,WAAA,WACN9xC,KAAK0yC,WAAWp1B,QAAQ,SAACy2B,GACxBA,EAASjC,YACV,GAEA9xC,KAAK2nB,QAGL3nB,KAAK4yC,2BAAwBjxC,EAC7B3B,KAAKuyC,oBAAiB5wC,EACtB3B,KAAKkyC,iCAA8BvwC,EACnC3B,KAAKiyC,yBAA0B,CAChC,EAACD,CAAA,sBnEjc+B,WAChC,MAAO,CACN77B,iBAAkB,UAClBC,oBAAqB,UACrBC,oBAAqB,EACrBC,sBAAuB,EACvBC,mBAAoB,GACpBC,WAAY,UACZC,aAAc,EACdC,kBAAmB,UACnBC,oBAAqB,EACrBC,kBAAmB,EACnBC,WAAY,EACZC,gBAAiB,UACjBC,gBAAiB,EACjBC,kBAAmB,EACnBC,OAAQ,EACRC,eAAWvV,EACXwV,kBAAcxV,EACdyV,iBAAazV,EACb0V,oBAAgB1V,EAElB,uBoEHakzC,GAAoB,CAChC7lB,gCAAAA,GACAC,0CAAAA,GACAC,kDAAAA,GACA/vB,kCAAAA,EACAkN,gCAAAA,EACAC,+CAAAA,EACAC,6CAAAA,EACAC,4CAAAA,EACAghC,8CAAAA,GACAC,sCAAAA,GACAF,uCAAAA,GACAnuC,6BAAAA,GCKKiV,GAAmB,CAAEC,OAAQ,SAAUC,OAAQ,SAoB/CC,GAAiB,CACtBC,MAAO,YACPW,MAAO,WAUK0/B,gBAAgC,SAAApvC,GAiB5C,SAAAovC,EACCj1C,GAA2E8F,IAAAA,EAG/C,OAD5BA,EAAAD,EAAAO,KAAAjG,KAAMH,GAAS,IAAM8F,MAnBtBzE,KAAO,sBAAqByE,EAEpBkU,UAAW,EAAKlU,EAChBsQ,iBAAStQ,EACToU,YAAsB,GAAEpU,EACxBmP,UACPT,GAAgB1O,EACToP,QAA6BP,GAAc7O,EAC3CyU,mBAAoB,EAAKzU,EAGzBsL,mBAAatL,EAAAA,EACb2U,iBAAW,EAAA3U,EACXgX,mBAAa,EAAAhX,EACb8jB,qBAMP9jB,EAAKxE,cAActB,GAAS8F,CAC7B,CAACU,EAAAyuC,EAAApvC,GAAArE,IAAAA,EAAAyzC,EAAAxzC,UAkUA,OAlUAD,EAEMF,cAAA,SACNtB,GAIA6F,EAAApE,UAAMH,cAAa8E,KAACpG,KAAAA,GAEhBA,MAAAA,GAAAA,EAASka,cACZ/Z,KAAK+Z,YAAcla,EAAQka,aAGD,QAAhB,MAAPla,OAAO,EAAPA,EAASiV,WACZ9U,KAAK8U,UAAY,CAAER,OAAQ,KAAMC,OAAQ,MACxB,MAAP1U,GAAAA,EAASiV,YACnB9U,KAAK8U,UAAS1T,KAAQpB,KAAK8U,UAAcjV,EAAQiV,YAG9CjV,MAAAA,GAAAA,EAASkV,UACZ/U,KAAK+U,QAAO3T,EAAA,CAAA,EAAQpB,KAAK+U,QAAYlV,EAAQkV,SAE/C,EAAC1T,EAEO+T,MAAA,eAAK9E,EACZ,QAAuB3O,IAAnB3B,KAAKiW,WAIOjW,KAAKiR,cAAc1B,iBAAiB,CACnDL,UAAWlP,KAAKiW,UAChB7G,mBAAiBkB,EAAAA,CAAAA,EAAAA,EACf9S,EAAkBE,wBAAoBiE,EAAS2O,GAEjDvM,QAAS,CAAEL,WAAY3G,EAAY8Q,OAAQ0H,OAAQvY,KAGpD,CAIA,IAAMkS,EAAYlP,KAAKiW,UAEvBjW,KAAKypB,cAAoB,SAEzBzpB,KAAK6Z,UAAW,EAChB7Z,KAAKiW,eAAYtU,EAGE,YAAf3B,KAAKsV,OACRtV,KAAKkC,aAGNlC,KAAK0C,SAASwM,EAAW,CACxBhO,KAAMlB,KAAKkB,KACXqU,OAAQvY,GAhBT,CAkBD,EAACqE,EAGDoT,MAAA,WACCzU,KAAKkC,aACLlC,KAAKc,UAAUd,KAAK+U,QAAQN,MAC7B,EAACpT,EAGDwU,KAAA,WACC7V,KAAK8V,UACL9V,KAAKmC,aACLnC,KAAKc,UAAU,QAChB,EAACO,EAGDoD,YAAA,SAAY1C,GACX,QAAuBJ,IAAnB3B,KAAKiW,YAA6C,IAAlBjW,KAAK6Z,SAAzC,CAKA,IAAAc,EAAmC3a,KAAKsa,YAAYjB,cACnDrZ,KAAKiW,WACJ,GAEF6E,EAAiB9a,KAAKa,QAJJ8Z,EAAEE,GAAWF,EAAA,IAKzBhT,EAAWiR,GAChB,CAAElQ,EAFMoS,EAADpS,EAEFC,EAFMmS,EAADnS,GAGV,CAAED,EAAG3G,EAAMgZ,WAAYpS,EAAG5G,EAAMiZ,aAGjCC,EAAiCjb,KAAKsa,YAAYjB,cACjDrZ,KAAKiW,WACJ,GAEFiF,EAAqClb,KAAKa,QAJzBoa,EAAA,GAAYA,MAKvB85B,EAAkBn8B,GACvB,CAAElQ,EAFgBwS,EAAXxS,EAEQC,EAFgBuS,EAAXvS,GAGpB,CAAED,EAAG3G,EAAMgZ,WAAYpS,EAAG5G,EAAMiZ,aAWjC,GAPChb,KAAKc,UADFi0C,EAAkB/0C,KAAKK,gBACXL,KAAK+U,QAAQK,MAEbpV,KAAK+U,QAAQN,SAKzB9M,EAAW3H,KAAK+Z,aAApB,CAIA,IAAMkQ,EAAUjqB,KAAKiR,cAAc1B,iBAAiB,CACnDL,UAAWlP,KAAKiW,UAChB9G,oBAAqB,CACpB,CACCnO,KAAMyM,EACN0E,OAAQ,EACRpG,WAAY,CAAChK,EAAMyG,IAAKzG,EAAM0G,OAGhC1E,QAAS,CAAEL,WAAY3G,EAAY4G,eAG/BsmB,GAILjqB,KAAKypB,cAAcjZ,OAAOyZ,EAAQ9mB,SAASE,YAlB3C,CAhCA,MAFCrD,KAAKc,UAAUd,KAAK+U,QAAQN,MAqD9B,EAACpT,EAGDqD,QAAA,SAAQ3C,GACP,GACmB,UAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcZ,WAAYyC,IACrC,SAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcV,UAAWuC,IACrDA,EAAMiU,eACNhW,KAAK6B,kBAAkB7B,KAAKE,cAAcX,YAAawC,GACvD,CACD,GAAI/B,KAAKoa,kBACR,OAGD,IAAsB,IAAlBpa,KAAK6Z,SAAoB,CAAA,IAAA1J,EAC5BsK,EAAoCza,KAAKiR,cAAcjD,iBACtD,CACC3K,YAAa,CACZ,CAACtB,EAAMyG,IAAKzG,EAAM0G,KAClB,CAAC1G,EAAMyG,IAAKzG,EAAM0G,MAEnB9J,YAAUwR,EACTjP,CAAAA,KAAMlB,KAAKkB,MAAIiP,EACd3S,EAAkBE,oBAAoB,EAAIyS,KARlC6kC,EAASv6B,EAAbvX,GAuBR,OAVAlD,KAAKypB,cAAc9V,OAbY8G,EAARtX,SAaYE,aACnCrD,KAAKiW,UAAY++B,EACjBh1C,KAAK6Z,UAAW,OAIG,YAAf7Z,KAAKsV,OACRtV,KAAKgC,aAIP,CAEAhC,KAAKoV,OACN,CACD,EAAC/T,EAGD6C,UAAA,aAAc7C,EAGd8C,QAAA,SAAQpC,GACHA,EAAMqD,MAAQpF,KAAK8U,UAAUR,OAChCtU,KAAK8V,UACK/T,EAAMqD,MAAQpF,KAAK8U,UAAUP,SACjB,IAAlBvU,KAAK6Z,UACR7Z,KAAKoV,OAGR,EAAC/T,EAGD5B,YAAA,aAAgB4B,EAGhB3B,OAAA,aAAW2B,EAGX1B,UAAA,WAAc0B,EAAAA,EAGdyU,QAAA,WACC,IAAM0F,EAAYxb,KAAKiW,UAEvBjW,KAAKiW,eAAYtU,EACjB3B,KAAK6Z,UAAW,EACG,YAAf7Z,KAAKsV,OACRtV,KAAKkC,aAGNlC,KAAKiR,cAAcxB,uBAAuB+L,GAC1Cxb,KAAKypB,sBACN,EAACpoB,EAGD6U,aAAA,SAAa5X,GACZ,IAAMmD,EAAML,EAAQsa,CAAAA,ErE/Sd,CACNvF,iBAAkB,UAClBC,oBAAqB,UACrBC,oBAAqB,EACrBC,sBAAuB,EACvBC,mBAAoB,GACpBC,WAAY,UACZC,aAAc,EACdC,kBAAmB,UACnBC,oBAAqB,EACrBC,kBAAmB,EACnBC,WAAY,EACZC,gBAAiB,UACjBC,gBAAiB,EACjBC,kBAAmB,EACnBC,OAAQ,EACRC,eAAWvV,EACXwV,kBAAcxV,EACdyV,iBAAazV,EACb0V,oBAAgB1V,IqE8RhB,MACkB,YAAjBrD,EAAQ0C,MACkB,eAA1B1C,EAAQ6E,SAASnC,MACjB1C,EAAQK,WAAWuC,OAASlB,KAAKkB,MAEjCO,EAAO4V,eAAiBrX,KAAKyB,OAAO4V,eAEpC5V,EAAOqV,gBAAkB9W,KAAK4E,wBAC7B5E,KAAKyB,OAAOqV,gBACZrV,EAAOqV,gBACPxY,GAGDmD,EAAOuV,kBAAoBhX,KAAKgF,uBAC/BhF,KAAKyB,OAAOuV,uBACiBrV,IAA7BF,EAAOuV,kBAAkC,EAAIvV,EAAOuV,kBACpD1Y,GAGDmD,EAAOsV,gBAAkB/W,KAAKgF,uBAC7BhF,KAAKyB,OAAOsV,gBACZtV,EAAOsV,gBACPzY,GAGDmD,EAAOwV,OAAS7Y,EAETqD,GAEU,YAAjBnD,EAAQ0C,MACkB,UAA1B1C,EAAQ6E,SAASnC,MACjB1C,EAAQK,WAAWuC,OAASlB,KAAKkB,MAEjCO,EAAOoV,WAAa7W,KAAKgF,uBACxBhF,KAAKyB,OAAOka,kBACZla,EAAOoV,WACPvY,GAGDmD,EAAOgV,aAAezW,KAAKgF,uBAC1BhF,KAAKyB,OAAOoa,oBACZ,EACAvd,GAGDmD,EAAO+U,WAAaxW,KAAK4E,wBACxB5E,KAAKyB,OAAOma,kBACZna,EAAO+U,WACPlY,GAGDmD,EAAOiV,kBAAoB1W,KAAK4E,wBAC/B5E,KAAKyB,OAAOqa,yBACZra,EAAOiV,kBACPpY,GAGDmD,EAAOkV,oBAAsB3W,KAAKgF,uBACjChF,KAAKyB,OAAOua,2BACZ,EACA1d,GAGDmD,EAAOmV,kBAAoB5W,KAAKgF,uBAC/BhF,KAAKyB,OAAOsa,yBACZ,EACAzd,GAGDmD,EAAOwV,OtF/FG,GsFiGHxV,GAGDA,CACR,EAACJ,EAEDsB,gBAAA,SAAgBrE,GAAgBmQ,IAAAA,OAC/B,OAAOzO,KAAK4D,oBAAoBtF,EAAS,SAACqZ,GACzC,OAAAwI,GAA0BxI,EAAsBlJ,EAAKnO,oBAAoB,EAE3E,EAACe,EAEDyB,oBAAA,SAAoBxE,GAIf0B,KAAKiW,YAAc3X,EAAQ4E,KAC9BlD,KAAKypB,cAAoB,SACzBzpB,KAAK6Z,UAAW,EAChB7Z,KAAKiW,eAAYtU,EAEnB,EAACN,EAEDE,kBAAA,SAAkBc,GACjBrC,KAAKsa,YAAc,IAAIxB,GAAoBzW,GAC3CrC,KAAKiR,cAAgB,IAAIvD,GAAsBrL,EAAQ,CACtDjC,SAAUJ,KAAKI,WAEhBJ,KAAK2c,cAAgB,IAAIL,GAAsBja,GAC/CrC,KAAKypB,cAAgB,IAAIrF,GACxB/hB,EACArC,KAAK2c,cACL3c,KAAKiR,cACLjR,KAAKsa,YAEP,EAACw6B,CAAA,CAxV2C,CAAQl1C,GCjErC,SAAAq1C,GAAiBpwC,GAEhC,GAAc,OAAVA,EACH,SAID,GAAqB,kBAAVA,EACV,OAAW,EAIZ,GAAqB,iBAAVA,EACV,OAAW,EAIZ,QAAclD,IAAVkD,EACH,OAAY,EAIb,GAAqB,iBAAVA,EACV,OAAOua,OAAO0H,SAASjiB,GAIxB,GAAqB,iBAAVA,EACV,OAAY,EAIb,GAAqB,iBAAVA,EACV,SAID,GAAqB,mBAAVA,EACV,OAAY,EAIb,GAAIA,aAAiBqwC,OACpB,OAAO,EAIR,GAAIrwC,aAAiB0lC,IACpB,OAAY,EAIb,GAAI1lC,aAAiBkmC,IACpB,OAAO,EAIR,GAAIlmC,aAAiB9F,KACpB,OAAY,EAIb,GAAqB,iBAAV8F,GAAgC,OAAVA,IAAmBrG,MAAMC,QAAQoG,GAAQ,CACzE,IAAMswC,EAAQphC,OAAOqhC,eAAevwC,GACpC,GAAIswC,IAAUphC,OAAOzS,WAAuB,OAAV6zC,EACjC,OAAY,CAEd,CAGA,GAAIE,YAAYC,OAAOzwC,MAAYA,aAAiB0wC,UACnD,OAAO,EAIR,GAAI/2C,MAAMC,QAAQoG,GACjB,IAAA+N,IAAwBf,EAAxBe,EAAAC,EAAmBhO,KAAKgN,EAAAe,KAAAE,MACvB,IAAKmiC,GADSpjC,EAAAhN,OAEb,SAMH,MAAqB,iBAAVA,GACHkP,OAAOg5B,KAAKloC,GAAO2gB,MACzB,SAACpgB,GAAG,MACY,iBAARA,GACP6vC,GAAiBpwC,EAAMO,GAAsC,EAMjE,CCvDA,IAAMoP,GAAiB,CACtBb,OAAQ,YACR0U,UAAW,WACXC,QAAS,aASGktB,gBAAoB9vC,SAAAA,GAgBhC,SAAA8vC,EAAY31C,GAAuD,IAAA8F,EAEtC,OAD5BA,EAAAD,EAAAO,KAAMpG,KAAAA,GAAS,IAAM8F,MAhBtBzE,KAAO,SAAiByE,EAGhBoP,QAA6BP,GAAc7O,EAC3CqjB,UAAoB,EAAKrjB,EAGzBsjB,qBAAetjB,EAAAA,EAGfgX,mBAAahX,EAAAA,EACbiX,sBAAgB,EAAAjX,EAChB8pB,iBAAW,EAAA9pB,EACXsL,mBAIPtL,EAAAA,EAAKxE,cAActB,GAAS8F,CAC7B,CAACU,EAAAmvC,EAAA9vC,GAAArE,IAAAA,EAAAm0C,EAAAl0C,UA+OAk0C,OA/OAn0C,EAEDF,cAAA,SACCtB,GAEA6F,EAAApE,UAAMH,cAAa8E,KAACpG,KAAAA,GAET,MAAPA,GAAAA,EAASkV,UACZ/U,KAAK+U,QAAO3T,KAAQpB,KAAK+U,QAAYlV,EAAQkV,UAGnC,MAAPlV,GAAAA,EAASmpB,WACZhpB,KAAKgpB,SAAWnpB,EAAQmpB,SAE1B,EAAC3nB,EAGDoT,MAAA,WACCzU,KAAKkC,aACLlC,KAAKc,UAAUd,KAAK+U,QAAQpB,OAC7B,EAACtS,EAGDwU,KAAA,WACC7V,KAAK8V,UACL9V,KAAKmC,aACLnC,KAAKc,UAAU,QAChB,EAACO,EAGDqD,QAAA,SAAQ3C,GAEY,UAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcZ,WAAYyC,IACtDA,EAAMiU,eACNhW,KAAK6B,kBAAkB7B,KAAKE,cAAcX,YAAawC,GAExD/B,KAAK0rB,aAAa3pB,GAGD,SAAjBA,EAAMgU,QACN/V,KAAK6B,kBAAkB7B,KAAKE,cAAcV,UAAWuC,IAErD/B,KAAK8rB,YAAY/pB,EAGnB,EAACV,EAGDoD,YAAA,WAAgBpD,EAAAA,EAGhB6C,UAAA,aAAc7C,EAGd8C,QAAA,aAAY9C,EAGZyU,QAAA,WACC9V,KAAKipB,qBAAkBtnB,CACxB,EAACN,EAED5B,YAAA,SACCsC,EACA4C,GAEA,GAAK3E,KAAK6B,kBAAkB7B,KAAKE,cAAcT,YAAasC,GAA5D,CAIA,GAAI/B,KAAKgpB,SAAU,CAClB,IAAM0G,EACL1vB,KAAKyvB,YAAYJ,uBAAuBttB,GACzC/B,KAAKipB,gBAAqC,MAAnByG,OAAmB,EAAnBA,EAAqBxsB,EAC7C,CAIKlD,KAAKipB,kBAKVjpB,KAAKc,UAAUd,KAAK+U,QAAQsT,WAE5B1jB,GAAmB,GAjBnB,CAkBD,EAACtD,EAGD3B,OAAA,SACCqC,EACA4C,GAA8C2L,IAAAA,EAEzCtQ,KAAK6B,kBAAkB7B,KAAKE,cAAcR,OAAQqC,SAI1BJ,IAAzB3B,KAAKipB,iBAITjpB,KAAKiR,cAAclC,YAAY,CAC9BG,UAAWlP,KAAKipB,gBAChB9Z,oBAAqB,CACpBnO,KAAMyM,GACNpK,YAAa,CAACtB,EAAMyG,IAAKzG,EAAM0G,MAEhC2G,mBAAiBkB,EAAAA,CAAAA,EAAAA,EACf9S,EAAkBG,SAAS,EAAI2S,GAEjCvM,QAAS,CAAEL,WAAY3G,EAAY4G,cAErC,EAACtC,EAGD1B,UAAA,SACCoC,EACA4C,GAA8C,IAAAsmB,EAE9C,GAAKjrB,KAAK6B,kBAAkB7B,KAAKE,cAAcP,UAAWoC,SAI7BJ,IAAzB3B,KAAKipB,iBAIOjpB,KAAKiR,cAAclC,YAAY,CAC9CG,UAAWlP,KAAKipB,gBAChB7Z,mBAAiB6b,EAAA,CAChB/pB,KAAMlB,KAAKkB,MAAI+pB,EACdztB,EAAkBG,SAAS,EAAKstB,GAElClnB,QAAS,CAAEL,WAAY3G,EAAY8Q,OAAQ0H,OAAQ,UAGpD,CAIA,IAAMrG,EAAYlP,KAAKipB,gBAEvBjpB,KAAKc,UAAUd,KAAK+U,QAAQuT,SAC5BtoB,KAAKipB,qBAAkBtnB,EACvBgD,GAAmB,GAEnB3E,KAAK0C,SAASwM,EAAW,CACxBhO,KAAMlB,KAAKkB,KACXqU,OAAQvY,GAVT,CAYD,EAACqE,EAEDE,kBAAA,SAAkBc,GACjBrC,KAAK2c,cAAgB,IAAIL,GAAsBja,GAC/CrC,KAAK4c,iBAAmB,IAAIP,GAAyBha,GACrDrC,KAAKyvB,YAAc,IAAIL,GACtB/sB,EACArC,KAAK2c,cACL3c,KAAK4c,kBAEN5c,KAAKiR,cAAgB,IAAIvD,GAAsBrL,EAAQ,CACtDjC,SAAUJ,KAAKI,UAEjB,EAACiB,EAGD6U,aAAA,SAAa5X,GACZ,IAMEm3C,EAAAC,EAAAC,EANIl0C,EAAML,EAAQsa,CAAAA,EvE/Od,CACNvF,iBAAkB,UAClBC,oBAAqB,UACrBC,oBAAqB,EACrBC,sBAAuB,EACvBC,mBAAoB,GACpBC,WAAY,UACZC,aAAc,EACdC,kBAAmB,UACnBC,oBAAqB,EACrBC,kBAAmB,EACnBC,WAAY,EACZC,gBAAiB,UACjBC,gBAAiB,EACjBC,kBAAmB,EACnBC,OAAQ,EACRC,eAAWvV,EACXwV,kBAAcxV,EACdyV,iBAAazV,EACb0V,oBAAgB1V,IuEqPhB,MAtBkB,YAAjBrD,EAAQ0C,MACkB,UAA1B1C,EAAQ6E,SAASnC,MACjB1C,EAAQK,WAAWuC,OAASlB,KAAKkB,OAEjCO,EAAOwV,OxF+BI,GwF9BXxV,EAAO0V,aAAenX,KAAKgF,uBACf,OADqCywC,EAChDz1C,KAAKyB,aAAM,EAAXg0C,EAAat+B,aACb,GACA7Y,GAEDmD,EAAO2V,YAAcpX,KAAKgF,uBACd,OADoC0wC,EAC/C11C,KAAKyB,aAAM,EAAXi0C,EAAat+B,YACb,GACA9Y,GAEDmD,EAAOyV,UAAYlX,KAAKiF,mBACZ,OAD8B0wC,EACzC31C,KAAKyB,aAAM,EAAXk0C,EAAaz+B,UACbja,EACAqB,IAIKmD,CACR,EAACJ,EAEDsB,gBAAA,SAAgBrE,GAAgBmQ,IAAAA,EAC/BzO,KAAA,YAAY4D,oBAAoBtF,EAAS,SAACqZ,GAAoB,OAC7DwX,GAAqBxX,EAAsBlJ,EAAKnO,oBAAoB,EAEtE,EAACe,EAEOyqB,YAAA,SAAY/pB,GAA0B,IAAAoO,EACvC7R,EAAU0B,KAAKiR,cAAcrD,YAAY,CAC9CvK,YAAa,CAACtB,EAAMyG,IAAKzG,EAAM0G,KAC/B9J,YAAUwR,EAAA,CACTjP,KAAMlB,KAAKkB,MAAIiP,EACd3S,EAAkBW,SAAS,EAAIgS,GAEjCpM,QAAS,CAAEL,WAAY3G,EAAY8Q,OAAQ0H,OAAQvY,KAGhDsB,GACH0B,KAAK0C,SAASpE,EAAQ4E,GAAI,CACzBhC,KAAMlB,KAAKkB,KACXqU,OAAQvY,GAGX,EAACqE,EAEOqqB,aAAA,SAAa3pB,GAEpB,GAAK/B,KAAKgpB,SAAV,CAIA,IAAMsG,EAAiBtvB,KAAKyvB,YAAYJ,uBAAuBttB,GAE3DutB,GACHtvB,KAAKiR,cAAcxB,uBAAuB6f,EAAepsB,GAL1D,CAOD,EAAC7B,EAEDyB,oBAAA,SAAoBxE,GAGf0B,KAAKipB,kBAAoB3qB,EAAQ4E,KACpClD,KAAKipB,qBAAkBtnB,EACvB3B,KAAKc,UAAUd,KAAK+U,QAAQpB,QAE9B,EAAC6hC,CAAA,CAlQ+B9vC,CAAQ9F,GC5CnCg2C,GAA2D,CAChE,CAAExwC,IAAK,IAAK67B,SAAU,CAAC,SACvB,CAAE77B,IAAK,IAAK67B,SAAU,CAAC,aAGlB4U,GAA2D,CAChE,CAAEzwC,IAAK,IAAK67B,SAAU,CAAC,OAAQ,UAC/B,CAAE77B,IAAK,IAAK67B,SAAU,CAAC,UAAW,UAClC,CAAE77B,IAAK,IAAK67B,SAAU,CAAC,aAGX6U,GAAkB,SAC9B/zC,EACAg0C,GAEA,IAAMC,EAAgBj0C,EAAMqD,IAAI6wC,cAC1BC,EAAqB,IAAInL,IAC9BhpC,EAAMk/B,SACJryB,IAAI,SAACunC,GAAY,OAAAA,EAAQF,aAAa,GACtClmC,OAAO,SAAComC,GAAO,OAAKA,IAAYH,CAAa,IAIhD,GADoBD,EAAS3wC,IAAI6wC,gBACbD,EACnB,OAAY,EAGb,IAAMI,EAA6B,IAAIrL,IACtCgL,EAAS9U,SAASryB,IAAI,SAACynC,GAAe,OAAKA,EAAgBJ,aAAa,IAGzE,GAAIC,EAAmBzJ,OAAS2J,EAA2B3J,KAC1D,OAAY,EAGb,IAAA75B,IAAwDf,EAAxDe,EAAAC,EAA8BujC,KAA0BvkC,EAAAe,KAAAE,MACvD,IAAKojC,EAAmBxmC,IADCmC,EAAAhN,OAExB,OAAY,EAId,QACD,EAEayxC,gBAMZ,WAAA,SAAAA,EAAYz2C,GAGX02C,IAAAA,EAAAC,EAAAx2C,KANOy2C,2BACAC,EAAAA,KAAAA,6BAMP12C,KAAKy2C,sBAAqCF,OAAhBA,EAAU,MAAP12C,OAAO,EAAPA,EAASuE,MAAImyC,EAAIX,GAC9C51C,KAAK02C,6BAAqBF,EAAU,MAAP32C,OAAO,EAAPA,EAAS2E,MAAIgyC,EAAIX,EAC/C,CAAC,IAAAx0C,EAAAi1C,EAAAh1C,iBAAAD,EAEDs1C,uBAAA,SAAuB50C,GACtB,YAAY00C,sBAAsBG,KAAK,SAACb,UACvCD,GAAgB/zC,EAAOg0C,EAAS,EAElC,EAAC10C,EAEDw1C,uBAAA,SAAuB90C,GACtB,OAAO/B,KAAK02C,sBAAsBE,KAAK,SAACb,GACvC,OAAAD,GAAgB/zC,EAAOg0C,EAAS,EAElC,EAACO,CAAA,CAlBD,YC9DeQ,GAAsBnwB,GACrC,YAAqBhlB,IAAjBglB,GAA+BvH,OAAO0H,SAASH,GAI5ChgB,KAAK6T,IAAI,EAAG7T,KAAK2Y,MAAMqH,IAHtBvH,OAAO2H,iBAIhB,CCQa,IAAAgwB,GACN,OADMA,GAEN,OAFMA,GAGN,OAGMC,GACN,OADMA,GAEH,UCWGC,gBAAqB,WAgBjC,SAAAA,EAAYp3C,GAAkCG,KAftCk3C,kBACAC,EAAAA,KAAAA,yBAGAC,EAAAA,KAAAA,qBACAC,cAAQ,EAAAr3C,KACRs3C,sBAAgB,EAAAt3C,KAChBu3C,qBACS5wB,EAAAA,KAAAA,yBAET6wB,iBAAmB,CAC1BlzC,SAAU,EACVC,SAAU,GAIVvE,KAAK2mB,aAAemwB,GAA6B,MAAPj3C,OAAO,EAAPA,EAAS8mB,aACpD,CAAC,IAAAtlB,EAAA41C,EAAA31C,iBAAAD,EAEDo2C,gBAAA,WACC,OAAWz3C,KAAC2mB,YACb,EAACtlB,EAEDe,SAAA,SAASvC,GAQRG,KAAKk3C,aAAer3C,EAAQq3C,aAC5Bl3C,KAAKm3C,oBAAsBt3C,EAAQs3C,oBACnCn3C,KAAKo3C,SAAWv3C,EAAQu3C,SACxBp3C,KAAKq3C,SAAWx3C,EAAQw3C,SACxBr3C,KAAKs3C,iBAAmBz3C,EAAQy3C,iBAChCt3C,KAAKu3C,gBAAkB13C,EAAQ03C,eAChC,EAACl2C,EAEOq2C,eAAA,WACP,aAAYR,cAAuC,YAAxBl3C,KAAKk3C,cACjC,EAAC71C,EAEDs2C,QAAA,WACC,QAAK33C,KAAK03C,kBAIW13C,KAAK43C,kBAAlBtzC,SACU,CACnB,EAACjD,EAEDw2C,QAAA,WACC,QAAK73C,KAAK03C,kBAIW13C,KAAK43C,kBAAlBrzC,SACU,CACnB,EAAClD,EAED+C,KAAA,WACC,SAAKpE,KAAK23C,YAAc33C,KAAKo3C,WAI7Bp3C,KAAKo3C,WACLp3C,KAAK83C,kBAAkBf,IACZ,GACZ,EAAC11C,EAEDmD,KAAA,WACC,SAAKxE,KAAK63C,YAAc73C,KAAKq3C,WAI7Br3C,KAAKq3C,WACLr3C,KAAK83C,kBAAkBf,OAExB,EAAC11C,EAEDgD,aAAA,WACKrE,KAAKs3C,kBACRt3C,KAAKs3C,mBAGNt3C,KAAKw3C,iBAAmB,CACvBlzC,SAAU,EACVC,SAAU,EAEZ,EAAClD,EAEDu2C,gBAAA,WACC,OAAK53C,KAAKm3C,oBAICn3C,KAACm3C,sBAHJ,CAAE7yC,SAAU,EAAGC,SAAU,EAIlC,EAAClD,EAEDiD,SAAA,WACC,OAAWtE,KAAC43C,kBAAkBtzC,QAC/B,EAACjD,EAEDkD,SAAA,WACC,OAAOvE,KAAK43C,kBAAkBrzC,QAC/B,EAAClD,EAED02C,yCAAA,WACC,GAAK/3C,KAAK03C,iBAAV,CAIA,IAAMM,EAAsBh4C,KAAK43C,kBAEhCI,EAAoB1zC,WAAatE,KAAKw3C,iBAAiBlzC,UACvD0zC,EAAoBzzC,WAAavE,KAAKw3C,iBAAiBjzC,UAEvDvE,KAAK83C,kBAAkBf,GAPxB,CASD,EAAC11C,EAED42C,yBAAA,SAAyBC,GACxB,GAAKl4C,KAAK03C,iBAAV,CAIA,IAAMS,EAAQn4C,KAAK43C,kBAElBO,EAAM7zC,WAAa4zC,EAAO5zC,UAC1B6zC,EAAM5zC,WAAa2zC,EAAO3zC,UAE1BvE,KAAK83C,kBAAkBf,GAPxB,CASD,EAAC11C,EAEDy2C,kBAAA,SAAkBM,GACjB,GAAKp4C,KAAKu3C,gBAAV,CAIA,IAAAc,EAA+Br4C,KAAK43C,kBAA5BtzC,EAAQ+zC,EAAR/zC,SAAUC,EAAQ8zC,EAAR9zC,SAClBvE,KAAKw3C,iBAAmB,CACvBlzC,SAAAA,EACAC,SAAAA,GAGDvE,KAAKu3C,gBAAgB,CACpBa,MAAAA,EACA1R,MAAOsQ,GACPsB,cAAeh0C,EACfi0C,cAAeh0C,GAZhB,CAcD,EAAC0yC,CAAA,CA1JgC,GCYrBuB,gBAaZ,WAAA,SAAAA,EAAY34C,GAAkC8F,IAAAA,EAZtC8yC,KAAAA,KAAAA,iBACAlB,qBAAe,EAAAv3C,KACN2mB,kBAET+xB,EAAAA,KAAAA,YAAyD,CAAA,OACzDC,UAA8B,GAC9BC,KAAAA,yBAAuD,CAAE,OACzDC,yBAAuD,CAAE,EACzDC,KAAAA,kBAAgD,CAAE,OAClDC,UAA8B,GAC9BC,KAAAA,oBAAqB,EAAKh5C,KA0B1Bi5C,gBAAkB,SAACb,GAC1BzyC,EAAK4xC,iBACJ5xC,EAAK4xC,gBAAgB,CACpBa,MAAAA,EACA1R,MAAOsQ,GACPsB,cAAe3yC,EAAKgzC,UAAU7yC,OAC9ByyC,cAAe5yC,EAAKozC,UAAUjzC,QAEjC,OAwBQozC,aAAe,SACtBz0B,EACAzjB,EACA+C,GAEA,GAAK4B,EAAK8yC,OAAQ9yC,EAAKwzC,aAIG,IAAtBxzC,EAAKghB,aAIT,GAAa,WAAT3lB,GA6CJ,GAAa,WAATA,GAA8B,WAATA,EAIzB,GAAa,WAATA,EAAJ,CAiFA,IAPA,IAOwBqS,EAPpB+lC,GAAW,EAETC,EAIA,GACN/lC,EAAAT,EANgBrU,MAAMC,QAAQgmB,GAAOA,EAAM,CAACA,MAMpBpR,EAAAC,KAAAR,MAAE,CAAA,IAAf5P,EAAEmQ,EAAAxO,MACNO,EAAMylC,OAAO3nC,GAGnB,GAAIyC,EAAKkzC,yBAAyB31C,UAC1ByC,EAAKkzC,yBAAyB31C,QAKtC,GAAKyC,EAAK+yC,YAAYtzC,GAAtB,CAKA,IAAMk0C,EAAY3zC,EAAK+yC,YAAYtzC,GAAKU,OAAS,EACjD,GAAIwzC,GAAa,EAAG,CACnB,IAAMC,EAAW5zC,EAAK+yC,YAAYtzC,GAAKk0C,GACvC,IAAKC,EACJ,SAGDF,EAAkBtvC,KAAK,CACtB7G,GAAAA,EACAs2C,QAASF,EACTC,SAAAA,IAED5zC,EAAKmzC,kBAAkB51C,IAAM,EAC7Bk2C,GAAW,CACZ,CAjBA,CAkBD,CAEA,GAAIC,EAAkBvzC,OAAS,EAC9BH,EAAK8zC,mBAAmB,CACvBv2C,GAAIm2C,EAAkB,GAAGn2C,GACzBs2C,QAASH,EAAkB,GAAGG,QAC9BjkC,OAAQ,eACRmkC,SAAU,CAAE1lC,QAASqlC,UAEZA,GAA6B,IAA7BA,EAAkBvzC,OAAc,CAC1C,IAAM6zC,EAAWN,EAAkB,GACnC1zC,EAAK8zC,mBAAmB,CACvBv2C,GAAIy2C,EAASz2C,GACbs2C,QAASG,EAASH,QAClBjkC,OAAQ,UAEV,CAGI6jC,IACHzzC,EAAKozC,UAAUjzC,OAAS,EACxBH,EAAKszC,gBAAgBlC,IA5DtB,KAxEA,CAMC,QAJap1C,IAAZoC,KACA,WAAYA,IACO,QAAnBA,EAAQmF,OAGR,OAWD,IARA,IAQwBiK,EARpBymC,GAAiB,EAEfC,EAIA,GAENzmC,EAAAP,EAPgBrU,MAAMC,QAAQgmB,GAAOA,EAAM,CAACA,MAOpBtR,EAAAC,KAAAN,MAAE,CAAf,IAAA5P,EAAEiQ,EAAAtO,MACZ,GAAIc,EAAKizC,yBAAyB11C,UAC1ByC,EAAKizC,yBAAyB11C,UAC9ByC,EAAKmzC,kBAAkB51C,OAF/B,CAMA,IAAMkC,EAAMylC,OAAO3nC,GACb5E,EAAUqH,EAAK8yC,KAAKqB,mBAAmB52C,GACxC5E,IAIDqH,EAAKmzC,kBAAkB51C,KAC1ByC,EAAK+yC,YAAYtzC,GAAO,UACjBO,EAAKmzC,kBAAkB51C,IAG1ByC,EAAK+yC,YAAYtzC,KACrBO,EAAK+yC,YAAYtzC,GAAO,IAGzBO,EAAK+yC,YAAYtzC,GAAK2E,KAAKzL,GAE3Bu7C,EAAkB9vC,KAAK,CACtB7G,GAAAA,EACAs2C,QAHe7zC,EAAK+yC,YAAYtzC,GAAKU,OAAS,EAI9CyzC,SAAUj7C,IAEXs7C,GAAiB,EAxBjB,CAyBD,CAEA,GAAIC,EAAkB/zC,OAAS,EAC9BH,EAAK8zC,mBAAmB,CACvBv2C,GAAI22C,EAAkB,GAAG32C,GACzBs2C,QAASK,EAAkB,GAAGL,QAC9BjkC,OAAQ,eACRmkC,SAAU,CAAE1lC,QAAS6lC,UAEhB,GAAiC,IAA7BA,EAAkB/zC,OAAc,CAC1C,IAAMi0C,EAAWF,EAAkB,GACnCl0C,EAAK8zC,mBAAmB,CACvBv2C,GAAI62C,EAAS72C,GACbs2C,QAASO,EAASP,QAClBjkC,OAAQ,UAEV,CAEIqkC,IACHj0C,EAAKozC,UAAUjzC,OAAS,EACxBH,EAAKszC,gBAAgBlC,IAIvB,MAzHA,CAMC,QAJap1C,IAAZoC,KACA,WAAYA,IACO,QAAnBA,EAAQmF,QAEWvD,EAAKqzC,mBACxB,OAMD,IAHA,IAGwBnnC,EAFpBmoC,GAAiB,EAErBpnC,EAAAC,EAHgBrU,MAAMC,QAAQgmB,GAAOA,EAAM,CAACA,MAGpB5S,EAAAe,KAAAE,MAAE,CAAf,IAAA5P,EAAE2O,EAAAhN,MACZ,GAAI3B,QAAJ,CAIA,IAAMkC,EAAMylC,OAAO3nC,GACb5E,EAAUqH,EAAK8yC,KAAKqB,mBAAmB52C,GACxC5E,IAIAqH,EAAK+yC,YAAYtzC,KACrBO,EAAK+yC,YAAYtzC,GAAO,IAGzBO,EAAK+yC,YAAYtzC,GAAK2E,KAAKzL,GAC3BqH,EAAK8zC,mBAAmB,CACvBv2C,GAAAA,EACAs2C,QAAS7zC,EAAK+yC,YAAYtzC,GAAKU,OAAS,EACxCyP,OAAQ,WAETykC,GAAiB,EAlBjB,CAmBD,CAEIA,IACHr0C,EAAKozC,UAAUjzC,OAAS,EACxBH,EAAKszC,gBAAgBlC,IAIvB,CA4ID,EAAC/2C,KAEOi6C,aAAe,SAACx1B,GACvB,GAAK9e,EAAK8yC,MAIgB,IAAtB9yC,EAAKghB,eAILhhB,EAAKqzC,mBAMT,IAFA,IAEwBkB,EADpBC,GAAuB,EAC3BC,EAAAvnC,EAFgBrU,MAAMC,QAAQgmB,GAAOA,EAAM,CAACA,MAEpBy1B,EAAAE,KAAAtnC,MAAE,CAAA,IAAf5P,EAAEg3C,EAAAr1C,MACZ,GAAI3B,QAAJ,CAEA,IAAMkC,EAAMylC,OAAO3nC,GAEb5E,EAAUqH,EAAK8yC,KAAKqB,mBAAmB52C,GACxC5E,IAEAqH,EAAK+yC,YAAYtzC,KAAMO,EAAK+yC,YAAYtzC,GAAO,IACpDO,EAAK+yC,YAAYtzC,GAAK2E,KAAKzL,GAEtB67C,IAEJx0C,EAAKozC,UAAUjzC,OAAS,EACxBq0C,GAAuB,GAIxBx0C,EAAK8zC,mBAAmB,CACvBv2C,GAAAA,EACAs2C,QAAS7zC,EAAK+yC,YAAYtzC,GAAKU,OAAS,EACxCyP,OAAQ,WAET5P,EAAKszC,gBAAgBlC,IAtBgB,CAuBtC,CACD,EArSC/2C,KAAK2mB,aAAemwB,SAAsBj3C,SAAAA,EAAS8mB,aACpD,CAAC,IAAAtlB,EAAAm3C,EAAAl3C,UAgnBA,OAhnBAD,EAEDe,SAAA,SAASvC,GAIJG,KAAKy4C,OAAS54C,EAAQ44C,MAKtBz4C,KAAKy4C,OACRz4C,KAAKy4C,KAAK4B,IAAI,SAAUr6C,KAAKk5C,cAC7Bl5C,KAAKy4C,KAAK4B,IAAI,SAAUr6C,KAAKi6C,eAG9Bj6C,KAAKy4C,KAAO54C,EAAQ44C,KACpBz4C,KAAKy4C,KAAK6B,GAAG,SAAUt6C,KAAKk5C,cAC5Bl5C,KAAKy4C,KAAK6B,GAAG,SAAUt6C,KAAKi6C,cAC5Bj6C,KAAKu3C,gBAAkB13C,EAAQ03C,iBAZ9Bv3C,KAAKu3C,gBAAkB13C,EAAQ03C,eAajC,EAACl2C,EAYOo4C,mBAAA,SAAmBpyB,GACA,IAAtBrnB,KAAK2mB,eAIT3mB,KAAK24C,UAAU5uC,KAAKsd,GAChBrnB,KAAK24C,UAAU7yC,OAAS9F,KAAK2mB,cAChC3mB,KAAK24C,UAAUxxB,QAEjB,EAAC9lB,EAEOk5C,mBAAA,SAAmBlzB,GACA,IAAtBrnB,KAAK2mB,eAIT3mB,KAAK+4C,UAAUhvC,KAAKsd,GAChBrnB,KAAK+4C,UAAUjzC,OAAS9F,KAAK2mB,cAChC3mB,KAAK+4C,UAAU5xB,QAEjB,EAAC9lB,EAkPO83C,UAAA,WACP,QAAOn5C,KAAKy4C,MAAoC,YAA7Bz4C,KAAKy4C,KAAKvB,cAC9B,EAAC71C,EAIOm5C,0BAAA,SACPt3C,EACAq2C,GAEA,GAAKv5C,KAAKy4C,KAAV,CAIAz4C,KAAKg5C,oBAAqB,EAC1B,IACKh5C,KAAKy4C,KAAKj/B,WAAWtW,KACxBlD,KAAK64C,yBAAyB31C,IAAM,EACpClD,KAAKy4C,KAAKgC,eAAe,CAACv3C,KAG3BlD,KAAK44C,yBAAyB11C,IAAM,SAC7BlD,KAAK84C,kBAAkB51C,GAC9BlD,KAAKy4C,KAAKiC,YAAY,CAACnB,GACxB,CAAC,QACAv5C,KAAKg5C,oBAAqB,CAC3B,CAdA,CAeD,EAAC33C,EAEDs2C,QAAA,WACC,SAAK33C,KAAKy4C,MAAQz4C,KAAKm5C,cAIhBn5C,KAAK24C,UAAU7yC,OAAS,CAChC,EAACzE,EAEDw2C,QAAA,WACC,SAAK73C,KAAKy4C,MAAQz4C,KAAKm5C,mBAIXJ,UAAUjzC,OAAS,CAChC,EAACzE,EAED+C,KAAA,WAAIqK,IAAAA,OACH,IAAKzO,KAAK23C,UACT,OAAO,EAGR,IAAK33C,KAAKy4C,KACT,SAGD,IAAMkC,EAAiB36C,KAAK24C,UAAU5wB,MACtC,IAAK4yB,EAEJ,OADA36C,KAAKi5C,gBAAgBlC,KACd,EAGR,GAA8B,iBAA1B4D,EAAeplC,OAA2B,CAAAqlC,IAAAA,EACvCC,UAAkBD,EAAAD,EAAejB,iBAAfkB,EAAyB5mC,UAAW,GAC5D,GAA+B,IAA3B6mC,EAAgB/0C,OAEnB,OADA9F,KAAKi5C,gBAAgBlC,OAItB,IAAM+D,EAAcD,EAAgBjsC,IAAI,SAACyY,GAAK,OAAKA,EAAMnkB,EAAE,GAc3D,OAbA43C,EAAYx9B,QAAQ,SAACpO,GACpBT,EAAKoqC,yBAAyB3pC,IAAa,EAC3CT,EAAKqqC,kBAAkB5pC,IAAa,CACrC,GAEAlP,KAAKy4C,KAAKgC,eAAeK,GACzB96C,KAAKu6C,mBAAmB,CACvBr3C,GAAI23C,EAAgB,GAAG33C,GACvBs2C,QAASqB,EAAgB,GAAGrB,QAC5BjkC,OAAQ,eACRmkC,SAAU,CAAE1lC,QAAS6mC,KAEtB76C,KAAKi5C,gBAAgBlC,KACd,CACR,CAEA,GAA8B,iBAA1B4D,EAAeplC,OAA2B,CAAA,IAAAwlC,EACvCC,UAAmBD,EAAAJ,EAAejB,iBAAfqB,EAAyB/mC,UAAW,GAC7D,GAAgC,IAA5BgnC,EAAiBl1C,OAEpB,OADA9F,KAAKi5C,gBAAgBlC,OAItB,IAAMkE,EAAqBD,EACzBpsC,IAAI,SAACyY,UAAUA,EAAMkyB,QAAQ,GAC7BxpC,OAAO,SAACwpC,GAAQ,YAAkB53C,IAAb43C,CAAsB,GAiB7C,OAfI0B,EAAmBn1C,OAAS,IAC/Bk1C,EAAiB19B,QAAQ,SAAC+J,GACzB5Y,EAAKmqC,yBAAyBvxB,EAAMnkB,KAAM,SACnCuL,EAAKqqC,kBAAkBzxB,EAAMnkB,GACrC,GACAlD,KAAKy4C,KAAKiC,YAAYO,IAGvBj7C,KAAKu6C,mBAAmB,CACvBr3C,GAAI83C,EAAiB,GAAG93C,GACxBs2C,QAASwB,EAAiB,GAAGxB,QAC7BjkC,OAAQ,eACRmkC,SAAU,CAAE1lC,QAASgnC,KAEtBh7C,KAAKi5C,gBAAgBlC,MAEtB,CAEA,IAAM7zC,EAAKy3C,EAAez3C,GACpBiP,EAAQwoC,EAAenB,QAEvBp0C,EAAMylC,OAAO3nC,GACbwjC,EAAQ1mC,KAAK04C,YAAYtzC,GAC/B,IAAKshC,GAA0B,IAAjBA,EAAM5gC,OAEnB,OADA9F,KAAKi5C,gBAAgBlC,OAKtB,IAAMmE,EAAev0C,KAAK4T,IAAIpI,EAAOu0B,EAAM5gC,OAAS,GAIpD,IADsB9F,KAAKy4C,KAAKj/B,WAAWtW,GACvB,CACnB,IAAMi4C,EAAoBzU,EAAMwU,GAChC,OAAKC,GAILn7C,KAAK44C,yBAAyB11C,IAAM,cACxB41C,kBAAkB51C,GAC9BlD,KAAKy4C,KAAKiC,YAAY,CAACS,IAGvBn7C,KAAKu6C,mBAAmB,CACvBr3C,GAAAA,EACAs2C,QAAS0B,EACT3lC,OAAQ,SACRgkC,SAAU4B,IAEXn7C,KAAKi5C,gBAAgBlC,SAdpB/2C,KAAKi5C,gBAAgBlC,OAgBvB,CAGA,GAAImE,GAAgB,EAanB,OAXAl7C,KAAKu6C,mBAAmB,CAAEr3C,GAAAA,EAAIs2C,QAAS,EAAGjkC,OAAQ,WAElDvV,KAAK64C,yBAAyB31C,IAAM,EACpClD,KAAK84C,kBAAkB51C,IAAM,EAC7BlD,KAAKy4C,KAAKgC,eAAe,CAACv3C,IAG1BlD,KAAK24C,UAAY34C,KAAK24C,UAAU5oC,OAC/B,SAACqrC,GAAe,OAAAA,EAAWl4C,KAAOA,CAAE,GAErClD,KAAKi5C,gBAAgBlC,KACV,EAIZ,IAAMsE,EAAe3U,EAAMwU,GACrBI,EAAmB5U,EAAMwU,EAAe,GAe9C,OAZIG,GACHr7C,KAAKu6C,mBAAmB,CACvBr3C,GAAAA,EACAs2C,QAAS0B,EACT3B,SAAU8B,EACV9lC,OAAQ,WAIVvV,KAAKw6C,0BAA0Bt3C,EAAIo4C,GACnC5U,EAAM5gC,OAASo1C,EACfl7C,KAAKi5C,gBAAgBlC,KACd,CACR,EAAC11C,EAEDmD,KAAA,eAAIqL,EAAA7P,KACH,IAAKA,KAAK63C,UACT,SAGD,IAAK73C,KAAKy4C,KACT,OAAY,EAGb,IAAM8C,EAAuBv7C,KAAK+4C,UAAUhxB,MACpC7kB,EAA4Cq4C,EAA5Cr4C,GAAIs2C,EAAwC+B,EAAxC/B,QAASD,EAA+BgC,EAA/BhC,SAAUhkC,EAAqBgmC,EAArBhmC,OAAQmkC,EAAa6B,EAAb7B,SAEvC,GAAe,iBAAXnkC,EAA2B,CAC9B,IAAMimC,GAAkB9B,MAAAA,OAAAA,EAAAA,EAAU1lC,UAAW,GAC7C,GAA+B,IAA3BwnC,EAAgB11C,OAEnB,OADA9F,KAAKi5C,gBAAgBlC,KACT,EAGb,IAAM0E,EAAoBD,EACxB5sC,IAAI,SAACyY,GAAK,OAAKA,EAAMkyB,QAAQ,GAC7BxpC,OAAO,SAAC2rC,eAA0C/5C,IAArB+5C,CAA8B,GAgB7D,OAdID,EAAkB31C,OAAS,IAC9B01C,EAAgBl+B,QAAQ,SAAC+J,GACxBxX,EAAK+oC,yBAAyBvxB,EAAMnkB,KAAM,CAC3C,GACAlD,KAAKy4C,KAAKiC,YAAYe,IAGvBz7C,KAAKy5C,mBAAmB,CACvBv2C,GAAIs4C,EAAgB,GAAGt4C,GACvBs2C,QAASgC,EAAgB,GAAGhC,QAC5BjkC,OAAQ,eACRmkC,SAAU,CAAE1lC,QAASwnC,KAEtBx7C,KAAKi5C,gBAAgBlC,KACd,CACR,CAEA,GAAe,iBAAXxhC,EAA2B,CAC9B,IAAMslC,GAA0B,MAARnB,OAAQ,EAARA,EAAU1lC,UAAW,GAC7C,GAA+B,IAA3B6mC,EAAgB/0C,OAEnB,OADA9F,KAAKi5C,gBAAgBlC,KACd,EAGR,IAAM+D,EAAcD,EAAgBjsC,IAAI,SAACyY,GAAK,OAAKA,EAAMnkB,EAAE,GAe3D,OAbA43C,EAAYx9B,QAAQ,SAACpO,GACpBW,EAAKgpC,yBAAyB3pC,IAAa,EAC3CW,EAAKipC,kBAAkB5pC,IAAa,CACrC,GAEAlP,KAAKy4C,KAAKgC,eAAeK,GACzB96C,KAAKy5C,mBAAmB,CACvBv2C,GAAI23C,EAAgB,GAAG33C,GACvBs2C,QAASqB,EAAgB,GAAGrB,QAC5BjkC,OAAQ,eACRmkC,SAAU,CAAE1lC,QAAS6mC,KAEtB76C,KAAKi5C,gBAAgBlC,KACV,CACZ,CAEA,IAAM3xC,EAAMylC,OAAO3nC,GACbwjC,EAAQ1mC,KAAK04C,YAAYtzC,KAASpF,KAAK04C,YAAYtzC,GAAO,IAGhE,GAAe,WAAXmQ,EAOH,OANAvV,KAAK64C,yBAAyB31C,IAAM,EACpClD,KAAK84C,kBAAkB51C,IAAM,EAC7BlD,KAAKy4C,KAAKgC,eAAe,CAACv3C,IAE1BlD,KAAKy5C,mBAAmB,CAAEv2C,GAAAA,EAAIs2C,QAAAA,EAASjkC,OAAQ,WAC/CvV,KAAKi5C,gBAAgBlC,OAItB,GAAIyC,GAAW,EAAG,CAEjB,IAAMmC,EAAUjV,EAAM,GACtB,QAAKiV,IAGL37C,KAAK44C,yBAAyB11C,IAAM,EACpClD,KAAKy4C,KAAKiC,YAAY,CAACiB,IAGvB37C,KAAKy5C,mBAAmB,CAAEv2C,GAAAA,EAAIs2C,QAAS,EAAGjkC,OAAQ,WAClDvV,KAAKi5C,gBAAgBlC,KACV,EACZ,CAGA,IAAM6E,EAAOrC,GAAY7S,EAAM8S,GAC/B,QAAKoC,IAKDlV,EAAM5gC,SAAW0zC,EACpB9S,EAAM38B,KAAK6xC,IAEXlV,EAAM8S,GAAWoC,EACjBlV,EAAM5gC,OAAS0zC,EAAU,GAM1Bx5C,KAAKw6C,0BAA0Bt3C,EAAI04C,GAGnC57C,KAAKy5C,mBAAmB,CAAEv2C,GAAAA,EAAIs2C,QAAAA,EAASjkC,OAAQ,WAC/CvV,KAAKi5C,gBAAgBlC,KACV,EACZ,EAAC11C,EAEDgD,aAAA,WACC,IAAMw3C,EAAiE,CAAE,EAEzE,GAAI77C,KAAKy4C,OAASz4C,KAAKm5C,YAEtB,IADA,IACsC2C,EAAtCC,EAAAlpC,EADyB7S,KAAKy4C,KAAKuD,iBACGF,EAAAC,KAAAjpC,MAAE,CAA7B,IAAAxU,EAAOw9C,EAAAj3C,MAEjBg3C,EAAoBhR,OADFvsC,EAAQ4E,KACe,CAAC5E,EAC3C,CAGD0B,KAAK04C,YAAcmD,EACnB77C,KAAK24C,UAAY,GACjB34C,KAAK44C,yBAA2B,CAAE,EAClC54C,KAAK64C,yBAA2B,CAAA,EAChC74C,KAAK84C,kBAAoB,GACzB94C,KAAK+4C,UAAY,EAClB,EAAC13C,EAEDiD,SAAA,WACC,OAAOtE,KAAK24C,UAAU7yC,MACvB,EAACzE,EAEDkD,SAAA,WACC,YAAYw0C,UAAUjzC,MACvB,EAAC0yC,CAAA,CAlnBD,GCzCYyD,gBAOZ,WAAA,SAAAA,EAAYp8C,OAA4Cq8C,EAAAl8C,KANhDm8C,eACAC,EAAAA,KAAAA,kBACAC,EAAAA,KAAAA,6BACA9E,qBAAe,EAAAv3C,KACfs8C,6BAGP,EAAAt8C,KAAKm8C,UAAYt8C,EAAQs8C,UACzBn8C,KAAKo8C,aAAev8C,EAAQu8C,aAC5Bp8C,KAAKq8C,iBAAmBx8C,EAAQw8C,iBAChCr8C,KAAKu3C,gBAAkB13C,EAAQ03C,gBAC/Bv3C,KAAKs8C,wBAC2B,OADJJ,EAC3Br8C,EAAQy8C,yBAAuBJ,EAAK,WAAA,QAAU,CAChD,CAAC,IAAA76C,EAAA46C,EAAA36C,iBAAAD,EAEDk7C,uBAAA,SAAuBhQ,GACjBvsC,KAAKs8C,2BAINt8C,KAAKu3C,iBACRv3C,KAAKu3C,gBAAgB,CACpBa,MAAO7L,EAAO6L,MACd1R,MAAO6F,EAAO7F,MACdpiC,SAAUioC,EAAO+L,cACjB/zC,SAAUgoC,EAAOgM,eAGpB,EAACl3C,EAEOm7C,eAAA,WACP,OAAOj+C,QAAQyB,KAAKo8C,cAAgBp8C,KAAKo8C,aAAazE,UACvD,EAACt2C,EAEOo7C,eAAA,WACP,OAAOl+C,QAAQyB,KAAKo8C,cAAgBp8C,KAAKo8C,aAAavE,UACvD,EAACx2C,EAEOq7C,mBAAA,eAAkBC,EAAAC,EACzB,OAAI58C,KAAKq8C,oBAAsBM,OAAJA,EAAI38C,KAAKm8C,YAALQ,EAAgBhF,UACvCX,GAGJh3C,KAAKw8C,iBACDxF,GAGJ4F,OAAJA,EAAI58C,KAAKm8C,YAALS,EAAgBjF,UACZX,QADR,CAKD,EAAC31C,EAEOw7C,mBAAA,WAAkB,IAAAC,EAAAC,EACzB,OAAI/8C,KAAKq8C,oBAAoC,OAAlBS,EAAI98C,KAAKm8C,YAALW,EAAgBjF,UACvCb,GAGJh3C,KAAKy8C,iBACDzF,GAGU,OAAlB+F,EAAI/8C,KAAKm8C,YAALY,EAAgBlF,UACZb,QADR,CAKD,EAAC31C,EAEDs2C,QAAA,WACC,YAAqCh2C,IAA9B3B,KAAK08C,oBACb,EAACr7C,EAEDw2C,QAAA,WACC,YAAqCl2C,IAA9B3B,KAAK68C,oBACb,EAACx7C,EAED+C,KAAA,WACC,IAAMsiC,EAAQ1mC,KAAK08C,qBACnB,QAAKhW,IAIDA,IAAUsQ,KACFh3C,KAACm8C,WAAYn8C,KAAKm8C,UAAU/3C,UAGpCpE,KAAKo8C,eAAgBp8C,KAAKo8C,aAAazE,YAC/B33C,KAACo8C,aAAah4C,OAI3B,EAAC/C,EAEDmD,KAAA,WACC,IAAMkiC,EAAQ1mC,KAAK68C,qBACnB,QAAKnW,IAIDA,IAAUsQ,KACFh3C,KAACm8C,WAAYn8C,KAAKm8C,UAAU33C,UAGpCxE,KAAKo8C,eAAgBp8C,KAAKo8C,aAAavE,YAC/B73C,KAACo8C,aAAa53C,OAI3B,EAACnD,EAEDgD,aAAA,WACKrE,KAAKm8C,WACRn8C,KAAKm8C,UAAU93C,eAGZrE,KAAKo8C,cACRp8C,KAAKo8C,aAAa/3C,cAEpB,EAAChD,EAED27C,kCAAA,WACKh9C,KAAKo8C,aACRp8C,KAAKu8C,uBAAuB,CAC3BnE,MAAOrB,GACPuB,cAAet4C,KAAKo8C,aAAa93C,WACjCi0C,cAAev4C,KAAKo8C,aAAa73C,WACjCmiC,MAAOsQ,KAKLh3C,KAAKm8C,WACRn8C,KAAKu8C,uBAAuB,CAC3BnE,MAAOrB,GACPuB,cAAet4C,KAAKm8C,UAAU73C,WAC9Bi0C,cAAev4C,KAAKm8C,UAAU53C,WAC9BmiC,MAAOsQ,IAGV,EAACiF,CAAA,CAvID,kCCmIA,WAAA,SAAAgB,EAAYp9C,OAUXq9C,EAAAC,EAAAC,EAAAC,EAAA13C,EAAA3F,KAAAA,KAhCOs9C,YAGAC,EAAAA,KAAAA,kBACAC,cAAQ,EAAAx9C,KACRy9C,UAAW,OACXC,YAAM,EAAA19C,KACN29C,qBAQAC,EAAAA,KAAAA,0BACAC,EAAAA,KAAAA,wBAAyB,EAAK79C,KAC9B89C,8BACAC,EAAAA,KAAAA,4BACAC,qBAAe,EAAAh+C,KACfi+C,yBAaP,EAAAj+C,KAAKw9C,SAAW39C,EAAQq+C,QACxBl+C,KAAK49C,qBAAuB,GAG5B,IAAMO,EAA2BjB,MAAPr9C,GAAAq9C,OAAOA,EAAPr9C,EAAS6pB,eAATwzB,EAAAA,EAAmBf,UACzCgC,IACHn+C,KAAK+9C,gBAAkBI,GAGxB,IAAML,EAAkC,MAAPj+C,GAAiB,OAAVs9C,EAAPt9C,EAAS6pB,eAAQ,EAAjByzB,EAAmBiB,kBAChDN,IACH99C,KAAK89C,yBAA2BA,GAGjC99C,KAAK69C,uBAAyBt/C,QAAe,MAAPsB,UAAOu9C,EAAPv9C,EAAS6pB,iBAAT0zB,EAAmBhB,cACzD,IAAMiC,EAA8B,MAAPx+C,GAAiB,OAAVw9C,EAAPx9C,EAAS6pB,eAAQ,EAAjB2zB,EAAmBjB,aAEhDp8C,KAAKu9C,MAAQ,IAAI/Y,GAGjB,IAAM8Z,EAAuB,IAAIvT,IAG3BwT,EAAW1+C,EAAQ2+C,MAAMlmB,OAE5B,SAACmmB,EAASC,GACZ,GAAIJ,EAAqB5uC,IAAIgvC,EAAYx9C,MACxC,MAAU,IAAAe,MAA4By8C,sBAAAA,EAAYx9C,KAAI,kBAIvD,OAFAo9C,EAAqBtT,IAAI0T,EAAYx9C,MACrCu9C,EAAQC,EAAYx9C,MAAQw9C,EACrBD,CACR,EAAG,CAAA,GAGGE,EAAW5qC,OAAOg5B,KAAKwR,GAG7B,GAAwB,IAApBI,EAAS74C,OACZ,MAAM,IAAI7D,MAAM,qBAIjB08C,EAASrhC,QAAQ,SAACpc,GACbq9C,EAASr9C,GAAMF,OAAS9B,EAAUkH,QAItCT,EAAKi4C,qBAAqB7zC,KAAK7I,EAChC,GAEAlB,KAAKs9C,OAAMl8C,EAAQm9C,CAAAA,EAAAA,GAAUK,OAAQ5+C,KAAKu9C,QAC1Cv9C,KAAK29C,gBAAkB,CACtBpR,OAAQ,GACR7M,OAAQ,GACRhC,SAAU,GACVnpB,OAAQ,GACRsqC,MAAO,GACP33B,QAAS,IAEVlnB,KAAK09C,OAAS,IAAIlS,GAGhB,CACDC,UAAS5rC,EAAQ4rC,QACjBhoC,WAAY5D,EAAQ4D,WAAa5D,EAAQ4D,gBAAa9B,IAGvD,IAAMm9C,EAAa,SAClBr6B,GAKA,IAAMs6B,EAAkC,GAElCC,EAAYr5C,EAAK+3C,OAAO7Q,UAAU98B,OAAO,SAAC8P,GAC/C,OAAI4E,EAAIrhB,SAASyc,EAAE3c,MAClB67C,EAAQh1C,KAAK8V,IACD,EAId,GAEA,MAAO,CAAEk/B,QAAAA,EAASC,UAAAA,EACnB,EAEMt8C,EAAW,SAACoB,EAAuBC,OAA4Bk7C,EAC/Dt5C,EAAK83C,WAIV93C,EAAKg4C,gBAAgBppC,OAAO+I,QAAQ,SAACy2B,GACpCA,EAASjwC,EAAYC,EACtB,UAEAk7C,EAAAt5C,EAAKs4C,sBAALgB,EAA0BjC,oCAC3B,EAEMz6C,EAAqE,SAC1EkiB,EACA1iB,EACAgC,GAEA,GAAK4B,EAAK83C,SAAV,CAIA93C,EAAKg4C,gBAAgBpR,OAAOjvB,QAAQ,SAACy2B,GACpCA,EAAStvB,EAAK1iB,EAAOgC,EACtB,GAEA4B,EAAKu5C,kDAEL,IAAAC,EAA+BL,EAAWr6B,GAAlCs6B,EAAOI,EAAPJ,QAASC,EAASG,EAATH,UAEH,WAAVj9C,EACH4D,EAAK63C,SAAS4B,OACb,CACC1pC,QAASqpC,EACTM,WAAY,GACZL,UAAAA,EACA/0B,QAAS,IAEVtkB,EAAK25C,iBAEc,WAAVv9C,EACV4D,EAAK63C,SAAS4B,OACb,CACC1pC,QAAS,GACT2pC,WAAY,GACZL,UAAAA,EACA/0B,QAAS80B,GAEVp5C,EAAK25C,iBAEc,WAAVv9C,EACV4D,EAAK63C,SAAS4B,OACb,CAAE1pC,QAAS,GAAI2pC,WAAY56B,EAAKu6B,UAAAA,EAAW/0B,QAAS,IACpDtkB,EAAK25C,iBAEc,YAAVv9C,GACV4D,EAAK63C,SAAS4B,OACb,CAAE1pC,QAAS,GAAI2pC,WAAY,GAAIL,UAAAA,EAAW/0B,QAAS,IACnDtkB,EAAK25C,gBAtCP,CAyCD,EAEM98C,EAAW,SAACyB,GACjB,GAAK0B,EAAK83C,SAAV,CAIA93C,EAAKg4C,gBAAgBje,OAAOpiB,QAAQ,SAACy2B,GACpCA,EAAS9vC,EACV,GAEA,IAAAs7C,EAA+BT,EAAW,CAAC76C,IAE3C0B,EAAK63C,SAAS4B,OACb,CAAE1pC,QAAS,GAAI2pC,WAAY,GAAIL,UAHNO,EAATP,UAG0B/0B,QAH5Bs1B,EAAPR,SAIPp5C,EAAK25C,gBAVN,CAYD,EAEM78C,EAAa,SAACuB,GACnB,GAAK2B,EAAK83C,SAAV,CAIA93C,EAAKg4C,gBAAgBjgB,SAASpgB,QAAQ,SAACy2B,GACtCA,EAAS/vC,EACV,GAEA,IAAAw7C,EAA+BV,EAAW,CAAC96C,IAAnC+6C,EAAOS,EAAPT,QAKJA,GACHp5C,EAAK63C,SAAS4B,OACb,CACC1pC,QAAS,GACT2pC,WAAY,GACZL,UAVuBQ,EAATR,UAWd/0B,QAAS80B,GAEVp5C,EAAK25C,gBAnBP,CAsBD,EAGAvrC,OAAOg5B,KAAK/sC,KAAKs9C,QAAQhgC,QAAQ,SAACmiC,GAAU,IAAAC,EAC3C/5C,EAAK23C,OAAOmC,GAAQr9C,SAAS,CAC5BlB,KAAMu+C,EACNh/C,MAAOkF,EAAK+3C,OACZ58C,UAAW6E,EAAK63C,SAAS18C,UAAU8zC,KAAKjvC,EAAK63C,UAC7C38C,QAAS8E,EAAK63C,SAAS38C,QAAQ+zC,KAAKjvC,EAAK63C,UACzC58C,UAAW+E,EAAK63C,SAAS58C,UAAUg0C,KAAKjvC,EAAK63C,UAC7C78C,qBAAsBgF,EAAK63C,SAAS78C,qBAAqBi0C,KACxDjvC,EAAK63C,UAENj7C,SAAUA,EACVC,SAAUA,EACVC,WAAYA,EACZC,SAAUA,EACVpC,oBAAqBqF,EAAK63C,SAASxJ,yBACnCzzC,qBAAsBm/C,OAAFA,EAAE/5C,EAAKo4C,kBAAgC,MAArC2B,EAAsBjI,qBAAe,EAArCiI,EAAsBjI,mBAE9C,GAEIz3C,KAAK69C,wBAA0BQ,IAClCr+C,KAAKg+C,gBAAkBK,EACvBA,EAAqBj8C,SAAS,CAC7Bq2C,KAAMz4C,KACNu3C,gBAAiB,SAACoI,GAAiB,IAAAC,EACV,OAAxBA,EAAAj6C,EAAKs4C,sBAAL2B,EAA0BrD,uBAAuBoD,EAClD,KAIE3/C,KAAK+9C,iBACR/9C,KAAK+9C,gBAAgB37C,SAAS,CAC7B80C,aAAc,WAAF,OAAQvxC,EAAKuxC,cAAc,EACvCC,oBAAqB,WAAF,OAAQxxC,EAAKk6C,wBAAwB,EACxDzI,SAAU,WACLzxC,EAAK43C,MAAMn5C,MACduB,EAAK43C,MAAMn5C,MAEb,EACAizC,SAAU,WACL1xC,EAAK43C,MAAM/4C,MACdmB,EAAK43C,MAAM/4C,MAEb,EACA8yC,iBAAkB,WACjB,IAAMwI,EAAuBn6C,EAAK43C,MAE9BuC,EAAqBz7C,cACxBy7C,EAAqBz7C,cAEvB,EACAkzC,gBAAiB,SAACoI,GAAiB,IAAAI,SAClCA,EAAAp6C,EAAKs4C,sBAAL8B,EAA0BxD,uBAAuBoD,EAClD,IAIF3/C,KAAKi+C,oBAAsB,IAAIhC,GAA6B,CAC3DE,UAAWn8C,KAAK+9C,gBAChB3B,aAAcp8C,KAAKg+C,gBACnB3B,iBAAkB,WAAM,MAAwB,YAAxB12C,EAAKuxC,cAA4B,EACzDK,gBAAiB,SAACoI,GACjBh6C,EAAKg4C,gBAAgBz2B,QAAQ5J,QAAQ,SAACy2B,GACrCA,EAAS4L,EACV,EACD,EACArD,wBAAyB,WAAF,OAAQ32C,EAAK83C,QAAQ,GAE9C,CAAC,IAAAp8C,EAAA47C,EAAA37C,iBAAAD,EAEO2+C,aAAA,WACP,IAAKhgD,KAAKy9C,SACT,UAAUx7C,MAAM,4BAElB,EAACZ,EAEO4+C,+BAAA,SACPl+C,GAEA,IAAK/B,KAAK+9C,kBAAoB/9C,KAAK69C,uBAClC,SAGD,IAAK79C,KAAK89C,yBACT,SAGD,IAAMoC,EACLlgD,KAAK89C,yBAAyBnH,uBAAuB50C,GAChDo+C,EACLngD,KAAK89C,yBAAyBjH,uBAAuB90C,GAEtD,GAAIm+C,EAAgB,CACnB,IAAKlgD,KAAK23C,UACT,SAGD,IAAMyI,EAAUpgD,KAAKoE,OAIrB,OAHIg8C,GACHr+C,EAAMu/B,iBAEA8e,CACR,CAEA,GAAID,EAAgB,CACnB,IAAKngD,KAAK63C,UACT,SAGD,IAAMwI,EAAUrgD,KAAKwE,OAIrB,OAHI67C,GACHt+C,EAAMu/B,iBAEA+e,CACR,CAEA,OAAY,CACb,EAACh/C,EAEOw+C,uBAAA,WAWP,MAAO,CAAEv7C,SATRtE,KAAKu9C,MAAMj5C,UAA2C,mBAApBtE,KAACu9C,MAAMj5C,SACtCtE,KAAKu9C,MAAMj5C,WACX,EAOeC,SAJlBvE,KAAKu9C,MAAMh5C,UAA2C,mBAApBvE,KAACu9C,MAAMh5C,SACtCvE,KAAKu9C,MAAMh5C,WACX,EAGL,EAAClD,EAEO69C,gDAAA,WACFl/C,KAAK+9C,iBAIV/9C,KAAK+9C,gBAAgBhG,0CACtB,EAAC12C,EAEOi/C,gCAAA,SAAgCpI,GAIlCl4C,KAAK+9C,iBAIV/9C,KAAK+9C,gBAAgB9F,yBAAyBC,EAC/C,EAAC72C,EAEOi+C,cAAA,WAAa7wC,IAAAA,OACd8xC,EAEF,CAAA,EAEEC,EAAmBxgD,KAAK49C,qBAAqBx6C,SAASpD,KAAKu9C,MAAMr8C,MACpElB,KAAKu9C,MAAMr8C,UACXS,EAkBH,OAhBAoS,OAAOg5B,KAAK/sC,KAAKs9C,QAAQhgC,QAAQ,SAACpc,GACjCq/C,EAAWr/C,GAAQ,SAAC5C,GAEnB,OACCkiD,GACAliD,EAAQK,WAAWxB,EAAkBC,UAE9BqR,EAAK6uC,OAAOkD,GAAkBtqC,aAAa0+B,KACjDnmC,EAAK6uC,OAAOkD,GADN/xC,CAELnQ,GAIImQ,EAAK6uC,OAAOp8C,GAAMgV,aAAa0+B,KAAKnmC,EAAK6uC,OAAOp8C,GAAhDuN,CAAuDnQ,EAC/D,CACD,GACOiiD,CACR,EAACl/C,EAEOo/C,mBAAA,SAAkB1zC,EAQzBlN,GAA2B,IAN1B2I,EAAGuE,EAAHvE,IACAC,EAAGsE,EAAHtE,IAOKpI,EACLR,QAAuC8B,IAA5B9B,EAAQQ,gBAChBR,EAAQQ,gBACR,GAEEqgD,GACL7gD,QAA4C8B,IAAjC9B,EAAQ6gD,sBAChB7gD,EAAQ6gD,qBAGNC,KACL9gD,QAA8C8B,IAAnC9B,EAAQ8gD,yBAChB9gD,EAAQ8gD,uBAGNC,KACL/gD,QAA8C8B,IAAnC9B,EAAQ+gD,yBAChB/gD,EAAQ+gD,uBAGNC,KACLhhD,QAA2C8B,IAAhC9B,EAAQghD,sBAChBhhD,EAAQghD,oBAGNC,KACLjhD,QAA4C8B,IAAjC9B,EAAQihD,uBAChBjhD,EAAQihD,qBAGNlgD,EAAYZ,KAAKw9C,SAAS58C,UAAUg0C,KAAK50C,KAAKw9C,UAC9C38C,EAAUb,KAAKw9C,SAAS38C,QAAQ+zC,KAAK50C,KAAKw9C,UAE1CuD,EAAalgD,EAAQ2H,EAAKC,GAE1BwU,EAAOhB,GAAoB,CAChCrb,UAAAA,EACAsb,MAAO6kC,EACP1gD,gBAAAA,IAKD,OAFiBL,KAAK09C,OAAOxgC,OAAOD,GAGlClN,OAAO,SAACzR,GACR,GACCoiD,IACCpiD,EAAQK,WAAWxB,EAAkBE,YACrCiB,EAAQK,WAAWxB,EAAkBI,kBAEtC,SAGD,GACCojD,GACAriD,EAAQK,WAAWnB,EAAkBM,kBAErC,OAAO,EAGR,GACC+iD,GACAviD,EAAQK,WAAWnB,EAAkBI,eAErC,OAAO,EAGR,GACCgjD,GACAtiD,EAAQK,WAAWnB,EAAkBE,mBAErC,OAAO,EAGR,GACCojD,GACAxiD,EAAQK,WAAWnB,EAAkBK,gBAErC,OAAO,EAGR,GAA8B,UAA1BS,EAAQ6E,SAASnC,KAAkB,CACtC,IAAMggD,EAAmB1iD,EAAQ6E,SAASE,YACpC49C,EAAUpgD,EAAQmgD,EAAiB,GAAIA,EAAiB,IAE9D,OADiBpoC,GAAkBmoC,EAAYE,GAC7B5gD,CACnB,IAAqC,eAA1B/B,EAAQ6E,SAASnC,KAAuB,CAGlD,IAFA,IAAMqC,EAA0B/E,EAAQ6E,SAASE,YAExCwG,EAAI,EAAGA,EAAIxG,EAAYyC,OAAS,EAAG+D,IAAK,CAChD,IAAMI,EAAQ5G,EAAYwG,GACpBksB,EAAY1yB,EAAYwG,EAAI,GAOlC,GANuBgrB,GACtBksB,EACAlgD,EAAQoJ,EAAM,GAAIA,EAAM,IACxBpJ,EAAQk1B,EAAU,GAAIA,EAAU,KAGZ11B,EACpB,OAAW,CAEb,CACA,QACD,CAMC,GAL4B6zB,GAC3B,CAAC1rB,EAAKC,GACNnK,EAAQ6E,SAASE,aAIjB,SAGD,GAAW,MAAPxD,GAAAA,EAASqhD,qCAGZ,IAFA,IAEwBrvC,EAAxBe,EAAAC,EAF4BvU,EAAQ6E,SAASE,eAErBwO,EAAAe,KAAAE,MACvB,IADyB,IAAf2hB,EAAI5iB,EAAAhN,MACLgF,EAAI,EAAGA,EAAI4qB,EAAK3uB,OAAS,EAAG+D,IAAK,CACzC,IAAMI,EAAQwqB,EAAK5qB,GACbksB,EAAYtB,EAAK5qB,EAAI,GAErBs3C,EAAiBtgD,EAAQoJ,EAAM,GAAIA,EAAM,IACzCm3C,EAAevgD,EAAQk1B,EAAU,GAAIA,EAAU,IAQrD,GANuBlB,GACtBksB,EACAI,EACAC,GAGoB/gD,EACpB,OAAO,CAET,CAIF,QAEF,GACCuO,IAAI,SAACtQ,GACL,GAAKuB,MAAAA,IAAAA,EAASwhD,qCACb,OAAO/iD,EAGR,IAAI+E,EACJ,GAA8B,YAA1B/E,EAAQ6E,SAASnC,KACpBqC,EAAc/E,EAAQ6E,SAASE,YAAY,GAAG2O,MAAM,GAAI,OAC9C1T,IAA0B,eAA1BA,EAAQ6E,SAASnC,KAI3B,OAAO1C,EAHP+E,EAAc/E,EAAQ6E,SAASE,WAIhC,CAOA,IALA,IAEIm0B,EAFAgG,GAAgB,EAChB1b,EAAkB5V,SAIbrC,EAAI,EAAGA,EAAIxG,EAAYyC,OAAQ+D,IAAK,CAC5C,IAAMkC,EAAa1I,EAAYwG,GACzBlC,EAAWiR,GAChB/X,EAAQkL,EAAW,GAAIA,EAAW,IAClCg1C,GAGGp5C,EAAWma,IACd0b,EAAe3zB,EACfiY,EAAkBna,EAClB6vB,EAAoBzrB,EAEtB,CAQA,OANAzN,EAAQK,WAAW2iD,8BAAgC9jB,EACnDl/B,EAAQK,WAAW4iD,sCAClBz/B,EACDxjB,EAAQK,WAAW6iD,mCAClBl7C,EAA4BkxB,EAAoB,CAAChvB,EAAKC,IAEhDnK,CACR,EACF,EAAC+C,EAEOogD,qBAAA,SAAqBC,YAAAA,IAAAA,OAAiC//C,GAC7D,IAAMggD,EAAkB3hD,KAAK4hD,cAAc,CAC1CC,oBAAoB,EACpBH,WAAAA,IAGD,IAAKC,EACJ,MAAU,IAAA1/C,MAAM,sCAGjB,OAAO0/C,CACR,EAACtgD,EAEOugD,cAAA,SAAa3zC,GACpB,IAAA4zC,EAAkB5zC,EAAlB4zC,mBACAH,EAAUzzC,EAAVyzC,WAKA1hD,KAAKggD,eACL,IAaI8B,EAbEpD,EAAc1+C,KAAK+hD,UAEzB,GAAyC,IAArC/hD,KAAK49C,qBAAqB93C,OAC7B,OAAO,KAGR,QACgBnE,IAAf+/C,IACC1hD,KAAK49C,qBAAqBx6C,SAASs+C,GAEpC,MAAM,IAAIz/C,MAAK,0CAA2Cy/C,GAyB3D,OAlBCI,OADkBngD,IAAf+/C,EACSA,EAGJ1hD,KAAK49C,qBAAqBx6C,SAASs7C,GAC/BA,EAIA1+C,KAAK49C,qBAAqB,GAInCiE,GAAsBnD,IAAgBoD,GACzC9hD,KAAKgiD,QAAQF,GAGD9hD,KAAKs9C,OAAOwE,EAG1B,EAACzgD,EAEO4gD,kBAAA,SAAkB3jD,GACzB,OAAOC,QACND,EAAQK,WAAWxB,EAAkBE,YACrCiB,EAAQK,WAAWxB,EAAkBI,kBACrCe,EAAQK,WAAWnB,EAAkBM,mBACrCQ,EAAQK,WAAWnB,EAAkBK,gBAEvC,EAACwD,EAYD6gD,cAAA,SACChhD,EACAO,GAGA,GADAzB,KAAKggD,gBACAhgD,KAAKs9C,OAAOp8C,GAChB,UAAUe,MAAM,kCAIhBjC,KAAKs9C,OAAOp8C,GAAqCO,OAASA,CAC5D,EAACJ,EASD8gD,kBAAA,SACCjhD,EACArB,GAGA,GADAG,KAAKggD,gBACAhgD,KAAKs9C,OAAOp8C,GAChB,UAAUe,MAAM,kCAGjBjC,KAAKs9C,OAAOp8C,GAAMC,cACjBtB,EAEF,EAACwB,EAOD26C,YAAA,WAEC,YAAY0B,OAAO7Q,SACpB,EAACxrC,EAODy4C,mBAAA,SAAmB52C,GAClB,GAAKlD,KAAK09C,OAAOhuC,IAAIxM,GAIrB,OAAOlD,KAAK09C,OAAO9Q,KAAK1pC,EACzB,EAAC7B,EAMDsmB,MAAA,WACC3nB,KAAKggD,eACLhgD,KAAKw9C,SAAS71B,OACf,EAACtmB,EAyBD0gD,QAAA,WAEC,OAAW/hD,KAACu9C,MAAMr8C,IACnB,EAACG,EAOD61C,aAAA,WACC,OAAWl3C,KAACu9C,MAAMjoC,KACnB,EAACjU,EAOD2gD,QAAA,SAAQ9gD,GAGP,GAFAlB,KAAKggD,gBAEDhgD,KAAKs9C,OAAOp8C,GAcf,MAAU,IAAAe,MAAM,kCAThBjC,KAAKu9C,MAAM1nC,OAGX7V,KAAKu9C,MAAQv9C,KAAKs9C,OAAOp8C,GAGzBlB,KAAKu9C,MAAM9oC,OAKb,EAACpT,EAODo5C,eAAA,SAAeh2B,GAAgB,IAAA5U,EAC9B7P,KAAAA,KAAKggD,eAEL,IAAMoC,EAAwC,GAExCtH,EAA2B,GAE7BuH,OAAoC1gD,EAExC8iB,EAAInH,QAAQ,SAACpa,GAEZ,IAAK2M,EAAK6tC,OAAOhuC,IAAIxM,GACpB,MAAU,IAAAjB,MAA4BiB,sBAAAA,sBAGvC,IAAMvE,EAAakR,EAAK6tC,OAAOnsC,kBAAkBrO,GAC7CvE,EAAWxB,EAAkBC,WAChCyS,EAAK+vB,gBAAgB18B,GAIlBvE,EAAWnB,EAAkBE,oBAC5BmS,EAAKytC,OAAO3+C,EAAWuC,MAC1BmhD,EAAgB1jD,EAAWuC,MAMzBvC,EAAWnB,EAAkBQ,uBAChCokD,EAAyBr4C,KAAI7D,MAA7Bk8C,EACKzjD,EACHnB,EAAkBQ,uBAKrB88C,EAAY/wC,KAAK7G,GAClB,GAEAlD,KAAK09C,OAAa,OAAA,GAAAv3C,OAAK20C,EAAgBsH,GAA2B,CACjEl5C,OAAQ,QAMRm5C,GACAriD,KAAKs9C,OAAO+E,IACZriD,KAAKs9C,OAAO+E,GAAevsC,WAE3B9V,KAAKs9C,OAAO+E,GAAevsC,SAE7B,EAACzU,EAUDo+B,cAAA,SAAcv8B,EAAew+C,GACD1hD,KAAKyhD,qBAAqBC,GAElCjiB,cAAcv8B,EAClC,EAAC7B,EAQDu+B,gBAAA,SAAgB18B,GACYlD,KAAKyhD,uBAEb7hB,gBAAgB18B,EACpC,EAAC7B,EASDihD,aAAA,WACC,OAAWtiD,KAAC09C,OAAOxS,OACpB,EAAC7pC,EAMDmY,WAAA,SAAWtW,GACV,YAAYw6C,OAAOhuC,IAAIxM,EACxB,EAAC7B,EAOOkhD,wBAAA,SAAwBC,GAM/B,UAL4Br8C,OACxB4N,OAAO0uC,OAAOtlD,GACd4W,OAAO0uC,OAAOjlD,IAGa4F,SAC9Bo/C,EAEF,EAACnhD,EASD+O,wBAAA,SACClN,EACAvE,GAA4C,IAAA+jD,EAAAzyC,EAAAyyC,KAE5C,IAAK1iD,KAAK09C,OAAOhuC,IAAIxM,GACpB,UAAUjB,4BAA4BiB,EAAE,qBAGzC,IAAM5E,EAAU0B,KAAK09C,OAAO9Q,KAAK1pC,GAGjC,GAAIlD,KAAKiiD,kBAAkB3jD,GAC1B,UAAU2D,mEAKX,IAAMf,EAAO5C,EAAQK,WAAWuC,KAGhC,IAFqBlB,KAAKs9C,OAAOp8C,GAGhC,UAAUe,2BAA2Bf,EAAI,wBAG1C,IAAM8S,EAAUD,OAAOC,QAAQrV,GAG/BqV,EAAQsJ,QAAQ,SAAAnP,GAAE,IAAAq0C,EAAYr0C,KAAEtJ,EAAKsJ,EACpC,GAEA,IAF2B8B,EAAKsyC,wBAAwBC,GAGvD,MAAM,IAAIvgD,MAAK,sDACwCugD,EAA2C,iCAInG,QAAc7gD,IAAVkD,IAAwBowC,GAAiBpwC,GAC5C,MAAU,IAAA5C,MACmCugD,4CAAAA,EAG/C,GAEAxiD,KAAK09C,OAAOtpC,eACXJ,EAAQpF,IAAI,SAAAN,GAA4B,MAAA,CACvCpL,GAAI5E,EAAQ4E,GACZgR,SAFyB5F,KAGzBzJ,MAHgCyJ,EAAO,GAIvC,GACD,CAAEpF,OAAQ,QAGXw5C,OAAAA,EAAI1iD,KAACi+C,sBAALyE,EAA0B1F,mCAC3B,EAAC37C,EAQDshD,sBAAA,SAAsBz/C,EAAeC,OAAgCy/C,EACpE,IAAK5iD,KAAK09C,OAAOhuC,IAAIxM,GACpB,MAAU,IAAAjB,MAA4BiB,sBAAAA,EAAqB,qBAG5D,IAAM5E,EAAU0B,KAAK09C,OAAO9Q,KAAK1pC,GAGjC,GAAIlD,KAAKiiD,kBAAkB3jD,GAC1B,MAAM,IAAI2D,MAAK,6DAMhB,KAAK3D,GAAY6E,GAAaA,EAASnC,MAASmC,EAASE,aACxD,MAAM,IAAIpB,MAAM,6BAEjB,GAAIkB,EAASnC,OAAS1C,EAAQ6E,SAASnC,KACtC,UAAUiB,0CAC2B3D,EAAQ6E,SAASnC,cAAamC,EAASnC,MAI7E,IAAME,EAAO5C,EAAQK,WAAWuC,KAC1B2hD,EAAe7iD,KAAKs9C,OAAOp8C,GAEjC,IAAK2hD,EACJ,UAAU5gD,2BAA2Bf,EAAI,wBAG1C,IAAM84B,EAAc54B,EAAA,GAAQ9C,EAAS6E,CAAAA,SAAAA,IAE/BiuB,EAAmByxB,EAAalgD,gBAAgBq3B,GAEtD,IAAK5I,EAAiB9tB,MACrB,UAAUrB,MACqBmvB,+BAAAA,EAAiB7tB,QAAU,mBAU3D,GANAvD,KAAK09C,OAAO7pC,eACX,CAAC,CAAE3Q,GAAI5E,EAAQ4E,GAAiBC,SAAAA,IAChC,CAAE+F,OAAQ,QAIP25C,EAAa//C,oBAAqB,CACrC+/C,EAAa//C,oBAAoBk3B,GAEjC,IAAM8oB,EACL9oB,EAAer7B,WAAWxB,EAAkBC,UACvC2lD,EAAoB/iD,KAAK4hD,cAAc,CAC5CC,oBAAoB,IAGjBkB,GAAqBD,GACxBC,EAAkBjgD,oBAAoBk3B,EAExC,CAEA4oB,OAAAA,EAAI5iD,KAACi+C,sBAAL2E,EAA0B5F,mCAC3B,EAAC37C,EAQD2hD,yBAAA,SACC9/C,EACA+/C,OAiBIC,EAAA11B,EAAAxtB,KAEJ,IAAKA,KAAK09C,OAAOhuC,IAAIxM,GACpB,UAAUjB,MAA4BiB,sBAAAA,uBAGvC,IAAI5E,EAAU0B,KAAK09C,OAAO9Q,KAAK1pC,GAG/B,GAAIlD,KAAKiiD,kBAAkB3jD,GAC1B,MAAU,IAAA2D,MACkD,6DAI7D,IAOIoB,EAPEnC,EAAO5C,EAAQK,WAAWuC,KAC1B2hD,EAAe7iD,KAAKs9C,OAAOp8C,GAEjC,IAAK2hD,EACJ,MAAU,IAAA5gD,MAA2Bf,qBAAAA,EAA0B,wBAIhE,GAA8B,YAA1B5C,EAAQ6E,SAASnC,KACpBqC,EAAc/E,EAAQ6E,SAASE,YAAY,WACP,eAA1B/E,EAAQ6E,SAASnC,KAG3B,MAAM,IAAIiB,MAAK,yBACW3D,EAAQ6E,SAASnC,KAAI,wCAH/CqC,EAAc/E,EAAQ6E,SAASE,WAKhC,CAEA,GAAiC,gBAA7B4/C,EAAeviD,WAsClB,MAAU,IAAAuB,MACKghD,cAAAA,EAAeviD,WAAU,kDAtCxC,GAA4B,UAAxBuiD,EAAejiD,KAAkB,CACpC,IAAAmX,EAAmC5P,EAClC06C,EAAe/5C,OAAO,GACtB+5C,EAAe/5C,OAAO,IAMvB0xB,GAAqC,CACpCv3B,YAAAA,EACAw3B,QAViB1iB,EAAVzP,EAWPoyB,QAX6B3iB,EAAVxP,EAYnBoyB,OAPckoB,EAAepjD,QAAQk7B,QAAU,EAQ/CC,OAPcioB,EAAepjD,QAAQm7B,QAAU,GASjD,KAAmC,WAAxBioB,EAAejiD,OAOzBqC,EAC2B,aAN3B/E,EAAU65B,GACT75B,EAFa2kD,EAAepjD,QAAQ0Y,OAAS,IAOrCpV,SAASnC,KACb1C,EAAQ6E,SAAqBE,YAAY,GACzC/E,EAAQ6E,SAAwBE,aAqBvC,GAlBCA,EAAcA,EAAYuL,IAAI,SAAC3E,GAAU,MAAA,CACxCnC,EAAemC,EAAM,GAAIujB,EAAKgwB,SAASxJ,0BACvClsC,EAAemC,EAAM,GAAIujB,EAAKgwB,SAASxJ,0BACvC,GAED11C,EAAQ6E,SAASE,YACU,YAA1B/E,EAAQ6E,SAASnC,KAAqB,CAACqC,GAAeA,EAOxDrD,KAAK09C,OAAO7pC,eACX,CAAC,CAAE3Q,GAAI5E,EAAQ4E,GAAiBC,SAAU7E,EAAQ6E,WAClD,CAAE+F,OAAQ,QAGP25C,EAAa//C,oBAAqB,CACrC+/C,EAAa//C,oBAAoBxE,GACjC,IAAMwkD,EAAoBxkD,EAAQK,WAAWxB,EAAkBC,UACzD2lD,EAAoB/iD,KAAK4hD,cAAc,CAC5CC,oBAAoB,IAGjBkB,GAAqBD,GACxBC,EAAkBjgD,oBAAoBxE,EAExC,CAEwB,OAAxB4kD,EAAAljD,KAAKi+C,sBAALiF,EAA0BlG,mCAC3B,EAAC37C,EAED+C,KAAA,WAEC,OADApE,KAAKggD,iBACMhgD,KAACi+C,qBAAsBj+C,KAAKi+C,oBAAoB75C,MAC5D,EAAC/C,EAEDs2C,QAAA,WAEC,OADA33C,KAAKggD,sBACO/B,qBACTj+C,KAAKi+C,oBAAoBtG,SAE7B,EAACt2C,EAEDw2C,QAAA,WAEC,OADA73C,KAAKggD,iBACEhgD,KAAKi+C,qBACTj+C,KAAKi+C,oBAAoBpG,SAE7B,EAACx2C,EAEDmD,KAAA,WAEC,OADAxE,KAAKggD,iBACEhgD,KAAKi+C,qBAAsBj+C,KAAKi+C,oBAAoBz5C,MAC5D,EAACnD,EAED8hD,qBAAA,WACCnjD,KAAKggD,eACDhgD,KAAKi+C,qBACRj+C,KAAKi+C,oBAAoB55C,cAE3B,EAAChD,EASDq5C,YAAA,SAAY/rC,GAAgC,IAAAkf,EAC3C7tB,KAEA,OAFAA,KAAKggD,eAEmB,IAApBrxC,EAAS7I,OACL,GAGG9F,KAAC09C,OAAOpW,KAClB34B,EACA,SAACrQ,GAEA,GAAII,EAAgBJ,GAAU,CAC7B,IAAM8kD,EAAc9kD,EAAQK,WAAWuC,KACjCmiD,EAAcx1B,EAAKyvB,OAAO8F,GAGhC,IAAKC,EACJ,MAAO,CACNngD,GAAK5E,EAA+B4E,GACpCI,OAAO,EACPC,OAAW6/C,oDAKb,IACMhyB,EADaiyB,EAAY1gD,gBAAgBiyC,KAAKyO,EAC3B3hD,CAAWpD,GAOpC,MAAO,CACN4E,GAAK5E,EAA+B4E,GACpCI,MARa8tB,EAAiB9tB,MAS9BC,OARc6tB,EAAiB7tB,OAC7B6tB,EAAiB7tB,OAChB6tB,EAAiB9tB,WAEjB3B,EADA,qBAOL,CAGA,MAAO,CACNuB,GAAK5E,EAA+B4E,GACpCI,OAAO,EACPC,OAAQ,+BAEV,EACA,SAACjF,GACA,GAAII,EAAgBJ,GAAU,CAC7B,IACM+kD,EAAcx1B,EAAKyvB,OADLh/C,EAAQK,WAAWuC,MAEnCmiD,GAAeA,EAAYxgD,mBAC9BwgD,EAAYxgD,kBAAkBvE,EAEhC,CACD,EACA,CAAE4K,OAAQ,OAEZ,EAAC7H,EAMDoT,MAAA,WAAK,IAAAq4B,EAAA9sC,KAEAA,KAAKy9C,WAITz9C,KAAKy9C,UAAW,EAChBz9C,KAAKw9C,SAASp7C,SAAS,CACtBkhD,QAAS,WACRxW,EAAK6Q,gBAAgBkB,MAAMvhC,QAAQ,SAACy2B,GACnCA,GACD,EACD,EACAS,SAAU,WACT,OAAO1H,EAAKyQ,MAAMjoC,KACnB,EACA5Q,QAAS,SAAC3C,GACT,IAAMwhD,EAA4BzW,EAAKiR,gBACpCjR,EAAKiR,gBAAgBnG,kBACrB,CAAEtzC,SAAU,EAAGC,SAAU,GAC5BuoC,EAAKyQ,MAAM74C,QAAQ3C,GACnB+qC,EAAKwT,gCAAgCiD,EACtC,EACA9+C,YAAa,SAAC1C,GACb+qC,EAAKyQ,MAAM94C,YAAY1C,EACxB,EACAmC,UAAW,SAACnC,GACP+qC,EAAKmT,+BAA+Bl+C,IAIxC+qC,EAAKyQ,MAAMr5C,UAAUnC,EACtB,EACAoC,QAAS,SAACpC,GACT,IAAMyhD,EAA4B1W,EAAKiR,gBACpCjR,EAAKiR,gBAAgBnG,kBACrB,CAAEtzC,SAAU,EAAGC,SAAU,GAC5BuoC,EAAKyQ,MAAMp5C,QAAQpC,GACnB+qC,EAAKwT,gCAAgCkD,EACtC,EACA/jD,YAAa,SAACsC,EAAO4C,GACpBmoC,EAAKyQ,MAAM99C,YAAYsC,EAAO4C,EAC/B,EACAjF,OAAQ,SAACqC,EAAO4C,GACfmoC,EAAKyQ,MAAM79C,OAAOqC,EAAO4C,EAC1B,EACAhF,UAAW,SAACoC,EAAO4C,GAClBmoC,EAAKyQ,MAAM59C,UAAUoC,EAAO4C,EAC7B,EACA8+C,QAAS,WAGR3W,EAAKyQ,MAAMznC,UAGXg3B,EAAK4Q,OAAO/1B,MAAM,CAAEze,OAAQ,OAC7B,IAEF,EAAC7H,EAODqiD,oBAAA,SACCriC,EACAxhB,GAIA,OAAWG,KAACygD,mBACX,CACCj4C,IAJmB6Y,EAAb7Y,IAKNC,IALmB4Y,EAAR5Y,KAOZ5I,EAEF,EAACwB,EAMDsiD,0BAAA,SACC5hD,EACAlC,GAEA,IAIMwhB,EAJqBrhB,KAAKw9C,SAAS7J,mBAAmBiB,KAC3D50C,KAAKw9C,SAGS7J,CAAmB5xC,GAIlC,OAAe,OAAXsf,EACI,GAGDrhB,KAAKygD,mBAAmBp/B,EAAQxhB,EACxC,EAACwB,EAMDwU,KAAA,WAEM7V,KAAKy9C,WAIVz9C,KAAKy9C,UAAW,EAChBz9C,KAAKw9C,SAAS1L,aACf,EAACzwC,EASDi5C,GAAA,SACCv4C,EACA8vC,GAEA,IAAM+R,EAAY5jD,KAAK29C,gBACtB57C,GAEI6hD,EAAUxgD,SAASyuC,IACvB+R,EAAU75C,KAAK8nC,EAEjB,EAACxwC,EASDg5C,IAAA,SACCt4C,EACA8vC,GAEA,IAAM+R,EAAY5jD,KAAK29C,gBACtB57C,GAEG6hD,EAAUxgD,SAASyuC,IACtB+R,EAAUljB,OAAOkjB,EAAUvhC,QAAQwvB,GAAW,EAEhD,EAAC1sC,EAAA83C,EAAA73C,CAAAA,CAAAA,cAAAC,IA5qBD,WACC,OAAOrF,KAAKy9C,QACb,EAACn4C,IAKD,SAAYC,GACX,MAAM,IAAItD,MAAM,uBACjB,IAsqBD,CA14CC,uoBCnJ0C,SAC1C3D,EACAulD,GAEA,MAA8B,YAA1BvlD,EAAQ6E,SAASnC,KACb,CACNsC,OAAO,EACPC,OAAQpE,GAIG8tC,GAAwB3uC,EAAQ6E,UAElC0gD,EACH,CACNvgD,OAAO,EACPC,OAlBF,2CAsBO,CAAED,OAAO,EACjB,sCrBrB2C,SAC1ChF,EACAwlD,GAEA,MAA8B,YAA1BxlD,EAAQ6E,SAASnC,KACb,CACNsC,OAAO,EACPC,OAAQpE,GAIN8tC,GAAwB3uC,EAAQ6E,UAAY2gD,EACxC,CACNxgD,OAAO,EACPC,OAAQgqC,IAIH,CAAEjqC,OAAO,EACjB,sCCjB2C,SAC1ChF,GAEA,MAC2B,YAA1BA,EAAQ6E,SAASnC,MACS,eAA1B1C,EAAQ6E,SAASnC,KAEV,CACNsC,OAAO,EACPC,OAAQiqC,IAImBxjC,EAC5B1L,GAIO,CACNgF,OAAO,EACPC,OAAQkqC,IAIH,CAAEnqC,OAAO,EACjB"}